def prepi3D(image): """ Name prepi3D - prepare 3-D image for rotation/shift Input image: input image that is going to be rotated and shifted using rot_shif3D_grid Output imageft: image prepared for gridding rotation and shift kb: interpolants (tabulated Kaiser-Bessel function) """ from EMAN2 import Processor M = image.get_xsize() # padding size: npad = 2 N = M*npad # support of the window: K = 6 alpha = 1.75 r = M/2 v = K/2.0/N kb = Util.KaiserBessel(alpha, K, r, v, N) # pad with zeros in Fourier space: q = image.FourInterpol(N, N, N, 0) params = {"filter_type": Processor.fourier_filter_types.KAISER_SINH_INVERSE, "alpha":alpha, "K":K, "r":r, "v":v, "N":N} q = Processor.EMFourierFilter(q, params) params = {"filter_type" : Processor.fourier_filter_types.TOP_HAT_LOW_PASS, "cutoff_abs" : 0.25, "dopad" : False} q = Processor.EMFourierFilter(q, params) return fft(q), kb
def prepi(image): """ Name prepi - prepare 2-D image for rotation/shift Input image: input image that is going to be rotated and shifted using rtshgkb Output imageft: real space image prepared for gridding rotation and shift by convolution kb: interpolants (tabulated Kaiser-Bessel function) """ from EMAN2 import Processor M = image.get_xsize() # pad two times npad = 2 N = M*npad # support of the window K = 6 alpha = 1.75 r = M/2 v = K/2.0/N kb = Util.KaiserBessel(alpha, K, r, v, N) #out = rotshift2dg(image, angle*pi/180., sx, sy, kb,alpha) # first pad it with zeros in Fourier space q = image.FourInterpol(N, N, 1, 0) params = {"filter_type": Processor.fourier_filter_types.KAISER_SINH_INVERSE, "alpha":alpha, "K":K, "r":r, "v":v, "N":N} q = Processor.EMFourierFilter(q, params) params = {"filter_type" : Processor.fourier_filter_types.TOP_HAT_LOW_PASS, "cutoff_abs" : 0.25, "dopad" : False} q = Processor.EMFourierFilter(q, params) return fft(q), kb
def project(volume, params, radius=-1): """ Name project - calculate 2-D projection of a 3-D volume using trilinear interpolation Input vol: input volume, all dimensions have to be the same params: input parameters given as a list [phi, theta, psi, s2x, s2y], projection in calculated using the three Eulerian angles and then shifted by s2x,s2y radius: radius of a sphere within which the projection of the volume will be calculated Output proj: generated 2-D projection """ # angles phi, theta, psi from fundamentals import rot_shift2D from utilities import set_params_proj from EMAN2 import Processor if(radius>0): myparams = {"transform":Transform({"type":"spider","phi":params[0],"theta":params[1],"psi":params[2]}), "radius":radius} else: myparams = {"transform":Transform({"type":"spider","phi":params[0],"theta":params[1],"psi":params[2]})} proj = volume.project("pawel", myparams) if(params[3]!=0. or params[4]!=0.): params2 = {"filter_type" : Processor.fourier_filter_types.SHIFT, "x_shift" : params[3], "y_shift" : params[4], "z_shift" : 0.0} proj=Processor.EMFourierFilter(proj, params2) #proj = rot_shift2D(proj, sx = params[3], sy = params[4], interpolation_method = "linear") set_params_proj(proj, [params[0], params[1], params[2], -params[3], -params[4]]) proj.set_attr_dict({ 'ctf_applied':0}) return proj
def filt_tanb(e, freql, low_fall_off, freqh, high_fall_off, pad=False): """ Name filt_tanb - hyperbolic tangent band-pass Fourier filter Input e: input image (can be either real or Fourier) freql: low-end frequency of the filter pass-band low_fall_off: fall off of the filter at the low-end frequency freqh: high-end frequency of the filter pass-band high_fall_off: fall off of the filter at the high-and frequency pad: logical flag specifying whether before filtering the image should be padded with zeroes in real space to twice the size (this helps avoiding aliasing artifacts). (Default pad = False). All frequencies are in absolute frequency units fa and their valid range is [0:0.5]. Output filtered image. Output image is real when input image is real or Fourier when input image is Fourier """ from EMAN2 import Processor params = { "filter_type": Processor.fourier_filter_types.TANH_BAND_PASS, "low_cutoff_frequency": freql, "Low_fall_off": low_fall_off, "high_cutoff_frequency": freqh, "high_fall_off": high_fall_off, "dopad": pad } return Processor.EMFourierFilter(e, params)
def prepg(image, kb): """ Name prepg - prepare 2-D image for rotation/shift using gridding method. Input image: input image that is going to be rotated and shifted using rtshgkb kb: interpolants (tabulated Kaiser-Bessel function) Output imageft: image prepared for gridding rotation and shift """ from EMAN2 import Processor M = image.get_xsize() # padd two times npad = 2 N = M*npad # support of the window K = 6 alpha = 1.75 r = M/2 v = K/2.0/N # first pad it with zeros in Fourier space o = image.FourInterpol(2*M,2*M,1,0) params = {"filter_type" : Processor.fourier_filter_types.KAISER_SINH_INVERSE, "alpha" : alpha, "K":K,"r":r,"v":v,"N":N} q = Processor.EMFourierFilter(o,params) return fft(q)
def rotshift2dg(image, ang, dx, dy, kb, scale=1.0): """Rotate and shift an image using gridding """ from math import radians from EMAN2 import Processor M = image.get_xsize() alpha = 1.75 K = 6 N = M * 2 # npad*image size r = M / 2 v = K / 2.0 / N # first pad it with zeros in Fourier space o = image.FourInterpol(N, N, 1, 0) params = { "filter_type": Processor.fourier_filter_types.KAISER_SINH_INVERSE, "alpha": alpha, "K": K, "r": r, "v": v, "N": N } q = Processor.EMFourierFilter(o, params) o = fft(q) # gridding rotation return o.rot_scale_conv(radians(ang), dx, dy, kb, scale)
def filt_unctf(e, dz, cs, voltage, pixel, wgh=0.1, b_factor=0.0, sign=-1.0, dza=0.0, azz=0.0): """ defocus: Angstrom cs: mm voltage: Kv pixel size: Angstrom b_factor: Angstrom^2 wgh: Unitless """ from EMAN2 import Processor params = { "filter_type": Processor.fourier_filter_types.CTF_, "defocus": dz, "Cs": cs, "voltage": voltage, "Pixel_size": pixel, "B_factor": b_factor, "amp_contrast": wgh, "sign": sign, "dza": dza, "azz": azz, "undo": 1 } return Processor.EMFourierFilter(e, params)
def prgs1d(prjft, kb, params): from fundamentals import fft from math import cos, sin, pi from EMAN2 import Processor alpha = params[0] shift = params[1] tmp = alpha / 180.0 * pi nuxnew = cos(tmp) nuynew = -sin(tmp) line = prjft.extractline(kb, nuxnew, nuynew) line = fft(line) M = line.get_xsize() / 2 Util.cyclicshift(line, {"dx": M, "dy": 0, "dz": 0}) line = Util.window(line, M, 1, 1, 0, 0, 0) if shift != 0: filt_params = { "filter_type": Processor.fourier_filter_types.SHIFT, "x_shift": shift, "y_shift": 0.0, "z_shift": 0.0 } line = Processor.EMFourierFilter(temp, filt_params) line.set_attr_dict({'alpha': alpha, 's1x': shift}) return line
def filt_kaisersinhinvp(e, alpha): from EMAN2 import Processor M = e.get_xsize() K = 6 N = M*2 # npad*image size r=M/2 v=K/2.0/N from EMAN2 import Processor params = {"filter_type":Processor.fourier_filter_types.KAISER_SINH_INVERSE, "dopad" : 1, "alpha":alpha, "K":K,"r":r,"v":v,"N":N} return Processor.EMFourierFilter(e, params)
def prgl(volft, params, interpolation_method=0, return_real=True): """ Name prgl - calculate 2-D projection of a 3-D volume Input vol: input volume, the volume has to be cubic params: input parameters given as a list [phi, theta, psi, s2x, s2y], projection in calculated using the three Eulerian angles and then shifted by sx,sy interpolation_method = 0 NN interpolation_method = 1 trilinear return_real: True - return real; False - return FT of a projection. Output proj: generated 2-D projection """ # params: phi, theta, psi, sx, sy from fundamentals import fft from utilities import set_params_proj, info from EMAN2 import Processor npad = volft.get_attr_default("npad", 1) R = Transform({ "type": "spider", "phi": params[0], "theta": params[1], "psi": params[2] }) if (npad == 1): temp = volft.extract_section(R, interpolation_method) if (npad == 2): temp = volft.extract_section2(R, interpolation_method) temp.fft_shuffle() temp.center_origin_fft() if (params[3] != 0. or params[4] != 0.): filt_params = { "filter_type": Processor.fourier_filter_types.SHIFT, "x_shift": params[3], "y_shift": params[4], "z_shift": 0.0 } temp = Processor.EMFourierFilter(temp, filt_params) if return_real: temp.do_ift_inplace() if (interpolation_method == 1): temp.set_attr_dict({'ctf_applied': 0, 'npad': 1}) else: temp.set_attr_dict({'ctf_applied': 0, 'npad': npad}) temp.depad() else: temp.set_attr_dict({'ctf_applied': 0, 'npad': volft.get_attr("npad")}) set_params_proj(temp, [params[0], params[1], params[2], -params[3], -params[4]]) return temp
def prgs(volft, kb, params, kbx=None, kby=None): """ Name prg - calculate 2-D projection of a 3-D volume Input vol: input volume, the volume can be either cubic or rectangular kb: interpolants generated using prep_vol (tabulated Kaiser-Bessel function). If the volume is cubic, kb is the only interpolant. Otherwise, kb is the for caculating weigthing along z direction. kbx,kby: interpolants generated using prep_vol used to calculae weighting aling x and y directin. Default is none when the volume is cubic. If the volume is rectangular, kbx and kby must be given. params: input parameters given as a list [phi, theta, psi, s2x, s2y], projection in calculated using the three Eulerian angles and then shifted by sx,sy Output proj: generated 2-D projection """ # params: phi, theta, psi, sx, sy from fundamentals import fft from utilities import set_params_proj from EMAN2 import Processor R = Transform({ "type": "spider", "phi": params[0], "theta": params[1], "psi": params[2] }) if kbx is None: temp = volft.extract_plane(R, kb) else: temp = volft.extract_plane_rect(R, kbx, kby, kb) temp.fft_shuffle() temp.center_origin_fft() if (params[3] != 0. or params[4] != 0.): filt_params = { "filter_type": Processor.fourier_filter_types.SHIFT, "x_shift": params[3], "y_shift": params[4], "z_shift": 0.0 } temp = Processor.EMFourierFilter(temp, filt_params) temp.do_ift_inplace() set_params_proj(temp, [params[0], params[1], params[2], -params[3], -params[4]]) # horatio active_refactoring Jy51i1EwmLD4tWZ9_00000_1 # temp.set_attr_dict({'active':1, 'ctf_applied':0, 'npad':2}) temp.set_attr_dict({'ctf_applied': 0, 'npad': 2}) temp.depad() return temp
def cml_sinogram_shift(image2D, diameter, shifts=[0.0, 0.0], d_psi=1): from math import cos, sin from fundamentals import fft M_PI = 3.141592653589793238462643383279502884197 # prepare M = image2D.get_xsize() # padd two times npad = 2 N = M * npad # support of the window K = 6 alpha = 1.75 r = M / 2 v = K / 2.0 / N kb = Util.KaiserBessel(alpha, K, r, K / (2. * N), N) volft = image2D.average_circ_sub() # ASTA - in spider volft.divkbsinh(kb) # DIVKB2 - in spider volft = volft.norm_pad(False, npad) volft.do_fft_inplace() # Apply shift from EMAN2 import Processor params2 = { "filter_type": Processor.fourier_filter_types.SHIFT, "x_shift": 2 * shifts[0], "y_shift": 2 * shifts[1], "z_shift": 0.0 } volft = Processor.EMFourierFilter(volft, params2) volft.center_origin_fft() volft.fft_shuffle() # get line projection nangle = int(180.0 / d_psi) dangle = M_PI / float(nangle) e = EMData() e.set_size(diameter, nangle, 1) offset = M - diameter // 2 for j in xrange(nangle): nuxnew = cos(dangle * j) nuynew = -sin(dangle * j) line = fft(volft.extractline(kb, nuxnew, nuynew)) Util.cyclicshift(line, {"dx": M, "dy": 0, "dz": 0}) Util.set_line(e, j, line, offset, diameter) return e
def gridrot_shift2D(image, ang=0.0, sx=0.0, sy=0.0, scale=1.0): """ Rotate and shift an image using gridding in Fourier space. """ from EMAN2 import Processor from fundamentals import fftip, fft nx = image.get_xsize() # split shift into integer and fractional parts isx = int(sx) fsx = sx - isx isy = int(sy) fsy = sy - isy # prepare npad = 2 N = nx * npad K = 6 alpha = 1.75 r = nx / 2 v = K / 2.0 / N kb = Util.KaiserBessel(alpha, K, r, v, N) image1 = image.copy( ) # This step is needed, otherwise image will be changed outside the function # divide out gridding weights image1.divkbsinh(kb) # pad and center image, then FFT image1 = image1.norm_pad(False, npad) fftip(image1) # Put the origin of the (real-space) image at the center image1.center_origin_fft() # gridding rotation image1 = image1.fouriergridrot2d(ang, scale, kb) if (fsx != 0.0 or fsy != 0.0): params = { "filter_type": Processor.fourier_filter_types.SHIFT, "x_shift": float(fsx), "y_shift": float(fsy), "z_shift": 0.0 } image1 = Processor.EMFourierFilter(image1, params) # put the origin back in the corner image1.center_origin_fft() # undo FFT and remove padding (window) image1 = fft(image1) image1 = image1.window_center(nx) Util.cyclicshift(image1, {"dx": isx, "dy": isy, "dz": 0}) return image1
def filt_tophath(e, freq, pad = False): """ Name filt_tophath - top-hat high-pass Fourier filter (truncation of a Fourier series) Input e: input image (can be either real or Fourier) freq: pass-band frequency pad: logical flag specifying whether before filtering the image should be padded with zeroes in real space to twice the size (this helps avoiding aliasing artifacts). (Default pad = False). All frequencies are in absolute frequency units fa and their valid range is [0:0.5]. Output filtered image. Output image is real when input image is real or Fourier when input image is Fourier """ from EMAN2 import Processor params = {"filter_type" : Processor.fourier_filter_types.TOP_HAT_HIGH_PASS, "cutoff_abs" : freq, "dopad" : pad} return Processor.EMFourierFilter(e, params)
def filt_gausso(e, sigma, value, pad = False): """ Name filt_gausso - Gaussian homomorphic Fourier filter Input e: input image (can be either real or Fourier) sigma: standard deviation of the Gaussian function in absolute frequency units fa. value: center - value of the filter at zero freqeuncy pad: logical flag specifying whether before filtering the image should be padded with zeroes in real space to twice the size (this helps avoiding aliasing artifacts). (Default pad = False). Output filtered image. Output image is real when input image is real or Fourier when input image is Fourier """ from EMAN2 import Processor params = {"filter_type" : Processor.fourier_filter_types.GAUSS_HOMOMORPHIC, "cutoff_abs" : sigma, "value_at_zero_frequency" : value, "dopad" : pad} return Processor.EMFourierFilter(e, params)
def filt_gaussb(e, sigma, center, pad = False): """ Name filt_gaussb - Gaussian band-pass Fourier filter Input e: input image (can be either real or Fourier) sigma: standard deviation of the Gaussian function in absolute frequency units fa. center: frequency in absolute frequency units fa at which the filter reaches maximum (=1). pad: logical flag specifying whether before filtering the image should be padded with zeroes in real space to twice the size (this helps avoiding aliasing artifacts). (Default pad = False). Output filtered image. Output image is real when input image is real or Fourier when input image is Fourier """ from EMAN2 import Processor params = {"filter_type" : Processor.fourier_filter_types.GAUSS_BAND_PASS, "cutoff_abs" : sigma, "center" : center, "dopad" : pad} return Processor.EMFourierFilter(e, params)
def filt_gaussh(e, sigma, pad = False): """ Name filt_gaussh - Gaussian high-pass Fourier filter Input e: input image (can be either real or Fourier) sigma: standard deviation of the Gaussian function in absolute frequency units fa. pad: logical flag specifying whether before filtering the image should be padded with zeroes in real space to twice the size (this helps avoiding aliasing artifacts). (Default pad = False). Note: for sigma = 0.5 (the Nyquist frequency) the value of the filter at the maximum frequency is 1-G(0)=1-1e=0.39 Output filtered image. Output image is real when input image is real or Fourier when input image is Fourier """ from EMAN2 import Processor params = {"filter_type" : Processor.fourier_filter_types.GAUSS_HIGH_PASS, "cutoff_abs" : sigma, "dopad" : pad} return Processor.EMFourierFilter(e, params)
def fshift(e, delx=0, dely=0, delz=0): """ Name fshift - shift an image using phase multiplication in Fourier space Input image: input image sx: shift in pixels in the x direction, can be negative sy: shift in pixels in the y direction, can be negative sz: shift in pixels in the z direction, can be negative Output output image """ from EMAN2 import Processor params = {"filter_type" : Processor.fourier_filter_types.SHIFT, "x_shift" : float(delx), "y_shift" : float(dely), "z_shift" : float(delz) } return Processor.EMFourierFilter(e, params)
def filt_table(e, table): """ Name filt_table - filter image using a user-provided (as a list) of Fourier filter values Input e: input image (real or Fourier) table: user-provided 1-D table of filter values. Output image Fourier-filtered using coefficients in table (real or Fourier, according the input image) Options fast: use the fast method; may combust certain computers. huge: gobble memory; there is plenty of it, anyway. """ from EMAN2 import Processor params = {"filter_type" : Processor.fourier_filter_types.RADIAL_TABLE, "table" : table} return Processor.EMFourierFilter(e, params)
def filt_tanl(e, freq, fall_off, pad = False): """ Name filt_tanl - hyperbolic tangent low-pass Fourier filter Input e: input image (can be either real or Fourier) freq: stop-band frequency fall_off: fall off of the filter pad: logical flag specifying whether before filtering the image should be padded with zeroes in real space to twice the size (this helps avoiding aliasing artifacts). (Default pad = False). All frequencies are in absolute frequency units fa and their valid range is [0:0.5]. Output filtered image. Output image is real when input image is real or Fourier when input image is Fourier """ from EMAN2 import Processor params = {"filter_type" : Processor.fourier_filter_types.TANH_LOW_PASS, "cutoff_abs" : freq, "fall_off": fall_off, "dopad" : pad} return Processor.EMFourierFilter(e, params)
def filt_btwl(e, freql, freqh, pad = False): """ Name filt_btwl - Butterworth low-pass Fourier filter Input e: input image (can be either real or Fourier) freql: low - pass-band frequency freqh: high - stop-band frequency pad: logical flag specifying whether before filtering the image should be padded with zeroes in real space to twice the size (this helps avoiding aliasing artifacts). (Default pad = False). All frequencies are in absolute frequency units fa and their valid range is [0:0.5]. Output filtered image. Output image is real when input image is real or Fourier when input image is Fourier """ from EMAN2 import Processor params = {"filter_type" : Processor.fourier_filter_types.BUTTERWORTH_LOW_PASS, "low_cutoff_frequency" : freql, "high_cutoff_frequency" : freqh, "dopad" : pad} return Processor.EMFourierFilter(e, params)
def filt_ctf(img, ctf, dopad=True, sign=1, binary=0): """ Name filt_ctf - apply Contrast Transfer Function (CTF) to an image in Fourier space Input image: input image, it can be real or complex ctf: an CTF object, please see CTF_info for description. pad: apply padding with zeroes in real space to twice the size before CTF application (Default is True, if set to False, no padding, if input image is Fourier, the flag has no effect). sign: sign of the CTF. If cryo data had inverted contrast, i.e., images were multiplied by -1 and particle projections appear bright on dark background, it has to be set to -1). (Default is 1). binary: phase flipping if set to 1 (default is 0). Output image multiplied in Fourier space by the CTF, the output image has the same format as the input image. """ from EMAN2 import Processor assert img.get_ysize() > 1 dict = ctf.to_dict() dz = dict["defocus"] cs = dict["cs"] voltage = dict["voltage"] pixel_size = dict["apix"] b_factor = dict["bfactor"] ampcont = dict["ampcont"] dza = dict["dfdiff"] azz = dict["dfang"] if dopad and not img.is_complex(): ip = 1 else: ip = 0 params = { "filter_type": Processor.fourier_filter_types.CTF_, "defocus": dz, "Cs": cs, "voltage": voltage, "Pixel_size": pixel_size, "B_factor": b_factor, "amp_contrast": ampcont, "dopad": ip, "binary": binary, "sign": sign, "dza": dza, "azz": azz } tmp = Processor.EMFourierFilter(img, params) tmp.set_attr_dict({"ctf": ctf}) return tmp
def filt_tophato(e, freql, freqh, value, pad = False): """ Name filt_tophato - top-hat homomorphic Fourier filter (truncation of a Fourier series) Input e: input image (can be either real or Fourier) freql: low-end frequency of the filter pass-band freqh: high-end frequency of the filter pass-band value: value of the filter in spatial frequencies lower than freql pad: logical flag specifying whether before filtering the image should be padded with zeroes in real space to twice the size (this helps avoiding aliasing artifacts). (Default pad = False). All frequencies are in absolute frequency units fa and their valid range is [0:0.5]. Output filtered image. Output image is real when input image is real or Fourier when input image is Fourier """ from EMAN2 import Processor params = {"filter_type" : Processor.fourier_filter_types.TOP_HOMOMORPHIC, "low_cutoff_frequency" : freql, "high_cutoff_frequency" : freqh, "value_at_zero_frequency" : value, "dopad" : pad} return Processor.EMFourierFilter(e, params)
def shiftali_MPI(stack, maskfile=None, maxit=100, CTF=False, snr=1.0, Fourvar=False, search_rng=-1, oneDx=False, search_rng_y=-1): number_of_proc = 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("shiftali_MPI") max_iter = int(maxit) if myid == main_node: if ftp == "bdb": from EMAN2db import db_open_dict dummy = db_open_dict(stack, True) nima = EMUtil.get_image_count(stack) else: nima = 0 nima = bcast_number_to_all(nima, source_node=main_node) list_of_particles = list(range(nima)) image_start, image_end = MPI_start_end(nima, number_of_proc, myid) list_of_particles = list_of_particles[image_start:image_end] # read nx and ctf_app (if CTF) and broadcast to all nodes if myid == main_node: ima = EMData() ima.read_image(stack, list_of_particles[0], True) nx = ima.get_xsize() ny = ima.get_ysize() if CTF: ctf_app = ima.get_attr_default('ctf_applied', 2) del ima else: nx = 0 ny = 0 if CTF: ctf_app = 0 nx = bcast_number_to_all(nx, source_node=main_node) ny = bcast_number_to_all(ny, source_node=main_node) if CTF: ctf_app = bcast_number_to_all(ctf_app, source_node=main_node) if ctf_app > 0: ERROR("data cannot be ctf-applied", myid=myid) if maskfile == None: mrad = min(nx, ny) mask = model_circle(mrad // 2 - 2, nx, ny) else: mask = get_im(maskfile) 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 from sp_global_def import CACHE_DISABLE if CACHE_DISABLE: data = EMData.read_images(stack, list_of_particles) else: for i in range(number_of_proc): if myid == i: data = EMData.read_images(stack, list_of_particles) if ftp == "bdb": mpi.mpi_barrier(mpi.MPI_COMM_WORLD) for im in range(len(data)): 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") ctfimg = ctf_img(nx, ctf_params, ny=ny) Util.add_img2(ctf_2_sum, ctfimg) Util.add_img_abs(ctf_abs_sum, ctfimg) if CTF: reduce_EMData_to_root(ctf_2_sum, myid, main_node) reduce_EMData_to_root(ctf_abs_sum, myid, main_node) else: ctf_2_sum = None if CTF: if myid != main_node: del ctf_2_sum del ctf_abs_sum else: temp = EMData(nx, ny, 1, False) for i in range(0, nx, 2): for j in range(ny): temp.set_value_at(i, j, snr) Util.add_img(ctf_2_sum, temp) del temp total_iter = 0 # apply initial xform.align2d parameters stored in header init_params = [] for im in range(len(data)): t = data[im].get_attr('xform.align2d') init_params.append(t) p = t.get_params("2d") data[im] = rot_shift2D(data[im], p['alpha'], sx=p['tx'], sy=p['ty'], mirror=p['mirror'], scale=p['scale']) # fourier transform all images, and apply ctf if CTF for im in range(len(data)): if CTF: ctf_params = data[im].get_attr("ctf") data[im] = filt_ctf(fft(data[im]), ctf_params) else: data[im] = fft(data[im]) sx_sum = 0 sy_sum = 0 sx_sum_total = 0 sy_sum_total = 0 shift_x = [0.0] * len(data) shift_y = [0.0] * len(data) ishift_x = [0.0] * len(data) ishift_y = [0.0] * len(data) 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 data: Util.add_img(avg, 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 = EMData(nx, ny, 1, False) 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) # 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) tavg = fft(tavg) if Fourvar: del vav bcast_EMData_to_all(tavg, myid, main_node) sx_sum = 0 sy_sum = 0 if search_rng > 0: nwx = 2 * search_rng + 1 else: nwx = nx if search_rng_y > 0: nwy = 2 * search_rng_y + 1 else: nwy = ny not_zero = 0 for im in range(len(data)): if oneDx: ctx = Util.window(ccf(data[im], tavg), nwx, 1) p1 = peak_search(ctx) p1_x = -int(p1[0][3]) ishift_x[im] = p1_x sx_sum += p1_x else: p1 = peak_search(Util.window(ccf(data[im], tavg), nwx, nwy)) p1_x = -int(p1[0][4]) p1_y = -int(p1[0][5]) ishift_x[im] = p1_x ishift_y[im] = p1_y sx_sum += p1_x sy_sum += p1_y if not_zero == 0: if (not (ishift_x[im] == 0.0)) or (not (ishift_y[im] == 0.0)): not_zero = 1 sx_sum = mpi.mpi_reduce(sx_sum, 1, mpi.MPI_INT, mpi.MPI_SUM, main_node, mpi.MPI_COMM_WORLD) if not oneDx: sy_sum = mpi.mpi_reduce(sy_sum, 1, mpi.MPI_INT, mpi.MPI_SUM, main_node, mpi.MPI_COMM_WORLD) if myid == main_node: sx_sum_total = int(sx_sum[0]) if not oneDx: sy_sum_total = int(sy_sum[0]) else: sx_sum_total = 0 sy_sum_total = 0 sx_sum_total = bcast_number_to_all(sx_sum_total, source_node=main_node) if not oneDx: sy_sum_total = bcast_number_to_all(sy_sum_total, source_node=main_node) sx_ave = round(float(sx_sum_total) / nima) sy_ave = round(float(sy_sum_total) / nima) for im in range(len(data)): p1_x = ishift_x[im] - sx_ave p1_y = ishift_y[im] - sy_ave params2 = { "filter_type": Processor.fourier_filter_types.SHIFT, "x_shift": p1_x, "y_shift": p1_y, "z_shift": 0.0 } data[im] = Processor.EMFourierFilter(data[im], params2) shift_x[im] += p1_x shift_y[im] += p1_y # stop if all shifts are zero not_zero = mpi.mpi_reduce(not_zero, 1, mpi.MPI_INT, mpi.MPI_SUM, main_node, mpi.MPI_COMM_WORLD) if myid == main_node: not_zero_all = int(not_zero[0]) else: not_zero_all = 0 not_zero_all = bcast_number_to_all(not_zero_all, source_node=main_node) if myid == main_node: print_msg("Time of iteration = %12.2f\n" % (time() - start_time)) start_time = time() if not_zero_all == 0: break #for im in xrange(len(data)): data[im] = fft(data[im]) This should not be required as only header information is used # combine shifts found with the original parameters for im in range(len(data)): t0 = init_params[im] t1 = Transform() t1.set_params({ "type": "2D", "alpha": 0, "scale": t0.get_scale(), "mirror": 0, "tx": shift_x[im], "ty": shift_y[im] }) # combine t0 and t1 tt = t1 * t0 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, 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("shiftali_MPI")
def main(): import sys import os import math import random import pyemtbx.options import time from random import random, seed, randint from optparse import OptionParser progname = os.path.basename(sys.argv[0]) usage = progname + """ [options] <inputfile> <outputfile> Generic 2-D image processing programs. Functionality: 1. Phase flip a stack of images and write output to new file: sxprocess.py input_stack.hdf output_stack.hdf --phase_flip 2. Resample (decimate or interpolate up) images (2D or 3D) in a stack to change the pixel size. The window size will change accordingly. sxprocess input.hdf output.hdf --changesize --ratio=0.5 3. Compute average power spectrum of a stack of 2D images with optional padding (option wn) with zeroes. sxprocess.py input_stack.hdf powerspectrum.hdf --pw [--wn=1024] 4. Generate a stack of projections bdb:data and micrographs with prefix mic (i.e., mic0.hdf, mic1.hdf etc) from structure input_structure.hdf, with CTF applied to both projections and micrographs: sxprocess.py input_structure.hdf data mic --generate_projections format="bdb":apix=5.2:CTF=True:boxsize=64 5. Retrieve original image numbers in the selected ISAC group (here group 12 from generation 3): sxprocess.py bdb:test3 class_averages_generation_3.hdf list3_12.txt --isacgroup=12 --params=originalid 6. Retrieve original image numbers of images listed in ISAC output stack of averages: sxprocess.py select1.hdf ohk.txt 7. Adjust rotationally averaged power spectrum of an image to that of a reference image or a reference 1D power spectrum stored in an ASCII file. Optionally use a tangent low-pass filter. Also works for a stack of images, in which case the output is also a stack. sxprocess.py vol.hdf ref.hdf avol.hdf < 0.25 0.2> --adjpw sxprocess.py vol.hdf pw.txt avol.hdf < 0.25 0.2> --adjpw 8. Generate a 1D rotationally averaged power spectrum of an image. sxprocess.py vol.hdf --rotwp=rotpw.txt # Output will contain three columns: (1) rotationally averaged power spectrum (2) logarithm of the rotationally averaged power spectrum (3) integer line number (from zero to approximately to half the image size) 9. Apply 3D transformation (rotation and/or shift) to a set of orientation parameters associated with projection data. sxprocess.py --transfromparams=phi,theta,psi,tx,ty,tz input.txt output.txt The output file is then imported and 3D transformed volume computed: sxheader.py bdb:p --params=xform.projection --import=output.txt mpirun -np 2 sxrecons3d_n.py bdb:p tvol.hdf --MPI The reconstructed volume is in the position of the volume computed using the input.txt parameters and then transformed with rot_shift3D(vol, phi,theta,psi,tx,ty,tz) 10. Import ctf parameters from the output of sxcter into windowed particle headers. There are three possible input files formats: (1) all particles are in one stack, (2 aor 3) particles are in stacks, each stack corresponds to a single micrograph. In each case the particles should contain a name of the micrograph of origin stores using attribute name 'ptcl_source_image'. Normally this is done by e2boxer.py during windowing. Particles whose defocus or astigmatism error exceed set thresholds will be skipped, otherwise, virtual stacks with the original way preceded by G will be created. sxprocess.py --input=bdb:data --importctf=outdir/partres --defocuserror=10.0 --astigmatismerror=5.0 # Output will be a vritual stack bdb:Gdata sxprocess.py --input="bdb:directory/stacks*" --importctf=outdir/partres --defocuserror=10.0 --astigmatismerror=5.0 To concatenate output files: cd directory e2bdb.py . --makevstack=bdb:allparticles --filt=G IMPORTANT: Please do not move (or remove!) any input/intermediate EMAN2DB files as the information is linked between them. 11. Scale 3D shifts. The shifts in the input five columns text file with 3D orientation parameters will be DIVIDED by the scale factor sxprocess.py orientationparams.txt scaledparams.txt scale=0.5 12. Generate adaptive mask from a given 3-D volume. """ parser = OptionParser(usage, version=SPARXVERSION) parser.add_option( "--order", action="store_true", help= "Two arguments are required: name of input stack and desired name of output stack. The output stack is the input stack sorted by similarity in terms of cross-correlation coefficent.", default=False) parser.add_option("--order_lookup", action="store_true", help="Test/Debug.", default=False) parser.add_option("--order_metropolis", action="store_true", help="Test/Debug.", default=False) parser.add_option("--order_pca", action="store_true", help="Test/Debug.", 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( "--circular", action="store_true", help= "Select circular ordering (fisr image has to be similar to the last", default=False) parser.add_option( "--radius", type="int", default=-1, help="Radius of a circular mask for similarity based ordering") parser.add_option( "--changesize", action="store_true", help= "resample (decimate or interpolate up) images (2D or 3D) in a stack to change the pixel size.", default=False) parser.add_option( "--ratio", type="float", default=1.0, help= "The ratio of new to old image size (if <1 the pixel size will increase and image size decrease, if>1, the other way round" ) parser.add_option( "--pw", action="store_true", help= "compute average power spectrum of a stack of 2-D images with optional padding (option wn) with zeroes", default=False) parser.add_option( "--wn", type="int", default=-1, help= "Size of window to use (should be larger/equal than particle box size, default padding to max(nx,ny))" ) parser.add_option("--phase_flip", action="store_true", help="Phase flip the input stack", default=False) parser.add_option( "--makedb", metavar="param1=value1:param2=value2", type="string", action="append", help= "One argument is required: name of key with which the database will be created. Fill in database with parameters specified as follows: --makedb param1=value1:param2=value2, e.g. 'gauss_width'=1.0:'pixel_input'=5.2:'pixel_output'=5.2:'thr_low'=1.0" ) parser.add_option( "--generate_projections", metavar="param1=value1:param2=value2", type="string", action="append", help= "Three arguments are required: name of input structure from which to generate projections, desired name of output projection stack, and desired prefix for micrographs (e.g. if prefix is 'mic', then micrographs mic0.hdf, mic1.hdf etc will be generated). Optional arguments specifying format, apix, box size and whether to add CTF effects can be entered as follows after --generate_projections: format='bdb':apix=5.2:CTF=True:boxsize=100, or format='hdf', etc., where format is bdb or hdf, apix (pixel size) is a float, CTF is True or False, and boxsize denotes the dimension of the box (assumed to be a square). If an optional parameter is not specified, it will default as follows: format='bdb', apix=2.5, CTF=False, boxsize=64." ) parser.add_option( "--isacgroup", type="int", help= "Retrieve original image numbers in the selected ISAC group. See ISAC documentation for details.", default=-1) parser.add_option( "--isacselect", action="store_true", help= "Retrieve original image numbers of images listed in ISAC output stack of averages. See ISAC documentation for details.", default=False) parser.add_option( "--params", type="string", default=None, help="Name of header of parameter, which one depends on specific option" ) parser.add_option( "--adjpw", action="store_true", help="Adjust rotationally averaged power spectrum of an image", default=False) parser.add_option( "--rotpw", type="string", default=None, help= "Name of the text file to contain rotationally averaged power spectrum of the input image." ) parser.add_option( "--transformparams", type="string", default=None, help= "Transform 3D projection orientation parameters using six 3D parameters (phi, theta,psi,sx,sy,sz). Input: --transformparams=45.,66.,12.,-2,3,-5.5 desired six transformation of the reconstructed structure. Output: file with modified orientation parameters." ) # import ctf estimates done using cter parser.add_option("--input", type="string", default=None, help="Input particles.") parser.add_option( "--importctf", type="string", default=None, help="Name of the file containing CTF parameters produced by sxcter.") parser.add_option( "--defocuserror", type="float", default=1000000.0, help= "Exclude micrographs whose relative defocus error as estimated by sxcter is larger than defocuserror percent. The error is computed as (std dev defocus)/defocus*100%" ) parser.add_option( "--astigmatismerror", type="float", default=360.0, help= "Set to zero astigmatism for micrographs whose astigmatism angular error as estimated by sxcter is larger than astigmatismerror degrees." ) # import ctf estimates done using cter parser.add_option( "--scale", type="float", default=-1.0, help= "Divide shifts in the input 3D orientation parameters text file by the scale factor." ) # generate adaptive mask from an given 3-Db volue parser.add_option("--adaptive_mask", action="store_true", help="create adavptive 3-D mask from a given volume", default=False) parser.add_option( "--nsigma", type="float", default=1., help= "number of times of sigma of the input volume to obtain the the large density cluster" ) parser.add_option( "--ndilation", type="int", default=3, help= "number of times of dilation applied to the largest cluster of density" ) parser.add_option( "--kernel_size", type="int", default=11, help="convolution kernel for smoothing the edge of the mask") parser.add_option( "--gauss_standard_dev", type="int", default=9, help="stanadard deviation value to generate Gaussian edge") (options, args) = parser.parse_args() global_def.BATCH = True if options.phase_flip: nargs = len(args) if nargs != 2: print "must provide name of input and output file!" return from EMAN2 import Processor instack = args[0] outstack = args[1] nima = EMUtil.get_image_count(instack) from filter import filt_ctf for i in xrange(nima): img = EMData() img.read_image(instack, i) try: ctf = img.get_attr('ctf') except: print "no ctf information in input stack! Exiting..." return dopad = True sign = 1 binary = 1 # phase flip assert img.get_ysize() > 1 dict = ctf.to_dict() dz = dict["defocus"] cs = dict["cs"] voltage = dict["voltage"] pixel_size = dict["apix"] b_factor = dict["bfactor"] ampcont = dict["ampcont"] dza = dict["dfdiff"] azz = dict["dfang"] if dopad and not img.is_complex(): ip = 1 else: ip = 0 params = { "filter_type": Processor.fourier_filter_types.CTF_, "defocus": dz, "Cs": cs, "voltage": voltage, "Pixel_size": pixel_size, "B_factor": b_factor, "amp_contrast": ampcont, "dopad": ip, "binary": binary, "sign": sign, "dza": dza, "azz": azz } tmp = Processor.EMFourierFilter(img, params) tmp.set_attr_dict({"ctf": ctf}) tmp.write_image(outstack, i) elif options.changesize: nargs = len(args) if nargs != 2: ERROR("must provide name of input and output file!", "change size", 1) return from utilities import get_im instack = args[0] outstack = args[1] sub_rate = float(options.ratio) nima = EMUtil.get_image_count(instack) from fundamentals import resample for i in xrange(nima): resample(get_im(instack, i), sub_rate).write_image(outstack, i) elif options.isacgroup > -1: nargs = len(args) if nargs != 3: ERROR("Three files needed on input!", "isacgroup", 1) return from utilities import get_im instack = args[0] m = get_im(args[1], int(options.isacgroup)).get_attr("members") l = [] for k in m: l.append(int(get_im(args[0], k).get_attr(options.params))) from utilities import write_text_file write_text_file(l, args[2]) elif options.isacselect: nargs = len(args) if nargs != 2: ERROR("Two files needed on input!", "isacgroup", 1) return from utilities import get_im nima = EMUtil.get_image_count(args[0]) m = [] for k in xrange(nima): m += get_im(args[0], k).get_attr("members") m.sort() from utilities import write_text_file write_text_file(m, args[1]) elif options.pw: nargs = len(args) if nargs < 2: ERROR("must provide name of input and output file!", "pw", 1) return from utilities import get_im d = get_im(args[0]) nx = d.get_xsize() ny = d.get_ysize() if nargs == 3: mask = get_im(args[2]) wn = int(options.wn) if wn == -1: wn = max(nx, ny) else: if ((wn < nx) or (wn < ny)): ERROR("window size cannot be smaller than the image size", "pw", 1) n = EMUtil.get_image_count(args[0]) from utilities import model_blank, model_circle, pad from EMAN2 import periodogram p = model_blank(wn, wn) for i in xrange(n): d = get_im(args[0], i) if nargs == 3: d *= mask st = Util.infomask(d, None, True) d -= st[0] p += periodogram(pad(d, wn, wn, 1, 0.)) p /= n p.write_image(args[1]) elif options.adjpw: if len(args) < 3: ERROR( "filt_by_rops input target output fl aa (the last two are optional parameters of a low-pass filter)", "adjpw", 1) return img_stack = args[0] from math import sqrt from fundamentals import rops_table, fft from utilities import read_text_file, get_im from filter import filt_tanl, filt_table if (args[1][-3:] == 'txt'): rops_dst = read_text_file(args[1]) else: rops_dst = rops_table(get_im(args[1])) out_stack = args[2] if (len(args) > 4): fl = float(args[3]) aa = float(args[4]) else: fl = -1.0 aa = 0.0 nimage = EMUtil.get_image_count(img_stack) for i in xrange(nimage): img = fft(get_im(img_stack, i)) rops_src = rops_table(img) assert len(rops_dst) == len(rops_src) table = [0.0] * len(rops_dst) for j in xrange(len(rops_dst)): table[j] = sqrt(rops_dst[j] / rops_src[j]) if (fl > 0.0): img = filt_tanl(img, fl, aa) img = fft(filt_table(img, table)) img.write_image(out_stack, i) elif options.rotpw != None: if len(args) != 1: ERROR("Only one input permitted", "rotpw", 1) return from utilities import write_text_file, get_im from fundamentals import rops_table from math import log10 t = rops_table(get_im(args[0])) x = range(len(t)) r = [0.0] * len(x) for i in x: r[i] = log10(t[i]) write_text_file([t, r, x], options.rotpw) elif options.transformparams != None: if len(args) != 2: ERROR( "Please provide names of input and output files with orientation parameters", "transformparams", 1) return from utilities import read_text_row, write_text_row transf = [0.0] * 6 spl = options.transformparams.split(',') for i in xrange(len(spl)): transf[i] = float(spl[i]) write_text_row(rotate_shift_params(read_text_row(args[0]), transf), args[1]) elif options.makedb != None: nargs = len(args) if nargs != 1: print "must provide exactly one argument denoting database key under which the input params will be stored" return dbkey = args[0] print "database key under which params will be stored: ", dbkey gbdb = js_open_dict("e2boxercache/gauss_box_DB.json") parmstr = 'dummy:' + options.makedb[0] (processorname, param_dict) = parsemodopt(parmstr) dbdict = {} for pkey in param_dict: if (pkey == 'invert_contrast') or (pkey == 'use_variance'): if param_dict[pkey] == 'True': dbdict[pkey] = True else: dbdict[pkey] = False else: dbdict[pkey] = param_dict[pkey] gbdb[dbkey] = dbdict elif options.generate_projections: nargs = len(args) if nargs != 3: ERROR("Must provide name of input structure(s) from which to generate projections, name of output projection stack, and prefix for output micrographs."\ "sxprocess - generate projections",1) return inpstr = args[0] outstk = args[1] micpref = args[2] parmstr = 'dummy:' + options.generate_projections[0] (processorname, param_dict) = parsemodopt(parmstr) parm_CTF = False parm_format = 'bdb' parm_apix = 2.5 if 'CTF' in param_dict: if param_dict['CTF'] == 'True': parm_CTF = True if 'format' in param_dict: parm_format = param_dict['format'] if 'apix' in param_dict: parm_apix = float(param_dict['apix']) boxsize = 64 if 'boxsize' in param_dict: boxsize = int(param_dict['boxsize']) print "pixel size: ", parm_apix, " format: ", parm_format, " add CTF: ", parm_CTF, " box size: ", boxsize scale_mult = 2500 sigma_add = 1.5 sigma_proj = 30.0 sigma2_proj = 17.5 sigma_gauss = 0.3 sigma_mic = 30.0 sigma2_mic = 17.5 sigma_gauss_mic = 0.3 if 'scale_mult' in param_dict: scale_mult = float(param_dict['scale_mult']) if 'sigma_add' in param_dict: sigma_add = float(param_dict['sigma_add']) if 'sigma_proj' in param_dict: sigma_proj = float(param_dict['sigma_proj']) if 'sigma2_proj' in param_dict: sigma2_proj = float(param_dict['sigma2_proj']) if 'sigma_gauss' in param_dict: sigma_gauss = float(param_dict['sigma_gauss']) if 'sigma_mic' in param_dict: sigma_mic = float(param_dict['sigma_mic']) if 'sigma2_mic' in param_dict: sigma2_mic = float(param_dict['sigma2_mic']) if 'sigma_gauss_mic' in param_dict: sigma_gauss_mic = float(param_dict['sigma_gauss_mic']) from filter import filt_gaussl, filt_ctf from utilities import drop_spider_doc, even_angles, model_gauss, delete_bdb, model_blank, pad, model_gauss_noise, set_params2D, set_params_proj from projection import prep_vol, prgs seed(14567) delta = 29 angles = even_angles(delta, 0.0, 89.9, 0.0, 359.9, "S") nangle = len(angles) modelvol = [] nvlms = EMUtil.get_image_count(inpstr) from utilities import get_im for k in xrange(nvlms): modelvol.append(get_im(inpstr, k)) nx = modelvol[0].get_xsize() if nx != boxsize: ERROR("Requested box dimension does not match dimension of the input model.", \ "sxprocess - generate projections",1) nvol = 10 volfts = [[] for k in xrange(nvlms)] for k in xrange(nvlms): for i in xrange(nvol): sigma = sigma_add + random() # 1.5-2.5 addon = model_gauss(sigma, boxsize, boxsize, boxsize, sigma, sigma, 38, 38, 40) scale = scale_mult * (0.5 + random()) vf, kb = prep_vol(modelvol[k] + scale * addon) volfts[k].append(vf) del vf, modelvol if parm_format == "bdb": stack_data = "bdb:" + outstk delete_bdb(stack_data) else: stack_data = outstk + ".hdf" Cs = 2.0 pixel = parm_apix voltage = 120.0 ampcont = 10.0 ibd = 4096 / 2 - boxsize iprj = 0 width = 240 xstart = 8 + boxsize / 2 ystart = 8 + boxsize / 2 rowlen = 17 from random import randint params = [] for idef in xrange(3, 8): irow = 0 icol = 0 mic = model_blank(4096, 4096) defocus = idef * 0.5 #0.2 if parm_CTF: astampl = defocus * 0.15 astangl = 50.0 ctf = generate_ctf([ defocus, Cs, voltage, pixel, ampcont, 0.0, astampl, astangl ]) for i in xrange(nangle): for k in xrange(12): dphi = 8.0 * (random() - 0.5) dtht = 8.0 * (random() - 0.5) psi = 360.0 * random() phi = angles[i][0] + dphi tht = angles[i][1] + dtht s2x = 4.0 * (random() - 0.5) s2y = 4.0 * (random() - 0.5) params.append([phi, tht, psi, s2x, s2y]) ivol = iprj % nvol #imgsrc = randint(0,nvlms-1) imgsrc = iprj % nvlms proj = prgs(volfts[imgsrc][ivol], kb, [phi, tht, psi, -s2x, -s2y]) x = xstart + irow * width y = ystart + icol * width mic += pad(proj, 4096, 4096, 1, 0.0, x - 2048, y - 2048, 0) proj = proj + model_gauss_noise(sigma_proj, nx, nx) if parm_CTF: proj = filt_ctf(proj, ctf) proj.set_attr_dict({"ctf": ctf, "ctf_applied": 0}) proj = proj + filt_gaussl( model_gauss_noise(sigma2_proj, nx, nx), sigma_gauss) proj.set_attr("origimgsrc", imgsrc) proj.set_attr("test_id", iprj) # flags describing the status of the image (1 = true, 0 = false) set_params2D(proj, [0.0, 0.0, 0.0, 0, 1.0]) set_params_proj(proj, [phi, tht, psi, s2x, s2y]) proj.write_image(stack_data, iprj) icol += 1 if icol == rowlen: icol = 0 irow += 1 iprj += 1 mic += model_gauss_noise(sigma_mic, 4096, 4096) if parm_CTF: #apply CTF mic = filt_ctf(mic, ctf) mic += filt_gaussl(model_gauss_noise(sigma2_mic, 4096, 4096), sigma_gauss_mic) mic.write_image(micpref + "%1d.hdf" % (idef - 3), 0) drop_spider_doc("params.txt", params) elif options.importctf != None: print ' IMPORTCTF ' from utilities import read_text_row, write_text_row from random import randint import subprocess grpfile = 'groupid%04d' % randint(1000, 9999) ctfpfile = 'ctfpfile%04d' % randint(1000, 9999) cterr = [options.defocuserror / 100.0, options.astigmatismerror] ctfs = read_text_row(options.importctf) for kk in xrange(len(ctfs)): root, name = os.path.split(ctfs[kk][-1]) ctfs[kk][-1] = name[:-4] if (options.input[:4] != 'bdb:'): ERROR('Sorry, only bdb files implemented', 'importctf', 1) d = options.input[4:] #try: str = d.index('*') #except: str = -1 from string import split import glob uu = os.path.split(d) uu = os.path.join(uu[0], 'EMAN2DB', uu[1] + '.bdb') flist = glob.glob(uu) for i in xrange(len(flist)): root, name = os.path.split(flist[i]) root = root[:-7] name = name[:-4] fil = 'bdb:' + os.path.join(root, name) sourcemic = EMUtil.get_all_attributes(fil, 'ptcl_source_image') nn = len(sourcemic) gctfp = [] groupid = [] for kk in xrange(nn): junk, name2 = os.path.split(sourcemic[kk]) name2 = name2[:-4] ctfp = [-1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] for ll in xrange(len(ctfs)): if (name2 == ctfs[ll][-1]): # found correct if (ctfs[ll][8] / ctfs[ll][0] <= cterr[0]): # acceptable defocus error ctfp = ctfs[ll][:8] if (ctfs[ll][10] > cterr[1]): # error of astigmatism exceed the threshold, set astigmatism to zero. ctfp[6] = 0.0 ctfp[7] = 0.0 gctfp.append(ctfp) groupid.append(kk) break if (len(groupid) > 0): write_text_row(groupid, grpfile) write_text_row(gctfp, ctfpfile) cmd = "{} {} {} {}".format( 'e2bdb.py', fil, '--makevstack=bdb:' + root + 'G' + name, '--list=' + grpfile) #print cmd subprocess.call(cmd, shell=True) cmd = "{} {} {} {}".format('sxheader.py', 'bdb:' + root + 'G' + name, '--params=ctf', '--import=' + ctfpfile) #print cmd subprocess.call(cmd, shell=True) else: print ' >>> Group ', name, ' skipped.' cmd = "{} {} {}".format("rm -f", grpfile, ctfpfile) subprocess.call(cmd, shell=True) elif options.scale > 0.0: from utilities import read_text_row, write_text_row scale = options.scale nargs = len(args) if nargs != 2: print "Please provide names of input and output file!" return p = read_text_row(args[0]) for i in xrange(len(p)): p[i][3] /= scale p[i][4] /= scale write_text_row(p, args[1]) elif options.adaptive_mask: from utilities import get_im from morphology import adaptive_mask nsigma = options.nsigma ndilation = options.ndilation kernel_size = options.kernel_size gauss_standard_dev = options.gauss_standard_dev nargs = len(args) if nargs > 2: print "Too many inputs are given, try again!" return else: inputvol = get_im(args[0]) input_path, input_file_name = os.path.split(args[0]) input_file_name_root, ext = os.path.splitext(input_file_name) if nargs == 2: mask_file_name = args[1] else: mask_file_name = "adaptive_mask_for" + input_file_name_root + ".hdf" # Only hdf file is output. mask3d = adaptive_mask(inputvol, nsigma, ndilation, kernel_size, gauss_standard_dev) mask3d.write_image(mask_file_name) else: ERROR("Please provide option name", "sxprocess.py", 1)