def getResolution(self, defocus, raddata, PSD, lowerBoundIndex, show=True):

                ctffitdata = genctf.generateCTF1d(raddata*1e10, focus=defocus, cs=self.ctfvalues['cs'],
                        volts=self.ctfvalues['volts'], ampconst=self.ctfvalues['amplitude_contrast'], failParams=False)

                peaks = ctftools.getCtfExtrema(defocus, self.freq*1e10, self.ctfvalues['cs'], 
                        self.ctfvalues['volts'], self.ctfvalues['amplitude_contrast'], numzeros=25, zerotype="peak")

                ### get the confidence
                confraddata, confdata = ctfres.getCorrelationProfile(raddata, PSD, ctffitdata, peaks, self.freq)

                res5 = None
                res8 = None
                if confdata is not None and confdata.max() > self.maxAmpCon:
                        res5 = ctfres.getResolutionFromConf(confraddata, confdata, limit=0.5)
                        res8 = ctfres.getResolutionFromConf(confraddata, confdata, limit=0.8)

                if res8 is None:
                        res8 = 100
                if res5 is None:
                        res5 = 100

                if (res8+res5) < self.bestres and 0.0 < self.ctfvalues['amplitude_contrast'] < self.maxAmpCon:
                        apDisplay.printColor("Congrats! Saving best resolution values %.3e and %.2f"
                                %(defocus, self.ctfvalues['amplitude_contrast']), "green")
                        self.bestres = (res8+res5)
                        self.bestvalues = copy.deepcopy(self.ctfvalues)
                        self.bestvalues['defocus'] = defocus
                        self.bestellipse = copy.deepcopy(self.ellipseParams)
                elif show is True:
                        print "not saving values %.2f, need an average better than %.2f"%((res8+res5), self.bestres)

                ## normalize the data
                PSD -= (PSD[lowerBoundIndex:]).min()
                PSD /= numpy.abs(PSD[lowerBoundIndex:]).max()

                if self.debug is True and show is True:
                        ### Show the data
                        raddatasq = raddata**2
                        confraddatasq = confraddata**2
                        peakradii = ctftools.getCtfExtrema(defocus, self.freq*1e10,
                                self.ctfvalues['cs'], self.ctfvalues['volts'], self.ctfvalues['amplitude_contrast'],
                                numzeros=2, zerotype="peaks")
                        firstpeak = peakradii[0]

                        from matplotlib import pyplot
                        pyplot.clf()
                        ### raw powerspectra data
                        pyplot.plot(raddatasq[lowerBoundIndex:], PSD[lowerBoundIndex:], '-', color="red", alpha=0.5, linewidth=1)
                        ### ctf fit data
                        pyplot.plot(raddatasq[lowerBoundIndex:], ctffitdata[lowerBoundIndex:], '-', color="black", alpha=0.5, linewidth=1)
                        ### confidence profile
                        pyplot.plot(confraddatasq, confdata, '.', color="blue", alpha=0.9, markersize=10)
                        pyplot.plot(confraddatasq, confdata, '-', color="blue", alpha=0.9, linewidth=2)

                        pyplot.axvline(x=1/res8**2, linewidth=2, color="gold")
                        pyplot.axvline(x=1/res5**2, linewidth=2, color="red")
                
                        pyplot.title("Resolution values of %.3fA at 0.8 and %.3fA at 0.5"%(res8,res5))
                        pyplot.xlim(xmin=raddatasq[lowerBoundIndex-1], xmax=raddatasq.max())
                        pyplot.ylim(ymin=-0.05, ymax=1.05)
                        pyplot.subplots_adjust(wspace=0.05, hspace=0.05,
                                bottom=0.05, left=0.05, top=0.95, right=0.95, )
                        pyplot.show()

                apDisplay.printColor("Resolution values of %.4fA at 0.8 and %.4fA at 0.5"
                        %(res8,res5), "magenta")

                return (res8+res5)/2.0
Example #2
0
    def getResolution(self, defocus, raddata, PSD, lowerBoundIndex, show=True):

        ctffitdata = genctf.generateCTF1d(
            raddata * 1e10,
            focus=defocus,
            cs=self.ctfvalues['cs'],
            volts=self.ctfvalues['volts'],
            ampconst=self.ctfvalues['amplitude_contrast'],
            failParams=False)

        peaks = ctftools.getCtfExtrema(defocus,
                                       self.freq * 1e10,
                                       self.ctfvalues['cs'],
                                       self.ctfvalues['volts'],
                                       self.ctfvalues['amplitude_contrast'],
                                       numzeros=25,
                                       zerotype="peak")

        ### get the confidence
        confraddata, confdata = ctfres.getCorrelationProfile(
            raddata, PSD, ctffitdata, peaks, self.freq)

        res5 = None
        res8 = None
        if confdata is not None and confdata.max() > self.maxAmpCon:
            res5 = ctfres.getResolutionFromConf(confraddata,
                                                confdata,
                                                limit=0.5)
            res8 = ctfres.getResolutionFromConf(confraddata,
                                                confdata,
                                                limit=0.8)

        if res8 is None:
            res8 = 100
        if res5 is None:
            res5 = 100

        if (res8 + res5) < self.bestres and self.minAmpCon < self.ctfvalues[
                'amplitude_contrast'] < self.maxAmpCon:
            apDisplay.printColor(
                "Congrats! Saving best resolution values %.3e and %.2f" %
                (defocus, self.ctfvalues['amplitude_contrast']), "green")
            self.bestres = (res8 + res5)
            self.bestvalues = copy.deepcopy(self.ctfvalues)
            self.bestvalues['defocus'] = defocus
            self.bestellipse = copy.deepcopy(self.ellipseParams)
        elif show is True:
            if (res8 + res5) >= self.bestres:
                print(
                    "not saving values %.2f, need an average better than %.2f"
                    % ((res8 + res5), self.bestres))
            elif not (self.minAmpCon < self.ctfvalues['amplitude_contrast'] <
                      self.maxAmpCon):
                print(
                    "not saving values amplitude contrast %.4f out of range (%.4f <> %.4f)"
                    % (self.ctfvalues['amplitude_contrast'], self.minAmpCon,
                       self.maxAmpCon))
            else:
                apDisplay.printError("Something went wrong")

        ## normalize the data
        PSD -= (PSD[lowerBoundIndex:]).min()
        PSD /= numpy.abs(PSD[lowerBoundIndex:]).max()

        if self.debug is True and show is True:
            ### Show the data
            raddatasq = raddata**2
            confraddatasq = confraddata**2
            peakradii = ctftools.getCtfExtrema(
                defocus,
                self.freq * 1e10,
                self.ctfvalues['cs'],
                self.ctfvalues['volts'],
                self.ctfvalues['amplitude_contrast'],
                numzeros=2,
                zerotype="peaks")
            firstpeak = peakradii[0]

            from matplotlib import pyplot
            pyplot.clf()
            ### raw powerspectra data
            pyplot.plot(raddatasq[lowerBoundIndex:],
                        PSD[lowerBoundIndex:],
                        '-',
                        color="red",
                        alpha=0.5,
                        linewidth=1)
            ### ctf fit data
            pyplot.plot(raddatasq[lowerBoundIndex:],
                        ctffitdata[lowerBoundIndex:],
                        '-',
                        color="black",
                        alpha=0.5,
                        linewidth=1)
            ### confidence profile
            pyplot.plot(confraddatasq,
                        confdata,
                        '.',
                        color="blue",
                        alpha=0.9,
                        markersize=10)
            pyplot.plot(confraddatasq,
                        confdata,
                        '-',
                        color="blue",
                        alpha=0.9,
                        linewidth=2)

            pyplot.axvline(x=1 / res8**2, linewidth=2, color="gold")
            pyplot.axvline(x=1 / res5**2, linewidth=2, color="red")

            pyplot.title("Resolution values of %.3fA at 0.8 and %.3fA at 0.5" %
                         (res8, res5))
            pyplot.xlim(xmin=raddatasq[lowerBoundIndex - 1],
                        xmax=raddatasq.max())
            pyplot.ylim(ymin=-0.05, ymax=1.05)
            pyplot.subplots_adjust(
                wspace=0.05,
                hspace=0.05,
                bottom=0.05,
                left=0.05,
                top=0.95,
                right=0.95,
            )
            pyplot.show()

        apDisplay.printColor(
            "Resolution values of %.4fA at 0.8 and %.4fA at 0.5" %
            (res8, res5), "magenta")

        return (res8 + res5) / 2.0
	def normalizeCtf(self, zdata2d, twod=True):
		"""
		inner cut radius - radius for number of pixels to clip in the center of image
		"""
		### 
		### PART 1: SETUP PARAMETERS AND ELLIPTICAL AVERAGE
		###
		apDisplay.printColor("PART 1: SETUP PARAMETERS AND ELLIPTICAL AVERAGE", "magenta")

		meandefocus = math.sqrt(self.defocus1*self.defocus2)
		if meandefocus < 0.6e-6:
			self.ringwidth = 3.0
		elif meandefocus < 1.0e-6:
			self.ringwidth = 2.0
		elif meandefocus > 5.0e-6:
			self.ringwidth = 0.5

		### get all peak (not valley)
		peak = ctftools.getCtfExtrema(meandefocus, self.trimfreq*1e10, self.cs, self.volts, 
			self.ampcontrast, numzeros=250, zerotype="peak")
		apDisplay.printMsg("Number of available peaks is %d"%(len(peak)))
		if len(peak) < 6:
			apDisplay.printWarning("Too few peaks to work with, probably bad defocus estimate")
			return None
		firstpeak = peak[0]
		peakradii = numpy.array(peak, dtype=numpy.float64)*self.trimfreq
		### get all valley (not peak)
		valley = ctftools.getCtfExtrema(meandefocus, self.trimfreq*1e10, self.cs, self.volts, 
			self.ampcontrast, numzeros=250, zerotype="valley")
		firstvalley = valley[0]
		valleyradii = numpy.array(valley, dtype=numpy.float64)*self.trimfreq

		### do the elliptical average
		if self.ellipratio is None:
			return None
		pixelrdata, rotdata = ctftools.ellipticalAverage(zdata2d, self.ellipratio, self.angle,
			self.ringwidth, firstpeak, full=False)
		raddata = pixelrdata*self.trimfreq

		if self.debug is True:
			print "Elliptical CTF limits %.1f A -->> %.1fA"%(1./raddata.min(), 1./raddata.max())

		apDisplay.printMsg("Determine and subtract noise model")
		CtfNoise = ctfnoise.CtfNoise()

		### 
		### PART 2: BACKGROUND NOISE SUBTRACTION
		### 
		apDisplay.printColor("PART 2: BACKGROUND NOISE SUBTRACTION", "magenta")

		### split the function up in first 3/5 and last 3/5 of data with 1/5 overlap
		firstvalleyindex = numpy.searchsorted(raddata, self.trimfreq*firstvalley)
		numpoints = len(raddata) - firstvalleyindex
		# require at least 10 points past first peak of CTF to perform estimation
		if numpoints < 10:
			apDisplay.printWarning("Not enough points past first peak (n=%d < 10) to do background subtraction"
				%(numpoints))
			return None
		npart1start = firstvalleyindex
		npart1end = int(firstvalleyindex + numpoints*6/10.)
		npart2start = int(firstvalleyindex + numpoints*5/10.)
		npart2end = int(firstvalleyindex + numpoints*9/10.)
		npart3start = int(firstvalleyindex + numpoints*8/10.)
		npart3end = len(raddata)
		
		svalleydata = ctfnoise.peakExtender(raddata, rotdata, valleyradii, "below")

		### fit function below log(CTF), i.e., noise model	
		## first part data
		noisefitparams1 = CtfNoise.modelCTFNoise(raddata[npart1start:npart1end],
			svalleydata[npart1start:npart1end], "below")
		noisedata1 = CtfNoise.noiseModel(noisefitparams1, raddata)

		## second part data
		noisefitparams2 = CtfNoise.modelCTFNoise(raddata[npart2start:npart2end],
			rotdata[npart2start:npart2end], "below")
		noisedata2 = CtfNoise.noiseModel(noisefitparams2, raddata)

		## third part data
		#noisefitparams3 = CtfNoise.modelCTFNoise(raddata[npart3start:npart3end],
		#	svalleydata[npart3start:npart3end], "below")
		noisefitparams3 = CtfNoise.modelCTFNoise(raddata[npart3start:npart3end],
			rotdata[npart3start:npart3end], "below")
		noisedata3 = CtfNoise.noiseModel(noisefitparams3, raddata)

		## debug only
		if self.debug is True:
			singlenoisefitparams = CtfNoise.modelCTFNoise(raddata[npart1start:npart3end],
				svalleydata[npart1start:npart3end], "below")
			singlenoisedata = CtfNoise.noiseModel(singlenoisefitparams, raddata)

		## merge data
		scale = numpy.arange(npart1end-npart2start, dtype=numpy.float32)
		scale /= scale.max()
		overlapdata1 = noisedata1[npart2start:npart1end]*(1-scale) + noisedata2[npart2start:npart1end]*scale
		scale = numpy.arange(npart2end-npart3start, dtype=numpy.float32)
		scale /= scale.max()
		overlapdata2 = noisedata2[npart3start:npart2end]*(1-scale) + noisedata3[npart3start:npart2end]*scale

		mergedata = numpy.hstack((noisedata1[:npart2start], overlapdata1,
			noisedata2[npart1end:npart3start], overlapdata2,
			noisedata3[npart2end:]))

		noisedata = mergedata

		### DO THE SUBTRACTION
		normexprotdata = numpy.exp(rotdata) - numpy.exp(noisedata)

		### CUT OUT ANY NEGATIVE VALUES FOR DISPLAY AND FITTING PURPOSES ONLY
		minval = -1
		mindata = ndimage.maximum_filter(normexprotdata, 2)
		count = 0
		while minval < 3 and count < 10:
			count += 1
			mindata = ndimage.maximum_filter(mindata, 2)
			minval = mindata.min()
			if self.debug is True:
				apDisplay.printMsg("Minimum value for normalization: %.3f"%(minval))
		if minval < 3:
			minval = 3
		normlogrotdata = numpy.log(numpy.where(normexprotdata<minval, minval, normexprotdata))
		if numpy.isnan(normlogrotdata).any() is True:
			apDisplay.printError("Error in log normalization of CTF data")

		### 
		### PART 3: ENVELOPE NORMALIZATION
		### 
		apDisplay.printColor("PART 3: ENVELOPE NORMALIZATION", "magenta")

		### split the function up in first 3/5 and last 3/5 of data with 1/5 overlap
		firstpeakindex = numpy.searchsorted(raddata, firstpeak*self.trimfreq)
		numpoints = len(raddata) - firstpeakindex
		epart1start = firstpeakindex
		epart1end = int(firstpeakindex + numpoints*6/10.)
		epart2start = int(firstpeakindex + numpoints*5/10.)
		epart2end = int(firstpeakindex + numpoints*9/10.)
		epart3start = int(firstpeakindex + numpoints*8/10.)
		epart3end = len(raddata)

		peakdata = ctfnoise.peakExtender(raddata, normlogrotdata, peakradii, "above")

		## first part data
		envelopfitparams1 = CtfNoise.modelCTFNoise(raddata[epart1start:epart1end],
			peakdata[epart1start:epart1end], "above")
		envelopdata1 = CtfNoise.noiseModel(envelopfitparams1, raddata)

		## second part data
		envelopfitparams2 = CtfNoise.modelCTFNoise(raddata[epart2start:epart2end],
			peakdata[epart2start:epart2end], "above")
		envelopdata2 = CtfNoise.noiseModel(envelopfitparams2, raddata)

		## third part data
		envelopfitparams3 = CtfNoise.modelCTFNoise(raddata[epart3start:epart3end],
			peakdata[epart3start:epart3end], "above")
		envelopdata3 = CtfNoise.noiseModel(envelopfitparams3, raddata)

		## merge data
		scale = numpy.arange(epart1end-epart2start, dtype=numpy.float32)
		scale /= scale.max()
		overlapdata1 = envelopdata1[epart2start:epart1end]*(1-scale) + envelopdata2[epart2start:epart1end]*scale
		scale = numpy.arange(epart2end-epart3start, dtype=numpy.float32)
		scale /= scale.max()
		overlapdata2 = envelopdata2[epart3start:epart2end]*(1-scale) + envelopdata3[epart3start:epart2end]*scale

		mergedata = numpy.hstack((envelopdata1[:epart2start], overlapdata1,
			envelopdata2[epart1end:epart3start], overlapdata2,
			envelopdata3[epart2end:]))
		envelopdata = mergedata

		normnormexprotdata = normexprotdata / numpy.exp(envelopdata)

		### 
		### PART 4: PEAK EXTENSION
		### 
		apDisplay.printColor("PART 4: PEAK EXTENSION", "magenta")

		### Subtract fit valley locations
		valleydata = ctfnoise.peakExtender(raddata, normnormexprotdata, valleyradii, "below")
		valleydata = ndimage.gaussian_filter1d(valleydata, 1)
		normvalleydata = normnormexprotdata - valleydata

		### Normalize fit peak locations
		peakdata = ctfnoise.peakExtender(raddata, normvalleydata, peakradii, "above")
		peakdata = ndimage.gaussian_filter1d(peakdata, 1)
		normpeakdata = normvalleydata / peakdata

		### 
		### PART 5: CTF FIT AND CONFIDENCE
		### 
		apDisplay.printColor("PART 5: CTF FIT AND CONFIDENCE", "magenta")

		### everything in mks units, because rdata is 1/A multiply be 1e10 to get 1/m
		ctffitdata = genctf.generateCTF1d(raddata*1e10, focus=meandefocus, cs=self.cs,
			volts=self.volts, ampconst=self.ampcontrast, failParams=False)
		#ctffitdata2 = genctf.generateCTF1dACE2(raddata*1e10, focus=meandefocus, cs=self.cs,
		#	volts=self.volts, ampconst=self.ampcontrast, failParams=False)
		overctffitdata = genctf.generateCTF1d(raddata*1e10, focus=meandefocus, cs=self.cs,
			volts=self.volts, ampconst=self.ampcontrast, failParams=False, overfocus=True)

		ind30 = numpy.searchsorted(raddata, 1/30.)
		ind10 = numpy.searchsorted(raddata, 1/10.)
		self.conf3010 = scipy.stats.pearsonr(normpeakdata[ind30:ind10], ctffitdata[ind30:ind10])[0]
		self.overconf3010 = scipy.stats.pearsonr(normpeakdata[ind30:ind10], overctffitdata[ind30:ind10])[0]
		apDisplay.printColor("1/30A - 1/10A confidence is %.3f (overfocus %.3f)"%(self.conf3010, self.overconf3010), "green")
		if self.overconf3010 > self.conf3010*1.1:
			apDisplay.printWarning("Image is possibly over-focused")

		ind5peak1 = numpy.searchsorted(raddata, peakradii[0])
		ind5peak2 = numpy.searchsorted(raddata, peakradii[5])
		self.conf5peak = scipy.stats.pearsonr(normpeakdata[ind5peak1:ind5peak2], ctffitdata[ind5peak1:ind5peak2])[0]
		self.overconf5peak = scipy.stats.pearsonr(normpeakdata[ind5peak1:ind5peak2], overctffitdata[ind5peak1:ind5peak2])[0]
		apDisplay.printColor("5 peak confidence is %.3f (overfocus %.3f)"%(self.conf5peak, self.overconf5peak), "green")
		if self.overconf5peak > self.conf5peak*1.1:
			apDisplay.printWarning("Image is possibly over-focused")

		### 
		### PART 6: CTF RESOLUTION LIMITS
		### 
		apDisplay.printColor("PART 6: CTF RESOLUTION LIMITS", "magenta")

		confraddata, confdata = ctfres.getCorrelationProfile(raddata, 
			normpeakdata, ctffitdata, peak, self.trimfreq)
		overconfraddata, overconfdata = ctfres.getCorrelationProfile(raddata, 
			normpeakdata, overctffitdata, peak, self.trimfreq)

		self.res80 = ctfres.getResolutionFromConf(confraddata, confdata, limit=0.8)
		if self.res80 is None:
			self.res80 = 100.0
		self.overres80 = ctfres.getResolutionFromConf(overconfraddata, overconfdata, limit=0.8)
		if self.overres80 is None:
			self.overres80 = 100.0
		self.res50 = ctfres.getResolutionFromConf(confraddata, confdata, limit=0.5)
		if self.res50 is None:
			self.res50 = 100.0
			res50max = min(raddata.max(), 1/10.)
		elif self.res50 > 15.0:
			res50max = min(raddata.max(), 1/10.)
		else:
			res50max = min(raddata.max(), 1.5/self.res50)
		self.overres50 = ctfres.getResolutionFromConf(overconfraddata, overconfdata, limit=0.5)
		if self.overres50 is None:
			self.overres50 = 100.0


		apDisplay.printColor("Resolution limit is %.2f at 0.8 and %.2f at 0.5"
			%(self.res80, self.res50), "green")

		### 
		### PART 7: MAKE 1D PLOT SUMMARY FIGURE
		### 
		apDisplay.printColor("PART 7: MAKE 1D PLOT SUMMARY FIGURE", "magenta")

		titlefontsize=8
		axisfontsize=7
		raddatasq = raddata**2
		confraddatasq = confraddata**2
		valleyradiisq = valleyradii**2
		peakradiisq = peakradii**2
		fpi = firstpeakindex

		pyplot.clf()

		if 'subplot2grid' in dir(pyplot):
			pyplot.subplot2grid((3,2), (0,0))
		else:
			pyplot.subplot(2,2,1) # 2 rows, 2 columns, plot 1
		pyplot.title("Background Noise Subtraction", fontsize=titlefontsize)
		pyplot.ylabel("Log(PSD)", fontsize=axisfontsize)
		pyplot.plot(raddata[fpi:], rotdata[fpi:], 
			'-', color="blue", alpha=0.5, linewidth=0.5)
		pyplot.plot(raddata[fpi:], rotdata[fpi:], 
			'.', color="blue", alpha=0.75, markersize=2.0)
		pyplot.plot(raddata[npart1start:npart1end], noisedata1[npart1start:npart1end],
			'-', color="magenta", alpha=0.5, linewidth=2)
		pyplot.plot(raddata[npart2start:npart2end], noisedata2[npart2start:npart2end],
			'-', color="red", alpha=0.5, linewidth=2)
		pyplot.plot(raddata[npart3start:npart3end], noisedata3[npart3start:npart3end], 
			'-', color="orange", alpha=0.5, linewidth=2)
		pyplot.plot(raddata[fpi:], noisedata[fpi:], 
			'--', color="purple", alpha=1.0, linewidth=1)
		self.setPyPlotXLabels(raddata, valleyradii=valleyradii, maxloc=res50max)
		pyplot.ylim(ymin=noisedata.min())

		if 'subplot2grid' in dir(pyplot):
			pyplot.subplot2grid((3,2), (0,1))
		else:
			pyplot.subplot(2,2,2) # 2 rows, 2 columns, plot 2
		pyplot.title("Envelope Normalization", fontsize=titlefontsize)
		pyplot.ylabel("Log(PSD-Noise)", fontsize=axisfontsize)
		pyplot.plot(raddata[fpi:], normlogrotdata[fpi:],
			'-', color="blue", alpha=0.5, linewidth=0.5)
		pyplot.plot(raddata[fpi:], normlogrotdata[fpi:],
			'.', color="blue", alpha=0.75, markersize=2.0)
		pyplot.plot(raddata[epart1start:epart1end], envelopdata1[epart1start:epart1end],
			'-', color="magenta", alpha=0.5, linewidth=2)
		pyplot.plot(raddata[epart2start:epart2end], envelopdata2[epart2start:epart2end],
			'-', color="red", alpha=0.5, linewidth=2)
		pyplot.plot(raddata[epart3start:epart3end], envelopdata3[epart3start:epart3end],
			'-', color="orange", alpha=0.5, linewidth=2)
		pyplot.plot(raddata[fpi:], envelopdata[fpi:],
			'--', color="purple", alpha=1.0, linewidth=1)
		self.setPyPlotXLabels(raddata, peakradii=peakradii, maxloc=res50max)
		pyplot.ylim(ymax=envelopdata.max())

		if 'subplot2grid' in dir(pyplot):
			pyplot.subplot2grid((3,2), (1,0), colspan=2)
		else:
			pyplot.subplot(2,2,3) # 2 rows, 2 columns, plot 3
		pyplot.title("Fit of CTF data (30-10A %.3f / 5-peak %.3f) Def1= %.3e / Def2= %.3e"
			%(self.conf3010, self.conf5peak, self.defocus1, self.defocus2), fontsize=titlefontsize)
		pyplot.ylabel("Norm PSD", fontsize=titlefontsize)
		pyplot.plot(raddatasq[fpi:], ctffitdata[fpi:],
			'-', color="black", alpha=0.5, linewidth=1)
		#pyplot.plot(raddatasq[fpi:], overctffitdata[fpi:],
		#	'-', color="red", alpha=0.75, linewidth=1)
		pyplot.plot(raddatasq[fpi:], normpeakdata[fpi:],
			'-', color="blue", alpha=0.5, linewidth=0.5)
		pyplot.plot(raddatasq[fpi:], normpeakdata[fpi:],
			'.', color="blue", alpha=0.75, markersize=2.0)
		self.setPyPlotXLabels(raddatasq, maxloc=1.0/self.outerAngstrom1D**2, square=True)
		pyplot.grid(True, linestyle=':', )
		pyplot.ylim(-0.05, 1.05)

		"""
		pyplot.subplot2grid((3,2), (1,1))
		tenangindex = numpy.searchsorted(raddata, 1/10.)-1
		pyplot.title("Defocus1= %.3e / Defocus2= %.3e"
			%(self.defocus1, self.defocus2), fontsize=titlefontsize)
		pyplot.ylabel("Norm PSD", fontsize=titlefontsize)
		pyplot.plot(raddatasq[tenangindex:], ctffitdata[tenangindex:],
			'-', color="black", alpha=0.5, linewidth=1)
		pyplot.plot(raddatasq[tenangindex:], normpeakdata[tenangindex:],
			'-', color="blue", alpha=0.5, linewidth=0.5)
		pyplot.plot(raddatasq[tenangindex:], normpeakdata[tenangindex:],
			'.', color="blue", alpha=0.75, markersize=2.0)
		self.setPyPlotXLabels(raddatasq[tenangindex:], maxloc=1/7.**2, square=True)
		pyplot.grid(True, linestyle=':', )
		pyplot.ylim(-0.05, 1.05)
		"""

		if 'subplot2grid' in dir(pyplot):
			pyplot.subplot2grid((3,2), (2,0), colspan=2)
		else:
			pyplot.subplot(2,2,4) # 2 rows, 2 columns, plot 4
		pyplot.title("Resolution limits: %.2fA at 0.8 and %.2fA at 0.5"
			%(self.res80, self.res50), fontsize=titlefontsize)
		pyplot.ylabel("Correlation", fontsize=titlefontsize)
		pyplot.plot(raddata[fpi:], ctffitdata[fpi:],
			'-', color="black", alpha=0.2, linewidth=1)
		pyplot.plot(raddata[fpi:], normpeakdata[fpi:],
			'-', color="blue", alpha=0.2, linewidth=1)
		#pyplot.plot(raddata[fpi:], normpeakdata[fpi:],
		#	'.', color="black", alpha=0.25, markersize=1.0)
		pyplot.axvline(x=1.0/self.res80, linewidth=2, color="gold", alpha=0.95, ymin=0, ymax=0.8)
		pyplot.axvline(x=1.0/self.res50, linewidth=2, color="red", alpha=0.95, ymin=0, ymax=0.5)
		res80index = numpy.searchsorted(confraddata, 1.0/self.res80)
		pyplot.plot(confraddata[:res80index+1], confdata[:res80index+1],
			'-', color="green", alpha=1, linewidth=2)
		res50index = numpy.searchsorted(confraddata, 1.0/self.res50)
		pyplot.plot(confraddata[res80index-1:res50index+1], confdata[res80index-1:res50index+1],
			'-', color="orange", alpha=1, linewidth=2)
		pyplot.plot(confraddata[res50index-1:], confdata[res50index-1:],
			'-', color="red", alpha=1, linewidth=2)
		self.setPyPlotXLabels(raddata, maxloc=res50max)
		pyplot.grid(True, linestyle=':', )
		if self.res80 < 99:
			pyplot.ylim(-0.05, 1.05)
		elif self.res50 < 99:
			pyplot.ylim(-0.25, 1.05)
		else:
			pyplot.ylim(-0.55, 1.05)


		pyplot.subplots_adjust(wspace=0.22, hspace=0.50, 
			bottom=0.08, left=0.07, top=0.95, right=0.965, )
		self.plotsfile = apDisplay.short(self.imgname)+"-plots.png"
		apDisplay.printMsg("Saving 1D graph to file %s"%(self.plotsfile))
		pyplot.savefig(self.plotsfile, format="png", dpi=300, orientation='landscape', pad_inches=0.0)


		if self.debug is True:
			### write a 1d profile dat files

			f = open(apDisplay.short(self.imgname)+"-noise_fit.dat", "w")
			for i in range(npart1start, npart3end):
				f.write("%.16f\t%.16f\t%.16f\t%.16f\n"%(raddata[i], rotdata[i], singlenoisedata[i], noisedata[i]))
			f.write("&\n")
			for i in range(npart1start, npart1end):
				f.write("%.16f\t%.16f\n"%(raddata[i], noisedata1[i]))
			f.write("&\n")
			for i in range(npart2start, npart2end):
				f.write("%.16f\t%.16f\n"%(raddata[i], noisedata2[i]))
			f.write("&\n")
			for i in range(npart3start, npart3end):
				f.write("%.16f\t%.16f\n"%(raddata[i], noisedata3[i]))
			f.write("&\n")
			f.close()

			#smallrotdata = numpy.where(rotdata-singlenoisedata>0.19, 0.19, rotdata-singlenoisedata)
			noiseexp = numpy.exp(singlenoisedata)
			smallrotdata = numpy.exp(rotdata) - noiseexp
			minval = 3

			smallrotdata = numpy.log(numpy.where(smallrotdata<minval, minval, smallrotdata))
			smallnoise = numpy.exp(noisedata) - noiseexp
			smallnoise = numpy.log(numpy.where(smallnoise<minval, minval, smallnoise))
			smallnoise1 = numpy.exp(noisedata1) - noiseexp
			smallnoise1 = numpy.log(numpy.where(smallnoise1<minval, minval, smallnoise1))
			smallnoise2 = numpy.exp(noisedata2) - noiseexp
			smallnoise2 = numpy.log(numpy.where(smallnoise2<minval, minval, smallnoise2))
			smallnoise3 = numpy.exp(noisedata3) - noiseexp
			smallnoise3 = numpy.log(numpy.where(smallnoise3<minval, minval, smallnoise3))
			f = open(apDisplay.short(self.imgname)+"-noisesubt_fit.dat", "w")
			for i in range(len(ctffitdata)):
				f.write("%.16f\t%.16f\n"%(raddata[i], smallrotdata[i]))
			f.write("&\n")
			for i in range(npart1start, npart3end):
				f.write("%.16f\t%.16f\t%.16f\t%.16f\n"%(raddata[i], smallrotdata[i], smallnoise[i], 0))
			f.write("&\n")
			for i in range(npart1start, npart1end):
				f.write("%.16f\t%.16f\n"%(raddata[i], smallnoise1[i]))
			f.write("&\n")
			for i in range(npart2start, npart2end):
				f.write("%.16f\t%.16f\n"%(raddata[i], smallnoise2[i]))
			f.write("&\n")
			for i in range(npart3start, npart3end):
				f.write("%.16f\t%.16f\n"%(raddata[i], smallnoise3[i]))
			f.write("&\n")
			f.close()

			f = open(apDisplay.short(self.imgname)+"-ctf_fit.dat", "w")
			for i in range(len(ctffitdata)):
				f.write("%.16f\t%.16f\t%.16f\n"%(raddata[i], normpeakdata[i], ctffitdata[i]))
			f.close()
			#sys.exit(1)

		if self.debug is True:
			print "Showing results"
			#pyplot.show()
			#plotspng = Image.open(self.plotsfile)
			#plotspng.show()
		pyplot.clf()

		if twod is False:
			return zdata2d

		### 
		### PART 8: NORMALIZE THE 2D IMAGE
		### 
		apDisplay.printColor("PART 8: NORMALIZE THE 2D IMAGE", "magenta")

		### Convert 1D array into 2D array by un-elliptical average
		noise2d = ctftools.unEllipticalAverage(pixelrdata, noisedata,
			self.ellipratio, self.angle, zdata2d.shape)
		envelop2d = ctftools.unEllipticalAverage(pixelrdata, envelopdata,
			self.ellipratio, self.angle, zdata2d.shape)
		valley2d = ctftools.unEllipticalAverage(pixelrdata, valleydata,
			self.ellipratio, self.angle, zdata2d.shape)
		peak2d = ctftools.unEllipticalAverage(pixelrdata, peakdata,
			self.ellipratio, self.angle, zdata2d.shape)

		### Do the normalization on the 2d data
		#blur2d = ndimage.gaussian_filter(zdata2d, 2)
		normal2d = numpy.exp(zdata2d) - numpy.exp(noise2d)
		normal2d = normal2d / numpy.exp(envelop2d)
		normal2d = normal2d - valley2d
		normal2d = normal2d / peak2d
		normal2d = numpy.where(normal2d < -0.2, -0.2, normal2d)
		normal2d = numpy.where(normal2d > 1.2, 1.2, normal2d)

		return normal2d