Ejemplo n.º 1
0
def db_compute_fsc(a, b, apix, pathname, dbname):
	fsc = a.calc_fourier_shell_correlation(b)
	third = len(fsc)/3
	xaxis = fsc[0:third]
	plot = fsc[third:2*third]
	error = fsc[2*third:]
		
	convergence_db_name = "bdb:"+pathname+"#convergence.results"
	db = db_open_dict(convergence_db_name)
	
	tmpaxis = [x/apix for x in xaxis]
	db[dbname] = [tmpaxis[1:],plot[1:]]
	#db["error_"+s+"_fsc"] = [xaxis,error] #we're not plotting the errors
	db_close_dict(convergence_db_name)
Ejemplo n.º 2
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] <volume> <mask> <output>

	WARNING: Do not use this program. The whole concept has been replaced by "gold standard" refinement.

	Note that this method has not yet been published, and is not yet a reliable
	scheme for resolution determination. DO NOT EXPECT RELIABLE ANSWERS AT THIS POINT !

	This will compute an FSC resolution curve from a single structure by
	comparing the power spectrum of the noise region to the power spectrum
	of the reconstructed particle. The 'mask' input should mask out the particle,
	and should be a 'soft' mask. Sharp edges on the mask may ruin the results.
	proc3d (EMAN1) with the automask2 option can produce appropriate masks. The
	3rd parameter (in automask2) should be about 10 percent of the box size. This will not
	work with particles that have been tightly masked already. If doing an EMAN1
	reconstruction with the amask= option, you must also use the refmaskali option
	(in the refine command). Note that the resultant curve is guaranteed to go
	to zero at near Nyquist because it assumes that the SNR is zero near Nyquist.
	If your data is undersampled, the resulting curve may also be inaccurate.
	Models should also not be heavily low-pass filtered
	"""
    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_pos_argument(name="volume",
                            help="Volume to compute resolution on.",
                            default="",
                            guitype='filebox',
                            row=0,
                            col=0,
                            rowspan=1,
                            colspan=2)
    parser.add_pos_argument(
        name="mask",
        help=
        "Mask for the volume. The volume is masked by this file (should be ssoft mask).",
        default="",
        guitype='filebox',
        row=1,
        col=0,
        rowspan=1,
        colspan=2)
    parser.add_pos_argument(
        name="output",
        help="Name of the output file. These data will contain FSC stats.",
        default="",
        guitype='strbox',
        row=2,
        col=0,
        rowspan=1,
        colspan=2)
    parser.add_header(
        name="eotestheader",
        help='Options below this label are specific to e2resolution',
        title="### e2resolution options ###",
        row=3,
        col=0,
        rowspan=1,
        colspan=2)
    parser.add_argument("--apix",
                        "-A",
                        type=float,
                        help="A/voxel",
                        default=-1.0,
                        guitype='floatbox',
                        row=4,
                        col=0,
                        rowspan=1,
                        colspan=1)
    parser.add_argument(
        "--path",
        type=str,
        help=
        "The name the e2refine directory that contains the reconstruction data. If specified will place curves generated in bdb:path#convergence.results",
        guitype='dirbox',
        default=None,
        dirbasename='refine',
        row=4,
        col=1,
        rowspan=1,
        colspan=1)
    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()

    if len(args) < 3: parser.error("Input and output files required")

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

    #options.align=parsemodopt(options.align)

    print(
        "WARNING:  e2resolution is an experimental program. It does not (yet) produce reliable resolution curves in most cases."
    )

    print("read models")
    data = EMData(args[0], 0)
    mask = EMData(args[1], 0)

    #	mask.to_one()
    #	mask.process_inplace("mask.gaussian",{"outer_radius":mask.get_xsize()/6,"inner_radius":mask.get_xsize()/6})
    mask.write_image("msk.mrc", 0)

    # inverted mask
    maski = mask.copy()
    maski *= -1.0
    maski += 1.0
    maski.process_inplace(
        "mask.gaussian", {
            "outer_radius": old_div(mask.get_xsize(), 6),
            "inner_radius": old_div(mask.get_xsize(), 3)
        })
    maski.write_image("msk2.mrc", 0)

    noise = data.copy()
    noise *= maski

    data *= mask

    print("compute FFT")
    dataf = data.do_fft()
    noisef = noise.do_fft()

    print("compute power 1")
    datapow = dataf.calc_radial_dist(
        old_div(dataf.get_ysize(), 2) - 1, 1, 1, 1)
    print("compute power 2")
    noisepow = noisef.calc_radial_dist(
        old_div(noisef.get_ysize(), 2) - 1, 1, 1, 1)

    x = list(range(1, len(datapow) + 1))
    if options.apix > 0:
        x = [old_div(i, (len(datapow) * options.apix * 2.0)) for i in x]
    else:
        x = [old_div(i, (len(datapow) * data["apix_x"] * 2.0)) for i in x]

    # normalize noise near Nyquist
    s = 0
    sn = 0
    for i in range(int(len(noisepow) * .9), len(noisepow) - 1):
        if datapow[i] < datapow[i + 1] or noisepow[i] < noisepow[i + 1]:
            continue
        s += old_div(datapow[i], noisepow[i])
        sn += 1.0
    if sn == 0:
        print("Warning, strange normalization")
        s = old_div(datapow[int(len(noisepow) * .9)],
                    noisepow[int(len(noisepow) * .9)])
    else:
        s /= sn

    noisepow = [i * s for i in noisepow]
    #
    #	# normalize based on volume
    #	datapow=[v/mask["mean"] for v in datapow]
    #	noisepow=[v/maski["mean"] for v in noisepow]

    # compute signal to noise ratio
    snr = []
    for i in range(len(datapow)):
        try:
            snr.append(old_div((datapow[i] - noisepow[i]), noisepow[i]))
        except:
            snr.append(0)

    # convert to FSC
    fsc = [old_div(i, (2.0 + i)) for i in snr]

    out = open(args[2], "w")
    for i in range(len(fsc)):
        out.write("%f\t%f\n" % (x[i], fsc[i]))
    out.close()

    out = open(args[2] + ".dat", "w")
    for i in range(len(fsc)):
        out.write("%f\t%f\n" % (x[i], datapow[i]))
    out.close()

    out = open(args[2] + ".noi", "w")
    for i in range(len(noisepow)):
        out.write("%f\t%f\n" % (x[i], noisepow[i]))
    out.close()

    if options.path != None:
        s = base_name(args[0])
        db = db_open_dict("bdb:" + options.path + "#convergence.results")
        db[s + "res_fsc"] = [
            x, fsc
        ]  # warning, changing this naming convention will disrupt forms in the workflow (make them fail)
        db[s + "res_datapow"] = [x, datapow]
        db[s + "res_noisepow"] = [x, noisepow]
        db_close_dict("bdb:" + options.path + "#convergence.results")

    E2end(E2n)
Ejemplo n.º 3
0
def filter_shrink(input_bdb_name,
                  output_stack_path,
                  output_bdb_name,
                  alignYN=False,
                  filtrad=None,
                  shrink=None,
                  verbose=False):
    """
	Filters and shrinks image stack.
	
	Arguments:
		input_bdb_name : Input BDB stack  (in the form bdb:DIRECTORY#STACK)
		output_stack_path : Name for output image stack (MRCS/HDF/etc.)
		output_bdb_name : Name for output BDB stack (in the form bdb:DIRECTORY#STACK)
		alignYN: (boolean) Whether to apply alignments
		filtrad : Filter radius, reciprocal pixels
		shrink : Downsampling factor
		combined_params_file : Output combined alignment parameters
		verbose : (boolean) Whether to write to screen
	"""

    input_stack = EMData.read_images(input_bdb_name)
    num_imgs = EMUtil.get_image_count(input_bdb_name)

    box_size = input_stack[0].get_attr('nx')

    if options.shrink:
        sub_rate = float(1) / options.shrink
        box_size = int(float(box_size) / options.shrink + 0.5)
        if verbose:
            print('sub_rate', sub_rate, type(sub_rate), box_size,
                  options.shrink)

    # Initialize stack & BDB
    aligned_stack_obj = EMData(box_size, box_size, num_imgs)
    new_bdb_dict = db_open_dict(output_bdb_name)

    # Loop through images
    for img_num in range(len(input_stack)):
        img_orig = input_stack[img_num]

        try:
            alpha, sx, sy, mirror, scale = get_params2D(img_orig)
        except RuntimeError:
            print('\nERROR! Exiting with RuntimeError')
            img_prev = input_stack[img_num - 1]
            print('\nPrevious particle: %s %s' %
                  (img_num - 1, img_prev.get_attr_dict()))
            print('\nCurrent particle: %s %s' %
                  (img_num, img_orig.get_attr_dict()))
            exit()

        # Optionally apply alignment parameters
        if alignYN:
            img_ali = rot_shift2D(img_orig, alpha, sx, sy, mirror, scale,
                                  "quadratic")
        else:
            img_ali = img_orig

        if verbose and img_num == 0:
            print('\nimg_orig.get_attr_dict0', img_orig.get_attr_dict())
            img_ali_dict = img_ali.get_attr_dict()
            print('\nimg_ali.get_attr_dict1\n', img_ali.get_attr_dict())

        if filtrad:
            img_ali = filt_gaussl(img_ali, filtrad)

        if shrink:
            img_ali = resample(img_ali, sub_rate)
            #### (Maybe update resample_ratio)

        img_ali_dict = img_ali.get_attr_dict()
        img_ali_dict["data_path"] = os.path.join(
            '..', STACKFILEDIR, os.path.basename(output_stack_path))
        img_ali_dict["ptcl_source_coord_id"] = img_num
        new_bdb_dict[img_num] = img_ali_dict

        aligned_stack_obj.insert_clip(img_ali, (0, 0, img_num))
    # End image-loop

    aligned_stack_obj.write_image(output_stack_path)
    db_close_dict(output_bdb_name)

    return num_imgs
Ejemplo n.º 4
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """prog [options] <volume> <mask> <output>

	WARNING: Do not use this program. The whole concept has been replaced by "gold standard" refinement.

	Note that this method has not yet been published, and is not yet a reliable
	scheme for resolution determination. DO NOT EXPECT RELIABLE ANSWERS AT THIS POINT !

	This will compute an FSC resolution curve from a single structure by
	comparing the power spectrum of the noise region to the power spectrum
	of the reconstructed particle. The 'mask' input should mask out the particle,
	and should be a 'soft' mask. Sharp edges on the mask may ruin the results.
	proc3d (EMAN1) with the automask2 option can produce appropriate masks. The
	3rd parameter (in automask2) should be about 10 percent of the box size. This will not
	work with particles that have been tightly masked already. If doing an EMAN1
	reconstruction with the amask= option, you must also use the refmaskali option
	(in the refine command). Note that the resultant curve is guaranteed to go
	to zero at near Nyquist because it assumes that the SNR is zero near Nyquist.
	If your data is undersampled, the resulting curve may also be inaccurate.
	Models should also not be heavily low-pass filtered
	"""
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)

	parser.add_pos_argument(name="volume",help="Volume to compute resolution on.", default="", guitype='filebox',  row=0, col=0,rowspan=1, colspan=2)
	parser.add_pos_argument(name="mask",help="Mask for the volume. The volume is masked by this file (should be ssoft mask).", default="", guitype='filebox',  row=1, col=0,rowspan=1, colspan=2)
	parser.add_pos_argument(name="output",help="Name of the output file. These data will contain FSC stats.", default="", guitype='strbox',  row=2, col=0,rowspan=1, colspan=2)
	parser.add_header(name="eotestheader", help='Options below this label are specific to e2resolution', title="### e2resolution options ###", row=3, col=0, rowspan=1, colspan=2)
	parser.add_argument("--apix", "-A", type=float, help="A/voxel", default=-1.0, guitype='floatbox', row=4, col=0, rowspan=1, colspan=1)
	parser.add_argument("--path", type=str,help="The name the e2refine directory that contains the reconstruction data. If specified will place curves generated in bdb:path#convergence.results", guitype='dirbox', default=None, dirbasename='refine', row=4, col=1,rowspan=1, colspan=1)
	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()
	
	if len(args)<3 : parser.error("Input and output files required")
	
	E2n=E2init(sys.argv,options.ppid)
	
	#options.align=parsemodopt(options.align)

	print "WARNING:  e2resolution is an experimental program. It does not (yet) produce reliable resolution curves in most cases."

	print "read models"
	data=EMData(args[0],0)
	mask=EMData(args[1],0)

#	mask.to_one()
#	mask.process_inplace("mask.gaussian",{"outer_radius":mask.get_xsize()/6,"inner_radius":mask.get_xsize()/6})
	mask.write_image("msk.mrc",0)

	# inverted mask
	maski=mask.copy()
	maski*=-1.0
	maski+=1.0
	maski.process_inplace("mask.gaussian",{"outer_radius":mask.get_xsize()/6,"inner_radius":mask.get_xsize()/3})
	maski.write_image("msk2.mrc",0)

	noise=data.copy()
	noise*=maski

	data*=mask

	print "compute FFT"
	dataf=data.do_fft()
	noisef=noise.do_fft()

	print "compute power 1"
	datapow=dataf.calc_radial_dist(dataf.get_ysize()/2-1,1,1,1)
	print "compute power 2"
	noisepow=noisef.calc_radial_dist(noisef.get_ysize()/2-1,1,1,1)

	x=range(1,len(datapow)+1)
	if options.apix>0:
		x=[i/(len(datapow)*options.apix*2.0) for i in x]
	else:
		x=[i/(len(datapow)*data["apix_x"]*2.0) for i in x]

	# normalize noise near Nyquist
	s=0
	sn=0
	for i in range(int(len(noisepow)*.9),len(noisepow)-1):
		if datapow[i]<datapow[i+1] or noisepow[i]<noisepow[i+1] : continue
		s+=datapow[i]/noisepow[i]
		sn+=1.0
	if sn==0 :
		print "Warning, strange normalization"
		s=datapow[int(len(noisepow)*.9)]/noisepow[int(len(noisepow)*.9)]
	else: s/=sn

	noisepow=[i*s for i in noisepow]
#
#	# normalize based on volume
#	datapow=[v/mask["mean"] for v in datapow]
#	noisepow=[v/maski["mean"] for v in noisepow]

	# compute signal to noise ratio
	snr=[]
	for i in range(len(datapow)):
		try: snr.append((datapow[i]-noisepow[i])/noisepow[i])
		except: snr.append(0)
	
	# convert to FSC
	fsc=[i/(2.0+i) for i in snr]

	out=file(args[2],"w")
	for i in range(len(fsc)): out.write("%f\t%f\n"%(x[i],fsc[i]))
	out.close()
	
	out=file(args[2]+".dat","w")
	for i in range(len(fsc)): out.write("%f\t%f\n"%(x[i],datapow[i]))
	out.close()

	out=file(args[2]+".noi","w")
	for i in range(len(noisepow)): out.write("%f\t%f\n"%(x[i],noisepow[i]))
	out.close()
	
	if options.path != None:
		s = base_name(args[0])
		db = db_open_dict("bdb:"+options.path+"#convergence.results")	
		db[s+"res_fsc"] = [x,fsc] # warning, changing this naming convention will disrupt forms in the workflow (make them fail)
		db[s+"res_datapow"] = [x,datapow]
		db[s+"res_noisepow"] = [x,noisepow]
		db_close_dict("bdb:"+options.path+"#convergence.results")
		

	E2end(E2n)