def cut_patch(projection, ang, pick_position, vol_size=200, binning=8, dimz=None, offset=[0, 0, 0], projection_name=None): from pytom.tompy.tools import taper_edges #from pytom.gpu.initialize import xp from pytom.voltools import transform from pytom.tompy.transform import rotate3d, rotate_axis from pytom.tompy.transform import cut_from_projection from pytom.tompy.io import read # Get the size of the original projection dim_x = projection.shape[0] dim_z = dim_x if dimz is None else dimz x, y, z = pick_position x = (x + offset[0]) * binning y = (y + offset[1]) * binning z = (z + offset[2]) * binning # Get coordinates of the paricle adjusted for the tilt angle yy = y # assume the rotation axis is around y xx = (xp.cos(ang * xp.pi / 180) * (x - dim_x / 2) - xp.sin(ang * xp.pi / 180) * (z - dim_z / 2)) + dim_x / 2 # Cut the small patch out patch = projection[max(0, int(xp.floor(xx)) - vol_size // 2):int(xp.floor(xx)) + vol_size // 2, int(yy) - vol_size // 2:int(yy) + vol_size // 2, :] shiftedPatch = xp.zeros_like(patch) transform(patch, output=shiftedPatch, translation=[xx % 1, yy % 1, 0], device=device, interpolation='filt_bspline') return shiftedPatch.squeeze()
def design_fsc_filter(fsc, fildim=None, fsc_criterion=0.143): """ design spectral filter to weight by SNR of frequency @param fsc: input fsc @type fsc: 1-d list @param fildim: filter dimension @type fildim: int @return: filter @rtype: list @author: FF """ from math import sqrt from pytom.basic.resolution import getResolutionBandFromFSC if not fildim: fildim = len(fsc) nband = len(fsc) if fsc_criterion != 0.0: resolutionBand = getResolutionBandFromFSC(fsc, criterion=fsc_criterion) smooth = max(resolutionBand / 5, 2) else: resolutionBand = len(fsc) smooth = 1 #print "filter: fsc_criterion %2.3f, resolutionBand %d" % (fsc_criterion, resolutionBand) # filter by sqrt(FSC) fsc_fil = len(fsc) * [0.] for ii in range(0, len(fsc)): fscval = fsc[ii] if fscval > 0.: #fsc_fil[ii] = sqrt(fsc[ii]) if ii <= resolutionBand: fsc_fil[ii] = sqrt(fsc[ii]) elif (ii > resolutionBand) and (ii <= resolutionBand + smooth): fsc_fil[ii] = sqrt(fsc[ii]) * (( (resolutionBand + smooth) - ii) / smooth)**2 # squared filter else: fsc_fil[ii] = 0. else: fsc_fil[ii] = 0. #design filter fil = xp.array(fildim * [0.]) if nband != len(fil): shrinkfac = 1. / (len(fil) / nband) for ii in range(len(fil) - 1): # linear resample fsc if nband ~= size(fil) if nband != len(fil): ilow = int(xp.floor(shrinkfac * ii)) dlow = shrinkfac * ii - ilow ihi = ilow + 1 dhi = ihi - shrinkfac * ii fil[ii] = fsc_fil[ilow] * dhi + fsc_fil[ihi] * dlow else: fil[ii] = fsc_fil[ii] return fil
def cut_patch(projection, ang, pick_position, vol_size=200, binning=8, dimz=0, offset=[0, 0, 0], projection_name=None): #from pytom.gpu.initialize import xp from pytom.voltools import transform from pytom.tompy.transform import rotate3d, rotate_axis from pytom.tompy.transform import cut_from_projection from pytom.tompy.io import read # Get the size of the original projection dim_x = projection.shape[0] dim_z = dim_x if dimz is None else dimz x, y, z = pick_position x = (x + offset[0]) * binning y = (y + offset[1]) * binning z = (z + offset[2]) * binning # Get coordinates of the paricle adjusted for the tilt angle yy = y # assume the rotation axis is around y xx = (xp.cos(ang * xp.pi / 180) * (x - dim_x / 2) - xp.sin(ang * xp.pi / 180) * (z - dim_z / 2)) + dim_x / 2 # Cut the small patch out patch = projection[max(0, int(xp.floor(xx)) - vol_size // 2):int(xp.floor(xx)) + vol_size // 2, int(yy) - vol_size // 2:int(yy) + vol_size // 2, :] #transform(patch, output=patch, translation=[0,xx-float(xx),0], device='gpu:1') #patch -= patch.mean() return patch, xx, yy
def profile2FourierVol(profile, dim=None, reduced=False): """ create Volume from 1d radial profile, e.g., to modulate signal with \ specific function such as CTF or FSC. Simple linear interpolation is used\ for sampling. @param profile: profile @type profile: 1-d L{pytom_volume.vol} or 1-d python array @param dim: dimension of (cubic) output @type dim: L{int} @param reduced: If true reduced Fourier representation (N/2+1, N, N) is generated. @type reduced: L{bool} @return: 3-dim complex volume with spherically symmetrical profile @rtype: L{pytom_volume.vol} @author: FF """ if dim is None: try: dim = [ 2 * profile.shape[0], ] * 3 except: dim = [ 2 * len(profile), ] * 3 is3D = (len(dim) == 3) nx, ny = dim[:2] if reduced: if is3D: nz = int(dim[2] // 2) + 1 else: ny = int(ny // 2) + 1 else: if is3D: nz = dim[2] try: r_max = profile.shape[0] - 1 except: r_max = len(profile) - 1 if len(dim) == 3: if reduced: X, Y, Z = xp.meshgrid(xp.arange(-nx // 2, nx // 2 + nx % 2), xp.arange(-ny // 2, ny // 2 + ny % 2), xp.arange(0, nz)) else: X, Y, Z = xp.meshgrid(xp.arange(-nx // 2, nx // 2 + nx % 2), xp.arange(-ny // 2, ny // 2 + ny % 2), xp.arange(-nz // 2, nz // 2 + nz % 2)) R = xp.sqrt(X**2 + Y**2 + Z**2) else: if reduced: X, Y = xp.meshgrid(xp.arange(-nx // 2, ny // 2 + ny % 2), xp.arange(0, ny)) else: X, Y = xp.meshgrid(xp.arange(-nx // 2, nx // 2 + nx % 2), xp.arange(-ny // 2, ny // 2 + ny % 2)) R = xp.sqrt(X**2 + Y**2) IR = xp.floor(R).astype(xp.int64) valIR_l1 = IR.copy() valIR_l2 = valIR_l1 + 1 val_l1, val_l2 = xp.zeros_like(X, dtype=xp.float64), xp.zeros_like( X, dtype=xp.float64) l1 = R - IR.astype(xp.float32) l2 = 1 - l1 try: profile = xp.array(profile) except: import numpy profile = xp.array(numpy.array(profile)) for n in xp.arange(r_max): val_l1[valIR_l1 == n] = profile[n] val_l2[valIR_l2 == n + 1] = profile[n + 1] val_l1[IR == r_max] = profile[n + 1] val_l2[IR == r_max] = profile[n + 1] val_l1[R > r_max] = 0 val_l2[R > r_max] = 0 fkernel = l2 * val_l1 + l1 * val_l2 if reduced: fkernel = xp.fft.fftshift(fkernel, axes=(0, 1)) else: fkernel = xp.fft.fftshift(fkernel) return fkernel
def resizeFourier(fvol, factor, isodd=False): """ resize Fourier transformed by factor @param fvol: Fourier transformed of a volume - reduced complex @type fvol: L{pytom_volume.vol_comp} @param factor: a factor > 0. Factors < 1 will de-magnify the volume, factors > 1 will magnify. @type factor: float @return: resized Fourier volume (deruced complex) @rtype: L{pytom_volume.vol_comp} @author: FF """ fvol = fvol.squeeze() if factor == 1: return fvol oldFNx = fvol.shape[0] oldFNy = fvol.shape[1] # new dims in real and Fourier space newNx = newFNx = int(xp.floor(oldFNx * factor + 0.5)) newNy = newFNy = int(xp.floor(oldFNy * factor + 0.5)) # check 3D images if len(fvol.shape) == 3: oldNz = int((fvol.shape[2] - 1) * 2 + 1 * isodd) newNz = int(xp.floor(oldNz * factor + 0.5)) newFNz = newNz // 2 + 1 oldFNz = fvol.shape[2] scf = 1 #oldNz **3 / (newNx * newNy * newNz) newxIsEven = newFNx % 2 newyIsEven = newFNy % 2 fvol_center_scaled = xp.fft.fftshift(fvol, axes=(0, 1)) * scf newfvol = xp.zeros((newFNx, newFNy, newFNz), dtype=fvol.dtype) if factor >= 1: # Effectively zero-padding newfvol[newFNx // 2 - oldFNx // 2 + newxIsEven:newFNx // 2 + oldFNx // 2 + isodd + newxIsEven, newFNy // 2 - oldFNy // 2 + newyIsEven:newFNy // 2 + oldFNy // 2 + isodd + newyIsEven, :oldFNz] = fvol_center_scaled # newFNz // 2 - oldFNz // 2 :newFNz // 2 + oldFNz // 2 + 1] = fvol_center_scaled else: # Effectively cropping newfvol = fvol_center_scaled[oldFNx // 2 - newFNx // 2 - newxIsEven:oldFNx // 2 + newFNx // 2 + isodd, oldFNy // 2 - newFNy // 2 - newyIsEven:oldFNy // 2 + newFNy // 2 + isodd, :newFNz] newfvol = xp.fft.fftshift(newfvol, axes=(0, 1)) else: newNz = 1 scf = 1. / (newNx * newNy * newNz) newFNz = 1 newFNy = newNy #// 2 + 1 fvol_center_scaled = xp.fft.fftshift(fvol, axes=(0)) newfvol = xp.zeros((newFNx, newFNy), dtype=fvol.dtype) * scf if factor >= 1: newfvol[newFNx // 2 - oldFNx // 2:newFNx // 2 + oldFNx // 2 + isodd, :oldFNx] = fvol_center_scaled else: newfvol = fvol_center_scaled[oldFNx // 2 - newFNx // 2:oldFNx // 2 + newFNx // 2 + isodd, :newFNy] newfvol = xp.fft.fftshift(newfvol, axes=(0)) #newfvol = xp.expand_dims(newfvol,2) return newfvol
def scale(volume, factor, interpolation='Spline'): """ scale: Scale a volume by a factor in REAL SPACE - see also resize function for more accurate operation in Fourier \ space @param volume: input volume @type volume: L{pytom_volume.vol} @param factor: a factor > 0. Factors < 1 will de-magnify the volume, factors > 1 will magnify. @type factor: L{float} @param interpolation: Can be Spline (default), Cubic or Linear @type interpolation: L{str} @return: The scaled volume @author: Thomas Hrabe """ from pytom.voltools import transform from pytom.tompy.tools import paste_in_center if factor <= 0: raise RuntimeError('Scaling factor must be > 0!') interpolation_dict = { 'Spline': 'filt_bspline', 'Linear': 'linear', 'Cubic': 'filt_bspline', 'filt_bspline': 'filt_bspline', 'linear': 'linear' } interpolation = interpolation_dict[interpolation] volume = volume.squeeze() sizeX = volume.shape[0] sizeY = volume.shape[1] sizeZ = 1 newSizeX = int(xp.floor(sizeX * float(factor) + 0.5)) newSizeY = int(xp.floor(sizeY * float(factor) + 0.5)) newSizeZ = 1 if len(volume.shape) == 3: sizeZ = volume.shape[2] newSizeZ = int(xp.floor(sizeZ * factor + 0.5)) scaleF = [1 / factor, 1 / factor, 1 / factor] else: scaleF = [1 / factor, 1 / factor, 1] volume = xp.expand_dims(volume, 2) if factor == 1: rescaledVolume = volume elif factor > 1: newVolume = xp.zeros((newSizeX, newSizeY, newSizeZ), dtype=volume.dtype) newVolume = paste_in_center(volume, newVolume) rescaledVolume = xp.zeros_like(newVolume) transform(newVolume, scale=scaleF, output=rescaledVolume, device=device, interpolation=interpolation) else: rescaledVolumeFull = xp.zeros_like(volume) transform(volume, scale=scaleF, output=rescaledVolumeFull, device=device, interpolation=interpolation) rescaledVolume = xp.zeros((newSizeX, newSizeY, newSizeZ), dtype=volume.dtype) rescaledVolume = paste_in_center(rescaledVolumeFull, rescaledVolume) return rescaledVolume