Esempio n. 1
0
def extractCandidates(jobFilename='', resultFilename='', orientFilename='', sizeParticle=None, maxNumParticle=0,
                      minScore=-1, write2disk=0, margin=None,mask=None, structuredMask=None):
    # construct the original job from the xml file
    if jobFilename=='':
        jobFilename='JobInfo.xml'
        
    from pytom.localization.peak_job import PeakJob
    job = PeakJob()
    job.fromXMLFile(jobFilename)
    
    from pytom.localization.extraction_peak_result import ExPeakResult
    res = ExPeakResult()
    res.volFilename = job.volume.getFilename()


    from pytom.basic.files import read
    from pytom_numpy import vol2npy
    from copy import deepcopy


    if resultFilename=='':
        res.resultFilename='scores.em'
    else:
        res.resultFilename = resultFilename
    if orientFilename=='':
        res.orientFilename='angles.em'
    else:
        res.orientFilename = orientFilename

    if mask:
        resultfile, maskfile = read(res.resultFilename), read(mask)
        resultdata, maskdata = deepcopy(vol2npy(resultfile)), deepcopy(vol2npy(maskfile))

        import mrcfile
        x,y,z,sx,sy,sz = job.volume.subregion

        masked_data = (resultdata*maskdata[x:x+sx,y:y+sy,z:z+sz])
        #masked_data[masked_data < 0.00001] = resultdata.median()

        mrcfile.new(res.resultFilename.replace('.em', '_masked.em'),masked_data.T, overwrite=True)
        res.resultFilename = res.resultFilename.replace('.em', '_masked.em')


    res.angleList = job.rotations[:]
    res.score = job.score.__class__
    
    if maxNumParticle <= 0:
        return None
    
    res.readAll()
    
    if sizeParticle==None:
        ref = job.reference.getVolume()
        sizeParticle = [ref.sizeX(),ref.sizeY(),ref.sizeZ()]
    print(job.volume.subregion[:3])
    particleList = res.findParticles(sizeParticle,maxNumParticle,minScore,write2disk,margin, offset=job.volume.subregion[:3], structured_mask=structuredMask)
    
    return particleList
Esempio n. 2
0
def fourierReconstructGPU(vol_img,
                          vol_bp,
                          vol_phi,
                          vol_the,
                          recPosVol=[0, 0, 0],
                          vol_offsetProjections=[0, 0, 0]):
    from pytom_numpy import vol2npy
    import cupy as cp
    from pytom.voltools import transform
    from cupy.fft import fftshift, ifftn, fftn
    import numpy
    from cupyx.scipy.ndimage import rotate
    interpolation = 'filt_bspline'
    projections = vol2npy(vol_img)
    projections = cp.array(projections)
    proj_angles = vol2npy(vol_the)[0, 0, :]
    dims = (projections.shape[0], projections.shape[0], projections.shape[0])
    tot = cp.zeros(dims, cp.complex64)

    for n in range(projections.shape[2]):
        org = cp.zeros(dims, dtype=cp.complex64)
        rot = cp.zeros(dims, dtype=cp.complex64)
        ff = fftshift(fftn(fftshift(projections[:, :, n])))

        org[:, :, dims[0] // 2] = ff
        #print(n,ff.shape, org.shape)
        if 0:
            rot.real = rotate(org.real,
                              proj_angles[n],
                              axes=(2, 0),
                              reshape=False)
            rot.imag = rotate(org.imag,
                              proj_angles[n],
                              axes=(2, 0),
                              reshape=False)
        else:
            rot.real = transform(org.real,
                                 rotation=(0, proj_angles[n], 0),
                                 rotation_order='sxyz',
                                 interpolation=interpolation)
            rot.imag = transform(org.imag,
                                 rotation=(0, proj_angles[n], 0),
                                 rotation_order='sxyz',
                                 interpolation=interpolation)
        tot += rot
        del org, rot

    if dims[0] % 2:
        t = cp.zeros_like(tot)
        t[1:, 1:, 1:] = tot[:-1, :-1, :-1]
    else:
        t = tot

    return fftshift((ifftn(fftshift(t)).real)).get()
Esempio n. 3
0
def project(v, rot, verbose=False):
    """
    rotate and subsequently project volume along z
    @param v: volume
    @type v: L{pytom_volume.vol}
    @param rot: rotation - either Rotation object or single angle interpreted as rotation along y-axis
    @type rot: L{pytom.basic.structures.Rotation} or float
    @return: projection (2D image)
    @rtype: L{pytom_volume.vol}
    @author: FF
    """
    from pytom_volume import vol
    from pytom_numpy import vol2npy, npy2vol
    from numpy import ndarray, float32
    from pytom.basic.transformations import general_transform_crop
    from pytom.basic.structures import Rotation
    from numpy import sum as proj

    if not isinstance(v, vol):
        raise TypeError('project: v must be of type pytom_volume.vol! Got ' + str(v.__class__) + ' instead!')
    if isinstance(rot, float):
        rot = Rotation(z1=90., z2=270., x=rot, paradigm='ZXZ')
    if not isinstance(rot, Rotation):
        raise TypeError('project: rot must be of type Rotation or float! Got ' + str(v.__class__) + ' instead!')
    if verbose:
        print("project: Rotation for projection: "+str(rot))
    rotvol = general_transform_crop(v=v, rot=rot, shift=None, scale=None, order=[0, 1, 2])
    # slightly awkward: projection in numpy ...
    npvol = vol2npy(rotvol)
    npprojection = ndarray([v.sizeX(), v.sizeY(), 1], dtype=float32, buffer=None, offset=0, strides=npvol.strides,
                           order='F')
    proj(npvol, axis=2, dtype=float32, out=npprojection)
    projection = npy2vol(npprojection,3)
    return projection
Esempio n. 4
0
def pcacov(matrix):
    """
    pcacov: Will determine eigenVector, eigenValue, eigenValueNormed for a matrix consistent to the matlab pcacov function.
    @param matrix: The matrix
    @return: [eigenVector, eigenValue, eigenVectorNormed] - eigenvectors are [nth vector, value] 
    @author: Thomas Hrabe 
    """
    
    from numpy import sum,max,diag
    from scipy.linalg import svd
    
    from pytom_volume import vol
    
    if matrix.__class__ == vol:
        from pytom_numpy import vol2npy
        matrix = vol2npy(matrix)
    
    [x,latent,coeff] = svd(matrix)
    
    totalvar = sum(diag(latent))
    
    explained = 100*latent / totalvar
    
    [sizeX,sizeY] = coeff.shape
    
    abscoeff = abs(coeff)
       
    maxIndex = abscoeff.argmax(1)

    for x in range(sizeX):
        if coeff[x,maxIndex[x]] < 0:
            coeff[x,:] = coeff[x,:] * -1

    return [coeff,latent,explained]
Esempio n. 5
0
File: io.py Progetto: mvanevic/PyTom
def write(filename, data, tilt_angle=0, pixel_size=1):
    """Write EM or MRC file. Now only support written in type float32 on little-endian machines.

    @param filename: file name.
    @param data: data which should be written to file. Can be ndarray or pytom volume
    @param tilt_angle: if data is a projection, this is the tilt angle of the projection.
    @param ndarray: is the data a ndarray or not (if not it is assumed to be a pytom volume).
    @param data: data to write.
    """
    assert filename
    assert filename.split('.')[-1].lower() in ('em', 'mrc')

    if not type(data) == type(np.array((1))):
        from pytom_numpy import vol2npy
        try:
            data = vol2npy(data).copy()
        except:
            raise Exception(
                'Invalid data type of data. Please provide an ndarray or a pytom volume object.'
            )

    if data.dtype != np.dtype("float32"):
        data = data.astype(np.float32)

    if filename.endswith('.em'):
        write_em(filename, data, tilt_angle)
    elif filename.endswith('.mrc'):
        write_mrc(filename, data, tilt_angle, pixel_size=pixel_size)
    else:
        raise Exception(
            'Unsupported file format, cannot write an {}-file'.format(
                filename.split('.')[-1]))
Esempio n. 6
0
def gaussian_filter(vol, sigma):
    """
    @param vol: input volume
    @type vol: L{pytom_volume.vol}
    @param sigma: xxx
    @type sigma: xxx
    @return: resulting volume
    @rtype: L{pytom_volume.vol}
    """
#    # construct the Gaussian kernel
#    import numpy as np
#    from scipy import mgrid, exp
#    sizex = vol.sizeX()
#    sizey = vol.sizeY()
#    sizez = vol.sizeZ()
#    
#    [x, y, z] = mgrid[-(sizex/2):(sizex+1)/2, -(sizey/2):(sizey+1)/2, -(sizez/2):(sizez+1)/2]
#    g = exp(-(x**2+y**2+z**2)/(2*float(sigma)**2))
#    g /= g.sum()
#    
#    # transfer to vol obj and do the filtering
#    from pytom_numpy import npy2vol
#    kernel = npy2vol(np.array(g, dtype='float32', order='F'), 3)
#    
#    from pytom.basic.fourier import convolute
#    res = convolute(vol, kernel, False)

    import numpy as np
    from pytom_numpy import vol2npy, npy2vol
    from scipy.ndimage.filters import gaussian_filter
    v = vol2npy(vol)
    r = gaussian_filter(v, sigma)
    res = npy2vol(np.array(r, dtype='float32', order='F'), 3)
    
    return res
Esempio n. 7
0
def em2markerfile(filename, tiltangles):
    vol = read(filename)
    mf = copy.deepcopy(vol2npy(vol))

    (d, angles, num) = mf.shape
    # print mf.shape
    locX, locY = 1, 2

    mark_frames = -1 * numpy.ones((len(tiltangles), num, 2))

    # print mf[0,:,1:3].shape,self.coordinates[:,0,:].shape
    markers = []
    for i in range(num):
        for j in range(angles):
            m = -1

            for n, angle in enumerate(tiltangles):
                if abs(mf[0, j, i] - angle) < 1:
                    m = n
                    break
            if m == -1: continue

            mark_frames[m, i, 0] = mf[locX, j, i]
            mark_frames[m, i, 1] = mf[locY, j, i]

    return mark_frames
Esempio n. 8
0
def fourier_interpolate_3d_vol(v, nodes):
    """Given a real 3D volume data in PyTom format, interpolate at specified locations in Fourier space.
	@param v: 3D volume data in PyTom format.
	@dtype v: Pytom_volume.vol
	@param nodes: a list of locations in Fourier space. Each node must be in the range [-0.5, 0.5).
	@dtype nodes: List. [[-0.5, -0.5, 0.3], ...]
	@return: interpolated complex values in a list.
	@rtype: List.
	"""
    from pytom_numpy import vol2npy

    # convert to numpy format
    v = vol2npy(v)
    dim_x, dim_y, dim_z = v.shape

    # shift it
    v = np.fft.fftshift(v)

    # linearize it
    v = v.reshape((v.size))

    # linearize it
    nodes = np.array(nodes, dtype="double")
    nodes = nodes.reshape((nodes.size))

    # call the function
    res = fourier_interpolate_3d(v, dim_x, dim_y, dim_z, nodes, nodes.size / 3)

    # convert to complex format
    res = res[::2] + 1j * res[1::2]

    return res
Esempio n. 9
0
def extractPeaksGPU(volume, reference, rotations, scoreFnc=None, mask=None, maskIsSphere=False, wedgeInfo=None, padding=True, **kwargs):
    from pytom_numpy import vol2npy
    from pytom.gpu.gpuStructures import TemplateMatchingGPU
    from pytom.tools.calcFactors import calc_fast_gpu_dimensions
    import time
    import numpy as np
    from pytom_freqweight import weight

    angles = rotations[:]
    volume, ref, mask = [vol2npy(vol) for vol in (volume, reference, mask)]

    wedgeAngle = 30
    wedgeFilter = weight(wedgeAngle, wedgeAngle, ref.shape[0] // 2, ref.shape[0], ref.shape[1], ref.shape[2], 0)
    wedgeVolume = wedgeFilter.getWeightVolume(True)
    wedge = vol2npy(wedgeVolume).copy()

    if padding:
        dimx, dimy, dimz = volume.shape

        cx = calc_fast_gpu_dimensions(dimx - 2, 4000)[0]
        cy = calc_fast_gpu_dimensions(dimy - 2, 4000)[0]
        cz = calc_fast_gpu_dimensions(dimz - 2, 4000)[0]
        voluNDAs = np.zeros([cx, cy, cz], dtype=np.float32)
        voluNDAs[:min(cx, dimx), :min(cy, dimy), :min(cz, dimz)] = volume[:min(cx, dimx), :min(cy, dimy),
                                                                   :min(cz, dimz)]
        volume = voluNDAs
        print(f'dimensions of volume: {ref.shape}')

    input = (volume, ref, mask, wedge, angles, volume.shape)

    tm_process = TemplateMatchingGPU(0, kwargs['gpuID'][0], input=input)
    tm_process.start()
    while tm_process.is_alive():
        time.sleep(1)

    if tm_process.completed:
        print('Templated matching completed successfully')
        return [tm_process.plan.scores.get(), tm_process.plan.angles.get(), None, None]
    else:
        raise Exception('failed template matching')
Esempio n. 10
0
    def numpy_T(self, v=None):
        import pytom_numpy

        if not v:
            from pytom_volume import vol, gaussianNoise
            v = vol(10, 10, 10)
            gaussianNoise(v, 0, 1)

        nv = pytom_numpy.vol2npy(v)
        #print 'hier'
        #print nv.shape,nv.strides,nv.dtype
        #print v.strideX(),v.strideY(),v.strideZ()
        vv = pytom_numpy.npy2vol(nv, 3)

        self.assertTrue(v.equalsTo(vv), msg='numpy issue :(')
Esempio n. 11
0
def readMarkerfile(filename, num_tilt_images=0):
    if filename.endswith('.em'):
        from pytom.basic.files import read
        from pytom_numpy import vol2npy
        markerfile = read(filename)
        markerdata = vol2npy(markerfile).copy()
        return markerdata

    elif filename.endswith('.txt'):
        data = loadstar(filename)
        datalen = data.shape[0]
        num_tilt_images = (data[:, 0] == data[0, 0]).sum()
        x, y = datalen // num_tilt_images, num_tilt_images
        markerdata = data.reshape(x, y, 4)[:, :, 1:].transpose(2, 1, 0)
        return markerdata
Esempio n. 12
0
 def getSlice(self, n, projectionAxis='z'):
     assert n>= 0
     
     from pytom_numpy import vol2npy
     nvol = vol2npy(self.vol)
     
     from pytom_volume import subvolume
     if projectionAxis == 'x':
         slice = nvol[n,:,:]
     elif projectionAxis == 'y':
         slice = nvol[:,n,:]
     elif projectionAxis == 'z':
         slice = nvol[:,:,n]
     else:
         raise Exception("Projection axis must be either 'x', 'y' or 'z'!")
     
     return slice
Esempio n. 13
0
def recenterVolume(volume, densityNegative=False):
    from scipy.ndimage import center_of_mass
    from pytom.tompy.io import read, write
    from pytom.tompy.tools import paste_in_center
    from pytom.gpu.initialize import xp
    from pytom_numpy import vol2npy
    import os

    try:
        a = vol2npy(volume).copy()
        vol = True
    except:
        a = volume
        vol = False

    if densityNegative:
        a *= -1

    x, y, z = list(map(int, center_of_mass(a)))
    cx, cy, cz = a.shape[0] // 2, a.shape[1] // 2, a.shape[2] // 2

    sx = min(x, a.shape[0] - x)
    sy = min(y, a.shape[0] - y)
    sz = min(z, a.shape[0] - z)

    ac = a[x - sx:x + sx, y - sy:y + sy, z - sz:z + sz]
    b = xp.zeros_like(a)

    b = paste_in_center(ac, b)

    if densityNegative: b *= -1

    if vol:
        write('recenteredDBV21.em', b)
        from pytom.basic.files import read
        vol = read('recenteredDBV21.em')
        os.system('rm recenteredDBV21.em')
        return vol
    else:
        return b
Esempio n. 14
0
def fourier_rotate_vol(v, angle):
    """Be careful with rotating a odd-sized volume, since nfft will not give correct result!
	"""
    # get the rotation matrix
    from pytom.basic.structures import Rotation
    rot = Rotation(angle)
    m = rot.toMatrix()
    m = m.transpose()  # get the invert rotation matrix
    m = np.array([m.getRow(0), m.getRow(1), m.getRow(2)], dtype="float32")
    m = m.flatten()

    # prepare the volume
    from pytom_numpy import vol2npy

    v = vol2npy(v)
    dim_x, dim_y, dim_z = v.shape

    # twice shift means no shift!
    # v = np.fft.fftshift(v)

    # linearize it
    v = v.reshape((v.size))

    # allocate the memory for the result
    res = np.zeros(v.size * 2, dtype="float32")

    # call the low level c function
    swig_nufft.fourier_rotate_vol(v, dim_x, dim_y, dim_z, m, res)

    res = res[::2] + 1j * res[1::2]
    res = res.reshape((dim_x, dim_y, dim_z), order='F')

    # inverse fft
    ans = np.fft.ifftshift(np.real(np.fft.ifftn(np.fft.ifftshift(res))))

    # transfer to pytom volume format
    from sh.frm import np2vol
    res = np2vol(ans)

    return res
Esempio n. 15
0
def decomposeMatrix(matrixFile):
    """
    decomposeMatrix: Will perform analysis on calculated matrix using scipy.linalg tools
    @param matrixFile: Correlation matrix in em format
    @type matrixFile: Either the matrix as volume or a string   
    @return: [eigenValues,eigenVectors] of the matrix
    """

    from scipy import linalg
    from numpy import matrix

    if matrixFile.__class__ == str:
        from pytom_volume import read
        corrMatrix = read(matrixFile)
    else:
        corrMatrix = matrixFile

    matStr = ''  #copy all matrix values into string
    try:
        #try to use shortest path by converting from tom volume to numpy matrix
        from pytom_numpy import vol2npy

        mat = matrix(vol2npy(corrMatrix))

    except ImportError:
        #numpy did not work. copy each entry into string and proceed, takes long time

        for x in range(corrMatrix.sizeX()):
            for y in range(corrMatrix.sizeY()):
                matStr = matStr + ' ' + str(corrMatrix.getV(x, y, 0))
            if x < (corrMatrix.sizeX() - 1):
                matStr = matStr + ';'

            mat = matrix(matStr)  #generate numpy.matrix from string

    return linalg.eigh(mat)  #determine values
Esempio n. 16
0
def extractPeaksGPU(volume,
                    reference,
                    rotations,
                    scoreFnc=None,
                    mask=None,
                    maskIsSphere=False,
                    wedgeInfo=None,
                    padding=True,
                    **kwargs):
    from pytom_numpy import vol2npy
    from pytom.tompy.filter import create_wedge, applyFourierFilter
    from pytom.tompy.io import write
    from pytom.gpu.gpuStructures import TemplateMatchingGPU
    from pytom.tools.calcFactors import calc_fast_gpu_dimensions
    import time
    import numpy as np
    from pytom_freqweight import weight

    angles = rotations[:]
    #volume = wedgeInfo.apply(volume)

    volume, ref, mask = [vol2npy(vol) for vol in (volume, reference, mask)]
    SX, SY, SZ = volume.shape
    sx, sy, sz = ref.shape
    angle = wedgeInfo.getWedgeAngle()

    if angle.__class__ != list:
        w1 = w2 = angle
    else:
        w1, w1 = angle

    if w1 > 1E-3 or w2 > 1E-3:
        print('Wedge applied to volume')
        cutoff = wedgeInfo._wedgeObject._cutoffRadius if wedgeInfo._wedgeObject._cutoffRadius > 1E-3 else sx // 2
        smooth = wedgeInfo._wedgeObject._smooth
        wedge = create_wedge(w1, w2, cutoff, sx, sy, sz,
                             smooth).astype(np.complex64)
        wedgeVolume = create_wedge(w1, w2, SX // 2 - 2, SX, SY, SZ,
                                   smooth).astype(np.float32)
        volume = np.real(
            np.fft.irfftn(np.fft.rfftn(volume) * wedgeVolume.get()))

    else:
        wedge = np.ones((sx, sy, sz // 2 + 1), dtype='float32')
        #wedgeVolume = np.ones_like(volume,dtype='float32')

    if padding:
        dimx, dimy, dimz = volume.shape

        cx = max(ref.shape[0], calc_fast_gpu_dimensions(dimx - 2, 4000)[0])
        cy = max(ref.shape[1], calc_fast_gpu_dimensions(dimy - 2, 4000)[0])
        cz = max(ref.shape[2], calc_fast_gpu_dimensions(dimz - 2, 4000)[0])
        voluNDAs = np.zeros([cx, cy, cz], dtype=np.float32)
        voluNDAs[:min(cx, dimx), :min(cy, dimy), :min(cz, dimz)] = volume[:min(
            cx, dimx), :min(cy, dimy), :min(cz, dimz)]
        volume = voluNDAs
        print(f'dimensions of volume: {ref.shape} {mask.shape} ')

    input = (volume, ref, mask, wedge, angles, volume.shape)

    tm_process = TemplateMatchingGPU(0, kwargs['gpuID'][0], input=input)
    tm_process.start()
    while tm_process.is_alive():
        time.sleep(1)

    if tm_process.completed:
        print('Templated matching completed successfully')
        return [
            tm_process.plan.scores.get(),
            tm_process.plan.angles.get(), None, None
        ]
    else:
        raise Exception('failed template matching')
Esempio n. 17
0
def createMetaDataFiles(nanographfolder,
                        mdocfiles=[],
                        target='',
                        mdoc_only=False):

    if not mdocfiles:
        mdocfiles = [
            mdocfile for mdocfile in os.listdir(nanographfolder)
            if mdocfile.endswith('.mdoc')
        ]
    datafiles = [
        fname for fname in os.listdir(nanographfolder)
        if fname.split('.')[-1] in ('tif', 'mrc', 'em',
                                    'st') and not (fname[0] in '0123456789')
    ]

    annotated = {}

    tomo_from_filename = {}
    tomo_from_stack = {}

    for df in datafiles:
        annotated[os.path.basename(df)] = 0
        if os.path.basename(df).endswith('.st'):
            annotated[os.path.basename(df)] = 'st'

    tiltAxis = 180
    pixelSpacing = 1.5
    voltage = 300

    for nr, mdocfile in enumerate(sorted(mdocfiles)):
        metadata = []
        mdocfilepath = os.path.join(nanographfolder, mdocfile)
        header = False
        datadict = {
            'TiltAngle': tiltAxis,
            'Magnification': 79000,
            'Intensity': 0.0,
            'PixelSpacing': pixelSpacing,
            'Defocus': 3,
            'RotationAngle': 270,
            'SubFramePath': '',
            'Voltage': voltage,
            'MarkerDiameter': 100,
            'SphericalAberration': 2.7,
            'AmplitudeContrast': 0.08,
            'PhaseContrast': 0.,
        }
        for description, dtype in datatype:
            if not description in datadict.keys(): datadict[description] = 0.

        mdocdata = [
            line.split() for line in open(mdocfilepath).readlines()
            if len(line.split()) >= 3
        ]
        nrTiltImages = 0
        for nn, line in enumerate(mdocdata):
            if '[ZValue' == line[0] and not header:
                header = True
                continue

            if not header:
                if line[0] == 'PixelSpacing':
                    datadict[line[0]] = float(line[2])
                elif line[0] == 'Voltage':
                    datadict[line[0]] = int(line[2])
                elif line[0] == 'ImageSize':
                    try:
                        datadict[line[0]] = min(int(line[2]), int(line[3]))
                    except:
                        pass
                elif 'axis' in line:
                    datadict['InPlaneRotation'] = float(
                        line[6].strip(',')) - 250
                continue

            if line[0] in datadict.keys():
                if line[0] == 'RotationAngle': line[0] = 'RotationTheta'
                try:
                    datadict[line[0]] = float(line[2])
                except:
                    fname = os.path.basename(line[2].replace('\\', '/'))
                    datadict['FileName'] = fname
                    if fname in annotated.keys():
                        annotated[fname] += 1

            if '[ZValue' == line[0] or nn + 1 == len(mdocdata):
                data = [
                    0.,
                ] * len(datatype)
                for n, (description, dtype) in enumerate(datatype):
                    if description in datadict.keys():
                        data[n] = datadict[description]
                if 'Defocus' in datadict.keys():
                    data[0] = datadict['Defocus']
                    data[1] = datadict['Defocus']

                if 'AcquisitionOrder' == datatype[-2][0]:
                    data[-2] = nrTiltImages
                    nrTiltImages += 1

                metadata.append(tuple(data))

        if len(metadata) == 0: continue
        a = numpy.rec.array(metadata, dtype=datatype)
        a = numpy.sort(a, order='TiltAngle')

        outname = mdocfilepath.replace('mdoc', 'meta')
        if target:
            outname = os.path.join(target, mdocfile.replace('mdoc', 'meta'))
        savestar(outname, a, fmt=fmt, header=headerText)

    if mdoc_only: return

    acquisition_order = {}
    size = {}

    for k, v in annotated.items():
        if v == 0:
            tomoname = k.split('_')[0]
            if not tomoname in tomo_from_filename.keys():
                tomo_from_filename[tomoname] = []

                if k.split('.')[-1] in ('mrc', 'em'):
                    vol = read(os.path.join(nanographfolder, k))
                    data = copy.deepcopy(vol2npy(vol))
                    size[tomoname] = numpy.min(data.shape)
                else:

                    #try:
                    #    data = imread( os.path.join(nanographfolder,k) )
                    #    size[tomoname] = numpy.min(data.shape)
                    #except:
                    aa = os.popen(
                        'header {} | grep "Number of columns, rows, sections" '
                        .format(os.path.join(nanographfolder, k))).read()[:-1]
                    dd = list(map(int, aa.split()[-3:-1]))
                    size[tomoname] = numpy.min(dd)

            #Find tiltangle

            if k.endswith('em'):
                fileHeader = read_em_header(os.path.join(nanographfolder, k))
                tiltangle = fileHeader.get_tiltangle()

            elif k.endswith('mrc'):
                tiltangle = read_angle(os.path.join(nanographfolder, k))
            else:
                tiltangle = 0.

            tomo_from_filename[tomoname].append([
                k.replace('[', '_').replace(']', '_').split('_'), tiltangle, k
            ])

        if v == 'st':
            from pytom.tompy.io import read as readNPY, read_size, read_pixelsize
            from numpy import loadtxt

            stackfile = os.path.join(nanographfolder, k)
            tltfile = stackfile.replace('.st', '.tlt')

            x, y, z = read_size(os.path.join(nanographfolder, k))
            pixelsize = read_pixelsize(stackfile, 'x')

            print(f'\n\n\n{tltfile}')

            if not os.path.exists(tltfile):
                print(f'failed for {tltfile}')
                continue

            tiltangles = loadtxt(tltfile)

            tomoname = k[:-3]

            metadata = numpy.zeros((len(tiltangles)), dtype=datatype)

            for i, tiltangle in enumerate(tiltangles):

                metadata['TiltAngle'][i] = tiltangle
                metadata['FileName'][
                    i] = f'{nanographfolder}/IMODSTACK_{tomoname}_{i:02d}.mrc'
                metadata['ImageSize'][i] = min(x, y)
                metadata['PixelSpacing'][i] = pixelsize
                metadata['DefocusU'][i] = 3
                metadata['DefocusV'][i] = 3
                metadata['Voltage'][i] = 200
                metadata['SphericalAberration'][i] = 2.7
                metadata['AmplitudeContrast'][i] = 0.8
                metadata['MarkerDiameter'][i] = 100

            a = numpy.sort(metadata, order='TiltAngle')

            outname = '{}/{}.meta'.format(nanographfolder, tomoname)
            print(outname)
            savestar(outname, a, fmt=fmt, header=headerText)

    for NR, (k, v) in enumerate(tomo_from_filename.items()):

        neg = numpy.array([
            0,
        ] * len(v[0][0]), dtype=int)
        tiltangles_header = []
        for list2, angle, fname in v:
            tiltangles_header.append(angle)
            for n, part in enumerate(list2):
                if '-' in part:
                    neg[n] += 1

        loc = numpy.argmax(neg[neg < len(v)])

        if not neg[loc] > 0:
            loc = -1

        tiltangles_header = numpy.array(tiltangles_header)
        metadata = [
            [
                0.,
            ] * len(datatype),
        ] * len(v)

        for NR, (d, t) in enumerate(datatype):
            if d == 'TiltAngle':

                break

        if len(v) < 10:
            return

        if loc > -0.5:
            for i in range(len(v)):
                metadata[i][NR] = float(v[i][0][loc])
                metadata[i][-1] = v[i][2]
                if datatype[-3][0] == 'ImageSize': metadata[i][-3] = size[k]
                metadata[i] = tuple(metadata[i])

        elif len(numpy.unique(numpy.round(tiltangles_header).astype(
                int))) == len(tiltangles_header):
            for i in range(len(v)):
                metadata[i][NR] = float(tiltangles_header[i])
                metadata[i][-1] = v[i][2]
                if datatype[-3][0] == 'ImageSize': metadata[i][-3] = size[k]
                metadata[i] = tuple(metadata[i])

        else:
            continue

        a = numpy.rec.array(metadata, dtype=datatype)
        a = numpy.sort(a, order='TiltAngle')

        outname = '{}/{}.meta'.format(nanographfolder, v[0][0][0])
        savestar(outname, a, fmt=fmt, header=headerText)
Esempio n. 18
0
File: misc.py Progetto: xmzzaa/PyTom
def bart_align_vol(vf, wf, vg, wg, b, radius=None, peak_offset=None):
    """Implementation of Bartesaghi's approach for alignment. For detail, please check the paper.

    Parameters
    ----------
    vf: The volume you want to match.
        pytom_volume.vol

    wf: The single tilt wedge information of volume vf.
        [missing_wedge_angle1, missing_wedge_angle2]. Note this is defined different with frm_align im frm.py!

    vg: The reference volume.
        pytom_volume.vol

    wg: The single tilt wedge information of volume vg.
        [missing_wedge_angle1, missing_wedge_angle2]. Note this is defined different with frm_align im frm.py!

    b: The bandwidth of spherical harmonics.
       Integer in the range [4, 64]

    radius: The maximal radius in the Fourier space, which is equal to say the maximal frequency involved in calculation.
            Integer. By default is half of the volume size.

    peak_offset: The maximal offset which allows the peak of the score to be.
                 Or simply speaking, the maximal distance allowed to shift vg to match vf.
                 This parameter is needed to prevent shifting the reference volume out of the frame.
                 Integer. By default is half of the volume size.

    Returns
    -------
    The best translation and rotation (Euler angle, ZXZ convention [Phi, Psi, Theta]) to transform vg to match vf.
    (best_translation, best_rotation, correlation_score)
    """
    from pytom_volume import vol, rotateSpline, max, peak
    from pytom.basic.correlation import nXcf
    from pytom.basic.filter import lowpassFilter
    from pytom.basic.structures import WedgeInfo
    from pytom_volume import initSphere

    if not radius: # set the radius
        radius = vf.sizeX()/2

    if peak_offset is None:
        peak_offset = vol(vf.sizeX(), vf.sizeY(), vf.sizeZ())
        initSphere(peak_offset, vf.sizeX()/2, 0,0, vf.sizeX()/2,vf.sizeY()/2,vf.sizeZ()/2)
    elif isinstance(peak_offset, int):
        peak_radius = peak_offset
        peak_offset = vol(vf.sizeX(), vf.sizeY(), vf.sizeZ())
        initSphere(peak_offset, peak_radius, 0,0, vf.sizeX()/2,vf.sizeY()/2,vf.sizeZ()/2)
    elif peak_offset.__class__ == vol:
        pass
    else:
        raise RuntimeError('Peak offset is given wrong!')
    
    from pytom.basic.fourier import fft, ifft, ftshift, iftshift
    from pytom_volume import vol, reducedToFull, rescale, abs, real
    from .vol2sf import vol2sf
    from pytom_numpy import vol2npy
    from math import log, ceil, pow

    # IMPORTANT!!! Should firstly do the IFFTSHIFT on the volume data (NOT FFTSHIFT since for odd-sized data it matters!),
    # and then followed by the FFT.
    ff = abs(ftshift(reducedToFull(fft(iftshift(vf, inplace=False))), inplace=False))
    ff = real(ff)
    gg = abs(ftshift(reducedToFull(fft(iftshift(vg, inplace=False))), inplace=False))
    gg = real(gg)
    
    sf = None
    sg = None
    mf = create_wedge_sf(wf[0], wf[1], b)
    mg = create_wedge_sf(wg[0], wg[1], b)

    for r in range(3, radius+1): # Should start from 3 since the interpolation in the first 2 bands is not accurate.
        if sf is None:
            sf = vol2sf(ff, r, b)
            sg = vol2sf(gg, r, b)
        else:
            sf += vol2sf(ff, r, b)
            sg += vol2sf(gg, r, b)
    
    corr = frm_constrained_corr(sf, mf, sg, mg)
    ang, val = frm_find_best_angle_interp(corr)

    tmp = vol(vg.sizeX(),vg.sizeY(),vg.sizeZ())
    rotateSpline(vg, tmp, ang[0], ang[1], ang[2])
    wedge_f = WedgeInfo(90+wf[0], 90-wf[1])
    wedge_g = WedgeInfo(90+wg[0], 90-wg[1])
    cc = nXcf(lowpassFilter(wedge_g.apply(vf), radius, 0)[0], lowpassFilter(wedge_f.apply(tmp), radius, 0)[0])
    pos = peak(cc, peak_offset)
    pos, score = find_subpixel_peak_position(vol2npy(cc), pos)

    return (pos, ang, score)
Esempio n. 19
0
File: misc.py Progetto: xmzzaa/PyTom
def xu_align_vol(vf, wf, vg, wg, b, radius=None, mask=None, peak_offset=None):
    """Implementation of Xu's approach for alignment. For detail, please check the paper.

    Parameters
    ----------
    vf: The volume you want to match.
        pytom_volume.vol

    wf: The single tilt wedge information of volume vf.
        [missing_wedge_angle1, missing_wedge_angle2]. Note this is defined different with frm_align im frm.py!

    vg: The reference volume.
        pytom_volume.vol

    wg: The single tilt wedge information of volume vg.
        [missing_wedge_angle1, missing_wedge_angle2]. Note this is defined different with frm_align im frm.py!

    b: The adaptive bandwidth of spherical harmonics.
       List [min_bandwidth, max_bandwidth], min_bandwidth, max_bandwidth in the range [4, 64].
       Or integer, which would then mean to use fixed bandwidth: min_bandwidth = max_bandwidth = integer.

    radius: The maximal radius in the Fourier space, which is equal to say the maximal frequency involved in calculation.
            Integer. By default is half of the volume size.

    peak_offset: The maximal offset which allows the peak of the score to be.
                 Or simply speaking, the maximal distance allowed to shift vg to match vf.
                 This parameter is needed to prevent shifting the reference volume out of the frame.
                 Integer. By default is half of the volume size.

    Returns
    -------
    The best translation and rotation (Euler angle, ZXZ convention [Phi, Psi, Theta]) to transform vg to match vf.
    (best_translation, best_rotation, correlation_score)
    """
    from pytom_volume import vol, rotateSpline, peak
    from pytom.basic.transformations import shift
    from pytom.basic.correlation import nXcf
    from pytom.basic.filter import lowpassFilter
    from pytom.basic.structures import Mask
    from pytom_volume import initSphere
    from pytom_numpy import vol2npy

    if vf.sizeX()!=vg.sizeX() or vf.sizeY()!=vg.sizeY() or vf.sizeZ()!=vg.sizeZ():
        raise RuntimeError('Two volumes must have the same size!')

    if mask is None:
        mask = vol(vf.sizeX(), vf.sizeY(), vf.sizeZ())
        initSphere(mask, vf.sizeX()/2, 0,0, vf.sizeX()/2,vf.sizeY()/2,vf.sizeZ()/2)
    elif mask.__class__ == vol:
        pass
    elif mask.__class__ == Mask:
        mask = mask.getVolume()
    elif isinstance(mask, int):
        mask_radius = mask
        mask = vol(vf.sizeX(), vf.sizeY(), vf.sizeZ())
        initSphere(mask, mask_radius, 0,0, vf.sizeX()/2,vf.sizeY()/2,vf.sizeZ()/2)
    else:
        raise RuntimeError('Given mask has wrong type!')

    if peak_offset is None:
        peak_offset = vol(vf.sizeX(), vf.sizeY(), vf.sizeZ())
        initSphere(peak_offset, vf.sizeX()/2, 0,0, vf.sizeX()/2,vf.sizeY()/2,vf.sizeZ()/2)
    elif isinstance(peak_offset, int):
        peak_radius = peak_offset
        peak_offset = vol(vf.sizeX(), vf.sizeY(), vf.sizeZ())
        initSphere(peak_offset, peak_radius, 0,0, vf.sizeX()/2,vf.sizeY()/2,vf.sizeZ()/2)
    elif peak_offset.__class__ == vol:
        pass
    else:
        raise RuntimeError('Peak offset is given wrong!')

    # cut out the outer part which normally contains nonsense
    vf = vf*mask

    position = None
    if position is None: # if position is not given, we have to find it ourself
        # first roughtly determine the orientation (only according to the energy info)
        # get multiple candidate orientations
        orientations = frm_determine_orientation(vf, wf, vg, wg, b, radius, None, None, False)
    else:
        # the position is given by the user
        vf2 = shift(vf, -position[0]+vf.sizeX()/2, -position[1]+vf.sizeY()/2, -position[2]+vf.sizeZ()/2, 'spline')
        res = frm_fourier_adaptive_wedge_vol(vf2, wf, vg, wg, b, radius, None, None, False)
        orientation, max_value = frm_find_best_angle_interp(res)

        return position, orientation, max_value

    
    from pytom.basic.structures import WedgeInfo
    from pytom.tools.maths import euclidianDistance
    max_iter = 1 # maximal number of iterations
    wedge = WedgeInfo([90+wf[0], 90-wf[1]])
    old_pos = [-1, -1, -1]
    vg2 = vol(vg.sizeX(), vg.sizeY(), vg.sizeZ())
    lowpass_vf = lowpassFilter(vf, radius, 0)[0]
    
    peak_value = 0.0
    position = None
    ang = None
    for orientation in orientations:
        orientation = orientation[0]

        rotateSpline(vg, vg2, orientation[0], orientation[1], orientation[2]) # first rotate
        vg2 = wedge.apply(vg2) # then apply the wedge
        vg2 = lowpassFilter(vg2, radius, 0)[0]
        res = nXcf(lowpass_vf, vg2) # find the position
        pos = peak(res, peak_offset)
        # val = res(pos[0], pos[1], pos[2])
        pos, val = find_subpixel_peak_position(vol2npy(res), pos)
        if val > peak_value:
            position = pos
            ang = orientation
            peak_value = val

    return position, ang, peak_value
Esempio n. 20
0
File: test.py Progetto: xmzzaa/PyTom
    InterFunc = 1. + (IijFunc_sum)
    wf = 1. / InterFunc
    for ix in range(0, sX):
        for iy in range(0, sizeY):
            weightFunc.setV(wf[ix], ix, iy, 0)

    return weightFunc


#import matplotlib
#matplotlib.use('Qt5Agg')

sX, sY = 1000, 1000
tilt_angles = range(-60, 60, 2)
tiltAngle = 0
sliceWidth = 1000

from pytom_numpy import vol2npy
from copy import deepcopy

d = exactFilter(tilt_angles, tiltAngle, sX, sY, sliceWidth)

data = deepcopy(vol2npy(d))

print(data.shape, data.sum())

from pylab import *

plot(data)
show()
Esempio n. 21
0
    num_angles, size = map(int, sys.argv[1:3])
    size2 = int(sys.argv[3])
    csize = int(sys.argv[4])

    try:
        start, end = map(int, sys.argv[5:7])
    except:
        start, end = 0, csize

    wedgeAngle = 30
    wedgeFilter = weight(wedgeAngle, 0, end - start, size, size)
    wedgeVolume = wedgeFilter.getWeightVolume(True)

    filterVolume = pytom_volume.reducedToFull(wedgeVolume)
    wedgeV = vol2npy(filterVolume).copy()

    from pytom.tompy.io import read
    import mrcfile

    # NDARRAYS
    voluNDA = mrcfile.open('tomo.mrc', permissive=True).data.copy()
    tempNDA = read('template.em')
    maskNDA = read("mask.em")

    sox, soy, soz = tempNDA.shape
    spx, spy, spz = voluNDA.shape

    #GPUARRAYS
    voluGPU = gu.to_gpu(voluNDA.astype(np.float32))
    tempGPU = gu.to_gpu(tempNDA.astype(np.float32))
Esempio n. 22
0
def frm_constrained_align(vf,
                          wf,
                          vg,
                          wg,
                          b,
                          max_freq,
                          peak_offset=None,
                          mask=None,
                          constraint=None,
                          weights=None,
                          position=None,
                          num_seeds=5,
                          pytom_volume=None):
    """Find the best alignment (translation & rotation) of volume vg (reference) to match vf.
    For details, please check the paper.

    Parameters
    ----------
    vf: Volume Nr. 1
        pytom_volume.vol

    wf: Mask of vf in Fourier space.
        pytom.basic.structures.Wedge. If none, no missing wedge.

    vg: Volume Nr. 2 / Reference
        pytom_volume.vol

    wg: Mask of vg in Fourier space.
        pytom.basic.structures.Wedge. If none, no missing wedge.

    b: Bandwidth range of spherical harmonics.
       None -> [4, 64]
       List -> [b_min, b_max]
       Integer -> [b, b]

    max_freq: Maximal frequency involved in calculation.
              Integer.

    peak_offset: The maximal offset which allows the peak of the score to be.
                 Or simply speaking, the maximal distance allowed to shift vg to match vf.
                 This parameter is needed to prevent shifting the reference volume out of the frame.
                 pytom_volume.vol / Integer. By default is half of the volume radius.

    mask: Mask volume for vg in real space.
          pytom_volume.vol

    constraint: Angular constraint
                sh_alignment.constrained_frm.AngularConstraint

    weights: Obsolete.

    position: If the translation is already known or not. If provided, no translational search will be conducted.
              List: [x,y,z], default None.

    num_seeds: Number of threads for the expectation maximization procedure. The more the better, yet slower.
               Integer, default is 5.

    Returns
    -------
    (The best translation and rotation (Euler angle, ZXZ convention [Phi, Psi, Theta]) to transform vg to match vf.
    (best_translation, best_rotation, correlation_score)
    """
    from pytom_volume import vol, rotateSpline, peak
    from pytom.basic.transformations import shift
    from pytom.basic.correlation import FLCF
    from pytom.basic.filter import lowpassFilter
    from pytom.basic.structures import Mask, SingleTiltWedge
    from pytom_volume import initSphere
    from pytom_numpy import vol2npy

    if vf.sizeX() != vg.sizeX() or vf.sizeY() != vg.sizeY() or vf.sizeZ(
    ) != vg.sizeZ():
        raise RuntimeError('Two volumes must have the same size!')

    if wf is None:
        wf = SingleTiltWedge(0)
    if wg is None:
        wg = SingleTiltWedge(0)

    if peak_offset is None:
        peak_offset = vol(vf.sizeX(), vf.sizeY(), vf.sizeZ())
        initSphere(peak_offset,
                   vf.sizeX() / 4, 0, 0,
                   vf.sizeX() / 2,
                   vf.sizeY() / 2,
                   vf.sizeZ() / 2)
    elif peak_offset.__class__ == int:
        peak_radius = peak_offset
        peak_offset = vol(vf.sizeX(), vf.sizeY(), vf.sizeZ())
        initSphere(peak_offset, peak_radius, 0, 0,
                   vf.sizeX() / 2,
                   vf.sizeY() / 2,
                   vf.sizeZ() / 2)
    elif peak_offset.__class__ == vol:
        pass
    else:
        raise RuntimeError('Peak offset is given wrong!')

    # cut out the outer part which normally contains nonsense
    m = vol(vf.sizeX(), vf.sizeY(), vf.sizeZ())
    initSphere(m,
               vf.sizeX() / 2, 0, 0,
               vf.sizeX() / 2,
               vf.sizeY() / 2,
               vf.sizeZ() / 2)
    vf = vf * m
    vg = vg * m
    if mask is None:
        mask = m
    else:
        vg = vg * mask

    if position is None:  # if position is not given, we have to find it ourself
        # first roughtly determine the orientation (only according to the energy info)
        # get multiple candidate orientations
        numerator, denominator1, denominator2 = frm_correlate(
            vf, wf, vg, wg, b, max_freq, weights, True, None, None, False)
        score = numerator / (denominator1 * denominator2)**0.5
        res = frm_find_topn_constrained_angles_interp(
            score, num_seeds,
            get_adaptive_bw(max_freq, b) / 16., constraint)
    else:
        # the position is given by the user
        vf2 = shift(vf, -position[0] + vf.sizeX() / 2,
                    -position[1] + vf.sizeY() / 2,
                    -position[2] + vf.sizeZ() / 2, 'fourier')
        score = frm_correlate(vf2, wf, vg, wg, b, max_freq, weights, ps=False)
        orientation, max_value = frm_find_best_constrained_angle_interp(
            score, constraint=constraint)

        return position, orientation, max_value

    # iteratively refine the position & orientation
    from pytom.tools.maths import euclidianDistance
    max_iter = 10  # maximal number of iterations
    mask2 = vol(mask.sizeX(), mask.sizeY(),
                mask.sizeZ())  # store the rotated mask
    vg2 = vol(vg.sizeX(), vg.sizeY(), vg.sizeZ())
    lowpass_vf = lowpassFilter(vf, max_freq, max_freq / 10.)[0]

    max_position = None
    max_orientation = None
    max_value = -1.0
    for i in xrange(num_seeds):
        old_pos = [-1, -1, -1]
        lm_pos = [-1, -1, -1]
        lm_ang = None
        lm_value = -1.0
        orientation = res[i][0]  # initial orientation
        for j in xrange(max_iter):
            rotateSpline(vg, vg2, orientation[0], orientation[1],
                         orientation[2])  # first rotate
            rotateSpline(mask, mask2, orientation[0], orientation[1],
                         orientation[2])  # rotate the mask as well
            vg2 = wf.apply(vg2)  # then apply the wedge
            vg2 = lowpassFilter(vg2, max_freq, max_freq / 10.)[0]
            score = FLCF(lowpass_vf, vg2, mask2)  # find the position
            pos = peak(score, peak_offset)
            pos, val = find_subpixel_peak_position(vol2npy(score), pos)
            if val > lm_value:
                lm_pos = pos
                lm_ang = orientation
                lm_value = val

            if euclidianDistance(lm_pos, old_pos) <= 1.0:
                # terminate this thread
                if lm_value > max_value:
                    max_position = lm_pos
                    max_orientation = lm_ang
                    max_value = lm_value

                break
            else:
                old_pos = lm_pos

            # here we shift the target, not the reference
            # if you dont want the shift to change the energy landscape, use fourier shift
            vf2 = shift(vf, -lm_pos[0] + vf.sizeX() / 2,
                        -lm_pos[1] + vf.sizeY() / 2,
                        -lm_pos[2] + vf.sizeZ() / 2, 'fourier')
            score = frm_correlate(vf2, wf, vg, wg, b, max_freq, weights, False,
                                  denominator1, denominator2, True)
            orientation, val = frm_find_best_constrained_angle_interp(
                score, constraint=constraint)

        else:  # no converge after the specified iteration, still get the best result as we can
            if lm_value > max_value:
                max_position = lm_pos
                max_orientation = lm_ang
                max_value = lm_value

        # print max_value # for show the convergence of the algorithm

    return max_position, max_orientation, max_value
Esempio n. 23
0
def backProjectGPU2(vol_img, vol_bp, vol_phi, vol_the, recPosVol=[0,0,0], vol_offsetProjections=[0,0,0]):
    from pytom_numpy import vol2npy
    import cupy as cp
    from cupy import cos, sin
    import voltools

    projections = vol2npy(vol_img)
    proj_angles = vol2npy(vol_the)[0,0,:]

    dims = (vol_bp.sizeX(), vol_bp.sizeY(), vol_bp.sizeZ())
    # TODO add offsets

    # preparation
    reconstruction = cp.zeros(dims, dtype=cp.float32)
    theta_angles = cp.deg2rad(cp.array(proj_angles))

    # theta_angles_rad = (theta_angles)
    assert len(theta_angles) == projections.shape[2] #'Number of angles and projections should match'
    # create coordinates and stack them
    x, y, z = cp.meshgrid(cp.arange(0, dims[0]), cp.arange(0, dims[1]), cp.arange(0, dims[2]), indexing='ij')
    # backproject each projection into reconstruction

    for n in range(projections.shape[2]):
        # get projection
        src = cp.array(projections[:,:,n])

        # previous
        Z1 = Z2 = 0.0
        Y = theta_angles[n]
        x_offset = y_offset = z_offset = 0
        x_proj_offset = y_proj_offset = 0
        tr11 = cos(Y)*cos(Z1)*cos(Z2)-sin(Z1)*sin(Z2)
        # tr21 = cos(Y)*sin(Z1)*cos(Z2)+cos(Z1)*sin(Z2)
        tr31 = -sin(Y)*cos(Z2)
        # tr12 = -cos(Y)*cos(Z1)*sin(Z2)-sin(Z1)*cos(Z2)
        tr22 = -cos(Y)*sin(Z1)*sin(Z2)+cos(Z1)*cos(Z2)
        # tr32 = sin(Y)*sin(Z2)
        reconstruction_center_x = dims[0] // 2 - x_offset
        reconstruction_center_y = dims[1] // 2 - y_offset
        reconstruction_center_z = dims[2] // 2 - z_offset
        projection_center_x = dims[0] // 2 + x_proj_offset
        projection_center_y = dims[1] // 2 + y_proj_offset
        # interpolation_position_x = tr11 * (x - reconstruction_center_x) + tr21 * (y - reconstruction_center_y) + tr31 * (z - reconstruction_center_z) + projection_center_x
        # interpolation_position_y = tr12 * (x - reconstruction_center_x) + tr22 * (y - reconstruction_center_y) + tr32 * (z - reconstruction_center_z) + projection_center_y
        interpolation_position_x = tr11 * (x - reconstruction_center_x) + tr31 * (z - reconstruction_center_z) + projection_center_x
        interpolation_position_y = tr22 * (y - reconstruction_center_y) + projection_center_y
        proj_position_x = interpolation_position_x.astype(int)
        proj_position_y = interpolation_position_y.astype(int)
        interpolation_offset_x = (interpolation_position_x - proj_position_x)
        interpolation_offset_y = (interpolation_position_y - proj_position_y)
        m0, m1, m2 = cp.where((proj_position_x >= 1) & (proj_position_x < dims[0]) & (proj_position_y >= 1) & (proj_position_y < dims[1]))
        value_x1 = src[proj_position_x[m0, m1, m2]-1, proj_position_y[m0, m1, m2]-1] + \
                   (src[proj_position_x[m0, m1, m2], proj_position_y[m0, m1, m2]-1] - src[proj_position_x[m0, m1, m2]-1, proj_position_y[m0, m1, m2]-1]) * interpolation_offset_x[m0, m1, m2]
        value_x2 = src[proj_position_x[m0, m1, m2]-1, proj_position_y[m0, m1, m2]] + \
                   (src[proj_position_x[m0, m1, m2], proj_position_y[m0, m1, m2]] - src[proj_position_x[m0, m1, m2]-1, proj_position_y[m0, m1, m2]]) * interpolation_offset_x[m0, m1, m2]
        value_y = value_x1 + (value_x2 - value_x1) * interpolation_offset_y[m0, m1, m2]
        reconstruction[m0, m1, m2] += value_y
        del value_y
        del value_x1
        del value_x2
        del m0, m1, m2
        # import napari
        # with napari.gui_qt():
        #     viewer = napari.Viewer()
        #     viewer.add_image(reconstruction.get(), name='recon', interpolation='bilinear')
        #     viewer.add_image(np.log10(np.abs(np.fft.fftshift(np.fft.fftn(reconstruction.get())))), name='fft', interpolation='bilinear')
    rec = reconstruction.get()
    return rec

    for i in range(dims[0]):
        for j in range(dims[1]):
            for k in range(dims[2]):
                vol_bp.setV(float(rec[i][j][k]), int(i), int(j), int(k))


    return vol_bp
Esempio n. 24
0
def vol2sf(vol, r, b, center=None):
    """Transfer a volume into a serial of spherical functions. The volume will be decomposed into a serials of concentric shells.
    It will sample the volume on equiangular 2B*2B grid. (Trilinear interpolation) For more detail, see "http://www.cs.dartmouth.edu/~geelong/sphere/".
    
    Parameters
    ----------
    vol: Target volume
         pytom_volume.vol

    r: The radius of shell you want to get from the volume (in voxel)
       Integer

    b: Bandwidth, which determines the sampling on the sphere
       Integer

    center: The center of the circle (By default is the center of the volume)
            list [x, y, z]
    
    Returns
    -------
    f(the_0, phi_0) ... f(the_0, phi_2B-1), f(the_2B-1, phi_0) ... f(the_2B-1, phi_2B-1)
    List
    """
    if r >= vol.sizeX() / 2 or r >= vol.sizeY() / 2 or r >= vol.sizeZ() / 2:
        raise RuntimeError("Given radius is larger than the volume!")
    elif r <= 0:
        raise RuntimeError("Radius should be larger than the 0!")

    from pytom_volume import volTOsf
    from pytom_numpy import vol2npy
    if center:
        m_x, m_y, m_z = center
    else:
        # the middle point of the volume
        m_x = int(vol.sizeX() / 2)
        m_y = int(vol.sizeY() / 2)
        m_z = int(vol.sizeZ() / 2)
    res = volTOsf(vol, r, b, m_x, m_y, m_z)

    # transfer the data format from volume to numpy array
    tmp = vol2npy(
        res)  # somehow have to split the steps like this, otherwise wont work

    import numpy as np
    res = np.array(
        tmp)  # copy the memory, otherwise the memory is shared with volume

    #    from math import pi, sin, cos
    #    res = [] # result list
    #
    #    from pytom_volume import interpolateSpline
    #
    #    if center:
    #        m_x, m_y, m_z = center
    #    else:
    #        # the middle point of the volume
    #        m_x = int(vol.sizeX()/2); m_y = int(vol.sizeY()/2); m_z = int(vol.sizeZ()/2)
    #
    #    for j in xrange(2*b):
    #        for k in xrange(2*b):
    #            the = pi*(2*j+1)/(4*b) # (0,pi)
    #            phi = pi*k/b # [0,2*pi)
    #
    #            # trilinear interpolation
    #            x = r*cos(phi)*sin(the); # _x = int(ceil(x)); x_ = int(floor(x)); dx = x-x_
    #            y = r*sin(phi)*sin(the); # _y = int(ceil(y)); y_ = int(floor(y)); dy = y-y_
    #            z = r*cos(the); # _z = int(ceil(z)); z_ = int(floor(z)); dz = z-z_
    ##            c_000 = vol.getV(m_x+x_,m_y+y_,m_z+z_)
    ##            c_100 = vol.getV(m_x+_x,m_y+y_,m_z+z_)
    ##            c_001 = vol.getV(m_x+x_,m_y+y_,m_z+_z)
    ##            c_101 = vol.getV(m_x+_x,m_y+y_,m_z+_z)
    ##            c_010 = vol.getV(m_x+x_,m_y+_y,m_z+z_)
    ##            c_110 = vol.getV(m_x+_x,m_y+_y,m_z+z_)
    ##            c_011 = vol.getV(m_x+x_,m_y+_y,m_z+_z)
    ##            c_111 = vol.getV(m_x+_x,m_y+_y,m_z+_z)
    ##
    ##            c_00 = c_000*(1-dx)+c_100*dx
    ##            c_01 = c_001*(1-dx)+c_101*dx
    ##            c_10 = c_010*(1-dx)+c_110*dx
    ##            c_11 = c_011*(1-dx)+c_111*dx
    ##            c_0 = c_00*(1-dy)+c_10*dy
    ##            c_1 = c_01*(1-dy)+c_11*dy
    ##            c = c_0*(1-dz)+c_1*dz
    #
    #            c = interpolateSpline(vol, m_x+x, m_y+y, m_z+z)
    #            res.append(c)

    return res
Esempio n. 25
0
def generate_model(outputFolder,
                   modelID,
                   listpdbs,
                   waterdensity=1,
                   numberOfParticles=1000):
    if not os.path.exists(os.path.join(outputFolder, f'model_{modelID}')):
        os.mkdir(os.path.join(outputFolder, f'model_{modelID}'))

    # ['3cf3', '1s3x','1u6g','4b4t','1qvr','3h84','2cg9','3qm1','3gl1','3d2f','4d8q','1bxn']

    factor = 10
    skipped = 0
    models = []
    dims = []
    for n, pdbid in enumerate(listpdbs):
        if not os.path.exists('{}/{}_model.mrc'.format(outputFolder, pdbid)):
            fname = generate_map(pdbid, n + skipped)
        else:
            fname = '{}/{}_model.mrc'.format(outputFolder, pdbid)
            skipped += 1
        if 1 or not os.path.exists('{}/{}_model_binned.mrc'.format(
                outputFolder, pdbid)):
            m = read_mrc(fname)
            size = max(m.shape)
            m2 = numpy.zeros((size, size, size))
            dx, dy, dz = m.shape
            sx, ex = (size - dx) // 2, size - int(ceil((size - dx) / 2.))
            sy, ey = (size - dy) // 2, size - int(ceil((size - dy) / 2.))
            sz, ez = (size - dz) // 2, size - int(ceil((size - dz) / 2.))
            m2[sx:ex, sy:ey, sz:ez] = m
            m_r = crop(m2, factor)
            # print m_r.sum(), m2.sum(), m_r.max(), m2.max()
            # m_str = addStructuralNoise(m_r,m_r.shape[0])
            # print median(m_str[m_str > 1.]),median(m_r[m_r > 1.])
            convert_numpy_array3d_mrc(
                m_r, '{}/{}_model_binned.mrc'.format(outputFolder, pdbid))

        else:
            m_r = read_mrc('{}/{}_model_binned.mrc'.format(
                outputFolder, pdbid))

        models.append(m_r)
        dims.append(m_r.shape[0])

    X, Y, Z = 200, SIZE, SIZE
    cell = numpy.zeros((X, Y, Z))

    cell[:, :, :] = waterdensity

    mask = numpy.zeros_like(cell)

    #if addStructNoise:
    #    cell = addStructuralNoise(cell)
    volumes = []
    for i in range(len(models)):
        vol = read('{}_model_binned.mrc'.format(listpdbs[i]))
        volumes.append(vol)

    total = [
        0,
    ] * len(models)
    particleNr = 0
    outline = ''
    for i in range(numberOfParticles):
        if i % 200 == 0:
            print(i)
        a = numpy.random.randint(0, len(models))
        q = rand_quat()
        euler = euler_from_quat(q)
        euler *= 180. / pi

        mdl_vol = rotate(volumes[a],
                         float(euler[0]),
                         x=float(euler[1]),
                         z2=float(euler[2]))
        mdl = vol2npy(mdl_vol)
        # mdl = rotate(models[a],randint(0,360),reshape=False)
        xx, yy, zz = mdl.shape

        for i in range(900):
            loc_x = numpy.random.randint(xx // 2 + 1, X - xx // 2 - 1)
            loc_y = numpy.random.randint(yy // 2 + 1, Y - yy // 2 - 1)
            loc_z = numpy.random.randint(zz // 2 + 1, Z - zz // 2 - 1)

            if mask[loc_x - dims[a] // 2:loc_x + dims[a] // 2 + dims[a] % 2,
                    loc_y - dims[a] // 2:loc_y + dims[a] // 2 + dims[a] % 2,
                    loc_z - dims[a] // 2:loc_z + dims[a] // 2 +
                    dims[a] % 2].sum() == 0:
                break
        if i > 898:
            continue
        # print ('place particle {} at: {},{},{}'.format(particleNr,loc_x,loc_y,loc_z))

        mask[loc_x - dims[a] // 2:loc_x + dims[a] // 2 + dims[a] % 2,
             loc_y - dims[a] // 2:loc_y + dims[a] // 2 + dims[a] % 2,
             loc_z - dims[a] // 2:loc_z + dims[a] // 2 + dims[a] % 2] = 1

        cell[loc_x - dims[a] // 2:loc_x + dims[a] // 2 + dims[a] % 2,
             loc_y - dims[a] // 2:loc_y + dims[a] // 2 + dims[a] % 2,
             loc_z - dims[a] // 2:loc_z + dims[a] // 2 + dims[a] % 2] = mdl

        if abs(512 - loc_y) < 256 and abs(512 - loc_z) < 256:
            outline += "{} {:4d} {:4d} {:4d} {:4.0f} {:4.0f} {:4.0f}\n".format(
                listpdbs[a], loc_x, loc_y - 256, loc_z - 256, euler[0],
                euler[1], euler[2])

        particleNr += 1

        total[a] += 1

    cell = addStructuralNoise(cell)

    grandcell = zeros((750, SIZE, SIZE))
    grandcell[275:475, :, :] = cell

    convert_numpy_array3d_mrc(
        grandcell, f'{outputFolder}/model_{modelID}/grandmodel_{modelID}.mrc')

    convert_numpy_array3d_mrc(
        cell[:, SIZE // 4:-SIZE // 4, SIZE // 4:-SIZE // 4],
        f'{outputFolder}/model_{modelID}/grandmodel_{modelID}.mrc')

    outfile = open(
        f'{outputFolder}/model_{modelID}/particle_locations_model_{modelID}.txt',
        'w')
    outfile.write(outline)

    return grandcell
Esempio n. 26
0
def toProjectionStackFromAlignmentResultsFile(alignmentResultsFile,
                                              weighting=None,
                                              lowpassFilter=0.9,
                                              binning=1,
                                              circleFilter=False,
                                              num_procs=1,
                                              outdir='',
                                              prefix='sorted_aligned'):
    """read image and create aligned projection stack, based on the results described in the alignmentResultFile.

       @param alignmentResultsFile: result file generate by the alignment script.
       @type datatypeAR: gui.guiFunction.datatypeAR
       @param weighting: weighting (<0: analytical weighting, >1: exact weighting, 0/None: no weighting )
       @type weighting: float
       @param lowpassFilter: lowpass filter (in Nyquist)
       @type lowpassFilter: float
       @param binning: binning (default: 1 = no binning). binning=2: 2x2 pixels -> 1 pixel, binning=3: 3x3 pixels -> 1 pixel, etc.

       @author: GvdS
    """
    print('weighting: ', weighting)
    import numpy
    from pytom_numpy import vol2npy
    from pytom.basic.files import read_em, write_em
    from pytom.basic.functions import taper_edges
    from pytom.basic.transformations import general_transform2d
    from pytom.basic.fourier import ifft, fft
    from pytom.basic.filter import filter as filterFunction, bandpassFilter
    from pytom.basic.filter import circleFilter, rampFilter, exactFilter, fourierFilterShift, \
        fourierFilterShift_ReducedComplex
    from pytom_volume import complexRealMult, vol, paste
    import pytom_freqweight
    from pytom.basic.transformations import resize, rotate
    from pytom.gui.guiFunctions import fmtAR, headerAlignmentResults, datatype, datatypeAR, loadstar
    from pytom.reconstruction.reconstructionStructures import Projection, ProjectionList
    from pytom_numpy import vol2npy
    import mrcfile
    from pytom.tompy.io import write, read_size
    import os

    print("Create aligned images from alignResults.txt")

    alignmentResults = loadstar(alignmentResultsFile, dtype=datatypeAR)
    imageList = alignmentResults['FileName']
    tilt_angles = alignmentResults['TiltAngle']

    imdim = int(read_size(imageList[0], 'x'))

    if binning > 1:
        imdim = int(float(imdim) / float(binning) + .5)
    else:
        imdim = imdim

    sliceWidth = imdim

    # pre-determine analytical weighting function and lowpass for speedup
    if (weighting != None) and (float(weighting) < -0.001):
        weightSlice = fourierFilterShift(rampFilter(imdim, imdim))

    if circleFilter:
        circleFilterRadius = imdim // 2
        circleSlice = fourierFilterShift_ReducedComplex(
            circleFilter(imdim, imdim, circleFilterRadius))
    else:
        circleSlice = vol(imdim, imdim // 2 + 1, 1)
        circleSlice.setAll(1.0)

    # design lowpass filter
    if lowpassFilter:
        if lowpassFilter > 1.:
            lowpassFilter = 1.
            print("Warning: lowpassFilter > 1 - set to 1 (=Nyquist)")
        # weighting filter: arguments: (angle, cutoff radius, dimx, dimy,
        lpf = pytom_freqweight.weight(0.0, lowpassFilter * imdim // 2, imdim,
                                      imdim // 2 + 1, 1,
                                      lowpassFilter / 5. * imdim)
        # lpf = bandpassFilter(volume=vol(imdim, imdim,1),lowestFrequency=0,highestFrequency=int(lowpassFilter*imdim/2),
        #                     bpf=None,smooth=lowpassFilter/5.*imdim,fourierOnly=False)[1]

    projectionList = ProjectionList()
    imageList = []
    tilt_angles = []
    for n, image in enumerate(alignmentResults['FileName']):
        atx = alignmentResults['AlignmentTransX'][n]
        aty = alignmentResults['AlignmentTransY'][n]
        rot = alignmentResults['InPlaneRotation'][n]
        mag = alignmentResults['Magnification'][n]
        # print(image, alignmentResults['TiltAngle'][n])
        # if abs(alignmentResults['TiltAngle'][n]) > 20:
        #     continue
        tilt_angles.append(alignmentResults['TiltAngle'][n])
        imageList.append(image)
        projection = Projection(imageList[-1],
                                tiltAngle=tilt_angles[-1],
                                alignmentTransX=atx,
                                alignmentTransY=aty,
                                alignmentRotation=rot,
                                alignmentMagnification=mag)
        projectionList.append(projection)

    stack = vol(imdim, imdim, len(imageList))
    stack.setAll(0.0)

    phiStack = vol(1, 1, len(imageList))
    phiStack.setAll(0.0)

    thetaStack = vol(1, 1, len(imageList))
    thetaStack.setAll(0.0)

    offsetStack = vol(1, 2, len(imageList))
    offsetStack.setAll(0.0)

    for (ii, projection) in enumerate(projectionList):
        if projection._filename.split('.')[-1] == 'st':
            from pytom.basic.files import EMHeader, read
            idx = projection._index
            image = read(file=projection._filename,
                         subregion=[0, 0, idx - 1, imdim, imdim, 1],
                         sampling=[0, 0, 0],
                         binning=[0, 0, 0])
            if not (binning == 1) or (binning == None):
                image = resize(volume=image, factor=1 / float(binning))[0]
        else:
            # read projection files
            from pytom.basic.files import EMHeader, read, read_em_header
            image = read(str(projection._filename))
            # image = rotate(image,180.,0.,0.)
            image = resize(volume=image, factor=1 / float(binning))[0]

        if lowpassFilter:
            filtered = filterFunction(volume=image,
                                      filterObject=lpf,
                                      fourierOnly=False)
            image = filtered[0]

        tiltAngle = projection._tiltAngle

        # normalize to contrast - subtract mean and norm to mean
        immean = vol2npy(image).mean()
        image = (image - immean) / immean

        print(ii, immean, projection._filename)

        # smoothen borders to prevent high contrast oscillations
        image = taper_edges(image, imdim // 30)[0]

        # transform projection according to tilt alignment
        transX = projection._alignmentTransX / binning
        transY = projection._alignmentTransY / binning
        rot = float(projection._alignmentRotation)
        mag = float(projection._alignmentMagnification)

        image = general_transform2d(v=image,
                                    rot=rot,
                                    shift=[transX, transY],
                                    scale=mag,
                                    order=[2, 1, 0],
                                    crop=True)

        # smoothen once more to avoid edges
        image = taper_edges(image, imdim // 30)[0]

        # analytical weighting
        if (weighting != None) and (weighting < 0):
            # image = (ifft(complexRealMult(fft(image), w_func)) / (image.sizeX() * image.sizeY() * image.sizeZ()))
            image = ifft(complexRealMult(
                complexRealMult(fft(image), weightSlice), circleSlice),
                         scaling=True)

        elif (weighting != None) and (weighting > 0):
            weightSlice = fourierFilterShift(
                exactFilter(tilt_angles, tiltAngle, imdim, imdim, sliceWidth))
            # image = (ifft(complexRealMult(fft(image), w_func)) / (image.sizeX() * image.sizeY() * image.sizeZ()))
            image = ifft(complexRealMult(
                complexRealMult(fft(image), weightSlice), circleSlice),
                         scaling=True)

        thetaStack(int(round(projection.getTiltAngle())), 0, 0, ii)
        offsetStack(int(round(projection.getOffsetX())), 0, 0, ii)
        offsetStack(int(round(projection.getOffsetY())), 0, 1, ii)
        paste(image, stack, 0, 0, ii)
        fname = '{}_{:02d}.mrc'.format(
            prefix, int(imageList[ii].split('_')[-1].split('.')[0]))
        if outdir:
            import mrcfile
            # write_em(os.path.join(outdir, fname.replace('mrc', 'em')), image)
            write(os.path.join(outdir, fname),
                  vol2npy(image).copy().astype('float32'))
            print('written file: ', fname)

    return [stack, phiStack, thetaStack, offsetStack]
Esempio n. 27
0
        sys.exit()

    try:
        fname, ps, sliceId, f_ds, sliceDir, phases, b_help = parse_script_options(
            sys.argv[1:], helper)
    except:
        print(helper)
        sys.exit()

    if b_help:
        print(helper)
        sys.exit()

    if fname.endswith('.em'):
        vol = read(fname)
        data = copy.deepcopy(vol2npy(vol)).T
    else:
        import mrcfile
        data = copy.deepcopy(mrcfile.open(fname, permissive=True).data)

    print('max: {} min: {} mean: {} std: {}'.format(data.max(), data.min(),
                                                    data.mean(), data.std()))
    print(data.shape)
    from scipy.ndimage import gaussian_filter

    print(data.shape)

    if sliceDir is None: sliceDir = 'z'
    else: sliceDir = sliceDir.lower()

    if not sliceDir in ['x', 'y', 'z']:
Esempio n. 28
0
def writeAlignedProjections(TiltSeries_,
                            weighting=None,
                            lowpassFilter=None,
                            binning=None,
                            verbose=False,
                            write_images=True):
    """write weighted and aligned projections to disk1

       @param TiltSeries_: Tilt Series
       @type TiltSeries_: reconstruction.TiltSeries
       @param weighting: weighting (<0: analytical weighting, >1 exact weighting (value corresponds to object diameter in pixel AFTER binning)
       @type weighting: float
       @param lowpassFilter: lowpass filter (in Nyquist)
       @type lowpassFilter: float
       @param binning: binning (default: 1 = no binning). binning=2: 2x2 pixels -> 1 pixel, binning=3: 3x3 pixels -> 1 pixel, etc.

       @author: FF
    """
    import numpy
    from pytom_numpy import vol2npy
    from pytom.basic.files import read_em, write_em
    from pytom.basic.functions import taper_edges
    from pytom.basic.transformations import general_transform2d
    from pytom.basic.fourier import ifft, fft
    from pytom.basic.filter import filter as filterFunction, bandpassFilter
    from pytom.basic.filter import circleFilter, rampFilter, exactFilter, fourierFilterShift, rotateFilter
    from pytom_volume import complexRealMult, vol
    import pytom_freqweight
    from pytom.basic.transformations import resize
    from pytom.gui.guiFunctions import fmtAR, headerAlignmentResults, datatypeAR
    import os

    if binning:
        imdim = int(float(TiltSeries_._imdim) / float(binning) + .5)
    else:
        imdim = TiltSeries_._imdim
    print('imdim', imdim)

    sliceWidth = imdim

    # pre-determine analytical weighting function and lowpass for speedup
    if (weighting != None) and (weighting < -0.001):
        w_func = fourierFilterShift(rampFilter(imdim, imdim))
    print('start weighting')
    # design lowpass filter
    if lowpassFilter:
        if lowpassFilter > 1.:
            lowpassFilter = 1.
            print("Warning: lowpassFilter > 1 - set to 1 (=Nyquist)")
        # weighting filter: arguments: (angle, cutoff radius, dimx, dimy,
        lpf = pytom_freqweight.weight(0.0, lowpassFilter * imdim / 2, imdim,
                                      imdim // 2 + 1, 1,
                                      lowpassFilter / 5. * imdim)
        #lpf = bandpassFilter(volume=vol(imdim, imdim,1),lowestFrequency=0,highestFrequency=int(lowpassFilter*imdim/2),
        #                     bpf=None,smooth=lowpassFilter/5.*imdim,fourierOnly=False)[1]

    tilt_angles = []

    for projection in TiltSeries_._ProjectionList:
        tilt_angles.append(projection._tiltAngle)
    tilt_angles = sorted(tilt_angles)
    print(tilt_angles)
    #q = numpy.matrix(abs(numpy.arange(-imdim//2, imdim//2)))

    alignmentResults = numpy.zeros((len(TiltSeries_._ProjectionList)),
                                   dtype=datatypeAR)
    alignmentResults['TiltAngle'] = tilt_angles

    for (ii, projection) in enumerate(TiltSeries_._ProjectionList):

        alignmentResults['FileName'][ii] = os.path.join(
            os.getcwd(), projection._filename)
        transX = -projection._alignmentTransX / binning
        transY = -projection._alignmentTransY / binning
        rot = -(projection._alignmentRotation + 90.)
        mag = projection._alignmentMagnification

        alignmentResults['AlignmentTransX'][ii] = transX
        alignmentResults['AlignmentTransY'][ii] = transY
        alignmentResults['InPlaneRotation'][ii] = rot
        alignmentResults['Magnification'][ii] = mag

        if write_images:
            if projection._filename.split('.')[-1] == 'st':
                from pytom.basic.files import EMHeader, read
                header = EMHeader()
                header.set_dim(x=imdim, y=imdim, z=1)
                idx = projection._index
                if verbose:
                    print("reading in projection %d" % idx)
                image = read(file=projection._filename,
                             subregion=[
                                 0, 0, idx - 1, TiltSeries_._imdim,
                                 TiltSeries_._imdim, 1
                             ],
                             sampling=[0, 0, 0],
                             binning=[0, 0, 0])
                if not (binning == 1) or (binning == None):
                    image = resize(volume=image, factor=1 / float(binning))[0]
            else:
                # read projection files
                from pytom.basic.files import EMHeader, read, read_em_header
                print(projection._filename)
                image = read(projection._filename)
                image = resize(volume=image, factor=1 / float(binning))[0]

                if projection._filename[-3:] == '.em':
                    header = read_em_header(projection._filename)
                else:
                    header = EMHeader()
                    header.set_dim(x=imdim, y=imdim, z=1)

            if lowpassFilter:
                filtered = filterFunction(volume=image,
                                          filterObject=lpf,
                                          fourierOnly=False)
                image = filtered[0]
            tiltAngle = projection._tiltAngle
            header.set_tiltangle(tiltAngle)
            # normalize to contrast - subtract mean and norm to mean
            immean = vol2npy(image).mean()
            image = (image - immean) / immean
            # smoothen borders to prevent high contrast oscillations
            image = taper_edges(image, imdim // 30)[0]
            # transform projection according to tilt alignment

            if projection._filename.split('.')[-1] == 'st':
                newFilename = (TiltSeries_._alignedTiltSeriesName + "_" +
                               str(projection.getIndex()) + '.em')
            else:
                TiltSeries_._tiltSeriesFormat = 'mrc'
                newFilename = (TiltSeries_._alignedTiltSeriesName + "_" +
                               str(projection.getIndex()) + '.' +
                               TiltSeries_._tiltSeriesFormat)
            if verbose:
                tline = ("%30s" % newFilename)
                tline = tline + (" (tiltAngle=%6.2f)" % tiltAngle)
                tline = tline + (": transX=%6.1f" % transX)
                tline = tline + (", transY=%6.1f" % transY)
                tline = tline + (", rot=%6.2f" % rot)
                tline = tline + (", mag=%5.4f" % mag)
                print(tline)

            image = general_transform2d(v=image,
                                        rot=rot,
                                        shift=[transX, transY],
                                        scale=mag,
                                        order=[2, 1, 0],
                                        crop=True)

            # smoothen once more to avoid edges
            image = taper_edges(image, imdim // 30)[0]

            # analytical weighting
            if (weighting != None) and (weighting < 0):
                image = (ifft(complexRealMult(fft(image), w_func)) /
                         (image.sizeX() * image.sizeY() * image.sizeZ()))

            elif (weighting != None) and (weighting > 0):
                if abs(weighting - 2) < 0.001:
                    w_func = fourierFilterShift(
                        rotateFilter(tilt_angles, tiltAngle, imdim, imdim,
                                     sliceWidth))
                else:
                    w_func = fourierFilterShift(
                        exactFilter(tilt_angles, tiltAngle, imdim, imdim,
                                    sliceWidth))

                image = (ifft(complexRealMult(fft(image), w_func)) /
                         (image.sizeX() * image.sizeY() * image.sizeZ()))
            header.set_tiltangle(tilt_angles[ii])

            if newFilename.endswith('.mrc'):
                data = copy.deepcopy(vol2npy(image))
                mrcfile.new(newFilename,
                            data.T.astype(float32),
                            overwrite=True)
            else:
                write_em(filename=newFilename, data=image, header=header)

            if verbose:
                tline = ("%30s written ..." % newFilename)

    outname = os.path.join(os.path.dirname(TiltSeries_._alignedTiltSeriesName),
                           'alignmentResults.txt')
    numpy.savetxt(outname,
                  alignmentResults,
                  fmt=fmtAR,
                  header=headerAlignmentResults)
    print('Alignment successful. See {} for results.'.format(outname))
def sag_fine_grained_alignment(vf,
                               wf,
                               vg,
                               wg,
                               max_freq,
                               ang=[0, 0, 0],
                               loc=[0, 0, 0],
                               mask=None,
                               B,
                               alpha,
                               maxIter,
                               lambda1):
    """SAG-based fine-grained alignment between experimental data and reference data.
    Parameters
    vf: Experimental data
        pytom_volume.vol

    wf: Mask of vf in Fourier space.
        pytom.basic.structures.Wedge. If none, no missing wedge.

    vg: Reference data 
        pytom_volume.vol

    wg: Mask of vg in Fourier space.
        pytom.basic.structures.Wedge. If none, no missing wedge.

    max_freq: Maximal frequency involved in calculation.
              Integer.

    ang: Initial rotation angle

    loc: Initial translation value
    
    mask: Mask volume in real space.
          pytom_volume.vol

    B: Batch number 

    alpha: Step size

    maxIter: The max iteration number

    lambda1: Regularization parameter

    Returns
    -------
    (Optimal rotation angle and translation value.
    (best_translation, best_rotation, correlation_score)
    """
    from pytom_volume import vol, rotateSpline, peak, sum, power
    from pytom.basic.transformations import shift
    from pytom.basic.filter import lowpassFilter
    from pytom.basic.structures import Mask, SingleTiltWedge, Rotation
    from pytom_volume import initSphere
    from pytom_numpy import vol2npy

    import math
    import random

    if vf.sizeX() != vg.sizeX() or vf.sizeY() != vg.sizeY() or vf.sizeZ(
    ) != vg.sizeZ():
        raise RuntimeError('Two volumes must have the same size!')

    if wf is None:
        wf = SingleTiltWedge(0)
    else:
        vf = wf.apply(vf)
    if wg is None:
        wg = SingleTiltWedge(0)
    else:
        vg = wg.apply(vg)

    if mask is None:
        m = vol(vf.sizeX(), vf.sizeY(), vf.sizeZ())
        initSphere(m,
                   vf.sizeX() / 2, 0, 0,
                   vf.sizeX() / 2,
                   vf.sizeY() / 2,
                   vf.sizeZ() / 2)
        mask = m

    old_value = -1
    max_pos = [-1, -1, -1]
    max_ang = None
    max_value = -1.0

    ang_epsilon = np.ones(3) * (math.pi * (1.0 / 180))
    loc_epsilon = np.ones(3) * 1.0

    n = vf.sizeX()
    vf0_n = vol2npy(vf)

    if maxIter is None:
        maxIter = n / 2
    iVals = np.int32(np.ceil((n - B) * np.random.random(maxIter)))

    if lambda1 is None:
        lambda1 = 1 / n
    eps = np.finfo(np.float32).eps
    Lmax = 0.25 * np.max(np.sum(vf0_n**2)) + lambda1
    if alpha is None:
        alpha = 1 / Lmax

    d = np.zeros(6)
    g = np.zeros([n, 6])
    covered = np.int32(np.zeros(n))
    nCovered = 0
    grad = np.zeros(6)
    deri = np.zeros(6)
    vg2 = vol(vf.sizeX(), vf.sizeY(), vf.sizeZ())
    mask2 = vol(mask.sizeX(), mask.sizeY(), mask.sizeZ())

    for i in range(n):
        if (covered[i] != 0):
            nCovered += 1

    for k in range(maxIter):
        i = iVals[k] - 1
        if k == 0:
            rotateSpline(vg, vg2, ang[0], ang[1], ang[2])
            rotateSpline(mask, mask2, ang[0], ang[1], ang[2])

            vg2 = wf.apply(vg2)
            vg2 = lowpassFilter(vg2, max_freq, max_freq / 10.)[0]
            vg2_s = transform_single_vol(vg2, mask2)

            vf2 = shift(vf,
                        -loc[0] + vf.sizeX() / 2,
                        -loc[1] + vf.sizeY() / 2,
                        -loc[2] + vf.sizeZ() / 2,
                        imethod='spline')
            vf2 = lowpassFilter(vf2, max_freq, max_freq / 10.)[0]
            vf2 = wg.apply(vf2, Rotation(ang))
            vf2_s = transform_single_vol(vf2, mask2)

            i = 0
            ri = np.sum(
                vol2npy(vf2_s)[i:i + B, :, :] - vol2npy(vg2_s)[i:i + B, :, :])

        vg2_p = vol(n, n, n)
        vg2_m = vol(n, n, n)
        mask2_p = vol(n, n, n)
        mask2_m = vol(n, n, n)
        for dim_i in range(3):
            if abs(ang_epsilon[dim_i]) > eps:
                ang_epsilon_t = np.zeros(3)
                ang_epsilon_t[dim_i] = ang_epsilon[dim_i]

                angle = ang + ang_epsilon_t
                rotateSpline(vg, vg2_p, angle[0], angle[1], angle[2])
                rotateSpline(mask, mask2_p, angle[0], angle[1], angle[2])
                vg2_p = wf.apply(vg2_p)
                vg2_p = lowpassFilter(vg2_p, max_freq, max_freq / 10.)[0]
                vg2_pf = transform_single_vol(vg2_p, mask2_p)

                angle = ang - ang_epsilon_t
                rotateSpline(vg, vg2_m, angle[0], angle[1], angle[2])
                rotateSpline(mask, mask2_m, angle[0], angle[1], angle[2])
                vg2_m = wf.apply(vg2_m)
                vg2_m = lowpassFilter(vg2_m, max_freq, max_freq / 10.)[0]
                vg2_mf = transform_single_vol(vg2_m, mask2_m)

                vg2_ang_deri = (vg2_pf - vg2_mf) / (2 * ang_epsilon[dim_i])
                vg2_ang_deri_n = vol2npy(vg2_ang_deri)
                deri[dim_i] = np.sum(vg2_ang_deri_n[i:i + B, :, :])

                del vg2_pf, vg2_mf, vg2_ang_deri, vg2_ang_deri_n, angle
        del vg2_p, vg2_m, mask2_p, mask2_m

        vf1_ps = vol(n, n, n)
        vf1_ms = vol(n, n, n)
        ang_f = [ang[0], ang[1], ang[2]]
        for dim_i in range(3):
            if abs(loc_epsilon[dim_i]) > eps:
                loc_epsilon_t = np.zeros(3)
                loc_epsilon_t[dim_i] = ang_epsilon[dim_i]

                vf1_ps.copyVolume(vf)
                vf1_ms.copyVolume(vf)

                loc_r = loc + loc_epsilon_t
                vf1_tp = shift(vf1_ps, -loc_r[0] + vf1_ps.sizeX() / 2,
                               -loc_r[1] + vf1_ps.sizeY() / 2,
                               -loc_r[2] + vf1_ps.sizeZ() / 2, 'spline')
                vf1_tp = lowpassFilter(vf1_tp, max_freq, max_freq / 10.)[0]
                vf1_tp = wg.apply(vf1_tp, Rotation(ang_f))

                loc_r = loc - loc_epsilon_t
                vf1_tm = shift(vf1_ms, -loc_r[0] + vf1_ms.sizeX() / 2,
                               -loc_r[1] + vf1_ms.sizeY() / 2,
                               -loc_r[2] + vf1_ms.sizeZ() / 2, 'spline')
                vf1_tm = lowpassFilter(vf1_tm, max_freq, max_freq / 10.)[0]
                vf1_tm = wg.apply(vf1_tm, Rotation(ang_f))

                vf1_tpf = transform_single_vol(vf1_tp, mask2)
                vf1_tmf = transform_single_vol(vf1_tm, mask2)
                vf1_loc_deri = (vf1_tpf - vf1_tmf) / (2 * ang_epsilon[dim_i])
                vf1_loc_deri_n = vol2npy(vf1_loc_deri)
                deri[dim_i + 3] = np.sum(vf1_loc_deri_n[i:i + B, :, :])

                del vf1_tp, vf1_tm, vf1_tpf, vf1_tmf, vf1_loc_deri, vf1_loc_deri_n
        del vf1_ps, vf1_ms, ang_f

        for dim_i in range(6):
            grad[dim_i] = ri * deri[dim_i] / B

        for dim_i in range(6):
            d[dim_i] += grad[dim_i] - np.sum(g[i:i + B, dim_i])

        for dim_i in range(6):
            g[i:i + B, dim_i] = grad[dim_i]

        for j0 in range(i, i + B + 1):
            if (covered[j0] == 0):
                covered[j0] = 1
                nCovered += 1

        for dim_i in range(6):
            opt_beta[dim_i] -= alpha * d[dim_i] / nCovered
        ang = opt_beta[:3]
        loc = opt_beta[3:]

        rotateSpline(vg, vg2, ang[0], ang[1], ang[2])
        rotateSpline(mask, mask2, ang[0], ang[1], ang[2])

        vg2 = wf.apply(vg2)
        vg2 = lowpassFilter(vg2, max_freq, max_freq / 10.)[0]
        vg2_s = transform_single_vol(vg2, mask2)

        vf2 = shift(vf,
                    -loc[0] + vf.sizeX() / 2,
                    -loc[1] + vf.sizeY() / 2,
                    -loc[2] + vf.sizeZ() / 2,
                    imethod='spline')
        vf2 = lowpassFilter(vf2, max_freq, max_freq / 10.)[0]
        vf2 = wg.apply(vf2, Rotation(ang))
        vf2_s = transform_single_vol(vf2, mask2)
        ri = np.sum(
            vol2npy(vf2_s)[i:i + B, :, :] - vol2npy(vg2_s)[i:i + B, :, :])
        from pytom.basic.correlation import nxcc
        val = nxcc(vf2_s, vg2_s, mask)

        if val > max_value:
            max_pos = loc
            max_ang = ang
            max_value = val
        if abs(max_value - old_value) <= eps:
            break
        else:
            old_value = max_value
        del vg2_s, vf2, vf2_s

    del d, g, grad, deri

    return max_pos, max_ang, max_value
Esempio n. 30
0
    boxhalf_x = boxhalf_y = boxhalf_z = window_size/2 
    nvox = pid = 0
    pid_matrix = []
    for zz in xrange(0,nz):
        for yy in xrange(0,ny):
            for xx in xrange(0,nx):
                if (pmask(xx,yy,zz)):
                    nvox+=1
                    pid += 1
                    key_value = (pid,(xx,yy,zz))
                    pid_matrix.append(key_value) 
    
    del nvox

     
    vol1_n = vol2npy(hm1) #must transform into 3D matrix
    vol2_n = vol2npy(hm20)
    vol1_np = np.zeros((nx,ny,nz),dtype=np.float32,order='F') 
    vol2_np = np.zeros((nx,ny,nz),dtype=np.float32,order='F') 
    vol1_np = vol1_n    
    vol2_np = vol2_n   
    

    BC_vol1 = sc.broadcast(vol1_np) 
    BC_vol2 = sc.broadcast(vol2_np) 

    BC_max_resolution = sc.broadcast(max_resolution)
    BC_pixelSize = sc.broadcast(pixelSize) 
    BC_numberBands = sc.broadcast(numberBands) 
    BC_fsc_criterion = sc.broadcast(fsc_criterion) 
    BC_sizeX = sc.broadcast(sizeX)