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