def inputScale(self): gd=GenericDialog("Scale ROI") gd.addStringField("X Scale:",str(self.xScale)) gd.addStringField("Y Scale:",str(self.yScale)) gd.addStringField("Scale X to pixel:",str(self.impXpixel)) gd.addStringField("Scale Y to pixel:",str(self.impYpixel)) fields=gd.getStringFields() self.XscaleField,self.YscaleField=fields[0],fields[1] self.toXfield,self.toYfield=fields[2],fields[3] self.XscaleField.addTextListener(self) self.YscaleField.addTextListener(self) self.toXfield.addTextListener(self) self.toYfield.addTextListener(self) gd.showDialog() if gd.wasOKed(): return(self.xScale,self.yScale) else: return(1.0,1.0)
class Colortags: ''' This class handles persistence of the name of different color channels. It instantiates a GUI window to capture and show the color names in use. Other classes such as ColorMerger needs this to determine the color of the channel being processed. ''' def __init__(self): self.window = None self.tags = {} self.prefkeys = ["{0}.{1}".format(SUBKEY, name) for name in COLORS] self.userprefs = Prefs() self.load() while not self.tags: self.edit("Please set at least one colortag.\n\n") def load(self): ''' Tries to load IBPlib colortags from IJ prefs. ''' for i in range(7): storedtags = self.userprefs.getString(".{0}".format(self.prefkeys[i]), "") if not storedtags: continue trimmedtagslist = [t.strip() for t in storedtags.split(",")] self.tags.update({i:trimmedtagslist}) def edit(self, msg=""): ''' Opens the color tags dialog to update color tags ''' self.window = GenericDialog("ColorMerger - Edit color tags") self.window.addMessage("{0}Separate tags with a comma.\nBlank values will be ignored.".format(msg)) for i in range(7): try: self.window.addStringField(COLORS[i], ", ".join(self.tags[i]), 30) except KeyError: self.window.addStringField(COLORS[i], "", 30) self.window.setOKLabel("Save") self.window.showDialog() if self.window.wasOKed(): self.__savetags() self.load() def __validate(self): fields = self.window.getStringFields() newvalues = {} for i in range(len(fields)): txt = fields[i].getText() newvalues.update({i: txt.strip()}) return newvalues def __savetags(self): newvalues = self.__validate() for i, tags in newvalues.items(): key = self.prefkeys[i] self.userprefs.set(key, tags) self.userprefs.savePreferences()
def analysis_parameters_gui(rerun_analysis=False, params=None): """GUI for setting analysis parameters at the start of a run. TODO: more effectively separate model and view""" if params is None: params = Parameters(load_last_params = True); dialog = GenericDialog("Analysis parameters"); controls = []; if rerun_analysis: params.setUseSingleChannel(False); params.togglePerformUserQC(False); params.setDoInnerOuterComparison(False); controls.append(MyControlDefinition(u'Curvature length parameter (\u00b5m): ', MyControlDefinition.Numeric, round(params.curvature_length_um, 2), params.setCurvatureLengthUm)); controls.append(MyControlDefinition(u'Width of region for intensity analysis (\u00b5m): ', MyControlDefinition.Numeric, round(params.intensity_profile_width_um, 2), params.setIntensityProfileWidthUm)) controls.append(MyControlDefinition("Threshold method: ", MyControlDefinition.Choice, params.threshold_method, params.setThresholdMethod, choices=params.listThresholdMethods(), enabled=(not rerun_analysis))); controls.append(MyControlDefinition("Curvature overlay LUT: ", MyControlDefinition.Choice, params.curvature_overlay_lut_string, params.setCurvatureOverlayLUT, choices=IJ.getLuts())); controls.append(MyControlDefinition("Curvature kymograph LUT: ", MyControlDefinition.Choice, params.curvature_kymograph_lut_string, params.setCurvatureKymographLUT, choices=IJ.getLuts())); controls.append(MyControlDefinition("Labelled species kymograph LUT: ", MyControlDefinition.Choice, params.actin_kymograph_lut_string, params.setActinKymographLUT, choices=IJ.getLuts())); controls.append(MyControlDefinition("Labelled species for intensity analysis: ", MyControlDefinition.String, params.labeled_species, params.setLabeledSpecies)); controls.append(MyControlDefinition("Use intensity channel for segmentation too?", MyControlDefinition.Checkbox, params.use_single_channel, params.setUseSingleChannel, enabled=(not rerun_analysis))); controls.append(MyControlDefinition("Metadata source: ", MyControlDefinition.RadioButtonGroup, params.metadata_source, params.setMetadataSource, choices=["Image metadata", "Acquisition metadata"])); controls.append(MyControlDefinition("Constrain anchors close to manual selections?", MyControlDefinition.Checkbox, params.constrain_anchors, params.toggleConstrainAnchors, enabled=(not rerun_analysis))); controls.append(MyControlDefinition("Filter out negative curvatures", MyControlDefinition.Checkbox, params.filter_negative_curvatures, params.setFilterNegativeCurvatures)); controls.append(MyControlDefinition("Account for photobleaching?", MyControlDefinition.Checkbox, params.photobleaching_correction, params.togglePhotobleachingCorrection)); controls.append(MyControlDefinition("Perform quality control of membrane edges?", MyControlDefinition.Checkbox, params.perform_user_qc, params.togglePerformUserQC, enabled=(not rerun_analysis))); controls.append(MyControlDefinition("Perform quality control of background regions?", MyControlDefinition.Checkbox, params.qc_background_rois, params.toggleBackgroundQc)); controls.append(MyControlDefinition("Perform spatial cropping?", MyControlDefinition.Checkbox, params.perform_spatial_crop, params.toggleSpatialCrop, enabled=(not rerun_analysis))); controls.append(MyControlDefinition("Perform time cropping?", MyControlDefinition.Checkbox, params.perform_time_crop, params.toggleTimeCrop, enabled=(not rerun_analysis))); controls.append(MyControlDefinition("Close images on completion?", MyControlDefinition.Checkbox, params.close_on_completion, params.toggleCloseOnCompletion)); controls.append(MyControlDefinition("Compare inner and outer curvature regions?", MyControlDefinition.Checkbox, params.inner_outer_comparison, params.setDoInnerOuterComparison, enabled=(not rerun_analysis))); for control in controls: control.addControl(dialog); dialog.showDialog(); if dialog.wasCanceled(): raise KeyboardInterrupt("Run canceled"); numeric_controls = [c for c in controls if c.control_type==MyControlDefinition.Numeric]; for nc, nf in zip(numeric_controls, dialog.getNumericFields()): nc.setter(float(nf.getText())); string_controls = [c for c in controls if c.control_type==MyControlDefinition.String]; for sc, sf in zip(string_controls, dialog.getStringFields()): sc.setter(sf.getText()); choice_controls = [c for c in controls if c.control_type==MyControlDefinition.Choice]; for cc, cf in zip(choice_controls, dialog.getChoices()): cc.setter(cf.getSelectedItem()); checkbox_controls = [c for c in controls if c.control_type==MyControlDefinition.Checkbox]; for cbc, cbf in zip(checkbox_controls, dialog.getCheckboxes()): cbc.setter(cbf.getState()); radiobuttongroup_controls = [c for c in controls if c.control_type==MyControlDefinition.RadioButtonGroup]; for rbc in radiobuttongroup_controls: rbc.setter(rbc.checkboxes[[cb.getState() for cb in rbc.checkboxes].index(True)].getLabel()); params.persistParameters(); return params;
def run(): ### Default arguments two_sarcomere_size = 25 # determined by filter used. rotation_angle = 0.0 ### Get the image we'd like to work with. # Don't need to ask where to save the intermediate image since it'll just be saved in the matchedmyo folder anyway # may change this though. In case they want to keep that image around. this_img = WindowManager.getCurrentImage() if this_img == None: ud = WaitForUserDialog( "Please select the image you would like to analyze.") ud.show() this_img = WindowManager.getCurrentImage() img_name = this_img.getTitle() matchedmyo_path = "/home/AD/dfco222/scratchMarx/matchedmyo/" # this would be grabbed from the prompt gd = GenericDialog("Preprocessing Options") gd.addCheckbox("Automatic Resizing/Rotation", True) gd.addCheckbox("CLAHE", True) gd.addCheckbox("Normalization to Transverse Tubules", True) gd.showDialog() if gd.wasCanceled(): return auto_resize_rotate = gd.getNextBoolean() clahe = gd.getNextBoolean() normalize = gd.getNextBoolean() if auto_resize_rotate: # Clear selection so it takes FFT of full image rotation_angle = auto_resize_angle_measure(this_img, two_sarcomere_size) if clahe: clahe_args = "blocksize={} histogram=256 maximum=3 mask=*None* fast_(less_accurate)".format( two_sarcomere_size) IJ.run(this_img, "Enhance Local Contrast (CLAHE)", clahe_args) if normalize: # Ask the user to select a subsection of the image that looks healthy-ish. ud = WaitForUserDialog( "Please select a subsection exhibiting a measure of healthy TT structure using the Rectangle tool.\n" + " Only a single cell or several are needed.\n\n" + " Press 'OK' when finished.") ud.show() IJ.setTool("rectangle") # Duplicate the selected subsection. selection = this_img.crop() IJ.run(selection, "Duplicate...", "title=subsection.tif") # Grab the subsection image and rotate it. selection = WindowManager.getImage("subsection.tif") IJ.run( selection, "Rotate...", "angle={} grid=1 interpolation=Bicubic enlarge".format( rotation_angle)) # Ask the user to select a bounding box that contains only tubules # NOTE: Need to get rid of initial selection since it's the entire image and it's annoying to click out of IJ.setTool("rectangle") IJ.run(selection, "Select None", "") ud = WaitForUserDialog( "Select a subsection of the image that contains only tubules and no membrane." ) ud.show() # Grab the subsection ImagePlus selection = WindowManager.getCurrentImage() this_window = WindowManager.getActiveWindow() selection_small = selection.crop() IJ.run(selection, "Close", "") # NOTE: May not actually display this depending on how the macros work IJ.run(selection_small, "Duplicate...", "title=subsection_small.tif") # Smooth the selection using the single TT filter. # NOTE: It won't read in so we're just going to hard code it in since it's simple tt_filt_row = "0 0 0 1 1 1 1 1 1 0 0 0 0\n" tt_filt = "" for i in range(21): tt_filt += tt_filt_row IJ.run("Convolve...", "text1=[" + tt_filt + "] normalize") # Segment out the TTs from the 'gaps' using Gaussian Adaptive Thresholding. selection_small = WindowManager.getImage("subsection_small.tif") IJ.run(selection_small, "Duplicate...", "title=thresholded.tif") threshed = WindowManager.getImage("thresholded.tif") IJ.run(threshed, "Auto Local Threshold", "method=Bernsen radius=7 parameter_1=1 parameter_2=0 white") # Select the TTs from the thresholded image. IJ.run(threshed, "Create Selection", "") tt_selection = WindowManager.getImage("subsection_small.tif") IJ.selectWindow("thresholded.tif") IJ.selectWindow("subsection_small.tif") IJ.run(tt_selection, "Restore Selection", "") # Get TT intensity statistics. stat_options = IS.MEAN | IS.MIN_MAX | IS.STD_DEV stats = IS.getStatistics(tt_selection.getProcessor(), stat_options, selection_small.getCalibration()) # Calculate pixel ceiling intensity value based on heuristic. # TODO: Add a catch for data type overflow. pixel_ceiling = stats.mean + 3 * stats.stdDev print "px ceil:", pixel_ceiling # Invert selection to get inter-sarcomeric gap intensity statistics. IJ.run(tt_selection, "Make Inverse", "") stat_options = IS.MEAN | IS.MIN_MAX | IS.STD_DEV stats = IS.getStatistics(tt_selection.getProcessor(), stat_options, selection_small.getCalibration()) # Calculate pixel floor intensity value based on heuristic. pixel_floor = stats.mean - stats.stdDev # TODO: Add a catch for data type underflow. print "px floor:", pixel_floor # Threshold original image based on these values. IJ.selectWindow(this_img.getTitle()) IJ.run(this_img, "Select All", "") IJ.setMinAndMax(pixel_floor, pixel_ceiling) IJ.run(this_img, "Apply LUT", "") ## Ask if it is acceptable. gd = GenericDialog("Acceptable?") gd.addMessage( "If the preprocessed image is acceptable for analysis, hit 'OK' to being analysis.\n" + " If the image is unacceptable or an error occurred, hit 'Cancel'") gd.showDialog() if gd.wasCanceled(): return ## Save the preprocessed image. imp = IJ.getImage() fs = FileSaver(imp) img_save_dir = matchedmyo_path + "myoimages/" # actually get from user at some point img_file_path = img_save_dir + img_name[:-4] + "_preprocessed.tif" if os.path.exists(img_save_dir) and os.path.isdir(img_save_dir): print "Saving image as:", img_file_path if os.path.exists(img_file_path): # use dialog box to ask if they want to overwrite gd = GenericDialog("Overwrite?") gd.addMessage( "A file exists with the specified path, \"{}\". Would you like to overwrite it?" .format(img_file_path)) gd.enableYesNoCancel() gd.showDialog() if gd.wasCanceled(): return elif fs.saveAsTiff(img_file_path): print "Preprocessed image saved successfully at:", '"' + img_file_path + '"' else: print "Folder does not exist or is not a folder!" ### Create the YAML file containing the parameters for classification ## Ask user for YAML input gd = GenericDialog("YAML Input") gd.addStringField("imageName", img_file_path, 50) #gd.addStringField("maskName", "None") gd.addStringField("outputParams_fileRoot", img_file_path[:-4], 50) gd.addStringField("outputParams_fileType", "tif") gd.addNumericField("outputParams_dpi", 300, 0) gd.addCheckbox("outputParams_saveHitsArray", False) gd.addStringField("outputParams_csvFile", matchedmyo_path + "results/") gd.addCheckbox("TT Filtering", True) gd.addToSameRow() gd.addCheckbox("LT Filtering", True) gd.addToSameRow() gd.addCheckbox("TA Filtering", True) gd.addNumericField("scopeResolutions_x", 5.0, 3) gd.addToSameRow() gd.addNumericField("scopeResolutions_y", 5.0, 3) gd.addMessage("Enter in filter rotation angles separated by commas.") gd.addStringField("", "-25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25", 50) gd.addCheckbox("returnAngles", False) gd.addCheckbox("returnPastedFilter", True) gd.showDialog() if gd.wasCanceled(): return strings = [st.text for st in gd.getStringFields()] #if strings[1] == "None" or "": # strings[1] = None nums = [float(num.text) for num in gd.getNumericFields()] nums[0] = int(nums[0]) # Have to make sure the dpi variable is an integer checks = [str(bool(boo.state)) for boo in gd.getCheckboxes()] iter_argument = ','.join( [str(float(it) - rotation_angle) for it in strings[4].split(',')]) string_block = """imageName: {0[0]} outputParams: fileRoot: {0[1]} fileType: {0[2]} dpi: {1[0]} saveHitsArray: {2[0]} csvFile: {0[3]} preprocess: False filterTypes: TT: {2[1]} LT: {2[2]} TA: {2[3]} scopeResolutions: x: {1[1]} y: {1[2]} iters: [{3}] returnAngles: {2[4]} returnPastedFilter: {2[5]}""".format(strings, nums, checks, iter_argument) im_title = this_img.getTitle() with cd(matchedmyo_path): yaml_file_path = "./YAML_files/" + im_title[:-4] + ".yml" with open("./YAML_files/" + im_title[:-4] + ".yml", "w") as ym: ym.write(string_block) print "Wrote YAML file to:", matchedmyo_path + yaml_file_path[2:] ### Run the matchedmyo code on the preprocessed image with cd(matchedmyo_path): #os.chdir(matchedmyo_path) #subprocess.call(["python3", matchedmyo_path+"matchedmyo.py", "fullValidation"]) subprocess.call( ["python3", "matchedmyo.py", "run", "--yamlFile", yaml_file_path])
from java.awt import Color from java.awt.event import TextListener from ij import IJ from ij import Menus from ij.gui import GenericDialog #commands = [c for c in ij.Menus.getCommands().keySet()] # Above, equivalent list as below: commands = Menus.getCommands().keySet().toArray() gd = GenericDialog('Command Launcher') gd.addStringField('Command: ', ''); prompt = gd.getStringFields().get(0) prompt.setForeground(Color.red) class TypeListener(TextListener): def textValueChanged(self, tvc): if prompt.getText() in commands: prompt.setForeground(Color.black) return prompt.setForeground(Color.red) # or loop: #for c in commands: # if c == text: # prompt.setForeground(Color.black) # return # #prompt.setForeground(Color.red) prompt.addTextListener(TypeListener()) gd.showDialog() if not gd.wasCanceled(): IJ.doCommand(gd.getNextString())