def filterlocal(ui, vi, m, falloff, myid, main_node, number_of_proc): if myid == main_node: nx = vi.get_xsize() ny = vi.get_ysize() nz = vi.get_zsize() # Round all resolution numbers to two digits for x in range(nx): for y in range(ny): for z in range(nz): ui.set_value_at_fast(x, y, z, round(ui.get_value_at(x, y, z), 2)) dis = [nx, ny, nz] else: falloff = 0.0 radius = 0 dis = [0, 0, 0] falloff = sp_utilities.bcast_number_to_all(falloff, main_node) dis = sp_utilities.bcast_list_to_all(dis, myid, source_node=main_node) if myid != main_node: nx = int(dis[0]) ny = int(dis[1]) nz = int(dis[2]) vi = sp_utilities.model_blank(nx, ny, nz) ui = sp_utilities.model_blank(nx, ny, nz) sp_utilities.bcast_EMData_to_all(vi, myid, main_node) sp_utilities.bcast_EMData_to_all(ui, myid, main_node) sp_fundamentals.fftip(vi) # volume to be filtered st = EMAN2_cppwrap.Util.infomask(ui, m, True) filteredvol = sp_utilities.model_blank(nx, ny, nz) cutoff = max(st[2] - 0.01, 0.0) while cutoff < st[3]: cutoff = round(cutoff + 0.01, 2) # if(myid == main_node): print cutoff,st pt = EMAN2_cppwrap.Util.infomask( sp_morphology.threshold_outside(ui, cutoff - 0.00501, cutoff + 0.005), m, True, ) # Ideally, one would want to check only slices in question... if pt[0] != 0.0: # print cutoff,pt[0] vovo = sp_fundamentals.fft(filt_tanl(vi, cutoff, falloff)) for z in range(myid, nz, number_of_proc): for x in range(nx): for y in range(ny): if m.get_value_at(x, y, z) > 0.5: if round(ui.get_value_at(x, y, z), 2) == cutoff: filteredvol.set_value_at_fast( x, y, z, vovo.get_value_at(x, y, z) ) mpi.mpi_barrier(mpi.MPI_COMM_WORLD) sp_utilities.reduce_EMData_to_root(filteredvol, myid, main_node, mpi.MPI_COMM_WORLD) return filteredvol
def prgq(volft, kb, nx, delta, ref_a, sym, MPI=False): """ Generate set of projections based on even angles The command returns list of ffts of projections """ from sp_projection import prep_vol, prgs from sp_applications import MPI_start_end from sp_utilities import even_angles, model_blank from sp_fundamentals import fft # generate list of Eulerian angles for reference projections # phi, theta, psi mode = "F" ref_angles = even_angles(delta, symmetry=sym, method=ref_a, phiEqpsi="Minus") cnx = nx // 2 + 1 cny = nx // 2 + 1 num_ref = len(ref_angles) if MPI: from mpi import mpi_comm_rank, mpi_comm_size, MPI_COMM_WORLD myid = mpi_comm_rank(MPI_COMM_WORLD) ncpu = mpi_comm_size(MPI_COMM_WORLD) else: ncpu = 1 myid = 0 from sp_applications import MPI_start_end ref_start, ref_end = MPI_start_end(num_ref, ncpu, myid) prjref = [ ] # list of (image objects) reference projections in Fourier representation for i in range(num_ref): prjref.append(model_blank( nx, nx)) # I am not sure why is that necessary, why not put None's?? for i in range(ref_start, ref_end): prjref[i] = prgs( volft, kb, [ref_angles[i][0], ref_angles[i][1], ref_angles[i][2], 0.0, 0.0]) if MPI: from sp_utilities import bcast_EMData_to_all for i in range(num_ref): for j in range(ncpu): ref_start, ref_end = MPI_start_end(num_ref, ncpu, j) if i >= ref_start and i < ref_end: rootid = j bcast_EMData_to_all(prjref[i], myid, rootid) for i in range(len(ref_angles)): prjref[i].set_attr_dict({ "phi": ref_angles[i][0], "theta": ref_angles[i][1], "psi": ref_angles[i][2] }) return prjref
def plot_angles(agls, nx=256): from math import cos, sin, fmod, pi, radians from sp_utilities import model_blank # var im = model_blank(nx, nx) """ c = 2 kc = 10 # draw reperes for i in xrange(nx): im.set_value_at(i, int(nx / 2.0), 0.006) im.set_value_at(int(nx / 2.0), i, 0.006) # draw the circles lth = range(0, 90, kc) lth.append(90) for th in lth: if th == 90: color = 0.03 else: color = 0.006 rc = sin((float(th) / 180.0) * pi) rc *= (nx - 1) for n in xrange(3600): a = (n / 1800.0) * pi px = nx / 2.0 + (rc - 1) / 2.0 * cos(a) py = nx / 2.0 + (rc - 1) / 2.0 * sin(a) im.set_value_at(int(px), int(py), color) """ # for each angles plot on circle area # agsl: [phi, theta, psi] ri = nx // 2 rr = ri - 1 conv = pi / 180.0 for i in range(len(agls)): if agls[i][1] > 90.0: agls[i][0] = agls[i][0] + 180.0 agls[i][1] = 180.0 - float(agls[i][1]) rc = rr * sin(radians(agls[i][1])) rd = radians(agls[i][0]) px = ri + rc * cos(rd) py = ri + rc * sin(rd) px = min(max(int(px + 0.5), 0), nx - 1) py = min(max(int(py + 0.5), 0), nx - 1) im.set_value_at(px, py, 1.0 + im.get_value_at(px, py)) return im
def makeAngRes(freqvol, nx, ny, nz, pxSize, freq_to_real=True): outAngResVol = sp_utilities.model_blank(nx, ny, nz) data_in = freqvol.get_3dview() data_out = outAngResVol.get_3dview() if freq_to_real: mask = data_in > 0.0 else: mask = data_in > 0.0 data_out[mask] = pxSize / data_in[mask] return outAngResVol
def montage2(inputstack, ncol, marginwidth=0, bkgd=0, outfile=None): """ Generates montage of images into one image. Adapted from sxmontage.py Arguments: inputstack : Stack of input images to merge into montage ncol : Number of images per row marginwidth : Margin width, pixels bkgd : Background value of montage outfile : Optional output file with montage output Returns: montage : EMData object of image montage """ if isinstance(inputstack, str): inputstack = EMData.read_images(inputstack) # Get single-image dimensions nx = inputstack[0].get_xsize() ny = inputstack[0].get_ysize() # Get number of images and calculate montage dimensions numimgs = len(inputstack) numrows = (numimgs - 1) / ncol + 1 # Create blank image montage_xdim = (nx + marginwidth) * ncol montage_ydim = (ny + marginwidth) * numrows montage = model_blank(montage_xdim, montage_ydim, 1, bkgd) # Loop through images for imgnum in range(numimgs): # Horizontal grid position is image# modulo NCOL colnum = imgnum % ncol # Montage is numbered from the top down rownum = numrows - 1 - imgnum / ncol xoffset = colnum * (nx + marginwidth) yoffset = rownum * (ny + marginwidth) insert_image(inputstack[imgnum], montage, xoffset, yoffset) if outfile: montage.write_image(outfile) return montage
def test_input_image_returns_values_freq_to_real(self): nx = 10 ny = 10 nz = 10 apix = 2 test_data = numpy.arange(nx * ny * nz, dtype=numpy.float32).reshape( nx, ny, nz ) / (2 * nx * ny * nz) mask = test_data > 0 blank_data = sp_utilities.model_blank(nx, ny, nz) data_in = blank_data.get_3dview() data_in[...] = copy.deepcopy(test_data) returned_data = sp_locres.makeAngRes(blank_data, nx, ny, nz, apix) expected_data = copy.deepcopy(test_data) expected_data[mask] = apix / test_data[mask] assert numpy.array_equal(expected_data, returned_data.get_3dview())
def test_input_image_returns_values_real_to_freq(self): nx = 10 ny = 10 nz = 10 apix = 2 test_data = numpy.arange(nx * ny * nz, dtype=numpy.float32).reshape(nx, ny, nz) mask = test_data >= 2 * apix blank_data = sp_utilities.model_blank(nx, ny, nz) data_in = blank_data.get_3dview() data_in[...] = copy.deepcopy(test_data) returned_data = sp_locres.makeAngRes(blank_data, nx, ny, nz, apix, False) expected_data = copy.deepcopy(test_data) expected_data[mask] = apix / expected_data[mask] expected_data[~mask] = 0 print("EXP", expected_data) print("RET", returned_data.get_3dview()) assert numpy.array_equal(expected_data, returned_data.get_3dview())
def filterlocal(ui, vi, m, falloff, myid, main_node, number_of_proc): from mpi import mpi_init, mpi_comm_size, mpi_comm_rank, MPI_COMM_WORLD from mpi import mpi_reduce, mpi_bcast, mpi_barrier, mpi_gatherv, mpi_send, mpi_recv from mpi import MPI_SUM, MPI_FLOAT, MPI_INT from sp_utilities import bcast_number_to_all, bcast_list_to_all, model_blank, bcast_EMData_to_all, reduce_EMData_to_root from sp_morphology import threshold_outside from sp_filter import filt_tanl from sp_fundamentals import fft, fftip if(myid == main_node): nx = vi.get_xsize() ny = vi.get_ysize() nz = vi.get_zsize() # Round all resolution numbers to two digits for x in range(nx): for y in range(ny): for z in range(nz): ui.set_value_at_fast( x,y,z, round(ui.get_value_at(x,y,z), 2) ) dis = [nx,ny,nz] else: falloff = 0.0 radius = 0 dis = [0,0,0] falloff = bcast_number_to_all(falloff, main_node) dis = bcast_list_to_all(dis, myid, source_node = main_node) if(myid != main_node): nx = int(dis[0]) ny = int(dis[1]) nz = int(dis[2]) vi = model_blank(nx,ny,nz) ui = model_blank(nx,ny,nz) bcast_EMData_to_all(vi, myid, main_node) bcast_EMData_to_all(ui, myid, main_node) fftip(vi) # volume to be filtered st = Util.infomask(ui, m, True) filteredvol = model_blank(nx,ny,nz) cutoff = max(st[2] - 0.01,0.0) while(cutoff < st[3] ): cutoff = round(cutoff + 0.01, 2) #if(myid == main_node): print cutoff,st pt = Util.infomask( threshold_outside(ui, cutoff - 0.00501, cutoff + 0.005), m, True) # Ideally, one would want to check only slices in question... if(pt[0] != 0.0): #print cutoff,pt[0] vovo = fft( filt_tanl(vi, cutoff, falloff) ) for z in range(myid, nz, number_of_proc): for x in range(nx): for y in range(ny): if(m.get_value_at(x,y,z) > 0.5): if(round(ui.get_value_at(x,y,z),2) == cutoff): filteredvol.set_value_at_fast(x,y,z,vovo.get_value_at(x,y,z)) mpi_barrier(MPI_COMM_WORLD) reduce_EMData_to_root(filteredvol, myid, main_node, MPI_COMM_WORLD) return filteredvol
def write_montage_file(stack, montage_file, N, gx, gy, bg, scale, number, begin_zero): from sp_utilities import model_blank font = [ "0011100010001010000011000001100000110000011000001100000101000100011100", "0001000001100001010001001000000100000010000001000000100000010001111111", "0111110100000110000010000001000001000001000011000010000001000001111111", "1111111000000100000100000100000111000000010000001000000110000010111110", "0000010000011000010100010010010001010000101111111000001000000100000010", "1111111100000010000001011110110000100000010000001000000110000010111110", "0011110010000010000001000000101111101100000110000011000001100000101111", "1111111000000100000010000010000010000100000100000010000010000010000000", "0011100010001010000010100010001110001000101000001100000101000010011100", "0111110100000011000001100000110000110111101000000100000010000010011110" ] if gy == -1: gy = gx data = EMData.read_images(stack) if scale: for im in data: st = Util.infomask(im, None, True) im -= st[0] im /= st[1] nx = data[0].get_xsize() ny = data[0].get_ysize() K = len(data) M = (K - 1) / N + 1 NX = (nx + gx) * N NY = (ny + gy) * M maxn = -1.e-20 minn = 1.e+20 avgn = 0 for im in data: st = Util.infomask(im, None, True) avgn += st[0] if st[3] > maxn: maxn = st[3] if st[2] < minn: minn = st[2] avgn /= K if bg == 0: bk = minn elif bg == 1: bk = maxn elif bg == 2: bk = 0 else: bk = avgn montage = model_blank(NX, NY, 1, bk) for i in range(K): col = i % N row = M - 1 - i / N for s in range(nx): for t in range(ny): v = data[i].get_value_at(s, t) montage.set_value_at(col * (nx + gx) + s, row * (ny + gy) + t, v) if number: for s in range(10): for t in range(7): if font[i % 10][s * 7 + t] == '1': montage.set_value_at(col * (nx + gx) + 2 + t, row * (ny + gy) + 2 + 10 - s, maxn) montage.write_image(montage_file)
def align2d_direct3(input_images, refim, xrng=1, yrng=1, psimax=180, psistep=1, ou=-1, CTF=None): nx = input_images[0].get_xsize() if ou < 0: ou = old_div(nx, 2) - 1 mask = sp_utilities.model_circle(ou, nx, nx) nk = int(old_div(psimax, psistep)) nm = 2 * nk + 1 nc = nk + 1 refs = [None] * nm * 2 for i in range(nm): temp = sp_fundamentals.rot_shift2D(refim, (i - nc) * psistep) * mask refs[2 * i] = [ sp_fundamentals.fft(temp), sp_fundamentals.fft(sp_fundamentals.mirror(temp)), ] temp = sp_fundamentals.rot_shift2D(refim, (i - nc) * psistep + 180.0) * mask refs[2 * i + 1] = [ sp_fundamentals.fft(temp), sp_fundamentals.fft(sp_fundamentals.mirror(temp)), ] del temp results = [] mir = 0 for image in input_images: if CTF: ims = sp_filter.filt_ctf(sp_fundamentals.fft(image), image.get_attr("ctf")) else: ims = sp_fundamentals.fft(image) ama = -1.0e23 bang = 0.0 bsx = 0.0 bsy = 0.0 for i in range(nm * 2): for mirror_flag in [0, 1]: c = sp_fundamentals.ccf(ims, refs[i][mirror_flag]) w = EMAN2_cppwrap.Util.window(c, 2 * xrng + 1, 2 * yrng + 1) pp = sp_utilities.peak_search(w)[0] px = int(pp[4]) py = int(pp[5]) if pp[0] == 1.0 and px == 0 and py == 0: pass # XSH, YSH, PEAKV = 0.,0.,0. else: ww = sp_utilities.model_blank(3, 3) ux = int(pp[1]) uy = int(pp[2]) for k in range(3): for l in range(3): ww[k, l] = w[k + ux - 1, l + uy - 1] XSH, YSH, PEAKV = parabl(ww) # print i,pp[-1],XSH, YSH,px+XSH, py+YSH, PEAKV if PEAKV > ama: ama = PEAKV bsx = px + round(XSH, 2) bsy = py + round(YSH, 2) bang = i mir = mirror_flag # returned parameters have to be inverted bang = (old_div(bang, 2) - nc) * psistep + 180.0 * (bang % 2) bang, bsx, bsy, _ = sp_utilities.inverse_transform2( bang, (1 - 2 * mir) * bsx, bsy, mir) results.append([bang, bsx, bsy, mir, ama]) return results
def main(): arglist = [] for arg in sys.argv: arglist.append(arg) progname = optparse.os.path.basename(arglist[0]) usage = progname + """ inputvolume locresvolume maskfile outputfile --radius --falloff --MPI Locally filer a volume based on local resolution volume (sxlocres.py) within area outlined by the maskfile """ parser = optparse.OptionParser(usage, version=sp_global_def.SPARXVERSION) parser.add_option( "--radius", type="int", default=-1, help= "if there is no maskfile, sphere with r=radius will be used, by default the radius is nx/2-1" ) parser.add_option("--falloff", type="float", default=0.1, help="falloff of tanl filter (default 0.1)") parser.add_option("--MPI", action="store_true", default=False, help="use MPI version") (options, args) = parser.parse_args(arglist[1:]) if len(args) < 3 or len(args) > 4: sp_global_def.sxprint("See usage " + usage) sp_global_def.ERROR( "Wrong number of parameters. Please see usage information above.") return if sp_global_def.CACHE_DISABLE: pass #IMPORTIMPORTIMPORT from sp_utilities import disable_bdb_cache sp_utilities.disable_bdb_cache() if options.MPI: number_of_proc = mpi.mpi_comm_size(mpi.MPI_COMM_WORLD) myid = mpi.mpi_comm_rank(mpi.MPI_COMM_WORLD) main_node = 0 if (myid == main_node): #print sys.argv vi = sp_utilities.get_im(sys.argv[1]) ui = sp_utilities.get_im(sys.argv[2]) #print Util.infomask(ui, None, True) radius = options.radius nx = vi.get_xsize() ny = vi.get_ysize() nz = vi.get_zsize() dis = [nx, ny, nz] else: falloff = 0.0 radius = 0 dis = [0, 0, 0] vi = None ui = None dis = sp_utilities.bcast_list_to_all(dis, myid, source_node=main_node) if (myid != main_node): nx = int(dis[0]) ny = int(dis[1]) nz = int(dis[2]) radius = sp_utilities.bcast_number_to_all(radius, main_node) if len(args) == 3: if (radius == -1): radius = min(nx, ny, nz) // 2 - 1 m = sp_utilities.model_circle(radius, nx, ny, nz) outvol = args[2] elif len(args) == 4: if (myid == main_node): m = sp_morphology.binarize(sp_utilities.get_im(args[2]), 0.5) else: m = sp_utilities.model_blank(nx, ny, nz) outvol = args[3] sp_utilities.bcast_EMData_to_all(m, myid, main_node) pass #IMPORTIMPORTIMPORT from sp_filter import filterlocal filteredvol = sp_filter.filterlocal(ui, vi, m, options.falloff, myid, main_node, number_of_proc) if (myid == 0): filteredvol.write_image(outvol) else: vi = sp_utilities.get_im(args[0]) ui = sp_utilities.get_im( args[1] ) # resolution volume, values are assumed to be from 0 to 0.5 nn = vi.get_xsize() falloff = options.falloff if len(args) == 3: radius = options.radius if (radius == -1): radius = nn // 2 - 1 m = sp_utilities.model_circle(radius, nn, nn, nn) outvol = args[2] elif len(args) == 4: m = sp_morphology.binarize(sp_utilities.get_im(args[2]), 0.5) outvol = args[3] sp_fundamentals.fftip(vi) # this is the volume to be filtered # Round all resolution numbers to two digits for x in range(nn): for y in range(nn): for z in range(nn): ui.set_value_at_fast(x, y, z, round(ui.get_value_at(x, y, z), 2)) st = EMAN2_cppwrap.Util.infomask(ui, m, True) filteredvol = sp_utilities.model_blank(nn, nn, nn) cutoff = max(st[2] - 0.01, 0.0) while (cutoff < st[3]): cutoff = round(cutoff + 0.01, 2) pt = EMAN2_cppwrap.Util.infomask( sp_morphology.threshold_outside(ui, cutoff - 0.00501, cutoff + 0.005), m, True) if (pt[0] != 0.0): vovo = sp_fundamentals.fft( sp_filter.filt_tanl(vi, cutoff, falloff)) for x in range(nn): for y in range(nn): for z in range(nn): if (m.get_value_at(x, y, z) > 0.5): if (round(ui.get_value_at(x, y, z), 2) == cutoff): filteredvol.set_value_at_fast( x, y, z, vovo.get_value_at(x, y, z)) sp_global_def.write_command(optparse.os.path.dirname(outvol)) filteredvol.write_image(outvol)
def main(): """ Main function. Arguments: None Returns: None """ command_args = parse_command_line() # Import volume sp_global_def.sxprint("Import volume.") input_vol = sp_utilities.get_im(command_args.input_volume) # Sanity checks sanity_checks(command_args, input_vol) try: os.makedirs(command_args.output_dir) except OSError: sp_global_def.sxprint( "Output directory already exists. No need to create it.") else: sp_global_def.sxprint("Created output directory.") sp_global_def.write_command(command_args.output_dir) output_prefix = os.path.join(command_args.output_dir, command_args.prefix) # Filter volume if specified if command_args.low_pass_filter_resolution is not None: sp_global_def.sxprint("Filter volume to {0}A.".format( command_args.low_pass_filter_resolution)) input_vol = sp_filter.filt_tanl( input_vol, old_div(command_args.pixel_size, command_args.low_pass_filter_resolution), command_args.low_pass_filter_falloff, ) input_vol.write_image(output_prefix + "_filtered_volume.hdf") else: sp_global_def.sxprint("Skip filter volume.") # Create a mask based on the filtered volume sp_global_def.sxprint("Create mask") density_threshold = -9999.0 nsigma = 1.0 if command_args.mol_mass: density_threshold = input_vol.find_3d_threshold( command_args.mol_mass, command_args.pixel_size) sp_global_def.sxprint( "Mask molecular mass translated into binary threshold: ", density_threshold) elif command_args.threshold: density_threshold = command_args.threshold elif command_args.nsigma: nsigma = command_args.nsigma else: assert False if command_args.edge_type == "cosine": mode = "C" elif command_args.edge_type == "gaussian": mode = "G" else: assert False mask_first = sp_morphology.adaptive_mask_scipy( input_vol, nsigma=nsigma, threshold=density_threshold, ndilation=command_args.ndilation, nerosion=command_args.nerosion, edge_width=command_args.edge_width, allow_disconnected=command_args.allow_disconnected, mode=mode, do_approx=command_args.do_old, do_fill=command_args.fill_mask, do_print=True, ) # Create a second mask based on the filtered volume s_mask = None s_density_threshold = 1 s_nsigma = 1.0 if command_args.second_mask is not None: sp_global_def.sxprint("Prepare second mask") s_mask = sp_utilities.get_im(command_args.second_mask) s_density_threshold = -9999.0 s_nsigma = 1.0 if command_args.s_mol_mass: s_density_threshold = input_vol.find_3d_threshold( command_args.s_mol_mass, command_args.s_pixel_size) sp_global_def.sxprint( "Second mask molecular mass translated into binary threshold: ", s_density_threshold, ) elif command_args.s_threshold: s_density_threshold = command_args.s_threshold elif command_args.s_nsigma: s_nsigma = command_args.s_nsigma else: assert False elif command_args.second_mask_shape is not None: sp_global_def.sxprint("Prepare second mask") nx = mask_first.get_xsize() ny = mask_first.get_ysize() nz = mask_first.get_zsize() if command_args.second_mask_shape == "cube": s_nx = command_args.s_nx s_ny = command_args.s_ny s_nz = command_args.s_nz s_mask = sp_utilities.model_blank(s_nx, s_ny, s_nz, 1) elif command_args.second_mask_shape == "cylinder": s_radius = command_args.s_radius s_nx = command_args.s_nx s_ny = command_args.s_ny s_nz = command_args.s_nz try: s_mask = sp_utilities.model_cylinder(s_radius, s_nx, s_ny, s_nz) except RuntimeError as e: sp_global_def.sxprint( "An error occured! Please check the error log") raise elif command_args.second_mask_shape == "sphere": s_radius = command_args.s_radius s_nx = command_args.s_nx s_ny = command_args.s_ny s_nz = command_args.s_nz try: s_mask = sp_utilities.model_circle(s_radius, s_nx, s_ny, s_nz) except RuntimeError as e: sp_global_def.sxprint( "An error occured! Please check the error log") raise else: assert False s_mask = sp_utilities.pad(s_mask, nx, ny, nz, 0) if s_mask is not None: sp_global_def.sxprint("Create second mask") if command_args.s_edge_type == "cosine": mode = "C" elif command_args.s_edge_type == "gaussian": mode = "G" else: assert False s_mask = sp_morphology.adaptive_mask_scipy( s_mask, nsigma=s_nsigma, threshold=s_density_threshold, ndilation=command_args.s_ndilation, nerosion=command_args.s_nerosion, edge_width=command_args.s_edge_width, allow_disconnected=command_args.s_allow_disconnected, mode=mode, do_approx=command_args.s_do_old, do_fill=command_args.s_fill_mask, do_print=True, ) if command_args.s_invert: s_mask = 1 - s_mask sp_global_def.sxprint("Write outputs.") mask_first.write_image(output_prefix + "_mask_first.hdf") s_mask.write_image(output_prefix + "_mask_second.hdf") masked_combined = mask_first * s_mask masked_combined.write_image(output_prefix + "_mask.hdf") else: sp_global_def.sxprint("Write outputs.") mask_first.write_image(output_prefix + "_mask.hdf")
def recons3d_4nn_ctf_MPI( myid, prjlist, snr=1.0, sign=1, symmetry="c1", finfo=None, npad=2, xysize=-1, zsize=-1, mpi_comm=None, smearstep=0.0, ): """ recons3d_4nn_ctf - calculate CTF-corrected 3-D reconstruction from a set of projections using three Eulerian angles, two shifts, and CTF settings for each projeciton image Input stack: name of the stack file containing projection data, projections have to be squares list_proj: list of projections to be included in the reconstruction or image iterator snr: Signal-to-Noise Ratio of the data sign: sign of the CTF symmetry: point-group symmetry to be enforced, each projection will enter the reconstruction in all symmetry-related directions. """ if mpi_comm == None: mpi_comm = mpi.MPI_COMM_WORLD if type(prjlist) == list: prjlist = sp_utilities.iterImagesList(prjlist) if not prjlist.goToNext(): sp_global_def.ERROR("empty input list", "recons3d_4nn_ctf_MPI", 1) imgsize = prjlist.image().get_xsize() if prjlist.image().get_ysize() != imgsize: imgsize = max(imgsize, prjlist.image().get_ysize()) dopad = True else: dopad = False prjlist.goToPrev() fftvol = EMAN2_cppwrap.EMData() if smearstep > 0.0: # if myid == 0: print " Setting smear in prepare_recons_ctf" ns = 1 smear = [] for j in range(-ns, ns + 1): if j != 0: for i in range(-ns, ns + 1): for k in range(-ns, ns + 1): smear += [ i * smearstep, j * smearstep, k * smearstep, 1.0 ] # Deal with theta = 0.0 cases prj = [] for i in range(-ns, ns + 1): for k in range(-ns, ns + 1): prj.append(i + k) for i in range(-2 * ns, 2 * ns + 1, 1): smear += [i * smearstep, 0.0, 0.0, float(prj.count(i))] # if myid == 0: print " Smear ",smear fftvol.set_attr("smear", smear) weight = EMAN2_cppwrap.EMData() if xysize == -1 and zsize == -1: params = { "size": imgsize, "npad": npad, "snr": snr, "sign": sign, "symmetry": symmetry, "fftvol": fftvol, "weight": weight, } r = EMAN2_cppwrap.Reconstructors.get("nn4_ctf", params) else: if xysize != -1 and zsize != -1: rx = old_div(float(xysize), imgsize) ry = old_div(float(xysize), imgsize) rz = old_div(float(zsize), imgsize) elif xysize != -1: rx = old_div(float(xysize), imgsize) ry = old_div(float(xysize), imgsize) rz = 1.0 else: rx = 1.0 ry = 1.0 rz = old_div(float(zsize), imgsize) # There is an error here with sizeprojection PAP 10/22/2014 params = { "size": sizeprojection, "npad": npad, "snr": snr, "sign": sign, "symmetry": symmetry, "fftvol": fftvol, "weight": weight, "xratio": rx, "yratio": ry, "zratio": rz, } r = EMAN2_cppwrap.Reconstructors.get("nn4_ctf_rect", params) r.setup() # if not (finfo is None): nimg = 0 while prjlist.goToNext(): prj = prjlist.image() if dopad: prj = sp_utilities.pad(prj, imgsize, imgsize, 1, "circumference") # if params: insert_slices(r, prj) if not (finfo is None): nimg += 1 finfo.write(" %4d inserted\n" % (nimg)) finfo.flush() del sp_utilities.pad if not (finfo is None): finfo.write("begin reduce\n") finfo.flush() sp_utilities.reduce_EMData_to_root(fftvol, myid, comm=mpi_comm) sp_utilities.reduce_EMData_to_root(weight, myid, comm=mpi_comm) if not (finfo is None): finfo.write("after reduce\n") finfo.flush() if myid == 0: dummy = r.finish(True) else: if xysize == -1 and zsize == -1: fftvol = sp_utilities.model_blank(imgsize, imgsize, imgsize) else: if zsize == -1: fftvol = sp_utilities.model_blank(xysize, xysize, imgsize) elif xysize == -1: fftvol = sp_utilities.model_blank(imgsize, imgsize, zsize) else: fftvol = sp_utilities.model_blank(xysize, xysize, zsize) return fftvol
def recons3d_trl_struct_MPI( myid, main_node, prjlist, paramstructure, refang, rshifts_shrank, delta, upweighted=True, mpi_comm=None, CTF=True, target_size=-1, avgnorm=1.0, norm_per_particle=None, ): """ recons3d_4nn_ctf - calculate CTF-corrected 3-D reconstruction from a set of projections using three Eulerian angles, two shifts, and CTF settings for each projeciton image Input list_of_prjlist: list of lists of projections to be included in the reconstruction """ if mpi_comm == None: mpi_comm = mpi.MPI_COMM_WORLD refvol = sp_utilities.model_blank(target_size) refvol.set_attr("fudge", 1.0) if CTF: do_ctf = 1 else: do_ctf = 0 fftvol = EMAN2_cppwrap.EMData() weight = EMAN2_cppwrap.EMData() params = { "size": target_size, "npad": 2, "snr": 1.0, "sign": 1, "symmetry": "c1", "refvol": refvol, "fftvol": fftvol, "weight": weight, "do_ctf": do_ctf, } r = EMAN2_cppwrap.Reconstructors.get("nn4_ctfw", params) r.setup() if prjlist: if norm_per_particle == None: norm_per_particle = len(prjlist) * [1.0] nnx = prjlist[0].get_xsize() nny = prjlist[0].get_ysize() nshifts = len(rshifts_shrank) for im in range(len(prjlist)): # parse projection structure, generate three lists: # [ipsi+iang], [ishift], [probability] # Number of orientations for a given image numbor = len(paramstructure[im][2]) ipsiandiang = [ old_div(paramstructure[im][2][i][0], 1000) for i in range(numbor) ] allshifts = [ paramstructure[im][2][i][0] % 1000 for i in range(numbor) ] probs = [paramstructure[im][2][i][1] for i in range(numbor)] # Find unique projection directions tdir = list(set(ipsiandiang)) bckgn = prjlist[im].get_attr("bckgnoise") ct = prjlist[im].get_attr("ctf") # For each unique projection direction: data = [None] * nshifts for ii in range(len(tdir)): # Find the number of times given projection direction appears on the list, it is the number of different shifts associated with it. lshifts = sp_utilities.findall(tdir[ii], ipsiandiang) toprab = 0.0 for ki in range(len(lshifts)): toprab += probs[lshifts[ki]] recdata = EMAN2_cppwrap.EMData(nny, nny, 1, False) recdata.set_attr("is_complex", 0) for ki in range(len(lshifts)): lpt = allshifts[lshifts[ki]] if data[lpt] == None: data[lpt] = sp_fundamentals.fshift( prjlist[im], rshifts_shrank[lpt][0], rshifts_shrank[lpt][1]) data[lpt].set_attr("is_complex", 0) EMAN2_cppwrap.Util.add_img( recdata, EMAN2_cppwrap.Util.mult_scalar( data[lpt], old_div(probs[lshifts[ki]], toprab)), ) recdata.set_attr_dict({ "padffted": 1, "is_fftpad": 1, "is_fftodd": 0, "is_complex_ri": 1, "is_complex": 1, }) if not upweighted: recdata = sp_filter.filt_table(recdata, bckgn) recdata.set_attr_dict({"bckgnoise": bckgn, "ctf": ct}) ipsi = tdir[ii] % 100000 iang = old_div(tdir[ii], 100000) r.insert_slice( recdata, EMAN2_cppwrap.Transform({ "type": "spider", "phi": refang[iang][0], "theta": refang[iang][1], "psi": refang[iang][2] + ipsi * delta, }), old_div(toprab * avgnorm, norm_per_particle[im]), ) # clean stuff del bckgn, recdata, tdir, ipsiandiang, allshifts, probs sp_utilities.reduce_EMData_to_root(fftvol, myid, main_node, comm=mpi_comm) sp_utilities.reduce_EMData_to_root(weight, myid, main_node, comm=mpi_comm) if myid == main_node: dummy = r.finish(True) mpi.mpi_barrier(mpi_comm) if myid == main_node: return fftvol, weight, refvol else: return None, None, None
def recons3d_4nnw_MPI( myid, prjlist, bckgdata, snr=1.0, sign=1, symmetry="c1", finfo=None, npad=2, xysize=-1, zsize=-1, mpi_comm=None, smearstep=0.0, fsc=None, ): """ recons3d_4nn_ctf - calculate CTF-corrected 3-D reconstruction from a set of projections using three Eulerian angles, two shifts, and CTF settings for each projeciton image Input stack: name of the stack file containing projection data, projections have to be squares prjlist: list of projections to be included in the reconstruction or image iterator bckgdata = [get_im("tsd.hdf"),read_text_file("data_stamp.txt")] snr: Signal-to-Noise Ratio of the data sign: sign of the CTF symmetry: point-group symmetry to be enforced, each projection will enter the reconstruction in all symmetry-related directions. """ pass # IMPORTIMPORTIMPORT from sp_utilities import reduce_EMData_to_root, pad pass # IMPORTIMPORTIMPORT from EMAN2 import Reconstructors pass # IMPORTIMPORTIMPORT from sp_utilities import iterImagesList, set_params_proj, model_blank pass # IMPORTIMPORTIMPORT from mpi import MPI_COMM_WORLD pass # IMPORTIMPORTIMPORT import types if mpi_comm == None: mpi_comm = mpi.MPI_COMM_WORLD if type(prjlist) == list: prjlist = sp_utilities.iterImagesList(prjlist) if not prjlist.goToNext(): sp_global_def.ERROR("empty input list", "recons3d_4nnw_MPI", 1) imgsize = prjlist.image().get_xsize() if prjlist.image().get_ysize() != imgsize: imgsize = max(imgsize, prjlist.image().get_ysize()) dopad = True else: dopad = False prjlist.goToPrev() # Do the FSC shtick. bnx = old_div(imgsize * npad, 2) + 1 if fsc: pass # IMPORTIMPORTIMPORT from math import sqrt pass # IMPORTIMPORTIMPORT from sp_utilities import reshape_1d t = [0.0] * len(fsc) for i in range(len(fsc)): t[i] = min(max(fsc[i], 0.0), 0.999) t = sp_utilities.reshape_1d(t, len(t), npad * len(t)) refvol = sp_utilities.model_blank(bnx, 1, 1, 0.0) for i in range(len(fsc)): refvol.set_value_at(i, t[i]) else: refvol = sp_utilities.model_blank(bnx, 1, 1, 1.0) refvol.set_attr("fudge", 1.0) fftvol = EMAN2_cppwrap.EMData() weight = EMAN2_cppwrap.EMData() if smearstep > 0.0: # if myid == 0: print " Setting smear in prepare_recons_ctf" ns = 1 smear = [] for j in range(-ns, ns + 1): if j != 0: for i in range(-ns, ns + 1): for k in range(-ns, ns + 1): smear += [ i * smearstep, j * smearstep, k * smearstep, 1.0 ] # Deal with theta = 0.0 cases prj = [] for i in range(-ns, ns + 1): for k in range(-ns, ns + 1): prj.append(i + k) for i in range(-2 * ns, 2 * ns + 1, 1): smear += [i * smearstep, 0.0, 0.0, float(prj.count(i))] # if myid == 0: print " Smear ",smear fftvol.set_attr("smear", smear) if xysize == -1 and zsize == -1: params = { "size": imgsize, "npad": npad, "snr": snr, "sign": sign, "symmetry": symmetry, "refvol": refvol, "fftvol": fftvol, "weight": weight, } r = EMAN2_cppwrap.Reconstructors.get("nn4_ctfw", params) else: if xysize != -1 and zsize != -1: rx = old_div(float(xysize), imgsize) ry = old_div(float(xysize), imgsize) rz = old_div(float(zsize), imgsize) elif xysize != -1: rx = old_div(float(xysize), imgsize) ry = old_div(float(xysize), imgsize) rz = 1.0 else: rx = 1.0 ry = 1.0 rz = old_div(float(zsize), imgsize) # There is an error here with sizeprojection PAP 10/22/2014 params = { "size": sizeprojection, "npad": npad, "snr": snr, "sign": sign, "symmetry": symmetry, "fftvol": fftvol, "weight": weight, "xratio": rx, "yratio": ry, "zratio": rz, } r = EMAN2_cppwrap.Reconstructors.get("nn4_ctf_rect", params) r.setup() # from utilities import model_blank, get_im, read_text_file # bckgdata = [get_im("tsd.hdf"),read_text_file("data_stamp.txt")] nnx = bckgdata[0].get_xsize() nny = bckgdata[0].get_ysize() bckgnoise = [] for i in range(nny): prj = sp_utilities.model_blank(nnx) for k in range(nnx): prj[k] = bckgdata[0].get_value_at(k, i) bckgnoise.append(prj) datastamp = bckgdata[1] if not (finfo is None): nimg = 0 while prjlist.goToNext(): prj = prjlist.image() try: stmp = old_div(nnx, 0) stmp = prj.get_attr("ptcl_source_image") except: try: stmp = prj.get_attr("ctf") stmp = round(stmp.defocus, 4) except: sp_global_def.ERROR( "Either ptcl_source_image or ctf has to be present in the header.", "recons3d_4nnw_MPI", 1, myid, ) try: indx = datastamp.index(stmp) except: sp_global_def.ERROR("Problem with indexing ptcl_source_image.", "recons3d_4nnw_MPI", 1, myid) if dopad: prj = sp_utilities.pad(prj, imgsize, imgsize, 1, "circumference") prj.set_attr("bckgnoise", bckgnoise[indx]) insert_slices(r, prj) if not (finfo is None): nimg += 1 finfo.write(" %4d inserted\n" % (nimg)) finfo.flush() del sp_utilities.pad if not (finfo is None): finfo.write("begin reduce\n") finfo.flush() sp_utilities.reduce_EMData_to_root(fftvol, myid, comm=mpi_comm) sp_utilities.reduce_EMData_to_root(weight, myid, comm=mpi_comm) if not (finfo is None): finfo.write("after reduce\n") finfo.flush() if myid == 0: dummy = r.finish(True) else: pass # IMPORTIMPORTIMPORT from sp_utilities import model_blank if xysize == -1 and zsize == -1: fftvol = sp_utilities.model_blank(imgsize, imgsize, imgsize) else: if zsize == -1: fftvol = sp_utilities.model_blank(xysize, xysize, imgsize) elif xysize == -1: fftvol = sp_utilities.model_blank(imgsize, imgsize, zsize) else: fftvol = sp_utilities.model_blank(xysize, xysize, zsize) return fftvol
def recons3d_4nn_MPI( myid, prjlist, symmetry="c1", finfo=None, snr=1.0, npad=2, xysize=-1, zsize=-1, mpi_comm=None, ): if mpi_comm == None: mpi_comm = mpi.MPI_COMM_WORLD if type(prjlist) == list: prjlist = sp_utilities.iterImagesList(prjlist) if not prjlist.goToNext(): sp_global_def.ERROR("empty input list", "recons3d_4nn_MPI", 1) imgsize = prjlist.image().get_xsize() if prjlist.image().get_ysize() != imgsize: imgsize = max(imgsize, prjlist.image().get_ysize()) dopad = True else: dopad = False prjlist.goToPrev() fftvol = EMAN2_cppwrap.EMData() weight = EMAN2_cppwrap.EMData() if xysize == -1 and zsize == -1: params = { "size": imgsize, "npad": npad, "symmetry": symmetry, "fftvol": fftvol, "weight": weight, "snr": snr, } r = EMAN2_cppwrap.Reconstructors.get("nn4", params) else: if xysize != -1 and zsize != -1: rx = old_div(float(xysize), imgsize) ry = old_div(float(xysize), imgsize) rz = old_div(float(zsize), imgsize) elif xysize != -1: rx = old_div(float(xysize), imgsize) ry = old_div(float(xysize), imgsize) rz = 1.0 else: rx = 1.0 ry = 1.0 rz = old_div(float(zsize), imgsize) params = { "sizeprojection": imgsize, "npad": npad, "symmetry": symmetry, "fftvol": fftvol, "weight": weight, "xratio": rx, "yratio": ry, "zratio": rz, } r = EMAN2_cppwrap.Reconstructors.get("nn4_rect", params) r.setup() if not (finfo is None): nimg = 0 while prjlist.goToNext(): prj = prjlist.image() if dopad: prj = sp_utilities.pad(prj, imgsize, imgsize, 1, "circumference") insert_slices(r, prj) if not (finfo is None): nimg += 1 finfo.write("Image %4d inserted.\n" % (nimg)) finfo.flush() if not (finfo is None): finfo.write("Begin reducing ...\n") finfo.flush() sp_utilities.reduce_EMData_to_root(fftvol, myid, comm=mpi_comm) sp_utilities.reduce_EMData_to_root(weight, myid, comm=mpi_comm) if myid == 0: dummy = r.finish(True) else: if xysize == -1 and zsize == -1: fftvol = sp_utilities.model_blank(imgsize, imgsize, imgsize) else: if zsize == -1: fftvol = sp_utilities.model_blank(xysize, xysize, imgsize) elif xysize == -1: fftvol = sp_utilities.model_blank(imgsize, imgsize, zsize) else: fftvol = sp_utilities.model_blank(xysize, xysize, zsize) return fftvol
def multalign2d_scf(image, refrings, frotim, numr, xrng=-1, yrng=-1, ou=-1): nx = image.get_xsize() ny = image.get_xsize() if ou < 0: ou = min(old_div(nx, 2) - 1, old_div(ny, 2) - 1) if yrng < 0: yrng = xrng if ou < 2: sp_global_def.ERROR("Radius of the object (ou) has to be given", "align2d_scf", 1) sci = sp_fundamentals.scf(image) first_ring = 1 # center in SPIDER convention cnx = old_div(nx, 2) + 1 cny = old_div(ny, 2) + 1 cimage = EMAN2_cppwrap.Util.Polar2Dm(sci, cnx, cny, numr, "H") EMAN2_cppwrap.Util.Frngs(cimage, numr) mimage = EMAN2_cppwrap.Util.Polar2Dm(sp_fundamentals.mirror(sci), cnx, cny, numr, "H") EMAN2_cppwrap.Util.Frngs(mimage, numr) nrx = min(2 * (xrng + 1) + 1, ((old_div((nx - 2), 2)) * 2 + 1)) nry = min(2 * (yrng + 1) + 1, ((old_div((ny - 2), 2)) * 2 + 1)) totpeak = -1.0e23 for iki in range(len(refrings)): # print "TEMPLATE ",iki # Find angle retvals = EMAN2_cppwrap.Util.Crosrng_e(refrings[iki], cimage, numr, 0, 0.0) alpha1 = ang_n(retvals["tot"], "H", numr[-1]) peak1 = retvals["qn"] retvals = EMAN2_cppwrap.Util.Crosrng_e(refrings[iki], mimage, numr, 0, 0.0) alpha2 = ang_n(retvals["tot"], "H", numr[-1]) peak2 = retvals["qn"] # print alpha1, peak1 # print alpha2, peak2 if peak1 > peak2: mirr = 0 alpha = alpha1 else: mirr = 1 alpha = -alpha2 ccf1 = EMAN2_cppwrap.Util.window( sp_fundamentals.ccf( sp_fundamentals.rot_shift2D(image, alpha, 0.0, 0.0, mirr), frotim[iki]), nrx, nry, ) p1 = sp_utilities.peak_search(ccf1) ccf2 = EMAN2_cppwrap.Util.window( sp_fundamentals.ccf( sp_fundamentals.rot_shift2D(image, alpha + 180.0, 0.0, 0.0, mirr), frotim[iki], ), nrx, nry, ) p2 = sp_utilities.peak_search(ccf2) # print p1 # print p2 peak_val1 = p1[0][0] peak_val2 = p2[0][0] if peak_val1 > peak_val2: sxs = -p1[0][4] sys = -p1[0][5] cx = int(p1[0][1]) cy = int(p1[0][2]) peak = peak_val1 else: alpha += 180.0 sxs = -p2[0][4] sys = -p2[0][5] peak = peak_val2 cx = int(p2[0][1]) cy = int(p2[0][2]) ccf1 = ccf2 # print cx,cy z = sp_utilities.model_blank(3, 3) for i in range(3): for j in range(3): z[i, j] = ccf1[i + cx - 1, j + cy - 1] # print ccf1[cx,cy],z[1,1] XSH, YSH, PEAKV = parabl(z) # print PEAKV if PEAKV > totpeak: totpeak = PEAKV iref = iki if mirr == 1: sx = -sxs + XSH else: sx = sxs - XSH sy = sys - YSH talpha = alpha tmirr = mirr # print "BETTER",sx,sy,iref,talpha,tmirr,totpeak # return alpha, sx, sys-YSH, mirr, PEAKV return sx, sy, iref, talpha, tmirr, totpeak
def align2d_scf(image, refim, xrng=-1, yrng=-1, ou=-1): nx = image.get_xsize() ny = image.get_xsize() if ou < 0: ou = min(old_div(nx, 2) - 1, old_div(ny, 2) - 1) if yrng < 0: yrng = xrng if ou < 2: sp_global_def.ERROR("Radius of the object (ou) has to be given", "align2d_scf", 1) sci = sp_fundamentals.scf(image) scr = sp_fundamentals.scf(refim) first_ring = 1 # alpha1, sxs, sys, mirr, peak1 = align2d_no_mirror(scf(image), scr, last_ring=ou, mode="H") # alpha2, sxs, sys, mirr, peak2 = align2d_no_mirror(scf(mirror(image)), scr, last_ring=ou, mode="H") # alpha1, sxs, sys, mirr, peak1 = align2d_no_mirror(sci, scr, first_ring = 1, last_ring=ou, mode="H") # alpha2, sxs, sys, mirr, peak2 = align2d_no_mirror(mirror(sci), scr, first_ring = 1, last_ring=ou, mode="H") # center in SPIDER convention cnx = old_div(nx, 2) + 1 cny = old_div(ny, 2) + 1 # precalculate rings numr = Numrinit(first_ring, ou, 1, "H") wr = ringwe(numr, "H") crefim = EMAN2_cppwrap.Util.Polar2Dm(scr, cnx, cny, numr, "H") EMAN2_cppwrap.Util.Frngs(crefim, numr) EMAN2_cppwrap.Util.Applyws(crefim, numr, wr) alpha1, sxs, sys, mirr, peak1 = ornq(sci, crefim, [0.0], [0.0], 1.0, "H", numr, cnx, cny) alpha2, sxs, sys, mirr, peak2 = ornq(sp_fundamentals.mirror(sci), crefim, [0.0], [0.0], 1.0, "H", numr, cnx, cny) if peak1 > peak2: mirr = 0 alpha = alpha1 else: mirr = 1 alpha = -alpha2 nrx = min(2 * (xrng + 1) + 1, ((old_div((nx - 2), 2)) * 2 + 1)) nry = min(2 * (yrng + 1) + 1, ((old_div((ny - 2), 2)) * 2 + 1)) frotim = sp_fundamentals.fft(refim) ccf1 = EMAN2_cppwrap.Util.window( sp_fundamentals.ccf( sp_fundamentals.rot_shift2D(image, alpha, 0.0, 0.0, mirr), frotim), nrx, nry, ) p1 = sp_utilities.peak_search(ccf1) ccf2 = EMAN2_cppwrap.Util.window( sp_fundamentals.ccf( sp_fundamentals.rot_shift2D(image, alpha + 180.0, 0.0, 0.0, mirr), frotim), nrx, nry, ) p2 = sp_utilities.peak_search(ccf2) # print p1 # print p2 peak_val1 = p1[0][0] peak_val2 = p2[0][0] if peak_val1 > peak_val2: sxs = -p1[0][4] sys = -p1[0][5] cx = int(p1[0][1]) cy = int(p1[0][2]) peak = peak_val1 else: alpha += 180.0 sxs = -p2[0][4] sys = -p2[0][5] peak = peak_val2 cx = int(p2[0][1]) cy = int(p2[0][2]) ccf1 = ccf2 # print cx,cy z = sp_utilities.model_blank(3, 3) for i in range(3): for j in range(3): z[i, j] = ccf1[i + cx - 1, j + cy - 1] # print ccf1[cx,cy],z[1,1] XSH, YSH, PEAKV = parabl(z) # print sxs, sys, XSH, YSH, PEAKV, peak if mirr == 1: sx = -sxs + XSH else: sx = sxs - XSH return alpha, sx, sys - YSH, mirr, PEAKV
def generate_helimic(refvol, outdir, pixel, CTF=False, Cs=2.0, voltage=200.0, ampcont=10.0, nonoise=False, rand_seed=14567): from sp_utilities import model_blank, model_gauss, model_gauss_noise, pad, get_im from random import random from sp_projection import prgs, prep_vol from sp_filter import filt_gaussl, filt_ctf from EMAN2 import EMAN2Ctf if os.path.exists(outdir): ERROR( "Output directory exists, please change the name and restart the program" ) return os.mkdir(outdir) seed(rand_seed) Util.set_randnum_seed(rand_seed) angles = [] for i in range(3): angles.append([0.0 + 60.0 * i, 90.0 - i * 5, 0.0, 0.0, 0.0]) nangle = len(angles) volfts = get_im(refvol) nx = volfts.get_xsize() ny = volfts.get_ysize() nz = volfts.get_zsize() volfts, kbx, kby, kbz = prep_vol(volfts) iprj = 0 width = 500 xstart = 0 ystart = 0 for idef in range(3, 6): mic = model_blank(2048, 2048) #defocus = idef*0.2 defocus = idef * 0.6 ##@ming if CTF: #ctf = EMAN2Ctf() #ctf.from_dict( {"defocus":defocus, "cs":Cs, "voltage":voltage, "apix":pixel, "ampcont":ampcont, "bfactor":0.0} ) from sp_utilities import generate_ctf ctf = generate_ctf( [defocus, 2, 200, 1.84, 0.0, ampcont, defocus * 0.2, 80] ) ##@ming the range of astigmatism amplitude is between 10 percent and 22 percent. 20 percent is a good choice. i = idef - 4 for k in range(1): psi = 90 + 10 * i proj = prgs( volfts, kbz, [angles[idef - 3][0], angles[idef - 3][1], psi, 0.0, 0.0], kbx, kby) proj = Util.window(proj, 320, nz) mic += pad(proj, 2048, 2048, 1, 0.0, 750 * i, 20 * i, 0) if not nonoise: mic += model_gauss_noise(30.0, 2048, 2048) if CTF: #apply CTF mic = filt_ctf(mic, ctf) if not nonoise: mic += filt_gaussl(model_gauss_noise(17.5, 2048, 2048), 0.3) mic.write_image("%s/mic%1d.hdf" % (outdir, idef - 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)
emnumpy2 = EMNumPy() bigbuffer = emnumpy2.register_numpy_to_emdata(buffer) # bigbuffer = EMNumPy.numpy2em(buffer) if (Blockdata["myid_on_node"] == 0): # read data on process 0 of each node #print " READING DATA FIRST :",Blockdata["myid"],Blockdata["stack_ali2d"],len(plist) for i in range(nimastack): bigbuffer.insert_clip(data[i], (0, 0, i)) mpi.mpi_barrier(mpi.MPI_COMM_WORLD) alldata = [None] * nimastack emnumpy3 = [None] * nimastack msk = sp_utilities.model_blank(target_nx, target_nx, 1, 1) # for i in range(nimastack): # pointer_location = base_ptr + i*size_of_one_image*disp_unit # img_buffer = np.frombuffer(np.core.multiarray.int_asbuffer(pointer_location, size_of_one_image*disp_unit), dtype = 'f4') # img_buffer = img_buffer.reshape(target_nx, target_nx) # emnumpy3[i] = EMNumPy() # alldata[i] = emnumpy3[i].register_numpy_to_emdata(img_buffer) for i in range(nimastack): newpoint = base_ptr + i * size_of_one_image * disp_unit pointer_location = ctypes.cast( newpoint, ctypes.POINTER(ctypes.c_int * size_of_one_image)) img_buffer = numpy.frombuffer(pointer_location.contents, dtype="f4") img_buffer = img_buffer.reshape(target_nx, target_nx) emnumpy3[i] = EMNumPy() alldata[i] = emnumpy3[i].register_numpy_to_emdata(img_buffer)
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)
def cml_open_proj(stack, ir, ou, lf, hf, dpsi=1): from sp_projection import cml_sinogram from sp_utilities import model_circle, get_params_proj, model_blank, get_im from sp_fundamentals import fftip from sp_filter import filt_tanh # number of projections if type(stack) == type(""): nprj = EMUtil.get_image_count(stack) else: nprj = len(stack) Prj = [] # list of projections Ori = [ -1 ] * 4 * nprj # orientation intial (phi, theta, psi, index) for each projection for i in range(nprj): image = get_im(stack, i) # read initial angles if given try: Ori[4 * i], Ori[4 * i + 1], Ori[4 * i + 2], s2x, s2y = get_params_proj(image) except: pass if (i == 0): nx = image.get_xsize() if (ou < 1): ou = nx // 2 - 1 diameter = int(2 * ou) mask2D = model_circle(ou, nx, nx) if ir > 0: mask2D -= model_circle(ir, nx, nx) # normalize under the mask [mean_a, sigma, imin, imax] = Util.infomask(image, mask2D, True) image -= mean_a Util.mul_scalar(image, 1.0 / sigma) Util.mul_img(image, mask2D) # sinogram sino = cml_sinogram(image, diameter, dpsi) # prepare the cut positions in order to filter (lf: low freq; hf: high freq) ihf = min(int(2 * hf * diameter), diameter + (diameter + 1) % 2) ihf = ihf + (ihf + 1) % 2 # index ihf must be odd to take the img part ilf = max(int(2 * lf * diameter), 0) ilf = ilf + ilf % 2 # index ilf must be even to fall in the real part bdf = ihf - ilf + 1 # process lines nxe = sino.get_xsize() nye = sino.get_ysize() prj = model_blank(bdf, 2 * nye) pp = model_blank(nxe, 2 * nye) for li in range(nye): # get the line li line = Util.window(sino, nxe, 1, 1, 0, li - nye // 2, 0) # u2 (not improve the results) #line = filt_tanh(line, ou / float(nx), ou / float(nx)) # normalize this line [mean_l, sigma_l, imin, imax] = Util.infomask(line, None, True) line = (line - mean_l) / sigma_l # fft fftip(line) # filter (cut part of coef) and create mirror line Util.cml_prepare_line(prj, line, ilf, ihf, li, nye) # store the projection Prj.append(prj) return Prj, Ori
def helicalshiftali_MPI(stack, maskfile=None, maxit=100, CTF=False, snr=1.0, Fourvar=False, search_rng=-1): nproc = mpi.mpi_comm_size(mpi.MPI_COMM_WORLD) myid = mpi.mpi_comm_rank(mpi.MPI_COMM_WORLD) main_node = 0 ftp = file_type(stack) if myid == main_node: print_begin_msg("helical-shiftali_MPI") max_iter = int(maxit) if (myid == main_node): infils = EMUtil.get_all_attributes(stack, "filament") ptlcoords = EMUtil.get_all_attributes(stack, 'ptcl_source_coord') filaments = ordersegments(infils, ptlcoords) total_nfils = len(filaments) inidl = [0] * total_nfils for i in range(total_nfils): inidl[i] = len(filaments[i]) linidl = sum(inidl) nima = linidl tfilaments = [] for i in range(total_nfils): tfilaments += filaments[i] del filaments else: total_nfils = 0 linidl = 0 total_nfils = bcast_number_to_all(total_nfils, source_node=main_node) if myid != main_node: inidl = [-1] * total_nfils inidl = bcast_list_to_all(inidl, myid, source_node=main_node) linidl = bcast_number_to_all(linidl, source_node=main_node) if myid != main_node: tfilaments = [-1] * linidl tfilaments = bcast_list_to_all(tfilaments, myid, source_node=main_node) filaments = [] iendi = 0 for i in range(total_nfils): isti = iendi iendi = isti + inidl[i] filaments.append(tfilaments[isti:iendi]) del tfilaments, inidl if myid == main_node: print_msg("total number of filaments: %d" % total_nfils) if total_nfils < nproc: ERROR( 'number of CPUs (%i) is larger than the number of filaments (%i), please reduce the number of CPUs used' % (nproc, total_nfils), myid=myid) # balanced load temp = chunks_distribution([[len(filaments[i]), i] for i in range(len(filaments))], nproc)[myid:myid + 1][0] filaments = [filaments[temp[i][1]] for i in range(len(temp))] nfils = len(filaments) #filaments = [[0,1]] #print "filaments",filaments list_of_particles = [] indcs = [] k = 0 for i in range(nfils): list_of_particles += filaments[i] k1 = k + len(filaments[i]) indcs.append([k, k1]) k = k1 data = EMData.read_images(stack, list_of_particles) ldata = len(data) sxprint("ldata=", ldata) nx = data[0].get_xsize() ny = data[0].get_ysize() if maskfile == None: mrad = min(nx, ny) // 2 - 2 mask = pad(model_blank(2 * mrad + 1, ny, 1, 1.0), nx, ny, 1, 0.0) else: mask = get_im(maskfile) # apply initial xform.align2d parameters stored in header init_params = [] for im in range(ldata): t = data[im].get_attr('xform.align2d') init_params.append(t) p = t.get_params("2d") data[im] = rot_shift2D(data[im], p['alpha'], p['tx'], p['ty'], p['mirror'], p['scale']) if CTF: from sp_filter import filt_ctf from sp_morphology import ctf_img ctf_abs_sum = EMData(nx, ny, 1, False) ctf_2_sum = EMData(nx, ny, 1, False) else: ctf_2_sum = None ctf_abs_sum = None from sp_utilities import info for im in range(ldata): data[im].set_attr('ID', list_of_particles[im]) st = Util.infomask(data[im], mask, False) data[im] -= st[0] if CTF: ctf_params = data[im].get_attr("ctf") qctf = data[im].get_attr("ctf_applied") if qctf == 0: data[im] = filt_ctf(fft(data[im]), ctf_params) data[im].set_attr('ctf_applied', 1) elif qctf != 1: ERROR('Incorrectly set qctf flag', myid=myid) ctfimg = ctf_img(nx, ctf_params, ny=ny) Util.add_img2(ctf_2_sum, ctfimg) Util.add_img_abs(ctf_abs_sum, ctfimg) else: data[im] = fft(data[im]) del list_of_particles if CTF: reduce_EMData_to_root(ctf_2_sum, myid, main_node) reduce_EMData_to_root(ctf_abs_sum, myid, main_node) if CTF: if myid != main_node: del ctf_2_sum del ctf_abs_sum else: temp = EMData(nx, ny, 1, False) tsnr = 1. / snr for i in range(0, nx + 2, 2): for j in range(ny): temp.set_value_at(i, j, tsnr) temp.set_value_at(i + 1, j, 0.0) #info(ctf_2_sum) Util.add_img(ctf_2_sum, temp) #info(ctf_2_sum) del temp total_iter = 0 shift_x = [0.0] * ldata for Iter in range(max_iter): if myid == main_node: start_time = time() print_msg("Iteration #%4d\n" % (total_iter)) total_iter += 1 avg = EMData(nx, ny, 1, False) for im in range(ldata): Util.add_img(avg, fshift(data[im], shift_x[im])) reduce_EMData_to_root(avg, myid, main_node) if myid == main_node: if CTF: tavg = Util.divn_filter(avg, ctf_2_sum) else: tavg = Util.mult_scalar(avg, 1.0 / float(nima)) else: tavg = model_blank(nx, ny) if Fourvar: bcast_EMData_to_all(tavg, myid, main_node) vav, rvar = varf2d_MPI(myid, data, tavg, mask, "a", CTF) if myid == main_node: if Fourvar: tavg = fft(Util.divn_img(fft(tavg), vav)) vav_r = Util.pack_complex_to_real(vav) # normalize and mask tavg in real space tavg = fft(tavg) stat = Util.infomask(tavg, mask, False) tavg -= stat[0] Util.mul_img(tavg, mask) tavg.write_image("tavg.hdf", Iter) # For testing purposes: shift tavg to some random place and see if the centering is still correct #tavg = rot_shift3D(tavg,sx=3,sy=-4) if Fourvar: del vav bcast_EMData_to_all(tavg, myid, main_node) tavg = fft(tavg) sx_sum = 0.0 nxc = nx // 2 for ifil in range(nfils): """ # Calculate filament average avg = EMData(nx, ny, 1, False) filnima = 0 for im in xrange(indcs[ifil][0], indcs[ifil][1]): Util.add_img(avg, data[im]) filnima += 1 tavg = Util.mult_scalar(avg, 1.0/float(filnima)) """ # Calculate 1D ccf between each segment and filament average nsegms = indcs[ifil][1] - indcs[ifil][0] ctx = [None] * nsegms pcoords = [None] * nsegms for im in range(indcs[ifil][0], indcs[ifil][1]): ctx[im - indcs[ifil][0]] = Util.window(ccf(tavg, data[im]), nx, 1) pcoords[im - indcs[ifil][0]] = data[im].get_attr( 'ptcl_source_coord') #ctx[im-indcs[ifil][0]].write_image("ctx.hdf",im-indcs[ifil][0]) #print " CTX ",myid,im,Util.infomask(ctx[im-indcs[ifil][0]], None, True) # search for best x-shift cents = nsegms // 2 dst = sqrt( max((pcoords[cents][0] - pcoords[0][0])**2 + (pcoords[cents][1] - pcoords[0][1])**2, (pcoords[cents][0] - pcoords[-1][0])**2 + (pcoords[cents][1] - pcoords[-1][1])**2)) maxincline = atan2(ny // 2 - 2 - float(search_rng), dst) kang = int(dst * tan(maxincline) + 0.5) #print " settings ",nsegms,cents,dst,search_rng,maxincline,kang # ## C code for alignment. @ming results = [0.0] * 3 results = Util.helixshiftali(ctx, pcoords, nsegms, maxincline, kang, search_rng, nxc) sib = int(results[0]) bang = results[1] qm = results[2] #print qm, sib, bang # qm = -1.e23 # # for six in xrange(-search_rng, search_rng+1,1): # q0 = ctx[cents].get_value_at(six+nxc) # for incline in xrange(kang+1): # qt = q0 # qu = q0 # if(kang>0): tang = tan(maxincline/kang*incline) # else: tang = 0.0 # for kim in xrange(cents+1,nsegms): # dst = sqrt((pcoords[cents][0] - pcoords[kim][0])**2 + (pcoords[cents][1] - pcoords[kim][1])**2) # xl = dst*tang+six+nxc # ixl = int(xl) # dxl = xl - ixl # #print " A ", ifil,six,incline,kim,xl,ixl,dxl # qt += (1.0-dxl)*ctx[kim].get_value_at(ixl) + dxl*ctx[kim].get_value_at(ixl+1) # xl = -dst*tang+six+nxc # ixl = int(xl) # dxl = xl - ixl # qu += (1.0-dxl)*ctx[kim].get_value_at(ixl) + dxl*ctx[kim].get_value_at(ixl+1) # for kim in xrange(cents): # dst = sqrt((pcoords[cents][0] - pcoords[kim][0])**2 + (pcoords[cents][1] - pcoords[kim][1])**2) # xl = -dst*tang+six+nxc # ixl = int(xl) # dxl = xl - ixl # qt += (1.0-dxl)*ctx[kim].get_value_at(ixl) + dxl*ctx[kim].get_value_at(ixl+1) # xl = dst*tang+six+nxc # ixl = int(xl) # dxl = xl - ixl # qu += (1.0-dxl)*ctx[kim].get_value_at(ixl) + dxl*ctx[kim].get_value_at(ixl+1) # if( qt > qm ): # qm = qt # sib = six # bang = tang # if( qu > qm ): # qm = qu # sib = six # bang = -tang #if incline == 0: print "incline = 0 ",six,tang,qt,qu #print qm,six,sib,bang #print " got results ",indcs[ifil][0], indcs[ifil][1], ifil,myid,qm,sib,tang,bang,len(ctx),Util.infomask(ctx[0], None, True) for im in range(indcs[ifil][0], indcs[ifil][1]): kim = im - indcs[ifil][0] dst = sqrt((pcoords[cents][0] - pcoords[kim][0])**2 + (pcoords[cents][1] - pcoords[kim][1])**2) if (kim < cents): xl = -dst * bang + sib else: xl = dst * bang + sib shift_x[im] = xl # Average shift sx_sum += shift_x[indcs[ifil][0] + cents] # #print myid,sx_sum,total_nfils sx_sum = mpi.mpi_reduce(sx_sum, 1, mpi.MPI_FLOAT, mpi.MPI_SUM, main_node, mpi.MPI_COMM_WORLD) if myid == main_node: sx_sum = float(sx_sum[0]) / total_nfils print_msg("Average shift %6.2f\n" % (sx_sum)) else: sx_sum = 0.0 sx_sum = 0.0 sx_sum = bcast_number_to_all(sx_sum, source_node=main_node) for im in range(ldata): shift_x[im] -= sx_sum #print " %3d %6.3f"%(im,shift_x[im]) #exit() # combine shifts found with the original parameters for im in range(ldata): t1 = Transform() ##import random ##shix=random.randint(-10, 10) ##t1.set_params({"type":"2D","tx":shix}) t1.set_params({"type": "2D", "tx": shift_x[im]}) # combine t0 and t1 tt = t1 * init_params[im] data[im].set_attr("xform.align2d", tt) # write out headers and STOP, under MPI writing has to be done sequentially mpi.mpi_barrier(mpi.MPI_COMM_WORLD) par_str = ["xform.align2d", "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, 0, ldata, nproc) else: from sp_utilities import recv_attr_dict recv_attr_dict(main_node, stack, data, par_str, 0, ldata, nproc) else: send_attr_dict(main_node, data, par_str, 0, ldata) if myid == main_node: print_end_msg("helical-shiftali_MPI")
def main(): arglist = [] for arg in sys.argv: arglist.append(arg) progname = os.path.basename(arglist[0]) usage = progname + """ firstvolume secondvolume maskfile directory --prefix --wn --step --cutoff --radius --fsc --res_overall --out_ang_res --apix --MPI Compute local resolution in real space within area outlined by the maskfile and within regions wn x wn x wn """ parser = optparse.OptionParser(usage, version=sp_global_def.SPARXVERSION) parser.add_option("--prefix", type="str", default='localres', help="Prefix for the output files. (default localres)") parser.add_option( "--wn", type="int", default=7, help= "Size of window within which local real-space FSC is computed. (default 7)" ) parser.add_option( "--step", type="float", default=1.0, help="Shell step in Fourier size in pixels. (default 1.0)") parser.add_option("--cutoff", type="float", default=0.143, help="Resolution cut-off for FSC. (default 0.143)") parser.add_option( "--radius", type="int", default=-1, help= "If there is no maskfile, sphere with r=radius will be used. By default, the radius is nx/2-wn (default -1)" ) parser.add_option( "--fsc", type="string", default=None, help= "Save overall FSC curve (might be truncated). By default, the program does not save the FSC curve. (default none)" ) parser.add_option( "--res_overall", type="float", default=-1.0, help= "Overall resolution at the cutoff level estimated by the user [abs units]. (default None)" ) parser.add_option( "--out_ang_res", action="store_true", default=False, help= "Additionally creates a local resolution file in Angstroms. (default False)" ) parser.add_option( "--apix", type="float", default=1.0, help= "Pixel size in Angstrom. Effective only with --out_ang_res options. (default 1.0)" ) parser.add_option("--MPI", action="store_true", default=False, help="Use MPI version.") (options, args) = parser.parse_args(arglist[1:]) if len(args) < 3 or len(args) > 4: sxprint("Usage: " + usage) ERROR( "Invalid number of parameters used. Please see usage information above." ) return if sp_global_def.CACHE_DISABLE: sp_utilities.disable_bdb_cache() res_overall = options.res_overall if options.MPI: number_of_proc = mpi.mpi_comm_size(mpi.MPI_COMM_WORLD) myid = mpi.mpi_comm_rank(mpi.MPI_COMM_WORLD) main_node = 0 sp_global_def.MPI = True cutoff = options.cutoff nk = int(options.wn) if (myid == main_node): #print sys.argv vi = sp_utilities.get_im(sys.argv[1]) ui = sp_utilities.get_im(sys.argv[2]) nx = vi.get_xsize() ny = vi.get_ysize() nz = vi.get_zsize() dis = [nx, ny, nz] else: dis = [0, 0, 0, 0] sp_global_def.BATCH = True dis = sp_utilities.bcast_list_to_all(dis, myid, source_node=main_node) if (myid != main_node): nx = int(dis[0]) ny = int(dis[1]) nz = int(dis[2]) vi = sp_utilities.model_blank(nx, ny, nz) ui = sp_utilities.model_blank(nx, ny, nz) if len(args) == 3: m = sp_utilities.model_circle((min(nx, ny, nz) - nk) // 2, nx, ny, nz) outdir = args[2] elif len(args) == 4: if (myid == main_node): m = sp_morphology.binarize(sp_utilities.get_im(args[2]), 0.5) else: m = sp_utilities.model_blank(nx, ny, nz) outdir = args[3] if os.path.exists(outdir) and myid == 0: sp_global_def.ERROR('Output directory already exists!') elif myid == 0: os.makedirs(outdir) sp_global_def.write_command(outdir) sp_utilities.bcast_EMData_to_all(m, myid, main_node) """Multiline Comment0""" freqvol, resolut = sp_statistics.locres(vi, ui, m, nk, cutoff, options.step, myid, main_node, number_of_proc) if (myid == 0): # Remove outliers based on the Interquartile range output_volume(freqvol, resolut, options.apix, outdir, options.prefix, options.fsc, options.out_ang_res, nx, ny, nz, res_overall) else: cutoff = options.cutoff vi = sp_utilities.get_im(args[0]) ui = sp_utilities.get_im(args[1]) nn = vi.get_xsize() nx = nn ny = nn nz = nn nk = int(options.wn) if len(args) == 3: m = sp_utilities.model_circle((nn - nk) // 2, nn, nn, nn) outdir = args[2] elif len(args) == 4: m = sp_morphology.binarize(sp_utilities.get_im(args[2]), 0.5) outdir = args[3] if os.path.exists(outdir): sp_global_def.ERROR('Output directory already exists!') else: os.makedirs(outdir) sp_global_def.write_command(outdir) mc = sp_utilities.model_blank(nn, nn, nn, 1.0) - m vf = sp_fundamentals.fft(vi) uf = sp_fundamentals.fft(ui) """Multiline Comment1""" lp = int(nn / 2 / options.step + 0.5) step = 0.5 / lp freqvol = sp_utilities.model_blank(nn, nn, nn) resolut = [] for i in range(1, lp): fl = step * i fh = fl + step #print(lp,i,step,fl,fh) v = sp_fundamentals.fft(sp_filter.filt_tophatb(vf, fl, fh)) u = sp_fundamentals.fft(sp_filter.filt_tophatb(uf, fl, fh)) tmp1 = EMAN2_cppwrap.Util.muln_img(v, v) tmp2 = EMAN2_cppwrap.Util.muln_img(u, u) do = EMAN2_cppwrap.Util.infomask( sp_morphology.square_root( sp_morphology.threshold( EMAN2_cppwrap.Util.muln_img(tmp1, tmp2))), m, True)[0] tmp3 = EMAN2_cppwrap.Util.muln_img(u, v) dp = EMAN2_cppwrap.Util.infomask(tmp3, m, True)[0] resolut.append([i, (fl + fh) / 2.0, dp / do]) tmp1 = EMAN2_cppwrap.Util.box_convolution(tmp1, nk) tmp2 = EMAN2_cppwrap.Util.box_convolution(tmp2, nk) tmp3 = EMAN2_cppwrap.Util.box_convolution(tmp3, nk) EMAN2_cppwrap.Util.mul_img(tmp1, tmp2) tmp1 = sp_morphology.square_root(sp_morphology.threshold(tmp1)) EMAN2_cppwrap.Util.mul_img(tmp1, m) EMAN2_cppwrap.Util.add_img(tmp1, mc) EMAN2_cppwrap.Util.mul_img(tmp3, m) EMAN2_cppwrap.Util.add_img(tmp3, mc) EMAN2_cppwrap.Util.div_img(tmp3, tmp1) EMAN2_cppwrap.Util.mul_img(tmp3, m) freq = (fl + fh) / 2.0 bailout = True for x in range(nn): for y in range(nn): for z in range(nn): if (m.get_value_at(x, y, z) > 0.5): if (freqvol.get_value_at(x, y, z) == 0.0): if (tmp3.get_value_at(x, y, z) < cutoff): freqvol.set_value_at(x, y, z, freq) bailout = False else: bailout = False if (bailout): break #print(len(resolut)) # remove outliers output_volume(freqvol, resolut, options.apix, outdir, options.prefix, options.fsc, options.out_ang_res, nx, ny, nz, res_overall)