def run(): global pmWin global imgData helpText = "This is Point Marker, " + \ "a program for marking points in images.\n\n" + \ ">> Press OK to Select a file for storing points infomation.\n"+\ ">> TIF-Images within the same directory will be auto-loaded." MessageDialog(IJ.getInstance(),"Point Marker Guide", helpText) fileChooser = OpenDialog("Point Marker: Choose working directory and file") outfilePath = fileChooser.getPath() imgDir = fileChooser.getDirectory() if not imgDir: return imgPaths = [] if imgDir: for root, directories, filenames in os.walk(imgDir): for filename in filenames: if not filename.endswith(".tif"): continue imgPaths.append(os.path.join(root, filename)) pointsTable1 = readPoints(outfilePath) imgData = PointMarkerData(imgPaths, outfilePath, pointsTable1) IJ.setTool("multipoint") PointRoi.setDefaultSize(3) pmWin = PointMarkerWin(imgData) pmWin.win.setLocation(IJ.getInstance().getLocation()) prepareNewImage(imgData)
def getOptions(): global listener, xlist, ylist, zlist, manager gd = GenericDialog("Target Selection") gd.addChoice('type', ['point', 'circle', 'spiral'], 'point') gd.addNumericField(" power (%)", 85, 0) gd.addNumericField(" duration (ms)", 1, 0) gd.addNumericField(" radius(circle/spiral)", 5, 0) gd.addNumericField(" # revolutions (circle/spiral)", 3, 0) gd.addNumericField( " add CAMERA_TRIGGER after every (entries)", 1, 0) gd.addNumericField(" Prewait between entries (ms)", 5000, 0) gd.addNumericField(" Z-start of stack (um)", 0, 0) gd.addNumericField(" Z-step of stack (um)", 5, 0) gd.addMessage('Press ENTER to save\n') gd.addMessage('Press ESC to restart\n') gd.showDialog() profileType = gd.getNextChoice() power = gd.getNextNumber() duration = gd.getNextNumber() r = gd.getNextNumber() Nturns = gd.getNextNumber() camTriggerEvery = gd.getNextNumber() prewait = gd.getNextNumber() zStart = gd.getNextNumber() zStep = gd.getNextNumber() if gd.wasCanceled(): IJ.setTool(Toolbar.RECTANGLE) return else: return r, power, profileType, duration, Nturns, camTriggerEvery, zStart, zStep, prewait
def run(): global pmWin global imgData helpText = "This is Point Marker, " + \ "a program for marking points in images.\n\n" + \ ">> Press OK to Select a file for storing points infomation.\n"+\ ">> TIF-Images within the same directory will be auto-loaded." MessageDialog(IJ.getInstance(), "Point Marker Guide", helpText) fileChooser = OpenDialog("Point Marker: Choose working directory and file") outfilePath = fileChooser.getPath() imgDir = fileChooser.getDirectory() if not imgDir: return imgPaths = [] if imgDir: for root, directories, filenames in os.walk(imgDir): for filename in filenames: if not filename.endswith(".tif"): continue imgPaths.append(os.path.join(root, filename)) pointsTable1 = readPoints(outfilePath) imgData = PointMarkerData(imgPaths, outfilePath, pointsTable1) IJ.setTool("multipoint") PointRoi.setDefaultSize(3) pmWin = PointMarkerWin(imgData) pmWin.win.setLocation(IJ.getInstance().getLocation()) prepareNewImage(imgData)
def twist_and_unwrap(imp): """from the output of angular projection, define an axis along which to unzip the vessel and return this unzipped image""" tile_imp = make_tiled_imp(imp) tile_imp.show() IJ.setTool("freeline") WaitForUserDialog( "Input required...", "Please draw the line down which unwrapping should occur...").show() roi = tile_imp.getRoi() if roi is None: raise ValueError unwrap_poly = roi.getPolygon() unwrap_poly_xs = [x for x in unwrap_poly.xpoints] unwrap_poly_ys = [y for y in unwrap_poly.ypoints] # extend to the top and bottom of the image: unwrap_poly_xs.insert(0, unwrap_poly_xs[0]) unwrap_poly_xs.append(unwrap_poly_xs[-1]) if unwrap_poly_ys[0] < unwrap_poly_ys[-1]: unwrap_poly_ys.insert(0, 1) unwrap_poly_ys.append(imp.getHeight()) else: unwrap_poly_ys.insert(0, imp.getHeight()) unwrap_poly_ys.append(1) unwrap_axis = [(x, y) for (x, y) in zip(unwrap_poly_xs, unwrap_poly_ys)] unwrapped_projection_imp = do_unwrap(tile_imp, unwrap_axis, imp_title=imp.getTitle()) return unwrapped_projection_imp, unwrap_axis
def perform_cropping(imp, info, output_folder, default_path): imp.show() imp.setC(info.get_mosaic_labeled_ch()) IJ.run("Enhance Contrast", "saturated=0.35") zcrop_imp, z_lims = z_crop(imp) info.set_z_crop_frames(z_lims) info.set_mosaic_labeled_ch(imp.getC()) IJ.setTool("rect") zcrop_imp.hide() imp2 = ZProjector.run(zcrop_imp, "max") imp2.show() imp2.setC(info.get_mosaic_labeled_ch()) crop_roi = None while crop_roi is None: WaitForUserDialog("Select XY region to crop...").show() crop_roi = imp2.getRoi() if crop_roi.getType(): info.set_xy_crop_rect( str([(x, y) for x, y in zip(crop_roi.getPolygon().xpoints, crop_roi.getPolygon().ypoints)])) else: info.set_xy_crop_rect(crop_roi.getBounds().toString()) imp2.close() zcrop_imp.show() zcrop_imp.setRoi(crop_roi) IJ.run("Crop", "") if crop_roi.getType(): IJ.run(zcrop_imp, "Make Inverse", "") inv_roi = zcrop_imp.getRoi() IJ.run(zcrop_imp, "Set...", "value=0 stack") IJ.run(zcrop_imp, "Make Inverse", "") # zcrop_imp = z_crop_finetune(zcrop_imp, info); return imp, zcrop_imp, info, info.get_input_file_path()
def crop_to_ROI(imp, params): """prompt user to select ROI for subsequent analysis""" roi = None; if params.perform_spatial_crop: if params.spatial_crop is not None: roi = params.parse_roistr_to_roi(); imp.setRoi(roi); else: IJ.setTool("rect"); MyWaitForUser("Crop", "If desired, select an area ROI to crop to..."); roi = imp.getRoi(); crop_params = None; original_imp = Duplicator().run(imp); if roi is not None: if not roi.isArea(): raise TypeError("selected ROI should be an area"); if roi.getType(): crop_params = str([(x, y) for x, y in zip(roi.getPolygon().xpoints, roi.getPolygon().ypoints)]); IJ.run(imp, "Make Inverse", ""); roi = imp.getRoi(); fill_val = mb.calculate_percentile(imp, roi, 25); IJ.run(imp, "Set...", "value=" + str(round(fill_val)) + " stack"); IJ.run(imp, "Make Inverse", ""); else: crop_params = roi.getBounds().toString(); IJ.run(imp, "Crop", ""); imp.killRoi(); params.setSpatialCrop(crop_params) else: params.setSpatialCrop(None); return original_imp, crop_params;
def show_and_select_colonies(): original_image.show() IJ.run("Point Tool...", "type=Hybrid color=Red size=Small"); if len(x_centroid_list) != 0: points = ij.gui.PointRoi(x_centroid_list, y_centroid_list, len(x_centroid_list)) original_image.setRoi(points, True) IJ.setTool('multipoint') dial = WaitForUserDialog('Please select colonies.')
def perform_manual_qc(imp, rois, important_channel=1): """given cell rois generated by automatic methods, allow user to delete/add/redraw as appropriate""" for ch in range(imp.getNChannels()): imp.setC(ch + 1) sat_frac = 0.99 if (ch + 1) == important_channel else 0.01 IJ.run(imp, "Enhance Contrast", "saturated={}".format(sat_frac)) imp.setC(important_channel) IJ.setTool("freehand") proceed = False roim = RoiManager() roim.runCommand("Show all with labels") for roi in rois: roim.addRoi(roi) auto_rois_only = rois while not proceed: dialog = NonBlockingGenericDialog("Perform manual segmentation") dialog.setOKLabel("Proceed to next image...") dialog.addMessage("Perform manual correction of segmentation: ") dialog.addMessage( "Draw around cells and add to the region of interest manager (Ctrl+T). " ) dialog.addMessage("Delete and redraw cells as appropriate. ") dialog.addMessage( "Then press \"proceed to next image\" when all cells have been added. " ) dialog.showDialog() if dialog.wasCanceled(): print("Manual segmentation canceled") return auto_rois_only elif dialog.wasOKed(): if roim.getCount() == 0: rois = [] confirm_dialog = GenericDialog("Continue?") confirm_dialog.addMessage( "No rois selected in this FOV. Are you sure you want to proceed?" ) confirm_dialog.setOKLabel("Yes, proceed") confirm_dialog.setCancelLabel("No, not yet") confirm_dialog.showDialog() if confirm_dialog.wasOKed(): proceed = True else: rois = roim.getRoisAsArray() proceed = True roim.reset() roim.close() for ch in range(imp.getNChannels()): imp.setC(ch + 1) IJ.run(imp, "Enhance Contrast", "saturated={}".format(0.35)) imp.setC(important_channel) return rois
def getColonyCenter(brightfield): '''Returns the center of the colony based on the brightfield image. This will be automated in the future when we have better images. ''' brightfield.show() IJ.setTool("point") WaitForUserDialog("Please select the center of the homeland. Click OK when done.").show() brightfield.hide() point = brightfield.getRoi() boundingRectangle = point.getBounds() xCoord = boundingRectangle.getX() yCoord = boundingRectangle.getY() return (xCoord, yCoord)
def getHomelandDiameter(fluorescence): '''Determine the homeland diameter based on the fluorescence data.''' fluorescence.show() IJ.setTool("line") WaitForUserDialog("Please select the diameter of the homeland. Click OK when done.").show() fluorescence.hide() diameter = fluorescence.getRoi().getLength() # Make it uncalibrated for the next step pixelWidth = fluorescence.getCalibration().pixelWidth uncalibratedDiameter = diameter/pixelWidth return uncalibratedDiameter
def z_crop(imp): """trim a z stack based on interactively-defined start and end points""" IJ.setTool("zoom") IJ.run("Brightness/Contrast...") imp.setZ(1) WaitForUserDialog("Choose first z plane and click OK...").show() start_z = imp.getZ() WaitForUserDialog("Now choose last z plane and click OK...").show() end_z = imp.getZ() frames = imp.getNFrames() channels = imp.getNChannels() imp.killRoi() dupimp = Duplicator().run(imp, 1, channels, start_z, end_z, 1, frames) imp.hide() dupimp.show() return dupimp, (start_z, end_z)
def run(self): IJ.resetEscape() IJ.setTool("point") listener = ML() self.imp.show() canvas = self.imp.getWindow().getCanvas() canvas.addMouseListener(listener) # wait for mouse click while (not listener.mouseWasPressed) and (not IJ.escapePressed()): Thread.sleep(200) # todo: how to make this better? canvas.removeMouseListener(listener) if IJ.escapePressed(): IJ.log("command has been aborted") else: print listener.x, listener.y self.pos = [listener.x, listener.y]
def prompt_for_points(imp, title, message, n_points): """prompt the user to provide a number of points on the image""" imp.killRoi(); if (n_points == 1): IJ.setTool("point"); else: IJ.setTool("multipoint"); selected_points = 0; while (selected_points != n_points): MyWaitForUser(title, message); roi = imp.getRoi(); if roi is not None: selected_points = len(roi.getContainedPoints()); if ((roi is None) or (selected_points != n_points)): MyWaitForUser("Error!", "Wrong number of points selected! Please try again..."); imp.killRoi(); return [(p.x, p.y) for p in roi.getContainedPoints()];
def getOptions(): global listener, xlist, ylist, zlist, manager gd = GenericDialog("Target Selection") gd.addMessage('Mandatory parameters\n') gd.addChoice('type', ['point', 'circle', 'spiral'], 'point') gd.addNumericField(" power (%)", 85, 0) gd.addNumericField(" duration (millisec)", 3, 0) gd.addNumericField(" interval between entries (ms)", 5000, 0) gd.addNumericField(" Z-start of stack (microns)", 0, 0) gd.addNumericField(" Z-step of stack (microns)", 5, 0) gd.addMessage('Optional\n') gd.addNumericField(" radius of a circle/spiral", 5, 0) gd.addNumericField(" num. of turns per circle/spiral", 3, 0) gd.addNumericField(" take image after every .. entries", 1, 0) gd.addNumericField(" add offset to X coordinates", 0, 0) gd.addNumericField(" add offset to Y coordinates", 0, 0) gd.addNumericField( " imaging stack # for excitation onset (0,1,..)", 0, 0) gd.addMessage('Press ENTER to save the coordinate file\n') gd.addMessage('Press ESC to restart\n') gd.showDialog() profileType = gd.getNextChoice() power = gd.getNextNumber() duration = gd.getNextNumber() prewait = gd.getNextNumber() zStart = gd.getNextNumber() zStep = gd.getNextNumber() r = gd.getNextNumber() Nturns = gd.getNextNumber() camTriggerEvery = gd.getNextNumber() xOffset = gd.getNextNumber() yOffset = gd.getNextNumber() tmIndex = gd.getNextNumber() if gd.wasCanceled(): IJ.setTool(Toolbar.RECTANGLE) return else: return r, power, profileType, duration, Nturns, camTriggerEvery, zStart, zStep, prewait, xOffset, yOffset, tmIndex
def manual_analysis(imp, file_name, output_folder): """perform analysis based on manually drawn cells""" cal = imp.getCalibration() channel_imps = ChannelSplitter.split(imp) gfp_imp = channel_imps[0] IJ.setTool("freehand") proceed = False roim = RoiManager() roim.runCommand("Show all with labels") dialog = NonBlockingGenericDialog("Perform manual segmentation") dialog.setOKLabel("Proceed to next image...") dialog.addMessage("Perform manual segmentation: ") dialog.addMessage( "Draw around cells and add to the region of interest manager (Ctrl+T)") dialog.addMessage( "You can see what you've added so far if you check \"show all\" on the ROI manager" ) dialog.addMessage( "Then press \"proceed to next image\" when all cells have been added") dialog.showDialog() if dialog.wasCanceled(): raise KeyboardInterrupt("Run canceled") elif dialog.wasOKed(): rois = roim.getRoisAsArray() roim.reset() roim.close() out_stats = generate_cell_shape_results(rois, gfp_imp, cal, file_name) print("Number of cells identified = {}".format(len(out_stats))) # save output save_qc_image( imp, rois, "{}_plus_overlay.tiff".format( os.path.join(output_folder, os.path.splitext(file_name)[0]))) save_cell_rois(rois, output_folder, os.path.splitext(file_name)[0]) imp.changes = False imp.close() save_output_csv(out_stats, output_folder) return out_stats return None
def qc_background_regions(intensity_imp, bg_rois): """allow the user to view and correct automatically-determined background regions""" imp = Duplicator().run(intensity_imp); imp.setTitle("Background region QC"); imp.show(); imp.setPosition(1); autoset_zoom(imp); imp.setRoi(bg_rois[0]); IJ.setTool("freehand"); notOK = True; while notOK: listener = UpdateRoiImageListener(bg_rois, is_area=True); imp.addImageListener(listener); dialog = NonBlockingGenericDialog("Background region quality control"); dialog.enableYesNoCancel("Continue", "Use this region for all t"); dialog.setCancelLabel("Cancel analysis"); dialog.addMessage("Please redraw background regions as necessary...") dialog.showDialog(); if dialog.wasCanceled(): raise KeyboardInterrupt("Run canceled"); elif not(dialog.wasOKed()): this_roi = imp.getRoi(); bg_rois = [this_roi for _ in listener.getRoiList()]; imp.removeImageListener(listener); else: last_roi = imp.getRoi(); qcd_bg_rois = listener.getRoiList(); if imp.getNFrames() > imp.getNSlices(): qcd_bg_rois[imp.getT() - 1] = last_roi; else: qcd_bg_rois[imp.getZ() - 1] = last_roi; notOK = False; imp.removeImageListener(listener); imp.changes = False; imp.close(); return qcd_bg_rois;
def z_crop_finetune(imp, info): """define z cropping to allow freehand definition of lower bounds""" imp.setC(info.get_mosaic_labeled_ch()) rot_imp = rot3d(imp, axis='x') imp.close() rot_imp.show() IJ.setTool("freehand") WaitForUserDialog("Select XZ region to crop...").show() crop_roi = rot_imp.getRoi() if crop_roi is None: return if crop_roi.getType(): info.set_zx_crop_rect( str([(x, y) for x, y in zip(crop_roi.getPolygon().xpoints, crop_roi.getPolygon().ypoints)])) else: info.set_zx_crop_rect(crop_roi.getBounds().toString()) if crop_roi.getType(): IJ.run(zcrop_imp, "Make Inverse", "") inv_roi = zcrop_imp.getRoi() IJ.run(zcrop_imp, "Set...", "value=0 stack") IJ.run(zcrop_imp, "Make Inverse", "") imp = rot3d(rot_imp, axis='x') return imp
def process(subFolder, outputDirectory, filename): #IJ.close() imp = IJ.openImage(inputDirectory + subFolder + '/' + rreplace(filename, "_ch00.tif", ".tif")) imp.show() # Finds the pixel length in microns from the xml metadata file file_list = [file for file in os.listdir(inputDirectory + subFolder) if file.endswith('.xml')] if len(file_list) > 0: xml = os.path.join(inputDirectory + subFolder, file_list[0]) element_tree = ET.parse(xml) root = element_tree.getroot() for dimensions in root.iter('DimensionDescription'): num_pixels = int(dimensions.attrib['NumberOfElements']) if dimensions.attrib['Unit'] == "m": length = float(dimensions.attrib['Length']) * 1000000 else: length = float(dimensions.attrib['Length']) pixel_length = length / num_pixels else: pixel_length = 0.877017 log.write("Pixel Length:" + str(pixel_length) + "\n") IJ.run(imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=" + str(pixel_length) + " pixel_height=" + str(pixel_length) + " voxel_depth=25400.0508001") ic = ImageConverter(imp); ic.convertToGray8(); #IJ.setThreshold(imp, 2, 255) # If wand tool is enabled, then this will prompt that to be used if enableWand: # Call threshold function to adjust threshold and select Organoid ROI IJ.run("Threshold...") WaitForUserDialog("Adjust Threshold to create mask").show() IJ.setTool("Wand") WaitForUserDialog("Click on Organoid Area for it to be selected. Best selection will be at the edge of the organoid to get entire organoid shape.").show() IJ.run("Clear Outside") if not enableWand: IJ.setAutoThreshold(imp, "Mean dark no-reset") IJ.run(imp, "Convert to Mask", "") IJ.run(imp, "Analyze Particles...", "size=100000-Infinity add select") rm = RoiManager.getInstance() imp = getCurrentImage() rm.select(imp, 0) IJ.setBackgroundColor(0, 0, 0) IJ.run(imp, "Clear Outside", "") IJ.run(imp, "Convert to Mask", "") IJ.run(imp, "Remove Outliers...", "radius=5" + " threshold=50" + " which=Dark") IJ.run(imp, "Remove Outliers...", "radius=5" + " threshold=50" + " which=Bright") # #Save the mask and open it IJ.saveAs("tiff", inputDirectory + '/mask') mask = IJ.openImage(inputDirectory + '/mask.tif') if enableWand: #Select ROI again to add it to the the ROI manager so that intensities and area is saved #IJ.run("Threshold...") IJ.setTool("Wand") WaitForUserDialog("Select Organoid area again for it to register within the ROI manager").show() rm = RoiManager() boundroi = ThresholdToSelection.run(mask) rm.addRoi(boundroi) if not displayImages: imp.changes = False imp.close() images = [None] * 5 intensities = [None] * 5 blobsarea = [None] * 5 blobsnuclei = [None] * 5 bigAreas = [None] * 5 imp.close() #Loop to open all the channel images for chan in channels: v, x = chan images[x] = IJ.openImage( inputDirectory + subFolder + '/' + rreplace(filename, "_ch00.tif", "_ch0" + str(x) + ".tif")) # Apply Mask on all the images and save them into an array apply_mask = ImageCalculator() images[x] = apply_mask.run("Multiply create 32 bit", mask, images[x]) ic = ImageConverter(images[x]) ic.convertToGray8() imp = images[x] # Calculate the intensities for each channel as well as the organoid area for roi in rm.getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.MEAN | Measurements.AREA) intensities[x] = stats.mean bigAreas[x] = stats.area rm.close() # Opens the ch00 image and sets default properties apply_mask = ImageCalculator() imp = IJ.openImage(inputDirectory + subFolder + '/' + filename) imp = apply_mask.run("Multiply create 32 bit", mask, imp) IJ.run(imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=" + str(pixel_length) + " pixel_height=" + str(pixel_length) + " voxel_depth=25400.0508001") # Sets the threshold and watersheds. for more details on image processing, see https://imagej.nih.gov/ij/developer/api/ij/process/ImageProcessor.html ic = ImageConverter(imp); ic.convertToGray8(); IJ.run(imp, "Remove Outliers...", "radius=2" + " threshold=50" + " which=Dark") IJ.run(imp, "Gaussian Blur...", "sigma=" + str(blur)) IJ.setThreshold(imp, lowerBounds[0], 255) if displayImages: imp.show() IJ.run(imp, "Convert to Mask", "") IJ.run(imp, "Watershed", "") if not displayImages: imp.changes = False imp.close() # Counts and measures the area of particles and adds them to a table called areas. Also adds them to the ROI manager table = ResultsTable() roim = RoiManager(True) ParticleAnalyzer.setRoiManager(roim); pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA, table, 15, 9999999999999999, 0.2, 1.0) pa.setHideOutputImage(True) # imp = impM # imp.getProcessor().invert() pa.analyze(imp) areas = table.getColumn(0) # This loop goes through the remaining channels for the other markers, by replacing the ch00 at the end with its corresponding channel # It will save all the area fractions into a 2d array called areaFractionsArray areaFractionsArray = [None] * 5 for chan in channels: v, x = chan # Opens each image and thresholds imp = images[x] IJ.run(imp, "Properties...", "channels=1 slices=1 frames=1 unit=um pixel_width=" + str(pixel_length) + " pixel_height=" + str(pixel_length) + " voxel_depth=25400.0508001") ic = ImageConverter(imp); ic.convertToGray8(); IJ.setThreshold(imp, lowerBounds[x], 255) if displayImages: imp.show() WaitForUserDialog("Title", "Adjust Threshold for Marker " + v).show() IJ.run(imp, "Convert to Mask", "") # Measures the area fraction of the new image for each ROI from the ROI manager. areaFractions = [] for roi in roim.getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.AREA_FRACTION) areaFractions.append(stats.areaFraction) # Saves the results in areaFractionArray areaFractionsArray[x] = areaFractions roim.close() for chan in channels: v, x = chan imp = images[x] imp.deleteRoi() roim = RoiManager(True) ParticleAnalyzer.setRoiManager(roim); pa = ParticleAnalyzer(ParticleAnalyzer.ADD_TO_MANAGER, Measurements.AREA, table, 15, 9999999999999999, 0.2, 1.0) pa.analyze(imp) blobs = [] for roi in roim.getRoisAsArray(): imp.setRoi(roi) stats = imp.getStatistics(Measurements.AREA) blobs.append(stats.area) blobsarea[x] = sum(blobs) #take this out and use intial mask tissue area from the beginning blobsnuclei[x] = len(blobs) if not displayImages: imp.changes = False imp.close() roim.reset() roim.close() imp.close() # Creates the summary dictionary which will correspond to a single row in the output csv, with each key being a column summary = {} summary['Image'] = filename summary['Directory'] = subFolder # Adds usual columns summary['size-average'] = 0 summary['#nuclei'] = 0 summary['all-negative'] = 0 summary['too-big-(>' + str(tooBigThreshold) + ')'] = 0 summary['too-small-(<' + str(tooSmallThreshold) + ')'] = 0 # Creates the fieldnames variable needed to create the csv file at the end. fieldnames = ['Name', 'Directory', 'Image', 'size-average', 'too-big-(>' + str(tooBigThreshold) + ')', 'too-small-(<' + str(tooSmallThreshold) + ')', '#nuclei', 'all-negative'] # Adds the columns for each individual marker (ignoring Dapi since it was used to count nuclei) summary["organoid-area"] = bigAreas[x] fieldnames.append("organoid-area") for chan in channels: v, x = chan summary[v + "-positive"] = 0 fieldnames.append(v + "-positive") summary[v + "-intensity"] = intensities[x] fieldnames.append(v + "-intensity") summary[v + "-blobsarea"] = blobsarea[x] fieldnames.append(v + "-blobsarea") summary[v + "-blobsnuclei"] = blobsnuclei[x] fieldnames.append(v + "-blobsnuclei") # Adds the column for colocalization between first and second marker if len(channels) > 2: summary[channels[1][0] + '-' + channels[2][0] + '-positive'] = 0 fieldnames.append(channels[1][0] + '-' + channels[2][0] + '-positive') # Adds the columns for colocalization between all three markers if len(channels) > 3: summary[channels[1][0] + '-' + channels[3][0] + '-positive'] = 0 summary[channels[2][0] + '-' + channels[3][0] + '-positive'] = 0 summary[channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive'] = 0 fieldnames.append(channels[1][0] + '-' + channels[3][0] + '-positive') fieldnames.append(channels[2][0] + '-' + channels[3][0] + '-positive') fieldnames.append(channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive') # Loops through each particle and adds it to each field that it is True for. areaCounter = 0 for z, area in enumerate(areas): log.write(str(area)) log.write("\n") if area > tooBigThreshold: summary['too-big-(>' + str(tooBigThreshold) + ')'] += 1 elif area < tooSmallThreshold: summary['too-small-(<' + str(tooSmallThreshold) + ')'] += 1 else: summary['#nuclei'] += 1 areaCounter += area temp = 0 for chan in channels: v, x = chan if areaFractionsArray[x][z] > areaFractionThreshold[ 0]: # theres an error here im not sure why. i remember fixing it before summary[chan[0] + '-positive'] += 1 if x != 0: temp += 1 if temp == 0: summary['all-negative'] += 1 if len(channels) > 2: if areaFractionsArray[1][z] > areaFractionThreshold[1]: if areaFractionsArray[2][z] > areaFractionThreshold[2]: summary[channels[1][0] + '-' + channels[2][0] + '-positive'] += 1 if len(channels) > 3: if areaFractionsArray[1][z] > areaFractionThreshold[1]: if areaFractionsArray[3][z] > areaFractionThreshold[3]: summary[channels[1][0] + '-' + channels[3][0] + '-positive'] += 1 if areaFractionsArray[2][z] > areaFractionThreshold[2]: if areaFractionsArray[3][z] > areaFractionThreshold[3]: summary[channels[2][0] + '-' + channels[3][0] + '-positive'] += 1 if areaFractionsArray[1][z] > areaFractionThreshold[1]: summary[channels[1][0] + '-' + channels[2][0] + '-' + channels[3][0] + '-positive'] += 1 # Calculate the average of the particles sizes if float(summary['#nuclei']) > 0: summary['size-average'] = round(areaCounter / summary['#nuclei'], 2) # Opens and appends one line on the final csv file for the subfolder (remember that this is still inside the loop that goes through each image) with open(outputDirectory + "/" + outputName + ".csv", 'a') as csvfile: writer = csv.DictWriter(csvfile, fieldnames=fieldnames, extrasaction='ignore', lineterminator='\n') if os.path.getsize(outputDirectory + "/" + outputName + ".csv") < 1: writer.writeheader() writer.writerow(summary) IJ.run(imp, "Close All", "")
def main(): # define here which membrane indices will be used in the analysis, with last index the "control" index membrane_indices = [-1, 0, 1, 3] # for now, work with frontmost open image... imp = IJ.getImage() im_title = imp.getTitle() settings = MembraneEvolutionAnalysisSettings( membrane_indices=membrane_indices) settings.loadPersistedSettings() timestamp = datetime.strftime(datetime.now(), '%Y-%m-%d %H-%M-%S') DirectoryChooser.setDefaultDirectory((settings.output_path)) dc = DirectoryChooser('Select the root folder for saving output') output_root = dc.getDirectory() if output_root is None: raise IOError('no output path chosen') settings.output_path = output_root # get calibration cal = imp.getCalibration() if cal.getTimeUnit() == "sec": cal.setTimeUnit('s') # pop up a dialog prompting for selection of zero time point, frame interval, and time step for analysis time_steps_not_ok = True while time_steps_not_ok: dialog = NonBlockingGenericDialog("Determine time parameters...") dialog.addNumericField("0 timepoint frame (1-index): ", settings.zero_timepoint_frame, 0) dialog.addNumericField("Acquisition time step (s): ", cal.frameInterval, 2) # assume stored in seconds dialog.addNumericField( "Time step for analysis (s): ", cal.frameInterval * settings.analysis_frame_step, 2) dialog.showDialog() if dialog.wasCanceled(): return zero_f = dialog.getNextNumber() acq_t_step = dialog.getNextNumber() analysis_t_step = dialog.getNextNumber() if acq_t_step != 0 and analysis_t_step != 0: analysis_frame_step = analysis_t_step / acq_t_step if round(analysis_frame_step) == analysis_frame_step: time_steps_not_ok = False settings.zero_timepoint_frame = zero_f settings.analysis_frame_step = analysis_frame_step if time_steps_not_ok: warning_dlg = GenericDialog("Error!") warning_dlg.addMessage( "Analysis time step must be an integer multiple of acquisition time steps, and neither should be zero!!" ) warning_dlg.setOKLabel("Try again...") warning_dlg.showDialog() if warning_dlg.wasCanceled(): return start_frame = int(((zero_f - 1) % analysis_frame_step) + 1) end_frame = int(imp.getNFrames() - (imp.getNFrames() - zero_f) % analysis_frame_step) frames = [ f + 1 for f in range(start_frame - 1, end_frame, int(analysis_frame_step)) ] print("frames = " + str(frames)) imp.killRoi() analysis_imp = SubstackMaker().makeSubstack( imp, str(start_frame) + "-" + str(end_frame) + "-" + str(int(analysis_frame_step))) imp.changes = False imp.close() analysis_imp.show() drawn_membranes = [ TimepointsMembranes(input_image_title=im_title, time_point_s=(t - 1) * acq_t_step) for t in frames ] membranes_listener = UpdateRoiImageListener(drawn_membranes) analysis_imp.addImageListener(membranes_listener) # now attach roi listener to store all 0th membranes after showing a waitforuserdialog to prompt continuation IJ.setTool("freeline") for membrane_idx in membrane_indices: # if membrane_idx>50: # IJ.setTool("line"); analysis_imp.killRoi() membranes_listener.resetLastFrame() membranes_listener.setCurrentMembraneIndex(membrane_idx) analysis_imp.setZ(1) continue_dlg = WaitForUserDialog( "Continue?", "Click OK once all the " + str(membrane_idx) + "-index membranes have been drawn") continue_dlg.show() membranes_listener.imageUpdated(analysis_imp) drawn_membranes = membranes_listener.getDrawnMembraneTimepointsList() json_path = os.path.join(output_root, "Membranes " + timestamp + ".json") f = open(json_path, 'w+') try: json.dump(drawn_membranes, f, default=encode_membrane) finally: f.close() # save csv containing mebrane measurements for current membrane index csv_path = os.path.join( output_root, ("Membrane measurements " + timestamp + ".csv")) if membrane_idx == membrane_indices[0]: try: f = open(csv_path, 'wb') writer = csv.writer(f) writer.writerow([ "Membrane index", ("Time point, " + cal.getTimeUnit()), ("Membrane length, " + cal.getUnit()), ("Euclidean length, " + cal.getUnit()), "Membrane sinuoisty" ]) finally: f.close() try: f = open(csv_path, 'ab') writer = csv.writer(f) for mems in drawn_membranes: mem = mems.getMembrane(membrane_idx) if mem is not None: writer.writerow([ membrane_idx, mems.time_point_s, mem.getPathLength() * cal.pixelWidth, mem.getEuclidean() * cal.pixelWidth, mem.getSinuosity() ]) finally: f.close() settings.persistSettings() settings.save_settings() print("Finished getting all membranes with indices " + str(membrane_indices)) analysis_imp.close()
win.setLocation(int(xpos_det), int(ypos_det)) getOptions(dest) else: pass firstpass = False imp = IJ.getImage() image_name = imp.title bit_depth = bit_tester(image_name) colorscale() #set a manual background value# if man_bck_det is True: if current_image != image_name: IJ.setTool("oval") region = "Select Background" selection(region) to_transport_channel() man_bck_list=[] for channel in channel_iterator: channel_first = int(channel) IJ.setSlice(channel_first) man_bck_list.append(selection_mean()) background = man_bck_list[0] to_transport_channel() if mean_max_det is True: IJ.setTool("polygon") else: IJ.setTool("rectangle")
emissionWL.append(WL) except ValueError: raise Exception("Couldn't find the EmissionWavelength info in the metadata") # Make the maximum intensity projection # and show it for user input. project = ZProjector() project.setMethod(ZProjector.MAX_METHOD) project.setImage(imp) project.doProjection() projection = project.getProjection() projection.show() # Wait for the user to draw a line # and check if line ROI. IJ.setTool("line"); myWait = WaitForUserDialog ("waitForUser", "Make a line with the region of interest and press OK") myWait.show() roi = projection.getRoi() # Check if roi is a line # otherwise exit if not (roi.isLine()): raise Exception("Line selection required") # Loop through existing files to avoid # overwriting. Will increment the number # at the end. Saves the MIP with input. fileName = shortTitle + "ROI" + str(num); overlayOutput = os.path.join(output,"MAX_" + fileName)
if numSlices > 1: for i in range(numSlices - 1): stack.deleteSlice(1) image.setStack(stack) IJ.run("Set Measurements...", " redirect=None decimal=3"); numTimesToMeasure = 5 # Draw the radius N times and record the result centerList = [] radiusList = [] for i in range(numTimesToMeasure): IJ.run("Select None") IJ.setTool('line') WaitForUserDialog('Draw the radius.').show() # Get the center and the radius selected currentROI = image.getRoi() cx, cy = currentROI.x1, currentROI.y1 rx, ry = currentROI.x2, currentROI.y2 # Always assumes you draw from center to radius! If you do # not, bad things happen. centerList.append([cx, cy]) radius = ((cx-rx)**2 + (cy-ry)**2)**0.5 radiusList.append(radius) IJ.run('Measure') cx_list = [f[0] for f in centerList] cy_list = [f[1] for f in centerList]
if f != "": array = get_array(f[0]) if f[1] == "b": color = "black" else: color = "white" draw(i, j, array, color) def draw_field(field, selectedX, selectedY): for j in range(0, 8): for i in range(0, 8): draw_one(i, j, field, selectedX, selectedY) IJ.setTool(Toolbar.HAND) field = initial_field() currentX = -1 currentY = -1 draw_field(field, currentX, currentY) canvas = WindowManager.getCurrentImage().getCanvas() clicked = 0 while True: p = canvas.getCursorLoc() x = int(p.x / w) y = int(p.y / h) newClicked = canvas.getModifiers() & 16 if clicked and not newClicked: if currentX >= 0: if x != currentX or y != currentY:
def perform_user_qc(in_imp, edges, alt_edges, fixed_anchors_list, params): """allow the user to intervene to fix erroneously identified membrane edges""" n_frames = in_imp.getNFrames(); n_channels = in_imp.getNChannels(); output_folder = params.output_path; current_edges = edges; rgbstack = ImageStack(in_imp.getWidth(), in_imp.getHeight()); if n_frames > 1: for tidx in range(n_frames): in_imp.setT(tidx+1); ip = in_imp.getProcessor(); rgbip = ip.convertToRGB(); rgbstack.addSlice(rgbip); else: for cidx in range(n_channels): in_imp.setC(cidx+1); ip = in_imp.getProcessor(); rgbip = ip.convertToRGB(); rgbstack.addSlice(rgbip); imp = ImagePlus(("RGB " + in_imp.getTitle()), rgbstack); IJ.run("Colors...", "foreground=red background=white selection=yellow"); for tidx in range(imp.getNSlices()): imp.setSlice(tidx+1); for anchor in params.manual_anchor_positions: imp.setRoi(PointRoi(anchor[0], anchor[1])); IJ.run(imp, "Draw", "slice"); imp.show(); autoset_zoom(imp); imp.setPosition(1); imp.setRoi(current_edges[0]); if n_frames > 1: listener = UpdateRoiImageListener(current_edges); imp.addImageListener(listener); IJ.setTool("freeline"); do_flip = True; while do_flip: dialog = NonBlockingGenericDialog("User quality control"); dialog.enableYesNoCancel("Continue", "Flip all edges"); dialog.setCancelLabel("Cancel analysis"); dialog.addMessage("Please redraw the membrane edges as necessary, \n" + "making sure to draw beyond anchor points at either end...\n" + "Click OK when done. "); p = Panel(); but = Button("Flip this edge"); al = Listener(edges, alt_edges, imp); but.addActionListener(al); p.add(but); dialog.addPanel(p); dialog.showDialog(); if dialog.wasCanceled(): raise KeyboardInterrupt("Run canceled"); elif dialog.wasOKed(): do_flip = False; else: print("flip edges"); do_flip = True; if n_frames > 1: imp.removeImageListener(listener); current_edges = alt_edges if (current_edges == edges) else edges; imp.setPosition(1); imp.setRoi(current_edges[0]); if n_frames > 1: listener = UpdateRoiImageListener(current_edges); imp.addImageListener(listener); last_roi = imp.getRoi(); if n_frames > 1: qcd_edges = listener.getRoiList(); if imp.getNFrames() > imp.getNSlices(): qcd_edges[imp.getT() - 1] = last_roi; else: qcd_edges[imp.getZ() - 1] = last_roi; imp.removeImageListener(listener); else: qcd_edges = [last_roi]; mbio.save_qcd_edges2(qcd_edges, output_folder); # next four lines are a quick and dirty hack... if n_frames > 1: nframes = imp.getNFrames() if imp.getNFrames()>imp.getNSlices() else imp.getNSlices(); else: nframes = n_frames; for fridx in range(0, nframes): if (qcd_edges[fridx].getType()==Roi.FREELINE) or (qcd_edges[fridx].getType()==Roi.POLYLINE): if (fridx == 0) or params.constrain_anchors: anchors = params.manual_anchor_positions; else: anchors = fixed_anchors_list[fridx - 1]; fixed_anchors = mb.fix_anchors_to_membrane(anchors, qcd_edges[fridx], params); fixed_anchors = mb.order_anchors(fixed_anchors, params.manual_anchor_midpoint); fixed_anchors_list[fridx] = fixed_anchors; poly = qcd_edges[fridx].getInterpolatedPolygon(0.25, False); polypoints = [(x,y) for x,y in zip(poly.xpoints, poly.ypoints)]; idx = [polypoints.index(fixed_anchors[0]), polypoints.index(fixed_anchors[1])]; idx.sort(); polypoints = polypoints[idx[0]:idx[1]]; newedge = PolygonRoi([x for (x,y) in polypoints], [y for (x,y) in polypoints], Roi.POLYLINE); newedge = mb.check_edge_order(anchors, newedge); imp.setPosition(fridx + 1); imp.setRoi(newedge); IJ.run(imp, "Interpolate", "interval=1.0 smooth adjust"); IJ.run(imp, "Fit Spline", ""); qcd_edges[fridx] = imp.getRoi(); mbio.save_qcd_edges2(qcd_edges, output_folder); imp.changes = False; imp.close(); return qcd_edges, fixed_anchors_list;
checkbox = False while checkbox == False: gd = GenericDialog("Title here") gd.addStringField("id", "") gd.addCheckbox("Same Image", True) gd.showDialog() checkbox = gd.getNextBoolean() id = gd.getNextString() if checkbox == False: IJ.run("Open Next") else: break imp = IJ.getImage() IJ.setTool("multipoint") WaitForUserDialog("make 11 points").show() proi = imp.getRoi() p = proi.getPolygon() xpts = p.xpoints ypts = p.ypoints xpts.insert(0, 1111) # inserts a dummy variables so that numbers makes sense ypts.insert(0, 1111) thorax_width = distance(xpts[2], ypts[2], xpts[3], ypts[3]) total_body_length = distance(xpts[1], ypts[1], xpts[5], ypts[5]) abdomen_length = distance(xpts[1], ypts[1], xpts[4], ypts[4]) abdomen_width = distance(xpts[6], ypts[6], xpts[7], ypts[7])
ip = FloatProcessor(w, h) pix = ip.getPixels() for x in range(w): for y in range(h): pix[y * w + x] = projected_im_pix[y][x] out_imp = ImagePlus("projected", ip) out_imp.show() egfp_imp_disp.show() roi_stack.show() #egfp_imp_disp.addImageListener(UpdateRoiImageListener(ring_rois)); unwrapped_imp = IJ.createImage("twisted unwrap", 2 * out_imp.getWidth(), out_imp.getHeight(), 1, 32) unwrapped_imp.show() IJ.setTool("freeline") WaitForUserDialog("input unwrap axis").show() unwrap_poly = out_imp.getRoi().getPolygon() unwrap_poly_xs #print("unzip axis = " + str(unzip_axis)); #right_side_xs = unzip_axis; #right_side_xs.append(out_imp.getWidth()); #right_side_xs.append(out_imp.getWidth()); #right_side_ys = [y+1 for y in range(out_imp.getHeight())]; #right_side_ys.append(out_imp.getHeight()); #right_side_ys.append(1); #right_side_roi = PolygonRoi(right_side_xs, right_side_ys, Roi.POLYGON); #out_imp.setRoi(right_side_roi);
if f != '': array = get_array(f[0]) if f[1] == 'b': color = 'black' else: color = 'white' draw(i, j, array, color) def draw_field(field, selectedX, selectedY): for j in range(0, 8): for i in range(0, 8): draw_one(i, j, field, selectedX, selectedY) IJ.setTool(Toolbar.HAND) field = initial_field() currentX = -1 currentY = -1 draw_field(field, currentX, currentY) canvas = WindowManager.getCurrentImage().getCanvas() clicked = 0 while True: p = canvas.getCursorLoc() x = int(p.x / w) y = int(p.y / h) newClicked = canvas.getModifiers() & 16 if clicked and not newClicked: if currentX >= 0: if x != currentX or y != currentY:
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])
def makeArrow(x1, y1, x2, y2): IJ.setTool("arrow") imp = IJ.getImage() imp.setRoi(Line(x1, y1, x2, y2))
def duty_cycle(i, horizontal): IJ.open(i) IJ.run("Enhance Contrast...", "saturated=0.3 equalize") IJ.run("Smooth", "") 'IJ.run("Anisotropic Diffusion 2D", "number=20 smoothings=1 keep=20 a1=0.50 a2=0.90 dt=20 edge=5") # use instead of smooth for better results, slower imp = IJ.getImage() ImageConverter(imp).convertToGray8() file_base = str(imp.title) # convert name into string file_base = file_base.split('.', 1)[0] # remove all characters including and after . sample_id = file_base.split('_', 1)[0] height = imp.height width = imp.width IJ.run(imp, "Set Scale...", "distance=5000 known=1 pixel=1 unit=cm") IJ.setTool("line") for scan in range(1, num_scans): row_count = 0 data=[] data2=[] last = 0 filename = file_base + "_" + str(scan) if not horizontal: IJ.makeLine(0, scan*height/num_scans, width, scan*height/num_scans) # horizontal line to measure vertical grating profile else: IJ.makeLine(width*scan/num_scans, 9*height/10, width*scan/num_scans, 0) # vertical line to measure horizontal grating profile IJ.run(imp, "Plot Profile", "") imp_plot = IJ.getImage() IJ.run(imp, "Find Peaks", setting) # nw07 params: min._peak_amplitude=60 min._peak_distance=0 min._value=100 max._value=0 exclude list IJ.saveAs("Results", csvpath + filename + "_raw.csv") imp_plot.close() imp_plot = IJ.getImage() IJ.saveAs("Png", csvpath + "Peaks in Plot of " + filename + ".png") imp_plot.close() IJ.selectWindow(filename + "_raw.csv") IJ.run("Close") with open(csvpath + filename + "_raw.csv", "rb") as fin, open(csvpath + filename + "_peaks.csv", "wb") as fout: writer = csv.writer(fout) for row in csv.reader(fin): if not row[2] == '': writer.writerow(row) with open(csvpath + filename + "_peaks.csv", "rb") as File: reader = csv.reader(File) for row in reader: row_count += 1 if row_count == 1: continue data.append(tuple(row)) # Append all non-header rows into a list of data as a tuple of cells for row in sort_table(data, 2): data2.append(tuple(row)) if len(data2) < 3: IJ.log(filename + " no peaks detected, skipping...") continue else: peaks = len(data2) last = data2[0] last = last[2] row_count = 0 diff = 0 colG = [] blank = "" duty = zip(*data2) for row in data2: row_count += 1 if row_count == 1: continue else: print row[2] print last diff = float(row[2]) - float(last) colG.append(diff) last = row[2] a, b = colG[::2], colG[1::2] avga = sum(a)/len(a) avgb = sum(b)/len(b) a_len_dev = len(a) - 1 b_len_dev = len(b) - 1 if b_len_dev > 1: a_stdev = sqrt(sum((x - avga)**2 for x in a) / a_len_dev) b_stdev = sqrt(sum((x - avgb)**2 for x in b) / b_len_dev) else: a_stdev = 1 b_stdev = 1 duty_cyc = avga/(avga+avgb) perc = duty_cyc*100 invperc = 100 - perc inv_duty = 1 - duty_cyc duty_max = max(duty_cyc, inv_duty) duty_min = min(duty_cyc, inv_duty) percs = round(perc) percs = int(percs) percs = str(percs) invpercs = round(invperc) invpercs = int(invpercs) invpercs = str(invpercs) colG.insert(0, blank) a.insert(0, blank) b.insert(0, blank) b.insert(1, blank) i = 0 while i < len(a): i += 2 a.insert(i, blank) i = 1 while i < len(b): i += 2 b.insert(i, blank) duty.append(colG) duty.append(a) duty.append(b) duty = zip(*duty) result = [sample_id, file_base, scan, duty_cyc, inv_duty, a_stdev, b_stdev, peaks, duty_max, duty_min] header = ["X0", "Y0", "X1", "Y1", "X2", "Y2", "diff", "a", "b"] results.append(result) with open(csvpath + filename + "_duty.csv", 'wb') as myfile: wr = csv.writer(myfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) wr.writerow(header) wr.writerows(duty) print(filename + " duty cycle is " + percs + "/" + invpercs + "%.") IJ.log(filename + " duty cycle is " + percs + "/" + invpercs + "% (" + str(peaks) + " peaks found)") with open(csvpath + "results.csv", 'wb') as myfile: wr = csv.writer(myfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) wr.writerows(results) # Write the result data from all images into a single csv file
def main(): ### debug ############################################################### #print (sys.version_info); #print(sys.path); #file_path = "D:\\data\\Inverse blebbing\\MAX_2dpf marcksl1b-EGFP inj_TgLifeact-mCh_movie e4_split-bleb1.tif"; #output_root = "D:\\data\\Inverse blebbing\\output"; #from datetime import datetime #timestamp = datetime.strftime(datetime.now(), '%Y-%m-%d %H-%M-%S'); #output_folder = os.path.join(output_root, (timestamp + ' output')); #os.mkdir(output_folder); ######################################################################## # ensure consistent preference settings Prefs.blackBackground = False; # prompt user for input parameters params = mbui.analysis_parameters_gui(); # prompt user for file locations file_path, output_folder = mbio.file_location_chooser(params.input_image_path); params.setInputImagePath(file_path); params.setOutputPath(output_folder); # get image file import_opts, params = mbui.choose_series(file_path, params); imps = bf.openImagePlus(import_opts); imp = imps[0]; # catch unexpected image dimensions - for now, project in Z...: if imp.getNSlices() > 1: mbui.warning_dialog(["More than one Z plane detected.", "I will do a maximum projection before proceeding", "Continue?"]); imp = ZProjector.run(imp,"max all"); params = mbio.get_metadata(params); params.setCurvatureLengthUm(round(params.curvature_length_um / params.pixel_physical_size) * params.pixel_physical_size); params.persistParameters(); IJ.run(imp, "Set Scale...", "distance=0 known=0 pixel=1 unit=pixel"); imp.show(); if imp.getNChannels() > 1: imp.setPosition(params.membrane_channel_number, 1, 1); mbui.autoset_zoom(imp); IJ.run("Enhance Contrast", "saturated=0.35"); # prompt user to select ROI original_imp, crop_params = mbui.crop_to_ROI(imp, params); if crop_params is not None: params.perform_spatial_crop = True; mbui.autoset_zoom(imp); else: params.perform_spatial_crop = False; # prompt user to do time cropping imp, start_end_tuple = mbui.time_crop(imp, params); params.setTimeCropStartEnd(start_end_tuple); repeats = 1; inner_outer_comparisons = None; if params.inner_outer_comparison: inner_outer_comparisons = InnerOuterComparisonData(); repeats = 2; IJ.selectWindow(imp.getTitle()); IJ.run("Enhance Contrast", "saturated=0.35"); for r in range(0, repeats): calculated_objects = CalculatedObjects(); if params.time_crop_start_end[0] is not None: calculated_objects.timelist = [idx * params.frame_interval for idx in range(params.time_crop_start_end[0], params.time_crop_start_end[1]+1)] else: calculated_objects.timelist = [idx * params.frame_interval for idx in range(imp.getNFrames())]; calculated_objects, params, split_channels = mbfs.generate_edges(imp, params, calculated_objects, (r+1)/repeats); membrane_channel_imp = split_channels[0]; actin_channel_imp = split_channels[1]; segmentation_channel_imp = split_channels[2]; calculated_objects = mbfs.calculate_outputs(params, calculated_objects, split_channels, repeat_fraction=(r+1)/repeats); # output colormapped images and kymographs fig_imp_list = mbfs.generate_and_save_figures(imp, calculated_objects, params, membrane_channel_imp, segmentation_channel_imp); mbfs.save_csvs(calculated_objects, params); params.saveParametersToJson(os.path.join(params.output_path, "parameters used.json")); imp.changes = False; IJ.setTool("zoom"); if params.close_on_completion or (params.inner_outer_comparison and r!=(repeats-1)): for fig_imp in fig_imp_list: fig_imp.close(); elif params.close_on_completion and (r==(repeats-1)): imp.close(); if params.inner_outer_comparison: tname = "Time, " + params.interval_unit; output_folder = os.path.dirname(params.output_path); profile = [[((inner, outer), (float(outer)/inner)) for inner, outer in zip(calculated_objects.inner_outer_data.inner_means, calculated_objects.inner_outer_data.outer_means)]]; mbio.save_profile_as_csv(profile, os.path.join(output_folder, "Intensity ratios.csv"), "outer/inner", xname="inner", yname="outer", tname=tname, time_list=calculated_objects.timelist); sd_profile = [[((inner, outer), (float(outer)/inner)) for inner, outer in zip(calculated_objects.inner_outer_data.inner_sds, calculated_objects.inner_outer_data.outer_sds)]]; mbio.save_profile_as_csv(profile, os.path.join(output_folder, "Intensity standard deviation ratios.csv"), "outer sd/inner sd", xname="inner sd", yname="outer sd", tname=tname, time_list=calculated_objects.timelist); return;
# return # Prevent further propagation of the key event: keyEvent.consume() # MAIN code imp = IJ.getImage() killIt = False if imp.getHeight() == 1024: # half-chip size hOffset = 512 elif imp.getHeight() == 2048: #full-chip image hOffset = 0 else: gdGoodBye = GenericDialog("Dimensions error") gdGoodBye.addMessage( 'Image must be 2048x2048, or 2048x1024 pixels! \n I retire!') gdGoodBye.showDialog() killIt = True if not killIt: IJ.setTool(Toolbar.RECTANGLE) manager = RoiManager.getInstance() if manager is None: manager = RoiManager() reset() listener = ML() keyLis = ListenToKey() win = imp.getWindow() win.getCanvas().addMouseListener(listener) win.getCanvas().addKeyListener(keyLis)
for time in timepoint_list: imp.setT(time) if channel == 1: background = selection_mean() background_c1.append(background) if channel == 2: background = selection_mean() background_c2.append(background) return background_c1, background_c2 background_c1 = [] background_c2 = [] if back_state == 'optional': print("optional") IJ.setTool("oval") region = "Select Background" selection(region) imp = IJ.getImage() roi_bck = imp.getRoi() background_c1, background_c2 = background_assay() if back_state != 'optional': print("not Optional") with open(back_state, 'r') as csvfile: csvreader = csv.reader(csvfile) for row in csvreader: background_c1.append(float(row[0])) background_c2.append(float(row[1])) # ok we can now access these variables.
def main(): # ensure consistent preference settings Prefs.blackBackground = False # get locations for previous and new outputs params = Parameters() params.loadLastParams() output_folder_old, output_folder = mbio.rerun_location_chooser( params.input_image_path) params.loadParametersFromJson( os.path.join(output_folder_old, 'parameters used.json')) params.setOutputPath(output_folder) # present user with the familiar setup UI, with options that don't make sense/aren't yet implemented disabled params = mbui.analysis_parameters_gui(rerun_analysis=True, params=params) # get original image file (for overlays etc.) if not os.path.isfile(params.input_image_path): mbui.warning_dialog([ "The original data can't be found at the location specified in saved parameters. ", "(Possibly something as simple as a change in network drive mapping has occurred)", "Please specify the location of the original image file..." ]) params.setInputImagePath( mbio.input_file_location_chooser(params.output_path)) import_opts, params = mbui.choose_series(params.input_image_path, params) imps = bf.openImagePlus(import_opts) imp = imps[0] if imp.getNSlices() > 1: mbui.warning_dialog([ "More than one Z plane detected.", "I will do a maximum projection before proceeding", "Continue?" ]) imp = ZProjector.run(imp, "max all") params = mbio.get_metadata(params) params.setCurvatureLengthUm( round(params.curvature_length_um / params.pixel_physical_size) * params.pixel_physical_size) params.persistParameters() IJ.run(imp, "Set Scale...", "distance=0 known=0 pixel=1 unit=pixel") imp.show() if imp.getNChannels() > 1: imp.setPosition(params.membrane_channel_number, 1, 1) mbui.autoset_zoom(imp) IJ.run("Enhance Contrast", "saturated=0.35") # prompt user to select ROI original_imp = Duplicator().run(imp) _, crop_params = mbui.crop_to_ROI(imp, params) imp.show() if crop_params is not None: params.perform_spatial_crop = True mbui.autoset_zoom(imp) imp.updateAndDraw() review_crop = mb.check_cropping(output_folder_old, params) keep_crop = not review_crop if review_crop: keep_crop = mbui.crop_review() if not keep_crop: imp.changes = False imp.close() imp = original_imp else: original_imp.close() else: original_imp.close() # prompt user to do time cropping imp, start_end_tuple = mbui.time_crop(imp, params) params.setTimeCropStartEnd(start_end_tuple) # import edges membrane_edges = mbio.load_qcd_edges2( os.path.join(output_folder_old, "user_defined_edges.zip")) mbio.save_qcd_edges2(membrane_edges, params.output_path) calculated_objects = CalculatedObjects() calculated_objects.membrane_edges = membrane_edges if params.time_crop_start_end[0] is not None: calculated_objects.timelist = [ idx * params.frame_interval for idx in range(params.time_crop_start_end[0], params.time_crop_start_end[1] + 1) ] else: calculated_objects.timelist = [ idx * params.frame_interval for idx in range(imp.getNFrames()) ] split_channels = mbfs.split_image_plus(imp, params) membrane_channel_imp = split_channels[0] actin_channel_imp = split_channels[1] segmentation_channel_imp = None if params.photobleaching_correction: if os.path.isfile( os.path.join(output_folder_old, 'binary_membrane_stack.tif')): segmentation_binary_path = os.path.join( output_folder_old, 'binary_membrane_stack.tif') segmentation_channel_imp = IJ.openImage(segmentation_binary_path) else: segmentation_channel_imp = split_channels[2] segmentation_channel_imp = mb.make_and_clean_binary( segmentation_channel_imp, params.threshold_method) split_channels[2] = segmentation_channel_imp calculated_objects = mbfs.calculate_outputs(params, calculated_objects, split_channels) # output colormapped images and kymographs fig_imp_list = mbfs.generate_and_save_figures(imp, calculated_objects, params, membrane_channel_imp, segmentation_channel_imp) mbfs.save_csvs(calculated_objects, params) params.saveParametersToJson( os.path.join(params.output_path, "parameters used.json")) imp.changes = False IJ.setTool("zoom") if params.close_on_completion: for fig_imp in fig_imp_list: fig_imp.close() imp.close() return
metadata_file_path = os.path.splitext(image_file_path)[0] + ".txt" metadata = import_iq3_metadata(metadata_file_path) #imp2 = HyperStackConverter.toHyperStack(imp, int(metadata['n_channels']), int(metadata['z_pixels']), 1, "Composite"); print(metadata) IJ.run( imp, "Properties...", "channels=" + str(int(metadata['n_channels'])) + " slices=" + str(int(metadata['z_pixels'])) + " frames=1 unit=" + str(metadata['x_unit']) + " pixel_width=" + str(metadata['x_physical_size']) + " pixel_height=" + str(metadata['y_physical_size']) + " voxel_depth=" + str(metadata['z_extent'] / metadata['z_pixels'])) imp.show() imp, z_lims = z_crop(imp) use_ch = imp.getC() print(use_ch) IJ.setTool("rect") imp.hide() imp2 = ZProjector.run(imp, "max") imp2.show() imp2.setC(use_ch + 1) WaitForUserDialog("Select XY region to crop...").show() crop_roi = imp2.getRoi() imp2.close() imp.show() imp.setRoi(crop_roi) IJ.run("Crop", "") frames = imp.getNFrames() slices = imp.getNSlices() imp = Duplicator().run(imp, use_ch + 1, use_ch + 1, 1, slices, 1, frames) imp.show()