def fixAmpContrast(self, defocus, raddata, PSDarray, lowerbound, upperbound): if self.ctfvalues['amplitude_contrast'] > 0 and self.ctfvalues['amplitude_contrast'] < self.maxAmpCon: return defocus bad = True newdefocus = defocus count = 0 while count < 20: count += 1 amplitudecontrast = sinefit.refineAmplitudeContrast(raddata[lowerbound:upperbound]*1e10, newdefocus, PSDarray[lowerbound:upperbound], self.ctfvalues['cs'], self.wavelength, msg=self.debug) if amplitudecontrast is None: apDisplay.printWarning("FAILED to fix amplitude contrast") return defocus elif amplitudecontrast < 0: apDisplay.printColor("Amp Cont: %.3f too small, decrease defocus %.3e"% (amplitudecontrast, newdefocus), "blue") scaleFactor = 0.999 - abs(amplitudecontrast)/5. newdefocus = newdefocus*scaleFactor elif amplitudecontrast > self.maxAmpCon: apDisplay.printColor("Amp Cont: %.3f too large, increase defocus %.3e"% (amplitudecontrast, newdefocus), "cyan") scaleFactor = 1.001 + abs(amplitudecontrast - self.maxAmpCon)/5. newdefocus = newdefocus*scaleFactor else: apDisplay.printColor("Amp Cont: %.3f in range!!! defocus %.3e"% (amplitudecontrast, newdefocus), "green") avgres = self.getResolution(newdefocus, raddata, PSDarray, lowerbound) self.ctfvalues['amplitude_contrast'] = amplitudecontrast return newdefocus avgres = self.getResolution(newdefocus, raddata, PSDarray, lowerbound) if avgres < self.bestres: defocus = newdefocus apDisplay.printWarning("FAILED to fix amplitude contrast") return defocus
def fixAmpContrast(self, defocus, raddata, PSDarray, lowerbound, upperbound): if self.ctfvalues[ 'amplitude_contrast'] > self.minAmpCon and self.ctfvalues[ 'amplitude_contrast'] < self.maxAmpCon: return defocus bad = True newdefocus = defocus count = 0 while count < 20: count += 1 amplitudecontrast = sinefit.refineAmplitudeContrast( raddata[lowerbound:upperbound] * 1e10, newdefocus, PSDarray[lowerbound:upperbound], self.ctfvalues['cs'], self.wavelength, msg=self.debug) if amplitudecontrast is None: apDisplay.printWarning("FAILED to fix amplitude contrast") return defocus elif amplitudecontrast < self.minAmpCon: apDisplay.printColor( "Amp Cont: %.3f too small, decrease defocus %.3e" % (amplitudecontrast, newdefocus), "blue") scaleFactor = 0.999 - abs(amplitudecontrast) / 5. newdefocus = newdefocus * scaleFactor elif amplitudecontrast > self.maxAmpCon: apDisplay.printColor( "Amp Cont: %.3f too large, increase defocus %.3e" % (amplitudecontrast, newdefocus), "cyan") scaleFactor = 1.001 + abs(amplitudecontrast - self.maxAmpCon) / 5. newdefocus = newdefocus * scaleFactor else: apDisplay.printColor( "Amp Cont: %.3f in range!!! defocus %.3e" % (amplitudecontrast, newdefocus), "green") avgres = self.getResolution(newdefocus, raddata, PSDarray, lowerbound) self.ctfvalues['amplitude_contrast'] = amplitudecontrast return newdefocus avgres = self.getResolution(newdefocus, raddata, PSDarray, lowerbound) if avgres < self.bestres: defocus = newdefocus apDisplay.printWarning("FAILED to fix amplitude contrast") return defocus
def gridSearch(self, raddata, PSDarray, lowerbound, mindef=None, maxdef=None): #location of first zero is linear with 1/sqrt(z) if mindef is None: mindef = self.params['mindef'] if maxdef is None: maxdef = self.params['maxdef'] maxVal = 1.0/math.sqrt(mindef) minVal = 1.0/math.sqrt(maxdef) randNum = (random.random() + random.random() + random.random()) / 3.0 stepSize = 30 * randNum if self.params['fast'] is True: stepSize *= 2 invGuesses = numpy.arange(minVal, maxVal, stepSize) random.shuffle(invGuesses) bestres = 1000.0 oldampcontrast = self.ctfvalues['amplitude_contrast'] resVals = [] print "Guessing %d different defocus values"%(len(invGuesses)) for invDefocus in invGuesses: defocus = 1.0/invDefocus**2 ampcontrast = sinefit.refineAmplitudeContrast(raddata[lowerbound:]*1e10, defocus, PSDarray[lowerbound:], self.ctfvalues['cs'], self.wavelength, msg=False) if ampcontrast is not None: self.ctfvalues['amplitude_contrast'] = ampcontrast avgres = self.getResolution(defocus, raddata, PSDarray, lowerbound, show=False) apDisplay.printColor("Def %.3e; Res %.1f"%(defocus, avgres), "red") resVals.append(avgres) if avgres < bestres: bestdef = defocus bestres = avgres avgres = self.getResolution(defocus, raddata, PSDarray, lowerbound, show=True) self.ctfvalues['amplitude_contrast'] = oldampcontrast if self.debug is True: from matplotlib import pyplot pyplot.clf() pyplot.plot(1.0e6/numpy.power(invGuesses,2), resVals, "o") #pyplot.axis('auto') #pyplot.ylim(ymin=5, ymax=80) pyplot.yscale('log') pyplot.show() return bestdef
def gridSearch(self, raddata, PSDarray, lowerbound, mindef=None, maxdef=None): #location of first zero is linear with 1/sqrt(z) if mindef is None: mindef = self.params['mindef'] if maxdef is None: maxdef = self.params['maxdef'] maxVal = 1.0 / math.sqrt(mindef) minVal = 1.0 / math.sqrt(maxdef) randNum = (random.random() + random.random() + random.random()) / 3.0 stepSize = 30 * randNum if self.params['fast'] is True: stepSize *= 2 invGuesses = numpy.arange(minVal, maxVal, stepSize) random.shuffle(invGuesses) bestres = 1000.0 oldampcontrast = self.ctfvalues['amplitude_contrast'] resVals = [] print "Guessing %d different defocus values" % (len(invGuesses)) for invDefocus in invGuesses: defocus = 1.0 / invDefocus**2 ampcontrast = sinefit.refineAmplitudeContrast( raddata[lowerbound:] * 1e10, defocus, PSDarray[lowerbound:], self.ctfvalues['cs'], self.wavelength, msg=False) if ampcontrast is not None: self.ctfvalues['amplitude_contrast'] = ampcontrast avgres = self.getResolution(defocus, raddata, PSDarray, lowerbound, show=False) apDisplay.printColor("Def %.3e; Res %.1f" % (defocus, avgres), "red") resVals.append(avgres) if avgres < bestres: bestdef = defocus bestres = avgres avgres = self.getResolution(defocus, raddata, PSDarray, lowerbound, show=True) self.ctfvalues['amplitude_contrast'] = oldampcontrast if self.debug is True: from matplotlib import pyplot pyplot.clf() pyplot.plot(1.0e6 / numpy.power(invGuesses, 2), resVals, "o") #pyplot.axis('auto') #pyplot.ylim(ymin=5, ymax=80) pyplot.yscale('log') pyplot.show() return bestdef
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