Ejemplo n.º 1
0
def parse_relion(fp):

    star_dict = StarFile(fp)

    training_data_dict = {}

    # Check that the STAR file contains necessary metadata for the particles
    metadata_list = [
        'rlnVoltage', 'rlnSphericalAberration', 'rlnAmplitudeContrast',
        'rlnImagePixelSize'
    ]
    for metadata in metadata_list:
        if metadata not in star_dict:
            warnings.warn('STAR file is missing metadata: %s' % metadata)
        else:
            training_data_dict[metadata] = star_dict[metadata][0]

    # Check that the STAR file has the following necessary parameters for particles
    parameter_list = ['rlnCoordinateX', 'rlnCoordinateY', 'rlnMicrographName']
    for parameter in parameter_list:
        if parameter in star_dict:
            training_data_dict[parameter] = star_dict[parameter]
        else:
            raise Exception('STAR file is missing necessary parameter: %s' %
                            parameter)
    assert (len(star_dict['rlnCoordinateX']) == len(
        star_dict['rlnCoordinateY']) == len(star_dict['rlnMicrographName'])
            )  # sanity check

    return training_data_dict
Ejemplo n.º 2
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """prog [options] <relion STAR file>

This program will take data from a Relion project and convert it into a basic EMAN2 project. Provide 
the name of the Relion STAR file associated with the raw particle data. An eman2 subdirectory will be
created, and the images, and available metadata will be copied into the new project. CTF parameters
will be extracted from the STAR file and stored as frame CTF parameters. You will still need to run
CTF autoprocessing after importing is complete.

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

	#options associated with e2refine.py
	parser.add_header(name="text1", help='Important instructions', title="Use this to create an EMAN2.1 project from a Relion project:", row=0, col=0, rowspan=1, colspan=3)
	parser.add_header(name="text2", help='Important instructions', title="* cd <folder with Relion STAR file>", row=1, col=0, rowspan=1, colspan=3)
	parser.add_header(name="text3", help='Important instructions', title="* run e2projectmanager, and use this tool", row=2, col=0, rowspan=1, colspan=3)
	parser.add_header(name="text4", help='Important instructions', title="* exit PM, cd eman2, run PM from new eman2 folder", row=3, col=0, rowspan=1, colspan=3)
	parser.add_pos_argument(name="star_file",help="Select STAR file", default="", guitype='filebox', browser="EMParticlesEditTable(withmodal=True,multiselect=False)",  row=6, col=0,rowspan=1, colspan=3)
	parser.add_argument("--apix", default=0, type=float,help="The angstrom per pixel of the input particles.", guitype='floatbox', row=8, col=0, rowspan=1, colspan=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")
	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()


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

	try: os.mkdir("eman2")
	except: pass
	try: os.mkdir("eman2/particles")
	except: pass
	os.chdir("eman2")	# many things need to happen with the project directory as a base

	if options.verbose>0 : print("Parsing STAR file")
	star=StarFile("../"+args[0])

	if options.apix<=0 :
		try:
			options.apix=old_div(star["rlnDetectorPixelSize"][0],star["rlnMagnification"][0])*10000.0
			print("Using {} A/pix from Relion file".format(options.apix))
		except:
			print("A/pix not specified and not found in STAR file")
			sys.exit(1)

	prj=js_open_dict("info/project.json")
	try:
		prj["global.apix"]=options.apix
		prj["global.microscope_cs"]=star["rlnSphericalAberration"][0]
		if prj["global.microscope_cs"]<=0.0 : prj["global.microscope_cs"]=0.001
		prj["global.microscope_voltage"]=star["rlnVoltage"][0]
		print("V={} Cs={}".format(prj["global.microscope_voltage"],prj["global.microscope_cs"]))
	except:
		print("Did not find Voltage and Cs in Relion file")
	
	if "rlnMicrographName" in star : difkey="rlnMicrographName"
	else: difkey="rlnDefocusU"
	
	oldname=""
	olddf=-1.0
	micronum=0		# number of micrograph
	fnum=0			# image number in new file
	for i in range(len(star["rlnImageName"])):
		name=star["rlnImageName"][i].split("@")[1]
		imgnum=int(star["rlnImageName"][i].split("@")[0])-1
	
		if name!=oldname:
			hdr=EMData("../"+name,0,True)
			nx=hdr["nx"]
			ny=hdr["ny"]
			oldname=name
			if options.verbose>0 : print("Particle dimensions: {}x{}".format(nx,ny))
		
		if i==0 or star[difkey][i-1]!=star[difkey][i]:
			if micronum>0 and options.verbose>0 : print("Image {}: {} particles processed, df={}".format(micronum,fnum,ctf.defocus))
			micronum+=1
			fnum=0
			microname="particles/{}_{:04d}.hdf".format(base_name(name),micronum)
			jdb=js_open_dict(info_name(microname))
			
			# Make a "micrograph" CTF entry for each set of different defocuses to use when fitting
			dfu=star["rlnDefocusU"][i]
			dfv=star["rlnDefocusV"][i]
			dfang=star["rlnDefocusAngle"][i]
			ctf=EMAN2Ctf()
			ctf.from_dict({"defocus":old_div((dfu+dfv),20000.0),"dfang":dfang,"dfdiff":old_div((dfu-dfv),10000.0),"voltage":star["rlnVoltage"][i],"cs":max(star["rlnSphericalAberration"][i],0.0001),"ampcont":star["rlnAmplitudeContrast"][i]*100.0,"apix":options.apix})
			jdb["ctf_frame"]=[512,ctf,(256,256),tuple(),5,1]
		
		# copy the image
		if name[-5:]==".mrcs" : img=EMData("../"+name,imgnum)		# read one slice from the MRC stack
		else: img=EMData("../"+name,0,False,Region(0,0,imgnum,nx,ny,1))		# read one slice from the MRC stack
		img.write_image(microname,fnum)
		fnum+=1

	
	E2end(logid)
Ejemplo n.º 3
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] files
	This program performs a variety of tasks for getting data or metadata from other programs into an EMAN2 project.

	import_particles - will simply copy a set of per-micrograph particle files into EMAN2.1's preferred HDF format in particles/
	import_boxes - will read EMAN1 '.box' files (text files containing coordinates) into appropriate info/*json files (see --box_type)
	import_tomos - imports subtomogams for a SPT project (see also --importation)
	import_eman1 - will convert a typical EMAN1 phase-flipped start.hed/img file into an EMAN2 project (converting files, fixing CTF, splitting, ...)
"""

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

    parser.add_pos_argument(
        name="import_files",
        help="List the files to import here.",
        default="",
        guitype='filebox',
        browser="EMBrowserWidget(withmodal=True,multiselect=True)",
        row=0,
        col=0,
        rowspan=1,
        colspan=2,
        nosharedb=True,
        mode='coords,parts,tomos,eman1')
    parser.add_header(name="filterheader",
                      help='Options below this label are specific to e2import',
                      title="### e2import options ###",
                      row=1,
                      col=0,
                      rowspan=1,
                      colspan=2,
                      mode='coords,parts,tomos')
    parser.add_argument("--import_particles",
                        action="store_true",
                        help="Import particles",
                        default=False,
                        guitype='boolbox',
                        row=2,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode='parts[True]')
    parser.add_argument(
        "--import_eman1",
        action="store_true",
        help="This will import a phase-flipped particle stack from EMAN1",
        default=False,
        guitype='boolbox',
        row=2,
        col=0,
        rowspan=1,
        colspan=1,
        mode='eman1[True]')
    parser.add_argument("--import_tomos",
                        action="store_true",
                        help="Import tomograms",
                        default=False,
                        guitype='boolbox',
                        row=2,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode='tomos[True]')
    parser.add_argument(
        "--shrink",
        type=int,
        help=
        "Shrink tomograms before importing. Dose not work while not copying.",
        default=1,
        guitype='intbox',
        row=3,
        col=0,
        rowspan=1,
        colspan=1,
        mode='tomos')
    parser.add_argument("--invert",
                        action="store_true",
                        help="Invert the contrast before importing tomograms",
                        default=False,
                        guitype='boolbox',
                        row=3,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode='tomos')
    parser.add_argument(
        "--tomoseg_auto",
        action="store_true",
        help=
        "Default process for tomogram segmentation, including lowpass, highpass, normalize, clampminmax.",
        default=True,
        guitype='boolbox',
        row=3,
        col=2,
        rowspan=1,
        colspan=1,
        mode='tomos')
    parser.add_argument(
        "--importation",
        help="Specify mode move, copy or link, for importing tomograms only",
        default='copy',
        guitype='combobox',
        choicelist='["move","copy","link"]',
        row=2,
        col=1,
        rowspan=1,
        colspan=1,
        mode='tomos')
    parser.add_argument(
        "--preprocess",
        type=str,
        help=
        "Other pre-processing operation before importing tomograms. Dose not work while not copying.",
        default="",
        guitype='strbox',
        row=4,
        col=0,
        rowspan=1,
        colspan=2,
        mode='tomos')
    parser.add_argument("--import_boxes",
                        action="store_true",
                        help="Import boxes",
                        default=False,
                        guitype='boolbox',
                        row=2,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode='coords[True]')
    parser.add_argument(
        "--extension",
        type=str,
        help="Extension of the micrographs that the boxes match",
        default='dm3')
    parser.add_argument(
        "--box_type",
        help=
        "Type of boxes to import, normally boxes, but for tilted data use tiltedboxes, and untiltedboxes for the tilted  particle partner",
        default="boxes",
        guitype='combobox',
        choicelist=
        '["boxes","coords","relion_star","tiltedboxes","untiltedboxes"]',
        row=2,
        col=1,
        rowspan=1,
        colspan=1,
        mode="coords['boxes']")
    parser.add_argument("--boxsize",
                        help="Specify the boxsize for each particle.",
                        type=int,
                        default=256)
    parser.add_argument(
        "--curdefocushint",
        action="store_true",
        help="Used with import_eman1, will use EMAN1 defocus as starting point",
        default=False,
        guitype='boolbox',
        row=4,
        col=0,
        rowspan=1,
        colspan=1,
        mode='eman1[True]')
    parser.add_argument(
        "--curdefocusfix",
        action="store_true",
        help=
        "Used with import_eman1, will use EMAN1 defocus unchanged (+-.001 um)",
        default=False,
        guitype='boolbox',
        row=4,
        col=1,
        rowspan=1,
        colspan=1,
        mode='eman1[False]')
    parser.add_argument(
        "--threads",
        default=1,
        type=int,
        help=
        "Number of threads to run in parallel on a single computer when multi-computer parallelism isn't useful",
        guitype='intbox',
        row=6,
        col=0,
        rowspan=1,
        colspan=1,
        mode='eman1[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")
    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()
    logid = E2init(sys.argv, options.ppid)

    # Import EMAN1
    # will read start.hed/img, split by micrograph (based on defocus), and reprocess CTF in EMAN2 style
    if options.import_eman1:
        try:
            n = EMUtil.get_image_count(args[0])
        except:
            print("Error, couldn't read images from: ", args[0])
            sys.exit(1)

        try:
            img = EMData(args[0], 0)
            ctf = img["ctf"]
        except:
            print("Error, start.hed/img must be phase-flipped to import")
            sys.exit(1)

        db = js_open_dict("info/project.json")
        db["global.apix"] = ctf.apix
        db["global.cs"] = ctf.cs
        db["global.voltage"] = ctf.voltage

        try:
            os.mkdir("particles")
        except:
            pass

        imgnum = 0
        lastdf = -1.0
        for i in xrange(n):
            img = EMData(args[0], i)
            ctf = img["ctf"]
            img.del_attr("ctf")
            fft1 = img.do_fft()
            if ctf.defocus != lastdf:
                imgnum += 1
                if options.verbose > 0:
                    print("Defocus {:4.2f} particles{:03d}".format(
                        ctf.defocus, imgnum))
                db = js_open_dict(
                    "info/particles{:03d}_info.json".format(imgnum))
                ctf2 = EMAN2Ctf()
                ctf2.defocus = ctf.defocus
                ctf2.cs = ctf.cs
                ctf2.apix = ctf.apix
                ctf2.voltage = ctf.voltage
                ctf2.ampcont = ctf.ampcont
                ctf2.dfdiff = 0
                ctf2.dfang = 0
                db["ctf"] = [ctf2]
                db.close()

                flipim = fft1.copy()
                ctf2.compute_2d_complex(flipim, Ctf.CtfType.CTF_SIGN)

            lastdf = ctf.defocus

            # unflip the EMAN1 phases (hopefully accurate enough)
            fft1.mult(flipim)
            img = fft1.do_ift()
            img.write_image("particles/particles{:03d}.hdf".format(imgnum),
                            -1)  # append particle to stack

        if options.curdefocusfix:
            flag = "--curdefocusfix"
            rbysnr = " "
        elif options.curdefocushint:
            flag = "--curdefocushint"
            rbysnr = "--refinebysnr"
        else:
            flag = ""
            rbysnr = "--refinebysnr"

        # fill in the needed CTF info
        launch_childprocess(
            "e2ctf.py --autofit {} --allparticles --threads {} --voltage {} --cs {} --ac {} --apix {} --computesf"
            .format(flag, options.threads, ctf.voltage, ctf.cs, ctf.ampcont,
                    ctf.apix))
        launch_childprocess(
            "e2ctf.py --autofit {} --allparticles --threads {} --voltage {} --cs {} --ac {} --apix {}"
            .format(flag, options.threads, ctf.voltage, ctf.cs, ctf.ampcont,
                    ctf.apix))

        # reflip flip the phases, and make "proc" images
        launch_childprocess(
            "e2ctf.py {} --phaseflip --allparticles --phaseflipproc filter.highpass.gauss:cutoff_freq=0.005 --phaseflipproc2 filter.lowpass.gauss:cutoff_freq=0.08 --phaseflipproc3 math.meanshrink:n=2"
            .format(rbysnr))

        # build sets
        launch_childprocess("e2buildsets.py --allparticles --setname all")

    # Import boxes
    if options.import_boxes:
        # Check to make sure there are micrographs
        if not os.access("info", os.R_OK):
            os.mkdir("info")
        # Do imports
        # we add boxsize/2 to the coords since box files are stored with origin being the lower left side of the box, but in EMAN2 origin is in the center
        if options.box_type == 'boxes':
            micros = os.listdir("micrographs")
            for filename in args:
                boxlist = []
                fh = open(filename, 'r')
                for line in fh.readlines():
                    if line[0] == "#": continue
                    fields = line.split()
                    if len(fields) < 4: continue  # skip lines that don't work
                    boxlist.append([
                        float(fields[0]) + float(fields[3]) / 2,
                        float(fields[1]) + float(fields[3]) / 2, 'manual'
                    ])

                js = js_open_dict(info_name(filename, nodir=True))
                js["boxes"] = boxlist
                js.close()
                if not "{}.hdf".format(base_name(filename,
                                                 nodir=True)) in micros:
                    print(
                        "Warning: Imported boxes for {}, but micrographs/{}.hdf does not exist"
                        .format(base_name(filename), base_name(filename,
                                                               True)))

        elif options.box_type == 'coords':
            micros = os.listdir("micrographs")
            for filename in args:
                boxlist = []
                fh = open(filename, 'r')
                for line in fh.readlines():
                    if line[0] == "#": continue
                    fields = line.split()
                    if len(fields) < 2: continue  # skip lines that don't work
                    boxlist.append(
                        [float(fields[0]),
                         float(fields[1]), 'manual'])
                js_open_dict(info_name(filename,
                                       nodir=True))["boxes"] = boxlist
                if not "{}.hdf".format(base_name(filename,
                                                 nodir=True)) in micros:
                    print(
                        "Warning: Imported boxes for {}, but micrographs/{}.hdf does not exist"
                        .format(base_name(filename), base_name(filename,
                                                               True)))

        elif options.box_type == 'tiltedboxes':

            for filename in args:
                boxlist = []
                fh = open(filename, 'r')
                for line in fh.readlines():
                    if line[0] == "#": continue
                    fields = line.split()
                    if len(fields) < 4: continue  # skip lines that don't work
                    boxlist.append([
                        float(fields[0]) + float(fields[3]) / 2,
                        float(fields[1]) + float(fields[3]) / 2, 'tilted'
                    ])
                js_open_dict(info_name(filename,
                                       nodir=True))["boxes_rct"] = boxlist

        elif options.box_type == 'untiltedboxes':
            for filename in args:
                boxlist = []
                fh = open(filename, 'r')
                for line in fh.readlines():
                    if line[0] == "#": continue
                    fields = line.split()
                    if len(fields) < 4: continue  # skip lines that don't work
                    boxlist.append([
                        float(fields[0]) + float(fields[3]) / 2,
                        float(fields[1]) + float(fields[3]) / 2, 'untilted'
                    ])
                js_open_dict(info_name(filename,
                                       nodir=True))["boxes_rct"] = boxlist

        elif options.box_type == 'relion_star':
            bs = options.boxsize
            starfs = [f for f in args if '.star' in f]
            if len(starfs) < 1:
                print(
                    "You must specify at least one .star file containing particle coordinates"
                )
                exit(1)
            for filename in starfs:
                print(("Importing from {}.star".format(
                    base_name(filename, nodir=True))))
                sf = StarFile(filename)
                hdr = sf.keys()
                if len(hdr) < 3:
                    print(("Could not parse {}".format(filename)))
                    continue
                mk = "rlnMicrographName"
                yk = "rlnCoordinateY"
                xk = "rlnCoordinateX"
                project_micros = os.listdir('micrographs')
                if mk not in hdr or yk not in hdr or xk not in hdr:
                    possible = "{}.hdf".format(
                        base_name(filename.replace('_autopick.star', ''),
                                  nodir=True))
                    if possible in project_micros:
                        micros = [possible]
                    else:
                        print((
                            "{} does not follow the RELION header convention for single particle data. To use this program"
                            .format(filename)))
                        if mk not in hdr:
                            print(
                                "Micrograph names should be listed under _rlnMicrographName"
                            )
                        if yk not in hdr:
                            print(
                                "Y coordinates must be listed under _rlnCoordinateY"
                            )
                        if xk not in hdr:
                            print(
                                "X coordinates must be listed under _rlnCoordinateX"
                            )
                        continue
                else:
                    micros = [i.split('/')[-1] for i in np.unique(sf[mk])]
                if len(micros) == 1:
                    mg = micros[0]
                    boxlist = []
                    print(("Found {} boxes for {}".format(len(sf[xk]), mg)))
                    for x, y in zip(sf[xk], sf[yk]):
                        xc = int(x)
                        yc = int(y)
                        boxlist.append([
                            xc, yc, 'manual'
                        ])  # should probably be 'relion' or 'from_star'
                    js_open_dict(info_name(mg, nodir=True))["boxes"] = boxlist
                    if not "{}.hdf".format(base_name(
                            mg, nodir=True)) in project_micros:
                        print(
                            "Warning: Imported boxes for {}.hdf, but micrographs/{}.hdf does not exist"
                            .format(base_name(filename),
                                    base_name(mg, nodir=True)))
                elif len(micros) > 1:
                    for mg in project_micros:
                        boxlist = []
                        ptcls = []
                        for i, name in enumerate(sf[mk]):
                            mgname = name.split('/')[-1].split('.')[0]
                            #print(mgname,hdf_name,mg)
                            if mg[:-4] in mgname: ptcls.append(i)
                        print(("Found {} boxes for {}".format(len(ptcls), mg)))
                        for p in ptcls:
                            xc = int(sf[xk][p])
                            yc = int(sf[yk][p])
                            boxlist.append([xc, yc, 'manual'])
                        js_open_dict(info_name(mg,
                                               nodir=True))["boxes"] = boxlist
                        if not "{}.hdf".format(base_name(
                                mg, nodir=True)) in project_micros:
                            print(
                                "Warning: Imported boxes for {}, but micrographs/{}.hdf does not exist"
                                .format(base_name(mg), base_name(mg,
                                                                 nodir=True)))

        else:
            print("ERROR: Unknown box_type")

    # Import particles
    if options.import_particles:
        if not os.access("particles", os.R_OK):
            os.mkdir("particles")

        fset = set([base_name(i) for i in args])
        if len(fset) != len(args):
            print(
                "ERROR: You specified multiple files to import with the same base name, eg - a10/abc123.spi and a12/abc123.spi. If you have multiple images with the same \
name, you will need to modify your naming convention (perhaps by prefixing the date) before importing. If the input files are in IMAGIC format, so you have .hed and .img files \
with the same name, you should specify only the .hed files (no renaming is necessary)."
            )
            sys.exit(1)

        for i, fsp in enumerate(args):
            E2progress(logid, float(i) / len(args))
            if EMData(fsp, 0, True)["nz"] > 1:
                run("e2proc2d.py {} particles/{}.hdf --threed2twod --inplace".
                    format(fsp, base_name(fsp)))
            else:
                run("e2proc2d.py {} particles/{}.hdf --inplace".format(
                    fsp, base_name(fsp)))

    # Import tomograms
    if options.import_tomos:
        tomosdir = os.path.join(".", "rawtomograms")
        if not os.access(tomosdir, os.R_OK):
            os.mkdir("rawtomograms")
        for filename in args:
            if options.importation == "move":
                os.rename(filename,
                          os.path.join(tomosdir, os.path.basename(filename)))
            if options.importation == "copy":
                ### use hdf file as output

                if options.shrink > 1:
                    shrinkstr = "_bin{:d}".format(options.shrink)
                else:
                    shrinkstr = ""

                tpos = filename.rfind('.')
                if tpos > 0:
                    newname = os.path.join(
                        tomosdir,
                        os.path.basename(filename[:tpos] + shrinkstr + '.hdf'))
                else:
                    newname = os.path.join(tomosdir,
                                           os.path.basename(filename))
                cmd = "e2proc3d.py {} {} ".format(filename, newname)
                if options.shrink > 1:
                    cmd += " --meanshrink {:d} ".format(options.shrink)
                if options.invert:
                    cmd += " --mult -1 --process normalize "
                if options.tomoseg_auto:
                    cmd += " --process filter.lowpass.gauss:cutoff_abs=.25 --process filter.highpass.gauss:cutoff_pixels=5 --process normalize --process threshold.clampminmax.nsigma:nsigma=3 "
                cmd += options.preprocess
                run(cmd)
                print("Done.")
                #shutil.copy(filename,os.path.join(tomosdir,os.path.basename(filename)))
            if options.importation == "link":
                os.symlink(filename,
                           os.path.join(tomosdir, os.path.basename(filename)))
    E2end(logid)
Ejemplo n.º 4
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """prog [options] files
	This program performs a variety of tasks for getting data or metadata from other programs into an EMAN2 project.

	import_movies - imports DDD movie data for a cryoEM project (--importation copy recommended)

	import_particles - will simply copy a set of per-micrograph particle files into EMAN2.1's preferred HDF format in particles/
	import_boxes - will read EMAN1 '.box' files (text files containing coordinates) into appropriate info/*json files (see --box_type)
	import_eman1 - will convert a typical EMAN1 phase-flipped start.hed/img file into an EMAN2 project (converting files, fixing CTF, splitting, ...)

	import_tomos - flag to handle imported files as subtomogams for a SPT project (see also --importation)
	import_serialem - flag to handle imported files as SerialEM mdoc files
	import_fei - flag to handle imported files as FEI tomography metadata files
	import_ucsftomo - flag to handle imported files as UCSF tomo metadata files
	import_tiltseries - imports tilt series for a tomography project (--importation copy recommended)
	"""

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

	parser.add_pos_argument(name="files",help="List the files to import here.", default="", guitype='filebox', browser="EMBrowserWidget(withmodal=True,multiselect=True)",  row=0, col=0, rowspan=1, colspan=3, nosharedb=True, mode='coords,parts,tomos,eman1,movies,rawtilts,meta,tiltseries')

	parser.add_header(name="filterheader", help='Options below this label are specific to e2import', title="### e2import options ###", row=2, col=0, rowspan=1, colspan=2, mode='coords,parts')

	# Type Flags
	parser.add_argument("--import_movies",action="store_true",help="Import DDD movies",default=False, guitype='boolbox', row=3, col=0, rowspan=1, colspan=1, mode='movies[True]')

	parser.add_argument("--darkrefs",help="Specify a comma separated list of dark refereence stacks/images to import. Files will be placed in movierefs_raw. See --importation for additional options.",default="", guitype='filebox', browser="EMBrowserWidget(withmodal=True,multiselect=True)", row=4, col=0, rowspan=1, colspan=2, mode='movies')
	parser.add_argument("--gainrefs",help="Specify a comma separated list of gain refereence stacks/images to import. Files will be placed in movierefs_raw. See --importation for additional options.",default="", guitype='filebox', browser="EMBrowserWidget(withmodal=True,multiselect=True)", row=5, col=0, rowspan=1, colspan=2, mode='movies')

	#parser.add_argument("--import_rawtilts",action="store_true",help="Import tilt images",default=False, guitype='boolbox', row=4, col=2, rowspan=1, colspan=1, mode='rawtilts[True]')
	parser.add_argument("--apix",help="Specify the apix of the tiltseries you are importing. If -1 (default), the apix in the header will not be changed.",type=float,default=-1,guitype='floatbox', row=5, col=1, rowspan=1, colspan=1,mode='tiltseries[-1]')

	parser.add_argument("--import_tiltseries",action="store_true",help="Import tiltseries",default=False, guitype='boolbox', row=5, col=2, rowspan=1, colspan=1, mode='tiltseries[True]')
	parser.add_argument("--import_tomos",action="store_true",help="Import tomograms for segmentation and/or subtomogram averaging",default=False, guitype='boolbox', row=4, col=2, rowspan=1, colspan=1, mode='tomos[True]')

	#parser.add_pos_argument(name="tilt_angles",help="Specify a file containing tilt angles corresponding to the input tilt images.", default="", guitype='filebox', browser="EMBrowserWidget(withmodal=True,multiselect=True)",  row=0, col=0, rowspan=1, colspan=2, nosharedb=True, mode='rawtilts')

	#parser.add_argument(name="--rawtlt",help="List the text file containing tilt angles for the tiltseries to be imported.", default="", guitype='filebox', browser="EMBrowserWidget(withmodal=True,multiselect=False)",  row=3, col=0, rowspan=1, colspan=3, nosharedb=True, mode='tiltseries')
	#parser.add_argument(name="--start",help="First tilt angle. Increment determined by number of tilts. Custom tilt angles can be specified by a tilt angles text file.", default="", guitype='floatbox', row=4, col=0, rowspan=1, colspan=3, nosharedb=True, mode='tiltseries')
	#parser.add_argument(name="--stop",help="Final tilt angle. Increment determined by number of tilts. Custom tilt angles can be specified by a tilt angles text file.", default="", guitype='floatbox', row=4, col=1, rowspan=1, colspan=3, nosharedb=True, mode='tiltseries')

	# parser.add_argument("--serialem_mdoc",action="store_true",help="Import metadata from corresponding SerialEM '.mdoc' files.",default=False, guitype='boolbox', row=1, col=0, rowspan=1, colspan=3, mode='meta')
	# parser.add_argument("--fei_tomo",action="store_true",help="Import metadata from corresponding FEI tomography files.",default=False, guitype='boolbox', row=2, col=0, rowspan=1, colspan=3, mode='meta')
	# parser.add_argument("--ucsf_tomo",action="store_true",help="Import metadata from corresponding UCSF Tomo files.",default=False, guitype='boolbox', row=3, col=0, rowspan=1, colspan=3, mode='meta')

	parser.add_argument("--import_particles",action="store_true",help="Import particles",default=False, guitype='boolbox', row=3, col=0, rowspan=1, colspan=1, mode='parts[True]')
	parser.add_argument("--import_eman1",action="store_true",help="This will import a phase-flipped particle stack from EMAN1",default=False, guitype='boolbox', row=3, col=0, rowspan=1, colspan=1, mode='eman1[True]')

	parser.add_argument("--importation",help="Specify import mode: move, copy or link",default='copy',guitype='combobox',choicelist='["move","copy","link"]',row=9,col=0,rowspan=1,colspan=2, mode='tomos["copy"],rawtilts["copy"],movies["move"],tiltseries["copy"]',choices=["move","copy","link"])

	parser.add_argument("--invert",action="store_true",help="Invert the contrast before importing tomograms",default=False, guitype='boolbox', row=5, col=0, rowspan=1, colspan=1, mode='tomos,rawtilts,tiltseries')
	#parser.add_argument("--tomoseg_auto",action="store_true",help="Default process for tomogram segmentation, including lowpass, highpass, normalize, clampminmax.",default=True, guitype='boolbox', row=4, col=1, rowspan=1, colspan=1, mode='tomos,rawtilts,tiltseries')
	parser.add_argument("--shrink",type=int,help="Shrink tomograms before importing. Does not work while not copying.",default=1, guitype='intbox', row=6, col=0, rowspan=1, colspan=1, mode='tomos')
	#parser.add_argument("--preprocess",type=str,help="Other pre-processing operation before importing tomograms. Dose not work while not copying.",default="", guitype='strbox', row=6, col=0, rowspan=1, colspan=2, mode='tomos,rawtilts,tiltseries')

	parser.add_argument("--import_boxes",action="store_true",help="Import boxes",default=False, guitype='boolbox', row=3, col=0, rowspan=1, colspan=1, mode='coords[True]')
	parser.add_argument("--extension",type=str,help="Extension of the micrographs that the boxes match", default='dm3')
	parser.add_argument("--box_type",help="Type of boxes to import, normally boxes, but for tilted data use tiltedboxes, and untiltedboxes for the tilted  particle partner",default="boxes",guitype='combobox',choicelist='["boxes","coords","relion_star","tiltedboxes","untiltedboxes"]',row=3,col=1,rowspan=1,colspan=1, mode="coords['boxes']")
	parser.add_argument("--boxsize",help="Specify the boxsize for each particle.",type=int,default=256)
	parser.add_argument("--curdefocushint",action="store_true",help="Used with import_eman1, will use EMAN1 defocus as starting point",default=False, guitype='boolbox', row=5, col=0, rowspan=1, colspan=1, mode='eman1[True]')
	parser.add_argument("--curdefocusfix",action="store_true",help="Used with import_eman1, will use EMAN1 defocus unchanged (+-.001 um)",default=False, guitype='boolbox', row=5, col=1, rowspan=1, colspan=1, mode='eman1[False]')

	parser.add_argument("--threads", default=1,type=int,help="Number of threads to run in parallel on a single computer when multi-computer parallelism isn't useful",guitype='intbox', row=7, col=0, rowspan=1, colspan=1, mode='eman1[1]')
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n", type=int, default=0, help="verbose level [0-9], higher number means higher level of verboseness")
	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()
	logid=E2init(sys.argv,options.ppid)

	# Import EMAN1
	# will read start.hed/img, split by micrograph (based on defocus), and reprocess CTF in EMAN2 style
	if options.import_eman1 :
		try:
			n=EMUtil.get_image_count(args[0])
		except:
			print("Error, couldn't read images from: ",args[0])
			sys.exit(1)

		try:
			img=EMData(args[0],0)
			ctf=img["ctf"]
		except:
			print("Error, start.hed/img must be phase-flipped to import")
			sys.exit(1)

		db=js_open_dict("info/project.json")
		db["global.apix"]=ctf.apix
		db["global.cs"]=ctf.cs
		db["global.voltage"]=ctf.voltage

		try: os.mkdir("particles")
		except: pass

		imgnum=0
		lastdf=-1.0
		for i in range(n):
			img=EMData(args[0],i)
			ctf=img["ctf"]
			img.del_attr("ctf")
			fft1=img.do_fft()
			if ctf.defocus!=lastdf :
				imgnum+=1
				if options.verbose>0: print("Defocus {:4.2f} particles{:03d}".format(ctf.defocus,imgnum))
				db=js_open_dict("info/particles{:03d}_info.json".format(imgnum))
				ctf2=EMAN2Ctf()
				ctf2.defocus=ctf.defocus
				ctf2.cs=ctf.cs
				ctf2.apix=ctf.apix
				ctf2.voltage=ctf.voltage
				ctf2.ampcont=ctf.ampcont
				ctf2.dfdiff=0
				ctf2.dfang=0
				db["ctf"]=[ctf2]
				db.close()

				flipim=fft1.copy()
				ctf2.compute_2d_complex(flipim,Ctf.CtfType.CTF_SIGN)

			lastdf=ctf.defocus

			# unflip the EMAN1 phases (hopefully accurate enough)
			fft1.mult(flipim)
			img=fft1.do_ift()
			img.write_image("particles/particles{:03d}.hdf".format(imgnum),-1)		# append particle to stack

		if options.curdefocusfix:
			flag="--curdefocusfix"
			rbysnr=" "
		elif options.curdefocushint:
			flag="--curdefocushint"
			rbysnr="--refinebysnr"
		else:
			flag=""
			rbysnr="--refinebysnr"

		# fill in the needed CTF info
		launch_childprocess("e2ctf.py --autofit {} --allparticles --threads {} --voltage {} --cs {} --ac {} --apix {} --computesf".format(flag,options.threads,ctf.voltage,ctf.cs,ctf.ampcont,ctf.apix))
		launch_childprocess("e2ctf.py --autofit {} --allparticles --threads {} --voltage {} --cs {} --ac {} --apix {}".format(flag,options.threads,ctf.voltage,ctf.cs,ctf.ampcont,ctf.apix))

		# reflip flip the phases, and make "proc" images
		launch_childprocess("e2ctf.py {} --phaseflip --allparticles --phaseflipproc filter.highpass.gauss:cutoff_freq=0.005 --phaseflipproc2 filter.lowpass.gauss:cutoff_freq=0.08 --phaseflipproc3 math.meanshrink:n=2".format(rbysnr))

		# build sets
		launch_childprocess("e2buildsets.py --allparticles --setname all")

	# Import boxes
	if options.import_boxes:
		# Check to make sure there are micrographs
		if not os.access("info", os.R_OK):
			os.mkdir("info")
		# Do imports
		# we add boxsize/2 to the coords since box files are stored with origin being the lower left side of the box, but in EMAN2 origin is in the center
		if options.box_type == 'boxes':
			micros=os.listdir("micrographs")
			for filename in args:
				boxlist = []
				fh = open(filename, 'r')
				for line in fh.readlines():
					if line[0]=="#" : continue
					fields = line.split()
					if len(fields)<4 : continue		# skip lines that don't work
					boxlist.append([float(fields[0])+old_div(float(fields[3]),2), float(fields[1])+old_div(float(fields[3]),2), 'manual'])

				js=js_open_dict(info_name(filename,nodir=True))
				js["boxes"]=boxlist
				js.close()
				if not "{}.hdf".format(base_name(filename,nodir=True)) in micros:
					print("Warning: Imported boxes for {}, but micrographs/{}.hdf does not exist".format(base_name(filename),base_name(filename,True)))

		elif options.box_type == 'coords':
			micros=os.listdir("micrographs")
			for filename in args:
				boxlist = []
				fh = open(filename, 'r')
				for line in fh.readlines():
					if line[0]=="#" : continue
					fields = line.split()
					if len(fields)<2 : continue		# skip lines that don't work
					boxlist.append([float(fields[0]), float(fields[1]), 'manual'])
				js_open_dict(info_name(filename,nodir=True))["boxes"]=boxlist
				if not "{}.hdf".format(base_name(filename,nodir=True)) in micros:
					print("Warning: Imported boxes for {}, but micrographs/{}.hdf does not exist".format(base_name(filename),base_name(filename,True)))


		elif options.box_type == 'tiltedboxes':

			for filename in args:
				boxlist = []
				fh = open(filename, 'r')
				for line in fh.readlines():
					if line[0]=="#" : continue
					fields = line.split()
					if len(fields)<4 : continue		# skip lines that don't work
					boxlist.append([float(fields[0])+old_div(float(fields[3]),2), float(fields[1])+old_div(float(fields[3]),2), 'tilted'])
				js_open_dict(info_name(filename,nodir=True))["boxes_rct"]=boxlist

		elif options.box_type == 'untiltedboxes':
			for filename in args:
				boxlist = []
				fh = open(filename, 'r')
				for line in fh.readlines():
					if line[0]=="#" : continue
					fields = line.split()
					if len(fields)<4 : continue		# skip lines that don't work
					boxlist.append([float(fields[0])+old_div(float(fields[3]),2), float(fields[1])+old_div(float(fields[3]),2), 'untilted'])
				js_open_dict(info_name(filename,nodir=True))["boxes_rct"]=boxlist

		elif options.box_type == 'relion_star':
			bs = options.boxsize
			starfs = [f for f in args if '.star' in f]
			if len(starfs) < 1:
				print("You must specify at least one .star file containing particle coordinates")
				exit(1)
			for filename in starfs:
				print(("Importing from {}.star".format(base_name(filename,nodir=True))))
				sf = StarFile(filename)
				hdr = list(sf.keys())
				if len(hdr) < 3:
					print(("Could not parse {}".format(filename)))
					continue
				mk = "rlnMicrographName"
				yk = "rlnCoordinateY"
				xk = "rlnCoordinateX"
				project_micros = os.listdir('micrographs')
				if mk not in hdr or yk not in hdr or xk not in hdr:
					possible = "{}.hdf".format(base_name(filename.replace('_autopick.star',''),nodir=True))
					if possible in project_micros:
						micros = [possible]
					else:
						print(("{} does not follow the RELION header convention for single particle data. To use this program".format(filename)))
						if mk not in hdr: print("Micrograph names should be listed under _rlnMicrographName")
						if yk not in hdr: print("Y coordinates must be listed under _rlnCoordinateY")
						if xk not in hdr: print("X coordinates must be listed under _rlnCoordinateX")
						continue
				else: micros=[i.split('/')[-1] for i in np.unique(sf[mk])]
				if len(micros) == 1:
					mg = micros[0]
					boxlist = []
					print(("Found {} boxes for {}".format(len(sf[xk]),mg)))
					for x,y in zip(sf[xk],sf[yk]):
						xc = int(x)
						yc = int(y)
						boxlist.append([xc,yc,'manual']) # should probably be 'relion' or 'from_star'
					js_open_dict(info_name(mg,nodir=True))["boxes"]=boxlist
					if not "{}.hdf".format(base_name(mg,nodir=True)) in project_micros:
						print("Warning: Imported boxes for {}.hdf, but micrographs/{}.hdf does not exist".format(base_name(filename),base_name(mg,nodir=True)))
				elif len(micros) > 1:
					for mg in project_micros:
						boxlist = []
						ptcls = []
						for i,name in enumerate(sf[mk]):
							mgname = name.split('/')[-1].split('.')[0]
							#print(mgname,hdf_name,mg)
							if mg[:-4] in mgname: ptcls.append(i)
						print(("Found {} boxes for {}".format(len(ptcls),mg)))
						for p in ptcls:
							xc = int(sf[xk][p])
							yc = int(sf[yk][p])
							boxlist.append([xc,yc,'manual'])
						js_open_dict(info_name(mg,nodir=True))["boxes"]=boxlist
						if not "{}.hdf".format(base_name(mg,nodir=True)) in project_micros:
							print("Warning: Imported boxes for {}, but micrographs/{}.hdf does not exist".format(base_name(mg),base_name(mg,nodir=True)))

		else : print("ERROR: Unknown box_type")

	# Import particles
	if options.import_particles:
		if not os.access("particles", os.R_OK):
			os.mkdir("particles")

		fset=set([base_name(i) for i in args])
		if len(fset)!=len(args):
			print("ERROR: You specified multiple files to import with the same base name, eg - a10/abc123.spi and a12/abc123.spi. If you have multiple images with the same \
name, you will need to modify your naming convention (perhaps by prefixing the date) before importing. If the input files are in IMAGIC format, so you have .hed and .img files \
with the same name, you should specify only the .hed files (no renaming is necessary).")
			sys.exit(1)

		for i,fsp in enumerate(args):
			E2progress(logid,old_div(float(i),len(args)))
			if EMData(fsp,0,True)["nz"]>1 :
				run("e2proc2d.py {} particles/{}.hdf --threed2twod --inplace".format(fsp,base_name(fsp)))
			else: run("e2proc2d.py {} particles/{}.hdf --inplace".format(fsp,base_name(fsp)))

	if options.gainrefs != "" or options.darkrefs != "":
		refsdir = os.path.join(".","movierefs")
		if not os.access(refsdir, os.R_OK):
			os.mkdir(refsdir)

	if options.gainrefs != "":
		for ref in options.gainrefs.split(","):
			refname=os.path.join(refsdir,os.path.basename(ref))
			if refname[-4:] == ".mrc": refname+="s"
			if not os.path.isfile(refname):
				if options.importation == "move":
					os.rename(ref,refname)
				elif options.importation == "link":
					print("Movie references must be moved or copied. Linking is not supported.")
					sys.exit(1)
				elif options.importation == "copy":
					run("e2proc2d.py {} {} ".format(ref, refname))

	if options.darkrefs != "":
		for ref in options.darkrefs.split(","):
			refname=os.path.join(refsdir,os.path.basename(ref))
			if refname[-4:] == ".mrc": refname+="s"
			if not os.path.isfile(refname):
				if options.importation == "move":
					os.rename(ref,refname)
				elif options.importation == "link":
					print("Movie references must be moved or copied. Linking is not supported.")
					sys.exit(1)
				elif options.importation == "copy":
					run("e2proc2d.py {} {} ".format(ref, refname))


	if options.import_movies:

		moviesdir = os.path.join(".","movies")
		if not os.access(moviesdir, os.R_OK):
			os.mkdir(moviesdir)

		for filename in args:
			newname=os.path.join(moviesdir,os.path.basename(filename))
			if not os.path.isfile(newname):
				if newname[-4:] == ".mrc": newname+="s"
				if options.importation == "move":
					os.rename(filename,newname)
				if options.importation == "copy":
					run("e2proc2d.py {} {} ".format(filename, newname))
				if options.importation == "link":
					os.symlink(filename,newname)
		print("Done.")

	# Import tilts
	# if options.import_rawtilts:

	# 	stdir = os.path.join(".","raw_tilts")
	# 	if not os.access(stdir, os.R_OK):
	# 		os.mkdir("tilts")

	# 	for filename in args:
	# 		newname=os.path.join(stdir,os.path.basename(filename))
	# 		if options.importation == "move":
	# 			os.rename(filename,newname)
	# 		if options.importation == "copy":
	# 			tpos=filename.rfind('.')
	# 			if tpos>0: newname=os.path.join(stdir,os.path.basename(filename[:tpos]+'.hdf'))
	# 			else: newname=os.path.join(stdir,os.path.basename(filename))
	# 			cmd="e2proc2d.py {} {} ".format(filename, newname)
	# 			if options.invert: cmd+=" --mult -1 --process normalize "
	# 			#if options.tomoseg_auto:
	# 			#	cmd+=" --process filter.lowpass.gauss:cutoff_abs=.25 --process filter.highpass.gauss:cutoff_pixels=5 --process threshold.clampminmax.nsigma:nsigma=3 "
	# 			cmd+=options.preprocess
	# 			run(cmd)
	# 			print("Done.")
	# 		if options.importation == "link":
	# 			os.symlink(filename,newname)

	# Import tilt series
	if options.import_tiltseries:
		# try:
		# 	db=js_open_dict("info/project.json")
		# 	if options.apix == -1: 
		# 		options.apix = db["global.apix"]
		# 		print("Using global apix: {}".format(db["global.apix"]))
		# except: pass

		stdir = os.path.join(".","tiltseries")
		if not os.access(stdir, os.R_OK) : os.mkdir("tiltseries")

		for filename in args:
			newname=os.path.join(stdir,os.path.basename(filename))
			if options.importation == "move":
				os.rename(filename,newname)
			if options.importation == "copy":
				if os.path.isfile(newname): os.remove(newname)
				tpos=filename.rfind('.')
				if tpos>0: newname=os.path.join(stdir,os.path.basename(filename[:tpos]+'.hdf'))
				else: newname=os.path.join(stdir,os.path.basename(filename))
				cmd="e2proc2d.py {} {} --inplace ".format(filename, newname)
				if options.invert: cmd+=" --mult -1 --process normalize "
				if options.apix != -1: cmd += " --apix {} ".format(options.apix)
				#if options.tomoseg_auto:
				#	cmd+=" --process filter.lowpass.gauss:cutoff_abs=.25 --process filter.highpass.gauss:cutoff_pixels=5 --process threshold.clampminmax.nsigma:nsigma=3 "
				#cmd+=options.preprocess
				run(cmd)
				print("Done.")
			if options.importation == "link": os.symlink(filename,newname)
			if (options.importation == "link" or options.importation == "move") and options.apix != -1:
				run("e2proc3d.py {} {} --apix {} --threed2twod".format(newname, newname, options.apix))
	
	# Import tomograms
	if options.import_tomos:
		tomosdir = os.path.join(".","tomograms")
		if not os.access(tomosdir, os.R_OK):
			os.mkdir("tomograms")
		for filename in args:
			if options.importation == "move":
				os.rename(filename,os.path.join(tomosdir,os.path.basename(filename)))
			if options.importation == "copy":
				### use hdf file as output
				if options.shrink>1:
					shrinkstr="_bin{:d}".format(options.shrink)
				else:
					shrinkstr=""
				tpos=filename.rfind('.')
				if tpos>0:
					newname=os.path.join(tomosdir,os.path.basename(filename[:tpos]+shrinkstr+'.hdf'))
				else:
					newname=os.path.join(tomosdir,os.path.basename(filename))
				hdr=EMData(filename,0,True)
				cmd="e2proc3d.py {} {} ".format(filename, newname)
				
				# shrink, and clip from the origin to give us a good box size. Done from origin so segmentation results will be positioned well for scaling
				if options.shrink>1:
					nx=good_size(old_div(hdr["nx"],options.shrink))*options.shrink
					ny=good_size(old_div(hdr["ny"],options.shrink))*options.shrink
					nz=good_size(old_div(hdr["nz"],options.shrink))*options.shrink
#					cmd+="--clip {},{},{},{},{},{} --meanshrink {:d} ".format(nx,ny,nz,nx/2,ny/2,nz/2,options.shrink)
					cmd+="--clip {},{},{} --meanshrink {:d} ".format(nx,ny,nz,options.shrink)		# no origin shift. If result is scaled up and clipped to original size this may work better
				else:
					nx=good_size(hdr["nx"])
					ny=good_size(hdr["ny"])
					nz=good_size(hdr["nz"])
#					cmd+="--clip {},{},{},{},{},{} ".format(nx,ny,nz,nx/2,ny/2,nz/2,options.shrink)
					cmd+="--clip {},{},{} ".format(nx,ny,nz,options.shrink)
					
				if options.invert:
					cmd+=" --mult -1 --process normalize "
					
				cmd+=" --process normalize "
				#if options.tomoseg_auto:
				#	cmd+=" --process filter.lowpass.gauss:cutoff_abs=.25 --process filter.highpass.gauss:cutoff_pixels=5 --process normalize --process threshold.clampminmax.nsigma:nsigma=3 "
				#cmd+=options.preprocess
				run(cmd)
				print("Done.")
			#shutil.copy(filename,os.path.join(tomosdir,os.path.basename(filename)))
			if options.importation == "link":
				os.symlink(filename,os.path.join(tomosdir,os.path.basename(filename)))

	# # Import serialEM metadata
	# if options.serialem_mdoc:
	# 	for fn in args:
	# 		mdoc = read_mdoc(fn)
	# 		# check and correct project parameters from MDOC file contents
	# 		d = js_open_dict("info/project.json")
	# 		try: d.setval("global.apix",mdoc["PixelSpacing"],deferupdate=True)
	# 		except: pass
	# 		try: d.setval("global.microscope_voltage",mdoc["Voltage"],deferupdate=True)
	# 		except: pass
	# 		d.close()
	# 		# for each referenced image, append pertinent keys/values to corresponding info.json
	# 		for z in range(mdoc["zval"]+1):
	# 			tlt = mdoc[z]["SubFramePath"].rsplit("\\")[-1]+"_RawImages"
	# 			d = js_open_dict(info_name(tlt))
	# 			for k in mdoc[z].keys():
	# 				d.setval(k,mdoc[z][k],deferupdate=True)
	# 			d.close()
	#
	# # Import FEI metadata
	# if options.fei_tomo:
	# 	print("FEI tomography metadata not yet handled by this program.")
	# 	sys.exit(1)
	#
	# # Import UCSF tomo metadata
	# if options.ucsf_tomo:
	# 	print("UCSF tomography metadata not yet handled by this program.")
	# 	sys.exit(1)

	E2end(logid)
Ejemplo n.º 5
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """prog [options] 
For more information on ctffind3 please see: Mindell, JA, Grigorieff N.  2003.  Accurate determination of local defocus and specimen tilt in electron microscopy. J Struct Biol. 142:334-47.

"""
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	parser.add_header(name="ctffind3header", help='Options below this label are specific to e2ctffind3util.py', title="### e2ctffind3util options (requires that ctffind3 be installed)###", row=0, col=0, rowspan=1, colspan=2, mode="import,run")

	#options associated with e2ctffind3.py
	parser.add_argument("--apix", default=0.0, type=float,help="The angstrom per pixel of the micrographs", guitype='floatbox', row=3, col=0, rowspan=1, colspan=1, mode="import,run")
	parser.add_argument("--cs", default=0.0, type=float,help="The spherical aberration of the microscope", guitype='floatbox', row=3, col=1, rowspan=1, colspan=1, mode="import,run")
	parser.add_argument("--voltage", default=0.0, type=float,help="The voltage (in kV) of the microscope", guitype='floatbox', row=4, col=0, rowspan=1, colspan=1, mode="import,run")
	parser.add_argument("--ac", default=0.0, type=float,help="The amplitude contrast of the micrographs", guitype='floatbox', row=4, col=1, rowspan=1, colspan=1, mode="import,run")
	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", guitype='intbox', row=5, col=0, rowspan=1, colspan=1, mode="import,run")
	parser.add_argument("--importrelionstar", default=False, action="store_true",help="Import CTFFIND3 data in Relion STAR format. Put STAR files in 'ctffind3' folder", guitype='boolbox', row=6, col=0, rowspan=1, colspan=1, mode='import[True]')
	parser.add_argument("--importctffind3", default=False, action="store_true",help="Import ctffind3 data?", guitype='boolbox', row=6, col=0, rowspan=1, colspan=1, mode='import[True]')
	parser.add_argument("--importctffind4", default=False, action="store_true",help="Import ctffind4 data?", guitype='boolbox', row=6, col=1, rowspan=1, colspan=1, mode='import[False]')
	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)

	parser.add_pos_argument(name="micrographs",help="List the micrographs to run ctffind3 on here.", default="", guitype='filebox', browser="EMRawDataTable(withmodal=True,multiselect=True)", filecheck=False, row=1, col=0,rowspan=1, colspan=2, mode='run')
	parser.add_argument("--allmicrographs", default=False, action="store_true",help="Run Ctffind3 on all micrographs in the micrographs directory?", guitype='boolbox', row=2, col=0, rowspan=1, colspan=1, mode="run")
	parser.add_argument("--maxres", default=0.0, type=float,help="The highest resolution to be fitted (Angstroms)", guitype='floatbox', row=6, col=0, rowspan=1, colspan=1, mode="run")
	parser.add_argument("--minres", default=0.0, type=float,help="The lowest resolution to be fitted (Angstroms)", guitype='floatbox', row=6, col=1, rowspan=1, colspan=1, mode="run")
	parser.add_argument("--defocusmin", default=0.0, type=float,help="The starting defocus value for grid search (microns)", guitype='floatbox', row=7, col=0, rowspan=1, colspan=1, mode="run")
	parser.add_argument("--defocusmax", default=0.0, type=float,help="The end defocus value for grid search (microns)", guitype='floatbox', row=7, col=1, rowspan=1, colspan=1, mode="run")
	parser.add_argument("--defocusstep", default=0.0, type=float,help="The step width for grid search (microns)", guitype='floatbox', row=8, col=0, rowspan=1, colspan=1, mode="run")
	parser.add_argument("--runctffind3", default=False, action="store_true",help="Run ctffind3 on the selected micrographs?", guitype='boolbox', row=9, col=0, rowspan=1, colspan=1, mode='run[True]')
	parser.add_argument("--runctffind4", default=False, action="store_true",help="Run ctffind4 on the selected micrographs?", guitype='boolbox', row=9, col=1, rowspan=1, colspan=1, mode='run[False]')
	parser.add_argument("--windowsize", default=0, type=int,help="The amplitude contrast of the micrographs", guitype='intbox', row=8, col=1, rowspan=1, colspan=1, mode="run")
	
	(options, args) = parser.parse_args()
	logid=E2init(sys.argv,options.ppid)

	if options.importrelionstar :
		fls=[i for i in os.listdir("ctffind3") if i[-5:]==".star"]
		if len(fls)==0:
			print "please create a folder called 'ctffind3' and put .star files in it before running this option"
			sys.exit(1)
		
		for f in fls:
			star=StarFile("ctffind3/"+f)
			if not star.has_key("rlnMicrographName") :
				print "No rlnMicrographName in ",f
				continue
			
			print f
			for i,imfsp in enumerate(star["rlnMicrographName"]):
				im=info_name(imfsp)		# should work regardless of extension
				jdb=js_open_dict(im)
				
				dfu=star["rlnDefocusU"][i]
				dfv=star["rlnDefocusV"][i]
				dfang=star["rlnDefocusAngle"][i]
				ctf=EMAN2Ctf()
				ctf.from_dict({"defocus":(dfu+dfv)/20000.0,"dfang":dfang,"dfdiff":(dfu-dfv)/10000.0,"voltage":star["rlnVoltage"][i],"cs":star["rlnSphericalAberration"][i],"ampcont":star["rlnAmplitudeContrast"][i]*100.0,"apix":options.apix})
				jdb["ctf_frame"]=[512,ctf,(256,256),tuple(),5,1]
				js_close_dict(im)

		launch_childprocess("e2ctf.py --voltage {} --cs {} --ac {} --apix {} --allparticles --autofit --curdefocusfix --astigmatism".format(ctf.voltage,ctf.cs,ctf.ampcont,ctf.apix))
		
		print "All done"
		sys.exit(0)


	if options.apix<= 0 :
		print "Angstrom per pixel (apix) must be specified!"
		exit(-1)
	if options.cs<= 0 :
		print "Spherical Aberration (cs) must be specified!"
		exit(-2)
	if options.voltage<= 0 :
		print "Voltage must be specified!"
		exit(-3)
	if options.ac<= 0 :
		print "Amplitude Contrast must be specified!"
		exit(-4)
		
	if options.allmicrographs:
		args = []
		for item in os.listdir("micrographs"):
			try: 
				if item.split(".")[1] == "mrc" or item.split(".")[1] == "hdf":
					args.append("micrographs/" + item)
			except:
				pass
	
		
	
	if options.runctffind4:
		version = "ctffind4"
		run_ctffind(options.apix, args, options.cs, options.voltage, options.ac, options.windowsize, options.minres, options.maxres, options.defocusmin*10000, options.defocusmax*10000, options.defocusstep*10000, options.verbose,version)
	elif options.runctffind3:
		version = "ctffind3"
		run_ctffind(options.apix, args, options.cs, options.voltage, options.ac, options.windowsize, options.minres, options.maxres, options.defocusmin*10000, options.defocusmax*10000, options.defocusstep*10000, options.verbose, version)

	if options.importctffind4 or options.runctffind4:
		version = "ctffind4"
	else:
		version = "ctffind3"
	import_ctf(options.voltage, options.cs, options.ac, options.apix, options.verbose, version)

	print "e2ctffind3util.py complete!"
	E2end(logid)
Ejemplo n.º 6
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] 
For more information on ctffind3 please see: Mindell, JA, Grigorieff N.  2003.  Accurate determination of local defocus and specimen tilt in electron microscopy. J Struct Biol. 142:334-47.

"""
    parser = EMArgumentParser(usage=usage, version=EMANVERSION)
    parser.add_header(
        name="ctffind3header",
        help='Options below this label are specific to e2ctffind3util.py',
        title=
        "### e2ctffind3util options (requires that ctffind3 be installed)###",
        row=0,
        col=0,
        rowspan=1,
        colspan=2,
        mode="import,run")

    #options associated with e2ctffind3.py
    parser.add_argument("--apix",
                        default=0.0,
                        type=float,
                        help="The angstrom per pixel of the micrographs",
                        guitype='floatbox',
                        row=3,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode="import,run")
    parser.add_argument("--cs",
                        default=0.0,
                        type=float,
                        help="The spherical aberration of the microscope",
                        guitype='floatbox',
                        row=3,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode="import,run")
    parser.add_argument("--voltage",
                        default=0.0,
                        type=float,
                        help="The voltage (in kV) of the microscope",
                        guitype='floatbox',
                        row=4,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode="import,run")
    parser.add_argument("--ac",
                        default=0.0,
                        type=float,
                        help="The amplitude contrast of the micrographs",
                        guitype='floatbox',
                        row=4,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode="import,run")
    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",
        guitype='intbox',
        row=5,
        col=0,
        rowspan=1,
        colspan=1,
        mode="import,run")
    parser.add_argument(
        "--importrelionstar",
        default=False,
        action="store_true",
        help=
        "Import CTFFIND3 data in Relion STAR format. Put STAR files in 'ctffind3' folder",
        guitype='boolbox',
        row=6,
        col=0,
        rowspan=1,
        colspan=1,
        mode='import[True]')
    parser.add_argument("--importctffind3",
                        default=False,
                        action="store_true",
                        help="Import ctffind3 data?",
                        guitype='boolbox',
                        row=6,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode='import[True]')
    parser.add_argument("--importctffind4",
                        default=False,
                        action="store_true",
                        help="Import ctffind4 data?",
                        guitype='boolbox',
                        row=6,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode='import[False]')
    parser.add_argument(
        "--ppid",
        type=int,
        help="Set the PID of the parent process, used for cross platform PPID",
        default=-1)

    parser.add_pos_argument(
        name="micrographs",
        help="List the micrographs to run ctffind3 on here.",
        default="",
        guitype='filebox',
        browser="EMRawDataTable(withmodal=True,multiselect=True)",
        filecheck=False,
        row=1,
        col=0,
        rowspan=1,
        colspan=2,
        mode='run')
    parser.add_argument(
        "--allmicrographs",
        default=False,
        action="store_true",
        help="Run Ctffind3 on all micrographs in the micrographs directory?",
        guitype='boolbox',
        row=2,
        col=0,
        rowspan=1,
        colspan=1,
        mode="run")
    parser.add_argument("--maxres",
                        default=0.0,
                        type=float,
                        help="The highest resolution to be fitted (Angstroms)",
                        guitype='floatbox',
                        row=6,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode="run")
    parser.add_argument("--minres",
                        default=0.0,
                        type=float,
                        help="The lowest resolution to be fitted (Angstroms)",
                        guitype='floatbox',
                        row=6,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode="run")
    parser.add_argument(
        "--defocusmin",
        default=0.0,
        type=float,
        help="The starting defocus value for grid search (microns)",
        guitype='floatbox',
        row=7,
        col=0,
        rowspan=1,
        colspan=1,
        mode="run")
    parser.add_argument("--defocusmax",
                        default=0.0,
                        type=float,
                        help="The end defocus value for grid search (microns)",
                        guitype='floatbox',
                        row=7,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode="run")
    parser.add_argument("--defocusstep",
                        default=0.0,
                        type=float,
                        help="The step width for grid search (microns)",
                        guitype='floatbox',
                        row=8,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode="run")
    parser.add_argument("--runctffind3",
                        default=False,
                        action="store_true",
                        help="Run ctffind3 on the selected micrographs?",
                        guitype='boolbox',
                        row=9,
                        col=0,
                        rowspan=1,
                        colspan=1,
                        mode='run[True]')
    parser.add_argument("--runctffind4",
                        default=False,
                        action="store_true",
                        help="Run ctffind4 on the selected micrographs?",
                        guitype='boolbox',
                        row=9,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode='run[False]')
    parser.add_argument("--windowsize",
                        default=0,
                        type=int,
                        help="The amplitude contrast of the micrographs",
                        guitype='intbox',
                        row=8,
                        col=1,
                        rowspan=1,
                        colspan=1,
                        mode="run")

    (options, args) = parser.parse_args()
    logid = E2init(sys.argv, options.ppid)

    if options.importrelionstar:
        fls = [i for i in os.listdir("ctffind3") if i[-5:] == ".star"]
        if len(fls) == 0:
            print "please create a folder called 'ctffind3' and put .star files in it before running this option"
            sys.exit(1)

        for f in fls:
            star = StarFile("ctffind3/" + f)
            if not star.has_key("rlnMicrographName"):
                print "No rlnMicrographName in ", f
                continue

            print f
            for i, imfsp in enumerate(star["rlnMicrographName"]):
                im = info_name(imfsp)  # should work regardless of extension
                jdb = js_open_dict(im)

                dfu = star["rlnDefocusU"][i]
                dfv = star["rlnDefocusV"][i]
                dfang = star["rlnDefocusAngle"][i]
                ctf = EMAN2Ctf()
                ctf.from_dict({
                    "defocus": (dfu + dfv) / 20000.0,
                    "dfang": dfang,
                    "dfdiff": (dfu - dfv) / 10000.0,
                    "voltage": star["rlnVoltage"][i],
                    "cs": star["rlnSphericalAberration"][i],
                    "ampcont": star["rlnAmplitudeContrast"][i] * 100.0,
                    "apix": options.apix
                })
                jdb["ctf_frame"] = [512, ctf, (256, 256), tuple(), 5, 1]
                js_close_dict(im)

        launch_childprocess(
            "e2ctf.py --voltage {} --cs {} --ac {} --apix {} --allparticles --autofit --curdefocusfix --astigmatism"
            .format(ctf.voltage, ctf.cs, ctf.ampcont, ctf.apix))

        print "All done"
        sys.exit(0)

    if options.apix <= 0:
        print "Angstrom per pixel (apix) must be specified!"
        exit(-1)
    if options.cs <= 0:
        print "Spherical Aberration (cs) must be specified!"
        exit(-2)
    if options.voltage <= 0:
        print "Voltage must be specified!"
        exit(-3)
    if options.ac <= 0:
        print "Amplitude Contrast must be specified!"
        exit(-4)

    if options.allmicrographs:
        args = []
        for item in os.listdir("micrographs"):
            try:
                if item.split(".")[1] == "mrc" or item.split(".")[1] == "hdf":
                    args.append("micrographs/" + item)
            except:
                pass

    if options.runctffind4:
        version = "ctffind4"
        run_ctffind(options.apix, args, options.cs, options.voltage,
                    options.ac, options.windowsize, options.minres,
                    options.maxres, options.defocusmin * 10000,
                    options.defocusmax * 10000, options.defocusstep * 10000,
                    options.verbose, version)
    elif options.runctffind3:
        version = "ctffind3"
        run_ctffind(options.apix, args, options.cs, options.voltage,
                    options.ac, options.windowsize, options.minres,
                    options.maxres, options.defocusmin * 10000,
                    options.defocusmax * 10000, options.defocusstep * 10000,
                    options.verbose, version)

    if options.importctffind4 or options.runctffind4:
        version = "ctffind4"
    else:
        version = "ctffind3"
    import_ctf(options.voltage, options.cs, options.ac, options.apix,
               options.verbose, version)

    print "e2ctffind3util.py complete!"
    E2end(logid)
Ejemplo n.º 7
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] files
	This program performs a variety of tasks for getting data or metadata from other programs into an EMAN2 project.

	import_particles - will simply copy a set of per-micrograph particle files into EMAN2.1's preferred HDF format in particles/
	import_boxes - will read EMAN1 '.box' files (text files containing coordinates) into appropriate info/*json files (see --box_type)
	import_tomos - imports subtomogams for a SPT project (see also --importation)
	import_eman1 - will convert a typical EMAN1 phase-flipped start.hed/img file into an EMAN2 project (converting files, fixing CTF, splitting, ...)
"""

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

    parser.add_pos_argument(
        name="import_files",
        help="List the files to import here.",
        default="",
        guitype="filebox",
        browser="EMBrowserWidget(withmodal=True,multiselect=True)",
        row=0,
        col=0,
        rowspan=1,
        colspan=2,
        nosharedb=True,
        mode="coords,parts,tomos,eman1",
    )
    parser.add_header(
        name="filterheader",
        help="Options below this label are specific to e2import",
        title="### e2import options ###",
        row=1,
        col=0,
        rowspan=1,
        colspan=2,
        mode="coords,parts,tomos",
    )
    parser.add_argument(
        "--import_particles",
        action="store_true",
        help="Import particles",
        default=False,
        guitype="boolbox",
        row=2,
        col=0,
        rowspan=1,
        colspan=1,
        mode="parts[True]",
    )
    parser.add_argument(
        "--import_eman1",
        action="store_true",
        help="This will import a phase-flipped particle stack from EMAN1",
        default=False,
        guitype="boolbox",
        row=2,
        col=0,
        rowspan=1,
        colspan=1,
        mode="eman1[True]",
    )
    parser.add_argument(
        "--import_tomos",
        action="store_true",
        help="Import tomograms",
        default=False,
        guitype="boolbox",
        row=2,
        col=0,
        rowspan=1,
        colspan=1,
        mode="tomos[True]",
    )
    parser.add_argument(
        "--shrink",
        type=int,
        help="Shrink tomograms before importing. Dose not work while not copying.",
        default=1,
        guitype="intbox",
        row=3,
        col=0,
        rowspan=1,
        colspan=1,
        mode="tomos",
    )
    parser.add_argument(
        "--invert",
        action="store_true",
        help="Invert the contrast before importing tomograms",
        default=False,
        guitype="boolbox",
        row=3,
        col=1,
        rowspan=1,
        colspan=1,
        mode="tomos",
    )
    parser.add_argument(
        "--local_normalize",
        action="store_true",
        help="Apply a localized normalization before importing. Dose not work while not copying.",
        default=True,
        guitype="boolbox",
        row=3,
        col=2,
        rowspan=1,
        colspan=1,
        mode="tomos",
    )
    parser.add_argument(
        "--importation",
        help="Specify mode move, copy or link, for importing tomograms only",
        default="copy",
        guitype="combobox",
        choicelist='["move","copy","link"]',
        row=2,
        col=1,
        rowspan=1,
        colspan=1,
        mode="tomos",
    )
    parser.add_argument(
        "--preprocess",
        type=str,
        help="Other pre-processing operation before importing tomograms. Dose not work while not copying.",
        default="",
        guitype="strbox",
        row=4,
        col=0,
        rowspan=1,
        colspan=2,
        mode="tomos",
    )
    parser.add_argument(
        "--import_boxes",
        action="store_true",
        help="Import boxes",
        default=False,
        guitype="boolbox",
        row=2,
        col=0,
        rowspan=1,
        colspan=1,
        mode="coords[True]",
    )
    parser.add_argument(
        "--extension", type=str, help="Extension of the micrographs that the boxes match", default="dm3"
    )
    parser.add_argument(
        "--box_type",
        help="Type of boxes to import, normally boxes, but for tilted data use tiltedboxes, and untiltedboxes for the tilted  particle partner",
        default="boxes",
        guitype="combobox",
        choicelist='["boxes","coords","relion_star","tiltedboxes","untiltedboxes"]',
        row=2,
        col=1,
        rowspan=1,
        colspan=1,
        mode="coords['boxes']",
    )
    parser.add_argument("--boxsize", help="Specify the boxsize for each particle.", type=int, default=256)
    parser.add_argument(
        "--curdefocushint",
        action="store_true",
        help="Used with import_eman1, will use EMAN1 defocus as starting point",
        default=False,
        guitype="boolbox",
        row=4,
        col=0,
        rowspan=1,
        colspan=1,
        mode="eman1[True]",
    )
    parser.add_argument(
        "--curdefocusfix",
        action="store_true",
        help="Used with import_eman1, will use EMAN1 defocus unchanged (+-.001 um)",
        default=False,
        guitype="boolbox",
        row=4,
        col=1,
        rowspan=1,
        colspan=1,
        mode="eman1[False]",
    )
    parser.add_argument(
        "--threads",
        default=1,
        type=int,
        help="Number of threads to run in parallel on a single computer when multi-computer parallelism isn't useful",
        guitype="intbox",
        row=6,
        col=0,
        rowspan=1,
        colspan=1,
        mode="eman1[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",
    )
    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()
    logid = E2init(sys.argv, options.ppid)

    # Import EMAN1
    # will read start.hed/img, split by micrograph (based on defocus), and reprocess CTF in EMAN2 style
    if options.import_eman1:
        try:
            n = EMUtil.get_image_count(args[0])
        except:
            print "Error, couldn't read images from: ", args[0]
            sys.exit(1)

        try:
            img = EMData(args[0], 0)
            ctf = img["ctf"]
        except:
            print "Error, start.hed/img must be phase-flipped to import"
            sys.exit(1)

        db = js_open_dict("info/project.json")
        db["global.apix"] = ctf.apix
        db["global.cs"] = ctf.cs
        db["global.voltage"] = ctf.voltage

        try:
            os.mkdir("particles")
        except:
            pass

        imgnum = 0
        lastdf = -1.0
        for i in xrange(n):
            img = EMData(args[0], i)
            ctf = img["ctf"]
            img.del_attr("ctf")
            fft1 = img.do_fft()
            if ctf.defocus != lastdf:
                imgnum += 1
                if options.verbose > 0:
                    print "Defocus {:4.2f} particles{:03d}".format(ctf.defocus, imgnum)
                db = js_open_dict("info/particles{:03d}_info.json".format(imgnum))
                ctf2 = EMAN2Ctf()
                ctf2.defocus = ctf.defocus
                ctf2.cs = ctf.cs
                ctf2.apix = ctf.apix
                ctf2.voltage = ctf.voltage
                ctf2.ampcont = ctf.ampcont
                ctf2.dfdiff = 0
                ctf2.dfang = 0
                db["ctf"] = [ctf2]
                db.close()

                flipim = fft1.copy()
                ctf2.compute_2d_complex(flipim, Ctf.CtfType.CTF_SIGN)

            lastdf = ctf.defocus

            # unflip the EMAN1 phases (hopefully accurate enough)
            fft1.mult(flipim)
            img = fft1.do_ift()
            img.write_image("particles/particles{:03d}.hdf".format(imgnum), -1)  # append particle to stack

        if options.curdefocusfix:
            flag = "--curdefocusfix"
            rbysnr = " "
        elif options.curdefocushint:
            flag = "--curdefocushint"
            rbysnr = "--refinebysnr"
        else:
            flag = ""
            rbysnr = "--refinebysnr"

            # fill in the needed CTF info
        launch_childprocess(
            "e2ctf.py --autofit {} --allparticles --threads {} --voltage {} --cs {} --ac {} --apix {} --computesf".format(
                flag, options.threads, ctf.voltage, ctf.cs, ctf.ampcont, ctf.apix
            )
        )
        launch_childprocess(
            "e2ctf.py --autofit {} --allparticles --threads {} --voltage {} --cs {} --ac {} --apix {}".format(
                flag, options.threads, ctf.voltage, ctf.cs, ctf.ampcont, ctf.apix
            )
        )

        # reflip flip the phases, and make "proc" images
        launch_childprocess(
            "e2ctf.py {} --phaseflip --allparticles --phaseflipproc filter.highpass.gauss:cutoff_freq=0.005 --phaseflipproc2 filter.lowpass.gauss:cutoff_freq=0.08 --phaseflipproc3 math.meanshrink:n=2".format(
                rbysnr
            )
        )

        # build sets
        launch_childprocess("e2buildsets.py --allparticles --setname all")

        # Import boxes
    if options.import_boxes:
        # Check to make sure there are micrographs
        if not os.access("info", os.R_OK):
            os.mkdir("info")
            # Do imports
            # we add boxsize/2 to the coords since box files are stored with origin being the lower left side of the box, but in EMAN2 origin is in the center
        if options.box_type == "boxes":
            micros = os.listdir("micrographs")
            for filename in args:
                boxlist = []
                fh = open(filename, "r")
                for line in fh.readlines():
                    if line[0] == "#":
                        continue
                    fields = line.split()
                    if len(fields) < 4:
                        continue  # skip lines that don't work
                    boxlist.append(
                        [float(fields[0]) + float(fields[3]) / 2, float(fields[1]) + float(fields[3]) / 2, "manual"]
                    )

                js = js_open_dict(info_name(filename, nodir=True))
                js["boxes"] = boxlist
                js.close()
                if not "{}.hdf".format(base_name(filename, nodir=True)) in micros:
                    print "Warning: Imported boxes for {}, but micrographs/{}.hdf does not exist".format(
                        base_name(filename), base_name(filename, True)
                    )

        elif options.box_type == "coords":
            micros = os.listdir("micrographs")
            for filename in args:
                boxlist = []
                fh = open(filename, "r")
                for line in fh.readlines():
                    if line[0] == "#":
                        continue
                    fields = line.split()
                    if len(fields) < 2:
                        continue  # skip lines that don't work
                    boxlist.append([float(fields[0]), float(fields[1]), "manual"])
                js_open_dict(info_name(filename, nodir=True))["boxes"] = boxlist
                if not "{}.hdf".format(base_name(filename, nodir=True)) in micros:
                    print "Warning: Imported boxes for {}, but micrographs/{}.hdf does not exist".format(
                        base_name(filename), base_name(filename, True)
                    )

        elif options.box_type == "tiltedboxes":

            for filename in args:
                boxlist = []
                fh = open(filename, "r")
                for line in fh.readlines():
                    if line[0] == "#":
                        continue
                    fields = line.split()
                    if len(fields) < 4:
                        continue  # skip lines that don't work
                    boxlist.append(
                        [float(fields[0]) + float(fields[3]) / 2, float(fields[1]) + float(fields[3]) / 2, "tilted"]
                    )
                js_open_dict(info_name(filename, nodir=True))["boxes_rct"] = boxlist

        elif options.box_type == "untiltedboxes":
            for filename in args:
                boxlist = []
                fh = open(filename, "r")
                for line in fh.readlines():
                    if line[0] == "#":
                        continue
                    fields = line.split()
                    if len(fields) < 4:
                        continue  # skip lines that don't work
                    boxlist.append(
                        [float(fields[0]) + float(fields[3]) / 2, float(fields[1]) + float(fields[3]) / 2, "untilted"]
                    )
                js_open_dict(info_name(filename, nodir=True))["boxes_rct"] = boxlist

        elif options.box_type == "relion_star":
            bs = options.boxsize
            starfs = [f for f in args if ".star" in f]
            if len(starfs) < 1:
                print ("You must specify at least one .star file containing particle coordinates")
                exit(1)
            for filename in starfs:
                print ("Importing from {}.star".format(base_name(filename, nodir=True)))
                sf = StarFile(filename)
                hdr = sf.keys()
                if len(hdr) < 3:
                    print ("Could not parse {}".format(filename))
                    continue
                mk = "rlnMicrographName"
                yk = "rlnCoordinateY"
                xk = "rlnCoordinateX"
                project_micros = os.listdir("micrographs")
                if mk not in hdr or yk not in hdr or xk not in hdr:
                    possible = "{}.hdf".format(base_name(filename.replace("_autopick.star", ""), nodir=True))
                    if possible in project_micros:
                        micros = [possible]
                    else:
                        print (
                            "{} does not follow the RELION header convention for single particle data. To use this program".format(
                                filename
                            )
                        )
                        if mk not in hdr:
                            print ("Micrograph names should be listed under _rlnMicrographName")
                        if yk not in hdr:
                            print ("Y coordinates must be listed under _rlnCoordinateY")
                        if xk not in hdr:
                            print ("X coordinates must be listed under _rlnCoordinateX")
                        continue
                else:
                    micros = [i.split("/")[-1] for i in np.unique(sf[mk])]
                if len(micros) == 1:
                    mg = micros[0]
                    boxlist = []
                    print ("Found {} boxes for {}".format(len(sf[xk]), mg))
                    for x, y in zip(sf[xk], sf[yk]):
                        xc = int(x)
                        yc = int(y)
                        boxlist.append([xc, yc, "manual"])  # should probably be 'relion' or 'from_star'
                    js_open_dict(info_name(mg, nodir=True))["boxes"] = boxlist
                    if not "{}.hdf".format(base_name(mg, nodir=True)) in project_micros:
                        print "Warning: Imported boxes for {}.hdf, but micrographs/{}.hdf does not exist".format(
                            base_name(filename), base_name(mg, nodir=True)
                        )
                elif len(micros) > 1:
                    for mg in project_micros:
                        boxlist = []
                        ptcls = []
                        for i, name in enumerate(sf[mk]):
                            mgname = name.split("/")[-1].split(".")[0]
                            # print(mgname,hdf_name,mg)
                            if mg[:-4] in mgname:
                                ptcls.append(i)
                        print ("Found {} boxes for {}".format(len(ptcls), mg))
                        for p in ptcls:
                            xc = int(sf[xk][p])
                            yc = int(sf[yk][p])
                            boxlist.append([xc, yc, "manual"])
                        js_open_dict(info_name(mg, nodir=True))["boxes"] = boxlist
                        if not "{}.hdf".format(base_name(mg, nodir=True)) in project_micros:
                            print "Warning: Imported boxes for {}, but micrographs/{}.hdf does not exist".format(
                                base_name(mg), base_name(mg, nodir=True)
                            )

        else:
            print "ERROR: Unknown box_type"

        # Import particles
    if options.import_particles:
        if not os.access("particles", os.R_OK):
            os.mkdir("particles")

        fset = set([base_name(i) for i in args])
        if len(fset) != len(args):
            print "ERROR: You specified multiple files to import with the same base name, eg - a10/abc123.spi and a12/abc123.spi. If you have multiple images with the same \
name, you will need to modify your naming convention (perhaps by prefixing the date) before importing. If the input files are in IMAGIC format, so you have .hed and .img files \
with the same name, you should specify only the .hed files (no renaming is necessary)."
            sys.exit(1)

        for i, fsp in enumerate(args):
            E2progress(logid, float(i) / len(args))
            if EMData(fsp, 0, True)["nz"] > 1:
                run("e2proc2d.py {} particles/{}.hdf --threed2twod --inplace".format(fsp, base_name(fsp)))
            else:
                run("e2proc2d.py {} particles/{}.hdf --inplace".format(fsp, base_name(fsp)))

            # Import tomograms
    if options.import_tomos:
        tomosdir = os.path.join(".", "rawtomograms")
        if not os.access(tomosdir, os.R_OK):
            os.mkdir("rawtomograms")
        for filename in args:
            if options.importation == "move":
                os.rename(filename, os.path.join(tomosdir, os.path.basename(filename)))
            if options.importation == "copy":
                ### use hdf file as output
                tpos = filename.rfind(".")
                if tpos > 0:
                    newname = os.path.join(tomosdir, os.path.basename(filename[:tpos] + ".hdf"))
                else:
                    newname = os.path.join(tomosdir, os.path.basename(filename))
                cmd = "e2proc3d.py {} {} ".format(filename, newname)
                if options.shrink > 1:
                    cmd += " --meanshrink {:d} ".format(options.shrink)
                if options.invert:
                    cmd += " --mult -1 --process normalize "
                if options.local_normalize:
                    cmd += " --process normalize.local:radius=64 "
                cmd += options.preprocess
                run(cmd)
                # shutil.copy(filename,os.path.join(tomosdir,os.path.basename(filename)))
            if options.importation == "link":
                os.symlink(filename, os.path.join(tomosdir, os.path.basename(filename)))
    E2end(logid)
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] <relion STAR file>

This program will take data from a Relion project and convert it into a basic EMAN2 project and generate a .lst file. Provide 
the name of the Relion STAR file associated with the raw particle data. An eman2 subdirectory will be
created, and the images, and available metadata will be copied into the new project. CTF parameters
will be extracted from the STAR file and will be automatically processed through EMAN1's CTF procedure
(this takes most of the time the script will require).

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

    parser.add_argument("--lst", type=str, default='', help='.lst file.')
    parser.add_argument('--boxsize', type=int, default=0, help='box size')
    parser.add_argument(
        '--allrelion',
        type=int,
        default=0,
        help='convert all relion parameters to lst file if set to 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")
    parser.add_argument(
        "--ny",
        type=int,
        help="Particle NY size, so no need to read image to get this value",
        default=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()

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

    inputStarFileName = args[0]
    if not os.path.islink(inputStarFileName):
        inputStarFileName = os.path.abspath(inputStarFileName)
    else:
        #print "%s is a link file"%(inputStarFileName)
        inputStarFileName = os.path.abspath(os.readlink(inputStarFileName))

    topdir = os.path.dirname(inputStarFileName)

    #	try: os.mkdir("particles")
    #	except: pass

    if options.verbose > 0:
        print "Parsing STAR file %s" % (inputStarFileName)

    star = StarFile(inputStarFileName)
    #print star

    if (options.lst):
        lstfile = options.lst
    else:
        lstfile = os.path.basename(inputStarFileName)
        lstfile = lstfile[0:lstfile.rfind('.')] + '.lst'

    oldname = ""
    olddf = -1.0
    micronum = 0  # number of micrograph
    fnum = 0  # image number in new file
    params = []
    for i in xrange(len(star["rlnImageName"])):
        name = star["rlnImageName"][i].split("@")[1]
        name = os.path.join(topdir, name)
        imgnum = int(star["rlnImageName"][i].split("@")[0]) - 1

        if (star.has_key("rlnMagnificationCorrection")
            ):  #for old version relion star filr
            apix = 1e4 * float(star["rlnDetectorPixelSize"][i]) / (
                float(star["rlnMagnification"][i]) *
                float(star["rlnMagnificationCorrection"][i]))
        else:
            apix = 1e4 * float(star["rlnDetectorPixelSize"][i]) / (float(
                star["rlnMagnification"][i]))

        if name != oldname:
            #		hdr=EMData(name,0,True)
            #		nx=hdr["nx"]
            #		ny=hdr["ny"]
            nx = options.ny
            ny = options.ny
            oldname = name

        if i == 0 or star["rlnDefocusU"][i - 1] != star["rlnDefocusU"][i]:
            #this line will not run when i==0 (the 1st loop)
            if micronum > 0 and options.verbose > 1:
                print "Image {}: {} particles, df={}, size={}x{}".format(
                    micronum, fnum, ctf.defocus, nx, ny)

            micronum += 1
            fnum = 0  #when reaching a new micrograph, fnum need to start from 0 for write_image to a new good particle HDF stack
            microname = "particles/{}_{:04d}.hdf".format(
                base_name(name), micronum)

        boxsize = options.boxsize
        if boxsize <= 0:
            boxsize = ny

        # Make a "micrograph" CTF entry for each set of different defocuses to use when fitting
        # check ctffind3.f function CTF(CS,WL,WGH1,WGH2,DFMID1,DFMID2,ANGAST,THETATR, IX, IY)
        dfu = star["rlnDefocusU"][i] / 1e4
        dfv = star["rlnDefocusV"][i] / 1e4
        dfang = star["rlnDefocusAngle"][i]

        defocus = (dfu + dfv) / 2.
        dfdiff = math.fabs(dfu -
                           dfv) / 2.  # dfu can be larger or smaller than dfv
        if dfu > dfv:
            dfang = math.fmod(
                dfang + 360. + 90., 360.
            )  # largest defocus direction to smallest defocus direction
        else:
            pass  # already at smallest defocus direction

        ctf = EMAN1Ctf()
        ctf.from_dict({
            "defocus": defocus,
            "dfang": dfang,
            "dfdiff": dfdiff,
            "voltage": star["rlnVoltage"][i],
            "cs": star["rlnSphericalAberration"][i],
            "ampcont": star["rlnAmplitudeContrast"][i] * 100.0,
            "apix": apix,
            "amplitude": 1,
            "bfactor": 1e-5
        })

        # copy the image
        #	if name[-5:]==".mrcs":
        #		img=EMData(name,imgnum)		# read one slice from the MRC stack
        #	else:
        #		img=EMData(name,0,False,Region(0,0,imgnum,nx,ny,1))		# read one slice from the MRC stack

        #	img["ctf"] = ctf
        #	img['apix_x'] = apix
        #	img['apix_y'] = apix

        #	if options.verbose>2:
        #		print "Particle %d: %s" % (i, img["ctf"].to_dict())

        #	img.write_image(microname,fnum,EMUtil.ImageType.IMAGE_HDF,False) #microname is a .hdf file, False tells it to write both header and image data

        #print star["rlnAngleRot"][i], star["rlnAngleTilt"][i], star["rlnAnglePsi"][i]
        alt, az, phi, x, y = relion2EMAN2(star["rlnAngleRot"][i],
                                          star["rlnAngleTilt"][i],
                                          star["rlnAnglePsi"][i],
                                          star["rlnOriginX"][i],
                                          star["rlnOriginY"][i], boxsize)

        #all particles in eman2/particles folder are good particles, so the 1st column in .lst file should be 0,1,2,3,4,... in order
        new_file = os.path.relpath(microname, os.getcwd())
        param = [fnum, new_file, alt, az, phi, x, y, defocus, dfdiff, dfang]

        if (options.allrelion):
            for var in sorted(star.keys()):
                param.append(star[var][i])

        params.append(param)
        fnum += 1

    #generate .lst file corresponding to EMAN2 convention
    fp = open(lstfile, 'w')
    fp.write("#LST\n")
    for p in params:
        fp.write(
            "%d\t%s\teuler=%g,%g,%g\tcenter=%g,%g\tdefocus=%s\tdfdiff=%s\tdfang=%s"
            % (p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]))
        if options.allrelion:
            vars = sorted(star.keys())
            for vi, var in enumerate(vars):
                fp.write("\t%s=%s" % (var.split("rln")[-1], p[10 + vi]))
        fp.write("\n")
    fp.close()

    if options.verbose > 0:
        print "%d particles saved to %s" % (len(star["rlnImageName"]), lstfile)

    E2end(logid)
Ejemplo n.º 9
0
def main(options):
    """
    Projection subtraction program entry point.
    :param options: Command-line arguments parsed by ArgumentParser.parse_args()
    :return: Exit status
    """
    rchop = lambda x, y: x if not x.endswith(y) or len(y) == 0 else x[:-len(y)]
    options.output = rchop(options.output, ".star")
    options.suffix = rchop(options.suffix, ".mrc")
    options.suffix = rchop(options.suffix, ".mrcs")

    star = StarFile(options.input)
    npart = len(star['rlnImageName'])

    sub_dens = EMData(options.submap)

    if options.wholemap is not None:
        dens = EMData(options.wholemap)
    else:
        print "Reference map is required."
        return 1

    # Write star header for output.star.
    top_header = "\ndata_\n\nloop_\n"
    headings = star.keys()
    output_star = open("{0}.star".format(options.output), 'w')

    output_star.write(top_header)
    for i, heading in enumerate(headings):
        output_star.write("_{0} #{1}\n".format(heading, i + 1))

    if options.recenter:  # Compute difference vector between new and old mass centers.
        if options.wholemap is None:
            print "Reference map required for recentering."
            return 1

        new_dens = dens - sub_dens
        # Note the sign of the shift in coordinate frame is opposite the shift in the CoM.
        recenter = Vec3f(*dens.phase_cog()[:3]) - Vec3f(
            *new_dens.phase_cog()[:3])
    else:
        recenter = None

    pool = None
    if options.nproc > 1:  # Compute subtraction in parallel.
        pool = Pool(processes=options.nproc)
        results = pool.imap(
            lambda x: subtract(x,
                               dens,
                               sub_dens,
                               recenter=recenter,
                               no_frc=options.no_frc,
                               low_cutoff=options.low_cutoff,
                               high_cutoff=options.high_cutoff),
            particles(star),
            chunksize=min(npart / options.nproc, options.maxchunk))
    else:  # Use serial generator.
        results = (subtract(x,
                            dens,
                            sub_dens,
                            recenter=recenter,
                            no_frc=options.no_frc,
                            low_cutoff=options.low_cutoff,
                            high_cutoff=options.high_cutoff)
                   for x in particles(star))

    # Write subtraction results to .mrcs and .star files.
    i = 0
    nfile = 1
    starpath = None
    mrcs = None
    mrcs_orig = None
    for r in results:
        if i % options.maxpart == 0:
            mrcsuffix = options.suffix + "_%d" % nfile
            nfile += 1
            starpath = "{0}.mrcs".format(
                os.path.sep.join(
                    os.path.relpath(mrcsuffix,
                                    options.output).split(os.path.sep)[1:]))
            mrcs = "{0}.mrcs".format(mrcsuffix)
            mrcs_orig = "{0}_original.mrcs".format(mrcsuffix)
            if os.path.exists(mrcs):
                os.remove(mrcs)
            if os.path.exists(mrcs_orig):
                os.remove(mrcs_orig)

        r.ptcl_norm_sub.append_image(mrcs)

        if options.original:
            r.ptcl.append_image(mrcs_orig)

        if logger.getEffectiveLevel(
        ) == logging.DEBUG:  # Write additional debug output.
            ptcl_sub_img = r.ptcl.process("math.sub.optimal", {
                "ref": r.ctfproj,
                "actual": r.ctfproj_sub,
                "return_subim": True
            })
            ptcl_lowpass = r.ptcl.process("filter.lowpass.gauss", {
                "apix": 1.22,
                "cutoff_freq": 0.05
            })
            ptcl_sub_lowpass = r.ptcl_norm_sub.process("filter.lowpass.gauss",
                                                       {
                                                           "apix": 1.22,
                                                           "cutoff_freq": 0.05
                                                       })
            ptcl_sub_img.write_image("poreclass_subimg.mrcs", -1)
            ptcl_lowpass.write_image("poreclass_lowpass.mrcs", -1)
            ptcl_sub_lowpass.write_image("poreclass_sublowpass.mrcs", -1)
            r.ctfproj.write_image("poreclass_ctfproj.mrcs", -1)
            r.ctfproj_sub.write_image("poreclass_ctfprojsub.mrcs", -1)

        assert r.meta.i == i  # Assert particle order is preserved.
        star['rlnImageName'][i] = "{0:06d}@{1}".format(
            i % options.maxpart + 1, starpath)  # Set new image name.
        r.meta.update(star)  # Update StarFile with altered fields.
        line = '  '.join(str(star[key][i]) for key in headings)
        output_star.write("{0}\n".format(line))
        i += 1

    output_star.close()

    if pool is not None:
        pool.close()
        pool.join()

    return 0
Ejemplo n.º 10
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] <relion STAR file> <output set name>

This program will take a STAR file representing a subset of data from a Relion project and convert it into an EMAN2
set, IF the EMAN2 project contains the same micrographs and exact same boxed out particles as the Relion project
which produced the STAR file. e2refinetoeman.py can be used to convert an entire Relion project into an EMAN2
project. This program can then be used in this established project to copy information about particle subsets
selected in Relion into EMAN2.
"""
    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    #options associated with e2refine.py
    parser.add_pos_argument(
        name="star_file",
        help="Select STAR file",
        default="",
        guitype='filebox',
        browser="EMParticlesEditTable(withmodal=True,multiselect=False)",
        row=6,
        col=0,
        rowspan=1,
        colspan=3)
    parser.add_pos_argument(name="output_set_name",
                            help="Name of output set",
                            default="from_relion",
                            guitype='str',
                            row=7,
                            col=0,
                            rowspan=1,
                            colspan=1)
    parser.add_argument(
        "--origname",
        action="store_true",
        help="Adds the original STAR name as a comment on each image",
        default=False)
    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higher number means higher level of verboseness")
    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()

    if options.verbose > 0: print("Parsing STAR file")
    star = StarFile(args[0])

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

    if "rlnMicrographName" in star: difkey = "rlnMicrographName"
    else: difkey = "rlnDefocusU"

    if '.lst' in args[1]:
        if not "sets/" in args[1]: args[1] = f"sets/{args[1]}"
    else:
        args[1] = f"sets/{args[1]}.lst"

    try:
        os.unlink(args[1])
    except:
        pass
    out = LSXFile(args[1])

    orig = None
    for i in range(len(star["rlnImageName"])):
        rlnname = star["rlnImageName"][i]
        name = rlnname.split("@")[1]
        imgnum = int(rlnname.split("@")[0]) - 1

        emanname = os.path.split(name)[1]
        emanname = os.path.join("particles",
                                os.path.splitext(emanname)[0] + ".hdf")

        if not os.path.exists(emanname):
            badname = emanname
            # this won't always work right, but it's worth a try
            emanname = os.path.split(name)[1]
            emanname = os.path.join(
                "particles",
                name.split("/")[-2] + "-" + os.path.splitext(emanname)[0] +
                ".hdf")
            if not os.path.exists(emanname):
                raise Exception(
                    f"Cannot find:{emanname} or {badname} (from {rlnname})")

        if options.origname: orig = "# " + rlnname
        out.write(-1, imgnum, emanname, orig)

    E2end(logid)
Ejemplo n.º 11
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] <relion STAR file>

This program will take data from a Relion project and convert it into a basic EMAN2 project. Provide 
the name of the Relion STAR file associated with the raw particle data. An eman2 subdirectory will be
created, and the images, and available metadata will be copied into the new project. CTF parameters
will be extracted from the STAR file and will be automatically processed through EMAN2's CTF procedure
(this takes most of the time the script will require).

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

    #options associated with e2refine.py
    parser.add_header(
        name="text1",
        help='Important instructions',
        title="Use this to create an EMAN2.1 project from a Relion project:",
        row=0,
        col=0,
        rowspan=1,
        colspan=3)
    parser.add_header(name="text2",
                      help='Important instructions',
                      title="* cd <folder with Relion STAR file>",
                      row=1,
                      col=0,
                      rowspan=1,
                      colspan=3)
    parser.add_header(name="text3",
                      help='Important instructions',
                      title="* run e2projectmanager, and use this tool",
                      row=2,
                      col=0,
                      rowspan=1,
                      colspan=3)
    parser.add_header(
        name="text4",
        help='Important instructions',
        title="* exit PM, cd eman2, run PM from new eman2 folder",
        row=3,
        col=0,
        rowspan=1,
        colspan=3)
    parser.add_pos_argument(
        name="star_file",
        help="Select STAR file",
        default="",
        guitype='filebox',
        browser="EMParticlesEditTable(withmodal=True,multiselect=False)",
        row=6,
        col=0,
        rowspan=1,
        colspan=3)
    parser.add_argument("--apix",
                        default=0,
                        type=float,
                        help="The angstrom per pixel of the input particles.",
                        guitype='floatbox',
                        row=8,
                        col=0,
                        rowspan=1,
                        colspan=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")
    parser.add_argument(
        "--fixeddefocus",
        action="store_true",
        help="Defocus and astigmatism are used unchanged from STAR file",
        default=False,
        guitype='boolbox',
        row=10,
        col=0,
        rowspan=1,
        colspan=1)
    parser.add_argument(
        "--refinedefocus",
        action="store_true",
        help=
        "Will refit defocus to +-0.1 micron then further optimize using SSNR",
        default=False,
        guitype='boolbox',
        row=10,
        col=2,
        rowspan=1,
        colspan=1,
        mode="[True]")
    parser.add_argument(
        "--refitdefocus",
        action="store_true",
        help=
        "Will use EMAN2 CTF fitting to refit the defocus values within +-0.1 micron, astigmatism unchanged",
        default=False,
        guitype='boolbox',
        row=10,
        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)

    (options, args) = parser.parse_args()

    if options.apix <= 0:
        print "A/pix must be specified"
        sys.exit(1)

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

    try:
        os.mkdir("eman2")
    except:
        pass
    try:
        os.mkdir("eman2/particles")
    except:
        pass
    os.chdir(
        "eman2"
    )  # many things need to happen with the project directory as a base

    if options.verbose > 0: print "Parsing STAR file"
    star = StarFile("../" + args[0])

    oldname = ""
    olddf = -1.0
    micronum = 0  # number of micrograph
    fnum = 0  # image number in new file
    for i in xrange(len(star["rlnImageName"])):
        name = star["rlnImageName"][i].split("@")[1]
        imgnum = int(star["rlnImageName"][i].split("@")[0]) - 1

        if name != oldname:
            hdr = EMData("../" + name, 0, True)
            nx = hdr["nx"]
            ny = hdr["ny"]
            oldname = name
            if options.verbose > 0:
                print "Particle dimensions: {}x{}".format(nx, ny)

        if i == 0 or star["rlnDefocusU"][i - 1] != star["rlnDefocusU"][i]:
            if micronum > 0 and options.verbose > 0:
                print "Image {}: {} particles processed, df={}".format(
                    micronum, fnum, ctf.defocus)
            micronum += 1
            fnum = 0
            microname = "particles/{}_{:04d}.hdf".format(
                base_name(name), micronum)
            jdb = js_open_dict(info_name(microname))

            # Make a "micrograph" CTF entry for each set of different defocuses to use when fitting
            dfu = star["rlnDefocusU"][i]
            dfv = star["rlnDefocusV"][i]
            dfang = star["rlnDefocusAngle"][i]
            ctf = EMAN2Ctf()
            ctf.from_dict({
                "defocus": (dfu + dfv) / 20000.0,
                "dfang": dfang,
                "dfdiff": (dfu - dfv) / 10000.0,
                "voltage": star["rlnVoltage"][i],
                "cs": star["rlnSphericalAberration"][i],
                "ampcont": star["rlnAmplitudeContrast"][i] * 100.0,
                "apix": options.apix
            })
            jdb["ctf_frame"] = [512, ctf, (256, 256), tuple(), 5, 1]

        # copy the image
        if name[-5:] == ".mrcs":
            img = EMData("../" + name,
                         imgnum)  # read one slice from the MRC stack
        else:
            img = EMData("../" + name, 0, False,
                         Region(0, 0, imgnum, nx, ny,
                                1))  # read one slice from the MRC stack
        img.write_image(microname, fnum)
        fnum += 1

    if options.refinedefocus:
        dfopt = "--curdefocushint --refinebysnr"
        if options.verbose > 0:
            print "Defocus Refit and SSNR Refinement to +-0.1 micron"
    elif options.refitdefocus:
        dfopt = "--curdefocushint"
        if options.verbose > 0:
            print "Defocus Refit to +-0.1 micron from Relion values"
    elif options.fixeddefocus:
        dfopt = "--curdefocusfix"
        if options.verbose > 0: print "Computing particle SNRs"
    else:
        dfopt = " "
        if options.verbose > 0: print "Full refit of CTF parameters"

    launch_childprocess(
        "e2ctf.py --voltage {} --cs {} --ac {} --apix {} --allparticles --autofit {} -v {}"
        .format(ctf.voltage, ctf.cs, ctf.ampcont, ctf.apix, dfopt,
                options.verbose - 1))

    E2end(logid)