Пример #1
0
def prepref(data, maskfile, cnx, cny, numr, mode, maxrangex, maxrangey, step):
    # step = 1
    mashi = cnx - numr[-3] - 2
    nima = len(data)
    istep = int(old_div(1.0, step))
    dimage = [[[None for j in range(2 * maxrangey * istep + 1)]
               for i in range(2 * maxrangex * istep + 1)]
              for im in range(nima)]
    for im in range(nima):
        sts = EMAN2_cppwrap.Util.infomask(data[im], maskfile, False)
        data[im] -= sts[0]
        data[im] = old_div(data[im], sts[1])
        alpha, sx, sy, mirror, dummy = sp_utilities.get_params2D(data[im])
        # alpha, sx, sy, dummy         = combine_params2(alpha, sx, sy, mirror, 0.0, -cs[0], -cs[1], 0)
        alphai, sxi, syi, dummy = sp_utilities.combine_params2(
            0.0, sx, sy, 0, -alpha, 0, 0, 0)
        #  introduce constraints on parameters to accomodate use of cs centering
        sxi = min(max(sxi, -mashi), mashi)
        syi = min(max(syi, -mashi), mashi)
        for j in range(-maxrangey * istep, maxrangey * istep + 1):
            iy = j * step
            for i in range(-maxrangex * istep, maxrangex * istep + 1):
                ix = i * step
                dimage[im][i +
                           maxrangex][j +
                                      maxrangey] = EMAN2_cppwrap.Util.Polar2Dm(
                                          data[im], cnx + sxi + ix,
                                          cny + syi + iy, numr, mode)
                # print ' prepref  ',j,i,j+maxrangey,i+maxrangex
                EMAN2_cppwrap.Util.Frngs(
                    dimage[im][i + maxrangex][j + maxrangey], numr)
        dimage[im][0][0].set_attr("sxi", sxi)
        dimage[im][0][0].set_attr("syi", syi)

    return dimage
Пример #2
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)
Пример #3
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = progname + """ Input Output [options]
	
	Generate three micrographs, each micrograph contains one projection of a long filament.
	Input: Reference Volume, output directory 
	Output: Three micrographs stored in output directory		
				 
		sxhelical_demo.py tmp.hdf  mic --generate_micrograph --CTF --apix=1.84	
	
	Generate noisy cylinder ini.hdf with radius 35 pixels and box size 100 by 100 by 200
	
		sxhelical_demo.py ini.hdf --generate_noisycyl --boxsize="100,100,200" --rad=35
	
	Generate rectangular 2D mask mask2d.hdf with width 60 pixels and image size 200 by 200 pixels
	
		sxhelical_demo.py mask2d.hdf --generate_mask --masksize="200,200" --maskwidth=60
	
	Apply the centering parameters to bdb:adata, normalize using average and standard deviation outside the mask, and output the new images to bdb:data
		
		sxhelical_demo.py bdb:adata bdb:data mask2d.hdf --applyparams
	
	Generate run through example script for helicon
	
		sxhelical_demo.py --generate_script --filename=run --seg_ny=180 --ptcl_dist=15 --fract=0.35
	"""
    parser = OptionParser(usage, version=SPARXVERSION)

    # helicise the Atom coordinates

    # generate micrographs of helical filament
    parser.add_option(
        "--generate_micrograph",
        action="store_true",
        default=False,
        help=
        "Generate three micrographs where each micrograph contains one projection of a long filament. \n Input: Reference Volume, output directory \n Output: Three micrographs containing helical filament projections stored in output directory"
    )
    parser.add_option("--CTF",
                      action="store_true",
                      default=False,
                      help="Use CTF correction")
    parser.add_option("--apix",
                      type="float",
                      default=-1,
                      help="pixel size in Angstroms")
    parser.add_option(
        "--rand_seed",
        type="int",
        default=14567,
        help=
        "the seed used for generating random numbers (default 14567) for adding noise to the generated micrographs."
    )
    parser.add_option("--Cs",
                      type="float",
                      default=2.0,
                      help="Microscope Cs (spherical aberation)")
    parser.add_option("--voltage",
                      type="float",
                      default=200.0,
                      help="Microscope voltage in KV")
    parser.add_option("--ac",
                      type="float",
                      default=10.0,
                      help="Amplitude contrast (percentage, default=10)")
    parser.add_option("--nonoise",
                      action="store_true",
                      default=False,
                      help="Do not add noise to the micrograph.")

    # generate initial volume
    parser.add_option("--generate_noisycyl",
                      action="store_true",
                      default=False,
                      help="Generate initial volume of noisy cylinder.")
    parser.add_option(
        "--boxsize",
        type="string",
        default="100,100,200",
        help=
        "String containing x , y, z dimensions (separated by comma) in pixels")
    parser.add_option("--rad",
                      type="int",
                      default=35,
                      help="Radius of initial volume in pixels")

    # generate 2D mask
    parser.add_option("--generate_mask",
                      action="store_true",
                      default=False,
                      help="Generate 2D rectangular mask.")
    parser.add_option(
        "--masksize",
        type="string",
        default="200,200",
        help=
        "String containing x and y dimensions (separated by comma) in pixels")
    parser.add_option("--maskwidth",
                      type="int",
                      default=60,
                      help="Width of rectangular mask")

    # Apply 2D alignment parameters to input stack and output new images to output stack
    parser.add_option(
        "--applyparams",
        action="store_true",
        default=False,
        help=
        "Apply the centering parameters to input stack, normalize using average and standard deviation outside the mask, and output the new images to output stack"
    )

    # Generate run script
    parser.add_option("--generate_script",
                      action="store_true",
                      default=False,
                      help="Generate script for helicon run through example")
    parser.add_option("--filename",
                      type="string",
                      default="runhelicon",
                      help="Name of run script to generate")
    parser.add_option("--seg_ny",
                      type="int",
                      default=180,
                      help="y-dimension of segment used for refinement")
    parser.add_option(
        "--ptcl_dist",
        type="int",
        default=15,
        help=
        "Distance in pixels between adjacent segments windowed from same filament"
    )
    parser.add_option(
        "--fract",
        type="float",
        default=0.35,
        help="Fraction of the volume used for applying helical symmetry.")

    (options, args) = parser.parse_args()
    if len(args) > 3:
        sxprint("usage: " + usage)
        sxprint("Please run '" + progname + " -h' for detailed options")
        ERROR(
            "Invalid number of parameters. Please see usage information above."
        )
        return

    else:
        if options.generate_script:
            generate_runscript(options.filename, options.seg_ny,
                               options.ptcl_dist, options.fract)

        if options.generate_micrograph:
            if options.apix <= 0:
                ERROR("Please enter pixel size.")
                return

            generate_helimic(args[0], args[1], options.apix, options.CTF,
                             options.Cs, options.voltage, options.ac,
                             options.nonoise, options.rand_seed)

        if options.generate_noisycyl:

            from sp_utilities import model_cylinder, model_gauss_noise
            outvol = args[0]
            boxdims = options.boxsize.split(',')

            if len(boxdims) < 1 or len(boxdims) > 3:
                ERROR(
                    "Enter box size as string containing x , y, z dimensions (separated by comma) in pixels. E.g.: --boxsize=\'100,100,200\'"
                )
                return

            nx = int(boxdims[0])

            if len(boxdims) == 1:
                ny = nx
                nz = nx
            else:
                ny = int(boxdims[1])
                if len(boxdims) == 3:
                    nz = int(boxdims[2])

            (model_cylinder(options.rad, nx, ny, nz) *
             model_gauss_noise(1.0, nx, ny, nz)).write_image(outvol)

        if options.generate_mask:
            from sp_utilities import model_blank, pad
            outvol = args[0]
            maskdims = options.masksize.split(',')

            if len(maskdims) < 1 or len(maskdims) > 2:
                ERROR(
                    "Enter box size as string containing x , y dimensions (separated by comma) in pixels. E.g.: --boxsize=\'200,200\'"
                )
                return

            nx = int(maskdims[0])

            if len(maskdims) == 1:
                ny = nx
            else:
                ny = int(maskdims[1])

            mask = pad(model_blank(options.maskwidth, ny, 1, 1.0), nx, ny, 1,
                       0.0)
            mask.write_image(outvol)

        if options.applyparams:
            from sp_utilities import get_im, get_params2D, set_params2D
            from sp_fundamentals import cyclic_shift
            stack = args[0]
            newstack = args[1]
            mask = get_im(args[2])
            nima = EMUtil.get_image_count(stack)
            for im in range(nima):
                prj = get_im(stack, im)
                alpha, sx, sy, mirror, scale = get_params2D(prj)
                prj = cyclic_shift(prj, int(sx))
                set_params2D(prj, [0.0, 0., 0.0, 0, 1])
                stat = Util.infomask(prj, mask, False)
                prj = (prj - stat[0]) / stat[1]
                ctf_params = prj.get_attr("ctf")
                prj.set_attr('ctf_applied', 0)
                prj.write_image(newstack, im)
Пример #4
0
def ali2d_single_iter(
    data,
    numr,
    wr,
    cs,
    tavg,
    cnx,
    cny,
    xrng,
    yrng,
    step,
    nomirror=False,
    mode="F",
    CTF=False,
    random_method="",
    T=1.0,
    ali_params="xform.align2d",
    delta=0.0,
):
    """
		single iteration of 2D alignment using ormq
		if CTF = True, apply CTF to data (not to reference!)
	"""

    maxrin = numr[-1]  #  length
    ou = numr[-3]  #  maximum radius
    if random_method == "SCF":
        frotim = [sp_fundamentals.fft(tavg)]
        xrng = int(xrng + 0.5)
        yrng = int(yrng + 0.5)
        cimage = EMAN2_cppwrap.Util.Polar2Dm(sp_fundamentals.scf(tavg), cnx,
                                             cny, numr, mode)
        EMAN2_cppwrap.Util.Frngs(cimage, numr)
        EMAN2_cppwrap.Util.Applyws(cimage, numr, wr)
    else:
        # 2D alignment using rotational ccf in polar coords and quadratic interpolation
        cimage = EMAN2_cppwrap.Util.Polar2Dm(tavg, cnx, cny, numr, mode)
        EMAN2_cppwrap.Util.Frngs(cimage, numr)
        EMAN2_cppwrap.Util.Applyws(cimage, numr, wr)

    sx_sum = 0.0
    sy_sum = 0.0
    sxn = 0.0
    syn = 0.0
    mn = 0
    nope = 0
    mashi = cnx - ou - 2
    for im in range(len(data)):
        if CTF:
            # Apply CTF to image
            ctf_params = data[im].get_attr("ctf")
            ima = sp_filter.filt_ctf(data[im], ctf_params, True)
        else:
            ima = data[im]

        if random_method == "PCP":
            sxi = data[im][0][0].get_attr("sxi")
            syi = data[im][0][0].get_attr("syi")
            nx = ny = data[im][0][0].get_attr("inx")
        else:
            nx = ima.get_xsize()
            ny = ima.get_ysize()
            alpha, sx, sy, mirror, dummy = sp_utilities.get_params2D(
                data[im], ali_params)
            alpha, sx, sy, dummy = sp_utilities.combine_params2(
                alpha, sx, sy, mirror, 0.0, -cs[0], -cs[1], 0)
            alphai, sxi, syi, scalei = sp_utilities.inverse_transform2(
                alpha, sx, sy)
            #  introduce constraints on parameters to accomodate use of cs centering
            sxi = min(max(sxi, -mashi), mashi)
            syi = min(max(syi, -mashi), mashi)

        #  The search range procedure was adjusted for 3D searches, so since in 2D the order of operations is inverted, we have to invert ranges
        txrng = search_range(nx, ou, sxi, xrng, "ali2d_single_iter")
        txrng = [txrng[1], txrng[0]]
        tyrng = search_range(ny, ou, syi, yrng, "ali2d_single_iter")
        tyrng = [tyrng[1], tyrng[0]]
        # print im, "B",cnx,sxi,syi,txrng, tyrng
        # align current image to the reference
        if random_method == "SHC":
            """Multiline Comment0"""
            #  For shc combining of shifts is problematic as the image may randomly slide away and never come back.
            #  A possibility would be to reject moves that results in too large departure from the center.
            #  On the other hand, one cannot simply do searches around the proper center all the time,
            #    as if xr is decreased, the image cannot be brought back if the established shifts are further than new range
            olo = EMAN2_cppwrap.Util.shc(
                ima,
                [cimage],
                txrng,
                tyrng,
                step,
                -1.0,
                mode,
                numr,
                cnx + sxi,
                cny + syi,
                "c1",
            )
            ##olo = Util.shc(ima, [cimage], xrng, yrng, step, -1.0, mode, numr, cnx, cny, "c1")
            if data[im].get_attr("previousmax") < olo[5]:
                # [angt, sxst, syst, mirrort, peakt] = ormq(ima, cimage, xrng, yrng, step, mode, numr, cnx+sxi, cny+syi, delta)
                # print  angt, sxst, syst, mirrort, peakt,olo
                angt = olo[0]
                sxst = olo[1]
                syst = olo[2]
                mirrort = int(olo[3])
                # combine parameters and set them to the header, ignore previous angle and mirror
                [alphan, sxn, syn,
                 mn] = sp_utilities.combine_params2(0.0, -sxi, -syi, 0, angt,
                                                    sxst, syst, mirrort)
                sp_utilities.set_params2D(data[im],
                                          [alphan, sxn, syn, mn, 1.0],
                                          ali_params)
                ##set_params2D(data[im], [angt, sxst, syst, mirrort, 1.0], ali_params)
                data[im].set_attr("previousmax", olo[5])
            else:
                # Did not find a better peak, but we have to set shifted parameters, as the average shifted
                sp_utilities.set_params2D(data[im],
                                          [alpha, sx, sy, mirror, 1.0],
                                          ali_params)
                nope += 1
                mn = 0
                sxn = 0.0
                syn = 0.0
        elif random_method == "SCF":
            sxst, syst, iref, angt, mirrort, totpeak = multalign2d_scf(
                data[im], [cimage], frotim, numr, xrng, yrng, ou=ou)
            [alphan, sxn, syn,
             mn] = sp_utilities.combine_params2(0.0, -sxi, -syi, 0, angt, sxst,
                                                syst, mirrort)
            sp_utilities.set_params2D(data[im], [alphan, sxn, syn, mn, 1.0],
                                      ali_params)
        elif random_method == "PCP":
            [angt, sxst, syst, mirrort,
             peakt] = ormq_fast(data[im], cimage, txrng, tyrng, step, numr,
                                mode, delta)
            sxst = rings[0][0][0].get_attr("sxi")
            syst = rings[0][0][0].get_attr("syi")
            sp_global_def.sxprint(sxst, syst, sx, sy)
            dummy, sxs, sys, dummy = sp_utilities.inverse_transform2(
                -angt, sx + sxst, sy + syst)
            sp_utilities.set_params2D(data[im][0][0],
                                      [angt, sxs, sys, mirrort, 1.0],
                                      ali_params)
        else:
            if nomirror:
                [angt, sxst, syst, mirrort,
                 peakt] = ornq(ima, cimage, txrng, tyrng, step, mode, numr,
                               cnx + sxi, cny + syi)
            else:
                [angt, sxst, syst, mirrort, peakt] = ormq(
                    ima,
                    cimage,
                    txrng,
                    tyrng,
                    step,
                    mode,
                    numr,
                    cnx + sxi,
                    cny + syi,
                    delta,
                )
            # combine parameters and set them to the header, ignore previous angle and mirror
            [alphan, sxn, syn,
             mn] = sp_utilities.combine_params2(0.0, -sxi, -syi, 0, angt, sxst,
                                                syst, mirrort)
            sp_utilities.set_params2D(data[im], [alphan, sxn, syn, mn, 1.0],
                                      ali_params)

        if mn == 0:
            sx_sum += sxn
        else:
            sx_sum -= sxn
        sy_sum += syn

    return sx_sum, sy_sum, nope
Пример #5
0
def filter_shrink(input_bdb_name,
                  output_stack_path,
                  output_bdb_name,
                  alignYN=False,
                  filtrad=None,
                  shrink=None,
                  verbose=False):
    """
	Filters and shrinks image stack.
	
	Arguments:
		input_bdb_name : Input BDB stack  (in the form bdb:DIRECTORY#STACK)
		output_stack_path : Name for output image stack (MRCS/HDF/etc.)
		output_bdb_name : Name for output BDB stack (in the form bdb:DIRECTORY#STACK)
		alignYN: (boolean) Whether to apply alignments
		filtrad : Filter radius, reciprocal pixels
		shrink : Downsampling factor
		combined_params_file : Output combined alignment parameters
		verbose : (boolean) Whether to write to screen
	"""

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

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

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

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

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

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

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

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

        if filtrad:
            img_ali = filt_gaussl(img_ali, filtrad)

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

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

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

    aligned_stack_obj.write_image(output_stack_path)
    db_close_dict(output_bdb_name)

    return num_imgs
Пример #6
0
def mref_ali2d_MPI(stack,
                   refim,
                   outdir,
                   maskfile=None,
                   ir=1,
                   ou=-1,
                   rs=1,
                   xrng=0,
                   yrng=0,
                   step=1,
                   center=1,
                   maxit=10,
                   CTF=False,
                   snr=1.0,
                   user_func_name="ref_ali2d",
                   rand_seed=1000):
    # 2D multi-reference alignment using rotational ccf in polar coordinates and quadratic interpolation

    from sp_utilities import model_circle, combine_params2, inverse_transform2, drop_image, get_image, get_im
    from sp_utilities import reduce_EMData_to_root, bcast_EMData_to_all, bcast_number_to_all
    from sp_utilities import send_attr_dict
    from sp_utilities import center_2D
    from sp_statistics import fsc_mask
    from sp_alignment import Numrinit, ringwe, search_range
    from sp_fundamentals import rot_shift2D, fshift
    from sp_utilities import get_params2D, set_params2D
    from random import seed, randint
    from sp_morphology import ctf_2
    from sp_filter import filt_btwl, filt_params
    from numpy import reshape, shape
    from sp_utilities import print_msg, print_begin_msg, print_end_msg
    import os
    import sys
    import shutil
    from sp_applications import MPI_start_end
    from mpi import mpi_comm_size, mpi_comm_rank, MPI_COMM_WORLD
    from mpi import mpi_reduce, mpi_bcast, mpi_barrier, mpi_recv, mpi_send
    from mpi import MPI_SUM, MPI_FLOAT, MPI_INT

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

    # create the output directory, if it does not exist

    if os.path.exists(outdir):
        ERROR(
            'Output directory exists, please change the name and restart the program',
            "mref_ali2d_MPI ", 1, myid)
    mpi_barrier(MPI_COMM_WORLD)

    import sp_global_def
    if myid == main_node:
        os.mkdir(outdir)
        sp_global_def.LOGFILE = os.path.join(outdir, sp_global_def.LOGFILE)
        print_begin_msg("mref_ali2d_MPI")

    nima = EMUtil.get_image_count(stack)

    image_start, image_end = MPI_start_end(nima, number_of_proc, myid)

    nima = EMUtil.get_image_count(stack)
    ima = EMData()
    ima.read_image(stack, image_start)

    first_ring = int(ir)
    last_ring = int(ou)
    rstep = int(rs)
    max_iter = int(maxit)

    if max_iter == 0:
        max_iter = 10
        auto_stop = True
    else:
        auto_stop = False

    if myid == main_node:
        print_msg("Input stack                 : %s\n" % (stack))
        print_msg("Reference stack             : %s\n" % (refim))
        print_msg("Output directory            : %s\n" % (outdir))
        print_msg("Maskfile                    : %s\n" % (maskfile))
        print_msg("Inner radius                : %i\n" % (first_ring))

    nx = ima.get_xsize()
    # default value for the last ring
    if last_ring == -1: last_ring = nx / 2 - 2

    if myid == main_node:
        print_msg("Outer radius                : %i\n" % (last_ring))
        print_msg("Ring step                   : %i\n" % (rstep))
        print_msg("X search range              : %f\n" % (xrng))
        print_msg("Y search range              : %f\n" % (yrng))
        print_msg("Translational step          : %f\n" % (step))
        print_msg("Center type                 : %i\n" % (center))
        print_msg("Maximum iteration           : %i\n" % (max_iter))
        print_msg("CTF correction              : %s\n" % (CTF))
        print_msg("Signal-to-Noise Ratio       : %f\n" % (snr))
        print_msg("Random seed                 : %i\n\n" % (rand_seed))
        print_msg("User function               : %s\n" % (user_func_name))
    import sp_user_functions
    user_func = sp_user_functions.factory[user_func_name]

    if maskfile:
        import types
        if type(maskfile) is bytes: mask = get_image(maskfile)
        else: mask = maskfile
    else: mask = model_circle(last_ring, nx, nx)
    #  references, do them on all processors...
    refi = []
    numref = EMUtil.get_image_count(refim)

    # IMAGES ARE SQUARES! center is in SPIDER convention
    cnx = nx / 2 + 1
    cny = cnx

    mode = "F"
    #precalculate rings
    numr = Numrinit(first_ring, last_ring, rstep, mode)
    wr = ringwe(numr, mode)

    # prepare reference images on all nodes
    ima.to_zero()
    for j in range(numref):
        #  even, odd, numer of even, number of images.  After frc, totav
        refi.append([get_im(refim, j), ima.copy(), 0])
    #  for each node read its share of data
    data = EMData.read_images(stack, list(range(image_start, image_end)))
    for im in range(image_start, image_end):
        data[im - image_start].set_attr('ID', im)

    if myid == main_node: seed(rand_seed)

    a0 = -1.0
    again = True
    Iter = 0

    ref_data = [mask, center, None, None]

    while Iter < max_iter and again:
        ringref = []
        mashi = cnx - last_ring - 2
        for j in range(numref):
            refi[j][0].process_inplace("normalize.mask", {
                "mask": mask,
                "no_sigma": 1
            })  # normalize reference images to N(0,1)
            cimage = Util.Polar2Dm(refi[j][0], cnx, cny, numr, mode)
            Util.Frngs(cimage, numr)
            Util.Applyws(cimage, numr, wr)
            ringref.append(cimage)
            # zero refi
            refi[j][0].to_zero()
            refi[j][1].to_zero()
            refi[j][2] = 0

        assign = [[] for i in range(numref)]
        # begin MPI section
        for im in range(image_start, image_end):
            alpha, sx, sy, mirror, scale = get_params2D(data[im - image_start])
            #  Why inverse?  07/11/2015 PAP
            alphai, sxi, syi, scalei = inverse_transform2(alpha, sx, sy)
            # normalize
            data[im - image_start].process_inplace("normalize.mask", {
                "mask": mask,
                "no_sigma": 0
            })  # subtract average under the mask
            # If shifts are outside of the permissible range, reset them
            if (abs(sxi) > mashi or abs(syi) > mashi):
                sxi = 0.0
                syi = 0.0
                set_params2D(data[im - image_start], [0.0, 0.0, 0.0, 0, 1.0])
            ny = nx
            txrng = search_range(nx, last_ring, sxi, xrng, "mref_ali2d_MPI")
            txrng = [txrng[1], txrng[0]]
            tyrng = search_range(ny, last_ring, syi, yrng, "mref_ali2d_MPI")
            tyrng = [tyrng[1], tyrng[0]]
            # align current image to the reference
            [angt, sxst, syst, mirrort, xiref,
             peakt] = Util.multiref_polar_ali_2d(data[im - image_start],
                                                 ringref, txrng, tyrng, step,
                                                 mode, numr, cnx + sxi,
                                                 cny + syi)

            iref = int(xiref)
            # combine parameters and set them to the header, ignore previous angle and mirror
            [alphan, sxn, syn,
             mn] = combine_params2(0.0, -sxi, -syi, 0, angt, sxst, syst,
                                   (int)(mirrort))
            set_params2D(data[im - image_start],
                         [alphan, sxn, syn, int(mn), scale])
            data[im - image_start].set_attr('assign', iref)
            # apply current parameters and add to the average
            temp = rot_shift2D(data[im - image_start], alphan, sxn, syn, mn)
            it = im % 2
            Util.add_img(refi[iref][it], temp)
            assign[iref].append(im)
            #assign[im] = iref
            refi[iref][2] += 1.0
        del ringref
        # end MPI section, bring partial things together, calculate new reference images, broadcast them back

        for j in range(numref):
            reduce_EMData_to_root(refi[j][0], myid, main_node)
            reduce_EMData_to_root(refi[j][1], myid, main_node)
            refi[j][2] = mpi_reduce(refi[j][2], 1, MPI_FLOAT, MPI_SUM,
                                    main_node, MPI_COMM_WORLD)
            if (myid == main_node): refi[j][2] = int(refi[j][2][0])
        # gather assignements
        for j in range(numref):
            if myid == main_node:
                for n in range(number_of_proc):
                    if n != main_node:
                        import sp_global_def
                        ln = mpi_recv(1, MPI_INT, n,
                                      sp_global_def.SPARX_MPI_TAG_UNIVERSAL,
                                      MPI_COMM_WORLD)
                        lis = mpi_recv(ln[0], MPI_INT, n,
                                       sp_global_def.SPARX_MPI_TAG_UNIVERSAL,
                                       MPI_COMM_WORLD)
                        for l in range(ln[0]):
                            assign[j].append(int(lis[l]))
            else:
                import sp_global_def
                mpi_send(len(assign[j]), 1, MPI_INT, main_node,
                         sp_global_def.SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
                mpi_send(assign[j], len(assign[j]), MPI_INT, main_node,
                         sp_global_def.SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)

        if myid == main_node:
            # replace the name of the stack with reference with the current one
            refim = os.path.join(outdir, "aqm%03d.hdf" % Iter)
            a1 = 0.0
            ave_fsc = []
            for j in range(numref):
                if refi[j][2] < 4:
                    #ERROR("One of the references vanished","mref_ali2d_MPI",1)
                    #  if vanished, put a random image (only from main node!) there
                    assign[j] = []
                    assign[j].append(
                        randint(image_start, image_end - 1) - image_start)
                    refi[j][0] = data[assign[j][0]].copy()
                    #print 'ERROR', j
                else:
                    #frsc = fsc_mask(refi[j][0], refi[j][1], mask, 1.0, os.path.join(outdir,"drm%03d%04d"%(Iter, j)))
                    from sp_statistics import fsc
                    frsc = fsc(
                        refi[j][0], refi[j][1], 1.0,
                        os.path.join(outdir, "drm%03d%04d.txt" % (Iter, j)))
                    Util.add_img(refi[j][0], refi[j][1])
                    Util.mul_scalar(refi[j][0], 1.0 / float(refi[j][2]))

                    if ave_fsc == []:
                        for i in range(len(frsc[1])):
                            ave_fsc.append(frsc[1][i])
                        c_fsc = 1
                    else:
                        for i in range(len(frsc[1])):
                            ave_fsc[i] += frsc[1][i]
                        c_fsc += 1
                    #print 'OK', j, len(frsc[1]), frsc[1][0:5], ave_fsc[0:5]

            #print 'sum', sum(ave_fsc)
            if sum(ave_fsc) != 0:
                for i in range(len(ave_fsc)):
                    ave_fsc[i] /= float(c_fsc)
                    frsc[1][i] = ave_fsc[i]

            for j in range(numref):
                ref_data[2] = refi[j][0]
                ref_data[3] = frsc
                refi[j][0], cs = user_func(ref_data)

                # write the current average
                TMP = []
                for i_tmp in range(len(assign[j])):
                    TMP.append(float(assign[j][i_tmp]))
                TMP.sort()
                refi[j][0].set_attr_dict({'ave_n': refi[j][2], 'members': TMP})
                del TMP
                refi[j][0].process_inplace("normalize.mask", {
                    "mask": mask,
                    "no_sigma": 1
                })
                refi[j][0].write_image(refim, j)

            Iter += 1
            msg = "ITERATION #%3d        %d\n\n" % (Iter, again)
            print_msg(msg)
            for j in range(numref):
                msg = "   group #%3d   number of particles = %7d\n" % (
                    j, refi[j][2])
                print_msg(msg)
        Iter = bcast_number_to_all(Iter, main_node)  # need to tell all
        if again:
            for j in range(numref):
                bcast_EMData_to_all(refi[j][0], myid, main_node)

    #  clean up
    del assign
    # write out headers  and STOP, under MPI writing has to be done sequentially (time-consumming)
    mpi_barrier(MPI_COMM_WORLD)
    if CTF and data_had_ctf == 0:
        for im in range(len(data)):
            data[im].set_attr('ctf_applied', 0)
    par_str = ['xform.align2d', 'assign', 'ID']
    if myid == main_node:
        from sp_utilities import file_type
        if (file_type(stack) == "bdb"):
            from sp_utilities import recv_attr_dict_bdb
            recv_attr_dict_bdb(main_node, stack, data, par_str, image_start,
                               image_end, number_of_proc)
        else:
            from sp_utilities import recv_attr_dict
            recv_attr_dict(main_node, stack, data, par_str, image_start,
                           image_end, number_of_proc)
    else:
        send_attr_dict(main_node, data, par_str, image_start, image_end)
    if myid == main_node:
        print_end_msg("mref_ali2d_MPI")
Пример #7
0
def mref_ali2d(stack,
               refim,
               outdir,
               maskfile=None,
               ir=1,
               ou=-1,
               rs=1,
               xrng=0,
               yrng=0,
               step=1,
               center=1,
               maxit=0,
               CTF=False,
               snr=1.0,
               user_func_name="ref_ali2d",
               rand_seed=1000,
               MPI=False):
    """
        Name
            mref_ali2d - Perform 2-D multi-reference alignment of an image series
        Input
            stack: set of 2-D images in a stack file, images have to be squares
            refim: set of initial reference 2-D images in a stack file 
            maskfile: optional maskfile to be used in the alignment
            inner_radius: inner radius for rotational correlation > 0
            outer_radius: outer radius for rotational correlation < nx/2-1
            ring_step: step between rings in rotational correlation >0
            x_range: range for translation search in x direction, search is +/xr 
            y_range: range for translation search in y direction, search is +/yr 
            translation_step: step of translation search in both directions
            center: center the average
            max_iter: maximum number of iterations the program will perform
            CTF: if this flag is set, the program will use CTF information provided in file headers
            snr: signal-to-noise ratio of the data
            rand_seed: the seed used for generating random numbers
            MPI: whether to use MPI version
        Output
            output_directory: directory name into which the output files will be written.
            header: the alignment parameters are stored in the headers of input files as 'xform.align2d'.
    """
    # 2D multi-reference alignment using rotational ccf in polar coordinates and quadratic interpolation
    if MPI:
        mref_ali2d_MPI(stack, refim, outdir, maskfile, ir, ou, rs, xrng, yrng,
                       step, center, maxit, CTF, snr, user_func_name,
                       rand_seed)
        return

    from sp_utilities import model_circle, combine_params2, inverse_transform2, drop_image, get_image
    from sp_utilities import center_2D, get_im, get_params2D, set_params2D
    from sp_statistics import fsc
    from sp_alignment import Numrinit, ringwe, fine_2D_refinement, search_range
    from sp_fundamentals import rot_shift2D, fshift
    from random import seed, randint
    import os
    import sys

    from sp_utilities import print_begin_msg, print_end_msg, print_msg
    import shutil

    # create the output directory, if it does not exist
    if os.path.exists(outdir):
        shutil.rmtree(
            outdir
        )  #ERROR('Output directory exists, please change the name and restart the program', "mref_ali2d", 1)
    os.mkdir(outdir)
    import sp_global_def
    sp_global_def.LOGFILE = os.path.join(outdir, sp_global_def.LOGFILE)

    first_ring = int(ir)
    last_ring = int(ou)
    rstep = int(rs)
    max_iter = int(maxit)

    print_begin_msg("mref_ali2d")

    print_msg("Input stack                 : %s\n" % (stack))
    print_msg("Reference stack             : %s\n" % (refim))
    print_msg("Output directory            : %s\n" % (outdir))
    print_msg("Maskfile                    : %s\n" % (maskfile))
    print_msg("Inner radius                : %i\n" % (first_ring))

    ima = EMData()
    ima.read_image(stack, 0)
    nx = ima.get_xsize()
    # default value for the last ring
    if last_ring == -1: last_ring = nx / 2 - 2

    print_msg("Outer radius                : %i\n" % (last_ring))
    print_msg("Ring step                   : %i\n" % (rstep))
    print_msg("X search range              : %i\n" % (xrng))
    print_msg("Y search range              : %i\n" % (yrng))
    print_msg("Translational step          : %i\n" % (step))
    print_msg("Center type                 : %i\n" % (center))
    print_msg("Maximum iteration           : %i\n" % (max_iter))
    print_msg("CTF correction              : %s\n" % (CTF))
    print_msg("Signal-to-Noise Ratio       : %f\n" % (snr))
    print_msg("Random seed                 : %i\n\n" % (rand_seed))
    print_msg("User function               : %s\n" % (user_func_name))
    output = sys.stdout

    import sp_user_functions
    user_func = sp_user_functions.factory[user_func_name]

    if maskfile:
        import types
        if type(maskfile) is bytes: mask = get_image(maskfile)
        else: mask = maskfile
    else: mask = model_circle(last_ring, nx, nx)
    #  references
    refi = []
    numref = EMUtil.get_image_count(refim)

    # IMAGES ARE SQUARES! center is in SPIDER convention
    cnx = nx / 2 + 1
    cny = cnx

    mode = "F"
    #precalculate rings
    numr = Numrinit(first_ring, last_ring, rstep, mode)
    wr = ringwe(numr, mode)
    # reference images
    params = []
    #read all data
    data = EMData.read_images(stack)
    nima = len(data)
    # prepare the reference
    ima.to_zero()
    for j in range(numref):
        temp = EMData()
        temp.read_image(refim, j)
        #  eve, odd, numer of even, number of images.  After frc, totav
        refi.append([temp, ima.copy(), 0])

    seed(rand_seed)
    again = True

    ref_data = [mask, center, None, None]

    Iter = 0

    while Iter < max_iter and again:
        ringref = []
        #print "numref",numref

        ### Reference ###
        mashi = cnx - last_ring - 2
        for j in range(numref):
            refi[j][0].process_inplace("normalize.mask", {
                "mask": mask,
                "no_sigma": 1
            })
            cimage = Util.Polar2Dm(refi[j][0], cnx, cny, numr, mode)
            Util.Frngs(cimage, numr)
            Util.Applyws(cimage, numr, wr)
            ringref.append(cimage)

        assign = [[] for i in range(numref)]
        sx_sum = [0.0] * numref
        sy_sum = [0.0] * numref
        for im in range(nima):
            alpha, sx, sy, mirror, scale = get_params2D(data[im])
            #  Why inverse?  07/11/2015  PAP
            alphai, sxi, syi, scalei = inverse_transform2(alpha, sx, sy)
            # normalize
            data[im].process_inplace("normalize.mask", {
                "mask": mask,
                "no_sigma": 0
            })
            # If shifts are outside of the permissible range, reset them
            if (abs(sxi) > mashi or abs(syi) > mashi):
                sxi = 0.0
                syi = 0.0
                set_params2D(data[im], [0.0, 0.0, 0.0, 0, 1.0])
            ny = nx
            txrng = search_range(nx, last_ring, sxi, xrng, "mref_ali2d")
            txrng = [txrng[1], txrng[0]]
            tyrng = search_range(ny, last_ring, syi, yrng, "mref_ali2d")
            tyrng = [tyrng[1], tyrng[0]]
            # align current image to the reference
            #[angt, sxst, syst, mirrort, xiref, peakt] = Util.multiref_polar_ali_2d_p(data[im],
            #    ringref, txrng, tyrng, step, mode, numr, cnx+sxi, cny+syi)
            #print(angt, sxst, syst, mirrort, xiref, peakt)
            [angt, sxst, syst, mirrort, xiref,
             peakt] = Util.multiref_polar_ali_2d(data[im], ringref, txrng,
                                                 tyrng, step, mode, numr,
                                                 cnx + sxi, cny + syi)

            iref = int(xiref)
            # combine parameters and set them to the header, ignore previous angle and mirror
            [alphan, sxn, syn, mn] = combine_params2(0.0, -sxi, -syi, 0, angt,
                                                     sxst, syst, int(mirrort))
            set_params2D(data[im], [alphan, sxn, syn, int(mn), scale])
            if mn == 0: sx_sum[iref] += sxn
            else: sx_sum[iref] -= sxn
            sy_sum[iref] += syn
            data[im].set_attr('assign', iref)
            # apply current parameters and add to the average
            temp = rot_shift2D(data[im], alphan, sxn, syn, mn)
            it = im % 2
            Util.add_img(refi[iref][it], temp)

            assign[iref].append(im)
            refi[iref][2] += 1
        del ringref
        if again:
            a1 = 0.0
            for j in range(numref):
                msg = "   group #%3d   number of particles = %7d\n" % (
                    j, refi[j][2])
                print_msg(msg)
                if refi[j][2] < 4:
                    #ERROR("One of the references vanished","mref_ali2d",1)
                    #  if vanished, put a random image there
                    assign[j] = []
                    assign[j].append(randint(0, nima - 1))
                    refi[j][0] = data[assign[j][0]].copy()
                else:
                    max_inter = 0  # switch off fine refi.
                    br = 1.75
                    #  the loop has to
                    for INter in range(max_inter + 1):
                        # Calculate averages at least ones, meaning even if no within group refinement was requested
                        frsc = fsc(
                            refi[j][0], refi[j][1], 1.0,
                            os.path.join(outdir,
                                         "drm_%03d_%04d.txt" % (Iter, j)))
                        Util.add_img(refi[j][0], refi[j][1])
                        Util.mul_scalar(refi[j][0], 1.0 / float(refi[j][2]))

                        ref_data[2] = refi[j][0]
                        ref_data[3] = frsc
                        refi[j][0], cs = user_func(ref_data)
                        if center == -1:
                            cs[0] = sx_sum[j] / len(assign[j])
                            cs[1] = sy_sum[j] / len(assign[j])
                            refi[j][0] = fshift(refi[j][0], -cs[0], -cs[1])
                        for i in range(len(assign[j])):
                            im = assign[j][i]
                            alpha, sx, sy, mirror, scale = get_params2D(
                                data[im])
                            alphan, sxn, syn, mirrorn = combine_params2(
                                alpha, sx, sy, mirror, 0.0, -cs[0], -cs[1], 0)
                            set_params2D(
                                data[im],
                                [alphan, sxn, syn,
                                 int(mirrorn), scale])
                        # refine images within the group
                        #  Do the refinement only if max_inter>0, but skip it for the last iteration.
                        if INter < max_inter:
                            fine_2D_refinement(data, br, mask, refi[j][0], j)
                            #  Calculate updated average
                            refi[j][0].to_zero()
                            refi[j][1].to_zero()
                            for i in range(len(assign[j])):
                                im = assign[j][i]
                                alpha, sx, sy, mirror, scale = get_params2D(
                                    data[im])
                                # apply current parameters and add to the average
                                temp = rot_shift2D(data[im], alpha, sx, sy, mn)
                                it = im % 2
                                Util.add_img(refi[j][it], temp)
                # write the current average
                TMP = []
                for i_tmp in range(len(assign[j])):
                    TMP.append(float(assign[j][i_tmp]))
                TMP.sort()
                refi[j][0].set_attr_dict({'ave_n': refi[j][2], 'members': TMP})
                del TMP
                # replace the name of the stack with reference with the current one
                newrefim = os.path.join(outdir, "aqm%03d.hdf" % Iter)
                refi[j][0].write_image(newrefim, j)
            Iter += 1
            msg = "ITERATION #%3d        \n" % (Iter)
            print_msg(msg)

    newrefim = os.path.join(outdir, "multi_ref.hdf")
    for j in range(numref):
        refi[j][0].write_image(newrefim, j)
    from sp_utilities import write_headers
    write_headers(stack, data, list(range(nima)))
    print_end_msg("mref_ali2d")
Пример #8
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = progname + """ [options] <inputfile> <outputfile>

	Forms chains of 2D images based on their similarities.

	Functionality:


	Order a 2-D stack of image based on pair-wise similarity (computed as a cross-correlation coefficent).
		Options 1-3 require image stack to be aligned.  The program will apply orientation parameters if present in headers.
	    The ways to use the program:
	   1.  Use option initial to specify which image will be used as an initial seed to form the chain.
	        sp_chains.py input_stack.hdf output_stack.hdf --initial=23 --radius=25

	   2.  If options initial is omitted, the program will determine which image best serves as initial seed to form the chain
	        sp_chains.py input_stack.hdf output_stack.hdf --radius=25

	   3.  Use option circular to form a circular chain.
	        sp_chains.py input_stack.hdf output_stack.hdf --circular--radius=25

	   4.  New circular code based on pairwise alignments
			sp_chains.py aclf.hdf chain.hdf circle.hdf --align  --radius=25 --xr=2 --pairwiseccc=lcc.txt

	   5.  Circular ordering based on pairwise alignments
			sp_chains.py vols.hdf chain.hdf mask.hdf --dd  --radius=25


"""

    parser = OptionParser(usage, version=SPARXVERSION)
    parser.add_option(
        "--dd",
        action="store_true",
        help="Circular ordering without adjustment of orientations",
        default=False)
    parser.add_option(
        "--circular",
        action="store_true",
        help=
        "Select circular ordering (first image has to be similar to the last)",
        default=False)
    parser.add_option(
        "--align",
        action="store_true",
        help=
        "Compute all pairwise alignments and from the table of image similarities find the best chain",
        default=False)
    parser.add_option(
        "--initial",
        type="int",
        default=-1,
        help=
        "Specifies which image will be used as an initial seed to form the chain. (default = 0, means the first image)"
    )
    parser.add_option(
        "--radius",
        type="int",
        default=-1,
        help="Radius of a circular mask for similarity based ordering")
    #  import params for 2D alignment
    parser.add_option(
        "--ou",
        type="int",
        default=-1,
        help=
        "outer radius for 2D alignment < nx/2-1 (set to the radius of the particle)"
    )
    parser.add_option(
        "--xr",
        type="int",
        default=0,
        help="range for translation search in x direction, search is +/xr (0)")
    parser.add_option(
        "--yr",
        type="int",
        default=0,
        help="range for translation search in y direction, search is +/yr (0)")
    # parser.add_option("--nomirror",     action="store_true", default=False,   help="Disable checking mirror orientations of images (default False)")
    parser.add_option("--pairwiseccc",
                      type="string",
                      default=" ",
                      help="Input/output pairwise ccc file")

    (options, args) = parser.parse_args()

    sp_global_def.BATCH = True

    if options.dd:
        nargs = len(args)
        if nargs != 3:
            ERROR("Must provide name of input and two output files!")
            return

        stack = args[0]
        new_stack = args[1]

        from sp_utilities import model_circle
        from sp_statistics import ccc
        from sp_statistics import mono
        lend = EMUtil.get_image_count(stack)
        lccc = [None] * (old_div(lend * (lend - 1), 2))

        for i in range(lend - 1):
            v1 = get_im(stack, i)
            if (i == 0 and nargs == 2):
                nx = v1.get_xsize()
                ny = v1.get_ysize()
                nz = v1.get_ysize()
                if options.ou < 1:
                    radius = old_div(nx, 2) - 2
                else:
                    radius = options.ou
                mask = model_circle(radius, nx, ny, nz)
            else:
                mask = get_im(args[2])

            for j in range(i + 1, lend):
                lccc[mono(i, j)] = [ccc(v1, get_im(stack, j), mask), 0]

        order = tsp(lccc)
        if (len(order) != lend):
            ERROR("Problem with data length")
            return

        sxprint("Total sum of cccs :", TotalDistance(order, lccc))
        sxprint("ordering :", order)
        for i in range(lend):
            get_im(stack, order[i]).write_image(new_stack, i)

    elif options.align:
        nargs = len(args)
        if nargs != 3:
            ERROR("Must provide name of input and two output files!")
            return

        from sp_utilities import get_params2D, model_circle
        from sp_fundamentals import rot_shift2D
        from sp_statistics import ccc
        from time import time
        from sp_alignment import align2d, align2d_scf

        stack = args[0]
        new_stack = args[1]

        d = EMData.read_images(stack)
        if (len(d) < 6):
            ERROR(
                "Chains requires at least six images in the input stack to be executed"
            )
            return
        """
		# will align anyway
		try:
			ttt = d[0].get_attr('xform.params2d')
			for i in xrange(len(d)):
				alpha, sx, sy, mirror, scale = get_params2D(d[i])
				d[i] = rot_shift2D(d[i], alpha, sx, sy, mirror)
		except:
			pass
		"""

        nx = d[0].get_xsize()
        ny = d[0].get_ysize()
        if options.ou < 1:
            radius = old_div(nx, 2) - 2
        else:
            radius = options.ou
        mask = model_circle(radius, nx, ny)

        if (options.xr < 0):
            xrng = 0
        else:
            xrng = options.xr
        if (options.yr < 0):
            yrng = xrng
        else:
            yrng = options.yr

        initial = max(options.initial, 0)

        from sp_statistics import mono
        lend = len(d)
        lccc = [None] * (old_div(lend * (lend - 1), 2))
        from sp_utilities import read_text_row

        if options.pairwiseccc == " " or not os.path.exists(
                options.pairwiseccc):
            st = time()
            for i in range(lend - 1):
                for j in range(i + 1, lend):
                    #  j>i meaning mono entry (i,j) or (j,i) indicates T i->j (from smaller index to larger)
                    # alpha, sx, sy, mir, peak = align2d(d[i],d[j], xrng, yrng, step=options.ts, first_ring=options.ir, last_ring=radius, mode = "F")
                    alpha, sx, sy, mir, peak = align2d_scf(d[i],
                                                           d[j],
                                                           xrng,
                                                           yrng,
                                                           ou=radius)
                    lccc[mono(i, j)] = [
                        ccc(d[j], rot_shift2D(d[i], alpha, sx, sy, mir, 1.0),
                            mask), alpha, sx, sy, mir
                    ]
            # print "  %4d   %10.1f"%(i,time()-st)

            if ((not os.path.exists(options.pairwiseccc))
                    and (options.pairwiseccc != " ")):
                write_text_row([[initial, 0, 0, 0, 0]] + lccc,
                               options.pairwiseccc)
        elif (os.path.exists(options.pairwiseccc)):
            lccc = read_text_row(options.pairwiseccc)
            initial = int(lccc[0][0] + 0.1)
            del lccc[0]

        for i in range(len(lccc)):
            T = Transform({
                "type": "2D",
                "alpha": lccc[i][1],
                "tx": lccc[i][2],
                "ty": lccc[i][3],
                "mirror": int(lccc[i][4] + 0.1)
            })
            lccc[i] = [lccc[i][0], T]

        tdummy = Transform({"type": "2D"})
        maxsum = -1.023
        for m in range(0, lend):  # initial, initial+1):
            indc = list(range(lend))
            lsnake = [[m, tdummy, 0.0]]
            del indc[m]

            lsum = 0.0
            while len(indc) > 1:
                maxcit = -111.
                for i in range(len(indc)):
                    cuc = lccc[mono(indc[i], lsnake[-1][0])][0]
                    if cuc > maxcit:
                        maxcit = cuc
                        qi = indc[i]
                        #  Here we need transformation from the current to the previous,
                        #     meaning indc[i] -> lsnake[-1][0]
                        T = lccc[mono(indc[i], lsnake[-1][0])][1]
                        #  If direction is from larger to smaller index, the transformation has to be inverted
                        if (indc[i] > lsnake[-1][0]): T = T.inverse()

                lsnake.append([qi, T, maxcit])
                lsum += maxcit

                del indc[indc.index(qi)]

            T = lccc[mono(indc[-1], lsnake[-1][0])][1]
            if (indc[-1] > lsnake[-1][0]): T = T.inverse()
            lsnake.append(
                [indc[-1], T, lccc[mono(indc[-1], lsnake[-1][0])][0]])
            sxprint(" initial image and lsum  ", m, lsum)
            # print lsnake
            if (lsum > maxsum):
                maxsum = lsum
                init = m
                snake = [lsnake[i] for i in range(lend)]
        sxprint("  Initial image selected : ", init, maxsum, "    ",
                TotalDistance([snake[m][0] for m in range(lend)], lccc))
        # for q in snake: print q

        from copy import deepcopy
        trans = deepcopy([snake[i][1] for i in range(len(snake))])
        sxprint([snake[i][0] for i in range(len(snake))])
        """
		for m in xrange(lend):
			prms = trans[m].get_params("2D")
			print " %3d   %7.1f   %7.1f   %7.1f   %2d  %6.2f"%(snake[m][0], prms["alpha"], prms["tx"], prms["ty"], prms["mirror"], snake[m][2])
		"""
        for k in range(lend - 2, 0, -1):
            T = snake[k][1]
            for i in range(k + 1, lend):
                trans[i] = T * trans[i]
        #  To add - apply all transformations and do the overall centering.
        for m in range(lend):
            prms = trans[m].get_params("2D")
            # print(" %3d   %7.1f   %7.1f   %7.1f   %2d  %6.2f"%(snake[m][0], prms["alpha"], prms["tx"], prms["ty"], prms["mirror"], snake[m][2]) )
            # rot_shift2D(d[snake[m][0]], prms["alpha"], prms["tx"], prms["ty"], prms["mirror"]).write_image(new_stack, m)
            rot_shift2D(d[snake[m][0]], prms["alpha"], 0.0, 0.0,
                        prms["mirror"]).write_image(new_stack, m)

        order = tsp(lccc)
        if (len(order) != lend):
            ERROR("Problem with data length")
            return

        sxprint(TotalDistance(order, lccc))
        sxprint(order)
        ibeg = order.index(init)
        order = [order[(i + ibeg) % lend] for i in range(lend)]
        sxprint(TotalDistance(order, lccc))
        sxprint(order)

        snake = [tdummy]
        for i in range(1, lend):
            #  Here we need transformation from the current to the previous,
            #     meaning order[i] -> order[i-1]]
            T = lccc[mono(order[i], order[i - 1])][1]
            #  If direction is from larger to smaller index, the transformation has to be inverted
            if (order[i] > order[i - 1]): T = T.inverse()
            snake.append(T)
        assert (len(snake) == lend)
        from copy import deepcopy
        trans = deepcopy(snake)
        for k in range(lend - 2, 0, -1):
            T = snake[k]
            for i in range(k + 1, lend):
                trans[i] = T * trans[i]

        #  Try to smooth the angles - complicated, I am afraid one would have to use angles forward and backwards
        #     and find their average??
        #  In addition, one would have to recenter them
        """
		trms = []
		for m in xrange(lend):
			prms = trans[m].get_params("2D")
			trms.append([prms["alpha"], prms["mirror"]])
		for i in xrange(3):
			for m in xrange(lend):
				mb = (m-1)%lend
				me = (m+1)%lend
				#  angles order mb,m,me
				# calculate predicted angles mb->m 
		"""

        best_params = []
        for m in range(lend):
            prms = trans[m].get_params("2D")
            # rot_shift2D(d[order[m]], prms["alpha"], prms["tx"], prms["ty"], prms["mirror"]).write_image("metro.hdf", m)
            rot_shift2D(d[order[m]], prms["alpha"], 0.0, 0.0,
                        prms["mirror"]).write_image(args[2], m)
            best_params.append(
                [m, order[m], prms["alpha"], 0.0, 0.0, prms["mirror"]])

        # Write alignment parameters
        outdir = os.path.dirname(args[2])
        aligndoc = os.path.join(outdir, "chains_params.txt")
        write_text_row(best_params, aligndoc)
        """
		#  This was an effort to get number of loops, inconclusive, to say the least
		from numpy import outer, zeros, float32, sqrt
		lend = len(d)
 		cor = zeros(lend,float32)
 		cor = outer(cor, cor)
		for i in xrange(lend):  cor[i][i] = 1.0
		for i in xrange(lend-1):
			for j in xrange(i+1, lend):
				cor[i,j] = lccc[mono(i,j)][0]
				cor[j,i] = cor[i,j]

		lmbd, eigvec = pca(cor)

		from sp_utilities import write_text_file

		nvec=20
		print  [lmbd[j] for j in xrange(nvec)]
		print  " G"
		mm = [-1]*lend
		for i in xrange(lend):  # row
			mi = -1.0e23
			for j in xrange(nvec):
				qt = eigvec[j][i]
				if(abs(qt)>mi):
					mi = abs(qt)
					mm[i] = j
			for j in xrange(nvec):
				qt = eigvec[j][i]
				print  round(qt,3),   #  eigenvector
			print  mm[i]
		print
		for j in xrange(nvec):
			qt = []
			for i in xrange(lend):
				if(mm[i] == j):  qt.append(i)
			if(len(qt)>0):  write_text_file(qt,"loop%02d.txt"%j)
		"""
        """
		print  [lmbd[j] for j in xrange(nvec)]
		print  " B"
		mm = [-1]*lend
		for i in xrange(lend):  # row
			mi = -1.0e23
			for j in xrange(nvec):
				qt = eigvec[j][i]/sqrt(lmbd[j])
				if(abs(qt)>mi):
					mi = abs(qt)
					mm[i] = j
			for j in xrange(nvec):
				qt = eigvec[j][i]/sqrt(lmbd[j])
				print  round(qt,3),   #  eigenvector
			print  mm[i]
		print
		"""
        """
		lend=3
 		cor = zeros(lend,float32)

 		cor = outer(cor, cor)


 		cor[0][0] =136.77
 		cor[0][1] = 79.15
 		cor[0][2] = 37.13

 		cor[1][0] = 79.15
 		cor[2][0] = 37.13


 		cor[1][1] = 50.04
 		cor[1][2] = 21.65

 		cor[2][1] = 21.65


 		cor[2][2] = 13.26

		lmbd, eigvec = pca(cor)
		print  lmbd
		print  eigvec
		for i in xrange(lend):  # row
			for j in xrange(lend):  print  eigvec[j][i],   #  eigenvector
			print
		print  " B"
		for i in xrange(lend):  # row
			for j in xrange(lend):  print  eigvec[j][i]/sqrt(lmbd[j]),   #  eigenvector
			print
		print  " G"
		for i in xrange(lend):  # row
			for j in xrange(lend):  print  eigvec[j][i]*sqrt(lmbd[j]),   #  eigenvector
			print
		"""
    else:
        nargs = len(args)
        if nargs != 2:
            ERROR("Must provide name of input and output file!")
            return

        from sp_utilities import get_params2D, model_circle
        from sp_fundamentals import rot_shift2D
        from sp_statistics import ccc
        from time import time
        from sp_alignment import align2d

        stack = args[0]
        new_stack = args[1]

        d = EMData.read_images(stack)
        try:
            sxprint("Using 2D alignment parameters from header.")
            ttt = d[0].get_attr('xform.params2d')
            for i in range(len(d)):
                alpha, sx, sy, mirror, scale = get_params2D(d[i])
                d[i] = rot_shift2D(d[i], alpha, sx, sy, mirror)
        except:
            pass

        nx = d[0].get_xsize()
        ny = d[0].get_ysize()
        if options.radius < 1:
            radius = old_div(nx, 2) - 2
        else:
            radius = options.radius
        mask = model_circle(radius, nx, ny)

        init = options.initial

        if init > -1:
            sxprint("      initial image: %d" % init)
            temp = d[init].copy()
            temp.write_image(new_stack, 0)
            del d[init]
            k = 1
            lsum = 0.0
            while len(d) > 1:
                maxcit = -111.
                for i in range(len(d)):
                    cuc = ccc(d[i], temp, mask)
                    if cuc > maxcit:
                        maxcit = cuc
                        qi = i
                # 	sxprint k, maxcit
                lsum += maxcit
                temp = d[qi].copy()
                del d[qi]
                temp.write_image(new_stack, k)
                k += 1
            sxprint(lsum)
            d[0].write_image(new_stack, k)
        else:
            if options.circular:
                sxprint("Using options.circular, no alignment")
                #  figure the "best circular" starting image
                maxsum = -1.023
                for m in range(len(d)):
                    indc = list(range(len(d)))
                    lsnake = [-1] * (len(d) + 1)
                    lsnake[0] = m
                    lsnake[-1] = m
                    del indc[m]
                    temp = d[m].copy()
                    lsum = 0.0
                    direction = +1
                    k = 1
                    while len(indc) > 1:
                        maxcit = -111.
                        for i in range(len(indc)):
                            cuc = ccc(d[indc[i]], temp, mask)
                            if cuc > maxcit:
                                maxcit = cuc
                                qi = indc[i]
                        lsnake[k] = qi
                        lsum += maxcit
                        del indc[indc.index(qi)]
                        direction = -direction
                        for i in range(1, len(d)):
                            if (direction > 0):
                                if (lsnake[i] == -1):
                                    temp = d[lsnake[i - 1]].copy()
                                    # print  "  forw  ",lsnake[i-1]
                                    k = i
                                    break
                            else:
                                if (lsnake[len(d) - i] == -1):
                                    temp = d[lsnake[len(d) - i + 1]].copy()
                                    # print  "  back  ",lsnake[len(d) - i +1]
                                    k = len(d) - i
                                    break

                    lsnake[lsnake.index(-1)] = indc[-1]
                    # print  " initial image and lsum  ",m,lsum
                    # print lsnake
                    if (lsum > maxsum):
                        maxsum = lsum
                        init = m
                        snake = [lsnake[i] for i in range(len(d))]
                sxprint("  Initial image selected : ", init, maxsum)
                sxprint(lsnake)
                for m in range(len(d)):
                    d[snake[m]].write_image(new_stack, m)
            else:
                #  figure the "best" starting image
                sxprint("Straight chain, no alignment")
                maxsum = -1.023
                for m in range(len(d)):
                    indc = list(range(len(d)))
                    lsnake = [m]
                    del indc[m]
                    temp = d[m].copy()
                    lsum = 0.0
                    while len(indc) > 1:
                        maxcit = -111.
                        for i in range(len(indc)):
                            cuc = ccc(d[indc[i]], temp, mask)
                            if cuc > maxcit:
                                maxcit = cuc
                                qi = indc[i]
                        lsnake.append(qi)
                        lsum += maxcit
                        temp = d[qi].copy()
                        del indc[indc.index(qi)]

                    lsnake.append(indc[-1])
                    # sxprint  " initial image and lsum  ",m,lsum
                    # sxprint lsnake
                    if (lsum > maxsum):
                        maxsum = lsum
                        init = m
                        snake = [lsnake[i] for i in range(len(d))]
                sxprint("  Initial image selected : ", init, maxsum)
                sxprint(lsnake)
                for m in range(len(d)):
                    d[snake[m]].write_image(new_stack, m)
Пример #9
0
def main():
    from sp_utilities import get_input_from_string
    progname = os.path.basename(sys.argv[0])
    usage = progname + " stack output_average --radius=particle_radius --xr=xr --yr=yr --ts=ts --thld_err=thld_err --num_ali=num_ali --fl=fl --aa=aa --CTF --verbose --stables"
    parser = OptionParser(usage, version=SPARXVERSION)
    parser.add_option("--radius",
                      type="int",
                      default=-1,
                      help=" particle radius for alignment")
    parser.add_option(
        "--xr",
        type="string",
        default="2 1",
        help=
        "range for translation search in x direction, search is +/xr (default 2,1)"
    )
    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 (default: 1,0.5)"
    )
    parser.add_option("--thld_err",
                      type="float",
                      default=0.7,
                      help="threshld of pixel error (default = 0.75)")
    parser.add_option(
        "--num_ali",
        type="int",
        default=5,
        help="number of alignments performed for stability (default = 5)")
    parser.add_option("--maxit",
                      type="int",
                      default=30,
                      help="number of iterations for each xr (default = 30)")
    parser.add_option(
        "--fl",
        type="float",
        default=0.45,
        help=
        "cut-off frequency of hyperbolic tangent low-pass Fourier filter (default = 0.3)"
    )
    parser.add_option(
        "--aa",
        type="float",
        default=0.2,
        help=
        "fall-off of hyperbolic tangent low-pass Fourier filter (default = 0.2)"
    )
    parser.add_option("--CTF",
                      action="store_true",
                      default=False,
                      help="Use CTF correction during the alignment ")
    parser.add_option("--verbose",
                      action="store_true",
                      default=False,
                      help="print individual pixel error (default = False)")
    parser.add_option(
        "--stables",
        action="store_true",
        default=False,
        help="output the stable particles number in file (default = False)")
    parser.add_option(
        "--method",
        type="string",
        default=" ",
        help="SHC (standard method is default when flag is ommitted)")

    (options, args) = parser.parse_args()

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

        from sp_applications import within_group_refinement, ali2d_ras
        from sp_pixel_error import multi_align_stability
        from sp_utilities import write_text_file, write_text_row

        sp_global_def.BATCH = True

        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)

        class_data = EMData.read_images(args[0])

        nx = class_data[0].get_xsize()
        ou = options.radius
        num_ali = options.num_ali
        if ou == -1: ou = nx / 2 - 2
        from sp_utilities import model_circle, get_params2D, set_params2D
        mask = model_circle(ou, nx, nx)

        if options.CTF:
            from sp_filter import filt_ctf
            for im in range(len(class_data)):
                #  Flip phases
                class_data[im] = filt_ctf(class_data[im],
                                          class_data[im].get_attr("ctf"),
                                          binary=1)
        for im in class_data:
            im.set_attr("previousmax", -1.0e10)
            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])
        all_ali_params = []

        for ii in range(num_ali):
            ali_params = []
            if options.verbose:
                ALPHA = []
                SX = []
                SY = []
                MIRROR = []
            if (xrng[0] == 0.0 and yrng[0] == 0.0):
                avet = ali2d_ras(class_data, randomize = True, ir = 1, ou = ou, rs = 1, step = 1.0, dst = 90.0, \
                  maxit = options.maxit, check_mirror = True, FH=options.fl, FF=options.aa)
            else:
                avet = within_group_refinement(class_data, mask, True, 1, ou, 1, xrng, yrng, step, 90.0, \
                  maxit = options.maxit, FH=options.fl, FF=options.aa, method = options.method)
                from sp_utilities import info
                #print "  avet  ",info(avet)
            for im in class_data:
                alpha, sx, sy, mirror, scale = get_params2D(im)
                ali_params.extend([alpha, sx, sy, mirror])
                if options.verbose:
                    ALPHA.append(alpha)
                    SX.append(sx)
                    SY.append(sy)
                    MIRROR.append(mirror)
            all_ali_params.append(ali_params)
            if options.verbose:
                write_text_file([ALPHA, SX, SY, MIRROR],
                                "ali_params_run_%d" % ii)
        """
		avet = class_data[0]
		from sp_utilities import read_text_file
		all_ali_params = []
		for ii in xrange(5):
			temp = read_text_file( "ali_params_run_%d"%ii,-1)
			uuu = []
			for k in xrange(len(temp[0])):
				uuu.extend([temp[0][k],temp[1][k],temp[2][k],temp[3][k]])
			all_ali_params.append(uuu)


		"""

        stable_set, mir_stab_rate, pix_err = multi_align_stability(
            all_ali_params, 0.0, 10000.0, options.thld_err, options.verbose,
            2 * ou + 1)
        sxprint("%4s %20s %20s %20s %30s %6.2f" %
                ("", "Size of set", "Size of stable set", "Mirror stab rate",
                 "Pixel error prior to pruning the set above threshold of",
                 options.thld_err))
        sxprint("Average stat: %10d %20d %20.2f   %15.2f" %
                (len(class_data), len(stable_set), mir_stab_rate, pix_err))
        if (len(stable_set) > 0):
            if options.stables:
                stab_mem = [[0, 0.0, 0] for j in range(len(stable_set))]
                for j in range(len(stable_set)):
                    stab_mem[j] = [int(stable_set[j][1]), stable_set[j][0], j]
                write_text_row(stab_mem, "stable_particles.txt")

            stable_set_id = []
            particle_pixerr = []
            for s in stable_set:
                stable_set_id.append(s[1])
                particle_pixerr.append(s[0])
            from sp_fundamentals import rot_shift2D
            avet.to_zero()
            l = -1
            sxprint("average parameters:  angle, x-shift, y-shift, mirror")
            for j in stable_set_id:
                l += 1
                sxprint(" %4d  %4d  %12.2f %12.2f %12.2f        %1d" %
                        (l, j, stable_set[l][2][0], stable_set[l][2][1],
                         stable_set[l][2][2], int(stable_set[l][2][3])))
                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])
            avet /= (l + 1)
            avet.set_attr('members', stable_set_id)
            avet.set_attr('pix_err', pix_err)
            avet.set_attr('pixerr', particle_pixerr)
            avet.write_image(args[1])

        sp_global_def.BATCH = False