コード例 #1
0
def transform_scalars(dataset, threshold=None):
    """Remove bad pixels in tilt series."""

    from tomviz import utils
    import scipy.ndimage
    import numpy as np

    tiltSeries = utils.get_array(dataset).astype(np.float32)

    for i in range(tiltSeries.shape[2]):
        I = tiltSeries[:, :, i]
        I_pad = np.lib.pad(I, (1, 1), 'edge')

        # calculate standard deviation in a 3 x 3 window
        averageI2 = scipy.ndimage.filters.uniform_filter(I_pad ** 2)
        averageI = scipy.ndimage.filters.uniform_filter(I_pad)
        std = np.sqrt(abs(averageI2 - averageI**2))[1:-1, 1:-1]

        medianI = scipy.ndimage.filters.median_filter(I_pad, 2)[1:-1, 1:-1]

        #identiy bad pixels
        badPixelsMask = abs(I - medianI) > std * threshold

        I[badPixelsMask] = medianI[badPixelsMask]
        tiltSeries[:, :, i] = I

    # Set the result as the new scalars.
    utils.set_array(dataset, tiltSeries)
コード例 #2
0
    def transform_scalars(self, dataset, N=25):
        """Add Poisson noise to tilt images"""
        self.progress.maximum = 1

        tiltSeries = utils.get_array(dataset).astype(float)
        if tiltSeries is None:
            raise RuntimeError("No scalars found!")

        Ndata = tiltSeries.shape[0] * tiltSeries.shape[1]

        self.progress.maximum = tiltSeries.shape[2]
        step = 0
        for i in range(tiltSeries.shape[2]):
            if self.canceled:
                return

            tiltImage = tiltSeries[:, :, i].copy()
            tiltImage = tiltImage / np.sum(tiltSeries[:, :, i]) * (Ndata * N)
            tiltImage = np.random.poisson(tiltImage)
            tiltImage = tiltImage * np.sum(tiltSeries[:, :, i]) / (Ndata * N)

            tiltSeries[:, :, i] = tiltImage.copy()
            step += 1
            self.progress.value = step

        utils.set_array(dataset, tiltSeries)
コード例 #3
0
ファイル: ClipEdges.py プロジェクト: OpenChemistry/tomviz
def transform_scalars(dataset, clipNum=5):
    """Set values outside a cirular range to minimum(dataset) to
    remove reconstruction artifacts"""

    from tomviz import utils
    import numpy as np

    array = utils.get_array(dataset)

    # Constant values
    numX = array.shape[1]
    numY = array.shape[2]
    minVal = array.min()

    # Find the values to be clipped
    maxR = min([numX, numY]) / 2 - clipNum
    XX, YY = np.mgrid[0:numX, 0:numY]
    RR = np.sqrt((XX - numX / 2) ** 2 + (YY - numY / 2) ** 2)
    clipThese = np.where(RR >= maxR)

    # Apply the mask along the original tilt axis direction
    # (always the first direction in the array)
    for ii in range(0, array.shape[0]):
        curImage = array[ii, :, :] # points to the relevant 2D part of the array
        curImage[clipThese] = minVal

    # Return to tomviz
    utils.set_array(dataset, array)
コード例 #4
0
def transform_scalars(dataset):
    """Downsample volume by a factor of 2"""

    from tomviz import utils
    import scipy.ndimage
    import numpy as np

    array = utils.get_array(dataset)

    # Downsample the dataset x2 using order 1 spline (linear)
    # Calculate out array shape
    zoom = (0.5, 0.5, 0.5)
    result_shape = utils.zoom_shape(array, zoom)
    result = np.empty(result_shape, array.dtype, order='F')
    scipy.ndimage.interpolation.zoom(array, zoom,
                                     output=result, order=1,
                                     mode='constant', cval=0.0,
                                     prefilter=False)

    # Set the result as the new scalars.
    utils.set_array(dataset, result)

    # Update tilt angles if dataset is a tilt series.
    try:
        tilt_angles = utils.get_tilt_angles(dataset)
        result_shape = utils.zoom_shape(tilt_angles, 0.5)
        result = np.empty(result_shape, array.dtype, order='F')
        tilt_angles = scipy.ndimage.interpolation.zoom(tilt_angles, 0.5,
                                                       output=result)
        utils.set_tilt_angles(dataset, result)
    except: # noqa
        # TODO What exception are we ignoring?
        pass
コード例 #5
0
ファイル: deleteSlices.py プロジェクト: OpenChemistry/tomviz
def transform_scalars(dataset, firstSlice=None, lastSlice=None, axis=2):
    """Delete Slices in Dataset"""

    from tomviz import utils
    import numpy as np

    # Get the current dataset.
    array = utils.get_array(dataset)

    # Get indices of the slices to be deleted.
    indices = np.linspace(firstSlice, lastSlice,
                          lastSlice - firstSlice + 1).astype(int)

    # Delete the specified slices.
    array = np.delete(array, indices, axis)

    # Set the result as the new scalars.
    utils.set_array(dataset, array)

    # Delete corresponding tilt anlges if dataset is a tilt series.
    if axis == 2:
        try:
            tilt_angles = utils.get_tilt_angles(dataset)
            tilt_angles = np.delete(tilt_angles, indices)
            utils.set_tilt_angles(dataset, tilt_angles)
        except: # noqa
            # TODO what exception are we ignoring here?
            pass
コード例 #6
0
ファイル: Pad_Data.py プロジェクト: happy-fish/tomviz
def transform_scalars(dataset):
    """Pad dataset"""
    from tomviz import utils
    import numpy as np
    
    #----USER SPECIFIED VARIABLES-----#
    ###padWidthX###
    ###padWidthY###
    ###padWidthZ###
    ###padMode_index###
    #---------------------------------#
    padModes = ['constant','edge','wrap','minimum','median']
    padMode = padModes[padMode_index]
    array = utils.get_array(dataset) #get data as numpy array
    
    if array is None: #Check if data exists
        raise RuntimeError("No data array found!")
    
    pad_width = (padWidthX,padWidthY,padWidthZ)

    # pad the data.
    array = np.lib.pad(array, pad_width, padMode)

    # Set the data so that it is visible in the application.
    utils.set_array(dataset, array)

    # If dataset is marked as tilt series, update tilt angles
    if padWidthZ[0]+padWidthZ[1] >0:
        try:
            tilt_angles = utils.get_tilt_angles(dataset)
            tilt_angles = np.lib.pad(tilt_angles,padWidthZ, padMode)
            utils.set_tilt_angles(dataset, tilt_angles)
        except:
            pass
コード例 #7
0
ファイル: utils.py プロジェクト: OpenChemistry/tomviz
def label_object_principal_axes(dataset, label_value):
    import numpy as np
    from tomviz import utils
    labels = utils.get_array(dataset)
    num_voxels = np.sum(labels == label_value)
    xx, yy, zz = utils.get_coordinate_arrays(dataset)

    data = np.zeros((num_voxels, 3))
    selection = labels == label_value
    assert np.any(selection), \
        "No voxels with label %d in label map" % label_value
    data[:, 0] = xx[selection]
    data[:, 1] = yy[selection]
    data[:, 2] = zz[selection]

    # Compute PCA on coordinates
    from scipy import linalg as la
    m, n = data.shape
    center = data.mean(axis=0)
    data -= center
    R = np.cov(data, rowvar=False)
    evals, evecs = la.eigh(R)
    idx = np.argsort(evals)[::-1]
    evecs = evecs[:, idx]
    evals = evals[idx]
    return (evecs, center)
コード例 #8
0
ファイル: Rotate3D.py プロジェクト: Hovden/tomviz
def transform_scalars(dataset):

    #----USER SPECIFIED VARIABLES-----#
    ###ROT_AXIS###    #Specify Tilt Axis Dimensions x=0, y=1, z=2
    ###ROT_ANGLE###   #Rotate the dataset by an Angle (in degrees)
    #---------------------------------#
        
    from tomviz import utils
    import numpy as np
    from scipy import ndimage
    
    data_py = utils.get_array(dataset) #get data as numpy array
    
    if data_py is None: #Check if data exists
        raise RuntimeError("No data array found!")
    
    if ROT_AXIS == []: #If tilt axis is not given, assign one.
    #Find smallest array dimension, assume it is the tilt angle axis
        if data_py.ndim >= 2:
            ROT_AXIS = np.argmin( data_py.shape )
        else:
            raise RuntimeError("Data Array is not 2 or 3 dimensions!")

    if ROT_ANGLE == []: #If tilt axis is not given, assign it to 90 degrees.
        ROT_ANGLE = 90;
            
    print('Rotating Images...')
    
    data_py_return = ndimage.interpolation.rotate( data_py, ROT_ANGLE, axes=((ROT_AXIS+1)%3, (ROT_AXIS+2)%3) )
    
    utils.set_array(dataset, data_py_return)
    print('Rotate Complete')
コード例 #9
0
ファイル: Resample.py プロジェクト: OpenChemistry/tomviz
def transform_scalars(dataset, resampling_factor=[1, 1, 1]):
    """Resample dataset"""

    from tomviz import utils
    import scipy.ndimage
    import numpy as np

    array = utils.get_array(dataset)

    # Transform the dataset.
    result_shape = utils.zoom_shape(array, resampling_factor)
    result = np.empty(result_shape, array.dtype, order='F')
    scipy.ndimage.interpolation.zoom(array, resampling_factor, output=result)

    # Set the result as the new scalars.
    utils.set_array(dataset, result)

    # Update tilt angles if dataset is a tilt series.
    if resampling_factor[2] != 1:
        try:
            tilt_angles = utils.get_tilt_angles(dataset)

            result_shape = utils.zoom_shape(tilt_angles, resampling_factor[2])
            result = np.empty(result_shape, array.dtype, order='F')
            scipy.ndimage.interpolation.zoom(
                tilt_angles, resampling_factor[2], output=result)
            utils.set_tilt_angles(dataset, result)
        except: # noqa
            # TODO What exception are we ignoring?
            pass
コード例 #10
0
def transform_scalars(dataset):
    """3D Reconstruct from a tilt series using constraint-based Direct Fourier Method"""

    from tomviz import utils
    import numpy as np
    ###Niter###
    ###Niter_update_support###
    ###supportSigma###
    ###supportThreshold### #percent
    supportThreshold = supportThreshold/100.0
    
    nonnegativeVoxels = True
    tilt_angles = utils.get_tilt_angles(dataset) #Get Tilt angles

    tilt_images = utils.get_array(dataset)
    if tilt_images is None:
        raise RuntimeError("No scalars found!")

    #Direct Fourier recon without constraints
    (recon,recon_F) = dfm3(tilt_images,tilt_angles,np.size(tilt_images,0)*2)

    kr_cutoffs = np.linspace(0.05,0.5,10);
    I_data = radial_average(tilt_images,kr_cutoffs) #average Fourier magnitude of tilt series as a function of kr

    #Search for solutions that satisfy additional constraints
    recon = difference_map_update(recon_F,nonnegativeVoxels,I_data,kr_cutoffs,Niter,Niter_update_support,supportSigma,supportThreshold)

    print('Reconsruction Complete')

    # Set the result as the new scalars.
    utils.set_array(dataset, recon)

    # Mark dataset as volume
    utils.mark_as_volume(dataset)
コード例 #11
0
def transform_scalars(dataset):
    '''For each tilt image, the method uses average pixel value of selected region
      as the background level and subtracts it from the image.'''
    '''It does NOT set negative pixels to zero.'''

    from tomviz import utils
    import numpy as np

    #----USER SPECIFIED VARIABLES-----#
    ###XRANGE###
    ###YRANGE###
    ###ZRANGE###
    #---------------------------------#

    data_bs = utils.get_array(dataset) # Get data as numpy array.

    data_bs = data_bs.astype(np.float32) # Change tilt series type to float.

    if data_bs is None: #Check if data exists
        raise RuntimeError("No data array found!")    

    for i in range(ZRANGE[0],ZRANGE[1]):
        a = data_bs[:,:,i] - np.average(data_bs[XRANGE[0]:XRANGE[1],YRANGE[0]:YRANGE[1],i])
        data_bs[:,:,i] = a

    utils.set_array(dataset, data_bs)
コード例 #12
0
ファイル: Recon_WBP.py プロジェクト: LijieTu/tomviz
def transform_scalars(dataset):
    """3D Reconstruct from a tilt series using Weighted Back-projection Method"""
    
    from tomviz import utils
    import numpy as np
    interpolation_methods = ('linear','nearest','spline','cubic')
    filter_methods = ('none','ramp','shepp-logan','cosine','hamming','hann')

    ###Nrecon###
    ###filter###
    ###interp###
    
    #Get Tilt angles
    tilt_angles = utils.get_tilt_angles(dataset)
    
    data_py = utils.get_array(dataset)
    if data_py is None:
        raise RuntimeError("No scalars found!")

    recon = wbp3(data_py,tilt_angles,Nrecon,filter_methods[filter],interpolation_methods[interp])
    print('Reconsruction Complete')

    # set the result as the new scalars.
    utils.set_array(dataset, recon)
    
    # Mark dataset as volume
    utils.mark_as_volume(dataset)
コード例 #13
0
ファイル: deleteSlices.py プロジェクト: coldatom/tomviz
def transform_scalars(dataset):
    """Delete Slices in Dataset"""
    
    from tomviz import utils
    import numpy as np
    axis = 0;
    #----USER SPECIFIED VARIABLES-----#
    ###firstSlice###
    ###lastSlice###
    ###axis### #Axis along which to delete the subarray
    #---------------------------------#
    
    #get current dataset
    array = utils.get_array(dataset)
    
    #Get indices of the slices to be deleted
    indices = np.linspace(firstSlice,lastSlice,lastSlice-firstSlice+1).astype(int)

    # delete slices
    array = np.delete(array,indices,axis)

    #set the result as the new scalars.
    utils.set_array(dataset, array)

    #Delete corresponding tilt anlges if dataset is a tilt series
    if axis == 2:
        try:
            tilt_angles = utils.get_tilt_angles(dataset)
            tilt_angles = np.delete(tilt_angles,indices)
            utils.set_tilt_angles(dataset, tilt_angles)
        except:
            pass
コード例 #14
0
ファイル: Recon_ART.py プロジェクト: happy-fish/tomviz
def transform_scalars(dataset):
    """3D Reconstruct from a tilt series using Algebraic Reconstruction Technique (ART)"""
    ###Niter###

    # Get Tilt angles
    tiltAngles = utils.get_tilt_angles(dataset)

    # Get Tilt Series
    tiltSeries = utils.get_array(dataset)
    (Nslice,Nray,Nproj) = tiltSeries.shape

    if tiltSeries is None:
        raise RuntimeError("No scalars found!")

    # Generate measurement matrix
    A = parallelRay(Nray,1.0,tiltAngles,Nray,1.0) #A is a sparse matrix
    recon = np.zeros((Nslice,Nray,Nray))

    art3(A.todense(),tiltSeries,recon,Niter)

    # Set the result as the new scalars.
    utils.set_array(dataset, recon)

    # Mark dataset as volume
    utils.mark_as_volume(dataset)
コード例 #15
0
ファイル: RotationAlign.py プロジェクト: OpenChemistry/tomviz
def transform_scalars(dataset, SHIFT=None, rotation_angle=90.0):
    from tomviz import utils
    from scipy import ndimage
    import numpy as np

    data_py = utils.get_array(dataset) # Get data as numpy array.

    if data_py is None: #Check if data exists
        raise RuntimeError("No data array found!")
    if SHIFT is None:
        SHIFT = np.zeros(len(data_py.shape), dtype=np.int)
    data_py_return = np.empty_like(data_py)
    ndimage.interpolation.shift(data_py, SHIFT, order=0, output=data_py_return)

    rotation_axis = 2 # This operator always assumes the rotation axis is Z
    if rotation_angle == []: # If tilt angle not given, assign it to 90 degrees.
        rotation_angle = 90

    axis1 = (rotation_axis + 1) % 3
    axis2 = (rotation_axis + 2) % 3
    axes = (axis1, axis2)
    shape = utils.rotate_shape(data_py_return, rotation_angle, axes=axes)
    data_py_return2 = np.empty(shape, data_py_return.dtype, order='F')
    ndimage.interpolation.rotate(
        data_py_return, rotation_angle, output=data_py_return2, axes=axes)

    utils.set_array(dataset, data_py_return2)
コード例 #16
0
ファイル: Resample.py プロジェクト: happy-fish/tomviz
def transform_scalars(dataset):
    """Resample dataset"""

    from tomviz import utils
    import numpy as np
    import scipy.ndimage

    #----USER SPECIFIED VARIABLES-----#
    #resampingFactor  = [1,1,1]  #Specify the shifts (x,y,z) applied to data
    ###resampingFactor###
    #---------------------------------#
    array = utils.get_array(dataset)

    # Transform the dataset.
    result = scipy.ndimage.interpolation.zoom(array, resampingFactor)
    
    # Set the result as the new scalars.
    utils.set_array(dataset, result)

    # Update tilt angles if dataset is a tilt series.
    if resampingFactor[2] != 1:
        try:
            tilt_angles = utils.get_tilt_angles(dataset)
            tilt_angles = scipy.ndimage.interpolation.zoom(tilt_angles, resampingFactor[2])
            utils.set_tilt_angles(dataset, tilt_angles)
        except:
            pass
コード例 #17
0
ファイル: TiltSeries.py プロジェクト: coldatom/tomviz
def transform_scalars(dataset):
    """Generate Tilt Series from Volume"""
    
    from tomviz import utils
    import numpy as np
    import scipy.ndimage
    
    
    #----USER SPECIFIED VARIABLES-----#
    ###startAngle###    #Starting angle
    ###angleIncrement###   #Angle increment
    ###Nproj### #Number of tilts
    #---------------------------------#
    
    # Generate Tilt Angles
    angles = np.linspace(startAngle,startAngle+(Nproj-1)*angleIncrement,Nproj);
    
    array = utils.get_array(dataset)
    N = array.shape[0];
    Nslice = array.shape[2]; #Number of slices along rotation axis
    tiltSeries = np.zeros((Nslice, N ,Nproj))
    for i in range(Nproj):
        #Rotate volume
        rotatedArray = scipy.ndimage.interpolation.rotate(array, angles[i],axes=(0,1),reshape=False)
        #Calculate Projection
        tiltSeries[:,:,i] = np.sum(rotatedArray,axis=0).transpose()

    # set the result as the new scalars.
    utils.set_array(dataset, tiltSeries)

    # Mark dataset as tilt series
    utils.mark_as_tiltseries(dataset)

    # Save tilt angles
    utils.set_tilt_angles(dataset, angles)
コード例 #18
0
ファイル: Recon_DFT.py プロジェクト: ElliotPadgett/tomviz
def transform_scalars(dataset):
    from tomviz import utils
    import numpy as np

    #----USER SPECIFIED VARIABLES-----#
    TILT_AXIS  = []  #Specify the tilt axis, if none is specified
                     #it assume it is the smallest dimension
    ANGLES = []  #Specify the angles used in the tiltseries 
                 #For example, ANGLES = np.linspace(0,140,70)
    #---------------------------------#

    data_py = utils.get_array(dataset)
    if data_py is None:
        raise RuntimeError("No scalars found!")
        
    if TILT_AXIS == []: #If tilt axis is not given, find it
    #Find smallest array dimension, assume it is the tilt angle axis
        if data_py.ndim == 3:
            TILT_AXIS = np.argmin( data_py.shape )
        elif data_py.ndim == 2:
            raise RuntimeError("Data Array is 2 dimensions, it should be 3!")
        else: 
            raise RuntimeError("Data Array is not 2 or 3 dimensions!")
    
    if ANGLES == []: #If angles are not given, assume 2 degree tilts
        angles = np.linspace(0,146,74)
        
    dimx = np.size(data_py,0) #IN THE FUTURE THIS SHOULD NOT BE ASSUMED
    result3D = dfm3(data_py,angles,dimx)
    
    # set the result as the new scalars.
    utils.set_array(dataset, result3D)
    print('Reconsruction Complete')
コード例 #19
0
ファイル: Align_Images.py プロジェクト: ElliotPadgett/tomviz
def transform_scalars(dataset):

    #----USER SPECIFIED VARIABLES-----#
    TILT_AXIS  = []  #Specify Tilt Axis Dimensions x=0, y=1, z=2
    #---------------------------------#
        
    from tomviz import utils
    import numpy as np
    
    data_py = utils.get_array(dataset) #get data as numpy array
    
    if data_py is None: #Check if data exists
        raise RuntimeError("No data array found!")    
    
    if TILT_AXIS == []: #If tilt axis is not given, find it
    #Find smallest array dimension, assume it is the tilt angle axis
        if data_py.ndim == 3:
            TILT_AXIS = np.argmin( data_py.shape )
        elif data_py.ndim == 2:
            raise RuntimeError("Data Array is 2 dimensions, it should be 3!")
        else: 
            raise RuntimeError("Data Array is not 2 or 3 dimensions!")
    
    print('Aligning Images by Cross Correlation')
    for i in range(1,np.size(data_py,TILT_AXIS)):#Align image to previous
        if TILT_AXIS == 2:
            im0 = np.fft.fft2(data_py[:,:,i-1])
            im1 = np.fft.fft2(data_py[:,:,i])
            xcor = abs(np.fft.ifft2((im0 * im1.conjugate())))
            shift = np.unravel_index(xcor.argmax(), xcor.shape)
            print( shift )
            data_py[:,:,i] = np.roll( data_py[:,:,i], shift[0], axis = 0)
            data_py[:,:,i] = np.roll( data_py[:,:,i], shift[1], axis = 1)
        elif TILT_AXIS == 1:
            im0 = np.fft.fft2(data_py[:,i-1,:])
            im1 = np.fft.fft2(data_py[:,i,:])
            xcor = abs(np.fft.ifft2((im0 * im1.conjugate())))
            print( np.amax(xcor) )
            shift = np.unravel_index(xcor.argmax(), xcor.shape)
            print( shift )
            data_py[:,i,:] = np.roll( data_py[:,i,:], shift[0], axis = 0)
            data_py[:,i,:] = np.roll( data_py[:,i,:], shift[2], axis = 2)
        elif TILT_AXIS == 0:
            im0 = np.fft.fft2(data_py[i-1,:,:])
            im1 = np.fft.fft2(data_py[i,:,:])
            xcor = abs(np.fft.ifft2((im0 * im1.conjugate())))
            print( np.amax(xcor) )
            shift = np.unravel_index(xcor.argmax(), xcor.shape)
            print( shift )
            data_py[i,:,:] = np.roll( data_py[i,:,:], shift[1], axis = 1)
            data_py[i,:,:] = np.roll( data_py[i,:,:], shift[2], axis = 2)
        else:
            raise RuntimeError("Python Transform Error: Unknown TILT_AXIS.")
    
    utils.set_array(dataset, data_py)
    print('Align Images Complete')
コード例 #20
0
ファイル: Recon_WBP.py プロジェクト: cjh1/tomviz
    def transform_scalars(self, dataset, Nrecon=None, filter=None, interp=None):
        """
        3D Reconstruct from a tilt series using Weighted Back-projection Method
        """
        self.progress.maximum = 1

        from tomviz import utils
        interpolation_methods = ('linear', 'nearest', 'spline', 'cubic')
        filter_methods = ('none', 'ramp', 'shepp-logan',
                          'cosine', 'hamming', 'hann')

        # Get Tilt angles
        tilt_angles = utils.get_tilt_angles(dataset)

        tiltSeries = utils.get_array(dataset)
        if tiltSeries is None:
            raise RuntimeError("No scalars found!")

        Nslice = tiltSeries.shape[0]

        self.progress.maximum = Nslice
        step = 0

        recon = np.empty([Nslice, Nrecon, Nrecon], dtype=float, order='F')
        t0 = time.time()
        counter = 1
        etcMessage = 'Estimated time to complete: n/a'

        for i in range(Nslice):
            if self.canceled:
                return
            self.progress.message = 'Slice No.%d/%d. ' % (
                i + 1, Nslice) + etcMessage

            recon[i, :, :] = wbp2(tiltSeries[i, :, :], tilt_angles, Nrecon,
                                  filter_methods[filter],
                                  interpolation_methods[interp])
            step += 1
            self.progress.value = step
            timeLeft = (time.time() - t0) / counter * (Nslice - counter)
            counter += 1
            timeLeftMin, timeLeftSec = divmod(timeLeft, 60)
            timeLeftHour, timeLeftMin = divmod(timeLeftMin, 60)
            etcMessage = 'Estimated time to complete: %02d:%02d:%02d' % (
                timeLeftHour, timeLeftMin, timeLeftSec)

        # Set up the output dataset
        from vtk import vtkImageData
        recon_dataset = vtkImageData()
        recon_dataset.CopyStructure(dataset)
        utils.set_array(recon_dataset, recon)
        utils.mark_as_volume(recon_dataset)

        returnValues = {}
        returnValues["reconstruction"] = recon_dataset
        return returnValues
コード例 #21
0
    def transform_scalars(self, dataset):
        """Automatically align tilt images by cross-correlation"""
        self.progress.maximum = 1

        tiltSeries = utils.get_array(dataset).astype(float)
        tiltAngles = utils.get_tilt_angles(dataset)

        # determine reference image index
        zeroDegreeTiltImage = np.where(tiltAngles == 0)[0]
        if zeroDegreeTiltImage:
            referenceIndex = zeroDegreeTiltImage[0]
        else:
            referenceIndex = tiltSeries.shape[2] // 2

        # create Fourier space filter
        filterCutoff = 4
        (Ny, Nx, Nproj) = tiltSeries.shape
        ky = np.fft.fftfreq(Ny)
        kx = np.fft.fftfreq(Nx)
        [kX, kY] = np.meshgrid(kx, ky)
        kR = np.sqrt(kX**2 + kY**2)
        kFilter = (kR <= (0.5 / filterCutoff)) * \
            np.sin(2 * filterCutoff * np.pi * kR)**2

        # create real sapce filter to remove edge discontinuities
        y = np.linspace(1, Ny, Ny)
        x = np.linspace(1, Nx, Nx)
        [X, Y] = np.meshgrid(x, y)
        rFilter = (np.sin(np.pi * X / Nx) * np.sin(np.pi * Y / Ny)) ** 2

        self.progress.maximum = tiltSeries.shape[2] - 1
        step = 0

        for i in range(referenceIndex, Nproj - 1):
            if self.canceled:
                return
            self.progress.message = 'Processing tilt image No.%d/%d' % (
                i + 1, Nproj)

            tiltSeries[:, :, i + 1] = crossCorrelationAlign(
                tiltSeries[:, :, i + 1], tiltSeries[:, :, i], rFilter, kFilter)
            step += 1
            self.progress.value = step

        for i in range(referenceIndex, 0, -1):
            if self.canceled:
                return
            self.progress.message = 'Processing tilt image No.%d/%d' % (
                i, Nproj)
            tiltSeries[:, :, i - 1] = crossCorrelationAlign(
                tiltSeries[:, :, i - 1], tiltSeries[:, :, i], rFilter, kFilter)
            step += 1
            self.progress.value = step

        utils.set_array(dataset, tiltSeries)
コード例 #22
0
def transform_scalars(dataset):
    """Set negative voxels to zero"""

    from tomviz import utils

    data = utils.get_array(dataset)

    data[data < 0] = 0 # Set negative voxels to zero

    # Set the result as the new scalars.
    utils.set_array(dataset, data)
コード例 #23
0
    def transform_scalars(self, dataset):
        """Automatic align the tilt axis to the center of images"""
        self.progress.maximum = 1

        from tomviz import utils
        # Get Tilt angles
        tilt_angles = utils.get_tilt_angles(dataset)

        tiltSeries = utils.get_array(dataset)
        if tiltSeries is None:
            raise RuntimeError("No scalars found!")

        Nx, Ny, Nz = tiltSeries.shape

        shifts = (np.linspace(-20, 20, 41)).astype('int')
        numberOfSlices = 5  # number of slices used for recon

        # randomly choose slices with top 50% total intensities
        tiltSeriesSum = np.sum(tiltSeries, axis=(1, 2))
        temp = tiltSeriesSum.argsort()[Nx // 2:]
        slices = temp[np.random.permutation(temp.size)[:numberOfSlices]]
        print('Reconstruction slices:')
        print(slices)

        I = np.zeros(shifts.size)

        self.progress.maximum = shifts.size - 1
        step = 0

        for i in range(shifts.size):
            if self.canceled:
                return
            shiftedTiltSeries = np.roll(
                tiltSeries[slices, :, :, ], shifts[i], axis=1)
            for s in range(numberOfSlices):
                self.progress.message = ('Reconstructing slice No.%d with %d '
                                         'pixels shift' %
                                         (slices[s], shifts[i]))

                recon = wbp2(shiftedTiltSeries[s, :, :],
                             tilt_angles, Ny, 'ramp', 'linear')
                I[i] = I[i] + np.amax(recon)

            step += 1
            self.progress.value = step

        print('shift: %d' % shifts[np.argmax(I)])

        result = np.roll(tiltSeries, shifts[np.argmax(I)], axis=1)
        result = np.asfortranarray(result)

        # Set the result as the new scalars.
        utils.set_array(dataset, result)
コード例 #24
0
def transform_scalars(dataset):        
    from tomviz import utils
    import numpy as np
    
    #----USER SPECIFIED VARIABLES-----#
    TILT_AXIS  = []     #Specify Tilt Axis Dimensions x=0, y=1, z=2
    SHIFT_EXP  = 0.10   #Specify the Expected (mean) Random % Image Shift (0-1)
    SHIFT_STDDEV = 0.05 #Specify the Standard Deviation as % of Image (0-1)
    np.random.seed(12)   #Set a new seed to get different random alignments
    #---------------------------------#
    
    data_py = utils.get_array(dataset) #get data as numpy array
    
    if data_py is None: #Check if data exists
        raise RuntimeError("No data array found!")    
    
    if TILT_AXIS == []: #If tilt axis is not given, find it
    #Find smallest array dimension, assume it is the tilt angle axis
        if data_py.ndim == 3:
            TILT_AXIS = np.argmin( data_py.shape )
        elif data_py.ndim == 2:
            raise RuntimeError("Data Array is 2 dimensions, it should be 3!")
        else: 
            raise RuntimeError("Data Array is not 2 or 3 dimensions!")
            

    for i in range(0,np.size(data_py,TILT_AXIS)-1):
        if TILT_AXIS == 2:
            shift_mu    = np.size(data_py,0)*SHIFT_EXP
            shift_sigma = np.size(data_py,0)*SHIFT_STDDEV
            shift0 = int( np.random.normal(shift_mu, shift_sigma) )
            shift1 = int( np.random.normal(shift_mu, shift_sigma) )
            data_py[:,:,i] = np.roll( data_py[:,:,i], shift0, axis = 0)
            data_py[:,:,i] = np.roll( data_py[:,:,i], shift1, axis = 1)
        elif TILT_AXIS == 1:
            shift_mu    = np.size(data_py,0)*SHIFT_EXP
            shift_sigma = np.size(data_py,0)*SHIFT_STDDEV
            shift0 = int( np.random.normal(shift_mu, shift_sigma) )
            shift1 = int( np.random.normal(shift_mu, shift_sigma) )
            data_py[:,i,:] = np.roll( data_py[:,i,:], shift0, axis = 0)
            data_py[:,i,:] = np.roll( data_py[:,i,:], shift2, axis = 2)
        elif TILT_AXIS == 0:
            shift_mu    = np.size(data_py,1)*SHIFT_EXP
            shift_sigma = np.size(data_py,1)*SHIFT_STDDEV
            shift0 = int( np.random.normal(shift_mu, shift_sigma) )
            shift1 = int( np.random.normal(shift_mu, shift_sigma) )
            data_py[i,:,:] = np.roll( data_py[i,:,:], shift1, axis = 1)
            data_py[i,:,:] = np.roll( data_py[i,:,:], shift2, axis = 2)
        else:
            raise RuntimeError("Python Transform Error: Unknown TILT_AXIS.")
    
    utils.set_array(dataset, data_py)
    print('Misalign Images Complete')
コード例 #25
0
ファイル: LaplaceFilter.py プロジェクト: happy-fish/tomviz
def transform_scalars(dataset):
    """Apply a Laplace filter to dataset."""

    from tomviz import utils
    import numpy as np
    import scipy.ndimage

    array = utils.get_array(dataset)

    # Transform the dataset
    result = scipy.ndimage.filters.laplace(array)

    # Set the result as the new scalars.
    utils.set_array(dataset, result)
コード例 #26
0
ファイル: DownsampleByTwo.py プロジェクト: coldatom/tomviz
def transform_scalars(dataset):
    """Downsample dataset by a factor of 2"""
    
    from tomviz import utils
    import numpy as np
    import scipy.ndimage

    array = utils.get_array(dataset)

    # transform the dataset
    result = scipy.ndimage.interpolation.zoom(array, (0.5, 0.5, 0.5))
    
    # set the result as the new scalars.
    utils.set_array(dataset, result)
    
コード例 #27
0
def transform_scalars(dataset, shift=[0, 0, 0]):
    from tomviz import utils
    import numpy as np

    data_py = utils.get_array(dataset) # Get data as numpy array.

    if data_py is None: #Check if data exists
        raise RuntimeError("No data array found!")

    data_py[:] = np.roll(data_py, shift[0], axis=0)
    data_py[:] = np.roll(data_py, shift[1], axis=1)
    data_py[:] = np.roll(data_py, shift[2], axis=2)

    utils.set_array(dataset, data_py)
    print('Data has been shifted uniformly.')
コード例 #28
0
def transform_scalars(dataset):
    """Calculate 3D gradient magnitude using Sobel operator"""

    from tomviz import utils
    import numpy as np
    import scipy.ndimage

    array = utils.get_array(dataset)
    array = array.astype(np.float32)

    # Transform the dataset
    result = scipy.ndimage.filters.generic_gradient_magnitude(array, scipy.ndimage.filters.sobel)
    
    # Set the result as the new scalars.
    utils.set_array(dataset, result)
コード例 #29
0
ファイル: DownsampleByTwo.py プロジェクト: happy-fish/tomviz
def transform_scalars(dataset):
    """Downsample dataset by a factor of 2"""

    from tomviz import utils
    import numpy as np
    import scipy.ndimage

    array = utils.get_array(dataset)

    # Downsample the dataset x2 using order 1 spline (linear)
    result = scipy.ndimage.interpolation.zoom(array, 
                (0.5, 0.5, 0.5),output=None, order=1,
                mode='constant', cval=0.0, prefilter=False)

    # Set the result as the new scalars.
    utils.set_array(dataset, result)
コード例 #30
0
ファイル: ClearVolume.py プロジェクト: OpenChemistry/tomviz
def transform_scalars(dataset,  XRANGE=None, YRANGE=None, ZRANGE=None):
    """Define this method for Python operators that
    transform input scalars"""

    from tomviz import utils
    import numpy as np

    array = utils.get_array(dataset)
    if array is None:
        raise RuntimeError("No scalars found!")

    # Transform the dataset.
    result = np.copy(array)
    result[XRANGE[0]:XRANGE[1], YRANGE[0]:YRANGE[1], ZRANGE[0]:ZRANGE[1]] = 0
    # Set the result as the new scalars.
    utils.set_array(dataset, result)
コード例 #31
0
    def transform_scalars(self, dataset, Niter=10, Nupdates=0):
        """3D Reconstruct from a tilt series using simple TV minimzation"""
        self.progress.maximum = 1

        # Get Tilt angles
        tiltAngles = utils.get_tilt_angles(dataset)

        #remove zero tilt anlges
        if np.count_nonzero(tiltAngles) < tiltAngles.size:
            tiltAngles = tiltAngles + 0.001

        # Get Tilt Series
        tiltSeries = utils.get_array(dataset)
        (Nslice, Nray, Nproj) = tiltSeries.shape

        # Determine the slices for live updates.
        Nupdates = calc_Nupdates(Nupdates, Niter)

        # Generate measurement matrix
        A = parallelRay(Nray, 1.0, tiltAngles, Nray,
                        1.0)  #A is a sparse matrix
        recon = np.zeros([Nslice, Nray, Nray], dtype=np.float32, order='F')
        A = A.tocsr()

        (Nslice, Nray, Nproj) = tiltSeries.shape
        (Nrow, Ncol) = A.shape
        rowInnerProduct = np.zeros(Nrow, dtype=np.float32)
        row = np.zeros(Ncol, dtype=np.float32)
        f = np.zeros(Ncol, dtype=np.float32)  # Placeholder for 2d image

        ng = 5
        beta = 1.0
        r_max = 1.0
        gamma_red = 0.8

        # Calculate row inner product, preparation for ART recon
        for j in range(Nrow):
            row[:] = A[j, :].toarray()
            rowInnerProduct[j] = np.dot(row, row)

        self.progress.maximum = Niter * Nslice
        t0 = time.time()
        counter = 1
        etcMessage = 'Estimated time to complete: n/a'

        #Create child dataset for recon
        child = utils.make_child_dataset(dataset)
        utils.mark_as_volume(child)

        for i in range(Niter):  #main loop

            recon_temp = recon.copy()

            #ART recon
            for s in range(Nslice):  #
                if self.canceled:  #In case canceled during ART.
                    return

                self.progress.message = 'Slice No.%d/%d, Iteration No.%d/%d. '\
                    % (s + 1, Nslice, i + 1, Niter) + etcMessage

                if (i == 0):
                    f[:] = 0
                elif (i != 0):
                    f[:] = recon[s, :, :].flatten()

                b = tiltSeries[s, :, :].transpose().flatten()

                for j in range(Nrow):
                    row[:] = A[j, :].toarray()
                    a = (b[j] - np.dot(row, f)) / rowInnerProduct[j]
                    f = f + row * a * beta
                recon[s, :, :] = f.reshape((Nray, Nray))

                self.progress.value = i * Nslice + s

                timeLeft = (time.time() - t0) / counter * \
                    (Nslice * Niter - counter)
                counter += 1
                timeLeftMin, timeLeftSec = divmod(timeLeft, 60)
                timeLeftHour, timeLeftMin = divmod(timeLeftMin, 60)
                etcMessage = 'Estimated time to complete: %02d:%02d:%02d' % (
                    timeLeftHour, timeLeftMin, timeLeftSec)

            recon[recon < 0] = 0  #Positivity constraint

            #Update for XX iterations.
            if Nupdates != 0 and (i + 1) % Nupdates == 0:
                utils.set_array(child, recon)
                self.progress.data = child

            if i != (Niter - 1):

                self.progress.message = 'Minimizating the Objects TV'

                #calculate tomogram change due to POCS
                dPOCS = np.linalg.norm(recon_temp - recon)

                recon_temp = recon.copy()

                #3D TV minimization
                for j in range(ng):
                    R_0 = tv(recon)
                    v = tv_derivative(recon)
                    recon_prime = recon - dPOCS * v
                    recon_prime[recon_prime < 0] = 0
                    gamma = 1.0
                    R_f = tv(recon_prime)

                    #Projected Line search
                    while R_f > R_0:
                        gamma = gamma * gamma_red
                        recon_prime = recon - gamma * dPOCS * v
                        recon_prime[recon_prime < 0] = 0
                        R_f = tv(recon_prime)
                    recon = recon_prime

                dg = np.linalg.norm(recon - recon_temp)

                if dg > r_max * dPOCS:
                    recon = r_max * dPOCS / dg * (recon -
                                                  recon_temp) + recon_temp

        # One last update of the child data.
        utils.set_array(child, recon)  #add recon to child
        self.progress.data = child

        returnValues = {}
        returnValues["reconstruction"] = child
        return returnValues
コード例 #32
0
    def transform_scalars(self, dataset):
        """
          Automatic align the tilt axis to horizontal direction (x-axis)
        """
        self.progress.maximum = 1

        # Get Tilt Series
        tiltSeries = utils.get_array(dataset)

        if tiltSeries is None: #Check if data exists
            raise RuntimeError("No data array found!")

        (Nslice, Nray, Nproj) = tiltSeries.shape
        Intensity = np.zeros(tiltSeries.shape)

        self.progress.maximum = Nproj + 131 #coarse(90)+fine(41)
        step = 0

        self.progress.message = 'Initialization'
        #take FFT of all projections
        for i in range(Nproj):
            self.progress.message = ('Taking Fourier transofrm of tilt image'
                                     'No.%d/%d' % (i + 1, Nproj))
            tiltImage = tiltSeries[:, :, i]
            tiltImage_F = np.abs(np.fft.fft2(tiltImage))
            if (i == 0):
                temp = tiltImage_F[0, 0]
            Intensity[:, :, i] = np.fft.fftshift(tiltImage_F / temp)
            step += 1
            self.progress.value = step

        #rescale intensity
        Intensity = np.power(Intensity, 0.2)

        #calculate variation itensity image
        Intensity_var = np.var(Intensity, axis=2)
        #search angles
        coarseStep = 2
        fineStep = 0.1
        coarseAngles = np.arange(-90, 90, coarseStep)

        Nx = Intensity_var.shape[0]
        Ny = Intensity_var.shape[1]
        N = np.round(np.min([Nx, Ny]) // 3)

        #coarse search
        I = np.zeros((coarseAngles.size, N))
        for a in range(coarseAngles.size):
            if self.canceled:
                return
            self.progress.message = ('Calculating line intensity at angle %f'
                                     'degree' % (coarseAngles[a]))
            I[a, :] = calculateLineIntensity(Intensity_var, coarseAngles[a], N)
            step += 1
            self.progress.value = step

        I_sum = np.sum(I, axis=1)
        minIntensityIndex = np.argmin(I_sum)
        rot_ang = coarseAngles[minIntensityIndex]

        #now refine
        fineAngles = np.arange(rot_ang - coarseStep,
                               rot_ang + coarseStep + fineStep, fineStep)

        #fine search
        I = np.zeros((fineAngles.size, N))
        for a in range(fineAngles.size):
            if self.canceled:
                return
            self.progress.message = ('Calculating line intensity at angle %f'
                                     'degree' % (fineAngles[a]))

            I[a, :] = calculateLineIntensity(Intensity_var, fineAngles[a], N)
            step += 1
            self.progress.value = step

        I_sum = np.sum(I, axis=1)
        minIntensityIndex = np.argmin(I_sum)
        rot_ang = fineAngles[minIntensityIndex]

        self.progress.message = 'Rotating tilt series'
        axes = ((0, 1))
        shape = utils.rotate_shape(tiltSeries, -rot_ang, axes=axes)
        result = np.empty(shape, tiltSeries.dtype, order='F')
        ndimage.interpolation.rotate(
            tiltSeries, -rot_ang, axes=axes, output=result)

        print("rotate tilt series by %f degrees" % -rot_ang)

        # Set the result as the new scalars.
        utils.set_array(dataset, result)
コード例 #33
0
ファイル: Recon_WBP.py プロジェクト: serval2412/tomviz
    def transform_scalars(self,
                          dataset,
                          Nrecon=None,
                          filter=None,
                          interp=None):
        """
        3D Reconstruct from a tilt series using Weighted Back-projection Method
        """
        self.progress.maximum = 1

        from tomviz import utils
        interpolation_methods = ('linear', 'nearest', 'spline', 'cubic')
        filter_methods = ('none', 'ramp', 'shepp-logan', 'cosine', 'hamming',
                          'hann')

        # Get Tilt angles
        tilt_angles = utils.get_tilt_angles(dataset)

        tiltSeries = utils.get_array(dataset)
        if tiltSeries is None:
            raise RuntimeError("No scalars found!")

        Nslice = tiltSeries.shape[0]

        self.progress.maximum = Nslice
        step = 0

        recon = np.empty([Nslice, Nrecon, Nrecon], dtype=float, order='F')
        t0 = time.time()
        counter = 1
        etcMessage = 'Estimated time to complete: n/a'

        child = utils.make_child_dataset(dataset)  #create child for recon
        utils.mark_as_volume(child)

        for i in range(Nslice):
            if self.canceled:
                return
            self.progress.message = 'Slice No.%d/%d. ' % (i + 1,
                                                          Nslice) + etcMessage

            recon[i, :, :] = wbp2(tiltSeries[i, :, :], tilt_angles, Nrecon,
                                  filter_methods[filter],
                                  interpolation_methods[interp])
            step += 1
            self.progress.value = step
            timeLeft = (time.time() - t0) / counter * (Nslice - counter)
            counter += 1
            timeLeftMin, timeLeftSec = divmod(timeLeft, 60)
            timeLeftHour, timeLeftMin = divmod(timeLeftMin, 60)
            etcMessage = 'Estimated time to complete: %02d:%02d:%02d' % (
                timeLeftHour, timeLeftMin, timeLeftSec)

            # Update only once every so many steps
            if (i + 1) % 40 == 0:
                utils.set_array(child, recon)  #add recon to child
                # This copies data to the main thread
                self.progress.data = child

        # One last update of the child data.
        utils.set_array(child, recon)  #add recon to child
        self.progress.data = child

        returnValues = {}
        returnValues["reconstruction"] = child
        return returnValues
コード例 #34
0
ファイル: TV_Filter.py プロジェクト: lzyaass/tomviz-1
    def transform_scalars(self,
                          dataset,
                          Niter=100,
                          a=0.1,
                          wedgeSize=5,
                          kmin=5,
                          theta=0):
        """
        Remove Structured Artifacts with Total Variation Minimization"""

        #Import information from dataset
        array = utils.get_array(dataset)
        (nx, ny, nz) = array.shape

        # Convert angle from Degrees to Radians.
        theta = (theta + 90) * (np.pi / 180)
        dtheta = wedgeSize * (np.pi / 180)

        #Create coordinate grid in polar
        x = np.arange(-nx / 2, nx / 2 - 1, dtype=np.float64)
        y = np.arange(-ny / 2, ny / 2 - 1, dtype=np.float64)
        [x, y] = np.meshgrid(x, y, indexing='ij')
        rr = (np.square(x) + np.square(y))
        phi = np.arctan2(x, y)

        #Create the Angular Mask
        mask = np.ones((nx, ny), dtype=np.int8)
        mask[np.where((phi >= (theta - dtheta / 2))
                      & (phi <= (theta + dtheta / 2)))] = 0
        mask[np.where((phi >= (np.pi + theta - dtheta / 2))
                      & (phi <= (np.pi + theta + dtheta / 2)))] = 0
        mask[np.where((phi >= (-np.pi + theta - dtheta / 2))
                      & (phi <= (-np.pi + theta + dtheta / 2)))] = 0
        mask[np.where(rr < np.square(kmin))] = 1  # Keep values below rmin.
        mask = np.array(mask, dtype=bool)

        # Initialize Progress bar.
        self.progress.maximum = nz * Niter

        #Main Loop
        for i in range(nz):

            #FFT of the Original Image.
            FFT_image = fftshift(fftn(array[:, :, i]))

            # Reconstruction starts as random image.
            recon_init = np.random.rand(nx, ny)

            self.progress.message = 'Processing Image No.%d/%d ' % (i + 1, nz)

            #TV Artifact Removal Loop
            for j in range(Niter):

                # FFT of Reconstructed Image.
                FFT_recon = fftshift(fftn(recon_init))

                # Impose the Data Constraint
                FFT_recon[mask] = FFT_image[mask]

                #Inverse FFT
                recon_constraint = np.real(ifftn(ifftshift(FFT_recon)))

                # Positivity Constraint
                recon_constraint[recon_constraint < 0] = 0

                # TV Minimization Loop
                recon_minTV = recon_constraint
                d = np.linalg.norm(recon_minTV - recon_init)
                for k in range(20):
                    vst = TVDerivative(recon_minTV, nx, ny)
                    recon_minTV = recon_minTV - a * d * vst

                    if self.canceled:
                        return

                # Initializte the Next Loop.
                recon_init = recon_minTV

                # Update the Progress Bar.
                self.progress.value = i * Niter + j

            # Return reconstruction into stack.
            array[:, :, i] = recon_constraint

        #Set the result as the new scalars.
        utils.set_array(dataset, np.asfortranarray(array))
コード例 #35
0
    def transform_scalars(self, dataset):
        """Automatically align tilt images by cross-correlation"""
        self.progress.maximum = 1

        tiltSeries = utils.get_array(dataset).astype(float)
        tiltAngles = utils.get_tilt_angles(dataset)

        # determine reference image index
        zeroDegreeTiltImage = None
        if tiltAngles is not None:
            zeroDegreeTiltImage = np.where(tiltAngles == 0)[0]

        if zeroDegreeTiltImage:
            referenceIndex = zeroDegreeTiltImage[0]
        else:
            referenceIndex = tiltSeries.shape[2] // 2

        # create Fourier space filter
        filterCutoff = 4
        (Ny, Nx, Nproj) = tiltSeries.shape
        ky = np.fft.fftfreq(Ny)
        kx = np.fft.fftfreq(Nx)
        [kX, kY] = np.meshgrid(kx, ky)
        kR = np.sqrt(kX**2 + kY**2)
        kFilter = (kR <= (0.5 / filterCutoff)) * \
            np.sin(2 * filterCutoff * np.pi * kR)**2

        # create real sapce filter to remove edge discontinuities
        y = np.linspace(1, Ny, Ny)
        x = np.linspace(1, Nx, Nx)
        [X, Y] = np.meshgrid(x, y)
        rFilter = (np.sin(np.pi * X / Nx) * np.sin(np.pi * Y / Ny)) ** 2

        self.progress.maximum = tiltSeries.shape[2] - 1
        step = 1

        offsets = np.zeros((tiltSeries.shape[2], 2))

        for i in range(referenceIndex, Nproj - 1):
            if self.canceled:
                return
            self.progress.message = 'Processing tilt image No.%d/%d' % (
                step, Nproj)

            offsets[i + 1, :], tiltSeries[:, :, i + 1] = crossCorrelationAlign(
                tiltSeries[:, :, i + 1], tiltSeries[:, :, i], rFilter, kFilter)
            step += 1
            self.progress.value = step

        for i in range(referenceIndex, 0, -1):
            if self.canceled:
                return
            self.progress.message = 'Processing tilt image No.%d/%d' % (
                step, Nproj)
            offsets[i - 1, :], tiltSeries[:, :, i - 1] = crossCorrelationAlign(
                tiltSeries[:, :, i - 1], tiltSeries[:, :, i], rFilter, kFilter)
            step += 1
            self.progress.value = step

        utils.set_array(dataset, tiltSeries)

        # Assign Negative Shifts when Shift > N/2.
        indices_X = np.where(offsets[:, 0] > tiltSeries.shape[0] / 2)
        offsets[indices_X, 0] -= tiltSeries.shape[0]
        indices_Y = np.where(offsets[:, 1] > tiltSeries.shape[1] / 2)
        offsets[indices_Y, 1] -= tiltSeries.shape[1]

        # Create a spreadsheet data set from table data
        column_names = ["X Offset", "Y Offset"]
        offsetsTable = utils.make_spreadsheet(column_names, offsets)
        # Set up dictionary to return operator results
        returnValues = {}
        returnValues["alignments"] = offsetsTable
        return returnValues
コード例 #36
0
    def transform_scalars(self,
                          dataset,
                          Niter=None,
                          stepSize=None,
                          updateMethodIndex=None):
        """
        3D Reconstruct from a tilt series using Simultaneous Iterative
        Reconstruction Techniques (SIRT)"""
        self.progress.maximum = 1

        update_methods = ('landweber', 'cimmino', 'component averaging')
        #reference
        """L. Landweber, Amer. J. Math., 73 (1951), pp. 615–624"""
        """G. Cimmino, La Ric. Sci., XVI, Ser. II, Anno IX, 1 (1938),
        pp. 326–333
        """
        """Y. Censor et al, Parallel Comput., 27 (2001), pp. 777–808"""

        # Get Tilt angles
        tiltAngles = utils.get_tilt_angles(dataset)

        #remove zero tilt anlges
        if np.count_nonzero(tiltAngles) < tiltAngles.size:
            tiltAngles = tiltAngles + 0.001

        # Get Tilt Series
        tiltSeries = utils.get_array(dataset)
        (Nslice, Nray, Nproj) = tiltSeries.shape

        if tiltSeries is None:
            raise RuntimeError("No scalars found!")

        # Generate measurement matrix
        self.progress.message = 'Generating measurement matrix'
        A = parallelRay(Nray, 1.0, tiltAngles, Nray,
                        1.0)  #A is a sparse matrix
        recon = np.empty([Nslice, Nray, Nray], dtype=float, order='F')

        self.progress.maximum = Nslice + 1
        step = 0

        #create a reconstruction object
        r = SIRT(A, update_methods[updateMethodIndex])
        r.initialize()
        step += 1
        self.progress.value = step

        for s in range(Nslice):
            if self.canceled:
                return
            b = tiltSeries[s, :, :].transpose().flatten()
            self.progress.message = 'Slice No.%d/%d' % (s + 1, Nslice)
            recon[s, :, :] = r.recon2(b, Niter, stepSize).reshape((Nray, Nray))
            step += 1
            self.progress.value = step

        from vtk import vtkImageData
        recon_dataset = vtkImageData()
        recon_dataset.CopyStructure(dataset)
        utils.set_array(recon_dataset, recon)
        utils.mark_as_volume(recon_dataset)

        returnValues = {}
        returnValues["reconstruction"] = recon_dataset
        return returnValues
コード例 #37
0
    def transform_scalars(self,
                          dataset,
                          Niter=None,
                          Niter_update_support=None,
                          supportSigma=None,
                          supportThreshold=None):
        """
        3D Reconstruct from a tilt series using constraint-based Direct Fourier
        Method
        """
        self.progress.maximum = 1

        from tomviz import utils
        import numpy as np

        supportThreshold = supportThreshold / 100.0

        nonnegativeVoxels = True
        tiltAngles = utils.get_tilt_angles(dataset)  #Get Tilt angles

        tiltSeries = utils.get_array(dataset)
        if tiltSeries is None:
            raise RuntimeError("No scalars found!")

        self.progress.message = 'Initialization'
        #Direct Fourier recon without constraints
        (recon, recon_F) \
            = dfm3(tiltSeries, tiltAngles, np.size(tiltSeries, 0) * 2)

        kr_cutoffs = np.linspace(0.05, 0.5, 10)
        #average Fourier magnitude of tilt series as a function of kr
        I_data = radial_average(tiltSeries, kr_cutoffs)

        (Nx, Ny, Nz) = recon_F.shape
        #Note: Nz = np.int(Ny/2+1)
        Ntot = Nx * Ny * Ny
        f = pyfftw.n_byte_align_empty((Nx, Ny, Nz), 16, dtype='complex128')
        r = pyfftw.n_byte_align_empty((Nx, Ny, Ny), 16, dtype='float64')
        fft_forward = pyfftw.FFTW(r, f, axes=(0, 1, 2))
        fft_inverse = pyfftw.FFTW(f,
                                  r,
                                  direction='FFTW_BACKWARD',
                                  axes=(0, 1, 2))

        kx = np.fft.fftfreq(Nx)
        ky = np.fft.fftfreq(Ny)
        kz = ky[0:Nz]

        kX, kY, kZ = np.meshgrid(ky, kx, kz)
        kR = np.sqrt(kY**2 + kX**2 + kZ**2)

        sigma = 0.5 * supportSigma
        G = np.exp(-kR**2 / (2 * sigma**2))

        #create initial support using sw
        f = recon_F * G
        fft_inverse.update_arrays(f, r)
        fft_inverse.execute()
        cutoff = np.amax(r) * supportThreshold
        support = r >= cutoff

        recon_F[kR > kr_cutoffs[-1]] = 0

        x = np.random.rand(Nx, Ny, Ny)  #initial solution

        self.progress.maximum = Niter
        step = 0

        for i in range(Niter):
            if self.canceled:
                return
            self.progress.message = 'Iteration No.%d/%d' % (i + 1, Niter)

            #image space projection
            y1 = x.copy()

            if nonnegativeVoxels:
                y1[y1 < 0] = 0  #non-negative constraint

            y1[np.logical_not(support)] = 0  #support constraint

            #Fourier space projection
            y2 = 2 * y1 - x

            r = y2.copy()
            fft_forward.update_arrays(r, f)
            fft_forward.execute()

            f[kR > kr_cutoffs[-1]] = 0  #apply low pass filter
            f[recon_F != 0] = recon_F[recon_F != 0]  #data constraint

            #Fourier magnitude constraint
            #leave the inner shell unchanged
            for j in range(1, kr_cutoffs.size):
                shell = np.logical_and(kR > kr_cutoffs[j - 1],
                                       kR <= kr_cutoffs[j])
                shell[recon_F != 0] = False
                I = np.sum(np.absolute(f[shell]))
                if I != 0:
                    I = I / np.sum(shell)
                    # lower magnitude for high frequency information to reduce
                    # artifacts
                    f[shell] = f[shell] / I * I_data[j] * 0.5

            fft_inverse.update_arrays(f, r)
            fft_inverse.execute()
            y2 = r.copy() / Ntot

            #update
            x = x + y2 - y1

            #update support
            if (i < Niter and np.mod(i, Niter_update_support) == 0):
                print("updating support")
                recon = (y2 + y1) / 2
                r = recon.copy()
                fft_forward.update_arrays(r, f)
                fft_forward.execute()
                f = f * G
                fft_inverse.update_arrays(f, r)
                fft_inverse.execute()
                cutoff = np.amax(r) * supportThreshold
                support = r >= cutoff
            step += 1
            self.progress.value = step

        recon = (y2 + y1) / 2
        recon = np.fft.fftshift(recon)

        print('Reconsruction Complete')

        # Set the result as the new scalars.
        utils.set_array(dataset, recon)

        # Mark dataset as volume
        utils.mark_as_volume(dataset)
コード例 #38
0
    def transform_scalars(self, dataset, Niter=1):
        """3D Reconstruct from a tilt series using simple TV minimzation"""
        self.progress.maximum = 1

        # Get Tilt angles
        tiltAngles = utils.get_tilt_angles(dataset)

        #remove zero tilt anlges
        if np.count_nonzero(tiltAngles) < tiltAngles.size:
            tiltAngles = tiltAngles + 0.001

        # Get Tilt Series
        tiltSeries = utils.get_array(dataset)
        (Nslice, Nray, Nproj) = tiltSeries.shape

        if tiltSeries is None:
            raise RuntimeError("No scalars found!")

        # Generate measurement matrix
        A = parallelRay(Nray, 1.0, tiltAngles, Nray,
                        1.0)  #A is a sparse matrix
        recon = np.zeros((Nslice, Nray, Nray))  #allocate reconstruction matrix
        A = A.todense()

        (Nslice, Nray, Nproj) = tiltSeries.shape
        (Nrow, Ncol) = A.shape
        rowInnerProduct = np.zeros(Nrow)
        row = np.zeros(Ncol)
        f = np.zeros(Ncol)  # Placeholder for 2d image

        alpha = 0.2
        ng = 30
        beta_red = 0.995
        beta = 1.0
        # Calculate row inner product, preparation for ART recon
        for j in range(Nrow):
            row[:] = A[j, ].copy()
            rowInnerProduct[j] = np.dot(row, row)

        self.progress.maximum = Niter
        step = 0
        for i in range(Niter):  #main loop
            if self.canceled:
                return
            self.progress.message = 'Iteration No.%d/%d' % (i + 1, Niter)
            recon_temp = recon.copy()
            #ART recon
            for s in range(Nslice):  #
                f[:] = 0
                b = tiltSeries[s, :, :].transpose().flatten()
                for j in range(Nrow):
                    row[:] = A[j, ].copy()
                    row_f_product = np.dot(row, f)
                    a = (b[j] - row_f_product) / rowInnerProduct[j]
                    f = f + row * a * beta
                recon[s, :, :] = f.reshape((Nray, Nray))

            recon[recon < 0] = 0  #Positivity constraint

            #calculate tomogram change due to POCS
            dPOCS = np.linalg.norm(recon_temp - recon)

            #3D TV minimization
            for j in range(ng):
                r = np.lib.pad(recon, ((1, 1), (1, 1), (1, 1)), 'edge')
                v1n = 3 * r - np.roll(r, 1, axis=0) - \
                                      np.roll(r, 1, axis=1) - np.roll(r, 1, axis=2) # noqa TODO reformat this
                v1d = np.sqrt(
                    1e-8 + (r - np.roll(r, 1, axis=0))**2 +
                    (r - np.roll(r, 1, axis=1))**2 +
                    (r - np.roll(r, 1, axis=2))**2)  # noqa TODO reformat this

                v2n = r - np.roll(r, -1, axis=0)
                v2d = np.sqrt(1e-8 + (np.roll(r, -1, axis=0) - r)**2 + (
                    np.roll(r, -1, axis=0) -  # noqa TODO reformat this
                    np.roll(np.roll(r, -1, axis=0), 1, axis=1))**2 +
                              (np.roll(r, -1, axis=0) -
                               np.roll(np.roll(r, -1, axis=0), 1, axis=2))**
                              2)  # noqa TODO reformat this

                v3n = r - np.roll(r, -1, axis=1)
                v3d = np.sqrt(1e-8 +
                              (np.roll(r, -1, axis=1) -
                               np.roll(np.roll(r, -1, axis=1), 1, axis=0))**2
                              +  # noqa TODO reformat this
                              (np.roll(r, -1, axis=1) - r)**2
                              +  # noqa TODO reformat this
                              (np.roll(r, -1, axis=1) -
                               np.roll(np.roll(r, -1, axis=1), 1, axis=2))**
                              2)  # noqa TODO reformat this

                v4n = r - np.roll(r, -1, axis=2)
                v4d = np.sqrt(
                    1e-8 + (np.roll(r, -1, axis=2) -
                            np.roll(np.roll(r, -1, axis=2), 1, axis=0))**2
                    +  # noqa TODO reformat this
                    (
                        np.roll(r, -1, axis=2) -  # noqa TODO reformat this
                        np.roll(np.roll(r, -1, axis=1), 1, axis=1))**2 +
                    (np.roll(r, -1, axis=2) - r)**2)  # noqa TODO reformat this

                v = v1n / v1d + v2n / v2d + v3n / v3d + v4n / v4d
                v = v[1:-1, 1:-1, 1:-1]
                v = v / np.linalg.norm(v)
                recon = recon - alpha * dPOCS * v

            #adjust parameters
            beta = beta * beta_red
            step += 1
            self.progress.value = step

        # Set the result as the new scalars.
        utils.set_array(dataset, recon)

        # Mark dataset as volume
        utils.mark_as_volume(dataset)
コード例 #39
0
ファイル: GenerateTiltSeries.py プロジェクト: tjcorona/tomviz
    def transform_scalars(self,
                          dataset,
                          start_angle=-90.0,
                          angle_increment=3.0,
                          num_tilts=60):
        """Generate Tilt Series from Volume"""
        self.progress.maximum = 1

        self.progress.message = 'Initialization'
        # Generate Tilt Angles.
        angles = np.linspace(start_angle,
                             start_angle + (num_tilts - 1) * angle_increment,
                             num_tilts)

        volume = utils.get_array(dataset)
        Ny = volume.shape[1]
        Nz = volume.shape[2]
        # calculate the size s.t. it contains the entire volume
        N = np.round(np.sqrt(Ny**2 + Nz**2))
        N = int(np.floor(N / 2.0) * 2 + 1)  # make the size an odd integer

        # pad volume
        pad_y_pre = int(np.ceil((N - Ny) / 2.0))
        pad_y_post = int(np.floor((N - Ny) / 2.0))
        pad_z_pre = int(np.ceil((N - Nz) / 2.0))
        pad_z_post = int(np.floor((N - Nz) / 2.0))
        volume_pad = np.lib.pad(volume, ((0, 0), (pad_y_pre, pad_y_post),
                                         (pad_z_pre, pad_z_post)), 'constant')

        Nslice = volume.shape[0]  # Number of slices along rotation axis.
        tiltSeries = np.zeros((Nslice, N, num_tilts))

        self.progress.maximum = num_tilts
        step = 0

        for i in range(num_tilts):
            if self.canceled:
                return
            self.progress.message = 'Generating tilt image No.%d/%d' % (
                i + 1, num_tilts)

            # Rotate volume about x-axis
            rotatedVolume = np.empty_like(volume_pad)
            scipy.ndimage.interpolation.rotate(volume_pad,
                                               angles[i],
                                               axes=(1, 2),
                                               reshape=False,
                                               order=1,
                                               output=rotatedVolume)
            # Calculate projection
            tiltSeries[:, :, i] = np.sum(rotatedVolume, axis=2)

            step += 1
            self.progress.value = step

        # Set the result as the new scalars.
        utils.set_array(dataset, tiltSeries)

        # Mark dataset as tilt series.
        utils.mark_as_tiltseries(dataset)

        # Save tilt angles.
        utils.set_tilt_angles(dataset, angles)
コード例 #40
0
def convert_vtk_to_itk_image(vtk_image_data, itk_pixel_type=None):
    """Get an ITK image from the provided vtkImageData object.
    This image can be passed to ITK filters."""

    # Save the VTKGlue optimization for later
    #------------------------------------------
    #itk_import = itk.VTKImageToImageFilter[image_type].New()
    #itk_import.SetInput(vtk_image_data)
    #itk_import.Update()
    #itk_image = itk_import.GetOutput()
    #itk_image.DisconnectPipeline()
    #------------------------------------------
    import itk
    import itkTypes
    from vtkmodules.util import vtkConstants
    from vtkmodules.vtkImagingCore import vtkImageCast
    from tomviz import utils

    itk_to_vtk_type_map = {
        itkTypes.F: vtkConstants.VTK_FLOAT,
        itkTypes.D: vtkConstants.VTK_DOUBLE,
        itkTypes.LD: vtkConstants.VTK_DOUBLE,
        itkTypes.UC: vtkConstants.VTK_UNSIGNED_CHAR,
        itkTypes.US: vtkConstants.VTK_UNSIGNED_SHORT,
        itkTypes.UI: vtkConstants.VTK_UNSIGNED_INT,
        itkTypes.UL: vtkConstants.VTK_UNSIGNED_LONG,
        itkTypes.SC: vtkConstants.VTK_CHAR,
        itkTypes.SS: vtkConstants.VTK_SHORT,
        itkTypes.SI: vtkConstants.VTK_INT,
        itkTypes.SL: vtkConstants.VTK_LONG,
        itkTypes.B: vtkConstants.VTK_INT
    }

    # See if we need to cast to a wrapped type in ITK.
    src_type = vtk_image_data.GetScalarType()

    if itk_pixel_type is None:
        dst_type = vtk_cast_map()[src_type]
    else:
        dst_type = vtk_cast_map()[itk_to_vtk_type_map[itk_pixel_type]]
    if src_type != dst_type:
        caster = vtkImageCast()
        caster.SetOutputScalarType(dst_type)
        caster.ClampOverflowOn()
        caster.SetInputData(vtk_image_data)
        caster.Update()
        vtk_image_data = caster.GetOutput()

    array = utils.get_array(vtk_image_data, order='C')

    image_type = _get_itk_image_type(vtk_image_data)
    itk_converter = itk.PyBuffer[image_type]
    itk_image = itk_converter.GetImageFromArray(array)
    spacing = vtk_image_data.GetSpacing()
    origin = vtk_image_data.GetOrigin()
    itk_image.SetSpacing(spacing)
    itk_image.SetOrigin(origin)

    # Persist a reference to the source vtk_image_data, which is necessary since
    # VTK and ITK are using Python Buffer-Protocol NumPy array views
    itk_image.vtk_image_data = vtk_image_data

    return itk_image
コード例 #41
0
ファイル: Recon_ART.py プロジェクト: fbudin69500/tomviz
    def transform_scalars(self, dataset, Niter=1):
        """
        3D Reconstruction using Algebraic Reconstruction Technique (ART)
        """
        self.progress.maximum = 1

        # Get Tilt angles
        tiltAngles = utils.get_tilt_angles(dataset)

        # Get Tilt Series
        tiltSeries = utils.get_array(dataset)
        (Nslice, Nray, Nproj) = tiltSeries.shape

        if tiltSeries is None:
            raise RuntimeError("No scalars found!")

        # Generate measurement matrix
        self.progress.message = 'Generating measurement matrix'
        A = parallelRay(Nray, 1.0, tiltAngles, Nray,
                        1.0)  #A is a sparse matrix
        recon = np.empty([Nslice, Nray, Nray], dtype=float, order='F')

        A = A.todense()
        (Nslice, Nray, Nproj) = tiltSeries.shape
        (Nrow, Ncol) = A.shape
        rowInnerProduct = np.zeros(Nrow)
        row = np.zeros(Ncol)
        f = np.zeros(Ncol)  # Placeholder for 2d image
        beta = 1.0

        # Calculate row inner product
        for j in range(Nrow):
            row[:] = A[j, ].copy()
            rowInnerProduct[j] = np.dot(row, row)

        self.progress.maximum = Nslice
        step = 0

        for s in range(Nslice):
            if self.canceled:
                return
            f[:] = 0
            b = tiltSeries[s, :, :].transpose().flatten()
            for i in range(Niter):
                self.progress.message = 'Slice No.%d/%d, iteration No.%d/%d' % (
                    s + 1, Nslice, i + 1, Niter)
                for j in range(Nrow):
                    row[:] = A[j, ].copy()
                    row_f_product = np.dot(row, f)
                    a = (b[j] - row_f_product) / rowInnerProduct[j]
                    f = f + row * a * beta

            recon[s, :, :] = f.reshape((Nray, Nray))

            step += 1
            self.progress.value = step

        from vtk import vtkImageData
        # Set up the output dataset
        recon_dataset = vtkImageData()
        recon_dataset.CopyStructure(dataset)
        utils.set_array(recon_dataset, recon)
        utils.mark_as_volume(recon_dataset)

        returnValues = {}
        returnValues["reconstruction"] = recon_dataset
        return returnValues
コード例 #42
0
    def transform_scalars(self, dataset):
        """3D Reconstruct from a tilt series using Direct Fourier Method"""

        self.progress.maximum = 1

        from tomviz import utils
        import numpy as np

        # Get Tilt angles
        tiltAngles = utils.get_tilt_angles(dataset)

        tiltSeries = utils.get_array(dataset)
        if tiltSeries is None:
            raise RuntimeError("No scalars found!")

        tiltSeries = np.double(tiltSeries)
        (Nx, Ny, Nproj) = tiltSeries.shape
        Npad = Ny * 2

        tiltAngles = np.double(tiltAngles)
        pad_pre = int(np.ceil((Npad - Ny) / 2.0))
        pad_post = int(np.floor((Npad - Ny) / 2.0))

        # Initialization
        self.progress.message = 'Initialization'
        Nz = Ny
        w = np.zeros((Nx, Ny, Nz // 2 + 1))  #store weighting factors
        v = pyfftw.n_byte_align_empty((Nx, Ny, Nz // 2 + 1),
                                      16,
                                      dtype='complex128')
        v = np.zeros(v.shape) + 1j * np.zeros(v.shape)
        recon = pyfftw.n_byte_align_empty((Nx, Ny, Nz),
                                          16,
                                          dtype='float64',
                                          order='F')
        recon_fftw_object = pyfftw.FFTW(v,
                                        recon,
                                        direction='FFTW_BACKWARD',
                                        axes=(0, 1, 2))

        p = pyfftw.n_byte_align_empty((Nx, Npad), 16, dtype='float64')
        pF = pyfftw.n_byte_align_empty((Nx, Npad // 2 + 1),
                                       16,
                                       dtype='complex128')
        p_fftw_object = pyfftw.FFTW(p, pF, axes=(0, 1))

        dk = np.double(Ny) / np.double(Npad)

        self.progress.maximum = Nproj + 1
        step = 0

        t0 = time.time()
        etcMessage = 'Estimated time to complete: n/a'
        counter = 1
        for a in range(Nproj):
            if self.canceled:
                return
            self.progress.message = 'Tilt image No.%d/%d. ' % (
                a + 1, Nproj) + etcMessage

            ang = tiltAngles[a] * np.pi / 180
            projection = tiltSeries[:, :, a]  #2D projection image
            p = np.lib.pad(projection, ((0, 0), (pad_pre, pad_post)),
                           'constant',
                           constant_values=(0, 0))  #pad zeros
            p = np.fft.ifftshift(p)
            p_fftw_object.update_arrays(p, pF)
            p_fftw_object()

            probjection_f = pF.copy()
            if ang < 0:
                probjection_f = np.conj(pF.copy())
                probjection_f[1:, :] = np.flipud(probjection_f[1:, :])
                ang = np.pi + ang

            # Bilinear extrapolation
            for i in range(0, np.int(np.ceil(Npad / 2)) + 1):
                ky = i * dk
                #kz = 0
                ky_new = np.cos(ang) * ky  #new coord. after rotation
                kz_new = np.sin(ang) * ky
                sy = abs(np.floor(ky_new) - ky_new)  #calculate weights
                sz = abs(np.floor(kz_new) - kz_new)
                for b in range(1, 5):  #bilinear extrapolation
                    pz, py, weight = bilinear(kz_new, ky_new, sz, sy, Ny, b)
                    if (py >= 0 and py < Ny and pz >= 0 and pz < Nz / 2 + 1):
                        w[:, py, pz] = w[:, py, pz] + weight
                        v[:, py, pz] = v[:, py, pz] + \
                            weight * probjection_f[:, i]
            step += 1
            self.progress.value = step
            timeLeft = (time.time() - t0) / counter * (Nproj - counter)
            counter += 1
            timeLeftMin, timeLeftSec = divmod(timeLeft, 60)
            timeLeftHour, timeLeftMin = divmod(timeLeftMin, 60)
            etcMessage = 'Estimated time to complete: %02d:%02d:%02d' % (
                timeLeftHour, timeLeftMin, timeLeftSec)

        self.progress.message = 'Inverse Fourier transform'
        v[w != 0] = v[w != 0] / w[w != 0]
        recon_fftw_object.update_arrays(v, recon)
        recon_fftw_object()
        recon[:] = np.fft.fftshift(recon)

        step += 1
        self.progress.value = step

        from vtk import vtkImageData
        recon_dataset = vtkImageData()
        recon_dataset.CopyStructure(dataset)
        utils.set_array(recon_dataset, recon)
        utils.mark_as_volume(recon_dataset)

        returnValues = {}
        returnValues["reconstruction"] = recon_dataset
        return returnValues