Exemple #1
0
    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
Exemple #5
0
	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)
Exemple #6
0
	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
Exemple #7
0
    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)