def processImage(self, imgdata): stackedname = os.path.join(self.params['rundir'], imgdata['filename']+"power.jpg") if os.path.isfile(stackedname) and apFile.fileSize(stackedname) > 100: return ### make the power spectra powerspectra = imagefun.power(imgdata['image'], mask_radius=1.0, thresh=4) binpowerspectra = imagefun.bin2(powerspectra, self.params['bin']) del powerspectra if self.params['hp'] is True: binpowerspectra = apImage.fermiHighPassFilter(binpowerspectra, apix=4.0, radius=2000.0) binpowerspectra = apImage.normStdevMed(binpowerspectra, size=5) binpowerspectra = apImage.pixelLimitFilter(binpowerspectra, pixlimit=4) binpowerspectra = apImage.normRange(binpowerspectra) ### filter the image imagedata = imagefun.bin2(imgdata['image'], self.params['bin']) del imgdata['image'] imagedata = apImage.normStdevMed(imagedata, size=5) imagedata = apImage.pixelLimitFilter(imagedata, pixlimit=2) imagedata = apImage.normRange(imagedata) ### write to file stacked = numpy.hstack([imagedata, binpowerspectra]) del imagedata, binpowerspectra apImage.arrayToJpeg(stacked, stackedname)
def diffOfGauss(imgarray0, pixrad, k=1.2): """ given bin, apix and diam of particle perform a difference of Gaussian about the size of that particle k := sloppiness coefficient """ # find xi (E) function of k Ek = math.sqrt((k**2 - 1.0) / (2.0 * k**2 * math.log(k))) # convert pixrad to sigma1 sigma1 = Ek * pixrad # find sigmaprime sigmaprime = sigma1 * math.sqrt(k * k - 1.0) #determine pixel range pixrange = pixrad * (k - 1.0) / math.sqrt(k) apDisplay.printMsg("filtering particles of size " + str(pixrad) + " +/- " + str(round(pixrange, 1)) + " pixels") #do the blurring print sigma1, sigmaprime imgarray1 = ndimage.gaussian_filter(imgarray0, sigma=sigma1, mode='wrap') imgarray2 = ndimage.gaussian_filter(imgarray1, sigma=sigmaprime, mode='wrap') #apImage.arrayToJpeg(imgarray1, "imgarray1.jpg") #apImage.arrayToJpeg(imgarray2, "imgarray2.jpg") dogmap = imgarray1 - imgarray2 apImage.arrayToJpeg(dogmap, "dogmap.jpg") return dogmap
def processImage(self, imgdata): stackedname = os.path.join(self.params['rundir'], imgdata['filename'] + "power.jpg") if os.path.isfile(stackedname) and apFile.fileSize(stackedname) > 100: return ### make the power spectra powerspectra = imagefun.power(imgdata['image'], mask_radius=1.0, thresh=4) binpowerspectra = imagefun.bin2(powerspectra, self.params['bin']) del powerspectra if self.params['hp'] is True: binpowerspectra = apImage.fermiHighPassFilter(binpowerspectra, apix=4.0, radius=2000.0) binpowerspectra = apImage.normStdevMed(binpowerspectra, size=5) binpowerspectra = apImage.pixelLimitFilter(binpowerspectra, pixlimit=4) binpowerspectra = apImage.normRange(binpowerspectra) ### filter the image imagedata = imagefun.bin2(imgdata['image'], self.params['bin']) del imgdata['image'] imagedata = apImage.normStdevMed(imagedata, size=5) imagedata = apImage.pixelLimitFilter(imagedata, pixlimit=2) imagedata = apImage.normRange(imagedata) ### write to file stacked = numpy.hstack([imagedata, binpowerspectra]) del imagedata, binpowerspectra apImage.arrayToJpeg(stacked, stackedname)
def outputTestImage(array,name,description,testlog): width=25 if testlog[0]: # appionLoop current directory is params['rundir'] testpath = os.path.abspath("./tests") jpgname=os.path.join(testpath,"%02d%s.jpg" %(testlog[1],name)) space=(width-len(jpgname))*' ' testlog[2]+= "%s:%s%s\n" % (jpgname,space,description) testlog[1] += 1 else: return testlog apImage.arrayToJpeg(array,jpgname) return testlog
def outputTestImage(array, name, description, testlog): width = 25 if testlog[0]: # appionLoop current directory is params['rundir'] testpath = os.path.abspath("./tests") jpgname = os.path.join(testpath, "%02d%s.jpg" % (testlog[1], name)) space = (width - len(jpgname)) * ' ' testlog[2] += "%s:%s%s\n" % (jpgname, space, description) testlog[1] += 1 else: return testlog apImage.arrayToJpeg(array, jpgname) return testlog
def diffOfGauss(imgarray0, pixrad, k=1.2): """ given bin, apix and diam of particle perform a difference of Gaussian about the size of that particle k := sloppiness coefficient """ # find xi (E) function of k Ek = math.sqrt((k ** 2 - 1.0) / (2.0 * k ** 2 * math.log(k))) # convert pixrad to sigma1 sigma1 = Ek * pixrad # find sigmaprime sigmaprime = sigma1 * math.sqrt(k * k - 1.0) # determine pixel range pixrange = pixrad * (k - 1.0) / math.sqrt(k) apDisplay.printMsg("filtering particles of size " + str(pixrad) + " +/- " + str(round(pixrange, 1)) + " pixels") # do the blurring print sigma1, sigmaprime imgarray1 = ndimage.gaussian_filter(imgarray0, sigma=sigma1, mode="wrap") imgarray2 = ndimage.gaussian_filter(imgarray1, sigma=sigmaprime, mode="wrap") # apImage.arrayToJpeg(imgarray1, "imgarray1.jpg") # apImage.arrayToJpeg(imgarray2, "imgarray2.jpg") dogmap = imgarray1 - imgarray2 apImage.arrayToJpeg(dogmap, "dogmap.jpg") return dogmap
def processImage(self, imgdata): """ time ./ctffind3.exe << eof micrograph.mrc montage.pow 2.0, 200.0, 0.07, 60000, 7.0, 2 #! CS[mm], HT[kV], AmpCnst, XMAG, DStep[um], PAve 128, 200.0, 8.0, 5000.0, 40000.0, 5000.0 #! Box, ResMin[A], ResMax[A], dFMin[A], dFMax[A], FStep eof CARD 1: Input file name for image CARD 2: Output file name to check result CARD 3: CS[mm], HT[kV], AmpCnst, XMAG, DStep[um],PAve CARD 4: Box, ResMin[A], ResMax[A], dFMin[A], dFMax[A], FStep, dAst[A] CTFTILT also asks for TiltA[deg], TiltR[deg] at CARD4 The output image file to check the result of the fitting shows the filtered average power spectrum of the input image in one half, and the fitted CTF (squared) in the other half. The two halves should agree very well for a successful fit. CS: Spherical aberration coefficient of the objective in mm HT: Electron beam voltage in kV AmpCnst: Amount of amplitude contrast (fraction). For ice images 0.07, for negative stain about 0.15. XMAG: Magnification of original image DStep: Pixel size on scanner in microns, or apix*mag/10000 PAve: Pixel averaging (PAve x PAve) for input image Box: Tile size. The program divides the image into square tiles and calculates the average power spectrum. Tiles with a significantly higher or lower variance are excluded; these are parts of the image which are unlikely to contain useful information (beam edge, film number etc). IMPORTANT: Box must have a even pixel dimensions. ResMin: Low resolution end of data to be fitted. ResMaX: High resolution end of data to be fitted. dFMin: Starting defocus value for grid search in Angstrom. Positive values represent an underfocus. The program performs a systematic grid search of defocus values and astigmatism before fitting a CTF to machine precision. dFMax: End defocus value for grid search in Angstrom. FStep: Step width for grid search in Angstrom. dAst: An additional parameter, dAst, was added to CARD 4 to restrain the amount of astigmatism in the CTF fit. This makes the fitting procedure more robust, especially in cases where the Thon rings are not easily visible. TiltA: guessed tilt angle TiltR: angular range for initial coarse search """ #get Defocus in Angstroms self.ctfvalues = {} nominal = abs(imgdata['scope']['defocus'] * -1.0e10) ctfvalue = ctfdb.getBestCtfByResolution(imgdata) if ctfvalue is not None: bestdef = abs(ctfvalue['defocus1'] + ctfvalue['defocus2']) / 2.0 * 1.0e10 else: bestdef = nominal if ctfvalue is not None and self.params['bestdb'] is True: bestampcontrast = ctfvalue['amplitude_contrast'] beststigdiff = abs(ctfvalue['defocus1'] - ctfvalue['defocus2']) * 1e10 else: bestampcontrast = self.params['amp' + self.params['medium']] beststigdiff = self.params['dast'] # dstep is the physical detector pixel size dstep = None if 'camera' in imgdata and imgdata['camera'] and imgdata['camera'][ 'pixel size']: dstep = imgdata['camera']['pixel size']['x'] if dstep is None: dstep = apDatabase.getPixelSize( imgdata) * imgdata['scope']['magnification'] / 10000.0 dstep /= 1e6 dstep = float(dstep) mpixelsize = apDatabase.getPixelSize(imgdata) * 1e-10 xmag = dstep / mpixelsize apDisplay.printMsg("Xmag=%d, dstep=%.2e, mpix=%.2e" % (xmag, dstep, mpixelsize)) inputparams = { 'orig': os.path.join(imgdata['session']['image path'], imgdata['filename'] + ".mrc"), 'input': apDisplay.short(imgdata['filename']) + ".mrc", 'output': apDisplay.short(imgdata['filename']) + "-pow.mrc", 'cs': self.params['cs'], 'kv': imgdata['scope']['high tension'] / 1000.0, 'ampcnst': bestampcontrast, 'xmag': xmag, 'dstep': dstep * 1e6, 'pixavg': self.params['bin'], 'box': self.params['fieldsize'], 'resmin': self.params['resmin'], 'resmax': self.params['resmax'], 'defstep': self.params['defstep'], #round(defocus/32.0, 1), 'dast': beststigdiff, } defrange = self.params['defstep'] * self.params[ 'numstep'] ## do 25 steps in either direction inputparams['defmin'] = round(bestdef - defrange, 1) #in meters if inputparams['defmin'] < 0: apDisplay.printWarning("Defocus minimum is less than zero") inputparams['defmin'] = inputparams['defstep'] inputparams['defmax'] = round(bestdef + defrange, 1) #in meters apDisplay.printColor( "Defocus search range: %d A to %d A (%.2f to %.2f um)" % (inputparams['defmin'], inputparams['defmax'], inputparams['defmin'] * 1e-4, inputparams['defmax'] * 1e-4), "cyan") ### create local link to image if not os.path.exists(inputparams['input']): cmd = "ln -s " + inputparams['orig'] + " " + inputparams[ 'input'] + "\n" proc = subprocess.Popen(cmd, shell=True) proc.wait() ### make standard input for ctf estimation line1cmd = inputparams['input'] + "\n" line2cmd = inputparams['output'] + "\n" line3cmd = (str(inputparams['cs']) + "," + str(inputparams['kv']) + "," + str(inputparams['ampcnst']) + "," + str(inputparams['xmag']) + "," + str(inputparams['dstep']) + "," + str(inputparams['pixavg']) + "\n") line4cmd = (str(inputparams['box']) + "," + str(inputparams['resmin']) + "," + str(inputparams['resmax']) + "," + str(inputparams['defmin']) + "," + str(inputparams['defmax']) + "," + str(inputparams['defstep']) + "," + str(inputparams['dast'])) ### additional ctftilt parameters if self.params['ctftilt'] is True: tiltang = apDatabase.getTiltAngleDeg(imgdata) line4cmd += ("," + str(tiltang) + ",10") line4cmd += "\n" if os.path.isfile(inputparams['output']): # program crashes if this file exists apFile.removeFile(inputparams['output']) t0 = time.time() apDisplay.printMsg("running ctf estimation at " + time.asctime()) ctfproglog = os.path.join( self.logdir, os.path.splitext(imgdata['filename'])[0] + "-ctfprog.log") logf = open(ctfproglog, "w") ctfprogproc = subprocess.Popen(self.ctfprgmexe, shell=True, stdin=subprocess.PIPE, stdout=logf) apDisplay.printColor(self.ctfprgmexe, "magenta") apDisplay.printColor(line1cmd.strip(), "magenta") apDisplay.printColor(line2cmd.strip(), "magenta") apDisplay.printColor(line3cmd.strip(), "magenta") apDisplay.printColor(line4cmd.strip(), "magenta") ctfprogproc.stdin.write(line1cmd) ctfprogproc.stdin.write(line2cmd) ctfprogproc.stdin.write(line3cmd) ctfprogproc.stdin.write(line4cmd) ctfprogproc.communicate() logf.close() apDisplay.printMsg("ctf estimation completed in " + apDisplay.timeString(time.time() - t0)) #apFile.removeFile(inputparams['input']) ### parse ctf estimation output self.ctfvalues = {} logf = open(ctfproglog, "r") ## ctffind & ctftilt have diff # values numvals = 6 if self.params['ctftilt'] is True: numvals = 8 for line in logf: sline = line.strip() if sline[-12:] == "Final Values": #print sline if '**********' in sline: sline = re.sub('**********', ' **********', sline) bits = sline.split() if len(bits) != numvals: apDisplay.printError("wrong number of values in " + str(bits)) for i, bit in enumerate(bits[0:(numvals - 2)]): bits[i] = float(bit) self.ctfvalues = { 'defocus1': float(bits[0]) * 1e-10, 'defocus2': float(bits[1]) * 1e-10, # WARNING: this is the negative of the direct result 'angle_astigmatism': float(bits[2]), 'amplitude_contrast': inputparams['ampcnst'], 'cross_correlation': float(bits[numvals - 3]), 'nominal': nominal * 1e-10, 'defocusinit': bestdef * 1e-10, 'cs': self.params['cs'], 'volts': imgdata['scope']['high tension'], 'confidence': float(bits[numvals - 3]), 'confidence_d': round(math.sqrt(abs(float(bits[numvals - 3]))), 5) } if self.params['ctftilt'] is True: self.ctfvalues['tilt_axis_angle'] = float(bits[3]) self.ctfvalues['tilt_angle'] = float(bits[4]) ### write to log file f = open("ctfvalues.log", "a") f.write("=== " + imgdata['filename'] + " ===\n") line1 = ("nominal=%.1e, bestdef=%.1e," % (self.ctfvalues['nominal'], self.ctfvalues['defocusinit'])) if self.params['ctftilt'] is True: self.ctfvalues['origtiltang'] = tiltang line1 += " tilt=%.1f," % tiltang apDisplay.printMsg(line1) f.write(line1) line2 = ( "def_1=%.1e, def_2=%.1e, astig_angle=%.1f, cross_corr=%.3f,\n" % (self.ctfvalues['defocus1'], self.ctfvalues['defocus2'], self.ctfvalues['angle_astigmatism'], self.ctfvalues['cross_correlation'])) if self.params['ctftilt'] is True: line2 += ("tilt_angle=%.1f, tilt_axis_angle=%.1f,\n" % (self.ctfvalues['tilt_angle'], self.ctfvalues['tilt_axis_angle'])) apDisplay.printMsg(line2) f.write(line2) f.close() #convert powerspectra to JPEG outputjpgbase = os.path.basename( os.path.splitext(inputparams['output'])[0] + ".jpg") self.lastjpg = outputjpgbase outputjpg = os.path.join(self.powerspecdir, self.lastjpg) powspec = apImage.mrcToArray(inputparams['output']) apImage.arrayToJpeg(powspec, outputjpg) shutil.move(inputparams['output'], os.path.join(self.powerspecdir, inputparams['output'])) self.ctfvalues['graph1'] = outputjpg #apFile.removeFile(inputparams['input']) return
def processImage(self, imgdata): """ time ./ctffind3.exe << eof micrograph.mrc montage.pow 2.0, 200.0, 0.07, 60000, 7.0, 2 #! CS[mm], HT[kV], AmpCnst, XMAG, DStep[um], PAve 128, 200.0, 8.0, 5000.0, 40000.0, 5000.0 #! Box, ResMin[A], ResMax[A], dFMin[A], dFMax[A], FStep eof CARD 1: Input file name for image CARD 2: Output file name to check result CARD 3: CS[mm], HT[kV], AmpCnst, XMAG, DStep[um],PAve CARD 4: Box, ResMin[A], ResMax[A], dFMin[A], dFMax[A], FStep, dAst[A] CTFTILT also asks for TiltA[deg], TiltR[deg] at CARD4 The output image file to check the result of the fitting shows the filtered average power spectrum of the input image in one half, and the fitted CTF (squared) in the other half. The two halves should agree very well for a successful fit. CS: Spherical aberration coefficient of the objective in mm HT: Electron beam voltage in kV AmpCnst: Amount of amplitude contrast (fraction). For ice images 0.07, for negative stain about 0.15. XMAG: Magnification of original image DStep: Pixel size on scanner in microns, or apix*mag/10000 PAve: Pixel averaging (PAve x PAve) for input image Box: Tile size. The program divides the image into square tiles and calculates the average power spectrum. Tiles with a significantly higher or lower variance are excluded; these are parts of the image which are unlikely to contain useful information (beam edge, film number etc). IMPORTANT: Box must have a even pixel dimensions. ResMin: Low resolution end of data to be fitted. ResMaX: High resolution end of data to be fitted. dFMin: Starting defocus value for grid search in Angstrom. Positive values represent an underfocus. The program performs a systematic grid search of defocus values and astigmatism before fitting a CTF to machine precision. dFMax: End defocus value for grid search in Angstrom. FStep: Step width for grid search in Angstrom. dAst: An additional parameter, dAst, was added to CARD 4 to restrain the amount of astigmatism in the CTF fit. This makes the fitting procedure more robust, especially in cases where the Thon rings are not easily visible. TiltA: guessed tilt angle TiltR: angular range for initial coarse search """ #get Defocus in Angstroms self.ctfvalues = {} if self.params['nominal'] is not None: nominal = abs(self.params['nominal']*1e4) else: nominal = abs(imgdata['scope']['defocus']*-1.0e10) ctfvalue = ctfdb.getBestCtfByResolution(imgdata) if ctfvalue is not None: """ ## CTFFIND V3.5 (7-March-2012) prefers the smaller of the two values for astigmatic images I found that say you have an image with 1.1um and 1.5um defocus astigmatism. If you give CTFFIND the average value of 1.3um for the defocus and 0.4um astig (dast) then it will try to fit 1.3um and 1.8um, so you need to give it the minimum value (1.1um) for it to fit 1.1um and 1.5um. """ bestdef = min(ctfvalue['defocus1'],ctfvalue['defocus2'])*1.0e10 else: bestdef = nominal if ctfvalue is not None and self.params['bestdb'] is True: bestampcontrast = round(ctfvalue['amplitude_contrast'],3) beststigdiff = round(abs(ctfvalue['defocus1'] - ctfvalue['defocus2'])*1e10,1) else: bestampcontrast = self.params['amp'+self.params['medium']] beststigdiff = self.params['dast'] if ctfvalue is not None and self.params['bestdb'] is True: ### set res max from resolution_80_percent gmean = (ctfvalue['resolution_80_percent']*ctfvalue['resolution_50_percent']*self.params['resmax'])**(1/3.) if gmean < self.params['resmin']: # replace only if valid Issue #3291, #3547 self.params['resmax'] = round(gmean,2) apDisplay.printColor("Setting resmax to the geometric mean of resolution values", "purple") # dstep is the physical detector pixel size dstep = None if 'camera' in imgdata and imgdata['camera'] and imgdata['camera']['pixel size']: dstep = imgdata['camera']['pixel size']['x'] if dstep is None: dstep = apDatabase.getPixelSize(imgdata)*imgdata['scope']['magnification']/10000.0 dstep /=1e6 dstep = float(dstep) mpixelsize = apDatabase.getPixelSize(imgdata)*1e-10 if self.params['apix_man'] is not None: mpixelsize = self.params['apix_man']*1e-10 xmag = dstep / mpixelsize apDisplay.printMsg("Xmag=%d, dstep=%.2e, mpix=%.2e"%(xmag, dstep, mpixelsize)) inputparams = { 'orig': os.path.join(imgdata['session']['image path'], imgdata['filename']+".mrc"), 'input': apDisplay.short(imgdata['filename'])+".mrc", 'output': apDisplay.short(imgdata['filename'])+"-pow.mrc", 'cs': self.params['cs'], 'kv': imgdata['scope']['high tension']/1000.0, 'ampcnst': bestampcontrast, 'xmag': xmag, 'dstep': dstep*1e6, 'pixavg': self.params['bin'], 'box': self.params['fieldsize'], 'resmin': self.params['resmin'], 'resmax': self.params['resmax'], 'defstep': self.params['defstep'], #round(defocus/32.0, 1), 'dast': beststigdiff, } defrange = self.params['defstep'] * self.params['numstep'] ## do 25 steps in either direction inputparams['defmin']= round(bestdef-defrange, 1) #in meters if inputparams['defmin'] < 0: apDisplay.printWarning("Defocus minimum is less than zero") inputparams['defmin'] = inputparams['defstep'] inputparams['defmax']= round(bestdef+defrange, 1) #in meters apDisplay.printColor("Defocus search range: %d A to %d A (%.2f to %.2f um)" %(inputparams['defmin'], inputparams['defmax'], inputparams['defmin']*1e-4, inputparams['defmax']*1e-4), "cyan") ### secondary lock check right before it starts on the real part if self.params['parallel'] and os.path.isfile(apDisplay.short(imgdata['filename'])+".mrc"): # This is a secondary image lock check, checking the first output of the process. # It alone is not good enough apDisplay.printWarning('Some other parallel process is working on the same image. Skipping') return ### create local link to image if not os.path.exists(inputparams['input']): os.symlink(inputparams['orig'], inputparams['input']) ### make standard input for ctf estimation line1cmd = inputparams['input']+"\n" line2cmd = inputparams['output']+"\n" line3cmd = ( str(inputparams['cs'])+"," + str(inputparams['kv'])+"," + str(inputparams['ampcnst'])+"," + str(inputparams['xmag'])+"," + str(inputparams['dstep'])+"," + str(inputparams['pixavg'])+"\n") line4cmd = ( str(inputparams['box'])+"," + str(inputparams['resmin'])+"," + str(inputparams['resmax'])+"," + str(inputparams['defmin'])+"," + str(inputparams['defmax'])+"," + str(inputparams['defstep'])+"," + str(inputparams['dast'])) ### additional ctftilt parameters if self.params['ctftilt'] is True: tiltang = apDatabase.getTiltAngleDeg(imgdata) line4cmd += (","+str(tiltang)+",10") line4cmd += "\n" if os.path.isfile(inputparams['output']): # program crashes if this file exists apFile.removeFile(inputparams['output']) t0 = time.time() apDisplay.printMsg("running ctf estimation at "+time.asctime()) ctfproglog = os.path.join(self.logdir, os.path.splitext(imgdata['filename'])[0]+"-ctfprog.log") logf = open(ctfproglog, "w") ctfprogproc = subprocess.Popen(self.ctfprgmexe, shell=True, stdin=subprocess.PIPE, stdout=logf) apDisplay.printColor(self.ctfprgmexe, "magenta") apDisplay.printColor(line1cmd.strip(),"magenta") apDisplay.printColor(line2cmd.strip(),"magenta") apDisplay.printColor(line3cmd.strip(),"magenta") apDisplay.printColor(line4cmd.strip(),"magenta") ctfprogproc.stdin.write(line1cmd) ctfprogproc.stdin.write(line2cmd) ctfprogproc.stdin.write(line3cmd) ctfprogproc.stdin.write(line4cmd) ctfprogproc.communicate() logf.close() apDisplay.printMsg("ctf estimation completed in "+apDisplay.timeString(time.time()-t0)) #apFile.removeFile(inputparams['input']) ### parse ctf estimation output self.ctfvalues = {} logf = open(ctfproglog, "r") ## ctffind & ctftilt have diff # values numvals = 6 if self.params['ctftilt'] is True: numvals=8 for line in logf: sline = line.strip() if sline[-12:] == "Final Values": #print sline if '**********' in sline: sline = re.sub('**********', ' **********', sline) bits = sline.split() if len(bits) != numvals: apDisplay.printError("wrong number of values in "+str(bits)) for i,bit in enumerate(bits[0:(numvals-2)]): bits[i] = float(bit) self.ctfvalues = { 'defocus1': float(bits[0])*1e-10, 'defocus2': float(bits[1])*1e-10, # WARNING: this is the negative of the direct result 'angle_astigmatism': float(bits[2]), 'amplitude_contrast': inputparams['ampcnst'], 'cross_correlation': float(bits[numvals-3]), 'nominal': nominal*1e-10, 'defocusinit': bestdef*1e-10, 'cs': self.params['cs'], 'volts': imgdata['scope']['high tension'], 'confidence': float(bits[numvals-3]), 'confidence_d': round(math.sqrt(abs(float(bits[numvals-3]))), 5) } if self.params['ctftilt'] is True: self.ctfvalues['tilt_axis_angle']=float(bits[3]) self.ctfvalues['tilt_angle']=float(bits[4]) ### write to log file f = open("ctfvalues.log", "a") f.write("=== "+imgdata['filename']+" ===\n") if not self.ctfvalues: nominaldf = imgdata['scope']['defocus'] else: nominaldf = self.ctfvalues['nominal'] line1 = ("nominal=%.1e, bestdef=%.1e," % ( nominaldf, self.ctfvalues['defocusinit'])) if self.params['ctftilt'] is True: self.ctfvalues['origtiltang'] = tiltang line1+=" tilt=%.1f,"%tiltang apDisplay.printMsg(line1) f.write(line1) line2 = ("def_1=%.1e, def_2=%.1e, astig_angle=%.1f, cross_corr=%.3f,\n" % ( self.ctfvalues['defocus1'], self.ctfvalues['defocus2'], self.ctfvalues['angle_astigmatism'], self.ctfvalues['cross_correlation'] )) if self.params['ctftilt'] is True: line2+= ("tilt_angle=%.1f, tilt_axis_angle=%.1f,\n" % (self.ctfvalues['tilt_angle'], self.ctfvalues['tilt_axis_angle'])) apDisplay.printMsg(line2) f.write(line2) f.close() #convert powerspectra to JPEG outputjpgbase = os.path.basename(os.path.splitext(inputparams['output'])[0]+".jpg") self.lastjpg = outputjpgbase outputjpg = os.path.join(self.powerspecdir, self.lastjpg) powspec = apImage.mrcToArray(inputparams['output']) apImage.arrayToJpeg(powspec, outputjpg) shutil.move(inputparams['output'], os.path.join(self.powerspecdir, inputparams['output'])) self.ctfvalues['graph1'] = outputjpg #apFile.removeFile(inputparams['input']) return
def processImage(self, imgdata): self.ctfvalues = {} bestdef = ctfdb.getBestCtfByResolution(imgdata, msg=True) apix = apDatabase.getPixelSize(imgdata) if (not (self.params['onepass'] and self.params['zeropass'])): maskhighpass = False ace2inputpath = os.path.join(imgdata['session']['image path'],imgdata['filename']+".mrc") else: maskhighpass = True filterimg = apImage.maskHighPassFilter(imgdata['image'],apix,1,self.params['zeropass'],self.params['onepass']) ace2inputpath = os.path.join(self.params['rundir'],imgdata['filename']+".mrc") mrc.write(filterimg,ace2inputpath) # make sure that the image is a square dimx = imgdata['camera']['dimension']['x'] dimy = imgdata['camera']['dimension']['y'] if dimx != dimy: dims = [dimx,dimy] dims.sort() apDisplay.printMsg("resizing image: %ix%i to %ix%i" % (dimx,dimy,dims[0],dims[0])) mrcarray = apImage.mrcToArray(ace2inputpath,msg=False) clippedmrc = apImage.frame_cut(mrcarray,[dims[0],dims[0]]) ace2inputpath = os.path.join(self.params['rundir'],imgdata['filename']+".mrc") apImage.arrayToMrc(clippedmrc,ace2inputpath,msg=False) ### pad out image to speed up FFT calculations for non-standard image sizes print "checking prime factor" if primefactor.isGoodStack(dimx) is False: goodsize = primefactor.getNextEvenPrime(dimx) factor = float(goodsize) / float(dimx) apDisplay.printMsg("padding image: %ix%i to %ix%i" % (dimx,dimy,dimx*factor,dimy*factor)) mrcarray = apImage.mrcToArray(ace2inputpath,msg=False) # paddedmrc = imagefun.pad(mrcarray, None, factor) paddedmrc = apImage.frame_constant(mrcarray, (dimx*factor,dimy*factor), cval=mrcarray.mean()) ace2inputpath = os.path.join(self.params['rundir'],imgdata['filename']+".mrc") apImage.arrayToMrc(paddedmrc,ace2inputpath,msg=False) inputparams = { 'input': ace2inputpath, 'cs': self.params['cs'], 'kv': imgdata['scope']['high tension']/1000.0, 'apix': apix, 'binby': self.params['bin'], } ### make standard input for ACE 2 apDisplay.printMsg("Ace2 executable: "+self.ace2exe) commandline = ( self.ace2exe + " -i " + str(inputparams['input']) + " -b " + str(inputparams['binby']) + " -c " + str(inputparams['cs']) + " -k " + str(inputparams['kv']) + " -a " + str(inputparams['apix']) + " -e " + str(self.params['edge_b'])+","+str(self.params['edge_t']) + " -r " + str(self.params['rotblur']) + "\n" ) ### run ace2 apDisplay.printMsg("running ace2 at "+time.asctime()) apDisplay.printColor(commandline, "purple") t0 = time.time() if self.params['verbose'] is True: ace2proc = subprocess.Popen(commandline, shell=True) else: aceoutf = open("ace2.out", "a") aceerrf = open("ace2.err", "a") ace2proc = subprocess.Popen(commandline, shell=True, stderr=aceerrf, stdout=aceoutf) ace2proc.wait() ### check if ace2 worked basename = os.path.basename(ace2inputpath) imagelog = basename+".ctf.txt" if not os.path.isfile(imagelog) and self.stats['count'] <= 1: ### ace2 always crashes on first image??? .fft_wisdom file?? time.sleep(1) if self.params['verbose'] is True: ace2proc = subprocess.Popen(commandline, shell=True) else: aceoutf = open("ace2.out", "a") aceerrf = open("ace2.err", "a") ace2proc = subprocess.Popen(commandline, shell=True, stderr=aceerrf, stdout=aceoutf) ace2proc.wait() if self.params['verbose'] is False: aceoutf.close() aceerrf.close() if not os.path.isfile(imagelog): lddcmd = "ldd "+self.ace2exe lddproc = subprocess.Popen(lddcmd, shell=True) lddproc.wait() apDisplay.printError("ace2 did not run") apDisplay.printMsg("ace2 completed in " + apDisplay.timeString(time.time()-t0)) ### parse log file self.ctfvalues = { 'cs': self.params['cs'], 'volts': imgdata['scope']['high tension'], } logf = open(imagelog, "r") apDisplay.printMsg("reading log file %s"%(imagelog)) for line in logf: sline = line.strip() if re.search("^Final Defocus: ", sline): ### old ACE2 apDisplay.printError("This old version of ACE2 has a bug in the astigmastism, please upgrade ACE2 now") #parts = sline.split() #self.ctfvalues['defocus1'] = float(parts[2]) #self.ctfvalues['defocus2'] = float(parts[3]) ### convert to degrees #self.ctfvalues['angle_astigmatism'] = math.degrees(float(parts[4])) elif re.search("^Final Defocus \(m,m,deg\):", sline): ### new ACE2 apDisplay.printMsg("Reading new ACE2 defocus") parts = sline.split() #print parts self.ctfvalues['defocus1'] = float(parts[3]) self.ctfvalues['defocus2'] = float(parts[4]) # ace2 defines negative angle from +x toward +y self.ctfvalues['angle_astigmatism'] = -float(parts[5]) elif re.search("^Amplitude Contrast:",sline): parts = sline.split() self.ctfvalues['amplitude_contrast'] = float(parts[2]) elif re.search("^Confidence:",sline): parts = sline.split() self.ctfvalues['confidence'] = float(parts[1]) self.ctfvalues['confidence_d'] = float(parts[1]) logf.close() ### summary stats apDisplay.printMsg("============") avgdf = (self.ctfvalues['defocus1']+self.ctfvalues['defocus2'])/2.0 ampconst = 100.0*self.ctfvalues['amplitude_contrast'] pererror = 100.0 * (self.ctfvalues['defocus1']-self.ctfvalues['defocus2']) / avgdf apDisplay.printMsg("Defocus: %.3f x %.3f um (%.2f percent astigmatism)"% (self.ctfvalues['defocus1']*1.0e6, self.ctfvalues['defocus2']*1.0e6, pererror )) apDisplay.printMsg("Angle astigmatism: %.2f degrees"%(self.ctfvalues['angle_astigmatism'])) apDisplay.printMsg("Amplitude contrast: %.2f percent"%(ampconst)) apDisplay.printColor("Final confidence: %.3f"%(self.ctfvalues['confidence']),'cyan') ### double check that the values are reasonable if avgdf > self.params['maxdefocus'] or avgdf < self.params['mindefocus']: apDisplay.printWarning("bad defocus estimate, not committing values to database") self.badprocess = True if ampconst < 0.0 or ampconst > 80.0: apDisplay.printWarning("bad amplitude contrast, not committing values to database") self.badprocess = True if self.ctfvalues['confidence'] < 0.2: apDisplay.printWarning("bad confidence value, not committing values to database") self.badprocess = True ## create power spectra jpeg mrcfile = imgdata['filename']+".mrc.edge.mrc" if os.path.isfile(mrcfile): jpegfile = os.path.join(self.powerspecdir, apDisplay.short(imgdata['filename'])+".jpg") ps = apImage.mrcToArray(mrcfile,msg=False) c = numpy.array(ps.shape)/2.0 ps[c[0]-0,c[1]-0] = ps.mean() ps[c[0]-1,c[1]-0] = ps.mean() ps[c[0]-0,c[1]-1] = ps.mean() ps[c[0]-1,c[1]-1] = ps.mean() #print "%.3f -- %.3f -- %.3f"%(ps.min(), ps.mean(), ps.max()) ps = numpy.log(ps+1.0) ps = (ps-ps.mean())/ps.std() cutoff = -2.0*ps.min() ps = numpy.where(ps > cutoff, cutoff, ps) cutoff = ps.mean() ps = numpy.where(ps < cutoff, cutoff, ps) #print "%.3f -- %.3f -- %.3f"%(ps.min(), ps.mean(), ps.max()) apImage.arrayToJpeg(ps, jpegfile, msg=False) apFile.removeFile(mrcfile) self.ctfvalues['graph3'] = jpegfile otherfiles = glob.glob(imgdata['filename']+".*.txt") ### remove extra debugging files for filename in otherfiles: if filename[-9:] == ".norm.txt": continue elif filename[-8:] == ".ctf.txt": continue else: apFile.removeFile(filename) if maskhighpass and os.path.isfile(ace2inputpath): apFile.removeFile(ace2inputpath) return
def makeKeepMask(maskarray,keeplist1): # label the regions in the mask image array labeled_maskarray,countlabels = nd.label( maskarray ) # Remove any regions that are too small (happens with auto-masking) testlog = [False,0,""] infos={} infos, testlog = getLabeledInfo( maskarray, maskarray, labeled_maskarray, range(1,countlabels+1), False, infos, testlog ) goodregions = range(countlabels) goodareas = pruneByArea( infos, 400, 16777216, goodregions) labeled_maskarray, countlabels, infos = makePrunedLabels(labeled_maskarray, countlabels, infos, goodareas) # adjust the index of the regions keeplist0 = map((lambda x: x-1),keeplist1) # make a new image array that only includes the regions that have not been rejected labeled_maskarray = makeImageFromLabels(labeled_maskarray,countlabels,keeplist0) maskarray=getBmaskFromLabeled(labeled_maskarray) return maskarray if __name__ == '__main__': maskfile = '/home/acheng/testcrud/07jan05b/testa/masks/07jan05b_00018gr_00022sq_v01_00002sq_00_00002en_00_mask.png' mask = apImage.PngAlphaToBinarryArray(maskfile) labeled_image,ltotal = nd.label(mask) print ltotal goodlabels1 = [1] keeplist0 = map((lambda x: x-1),goodlabels1) goodmask = makeImageFromLabels(labeled_image,ltotal,keeplist0) apImage.arrayToJpeg(goodmask,'test.jpg')
def diffOfGaussLevels(imgarray, r0, N, dr, writeImg=False, apix=1): if writeImg is True: apImage.arrayToJpeg(imgarray, "binned-image.jpg") if dr >= 1.95 * r0: apDisplay.printError("size range has be less than twice the diameter") # initial params # print "r0=", r0*apix # print "dr=", dr*apix # print "N=", N # find k based on info k = estimateKfactorIncrement(r0, dr, N) # print "k=", k # find xi (E) function of k Ek = math.sqrt((k ** 2 - 1.0) / (2.0 * k ** 2 * math.log(k))) ##Ek = 1.0 / Ek # print "E(k)=", Ek # convert r0 to sigma1 sigma1 = Ek * r0 # print "sigma1=", sigma1*apix # find sigmaprime sigmaprime = sigma1 * math.sqrt(k ** 2 - 1.0) # print "sigma'=", sigmaprime*apix # sigma0 = sigma1 * k ^ (1-N)/2 power = float(1 - N) / 2.0 # print "power=", power sigma0 = sigma1 * k ** (float(1 - N) / 2.0) # print "sigma0=", sigma0*apix # calculate first image blur sigma = sigma0 gaussmap = ndimage.gaussian_filter(imgarray, sigma=sigma0) sigmavals = [sigma0] sigprimes = [] gaussmaps = [gaussmap] for i in range(N): sigmaprime = sigma * math.sqrt(k ** 2 - 1.0) sigprimes.append(sigmaprime) # calculate new sigma sigma = math.sqrt(sigma ** 2 + sigmaprime ** 2) sigmavals.append(sigma) # all subsequent blurs are by sigmaprime lastmap = gaussmaps[-1] gaussmap = ndimage.gaussian_filter(lastmap, sigma=sigmaprime) gaussmaps.append(gaussmap) # print "sigma' values= ", numpy.array(sigprimes)*apix sizevals = numpy.array(sigmavals) / Ek / math.sqrt(k) * apix # print "map sigma sizes= ", numpy.array(sigmavals)*apix sizevals = numpy.array(sigmavals) / Ek / math.sqrt(k) * apix # print "map central sizes=", sizevals sizevals = numpy.array(sigmavals) / Ek * apix # print "map pixel sizes= ", sizevals[:-1] if writeImg is True: for i, gaussmap in enumerate(gaussmaps): apImage.arrayToJpeg(gaussmap, "gaussmap" + str(i) + ".jpg") dogarrays = [] pixradlist = [] for i in range(N): pixrad = r0 * k ** (float(i) - float(N - 1) / 2.0) pixradlist.append(pixrad) # subtract blurs to get dog maps dogarray = gaussmaps[i] - gaussmaps[i + 1] dogarray = apImage.normStdev(dogarray) / 4.0 dogarrays.append(dogarray) if writeImg is True: apImage.arrayToJpeg(dogarray, "dogmap" + str(i) + ".jpg") sizevals = numpy.array(pixradlist) print "particle pixel sizes=", sizevals * apix # sys.exit(1) return dogarrays, sizevals
def diffOfGaussLevels(imgarray, r0, N, dr, writeImg=False, apix=1): if writeImg is True: apImage.arrayToJpeg(imgarray, "binned-image.jpg") if dr >= 1.95 * r0: apDisplay.printError("size range has be less than twice the diameter") # initial params #print "r0=", r0*apix #print "dr=", dr*apix #print "N=", N # find k based on info k = estimateKfactorIncrement(r0, dr, N) #print "k=", k # find xi (E) function of k Ek = math.sqrt((k**2 - 1.0) / (2.0 * k**2 * math.log(k))) ##Ek = 1.0 / Ek #print "E(k)=", Ek # convert r0 to sigma1 sigma1 = Ek * r0 #print "sigma1=", sigma1*apix # find sigmaprime sigmaprime = sigma1 * math.sqrt(k**2 - 1.0) #print "sigma'=", sigmaprime*apix #sigma0 = sigma1 * k ^ (1-N)/2 power = (float(1 - N) / 2.0) #print "power=", power sigma0 = sigma1 * k**(float(1 - N) / 2.0) #print "sigma0=", sigma0*apix # calculate first image blur sigma = sigma0 gaussmap = ndimage.gaussian_filter(imgarray, sigma=sigma0) sigmavals = [ sigma0, ] sigprimes = [] gaussmaps = [ gaussmap, ] for i in range(N): sigmaprime = sigma * math.sqrt(k**2 - 1.0) sigprimes.append(sigmaprime) #calculate new sigma sigma = math.sqrt(sigma**2 + sigmaprime**2) sigmavals.append(sigma) # all subsequent blurs are by sigmaprime lastmap = gaussmaps[-1] gaussmap = ndimage.gaussian_filter(lastmap, sigma=sigmaprime) gaussmaps.append(gaussmap) #print "sigma' values= ", numpy.array(sigprimes)*apix sizevals = numpy.array(sigmavals) / Ek / math.sqrt(k) * apix #print "map sigma sizes= ", numpy.array(sigmavals)*apix sizevals = numpy.array(sigmavals) / Ek / math.sqrt(k) * apix #print "map central sizes=", sizevals sizevals = numpy.array(sigmavals) / Ek * apix #print "map pixel sizes= ", sizevals[:-1] if writeImg is True: for i, gaussmap in enumerate(gaussmaps): apImage.arrayToJpeg(gaussmap, "gaussmap" + str(i) + ".jpg") dogarrays = [] pixradlist = [] for i in range(N): pixrad = r0 * k**(float(i) - float(N - 1) / 2.0) pixradlist.append(pixrad) # subtract blurs to get dog maps dogarray = gaussmaps[i] - gaussmaps[i + 1] dogarray = apImage.normStdev(dogarray) / 4.0 dogarrays.append(dogarray) if writeImg is True: apImage.arrayToJpeg(dogarray, "dogmap" + str(i) + ".jpg") sizevals = numpy.array(pixradlist) print "particle pixel sizes=", sizevals * apix #sys.exit(1) return dogarrays, sizevals
def processImage(self, imgdata): self.ctfvalues = {} bestdef = ctfdb.getBestCtfByResolution(imgdata, msg=True) apix = apDatabase.getPixelSize(imgdata) if (not (self.params['onepass'] and self.params['zeropass'])): maskhighpass = False ace2inputpath = os.path.join(imgdata['session']['image path'], imgdata['filename'] + ".mrc") else: maskhighpass = True filterimg = apImage.maskHighPassFilter(imgdata['image'], apix, 1, self.params['zeropass'], self.params['onepass']) ace2inputpath = os.path.join(self.params['rundir'], imgdata['filename'] + ".mrc") mrc.write(filterimg, ace2inputpath) # make sure that the image is a square dimx = imgdata['camera']['dimension']['x'] dimy = imgdata['camera']['dimension']['y'] if dimx != dimy: dims = [dimx, dimy] dims.sort() apDisplay.printMsg("resizing image: %ix%i to %ix%i" % (dimx, dimy, dims[0], dims[0])) mrcarray = apImage.mrcToArray(ace2inputpath, msg=False) clippedmrc = apImage.frame_cut(mrcarray, [dims[0], dims[0]]) ace2inputpath = os.path.join(self.params['rundir'], imgdata['filename'] + ".mrc") apImage.arrayToMrc(clippedmrc, ace2inputpath, msg=False) ### pad out image to speed up FFT calculations for non-standard image sizes print "checking prime factor" if primefactor.isGoodStack(dimx) is False: goodsize = primefactor.getNextEvenPrime(dimx) factor = float(goodsize) / float(dimx) apDisplay.printMsg("padding image: %ix%i to %ix%i" % (dimx, dimy, dimx * factor, dimy * factor)) mrcarray = apImage.mrcToArray(ace2inputpath, msg=False) # paddedmrc = imagefun.pad(mrcarray, None, factor) paddedmrc = apImage.frame_constant(mrcarray, (dimx * factor, dimy * factor), cval=mrcarray.mean()) ace2inputpath = os.path.join(self.params['rundir'], imgdata['filename'] + ".mrc") apImage.arrayToMrc(paddedmrc, ace2inputpath, msg=False) inputparams = { 'input': ace2inputpath, 'cs': self.params['cs'], 'kv': imgdata['scope']['high tension'] / 1000.0, 'apix': apix, 'binby': self.params['bin'], } ### make standard input for ACE 2 apDisplay.printMsg("Ace2 executable: " + self.ace2exe) commandline = (self.ace2exe + " -i " + str(inputparams['input']) + " -b " + str(inputparams['binby']) + " -c " + str(inputparams['cs']) + " -k " + str(inputparams['kv']) + " -a " + str(inputparams['apix']) + " -e " + str(self.params['edge_b']) + "," + str(self.params['edge_t']) + " -r " + str(self.params['rotblur']) + "\n") ### run ace2 apDisplay.printMsg("running ace2 at " + time.asctime()) apDisplay.printColor(commandline, "purple") t0 = time.time() if self.params['verbose'] is True: ace2proc = subprocess.Popen(commandline, shell=True) else: aceoutf = open("ace2.out", "a") aceerrf = open("ace2.err", "a") ace2proc = subprocess.Popen(commandline, shell=True, stderr=aceerrf, stdout=aceoutf) ace2proc.wait() ### check if ace2 worked basename = os.path.basename(ace2inputpath) imagelog = basename + ".ctf.txt" if not os.path.isfile(imagelog) and self.stats['count'] <= 1: ### ace2 always crashes on first image??? .fft_wisdom file?? time.sleep(1) if self.params['verbose'] is True: ace2proc = subprocess.Popen(commandline, shell=True) else: aceoutf = open("ace2.out", "a") aceerrf = open("ace2.err", "a") ace2proc = subprocess.Popen(commandline, shell=True, stderr=aceerrf, stdout=aceoutf) ace2proc.wait() if self.params['verbose'] is False: aceoutf.close() aceerrf.close() if not os.path.isfile(imagelog): lddcmd = "ldd " + self.ace2exe lddproc = subprocess.Popen(lddcmd, shell=True) lddproc.wait() apDisplay.printError("ace2 did not run") apDisplay.printMsg("ace2 completed in " + apDisplay.timeString(time.time() - t0)) ### parse log file self.ctfvalues = { 'cs': self.params['cs'], 'volts': imgdata['scope']['high tension'], } logf = open(imagelog, "r") apDisplay.printMsg("reading log file %s" % (imagelog)) for line in logf: sline = line.strip() if re.search("^Final Defocus: ", sline): ### old ACE2 apDisplay.printError( "This old version of ACE2 has a bug in the astigmastism, please upgrade ACE2 now" ) #parts = sline.split() #self.ctfvalues['defocus1'] = float(parts[2]) #self.ctfvalues['defocus2'] = float(parts[3]) ### convert to degrees #self.ctfvalues['angle_astigmatism'] = math.degrees(float(parts[4])) elif re.search("^Final Defocus \(m,m,deg\):", sline): ### new ACE2 apDisplay.printMsg("Reading new ACE2 defocus") parts = sline.split() #print parts self.ctfvalues['defocus1'] = float(parts[3]) self.ctfvalues['defocus2'] = float(parts[4]) # ace2 defines negative angle from +x toward +y self.ctfvalues['angle_astigmatism'] = -float(parts[5]) elif re.search("^Amplitude Contrast:", sline): parts = sline.split() self.ctfvalues['amplitude_contrast'] = float(parts[2]) elif re.search("^Confidence:", sline): parts = sline.split() self.ctfvalues['confidence'] = float(parts[1]) self.ctfvalues['confidence_d'] = float(parts[1]) logf.close() ### summary stats apDisplay.printMsg("============") avgdf = (self.ctfvalues['defocus1'] + self.ctfvalues['defocus2']) / 2.0 ampconst = 100.0 * self.ctfvalues['amplitude_contrast'] pererror = 100.0 * (self.ctfvalues['defocus1'] - self.ctfvalues['defocus2']) / avgdf apDisplay.printMsg( "Defocus: %.3f x %.3f um (%.2f percent astigmatism)" % (self.ctfvalues['defocus1'] * 1.0e6, self.ctfvalues['defocus2'] * 1.0e6, pererror)) apDisplay.printMsg("Angle astigmatism: %.2f degrees" % (self.ctfvalues['angle_astigmatism'])) apDisplay.printMsg("Amplitude contrast: %.2f percent" % (ampconst)) apDisplay.printColor( "Final confidence: %.3f" % (self.ctfvalues['confidence']), 'cyan') ### double check that the values are reasonable if avgdf > self.params['maxdefocus'] or avgdf < self.params[ 'mindefocus']: apDisplay.printWarning( "bad defocus estimate, not committing values to database") self.badprocess = True if ampconst < 0.0 or ampconst > 80.0: apDisplay.printWarning( "bad amplitude contrast, not committing values to database") self.badprocess = True if self.ctfvalues['confidence'] < 0.2: apDisplay.printWarning( "bad confidence value, not committing values to database") self.badprocess = True ## create power spectra jpeg mrcfile = imgdata['filename'] + ".mrc.edge.mrc" if os.path.isfile(mrcfile): jpegfile = os.path.join( self.powerspecdir, apDisplay.short(imgdata['filename']) + ".jpg") ps = apImage.mrcToArray(mrcfile, msg=False) c = numpy.array(ps.shape) / 2.0 ps[c[0] - 0, c[1] - 0] = ps.mean() ps[c[0] - 1, c[1] - 0] = ps.mean() ps[c[0] - 0, c[1] - 1] = ps.mean() ps[c[0] - 1, c[1] - 1] = ps.mean() #print "%.3f -- %.3f -- %.3f"%(ps.min(), ps.mean(), ps.max()) ps = numpy.log(ps + 1.0) ps = (ps - ps.mean()) / ps.std() cutoff = -2.0 * ps.min() ps = numpy.where(ps > cutoff, cutoff, ps) cutoff = ps.mean() ps = numpy.where(ps < cutoff, cutoff, ps) #print "%.3f -- %.3f -- %.3f"%(ps.min(), ps.mean(), ps.max()) apImage.arrayToJpeg(ps, jpegfile, msg=False) apFile.removeFile(mrcfile) self.ctfvalues['graph3'] = jpegfile otherfiles = glob.glob(imgdata['filename'] + ".*.txt") ### remove extra debugging files for filename in otherfiles: if filename[-9:] == ".norm.txt": continue elif filename[-8:] == ".ctf.txt": continue else: apFile.removeFile(filename) if maskhighpass and os.path.isfile(ace2inputpath): apFile.removeFile(ace2inputpath) return
def processImage(self, imgdata): """ time ./ctffind3.exe << eof Input image file name [input.mrc] : 15aug13neil2_14jul14d_05sq_012hl_02ed-a.mrc Output diagnostic filename [diagnostic_output.mrc] : 15aug13neil2_14jul14d_05sq_012hl_02ed-a-pow.mrc Pixel size [1.0] : 2.7 Acceleration voltage [300.0] : 300 Spherical aberration [2.7] : 2.7 Amplitude contrast [0.07] : 0.07 Size of power spectrum to compute [512] : 512 Minimum resolution [30.0] : 20 Maximum resolution [5.0] : 5 Minimum defocus [5000.0] : Maximum defocus [50000.0] : Defocus search step [500.0] : Expected (tolerated) astigmatism [100.0] : Find additional phase shift? [no] : """ paramInputOrder = ['input', 'output', 'apix', 'kv', 'cs', 'ampcontrast', 'fieldsize', 'resmin', 'resmax', 'defmin', 'defmax', 'defstep', 'expect_astig', 'phase', 'newline',] #get Defocus in Angstroms self.ctfvalues = {} nominal = abs(imgdata['scope']['defocus']*-1.0e10) ctfvalue = ctfdb.getBestCtfByResolution(imgdata) if ctfvalue is not None: """ ## CTFFIND V3.5 (7-March-2012) prefers the smaller of the two values for astigmatic images I found that say you have an image with 1.1um and 1.5um defocus astigmatism. If you give CTFFIND the average value of 1.3um for the defocus and 0.4um astig (dast) then it will try to fit 1.3um and 1.8um, so you need to give it the minimum value (1.1um) for it to fit 1.1um and 1.5um. """ bestdef = min(ctfvalue['defocus1'],ctfvalue['defocus2'])*1.0e10 else: bestdef = nominal if ctfvalue is not None and self.params['bestdb'] is True: bestampcontrast = round(ctfvalue['amplitude_contrast'],3) beststigdiff = round(abs(ctfvalue['defocus1'] - ctfvalue['defocus2'])*1e10,1) else: bestampcontrast = self.params['ampcontrast'] beststigdiff = self.params['dast']*10000. if ctfvalue is not None and self.params['bestdb'] is True: ### set res max from resolution_80_percent gmean = (ctfvalue['resolution_80_percent']*ctfvalue['resolution_50_percent']*self.params['resmax'])**(1/3.) if gmean < self.params['resmin']*0.9: # replace only if valid Issue #3291 self.params['resmax'] = round(gmean,2) apDisplay.printColor("Setting resmax to the geometric mean of resolution values", "purple") # dstep is the physical detector pixel size apix = apDatabase.getPixelSize(imgdata) # inputparams defocii and astig are in Angstroms inputparams = { 'orig': os.path.join(imgdata['session']['image path'], imgdata['filename']+".mrc"), 'input': apDisplay.short(imgdata['filename'])+".mrc", 'output': apDisplay.short(imgdata['filename'])+"-pow.mrc", 'apix': apix, 'kv': imgdata['scope']['high tension']/1000.0, 'cs': self.params['cs'], 'ampcontrast': bestampcontrast, 'fieldsize': self.params['fieldsize'], 'resmin': self.params['resmin'], 'resmax': self.params['resmax'], 'defstep': self.params['defstep']*10000., #round(defocus/32.0, 1), 'expect_astig': beststigdiff, 'phase': 'no', # this is a secondary amp contrast term for phase plates 'newline': '\n', } defrange = self.params['defstep'] * self.params['numstep'] * 1e4 ## do 25 steps in either direction # in angstrum inputparams['defmin']= round(bestdef-defrange, 1) #in angstrom if inputparams['defmin'] < 0: apDisplay.printWarning("Defocus minimum is less than zero") inputparams['defmin'] = inputparams['defstep'] inputparams['defmax']= round(bestdef+defrange, 1) #in angstrom apDisplay.printColor("Defocus search range: %d A to %d A (%.2f to %.2f um)" %(inputparams['defmin'], inputparams['defmax'], inputparams['defmin']*1e-4, inputparams['defmax']*1e-4), "cyan") ### secondary lock check right before it starts on the real part if self.params['parallel'] and os.path.isfile(apDisplay.short(imgdata['filename'])+".mrc"): # This is a secondary image lock check, checking the first output of the process. # It alone is not good enough apDisplay.printWarning('Some other parallel process is working on the same image. Skipping') return ### create local link to image if not os.path.exists(inputparams['input']): os.symlink(inputparams['orig'], inputparams['input']) if os.path.isfile(inputparams['output']): # program crashes if this file exists apFile.removeFile(inputparams['output']) t0 = time.time() apDisplay.printMsg("running ctf estimation at "+time.asctime()) for paramName in paramInputOrder: apDisplay.printColor("%s = %s"%(paramName,inputparams[paramName]),"magenta") print "" ctfprogproc = subprocess.Popen(self.ctfprgmexe, shell=True, stdin=subprocess.PIPE,) apDisplay.printColor(self.ctfprgmexe, "magenta") for paramName in paramInputOrder: apDisplay.printColor(inputparams[paramName],"magenta") ctfprogproc.stdin.write(str(inputparams[paramName])+'\n') ctfprogproc.communicate() tdiff = time.time()-t0 apDisplay.printMsg("ctf estimation completed in "+apDisplay.timeString(tdiff)) if tdiff < 1.0: apDisplay.printError("Failed to run CTFFIND4 program...") ### cannot run ctffind_plot_results.sh on CentOS 6 # This script requires gnuplot version >= 4.6, but you have version 4.2 ### parse ctf estimation output self.ctfvalues = {} ctfproglog = apDisplay.short(imgdata['filename'])+"-pow.txt" apDisplay.printMsg("reading %s"%(ctfproglog)) logf = open(ctfproglog, "r") for line in logf: sline = line.strip() if sline.startswith('#'): continue bits = sline.split() self.ctfvalues = { 'imagenum': int(float(bits[0])), 'defocus2': float(bits[1])*1e-10, 'defocus1': float(bits[2])*1e-10, 'angle_astigmatism': float(bits[3]), 'extra_phase': float(bits[4]), 'amplitude_contrast': inputparams['ampcontrast'], 'cross_correlation': float(bits[5]), 'ctffind4_resolution': float(bits[6]), 'defocusinit': bestdef*1e-10, 'cs': self.params['cs'], 'volts': imgdata['scope']['high tension'], 'confidence': float(bits[5]), 'confidence_d': round(math.sqrt(abs(float(bits[5]))), 5) } print self.ctfvalues #convert powerspectra to JPEG outputjpgbase = apDisplay.short(imgdata['filename'])+"-pow.jpg" self.lastjpg = outputjpgbase outputjpg = os.path.join(self.powerspecdir, self.lastjpg) powspec = apImage.mrcToArray(inputparams['output']) apImage.arrayToJpeg(powspec, outputjpg) shutil.move(inputparams['output'], os.path.join(self.powerspecdir, inputparams['output'])) self.ctfvalues['graph1'] = outputjpg #apFile.removeFile(inputparams['input']) return
# Remove any regions that are too small (happens with auto-masking) testlog = [False, 0, ""] infos = {} infos, testlog = getLabeledInfo(maskarray, maskarray, labeled_maskarray, range(1, countlabels + 1), False, infos, testlog) goodregions = range(countlabels) goodareas = pruneByArea(infos, 400, 16777216, goodregions) labeled_maskarray, countlabels, infos = makePrunedLabels( labeled_maskarray, countlabels, infos, goodareas) # adjust the index of the regions keeplist0 = map((lambda x: x - 1), keeplist1) # make a new image array that only includes the regions that have not been rejected labeled_maskarray = makeImageFromLabels(labeled_maskarray, countlabels, keeplist0) maskarray = getBmaskFromLabeled(labeled_maskarray) return maskarray if __name__ == '__main__': maskfile = '/home/acheng/testcrud/07jan05b/testa/masks/07jan05b_00018gr_00022sq_v01_00002sq_00_00002en_00_mask.png' mask = apImage.PngAlphaToBinarryArray(maskfile) labeled_image, ltotal = nd.label(mask) print ltotal goodlabels1 = [1] keeplist0 = map((lambda x: x - 1), goodlabels1) goodmask = makeImageFromLabels(labeled_image, ltotal, keeplist0) apImage.arrayToJpeg(goodmask, 'test.jpg')