# this is a python rewrite of the original ijm published at
# https://github.com/Hyojung-Choo/Myosoft/blob/Myosoft-hub/Scripts/central%20nuclei%20counter.ijm

# IJ imports
# TODO: are the imports RoiManager and ResultsTable needed when using the services?
from ij import IJ, WindowManager as wm
from ij.plugin import Duplicator, RoiEnlarger, RoiScaler

from ij.measure import ResultsTable

# Bio-formats imports
from loci.plugins import BF
from loci.plugins.in import ImporterOptions

# python imports
import time
import os
import sys

# TrackMate imports
from fiji.plugin.trackmate import Logger, Model, SelectionModel, Settings, TrackMate
from fiji.plugin.trackmate.action import LabelImgExporter
from fiji.plugin.trackmate.cellpose import CellposeDetectorFactory
from fiji.plugin.trackmate.cellpose.CellposeSettings import PretrainedModel
from fiji.plugin.trackmate.features import FeatureFilter
from fiji.plugin.trackmate.providers import (
    SpotAnalyzerProvider,
    SpotMorphologyAnalyzerProvider,
)
from fiji.plugin.trackmate.tracking.jaqaman import SparseLAPTrackerFactory

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


def fix_ij_options():
    """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
    IJ.run("Colors...", "foreground=white background=black selection=red")
    # black BG for binary images and pad edges when eroding
    IJ.run("Options...", "black pad")
    # set saving format to .txt files
    IJ.run("Input/Output...", "file=.txt save_column save_row")
    # ============= DON’T MOVE UPWARDS =============
    # set "Black Background" in "Binary Options"
    IJ.run("Options...", "black")
    # scale when converting = checked
    IJ.run("Conversions...", "scale")


def fix_ij_dirs(path):
    """use forward slashes in directory paths

    Parameters
    ----------
    path : string
        a directory path obtained from dialogue or script parameter

    Returns
    -------
    string
        a more robust path with forward slashes as separators
    """

    fixed_path = str(path).replace("\\", "/")
    # fixed_path = fixed_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

    Parameters
    ----------
    path_to_file : string
        path to the image file

    Returns
    -------
    ImagePlus
        the first imp stored in a give file
    """
    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 = image_title.replace(".czi", "")
    image_title = image_title.replace(" ", "_")
    image_title = image_title.replace("_-_", "")
    image_title = image_title.replace("__", "_")
    image_title = image_title.replace("#", "Series")

    return image_title


def preprocess_membrane_channel(imp):
    """apply myosoft pre-processing steps for the membrane channel

    Parameters
    ----------
    imp : ImagePlus
        a single channel image of the membrane staining
    """
    IJ.run(imp, "Enhance Contrast", "saturated=0.35")
    IJ.run(imp, "Apply LUT", "")
    IJ.run(imp, "Enhance Contrast", "saturated=1")
    IJ.run(imp, "8-bit", "")
    IJ.run(imp, "Invert", "")
    IJ.run(imp, "Convolve...", "text1=[-1.0 -1.0 -1.0 -1.0 -1.0\n-1.0 -1.0 -1.0 -1.0 0\n-1.0 -1.0 24.0 -1.0 -1.0\n-1.0 -1.0 -1.0 -1.0 -1.0\n-1.0 -1.0 -1.0 -1.0 0] normalize")


def get_threshold_from_method(imp, channel, method):
    """returns the threshold value of chosen IJ AutoThreshold method in desired channel

    Parameters
    ----------
    imp : ImagePlus
        the imp from which to get the threshold value
    channel : integer
        the channel in which to get the treshold
    method : string
        the AutoThreshold method to use

    Returns
    -------
    list
        the upper and the lower threshold (integer values)
    """
    imp.setC(channel) # starts at 1
    ip = imp.getProcessor()
    ip.setAutoThreshold(method + " dark")
    lower_thr = ip.getMinThreshold()
    upper_thr = ip.getMaxThreshold()
    ip.resetThreshold()

    return lower_thr, upper_thr


def run_tm(
    implus,
    channel_seg,
    cellpose_env,
    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],
    crop_roi=None,
    use_gpu=True,
):
    """
    Function to run TrackMate on open data

    Parameters
    ----------
    implus : ImagePlus
        ImagePlus on which to run the function
    channel_seg : int
        Channel of interest
    cellpose_env : str
        Path to the cellpose environment
    seg_model : PretrainedModel
        Model to use for the segmentation
    diam_seg : float
        Diameter to use for segmentation
    channel_sec : int, optional
        Secondary channel to use for segmentation, by default 0
    quality_thresh : float, optional
        Threshold for quality filtering, by default 0
    intensity_thresh : float, optional
        Threshold for intensity filtering, by default 0
    circularity_thresh : float, optional
        Threshold for circularity filtering, by default 0
    perimeter_thresh : float, optional
        Threshold for perimeter filtering, by default 0
    feret_thresh : float, optional
        Threshold for Feret filtering, by default 0
    area_thresh : float, optional
        Threshold for area filtering, by default 0
    crop_roi : ROI, optional
        ROI to crop on the image, by default None
    use_gpu : bool, optional
        Boolean to use GPU or not, by default True

    Returns
    -------
    ImagePlus
        Label image with the segmented objects
    """

    # Get image dimensions and calibration
    dims = implus.getDimensions()
    cal = implus.getCalibration()

    # If the image has more than one slice, adjust the dimensions
    if implus.getNSlices() > 1:
        implus.setDimensions(dims[2], dims[4], dims[3])

    # Set ROI if provided
    if crop_roi is not None:
        implus.setRoi(crop_roi)

    # Initialize TrackMate model
    model = Model()
    model.setLogger(Logger.IJTOOLBAR_LOGGER)

    # Prepare settings for TrackMate
    settings = Settings(implus)
    settings.detectorFactory = CellposeDetectorFactory()

    # Configure detector settings
    settings.detectorSettings["TARGET_CHANNEL"] = channel_seg
    settings.detectorSettings["OPTIONAL_CHANNEL_2"] = channel_sec
    settings.detectorSettings["CELLPOSE_PYTHON_FILEPATH"] = os.path.join(
        cellpose_env, "python.exe"
    )
    settings.detectorSettings["CELLPOSE_MODEL_FILEPATH"] = os.path.join(
        os.environ["USERPROFILE"], ".cellpose", "models"
    )
    settings.detectorSettings["CELLPOSE_MODEL"] = seg_model
    settings.detectorSettings["CELL_DIAMETER"] = diam_seg
    settings.detectorSettings["USE_GPU"] = use_gpu
    settings.detectorSettings["SIMPLIFY_CONTOURS"] = True

    settings.initialSpotFilterValue = -1.0

    # Add spot analyzers
    spotAnalyzerProvider = SpotAnalyzerProvider(1)
    spotMorphologyProvider = SpotMorphologyAnalyzerProvider(1)

    for key in spotAnalyzerProvider.getKeys():
        settings.addSpotAnalyzerFactory(spotAnalyzerProvider.getFactory(key))

    for key in spotMorphologyProvider.getKeys():
        settings.addSpotAnalyzerFactory(spotMorphologyProvider.getFactory(key))

    # Apply spot filters based on thresholds
    if any(quality_thresh):
        settings = set_trackmate_filter(settings, "QUALITY", quality_thresh)
    if any(intensity_thresh):
        settings = set_trackmate_filter(settings, "MEAN_INTENSITY_CH" + str(channel_seg), intensity_thresh)
    if any(circularity_thresh):
        settings = set_trackmate_filter(settings, "CIRCULARITY", circularity_thresh)
    if any(area_thresh):
        settings = set_trackmate_filter(settings, "AREA", area_thresh)
    if any(perimeter_thresh):
        settings = set_trackmate_filter(settings, "PERIMETER", perimeter_thresh)
    if any(feret_thresh):
        settings = set_trackmate_filter(settings, "FERET", feret_thresh)


    print(settings)

    # Configure tracker
    settings.trackerFactory = SparseLAPTrackerFactory()
    settings.trackerSettings = settings.trackerFactory.getDefaultSettings()
    # settings.addTrackAnalyzer(TrackDurationAnalyzer())
    settings.trackerSettings["LINKING_MAX_DISTANCE"] = 3.0
    settings.trackerSettings["GAP_CLOSING_MAX_DISTANCE"] = 3.0
    settings.trackerSettings["MAX_FRAME_GAP"] = 2


    # Initialize TrackMate with model and settings
    trackmate = TrackMate(model, settings)
    trackmate.computeSpotFeatures(True)
    trackmate.computeTrackFeatures(False)

    # Check input validity
    if not trackmate.checkInput():
        sys.exit(str(trackmate.getErrorMessage()))
        return

    # Process the data
    if not trackmate.process():
        if "[SparseLAPTracker] The spot collection is empty." in str(
            trackmate.getErrorMessage()
        ):
            return IJ.createImage(
                "Untitled",
                "8-bit black",
                implus.getWidth(),
                implus.getHeight(),
                implus.getNFrames(),
            )
        else:
            sys.exit(str(trackmate.getErrorMessage()))
            return

    # Export the label image
    # sm = SelectionModel(model)
    exportSpotsAsDots = False
    exportTracksOnly = False
    label_imp = LabelImgExporter.createLabelImagePlus(
        trackmate, exportSpotsAsDots, exportTracksOnly, False
    )
    label_imp.setDimensions(1, dims[3], dims[4])
    label_imp.setCalibration(cal)
    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.

    Parameters
    ----------
    settings : Settings
        TrackMate settings object to which the filter will be added.
    filter_name : str
        The name of the filter to be applied.
    filter_value : list
        A list containing two values for the filter. The first value is
        applied as an above-threshold filter, and the second as a below-threshold filter.
    """
    filter = FeatureFilter(filter_name, filter_value[0], True)
    settings.addSpotFilter(filter)
    filter = FeatureFilter(filter_name, filter_value[1], False)
    settings.addSpotFilter(filter)
    return settings

def delete_channel(imp, channel_number):
    """delete a channel from target imp

    Parameters
    ----------
    imp : ImagePlus
        the imp from which to delete target channel
    channel_number : integer
        the channel number to be deleted. starts at 0.
    """
    imp.setC(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

    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"

    Parameters
    ----------
    imp : ImagePlus
        the imp to measure on
    channel : integer
        the channel to measure in. starts at 1.
    rm : RoiManager
        a reference of the IJ-RoiManager
    """
    imp.setC(channel)
    rm.runCommand(imp,"Deselect")
    rm.runCommand(imp,"Measure")


def change_all_roi_color( rm, color ):
    """change the color of all ROIs in the RoiManager

    Parameters
    ----------
    rm : RoiManager
        a reference of the IJ-RoiManager
    color : string
        the desired color. e.g. "green", "red", "yellow", "magenta" ...
    """
    number_of_rois = rm.getCount()
    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

    Parameters
    ----------
    rm : RoiManager
        a reference of the IJ-RoiManager
    selected_rois : array
        ROIs in the RoiManager to change
    color : string
        the desired color. e.g. "green", "red", "yellow", "magenta" ...
    """
    rm.runCommand("Deselect")
    rm.setSelectedIndexes(selected_rois)
    rm.runCommand("Set Color", color)
    rm.runCommand("Deselect")


def show_all_rois_on_image(rm, imp):
    """shows all ROIs in the ROiManager on imp

    Parameters
    ----------
    rm : RoiManager
        a reference of the IJ-RoiManager
    imp : ImagePlus
        the imp on which to show the ROIs
    """
    imp.show()
    rm.runCommand(imp,"Show All")


def save_all_rois(rm, target):
    """save all ROIs in the RoiManager as zip to target path

    Parameters
    ----------
    rm : RoiManager
        a reference of the IJ-RoiManager
    target : string
        the path in to store the ROIs. e.g. /my-images/resulting_rois.zip
    """
    rm.runCommand("Save", target)


def save_selected_rois( rm, selected_rois, target ):
    """save selected ROIs in the RoiManager as zip to target path

    Parameters
    ----------
    rm : RoiManager
        a reference of the IJ-RoiManager
    selected_rois : array
        ROIs in the RoiManager to save
    target : string
        the path in to store the ROIs. e.g. /my-images/resulting_rois_subset.zip
    """
    rm.runCommand("Deselect")
    rm.setSelectedIndexes(selected_rois)
    rm.runCommand("save selected", 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

    Parameters
    ----------
    amount_in_um : float
        the value by which to enlarge in scaled units, e.g 3.5
    rm : RoiManager
        a reference of the IJ-RoiManager
    pixel_size_in_um : float
        the pixel size, e.g. 0.65 px/um
    """
    amount_px = amount_in_um / pixel_size_in_um
    all_rois = rm.getRoisAsArray()
    rm.reset()
    for roi in all_rois:
        enlarged_roi = RoiEnlarger.enlarge(roi, amount_px)
        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.
    See https://imagej.nih.gov/ij/developer/api/ij/process/ImageStatistics.html

    Parameters
    ----------
    imp : ImagePlus
        the imp on which to measure
    channel : integer
        the channel on which to measure. starts at 1
    rm : RoiManager
        a reference of the IJ-RoiManager
    min_intensity : integer
        the selection criterion (here: intensity threshold)

    Returns
    -------
    array
        a selection of ROIs which passed the selection criterion (are above the threshold)
    """
    imp.setC(channel)
    all_rois = rm.getRoisAsArray()
    selected_rois = []
    for i, roi in enumerate(all_rois):
        imp.setRoi(roi)
        stats = imp.getStatistics()
        if stats.mean > min_intensity:
            selected_rois.append(i)

    return selected_rois


def preset_results_column( rt, column, value):
    """pre-set all rows in given column of the IJ-ResultsTable with desired value

    Parameters
    ----------
    rt : ResultsTable
        a reference of the IJ-ResultsTable
    column : string
        the desired column. will be created if it does not yet exist
    value : string or float or integer
        the value to be set
    """
    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

    Parameters
    ----------
    rt : ResultsTable
        a reference of the IJ-ResultsTable
    column : string
        the column in which to add the values
    row : array
        the row numbers in which too add the values.
    value : string or float or integer
        the value to be set
    """
    for i in range( len( row ) ):
        rt.setValue(column, row[i], value)

    rt.show("Results")


def enhance_contrast( imp ):
    """use "Auto" Contrast & Brightness settings in each channel of imp

    Parameters
    ----------
    imp : 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
        IJ.run(imp, "Enhance Contrast", "saturated=0.35")


def renumber_rois(rm):
    """rename all ROIs in the RoiManager according to their number

    Parameters
    ----------
    rm : RoiManager
        a reference of the IJ-RoiManager
    """
    number_of_rois = rm.getCount()
    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

    Parameters
    ----------
    rm : RoiManager
        a reference of the IJ-RoiManager
    rt : ResultsTable
        a reference of the IJ-ResultsTable
    """
    fix_ij_options()
    rm.runCommand('reset')
    rt.reset()
    IJ.log("\\Clear")


execution_start_time = time.time()

setup_defined_ij(rm, rt)

print rt.size()

# open image using Bio-Formats
path_to_image = fix_ij_dirs(path_to_image)
raw = open_image_with_BF(path_to_image)

# get image info
raw_image_calibration = raw.getCalibration()
raw_image_title = fix_BF_czi_imagetitle(raw)
print("raw image title: ", str(raw_image_title))

# take care of paths and directories
output_dir = fix_ij_dirs(output_dir) + "/" + str(raw_image_title) + "/1_identify_fibers"
print("output_dir: ", str(output_dir))

if not os.path.exists( str(output_dir) ):
    os.makedirs( str(output_dir) )

# update the log for the user
IJ.log( "Now working on " + str(raw_image_title) )
if raw_image_calibration.scaled() == False:
    IJ.log("Your image is not spatially calibrated! Size measurements are only possible in [px].")
IJ.log( " -- settings used -- ")
IJ.log( "area = " + str(minAr) + "-" + str(maxAr) )
IJ.log( "perimeter = " + str(minPer) + "-" + str(maxPer) )
IJ.log( "circularity = " + str(minCir) + "-" + str(maxCir) )
IJ.log( "roundness = " + str(minRnd) + "-" + str(maxRnd) )
IJ.log( "solidity = " + str(minSol) + "-" + str(maxSol) )
IJ.log( "feret_ar = " + str(minFAR) + "-" + str(maxFAR) )
IJ.log( "min_feret = " + str(minMinFer) + "-" + str(maxMinFer) )
IJ.log( "ROI expansion [microns] = " + str(enlarge) )
IJ.log( "Membrane channel = " + str(membrane_channel) )
IJ.log( "MHC positive fiber channel = " + str(fiber_channel) )
IJ.log( "sub-tiling = " + str(tiling_factor) )
IJ.log( " -- settings used -- ")

# image (pre)processing and segmentation (-> ROIs)# imp, firstC, lastC, firstZ,
# lastZ, firstT, lastT
membrane = Duplicator().run(raw, membrane_channel, membrane_channel, 1, 1, 1, 1)
preprocess_membrane_channel(membrane)
imp_result = run_tm(membrane, 1, cellpose_dir.getPath(), PretrainedModel.CYTO2, 30.0, area_thresh=[minAr, maxAr], circularity_thresh=[minCir, maxCir],
        perimeter_thresh=[minPer, maxPer],
        # feret_thresh=[minMinFer, maxMinFer],
    )
IJ.saveAs(imp_result, "Tiff", output_dir + "/" + raw_image_title + "_all_fibers_binary")

sys.exit()

# modify rois
rm.hide()
raw.hide()
enlarge_all_rois( enlarge, rm, raw_image_calibration.pixelWidth )
renumber_rois(rm)
save_all_rois( rm, output_dir + "/" + raw_image_title + "_all_fiber_rois.zip" )

# check for positive fibers
if fiber_channel > 0:
    if min_fiber_intensity == 0:
        min_fiber_intensity = get_threshold_from_method(raw, fiber_channel, "Mean")[0]
        IJ.log( "automatic intensity threshold detection: True" )

    IJ.log( "fiber intensity threshold: " + str(min_fiber_intensity) )
    change_all_roi_color(rm, "blue")
    positive_fibers = select_positive_fibers( raw, fiber_channel, rm, min_fiber_intensity  )
    change_subset_roi_color(rm, positive_fibers, "magenta")
    save_selected_rois( rm, positive_fibers, output_dir + "/" + raw_image_title + "_mhc_positive_fiber_rois.zip")

# measure size & shape, save
IJ.run("Set Measurements...", "area perimeter shape feret's redirect=None decimal=4")
IJ.run("Clear Results", "")
measure_in_all_rois( raw, membrane_channel, rm )

rt = ResultsTable.getResultsTable("Results")

print rt.size()

if fiber_channel > 0:
    print rt.size()
    preset_results_column( rt, "MHC Positive Fibers (magenta)", "NO" )
    print rt.size()
    add_results( rt, "MHC Positive Fibers (magenta)", positive_fibers, "YES")
    print rt.size()

rt.save(output_dir + "/" + raw_image_title + "_all_fibers_results.csv")
print "saved the all_fibers_results.csv"
# dress up the original image, save a overlay-png, present original to the user
rm.show()
raw.show()
show_all_rois_on_image( rm, raw )
raw.setDisplayMode(IJ.COMPOSITE)
enhance_contrast( raw )
IJ.run("From ROI Manager", "") # ROIs -> overlays so they show up in the saved png
qc_duplicate = raw.duplicate()
IJ.saveAs(qc_duplicate, "PNG", output_dir + "/" + raw_image_title + "_all_fibers")
qc_duplicate.close()
wm.toFront( raw.getWindow() )
IJ.run("Remove Overlay", "")
raw.setDisplayMode(IJ.GRAYSCALE)
show_all_rois_on_image( rm, raw )
total_execution_time_min = (time.time() - execution_start_time) / 60.0
IJ.log("total time in minutes: " + str(total_execution_time_min))
IJ.log( "~~ all done ~~" )
IJ.selectWindow("Log")
IJ.saveAs("Text", str(output_dir + "/" + raw_image_title + "_all_fibers_Log"))
if close_raw == True:
    raw.close()