Tutorials#
Welcome to tutorials! We will go through the basics on how to detect density ridges from a .fits image and post-process the results.
Basic Usage#
Here, we will focus on how to identify density ridges in a 2D or 3D .fits image and post-process the results. Specifically, we will go over how to grid the results back into the image space and prune branches from the gridded results.
Find Ridges#
To detect density ridges in a .fits image :
from crispy import image_ridge_find as irf
# Set up the data and input parameters
image_file = "input_image.fits" # Input .fits image file
thres = 0.5 # Minimum density threshold for valid data points
h = 2 # Smoothing bandwidth (recommended: Nyquist-sampled resolution)
# Find ridges (e.g., filaments)
ridge_data = irf.run(image_file, h=h, thres=thres)
To save the results to a .txt file:
# Save the results to a file
ridge_file = "ridge_coords.txt"
irf.write_output(coords=ridge_data, fname=ridge_file)
Tips on Parameter Choices:
Smoothing Bandwidth (
h): Controls the resolution of ridge detection. For Nyquist-sampled images, start withh=2. Larger values suppress noise at the expense of resolution.Density Threshold (
thres): The minimum intensity for a pixel to be included in the run.Convergence Criterion (
eps): Defines the precision for ridge convergence. Lower precision are faster to converge.Walker Parameters: Include options for their initial placements. Reducing the number of walkers needed can greatly reduce the run time needed.
Grid Results#
To grid the ridge detection results back onto the native grid of the input image:
from crispy import grid_ridge as gr
# Input and output file paths
ridge_file = "ridge_coords.txt" # File containing the ridge coordinates
image_file = "input_image.fits" # Input/reference image file
skel_file = "gridded_skel.fits" # File to save gridded results (skeletons)
# Grid ridge results
gr.grid_skel(readFile=ridge_file, imgFile=image_file, writeFile=skel_file)
Prune Branches#
To prune branches from the gridded results (i.e., skeletons) into a branchless structure (i.e., spine):
from crispy.pruning import Skeleton
# Input and output file paths
skel_file = "ridge_skel.fits" # Gridded skeleton file
spine_file = "ridge_spine.fits" # Output file for pruned skeletons (spines)
# Load skeleton and apply pruning
skel_obj = Skeleton.Skeleton(skel_file)
skel_obj.prune_from_scratch()
# Save the pruned skeleton
skel_obj.save_pruned_skel(spine_file, overwrite=True)
Note
If you use the branch-pruning function, please also cite the FilFinder software for the 2D pruning algorithm from which MUFASA’s 3D version is based on:
Koch & Rosolowsky. “FilFinder: Filamentary structure in molecular clouds.” (2016).