Esempio n. 1
0
	def doRefit(self):
		parms=self.parms[self.curset]
		apix=self.sapix.getValue()
		ds=1.0/(apix*parms[0]*parms[5])

		try:
			parms[1]=e2ctf.ctf_fit(self.fft1d,parms[1].background,parms[1].background,self.fft,self.fftbg,parms[1].voltage,parms[1].cs,parms[1].ampcont,apix,bgadj=False,autohp=True,verbose=1)
			if self.cbgadj.getValue() :
				self.bgAdj()
				parms[1]=e2ctf.ctf_fit(self.fft1d,parms[1].background,parms[1].background,self.fft,self.fftbg,parms[1].voltage,parms[1].cs,parms[1].ampcont,apix,bgadj=False,autohp=True,verbose=1)
				if self.fitastig : e2ctf.ctf_fit_stig(self.fft,self.fftbg,parms[1],verbose=1)
				self.bgAdj()
			else:
				if self.fitastig : e2ctf.ctf_fit_stig(self.fft,self.fftbg,parms[1],verbose=1)

		except:
			print "CTF Autofit Failed"
			traceback.print_exc()
			parms[1].defocus=1.0

		if self.constbfactor>0 : parms[1].bfactor=self.constbfactor
		self.sdefocus.setValue(parms[1].defocus,True)
		self.sbfactor.setValue(parms[1].bfactor,True)
		self.sampcont.setValue(parms[1].ampcont,True)

		self.update_plot()
Esempio n. 2
0
	def doRefit(self):
		parms=self.parms[self.curset]
		apix=self.sapix.getValue()
		ds=1.0/(apix*parms[0]*parms[5])

		try:
			parms[1]=e2ctf.ctf_fit(self.fft1d,parms[1].background,parms[1].background,self.fft,self.fftbg,parms[1].voltage,parms[1].cs,parms[1].ampcont,apix,bgadj=False,autohp=True,verbose=1)
			if self.cbgadj.getValue() :
				self.bgAdj()
				parms[1]=e2ctf.ctf_fit(self.fft1d,parms[1].background,parms[1].background,self.fft,self.fftbg,parms[1].voltage,parms[1].cs,parms[1].ampcont,apix,bgadj=False,autohp=True,verbose=1)
				if self.fitastig : e2ctf.ctf_fit_stig(self.fft,self.fftbg,parms[1],verbose=1)
				self.bgAdj()
			else:
				if self.fitastig : e2ctf.ctf_fit_stig(self.fft,self.fftbg,parms[1],verbose=1)

		except:
			print "CTF Autofit Failed"
			traceback.print_exc()
			parms[1].defocus=1.0

		if self.constbfactor>0 : parms[1].bfactor=self.constbfactor
		self.sdefocus.setValue(parms[1].defocus,True)
		self.sbfactor.setValue(parms[1].bfactor,True)
		self.sampcont.setValue(parms[1].ampcont,True)

		self.update_plot()
Esempio n. 3
0
def importfn(i,arg,options):
	base = base_name(arg,nodir=not options.usefoldername)
	output = os.path.join(os.path.join(".","micrographs"),base+".hdf")
	cmd = "e2proc2d.py %s %s --inplace"%(arg,output)

	cmdext=[]
	if options.invert: cmdext.append(" --mult=-1")
	if options.edgenorm: cmdext.append(" --process=normalize.edgemean")
	if options.xraypixel: cmdext.append(" --process=threshold.clampminmax.nsigma:nsigma=4")
	if len(cmdext)>0 or arg!=output:
		cmd+="".join(cmdext)
		launch_childprocess(cmd)

	if options.moverawdata:
		os.rename(arg,os.path.join(originalsdir,os.path.basename(arg)))
		
	# We estimate the defocus and B-factor (no astigmatism) from the micrograph and store it in info and the header
	if options.ctfest :
		d=EMData(output,0)
		if d["nx"]<1000 or d["ny"]<1000 : 
			print("CTF estimation will only work with images at least 1000x1000 in size")
			sys.exit(1)
		if d["nx"]<2000 : box=256
		elif d["nx"]<4000 : box=512
		elif d["nx"]<6000 : box=768
		else : box=1024

		import e2ctf
		
		ds=1.0/(options.apix*box)
		ffta=None
		nbx=0
		for x in range(100,d["nx"]-box,box):
			for y in range(100,d["ny"]-box,box):
				clip=d.get_clip(Region(x,y,box,box))
				clip.process_inplace("normalize.edgemean")
				fft=clip.do_fft()
				fft.ri2inten()
				if ffta==None: ffta=fft
				else: ffta+=fft
				nbx+=1

		ffta.mult(1.0/(nbx*box**2))
		ffta.process_inplace("math.sqrt")
		ffta["is_intensity"]=0				# These 2 steps are done so the 2-D display of the FFT looks better. Things would still work properly in 1-D without it

		fftbg=ffta.process("math.nonconvex")
		fft1d=ffta.calc_radial_dist(ffta.get_ysize()/2,0.0,1.0,1)	# note that this handles the ri2inten averages properly

		# Compute 1-D curve and background
		bg_1d=e2ctf.low_bg_curve(fft1d,ds)

		#initial fit, background adjustment, refine fit, final background adjustment
		ctf=e2ctf.ctf_fit(fft1d,bg_1d,bg_1d,ffta,fftbg,options.voltage,options.cs,options.ac,options.phaseplate,options.apix,1,dfhint=(options.defocusmin,options.defocusmax))
		bgAdj(ctf,fft1d)
		ctf=e2ctf.ctf_fit(fft1d,ctf.background,ctf.background,ffta,fftbg,options.voltage,options.cs,options.ac,options.phaseplate,options.apix,1,dfhint=(options.defocusmin,options.defocusmax))
		bgAdj(ctf,fft1d)
		
		if options.astigmatism : e2ctf.ctf_fit_stig(ffta,fftbg,ctf)
		
		#ctf.background=bg_1d
		#ctf.dsbg=ds
		db=js_open_dict(info_name(arg,nodir=not options.usefoldername))
		db["ctf_frame"]=[box,ctf,(box/2,box/2),set(),5,1]
		db["quality"]=5
		db.close()
		print(info_name(arg,nodir=not options.usefoldername),ctf)
Esempio n. 4
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] <micrograph1, micrograph2....>
	Use this program to import and filter raw micrographs. If you choose to filter and/or convert format, this program will process each micrograph
	and dump them into the directory './micrographs.', otherwise the micrographs will simply be moved into './micrographs'. If you select the option
	--moverawdata AND you filter or change format, your original micrographs will be moved into the directory './raw_micrographs' and your
	filtered micrographs will be in './micrographs as usual. BDB files are not moved, but they can be processed."""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_pos_argument(
        name="micrographs",
        help="List the micrographs to filter here.",
        default="",
        guitype='filebox',
        browser="EMRawDataTable(withmodal=True,multiselect=True)",
        row=0,
        col=0,
        rowspan=1,
        colspan=2,
        mode='filter')
    parser.add_pos_argument(
        name="import_files",
        help="List the files to import/filter here.",
        default="",
        guitype='filebox',
        browser="EMBrowserWidget(withmodal=True,multiselect=True)",
        row=0,
        col=0,
        rowspan=1,
        colspan=2,
        mode='import')
    parser.add_header(
        name="filterheader",
        help='Options below this label are specific to filtering',
        title="### filtering options ###",
        row=1,
        col=0,
        rowspan=1,
        colspan=2,
        mode='import,filter')
    parser.add_argument("--invert",
                        action="store_true",
                        help="Invert contrast",
                        default=False,
                        guitype='boolbox',
                        row=2,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode='filter[True]')
    parser.add_argument("--edgenorm",
                        action="store_true",
                        help="Edge normalize",
                        default=False,
                        guitype='boolbox',
                        row=2,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode='filter[True]')
    parser.add_argument(
        "--usefoldername",
        action="store_true",
        help=
        "If you have the same image filename in multiple folders, and need to import into the same project, this will prepend the folder name on each image name",
        default=False,
        guitype='boolbox',
        row=2,
        col=2,
        rowspan=1,
        colspan=1,
        mode="import[False]")
    parser.add_argument("--xraypixel",
                        action="store_true",
                        help="Filter X-ray pixels",
                        default=False,
                        guitype='boolbox',
                        row=3,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode='filter[True]')
    parser.add_argument("--ctfest",
                        action="store_true",
                        help="Estimate defocus from whole micrograph",
                        default=False,
                        guitype='boolbox',
                        row=3,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode='filter[True]')
    parser.add_argument("--astigmatism",
                        action="store_true",
                        help="Includes astigmatism in automatic fitting",
                        default=False,
                        guitype='boolbox',
                        row=3,
                        col=2,
                        rowspan=1,
                        colspan=1,
                        mode='filter[False]')
    parser.add_argument(
        "--moverawdata",
        action="store_true",
        help="Move raw data to directory ./raw_micrographs after filtration",
        default=False)
    parser.add_argument("--apix",
                        type=float,
                        help="Angstroms per pixel for all images",
                        default=None,
                        guitype='floatbox',
                        row=5,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode="filter['self.pm().getAPIX()']")
    parser.add_argument("--voltage",
                        type=float,
                        help="Microscope voltage in KV",
                        default=None,
                        guitype='floatbox',
                        row=5,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode="filter['self.pm().getVoltage()']")
    parser.add_argument("--cs",
                        type=float,
                        help="Microscope Cs (spherical aberation)",
                        default=None,
                        guitype='floatbox',
                        row=6,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode="filter['self.pm().getCS()']")
    parser.add_argument("--ac",
                        type=float,
                        help="Amplitude contrast (percentage, default=10)",
                        default=10,
                        guitype='floatbox',
                        row=6,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode="filter")
    parser.add_argument("--defocusmin",
                        type=float,
                        help="Minimum autofit defocus",
                        default=0.6,
                        guitype='floatbox',
                        row=8,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode="filter[0.6]")
    parser.add_argument("--defocusmax",
                        type=float,
                        help="Maximum autofit defocus",
                        default=4,
                        guitype='floatbox',
                        row=8,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode='filter[4.0]')
    parser.add_argument(
        "--ppid",
        type=int,
        help="Set the PID of the parent process, used for cross platform PPID",
        default=-1)

    (options, args) = parser.parse_args()

    microdir = os.path.join(".", "micrographs")
    if not os.access(microdir, os.R_OK):
        os.mkdir("micrographs")

    logid = E2init(sys.argv, options.ppid)

    # After filtration we move micrographs to a directory 'raw_micrographs', if desired
    if options.moverawdata:
        originalsdir = os.path.join(".", "raw_micrographs")
        if not os.access(originalsdir, os.R_OK):
            os.mkdir("raw_micrographs")

    for i, arg in enumerate(args):
        base = base_name(arg, nodir=not options.usefoldername)
        output = os.path.join(os.path.join(".", "micrographs"), base + ".hdf")
        cmd = "e2proc2d.py %s %s --inplace" % (arg, output)

        if options.invert: cmd += " --mult=-1"
        if options.edgenorm: cmd += " --process=normalize.edgemean"
        if options.xraypixel:
            cmd += " --process=threshold.clampminmax.nsigma:nsigma=4"

        launch_childprocess(cmd)
        if options.moverawdata:
            os.rename(arg, os.path.join(originalsdir, os.path.basename(arg)))

        # We estimate the defocus and B-factor (no astigmatism) from the micrograph and store it in info and the header
        if options.ctfest:
            d = EMData(output, 0)
            if d["nx"] < 1200 or d["ny"] < 1200:
                print "CTF estimation will only work with images at least 1200x1200 in size"
                sys.exit(1)
            import e2ctf

            ds = 1.0 / (options.apix * 512)
            ffta = None
            nbx = 0
            for x in range(100, d["nx"] - 512, 512):
                for y in range(100, d["ny"] - 512, 512):
                    clip = d.get_clip(Region(x, y, 512, 512))
                    clip.process_inplace("normalize.edgemean")
                    fft = clip.do_fft()
                    fft.ri2inten()
                    if ffta == None: ffta = fft
                    else: ffta += fft
                    nbx += 1

            ffta.mult(1.0 / (nbx * 512**2))
            ffta.process_inplace("math.sqrt")
            ffta[
                "is_intensity"] = 0  # These 2 steps are done so the 2-D display of the FFT looks better. Things would still work properly in 1-D without it

            fftbg = ffta.process("math.nonconvex")
            fft1d = ffta.calc_radial_dist(
                ffta.get_ysize() / 2, 0.0, 1.0,
                1)  # note that this handles the ri2inten averages properly

            # Compute 1-D curve and background
            bg_1d = e2ctf.low_bg_curve(fft1d, ds)

            #initial fit, background adjustment, refine fit, final background adjustment
            ctf = e2ctf.ctf_fit(fft1d,
                                bg_1d,
                                bg_1d,
                                ffta,
                                fftbg,
                                options.voltage,
                                options.cs,
                                options.ac,
                                options.apix,
                                1,
                                dfhint=(options.defocusmin,
                                        options.defocusmax))
            bgAdj(ctf, fft1d)
            ctf = e2ctf.ctf_fit(fft1d,
                                ctf.background,
                                ctf.background,
                                ffta,
                                fftbg,
                                options.voltage,
                                options.cs,
                                options.ac,
                                options.apix,
                                1,
                                dfhint=(options.defocusmin,
                                        options.defocusmax))
            bgAdj(ctf, fft1d)

            if options.astigmatism: e2ctf.ctf_fit_stig(ffta, fftbg, ctf)

            #ctf.background=bg_1d
            #ctf.dsbg=ds
            db = js_open_dict(info_name(arg, nodir=not options.usefoldername))
            db["ctf_frame"] = [512, ctf, (256, 256), set(), 5, 1]
            print info_name(arg, nodir=not options.usefoldername), ctf

        E2progress(logid, (float(i) / float(len(args))))

    E2end(logid)
Esempio n. 5
0
def fit_defocus(options,img_file,fft_avg,voltage,cs,ampcont,phaseplate,apix,target_defocus,defocusmin=0.5,defocusmax=9.0,defocusstep=0.1):
	"""Fit defocus from an incoherent average of tiles 
	Author: Jesus Montoya, [email protected], 09/2019
	"""
	print("\n(fit_defocus) entering function")

	tilesize = fft_avg['ny']
	
	fft_bg = fft_avg.process("math.nonconvex")

	fft_avg_1d = fft_avg.calc_radial_dist(old_div(fft_avg.get_ysize(),2),0.0,1.0,1)	# note that this handles the ri2inten averages properly
	
	#print("\n(e2tomo_ctfraw)(fit_defocus) fft_avg_1d={}".format(fft_avg_1d))

	ctf = EMAN2Ctf()

	#print("\n(e2tomo_ctfraw)(fit_defocus) apix={}".format(apix))
	#print("\n(e2tomo_ctfraw)(fit_defocus) tilesize={}".format(tilesize))

	# Compute 1-D curve and background
	ds = old_div(1.0,( apix * tilesize ))
	#print("\n(e2tomo_ctfraw)(fit_defocus) ds={}".format(ds))
	
	bg_1d = e2ctf.low_bg_curve(fft_avg_1d,ds)
	#print("\n(e2tomo_ctfraw)(fit_defocus) bg_1d={}".format(bg_1d))
	
	dfhint=( defocusmin, defocusmax, defocusstep )
	ctf = e2ctf.ctf_fit( fft_avg_1d, bg_1d, bg_1d, fft_avg, fft_bg, float(voltage), float(cs), float(ampcont), phaseplate, float(apix), bgadj=1, autohp=True, dfhint=dfhint)		
	#print("\n(e2tomo_ctfraw)(fit_defocus) ctf={}".format(ctf))

	#bg_sub = numpy.array(fft_avg_1d) - numpy.array(bg_1d)

	bg_sub,bg_1d = e2ctf.calc_1dfrom2d(ctf, fft_avg, fft_bg)

	fit = ctf_get_fit_curve(ctf, ds, fft_avg_1d, bg_1d, bg_sub)
	fit/=max(fit)

	
	#ctf = adjust_ctf_bg(ctf,fft_avg_1d)

	#maxres,bfactor = ctf_fit_bfactor_and_maxres( list(bg_sub),ds,ctf)
	#print("\ndefocus={}, FIRST trial".format(ctf.defocus))


	ctf2 = EMAN2Ctf()
	dfhint2=(max(dfhint[0],ctf.defocus-0.1),min(dfhint[1],ctf.defocus+0.1),min(old_div(dfhint[2],2.0),0.01))
	ctf2 = e2ctf.ctf_fit( fft_avg_1d, bg_1d, bg_1d, fft_avg, fft_bg, float(voltage), float(cs), float(ampcont), phaseplate, float(apix), bgadj=1, autohp=True, dfhint=dfhint2 )		
	bg_sub2,bg_1d2 = e2ctf.calc_1dfrom2d(ctf2, fft_avg, fft_bg)
	
	#bg_sub2,bg_1d2 = e2ctf.calc_1dfrom2d(ctf2, fft_avg, fft_bg)
	fit2 = ctf_get_fit_curve(ctf2, ds, fft_avg_1d, bg_1d2, bg_sub2)
	fit2/=max(fit2)

	#maxres,bfactor = ctf_fit_bfactor_and_maxres( list(bg_sub2),ds,ctf)
	#print("\nmaxres calc={}, bfactor={}, defocus={}, SECOND trial".format(maxres,ctf2.bfactor,ctf2.defocus))

	bg_sub_final = numpy.array(bg_sub2) - numpy.array(bg_1d2)
	bg_sub_final/=max(bg_sub_final)
	import matplotlib.pyplot as plt
	
	if options.plots or options.debug:
		r = len(ctf.background)
		s = numpy.arange(0,ds*r,ds)
		
		if options.debug:
			plt.plot(s, fit2, 'k')
			plt.plot(s, bg_sub_final, 'b')
			plt.show()

		if options.plots:
			extension = os.path.splitext(os.path.basename( img_file ))[-1]

			print("\n(fit_defocus) should save plots")
			ps_file = img_file.replace(extension,'_1d_ps.txt')
			if ps_file == img_file:
				print("\nERROR: risk of overwritting input image")
				sys.exit(1)
			write_txt(s,bg_sub_final,ps_file)
			#with open(options.path + '/' + pfile,'w') as f:
			#	lines = [ str(s[i])+'\t'+str(bg_sub_final[i])+'\n' for i in range(len(s-1))]
			#	lines.append( str(s[-1]) + '\t' + str(bg_sub_final[-1]) )	#the last element does not need a 'return' or 'line break'
			
			fit_file = img_file.replace(extension,'_1d_fit.txt')
			if fit_file == img_file:
				print("\nERROR: risk of overwritting input image")
				sys.exit(1)
			#with open(options.path + '/' + pfile,'w') as f:
			#	lines = [ str(s[i])+'\t'+str(bg_sub_final[i])+'\n' for i in range(len(s-1))]
			#	lines.append( str(s[-1]) + '\t' + str(bg_sub_final[-1]) )	#the last element does not need a 'return' or 'line break'
			write_txt(s,fit2,fit_file)

	print("\n(fit_defocus) leaving function")

	return ctf
Esempio n. 6
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """prog [options] <micrograph1, micrograph2....>
	Use this program to import and filter raw micrographs. If you choose to filter and/or convert format, this program will process each micrograph
	and dump them into the directory './micrographs.', otherwise the micrographs will simply be moved into './micrographs'. If you select the option
	--moverawdata AND you filter or change format, your original micrographs will be moved into the directory './raw_micrographs' and your
	filtered micrographs will be in './micrographs as usual. BDB files are not moved, but they can be processed."""

	parser = EMArgumentParser(usage=usage,version=EMANVERSION)

	parser.add_pos_argument(name="micrographs",help="List the micrographs to filter here.", default="", guitype='filebox', browser="EMRawDataTable(withmodal=True,multiselect=True)",  row=0, col=0,rowspan=1, colspan=2, mode='filter')
	parser.add_pos_argument(name="import_files",help="List the files to import/filter here.", default="", guitype='filebox', browser="EMBrowserWidget(withmodal=True,multiselect=True)",  row=0, col=0,rowspan=1, colspan=2, mode='import')
	parser.add_header(name="filterheader", help='Options below this label are specific to filtering', title="### filtering options ###", row=1, col=0, rowspan=1, colspan=2, mode='import,filter')
	parser.add_argument("--invert",action="store_true",help="Invert contrast",default=False, guitype='boolbox', row=2, col=0, rowspan=1, colspan=1, mode='filter[True]')
	parser.add_argument("--edgenorm",action="store_true",help="Edge normalize",default=False, guitype='boolbox', row=2, col=1, rowspan=1, colspan=1, mode='filter[True]')
	parser.add_argument("--usefoldername",action="store_true",help="If you have the same image filename in multiple folders, and need to import into the same project, this will prepend the folder name on each image name",default=False,guitype='boolbox',row=2, col=2, rowspan=1, colspan=1, mode="import[False]")
	parser.add_argument("--xraypixel",action="store_true",help="Filter X-ray pixels",default=False, guitype='boolbox', row=3, col=0, rowspan=1, colspan=1, mode='filter[True]')
	parser.add_argument("--ctfest",action="store_true",help="Estimate defocus from whole micrograph",default=False, guitype='boolbox', row=3, col=1, rowspan=1, colspan=1, mode='filter[True]')
	parser.add_argument("--astigmatism",action="store_true",help="Includes astigmatism in automatic fitting",default=False, guitype='boolbox', row=3, col=2, rowspan=1, colspan=1, mode='filter[False]')
	parser.add_argument("--moverawdata",action="store_true",help="Move raw data to directory ./raw_micrographs after filtration",default=False)
	parser.add_argument("--apix",type=float,help="Angstroms per pixel for all images",default=None, guitype='floatbox', row=5, col=0, rowspan=1, colspan=1, mode="filter['self.pm().getAPIX()']")
	parser.add_argument("--voltage",type=float,help="Microscope voltage in KV",default=None, guitype='floatbox', row=5, col=1, rowspan=1, colspan=1, mode="filter['self.pm().getVoltage()']")
	parser.add_argument("--cs",type=float,help="Microscope Cs (spherical aberation)",default=None, guitype='floatbox', row=6, col=0, rowspan=1, colspan=1, mode="filter['self.pm().getCS()']")
	parser.add_argument("--ac",type=float,help="Amplitude contrast (percentage, default=10)",default=10, guitype='floatbox', row=6, col=1, rowspan=1, colspan=1, mode="filter")
	parser.add_argument("--defocusmin",type=float,help="Minimum autofit defocus",default=0.6, guitype='floatbox', row=8, col=0, rowspan=1, colspan=1, mode="filter[0.6]")
	parser.add_argument("--defocusmax",type=float,help="Maximum autofit defocus",default=4, guitype='floatbox', row=8, col=1, rowspan=1, colspan=1, mode='filter[4.0]')
	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)

	(options, args) = parser.parse_args()

	microdir = os.path.join(".","micrographs")
	if not os.access(microdir, os.R_OK):
		os.mkdir("micrographs")

	logid=E2init(sys.argv,options.ppid)

	# After filtration we move micrographs to a directory 'raw_micrographs', if desired
	if options.moverawdata:
		originalsdir = os.path.join(".","raw_micrographs")
		if not os.access(originalsdir, os.R_OK):
			os.mkdir("raw_micrographs")
			
	for i,arg in enumerate(args):
		base = base_name(arg,nodir=not options.usefoldername)
		output = os.path.join(os.path.join(".","micrographs"),base+".hdf")
		cmd = "e2proc2d.py %s %s --inplace"%(arg,output)

		if options.invert: cmd += " --mult=-1"
		if options.edgenorm: cmd += " --process=normalize.edgemean"
		if options.xraypixel: cmd += " --process=threshold.clampminmax.nsigma:nsigma=4"
		
		launch_childprocess(cmd)
		if options.moverawdata:
			os.rename(arg,os.path.join(originalsdir,os.path.basename(arg)))
			
		# We estimate the defocus and B-factor (no astigmatism) from the micrograph and store it in info and the header
		if options.ctfest :
			d=EMData(output,0)
			if d["nx"]<1200 or d["ny"]<1200 : 
				print "CTF estimation will only work with images at least 1200x1200 in size"
				sys.exit(1)
			import e2ctf
			
			ds=1.0/(options.apix*512)
			ffta=None
			nbx=0
			for x in range(100,d["nx"]-512,512):
				for y in range(100,d["ny"]-512,512):
					clip=d.get_clip(Region(x,y,512,512))
					clip.process_inplace("normalize.edgemean")
					fft=clip.do_fft()
					fft.ri2inten()
					if ffta==None: ffta=fft
					else: ffta+=fft
					nbx+=1

			ffta.mult(1.0/(nbx*512**2))
			ffta.process_inplace("math.sqrt")
			ffta["is_intensity"]=0				# These 2 steps are done so the 2-D display of the FFT looks better. Things would still work properly in 1-D without it

			fftbg=ffta.process("math.nonconvex")
			fft1d=ffta.calc_radial_dist(ffta.get_ysize()/2,0.0,1.0,1)	# note that this handles the ri2inten averages properly

			# Compute 1-D curve and background
			bg_1d=e2ctf.low_bg_curve(fft1d,ds)

			#initial fit, background adjustment, refine fit, final background adjustment
			ctf=e2ctf.ctf_fit(fft1d,bg_1d,bg_1d,ffta,fftbg,options.voltage,options.cs,options.ac,options.apix,1,dfhint=(options.defocusmin,options.defocusmax))
			bgAdj(ctf,fft1d)
			ctf=e2ctf.ctf_fit(fft1d,ctf.background,ctf.background,ffta,fftbg,options.voltage,options.cs,options.ac,options.apix,1,dfhint=(options.defocusmin,options.defocusmax))
			bgAdj(ctf,fft1d)
			
			if options.astigmatism : e2ctf.ctf_fit_stig(ffta,fftbg,ctf)
			
			#ctf.background=bg_1d
			#ctf.dsbg=ds
			db=js_open_dict(info_name(arg,nodir=not options.usefoldername))
			db["ctf_frame"]=[512,ctf,(256,256),set(),5,1]
			print info_name(arg,nodir=not options.usefoldername),ctf

		E2progress(logid,(float(i)/float(len(args))))

	E2end(logid)