Beispiel #1
0
def sanity_checks(args, myid):
	"""
	Check if the command line arguments are valid.

	Arguments:
	args - Command line arguments as dictionary
	myid - MPI id

	Returns:
	None
	"""

	if args['gain_file'] is not None:
		if not os.path.isfile(args['gain_file']):
			sp_global_def.ERROR('If the gain_file option is provided, the gain file must exist!', myid=myid)

	if args['additional_dose_unadjusted'] and args['skip_dose_adjustment']:
		sp_global_def.ERROR('If the additional_dose_unadjusted option is provided, the skip_dose_adjustment cannot be provided as well!', myid=myid)

	if args['selection_file'] is not None and not os.path.isfile(args.selection_file):
		sp_global_def.ERROR('If the selection_file option is provided, the specified file needs to exist!', myid=myid)

	if not glob.glob(args['input_micrograph_pattern']):
		sp_global_def.ERROR('No files found with the specified pattern!: {0}'.format(args['input_micrograph_pattern']), myid=myid)

	if os.path.exists(args['output_directory']) and not args['overwrite']:
		sp_global_def.ERROR('Output directory is not allowed to exist!', myid=myid)
Beispiel #2
0
def angle_diff_sym(angle1, angle2, simi=1):
    '''
	This function determines the relative angle around Z axis (phi) between two sets of angles
	   taking into account point group symmetry with multiplicity simi.
	The input has to be in the form [[phi0,theta0], [phi1,theta1], ...]
	  Only sets that have theta in the same range (0,90), or (90,180) are included in calculation.
	The resulting angle has to be added (modulo 360/simi) to the first set.
	'''
    pass  #IMPORTIMPORTIMPORT from math import cos, sin, pi, atan2, degrees, radians

    nima = len(angle1)
    if len(angle2) != nima:
        sp_global_def.ERROR("List lengths do not agree!", "angle_diff_sym", 1)

    cosi = 0.0
    sini = 0.0
    agree = 0
    for i in range(nima):
        if (((angle2[i][1] < 90.0) and (angle1[i][1] < 90.0))
                or ((angle2[i][1] > 90.0) and (angle1[i][1] > 90.0))):
            qt = numpy.radians((angle2[i][0] - angle1[i][0]) * simi)
            cosi += numpy.cos(qt)
            sini += numpy.sin(qt)
            agree += 1
    if (agree == 0): return 0.0
    else: return numpy.degrees(math.atan2(sini, cosi) / simi) % (360.0 / simi)
Beispiel #3
0
def sanity_checks(command_args, input_vol):

    if os.path.isfile(
            os.path.join(command_args.output_dir,
                         command_args.prefix + "_mask.hdf")):
        if not command_args.overwrite:

            sp_global_def.ERROR(
                "Output mask already exists! Please provide the overwrite option if you want to overwrite the existing mask."
            )

    if (command_args.s_nx is not None and command_args.s_ny is None
            and command_args.s_ny is None and command_args.second_mask_shape):
        command_args.s_ny = command_args.s_nx
        command_args.s_nz = command_args.s_nx
    elif (command_args.s_nx is not None and command_args.s_ny is not None
          and command_args.s_ny is not None
          and command_args.second_mask_shape):
        pass
    elif command_args.second_mask_shape:
        sp_global_def.ERROR(
            "You need to specify s_nx only or s_nx and s_ny and s_nz")

    if command_args.second_mask_shape in ("cylinder", "sphere"):
        nx = input_vol.get_xsize()
        ny = input_vol.get_ysize()
        nz = input_vol.get_zsize()
        if command_args.s_radius > old_div(
                nx, 2) or command_args.s_radius > old_div(ny, 2):
            sp_global_def.ERROR(
                "Provided radius is larger than input image dimensions!")

    if command_args.second_mask_shape is not None:
        nx = input_vol.get_xsize()
        ny = input_vol.get_ysize()
        nz = input_vol.get_zsize()
        if command_args.s_nx > nx or command_args.s_ny > ny or command_args.s_nz > nz:
            sp_global_def.ERROR(
                "Provided s_nx, s_ny, s_nz mask dimension is larger than input image dimensions!"
            )
Beispiel #4
0
def main():
	
	progname = os.path.basename(sys.argv[0])
	# # horatio active_refactoring Jy51i1EwmLD4tWZ9_00003_1
	# usage = progname + " stack <name_output> --ali --active --set_size=param_name_with_size --set_members=param_name_with_id"
	# # horatio active_refactoring Jy51i1EwmLD4tWZ9_00003_2	
	usage = progname + " stack <name_output> --ali --set_size=param_name_with_size --set_members=param_name_with_id"
	parser = OptionParser(usage,version=SPARXVERSION)
	parser.add_option("--ali"        , action = "store_true", default=False, help="Perform average using alignment parameters")

	# # horatio active_refactoring Jy51i1EwmLD4tWZ9_00004_1	
	# parser.add_option("--active"     , action = "store_true", default=False, help="Perform average only for active images")
	
	parser.add_option("--set_size"   , type   = "string"    , default=None , help="Save number of input images to parameter with given name")
	parser.add_option("--set_members", type   = "string"    , default=None , help="Save list of id of input images to parameter named \"members\", id of input images are taken from parameter with given name")
	parser.add_option("--filament"        , action = "store_true", default=False, help="Calculate stack of averages according to filament membership")
	(options, args) = parser.parse_args()
	if len(args) < 1 or len(args) > 2:
		sxprint( "Usage: " + usage )
		sxprint( "Please run \'" + progname + " -h\' for detailed options" )
		sp_global_def.ERROR( "Invalid number of parameters used. Please see usage information above." )
		return
		
	else: 
		if len(args) == 1: 
			name_output = None
		else:
			name_output = args[1]
		
		if options.filament:
			from sp_development import ave_ali_filament
	
			if sp_global_def.CACHE_DISABLE:
				from sp_utilities import disable_bdb_cache
				disable_bdb_cache()
	
			sp_global_def.BATCH = True
			ave_ali_filament(args[0], name_output, options.ali)
			sp_global_def.BATCH = False
		
		else:
			from sp_applications import ave_ali
	
			if sp_global_def.CACHE_DISABLE:
				from sp_utilities import disable_bdb_cache
				disable_bdb_cache()
	
			sp_global_def.BATCH = True
			ave_ali(args[0], name_output, options.ali, options.set_size, options.set_members)
			sp_global_def.BATCH = False
Beispiel #5
0
def prgl(volft, params, interpolation_method=0, return_real=True):
    """
		Name
			prgl - calculate 2-D projection of a 3-D volume using either NN Fourier or or trilinear Fourier
		Input
			vol: input volume, the volume has to be cubic
			params: input parameters given as a list [phi, theta, psi, s2x, s2y], projection in calculated using the three Eulerian angles and then shifted by sx,sy
			interpolation_method = 0  NN
			interpolation_method = 1  trilinear
			return_real:  True - return real; False - return FT of a projection.
		Output
			proj: generated 2-D projection
	"""
    #  params:  phi, theta, psi, sx, sy
    pass  #IMPORTIMPORTIMPORT from sp_fundamentals import fft
    pass  #IMPORTIMPORTIMPORT from sp_utilities import set_params_proj, info
    pass  #IMPORTIMPORTIMPORT from EMAN2 import Processor
    if (interpolation_method < 0 or interpolation_method > 1):
        sp_global_def.ERROR('Unsupported interpolation method',
                            "interpolation_method", 1, 0)
    npad = volft.get_attr_default("npad", 1)
    R = EMAN2_cppwrap.Transform({
        "type": "spider",
        "phi": params[0],
        "theta": params[1],
        "psi": params[2]
    })
    if (npad == 1): temp = volft.extract_section(R, interpolation_method)
    elif (npad == 2): temp = volft.extract_section2(R, interpolation_method)
    temp.fft_shuffle()
    temp.center_origin_fft()

    if (params[3] != 0. or params[4] != 0.):
        filt_params = {
            "filter_type": EMAN2_cppwrap.Processor.fourier_filter_types.SHIFT,
            "x_shift": params[3],
            "y_shift": params[4],
            "z_shift": 0.0
        }
        temp = EMAN2_cppwrap.Processor.EMFourierFilter(temp, filt_params)
    if return_real:
        temp.do_ift_inplace()
        temp.set_attr_dict({'ctf_applied': 0, 'npad': 1})
        temp.depad()
    else:
        temp.set_attr_dict({'ctf_applied': 0, 'npad': 1})
    sp_utilities.set_params_proj(
        temp, [params[0], params[1], params[2], -params[3], -params[4]])
    return temp
Beispiel #6
0
def ormq_fast(dimage, crefim, xrng, yrng, step, numr, mode, delta=0.0):
    """Determine shift and rotation between image and reference image (crefim)
		crefim should be as FT of polar coords with applied weights
	        consider mirror
		cnx, cny in FORTRAN convention
	"""
    # from math import pi, cos, sin, radians
    # print "ORMQ_FAST"
    maxrange = old_div(len(dimage), 2)
    # istep = int(2*step)
    istep = int(step)
    """Multiline Comment5"""

    lkx = rkx = int(xrng * istep)

    lky = rky = int(yrng * istep)

    peak = -1.0e23
    for j in range(-lky, rky + 1, istep):
        for i in range(-lkx, rkx + 1, istep):
            if delta == 0.0:
                retvals = EMAN2_cppwrap.Util.Crosrng_ms(
                    crefim, dimage[i + maxrange][j + maxrange], numr, 0.0)
            else:
                retvals = EMAN2_cppwrap.Util.Crosrng_ms_delta(
                    crefim, dimage[i + maxrange][j + maxrange], numr, delta)
            qn = retvals["qn"]
            qm = retvals["qm"]
            if qn >= peak or qm >= peak:
                sx = i
                sy = j
                if qn >= qm:
                    ang = ang_n(retvals["tot"], mode, numr[-1])
                    peak = qn
                    mirror = 0
                else:
                    ang = ang_n(retvals["tmt"], mode, numr[-1])
                    peak = qm
                    mirror = 1
    """Multiline Comment6"""
    if peak < -1.0e20:
        sp_global_def.ERROR("ormq_fast",
                            "failed, most likely due to search ranges", 1)
    # return  ang, sx/2.0, sy/2.0, mirror, peak
    return ang, sx, sy, mirror, peak
Beispiel #7
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = progname + " configure_file.cfg"

    parser = OptionParser(usage, version=SPARXVERSION)
    (options, args) = parser.parse_args()

    if len(args) != 1:
        sxprint("Usage: " + usage)
        sxprint("Please run \'" + progname + " -h\' for detailed options")
        sp_global_def.ERROR(
            "Invalid number of parameters used. Please see usage information above."
        )
        return

    if sp_global_def.CACHE_DISABLE:
        from sp_utilities import disable_bdb_cache
        disable_bdb_cache()

    from sp_development import ali2d_mref
    sp_global_def.BATCH = True
    ali2d_mref(args[0])
    sp_global_def.BATCH = False
Beispiel #8
0
def angle_diff(angle1, angle2):
    """
	This function determines the relative angle between two sets of angles.
	The resulting angle has to be added (modulo 360) to the first set.
	"""

    nima = len(angle1)
    nima2 = len(angle2)
    if nima2 != nima:
        sp_global_def.ERROR("Error: List lengths do not agree!", "angle_diff",
                            1)
    else:
        del nima2

    cosi = 0.0
    sini = 0.0
    for i in range(nima):
        qt = numpy.radians(angle2[i] - angle1[i])
        cosi += numpy.cos(qt)
        sini += numpy.sin(qt)
    alphai = numpy.degrees(math.atan2(sini, cosi)) % 360.0

    return alphai
Beispiel #9
0
def search_range(n, radius, shift, range, location=""):
    """
		Find permissible ranges for translational searches by resampling into polar coordinates
		n - image size; radius - particle radius, the circle has to fit into the square image;
		shift - current particle shift; range - desired maximum range search
		Output: a list of two elements:
		  left range (positive)
		  right range
		NOTE - ranges are with respect to the point n//2+1-shift within image (in 3D)
	"""
    cn = old_div(n, 2) + 1
    ql = cn + shift - radius - 2  # lower end is positive
    qe = n - cn - shift - radius  # upper end
    if ql < 0 or qe < 0:
        sp_global_def.ERROR(
            "Shift of particle too large, results may be incorrect:  %4d   %3d   %f  %f  %f  %f  %f"
            % (n, cn, radius, shift, range, ql, qe),
            "search_range  " + location,
            0,
        )
        ql = max(ql, 0)
        qe = max(qe, 0)
    # ???for mysterious reasons it has to be this way as C code changes the order of searches.
    return [min(qe, range), min(ql, range)]
Beispiel #10
0
def main():

    # Parse the Options
    progname = os.path.basename(sys.argv[0])
    usage = (progname +
             """ unblur_path input_micrograph_pattern output_directory
    --summovie_path
    --selection_list
    --nr_frames=nr_frames
    --pixel_size=pixel_size
    --voltage=voltage
    --exposure_per_frame=exposure_per_frame
    --pre_exposure=pre_exposure
    --nr_threads
    --save_frames
    --skip_dose_filter
    --expert_mode
    --shift_initial=shift_initial
    --shift_radius=shift_radius
    --b_factor=b_factor
    --fourier_vertical=fourier_vertical
    --fourier_horizontal=fourier_horizontal
    --shift_threshold=shift_threshold
    --iterations=iterations
    --dont_restore_noise
    --verbose

    sxunblur exists only in non-MPI version.

    Perform unblur and with dose filtering and summovie without dose filtering.

    sxunblur.py ~/my_app/unblur 'movies/micrograph_*_frames.mrc' outdir_unblur
    --summovie_path=~/my_app/summovie
    --nr_frames=25 --pixel_size=1.19 --exposure_per_frame=1.0
    --voltage=300.0 --pre_exposure=0.0 --nr_threads=1

    Perform unblur with dose filtering and summovie without dose filtering with selection list.

    sxunblur.py ~/my_app/unblur 'movies/micrograph_*_frames.mrc' outdir_unblur
    --summovie_path=~/my_app/summovie
    --selection_list=selected_micrograph_file
    --nr_frames=25 --pixel_size=1.19 --exposure_per_frame=1.0
    --voltage=300.0 --pre_exposure=0.0 --nr_threads=1

    Perform unblur without dose filtering.

    sxunblur.py ~/my_app/unblur 'movies/micrograph_*_frames.mrc' outdir_unblur
    --nr_frames=25 --pixel_size=1.19 --skip_dose_filter --nr_threads=1

    Perform unblur without dose filtering and save the frames.

    sxunblur.py ~/my_app/unblur 'movies/micrograph_*_frames.mrc' outdir_unblur
    --nr_frames=25 --pixel_size=1.19 --skip_dose_filter --save_frames --nr_threads=1

    Perform unblur with dose filtering and summovie without dose filtering with all options.

    sxunblur.py ~/my_app/unblur 'movies/micrograph_*_frames.mrc' outdir_unblur
    --summovie_path=~/my_app/summovie
    --nr_frames=25 --pixel_size=1.19 --exposure_per_frame=1.0
    --voltage=300.0 --pre_exposure=0.0 --save_frames --expert_mode
    --shift_initial=2.0 --shift_radius=200.0 --b_factor=1500.0
    --fourier_vertical=1 --fourier_horizontal=1 --shift_threshold=0.1
    --iterations=10 --verbose --nr_threads=1
    """)

    parser = optparse.OptionParser(usage, version=sp_global_def.SPARXVERSION)
    parser.add_option(
        "--summovie_path",
        type="str",
        default="",
        help=
        "summovie executable path (SPHIRE specific): Specify the file path of summovie executable. (default none)",
    )
    parser.add_option(
        "--selection_list",
        type="str",
        default="",
        help=
        "Micrograph selecting list (SPHIRE specific): Specify a name of micrograph selection list text file. The file extension must be '.txt'. If this is not provided, all files matched with the micrograph name pattern will be processed. (default none)",
    )
    parser.add_option(
        "--nr_frames",
        type="int",
        default=3,
        help=
        "Number of movie frames: The number of movie frames in each input micrograph. (default 3)",
    )
    parser.add_option("--sum_suffix",
                      type="str",
                      default="_sum",
                      help=optparse.SUPPRESS_HELP)
    parser.add_option("--shift_suffix",
                      type="str",
                      default="_shift",
                      help=optparse.SUPPRESS_HELP)
    parser.add_option(
        "--pixel_size",
        type="float",
        default=-1.0,
        help=
        "Pixel size [A]: The pixel size of input micrographs. (default required float)",
    )
    parser.add_option(
        "--voltage",
        type="float",
        default=300.0,
        help=
        "Microscope voltage [kV]: The acceleration voltage of microscope used for imaging. (default 300.0)",
    )
    parser.add_option(
        "--exposure_per_frame",
        type="float",
        default=2.0,
        help=
        "Per frame exposure [e/A^2]: The electron dose per frame in e/A^2. (default 2.0)",
    )
    parser.add_option(
        "--pre_exposure",
        type="float",
        default=0.0,
        help=
        "Pre-exposure [e/A^2]: The electron does in e/A^2 used for exposure prior to imaging .(default 0.0)",
    )
    parser.add_option(
        "--nr_threads",
        type="int",
        default=1,
        help=
        "Number of threads: The number of threads unblur can use. The higher the faster, but it requires larger memory. (default 1)",
    )
    parser.add_option(
        "--save_frames",
        action="store_true",
        default=False,
        help=
        "Save aligned movie frames: Save aligned movie frames. This option slows down the process. (default False)",
    )
    parser.add_option("--frames_suffix",
                      type="string",
                      default="_frames",
                      help=optparse.SUPPRESS_HELP)
    parser.add_option(
        "--skip_dose_filter",
        action="store_true",
        default=False,
        help=
        "Skip dose filter step: With this option, voltage, exposure per frame, and pre exposure will be ignored. (default False)",
    )
    parser.add_option(
        "--expert_mode",
        action="store_true",
        default=False,
        help=
        "Use expert mode: Requires initial shift, shift radius, b-factor, fourier_vertical, fourier_horizontal, shift threshold, iterations, restore noise, and verbosity options. (default False)",
    )
    parser.add_option("--frc_suffix",
                      type="string",
                      default="_frc",
                      help=optparse.SUPPRESS_HELP)
    parser.add_option(
        "--shift_initial",
        type="float",
        default=2.0,
        help=
        "Minimum shift for initial search [A] (expert mode): Effective with unblur expert mode. (default 2.0)",
    )
    parser.add_option(
        "--shift_radius",
        type="float",
        default=200.0,
        help=
        "Outer radius shift limit [A] (expert mode): Effective with unblur expert mode. (default 200.0)",
    )
    parser.add_option(
        "--b_factor",
        type="float",
        default=1500.0,
        help=
        "Apply B-factor to images [A^2] (expert mode): Effective with unblur expert mode. (default 1500.0)",
    )
    parser.add_option(
        "--fourier_vertical",
        type="int",
        default=1,
        help=
        "Vertical Fourier central mask size (expert mode): The half-width of central vertical line of Fourier mask. Effective with unblur expert mode. (default 1)",
    )
    parser.add_option(
        "--fourier_horizontal",
        type="int",
        default=1,
        help=
        "Horizontal Fourier central mask size (expert mode): The half-width of central horizontal line of Fourier mask. Effective with unblur expert mode. (default 1)",
    )
    parser.add_option(
        "--shift_threshold",
        type="float",
        default=0.1,
        help=
        "Termination shift threshold (expert mode): Effective with unblur expert mode. (default 0.1)",
    )
    parser.add_option(
        "--iterations",
        type="int",
        default=10,
        help=
        "Maximum iterations (expert mode): Effective with unblur expert mode. (default 10)",
    )
    parser.add_option(
        "--dont_restore_noise",
        action="store_true",
        default=False,
        help=
        "Do not restore noise power (expert mode): Effective with unblur expert mode. (default False)",
    )
    parser.add_option(
        "--verbose",
        action="store_true",
        default=False,
        help=
        "Verbose (expert mode): Effective with unblur expert mode. (default False)",
    )
    parser.add_option(
        "--unblur_ready",
        action="store_true",
        default=False,
        help=optparse.SUPPRESS_HELP,
    )

    # list of the options and the arguments
    (options, args) = parser.parse_args(sys.argv[1:])

    sp_global_def.BATCH = True

    # If there arent enough arguments, stop the script
    if len(args) != 3:
        sp_global_def.sxprint("Usage: " + usage)
        sp_global_def.ERROR(
            "Invalid number of parameters used. Please see usage information above."
        )
        return

    # Convert the realtive parts to absolute ones
    unblur_path = os.path.realpath(args[0])  # unblur_path
    input_image = os.path.realpath(args[1])  # input_micrograph_pattern
    output_dir = os.path.realpath(args[2])  # output_directory

    # If the unblur executable file does not exists, stop the script
    if not os.path.exists(unblur_path):
        sp_global_def.ERROR(
            "Unblur directory does not exist, please change the name and restart the program"
        )
        return

    # If the output directory exists, stop the script
    if os.path.exists(output_dir):
        sp_global_def.ERROR(
            "Output directory exists, please change the name and restart the program"
        )
        return

    # If the input file does not exists, stop the script
    file_list = glob.glob(input_image)

    if not file_list:
        sp_global_def.ERROR(
            "Input file does not exist, please change the name and restart the program"
        )
        return

    # If the skip_dose_filter option is false, the summovie path is necessary
    if not options.skip_dose_filter and not os.path.exists(
            options.summovie_path):
        sp_global_def.ERROR(
            "Path to the SumMovie executable is necessary when dose weighting is performed"
        )
        return

    # Output paths
    corrected_path = "{:s}/corrsum_dose_filtered".format(output_dir)
    uncorrected_path = "{:s}/corrsum".format(output_dir)
    shift_path = "{:s}/shift".format(output_dir)
    frc_path = "{:s}/frc".format(output_dir)
    log_path = "{:s}/logfiles".format(output_dir)
    temp_path = "{0}/temp".format(output_dir)

    # Split the path of the image name at the "/" Characters.
    # The last entry contains the micrograph name.
    # Split the micrograph name at the wildcard character for the
    # prefix and suffix.
    input_split = input_image.split("/")
    input_name = input_split[-1].split("*")

    # Get the input directory
    if len(input_split) != 1:
        input_dir = input_image[:-len(input_split[-1])]
    else:
        input_dir = ""

    # Create output directorys
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
        sp_global_def.write_command(output_dir)
    if not os.path.exists(uncorrected_path):
        os.mkdir(uncorrected_path)
    if not os.path.exists(shift_path):
        os.mkdir(shift_path)
    if not os.path.exists(corrected_path):
        if not options.skip_dose_filter:
            os.mkdir(corrected_path)
    if not os.path.exists(frc_path):
        if options.expert_mode or not options.skip_dose_filter:
            os.mkdir(frc_path)
    if not os.path.exists(temp_path) and not options.unblur_ready:
        os.mkdir(temp_path)
    if not os.path.exists(log_path):
        os.mkdir(log_path)

    # Run unblur
    run_unblur(
        unblur_path=unblur_path,
        input_image=input_image,
        input_dir=input_dir,
        output_dir=output_dir,
        corrected_path=corrected_path,
        uncorrected_path=uncorrected_path,
        shift_path=shift_path,
        frc_path=frc_path,
        temp_path=temp_path,
        log_path=log_path,
        file_list=file_list,
        options=options,
    )

    if not options.unblur_ready:
        # Remove temp folder
        for entry in glob.glob("{0}/*".format(temp_path)):
            os.remove(entry)
        os.rmdir(temp_path)

    sp_global_def.sxprint("All Done!")

    sp_global_def.BATCH = False
Beispiel #11
0
def run_unblur(
    unblur_path,
    input_image,
    input_dir,
    output_dir,
    corrected_path,
    uncorrected_path,
    shift_path,
    frc_path,
    temp_path,
    log_path,
    file_list,
    options,
):

    # Lists to write the text files later
    micrograph_list = []
    shift_list = []
    if options.save_frames:
        frames_list = []

    # If micrograph list is provided just process the images in the list
    mic_list = options.selection_list
    if mic_list:
        # Import list file
        try:
            set_selection = numpy.genfromtxt(mic_list, dtype=None)
        except TypeError:
            sp_global_def.ERROR("no entrys in list file {0}".format(mic_list))
        # List of files which are in pattern and list
        file_list = [
            entry for entry in file_list if
            entry[len(input_dir):] in set_selection and os.path.exists(entry)
        ]
        # If no match is there abort
        if len(file_list) == 0:
            sp_global_def.ERROR(
                "no files in {0} matched the file pattern:\n".format(mic_list),
                1)
    # Get the number of files
    nr_files = len(file_list)

    # Timeing stuff
    time_start = time.time()
    time_list = []

    # Loop over all files
    for index, inputfile in enumerate(sorted(file_list)):

        # Check, if there is an prefix and suffix.
        # If there is more then one entry: the suffix is the last one.
        # Otherwhise its just the one after the dot.
        input_suffix = inputfile.split("/")[-1].split(".")[-1]
        # First output to introduce the programm
        if index == 0:
            sp_global_def.sxprint(
                "Progress: 0.0%;  Time: --h:--m:--s/--h:--m:--s;  Unblur started!"
            )

        # Time begin
        t1 = time.time()

        # Get the output names
        file_name = inputfile[len(input_dir):-len(input_suffix) - 1]
        if options.skip_dose_filter:
            micrograph_name = "{0}/{1}{2}.mrc".format(uncorrected_path,
                                                      file_name,
                                                      options.sum_suffix)
            frames_name = "{0}/{1}{2}.mrc".format(uncorrected_path, file_name,
                                                  options.frames_suffix)
            frc_name = "{0}/{1}{2}.txt".format(frc_path, file_name,
                                               options.frc_suffix)
        else:
            micrograph_name = "{0}/{1}{2}.mrc".format(corrected_path,
                                                      file_name,
                                                      options.sum_suffix)
            frames_name = "{0}/{1}{2}.mrc".format(corrected_path, file_name,
                                                  options.frames_suffix)
            micrograph_name_skip = "{0}/{1}{2}.mrc".format(
                uncorrected_path, file_name, options.sum_suffix)
            frames_name_skip = "{0}/{1}{2}.mrc".format(uncorrected_path,
                                                       file_name,
                                                       options.frames_suffix)
            frc_name = "{0}/{1}{2}.txt".format(frc_path, file_name,
                                               options.frc_suffix)
            frc_summovie_name = "{0}/{1}_summovie{2}.txt".format(
                frc_path, file_name, options.frc_suffix)
        shift_name = "{0}/{1}{2}.txt".format(shift_path, file_name,
                                             options.shift_suffix)
        if not options.unblur_ready:
            temp_name = "{0}/{1}{2}.mrc".format(temp_path, file_name,
                                                options.sum_suffix)
        else:
            temp_name = inputfile
        log_name = "{0}/{1}.log".format(log_path, file_name)
        error_name = "{0}/{1}.err".format(log_path, file_name)
        # Append the names to the lists
        micrograph_list.append("{0}{1}.mrc".format(file_name,
                                                   options.sum_suffix))
        shift_list.append(shift_name)
        if options.save_frames:
            frames_list.append("{0}{1}.mrc".format(file_name,
                                                   options.frames_suffix))

        # First build the unblur/summovie command
        if not options.skip_dose_filter:
            unblur_command = create_unblur_command(temp_name, micrograph_name,
                                                   shift_name, frames_name,
                                                   frc_name, options)
            # Options for the summovie command
            options_summovie = {
                "first": 1,
                "last": -1,
                "nr_frames": options.nr_frames,
                "pixel_size": options.pixel_size,
                "exposure_per_frame": options.exposure_per_frame,
                "voltage": options.voltage,
                "pre_exposure": options.pre_exposure,
                "dont_restore_noise": options.dont_restore_noise,
                "apply_dose_filter": False,
            }
            summovie_command = sp_utilities.create_summovie_command(
                temp_name,
                micrograph_name_skip,
                shift_name,
                frc_summovie_name,
                options_summovie,
            )
        else:
            unblur_command = create_unblur_command(temp_name, micrograph_name,
                                                   shift_name, frc_name,
                                                   frames_name, options)

        # Export the number of threads
        export_threads_command = []

        # Export
        export_threads_command.append("export")
        # Nr of threads
        export_threads_command.append("OMP_NUM_THREADS={0}".format(
            options.nr_threads))

        if not options.unblur_ready:
            # Do a e2proc3d.py
            e2proc3d_command = []

            # e2proc3d
            e2proc3d_command.append("e2proc3d.py")
            # inputfile
            e2proc3d_command.append("{0}".format(inputfile))
            # outputfile
            e2proc3d_command.append("{0}".format(temp_name))

        # Translate the command to single strings
        if not options.unblur_ready:
            e2proc3d_command = r" ".join(e2proc3d_command)
        export_threads_command = r" ".join(export_threads_command)
        unblur_command = "\n".join(unblur_command)
        if not options.skip_dose_filter:
            summovie_command = "\n".join(summovie_command)

        # Build full command
        if not options.unblur_ready:
            if not options.skip_dose_filter:
                full_command = r'{0}; {1}; echo "{2}" | {3}'.format(
                    export_threads_command,
                    e2proc3d_command,
                    unblur_command,
                    unblur_path,
                )
                full_command_summovie = r'{0}; echo "{1}" | {2}'.format(
                    export_threads_command, summovie_command,
                    options.summovie_path)
            else:
                full_command = r'{0}; {1}; echo "{2}" | {3}'.format(
                    export_threads_command,
                    e2proc3d_command,
                    unblur_command,
                    unblur_path,
                )
        else:
            if not options.skip_dose_filter:
                full_command = r'{0}; echo "{1}" | {2}'.format(
                    export_threads_command, unblur_command, unblur_path)
                full_command_summovie = r'{0}; echo "{1}" | {2}'.format(
                    export_threads_command, summovie_command,
                    options.summovie_path)
            else:
                full_command = r'{0}; echo "{1}" | {2}'.format(
                    export_threads_command, unblur_command, unblur_path)

        # Remove temp unblur files
        temp_unblur_files = glob.glob(".UnBlur*")
        for entry in temp_unblur_files:
            os.remove(entry)

        # Remove temp summovie files
        temp_summovie_files = glob.glob(".SumMovie*")
        for entry in temp_summovie_files:
            os.remove(entry)

        with open(log_name, "w") as f:
            with open(error_name, "w") as e:
                # Execute Command
                if not options.skip_dose_filter:

                    subprocess.Popen([full_command],
                                     shell=True,
                                     stdout=f,
                                     stderr=e).wait()

                    # Remove temp unblur files
                    temp_unblur_files = glob.glob(".UnBlur*")
                    for entry in temp_unblur_files:
                        os.remove(entry)

                    # Remove temp summovie files
                    temp_summovie_files = glob.glob(".SumMovie*")
                    for entry in temp_summovie_files:
                        os.remove(entry)

                    subprocess.Popen([full_command_summovie],
                                     shell=True,
                                     stdout=f,
                                     stderr=e).wait()
                else:
                    subprocess.Popen([full_command],
                                     shell=True,
                                     stdout=f,
                                     stderr=e).wait()

        # Remove temp unblur files
        temp_unblur_files = glob.glob(".UnBlur*")
        for entry in temp_unblur_files:
            os.remove(entry)
        # Remove temp summovie files
        temp_summovie_files = glob.glob(".SumMovie*")
        for entry in temp_summovie_files:
            os.remove(entry)

        if not options.unblur_ready:
            if os.path.exists(temp_name):
                # Remove temp file
                os.remove(temp_name)
            else:
                sp_global_def.sxprint(
                    ("Error with file:\n{0}".format(inputfile)))

        # Check if SumMovie and UnBlur finished cleanly
        with open(log_name, "r") as r:
            clean_summovie = False
            clean_unblur = False
            for line in r:
                if "SumMovie finished cleanly." in line:
                    clean_summovie = True
                if "UnBlur finished cleanly." in line:
                    clean_unblur = True

        if clean_unblur:
            sp_global_def.sxprint("UnBlur finished cleanly.")
        else:
            sp_global_def.ERROR(
                "unblur error. check the logfile for more information: {0}".
                format(log_name),
                action=0,
            )

        if clean_summovie:
            sp_global_def.sxprint("SumMovie finished cleanly.")
        else:
            sp_global_def.ERROR(
                "summovie error. check the logfile for more information: {0}".
                format(log_name),
                action=0,
            )

        time_list.append(time.time() - t1)

        # Do progress output
        percent = round(100 * (index + 1) / float(nr_files), 2)
        estimated_time = nr_files * sum(time_list) / float(len(time_list))
        estimated_time_h = estimated_time // 3600
        estimated_time_m = (estimated_time - estimated_time_h * 3600) // 60
        estimated_time_s = (estimated_time - estimated_time_h * 3600 -
                            estimated_time_m * 60)
        current_time = time.time() - time_start
        current_time_h = current_time // 3600
        current_time_m = (current_time - current_time_h * 3600) // 60
        current_time_s = current_time - current_time_h * 3600 - current_time_m * 60
        sp_global_def.sxprint((
            "Progress: {0:.2f}%;  Time: {1:.0f}h:{2:.0f}m:{3:.0f}s/{4:.0f}h:{5:.0f}m:{6:.0f}s;  Micrograph done:{7}"
            .format(
                percent,
                current_time_h,
                current_time_m,
                current_time_s,
                estimated_time_h,
                estimated_time_m,
                estimated_time_s,
                file_name,
            )))

    # Write micrograph and shift list
    with open("{0}/unblur_micrographs.txt".format(output_dir), "w") as f:
        for entry in sorted(micrograph_list):
            f.write("{0}\n".format(entry))

    with open("{0}/unblur_shiftfiles.txt".format(output_dir), "w") as f:
        for entry in sorted(shift_list):
            f.write("{0}\n".format(entry))

    if options.save_frames:
        with open("{0}/unblur_frames.txt".format(output_dir), "w") as f:
            for entry in sorted(frames_list):
                f.write("{0}\n".format(entry))
Beispiel #12
0
def main_proj_compare(classavgstack,
                      reconfile,
                      outdir,
                      options,
                      mode='viper',
                      prjmethod='trilinear',
                      classangles=None,
                      partangles=None,
                      selectdoc=None,
                      verbose=False,
                      displayYN=False):
    """
	Main function overseeing various projection-comparison modes.
	
	Arguments:
		classavgstack : Input image stack
		reconfile : Map of which to generate projections (an optionally perform alignment)
		outdir : Output directory
		mode : Mode, viper (pre-existing angles for each input image), projmatch (angles from internal projection-matching)
		verbose : (boolean) Whether to write additional information to screen
		options : (list) Command-line options, run 'sxproj_compare.py -h' for an exhaustive list
		classangles : Angles and shifts for each input class average
		partangles : Angles and shifts for each particle (mode meridien)
		selectdoc : Selection file for included images
		prjmethod : Interpolation method to use
		displayYN : (boolean) Whether to automatically open montage
	"""

    # Expand path for outputs
    refprojstack = os.path.join(outdir, 'refproj.hdf')
    refanglesdoc = os.path.join(outdir, 'refangles.txt')
    outaligndoc = os.path.join(outdir, 'docalign2d.txt')

    # If not an input, will create an output, in modes projmatch
    if classangles == None:
        classangles = os.path.join(outdir, 'docangles.txt')

        # You need either input angles (mode viper) or to calculate them on the fly (mode projmatch)
        if mode == 'viper':
            sp_global_def.ERROR(
                "\nERROR!! Input alignment parameters not specified.",
                __file__, 1)
            sxprint('Type %s --help to see available options\n' %
                    os.path.basename(__file__))
            exit()

    # Check if inputs exist
    check(classavgstack, verbose=verbose)
    check(reconfile, verbose=verbose)
    if verbose: sxprint('')

    # Check that dimensions of images and volume agree (maybe rescale volume)
    voldim = EMAN2.EMData(reconfile).get_xsize()
    imgdim = EMAN2.EMData(classavgstack, 0).get_xsize()
    if voldim != imgdim:
        sp_global_def.ERROR(
            "\nERROR!! Dimension of input volume doesn't match that of image stack: %s vs. %s"
            % (voldim, imgdim), __file__, 1)

        scale = float(
            imgdim
        ) / voldim  # only approximate, since full-sized particle radius is arbitrary
        msg = 'The command to resize the volume will be of the form:\n'
        msg += 'e2proc3d.py %s resized_vol.hdf --scale=%1.5f --clip=%s,%s,%s\n' % (
            reconfile, scale, imgdim, imgdim, imgdim)
        msg += 'Check the file in the ISAC directory named "README_shrink_ratio.txt" for confirmation.\n'
        sxprint(msg)
        exit()

    #  Here if you want to be fancy, there should be an option to chose the projection method,
    #  the mechanism can be copied from sxproject3d.py  PAP
    if prjmethod == 'trilinear':
        method_num = 1
    elif prjmethod == 'gridding':
        method_num = -1
    elif prjmethod == 'nn':
        method_num = 0
    else:
        sp_global_def.ERROR(
            "\nERROR!! Valid projection methods are: trilinear (default), gridding, and nn (nearest neighbor).",
            __file__, 1)
        sxprint('Usage:\n%s' % USAGE)
        exit()

    # Set output directory and log file name
    log, verbose = prepare_outdir_log(outdir, verbose)

    # In case class averages include discarded images, apply selection file
    if mode == 'viper':
        if selectdoc:
            goodavgs, extension = os.path.splitext(
                os.path.basename(classavgstack))
            newclasses = os.path.join(outdir, goodavgs + "_kept" + extension)

            # e2proc2d appends to existing files, so rename existing output
            if os.path.exists(newclasses):
                renamefile = newclasses + '.bak'
                print_log_msg(
                    "Selected-classes stack %s exists, renaming to %s" %
                    (newclasses, renamefile), log, verbose)
                print_log_msg("mv %s %s\n" % (newclasses, renamefile), log,
                              verbose)
                os.rename(newclasses, renamefile)

            print_log_msg(
                'Creating subset of %s to %s based on selection list %s' %
                (classavgstack, newclasses, selectdoc), log, verbose)
            cmd = "e2proc2d.py %s %s --list=%s" % (classavgstack, newclasses,
                                                   selectdoc)
            print_log_msg(cmd, log, verbose)
            os.system(cmd)
            sxprint('')

            # Update class-averages
            classavgstack = newclasses

    # align de novo to reference map
    if mode == 'projmatch':
        # Generate reference projections
        print_log_msg(
            'Projecting %s to output %s using an increment of %s degrees using %s symmetry'
            % (reconfile, refprojstack, options.delta, options.symmetry), log,
            verbose)
        cmd = 'sxproject3d.py %s %s --delta=%s --method=S --phiEqpsi=Minus --symmetry=%s' % (
            reconfile, refprojstack, options.delta, options.symmetry)
        if options.prjmethod == 'trilinear': cmd += ' --trilinear'
        cmd += '\n'
        print_log_msg(cmd, log, verbose)
        project3d(reconfile,
                  refprojstack,
                  delta=options.delta,
                  symmetry=options.symmetry)

        # Export projection angles
        print_log_msg(
            "Exporting projection angles from %s to %s" %
            (refprojstack, refanglesdoc), log, verbose)
        cmd = "sp_header.py %s --params=xform.projection --import=%s\n" % (
            refprojstack, refanglesdoc)
        print_log_msg(cmd, log, verbose)
        header(refprojstack, 'xform.projection', fexport=refanglesdoc)

        # Perform multi-reference alignment
        if options.align == 'ali2d':
            projdir = os.path.join(
                outdir, 'Projdir')  # used if input angles no provided
            if os.path.isdir(projdir):
                print_log_msg('Removing pre-existing directory %s' % projdir,
                              log, verbose)
                print_log_msg('rm -r %s\n' % projdir, log, verbose)
                shutil.rmtree(
                    projdir)  # os.rmdir only removes empty directories

            # Zero out alignment parameters in header
            print_log_msg(
                'Zeroing out alignment parameters in header of %s' %
                classavgstack, log, verbose)
            cmd = 'sxheader.py %s --params xform.align2d --zero\n' % classavgstack
            print_log_msg(cmd, log, verbose)
            header(classavgstack, 'xform.align2d', zero=True)

            # Perform multi-reference alignment
            msg = 'Aligning images in %s to projections %s with a radius of %s and a maximum allowed shift of %s' % (
                classavgstack, refprojstack, options.matchrad,
                options.matchshift)
            print_log_msg(msg, log, verbose)
            cmd = 'sxmref_ali2d.py %s %s %s --ou=%s --xr=%s --yr=%s\n' % (
                classavgstack, refprojstack, projdir, options.matchrad,
                options.matchshift, options.matchshift)
            print_log_msg(cmd, log, verbose)
            mref_ali2d(classavgstack,
                       refprojstack,
                       projdir,
                       ou=options.matchrad,
                       xrng=options.matchshift,
                       yrng=options.matchshift)

            # Export alignment parameters
            print_log_msg(
                'Exporting angles from %s into %s' %
                (classavgstack, classangles), log, verbose)
            cmd = "sp_header.py %s --params=xform.align2d --export=%s\n" % (
                classavgstack, classangles)
            print_log_msg(cmd, log, verbose)
            header(classavgstack, 'xform.align2d', fexport=classangles)

        # By default, use AP SH
        else:
            apsh(refprojstack,
                 classavgstack,
                 outangles=classangles,
                 refanglesdoc=refanglesdoc,
                 outaligndoc=outaligndoc,
                 outerradius=options.matchrad,
                 maxshift=options.matchshift,
                 ringstep=options.matchstep,
                 log=log,
                 verbose=verbose)

        # Diagnostic
        alignlist = read_text_row(
            classangles)  # contain 2D alignment parameters
        nimg1 = EMAN2.EMUtil.get_image_count(classavgstack)
        assert len(alignlist) == nimg1, "MRK_DEBUG"

    # Get alignment parameters from MERIDIEN
    if mode == 'meridien':
        continueTF = True  # Will proceed unless some information is missing

        if not partangles:
            sp_global_def.ERROR(
                "\nERROR!! Input alignment parameters not provided.", __file__,
                1)
            continueTF = False

        if not continueTF:
            sxprint('Type %s --help to see available options\n' %
                    os.path.basename(__file__))
            exit()

        if not options.classdocs or options.outliers:
            classdir = os.path.join(outdir, 'Byclass')
            if not os.path.isdir(classdir): os.makedirs(classdir)

            if options.outliers:
                goodclassparttemplate = os.path.join(
                    classdir, 'goodpartsclass{0:03d}.txt')
            else:
                goodclassparttemplate = None

            if not options.classdocs:
                classmap = os.path.join(classdir, 'classmap.txt')
                classdoc = os.path.join(classdir, 'docclass{0:03d}.txt')
                options.classdocs = os.path.join(classdir, 'docclass*.txt')

                # Separate particles by class
                vomq(classavgstack,
                     classmap,
                     classdoc,
                     log=log,
                     verbose=verbose)

        mode_meridien(reconfile,
                      classavgstack,
                      options.classdocs,
                      partangles,
                      selectdoc,
                      options.refineshift,
                      options.refinerad,
                      classangles,
                      outaligndoc,
                      interpolation_method=method_num,
                      outliers=options.outliers,
                      goodclassparttemplate=goodclassparttemplate,
                      alignopt=options.align,
                      ringstep=options.refinestep,
                      log=log,
                      verbose=verbose)

    # Import Euler angles
    print_log_msg(
        "Importing parameter information into %s from %s" %
        (classavgstack, classangles), log, verbose)
    cmd = "sp_header.py %s --params=xform.projection --import=%s\n" % (
        classavgstack, classangles)
    print_log_msg(cmd, log, verbose)
    header(classavgstack, 'xform.projection', fimport=classangles)

    # Make comparison stack between class averages (images 0,2,4,...) and re-projections (images 1,3,5,...)
    compstack = compare_projs(reconfile,
                              classavgstack,
                              classangles,
                              outdir,
                              interpolation_method=method_num,
                              log=log,
                              verbose=verbose)

    # Optionally pop up e2display
    if displayYN:
        sxprint('Opening montage')
        cmd = "e2display.py %s\n" % compstack
        sxprint(cmd)
        os.system(cmd)

    sxprint("Done!")
Beispiel #13
0
def average_angles(alignlist,
                   partdoc,
                   selectdoc=None,
                   init_angles=None,
                   threshold=None,
                   goodpartdoc=None,
                   log=None,
                   verbose=False):
    """
	Computes a vector average of a set of particles' Euler angles phi and theta.
	
	Arguments:
		alignlist : Alignment parameter doc file, i.e., from MERIDIEN refinment
		partdoc : List of particle indices whose angles should be averaged
		selectdoc : Input substack selection file if particles removed before refinement (e.g., Substack/isac_substack_particle_id_list.txt)
		init_angles : List (2 elements) with initial phi and theta angles, for excluding outliers
		threshold : Angular threshold (degrees) beyond which particles exceeding this angular difference from init_angles will be excluded
		goodpartdoc : Output list of retained particles if a threshold was specified
		log : Logger object
		verbose : (boolean) Whether to write additional information to screen
	Returns:
		list of 2 elements:
			avg_phi
			avg_theta
	"""

    # Read alignment parameters
    if isinstance(alignlist, str): alignlist = read_text_row(outaligndoc)
    # (If loading the same parameters repeatedly, better to read the file once externally and pass only the list.)

    # Read class list
    partlist = read_text_row(partdoc)

    if selectdoc:
        selectlist = read_text_row(selectdoc)
    else:
        selectlist = None

    sum_phi = np.array([0.0, 0.0])
    sum_theta = np.array([0.0, 0.0])
    totparts = 0
    num_outliers = 0
    goodpartlist = []
    goodpartcounter = 0

    # Loop through particles
    for totpartnum in partlist:
        if selectlist:
            goodpartnum = selectlist.index(totpartnum)
        else:
            goodpartnum = totpartnum[0]

        try:
            phi_deg = alignlist[goodpartnum][0]
            theta_deg = alignlist[goodpartnum][1]
            phi_rad = np.deg2rad(phi_deg)
            theta_rad = np.deg2rad(theta_deg)
        except IndexError:
            msg = "\nERROR!! %s tries to access particle #%s" % (partdoc,
                                                                 goodpartnum)
            numalignparts = len(alignlist)
            msg += "\nAlignment doc file has only %s entries" % (numalignparts)
            msg += "\nMaybe try substack selection file with flag '--select <substack_select>'?"
            sp_global_def.ERROR(msg, __file__, 1)
            exit()

        if init_angles:
            angdif = angle_diff(init_angles, [phi_deg, theta_deg])
            if angdif > 180: angdif = 360.0 - angdif

        totparts += 1

        # Exclude particles exceeding optional threshold
        if threshold == None or angdif < threshold:
            sum_phi += (np.cos(phi_rad), np.sin(phi_rad))
            sum_theta += (np.cos(theta_rad), np.sin(theta_rad))
            goodpartlist.append(goodpartnum)
            goodpartcounter += 1
        else:
            num_outliers += 1

    # Compute final average
    avg_phi = degrees(atan2(sum_phi[1], sum_phi[0]))
    avg_theta = degrees(atan2(sum_theta[1], sum_theta[0]))

    # Clean up, might reuse
    del alignlist
    del partlist
    del selectlist

    msg = "Particle list %s: average angles (%s, %s)" % (partdoc, avg_phi,
                                                         avg_theta)
    print_log_msg(msg, log, verbose)

    if threshold:
        msg = "Found %s out of %s outliers exceeding an angle difference of %s degrees from initial estimate" % (
            num_outliers, totparts, threshold)
        print_log_msg(msg, log, verbose)

        if goodpartdoc:
            if goodpartcounter > 0:
                write_text_row(goodpartlist, goodpartdoc)
                msg = "Wrote %s particles to %s" % (goodpartcounter,
                                                    goodpartdoc)
                print_log_msg(msg, log, verbose)
            else:
                msg = "WARNING!! Kept 0 particles from class %s" % partdoc
                print_log_msg(msg, log, verbose)
                [avg_phi, avg_theta] = init_angles

    return [avg_phi, avg_theta]
Beispiel #14
0
    "--hold_flag",
    type=str,
    default=None,
    help="Hold flag for the submission command, e.g. -hold_jid",
)
parser.add_argument(
    "--first_hold_number",
    type=str,
    default=None,
    help="Wait number of an already running job",
)
args = parser.parse_args()

sp_global_def.BATCH = True
if not os.path.exists(args.input_run_dir):
    sp_global_def.ERROR("Input directory does not exist!", "sxbatch.py", 1)

qsub_dict = {
    "qsub": glob.re.compile("Your job (\w+)"),
    "sbatch": glob.re.compile("Submitted batch job (\w+)"),
}
if args.submission_command.split()[0] not in qsub_dict and args.hold_flag:
    sp_global_def.ERROR(
        "Qsub return output not known! Please contact the SPHIRE authors!",
        "sxbatch.py",
        1,
    )

sp_global_def.write_command(".")

if args.first_hold_number:
Beispiel #15
0
def recons3d_4nn_MPI(
    myid,
    prjlist,
    symmetry="c1",
    finfo=None,
    snr=1.0,
    npad=2,
    xysize=-1,
    zsize=-1,
    mpi_comm=None,
):
    if mpi_comm == None:
        mpi_comm = mpi.MPI_COMM_WORLD

    if type(prjlist) == list:
        prjlist = sp_utilities.iterImagesList(prjlist)

    if not prjlist.goToNext():
        sp_global_def.ERROR("empty input list", "recons3d_4nn_MPI", 1)

    imgsize = prjlist.image().get_xsize()
    if prjlist.image().get_ysize() != imgsize:
        imgsize = max(imgsize, prjlist.image().get_ysize())
        dopad = True
    else:
        dopad = False
    prjlist.goToPrev()

    fftvol = EMAN2_cppwrap.EMData()
    weight = EMAN2_cppwrap.EMData()
    if xysize == -1 and zsize == -1:
        params = {
            "size": imgsize,
            "npad": npad,
            "symmetry": symmetry,
            "fftvol": fftvol,
            "weight": weight,
            "snr": snr,
        }
        r = EMAN2_cppwrap.Reconstructors.get("nn4", params)
    else:
        if xysize != -1 and zsize != -1:
            rx = old_div(float(xysize), imgsize)
            ry = old_div(float(xysize), imgsize)
            rz = old_div(float(zsize), imgsize)
        elif xysize != -1:
            rx = old_div(float(xysize), imgsize)
            ry = old_div(float(xysize), imgsize)
            rz = 1.0
        else:
            rx = 1.0
            ry = 1.0
            rz = old_div(float(zsize), imgsize)
        params = {
            "sizeprojection": imgsize,
            "npad": npad,
            "symmetry": symmetry,
            "fftvol": fftvol,
            "weight": weight,
            "xratio": rx,
            "yratio": ry,
            "zratio": rz,
        }
        r = EMAN2_cppwrap.Reconstructors.get("nn4_rect", params)
    r.setup()

    if not (finfo is None):
        nimg = 0
    while prjlist.goToNext():
        prj = prjlist.image()
        if dopad:
            prj = sp_utilities.pad(prj, imgsize, imgsize, 1, "circumference")
        insert_slices(r, prj)
        if not (finfo is None):
            nimg += 1
            finfo.write("Image %4d inserted.\n" % (nimg))
            finfo.flush()

    if not (finfo is None):
        finfo.write("Begin reducing ...\n")
        finfo.flush()

    sp_utilities.reduce_EMData_to_root(fftvol, myid, comm=mpi_comm)
    sp_utilities.reduce_EMData_to_root(weight, myid, comm=mpi_comm)

    if myid == 0:
        dummy = r.finish(True)
    else:
        if xysize == -1 and zsize == -1:
            fftvol = sp_utilities.model_blank(imgsize, imgsize, imgsize)
        else:
            if zsize == -1:
                fftvol = sp_utilities.model_blank(xysize, xysize, imgsize)
            elif xysize == -1:
                fftvol = sp_utilities.model_blank(imgsize, imgsize, zsize)
            else:
                fftvol = sp_utilities.model_blank(xysize, xysize, zsize)
    return fftvol
Beispiel #16
0
def main():
    arglist = []
    for arg in sys.argv:
        arglist.append(arg)

    progname = optparse.os.path.basename(arglist[0])
    usage = (
        progname
        + " prj_stack volume [begin end step] --CTF --npad=ntimes_padding --list=file --group=ID --snr=SNR --sym=symmetry --verbose=(0|1) --xysize --MPI"
    )
    parser = optparse.OptionParser(usage, version=sp_global_def.SPARXVERSION)

    parser.add_option(
        "--CTF", action="store_true", default=False, help="apply CTF correction"
    )
    parser.add_option("--snr", type="float", default=1.0, help="Signal-to-Noise Ratio")
    parser.add_option("--sym", type="string", default="c1", help="symmetry")
    parser.add_option(
        "--list",
        type="string",
        help="file with list of images to be used in the first column",
    )
    parser.add_option(
        "--group",
        type="int",
        default=-1,
        help="perform reconstruction using images for a given group number (group is attribute in the header)",
    )
    parser.add_option(
        "--MPI", action="store_true", default=False, help="use MPI version "
    )
    parser.add_option(
        "--npad", type="int", default=2, help="number of times padding (default 2)"
    )
    parser.add_option(
        "--verbose",
        type="int",
        default=0,
        help="verbose level: 0 no verbose, 1 verbose",
    )
    parser.add_option(
        "--xysize", type="int", default=-1, help="user expected size at xy direction"
    )
    parser.add_option(
        "--zsize", type="int", default=-1, help="user expected size at z direction"
    )
    parser.add_option(
        "--smearstep",
        type="float",
        default=0.0,
        help="Rotational smear step (default 0.0, no smear)",
    )
    parser.add_option(
        "--interpolation_method",
        type="string",
        default="4nn",
        help="4nn, or tril: nearest neighbor, or trilinear interpolation",
    )
    parser.add_option(
        "--niter",
        type="int",
        default=10,
        help="number of iterations for iterative reconstruction",
    )
    parser.add_option(
        "--upweighted",
        action="store_true",
        default=False,
        help="apply background noise",
    )
    parser.add_option(
        "--compensate",
        action="store_true",
        default=False,
        help="compensate in reconstruction",
    )
    parser.add_option(
        "--chunk_id",
        type="int",
        default=-1,
        help="reconstruct both odd and even groups of particles",
    )
    parser.add_option(
        "--target_window_size",
        type="int",
        default=-1,
        help=" size of the targeted reconstruction ",
    )

    (options, args) = parser.parse_args(arglist[1:])

    if sp_global_def.CACHE_DISABLE:
        sp_utilities.disable_bdb_cache()

    if len(args) == 2:
        prj_stack = args[0]
        vol_stack = args[1]
        nimage = EMAN2_cppwrap.EMUtil.get_image_count(prj_stack)
        pid_list = list(range(0, nimage))
    elif len(args) == 5:
        prj_stack = args[0]
        vol_stack = args[1]
        begin = string.atoi(args[2])
        end = string.atoi(args[3])
        step = string.atoi(args[4])
        pid_list = list(range(begin, end, step))
    else:
        sp_global_def.ERROR("Incomplete list of arguments")
        return

    if options.list and options.group > -1:
        sp_global_def.ERROR("options group and list cannot be used together")
        return

    sp_global_def.BATCH = True
    if options.interpolation_method == "4nn":
        sp_applications.recons3d_n(
            prj_stack,
            pid_list,
            vol_stack,
            options.CTF,
            options.snr,
            1,
            options.npad,
            options.sym,
            options.list,
            options.group,
            options.verbose,
            options.MPI,
            options.xysize,
            options.zsize,
            options.smearstep,
            options.upweighted,
            options.compensate,
            options.chunk_id,
        )
    elif options.interpolation_method == "tril":
        if options.MPI is False:
            sp_global_def.ERROR(
                "Trilinear interpolation reconstruction has MPI version only!"
            )
            return
        sp_applications.recons3d_trl_MPI(
            prj_stack,
            pid_list,
            vol_stack,
            options.CTF,
            options.snr,
            1,
            options.npad,
            options.sym,
            options.verbose,
            options.niter,
            options.compensate,
            options.target_window_size,
        )

    else:
        sp_global_def.ERROR(
            "Wrong interpolation method. The current options are 4nn, and tril. 4nn is the default one."
        )
        return

    sp_global_def.write_command(optparse.os.path.dirname(vol_stack))
    sp_global_def.BATCH = False
Beispiel #17
0
def import_params(params_file, dim):
    """
	Import 2D  or 3D parameters.
	The 2d params file has the format:
	angle, shift x, shift y, mirror

	The 3d params file has the format:
	angle_phi, angle_theta, angle_psi, tx, ty

	Arguments:
	params_2d_file - File name of the 2d parameter files

	Returns:
	parameter array
	"""
    if dim == "2d":
        dtype_import_list = [
            ("angle_psi", float),
            ("shift_x", float),
            ("shift_y", float),
            ("mirror", int),
        ]
        sxprint("What happens with mirror?")
    elif dim == "3d":
        dtype_import_list = [
            ("angle_rot", float),
            ("angle_theta", float),
            ("angle_psi", float),
            ("shift_x", float),
            ("shift_y", float),
        ]
    else:
        sp_global_def.ERROR(
            "Dimension {0} not supported. Only '2d' and '3d' are supported.".
            format(dim),
            "sp_sphire2relion",
        )

    input_data = np.genfromtxt(params_file, dtype=dtype_import_list)

    dtype_output_list = [
        ("_rlnOriginX", float),
        ("_rlnOriginY", float),
        ("_rlnAngleRot", float),
        ("_rlnAngleTilt", float),
        ("_rlnAnglePsi", float),
    ]
    params_array = np.empty(len(input_data), dtype=sorted(dtype_output_list))

    params_array["_rlnOriginX"] = input_data["shift_x"]
    params_array["_rlnOriginY"] = input_data["shift_y"]
    params_array["_rlnAnglePsi"] = input_data["angle_psi"]

    if dim == "2d":
        params_array["_rlnAngleTilt"] = 0
        params_array["_rlnAngleRot"] = 0
    elif dim == "3d":
        params_array["_rlnAngleTilt"] = input_data["angle_theta"]
        params_array["_rlnAngleRot"] = input_data["angle_rot"]

    return params_array
Beispiel #18
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = progname + " stack outdir <maskfile> --ir=inner_radius --ou=outer_radius --rs=ring_step --xr=x_range --yr=y_range --ts=translation_step --dst=delta --center=center --maxit=max_iteration --CTF --snr=SNR --Fourvar=Fourier_variance --Ng=group_number --Function=user_function_name --CUDA --GPUID --MPI"
	parser = OptionParser(usage,version=SPARXVERSION)
	parser.add_option("--ir",       type="float",  default=1,             help="inner radius for rotational correlation > 0 (set to 1)")
	parser.add_option("--ou",       type="float",  default=-1,            help="outer radius for rotational correlation < nx/2-1 (set to the radius of the particle)")
	parser.add_option("--rs",       type="float",  default=1,             help="step between rings in rotational correlation > 0 (set to 1)" ) 
	parser.add_option("--xr",       type="string", default="4 2 1 1",     help="range for translation search in x direction, search is +/xr ")
	parser.add_option("--yr",       type="string", default="-1",          help="range for translation search in y direction, search is +/yr ")
	parser.add_option("--ts",       type="string", default="2 1 0.5 0.25",help="step of translation search in both directions")
	parser.add_option("--nomirror", action="store_true", default=False,   help="Disable checking mirror orientations of images (default False)")
	parser.add_option("--dst",      type="float",  default=0.0,           help="delta")
	parser.add_option("--center",   type="float",  default=-1,            help="-1.average center method; 0.not centered; 1.phase approximation; 2.cc with Gaussian function; 3.cc with donut-shaped image 4.cc with user-defined reference 5.cc with self-rotated average")
	parser.add_option("--maxit",    type="float",  default=0,             help="maximum number of iterations (0 means the maximum iterations is 10, but it will automatically stop should the criterion falls")
	parser.add_option("--CTF",      action="store_true", default=False,   help="use CTF correction during alignment")
	parser.add_option("--snr",      type="float",  default=1.0,           help="signal-to-noise ratio of the data (set to 1.0)")
	parser.add_option("--Fourvar",  action="store_true", default=False,   help="compute Fourier variance")
	#parser.add_option("--Ng",       type="int",          default=-1,      help="number of groups in the new CTF filteration")
	parser.add_option("--function", type="string",       default="ref_ali2d",  help="name of the reference preparation function (default ref_ali2d)")
	#parser.add_option("--CUDA",     action="store_true", default=False,   help="use CUDA program")
	#parser.add_option("--GPUID",    type="string",    default="",         help="ID of GPUs available")
	parser.add_option("--MPI",      action="store_true", default=False,   help="use MPI version ")
	parser.add_option("--rotational", action="store_true", default=False, help="rotational alignment with optional limited in-plane angle, the parameters are: ir, ou, rs, psi_max, mode(F or H), maxit, orient, randomize")
	parser.add_option("--psi_max",  type="float",        default=180.0,   help="psi_max")
	parser.add_option("--mode",     type="string",       default="F",     help="Full or Half rings, default F")
	parser.add_option("--randomize",action="store_true", default=False,   help="randomize initial rotations (suboption of friedel, default False)")
	parser.add_option("--orient",   action="store_true", default=False,   help="orient images such that the average is symmetric about x-axis, for layer lines (suboption of friedel, default False)")
	parser.add_option("--template", type="string",       default=None,    help="2D alignment will be initialized using the template provided (only non-MPI version, default None)")
	parser.add_option("--random_method",   type="string", default="",   help="use SHC or SCF (default standard method)")

	(options, args) = parser.parse_args()

	if len(args) < 2 or len(args) > 3:
		sxprint( "Usage: " + usage )
		sxprint( "Please run \'" + progname + " -h\' for detailed options" )
		sp_global_def.ERROR( "Invalid number of parameters used. Please see usage information above." )
		return

	elif(options.rotational):
		from sp_applications import ali2d_rotationaltop
		sp_global_def.BATCH = True
		ali2d_rotationaltop(args[1], args[0], options.randomize, options.orient, options.ir, options.ou, options.rs, options.psi_max, options.mode, options.maxit)
	else:
		if args[1] == 'None': 
			outdir = None
		else:		          
			outdir = args[1]

		if len(args) == 2: 
			mask = None
		else:              
			mask = args[2]
		
		if sp_global_def.CACHE_DISABLE:
			from sp_utilities import disable_bdb_cache
			disable_bdb_cache()
		
		sp_global_def.BATCH = True
		if  options.MPI:
			from sp_applications import ali2d_base
			from mpi import mpi_comm_size, mpi_comm_rank, MPI_COMM_WORLD

			number_of_proc = mpi_comm_size(MPI_COMM_WORLD)
			myid = mpi_comm_rank(MPI_COMM_WORLD)
			main_node = 0

			if(myid == main_node):
				import subprocess
				from sp_logger import Logger, BaseLogger_Files
				#  Create output directory
				log = Logger(BaseLogger_Files())
				log.prefix = os.path.join(outdir)
				cmd = "mkdir "+log.prefix
				outcome = subprocess.call(cmd, shell=True)
				log.prefix += "/"
			else:
				outcome = 0
				log = None
			from sp_utilities       import bcast_number_to_all
			outcome  = bcast_number_to_all(outcome, source_node = main_node)
			if(outcome == 1):
				sp_global_def.ERROR( "Output directory exists, please change the name and restart the program", myid=myid )

			dummy = ali2d_base(args[0], outdir, mask, options.ir, options.ou, options.rs, options.xr, options.yr, \
				options.ts, options.nomirror, options.dst, \
				options.center, options.maxit, options.CTF, options.snr, options.Fourvar, \
				options.function, random_method = options.random_method, log = log, \
				number_of_proc = number_of_proc, myid = myid, main_node = main_node, mpi_comm = MPI_COMM_WORLD,\
				write_headers = True)
		else:
			sxprint( " Non-MPI is no more in use, try MPI option, please." )
			"""
			from sp_applications import ali2d
			ali2d(args[0], outdir, mask, options.ir, options.ou, options.rs, options.xr, options.yr, \
				options.ts, options.nomirror, options.dst, \
				options.center, options.maxit, options.CTF, options.snr, options.Fourvar, \
				-1, options.function, False, "", options.MPI, \
				options.template, random_method = options.random_method)
	    	"""
		sp_global_def.BATCH = False
Beispiel #19
0
def main():
    arglist = []
    for arg in sys.argv:
        arglist.append(arg)
    progname = os.path.basename(arglist[0])
    usage = progname + """ firstvolume  secondvolume  maskfile  directory  --prefix  --wn  --step  --cutoff  --radius  --fsc  --res_overall  --out_ang_res  --apix  --MPI

	Compute local resolution in real space within area outlined by the maskfile and within regions wn x wn x wn
	"""
    parser = optparse.OptionParser(usage, version=sp_global_def.SPARXVERSION)

    parser.add_option("--prefix",
                      type="str",
                      default='localres',
                      help="Prefix for the output files. (default localres)")
    parser.add_option(
        "--wn",
        type="int",
        default=7,
        help=
        "Size of window within which local real-space FSC is computed. (default 7)"
    )
    parser.add_option(
        "--step",
        type="float",
        default=1.0,
        help="Shell step in Fourier size in pixels. (default 1.0)")
    parser.add_option("--cutoff",
                      type="float",
                      default=0.143,
                      help="Resolution cut-off for FSC. (default 0.143)")
    parser.add_option(
        "--radius",
        type="int",
        default=-1,
        help=
        "If there is no maskfile, sphere with r=radius will be used. By default, the radius is nx/2-wn (default -1)"
    )
    parser.add_option(
        "--fsc",
        type="string",
        default=None,
        help=
        "Save overall FSC curve (might be truncated). By default, the program does not save the FSC curve. (default none)"
    )
    parser.add_option(
        "--res_overall",
        type="float",
        default=-1.0,
        help=
        "Overall resolution at the cutoff level estimated by the user [abs units]. (default None)"
    )
    parser.add_option(
        "--out_ang_res",
        action="store_true",
        default=False,
        help=
        "Additionally creates a local resolution file in Angstroms. (default False)"
    )
    parser.add_option(
        "--apix",
        type="float",
        default=1.0,
        help=
        "Pixel size in Angstrom. Effective only with --out_ang_res options. (default 1.0)"
    )
    parser.add_option("--MPI",
                      action="store_true",
                      default=False,
                      help="Use MPI version.")

    (options, args) = parser.parse_args(arglist[1:])

    if len(args) < 3 or len(args) > 4:
        sxprint("Usage: " + usage)
        ERROR(
            "Invalid number of parameters used. Please see usage information above."
        )
        return

    if sp_global_def.CACHE_DISABLE:
        sp_utilities.disable_bdb_cache()

    res_overall = options.res_overall

    if options.MPI:

        number_of_proc = mpi.mpi_comm_size(mpi.MPI_COMM_WORLD)
        myid = mpi.mpi_comm_rank(mpi.MPI_COMM_WORLD)
        main_node = 0
        sp_global_def.MPI = True
        cutoff = options.cutoff

        nk = int(options.wn)

        if (myid == main_node):
            #print sys.argv
            vi = sp_utilities.get_im(sys.argv[1])
            ui = sp_utilities.get_im(sys.argv[2])

            nx = vi.get_xsize()
            ny = vi.get_ysize()
            nz = vi.get_zsize()
            dis = [nx, ny, nz]
        else:
            dis = [0, 0, 0, 0]

        sp_global_def.BATCH = True

        dis = sp_utilities.bcast_list_to_all(dis, myid, source_node=main_node)

        if (myid != main_node):
            nx = int(dis[0])
            ny = int(dis[1])
            nz = int(dis[2])

            vi = sp_utilities.model_blank(nx, ny, nz)
            ui = sp_utilities.model_blank(nx, ny, nz)

        if len(args) == 3:
            m = sp_utilities.model_circle((min(nx, ny, nz) - nk) // 2, nx, ny,
                                          nz)
            outdir = args[2]

        elif len(args) == 4:
            if (myid == main_node):
                m = sp_morphology.binarize(sp_utilities.get_im(args[2]), 0.5)
            else:
                m = sp_utilities.model_blank(nx, ny, nz)
            outdir = args[3]
        if os.path.exists(outdir) and myid == 0:
            sp_global_def.ERROR('Output directory already exists!')
        elif myid == 0:
            os.makedirs(outdir)
        sp_global_def.write_command(outdir)
        sp_utilities.bcast_EMData_to_all(m, myid, main_node)
        """Multiline Comment0"""
        freqvol, resolut = sp_statistics.locres(vi, ui, m, nk, cutoff,
                                                options.step, myid, main_node,
                                                number_of_proc)

        if (myid == 0):
            # Remove outliers based on the Interquartile range
            output_volume(freqvol, resolut, options.apix, outdir,
                          options.prefix, options.fsc, options.out_ang_res, nx,
                          ny, nz, res_overall)

    else:
        cutoff = options.cutoff
        vi = sp_utilities.get_im(args[0])
        ui = sp_utilities.get_im(args[1])

        nn = vi.get_xsize()
        nx = nn
        ny = nn
        nz = nn
        nk = int(options.wn)

        if len(args) == 3:
            m = sp_utilities.model_circle((nn - nk) // 2, nn, nn, nn)
            outdir = args[2]

        elif len(args) == 4:
            m = sp_morphology.binarize(sp_utilities.get_im(args[2]), 0.5)
            outdir = args[3]
        if os.path.exists(outdir):
            sp_global_def.ERROR('Output directory already exists!')
        else:
            os.makedirs(outdir)
        sp_global_def.write_command(outdir)

        mc = sp_utilities.model_blank(nn, nn, nn, 1.0) - m

        vf = sp_fundamentals.fft(vi)
        uf = sp_fundamentals.fft(ui)
        """Multiline Comment1"""
        lp = int(nn / 2 / options.step + 0.5)
        step = 0.5 / lp

        freqvol = sp_utilities.model_blank(nn, nn, nn)
        resolut = []
        for i in range(1, lp):
            fl = step * i
            fh = fl + step
            #print(lp,i,step,fl,fh)
            v = sp_fundamentals.fft(sp_filter.filt_tophatb(vf, fl, fh))
            u = sp_fundamentals.fft(sp_filter.filt_tophatb(uf, fl, fh))
            tmp1 = EMAN2_cppwrap.Util.muln_img(v, v)
            tmp2 = EMAN2_cppwrap.Util.muln_img(u, u)

            do = EMAN2_cppwrap.Util.infomask(
                sp_morphology.square_root(
                    sp_morphology.threshold(
                        EMAN2_cppwrap.Util.muln_img(tmp1, tmp2))), m, True)[0]

            tmp3 = EMAN2_cppwrap.Util.muln_img(u, v)
            dp = EMAN2_cppwrap.Util.infomask(tmp3, m, True)[0]
            resolut.append([i, (fl + fh) / 2.0, dp / do])

            tmp1 = EMAN2_cppwrap.Util.box_convolution(tmp1, nk)
            tmp2 = EMAN2_cppwrap.Util.box_convolution(tmp2, nk)
            tmp3 = EMAN2_cppwrap.Util.box_convolution(tmp3, nk)

            EMAN2_cppwrap.Util.mul_img(tmp1, tmp2)

            tmp1 = sp_morphology.square_root(sp_morphology.threshold(tmp1))

            EMAN2_cppwrap.Util.mul_img(tmp1, m)
            EMAN2_cppwrap.Util.add_img(tmp1, mc)

            EMAN2_cppwrap.Util.mul_img(tmp3, m)
            EMAN2_cppwrap.Util.add_img(tmp3, mc)

            EMAN2_cppwrap.Util.div_img(tmp3, tmp1)

            EMAN2_cppwrap.Util.mul_img(tmp3, m)
            freq = (fl + fh) / 2.0
            bailout = True
            for x in range(nn):
                for y in range(nn):
                    for z in range(nn):
                        if (m.get_value_at(x, y, z) > 0.5):
                            if (freqvol.get_value_at(x, y, z) == 0.0):
                                if (tmp3.get_value_at(x, y, z) < cutoff):
                                    freqvol.set_value_at(x, y, z, freq)
                                    bailout = False
                                else:
                                    bailout = False
            if (bailout): break
        #print(len(resolut))
        # remove outliers
        output_volume(freqvol, resolut, options.apix, outdir, options.prefix,
                      options.fsc, options.out_ang_res, nx, ny, nz,
                      res_overall)
Beispiel #20
0
def recons3d_4nn_ctf_MPI(
    myid,
    prjlist,
    snr=1.0,
    sign=1,
    symmetry="c1",
    finfo=None,
    npad=2,
    xysize=-1,
    zsize=-1,
    mpi_comm=None,
    smearstep=0.0,
):
    """
		recons3d_4nn_ctf - calculate CTF-corrected 3-D reconstruction from a set of projections using three Eulerian angles, two shifts, and CTF settings for each projeciton image
		Input
			stack: name of the stack file containing projection data, projections have to be squares
			list_proj: list of projections to be included in the reconstruction or image iterator
			snr: Signal-to-Noise Ratio of the data
			sign: sign of the CTF
			symmetry: point-group symmetry to be enforced, each projection will enter the reconstruction in all symmetry-related directions.
	"""

    if mpi_comm == None:
        mpi_comm = mpi.MPI_COMM_WORLD

    if type(prjlist) == list:
        prjlist = sp_utilities.iterImagesList(prjlist)
    if not prjlist.goToNext():
        sp_global_def.ERROR("empty input list", "recons3d_4nn_ctf_MPI", 1)
    imgsize = prjlist.image().get_xsize()
    if prjlist.image().get_ysize() != imgsize:
        imgsize = max(imgsize, prjlist.image().get_ysize())
        dopad = True
    else:
        dopad = False
    prjlist.goToPrev()

    fftvol = EMAN2_cppwrap.EMData()

    if smearstep > 0.0:
        # if myid == 0:  print "  Setting smear in prepare_recons_ctf"
        ns = 1
        smear = []
        for j in range(-ns, ns + 1):
            if j != 0:
                for i in range(-ns, ns + 1):
                    for k in range(-ns, ns + 1):
                        smear += [
                            i * smearstep, j * smearstep, k * smearstep, 1.0
                        ]
        # Deal with theta = 0.0 cases
        prj = []
        for i in range(-ns, ns + 1):
            for k in range(-ns, ns + 1):
                prj.append(i + k)
        for i in range(-2 * ns, 2 * ns + 1, 1):
            smear += [i * smearstep, 0.0, 0.0, float(prj.count(i))]
        # if myid == 0:  print "  Smear  ",smear
        fftvol.set_attr("smear", smear)

    weight = EMAN2_cppwrap.EMData()
    if xysize == -1 and zsize == -1:
        params = {
            "size": imgsize,
            "npad": npad,
            "snr": snr,
            "sign": sign,
            "symmetry": symmetry,
            "fftvol": fftvol,
            "weight": weight,
        }
        r = EMAN2_cppwrap.Reconstructors.get("nn4_ctf", params)
    else:
        if xysize != -1 and zsize != -1:
            rx = old_div(float(xysize), imgsize)
            ry = old_div(float(xysize), imgsize)
            rz = old_div(float(zsize), imgsize)
        elif xysize != -1:
            rx = old_div(float(xysize), imgsize)
            ry = old_div(float(xysize), imgsize)
            rz = 1.0
        else:
            rx = 1.0
            ry = 1.0
            rz = old_div(float(zsize), imgsize)
        #  There is an error here with sizeprojection  PAP 10/22/2014
        params = {
            "size": sizeprojection,
            "npad": npad,
            "snr": snr,
            "sign": sign,
            "symmetry": symmetry,
            "fftvol": fftvol,
            "weight": weight,
            "xratio": rx,
            "yratio": ry,
            "zratio": rz,
        }
        r = EMAN2_cppwrap.Reconstructors.get("nn4_ctf_rect", params)
    r.setup()

    # if not (finfo is None):
    nimg = 0
    while prjlist.goToNext():
        prj = prjlist.image()
        if dopad:
            prj = sp_utilities.pad(prj, imgsize, imgsize, 1, "circumference")
        # if params:
        insert_slices(r, prj)
        if not (finfo is None):
            nimg += 1
            finfo.write(" %4d inserted\n" % (nimg))
            finfo.flush()
    del sp_utilities.pad
    if not (finfo is None):
        finfo.write("begin reduce\n")
        finfo.flush()

    sp_utilities.reduce_EMData_to_root(fftvol, myid, comm=mpi_comm)
    sp_utilities.reduce_EMData_to_root(weight, myid, comm=mpi_comm)

    if not (finfo is None):
        finfo.write("after reduce\n")
        finfo.flush()

    if myid == 0:
        dummy = r.finish(True)
    else:
        if xysize == -1 and zsize == -1:
            fftvol = sp_utilities.model_blank(imgsize, imgsize, imgsize)
        else:
            if zsize == -1:
                fftvol = sp_utilities.model_blank(xysize, xysize, imgsize)
            elif xysize == -1:
                fftvol = sp_utilities.model_blank(imgsize, imgsize, zsize)
            else:
                fftvol = sp_utilities.model_blank(xysize, xysize, zsize)
    return fftvol
Beispiel #21
0
def recons3d_4nn(
    stack_name,
    list_proj=[],
    symmetry="c1",
    npad=4,
    snr=None,
    weighting=1,
    varsnr=False,
    xysize=-1,
    zsize=-1,
):
    """
	Perform a 3-D reconstruction using Pawel's FFT Back Projection algorithm.

	Input:
		stack_name - name of the file with projection data.

		list_proj -  list of projections to be used in the reconstruction

		symmetry - Point group of the target molecule (defaults to "C1")

		npad -

		Angles and shifts are passed in the file header as set_attr. Keywords are phi, theta, psi, sx, sy

		Return:  3D reconstructed volume image

		Usage:
			vol = recons3d_4nn(filepattern, list_proj, symmetry)
	"""

    if list_proj == []:
        if type(stack_name) == bytes:
            nima = EMAN2_cppwrap.EMUtil.get_image_count(stack_name)
        else:
            nima = len(stack_name)
        list_proj = list(range(nima))
    # read first image to determine the size to use
    if type(stack_name) == bytes:
        proj = EMAN2_cppwrap.EMData()
        proj.read_image(stack_name, list_proj[0])
    else:
        proj = stack_name[list_proj[0]].copy()

    size = proj.get_xsize()
    # sanity check -- image must be square
    if size != proj.get_ysize():
        sp_global_def.ERROR("input data has to be square", "recons3d_4nn", 1)

    # reconstructor
    fftvol = EMAN2_cppwrap.EMData()
    weight = EMAN2_cppwrap.EMData()
    params = {
        "npad": npad,
        "symmetry": symmetry,
        "weighting": weighting,
        "fftvol": fftvol,
        "weight": weight,
    }
    if xysize == -1 and zsize == -1:
        params["size"] = size
        if snr != None:
            params["snr"] = snr
            # params["varsnr"] = int(varsnr)
        r = EMAN2_cppwrap.Reconstructors.get("nn4", params)
    else:
        if xysize != -1 and zsize != -1:
            rx = old_div(float(xysize), size)
            ry = old_div(float(xysize), size)
            rz = old_div(float(zsize), size)
        elif xysize != -1:
            rx = old_div(float(xysize), size)
            ry = old_div(float(xysize), size)
            rz = 1.0
        else:
            rx = 1.0
            ry = 1.0
            rz = old_div(float(zsize), size)

        if snr is None:
            params["sizeprojection"] = size
            params["xratio"] = rx
            params["yratio"] = ry
            params["zratio"] = rz
        else:
            params["sizeprojection"] = size
            params["snr"] = snr
            params["varsnr"] = int(varsnr)
            params["xratio"] = rx
            params["yratio"] = ry
            params["zratio"] = rz
        r = EMAN2_cppwrap.Reconstructors.get("nn4_rect", params)

    r.setup()

    if type(stack_name) == bytes:
        for i in range(len(list_proj)):
            proj.read_image(stack_name, list_proj[i])
            # horatio active_refactoring Jy51i1EwmLD4tWZ9_00000_1
            # active = proj.get_attr_default('active', 1)
            # if active == 1:
            # 	insert_slices(r, proj)
            insert_slices(r, proj)
    else:
        for i in list_proj:
            # horatio active_refactoring Jy51i1EwmLD4tWZ9_00000_1
            # active = stack_name[i].get_attr_default('active', 1)
            # if active == 1:
            # 	insert_slices(r, stack_name[i])
            insert_slices(r, stack_name[i])

    dummy = r.finish(True)
    return fftvol
Beispiel #22
0
def recons3d_4nnw_MPI(
    myid,
    prjlist,
    bckgdata,
    snr=1.0,
    sign=1,
    symmetry="c1",
    finfo=None,
    npad=2,
    xysize=-1,
    zsize=-1,
    mpi_comm=None,
    smearstep=0.0,
    fsc=None,
):
    """
		recons3d_4nn_ctf - calculate CTF-corrected 3-D reconstruction from a set of projections using three Eulerian angles, two shifts, and CTF settings for each projeciton image
		Input
			stack: name of the stack file containing projection data, projections have to be squares
			prjlist: list of projections to be included in the reconstruction or image iterator
			bckgdata = [get_im("tsd.hdf"),read_text_file("data_stamp.txt")]
			snr: Signal-to-Noise Ratio of the data
			sign: sign of the CTF
			symmetry: point-group symmetry to be enforced, each projection will enter the reconstruction in all symmetry-related directions.
	"""
    pass  # IMPORTIMPORTIMPORT from sp_utilities  import reduce_EMData_to_root, pad
    pass  # IMPORTIMPORTIMPORT from EMAN2      import Reconstructors
    pass  # IMPORTIMPORTIMPORT from sp_utilities  import iterImagesList, set_params_proj, model_blank
    pass  # IMPORTIMPORTIMPORT from mpi        import MPI_COMM_WORLD
    pass  # IMPORTIMPORTIMPORT import types

    if mpi_comm == None:
        mpi_comm = mpi.MPI_COMM_WORLD

    if type(prjlist) == list:
        prjlist = sp_utilities.iterImagesList(prjlist)
    if not prjlist.goToNext():
        sp_global_def.ERROR("empty input list", "recons3d_4nnw_MPI", 1)
    imgsize = prjlist.image().get_xsize()
    if prjlist.image().get_ysize() != imgsize:
        imgsize = max(imgsize, prjlist.image().get_ysize())
        dopad = True
    else:
        dopad = False
    prjlist.goToPrev()

    #  Do the FSC shtick.
    bnx = old_div(imgsize * npad, 2) + 1
    if fsc:
        pass  # IMPORTIMPORTIMPORT from math import sqrt
        pass  # IMPORTIMPORTIMPORT from sp_utilities import reshape_1d
        t = [0.0] * len(fsc)
        for i in range(len(fsc)):
            t[i] = min(max(fsc[i], 0.0), 0.999)
        t = sp_utilities.reshape_1d(t, len(t), npad * len(t))
        refvol = sp_utilities.model_blank(bnx, 1, 1, 0.0)
        for i in range(len(fsc)):
            refvol.set_value_at(i, t[i])
    else:
        refvol = sp_utilities.model_blank(bnx, 1, 1, 1.0)
    refvol.set_attr("fudge", 1.0)

    fftvol = EMAN2_cppwrap.EMData()
    weight = EMAN2_cppwrap.EMData()

    if smearstep > 0.0:
        # if myid == 0:  print "  Setting smear in prepare_recons_ctf"
        ns = 1
        smear = []
        for j in range(-ns, ns + 1):
            if j != 0:
                for i in range(-ns, ns + 1):
                    for k in range(-ns, ns + 1):
                        smear += [
                            i * smearstep, j * smearstep, k * smearstep, 1.0
                        ]
        # Deal with theta = 0.0 cases
        prj = []
        for i in range(-ns, ns + 1):
            for k in range(-ns, ns + 1):
                prj.append(i + k)
        for i in range(-2 * ns, 2 * ns + 1, 1):
            smear += [i * smearstep, 0.0, 0.0, float(prj.count(i))]
        # if myid == 0:  print "  Smear  ",smear
        fftvol.set_attr("smear", smear)

    if xysize == -1 and zsize == -1:
        params = {
            "size": imgsize,
            "npad": npad,
            "snr": snr,
            "sign": sign,
            "symmetry": symmetry,
            "refvol": refvol,
            "fftvol": fftvol,
            "weight": weight,
        }
        r = EMAN2_cppwrap.Reconstructors.get("nn4_ctfw", params)
    else:
        if xysize != -1 and zsize != -1:
            rx = old_div(float(xysize), imgsize)
            ry = old_div(float(xysize), imgsize)
            rz = old_div(float(zsize), imgsize)
        elif xysize != -1:
            rx = old_div(float(xysize), imgsize)
            ry = old_div(float(xysize), imgsize)
            rz = 1.0
        else:
            rx = 1.0
            ry = 1.0
            rz = old_div(float(zsize), imgsize)
        #  There is an error here with sizeprojection  PAP 10/22/2014
        params = {
            "size": sizeprojection,
            "npad": npad,
            "snr": snr,
            "sign": sign,
            "symmetry": symmetry,
            "fftvol": fftvol,
            "weight": weight,
            "xratio": rx,
            "yratio": ry,
            "zratio": rz,
        }
        r = EMAN2_cppwrap.Reconstructors.get("nn4_ctf_rect", params)
    r.setup()

    # from utilities import model_blank, get_im, read_text_file
    # bckgdata = [get_im("tsd.hdf"),read_text_file("data_stamp.txt")]

    nnx = bckgdata[0].get_xsize()
    nny = bckgdata[0].get_ysize()
    bckgnoise = []
    for i in range(nny):
        prj = sp_utilities.model_blank(nnx)
        for k in range(nnx):
            prj[k] = bckgdata[0].get_value_at(k, i)
        bckgnoise.append(prj)

    datastamp = bckgdata[1]
    if not (finfo is None):
        nimg = 0
    while prjlist.goToNext():
        prj = prjlist.image()
        try:
            stmp = old_div(nnx, 0)
            stmp = prj.get_attr("ptcl_source_image")
        except:
            try:
                stmp = prj.get_attr("ctf")
                stmp = round(stmp.defocus, 4)
            except:
                sp_global_def.ERROR(
                    "Either ptcl_source_image or ctf has to be present in the header.",
                    "recons3d_4nnw_MPI",
                    1,
                    myid,
                )
        try:
            indx = datastamp.index(stmp)
        except:
            sp_global_def.ERROR("Problem with indexing ptcl_source_image.",
                                "recons3d_4nnw_MPI", 1, myid)

        if dopad:
            prj = sp_utilities.pad(prj, imgsize, imgsize, 1, "circumference")

        prj.set_attr("bckgnoise", bckgnoise[indx])
        insert_slices(r, prj)
        if not (finfo is None):
            nimg += 1
            finfo.write(" %4d inserted\n" % (nimg))
            finfo.flush()
    del sp_utilities.pad
    if not (finfo is None):
        finfo.write("begin reduce\n")
        finfo.flush()

    sp_utilities.reduce_EMData_to_root(fftvol, myid, comm=mpi_comm)
    sp_utilities.reduce_EMData_to_root(weight, myid, comm=mpi_comm)

    if not (finfo is None):
        finfo.write("after reduce\n")
        finfo.flush()

    if myid == 0:
        dummy = r.finish(True)
    else:
        pass  # IMPORTIMPORTIMPORT from sp_utilities import model_blank
        if xysize == -1 and zsize == -1:
            fftvol = sp_utilities.model_blank(imgsize, imgsize, imgsize)
        else:
            if zsize == -1:
                fftvol = sp_utilities.model_blank(xysize, xysize, imgsize)
            elif xysize == -1:
                fftvol = sp_utilities.model_blank(imgsize, imgsize, zsize)
            else:
                fftvol = sp_utilities.model_blank(xysize, xysize, zsize)
    return fftvol
Beispiel #23
0
def _main_():
	_, child_argparser = setup_argparser()
	# These global variables are kind of ugly, but are necessary in python2. Will be removed in
	# python 3.
	global STACK_FILE_PATH
	global PROJECTION_PARAMETERS
	global VOLUME1
	global VOLUME2
	global DEFOCUS_SEARCH_RANGE
	global DEFOCUS_STEP_SIZE
	global MASK_VOLUME
	global RESOLUTION
	global PIXEL_SIZE
	global HALF_MAP_ASSIGNEMENTS

	args = child_argparser.parse_args()

	if "meridien" in sys.argv[1]:
		meridien_path = args.meridien_path
		files = sp_ctf_refine_io.read_meridien_data(meridien_path)
		volume1_file_path = files["first_halfmap"]
		volume2_file_path = files["second_halfmap"]
		chunk_file_path = files["chunk1"]
		params_file_path = files["final_params"]
	else:
		volume1_file_path = args.volume
		volume2_file_path = args.volume2
		params_file_path = args.params_path
		chunk_file_path = args.chunk
		if volume2_file_path is None and chunk_file_path is not None:
			sp_global_def.ERROR(
				"If chunk file is specified, you need to specify a second volume (-v2)"
			)

	STACK_FILE_PATH = args.inputstack  # "bdb:name"

	mask_file_path = args.mask

	DEFOCUS_SEARCH_RANGE = args.range

	DEFOCUS_STEP_SIZE = args.delta

	output_folder = args.outputdir

	if os.path.exists(output_folder):
		sp_global_def.ERROR("Output folder already exists. Stop execution.")
	else:
		os.makedirs(output_folder)
		sp_global_def.write_command(output_folder)

	output_virtual_stack_path = "bdb:" + os.path.join(output_folder, "ctf_refined")

	output_stats_path = os.path.join(output_folder, "statistics")

	number_of_particles_to_read = args.number_particles

	volume_nominal_resolution = args.resolution
	RESOLUTION = volume_nominal_resolution
	PIXEL_SIZE = args.apix

	PROJECTION_PARAMETERS = sp_ctf_refine_io.read_meridien_params(params_file_path)

	num_cpu = multiprocessing.cpu_count() - 1

	volume1, volume2, MASK_VOLUME = sp_ctf_refine_io.read_volume(
		path_vol_1=volume1_file_path,
		path_vol_2=volume2_file_path,
		path_mask=mask_file_path,
		resolution=volume_nominal_resolution,
		pixel_size=PIXEL_SIZE,
	)
	VOLUME1 = volume1
	VOLUME2 = volume2

	particle_chunks, number_of_particles = indices_to_chunks(
		STACK_FILE_PATH,
		chunk_size=100,
		number_of_particles_to_read=number_of_particles_to_read,
	)

	if chunk_file_path:
		HALF_MAP_ASSIGNEMENTS = get_half_map_assigments_per_particle(
			stack_path=STACK_FILE_PATH,
			chunk_path=chunk_file_path,
			number_of_particles_to_read=number_of_particles_to_read,
		)

	sp_global_def.sxprint("####Start refinement####")
	start = time.time()

	# for chunk in particle_chunks:
	#   refine_set(chunk)

	#####################################################################
	# Python 2 workaround to get rid of a memory leak.
	# Pool eats up memory and only give it back after it returns.
	# So let it return more often by deviding chunks into chunks :-)
	#####################################################################
	num_chunks = len(particle_chunks)
	refinement_results = []

	with tqdm(total=num_chunks, file=sys.stdout) as pbar:
		for i in range(0, num_chunks, num_cpu):
			subset_chunk = particle_chunks[i: (i + num_cpu)]
			pool = multiprocessing.Pool(num_cpu)
			refinement_result = pool.map_async(refine_set, subset_chunk, chunksize=1)
			pool.close()
			# print_progress(refinement_result)
			pool.join()
			for res in refinement_result.get():
				refinement_results.append(res)
			pbar.update(len(subset_chunk))
	#####################################################################

	end = time.time()
	sp_global_def.sxprint("Time for ", number_of_particles, " Particles:", end - start)

	# Ouput results
	refined_ctfs_as_list, refinement_results_per_micrograph = merge_ctf_refinement_results(
		refinement_results=refinement_results
	)

	sp_ctf_refine_io.write_virtual_bdb_stack(
		output_stack_path=output_virtual_stack_path,
		origin_stack_path=STACK_FILE_PATH,
		refined_ctfs=refined_ctfs_as_list,
		number_of_particles=number_of_particles,
	)

	sp_global_def.sxprint("Write statistics...")
	# WRITE STATISTICS
	if not os.path.exists(output_stats_path):
		os.makedirs(output_stats_path)

	refinement_stats_per_micrograh = calc_statistics(refinement_results_per_micrograph)
	sp_ctf_refine_io.write_statistics(output_stats_path, refinement_stats_per_micrograh)

	# Estimate error Range
	min_max_error, min_max_ratio = calculate_result_ranges(
		refinement_results_per_micrograph
	)
	# Save particle plots
	sp_global_def.sxprint("Write images...")
	path_output_img = os.path.join(output_stats_path, "img/")
	if not os.path.exists(path_output_img):
		os.makedirs(path_output_img)
	sp_ctf_refine_plotting.create_and_save_particle_plots(
		path_output_img=path_output_img,
		stack_file_path=STACK_FILE_PATH,
		refinement_results_per_micrograph=refinement_results_per_micrograph,
		min_max_error=min_max_error,
		min_max_ratio=min_max_ratio,
	)

	sp_global_def.sxprint("Write other...")
	refinement_results_matrix = get_refinement_results_matrix(
		refinement_results_per_micrograph
	)

	particle_error_path = os.path.join(output_stats_path, "particle_results.txt")
	refinement_results_matrix = refinement_results_matrix[
		refinement_results_matrix[:, 0].argsort()
	]
	np.savetxt(
		particle_error_path,
		refinement_results_matrix,
		delimiter=",",
		fmt=["%d", "%f", "%f", "%f"],
	)

	sp_global_def.sxprint("Done")
Beispiel #24
0
def main():
	# Read arguments
	args = argparser.parse_args()

	architecture = args.architecture
	particle_diameter = args.particle_diameter
	trainging_dir = args.training_dir
	annot_dir = args.annot_dir
	input_size = args.input_size

	output_dir = args.output_directory
	if os.path.exists(output_dir):
		sp_global_def.ERROR("Output folder already exists. Stop execution.")
	else:
		os.makedirs(output_dir)
		sp_global_def.write_command(output_dir)

	num_patches = args.num_patches
	overlap_patches = args.overlap_patches
	train_times = args.train_times
	saved_weights_name = args.saved_weights_name
	saved_weights_name = os.path.join(output_dir, saved_weights_name)
	pretrained_weights_name = args.pretrained_weights_name
	batch_size = args.batch_size
	learning_rate = args.learning_rate
	np_epoch = args.np_epoch
	object_scale = args.object_scale
	no_object_scale = args.no_object_scale
	coord_scale = args.coord_scale
	valid_image_dir = args.valid_image_dir
	valid_annot_dir = args.valid_annot_dir
	fine_tune = args.fine_tune
	gpu_fraction = args.gpu_fraction
	num_cpu = args.num_cpu
	cryolo_train_path = args.cryolo_train_path

	skiplowpass = args.skiplowpass
	cutoff = args.cutoff
	filtered_dir = args.filtered_dir

	warmup = args.warmup
	early_stop = int(args.early)

	str_gpus = [str(entry).strip() for entry in args.gpu.split(",")]
	arg_gpu = ' '.join(str_gpus)

	# Create config file
	model_dict = {'architecture': architecture,
				  'input_size': input_size,
				  'anchors': [particle_diameter, particle_diameter],
				  'overlap_patches': overlap_patches,
				  'max_box_per_image': 1000,
				  'num_patches': num_patches}

	if not skiplowpass:
		model_dict['filter'] = [cutoff,filtered_dir]
	else:
		if args.usejanni:
			model_dict['filter'] = [args.janni_model, args.janni_overlap, args.janni_batches, filtered_dir]


	train_dict = {'train_image_folder': trainging_dir,
				  'train_annot_folder': annot_dir,
				  'train_times': train_times,
				  'pretrained_weights': pretrained_weights_name,
				  'batch_size': batch_size,
				  'learning_rate': learning_rate,
				  'nb_epoch': np_epoch,
				  'warmup_epochs': 0,
				  'object_scale': object_scale,
				  'no_object_scale': no_object_scale,
				  'coord_scale': coord_scale,
				  'class_scale': 1.0,
				  "saved_weights_name": saved_weights_name,
				  "debug": True,
				  "log_path": "cryolo_logs/"
				  }

	valid_dict = {'valid_image_folder': valid_image_dir,
				  'valid_annot_folder': valid_annot_dir,
				  'valid_times': 1
				  }
	dict = {"model": model_dict, "train": train_dict, "valid": valid_dict}

	path = os.path.join(output_dir,"config_yolo.json")
	with open(path, 'w') as f:
		dump(dict, f, ensure_ascii=False, indent=4)

	# Run the training
	config_argument = "-c=" + path
	warmup_argument = "-w=" + str(warmup)
	gpu_argument = "-g " + arg_gpu
	early_stop = "-e=" + str(early_stop)
	fine_tune_argument = ""
	if fine_tune:
		fine_tune_argument = "--fine_tune"
	gpu_fraction_arg = "--gpu_fraction=1.0"
	if gpu_fraction < 1.0 and gpu_fraction > 0.0:
		gpu_fraction_arg = "--gpu_fraction=" + str(gpu_fraction)

	num_cpu_arg = ""
	if num_cpu != -1:
		num_cpu_arg = "--num_cpu="+str(num_cpu)
	cryolo_ex_pth = "cryolo_train.py"
	if cryolo_train_path:
		cryolo_ex_pth = cryolo_train_path
	'''
		if not fine_tune:
			command = [cryolo_ex_pth, "-c=config_yolo.json", warmup_argument, gpu_argument, early_stop, gpu_fraction_arg]
	
			if num_cpu != -1:
				command.append(num_cpu_arg)
			subprocess.check_call(
				command)
	'''
	if fine_tune:
		warmup_argument = "-w=0"
	command = [cryolo_ex_pth, config_argument, warmup_argument, gpu_argument, early_stop, gpu_fraction_arg]
	if fine_tune:
		command.append(fine_tune_argument)
	if num_cpu != -1:
		command.append(num_cpu_arg)

	subprocess.check_call(
		command)
Beispiel #25
0
def main():

    progname = os.path.basename(sys.argv[0])
    usage = progname + " proj_stack output_averages --MPI"
    parser = OptionParser(usage, version=SPARXVERSION)

    parser.add_option("--img_per_group",
                      type="int",
                      default=100,
                      help="number of images per group")
    parser.add_option("--radius",
                      type="int",
                      default=-1,
                      help="radius for alignment")
    parser.add_option(
        "--xr",
        type="string",
        default="2 1",
        help="range for translation search in x direction, search is +/xr")
    parser.add_option(
        "--yr",
        type="string",
        default="-1",
        help=
        "range for translation search in y direction, search is +/yr (default = same as xr)"
    )
    parser.add_option(
        "--ts",
        type="string",
        default="1 0.5",
        help=
        "step size of the translation search in both directions, search is -xr, -xr+ts, 0, xr-ts, xr, can be fractional"
    )
    parser.add_option(
        "--iter",
        type="int",
        default=30,
        help="number of iterations within alignment (default = 30)")
    parser.add_option(
        "--num_ali",
        type="int",
        default=5,
        help="number of alignments performed for stability (default = 5)")
    parser.add_option("--thld_err",
                      type="float",
                      default=1.0,
                      help="threshold of pixel error (default = 1.732)")
    parser.add_option(
        "--grouping",
        type="string",
        default="GRP",
        help=
        "do grouping of projections: PPR - per projection, GRP - different size groups, exclusive (default), GEV - grouping equal size"
    )
    parser.add_option(
        "--delta",
        type="float",
        default=-1.0,
        help="angular step for reference projections (required for GEV method)"
    )
    parser.add_option(
        "--fl",
        type="float",
        default=0.3,
        help="cut-off frequency of hyperbolic tangent low-pass Fourier filter")
    parser.add_option(
        "--aa",
        type="float",
        default=0.2,
        help="fall-off of hyperbolic tangent low-pass Fourier filter")
    parser.add_option("--CTF",
                      action="store_true",
                      default=False,
                      help="Consider CTF correction during the alignment ")
    parser.add_option("--MPI",
                      action="store_true",
                      default=False,
                      help="use MPI version")

    (options, args) = parser.parse_args()

    myid = mpi.mpi_comm_rank(MPI_COMM_WORLD)
    number_of_proc = mpi.mpi_comm_size(MPI_COMM_WORLD)
    main_node = 0

    if len(args) == 2:
        stack = args[0]
        outdir = args[1]
    else:
        sp_global_def.ERROR("Incomplete list of arguments",
                            "sxproj_stability.main",
                            1,
                            myid=myid)
        return
    if not options.MPI:
        sp_global_def.ERROR("Non-MPI not supported!",
                            "sxproj_stability.main",
                            1,
                            myid=myid)
        return

    if sp_global_def.CACHE_DISABLE:
        from sp_utilities import disable_bdb_cache
        disable_bdb_cache()
    sp_global_def.BATCH = True

    img_per_grp = options.img_per_group
    radius = options.radius
    ite = options.iter
    num_ali = options.num_ali
    thld_err = options.thld_err

    xrng = get_input_from_string(options.xr)
    if options.yr == "-1":
        yrng = xrng
    else:
        yrng = get_input_from_string(options.yr)

    step = get_input_from_string(options.ts)

    if myid == main_node:
        nima = EMUtil.get_image_count(stack)
        img = get_image(stack)
        nx = img.get_xsize()
        ny = img.get_ysize()
    else:
        nima = 0
        nx = 0
        ny = 0
    nima = bcast_number_to_all(nima)
    nx = bcast_number_to_all(nx)
    ny = bcast_number_to_all(ny)
    if radius == -1: radius = nx / 2 - 2
    mask = model_circle(radius, nx, nx)

    st = time()
    if options.grouping == "GRP":
        if myid == main_node:
            sxprint("  A  ", myid, "  ", time() - st)
            proj_attr = EMUtil.get_all_attributes(stack, "xform.projection")
            proj_params = []
            for i in range(nima):
                dp = proj_attr[i].get_params("spider")
                phi, theta, psi, s2x, s2y = dp["phi"], dp["theta"], dp[
                    "psi"], -dp["tx"], -dp["ty"]
                proj_params.append([phi, theta, psi, s2x, s2y])

            # Here is where the grouping is done, I didn't put enough annotation in the group_proj_by_phitheta,
            # So I will briefly explain it here
            # proj_list  : Returns a list of list of particle numbers, each list contains img_per_grp particle numbers
            #              except for the last one. Depending on the number of particles left, they will either form a
            #              group or append themselves to the last group
            # angle_list : Also returns a list of list, each list contains three numbers (phi, theta, delta), (phi,
            #              theta) is the projection angle of the center of the group, delta is the range of this group
            # mirror_list: Also returns a list of list, each list contains img_per_grp True or False, which indicates
            #              whether it should take mirror position.
            # In this program angle_list and mirror list are not of interest.

            proj_list_all, angle_list, mirror_list = group_proj_by_phitheta(
                proj_params, img_per_grp=img_per_grp)
            del proj_params
            sxprint("  B  number of groups  ", myid, "  ", len(proj_list_all),
                    time() - st)
        mpi_barrier(MPI_COMM_WORLD)

        # Number of groups, actually there could be one or two more groups, since the size of the remaining group varies
        # we will simply assign them to main node.
        n_grp = nima / img_per_grp - 1

        # Divide proj_list_all equally to all nodes, and becomes proj_list
        proj_list = []
        for i in range(n_grp):
            proc_to_stay = i % number_of_proc
            if proc_to_stay == main_node:
                if myid == main_node: proj_list.append(proj_list_all[i])
            elif myid == main_node:
                mpi_send(len(proj_list_all[i]), 1, MPI_INT, proc_to_stay,
                         SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
                mpi_send(proj_list_all[i], len(proj_list_all[i]), MPI_INT,
                         proc_to_stay, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
            elif myid == proc_to_stay:
                img_per_grp = mpi_recv(1, MPI_INT, main_node,
                                       SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
                img_per_grp = int(img_per_grp[0])
                temp = mpi_recv(img_per_grp, MPI_INT, main_node,
                                SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
                proj_list.append(list(map(int, temp)))
                del temp
            mpi_barrier(MPI_COMM_WORLD)
        sxprint("  C  ", myid, "  ", time() - st)
        if myid == main_node:
            # Assign the remaining groups to main_node
            for i in range(n_grp, len(proj_list_all)):
                proj_list.append(proj_list_all[i])
            del proj_list_all, angle_list, mirror_list

    #   Compute stability per projection projection direction, equal number assigned, thus overlaps
    elif options.grouping == "GEV":

        if options.delta == -1.0:
            ERROR(
                "Angular step for reference projections is required for GEV method"
            )
            return

        from sp_utilities import even_angles, nearestk_to_refdir, getvec
        refproj = even_angles(options.delta)
        img_begin, img_end = MPI_start_end(len(refproj), number_of_proc, myid)
        # Now each processor keeps its own share of reference projections
        refprojdir = refproj[img_begin:img_end]
        del refproj

        ref_ang = [0.0] * (len(refprojdir) * 2)
        for i in range(len(refprojdir)):
            ref_ang[i * 2] = refprojdir[0][0]
            ref_ang[i * 2 + 1] = refprojdir[0][1] + i * 0.1

        sxprint("  A  ", myid, "  ", time() - st)
        proj_attr = EMUtil.get_all_attributes(stack, "xform.projection")
        #  the solution below is very slow, do not use it unless there is a problem with the i/O
        """
		for i in xrange(number_of_proc):
			if myid == i:
				proj_attr = EMUtil.get_all_attributes(stack, "xform.projection")
			mpi_barrier(MPI_COMM_WORLD)
		"""
        sxprint("  B  ", myid, "  ", time() - st)

        proj_ang = [0.0] * (nima * 2)
        for i in range(nima):
            dp = proj_attr[i].get_params("spider")
            proj_ang[i * 2] = dp["phi"]
            proj_ang[i * 2 + 1] = dp["theta"]
        sxprint("  C  ", myid, "  ", time() - st)
        asi = Util.nearestk_to_refdir(proj_ang, ref_ang, img_per_grp)
        del proj_ang, ref_ang
        proj_list = []
        for i in range(len(refprojdir)):
            proj_list.append(asi[i * img_per_grp:(i + 1) * img_per_grp])
        del asi
        sxprint("  D  ", myid, "  ", time() - st)
        #from sys import exit
        #exit()

    #   Compute stability per projection
    elif options.grouping == "PPR":
        sxprint("  A  ", myid, "  ", time() - st)
        proj_attr = EMUtil.get_all_attributes(stack, "xform.projection")
        sxprint("  B  ", myid, "  ", time() - st)
        proj_params = []
        for i in range(nima):
            dp = proj_attr[i].get_params("spider")
            phi, theta, psi, s2x, s2y = dp["phi"], dp["theta"], dp[
                "psi"], -dp["tx"], -dp["ty"]
            proj_params.append([phi, theta, psi, s2x, s2y])
        img_begin, img_end = MPI_start_end(nima, number_of_proc, myid)
        sxprint("  C  ", myid, "  ", time() - st)
        from sp_utilities import nearest_proj
        proj_list, mirror_list = nearest_proj(
            proj_params, img_per_grp,
            list(range(img_begin, img_begin + 1)))  #range(img_begin, img_end))
        refprojdir = proj_params[img_begin:img_end]
        del proj_params, mirror_list
        sxprint("  D  ", myid, "  ", time() - st)

    else:
        ERROR("Incorrect projection grouping option")
        return

    ###########################################################################################################
    # Begin stability test
    from sp_utilities import get_params_proj, read_text_file
    #if myid == 0:
    #	from utilities import read_text_file
    #	proj_list[0] = map(int, read_text_file("lggrpp0.txt"))

    from sp_utilities import model_blank
    aveList = [model_blank(nx, ny)] * len(proj_list)
    if options.grouping == "GRP":
        refprojdir = [[0.0, 0.0, -1.0]] * len(proj_list)
    for i in range(len(proj_list)):
        sxprint("  E  ", myid, "  ", time() - st)
        class_data = EMData.read_images(stack, proj_list[i])
        #print "  R  ",myid,"  ",time()-st
        if options.CTF:
            from sp_filter import filt_ctf
            for im in range(len(class_data)):  #  MEM LEAK!!
                atemp = class_data[im].copy()
                btemp = filt_ctf(atemp, atemp.get_attr("ctf"), binary=1)
                class_data[im] = btemp
                #class_data[im] = filt_ctf(class_data[im], class_data[im].get_attr("ctf"), binary=1)
        for im in class_data:
            try:
                t = im.get_attr(
                    "xform.align2d")  # if they are there, no need to set them!
            except:
                try:
                    t = im.get_attr("xform.projection")
                    d = t.get_params("spider")
                    set_params2D(im, [0.0, -d["tx"], -d["ty"], 0, 1.0])
                except:
                    set_params2D(im, [0.0, 0.0, 0.0, 0, 1.0])
        #print "  F  ",myid,"  ",time()-st
        # Here, we perform realignment num_ali times
        all_ali_params = []
        for j in range(num_ali):
            if (xrng[0] == 0.0 and yrng[0] == 0.0):
                avet = ali2d_ras(class_data,
                                 randomize=True,
                                 ir=1,
                                 ou=radius,
                                 rs=1,
                                 step=1.0,
                                 dst=90.0,
                                 maxit=ite,
                                 check_mirror=True,
                                 FH=options.fl,
                                 FF=options.aa)
            else:
                avet = within_group_refinement(class_data, mask, True, 1,
                                               radius, 1, xrng, yrng, step,
                                               90.0, ite, options.fl,
                                               options.aa)
            ali_params = []
            for im in range(len(class_data)):
                alpha, sx, sy, mirror, scale = get_params2D(class_data[im])
                ali_params.extend([alpha, sx, sy, mirror])
            all_ali_params.append(ali_params)
        #aveList[i] = avet
        #print "  G  ",myid,"  ",time()-st
        del ali_params
        # We determine the stability of this group here.
        # stable_set contains all particles deemed stable, it is a list of list
        # each list has two elements, the first is the pixel error, the second is the image number
        # stable_set is sorted based on pixel error
        #from utilities import write_text_file
        #write_text_file(all_ali_params, "all_ali_params%03d.txt"%myid)
        stable_set, mir_stab_rate, average_pix_err = multi_align_stability(
            all_ali_params, 0.0, 10000.0, thld_err, False, 2 * radius + 1)
        #print "  H  ",myid,"  ",time()-st
        if (len(stable_set) > 5):
            stable_set_id = []
            members = []
            pix_err = []
            # First put the stable members into attr 'members' and 'pix_err'
            for s in stable_set:
                # s[1] - number in this subset
                stable_set_id.append(s[1])
                # the original image number
                members.append(proj_list[i][s[1]])
                pix_err.append(s[0])
            # Then put the unstable members into attr 'members' and 'pix_err'
            from sp_fundamentals import rot_shift2D
            avet.to_zero()
            if options.grouping == "GRP":
                aphi = 0.0
                atht = 0.0
                vphi = 0.0
                vtht = 0.0
            l = -1
            for j in range(len(proj_list[i])):
                #  Here it will only work if stable_set_id is sorted in the increasing number, see how l progresses
                if j in stable_set_id:
                    l += 1
                    avet += rot_shift2D(class_data[j], stable_set[l][2][0],
                                        stable_set[l][2][1],
                                        stable_set[l][2][2],
                                        stable_set[l][2][3])
                    if options.grouping == "GRP":
                        phi, theta, psi, sxs, sy_s = get_params_proj(
                            class_data[j])
                        if (theta > 90.0):
                            phi = (phi + 540.0) % 360.0
                            theta = 180.0 - theta
                        aphi += phi
                        atht += theta
                        vphi += phi * phi
                        vtht += theta * theta
                else:
                    members.append(proj_list[i][j])
                    pix_err.append(99999.99)
            aveList[i] = avet.copy()
            if l > 1:
                l += 1
                aveList[i] /= l
                if options.grouping == "GRP":
                    aphi /= l
                    atht /= l
                    vphi = (vphi - l * aphi * aphi) / l
                    vtht = (vtht - l * atht * atht) / l
                    from math import sqrt
                    refprojdir[i] = [
                        aphi, atht,
                        (sqrt(max(vphi, 0.0)) + sqrt(max(vtht, 0.0))) / 2.0
                    ]

            # Here more information has to be stored, PARTICULARLY WHAT IS THE REFERENCE DIRECTION
            aveList[i].set_attr('members', members)
            aveList[i].set_attr('refprojdir', refprojdir[i])
            aveList[i].set_attr('pixerr', pix_err)
        else:
            sxprint(" empty group ", i, refprojdir[i])
            aveList[i].set_attr('members', [-1])
            aveList[i].set_attr('refprojdir', refprojdir[i])
            aveList[i].set_attr('pixerr', [99999.])

    del class_data

    if myid == main_node:
        km = 0
        for i in range(number_of_proc):
            if i == main_node:
                for im in range(len(aveList)):
                    aveList[im].write_image(args[1], km)
                    km += 1
            else:
                nl = mpi_recv(1, MPI_INT, i, SPARX_MPI_TAG_UNIVERSAL,
                              MPI_COMM_WORLD)
                nl = int(nl[0])
                for im in range(nl):
                    ave = recv_EMData(i, im + i + 70000)
                    nm = mpi_recv(1, MPI_INT, i, SPARX_MPI_TAG_UNIVERSAL,
                                  MPI_COMM_WORLD)
                    nm = int(nm[0])
                    members = mpi_recv(nm, MPI_INT, i, SPARX_MPI_TAG_UNIVERSAL,
                                       MPI_COMM_WORLD)
                    ave.set_attr('members', list(map(int, members)))
                    members = mpi_recv(nm, MPI_FLOAT, i,
                                       SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
                    ave.set_attr('pixerr', list(map(float, members)))
                    members = mpi_recv(3, MPI_FLOAT, i,
                                       SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
                    ave.set_attr('refprojdir', list(map(float, members)))
                    ave.write_image(args[1], km)
                    km += 1
    else:
        mpi_send(len(aveList), 1, MPI_INT, main_node, SPARX_MPI_TAG_UNIVERSAL,
                 MPI_COMM_WORLD)
        for im in range(len(aveList)):
            send_EMData(aveList[im], main_node, im + myid + 70000)
            members = aveList[im].get_attr('members')
            mpi_send(len(members), 1, MPI_INT, main_node,
                     SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
            mpi_send(members, len(members), MPI_INT, main_node,
                     SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
            members = aveList[im].get_attr('pixerr')
            mpi_send(members, len(members), MPI_FLOAT, main_node,
                     SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
            try:
                members = aveList[im].get_attr('refprojdir')
                mpi_send(members, 3, MPI_FLOAT, main_node,
                         SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
            except:
                mpi_send([-999.0, -999.0, -999.0], 3, MPI_FLOAT, main_node,
                         SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)

    sp_global_def.BATCH = False
    mpi_barrier(MPI_COMM_WORLD)
Beispiel #26
0
def main(args):

    progname = optparse.os.path.basename(sys.argv[0])
    usage = (
        progname +
        " stack  [output_directory] --ir=inner_radius --rs=ring_step --xr=x_range --yr=y_range  --ts=translational_search_step  --delta=angular_step --center=center_type --maxit1=max_iter1 --maxit2=max_iter2 --L2threshold=0.1 --ref_a=S --sym=c1"
    )
    usage += """

stack			2D images in a stack file: (default required string)
directory		output directory name: into which the results will be written (if it does not exist, it will be created, if it does exist, the results will be written possibly overwriting previous results) (default required string)
"""

    parser = optparse.OptionParser(usage, version=sp_global_def.SPARXVERSION)
    parser.add_option(
        "--radius",
        type="int",
        default=29,
        help=
        "radius of the particle: has to be less than < int(nx/2)-1 (default 29)",
    )

    parser.add_option(
        "--xr",
        type="string",
        default="0",
        help=
        "range for translation search in x direction: search is +/xr in pixels (default '0')",
    )
    parser.add_option(
        "--yr",
        type="string",
        default="0",
        help=
        "range for translation search in y direction: if omitted will be set to xr, search is +/yr in pixels (default '0')",
    )
    parser.add_option("--mask3D",
                      type="string",
                      default=None,
                      help="3D mask file: (default sphere)")
    parser.add_option(
        "--moon_elimination",
        type="string",
        default="",
        help=
        "elimination of disconnected pieces: two arguments: mass in KDa and pixel size in px/A separated by comma, no space (default none)",
    )
    parser.add_option(
        "--ir",
        type="int",
        default=1,
        help="inner radius for rotational search: > 0 (default 1)",
    )

    # 'radius' and 'ou' are the same as per Pawel's request; 'ou' is hidden from the user
    # the 'ou' variable is not changed to 'radius' in the 'sparx' program. This change is at interface level only for sxviper.
    ##### XXXXXXXXXXXXXXXXXXXXXX option does not exist in docs XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    parser.add_option("--ou",
                      type="int",
                      default=-1,
                      help=optparse.SUPPRESS_HELP)
    parser.add_option(
        "--rs",
        type="int",
        default=1,
        help="step between rings in rotational search: >0 (default 1)",
    )
    parser.add_option(
        "--ts",
        type="string",
        default="1.0",
        help=
        "step size of the translation search in x-y directions: search is -xr, -xr+ts, 0, xr-ts, xr, can be fractional (default '1.0')",
    )
    parser.add_option(
        "--delta",
        type="string",
        default="2.0",
        help="angular step of reference projections: (default '2.0')",
    )
    parser.add_option(
        "--center",
        type="float",
        default=-1.0,
        help=
        "centering of 3D template: average shift method; 0: no centering; 1: center of gravity (default -1.0)",
    )
    parser.add_option(
        "--maxit1",
        type="int",
        default=400,
        help=
        "maximum number of iterations performed for the GA part: (default 400)",
    )
    parser.add_option(
        "--maxit2",
        type="int",
        default=50,
        help=
        "maximum number of iterations performed for the finishing up part: (default 50)",
    )
    parser.add_option(
        "--L2threshold",
        type="float",
        default=0.03,
        help=
        "stopping criterion of GA: given as a maximum relative dispersion of volumes' L2 norms: (default 0.03)",
    )
    parser.add_option(
        "--ref_a",
        type="string",
        default="S",
        help=
        "method for generating the quasi-uniformly distributed projection directions: (default S)",
    )
    parser.add_option(
        "--sym",
        type="string",
        default="c1",
        help="point-group symmetry of the structure: (default c1)",
    )

    # parser.add_option("--function", type="string", default="ref_ali3d",         help="name of the reference preparation function (ref_ali3d by default)")
    ##### XXXXXXXXXXXXXXXXXXXXXX option does not exist in docs XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    parser.add_option("--function",
                      type="string",
                      default="ref_ali3d",
                      help=optparse.SUPPRESS_HELP)

    parser.add_option(
        "--nruns",
        type="int",
        default=6,
        help=
        "GA population: aka number of quasi-independent volumes (default 6)",
    )
    parser.add_option(
        "--doga",
        type="float",
        default=0.1,
        help=
        "do GA when fraction of orientation changes less than 1.0 degrees is at least doga: (default 0.1)",
    )
    ##### XXXXXXXXXXXXXXXXXXXXXX option does not exist in docs XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    parser.add_option(
        "--npad",
        type="int",
        default=2,
        help="padding size for 3D reconstruction (default=2)",
    )
    parser.add_option(
        "--fl",
        type="float",
        default=0.25,
        help=
        "cut-off frequency applied to the template volume: using a hyperbolic tangent low-pass filter (default 0.25)",
    )
    parser.add_option(
        "--aa",
        type="float",
        default=0.1,
        help="fall-off of hyperbolic tangent low-pass filter: (default 0.1)",
    )
    parser.add_option(
        "--pwreference",
        type="string",
        default="",
        help="text file with a reference power spectrum: (default none)",
    )
    parser.add_option(
        "--debug",
        action="store_true",
        default=False,
        help="debug info printout: (default False)",
    )

    ##### XXXXXXXXXXXXXXXXXXXXXX option does not exist in docs XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    parser.add_option(
        "--return_options",
        action="store_true",
        dest="return_options",
        default=False,
        help=optparse.SUPPRESS_HELP,
    )

    # parser.add_option("--an",       type="string", default= "-1",               help="NOT USED angular neighborhood for local searches (phi and theta)")
    # parser.add_option("--CTF",      action="store_true", default=False,         help="NOT USED Consider CTF correction during the alignment ")
    # parser.add_option("--snr",      type="float",  default= 1.0,                help="NOT USED Signal-to-Noise Ratio of the data (default 1.0)")
    # (options, args) = parser.parse_args(sys.argv[1:])

    required_option_list = ["radius"]
    (options, args) = parser.parse_args(args)
    # option_dict = vars(options)
    # print parser

    if options.return_options:
        return parser

    if options.moon_elimination == "":
        options.moon_elimination = []
    else:
        options.moon_elimination = list(
            map(float, options.moon_elimination.split(",")))

    # Making sure all required options appeared.
    for required_option in required_option_list:
        if not options.__dict__[required_option]:
            sp_global_def.sxprint("\n ==%s== mandatory option is missing.\n" %
                                  required_option)
            sp_global_def.sxprint("Please run '" + progname +
                                  " -h' for detailed options")
            sp_global_def.ERROR("Missing parameter. Please see above")
            return

    if len(args) < 2 or len(args) > 3:
        sp_global_def.sxprint("Usage: " + usage)
        sp_global_def.sxprint("Please run '" + progname +
                              " -h' for detailed options")
        sp_global_def.ERROR(
            "Invalid number of parameters used. Please see usage information above."
        )
        return

    log = sp_logger.Logger(sp_logger.BaseLogger_Files())

    # 'radius' and 'ou' are the same as per Pawel's request; 'ou' is hidden from the user
    # the 'ou' variable is not changed to 'radius' in the 'sparx' program. This change is at interface level only for sxviper.
    options.ou = options.radius
    runs_count = options.nruns
    mpi_rank = mpi.mpi_comm_rank(mpi.MPI_COMM_WORLD)
    mpi_size = mpi.mpi_comm_size(
        mpi.MPI_COMM_WORLD
    )  # Total number of processes, passed by --np option.

    if mpi_rank == 0:
        all_projs = EMAN2_cppwrap.EMData.read_images(args[0])
        subset = list(range(len(all_projs)))
        # if mpi_size > len(all_projs):
        # 	ERROR('Number of processes supplied by --np needs to be less than or equal to %d (total number of images) ' % len(all_projs), 'sxviper', 1)
        # 	mpi.mpi_finalize()
        # 	return
    else:
        all_projs = None
        subset = None

    outdir = args[1]
    error = 0
    if mpi_rank == 0:
        if mpi_size % options.nruns != 0:
            sp_global_def.ERROR(
                "Number of processes needs to be a multiple of total number of runs. Total runs by default are 3, you can change it by specifying --nruns option.",
                action=0,
            )
            error = 1

        if optparse.os.path.exists(outdir):
            sp_global_def.ERROR(
                "Output directory '%s' exists, please change the name and restart the program"
                % outdir,
                action=0,
            )
            error = 1
        sp_global_def.LOGFILE = optparse.os.path.join(outdir,
                                                      sp_global_def.LOGFILE)

    mpi.mpi_barrier(mpi.MPI_COMM_WORLD)
    error = sp_utilities.bcast_number_to_all(error,
                                             source_node=0,
                                             mpi_comm=mpi.MPI_COMM_WORLD)
    if error == 1:
        return

    if mpi_rank == 0:
        optparse.os.makedirs(outdir)
        sp_global_def.write_command(outdir)

    if outdir[-1] != "/":
        outdir += "/"
    log.prefix = outdir

    # if len(args) > 2:
    # 	ref_vol = get_im(args[2])
    # else:
    # ref_vol = None

    options.user_func = sp_user_functions.factory[options.function]

    options.CTF = False
    options.snr = 1.0
    options.an = -1.0
    out_params, out_vol, out_peaks = sp_multi_shc.multi_shc(
        all_projs,
        subset,
        runs_count,
        options,
        mpi_comm=mpi.MPI_COMM_WORLD,
        log=log)
Beispiel #27
0
def main():
    arglist = []
    for arg in sys.argv:
        arglist.append(arg)
    progname = optparse.os.path.basename(arglist[0])
    usage = progname + """ inputvolume  locresvolume maskfile outputfile   --radius --falloff  --MPI

	    Locally filer a volume based on local resolution volume (sxlocres.py) within area outlined by the maskfile
	"""
    parser = optparse.OptionParser(usage, version=sp_global_def.SPARXVERSION)

    parser.add_option(
        "--radius",
        type="int",
        default=-1,
        help=
        "if there is no maskfile, sphere with r=radius will be used, by default the radius is nx/2-1"
    )
    parser.add_option("--falloff",
                      type="float",
                      default=0.1,
                      help="falloff of tanl filter (default 0.1)")
    parser.add_option("--MPI",
                      action="store_true",
                      default=False,
                      help="use MPI version")

    (options, args) = parser.parse_args(arglist[1:])

    if len(args) < 3 or len(args) > 4:
        sp_global_def.sxprint("See usage " + usage)
        sp_global_def.ERROR(
            "Wrong number of parameters. Please see usage information above.")
        return

    if sp_global_def.CACHE_DISABLE:
        pass  #IMPORTIMPORTIMPORT from sp_utilities import disable_bdb_cache
        sp_utilities.disable_bdb_cache()

    if options.MPI:
        number_of_proc = mpi.mpi_comm_size(mpi.MPI_COMM_WORLD)
        myid = mpi.mpi_comm_rank(mpi.MPI_COMM_WORLD)
        main_node = 0

        if (myid == main_node):
            #print sys.argv
            vi = sp_utilities.get_im(sys.argv[1])
            ui = sp_utilities.get_im(sys.argv[2])
            #print   Util.infomask(ui, None, True)
            radius = options.radius
            nx = vi.get_xsize()
            ny = vi.get_ysize()
            nz = vi.get_zsize()
            dis = [nx, ny, nz]
        else:
            falloff = 0.0
            radius = 0
            dis = [0, 0, 0]
            vi = None
            ui = None
        dis = sp_utilities.bcast_list_to_all(dis, myid, source_node=main_node)

        if (myid != main_node):
            nx = int(dis[0])
            ny = int(dis[1])
            nz = int(dis[2])
        radius = sp_utilities.bcast_number_to_all(radius, main_node)
        if len(args) == 3:
            if (radius == -1):
                radius = min(nx, ny, nz) // 2 - 1
            m = sp_utilities.model_circle(radius, nx, ny, nz)
            outvol = args[2]

        elif len(args) == 4:
            if (myid == main_node):
                m = sp_morphology.binarize(sp_utilities.get_im(args[2]), 0.5)
            else:
                m = sp_utilities.model_blank(nx, ny, nz)
            outvol = args[3]
            sp_utilities.bcast_EMData_to_all(m, myid, main_node)

        pass  #IMPORTIMPORTIMPORT from sp_filter import filterlocal
        filteredvol = sp_filter.filterlocal(ui, vi, m, options.falloff, myid,
                                            main_node, number_of_proc)

        if (myid == 0):
            filteredvol.write_image(outvol)

    else:
        vi = sp_utilities.get_im(args[0])
        ui = sp_utilities.get_im(
            args[1]
        )  # resolution volume, values are assumed to be from 0 to 0.5

        nn = vi.get_xsize()

        falloff = options.falloff

        if len(args) == 3:
            radius = options.radius
            if (radius == -1):
                radius = nn // 2 - 1
            m = sp_utilities.model_circle(radius, nn, nn, nn)
            outvol = args[2]

        elif len(args) == 4:
            m = sp_morphology.binarize(sp_utilities.get_im(args[2]), 0.5)
            outvol = args[3]

        sp_fundamentals.fftip(vi)  # this is the volume to be filtered

        #  Round all resolution numbers to two digits
        for x in range(nn):
            for y in range(nn):
                for z in range(nn):
                    ui.set_value_at_fast(x, y, z,
                                         round(ui.get_value_at(x, y, z), 2))
        st = EMAN2_cppwrap.Util.infomask(ui, m, True)

        filteredvol = sp_utilities.model_blank(nn, nn, nn)
        cutoff = max(st[2] - 0.01, 0.0)
        while (cutoff < st[3]):
            cutoff = round(cutoff + 0.01, 2)
            pt = EMAN2_cppwrap.Util.infomask(
                sp_morphology.threshold_outside(ui, cutoff - 0.00501,
                                                cutoff + 0.005), m, True)
            if (pt[0] != 0.0):
                vovo = sp_fundamentals.fft(
                    sp_filter.filt_tanl(vi, cutoff, falloff))
                for x in range(nn):
                    for y in range(nn):
                        for z in range(nn):
                            if (m.get_value_at(x, y, z) > 0.5):
                                if (round(ui.get_value_at(x, y, z),
                                          2) == cutoff):
                                    filteredvol.set_value_at_fast(
                                        x, y, z, vovo.get_value_at(x, y, z))

        sp_global_def.write_command(optparse.os.path.dirname(outvol))
        filteredvol.write_image(outvol)
Beispiel #28
0
def sanity_checks(args):
    """
	Check if the settings are valid.

	Arguments:
	args - Command line arguments parsed via argparse

	Returns:
	Output file name
	"""
    file_exists_check = [
        args.particle_stack,
        args.partres_file,
        args.params_2d_file,
        args.params_3d_file,
        args.params_3d_index_file,
        args.list,
        args.exlist,
    ]
    stack_dependency_check = [
        args.params_2d_file,
        args.params_3d_file,
        args.params_3d_index_file,
        args.list,
        args.exlist,
    ]

    if not args.particle_stack and not args.partres_file:
        sp_global_def.ERROR(
            "Particle_stack or partres_file option needs to be present!",
            "sp_sphire2relion",
            1,
        )

    for option in stack_dependency_check:
        if option and not args.particle_stack:
            sp_global_def.ERROR(
                "{0} requires particle stack option!".format(option),
                "sp_sphire2relion",
                1,
            )

    for option in file_exists_check:
        if option:
            if option.startswith("bdb:"):
                if "#" in option:
                    raw_dirnames, basename = option.split("#")
                    dirnames = raw_dirnames[4:]
                else:
                    dirnames = os.path.dirname(option[4:])
                    if not dirnames:
                        dirnames = "."
                    basename = os.path.basename(option[4:])
                option = "{0}/EMAN2DB/{1}.bdb".format(dirnames, basename)
            if not os.path.isfile(option):
                sp_global_def.ERROR("{0} stack must exist!".format(option),
                                    "sp_sphire2relion", 1)

    if args.list and args.exlist:
        sp_global_def.ERROR(
            "Arguments list and exlist cannot be used at the same time.",
            "sp_sphire2relion",
            1,
        )

    if args.params_2d_file and args.params_3d_file:
        sp_global_def.ERROR(
            "Arguments params_2d_file and params_3d_file cannot be used at the same time.",
            "sp_sphire2relion",
            1,
        )

    if args.params_3d_index_file and not args.params_3d_file:
        sp_global_def.ERROR(
            "Arguments params_3d_index_file requires params_3d_file to be set.",
            "sp_sphire2relion",
            1,
        )

    if args.params_3d_chunk_file_0 and not args.params_3d_file:
        sp_global_def.ERROR(
            "Arguments params_3d_chunk_files requires params_3d_file to be set.",
            "sp_sphire2relion",
            1,
        )

    if args.params_3d_chunk_file_1 and not args.params_3d_file:
        sp_global_def.ERROR(
            "Arguments params_3d_chunk_files requires params_3d_file to be set.",
            "sp_sphire2relion",
            1,
        )

    try:
        os.makedirs(args.output_directory)
    except OSError:
        pass
    sp_global_def.write_command(args.output_directory)

    output_path = os.path.join(args.output_directory, args.output_name)
    if os.path.exists(output_path) and args.force:
        pass
    elif os.path.exists(output_path) and not args.force:
        sp_global_def.ERROR(
            "Output file {0} must not exist! Use the --force flag to overwrite existing files"
            .format(output_path),
            "sp_sphire2relion",
            1,
        )
    else:
        pass

    return output_path
Beispiel #29
0
def import_partres_file(partres_file):
    """
	Import the information from a SPHIRE partres file.

	Arguments:
	partres_file - Partres file name

	Returns:
	Array containing the ctf information.
	"""
    with open(partres_file, "r") as partres_reader:
        number_of_columns = len(partres_reader.readline().split())

    if number_of_columns == 22:
        columns = [0, 1, 2, 3, 6, 7, 17, 19, 20, 21]
        dtype_import_list = [
            ("defocus", float),
            ("cs", float),
            ("voltage", float),
            ("pixel_size", float),
            ("astig_amp", float),
            ("astig_angle", float),
            ("max_resolution", float),
            ("amplitude_contrast", float),
            ("phase_shift", float),
            ("micrograph_name", "|S1000"),
        ]
        dtype_output_list = [
            ("_rlnDefocusU", float),
            ("_rlnDefocusV", float),
            ("_rlnDefocusAngle", float),
            ("_rlnMicrographName", "|S1000"),
            ("_rlnDetectorPixelSize", float),
            ("_rlnMagnification", float),
            ("_rlnCtfMaxResolution", float),
            ("_rlnPhaseShift", float),
            ("_rlnAmplitudeContrast", float),
            ("_rlnSphericalAberration", float),
            ("_rlnVoltage", float),
        ]
    else:
        sp_global_def.ERROR(
            "Number of columns in partres file not known: {0}".format(
                number_of_columns),
            "sp_sphire2relion",
        )

    assert len(columns) == len(dtype_import_list)
    partres_import_array = np.genfromtxt(partres_file,
                                         dtype=dtype_import_list,
                                         usecols=columns)
    partres_array = np.empty(partres_import_array.shape[0],
                             sorted(dtype_output_list))

    partres_array["_rlnDefocusU"] = (
        20000 * partres_import_array["defocus"] -
        10000 * partres_import_array["astig_amp"]) / 2
    partres_array["_rlnDefocusV"] = (20000 * partres_import_array["defocus"] -
                                     partres_array["_rlnDefocusU"])
    partres_array[
        "_rlnDefocusAngle"] = 45 - partres_import_array["astig_angle"]
    partres_array["_rlnMicrographName"] = partres_import_array[
        "micrograph_name"]
    partres_array["_rlnAmplitudeContrast"] = (
        partres_import_array["amplitude_contrast"] / 100)
    partres_array["_rlnVoltage"] = partres_import_array["voltage"]
    partres_array["_rlnSphericalAberration"] = partres_import_array["cs"]
    partres_array["_rlnPhaseShift"] = partres_import_array["phase_shift"]
    partres_array["_rlnDetectorPixelSize"] = partres_import_array["pixel_size"]
    partres_array["_rlnMagnification"] = 10000
    partres_array[
        "_rlnCtfMaxResolution"] = 1 / partres_import_array["max_resolution"]

    return partres_array
Beispiel #30
0
    # If output directory not specified, write to same directory as class averages
    if not options.outdir:
        outdir = os.path.dirname(os.path.realpath(options.classavgs))
    else:
        outdir = options.outdir

    if options.mode == 'viper':
        selectdoc = options.classselect
    elif options.mode == 'projmatch':
        selectdoc = None
    elif options.mode == 'meridien':
        selectdoc = options.partselect
    else:
        sp_global_def.ERROR(
            "\nERROR!! Valid mode not specified. Valid modes are: viper, projmatch, and meridien.",
            __file__, 1)
        sxprint('Type %s --help to see available options\n' %
                os.path.basename(__file__))
        exit()

    main_proj_compare(options.classavgs,
                      options.vol3d,
                      outdir,
                      options,
                      mode=options.mode,
                      prjmethod=options.prjmethod,
                      classangles=options.classangles,
                      partangles=options.partangles,
                      selectdoc=selectdoc,
                      verbose=options.verbose,