def skipTestOnImage(self, imgdata): imgname = imgdata['filename'] skip = False reason = None #tiltskip is default to None since it might not need evaluation tiltskip = None if imgname in self.donedict: skip = True reason = 'done' elif self.reprocessImage(imgdata) is False: self._writeDoneDict(imgname) reason = 'reproc' skip = True if skip is True: return skip, reason else: # image not done or reprocessing allowed # check sibling status instead if wanted if self.params['sibassess'] is True: status = apDatabase.getSiblingImgCompleteStatus(imgdata) else: status = apDatabase.getImgCompleteStatus(imgdata) if self.params['norejects'] is True and status is False: reason = 'reject' skip = True elif self.params['bestimages'] is True and status is not True: reason = 'reject' skip = True elif (self.params['tiltangle'] is not None or self.params['tiltangle'] != 'all'): tiltangle = apDatabase.getTiltAngleDeg(imgdata) tiltangle = apDatabase.getTiltAngleDeg(imgdata) if (self.params['tiltangle'] == 'notilt' and abs(tiltangle) > 3.0): skip = True elif (self.params['tiltangle'] == 'hightilt' and abs(tiltangle) < 30.0): skip = True elif (self.params['tiltangle'] == 'lowtilt' and abs(tiltangle) >= 30.0): skip = True ### the reason why -2.0 and 2.0 are used is because the tilt angle is saved as 0 +/- a small amount elif (self.params['tiltangle'] == 'minustilt' and tiltangle > -2.0): skip = True elif (self.params['tiltangle'] == 'plustilt' and tiltangle < 2.0): skip = True if skip == True: reason = 'tilt' return skip, reason
def skipTestOnImage(self,imgdata): imgname = imgdata['filename'] skip = False reason = None #tiltskip is default to None since it might not need evaluation tiltskip = None if imgname in self.donedict: skip = True reason = 'done' elif self.reprocessImage(imgdata) is False: self._writeDoneDict(imgname) reason = 'reproc' skip = True if skip is True: return skip, reason else: # image not done or reprocessing allowed # check sibling status instead if wanted if self.params['sibassess'] is True: status=apDatabase.getSiblingImgCompleteStatus(imgdata) else: status=apDatabase.getImgCompleteStatus(imgdata) if self.params['norejects'] is True and status is False: reason = 'reject' skip = True elif self.params['bestimages'] is True and status is not True: reason = 'reject' skip = True elif ( self.params['tiltangle'] is not None or self.params['tiltangle'] != 'all' ): tiltangle = apDatabase.getTiltAngleDeg(imgdata) tiltangle = apDatabase.getTiltAngleDeg(imgdata) if (self.params['tiltangle'] == 'notilt' and abs(tiltangle) > 3.0 ): skip = True elif (self.params['tiltangle'] == 'hightilt' and abs(tiltangle) < 30.0 ): skip = True elif (self.params['tiltangle'] == 'lowtilt' and abs(tiltangle) >= 30.0 ): skip = True ### the reason why -2.0 and 2.0 are used is because the tilt angle is saved as 0 +/- a small amount elif (self.params['tiltangle'] == 'minustilt' and tiltangle > -2.0 ): skip = True elif (self.params['tiltangle'] == 'plustilt' and tiltangle < 2.0 ): skip = True if skip == True: reason = 'tilt' return skip, reason
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 runTiltAligner(self, imgdata, tiltdata): #reset targets self.app.onResetParams(None, False) self.tiltparams = {} #set tilt tilt1 = apDatabase.getTiltAngleDeg(imgdata) tilt2 = apDatabase.getTiltAngleDeg(tiltdata) self.theta = abs(tilt2) - abs(tilt1) self.app.data['theta'] = self.theta self.app.data['filetypeindex'] = self.params['outtypeindex'] outname = os.path.basename(imgdata['filename'])+"."+self.getExtension() outfile = os.path.join(self.params['pickdatadir'], outname) self.app.data['outfile'] = outfile self.app.data['dirname'] = self.params['pickdatadir'] self.app.data['image1file'] = apDisplay.short(imgdata['filename']) self.app.data['image2file'] = apDisplay.short(tiltdata['filename']) self.app.data['pixdiam'] = self.params['diam']/self.params['apix']/self.params['bin'] #print "pixdiam=", self.app.data['pixdiam'] #print "theta=",self.app.data['theta'] #pre-load particle picks self.app.picks1 = self.getParticlePicks(imgdata) self.app.picks2 = self.getParticlePicks(tiltdata) #set image assessment self.assess = self.getTiltAssess(imgdata, tiltdata) self.assessold = self.assess self.app.setAssessStatus() #open image file 1 imgname = imgdata['filename']+".dwn.mrc" imgpath = os.path.join(self.params['rundir'],imgname) self.app.panel1.openImageFile(imgpath) #open tilt file 2 tiltname = tiltdata['filename']+".dwn.mrc" tiltpath = os.path.join(self.params['rundir'],tiltname) self.app.panel2.openImageFile(tiltpath) #guess the shift outfile = self.app.data['outfile'] if not os.path.exists(outfile): if self.params['autopick'] is True and self.params['importalign'] is False: if len(self.app.picks1) > 0 and len(self.app.picks2) > 0: apDisplay.printMsg("Autopicking image") self.app.onGuessShift(None) elif self.params['importalign'] is True: self.importPreviousTiltParams(imgdata) else: self.app.readData(outfile) self.app.onAutoOptim(None) time.sleep(0.1) #run the picker self.app.MainLoop() ######################################### # RESULTS ######################################### self.app.panel1.openImageFile(None) self.app.panel2.openImageFile(None) # 1. tilt data are copied to self.tiltparams by app # 2. particles picks are copied to self.peaks1 and self.peaks2 by app # 3. particle errors are copied to self.peakerrors by app # 4. assessment status is copied to self.assess self.appdata = self.app.data self.peaktree1 = apPeaks.convertListToPeaks(self.peaks1, self.params) self.peaktree2 = apPeaks.convertListToPeaks(self.peaks2, self.params)
def processAndSaveAllImages(self): print "Pre-processing images before picking\nNow is a good time to go get a candy bar" count = 0 total = len(self.imgtree) for imgdata in self.imgtree: count += 1 tiltdata = apTiltPair.getTiltPair(imgdata) if tiltdata is None: #reject it apDatabase.insertImgAssessmentStatus(imgdata, "notiltpair", False) continue #First the image imgpath = os.path.join(self.params['rundir'], imgdata['filename']+'.dwn.mrc') if os.path.isfile(imgpath): sys.stderr.write(".") #print "already processed: ",apDisplay.short(imgdata['filename']) else: sys.stderr.write("#") #print "processing: ",apDisplay.short(imgdata['filename']) apFindEM.processAndSaveImage(imgdata, params=self.params) #Now for its tilt pair tiltpath = os.path.join(self.params['rundir'], tiltdata['filename']+'.dwn.mrc') if os.path.isfile(tiltpath): sys.stderr.write(".") #print "already processed: ",apDisplay.short(tiltdata['filename']) else: sys.stderr.write("#") #print "processing: ",apDisplay.short(tiltdata['filename']) apFindEM.processAndSaveImage(tiltdata, params=self.params) if count % 30 == 0: sys.stderr.write(" %d left\n" % (total-count)) ### check if automation was already run outname1 = os.path.basename(imgdata['filename'])+"."+self.getExtension() outname2 = os.path.basename(tiltdata['filename'])+"."+self.getExtension() outfile1 = os.path.join(self.params['pickdatadir'], outname1) outfile2 = os.path.join(self.params['pickdatadir'], outname2) if os.path.isfile(outfile1): sys.stderr.write(",") else: ### set important parameters picks1 = self.getParticlePicks(imgdata, False) picks2 = self.getParticlePicks(tiltdata, False) pixdiam = self.params['diam']/self.params['apix']/self.params['bin'] tilt1 = apDatabase.getTiltAngleDeg(imgdata) tilt2 = apDatabase.getTiltAngleDeg(tiltdata) tiltdiff = abs(tilt2) - abs(tilt1) tiltaxis = self.params['inittiltaxis'] ### run tilt automation if self.params['autopick'] is True and self.params['importalign'] is False: if len(picks1) > 0 and len(picks2) > 0: autotilter = autotilt.autoTilt() result = autotilter.processTiltPair(imgpath, tiltpath, picks1, picks2, tiltdiff, outfile1, pixdiam, tiltaxis, msg=False) if os.path.isfile(outfile1): if os.path.exists(outfile2): os.remove(outfile2) os.symlink(os.path.basename(outfile1), outfile2) sys.stderr.write("%") apDisplay.printMsg("done") return
def runTiltAligner(self, imgdata, tiltdata): ### set tilt tilt1 = apDatabase.getTiltAngleDeg(imgdata) tilt2 = apDatabase.getTiltAngleDeg(tiltdata) theta = abs(tilt2) - abs(tilt1) ### pre-load particle picks picks1 = self.getParticlePicks(imgdata) picks2 = self.getParticlePicks(tiltdata) if len(picks1) < 10 or len(picks2) < 10: apDisplay.printWarning( "Not enough particles ot run program on image pair") self.badprocess = True return ### set image file 1 imgname = imgdata['filename'] + ".dwn.mrc" imgpath = os.path.join(self.params['rundir'], imgname) ### set tilt file 2 tiltname = tiltdata['filename'] + ".dwn.mrc" tiltpath = os.path.join(self.params['rundir'], tiltname) ### set out file outname1 = os.path.basename( imgdata['filename']) + "." + self.getExtension() outfile1 = os.path.join(self.params['pickdatadir'], outname1) outname2 = os.path.basename( tiltdata['filename']) + "." + self.getExtension() outfile2 = os.path.join(self.params['pickdatadir'], outname1) pixdiam = self.params['diam'] / self.params['apix'] / self.params['bin'] tiltaxis = self.params['inittiltaxis'] ### run tilt automation autotilter = autotilt.autoTilt() result = autotilter.processTiltPair(imgpath, tiltpath, picks1, picks2, theta, outfile1, pixdiam, tiltaxis) if result is None: apDisplay.printWarning("Image processing failed") self.badprocess = True return if os.path.isfile(outfile1) and outfile1 != outfile2: if os.path.exists(outfile2): os.remove(outfile2) os.symlink(os.path.basename(outfile1), outfile2) ### read alignment results if not os.path.isfile(outfile1): apDisplay.printWarning("Image processing failed") self.badprocess = True return self.data = tiltfile.readData(outfile1) self.currentpicks1 = numpy.asarray(self.data['picks1']) self.currentpicks2 = numpy.asarray(self.data['picks2']) #print self.data # 1. tilt data are copied to self.tiltparams by app # 2. particles picks are copied to self.peaks1 and self.peaks2 by app # 3. particle errors are copied to self.peakerrors by app # 4. assessment status is copied to self.assess self.peaktree1 = apPeaks.convertListToPeaks(self.currentpicks1, self.params) self.peaktree2 = apPeaks.convertListToPeaks(self.currentpicks2, self.params) self.peakerrors = self.getRmsdArray() self.getOverlap(imgpath, tiltpath)
def runTiltAligner(self, imgdata, tiltdata): ### set tilt tilt1 = apDatabase.getTiltAngleDeg(imgdata) tilt2 = apDatabase.getTiltAngleDeg(tiltdata) theta = abs(tilt2) - abs(tilt1) ### pre-load particle picks picks1 = self.getParticlePicks(imgdata) picks2 = self.getParticlePicks(tiltdata) if len(picks1) < 10 or len(picks2) < 10: apDisplay.printWarning("Not enough particles ot run program on image pair") self.badprocess = True return ### set image file 1 imgname = imgdata['filename']+".dwn.mrc" imgpath = os.path.join(self.params['rundir'], imgname) ### set tilt file 2 tiltname = tiltdata['filename']+".dwn.mrc" tiltpath = os.path.join(self.params['rundir'], tiltname) ### set out file outname1 = os.path.basename(imgdata['filename'])+"."+self.getExtension() outfile1 = os.path.join(self.params['pickdatadir'], outname1) outname2 = os.path.basename(tiltdata['filename'])+"."+self.getExtension() outfile2 = os.path.join(self.params['pickdatadir'], outname1) pixdiam = self.params['diam']/self.params['apix']/self.params['bin'] tiltaxis = self.params['inittiltaxis'] ### run tilt automation autotilter = autotilt.autoTilt() result = autotilter.processTiltPair(imgpath, tiltpath, picks1, picks2, theta, outfile1, pixdiam, tiltaxis) if result is None: apDisplay.printWarning("Image processing failed") self.badprocess = True return if os.path.isfile(outfile1) and outfile1 != outfile2: if os.path.exists(outfile2): os.remove(outfile2) os.symlink(os.path.basename(outfile1), outfile2) ### read alignment results if not os.path.isfile(outfile1): apDisplay.printWarning("Image processing failed") self.badprocess = True return self.data = tiltfile.readData(outfile1) self.currentpicks1 = numpy.asarray(self.data['picks1']) self.currentpicks2 = numpy.asarray(self.data['picks2']) #print self.data # 1. tilt data are copied to self.tiltparams by app # 2. particles picks are copied to self.peaks1 and self.peaks2 by app # 3. particle errors are copied to self.peakerrors by app # 4. assessment status is copied to self.assess self.peaktree1 = apPeaks.convertListToPeaks(self.currentpicks1, self.params) self.peaktree2 = apPeaks.convertListToPeaks(self.currentpicks2, self.params) self.peakerrors = self.getRmsdArray() self.getOverlap(imgpath, tiltpath)