From 93356cacf14db8e5a54bef6f5345106c3741275b Mon Sep 17 00:00:00 2001 From: volker-baecker Date: Mon, 1 Apr 2024 12:28:21 +0200 Subject: [PATCH] first complete version --- .../batch_measure_intensity_without_spots.py | 27 ------ .../jump_to_label.py | 2 +- .../measure_intensity_without_spots.ijm | 26 +++++- .../measure_without_spots.py | 23 ++++- .../quantification.py | 4 +- .../remove_background.py | 84 ++++++++++++++++++- .../smooth_outer_gradient.py | 51 ----------- 7 files changed, 126 insertions(+), 91 deletions(-) delete mode 100644 volker/toolsets/measure_intensity_without_spots/batch_measure_intensity_without_spots.py delete mode 100644 volker/toolsets/measure_intensity_without_spots/smooth_outer_gradient.py diff --git a/volker/toolsets/measure_intensity_without_spots/batch_measure_intensity_without_spots.py b/volker/toolsets/measure_intensity_without_spots/batch_measure_intensity_without_spots.py deleted file mode 100644 index b44c87d..0000000 --- a/volker/toolsets/measure_intensity_without_spots/batch_measure_intensity_without_spots.py +++ /dev/null @@ -1,27 +0,0 @@ -from ij.io import OpenDialog -from fr.cnrs.mri.cialib.process import ImageIterator -from fr.cnrs.mri.cialib.quantification import StainingAnalyzer - - -def main(): - openDialog = OpenDialog("Select a file or folder") - - inPath = openDialog.getPath() - inDir = openDialog.getDirectory() - inFile = openDialog.getFileName() - - iterator = ImageIterator.getInstance(inPath) - - while(iterator.hasNext()): - image = iterator.next() - title = image.getTitle() - analyzer = StainingAnalyzer(image, 1, 2) - analyzer.setMinAreaNucleus(50) - analyzer.measure() - analyzer.createOverlayOfResults() - analyzer.results.show("measurements of " + title) - - -main() - - diff --git a/volker/toolsets/measure_intensity_without_spots/jump_to_label.py b/volker/toolsets/measure_intensity_without_spots/jump_to_label.py index 7d92cba..a911a65 100644 --- a/volker/toolsets/measure_intensity_without_spots/jump_to_label.py +++ b/volker/toolsets/measure_intensity_without_spots/jump_to_label.py @@ -79,7 +79,7 @@ def loadOptions(): if "=" in option: value = parts[1] if key=="label": - Label = int(value) + LABEL = int(value) if key=="zoom": NR_OF_ZOOM_OUTS = int(value) diff --git a/volker/toolsets/measure_intensity_without_spots/measure_intensity_without_spots.ijm b/volker/toolsets/measure_intensity_without_spots/measure_intensity_without_spots.ijm index d1e5696..3464767 100644 --- a/volker/toolsets/measure_intensity_without_spots/measure_intensity_without_spots.ijm +++ b/volker/toolsets/measure_intensity_without_spots/measure_intensity_without_spots.ijm @@ -70,6 +70,11 @@ macro "Remove Background [f2]" { } +macro "Remove Background (f2) Action Tool Options" { + showRemoveBackgroundOptions(); +} + + macro "Measure Image (f3) Action Tool - C000T4b12m" { measureImage(); } @@ -170,6 +175,13 @@ function convertWells() { } +function showRemoveBackgroundOptions() { + call("ij.Prefs.set", "mri.options.only", "true"); + run("remove background"); + call("ij.Prefs.set", "mri.options.only", "false"); +} + + function showMeasureIntensityOptions() { call("ij.Prefs.set", "mri.options.only", "true"); run("measure without spots"); @@ -212,14 +224,22 @@ function loadOptions(path) { function jumpToSelectedLabel() { call("ij.Prefs.set", "mri.options.only", "false"); row = Table.getSelectionStart; - col = Table.getColumn("Label"); - label =col[row]; + label = LABEL + if (row > -1) { + col = Table.getColumn("Label"); + label =col[row]; + } zoom = NR_OF_ZOOM_OUT; pluginsPath = getDirectory("plugins"); path = pluginsPath + "Measure-Intensity-Without-Spots/jtl-options.txt"; if (File.exists(path)) { - optionsString = File.openAsString(path); + optionsString = File.openAsString(path); parts = split(optionsString, " "); + if (row == -1) { + parts0 = split(parts[0], "="); + labelTxt = parts0[1]; + label = labelTxt.trim(); + } parts = split(parts[1], "="); zoomTxt = parts[1]; zoom = zoomTxt.trim(); diff --git a/volker/toolsets/measure_intensity_without_spots/measure_without_spots.py b/volker/toolsets/measure_intensity_without_spots/measure_without_spots.py index 45fe850..a492c10 100644 --- a/volker/toolsets/measure_intensity_without_spots/measure_without_spots.py +++ b/volker/toolsets/measure_intensity_without_spots/measure_without_spots.py @@ -12,6 +12,7 @@ NUCLEUS_MIN_AREA = 50 SHOW_LABELS = False SAVE_OPTIONS = True +ADDITIONAL_OPTIONS = [] URL = "https://github.com/MontpellierRessourcesImagerie/imagej_macros_and_scripts/wiki/Measure-Intensity-Without-Spots" @@ -42,13 +43,16 @@ def main(): def showDialog(): - global NUCLEI_CHANNEL, SIGNAL_CHANNEL, NUCLEUS_MIN_AREA, METHODS, METHOD, SAVE_OPTIONS, URL + global NUCLEI_CHANNEL, SIGNAL_CHANNEL, NUCLEUS_MIN_AREA, METHODS, METHOD, ADDITIONAL_OPTIONS, SAVE_OPTIONS, URL cls = NucleiSegmentationMethod methodClasses = list(set(cls.__subclasses__())) + ADDITIONAL_OPTIONS = [] for methodClass in methodClasses: - print(methodClass.name(), methodClass.options()) - + if methodClass.name() == METHOD: + for option in methodClass.options().values(): + ADDITIONAL_OPTIONS.append(option) + print(ADDITIONAL_OPTIONS) if os.path.exists(getOptionsPath()): loadOptions() gd = GenericDialog("Measure Without Spots Options"); @@ -56,6 +60,9 @@ def showDialog(): gd.addNumericField("Signal Channel: ", SIGNAL_CHANNEL) gd.addNumericField("Min. Area Nucleus: ", NUCLEUS_MIN_AREA) gd.addChoice("Method: ", METHODS, METHOD) + for option in ADDITIONAL_OPTIONS: + if option['type'] == int or option['type'] == float: + gd.addNumericField(option['name'] + ': ' , option['value']) gd.addCheckbox("Save Options", SAVE_OPTIONS) gd.addHelp(URL) gd.showDialog() @@ -65,6 +72,9 @@ def showDialog(): SIGNAL_CHANNEL = int(gd.getNextNumber()) NUCLEUS_MIN_AREA = float(gd.getNextNumber()) METHOD = gd.getNextChoice() + for option in ADDITIONAL_OPTIONS: + if option['type'] == int or option['type'] == float: + option['value'] = option['type'](gd.getNextNumber()) SAVE_OPTIONS = gd.getNextBoolean() if SAVE_OPTIONS: saveOptions() @@ -83,11 +93,13 @@ def getOptionsString(): optionsString = optionsString + " signal=" + str(SIGNAL_CHANNEL) optionsString = optionsString + " min.=" + str(NUCLEUS_MIN_AREA) optionsString = optionsString + " method.=" + str(METHOD) + for option in ADDITIONAL_OPTIONS: + optionsString = optionsString + " " + option['name'] + "=" + str(option['value']) return optionsString def loadOptions(): - global NUCLEI_CHANNEL, SIGNAL_CHANNEL, NUCLEUS_MIN_AREA, METHOD + global NUCLEI_CHANNEL, SIGNAL_CHANNEL, NUCLEUS_MIN_AREA, METHOD, ADDITIONAL_OPTIONS optionsPath = getOptionsPath() optionsString = IJ.openAsString(optionsPath) @@ -107,6 +119,9 @@ def loadOptions(): NUCLEUS_MIN_AREA = float(value) if key=="method": METHOD = str(value) + for additionalOption in ADDITIONAL_OPTIONS: + if key==additionalOption['name']: + additionalOption['value'] = additionalOption['type'](value) def saveOptions(): diff --git a/volker/toolsets/measure_intensity_without_spots/quantification.py b/volker/toolsets/measure_intensity_without_spots/quantification.py index 7500663..c1f20e2 100644 --- a/volker/toolsets/measure_intensity_without_spots/quantification.py +++ b/volker/toolsets/measure_intensity_without_spots/quantification.py @@ -258,12 +258,12 @@ class SubtractGaussianAndThresholdSegmentation(NucleiSegmentationMethod): @classmethod def name(cls): - return "subtract Gaussian and threshold" + return "subtract_Gaussian_and_threshold" @classmethod def options(cls): - return { 1 : {'name': 'sigma', 'defaultValue': 40.86, 'type' : int}} + return { 1 : {'name': 'sigma', 'value': 40.86, 'type' : float}} def __init__(self, image): diff --git a/volker/toolsets/measure_intensity_without_spots/remove_background.py b/volker/toolsets/measure_intensity_without_spots/remove_background.py index 4b5caa4..07fe59b 100644 --- a/volker/toolsets/measure_intensity_without_spots/remove_background.py +++ b/volker/toolsets/measure_intensity_without_spots/remove_background.py @@ -1,21 +1,30 @@ +import os from ij import IJ +from ij import Prefs +from ij.gui import GenericDialog from ij import WindowManager from ij.plugin import Duplicator from ij.plugin import RGBStackMerge -SPOTS_CHANNEL = 2 +SIGNAL_CHANNEL = 2 NUCLEI_CHANNEL = 1 LAMBDA_FLAT = 0.50 LAMBDA_DARK = 0.50 SAVE_OPTIONS = True URL = "https://github.com/MontpellierRessourcesImagerie/imagej_macros_and_scripts/wiki/Measure-Intensity-Without-Spots" -def main(): +def main(): + optionsOnly = Prefs.get("mri.options.only", "false") + if not showDialog(): + return + if optionsOnly=="true": + return + return image = IJ.getImage() width, height, nChannels, nSlices, nFrames = image.getDimensions() - spotsChannelImage = Duplicator().run(image, SPOTS_CHANNEL, SPOTS_CHANNEL, 1, nSlices, 1, nFrames) + spotsChannelImage = Duplicator().run(image, SIGNAL_CHANNEL, SIGNAL_CHANNEL, 1, nSlices, 1, nFrames) spotsChannelImage.show() title = spotsChannelImage.getTitle() IJ.run(spotsChannelImage, "BaSiC ", "processing_stack=[" + spotsChannelImage.getTitle() + "] flat-field=None dark-field=None shading_estimation=[Estimate shading profiles] shading_model=[Estimate both flat-field and dark-field] setting_regularisationparametes=Automatic temporal_drift=[Replace with zero] correction_options=[Compute shading and correct images] lambda_flat=" + str(LAMBDA_FLAT) + " lambda_dark=" + str(LAMBDA_DARK)) @@ -32,10 +41,79 @@ def main(): resultImage.setTitle(title) resultImage.show() + +def showDialog(): + global NUCLEI_CHANNEL, SIGNAL_CHANNEL, LAMBDA_FLAT, SAVE_OPTIONS, LAMBDA_DARK, URL + + if os.path.exists(getOptionsPath()): + loadOptions() + gd = GenericDialog("Remove Background Options"); + gd.addNumericField("Nuclei Channel: ", NUCLEI_CHANNEL) + gd.addNumericField("Signal Channel: ", SIGNAL_CHANNEL) + gd.addNumericField("Lambda_Flat: ", LAMBDA_FLAT) + gd.addNumericField("Lambda_Dark: ", LAMBDA_DARK) + gd.addCheckbox("Save Options", SAVE_OPTIONS) + gd.addHelp(URL) + gd.showDialog() + if gd.wasCanceled(): + return False + NUCLEI_CHANNEL = int(gd.getNextNumber()) + SIGNAL_CHANNEL = int(gd.getNextNumber()) + LAMBDA_FLAT = float(gd.getNextNumber()) + LAMBDA_DARK = float(gd.getNextNumber()) + SAVE_OPTIONS = gd.getNextBoolean() + if SAVE_OPTIONS: + saveOptions() + return True + + +def getOptionsPath(): + pluginsPath = IJ.getDirectory("plugins"); + optionsPath = pluginsPath + "Measure-Intensity-Without-Spots/rb-options.txt"; + return optionsPath; + +def getOptionsString(): + optionsString = "" + optionsString = optionsString + "nuclei=" + str(NUCLEI_CHANNEL) + optionsString = optionsString + " signal=" + str(SIGNAL_CHANNEL) + optionsString = optionsString + " lambda_flat=" + str(LAMBDA_FLAT) + optionsString = optionsString + " lambda_dark=" + str(LAMBDA_DARK) + return optionsString + + def closeWindow(title): win = WindowManager.getWindow(title) win.close() + + +def loadOptions(): + global NUCLEI_CHANNEL, SIGNAL_CHANNEL, LAMBDA_FLAT, LAMBDA_DARK + + optionsPath = getOptionsPath() + optionsString = IJ.openAsString(optionsPath) + optionsString = optionsString.replace("\n", "") + options = optionsString.split(" ") + for option in options: + parts = option.split("=") + key = parts[0] + value = "" + if "=" in option: + value = parts[1] + if key=="nuclei": + NUCLEI_CHANNEL = int(value) + if key=="signal": + SIGNAL_CHANNEL = int(value) + if key=="lambda_flat": + LAMBDA_FLAT = float(value) + if key=="lambda_dark": + LAMBDA_DARK = float(value) + + +def saveOptions(): + optionsString = getOptionsString() + optionsPath = getOptionsPath() + IJ.saveString(optionsString, getOptionsPath()) main() \ No newline at end of file diff --git a/volker/toolsets/measure_intensity_without_spots/smooth_outer_gradient.py b/volker/toolsets/measure_intensity_without_spots/smooth_outer_gradient.py deleted file mode 100644 index 66d546d..0000000 --- a/volker/toolsets/measure_intensity_without_spots/smooth_outer_gradient.py +++ /dev/null @@ -1,51 +0,0 @@ -import java -from ij import IJ -from jarray import array - -def main(): - STEP = 5 - - image = IJ.getImage() - width, height, nChannels, nSlices, nFrames = image.getDimensions() - found = True - counter = 1 - while found and counter < 11: - print("processing iteration: ", counter) - found = False - processor = image.getProcessor() - newProcessor = processor.duplicate() - numberOfChanges = 0 - for x in range(0, width): - for y in range(0, height): - value = processor.get(x, y) - if value == 0: - newValue = getMinAboveZeroInNeighborhood(x, y, processor) - if newValue == 65536: - continue - newProcessor.set(x, y, int(max(newValue-STEP, 1))) - found = True - numberOfChanges = numberOfChanges + 1 - print(str(numberOfChanges) + " pixels changed") - image.setProcessor(newProcessor) - counter = counter + 1 - - -def getMinAboveZeroInNeighborhood(x, y, processor): - imp = processor - line1 = array([float(0.0), float(0.0) ,float(0.0)], 'd') - line2 = array([float(0.0), float(0.0) ,float(0.0)], 'd') - line3 = array([float(0.0), float(0.0) ,float(0.0)], 'd') - neighbors = array([line1, line2, line3], java.lang.Class.forName("[D")) - imp.getNeighborhood(x, y, neighbors) - neighbors = list([list(line) for line in neighbors]) - smallest = 65536 - for line in neighbors: - for element in line: - if element == 0.0: - continue - if element < smallest: - smallest = element - return smallest - - -main() \ No newline at end of file