def runAceCorrect(imgdict,params): imgname = imgdict['filename'] imgpath = os.path.join(imgdict['session']['image path'], imgname+'.mrc') voltage = (imgdict['scope']['high tension']) apix = apDatabase.getPixelSize(imgdict) ctfvalues = ctfdb.getBestCtfByResolution(imgdata) conf = ctfdb.calculateConfidenceScore(bestctfvalue) ctdimname = imgname ctdimpath = os.path.join(params['rundir'],ctdimname) print "Corrected Image written to " + ctdimpath #pdb.set_trace() acecorrectcommand=("ctfcorrect1('%s', '%s', '%.32f', '%.32f', '%f', '%f', '%f');" % \ (imgpath, ctdimpath, ctfvalues['defocus1'], ctfvalues['defocus2'], -ctfvalues['angle_astigmatism'], voltage, apix)) print acecorrectcommand try: matlab = pymat.open("matlab -nosplash") except: apDisplay.environmentError() raise pymat.eval(matlab, acecorrectcommand) pymat.close(matlab) return
def reprocessImage(self, imgdata): """ Returns True, if an image should be reprocessed False, if an image was processed and should NOT be reprocessed None, if image has not yet been processed e.g. a confidence less than 80% """ if self.params['reprocess'] is None: return True ctfvalue = ctfdb.getBestCtfByResolution(imgdata, msg=False) if ctfvalue is None: return True if conf > self.params['reprocess']: # small, unbinned images can give same defocus values for 1 & 2: if self.params['bin'] == 1 or ctfvalue['defocus1'] != ctfvalue['defocus2']: return False return True
def reprocessImage(self, imgdata): """ Returns True, if an image should be reprocessed False, if an image was processed and should NOT be reprocessed None, if image has not yet been processed e.g. a confidence less than 80% """ if self.params['reprocess'] is None: return True ctfvalue = ctfdb.getBestCtfByResolution(imgdata, msg=False) if ctfvalue is None: return None avgres = (ctfvalue['resolution_80_percent'] + ctfvalue['resolution_50_percent'])/2.0 if avgres < self.params['reprocess']: return False return True
def reprocessImage(self, imgdata): """ Returns True, if an image should be reprocessed False, if an image was processed and should NOT be reprocessed None, if image has not yet been processed e.g. a confidence less than 80% """ if self.params['reprocess'] is None: return True ctfvalue = ctfdb.getBestCtfByResolution(imgdata, msg=False) if ctfvalue is None: return None avgres = (ctfvalue['resolution_80_percent'] + ctfvalue['resolution_50_percent']) / 2.0 if avgres < self.params['reprocess']: return False return True
def reprocessImage(self, imgdata): """ Returns True, if an image should be reprocessed False, if an image was processed and should NOT be reprocessed None, if image has not yet been processed e.g. a confidence less than 80% """ if self.params['reprocess'] is None: return True ctfvalue = ctfdb.getBestCtfByResolution(imgdata, msg=False) if ctfvalue is None: return True if conf > self.params['reprocess']: # small, unbinned images can give same defocus values for 1 & 2: if self.params['bin'] == 1 or ctfvalue['defocus1'] != ctfvalue[ 'defocus2']: return False return True
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 runRefineCTF(self, imgdata, fftpath): ### reset important values self.bestres = 1e10 self.bestellipse = None self.bestvalues = {} self.volts = imgdata['scope']['high tension'] self.wavelength = ctftools.getTEMLambda(self.volts) ## get value in meters self.cs = apInstrument.getCsValueFromSession( self.getSessionData()) * 1e-3 self.ctfvalues = { 'volts': self.volts, 'wavelength': self.wavelength, 'cs': self.cs, } ### need to get FFT file open and freq of said file fftarray = mrc.read(fftpath).astype(numpy.float64) self.freq = self.freqdict[fftpath] ### convert resolution limit into pixel distance fftwidth = fftarray.shape[0] maxres = 2.0 / (self.freq * fftwidth) if maxres > self.params['reslimit']: apDisplay.printWarning( "Cannot get requested res %.1fA higher than max Nyquist resolution %.1fA" % (self.params['reslimit'], maxres)) self.params['reslimit'] = math.ceil(maxres) limitwidth = int(math.ceil(2.0 / (self.params['reslimit'] * self.freq))) limitwidth = primefactor.getNextEvenPrime(limitwidth) requestres = 2.0 / (self.freq * limitwidth) if limitwidth > fftwidth: apDisplay.printError("Cannot get requested resolution" + ( " request res %.1fA higher than max res %.1fA for new widths %d > %d" % (requestres, maxres, limitwidth, fftwidth))) apDisplay.printColor( "Requested resolution OK: " + (" request res %.1fA less than max res %.1fA with fft widths %d < %d" % (requestres, maxres, limitwidth, fftwidth)), "green") newshape = (limitwidth, limitwidth) fftarray = imagefilter.frame_cut(fftarray, newshape) ### spacing parameters self.mfreq = self.freq * 1e10 fftwidth = min(fftarray.shape) self.apix = 1.0 / (fftwidth * self.freq) self.ctfvalues['apix'] = self.apix ### print message bestDbValues = ctfdb.getBestCtfByResolution(imgdata) if bestDbValues is None: apDisplay.printColor( "SKIPPING: No CTF values for image %s" % (apDisplay.short(imgdata['filename'])), "red") self.badprocess = True return ### skip if resolution > 90. if bestDbValues['resolution_50_percent'] > 90.: apDisplay.printColor( "SKIPPING: No decent CTF values for image %s" % (apDisplay.short(imgdata['filename'])), "yellow") self.badprocess = True return self.ctfvalues['amplitude_contrast'] = bestDbValues[ 'amplitude_contrast'] lowerrad1 = ctftools.getCtfExtrema( bestDbValues['defocus1'], self.mfreq, self.cs, self.volts, self.ctfvalues['amplitude_contrast'], 1, "valley") lowerrad2 = ctftools.getCtfExtrema( bestDbValues['defocus2'], self.mfreq, self.cs, self.volts, self.ctfvalues['amplitude_contrast'], 1, "valley") meanRad = (lowerrad1[0] + lowerrad2[0]) / 2.0 self.ellipseParams = { 'a': lowerrad1[0], 'b': lowerrad2[0], 'alpha': math.radians(bestDbValues['angle_astigmatism']), } ellipratio = self.ellipseParams['a'] / self.ellipseParams['b'] defratio = bestDbValues['defocus2'] / bestDbValues['defocus1'] print "ellr=%.3f, defr=%.3f, sqrt(defr)=%.3f" % (ellipratio, defratio, math.sqrt(defratio)) self.bestvalues['defocus'] = (bestDbValues['defocus1'] + bestDbValues['defocus2']) / 2.0 raddata, PSDarray = self.from2Dinto1D(fftarray) lowerbound = numpy.searchsorted(raddata, meanRad * self.freq) upperbound = numpy.searchsorted(raddata, 1 / 10.) ### # This is the start of the actual program ### self.refineEllipseLoop(fftarray, lowerbound, upperbound) ##================================== ## FINISH UP ##================================== apDisplay.printColor("Finishing up using best found CTF values", "blue") self.printBestValues() ### take best values and use them self.ctfvalues = self.bestvalues self.ellipseParams = self.bestellipse ### stupid fix, get value in millimeters self.ctfvalues['cs'] = apInstrument.getCsValueFromSession( self.getSessionData()) ### translate ellipse into ctf values if self.ellipseParams is not None: self.ctfvalues['angle_astigmatism'] = math.degrees( self.ellipseParams['alpha']) ellipratio = self.ellipseParams['a'] / self.ellipseParams['b'] phi = math.asin(self.ctfvalues['amplitude_contrast']) #note: a > b then def1 < def2 #major axis self.ctfvalues['defocus1'] = self.ctfvalues['defocus'] / ellipratio #minor axis self.ctfvalues['defocus2'] = self.ctfvalues['defocus'] * ellipratio defdiff = 1.0 - 2 * self.ctfvalues['defocus'] / ( self.ctfvalues['defocus1'] + self.ctfvalues['defocus2']) print "%.3e --> %.3e,%.3e" % (self.ctfvalues['defocus'], self.ctfvalues['defocus2'], self.ctfvalues['defocus1']) print defdiff * 100 if defdiff * 100 > 1: apDisplay.printWarning("Large astigmatism") #sys.exit(1) else: ellipratio = 1.0 self.ctfvalues['angle_astigmatism'] = 0.0 self.ctfvalues['defocus1'] = self.ctfvalues['defocus'] self.ctfvalues['defocus2'] = self.ctfvalues['defocus'] self.badprocess = True return try: if self.ctfvalues['amplitude_contrast'] < self.minAmpCon: self.ctfvalues['amplitude_contrast'] = self.minAmpCon if self.ctfvalues['amplitude_contrast'] > self.maxAmpCon: self.ctfvalues['amplitude_contrast'] = self.maxAmpCon except KeyError: pass if abs(self.ctfvalues['defocus1']) > abs(self.ctfvalues['defocus2']): # incorrect, need to shift angle by 90 degrees apDisplay.printWarning("|def1| > |def2|, flipping defocus axes") tempdef = self.ctfvalues['defocus1'] self.ctfvalues['defocus1'] = self.ctfvalues['defocus2'] self.ctfvalues['defocus2'] = tempdef self.ctfvalues['angle_astigmatism'] += 90 # get astig_angle within range -90 < angle <= 90 while self.ctfvalues['angle_astigmatism'] > 90: self.ctfvalues['angle_astigmatism'] -= 180 while self.ctfvalues['angle_astigmatism'] < -90: self.ctfvalues['angle_astigmatism'] += 180 avgres = self.getResolution(self.ctfvalues['defocus'], raddata, PSDarray, lowerbound) apDisplay.printColor( "Final defocus values %.3e -> %.3e, %.3e; ac=%.2f, res=%.1f" % (self.ctfvalues['defocus'], self.ctfvalues['defocus1'], self.ctfvalues['defocus2'], self.ctfvalues['amplitude_contrast'], avgres / 2.0), "green") for i in range(10): print "====================================" print "PREVIOUS VALUES" ctfdb.getBestCtfByResolution(imgdata) print "CURRENT VALUES" defocusratio = self.ctfvalues['defocus2'] / self.ctfvalues['defocus1'] apDisplay.printColor( "def1: %.2e | def2: %.2e | angle: %.1f | ampcontr %.2f | defratio %.3f" % (self.ctfvalues['defocus1'], self.ctfvalues['defocus2'], self.ctfvalues['angle_astigmatism'], self.ctfvalues['amplitude_contrast'], defocusratio), "blue") self.printBestValues() #ellipratio = self.ellipseParams['a']/self.ellipseParams['b'] print "ellr=%.3f, defr=%.3f, sqrt(defr)=%.3f" % ( ellipratio, defocusratio, math.sqrt(defocusratio)) print "====================================" 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 runRefineCTF(self, imgdata, fftpath): ### reset important values self.bestres = 1e10 self.bestellipse = None self.bestvalues = {} self.volts = imgdata['scope']['high tension'] self.wavelength = ctftools.getTEMLambda(self.volts) ## get value in meters self.cs = apInstrument.getCsValueFromSession(self.getSessionData())*1e-3 self.ctfvalues = { 'volts': self.volts, 'wavelength': self.wavelength, 'cs': self.cs, } ### need to get FFT file open and freq of said file fftarray = mrc.read(fftpath).astype(numpy.float64) self.freq = self.freqdict[fftpath] ### convert resolution limit into pixel distance fftwidth = fftarray.shape[0] maxres = 2.0/(self.freq*fftwidth) if maxres > self.params['reslimit']: apDisplay.printError("Cannot get requested res %.1fA higher than max res %.1fA" %(maxres, self.params['reslimit'])) limitwidth = int(math.ceil(2.0/(self.params['reslimit']*self.freq))) limitwidth = primefactor.getNextEvenPrime(limitwidth) requestres = 2.0/(self.freq*limitwidth) if limitwidth > fftwidth: apDisplay.printError("Cannot get requested resolution" +(" request res %.1fA higher than max res %.1fA for new widths %d > %d" %(requestres, maxres, limitwidth, fftwidth))) apDisplay.printColor("Requested resolution OK: " +(" request res %.1fA less than max res %.1fA with fft widths %d < %d" %(requestres, maxres, limitwidth, fftwidth)), "green") newshape = (limitwidth, limitwidth) fftarray = imagefilter.frame_cut(fftarray, newshape) ### spacing parameters self.mfreq = self.freq*1e10 fftwidth = min(fftarray.shape) self.apix = 1.0/(fftwidth*self.freq) self.ctfvalues['apix'] = self.apix ### print message bestDbValues = ctfdb.getBestCtfByResolution(imgdata) if bestDbValues is None: apDisplay.printColor("SKIPPING: No CTF values for image %s" %(apDisplay.short(imgdata['filename'])), "red") self.badprocess = True return ### skip if resolution > 90. if bestDbValues['resolution_50_percent'] > 90.: apDisplay.printColor("SKIPPING: No decent CTF values for image %s" %(apDisplay.short(imgdata['filename'])), "yellow") self.badprocess = True return self.ctfvalues['amplitude_contrast'] = bestDbValues['amplitude_contrast'] lowerrad1 = ctftools.getCtfExtrema(bestDbValues['defocus1'], self.mfreq, self.cs, self.volts, self.ctfvalues['amplitude_contrast'], 1, "valley") lowerrad2 = ctftools.getCtfExtrema(bestDbValues['defocus2'], self.mfreq, self.cs, self.volts, self.ctfvalues['amplitude_contrast'], 1, "valley") meanRad = (lowerrad1[0] + lowerrad2[0])/2.0 self.ellipseParams = { 'a': lowerrad1[0], 'b': lowerrad2[0], 'alpha': math.radians(bestDbValues['angle_astigmatism']), } ellipratio = self.ellipseParams['a']/self.ellipseParams['b'] defratio = bestDbValues['defocus2']/bestDbValues['defocus1'] print "ellr=%.3f, defr=%.3f, sqrt(defr)=%.3f"%(ellipratio, defratio, math.sqrt(defratio)) self.bestvalues['defocus'] = (bestDbValues['defocus1']+bestDbValues['defocus2'])/2.0 raddata, PSDarray = self.from2Dinto1D(fftarray) lowerbound = numpy.searchsorted(raddata, meanRad*self.freq) upperbound = numpy.searchsorted(raddata, 1/10.) ### # This is the start of the actual program ### self.refineEllipseLoop(fftarray, lowerbound, upperbound) ##================================== ## FINISH UP ##================================== apDisplay.printColor("Finishing up using best found CTF values", "blue") self.printBestValues() ### take best values and use them self.ctfvalues = self.bestvalues self.ellipseParams = self.bestellipse ### stupid fix, get value in millimeters self.ctfvalues['cs'] = apInstrument.getCsValueFromSession(self.getSessionData()) ### translate ellipse into ctf values if self.ellipseParams is not None: self.ctfvalues['angle_astigmatism'] = math.degrees(self.ellipseParams['alpha']) ellipratio = self.ellipseParams['a']/self.ellipseParams['b'] phi = math.asin(self.ctfvalues['amplitude_contrast']) #note: a > b then def1 < def2 #major axis self.ctfvalues['defocus1'] = self.ctfvalues['defocus']/ellipratio #minor axis self.ctfvalues['defocus2'] = self.ctfvalues['defocus']*ellipratio defdiff = 1.0 - 2*self.ctfvalues['defocus']/(self.ctfvalues['defocus1']+self.ctfvalues['defocus2']) print "%.3e --> %.3e,%.3e"%(self.ctfvalues['defocus'], self.ctfvalues['defocus2'], self.ctfvalues['defocus1']) print defdiff*100 if defdiff*100 > 1: apDisplay.printWarning("Large astigmatism") #sys.exit(1) else: ellipratio = 1.0 self.ctfvalues['angle_astigmatism'] = 0.0 self.ctfvalues['defocus1'] = self.ctfvalues['defocus'] self.ctfvalues['defocus2'] = self.ctfvalues['defocus'] if self.ctfvalues['amplitude_contrast'] < 0.0: self.ctfvalues['amplitude_contrast'] = 0.0 if self.ctfvalues['amplitude_contrast'] > self.maxAmpCon: self.ctfvalues['amplitude_contrast'] = self.maxAmpCon if abs(self.ctfvalues['defocus1']) > abs(self.ctfvalues['defocus2']): # incorrect, need to shift angle by 90 degrees apDisplay.printWarning("|def1| > |def2|, flipping defocus axes") tempdef = self.ctfvalues['defocus1'] self.ctfvalues['defocus1'] = self.ctfvalues['defocus2'] self.ctfvalues['defocus2'] = tempdef self.ctfvalues['angle_astigmatism'] += 90 # get astig_angle within range -90 < angle <= 90 while self.ctfvalues['angle_astigmatism'] > 90: self.ctfvalues['angle_astigmatism'] -= 180 while self.ctfvalues['angle_astigmatism'] < -90: self.ctfvalues['angle_astigmatism'] += 180 avgres = self.getResolution(self.ctfvalues['defocus'], raddata, PSDarray, lowerbound) apDisplay.printColor("Final defocus values %.3e -> %.3e, %.3e; ac=%.2f, res=%.1f" %(self.ctfvalues['defocus'], self.ctfvalues['defocus1'], self.ctfvalues['defocus2'], self.ctfvalues['amplitude_contrast'], avgres/2.0), "green") for i in range(10): print "====================================" print "PREVIOUS VALUES" ctfdb.getBestCtfByResolution(imgdata) print "CURRENT VALUES" defocusratio = self.ctfvalues['defocus2']/self.ctfvalues['defocus1'] apDisplay.printColor("def1: %.2e | def2: %.2e | angle: %.1f | ampcontr %.2f | defratio %.3f" %(self.ctfvalues['defocus1'], self.ctfvalues['defocus2'], self.ctfvalues['angle_astigmatism'], self.ctfvalues['amplitude_contrast'], defocusratio), "blue") self.printBestValues() #ellipratio = self.ellipseParams['a']/self.ellipseParams['b'] print "ellr=%.3f, defr=%.3f, sqrt(defr)=%.3f"%(ellipratio, defocusratio, math.sqrt(defocusratio)) print "====================================" return
def runPhasorCTF(self, imgdata, fftpath): ### reset important values self.bestres = 1e10 self.bestellipse = None self.bestvalues = None self.ellipseParams = None self.volts = imgdata['scope']['high tension'] self.wavelength = ctftools.getTEMLambda(self.volts) ## get value in meters self.cs = apInstrument.getCsValueFromSession(self.getSessionData())*1e-3 self.ctfvalues = { 'volts': self.volts, 'wavelength': self.wavelength, 'cs': self.cs, } if self.params['astig'] is False: self.maxRatio=1.3 else: self.maxRatio=2.0 ### need to get FFT file open and freq of said file fftarray = mrc.read(fftpath).astype(numpy.float64) self.freq = self.freqdict[fftpath] ### print message ctfdb.getBestCtfByResolution(imgdata) ### convert resolution limit into pixel distance fftwidth = fftarray.shape[0] maxres = 2.0/(self.freq*fftwidth) if maxres > self.params['reslimit']: apDisplay.printError("Cannot get requested res %.1fA higher than max res %.1fA" %(maxres, self.params['reslimit'])) limitwidth = int(math.ceil(2.0/(self.params['reslimit']*self.freq))) limitwidth = primefactor.getNextEvenPrime(limitwidth) requestres = 2.0/(self.freq*limitwidth) if limitwidth > fftwidth: apDisplay.printError("Cannot get requested resolution" +(" request res %.1fA higher than max res %.1fA for new widths %d > %d" %(requestres, maxres, limitwidth, fftwidth))) apDisplay.printColor("Requested resolution OK: " +(" request res %.1fA less than max res %.1fA with fft widths %d < %d" %(requestres, maxres, limitwidth, fftwidth)), "green") newshape = (limitwidth, limitwidth) fftarray = imagefilter.frame_cut(fftarray, newshape) ### spacing parameters self.mfreq = self.freq*1e10 fftwidth = min(fftarray.shape) self.apix = 1.0/(fftwidth*self.freq) self.ctfvalues['apix'] = self.apix if self.params['sample'] is 'stain': self.ctfvalues['amplitude_contrast'] = 0.14 else: self.ctfvalues['amplitude_contrast'] = 0.07 ### # This is the start of the actual program ### ### this is either simple rotational average, ### or complex elliptical average with edge find and RANSAC raddata, PSDarray = self.from2Dinto1D(fftarray) lowerrad = ctftools.getCtfExtrema(self.params['maxdef'], self.mfreq, self.cs, self.volts, self.ctfvalues['amplitude_contrast'], 1, "valley") lowerbound = numpy.searchsorted(raddata, lowerrad[0]*self.freq) if self.params['sample'] is 'stain': upperbound = numpy.searchsorted(raddata, 1/8.) else: upperbound = numpy.searchsorted(raddata, 1/12.) ### fun way to get initial defocus estimate fitData = self.fitLinearPlus(raddata, PSDarray) #lowessFit = lowess.lowess(raddata**2, PSDarray, smoothing=0.6666) if self.debug is True: from matplotlib import pyplot pyplot.clf() pyplot.plot(raddata**2, PSDarray) pyplot.plot(raddata**2, fitData) pyplot.show() flatPSDarray = PSDarray-fitData flatPSDarray /= numpy.abs(flatPSDarray[lowerbound:upperbound]).max() defocus = self.gridSearch(raddata, flatPSDarray, lowerbound) #defocus = findroots.estimateDefocus(raddata[lowerbound:upperbound], flatPSDarray[lowerbound:upperbound], # cs=self.cs, wavelength=self.wavelength, amp_con=self.ctfvalues['amplitude_contrast'], # mindef=self.params['mindef'], maxdef=self.params['maxdef'], volts=self.volts) amplitudecontrast = sinefit.refineAmplitudeContrast(raddata[lowerbound:upperbound]*1e10, defocus, flatPSDarray[lowerbound:upperbound], self.ctfvalues['cs'], self.wavelength, msg=self.debug) if amplitudecontrast is not None: print "amplitudecontrast", amplitudecontrast self.ctfvalues['amplitude_contrast'] = amplitudecontrast defocus = self.defocusLoop(defocus, raddata, flatPSDarray, lowerbound, upperbound) #lowerrad = ctftools.getCtfExtrema(defocus, self.mfreq, self.cs, self.volts, # self.ctfvalues['amplitude_contrast'], 1, "valley") #lowerbound = numpy.searchsorted(raddata, lowerrad[0]*self.freq) normPSDarray = self.fullTriSectionNormalize(raddata, PSDarray, defocus) defocus = self.defocusLoop(defocus, raddata, normPSDarray, lowerbound, upperbound) self.findEllipseLoop(fftarray, lowerbound, upperbound) self.refineEllipseLoop(fftarray, lowerbound, upperbound) ##================================== ## FINISH UP ##================================== apDisplay.printColor("Finishing up using best found CTF values", "blue") self.printBestValues() if self.bestvalues is None: apDisplay.printColor("No CTF estimate found for this image", "red") self.badprocess = True return ### take best values and use them self.ctfvalues = self.bestvalues self.ellipseParams = self.bestellipse ### stupid fix, get value in millimeters self.ctfvalues['cs'] = apInstrument.getCsValueFromSession(self.getSessionData()) ### translate ellipse into ctf values if self.ellipseParams is not None: self.ctfvalues['angle_astigmatism'] = math.degrees(self.ellipseParams['alpha']) ellipratio = self.ellipseParams['a']/self.ellipseParams['b'] phi = math.asin(self.ctfvalues['amplitude_contrast']) #note: a > b then def1 < def2 #major axis self.ctfvalues['defocus1'] = self.ctfvalues['defocus']/ellipratio #minor axis self.ctfvalues['defocus2'] = self.ctfvalues['defocus']*ellipratio defdiff = 1.0 - 2*self.ctfvalues['defocus']/(self.ctfvalues['defocus1']+self.ctfvalues['defocus2']) print "%.3e --> %.3e,%.3e"%(self.ctfvalues['defocus'], self.ctfvalues['defocus2'], self.ctfvalues['defocus1']) print defdiff*100 if defdiff*100 > 1: apDisplay.printWarning("Large astigmatism") #sys.exit(1) else: self.ctfvalues['angle_astigmatism'] = 0.0 self.ctfvalues['defocus1'] = self.ctfvalues['defocus'] self.ctfvalues['defocus2'] = self.ctfvalues['defocus'] if self.ctfvalues['amplitude_contrast'] < 0.0: self.ctfvalues['amplitude_contrast'] = 0.0 if self.ctfvalues['amplitude_contrast'] > self.maxAmpCon: self.ctfvalues['amplitude_contrast'] = self.maxAmpCon if abs(self.ctfvalues['defocus1']) > abs(self.ctfvalues['defocus2']): # incorrect, need to shift angle by 90 degrees apDisplay.printWarning("|def1| > |def2|, flipping defocus axes") tempdef = self.ctfvalues['defocus1'] self.ctfvalues['defocus1'] = self.ctfvalues['defocus2'] self.ctfvalues['defocus2'] = tempdef self.ctfvalues['angle_astigmatism'] += 90 # get astig_angle within range -90 < angle <= 90 while self.ctfvalues['angle_astigmatism'] > 90: self.ctfvalues['angle_astigmatism'] -= 180 while self.ctfvalues['angle_astigmatism'] < -90: self.ctfvalues['angle_astigmatism'] += 180 avgres = self.getResolution(self.ctfvalues['defocus'], raddata, PSDarray, lowerbound) apDisplay.printColor("Final defocus values %.3e -> %.3e, %.3e; ac=%.2f, res=%.1f" %(self.ctfvalues['defocus'], self.ctfvalues['defocus1'], self.ctfvalues['defocus2'], self.ctfvalues['amplitude_contrast'], avgres/2.0), "green") for i in range(10): print "====================================" print "PREVIOUS VALUES" ctfdb.getBestCtfByResolution(imgdata) print "CURRENT VALUES" defocusratio = self.ctfvalues['defocus2']/self.ctfvalues['defocus1'] apDisplay.printColor("def1: %.2e | def2: %.2e | angle: %.1f | ampcontr %.2f | defratio %.3f" %(self.ctfvalues['defocus1'], self.ctfvalues['defocus2'], self.ctfvalues['angle_astigmatism'], self.ctfvalues['amplitude_contrast'], defocusratio), "blue") self.printBestValues() print "====================================" return
count += 1 imagename = os.path.basename(imgfile) imagename = imagename.replace(".mrc", "") imgdata = apDatabase.getImageData(imagename) ### change project projid = apProject.getProjectIdFromImageData(imgdata) newdbname = apProject.getAppionDBFromProjectId(projid) sinedon.setConfig('appiondata', db=newdbname) powerspecfile = apDisplay.short(imagename)+"-powerspec.jpg" if os.path.isfile(powerspecfile): apDisplay.printColor("Skipping image %s, already complete"%(apDisplay.short(imagename)), "cyan") continue ctfdata = ctfdb.getBestCtfByResolution(imgdata) #ctfdata, bestconf = ctfdb.getBestCtfValueForImage(imgdata, method="ctffind") #ctfdata, bestconf = ctfdb.getBestCtfValueForImage(imgdata, method="ace2") if ctfdata is None: apDisplay.printColor("Skipping image %s, no CTF data"%(apDisplay.short(imagename)), "red") continue #print ctfdata if ctfdata['confidence_30_10'] < 0.88: apDisplay.printColor("Skipping image %s, poor confidence"%(apDisplay.short(imagename)), "red") continue """ if ctfdata['resolution_50_percent'] > 10 or ctfdata['resolution_50_percent'] < 7.5: apDisplay.printColor("Skipping image %s, not right 50per resolution"%(apDisplay.short(imagename)), "red") continue if ctfdata['resolution_80_percent'] > 13 or ctfdata['resolution_80_percent'] < 8.5: apDisplay.printColor("Skipping image %s, not right 80per resolution"%(apDisplay.short(imagename)), "red")
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
def runAce(matlab, imgdata, params, showprev=True): imgname = imgdata['filename'] if showprev is True: bestctfvalue = ctfdb.getBestCtfByResolution(imgdata) if bestctfvalue: bestconf = ctfdb.calculateConfidenceScore(bestctfvalue) print ( "Prev best: '"+bestctfvalue['acerun']['name']+"', conf="+ apDisplay.colorProb(bestconf)+", defocus="+str(round(-1.0*abs(bestctfvalue['defocus1']*1.0e6),2))+ " microns" ) if params['uncorrected']: tmpname='temporaryCorrectedImage.mrc' imgarray = apDBImage.correctImage(imgdata) imgpath = os.path.join(params['rundir'],tmpname) apImage.arrayToMrc(imgarray, imgpath) print "processing", imgpath else: imgpath = os.path.join(imgdata['session']['image path'], imgname+'.mrc') nominal = None if params['nominal'] is not None: nominal=params['nominal'] elif params['newnominal'] is True: bestctfvalue = ctfdb.getBestCtfByResolution(imgdata) nominal = bestctfvalue['defocus1'] if nominal is None: nominal = imgdata['scope']['defocus'] if nominal is None or nominal > 0 or nominal < -15e-6: apDisplay.printWarning("Nominal should be of the form nominal=-1.2e-6"+\ " for -1.2 microns NOT:"+str(nominal)) #Neil's Hack #if 'autosample' in params and params['autosample']: # x = abs(nominal*1.0e6) # val = 1.585 + 0.057587 * x - 0.044106 * x**2 + 0.010877 * x**3 # resamplefr_override = round(val,3) # print "resamplefr_override=",resamplefr_override # pymat.eval(matlab, "resamplefr="+str(resamplefr_override)+";") pymat.eval(matlab,("dforig = %e;" % nominal)) if params['stig'] == 0: plist = (imgpath, params['outtextfile'], params['display'], params['stig'],\ params['medium'], -nominal, params['tempdir']+"/") acecmd = makeMatlabCmd("ctfparams = ace(",");",plist) else: plist = (imgname, imgpath, params['outtextfile'], params['opimagedir'], \ params['matdir'], params['display'], params['stig'],\ params['medium'], -nominal, params['tempdir']+"/", params['resamplefr']) acecmd = makeMatlabCmd("ctfparams = measureAstigmatism(",");",plist) #print acecmd pymat.eval(matlab,acecmd) matfile = os.path.join(params['matdir'], imgname+".mrc.mat") if params['stig']==0: savematcmd = "save('"+matfile+"','ctfparams','scopeparams', 'dforig');" pymat.eval(matlab,savematcmd) ctfvalue = pymat.get(matlab, 'ctfparams') ctfvalue=ctfvalue[0] printResults(params, nominal, ctfvalue) return ctfvalue