From 5f704ad5acd38be5432f0f00f5fe6a20f06046f2 Mon Sep 17 00:00:00 2001 From: Laurent Guerard <laurent.guerard@unibas.ch> Date: Wed, 8 Jan 2025 14:38:47 +0100 Subject: [PATCH] Update docstrings --- 1_identify_fibers.py | 242 +++++++++++++++---------------------------- 1 file changed, 86 insertions(+), 156 deletions(-) diff --git a/1_identify_fibers.py b/1_identify_fibers.py index bb73a5a..2debeef 100755 --- a/1_identify_fibers.py +++ b/1_identify_fibers.py @@ -28,47 +28,19 @@ from fiji.plugin.trackmate.providers import ( SpotMorphologyAnalyzerProvider, ) from fiji.plugin.trackmate.tracking.jaqaman import SparseLAPTrackerFactory +from ij import IJ +from ij import WindowManager as wm +from ij.measure import ResultsTable +from ij.plugin import Duplicator, ImageCalculator, RoiEnlarger +from imcflibs import pathtools +from imcflibs.imagej import bioformats as bf +from imcflibs.imagej import misc -from java.lang import Double - -from ch.epfl.biop.ij2command import Labels2Rois - - -#@ String (visibility=MESSAGE, value="<html><b> Welcome to Myosoft - identify fibers! </b></html>") msg1 -#@ File (label="Select directory for output", style="directory") output_dir -#@ File (label="Select image file", description="select your image") path_to_image -#@ File(label="Cellpose environment folder", style="directory", description="Folder with the cellpose env") cellpose_dir -#@ Boolean (label="close image after processing", description="tick this box when using batch mode", value=False) close_raw -#@ String (visibility=MESSAGE, value="<html><b> Morphometric Gates </b></html>") msg2 -#@ Integer (label="Min Area [um²]", value=10) minAr -#@ Integer (label="Max Area [um²]", value=6000) maxAr -#@ Double (label="Min Circularity", value=0.5) minCir -#@ Double (label="Max Circularity", value=1) maxCir -#@ Double (label="Min solidity", value=0.0) minSol -#@ Double (label="Max solidity", value=1) maxSol -#@ Integer (label="Min perimeter [um]", value=5) minPer -#@ Integer (label="Max perimeter [um]", value=300) maxPer -#@ Integer (label="Min min ferret [um]", value=0.1) minMinFer -#@ Integer (label="Max min ferret [um]", value=100) maxMinFer -#@ Integer (label="Min ferret AR", value=0) minFAR -#@ Integer (label="Max ferret AR", value=8) maxFAR -#@ Double (label="Min roundess", value=0.2) minRnd -#@ Double (label="Max roundess", value=1) maxRnd -#@ String (visibility=MESSAGE, value="<html><b> Expand ROIS to match fibers </b></html>") msg3 -#@ Double (label="ROI expansion [microns]", value=1) enlarge -#@ String (visibility=MESSAGE, value="<html><b> channel positions in the hyperstack </b></html>") msg5 -#@ Integer (label="Membrane staining channel number", style="slider", min=1, max=5, value=1) membrane_channel -#@ Integer (label="Fiber staining (MHC) channel number (0=skip)", style="slider", min=0, max=5, value=3) fiber_channel -#@ Integer (label="minimum fiber intensity (0=auto)", description="0 = automatic threshold detection", value=0) min_fiber_intensity -#@ Integer (label="sub-tiling to economize RAM", style="slider", min=1, max=8, value=4) tiling_factor - -#@ RoiManager rm -#@ ResultsTable rt +# ─── Functions ──────────────────────────────────────────────────────────────── def fix_ij_options(): - """put IJ into a defined state - """ + """Put IJ into a defined state.""" # disable inverting LUT IJ.run("Appearance...", " menu=0 16-bit=Automatic") # set foreground color to be white, background black @@ -85,7 +57,7 @@ def fix_ij_options(): def fix_ij_dirs(path): - """use forward slashes in directory paths + """use forward slashes in directory paths. Parameters ---------- @@ -104,34 +76,32 @@ def fix_ij_dirs(path): return fixed_path -def open_image_with_BF(path_to_file): - """ use Bio-Formats to opens the first image from an image file path +def fix_BF_czi_imagetitle(imp): + """Fix the title of an image read using the bio-formats importer. + + The title is modified to remove the ".czi" extension and replace + spaces with underscores. Parameters ---------- - path_to_file : string - path to the image file + imp : ij.ImagePlus + The image to be processed. Returns ------- - ImagePlus - the first imp stored in a give file + string + The modified title of the image. """ - options = ImporterOptions() - options.setColorMode(ImporterOptions.COLOR_MODE_GRAYSCALE) - options.setAutoscale(True) - options.setId(path_to_file) - imps = BF.openImagePlus(options) # is an array of ImagePlus - - return imps[0] - - -def fix_BF_czi_imagetitle(imp): - image_title = os.path.basename( imp.getShortTitle() ) + image_title = os.path.basename(imp.getShortTitle()) + # remove the ".czi" extension image_title = image_title.replace(".czi", "") + # replace spaces with underscores image_title = image_title.replace(" ", "_") + # remove any double underscores image_title = image_title.replace("_-_", "") + # remove any double underscores image_title = image_title.replace("__", "_") + # remove any "#" characters image_title = image_title.replace("#", "Series") return image_title @@ -154,11 +124,13 @@ def preprocess_membrane_channel(imp): def get_threshold_from_method(imp, channel, method): - """returns the threshold value of chosen IJ AutoThreshold method in desired channel + """Get the value of automated threshold method. + + Returns the threshold value of chosen IJ AutoThreshold method in desired channel. Parameters ---------- - imp : ImagePlus + imp : ij.ImagePlus the imp from which to get the threshold value channel : integer the channel in which to get the treshold @@ -187,21 +159,20 @@ def run_tm( seg_model, diam_seg, channel_sec=0, - quality_thresh=[0,0], - intensity_thresh=[0,0], - circularity_thresh=[0,0], - perimeter_thresh=[0,0], - feret_thresh=[0,0], - area_thresh=[0,0], + quality_thresh=[0, 0], + intensity_thresh=[0, 0], + circularity_thresh=[0, 0], + perimeter_thresh=[0, 0], + area_thresh=[0, 0], crop_roi=None, use_gpu=True, ): """ - Function to run TrackMate on open data + Function to run TrackMate on open data, applying filters to spots. Parameters ---------- - implus : ImagePlus + implus : ij.ImagePlus ImagePlus on which to run the function channel_seg : int Channel of interest @@ -214,17 +185,15 @@ def run_tm( channel_sec : int, optional Secondary channel to use for segmentation, by default 0 quality_thresh : float, optional - Threshold for quality filtering, by default 0 + Threshold for quality filtering, by default None intensity_thresh : float, optional - Threshold for intensity filtering, by default 0 + Threshold for intensity filtering, by default None circularity_thresh : float, optional - Threshold for circularity filtering, by default 0 + Threshold for circularity filtering, by default None perimeter_thresh : float, optional - Threshold for perimeter filtering, by default 0 - feret_thresh : float, optional - Threshold for Feret filtering, by default 0 + Threshold for perimeter filtering, by default None area_thresh : float, optional - Threshold for area filtering, by default 0 + Threshold for area filtering, by default None crop_roi : ROI, optional ROI to crop on the image, by default None use_gpu : bool, optional @@ -232,7 +201,7 @@ def run_tm( Returns ------- - ImagePlus + ij.ImagePlus Label image with the segmented objects """ @@ -346,6 +315,7 @@ def run_tm( implus.setDimensions(dims[2], dims[3], dims[4]) return label_imp + def set_trackmate_filter(settings, filter_name, filter_value): """Sets a TrackMate spot filter with specified filter name and values. @@ -365,12 +335,13 @@ def set_trackmate_filter(settings, filter_name, filter_value): settings.addSpotFilter(filter) return settings + def delete_channel(imp, channel_number): - """delete a channel from target imp + """Delete a channel from target imp. Parameters ---------- - imp : ImagePlus + imp : ij.ImagePlus the imp from which to delete target channel channel_number : integer the channel number to be deleted. starts at 0. @@ -379,59 +350,14 @@ def delete_channel(imp, channel_number): IJ.run(imp, "Delete Slice", "delete=channel") -def run_extended_particle_analyzer( imp, eda_parameters ): - """identifies ROIs in target imp using the extended particle analyzer of the BioVoxxel toolbox - with given parameters +def measure_in_all_rois(imp, channel, rm): + """Gives measurements for all ROIs in ROIManager. - Parameters - ---------- - imp : ImagePlus - the image on which to run the EPA on. Should be 8-bit thresholded - eda_parameters : array - all user defined parameters to restrict ROI identification - """ - epa = Extended_Particle_Analyzer() - epa.readInputImageParameters(imp) - epa.setDefaultParameterFields() - - # expose all parameters explicitly - epa.usePixel = False - epa.usePixelForOutput = False - epa.Area = str(eda_parameters[0]) + "-" + str(eda_parameters[1]) - epa.Extent = "0.00-1.00" - epa.Perimeter = str(eda_parameters[2]) + "-" + str(eda_parameters[3]) - epa.Circularity = str(eda_parameters[4]) + "-" + str(eda_parameters[5]) - epa.Roundness = str(eda_parameters[6]) + "-" + str(eda_parameters[7]) - epa.Solidity = str(eda_parameters[8]) + "-" + str(eda_parameters[9]) - epa.Compactness = "0.00-1.00" - epa.AR = "0-Infinity" - epa.FeretAR = str(eda_parameters[10]) + "-" + str(eda_parameters[11]) - epa.EllipsoidAngle = "0-180" - epa.MaxFeret = "0-Infinity" - epa.MinFeret = str(eda_parameters[12]) + "-" + str(eda_parameters[13]) - epa.FeretAngle = "0-180" - epa.COV = "0.00-1.00" - epa.Output = "Nothing" - epa.Redirect = "None" - epa.Correction = "None" - epa.Reset = False - epa.DisplayResults = False - epa.ClearResults = False - epa.Summarize = False - epa.AddToManager = True - epa.ExcludeEdges = False - epa.IncludeHoles = False - - epa.defineParticleAnalyzers() - epa.particleAnalysis( imp.getProcessor(), imp, imp.getTitle() ) - - -def measure_in_all_rois( imp, channel, rm ): - """measures in all ROIS on a given channel of imp all parameters that are set in IJ "Set Measurements" + Measures in all ROIS on a given channel of imp all parameters that are set in IJ "Set Measurements". Parameters ---------- - imp : ImagePlus + imp : ij.ImagePlus the imp to measure on channel : integer the channel to measure in. starts at 1. @@ -439,12 +365,12 @@ def measure_in_all_rois( imp, channel, rm ): a reference of the IJ-RoiManager """ imp.setC(channel) - rm.runCommand(imp,"Deselect") - rm.runCommand(imp,"Measure") + rm.runCommand(imp, "Deselect") + rm.runCommand(imp, "Measure") -def change_all_roi_color( rm, color ): - """change the color of all ROIs in the RoiManager +def change_all_roi_color(rm, color): + """Cchange the color of all ROIs in the RoiManager. Parameters ---------- @@ -454,13 +380,13 @@ def change_all_roi_color( rm, color ): the desired color. e.g. "green", "red", "yellow", "magenta" ... """ number_of_rois = rm.getCount() - for roi in range( number_of_rois ): + for roi in range(number_of_rois): rm.select(roi) rm.runCommand("Set Color", color) -def change_subset_roi_color( rm, selected_rois, color ): - """change the color of selected ROIs in the RoiManager +def change_subset_roi_color(rm, selected_rois, color): + """Change the color of selected ROIs in the RoiManager. Parameters ---------- @@ -478,21 +404,21 @@ def change_subset_roi_color( rm, selected_rois, color ): def show_all_rois_on_image(rm, imp): - """shows all ROIs in the ROiManager on imp + """Shows all ROIs in the ROiManager on imp. Parameters ---------- rm : RoiManager a reference of the IJ-RoiManager - imp : ImagePlus + imp : ij.ImagePlus the imp on which to show the ROIs """ imp.show() - rm.runCommand(imp,"Show All") + rm.runCommand(imp, "Show All") def save_all_rois(rm, target): - """save all ROIs in the RoiManager as zip to target path + """Save all ROIs in the RoiManager as zip to target path. Parameters ---------- @@ -504,8 +430,8 @@ def save_all_rois(rm, target): rm.runCommand("Save", target) -def save_selected_rois( rm, selected_rois, target ): - """save selected ROIs in the RoiManager as zip to target path +def save_selected_rois(rm, selected_rois, target): + """Save selected ROIs in the RoiManager as zip to target path. Parameters ---------- @@ -522,8 +448,8 @@ def save_selected_rois( rm, selected_rois, target ): rm.runCommand("Deselect") -def enlarge_all_rois( amount_in_um, rm, pixel_size_in_um ): - """enlarges all ROIs in the RoiManager by x scaled units +def enlarge_all_rois(amount_in_um, rm, pixel_size_in_um): + """Enlarges all ROIs in the RoiManager by x scaled units. Parameters ---------- @@ -542,13 +468,15 @@ def enlarge_all_rois( amount_in_um, rm, pixel_size_in_um ): rm.addRoi(enlarged_roi) -def select_positive_fibers( imp, channel, rm, min_intensity ): - """For all ROIs in the RoiManager, select ROIs based on intensity measurement in given channel of imp. +def select_positive_fibers(imp, channel, rm, min_intensity): + """Select ROIs in ROIManager based on intensity in specific channel. + + For all ROIs in the RoiManager, select ROIs based on intensity measurement in given channel of imp. See https://imagej.nih.gov/ij/developer/api/ij/process/ImageStatistics.html Parameters ---------- - imp : ImagePlus + imp : ij.ImagePlus the imp on which to measure channel : integer the channel on which to measure. starts at 1 @@ -574,8 +502,10 @@ def select_positive_fibers( imp, channel, rm, min_intensity ): return selected_rois -def preset_results_column( rt, column, value): - """pre-set all rows in given column of the IJ-ResultsTable with desired value +def preset_results_column(rt, column, value): + """Pre-set values in selected column from the ResultsTable. + + Pre-set all rows in given column of the IJ-ResultsTable with desired value. Parameters ---------- @@ -586,14 +516,14 @@ def preset_results_column( rt, column, value): value : string or float or integer the value to be set """ - for i in range( rt.size() ): + for i in range(rt.size()): rt.setValue(column, i, value) rt.show("Results") -def add_results( rt, column, row, value ): - """adds a value in desired rows of a given column +def add_results(rt, column, row, value): + """Adds a value in desired rows of a given column. Parameters ---------- @@ -612,21 +542,21 @@ def add_results( rt, column, row, value ): rt.show("Results") -def enhance_contrast( imp ): - """use "Auto" Contrast & Brightness settings in each channel of imp +def enhance_contrast(imp): + """Use "Auto" Contrast & Brightness settings in each channel of imp. Parameters ---------- - imp : ImagePlus + imp : ij.ImagePlus the imp on which to change C&B """ - for channel in range( imp.getDimensions()[2] ): - imp.setC(channel + 1) # IJ channels start at 1 + for channel in range(imp.getDimensions()[2]): + imp.setC(channel + 1) # IJ channels start at 1 IJ.run(imp, "Enhance Contrast", "saturated=0.35") def renumber_rois(rm): - """rename all ROIs in the RoiManager according to their number + """Rename all ROIs in the RoiManager according to their number. Parameters ---------- @@ -634,12 +564,12 @@ def renumber_rois(rm): a reference of the IJ-RoiManager """ number_of_rois = rm.getCount() - for roi in range( number_of_rois ): - rm.rename( roi, str(roi + 1) ) + for roi in range(number_of_rois): + rm.rename(roi, str(roi + 1)) def setup_defined_ij(rm, rt): - """set up a clean and defined Fiji user environment + """Set up a clean and defined Fiji user environment. Parameters ---------- -- GitLab