示例#1
0
def convert32to16(fullFilePath):  #overwrite the file!!!
    if not os.path.isfile(fullFilePath):
        bPrintLog(
            '\nERROR: runOneFile() did not find file: ' + fullFilePath + '\n',
            0)
        return 0
    elif not fullFilePath.endswith('tif'):
        msg = fullFilePath + " is not a deconvoluted tif file"
        bPrintLog(msg, 2)
    else:
        bPrintLog(
            time.strftime("%H:%M:%S") +
            ' starting runOneFile()for overwrite: ' + fullFilePath, 1)

        #open and overwrite the deconvoluted file as 16 bit
        imp = Opener().openImage(fullFilePath)  #deconvoluted file
        if imp.getBitDepth() == 32:
            imp.show()
            msgStr = "Converting 32 to 16-bit..."
            bPrintLog(msgStr, 3)
            IJ.run("16-bit")

            msgStr = "Overwriting 32-bit with 16-bit File in" + fullFilePath
            bPrintLog(msgStr, 3)
            IJ.run(imp, "Save", "")  #save as replace without asking

        imp.close()
def convert32to16(fullFilePath): #overwrite the file!!!
	if not os.path.isfile(fullFilePath):
		bPrintLog('\nERROR: runOneFile() did not find file: ' + fullFilePath + '\n',0)
		return 0
	elif not fullFilePath.endswith('tif'):
		msg = fullFilePath +" is not a deconvoluted tif file"
		bPrintLog(msg,2)
	else:
		bPrintLog(time.strftime("%H:%M:%S") + ' starting runOneFile()for overwrite: ' + fullFilePath, 1)
	
		#open and overwrite the deconvoluted file as 16 bit
		imp = Opener().openImage(fullFilePath)	#deconvoluted file
		if imp.getBitDepth() == 32:
			imp.show()
			msgStr = "Converting 32 to 16-bit..."
			bPrintLog(msgStr,3)
			IJ.run("16-bit")
			
			msgStr = "Overwriting 32-bit with 16-bit File in" + fullFilePath
			bPrintLog(msgStr,3)
			IJ.run(imp,"Save","") #save as replace without asking
			
		imp.close()
class bImp:
	def __init__(self, filepath):
		"""
		Load an image or stack from filepath.

		Args:
			filepath (str): Full path to an image file. Can be .tif, .lsm, .czi, etc
		"""
		
		if not os.path.isfile(filepath):
			bPrintLog('ERROR: bImp() did not find file: ' + filepath,0)
			return 0

		self.filepath = filepath
		folderpath, filename = os.path.split(filepath)
		self.filename = filename
		self.enclosingPath = folderpath
		self.enclosingfolder = os.path.split(folderpath)[1]

		self.dateStr = ''
		self.timeStr = ''
		
		self.imp = None
		
		tmpBaseName, extension = os.path.splitext(filename)
		isZeiss = extension in ['.czi', '.lsm']
		self.islsm = extension == '.lsm'
		self.isczi = extension == '.czi'
		istif = extension == '.tif'
				
		if istif:
			# scanimage3 comes in with dimensions: [512, 512, 1, 52, 1]) = [width, height, numChannels, numSlices, numFrames]
			self.imp = Opener().openImage(filepath)
			self.imp.show()
			
		elif isZeiss:
			#open lsm using LOCI Bio-Formats
			options = ImporterOptions()
			#options.setColorMode(ImporterOptions.COLOR_MODE_GRAYSCALE)
			options.setId(filepath)
			imps = BF.openImagePlus(options)
			for imp in imps:
				self.imp = imp #WindowManager.getImage(self.windowname)
				imp.show()

		if not self.imp:
			bPrintLog('ERROR: bImp() was not able to open file: '+ filepath,0)
    				
		self.windowname = filename
		#self.imp = WindowManager.getImage(self.windowname)

		# numChannels is not correct for scanimage, corrected in readTiffHeader()
		(width, height, numChannels, numSlices, numFrames) = self.imp.getDimensions()

		self.width = width # pixelsPerLine
		self.height = height # linesPerFrame
		self.numChannels = numChannels
		self.numSlices = numSlices
		self.numFrames = numFrames

		self.infoStr = self.imp.getProperty("Info") #get all tags
				
		self.voxelx = 1
		self.voxely = 1
		self.voxelz = 1
		#self.numChannels = 1
		#self.bitsPerPixel = 8
		self.zoom = 1

		self.motorx = None
		self.motory = None
		self.motorz = None

		self.scanImageVersion = ''
		self.msPerLine = None
		self.dwellTime = None
		
		# read file headers (date, time, voxel size)
		if isZeiss:
			self.readZeissHeader(self.infoStr)
		elif istif:
			self.readTiffHeader(self.infoStr)

		self.updateInfoStr()
		
		self.channelWindows = []
		self.channelImp = []

		if self.numChannels == 1:
			self.channelWindows.append(self.windowname)
			self.channelImp.append(self.imp)
		else:
			self.deinterleave()
			
	def updateInfoStr(self):
		# Fill in infoStr with Map Manager tags		

		self.infoStr += 'Folder2MapManager=' + versionStr + '\n'

		self.infoStr += 'b_date=' + self.dateStr + '\n'
		self.infoStr += 'b_time=' + self.timeStr + '\n'
		
		# yevgeniya 20180314
		#if (self.numChannels > 3):
		#	self.numChannels = 3
		self.infoStr += 'b_numChannels=' + str(self.numChannels) + '\n'
		self.infoStr += 'b_pixelsPerline=' + str(self.width) + '\n'
		self.infoStr += 'b_linesPerFrame=' + str(self.height) + '\n'
		self.infoStr += 'b_numSlices=' + str(self.numSlices) + '\n'
		
		self.infoStr += 'b_voxelX=' + str(self.voxelx) + '\n'
		self.infoStr += 'b_voxelY=' + str(self.voxely) + '\n'
		self.infoStr += 'b_voxelZ=' + str(self.voxelz) + '\n'

		#self.infoStr += 'b_bitsPerPixel=' + str(self.bitsPerPixel) + '\n'

		self.infoStr += 'b_zoom=' + str(self.zoom) + '\n'
		
		self.infoStr += 'b_motorx=' + str(self.motorx) + '\n'
		self.infoStr += 'b_motory=' + str(self.motory) + '\n'
		self.infoStr += 'b_motorz=' + str(self.motorz) + '\n'

		self.infoStr += 'b_msPerLine=' + str(self.msPerLine) + '\n'

		self.infoStr += 'b_scanImageVersion=' + self.scanImageVersion + '\n'

	
	def readTiffHeader(self, infoStr):
		"""
		Read ScanImage 3/4 .tif headers
		"""
		logLevel = 3

		# splitting on '\r' for scanimage 3.x works
		# splitting on '\n' for scanimage 4.x works
		
		#we need to search whole infoStr to figure out scanimage 3 or 4.
		# we can't split info string because si3 uses \r and si4 uses \n
		
		infoStrDelim = '\n'
		if infoStr.find('scanimage.SI4') != -1:
			infoStrDelim = '\n'
			bPrintLog('Assuming SI4 infoStr to be delimited with backslash n', logLevel)
		elif infoStr.find('state.software.version') != -1:
			infoStrDelim = '\r'
			bPrintLog('Assuming SI3 infoStr to be delimited with backslash r', logLevel)
		else:
			bPrintLog('Splitting infoStr using backslah n', logLevel)

		# if we don't find zoom then voxel is an error (see end of function)
		foundZoom = False
		
		#for line in infoStr.split('\n'):
		for line in infoStr.split(infoStrDelim):
			#
			# ScanImage 4.x
			#
			
			# scanimage.SI4.versionMajor = 4.2
			if line.find('scanimage.SI4.versionMajor') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				self.scanImageVersion = rhs
			
			# scanimage.SI4.motorPosition = [-33936.5 -106316 -55308.5]
			if line.find('scanimage.SI4.motorPosition') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				rhs = rhs.replace('[','')
				rhs = rhs.replace(']','')
				floats = [float(x) for x in rhs.split()]
				self.motorx = floats[0]
				self.motory = floats[1]
				self.motorz = floats[2]

			# scanimage.SI4.channelsSave = [1;2]
			if line.find('scanimage.SI4.channelsSave') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				rhs = rhs.replace('[','')
				rhs = rhs.replace(']','')
				channels = [int(x) for x in rhs.split(';')]
				bPrintLog('reading scanimage.SI4.channelsSave inferred channels:' + str(channels), logLevel)
				self.numChannels = len(channels)

			# scanimage.SI4.scanZoomFactor = 5.9
			if line.find('scanimage.SI4.scanZoomFactor') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				self.zoom = float(rhs)
				foundZoom = True
				#self.voxelx = magic_scan_image_scale / self.zoom
				#self.voxely = magic_scan_image_scale / self.zoom

			# scanimage.SI4.triggerClockTimeFirst = '18-05-2015 11:58:43.788'
			if line.find('scanimage.SI4.triggerClockTimeFirst') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				rhs = rhs.replace("'","") # remove enclosing ' and '
				if rhs.startswith(' '): # if date string starts with space, remove it
					rhs = rhs[1:-1]
				datetime = rhs.split(' ')
				# 20170811, there is an extra f*****g space before datestr on the rhs
				# convert mm/dd/yyyy to yyyymmdd
				#print 'rhs:' + "'" + rhs + "'"
				#print 'datetime:', datetime
				datestr = bFixDate(datetime[0], logLevel)
				self.dateStr = datestr
				self.timeStr = datetime[1]
			
			#
			# ScanImage 3.x
			#
			
			# state.software.version = 3.8
			if line.find('state.software.version') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				self.scanImageVersion = rhs
			
			# state.acq.numberOfChannelsAcquire = 2
			if line.find('state.acq.numberOfChannelsAcquire') != -1:
				#print '\rDEBUG 12345'
				bPrintLog(line, logLevel)
				#print '\rDEBUG 12345'
				rhs = line.split('=')[1]
				self.numChannels = int(rhs)

			# state.acq.zoomFactor = 2.5
			if line.find('state.acq.zoomFactor') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				self.zoom = float(rhs)
				foundZoom = True
				# set (voxelx, voxely)
				#self.voxelx = magic_scan_image_scale / self.zoom
				#self.voxely = magic_scan_image_scale / self.zoom
				
			# state.acq.msPerLine = 2.32
			if line.find('state.acq.msPerLine') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				self.msPerLine = float(rhs)
			
			# state.acq.pixelTime = 3.2e-06
			if line.find('state.acq.pixelTime') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				self.dwellTime = float(rhs)

			# state.motor.absXPosition = -9894.4
			if line.find('state.motor.absXPosition') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				self.motorx = float(rhs)

			# state.motor.absYPosition = -18423.4
			if line.find('state.motor.absYPosition') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				self.motory = float(rhs)

			# state.motor.absZPosition = -23615.04
			if line.find('state.motor.absZPosition') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				self.motorz = float(rhs)

			# state.acq.zStepSize = 2
			if line.find('state.acq.zStepSize') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				self.voxelz = float(rhs)

			# state.internal.triggerTimeString = '10/2/2014 12:29:22.796'
			if line.find('state.internal.triggerTimeString') != -1:
				bPrintLog(line, logLevel)
				rhs = line.split('=')[1]
				rhs = rhs.replace("'","")
				if rhs.startswith(' '): # if date string starts with space, remove it
					rhs = rhs[1:-1]
				datetime = rhs.split(' ')
				# 20170811, there is an extra f*****g space before datestr on the rhs
				# convert mm/dd/yyyy to yyyymmdd
				#print 'rhs:' + "'" + rhs + "'"
				#print 'datetime:', datetime
				self.dateStr = bFixDate(datetime[0], logLevel)
				self.timeStr = bFixTime(datetime[1], logLevel)
				

			# state.acq.acqDelay = 0.000122
			# state.acq.bidirectionalScan = 0
			# state.acq.fillFraction = 0.706206896551724
			# state.acq.frameRate = 0.841864224137931
			# huganir lab keeps this off, image pixel intensities are 2^11 * samplesperpixel (e.g. binFactor?)
			# state.acq.binFactor = 16
			# state.internal.averageSamples = 1
			# the real image bit depth is usually inputBitDepth-1 (1 bit is not used?)
			# state.acq.inputBitDepth = 12

		if foundZoom:
			self.voxelx = magic_scan_image_scale / self.zoom * (1024 / self.width)
			self.voxely = magic_scan_image_scale / self.zoom * (1024 / self.height)
		else:
			bPrintLog('ERROR: Did not find zoom in SI header, voxel x/y will be wrong', logLevel)
			
	def readZeissHeader(self, infoStr):		
		# This is incredibly difficult to get working as (date, time, voxels) are in different obscure places in lsm and czi
		# Furthermore, just trying to read the raw ome xls is futile
		#
		# parsing ome xml as a string and searching it with regular expression(re) does not work
		# it is beyond the scope of my work to figure this out
		# the fact that it does not work and there is little documentaiton is a pretty big waste of time
		#
		# get and parse xml to find date/time
		#fi = self.imp.getOriginalFileInfo(); # returns a FileInfo object
		#omexml = fi.description #omexml is a string
		#omexml = omexml.encode('utf-8')
		#omexml = omexml.replaceAll("[^\\x20-\\x7e]", "") # see: https://stackoverflow.com/questions/2599919/java-parsing-xml-document-gives-content-not-allowed-in-prolog-error

		# (1) try and search the ome xml like a string, this gives errors
		#docsPattern = '<AcquisitionDate>.*</AcquisitionDate>'
		#searchresult = re.search(docsPattern, omexml)
		#print 'searchresult:', searchresult.group(0)
		
		# 2) treat the ome xml like any other xml (because it's xml, right?)
		# well this raises errors too
		#omexml has <AcquisitionDate>2016-08-17T15:21:50</AcquisitionDate>
		#import xml.etree.ElementTree
		#e = xml.etree.ElementTree.fromstring(omexml).getroot()		#print omexml
		#for atype in e.findall('AcquisitionDate'):
		#    print 'AcquisitionDate:', atype #.get('foobar')
		#
		#

		if self.islsm:
			# lsm have date hidden in omeMeta.getImageAcquisitionDate(0)
			# this is copied from code at: https://gist.github.com/ctrueden/6282856
			reader = ImageReader()
			omeMeta = MetadataTools.createOMEXMLMetadata() #omeMeta.getImageAcquisitionDate(0)
			reader.setMetadataStore(omeMeta)
			reader.setId(self.filepath)
			#seriesCount = reader.getSeriesCount()
			dateTimeStr = omeMeta.getImageAcquisitionDate(0) #2016-08-17T16:36:26
			reader.close()
			if dateTimeStr:
				self.dateStr, self.timeStr = dateTimeStr.toString().split('T')
				self.dateStr = bFixDate(self.dateStr)
				self.timeStr = bFixTime(self.timeStr)
				#bPrintLog('LSM date/time is: ' + self.dateStr + ' ' + self.timeStr, 3)
			else:
				bPrintLog('WARNING: did not get Zeiss date/time string')

			# lsm have voxels in infoStr
			for line in infoStr.split('\n'):
				#print line
				if line.find('VoxelSizeX') != -1:
					self.voxelx = float(line.split('=')[1])
				if line.find('VoxelSizeY') != -1:
					self.voxely = float(line.split('=')[1])
				if line.find('VoxelSizeZ') != -1:
					self.voxelz = float(line.split('=')[1])
				if line.find('SizeC') != -1:
					self.numChannels = int(line.split('=')[1])
				#if line.find('BitsPerPixel') and not line.startswith('Experiment') != -1: # 20170811, startswith is for czi
				#	self.bitsPerPixel = int(line.split('=')[1])
				if line.find('RecordingZoomX#1') != -1:
					self.zoom = int(line.split('=')[1])

		if self.isczi:
			# czi has date/time in infoStr (lsm does not)
			for line in infoStr.split('\n'):
				if line.find('CreationDate #1') != -1: # w.t.f. is #1 referring to?
					lhs, rhs = line.split('=')
					rhs = rhs.replace('  ', ' ')
					if rhs.startswith(' '):
						rhs = rhs[1:-1]
					#print "lhs: '" + lhs + "'" + "rhs: '" + rhs + "'"
					if rhs.find('T') != -1:
						self.dateStr, self.timeStr = rhs.split('T')
					else:
						self.dateStr, self.timeStr = rhs.split(' ')
					self.dateStr = bFixDate(self.dateStr)
					self.timeStr = bFixTime(self.timeStr)
					#bPrintLog('CZI date/time is: ' + self.dateStr + ' ' + self.timeStr, 3)
				# .czi
				# <Pixels BigEndian="false" DimensionOrder="XYCZT" ID="Pixels:0" Interleaved="false" PhysicalSizeX="0.20756645602494875" PhysicalSizeXUnit="µm" PhysicalSizeY="0.20756645602494875" PhysicalSizeYUnit="µm" PhysicalSizeZ="0.75" PhysicalSizeZUnit="µm" SignificantBits="8" SizeC="1" SizeT="1" SizeX="1024" SizeY="1024" SizeZ="50" Type="uint8">

			# czi have voxel in calibration
			self.voxelx = self.imp.getCalibration().pixelWidth; 
			self.voxely = self.imp.getCalibration().pixelHeight; 
			self.voxelz = self.imp.getCalibration().pixelDepth; 
			#bPrintLog('readZeissHeader() read czi scale as: ' + str(self.voxelx) + ' ' + str(self.voxely) + ' ' + str(self.voxelz), 3)

			# CLEARING self.infoStr for CZI ... it was WAY to big to parse in Map Manager
			self.infoStr = ''
			
	def printParams(self, loglevel=3): # careful, thefunction print() is already taken?
		bPrintLog('file:' + self.filepath, loglevel)
		bPrintLog("date:'" + self.dateStr + "' time:'" + self.timeStr + "'", loglevel)
		bPrintLog('channels:' + str(self.numChannels), loglevel)
		bPrintLog('zoom:' + str(self.zoom), loglevel)
		bPrintLog('pixels:' + str(self.width) + ',' + str(self.height)+ ',' + str(self.numSlices), loglevel)
		bPrintLog('voxels:' + str(self.voxelx) + ',' + str(self.voxely)+ ',' + str(self.voxelz), loglevel)

	def deinterleave(self):
		if self.numChannels == 1:
			bPrintLog('Warning: deinterleave() did not deinterleave with num channels 1', 0)
			return -1
		
		#IJ.run('Deinterleave', 'how=' + str(self.numChannels) +' keep') #makes ' #1' and ' #2', with ' #2' frontmost
		cmdStr = 'how=' + str(self.numChannels) + ' keep'
		IJ.run('Deinterleave', cmdStr) #makes ' #1' and ' #2', with ' #2' frontmost
		for i in range(self.numChannels):
			currenChannel = i + 1
			currentWindowName = self.windowname + ' #' + str(currenChannel)
			self.channelWindows.append(currentWindowName)
			
			currentImp = WindowManager.getImage(currentWindowName)
			if currentImp:
				self.channelImp.append(currentImp)
			else:
				bPrintLog('ERROR: deinterleave() did not find window names:' + currentWindowName, 0)
			
	def exportTifStack(self, destFolder=''):
		channelNumber = 1
		for imp in self.channelImp:
			if not destFolder:
				destFolder = os.path.join(self.enclosingPath, self.enclosingfolder + '_tif')
			if not os.path.isdir(destFolder):
				os.makedirs(destFolder)
			
			if not imp:
				bPrintLog("ERROR: exportTifStack() did not find an imp at channel number '" + str(channelNumber) + "'", 0)
				return -1
				
			self.updateInfoStr()
			imp.setProperty("Info", self.infoStr);

			saveFile = os.path.splitext(self.filename)[0] + '_ch' + str(channelNumber) + '.tif'
			savePath = os.path.join(destFolder, saveFile)

			# save
			fs = FileSaver(imp)
			bPrintLog('saveTifStack():' + savePath, 3)
			if imp.getNSlices()>1:
				fs.saveAsTiffStack(savePath)
			else:
				fs.saveAsTiff(savePath)

			channelNumber += 1

	def saveMaxProject(self, destFolder=''):
		channelNumber = 1
		for imp in self.channelImp:
			if not destFolder:
				destFolder = os.path.join(self.enclosingPath, self.enclosingfolder + '_tif', 'max')
			if not os.path.isdir(destFolder):
				os.makedirs(destFolder)

			# make max project
			zp = ZProjector(imp)
			zp.setMethod(ZProjector.MAX_METHOD)
			zp.doProjection()
			zimp = zp.getProjection()

			# save
			saveFile = 'max_' + os.path.splitext(self.filename)[0] + '_ch' + str(channelNumber) + '.tif'
			savePath = os.path.join(destFolder, saveFile)
			fs = FileSaver(zimp)
			bPrintLog('saveMaxProject():' + savePath, 3)
			fs.saveAsTiff(savePath)

			channelNumber += 1
			
	def closeAll(self):
		self.imp.close()
		for imp in self.channelImp:
			imp.close()
示例#4
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)
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)
示例#6
0
from org.python.core import codecs
codecs.setDefaultEncoding('utf-8')

import os
from java.io import File
from ij import ImageJ, ImagePlus
from ij.io import Opener
from net.imglib2.img import Img, ImgFactory
from net.imglib2.img.cell import CellImgFactory
from net.imglib2.img.display.imagej import ImageJFunctions
from net.imglib2.type.numeric.real import FloatType



gitDir  = os.environ['GIT_HOME']
relImg  = "/OSImageAnalysis/images"
# strImg  = gitDir + relImg + "/bridge.gif"
strImg  = gitDir + relImg + "/latex.tif"

fi = File(strImg)
imp = Opener().openImage( fi.getAbsolutePath() )
imp.show()

imgFactory = CellImgFactory(5 )
img1 = imgFactory.create( (20, 30, 40), FloatType() )
ImageJFunctions.show( img1 )
img2 = imgFactory.create( img1, img1.firstElement() )
ImageJFunctions.show( img2 )


def runOneFile(fullFilePath):

	global gNumChannels
	
	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 = ''
		
	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)

	#this is too much work for ScanImage4
	#try and guess channels if it is a scanimage file
	#scanImage3 = string.find(infoStr, 'scanimage') != -1
	#scanimage4 = find(infoStr, 'scanimage.SI4.channelSave = ')
	#print 'scanimage4:', scanimage4
	
	#
	# 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()

	infoStr += 'bAlignBatch6=' + time.strftime("%Y%m%d") + '\n'
	#
	# crop
	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
		imp.setRoi(roi)
		
		#time.sleep(1)
		
		#bPrintLog('cropping', 1)
		IJ.run('Crop')
		infoStr += 'cropping=' + str(gCropLeft) + ',' + str(gCropTop) + ',' + str(gCropWidth) + ',' + str(gCropHeight) + '\n'
	
	#
	# remove negative (<0) pixel values
	#ip = imp.getProcessor()
	#pixels = ip.getPixels()  # this returns a reference (not a copy)
	#for i in xrange(len(pixels)):  
	#	if pixels[i] < 0:  
	#		pixels[i] = 0
	# or this, for each pixel 'x', if  x<0 then 0 else x
	#pixels = map(lambda x: 0 if x<0 else x, pixels)
	
	#set our new values (without pixels <0) back into original (I hope this handles stacks and channels???)
	#ip.setPixels(pixels)
	
	#
	# remove calibration
	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)
				
			#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)
			
			#msgStr = 'adding calCoeff[0]='+str(calCoeff[0]) + ' to stack.'
			#bPrintLog(msgStr, 2)
			#subArgVal = 'value=%s stack' % (calCoeff[0],)
			#IJ.run('Add...', subArgVal)

			# 20150701, 'shift everybody over by linear calibration intercept calCoeff[0]'
			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 = 32768 - 128
				msgStr = 'Subtracting a magic number '+str(magicNumber) + ' from stack.'
				bPrintLog(msgStr, 2)
				subArgVal = 'value=%s stack' % (origMin,)
				IJ.run('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)
			
			#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()

			#append calibration to info string
			infoStr += 'calibCoeff_a = ' + str(calCoeff[0]) + '\n'
			infoStr += 'calibCoeff_b = ' + str(calCoeff[1]) + '\n'
			infoStr += 'origMin = ' + str(origMin) + '\n'
			infoStr += 'origMax = ' + str(origMax) + '\n'

	#
	# set up
	if gNumChannels == 1:
		impWinStr = imp.getTitle() #use this when only one channel
		impWin = WindowManager.getWindow(impWinStr) #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
		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 imp.getNSlices()>1:
		infoStr += 'AlignOnChannel=1' + '\n'
		#snap to middle slice
		if gAlignOnMiddleSlice:
			middleSlice = int(math.floor(imp.getNSlices() / 2)) #int() is necc., python is f*****g picky
		else:
			middleSlice = gAlignOnThisSlice
		imp.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'
	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 += 'AlignOnSlice=' + 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)
	
		#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
		ch1Imp.setProperty("Info", infoStr);
		#bPrintLog('Saving:' + ch1File, 1)
		bSaveStack(ch1Imp, ch1File)
		#max project
		bSaveZProject(ch1Imp, destMaxFolder, shortName+'_ch1')

		#ch2
		ch2Imp.setProperty("Info", infoStr);
		#bPrintLog('Saving:' + ch2File, 1)
		bSaveStack(ch2Imp, ch2File)
 		#max project
		bSaveZProject(ch2Imp, 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:' + ch1WinStr, 1)
				IJ.selectWindow(ch1WinStr)
				#IJ.run('resetMinAndMax()')
				
				#ch1Imp.resetStack()
				#ch1Imp.resetDisplayRange()
				
				IJ.run("8-bit")
				impFile = eightBitFolder + shortName + '_ch1.tif'
				bPrintLog('Saving 8-bit:' + impFile, 2)
				bSaveStack(ch1Imp, impFile)
				#max project
				bSaveZProject(ch1Imp, eightBitMaxFolder, shortName+'_ch1')

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

	#
	# close ch1/ch2
	if 1 and gNumChannels == 2:
		ch1Imp.changes = 0
		ch1Imp.close()
		ch2Imp.changes = 0
		ch2Imp.close()

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