Exemplo n.º 1
0
def gfp_analysis(imp, file_name, output_folder):
    """perform analysis based on gfp intensity thresholding"""
    cal = imp.getCalibration()
    channel_imps = ChannelSplitter.split(imp)
    gfp_imp = channel_imps[0]
    gfp_imp.setTitle("GFP")
    threshold_imp = Duplicator().run(gfp_imp)
    threshold_imp.setTitle("GFP_threshold_imp")
    ecad_imp = channel_imps[1]
    ecad_imp.setTitle("E-cadherin")
    nuc_imp = channel_imps[2]
    IJ.run(threshold_imp, "Make Binary",
           "method=Otsu background=Dark calculate")
    IJ.run(threshold_imp, "Fill Holes", "")
    erode_count = 2
    for _ in range(erode_count):
        IJ.run(threshold_imp, "Erode", "")
    threshold_imp = keep_blobs_bigger_than(threshold_imp, min_size_pix=1000)
    threshold_imp = my_kill_borders(threshold_imp)
    rois = generate_cell_rois(threshold_imp)
    out_stats = generate_cell_shape_results(rois, gfp_imp, cal, file_name)
    print("Number of cells identified = {}".format(len(out_stats)))
    threshold_imp.changes = False
    threshold_imp.close()
    # 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
Exemplo n.º 2
0
def get_no_nuclei_fully_enclosed(roi, full_nuclei_imp, overlap_threshold=0.65):
    """for a given cell roi and ImagePlus with binary nuclei, return how many nuclei lie ENTIRELY within the cell"""
    bbox = roi.getBounds()
    full_nuclei_imp.setRoi(roi)
    cropped_nuc_imp = full_nuclei_imp.crop()
    roi.setLocation(0, 0)
    cropped_nuc_imp.setRoi(roi)
    cropped_nuc_imp.killRoi()
    roim = RoiManager(False)
    mxsz = cropped_nuc_imp.getWidth() * cropped_nuc_imp.getHeight()
    pa = ParticleAnalyzer(
        ParticleAnalyzer.ADD_TO_MANAGER, ParticleAnalyzer.AREA
        | ParticleAnalyzer.SLICE | ParticleAnalyzer.CENTROID, None, 0, mxsz)
    pa.setRoiManager(roim)
    pa.analyze(cropped_nuc_imp)
    cell_imp = IJ.createImage("Cell binary", cropped_nuc_imp.getWidth(),
                              cropped_nuc_imp.getHeight(), 1, 8)
    IJ.run(cell_imp, "Select All", "")
    IJ.run(cell_imp, "Set...", "value=0 slice")
    cell_imp.setRoi(roi)
    IJ.run(cell_imp, "Set...", "value=255 slice")
    no_enclosed_nuclei = 0
    for idx, nuc_roi in enumerate(roim.getRoisAsArray()):
        test_imp = Duplicator().run(cell_imp)
        test_imp.setRoi(nuc_roi)
        IJ.run(test_imp, "Set...", "value=255 slice")
        test_imp.killRoi()
        IJ.run(test_imp, "Create Selection", "")
        IJ.run(test_imp, "Make Inverse", "")
        test_roi = test_imp.getRoi()
        test_roi_stats = test_roi.getStatistics()
        cell_roi_stats = roi.getStatistics()
        nuc_roi_stats = nuc_roi.getStatistics()
        if test_roi_stats.area < (
                cell_roi_stats.area +
            (1 - overlap_threshold) * nuc_roi_stats.area
        ):  # i.e. if more than (100*overlap_threshold)% of nucleus is inside cell...
            no_enclosed_nuclei += 1
        test_imp.changes = False
        test_imp.close()
    roi.setLocation(bbox.getX(), bbox.getY())
    cropped_nuc_imp.changes = False
    cropped_nuc_imp.close()
    cell_imp.changes = False
    cell_imp.close()
    return no_enclosed_nuclei
Exemplo n.º 3
0
def cut(event):
    roi = imp.getRoi()
    if roi != None:
        newRoi = roi.clone()
        Dup = Duplicator().run(imp, 1, imp.getNChannels(), 1, imp.getNSlices(), 1, imp.getNFrames())
        newRoi.setLocation(0,0)
        Dup.setRoi(newRoi)
        Dup.setTitle(Men.getTextField() + str(Men.getCounter()))
        Dup.show()
        #Men.setCounter()
        Men.addOlay(roi)
        imp.setOverlay(Men.getOverlay())    #setOverlay(Roi roi, java.awt.Color strokeColor, int strokeWidth, java.awt.Color fillColor) 
        imp.getOverlay().drawLabels(True) # drawNumbers
        imp.deleteRoi()
        
        #make cell instance and add to position instance
        p.addCell(cell(p.getMainPath(), p, Men.getCounter(), Dup))  #  cell(mainPath, position, ID, imp):
        Dup.close()
        Men.increaseCounter()
def cross_planes_approx_median_filter(stack_imp, filter_radius_um=5.0):
	"""relatively computationally cheap, slightly crude approximation of median filter"""
	title = stack_imp.getTitle();
	xy_imp = Duplicator().run(stack_imp);
	xy_imp.setTitle("xy {}".format(title));
	xz_imp = Duplicator().run(stack_imp);
	xz_imp.setTitle("xz {}".format(title));
	xz_imp = rot3d(xz_imp, 'x');
	zy_imp = Duplicator().run(stack_imp);
	zy_imp.setTitle("zy {}".format(title));
	zy_imp = rot3d(zy_imp, 'y');
	stack_imp.changes = False;
	stack_imp.close();
	xy_imp = stack_median_filter(xy_imp, radius_um=filter_radius_um);
	xz_imp = stack_median_filter(xz_imp, radius_um=filter_radius_um);
	zy_imp = stack_median_filter(zy_imp, radius_um=filter_radius_um);
	xz_imp = rot3d(xz_imp, 'x');
	zy_imp = rot3d(zy_imp, '-y');
	ic = ImageCalculator();
	dummy = ic.run("Add create 32-bit stack", xy_imp, xz_imp);
	xz_imp.close();
	xy_imp.close();
	output_imp = ic.run("Add create 32-bit stack", dummy, zy_imp);
	zy_imp.close();
	dummy.close();
	output_imp.show();
	IJ.run(output_imp, "Divide...", "value=3 stack");
	output_imp.setTitle("Cross-plane median filtered {} (r={} um)".format(title, filter_radius_um).replace(".tif", ""));
	print("Image size after applying approx median filter = ({}x{}x{})".format(output_imp.getWidth(), 
																			output_imp.getHeight(), 
																			output_imp.getNSlices()));
	return output_imp;
def split_and_rotate(imp, info):
    """return image to segment on, image to project out, and images to display"""
    # for now, assume that these are ISVs and that embryo is mounted in familiar fashion. First of these can be developed out...
    print("Image dimensions at start of split and rotate = ({}x{}x{}) pix".
          format(imp.getWidth(), imp.getHeight(), imp.getNSlices()))
    if imp.isVisible():
        IJ.run("Enhance Contrast", "saturated=0.35")
    seg_ch_idx, proj_ch_idx = ui.choose_segmentation_and_projection_channels(
        info)
    channels = ChannelSplitter().split(imp)
    seg_imp = Duplicator().run(channels[seg_ch_idx])
    # use Duplicator to decouple - can do smarter to save memory?
    proj_imp = Duplicator().run(channels[proj_ch_idx])
    rot_seg_imp = utils.rot3d(seg_imp, axis='x')
    rot_seg_imp.setTitle("rot_seg_imp")
    rot_proj_imp = utils.rot3d(proj_imp, axis='x')
    rot_proj_imp.setTitle("rot_proj_imp")
    egfp_mch_imps = []
    egfp_idx = 0 if "gfp" in info.ch1_label.lower() else 1
    mch_idx = int(not (egfp_idx))
    # assume two channel...
    for ch_idx in [egfp_idx, mch_idx]:
        if ch_idx == seg_ch_idx:
            egfp_mch_imps.append(Duplicator().run(rot_seg_imp))
        elif ch_idx == proj_ch_idx:
            egfp_mch_imps.append(Duplicator().run(rot_proj_imp))
        else:
            egfp_mch_imps.append(
                utils.rot3d(Duplicator().run(channels[ch_idx]), axis='x'))
    imp.changes = False
    imp.close()
    seg_imp.changes = False
    proj_imp.changes = False
    seg_imp.close()
    proj_imp.close()
    print("Image dimensions at start of split and rotate = ({}x{}x{}) pix".
          format(rot_proj_imp.getWidth(), rot_proj_imp.getHeight(),
                 rot_proj_imp.getNSlices()))
    return rot_seg_imp, rot_proj_imp, egfp_mch_imps
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 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
Exemplo n.º 8
0
def runOneFile(fullFilePath):

    global gNumChannels
    global gAlignBatchVersion

    if not os.path.isfile(fullFilePath):
        bPrintLog(
            '\nERROR: runOneFile() did not find file: ' + fullFilePath + '\n',
            0)
        return 0

    bPrintLog(
        time.strftime("%H:%M:%S") + ' starting runOneFile(): ' + fullFilePath,
        1)

    enclosingPath = os.path.dirname(fullFilePath)
    head, tail = os.path.split(enclosingPath)
    enclosingPath += '/'

    #make output folders
    destFolder = enclosingPath + tail + '_channels/'
    if not os.path.isdir(destFolder):
        os.makedirs(destFolder)
    destMaxFolder = destFolder + 'max/'
    if not os.path.isdir(destMaxFolder):
        os.makedirs(destMaxFolder)

    if gDoAlign:
        destAlignmentFolder = destFolder + 'alignment/'
        if not os.path.isdir(destAlignmentFolder):
            os.makedirs(destAlignmentFolder)

    if gSave8bit:
        eightBitFolder = destFolder + 'channels8/'
        if not os.path.isdir(eightBitFolder):
            os.makedirs(eightBitFolder)
        eightBitMaxFolder = eightBitFolder + 'max/'
        if not os.path.isdir(eightBitMaxFolder):
            os.makedirs(eightBitMaxFolder)

    # open image
    imp = Opener().openImage(fullFilePath)

    # get parameters of image
    (width, height, nChannels, nSlices, nFrames) = imp.getDimensions()
    bitDepth = imp.getBitDepth()
    infoStr = imp.getProperty("Info")  #get all .tif tags
    if not infoStr:
        infoStr = ''
    infoStr += 'bAlignBatch_Version=' + str(gAlignBatchVersion) + '\n'
    infoStr += 'bAlignBatch_Time=' + time.strftime(
        "%Y%m%d") + '_' + time.strftime("%H%M%S") + '\n'

    msgStr = 'w:' + str(width) + ' h:' + str(height) + ' slices:' + str(nSlices) \
       + ' channels:' + str(nChannels) + ' frames:' + str(nFrames) + ' bitDepth:' + str(bitDepth)
    bPrintLog(msgStr, 1)

    path, filename = os.path.split(fullFilePath)
    shortName, fileExtension = os.path.splitext(filename)

    #
    # look for num channels in ScanImage infoStr
    if gGetNumChanFromScanImage:
        for line in infoStr.split('\n'):
            #scanimage.SI4.channelsSave = [1;2]
            scanimage4 = find(line, 'scanimage.SI4.channelsSave =') == 0
            #state.acq.numberOfChannelsSave=2
            scanimage3 = find(line, 'state.acq.numberOfChannelsSave=') == 0
            if scanimage3:
                #print 'line:', line
                equalIdx = find(line, '=')
                line2 = line[equalIdx + 1:]
                if gGetNumChanFromScanImage:
                    gNumChannels = int(line2)
                    bPrintLog(
                        'over-riding gNumChannels with: ' + str(gNumChannels),
                        2)
            if scanimage4:
                #print '   we have a scanimage 4 file ... now i need to exptract the number of channel'
                #print 'line:', line
                equalIdx = find(line, '=')
                line2 = line[equalIdx + 1:]
                for delim in ';[]':
                    line2 = line2.replace(delim, ' ')
                if gGetNumChanFromScanImage:
                    gNumChannels = len(line2.split())
                    bPrintLog(
                        'over-riding gNumChannels with: ' + str(gNumChannels),
                        2)

    # show
    imp.show()
    # split channels if necc. and grab the original window names
    if gNumChannels == 1:
        origImpWinStr = imp.getTitle()  #use this when only one channel
        origImpWin = WindowManager.getWindow(
            origImpWinStr)  #returns java.awt.Window

    if gNumChannels == 2:
        winTitle = imp.getTitle()
        bPrintLog('Deinterleaving 2 channels...', 1)
        IJ.run('Deinterleave',
               'how=2 keep')  #makes ' #1' and ' #2', with ' #2' frontmost
        origCh1WinStr = winTitle + ' #1'
        origCh2WinStr = winTitle + ' #2'
        origCh1Imp = WindowManager.getImage(origCh1WinStr)
        origCh2Imp = WindowManager.getImage(origCh2WinStr)
        origCh1File = destFolder + shortName + '_ch1.tif'
        origCh2File = destFolder + shortName + '_ch2.tif'

    # work on a copy, mostly for alignment with cropping
    copy = Duplicator().run(imp)
    #copy.copyAttributes(imp) #don't copy attributes, it copies the name (which we do not want)
    copy.show()

    #
    # crop (on copy)
    if gDoCrop:
        bPrintLog('making cropping rectangle (left,top,width,height) ', 1)
        bPrintLog(
            str(gCropLeft) + ' ' + str(gCropTop) + ' ' + str(gCropWidth) +
            ' ' + str(gCropHeight), 2)

        roi = Roi(gCropLeft, gCropTop, gCropWidth,
                  gCropHeight)  #left,top,width,height
        copy.setRoi(roi)

        time.sleep(
            0.5
        )  # otherwise, crop SOMETIMES failes. WHAT THE F**K FIJI DEVELOPERS, REALLY, WHAT THE F**K

        #bPrintLog('cropping', 1)
        IJ.run('Crop')
        infoStr += 'bCropping=' + str(gCropLeft) + ',' + str(
            gCropTop) + ',' + str(gCropWidth) + ',' + str(gCropHeight) + '\n'

    #
    # remove calibration ( on original)
    if gRemoveCalibration:
        cal = imp.getCalibration()
        calCoeff = cal.getCoefficients()
        if calCoeff:
            msgStr = 'Calibration is y=a+bx' + ' a=' + str(
                calCoeff[0]) + ' b=' + str(calCoeff[1])
            bPrintLog(msgStr, 1)

            #remove calibration
            bPrintLog('\tRemoving Calibration', 2)
            imp.setCalibration(None)

            #without these, 8-bit conversion goes to all 0 !!! what the f**k !!!
            #bPrintLog('calling imp.resetStack() and imp.resetDisplayRange()', 2)
            imp.resetStack()
            imp.resetDisplayRange()

            #get and print out min/max
            origMin = StackStatistics(imp).min
            origMax = StackStatistics(imp).max
            msgStr = '\torig min=' + str(origMin) + ' max=' + str(origMax)
            bPrintLog(msgStr, 2)

            # 20150723, 'shift everybody over by linear calibration intercept calCoeff[0] - (magic number)
            if 1:
                # [1] was this
                #msgStr = 'Subtracting original min '+str(origMin) + ' from stack.'
                #bPrintLog(msgStr, 2)
                #subArgVal = 'value=%s stack' % (origMin,)
                #IJ.run('Subtract...', subArgVal)
                # [2] now this
                #msgStr = 'Adding calCoeff[0] '+str(calCoeff[0]) + ' from stack.'
                #bPrintLog(msgStr, 2)
                #addArgVal = 'value=%s stack' % (int(calCoeff[0]),)
                #IJ.run('Add...', addArgVal)
                # [3] subtract a magic number 2^15-2^7 = 32768 - 128
                magicNumber = gLinearShift  #2^15 - 128
                msgStr = 'Subtracting a magic number (linear shift) ' + str(
                    magicNumber) + ' from stack.'
                bPrintLog(msgStr, 2)
                infoStr += 'bLinearShift=' + str(gLinearShift) + '\n'
                subArgVal = 'value=%s stack' % (gLinearShift, )
            IJ.run(imp, 'Subtract...', subArgVal)

            # 20150701, set any pixel <0 to 0
            if 0:
                ip = imp.getProcessor()  # returns a reference
                pixels = ip.getPixels()  # returns a reference
                msgStr = '\tSet all pixels <0 to 0. This was added 20150701 ...'
                bPrintLog(msgStr, 2)
                pixels = map(lambda x: 0 if x < 0 else x, pixels)
                bPrintLog('\t\t... done', 2)

            #get and print out min/max
            newMin = StackStatistics(imp).min
            newMax = StackStatistics(imp).max
            msgStr = '\tnew min=' + str(newMin) + ' max=' + str(newMax)
            bPrintLog(msgStr, 2)

            #append calibration to info string
            infoStr += 'bCalibCoeff_a = ' + str(calCoeff[0]) + '\n'
            infoStr += 'bCalibCoeff_b = ' + str(calCoeff[1]) + '\n'
            infoStr += 'bNewMin = ' + str(newMin) + '\n'
            infoStr += 'bNewMax = ' + str(newMax) + '\n'

    #
    # set up
    if gNumChannels == 1:
        impWinStr = copy.getTitle()  #use this when only one channel
        impWin = WindowManager.getWindow(impWinStr)  #returns java.awt.Window

    if gNumChannels == 2:
        winTitle = copy.getTitle()
        bPrintLog('Deinterleaving 2 channels...', 1)
        IJ.run('Deinterleave',
               'how=2 keep')  #makes ' #1' and ' #2', with ' #2' frontmost
        ch1WinStr = winTitle + ' #1'
        ch2WinStr = winTitle + ' #2'
        ch1Imp = WindowManager.getImage(ch1WinStr)
        ch2Imp = WindowManager.getImage(ch2WinStr)
        ch1File = destFolder + shortName + '_ch1.tif'
        ch2File = destFolder + shortName + '_ch2.tif'

    #
    # alignment
    if gDoAlign and gNumChannels == 1 and copy.getNSlices() > 1:
        infoStr += 'AlignOnChannel=1' + '\n'
        #snap to middle slice
        if gAlignOnMiddleSlice:
            middleSlice = int(
                math.floor(copy.getNSlices() /
                           2))  #int() is necc., python is f*****g picky
        else:
            middleSlice = gAlignOnThisSlice
        copy.setSlice(middleSlice)

        transformationFile = destAlignmentFolder + shortName + '.txt'

        bPrintLog('MultiStackReg aligning:' + impWinStr, 1)
        stackRegParams = 'stack_1=[%s] action_1=Align file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body] save' % (
            impWin, transformationFile)
        IJ.run('MultiStackReg', stackRegParams)
        infoStr += 'AlignOnSlice=' + str(middleSlice) + '\n'

        #20150723, we just aligned on a cropped copy, apply alignment to original imp
        origImpTitle = imp.getTitle()
        stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' % (
            origImpTitle, transformationFile)
        IJ.run('MultiStackReg', stackRegParams)

    if gDoAlign and gNumChannels == 2 and ch1Imp.getNSlices(
    ) > 1 and ch2Imp.getNSlices() > 1:
        #apply to gAlignThisChannel
        alignThisWindow = ''
        applyAlignmentToThisWindow = ''
        if gAlignThisChannel == 1:
            infoStr += 'AlignOnChannel=1' + '\n'
            transformationFile = destAlignmentFolder + shortName + '_ch1.txt'
            alignThisWindow = ch1WinStr
            applyAlignmentToThisWindow = ch2WinStr
        else:
            infoStr += 'AlignOnChannel=2' + '\n'
            transformationFile = destAlignmentFolder + shortName + '_ch2.txt'
            alignThisWindow = ch2WinStr
            applyAlignmentToThisWindow = ch1WinStr

        alignThisImp = WindowManager.getImage(alignThisWindow)
        #snap to middle slice
        if gAlignOnMiddleSlice:
            middleSlice = int(
                math.floor(alignThisImp.getNSlices() /
                           2))  #int() is necc., python is f*****g picky
        else:
            middleSlice = gAlignOnThisSlice
        alignThisImp.setSlice(middleSlice)

        infoStr += 'bAlignOnSlice=' + str(middleSlice) + '\n'

        bPrintLog('MultiStackReg aligning:' + alignThisWindow, 1)
        stackRegParams = 'stack_1=[%s] action_1=Align file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body] save' % (
            alignThisWindow, transformationFile)
        IJ.run('MultiStackReg', stackRegParams)

        # 20150723, we just aligned on a copy, apply alignment to both channels of original
        # ch1
        bPrintLog('MultiStackReg applying alignment to:' + origCh1WinStr, 1)
        stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' % (
            origCh1WinStr, transformationFile)
        IJ.run('MultiStackReg', stackRegParams)
        # ch2
        bPrintLog('MultiStackReg applying alignment to:' + origCh2WinStr, 1)
        stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' % (
            origCh2WinStr, transformationFile)
        IJ.run('MultiStackReg', stackRegParams)

        #apply alignment to other window
        #bPrintLog('MultiStackReg applying alignment to:' + applyAlignmentToThisWindow, 1)
        #applyAlignThisImp = WindowManager.getImage(applyAlignmentToThisWindow)
        #stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' %(applyAlignmentToThisWindow,transformationFile)
        #IJ.run('MultiStackReg', stackRegParams)
    elif gDoAlign:
        bPrintLog('Skipping alignment, there may be only one slice?', 3)

    #
    # save
    if gNumChannels == 1:
        imp.setProperty("Info", infoStr)
        impFile = destFolder + shortName + '.tif'
        #bPrintLog('Saving:' + impFile, 1)
        bSaveStack(imp, impFile)
        #max project
        bSaveZProject(imp, destMaxFolder, shortName)

    if gNumChannels == 2:
        #ch1
        origCh1Imp.setProperty("Info", infoStr)
        #bPrintLog('Saving:' + ch1File, 1)
        bSaveStack(origCh1Imp, ch1File)
        #max project
        bSaveZProject(origCh1Imp, destMaxFolder, shortName + '_ch1')

        #ch2
        origCh2Imp.setProperty("Info", infoStr)
        #bPrintLog('Saving:' + ch2File, 1)
        bSaveStack(origCh2Imp, ch2File)
        #max project
        bSaveZProject(origCh2Imp, destMaxFolder, shortName + '_ch2')

#
    # post convert to 8-bit and save
    if gSave8bit:
        if bitDepth == 16:
            if gNumChannels == 1:
                bPrintLog('Converting to 8-bit:' + impWinStr, 1)
                IJ.selectWindow(impWinStr)
                #IJ.run('resetMinAndMax()')
                IJ.run("8-bit")
                impFile = eightBitFolder + shortName + '.tif'
                bPrintLog('Saving 8-bit:' + impFile, 2)
                bSaveStack(imp, impFile)
                #max project
                bSaveZProject(imp, eightBitMaxFolder, shortName)

            if gNumChannels == 2:
                #
                bPrintLog('Converting to 8-bit:' + origCh1WinStr, 1)
                IJ.selectWindow(origCh1WinStr)

                IJ.run("8-bit")
                impFile = eightBitFolder + shortName + '_ch1.tif'
                bPrintLog('Saving 8-bit:' + impFile, 2)
                bSaveStack(origCh1Imp, impFile)
                #max project
                bSaveZProject(origCh1Imp, eightBitMaxFolder,
                              shortName + '_ch1')

                #
                bPrintLog('Converting to 8-bit:' + origCh2WinStr, 1)
                IJ.selectWindow(origCh2WinStr)
                #IJ.run('resetMinAndMax()')
                IJ.run("8-bit")
                impFile = eightBitFolder + shortName + '_ch2.tif'
                bPrintLog('Saving 8-bit:' + impFile, 2)
                bSaveStack(origCh2Imp, impFile)
                #max project
                bSaveZProject(origCh2Imp, eightBitMaxFolder,
                              shortName + '_ch2')

    #
    # close original window
    imp.changes = 0
    imp.close()
    #copy
    copy.changes = 0
    copy.close()

    #
    # close ch1/ch2
    if gNumChannels == 2:
        #original
        origCh1Imp.changes = 0
        origCh1Imp.close()
        origCh2Imp.changes = 0
        origCh2Imp.close()
        #copy
        ch1Imp.changes = 0
        ch1Imp.close()
        ch2Imp.changes = 0
        ch2Imp.close()

    bPrintLog(
        time.strftime("%H:%M:%S") + ' finished runOneFile(): ' + fullFilePath,
        1)
Exemplo n.º 9
0
            centers.append([xcenter, ycenter])
            # print("Spot "+str(count)+" center: "+str(centers[count]))

            count += 1

    # work on a copy of the image
    from ij.plugin import Duplicator
    imp2 = Duplicator().run(imp, 1, channels, 1, 1, 1, 1)

    # clear the existing channel
    imp2.setDisplayMode(IJ.COLOR)
    imp2.setC(targetChannel)
    IJ.run(imp2, "Select All", "")
    IJ.setBackgroundColor(0, 0, 0)
    IJ.run(imp2, "Clear", "slice")

    # draw white circles to simulate cells
    IJ.setForegroundColor(255, 255, 255)
    for point in centers:
        drawSpot(point, celldiam)

    # save the simulated image
    IJ.saveAs(imp2, "Tiff",
              os.path.join(srcDir, basename + " sim " + str(trial) + ".tif"))
    imp2.close()

# print("Finished simulations.")

# close the original
imp.close()
Exemplo n.º 10
0
#imp.getCalibration() # DBG
if crop_image:
    imp.setRoi(int(xLoc-math.floor(winCrop/2)),int(yLoc-math.floor(winCrop/2)),winCrop,winCrop) # Create a ROI and crop it.
else:
    imp.setRoi(0,0,imp.width,imp.height) # Create a ROI and crop it.

crop = imp.crop("stack")
ij.process.ImageConverter(crop).convertToGray32()
tmp1 = Duplicator().run(crop, chDNA, chDNA, 1, crop.getNSlices(), 1, crop.getNFrames()) #Stack.setChannel(chDNA); run("Duplicate...", "channels=2 title=cropDNA duplicate");
tmp2 = Duplicator().run(crop, chDNA, chDNA, 1, crop.getNSlices(), 1, crop.getNFrames()) #run("Duplicate...", "title=tmp2 duplicate");

# === Band pass filtering
IJ.run(tmp1, "Gaussian Blur...", "sigma=%f stack" % sd1) #selectWindow("tmp1"); run("Gaussian Blur...", "sigma="+sd1+" stack");
IJ.run(tmp2, "Gaussian Blur...", "sigma=%f stack" % sd2) #selectWindow("tmp2"); run("Gaussian Blur...", "sigma="+sd2+" stack");
cropDNA_bPass = ImageCalculator().run("Subtract create 32-bit stack", tmp1, tmp2) #imageCalculator("Subtract create 32-bit stack", "tmp1","tmp2"); rename("cropDNA_bPass");
tmp1.close()
tmp2.close()

# === Create stack to be processed
# From https://stackoverflow.com/questions/48213759/combine-channels-in-imagej-jython
crop_channels = ij.plugin.ChannelSplitter.split(crop) # selectWindow("crop"); run("Split Channels");
if len(crop_channels)>=2:
    res_st = ij.plugin.RGBStackMerge().mergeHyperstacks([cropDNA_bPass, ]+[c for c in crop_channels], True) #run("Merge Channels...", "c1=cropDNA_bPass c2=C1-crop c3=C2-crop create")
else :
    IJ.log("NOT IMPLEMENTED ERROR")
    raise NotImplementedError

# === 3D drift correction (we are working with res_st as input image)
res_st.setRoi(int(winCrop/2)-int(winDrift/2), int(winCrop/2)-int(winDrift/2), winDrift, winDrift)
if run_DC:
    dc_st = correctDrift.run_cli(res_st, only_compute=False, multi_time_scale=False, verbose=False)
Exemplo n.º 11
0
def runOneFile(fullFilePath):
	global gFileType
	global gNumChannels
	global gAlignBatchVersion
	
	if not os.path.isfile(fullFilePath):
		bPrintLog('\nERROR: runOneFile() did not find file: ' + fullFilePath + '\n',0)
		return 0

	bPrintLog(time.strftime("%H:%M:%S") + ' starting runOneFile(): ' + fullFilePath, 1)
	
	enclosingPath = os.path.dirname(fullFilePath)
	head, tail = os.path.split(enclosingPath)
	enclosingPath += '/'
	
	#make output folders
	destFolder = enclosingPath + tail + '_channels/'
	if not os.path.isdir(destFolder):
		os.makedirs(destFolder)
	destMaxFolder = destFolder + 'max/'
	if not os.path.isdir(destMaxFolder):
		os.makedirs(destMaxFolder)

	if gDoAlign:
		destAlignmentFolder = destFolder + 'alignment/'
		if not os.path.isdir(destAlignmentFolder):
			os.makedirs(destAlignmentFolder)
			
	if gSave8bit:
		eightBitFolder = destFolder + 'channels8/'
		if not os.path.isdir(eightBitFolder):
			os.makedirs(eightBitFolder)
		eightBitMaxFolder = eightBitFolder + 'max/'
		if not os.path.isdir(eightBitMaxFolder):
			os.makedirs(eightBitMaxFolder)
	
	if gFileType=='tif':
		# open .tif image
		imp = Opener().openImage(fullFilePath)
	else:
		# open .lsm
		cmdStr = 'open=%s autoscale color_mode=Default view=Hyperstack stack_order=XYCZT' % (fullFilePath,)
		IJ.run('Bio-Formats Importer', cmdStr)
		lsmpath, lsmfilename = os.path.split(fullFilePath)
		lsWindow = lsmfilename
		imp = WindowManager.getImage(lsWindow)
		
	# get parameters of image
	(width, height, nChannels, nSlices, nFrames) = imp.getDimensions()
	bitDepth = imp.getBitDepth()
	infoStr = imp.getProperty("Info") #get all .tif tags
	if not infoStr:
		infoStr = ''
	infoStr += 'bAlignBatch_Version=' + str(gAlignBatchVersion) + '\n'
	infoStr += 'bAlignBatch_Time=' + time.strftime("%Y%m%d") + '_' + time.strftime("%H%M%S") + '\n'
		
	msgStr = 'w:' + str(width) + ' h:' + str(height) + ' slices:' + str(nSlices) \
				+ ' channels:' + str(nChannels) + ' frames:' + str(nFrames) + ' bitDepth:' + str(bitDepth)
	bPrintLog(msgStr, 1)
	
	path, filename = os.path.split(fullFilePath)
	shortName, fileExtension = os.path.splitext(filename)

	#
	# look for num channels in ScanImage infoStr
	if gGetNumChanFromScanImage:
		for line in infoStr.split('\n'):
			#scanimage.SI4.channelsSave = [1;2]
			scanimage4 = find(line, 'scanimage.SI4.channelsSave =') == 0
			#state.acq.numberOfChannelsSave=2
			scanimage3 = find(line, 'state.acq.numberOfChannelsSave=') == 0
			if scanimage3:
				#print 'line:', line
				equalIdx = find(line, '=')
				line2 = line[equalIdx+1:]
				if gGetNumChanFromScanImage:
					gNumChannels = int(line2)
					bPrintLog('over-riding gNumChannels with: ' + str(gNumChannels), 2)
			if scanimage4:
				#print '   we have a scanimage 4 file ... now i need to exptract the number of channel'
				#print 'line:', line
				equalIdx = find(line, '=')
				line2 = line[equalIdx+1:]
				for delim in ';[]':
					line2 = line2.replace(delim, ' ')
				if gGetNumChanFromScanImage:
					gNumChannels = len(line2.split())
					bPrintLog('over-riding gNumChannels with: ' + str(gNumChannels), 2)

	# show
	imp.show()
	# split channels if necc. and grab the original window names
	if gNumChannels == 1:
		origImpWinStr = imp.getTitle() #use this when only one channel
		origImpWin = WindowManager.getWindow(origImpWinStr) #returns java.awt.Window
	
	if gNumChannels == 2:
		winTitle = imp.getTitle()
		bPrintLog('Deinterleaving 2 channels...', 1)
		IJ.run('Deinterleave', 'how=2 keep') #makes ' #1' and ' #2', with ' #2' frontmost
		origCh1WinStr = winTitle + ' #1'
		origCh2WinStr = winTitle + ' #2'
		origCh1Imp = WindowManager.getImage(origCh1WinStr)
		origCh2Imp = WindowManager.getImage(origCh2WinStr)
		origCh1File = destFolder + shortName + '_ch1.tif'
		origCh2File = destFolder + shortName + '_ch2.tif'

	# work on a copy, mostly for alignment with cropping
	copy = Duplicator().run(imp)
	#copy.copyAttributes(imp) #don't copy attributes, it copies the name (which we do not want)
	copy.show()
	
	#
	# crop (on copy)
	if gDoCrop:
		bPrintLog('making cropping rectangle (left,top,width,height) ',1)
		bPrintLog(str(gCropLeft) + ' ' + str(gCropTop) + ' ' +str(gCropWidth) + ' ' +str(gCropHeight), 2)
		
		roi = Roi(gCropLeft, gCropTop, gCropWidth, gCropHeight) #left,top,width,height
		copy.setRoi(roi)
		
		time.sleep(0.5) # otherwise, crop SOMETIMES failes. WHAT THE F**K FIJI DEVELOPERS, REALLY, WHAT THE F**K
		
		#bPrintLog('cropping', 1)
		IJ.run('Crop')
		infoStr += 'bCropping=' + str(gCropLeft) + ',' + str(gCropTop) + ',' + str(gCropWidth) + ',' + str(gCropHeight) + '\n'
	
	#
	# remove calibration ( on original)
	if gRemoveCalibration:
		cal = imp.getCalibration()
		calCoeff = cal.getCoefficients()
		if calCoeff:
			msgStr = 'Calibration is y=a+bx' + ' a=' + str(calCoeff[0]) + ' b=' + str(calCoeff[1])
			bPrintLog(msgStr, 1)
			
			#remove calibration
			bPrintLog('\tRemoving Calibration', 2)
			imp.setCalibration(None)
				
			#without these, 8-bit conversion goes to all 0 !!! what the f**k !!!
			#bPrintLog('calling imp.resetStack() and imp.resetDisplayRange()', 2)
			imp.resetStack()
			imp.resetDisplayRange()

			#get and print out min/max
			origMin = StackStatistics(imp).min
			origMax = StackStatistics(imp).max
			msgStr = '\torig min=' + str(origMin) + ' max=' + str(origMax)
			bPrintLog(msgStr, 2)
			
			# 20150723, 'shift everybody over by linear calibration intercept calCoeff[0] - (magic number)
			if 1:
				# [1] was this
				#msgStr = 'Subtracting original min '+str(origMin) + ' from stack.'
				#bPrintLog(msgStr, 2)
				#subArgVal = 'value=%s stack' % (origMin,)
				#IJ.run('Subtract...', subArgVal)
				# [2] now this
				#msgStr = 'Adding calCoeff[0] '+str(calCoeff[0]) + ' from stack.'
				#bPrintLog(msgStr, 2)
				#addArgVal = 'value=%s stack' % (int(calCoeff[0]),)
				#IJ.run('Add...', addArgVal)
				# [3] subtract a magic number 2^15-2^7 = 32768 - 128
				magicNumber = gLinearShift #2^15 - 128
				msgStr = 'Subtracting a magic number (linear shift) '+str(magicNumber) + ' from stack.'
				bPrintLog(msgStr, 2)
				infoStr += 'bLinearShift=' + str(gLinearShift) + '\n'
				subArgVal = 'value=%s stack' % (gLinearShift,)
			IJ.run(imp, 'Subtract...', subArgVal)
				
			# 20150701, set any pixel <0 to 0
			if 0:
				ip = imp.getProcessor() # returns a reference
				pixels = ip.getPixels() # returns a reference
				msgStr = '\tSet all pixels <0 to 0. This was added 20150701 ...'
				bPrintLog(msgStr, 2)
				pixels = map(lambda x: 0 if x<0 else x, pixels)
				bPrintLog('\t\t... done', 2)
				
			#get and print out min/max
			newMin = StackStatistics(imp).min
			newMax = StackStatistics(imp).max
			msgStr = '\tnew min=' + str(newMin) + ' max=' + str(newMax)
			bPrintLog(msgStr, 2)
			
			#append calibration to info string
			infoStr += 'bCalibCoeff_a = ' + str(calCoeff[0]) + '\n'
			infoStr += 'bCalibCoeff_b = ' + str(calCoeff[1]) + '\n'
			infoStr += 'bNewMin = ' + str(newMin) + '\n'
			infoStr += 'bNewMax = ' + str(newMax) + '\n'

	#
	# set up
	if gNumChannels == 1:
		impWinStr = copy.getTitle() #use this when only one channel
		impWin = WindowManager.getWindow(impWinStr) #returns java.awt.Window
	
	if gNumChannels == 2:
		winTitle = copy.getTitle()
		bPrintLog('Deinterleaving 2 channels...', 1)
		IJ.run('Deinterleave', 'how=2 keep') #makes ' #1' and ' #2', with ' #2' frontmost
		ch1WinStr = winTitle + ' #1'
		ch2WinStr = winTitle + ' #2'
		ch1Imp = WindowManager.getImage(ch1WinStr)
		ch2Imp = WindowManager.getImage(ch2WinStr)
		ch1File = destFolder + shortName + '_ch1.tif'
		ch2File = destFolder + shortName + '_ch2.tif'
		
	#
	# alignment
	if gDoAlign and gNumChannels == 1 and copy.getNSlices()>1:
		infoStr += 'AlignOnChannel=1' + '\n'
		#snap to middle slice
		if gAlignOnMiddleSlice:
			middleSlice = int(math.floor(copy.getNSlices() / 2)) #int() is necc., python is f*****g picky
		else:
			middleSlice = gAlignOnThisSlice
		copy.setSlice(middleSlice)
		
		transformationFile = destAlignmentFolder + shortName + '.txt'
		
		bPrintLog('MultiStackReg aligning:' + impWinStr, 1)
		stackRegParams = 'stack_1=[%s] action_1=Align file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body] save' %(impWin,transformationFile)
		IJ.run('MultiStackReg', stackRegParams)
		infoStr += 'AlignOnSlice=' + str(middleSlice) + '\n'

		#20150723, we just aligned on a cropped copy, apply alignment to original imp
		origImpTitle = imp.getTitle()
		stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' %(origImpTitle,transformationFile)
		IJ.run('MultiStackReg', stackRegParams)		
		
	if gDoAlign and gNumChannels == 2 and ch1Imp.getNSlices()>1 and ch2Imp.getNSlices()>1:
		#apply to gAlignThisChannel
		alignThisWindow = ''
		applyAlignmentToThisWindow = ''
		if gAlignThisChannel == 1:
			infoStr += 'AlignOnChannel=1' + '\n'
			transformationFile = destAlignmentFolder + shortName + '_ch1.txt'
			alignThisWindow = ch1WinStr
			applyAlignmentToThisWindow = ch2WinStr
		else:
			infoStr += 'AlignOnChannel=2' + '\n'
			transformationFile = destAlignmentFolder + shortName + '_ch2.txt'
			alignThisWindow = ch2WinStr
			applyAlignmentToThisWindow = ch1WinStr
	
		alignThisImp = WindowManager.getImage(alignThisWindow)
		#snap to middle slice
		if gAlignOnMiddleSlice:
			middleSlice = int(math.floor(alignThisImp.getNSlices() / 2)) #int() is necc., python is f*****g picky
		else:
			middleSlice = gAlignOnThisSlice
		alignThisImp.setSlice(middleSlice)

		infoStr += 'bAlignOnSlice=' + str(middleSlice) + '\n'
		
		bPrintLog('MultiStackReg aligning:' + alignThisWindow, 1)
		stackRegParams = 'stack_1=[%s] action_1=Align file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body] save' %(alignThisWindow,transformationFile)
		IJ.run('MultiStackReg', stackRegParams)
	
		# 20150723, we just aligned on a copy, apply alignment to both channels of original
		# ch1
		bPrintLog('MultiStackReg applying alignment to:' + origCh1WinStr, 1)
		stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' %(origCh1WinStr,transformationFile)
		IJ.run('MultiStackReg', stackRegParams)		
		# ch2
		bPrintLog('MultiStackReg applying alignment to:' + origCh2WinStr, 1)
		stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' %(origCh2WinStr,transformationFile)
		IJ.run('MultiStackReg', stackRegParams)		
		
		#apply alignment to other window
		#bPrintLog('MultiStackReg applying alignment to:' + applyAlignmentToThisWindow, 1)
		#applyAlignThisImp = WindowManager.getImage(applyAlignmentToThisWindow)
		#stackRegParams = 'stack_1=[%s] action_1=[Load Transformation File] file_1=[%s] stack_2=None action_2=Ignore file_2=[] transformation=[Rigid Body]' %(applyAlignmentToThisWindow,transformationFile)
		#IJ.run('MultiStackReg', stackRegParams)		
	elif gDoAlign:
		bPrintLog('Skipping alignment, there may be only one slice?',3)
						
	#
	# save
	if gNumChannels == 1:
		imp.setProperty("Info", infoStr);
		impFile = destFolder + shortName + '.tif'
		#bPrintLog('Saving:' + impFile, 1)
		bSaveStack(imp, impFile)
		#max project
		bSaveZProject(imp, destMaxFolder, shortName)

	if gNumChannels == 2:
		#ch1
		origCh1Imp.setProperty("Info", infoStr);
		#bPrintLog('Saving:' + ch1File, 1)
		bSaveStack(origCh1Imp, ch1File)
		#max project
		bSaveZProject(origCh1Imp, destMaxFolder, shortName+'_ch1')

		#ch2
		origCh2Imp.setProperty("Info", infoStr);
		#bPrintLog('Saving:' + ch2File, 1)
		bSaveStack(origCh2Imp, ch2File)
 		#max project
		bSaveZProject(origCh2Imp, destMaxFolder, shortName+'_ch2')
		
 	#
	# post convert to 8-bit and save
	if gSave8bit:
		if bitDepth == 16:
			if gNumChannels == 1:
				bPrintLog('Converting to 8-bit:' + impWinStr, 1)
				IJ.selectWindow(impWinStr)
				#IJ.run('resetMinAndMax()')
				IJ.run("8-bit")
				impFile = eightBitFolder + shortName + '.tif'
				bPrintLog('Saving 8-bit:' + impFile, 2)
				bSaveStack(imp, impFile)
				#max project
				bSaveZProject(imp, eightBitMaxFolder, shortName)
				
			if gNumChannels == 2:
				#
				bPrintLog('Converting to 8-bit:' + origCh1WinStr, 1)
				IJ.selectWindow(origCh1WinStr)
				
				IJ.run("8-bit")
				impFile = eightBitFolder + shortName + '_ch1.tif'
				bPrintLog('Saving 8-bit:' + impFile, 2)
				bSaveStack(origCh1Imp, impFile)
				#max project
				bSaveZProject(origCh1Imp, eightBitMaxFolder, shortName+'_ch1')

				#
				bPrintLog('Converting to 8-bit:' + origCh2WinStr, 1)
				IJ.selectWindow(origCh2WinStr)
				#IJ.run('resetMinAndMax()')
				IJ.run("8-bit")
 				impFile = eightBitFolder + shortName + '_ch2.tif'
				bPrintLog('Saving 8-bit:' + impFile, 2)
				bSaveStack(origCh2Imp, impFile)
				#max project
				bSaveZProject(origCh2Imp, eightBitMaxFolder, shortName+'_ch2')
				
	#
	# close original window
	imp.changes = 0
	imp.close()
	#copy
	copy.changes = 0
	copy.close()

	#
	# close ch1/ch2
	if gNumChannels == 2:
		#original
		origCh1Imp.changes = 0
		origCh1Imp.close()
		origCh2Imp.changes = 0
		origCh2Imp.close()
		#copy
		ch1Imp.changes = 0
		ch1Imp.close()
		ch2Imp.changes = 0
		ch2Imp.close()

	bPrintLog(time.strftime("%H:%M:%S") + ' finished runOneFile(): ' + fullFilePath, 1)
def generate_background_rois(input_mask_imp,
                             params,
                             membrane_edges,
                             dilations=5,
                             threshold_method=None,
                             membrane_imp=None):
    """automatically identify background region based on auto-thresholded image, existing membrane edges and position of midpoint anchor"""
    if input_mask_imp is None and membrane_imp is not None:
        segmentation_imp = Duplicator().run(membrane_imp)
        # do thresholding using either previous method if threhsold_method is None or using (less conservative?) threshold method
        if (threshold_method is None
                or not (threshold_method in params.listThresholdMethods())):
            mask_imp = make_and_clean_binary(segmentation_imp,
                                             params.threshold_method)
        else:
            mask_imp = make_and_clean_binary(segmentation_imp,
                                             threshold_method)
        segmentation_imp.close()
    else:
        input_mask_imp.killRoi()
        mask_imp = Duplicator().run(input_mask_imp)

    rois = []
    IJ.setForegroundColor(0, 0, 0)
    roim = RoiManager(True)
    rt = ResultsTable()

    for fridx in range(mask_imp.getNFrames()):
        mask_imp.setT(fridx + 1)
        # add extra bit to binary mask from loaded membrane in case user refined edges...
        # flip midpoint anchor across the line joining the two extremes of the membrane,
        # and fill in the triangle made by this new point and those extremes
        poly = membrane_edges[fridx].getPolygon()
        l1 = (poly.xpoints[0], poly.ypoints[0])
        l2 = (poly.xpoints[-1], poly.ypoints[-1])
        M = (0.5 * (l1[0] + l2[0]), 0.5 * (l1[1] + l2[1]))
        Mp1 = (params.manual_anchor_midpoint[0][0] - M[0],
               params.manual_anchor_midpoint[0][1] - M[1])
        p2 = (M[0] - Mp1[0], M[1] - Mp1[1])
        new_poly_x = list(poly.xpoints)
        new_poly_x.append(p2[0])
        new_poly_y = list(poly.ypoints)
        new_poly_y.append(p2[1])
        mask_imp.setRoi(PolygonRoi(new_poly_x, new_poly_y, PolygonRoi.POLYGON))
        IJ.run(mask_imp, "Fill", "slice")
        mask_imp.killRoi()

        # now dilate the masked image and identify the unmasked region closest to the midpoint anchor
        ip = mask_imp.getProcessor()
        dilations = 5
        for d in range(dilations):
            ip.dilate()
        ip.invert()
        mask_imp.setProcessor(ip)
        mxsz = mask_imp.getWidth() * mask_imp.getHeight()
        pa = ParticleAnalyzer(
            ParticleAnalyzer.ADD_TO_MANAGER | ParticleAnalyzer.SHOW_PROGRESS,
            ParticleAnalyzer.CENTROID, rt, 0, mxsz)
        pa.setRoiManager(roim)
        pa.analyze(mask_imp)
        ds_to_anchor = [
            math.sqrt((x - params.manual_anchor_midpoint[0][0])**2 +
                      (y - params.manual_anchor_midpoint[0][1])**2)
            for x, y in zip(
                rt.getColumn(rt.getColumnIndex("X")).tolist(),
                rt.getColumn(rt.getColumnIndex("Y")).tolist())
        ]
        if len(ds_to_anchor) > 0:
            roi = roim.getRoi(ds_to_anchor.index(min(ds_to_anchor)))
            rois.append(roi)
        else:
            rois.append(None)
        roim.reset()
        rt.reset()
    roim.close()
    mask_imp.close()
    return rois
Exemplo n.º 13
0
def gfp_analysis(imp,
                 file_name,
                 output_folder,
                 gfp_channel_number=1,
                 dapi_channel_number=3,
                 red_channel_number=2,
                 threshold_method='Otsu',
                 do_manual_qc=False,
                 min_size_pix=1000):
    """perform analysis based on gfp intensity thresholding"""
    try:
        cal = imp.getCalibration()
        channel_imps = ChannelSplitter.split(imp)
        gfp_imp = channel_imps[gfp_channel_number - 1]
        gfp_imp.setTitle("GFP")
        threshold_imp = Duplicator().run(gfp_imp)
        threshold_imp.setTitle("GFP_threshold_imp")
        ecad_imp = channel_imps[red_channel_number - 1]
        ecad_imp.setTitle("E-cadherin")
        nuc_imp = channel_imps[dapi_channel_number - 1]
        nuclei_locations, full_nuclei_imp, ws_seeds_imp = get_nuclei_locations(
            nuc_imp, cal, distance_threshold_um=10, size_threshold_um2=100)
        ws_seeds_imp.changes = False
        ws_seeds_imp.close()
        full_nuclei_imp.hide()
        IJ.run(threshold_imp, "Make Binary",
               "method={} background=Dark calculate".format(threshold_method))
        IJ.run(threshold_imp, "Fill Holes", "")
        erode_count = 2
        for _ in range(erode_count):
            IJ.run(threshold_imp, "Erode", "")
        for _ in range(erode_count):
            IJ.run(threshold_imp, "Dilate", "")
        threshold_imp = keep_blobs_bigger_than(threshold_imp, min_size_pix)
        threshold_imp = my_kill_borders(threshold_imp)
        rois = generate_cell_rois(threshold_imp)
        threshold_imp.changes = False
        threshold_imp.close()
        rois = filter_cells_by_relative_nuclear_area(
            rois, full_nuclei_imp, relative_nuclear_area_threshold=0.75)
        if do_manual_qc:
            rois = perform_manual_qc(imp,
                                     rois,
                                     important_channel=gfp_channel_number)
        no_nuclei_centroids = [
            get_no_nuclei_in_cell(roi, nuclei_locations) for roi in rois
        ]
        no_enclosed_nuclei = [
            get_no_nuclei_fully_enclosed(roi, full_nuclei_imp) for roi in rois
        ]
        full_nuclei_imp.changes = False
        full_nuclei_imp.close()
        out_stats = generate_cell_shape_results(
            rois,
            gfp_imp,
            cal,
            file_name,
            no_nuclei_centroids=no_nuclei_centroids,
            no_enclosed_nuclei=no_enclosed_nuclei)
        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)
    except Exception as e:
        print("Ran into a problem analysing {}: {}. Skipping to next cell...".
              format(file_name, e.message))
        out_stats = []
        pass
    return out_stats
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);

	# 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");

	# 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);

	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");

	split_channels = mbfs.split_image_plus(imp, params);
	membrane_test_channel_imp = Duplicator().run(split_channels[0]);
	segmentation_channel_imp = split_channels[-1];

	# import edges
	imp.hide();
	membrane_edges = mbio.load_qcd_edges2(os.path.join(output_folder_old, "user_defined_edges.zip"));
	dummy_anchors = [params.manual_anchor_positions for _ in membrane_edges]
	membrane_edges, fixed_anchors = mbui.perform_user_qc(membrane_test_channel_imp, membrane_edges, membrane_edges, dummy_anchors, params);
	imp.show();
	rgbstack = ImageStack(imp.getWidth(), imp.getHeight());
	for tidx in range(imp.getNFrames()): 
		imp.setT(tidx+1);
		ip = imp.getProcessor();
		rgbip = ip.convertToRGB();
		rgbstack.addSlice(rgbip);
	rgbimp = ImagePlus(("RGB " + imp.getTitle()), rgbstack);
	imp.close();
	rgbimp.show();
	IJ.run("Colors...", "foreground=yellow background=white selection=yellow");
	for tidx in range(rgbimp.getNSlices()):
		rgbimp.setSlice(tidx+1);
		rgbimp.setRoi(membrane_edges[tidx]);
		IJ.run(rgbimp, "Draw", "slice");
	IJ.run("Colors...", "foreground=red background=white selection=yellow");
	for tidx in range(rgbimp.getNSlices()):
		rgbimp.setSlice(tidx+1);
		for anchor in params.manual_anchor_positions:
			rgbimp.setRoi(PointRoi(anchor[0], anchor[1]));
			IJ.run(rgbimp, "Draw", "slice");
	params.saveParametersToJson(os.path.join(params.output_path, "parameters used.json"));
	params.persistParameters();	
	rgbimp.changes = False;