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
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
Exemplo n.º 3
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
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;
Exemplo n.º 5
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.º 6
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)
Exemplo n.º 7
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