示例#1
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)
示例#2
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """prog [options] micrographs/<micrograph_name>

	This program will allow you to serially compute and write the 1D background subtracted power spectra for multiple micrographs.
	
	For the best background subtraction results, it is highly recommended to run this program within a project where CTF correction has been performed (i.e. running e2rawdata.py and/or e2ctf.py).
	"""

	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	parser.add_pos_argument(name="images",help="Calculate the power spectra of these images.", default="")#, guitype='filebox', browser="EMBrowserWidget(withmodal=True,multiselect=True)",  row=0, col=0,rowspan=1, colspan=2, mode="eval")
	parser.add_argument("--apix",type=float,help="Angstroms per pixel for all images",default=None)#, guitype='floatbox', row=3, col=0, rowspan=1, colspan=1, mode="eval['self.pm().getAPIX()']")
	parser.add_argument("--constbfactor",type=float,help="Set B-factor to fixed specified value, negative value autofits. Default is 200.0.",default=-1.0)#, guitype='floatbox', row=8, col=0, rowspan=1, colspan=1, mode='eval[-1.0]')
	parser.add_argument("--voltage",type=float,help="Microscope voltage in KV. Default is 200.0.",default=None)# guitype='floatbox', row=3, col=1, rowspan=1, colspan=1, mode="eval['self.pm().getVoltage()']")
	parser.add_argument("--cs",type=float,help="Microscope Cs (spherical aberation). Default is 4.1.",default=None)#, guitype='floatbox', row=4, col=0, rowspan=1, colspan=1, mode="eval['self.pm().getCS()']")
	parser.add_argument("--ac",type=float,help="Amplitude contrast (percentage). Default is 10.0",default=None)#, guitype='floatbox', row=4, col=1, rowspan=1, colspan=1, mode="eval")
	parser.add_argument("--box",type=int,help="Forced box size in grid mode.. ",default=512)#, guitype='intbox', row=5, col=0, rowspan=1, colspan=1, mode="eval")
	parser.add_argument("--oversamp",type=float,help="Oversample power spectrum. Default 1.0.",default=1.0)#, guitype='intbox', row=5, col=0, rowspan=1, colspan=1, mode="eval")
	parser.add_argument("--nobgsub",action="store_true",help="Skip background subtraction",default=False)#, guitype='floatbox', row=3, col=0, rowspan=1, colspan=1, mode="eval['self.pm().getAPIX()']")

	parser.add_argument("--pad",type=int,help="Exclude this many pixels around the edge of input micrograph(s) when computing power spectra.",default=64)#, guitype='intbox', row=5, col=0, rowspan=1, colspan=1, mode="eval")
	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n", type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness")
	(options, args) = parser.parse_args()

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

	try: os.mkdir('micrographs')
	except: pass

	if options.box<64 :
		print("Box size too small. Using larger box size of 512 pixels).")
		options.box=512
	box=options.box

	voltage=options.voltage
	cs=options.cs
	ac=options.ac
	constbfactor=options.constbfactor

	pad = options.pad

	if options.oversamp < 1: print("Oversamp must be greater than or equal to 1. Using --oversamp=1 instead.")
	oversamp = max(options.oversamp,1)

	for curset,arg in enumerate(args):
		sys.stdout.write("\r{}/{}: {}".format(curset+1,len(args),arg))
		sys.stdout.flush()
		data = EMData(arg,0)

		if options.apix == None:
			try: apix = data["apix_x"]
			except:
				print("Could not find apix. Please specify using --apix or assign the corresponding header parameter, i.e. 'apix_x'.")
				sys.exit(1)
		else: apix = options.apix

		noctfflag = False
		try: 
			ctf=js_open_dict(info_name(arg,nodir=True))["ctf"][0]
			print("")
			print("\tDefocus: {}".format(ctf.defocus))
			print("\tVoltage: {}".format(ctf.voltage))
			print("\tApix: {}".format(ctf.apix))
			print("\tCs: {}".format(ctf.cs))
			print("\tAC: {}".format(ctf.ampcont))
		except:
			print("Could not find CTF parameters. Skipping background subtraction.")
			#ctf = EMAN2Ctf()
			#ctf.from_dict({'defocus':0.0,'dfdiff':0.0,'dfang':0.0,'bfactor':200.0,'ampcont':10.0,'voltage':200.0,'cs':4.1,'apix':apix,'dsbg':-1})
			#if options.voltage!=None : ctf.voltage=options.voltage
			#if options.ac != None: ctf.ampcont = options.ac
			#if options.cs!=None : ctf.cs=options.cs
			#if options.constbfactor>0 : ctf.bfactor=options.constbfactor
			noctfflag = True

		ds=old_div(1.0,(apix*box*oversamp))
		nx=old_div(data["nx"],box)-1
		cumulfft=EMData(box,box)
		cumulfft.do_fft_inplace()
		nbx=0
		for ix,x in enumerate(range(nx)):
			for iy,y in enumerate(range(old_div(data["ny"],box)-1)):
				# read the data and make the FFT
				clip=data.get_clip(Region(x*box+old_div(box,2),y*box+old_div(box,2),box,box))
				clip.process_inplace("normalize.edgemean")
				if oversamp>1 : clip=clip.get_clip(Region(0,0,box*oversamp,box*oversamp))		# since we aren't using phases, doesn't matter if we center it or not
				fft=clip.do_fft()
				fft.ri2inten()
				cumulfft+=fft
				nbx+=1

		cumulfft.mult(old_div(1.0,(nbx*box**2)))
		cumulfft.process_inplace("math.sqrt")
		cumulfft["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=cumulfft.process("math.nonconvex")
		fft1d=cumulfft.calc_radial_dist(old_div(cumulfft.get_ysize(),2),0.0,1.0,1)	# note that this handles the ri2inten averages properly

		if options.nobgsub or noctfflag:
			s=np.arange(0,ds*len(fft1d),ds)

			pwsfn = "micrographs/{}-pws.txt".format(base_name(arg))
			try: os.remove(pwsfn)
			except: pass

			with open(pwsfn,"w") as pwsf:
				pwsf.write("# s(1/A); PWS(s)\n")
				for i in range(len(fft1d)):
					pwsf.write("{}\t{}\n".format(s[i],fft1d[i]))

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

			fft1d=np.asarray(fft1d)
			ds=ctf.dsbg
			bg_1d=list(ctf.background)

			xyd=XYData()

			# Find the minimum value near the origin, which we'll use as a zero (though it likely should not be)
			mv=(fft1d[1],1)
			fz=int(old_div(ctf.zero(0),(ds*2)))
			for lz in range(1,fz):
				mv=min(mv,(fft1d[lz],lz))

			xyd.insort(mv[1],mv[0])

			# now we add all of the zero locations to our XYData object
			for i in range(100):
				z=int(old_div(ctf.zero(i),ds))
				if z>=len(bg_1d)-1: break
				if fft1d[z-1]<fft1d[z] and fft1d[z-1]<fft1d[z+1]: mv=(z-1,fft1d[z-1])
				elif fft1d[z]<fft1d[z+1] : mv=(z,fft1d[z])
				else : mv=(z+1,fft1d[z+1])
				xyd.insort(mv[0],mv[1])

			# new background is interpolated XYData
			ctf.background=[xyd.get_yatx_smooth(i,1) for i in range(len(bg_1d))]

			# if our first point (between the origin and the first 0) is too high, we readjust it once
			bs=[fft1d[i]-ctf.background[i] for i in range(fz)]
			if min(bs)<0 :
				mv=(bs[0],fft1d[0],0)
				for i in range(1,fz): mv=min(mv,(bs[i],fft1d[i],i))
				xyd.set_x(0,mv[2])
				xyd.set_y(0,mv[1])
				
				ctf.background=[xyd.get_yatx_smooth(i,1) for i in range(len(bg_1d))]

			bg1d=np.array(ctf.background)
			r=len(ctf.background)
			s=np.arange(0,ds*r,ds)

			try: bgsub=fft1d-bg1d
			except:
				print("Error computing bgsub on this image")
				continue

			fit=np.array(ctf.compute_1d(len(s)*2,ds,Ctf.CtfType.CTF_AMP))		# The fit curve
			fit=fit*fit			# squared

			# auto-amplitude for b-factor adjustment
			rto,nrto=0,0
			for i in range(int(old_div(.04,ds))+1,min(int(old_div(0.15,ds)),len(s)-1)):
				if bgsub[i]>0 :
					rto+=fit[i]
					nrto+=fabs(bgsub[i])
			if nrto==0 : rto=1.0
			else : rto/=nrto
			fit=[old_div(fit[i],rto) for i in range(len(s))]

			pwsfn = "micrographs/{}-pws.txt".format(base_name(arg))

			try: os.remove(pwsfn)
			except: pass

			with open(pwsfn,"w") as pwsf:
				pwsf.write("# s(1/A); PWS-BG(s); CTF Fit(s); PWS(s); BG(s)\n")
				for i in range(len(fft1d)):
					pwsf.write("{}\t{}\t{}\t{}\t{}\n".format(s[i],bgsub[i],fit[i],fft1d[i],bg1d[i]))

	print("\nPower spectra files saved within the 'micrographs' directory.")
示例#3
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)
示例#4
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
示例#5
0
	def recalc_real(self):
		"Called to recompute the power spectra, also updates plot"

		self.needupdate=False

		if self.data==None :
			self.procthread=None
			return

		self.incalc=True	# to avoid incorrect plot updates

		# To simplify expressions
		parms=self.parms[self.curset]
		apix=self.sapix.getValue()
		if len(parms)==5 : parms.append(1)		# for old projects where there was no oversampling specification
		else: parms[5]=max(1,int(parms[5]))
		ds=1.0/(apix*parms[0]*parms[5])

		# Mode where user drags the box around the parent image
		if self.calcmode==0:

			# extract the data and do an fft
			clip=self.data.get_clip(Region(parms[2][0],parms[2][1],parms[0],parms[0]))
			clip.process_inplace("normalize.edgemean")

			if parms[5]>1 :
				clip=clip.get_clip(Region(0,0,parms[0]*parms[5],parms[0]*parms[5]))		# since we aren't using phases, doesn't matter if we center it or not
			self.fft=clip.do_fft()
#			self.fft.mult(1.0/parms[0]**2)
			self.fft.mult(1.0/parms[0])

		# mode where user selects/deselcts tiled image set
		elif self.calcmode==1:
			# update the box display on the image
			nx=self.data["nx"]/parms[0]-1
			self.fft=None
			nbx=0
			for x in range(nx):
				for y in range(self.data["ny"]/parms[0]-1):
					# User deselected this one
					if int(x+y*nx) in parms[3] : continue

					# read the data and make the FFT
					clip=self.data.get_clip(Region(x*parms[0]+parms[0]/2,y*parms[0]+parms[0]/2,parms[0],parms[0]))
					clip.process_inplace("normalize.edgemean")
					if parms[5]>1 :
						clip=clip.get_clip(Region(0,0,parms[0]*parms[5],parms[0]*parms[5]))		# since we aren't using phases, doesn't matter if we center it or not
					fft=clip.do_fft()
#					fft.mult(parms[0])
					fft.ri2inten()
					if self.fft==None: self.fft=fft
					else: self.fft+=fft
					nbx+=1

			self.fft.mult(1.0/(nbx*parms[0]**2))
			self.fft.process_inplace("math.sqrt")
			self.fft["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
#			self.fft.mult(1.0/(nbx*parms[0]**2))

		self.fftbg=self.fft.process("math.nonconvex")
		self.fft1d=self.fft.calc_radial_dist(self.fft.get_ysize()/2,0.0,1.0,1)	# note that this handles the ri2inten averages properly
		if self.plotmode==2 or self.plotmode==3:
			self.fft1dang=array(self.fft.calc_radial_dist(self.fft.get_ysize()/2,0.0,1.0,4,self.sang45.getValue()*.017453292,1))	# This form generates 4 sequential power spectra representing angular ranges
			self.fft1dang=self.fft1dang.reshape((4,self.fft.get_ysize()/2))
		else:
			self.fft1dang=None

		# Compute 1-D curve and background
		bg_1d=e2ctf.low_bg_curve(self.fft1d,ds)
		parms[1].background=bg_1d
		parms[1].dsbg=ds

		self.fft1d=array(self.fft1d)

		self.needredisp=True
		self.incalc=False
		time.sleep(.2)			# help make sure update has a chance
		self.procthread=None

		self.bgAdj()
示例#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)
示例#7
0
	def recalc_real(self):
		"Called to recompute the power spectra, also updates plot"

		self.needupdate=False

		if self.data==None :
			self.procthread=None
			return

		self.incalc=True	# to avoid incorrect plot updates

		# To simplify expressions
		parms=self.parms[self.curset]
		apix=self.sapix.getValue()
		if len(parms)==5 : parms.append(1)		# for old projects where there was no oversampling specification
		else: parms[5]=max(1,int(parms[5]))
		ds=1.0/(apix*parms[0]*parms[5])

		# Mode where user drags the box around the parent image
		if self.calcmode==0:

			# extract the data and do an fft
			clip=self.data.get_clip(Region(parms[2][0],parms[2][1],parms[0],parms[0]))
			clip.process_inplace("normalize.edgemean")

			if parms[5]>1 :
				clip=clip.get_clip(Region(0,0,parms[0]*parms[5],parms[0]*parms[5]))		# since we aren't using phases, doesn't matter if we center it or not
			self.fft=clip.do_fft()
#			self.fft.mult(1.0/parms[0]**2)
			self.fft.mult(1.0/parms[0])

		# mode where user selects/deselcts tiled image set
		elif self.calcmode==1:
			# update the box display on the image
			nx=self.data["nx"]/parms[0]-1
			self.fft=None
			nbx=0
			for x in range(nx):
				for y in range(self.data["ny"]/parms[0]-1):
					# User deselected this one
					if int(x+y*nx) in parms[3] : continue

					# read the data and make the FFT
					clip=self.data.get_clip(Region(x*parms[0]+parms[0]/2,y*parms[0]+parms[0]/2,parms[0],parms[0]))
					clip.process_inplace("normalize.edgemean")
					if parms[5]>1 :
						clip=clip.get_clip(Region(0,0,parms[0]*parms[5],parms[0]*parms[5]))		# since we aren't using phases, doesn't matter if we center it or not
					fft=clip.do_fft()
#					fft.mult(parms[0])
					fft.ri2inten()
					if self.fft==None: self.fft=fft
					else: self.fft+=fft
					nbx+=1

			self.fft.mult(1.0/(nbx*parms[0]**2))
			self.fft.process_inplace("math.sqrt")
			self.fft["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
#			self.fft.mult(1.0/(nbx*parms[0]**2))

		self.fftbg=self.fft.process("math.nonconvex")
		self.fft1d=self.fft.calc_radial_dist(self.fft.get_ysize()/2,0.0,1.0,1)	# note that this handles the ri2inten averages properly
		if self.plotmode==2 or self.plotmode==3:
			self.fft1dang=array(self.fft.calc_radial_dist(self.fft.get_ysize()/2,0.0,1.0,4,self.sang45.getValue()*.017453292,1))	# This form generates 4 sequential power spectra representing angular ranges
			self.fft1dang=self.fft1dang.reshape((4,self.fft.get_ysize()/2))
		else:
			self.fft1dang=None

		# Compute 1-D curve and background
		bg_1d=e2ctf.low_bg_curve(self.fft1d,ds)
		parms[1].background=bg_1d
		parms[1].dsbg=ds

		self.fft1d=array(self.fft1d)

		self.needredisp=True
		self.incalc=False
		time.sleep(.2)			# help make sure update has a chance
		self.procthread=None

		self.bgAdj()