def from2Dinto1D(self, fftarray): ellipratio = self.ellipseParams['a'] / self.ellipseParams['b'] ellipangle = math.degrees(self.ellipseParams['alpha']) pixelrdata, PSDarray = ctftools.ellipticalAverage( fftarray, ellipratio, ellipangle, self.params['ringwidth'], full=False) return self.removeBlackCenter(pixelrdata * self.freq, PSDarray)
def from2Dinto1D(self, fftarray): if self.params['astig'] is False and self.ellipseParams is None: ### simple case: do a rotational average pixelrdata, PSDarray = ctftools.rotationalAverage(fftarray, self.params['ringwidth'], full=False) return self.removeBlackCenter(pixelrdata*self.freq, PSDarray) if self.ellipseParams is None: ### hard case: find ellipse and do a elliptical average blurArray = copy.deepcopy(fftarray) for blurIter in range(2): ### each time the image is blurred more blurArray = self.rotationBlur(blurArray, angle=1, numIter=3) self.findEllipseEdge(blurArray) if self.ellipseParams is None: apDisplay.printWarning("Failed to find ellipse, continuing with no astig") pixelrdata, PSDarray = ctftools.rotationalAverage(fftarray, self.params['ringwidth'], full=False) return self.removeBlackCenter(pixelrdata*self.freq, PSDarray) ellipratio = self.ellipseParams['a']/self.ellipseParams['b'] ellipangle = math.degrees(self.ellipseParams['alpha']) pixelrdata, PSDarray = ctftools.ellipticalAverage(fftarray, ellipratio, ellipangle, self.params['ringwidth'], full=False) return self.removeBlackCenter(pixelrdata*self.freq, PSDarray)
def from2Dinto1D(self, fftarray): ellipratio = self.ellipseParams['a']/self.ellipseParams['b'] ellipangle = math.degrees(self.ellipseParams['alpha']) pixelrdata, PSDarray = ctftools.ellipticalAverage(fftarray, ellipratio, ellipangle, self.params['ringwidth'], full=False) return self.removeBlackCenter(pixelrdata*self.freq, PSDarray)
def drawPowerSpecImage(self, origpowerspec, maxsize=1200): origpowerspec = ctftools.trimPowerSpectraToOuterResolution(origpowerspec, self.plotlimit2DAngstrom, self.trimfreq) if self.debug is True: print "origpowerspec shape", origpowerspec.shape #compute elliptical average and merge with original image pixelrdata, rotdata = ctftools.ellipticalAverage(origpowerspec, self.ellipratio, self.angle, self.ringwidth*3, 1, full=True) ellipavgpowerspec = ctftools.unEllipticalAverage(pixelrdata, rotdata, self.ellipratio, self.angle, origpowerspec.shape) halfshape = origpowerspec.shape[1]/2 halfpowerspec = numpy.hstack( (origpowerspec[:,:halfshape] , ellipavgpowerspec[:,halfshape:] ) ) if halfpowerspec.shape != origpowerspec.shape: apDisplay.printError("Error in power spectra creation") if max(halfpowerspec.shape) > maxsize: scale = maxsize/float(max(halfpowerspec.shape)) #scale = math.sqrt((random.random()+random.random()+random.random())/3.0) apDisplay.printMsg( "Scaling final powerspec image by %.3f"%(scale)) powerspec = imagefilter.scaleImage(halfpowerspec, scale) else: scale = 1280./float(max(halfpowerspec.shape)) powerspec = imagefilter.scaleImage(halfpowerspec, scale) #scale = 1.0 #powerspec = halfpowerspec.copy() self.scaleapix = self.trimapix self.scalefreq = self.trimfreq/scale if self.debug is True: print "orig pixel", self.apix print "trim pixel", self.trimapix print "scale pixel", self.scaleapix numzeros = 13 radii1 = ctftools.getCtfExtrema(self.defocus1, self.scalefreq*1e10, self.cs, self.volts, self.ampcontrast, numzeros=numzeros, zerotype="valley") radii2 = ctftools.getCtfExtrema(self.defocus2, self.scalefreq*1e10, self.cs, self.volts, self.ampcontrast, numzeros=numzeros, zerotype="valley") #smallest of two defocii firstpeak = radii2[0] ### ### PART 9: DRAW THE 2D POWERSPEC IMAGE ### center = numpy.array(powerspec.shape, dtype=numpy.float)/2.0 foundzeros = min(len(radii1), len(radii2)) """ pyplot.clf() ax = pyplot.subplot(1,1,1) pyplot.xticks([], []) pyplot.yticks([], []) pyplot.imshow(powerspec) pyplot.gray() for i in range(foundzeros): # because |def1| < |def2| ==> firstzero1 > firstzero2 major = radii1[i]*2 minor = radii2[i]*2 ell = Ellipse(xy=center, width=major, height=minor, angle=self.angle+90, fill=False, edgecolor="yellow", antialiased=True, linewidth=0.5) ax.add_artist(ell) pyplot.subplots_adjust(wspace=0, hspace=0, bottom=0, left=0, top=1, right=1, ) self.newpowerspecfile = apDisplay.short(self.imgname)+"-powerspec-new.png" pyplot.savefig(self.newpowerspecfile, format="png", dpi=150, pad_inches=0.0) """ ### ### PART 9: DRAW THE 2D POWERSPEC IMAGE ### apDisplay.printColor("PART 9: DRAW THE 2D POWERSPEC IMAGE", "magenta") center = numpy.array(powerspec.shape, dtype=numpy.float)/2.0 originalimage = imagefile.arrayToImage(powerspec) originalimage = originalimage.convert("RGB") pilimage = originalimage.copy() draw = ImageDraw.Draw(pilimage) ######### ## draw astig axis line, if astig > 5% ######### perdiff = 2*abs(self.defocus1-self.defocus2)/abs(self.defocus1+self.defocus2) if self.debug is True: print "Percent Difference %.1f"%(perdiff*100) if perdiff > 0.05: #print self.angle, radii2[0], center x = 1*firstpeak*math.cos(math.radians(self.angle)) y = firstpeak*math.sin(math.radians(self.angle)) #print x,y xy = (x+center[0], y+center[1], -x+center[0], -y+center[1]) #print xy draw.line(xy, fill="#f23d3d", width=10) elif perdiff > 1e-6: #print self.angle, radii2[0], center x = 1*firstpeak*math.cos(math.radians(self.angle)) y = firstpeak*math.sin(math.radians(self.angle)) #print x,y xy = (x+center[0], y+center[1], -x+center[0], -y+center[1]) #print xy draw.line(xy, fill="#f23d3d", width=2) ######### ## draw colored CTF Thon rings ######### foundzeros = min(len(radii1), len(radii2)) #color="#3d3dd2" #blue color="#ffd700" #gold for i in range(foundzeros): # because |def1| < |def2| ==> firstzero1 > firstzero2 major = radii1[i] minor = radii2[i] if self.debug is True: print "major=%.1f, minor=%.1f, angle=%.1f"%(major, minor, self.angle) if minor > powerspec.shape[0]/math.sqrt(3): # this limits how far we draw out the ellipses sqrt(3) to corner, just 2 inside line break width = int(math.ceil(math.sqrt(numzeros - i)))*2 ### determine color of circle currentres = 1.0/(major*self.scalefreq) if currentres > self.res80: ringcolor = "green" elif currentres > self.res50: ringcolor = "gold" else: ringcolor = "red" ### determine number of points to use to draw ellipse, minimize distance btw points #isoceles triangle, b: radius ot CTF ring, a: distance btw points #a = 2 * b sin (theta/2) #a / 2b = sin(theta/2) #theta = 2 * asin (a/2b) #numpoints = 2 pi / theta ## define a to be 5 pixels a = 40 theta = 2.0 * math.asin (a/(2.0*major)) skipfactor = 2 numpoints = int(math.ceil(2.0*math.pi/theta/skipfactor))*skipfactor + 1 #print "numpoints", numpoints points = ellipse.generate_ellipse(major, minor, math.radians(self.angle), center, numpoints, None, "step", True) x = points[:,0] y = points[:,1] ## wrap around to end x = numpy.hstack((x, [x[0],])) y = numpy.hstack((y, [y[0],])) ## convert image numsteps = int(math.floor((len(x)-2)/skipfactor)) for j in range(numsteps): k = j*skipfactor xy = (x[k], y[k], x[k+1], y[k+1]) draw.line(xy, fill=ringcolor, width=width) ######### ## draw blue resolution ring ######### # 1/res = freq * pixrad => pixrad = 1/(res*freq) maxrad = (max(powerspec.shape)-1)/2.0 - 3 maxres = 1.0/(self.scalefreq*maxrad) bestres = math.ceil(maxres) pixrad = 1.0/(self.scalefreq*bestres) if self.debug is True: print "bestres %d Angstroms (max: %.3f)"%(bestres, maxres) print "pixrad %d (max: %.3f)"%(pixrad, maxrad) if pixrad > maxrad: apDisplay.printError("Too big of outer radius to draw") outpixrad = math.ceil(pixrad)+1 inpixrad = math.floor(pixrad)-1 for i in numpy.arange(-4.0,4.01,0.01): r = pixrad + i blackxy = numpy.array((center[0]-r,center[1]-r, center[0]+r,center[1]+r), dtype=numpy.float64) draw.ellipse(tuple(blackxy), outline="black") for i in numpy.arange(-1.50,1.51,0.01): r = pixrad + i whitexy = numpy.array((center[0]-r,center[1]-r, center[0]+r,center[1]+r), dtype=numpy.float64) draw.ellipse(tuple(whitexy), outline="#0BB5FF") ######### ## setup font to add text ######### fontpath = "/usr/share/fonts/liberation/LiberationSans-Regular.ttf" from PIL import ImageFont if os.path.isfile(fontpath): fontsize = int(math.ceil( 48/2. * min(powerspec.shape)/float(maxsize))*2) font = ImageFont.truetype(fontpath, fontsize) else: font = ImageFont.load_default() ######### ## add resolution ring text ######### angrad = maxrad/math.sqrt(2) + 1 coord = (angrad+maxrad, angrad+maxrad) for i in [-2,2]: for j in [-2,2]: draw.text((coord[0]+i,coord[1]+j), "%.1f A"%(bestres), font=font, fill="black") draw.text(coord, "%.1f A"%(bestres), font=font, fill="#0BB5FF") ######### ## add defocus value text ######### meandef = abs(self.defocus1+self.defocus2)/2.0 deftext = "%.2f um"%(meandef*1e6) tsize = draw.textsize(deftext, font=font) coord = (powerspec.shape[0]-4-tsize[0], powerspec.shape[0]-4-tsize[1]) for i in [-2,2]: for j in [-2,2]: draw.text((coord[0]+i,coord[1]+j), deftext, font=font, fill="black") draw.text(coord, deftext, font=font, fill="#AB82FF") ######### ## add text about what sides of powerspec are: ## left - raw data; right - elliptical average data ######### leftcoord = (4, 4) for i in [-3, -1, 0, 1, 3]: for j in [-3, -1, 0, 1, 3]: draw.text((leftcoord[0]+i,leftcoord[1]+j) , "Raw CTF Data", font=font, fill="black") draw.text(leftcoord, "Raw CTF Data", font=font, fill="#00BFFF") tsize = draw.textsize("Elliptical Average", font=font) xdist = powerspec.shape[0] - 4 - tsize[0] rightcoord = (xdist, 4) for i in [-2,2]: for j in [-2,2]: draw.text((rightcoord[0]+i,rightcoord[1]+j), "Elliptical Average", font=font, fill="black") draw.text(rightcoord, "Elliptical Average", font=font, fill="#00BFFF") ######### ## create an alpha blend effect ######### originalimage = Image.blend(originalimage, pilimage, 0.95) apDisplay.printMsg("Saving 2D powerspectra to file: %s"%(self.powerspecfile)) #pilimage.save(self.powerspecfile, "JPEG", quality=85) originalimage.save(self.powerspecfile, "JPEG", quality=85) if not os.path.isfile(self.powerspecfile): apDisplay.printWarning("power spec file not created") if self.debug is True: #powerspecjpg = Image.open(self.powerspecfile) #powerspecjpg.show() pass return
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