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
Exemplo n.º 2
0
    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
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
	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