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)
Example #2
0
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)
Example #3
0
def transform_scalars(dataset):
    """Downsample volume by a factor of 2"""

    from tomviz import utils
    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)

    # Update tilt angles if dataset is a tilt series.
    try:
        tilt_angles = utils.get_tilt_angles(dataset)
        tilt_angles = scipy.ndimage.interpolation.zoom(tilt_angles, 0.5)
        utils.set_tilt_angles(dataset, tilt_angles)
    except:  # noqa
        # TODO What exception are we ignoring?
        pass
Example #4
0
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
Example #5
0
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
Example #6
0
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
Example #7
0
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)
Example #8
0
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
Example #9
0
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
Example #10
0
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
Example #11
0
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
Example #12
0
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)
Example #13
0
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)
Example #14
0
    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
Example #15
0
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 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:
            pass
Example #16
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
Example #17
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 = 1

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

        utils.set_array(dataset, tiltSeries)
Example #18
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.zeros((Nslice, Nray, Nray))

        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

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

        # Mark dataset as volume
        utils.mark_as_volume(dataset)
Example #19
0
    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
    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)
Example #21
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)
Example #22
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)
Example #23
0
    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.zeros((Nslice, Nrecon, Nrecon))
        for i in range(Nslice):
            if self.canceled:
                return
            self.progress.message = 'Slice No.%d/%d' % (i + 1, Nslice)
            recon[i, :, :] = wbp2(tiltSeries[i, :, :], tilt_angles, Nrecon,
                                  filter_methods[filter],
                                  interpolation_methods[interp])
            step += 1
            self.progress.value = step

        print('Reconsruction Complete')

        # 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
Example #24
0
def transform_scalars(dataset,
                      pad_size_before=[0, 0, 0],
                      pad_size_after=[0, 0, 0],
                      pad_mode_index=0):
    """Pad dataset"""
    from tomviz import utils
    import numpy as np

    padModes = ['constant', 'edge', 'wrap', 'minimum', 'median']
    padMode = padModes[pad_mode_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!")

    padWidthX = (pad_size_before[0], pad_size_after[0])
    padWidthY = (pad_size_before[1], pad_size_after[1])
    padWidthZ = (pad_size_before[2], pad_size_after[2])

    pad_width = (padWidthX, padWidthY, padWidthZ)

    result_shape = np.zeros(3, dtype=int)
    result_shape[0] = array.shape[0] + pad_size_before[0] + pad_size_after[0]
    result_shape[1] = array.shape[1] + pad_size_before[1] + pad_size_after[1]
    result_shape[2] = array.shape[2] + pad_size_before[2] + pad_size_after[2]

    result = np.empty(result_shape, array.dtype, order='F')

    # pad the data.
    result[:] = np.lib.pad(array, pad_width, padMode)

    # Set the data so that it is visible in the application.
    extent = list(dataset.GetExtent())
    start = [x - y for (x, y) in zip(extent[0::2], pad_size_before)]

    utils.set_array(dataset, result, start)

    # 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:  # noqa
            # TODO What exception are we ignoring?
            pass
Example #25
0
def transform_scalars(dataset, pad_size_before=[0, 0, 0],
                      pad_size_after=[0, 0, 0], pad_mode_index=0):
    """Pad dataset"""
    from tomviz import utils
    import numpy as np

    padModes = ['constant', 'edge', 'wrap', 'minimum', 'median']
    padMode = padModes[pad_mode_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!")

    padWidthX = (pad_size_before[0], pad_size_after[0])
    padWidthY = (pad_size_before[1], pad_size_after[1])
    padWidthZ = (pad_size_before[2], pad_size_after[2])

    pad_width = (padWidthX, padWidthY, padWidthZ)

    result_shape = np.zeros(3, dtype=int)
    result_shape[0] = array.shape[0] + pad_size_before[0] + pad_size_after[0]
    result_shape[1] = array.shape[1] + pad_size_before[1] + pad_size_after[1]
    result_shape[2] = array.shape[2] + pad_size_before[2] + pad_size_after[2]

    result = np.empty(result_shape, array.dtype, order='F')

    # pad the data.
    result[:] = np.lib.pad(array, pad_width, padMode)

    # Set the data so that it is visible in the application.
    extent = list(dataset.GetExtent())
    start = [x - y for (x, y) in zip(extent[0::2], pad_size_before)]

    utils.set_array(dataset, result, start)

    # 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: # noqa
            # TODO What exception are we ignoring?
            pass
Example #26
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

    def dimensions(array):
        if array.ndim == 4:
            zoom = (0.5,0.5,0.5,1)
        
        else:
            zoom = (0.5, 0.5, 0.5)
        
        return zoom

    zoom = dimensions(array)
    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
Example #27
0
def transform_scalars(dataset):
    """3D Reconstruct from a tilt series using Direct Fourier Method"""

    from tomviz import utils
    import numpy as np

    # 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 = dfm3(data_py, tilt_angles, np.size(data_py, 0) * 2)
    print('Reconsruction Complete')

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

    # Mark dataset as volume
    utils.mark_as_volume(dataset)
Example #28
0
def transform_scalars(dataset):
    """3D Reconstruct from a tilt series using Direct Fourier Method"""

    from tomviz import utils
    import numpy as np

    # 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 = dfm3(data_py,tilt_angles,np.size(data_py,0)*2)
    print('Reconsruction Complete')

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

    # Mark dataset as volume
    utils.mark_as_volume(dataset)
Example #29
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)
Example #30
0
def transform_scalars(dataset, resampling_factor=[1, 1, 1]):
    """Resample dataset"""

    from tomviz import utils
    import scipy.ndimage

    array = utils.get_array(dataset)

    # Transform the dataset.
    result = scipy.ndimage.interpolation.zoom(array, resampling_factor)

    # 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)
            tilt_angles = scipy.ndimage.interpolation.zoom(
                tilt_angles, resampling_factor[2])
            utils.set_tilt_angles(dataset, tilt_angles)
        except:  # noqa
            # TODO What exception are we ignoring?
            pass
Example #31
0
def transform_scalars(dataset, rot_center=0, tune_rot_center=True):
    """Reconstruct sinograms using the tomopy gridrec algorithm

    Typically, a data exchange file would be loaded for this
    reconstruction. This operation will attempt to perform
    flat-field correction of the raw data using the dark and
    white background data found in the data exchange file.

    This operator also requires either the tomviz/tomopy-pipeline
    docker image, or a python environment with tomopy installed.
    """

    from tomviz import utils
    import numpy as np
    import tomopy

    # Get the current volume as a numpy array.
    array = utils.get_array(dataset)

    dark = dataset.dark
    white = dataset.white
    angles = utils.get_tilt_angles(dataset)
    tilt_axis = dataset.tilt_axis

    # TomoPy wants the tilt axis to be zero, so ensure that is true
    if tilt_axis == 2:
        order = [2, 1, 0]
        array = np.transpose(array, order)
        if dark is not None and white is not None:
            dark = np.transpose(dark, order)
            white = np.transpose(white, order)

    if angles is not None:
        # tomopy wants radians
        theta = np.radians(angles)
    else:
        # Assume it is equally spaced between 0 and 180 degrees
        theta = tomopy.angles(array.shape[0])

    # Perform flat-field correction of raw data
    if white is not None and dark is not None:
        array = tomopy.normalize(array, white, dark, cutoff=1.4)

    if rot_center == 0:
        # Try to find it automatically
        init = array.shape[2] / 2.0
        rot_center = tomopy.find_center(array,
                                        theta,
                                        init=init,
                                        ind=0,
                                        tol=0.5)
    elif tune_rot_center:
        # Tune the center
        rot_center = tomopy.find_center(array,
                                        theta,
                                        init=rot_center,
                                        ind=0,
                                        tol=0.5)

    # Calculate -log(array)
    array = tomopy.minus_log(array)

    # Remove nan, neg, and inf values
    array = tomopy.remove_nan(array, val=0.0)
    array = tomopy.remove_neg(array, val=0.00)
    array[np.where(array == np.inf)] = 0.00

    # Perform the reconstruction
    array = tomopy.recon(array, theta, center=rot_center, algorithm='gridrec')

    # Mask each reconstructed slice with a circle.
    array = tomopy.circ_mask(array, axis=0, ratio=0.95)

    # Set the transformed array
    child = utils.make_child_dataset(dataset)
    utils.mark_as_volume(child)
    utils.set_array(child, array)

    return_values = {}
    return_values['reconstruction'] = child
    return return_values
    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
Example #33
0
    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
        t0 = time.time()
        etcMessage = 'Estimated time to complete: n/a'

        counter = 1
        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) + etcMessage
                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

                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[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
Example #34
0
    def transform_scalars(self, dataset, Niter=1, Nupdates=0, beta=1.0):
        """
        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!")

        #Check if there's negative values, shift by minimum if true.
        if np.any(tiltSeries < 0):
            tiltSeries -= np.amin(tiltSeries)

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

        # 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.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
        beta = 1.0

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

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

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

        counter = 1
        for i in range(Niter):

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

                #Initialize slice as zeros on first iteration,
                #or vectorize the slice for the next iter.
                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))

                # Give 4 updates for first iteration.
                if Nupdates != 0 and i == 0 and (s + 1) % (Nslice // 4) == 0:
                    utils.set_array(child, recon)
                    self.progress.data = child

                step += 1
                self.progress.value = step

                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

        # 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
Example #35
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, 1) * 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

        t0 = time.time()
        counter = 1
        etcMessage = 'Estimated time to complete: n/a'

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

            #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):
                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
            timeLeft = (time.time() - t0) / counter * (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[:] = (y2 + y1) / 2
        recon[:] = np.fft.fftshift(recon)

        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
Example #36
0
    def transform_scalars(self,
                          dataset,
                          Niter=10,
                          stepSize=0.0001,
                          updateMethodIndex=0,
                          Nupdates=0):
        """
        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

        #Check if there's negative values, shift by minimum if true.
        if np.any(tiltSeries < 0):
            tiltSeries -= np.amin(tiltSeries)

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

        # Determine slice for live updates
        Nupdates = calc_Nupdates(Nupdates, Niter)

        # 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.zeros([Nslice, Nray, Nray], dtype=np.float32, order='F')

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

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

        t0 = time.time()
        counter = 1
        etcMessage = 'Estimated time to complete: n/a'

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

        for i in range(Niter):

            for s in range(Nslice):
                if self.canceled:
                    return

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

                b = tiltSeries[s, :, :].transpose().flatten()
                recon_slice = recon[s, :, :].flatten()
                recon[s, :, :] = r.recon2(b, recon_slice, stepSize, s).reshape(
                    (Nray, Nray))

                step += 1
                self.progress.value = step

                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)

                # Give 4 updates for first iteration.
                if Nupdates != 0 and i == 0 and (s + 1) % (Nslice // 4) == 0:
                    utils.set_array(child, recon)
                    self.progress.data = child

            #Positivity constraint.
            recon[recon < 0] = 0

            #Update at the end of each iteration.
            if Nupdates != 0 and (i + 1) % Nupdates == 0:
                utils.set_array(child, recon)
                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
Example #37
0
 def tilt_angles(self):
     return utils.get_tilt_angles(self._data_object)
Example #38
0
    def transform_scalars(self, dataset):
        """3D Reconstruct from a tilt series using Direct Fourier Method"""

        self.progress.maximum = 1

        # 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.empty_aligned(
            (Nx, Ny, Nz // 2 + 1), dtype='complex64', n=16)

        p = pyfftw.empty_aligned((Nx, Npad), dtype='float32', n=16)
        pF = pyfftw.empty_aligned(
            (Nx, Npad // 2 + 1), dtype='complex64', n=16)
        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.float32(np.fft.ifftshift(p))
            p_fftw_object.update_arrays(p, pF)
            p_fftw_object()
            p = None #Garbage collector (gc)

            if ang < 0:
                pF = np.conj(pF)
                pF[1:, :] = np.flipud(pF[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 * pF[:, 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)

        p = pF = None #gc

        self.progress.message = 'Inverse Fourier transform'
        v_temp = v.copy()
        recon = pyfftw.empty_aligned(
            (Nx, Ny, Nz), dtype='float32', order='F', n=16)
        recon_fftw_object = pyfftw.FFTW(
            v_temp, recon, direction='FFTW_BACKWARD', axes=(0, 1, 2))
        v[w != 0] = v[w != 0] / w[w != 0]
        recon_fftw_object.update_arrays(v, recon)
        v = v_temp = []    #gc
        recon_fftw_object()
        recon[:] = np.fft.fftshift(recon)

        step += 1
        self.progress.value = step

        self.progress.message = 'Passing data to Tomviz'
        from vtkmodules.vtkCommonDataModel import vtkImageData
        recon_dataset = vtkImageData()
        recon_dataset.CopyStructure(dataset)
        utils.set_array(recon_dataset, recon)
        utils.mark_as_volume(recon_dataset)

        recon = None #gc

        returnValues = {}
        returnValues["reconstruction"] = recon_dataset
        return returnValues
Example #39
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

        t0 = time.time()
        counter = 1
        etcMessage = 'Estimated time to complete: n/a'

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

            b = tiltSeries[s, :, :].transpose().flatten()
            recon[s, :, :] = r.recon2(b, Niter, stepSize).reshape((Nray, Nray))

            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)

        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
Example #40
0
    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.zeros((Nslice, Nray, Nray))

        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

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

        # Mark dataset as volume
        utils.mark_as_volume(dataset)
Example #41
0
    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
Example #42
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
Example #43
0
    def transform_scalars(self, dataset, Nrecon=None, filter=None,
                          interp=None, Nupdates=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=np.float32, 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 Nupdates != 0 and (i + 1) % (Nslice//Nupdates) == 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
Example #44
0
    def transform_scalars(self, dataset):
        """3D Reconstruct from a tilt series using Direct Fourier Method"""

        self.progress.maximum = 1

        # 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.empty_aligned(
            (Nx, Ny, Nz // 2 + 1), dtype='complex64', n=16)

        p = pyfftw.empty_aligned((Nx, Npad), dtype='float32', n=16)
        pF = pyfftw.empty_aligned(
            (Nx, Npad // 2 + 1), dtype='complex64', n=16)
        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.float32(np.fft.ifftshift(p))
            p_fftw_object.update_arrays(p, pF)
            p_fftw_object()
            p = None #Garbage collector (gc)

            if ang < 0:
                pF = np.conj(pF)
                pF[1:, :] = np.flipud(pF[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 < np.floor( Nz / 2 + 1 )):
                        w[:, py, pz] = w[:, py, pz] + weight
                        v[:, py, pz] = v[:, py, pz] + \
                            weight * pF[:, 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)

        p = pF = None #gc

        self.progress.message = 'Inverse Fourier transform'
        v_temp = v.copy()
        recon = pyfftw.empty_aligned(
            (Nx, Ny, Nz), dtype='float32', order='F', n=16)
        recon_fftw_object = pyfftw.FFTW(
            v_temp, recon, direction='FFTW_BACKWARD', axes=(0, 1, 2))
        v[w != 0] = v[w != 0] / w[w != 0]
        recon_fftw_object.update_arrays(v, recon)
        v = v_temp = []    #gc
        recon_fftw_object()
        recon[:] = np.fft.fftshift(recon)

        step += 1
        self.progress.value = step

        self.progress.message = 'Passing data to Tomviz'
        from vtkmodules.vtkCommonDataModel import vtkImageData
        recon_dataset = vtkImageData()
        recon_dataset.CopyStructure(dataset)
        utils.set_array(recon_dataset, recon)
        utils.mark_as_volume(recon_dataset)

        recon = None #gc

        returnValues = {}
        returnValues["reconstruction"] = recon_dataset
        return returnValues
Example #45
0
    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
        t0 = time.time()
        etcMessage = 'Estimated time to complete: n/a'

        counter = 1
        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) + etcMessage
                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

                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[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
Example #46
0
    def transform_scalars(self, dataset, Niter=10, stepSize=0.0001,
                          updateMethodIndex=0, Nupdates=0):
        """
        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

        #Check if there's negative values, shift by minimum if true.
        if np.any(tiltSeries < 0):
            tiltSeries -= np.amin(tiltSeries)

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

        # Determine slice for live updates
        Nupdates = calc_Nupdates(Nupdates, Niter)

        # 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.zeros([Nslice, Nray, Nray], dtype=np.float32, order='F')

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

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

        t0 = time.time()
        counter = 1
        etcMessage = 'Estimated time to complete: n/a'

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

        for i in range(Niter):

            for s in range(Nslice):
                if self.canceled:
                    return

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

                b = tiltSeries[s, :, :].transpose().flatten()
                recon_slice = recon[s, :, :].flatten()
                recon[s, :, :] = r.recon2(b, recon_slice, stepSize,
                                          s).reshape((Nray, Nray))

                step += 1
                self.progress.value = step

                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)

                # Give 4 updates for first iteration.
                if Nupdates != 0 and i == 0 and (s + 1) % (Nslice//4) == 0:
                    utils.set_array(child, recon)
                    self.progress.data = child

            #Positivity constraint.
            recon[recon < 0] = 0

            #Update at the end of each iteration.
            if Nupdates != 0 and (i + 1) % Nupdates == 0:
                utils.set_array(child, recon)
                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
Example #47
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, 1) * 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

        t0 = time.time()
        counter = 1
        etcMessage = 'Estimated time to complete: n/a'

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

            #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):
                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
            timeLeft = (time.time() - t0) / counter * (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[:] = (y2 + y1) / 2
        recon[:] = np.fft.fftshift(recon)

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

        # Mark dataset as volume
        utils.mark_as_volume(dataset)
Example #48
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!")

        Npad = np.size(tiltSeries, 0) * 2

        tiltSeries = np.double(tiltSeries)
        (Nx, Ny, Nproj) = tiltSeries.shape
        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')
        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

        for a in range(Nproj):
            if self.canceled:
                return
            self.progress.message = 'Tilt image No.%d/%d' % (a + 1, Nproj)

            #print angles[a]
            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

        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
    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.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

        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
        t0 = time.time()
        counter = 1

        etcMessage = 'Estimated time to complete: n/a'
        for i in range(Niter):  #main loop
            if self.canceled:
                return
            self.progress.message = 'Iteration No.%d/%d. ' % (
                i + 1, Niter) + etcMessage
            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

            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)

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

        # Mark dataset as volume
        utils.mark_as_volume(dataset)
Example #50
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.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

        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
        t0 = time.time()
        counter = 1

        etcMessage = 'Estimated time to complete: n/a'
        for i in range(Niter): #main loop
            if self.canceled:
                return
            self.progress.message = 'Iteration No.%d/%d. ' % (
                i + 1, Niter) + etcMessage
            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

            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)

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

        # Mark dataset as volume
        utils.mark_as_volume(dataset)