Example #1
0
    def __init__(self, data_obj, data_struct=True, **kwargs):
        # %% Store the input in the object
        # BE F*****G CONSISTENT WITH RENAMING ETC.
        self.pix = data_obj.voxels[0]
        self.angles = data_obj.angles
        self.src_rad = data_obj.src_rad
        self.det_rad = data_obj.det_rad
        self.magn = self.src_rad / (self.src_rad + self.det_rad)
        self.data_struct = data_struct
        self.rec_methods = []

        # %% Set up the geometry
        self.phantom = data_obj
        # Make the reconstruction space
        self.reco_space = self.phantom.reco_space
        voxels = self.phantom.voxels
        factor = 2
        dpix = [int(factor * voxels[0]), voxels[1]]
        self.w_detu = (2 * self.phantom.detecsize[0]) / dpix[0]
        self.w_detv = (2 * self.phantom.detecsize[1]) / dpix[1]
        if self.phantom.data_type == 'simulated':
            self.PH = data_obj.PH
            self.noise = data_obj.noise
            # Do we need a mask?
            src_radius = self.src_rad * self.phantom.volumesize[0] * 2
            det_radius = self.det_rad * self.phantom.volumesize[0] * 2
            # Make a circular scanning geometry
            angle_partition = odl.uniform_partition(0, 2 * np.pi, self.angles)
            self.angle_space = odl.uniform_discr_frompartition(angle_partition)
            # Make a flat detector space
            det_partition = odl.uniform_partition(-self.phantom.detecsize,
                                                  self.phantom.detecsize, dpix)
            self.det_space = odl.uniform_discr_frompartition(det_partition,
                                                             dtype='float32')
            # Create geometry
            self.geometry = odl.tomo.ConeFlatGeometry(angle_partition,
                                                      det_partition,
                                                      src_radius=src_radius,
                                                      det_radius=det_radius,
                                                      axis=[0, 0, 1])
        else:
            src_radius = self.phantom.src_rad
            det_radius = self.phantom.det_rad
            self.pix_size = self.phantom.pix_size
            self.angle_space = self.phantom.angle_space
            self.angles = np.size(self.angle_space)
            self.det_space = self.phantom.det_space
            self.geometry = self.phantom.geometry

        # %% Create the FP and BP and the data
        # Forward Projection
        self.FwP = odl.tomo.RayTransform(self.reco_space,
                                         self.geometry,
                                         use_cache=False)
        self.rs_detu = int(2**(np.ceil(np.log2(dpix[0])) + 1))
        self.g = self.phantom.g
Example #2
0
def test_astra_cpu_projector_fanflat():
    """ASTRA CPU forward and back projection for fanflat geometry."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5], [4, 5], (4, 5), dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0], max_pt=[4, 5])

    # Create fan beam geometry with flat detector
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition(-6, 6, 6)
    src_rad = 100
    det_rad = 10
    geom = odl.tomo.FanFlatGeometry(angle_part, det_part, src_rad, det_rad)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cpu_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cpu_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Example #3
0
def test_astra_cpu_projector_parallel2d():
    """ASTRA CPU forward and back projection for 2d parallel geometry."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5], [4, 5], (4, 5), dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0], max_pt=[4, 5])

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition(-6, 6, 6)
    geom = odl.tomo.Parallel2dGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cpu_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cpu_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Example #4
0
def test_scikit_radon_projector_parallel2d():
    """Parallel 2D forward and backward projectors on the GPU."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-5, -5], [5, 5], (5, 5), dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, begin=[0, 0], end=[5, 5])

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition(-6, 6, 6)
    geom = odl.tomo.Parallel2dGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = scikit_radon_forward(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = scikit_radon_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Example #5
0
def test_astra_cuda_projector_parallel3d():
    """Test 3D forward and backward projection functions on the GPU."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5, -6], [4, 5, 6], (4, 5, 6),
                                   dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, begin=[0, 0, 0], end=[4, 5, 6])

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition([-7, -8], [7, 8], (7, 8))
    geom = odl.tomo.Parallel3dAxisGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cuda_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cuda_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Example #6
0
def test_astra_cuda_projector(space_and_geometry, use_cache):
    """Test ASTRA CUDA projector."""

    # Create reco space and a phantom
    reco_space, geom = space_and_geometry
    phantom = odl.phantom.cuboid(reco_space)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype=reco_space.dtype)

    # Forward evaluation
    projector = AstraCudaProjectorImpl(geom, reco_space, proj_space,
                                       use_cache=use_cache)
    proj_data = projector.call_forward(phantom)
    assert proj_data in proj_space
    assert proj_data.norm() > 0
    assert np.all(proj_data.asarray() >= 0)

    # Backward evaluation
    back_projector = AstraCudaBackProjectorImpl(geom, reco_space, proj_space,
                                                use_cache=use_cache)
    backproj = back_projector.call_backward(proj_data)
    assert backproj in reco_space
    assert backproj.norm() > 0
    assert np.all(proj_data.asarray() >= 0)
Example #7
0
def test_scikit_radon_projector_parallel2d():
    """Parallel 2D forward and backward projectors on the GPU."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-5, -5], [5, 5], (5, 5), dtype='float32')
    phantom = odl.util.phantom.cuboid(reco_space, begin=0.5, end=1)

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition(-6, 6, 6)
    geom = odl.tomo.Parallel2dGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = scikit_radon_forward(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = scikit_radon_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Example #8
0
def test_astra_cuda_projector_parallel3d():
    """Test 3D forward and backward projection functions on the GPU."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5, -6], [4, 5, 6], (4, 5, 6),
                                   dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0, 0],
                                 max_pt=[4, 5, 6])

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, np.pi, 8)
    det_part = odl.uniform_partition([-7, -8], [7, 8], (7, 8))
    geom = odl.tomo.Parallel3dAxisGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cuda_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cuda_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Example #9
0
def test_astra_cuda_projector_helical_conebeam():
    """Test 3D forward and backward projection functions on the GPU."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5, -6], [4, 5, 6], (4, 5, 6),
                                   dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0, 0],
                                 max_pt=[4, 5, 6])

    # Create circular cone beam geometry with flat detector
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition([-7, -8], [7, 8], (7, 8))
    src_rad = 1000
    det_rad = 100
    pitch = 0.5
    geom = odl.tomo.HelicalConeFlatGeometry(angle_part, det_part, src_rad,
                                            det_rad, pitch)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cuda_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cuda_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Example #10
0
def test_astra_cuda_projector(space_and_geometry, use_cache):
    """Test ASTRA CUDA projector."""

    # Create reco space and a phantom
    reco_space, geom = space_and_geometry
    phantom = odl.phantom.cuboid(reco_space)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype=reco_space.dtype)

    # Forward evaluation
    projector = AstraCudaProjectorImpl(geom,
                                       reco_space,
                                       proj_space,
                                       use_cache=use_cache)
    proj_data = projector.call_forward(phantom)
    assert proj_data in proj_space
    assert proj_data.norm() > 0
    assert np.all(proj_data.asarray() >= 0)

    # Backward evaluation
    back_projector = AstraCudaBackProjectorImpl(geom,
                                                reco_space,
                                                proj_space,
                                                use_cache=use_cache)
    backproj = back_projector.call_backward(proj_data)
    assert backproj in reco_space
    assert backproj.norm() > 0
    assert np.all(proj_data.asarray() >= 0)
Example #11
0
def test_astra_cpu_projector_parallel2d():
    """ASTRA CPU forward and back projection for 2d parallel geometry."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5], [4, 5], (4, 5), dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, begin=[0, 0], end=[4, 5])

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition(-6, 6, 6)
    geom = odl.tomo.Parallel2dGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cpu_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cpu_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Example #12
0
def test_astra_cpu_projector_fanflat():
    """ASTRA CPU forward and back projection for fanflat geometry."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5], [4, 5], (4, 5), dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, begin=[0, 0], end=[4, 5])

    # Create fan beam geometry with flat detector
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition(-6, 6, 6)
    src_rad = 100
    det_rad = 10
    geom = odl.tomo.FanFlatGeometry(angle_part, det_part, src_rad, det_rad)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cpu_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cpu_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Example #13
0
def test_astra_cuda_projector_helical_conebeam():
    """Test 3D forward and backward projection functions on the GPU."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-4, -5, -6], [4, 5, 6], (4, 5, 6),
                                   dtype='float32')
    phantom = odl.phantom.cuboid(reco_space, begin=[0, 0, 0], end=[4, 5, 6])

    # Create circular cone beam geometry with flat detector
    angle_part = odl.uniform_partition(0, 2 * np.pi, 8)
    det_part = odl.uniform_partition([-7, -8], [7, 8], (7, 8))
    src_rad = 1000
    det_rad = 100
    pitch = 0.5
    geom = odl.tomo.HelicalConeFlatGeometry(angle_part, det_part, src_rad,
                                            det_rad, pitch)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype='float32')

    # Forward evaluation
    proj_data = astra_cuda_forward_projector(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = astra_cuda_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Example #14
0
def test_astra_cuda_projector(space_and_geometry):
    """Test ASTRA CUDA projector."""

    # Create reco space and a phantom
    vol_space, geom = space_and_geometry
    phantom = odl.phantom.cuboid(vol_space)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition,
                                                 dtype=vol_space.dtype)

    # create RayTransform implementation
    astra_cuda = AstraCudaImpl(geom, vol_space, proj_space)

    # Forward evaluation
    proj_data = astra_cuda.call_forward(phantom)
    assert proj_data in proj_space
    assert proj_data.norm() > 0
    assert np.all(proj_data.asarray() >= 0)

    # Backward evaluation
    backproj = astra_cuda.call_backward(proj_data)
    assert backproj in vol_space
    assert backproj.norm() > 0
    assert np.all(proj_data.asarray() >= 0)
Example #15
0
def fan_to_fan_flat(geometry, data):
    tmp_space = odl.uniform_discr_frompartition(geometry.partition,
                                                interp='linear')
    rot_angles = tmp_space.meshgrid[0]
    fan_angles = tmp_space.meshgrid[1]
    data = tmp_space.element(data)

    source_to_detector = geometry.src_radius + geometry.det_radius

    fan_dist = source_to_detector * np.arctan(fan_angles / source_to_detector)
    data = data.interpolation((rot_angles, fan_dist), bounds_check=False)
    data = data[::-1]
    return data
Example #16
0
def ExpOp_builder(bin_param, filter_space, interp):
    # Create binning scheme
    if interp == 'Full':
        spf_space = filter_space
        Exp_op = odl.IdentityOperator(filter_space)
    elif interp == 'uniform':
        # Create binning scheme
        dpix = np.size(filter_space)
        dsize = filter_space.max_pt
        filt_bin_space = odl.uniform_discr(-dsize, dsize, dpix // (bin_param))
        spf_space = odl.uniform_discr(0, dsize, dpix // (2 * bin_param))
        resamp = odl.Resampling(filt_bin_space, filter_space)
        sym = SymOp(spf_space, filt_bin_space)
        Exp_op = resamp * sym
    else:
        if interp == 'constant':
            interp = 'nearest'
        elif interp == 'linear':
            pass
        else:
            raise ValueError('unknown `expansion operator type` ({})'
                             ''.format(interp))
        B = ExpBin(bin_param, np.size(filter_space)) * \
                        filter_space.weighting.const
        B[-1] -= 1 / 2 * filter_space.weighting.const

        # Create sparse filter space
        spf_part = odl.nonuniform_partition(B, min_pt=0, max_pt=B[-1])
        spf_weight = np.ravel(
            np.multiply.reduce(np.meshgrid(*spf_part.cell_sizes_vecs)))
        spf_fspace = odl.FunctionSpace(spf_part.set)
        spf_space = odl.DiscreteLp(spf_fspace,
                                   spf_part,
                                   odl.rn(spf_part.size, weighting=spf_weight),
                                   interp=interp)
        filt_pos_part = odl.uniform_partition(0, B[-1],
                                              int(np.size(filter_space) / 2))

        filt_pos_space = odl.uniform_discr_frompartition(filt_pos_part,
                                                         dtype='float64')
        lin_interp = odl.Resampling(spf_space, filt_pos_space)

        # Create symmetry operator
        sym = SymOp(filt_pos_space, filter_space)

        # Create sparse filter operator
        Exp_op = sym * lin_interp
    return spf_space, Exp_op
Example #17
0
def test_scikit_radon_projector_parallel2d():
    """Parallel 2D forward and backward projectors with scikit."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-5, -5], [5, 5], (5, 5))
    phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0], max_pt=[5, 5])

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, np.pi, 5)
    det_part = odl.uniform_partition(-6, 6, 6)
    geom = odl.tomo.Parallel2dGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition)

    # Forward evaluation
    proj_data = scikit_radon_forward(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = scikit_radon_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Example #18
0
def test_skimage_radon_projector_parallel2d():
    """Parallel 2D forward and backward projectors with skimage."""

    # Create reco space and a phantom
    reco_space = odl.uniform_discr([-5, -5], [5, 5], (5, 5))
    phantom = odl.phantom.cuboid(reco_space, min_pt=[0, 0], max_pt=[5, 5])

    # Create parallel geometry
    angle_part = odl.uniform_partition(0, np.pi, 5)
    det_part = odl.uniform_partition(-6, 6, 6)
    geom = odl.tomo.Parallel2dGeometry(angle_part, det_part)

    # Make projection space
    proj_space = odl.uniform_discr_frompartition(geom.partition)

    # Forward evaluation
    proj_data = skimage_radon_forward(phantom, geom, proj_space)
    assert proj_data.shape == proj_space.shape
    assert proj_data.norm() > 0

    # Backward evaluation
    backproj = skimage_radon_back_projector(proj_data, geom, reco_space)
    assert backproj.shape == reco_space.shape
    assert backproj.norm() > 0
Example #19
0
    def __init__(self, dataset, pix_size, src_rad, det_rad, ang_freq,
                 vox=None, vecs=None, zoom=False, offset=0):
        self.data_type = 'real'
        # %% load data
        self.vecs = vecs
        self.ang_freq = ang_freq
        self.dataset = dataset
        self.offset = offset
        if type(dataset) == dict:
            g_vec = np.load(dataset['g'])
            # %% adapt data
            self.angles_in = np.shape(g_vec)[0]
            g_vec = g_vec[::ang_freq, :, :]
            rs_detu = np.min(np.shape(g_vec)[1:]) * 2
            diff = int((rs_detu - np.size(g_vec, 1)) / 2)
            g_vec = np.concatenate((np.zeros((
                    np.size(g_vec, 0), diff, np.size(g_vec, 2))), g_vec,
                    np.zeros((np.size(g_vec, 0), diff, np.size(g_vec, 2)))), 1)
        else:
            g_vec = dataset
        
        # Define the dimensions of the problem in cm
        self.pix_size = pix_size
        self.angles = g_vec.shape[0]
        self.src_rad = src_rad
        self.det_rad = det_rad
        if zoom:
            self.magn = 1 
        else:
            self.magn = self.src_rad / (self.src_rad + self.det_rad)
        
        self.dpix = [np.size(g_vec, 1), np.size(g_vec, 2)]
        u_size = self.dpix[0] * pix_size / 2
        v_size = self.dpix[1] * pix_size / 2
        self.detecsize = np.array([u_size, v_size])
        
        if vox is None:
            self.voxels = [self.dpix[1], self.dpix[1], self.dpix[1]]

            self.volumesize = np.array([self.detecsize[1] * self.magn,
                                        self.detecsize[1] * self.magn,
                                        self.detecsize[1] * self.magn],
                                        dtype='float32')
        else:
            self.voxels = [vox, vox, vox]
            volsize = vox * self.pix_size * self.magn / 2
            self.volumesize = np.array([volsize, volsize, volsize], 
                                       dtype='float32')
        # %%
        # Make the reconstruction space
        self.reco_space = odl.uniform_discr(min_pt=-self.volumesize,
                                            max_pt=self.volumesize,
                                            shape=self.voxels,
                                            dtype='float32')
        if 'ground_truth' in dataset:
            self.f = self.reco_space.element(np.load(dataset['ground_truth']))
            self.mask_name = dataset['mask']

        # Make a circular scanning geometry
        angle_partition = odl.uniform_partition(offset, 2 * np.pi + offset,
                                                self.angles)

        # Make a flat detector space
        det_partition = odl.uniform_partition(-self.detecsize,
                                              self.detecsize,
                                                   self.dpix)
        self.det_space = odl.uniform_discr_frompartition(det_partition,
                                                         dtype='float32')
        # Create geometry
        self.geometry = odl.tomo.ConeFlatGeometry(
                angle_partition, det_partition, src_radius=self.src_rad,
                                det_radius=self.det_rad, axis=[0, 0, 1])
        
        self.angle_space = odl.uniform_discr_frompartition(
                self.geometry.motion_partition)
        # Forward Projection
        self.FwP = odl.tomo.RayTransform(self.reco_space, self.geometry,
                                         use_cache=False)

        # Backward Projection
        self.BwP = odl.tomo.RayBackProjection(self.reco_space,
                                              self.geometry,
                                              use_cache=False)
        if self.vecs is None:
            self.g = self.BwP.domain.element(g_vec)
        else:
            self.g = g_vec
            self.geometry = vecs
        
        gc.collect()
Example #20
0
    def __init__(self, data_obj, data_struct=True, **kwargs):
        # %% Store the input in the object
        # BE F*****G CONSISTENT WITH RENAMING ETC.
        self.pix = data_obj.voxels[0]
        self.angles = data_obj.angles
        self.src_rad = data_obj.src_rad
        self.det_rad = data_obj.det_rad
        self.magn = self.src_rad / (self.src_rad + self.det_rad)
        self.data_struct = data_struct
        self.rec_methods = []
        if hasattr(data_obj, 'offset'):
            self.offset = data_obj.offset
        # %% If we need a data structure, make one:
        self.WV_obj = sup.working_var_map()
        self.WV_path = self.WV_obj.WV_path

        # %% Set up the geometry
        self.phantom = data_obj
        self.g = self.phantom.g
        # Make the reconstruction space
        self.reco_space = self.phantom.reco_space
        voxels = self.phantom.voxels
        dpix = [np.shape(self.g)[1], np.shape(self.g)[2]]
        self.w_detu = (2 * self.phantom.detecsize[0]) / dpix[0]
        self.w_detv = (2 * self.phantom.detecsize[1]) / dpix[1]
        if self.phantom.data_type == 'simulated':
            self.PH = data_obj.PH
            self.noise = data_obj.noise
            # Do we need a mask?
            if data_struct:
                self.phantom.make_mask(self.WV_path)
            else:
                pass
            src_radius = self.src_rad * self.phantom.volumesize[0] * 2
            det_radius = self.det_rad * self.phantom.volumesize[0] * 2
            # Make a circular scanning geometry
            angle_partition = odl.uniform_partition(0, 2 * np.pi, self.angles)
            self.angle_space = odl.uniform_discr_frompartition(angle_partition)
            # Make a flat detector space
            det_partition = odl.uniform_partition(-self.phantom.detecsize,
                                                  self.phantom.detecsize, dpix)
            self.det_space = odl.uniform_discr_frompartition(det_partition,
                                                             dtype='float32')
            # Create geometry
            self.geometry = odl.tomo.ConeFlatGeometry(angle_partition,
                                                      det_partition,
                                                      src_radius=src_radius,
                                                      det_radius=det_radius,
                                                      axis=[0, 0, 1])
        else:
            src_radius = self.phantom.src_rad
            det_radius = self.phantom.det_rad
            self.pix_size = self.phantom.pix_size
            self.angle_space = self.phantom.angle_space
            self.angles = np.size(self.angle_space)
            self.det_space = self.phantom.det_space
            self.geometry = self.phantom.geometry
        # Create filter space, same size as the detector, because stability
        filter_part = odl.uniform_partition(-self.phantom.detecsize[0],
                                            self.phantom.detecsize[0], dpix[0])
        #        filter_part = odl.uniform_partition(-2 * self.phantom.detecsize[0],
        #                                            2 * self.phantom.detecsize[0],
        #                                                 2 * dpix[0])

        self.filter_space = odl.uniform_discr_frompartition(filter_part,
                                                            dtype='float64')
        # %% Create the FP and BP
        # Create fourier filter space
        self.rs_detu = int(2**(np.ceil(np.log2(self.filter_space.size)) + 1))
        # set =filter.size if filter is twice the detector
        self.frs_detu = self.rs_detu // 2 + 1
        fourier_filter_part = odl.uniform_partition(0, np.pi, (self.frs_detu))
        self.fourier_filter_space = odl.uniform_discr_frompartition(
            fourier_filter_part, dtype='complex64')

        if self.phantom.vecs is None:
            # Forward Projection
            self.FwP = odl.tomo.RayTransform(self.reco_space,
                                             self.geometry,
                                             use_cache=False)

            # Backward Projection
            self.BwP = odl.tomo.RayBackProjection(self.reco_space,
                                                  self.geometry,
                                                  use_cache=False)

            # %% Create the operators for the FDK framework

            # Create the FDK weighting for the data
            w_FDK = sup.FDK_weighting(dpix, self.det_space, self.w_detu,
                                      self.w_detv, src_radius)

            # Scale the data according to the FDK weighting
            self.g_scl = np.asarray(self.g.copy())
            for a in range(self.angles):
                self.g_scl[a, :, :] *= w_FDK

            self.conv_op = sup.ConvolutionOp(self.filter_space, self.FwP.range,
                                             self.det_space, self.w_detv,
                                             self.g_scl,
                                             self.angle_space.weighting.const)

            # Create FDK operator which takes filter
            self.FDK_op = self.BwP * self.conv_op
Example #21
0
def Create_dataset_ASTRA_real(dataset,
                              pix_size,
                              src_rad,
                              det_rad,
                              ang_freq,
                              Exp_bin,
                              bin_param,
                              vox=None,
                              vecs=None):

    # ! ! ! We overide 'vox' and 'vecs' later on
    # The size of the measured objects in voxels
    data_obj = ddf.real_data(dataset,
                             pix_size,
                             src_rad,
                             det_rad,
                             ang_freq,
                             vox=vox,
                             vecs=vecs)
    g = np.ascontiguousarray(np.transpose(np.asarray(data_obj.g.copy()),
                                          (2, 0, 1)),
                             dtype=np.float32)
    v, ang, u = g.shape
    if vox is None:
        voxels = data_obj.voxels

    else:
        voxels = [vox, vox, vox]

    MaxVoxDataset = np.max([int(voxels[0]**3 * 0.005), 5 * 10**6])

    Smat = Make_Smat(voxels, MaxVoxDataset, '', real_data=dataset['mask'])

    # %% Create geometry
    geom = data_obj.geometry
    w_du = data_obj.pix_size
    dpix = [u, v]

    minvox = data_obj.reco_space.min_pt[0]
    maxvox = data_obj.reco_space.max_pt[0]
    vox = np.shape(data_obj.reco_space)[0]
    vol_geom = astra.create_vol_geom(vox, vox, vox, minvox, maxvox, minvox,
                                     maxvox, minvox, maxvox)

    # Build a vecs vector from the geometry, or load it
    if type(geom) == np.ndarray:
        vecs = geom
        proj_geom = astra.create_proj_geom('cone_vec', v, u, vecs)
    elif type(geom) == odl.tomo.geometry.conebeam.ConeFlatGeometry:
        angles = np.linspace((1 / ang) * np.pi, (2 + 1 / ang) * np.pi, ang,
                             False)
        w_du, w_dv = 2 * data_obj.geometry.detector.partition.max_pt / [u, v]
        proj_geom = astra.create_proj_geom('cone', w_dv, w_du, v, u, angles,
                                           data_obj.geometry.src_radius,
                                           data_obj.geometry.det_radius)

    filter_part = odl.uniform_partition(-data_obj.detecsize[0],
                                        data_obj.detecsize[0], dpix[0])

    filter_space = odl.uniform_discr_frompartition(filter_part,
                                                   dtype='float64')
    spf_space, Exp_op = ddf.ExpOp_builder(bin_param,
                                          filter_space,
                                          interp=Exp_bin)

    nParam = np.size(spf_space)

    fullFilterSize = int(2**(np.ceil(np.log2(dpix[0])) + 1))
    halfFilterSize = fullFilterSize // 2 + 1

    Resize_Op = odl.ResizingOperator(Exp_op.range, ran_shp=(fullFilterSize, ))
    # %% Create projection and reconstion objects
    proj_id = astra.data3d.link('-proj3d', proj_geom, g)

    rec = np.zeros(astra.geom_size(vol_geom), dtype=np.float32)
    rec_id = astra.data3d.link('-vol', vol_geom, rec)

    B = np.zeros((MaxVoxDataset, nParam + 1))

    # %% Make the matrix columns of the matrix B
    for nP in range(nParam):
        unit_vec = spf_space.zero()
        unit_vec[nP] = 1
        filt = Exp_op(unit_vec)

        rs_filt = Resize_Op(filt)

        f_filt = np.real(np.fft.rfft(np.fft.ifftshift(rs_filt)))
        filter2d = np.zeros((ang, halfFilterSize))
        for i in range(ang):
            filter2d[i, :] = f_filt * 4 * w_du

        # %% Make a filter geometry
        filter_geom = astra.create_proj_geom('parallel', w_du, halfFilterSize,
                                             np.zeros(ang))
        filter_id = astra.data2d.create('-sino', filter_geom, filter2d)
        #

        cfg = astra.astra_dict('FDK_CUDA')
        cfg['ReconstructionDataId'] = rec_id
        cfg['ProjectionDataId'] = proj_id
        cfg['option'] = {'FilterSinogramId': filter_id}
        # Create the algorithm object from the configuration structure
        alg_id = astra.algorithm.create(cfg)

        # %%
        astra.algorithm.run(alg_id)
        rec = np.transpose(rec, (2, 1, 0))
        B[:, nP] = rec[Smat]
    # %%
    # Clean up. Note that GPU memory is tied up in the algorithm object,
    # and main RAM in the data objects.
    B[:, -1] = data_obj.f[Smat]
    astra.algorithm.delete(alg_id)
    astra.data3d.delete(rec_id)
    astra.data3d.delete(proj_id)
    return B
Example #22
0
def test_fourier_trafo_completely():
    # Complete explicit test of all FT components on two small examples

    # Discretization with 4 points
    discr = odl.uniform_discr(-2, 2, 4, dtype="complex")
    # Interval boundaries -2, -1, 0, 1, 2
    assert np.allclose(discr.partition.cell_boundary_vecs[0], [-2, -1, 0, 1, 2])
    # Grid points -1.5, -0.5, 0.5, 1.5
    assert np.allclose(discr.grid.coord_vectors[0], [-1.5, -0.5, 0.5, 1.5])

    # First test function, symmetric. Can be represented exactly in the
    # discretization.
    def f(x):
        return (x >= -1) & (x <= 1)

    def fhat(x):
        return np.sqrt(2 / np.pi) * sinc(x)

    # Discretize f, check values
    f_discr = discr.element(f)
    assert np.allclose(f_discr, [0, 1, 1, 0])

    # "s" = shifted, "n" = not shifted

    # Reciprocal grids
    recip_s = reciprocal_grid(discr.grid, shift=True)
    recip_n = reciprocal_grid(discr.grid, shift=False)
    assert np.allclose(recip_s.coord_vectors[0], np.linspace(-np.pi, np.pi / 2, 4))
    assert np.allclose(recip_n.coord_vectors[0], np.linspace(-3 * np.pi / 4, 3 * np.pi / 4, 4))

    # Range
    range_part_s = odl.uniform_partition_fromgrid(recip_s)
    range_s = odl.uniform_discr_frompartition(range_part_s, dtype="complex")
    range_part_n = odl.uniform_partition_fromgrid(recip_n)
    range_n = odl.uniform_discr_frompartition(range_part_n, dtype="complex")

    # Pre-processing
    preproc_s = [1, -1, 1, -1]
    preproc_n = [np.exp(1j * 3 / 4 * np.pi * k) for k in range(4)]

    fpre_s = dft_preprocess_data(f_discr, shift=True)
    fpre_n = dft_preprocess_data(f_discr, shift=False)
    assert np.allclose(fpre_s, f_discr * discr.element(preproc_s))
    assert np.allclose(fpre_n, f_discr * discr.element(preproc_n))

    # FFT step, replicating the _call_numpy method
    fft_s = np.fft.fftn(fpre_s, s=discr.shape, axes=[0])
    fft_n = np.fft.fftn(fpre_n, s=discr.shape, axes=[0])
    assert np.allclose(fft_s, [0, -1 + 1j, 2, -1 - 1j])
    assert np.allclose(
        fft_n, [np.exp(1j * np.pi * (3 - 2 * k) / 4) + np.exp(1j * np.pi * (3 - 2 * k) / 2) for k in range(4)]
    )

    # Interpolation kernel FT
    interp_s = np.sinc(np.linspace(-1 / 2, 1 / 4, 4)) / np.sqrt(2 * np.pi)
    interp_n = np.sinc(np.linspace(-3 / 8, 3 / 8, 4)) / np.sqrt(2 * np.pi)
    assert np.allclose(interp_s, _interp_kernel_ft(np.linspace(-1 / 2, 1 / 4, 4), interp="nearest"))
    assert np.allclose(interp_n, _interp_kernel_ft(np.linspace(-3 / 8, 3 / 8, 4), interp="nearest"))

    # Post-processing
    postproc_s = np.exp(1j * np.pi * np.linspace(-3 / 2, 3 / 4, 4))
    postproc_n = np.exp(1j * np.pi * np.linspace(-9 / 8, 9 / 8, 4))

    fpost_s = dft_postprocess_data(
        range_s.element(fft_s), real_grid=discr.grid, recip_grid=recip_s, shift=[True], axes=(0,), interp="nearest"
    )
    fpost_n = dft_postprocess_data(
        range_n.element(fft_n), real_grid=discr.grid, recip_grid=recip_n, shift=[False], axes=(0,), interp="nearest"
    )

    assert np.allclose(fpost_s, fft_s * postproc_s * interp_s)
    assert np.allclose(fpost_n, fft_n * postproc_n * interp_n)

    # Comparing to the known result sqrt(2/pi) * sinc(x)
    assert np.allclose(fpost_s, fhat(recip_s.coord_vectors[0]))
    assert np.allclose(fpost_n, fhat(recip_n.coord_vectors[0]))

    # Doing the exact same with direct application of the FT operator
    ft_op_s = FourierTransform(discr, shift=True)
    ft_op_n = FourierTransform(discr, shift=False)
    assert ft_op_s.range.grid == recip_s
    assert ft_op_n.range.grid == recip_n

    ft_f_s = ft_op_s(f)
    ft_f_n = ft_op_n(f)
    assert np.allclose(ft_f_s, fhat(recip_s.coord_vectors[0]))
    assert np.allclose(ft_f_n, fhat(recip_n.coord_vectors[0]))

    # Second test function, asymmetric. Can also be represented exactly in the
    # discretization.
    def f(x):
        return (x >= 0) & (x <= 1)

    def fhat(x):
        return np.exp(-1j * x / 2) * sinc(x / 2) / np.sqrt(2 * np.pi)

    # Discretize f, check values
    f_discr = discr.element(f)
    assert np.allclose(f_discr, [0, 0, 1, 0])

    # Pre-processing
    fpre_s = dft_preprocess_data(f_discr, shift=True)
    fpre_n = dft_preprocess_data(f_discr, shift=False)
    assert np.allclose(fpre_s, [0, 0, 1, 0])
    assert np.allclose(fpre_n, [0, 0, -1j, 0])

    # FFT step
    fft_s = np.fft.fftn(fpre_s, s=discr.shape, axes=[0])
    fft_n = np.fft.fftn(fpre_n, s=discr.shape, axes=[0])
    assert np.allclose(fft_s, [1, -1, 1, -1])
    assert np.allclose(fft_n, [-1j, 1j, -1j, 1j])

    fpost_s = dft_postprocess_data(
        range_s.element(fft_s), real_grid=discr.grid, recip_grid=recip_s, shift=[True], axes=(0,), interp="nearest"
    )
    fpost_n = dft_postprocess_data(
        range_n.element(fft_n), real_grid=discr.grid, recip_grid=recip_n, shift=[False], axes=(0,), interp="nearest"
    )

    assert np.allclose(fpost_s, fft_s * postproc_s * interp_s)
    assert np.allclose(fpost_n, fft_n * postproc_n * interp_n)

    # Comparing to the known result exp(-1j*x/2) * sinc(x/2) / sqrt(2*pi)
    assert np.allclose(fpost_s, fhat(recip_s.coord_vectors[0]))
    assert np.allclose(fpost_n, fhat(recip_n.coord_vectors[0]))

    # Doing the exact same with direct application of the FT operator
    ft_f_s = ft_op_s(f)
    ft_f_n = ft_op_n(f)
    assert np.allclose(ft_f_s, fhat(recip_s.coord_vectors[0]))
    assert np.allclose(ft_f_n, fhat(recip_n.coord_vectors[0]))
Example #23
0
def Create_dataset_ASTRA_sim(pix, phantom, angles, src_rad, noise, Exp_bin,
                             bin_param, **kwargs):
    if phantom == 'Defrise':
        phantom = 'Defrise random'
    if phantom == 'Fourshape_test':
        phantom = 'Fourshape'

    if 'MaxVoxDataset' in kwargs:
        MaxVoxDataset = kwargs['MaxVoxDataset']

    else:
        MaxVoxDataset = np.max([int(pix**3 * 0.005), 1 * 10**6])

    # The size of the measured objects in voxels
    voxels = [pix, pix, pix]
    dpix = [voxels[0] * 2, voxels[1]]
    u, v = dpix
    # ! ! ! This will lead to some problems later on ! ! !
    det_rad = 0
    data_obj = ddf.phantom(voxels,
                           phantom,
                           angles,
                           noise,
                           src_rad,
                           det_rad,
                           compute_xHQ=True)
    WV_obj = ddf.support_functions.working_var_map()
    WV_path = WV_obj.WV_path
    data_obj.make_mask(WV_path)
    Smat = Make_Smat(voxels, MaxVoxDataset, WV_path)
    # %% saving tiffs for CNNs
    w_du = data_obj.w_detu
    filt = make_hann_filt(voxels, w_du)
    xFDK = ddf.FDK_ODL_astra_backend.FDK_astra(data_obj.g, filt,
                                               data_obj.geometry,
                                               data_obj.reco_space, None)

    # %% Create geometry
    # Make a circular scanning geometry
    minvox = data_obj.reco_space.min_pt[0]
    maxvox = data_obj.reco_space.max_pt[0]
    vox = np.shape(data_obj.reco_space)[0]
    vol_geom = astra.create_vol_geom(vox, vox, vox, minvox, maxvox, minvox,
                                     maxvox, minvox, maxvox)

    ang = np.linspace((1 / angles) * np.pi, (2 + 1 / angles) * np.pi, angles,
                      False)
    w_du, w_dv = 2 * data_obj.geometry.detector.partition.max_pt / [u, v]
    proj_geom = astra.create_proj_geom('cone', w_dv, w_du, v, u, ang,
                                       data_obj.geometry.src_radius,
                                       data_obj.geometry.det_radius)
    filter_part = odl.uniform_partition(-data_obj.detecsize[0],
                                        data_obj.detecsize[0], u)

    filter_space = odl.uniform_discr_frompartition(filter_part,
                                                   dtype='float64')
    spf_space, Exp_op = ddf.support_functions.ExpOp_builder(bin_param,
                                                            filter_space,
                                                            interp=Exp_bin)
    nParam = np.size(spf_space)

    fullFilterSize = int(2**(np.ceil(np.log2(dpix[0])) + 1))
    halfFilterSize = fullFilterSize // 2 + 1

    Resize_Op = odl.ResizingOperator(Exp_op.range, ran_shp=(fullFilterSize, ))
    # %% Create forward and backward projector
    #    project_id = astra.create_projector('cuda3d', proj_geom, vol_geom)
    #    W = astra.OpTomo(project_id)

    # %% Create data
    proj_data = np.transpose(np.asarray(data_obj.g), (2, 0, 1)).copy()
    #    W.FP(np.transpose(np.asarray(data_obj.f), (2, 1, 0)))

    # ! ! ! wat is deze? ! ! !
    # if noise is not None:
    #     g = add_poisson_noise(proj_data, noise[1])
    # else:
    g = proj_data

    proj_id = astra.data3d.link('-sino', proj_geom, g)

    rec = np.zeros(astra.geom_size(vol_geom), dtype=np.float32)
    rec_id = astra.data3d.link('-vol', vol_geom, rec)

    B = np.zeros((MaxVoxDataset, nParam + 1))

    # %% Make the matrix columns of the matrix B
    for nP in range(nParam):
        unit_vec = spf_space.zero()
        unit_vec[nP] = 1
        filt = Exp_op(unit_vec)

        rs_filt = Resize_Op(filt)

        f_filt = np.real(np.fft.rfft(np.fft.ifftshift(rs_filt)))
        filter2d = np.zeros((angles, halfFilterSize))
        for i in range(angles):
            filter2d[i, :] = f_filt * 4 * w_du

        # %% Make a filter geometry
        filter_geom = astra.create_proj_geom('parallel', w_du, halfFilterSize,
                                             np.zeros((angles)))

        filter_id = astra.data2d.create('-sino', filter_geom, filter2d)
        #

        cfg = astra.astra_dict('FDK_CUDA')
        cfg['ReconstructionDataId'] = rec_id
        cfg['ProjectionDataId'] = proj_id
        cfg['option'] = {'FilterSinogramId': filter_id}
        # Create the algorithm object from the configuration structure
        alg_id = astra.algorithm.create(cfg)

        # %%
        astra.algorithm.run(alg_id)
        rec = np.transpose(rec, (2, 1, 0))
        B[:, nP] = rec[Smat]
    # %%
    # Clean up. Note that GPU memory is tied up in the algorithm object,
    # and main RAM in the data objects.
    B[:, -1] = data_obj.xHQ[Smat]
    #    B[:, -1] = data_obj.f[Smat]
    astra.algorithm.delete(alg_id)
    astra.data3d.delete(rec_id)
    astra.data3d.delete(proj_id)
    return B, data_obj.xHQ, xFDK
Example #24
0
def test_fourier_trafo_completely():
    # Complete explicit test of all FT components on two small examples

    # Discretization with 4 points
    discr = odl.uniform_discr(-2, 2, 4, dtype='complex')
    # Interval boundaries -2, -1, 0, 1, 2
    assert np.allclose(discr.partition.cell_boundary_vecs[0],
                       [-2, -1, 0, 1, 2])
    # Grid points -1.5, -0.5, 0.5, 1.5
    assert np.allclose(discr.grid.coord_vectors[0], [-1.5, -0.5, 0.5, 1.5])

    # First test function, symmetric. Can be represented exactly in the
    # discretization.
    def f(x):
        return (x >= -1) & (x <= 1)

    def fhat(x):
        return np.sqrt(2 / np.pi) * sinc(x)

    # Discretize f, check values
    f_discr = discr.element(f)
    assert np.allclose(f_discr, [0, 1, 1, 0])

    # "s" = shifted, "n" = not shifted

    # Reciprocal grids
    recip_s = reciprocal_grid(discr.grid, shift=True)
    recip_n = reciprocal_grid(discr.grid, shift=False)
    assert np.allclose(recip_s.coord_vectors[0],
                       np.linspace(-np.pi, np.pi / 2, 4))
    assert np.allclose(recip_n.coord_vectors[0],
                       np.linspace(-3 * np.pi / 4, 3 * np.pi / 4, 4))

    # Range
    range_part_s = odl.uniform_partition_fromgrid(recip_s)
    range_s = odl.uniform_discr_frompartition(range_part_s, dtype='complex')
    range_part_n = odl.uniform_partition_fromgrid(recip_n)
    range_n = odl.uniform_discr_frompartition(range_part_n, dtype='complex')

    # Pre-processing
    preproc_s = [1, -1, 1, -1]
    preproc_n = [np.exp(1j * 3 / 4 * np.pi * k) for k in range(4)]

    fpre_s = dft_preprocess_data(f_discr, shift=True)
    fpre_n = dft_preprocess_data(f_discr, shift=False)
    assert np.allclose(fpre_s, f_discr * discr.element(preproc_s))
    assert np.allclose(fpre_n, f_discr * discr.element(preproc_n))

    # FFT step, replicating the _call_numpy method
    fft_s = np.fft.fftn(fpre_s, s=discr.shape, axes=[0])
    fft_n = np.fft.fftn(fpre_n, s=discr.shape, axes=[0])
    assert np.allclose(fft_s, [0, -1 + 1j, 2, -1 - 1j])
    assert np.allclose(fft_n, [
        np.exp(1j * np.pi * (3 - 2 * k) / 4) + np.exp(1j * np.pi *
                                                      (3 - 2 * k) / 2)
        for k in range(4)
    ])

    # Interpolation kernel FT
    interp_s = np.sinc(np.linspace(-1 / 2, 1 / 4, 4)) / np.sqrt(2 * np.pi)
    interp_n = np.sinc(np.linspace(-3 / 8, 3 / 8, 4)) / np.sqrt(2 * np.pi)
    assert np.allclose(
        interp_s,
        _interp_kernel_ft(np.linspace(-1 / 2, 1 / 4, 4), interp='nearest'))
    assert np.allclose(
        interp_n,
        _interp_kernel_ft(np.linspace(-3 / 8, 3 / 8, 4), interp='nearest'))

    # Post-processing
    postproc_s = np.exp(1j * np.pi * np.linspace(-3 / 2, 3 / 4, 4))
    postproc_n = np.exp(1j * np.pi * np.linspace(-9 / 8, 9 / 8, 4))

    fpost_s = dft_postprocess_data(range_s.element(fft_s),
                                   real_grid=discr.grid,
                                   recip_grid=recip_s,
                                   shift=[True],
                                   axes=(0, ),
                                   interp='nearest')
    fpost_n = dft_postprocess_data(range_n.element(fft_n),
                                   real_grid=discr.grid,
                                   recip_grid=recip_n,
                                   shift=[False],
                                   axes=(0, ),
                                   interp='nearest')

    assert np.allclose(fpost_s, fft_s * postproc_s * interp_s)
    assert np.allclose(fpost_n, fft_n * postproc_n * interp_n)

    # Comparing to the known result sqrt(2/pi) * sinc(x)
    assert np.allclose(fpost_s, fhat(recip_s.coord_vectors[0]))
    assert np.allclose(fpost_n, fhat(recip_n.coord_vectors[0]))

    # Doing the exact same with direct application of the FT operator
    ft_op_s = FourierTransform(discr, shift=True)
    ft_op_n = FourierTransform(discr, shift=False)
    assert ft_op_s.range.grid == recip_s
    assert ft_op_n.range.grid == recip_n

    ft_f_s = ft_op_s(f)
    ft_f_n = ft_op_n(f)
    assert np.allclose(ft_f_s, fhat(recip_s.coord_vectors[0]))
    assert np.allclose(ft_f_n, fhat(recip_n.coord_vectors[0]))

    # Second test function, asymmetric. Can also be represented exactly in the
    # discretization.
    def f(x):
        return (x >= 0) & (x <= 1)

    def fhat(x):
        return np.exp(-1j * x / 2) * sinc(x / 2) / np.sqrt(2 * np.pi)

    # Discretize f, check values
    f_discr = discr.element(f)
    assert np.allclose(f_discr, [0, 0, 1, 0])

    # Pre-processing
    fpre_s = dft_preprocess_data(f_discr, shift=True)
    fpre_n = dft_preprocess_data(f_discr, shift=False)
    assert np.allclose(fpre_s, [0, 0, 1, 0])
    assert np.allclose(fpre_n, [0, 0, -1j, 0])

    # FFT step
    fft_s = np.fft.fftn(fpre_s, s=discr.shape, axes=[0])
    fft_n = np.fft.fftn(fpre_n, s=discr.shape, axes=[0])
    assert np.allclose(fft_s, [1, -1, 1, -1])
    assert np.allclose(fft_n, [-1j, 1j, -1j, 1j])

    fpost_s = dft_postprocess_data(range_s.element(fft_s),
                                   real_grid=discr.grid,
                                   recip_grid=recip_s,
                                   shift=[True],
                                   axes=(0, ),
                                   interp='nearest')
    fpost_n = dft_postprocess_data(range_n.element(fft_n),
                                   real_grid=discr.grid,
                                   recip_grid=recip_n,
                                   shift=[False],
                                   axes=(0, ),
                                   interp='nearest')

    assert np.allclose(fpost_s, fft_s * postproc_s * interp_s)
    assert np.allclose(fpost_n, fft_n * postproc_n * interp_n)

    # Comparing to the known result exp(-1j*x/2) * sinc(x/2) / sqrt(2*pi)
    assert np.allclose(fpost_s, fhat(recip_s.coord_vectors[0]))
    assert np.allclose(fpost_n, fhat(recip_n.coord_vectors[0]))

    # Doing the exact same with direct application of the FT operator
    ft_f_s = ft_op_s(f)
    ft_f_n = ft_op_n(f)
    assert np.allclose(ft_f_s, fhat(recip_s.coord_vectors[0]))
    assert np.allclose(ft_f_n, fhat(recip_n.coord_vectors[0]))
Example #25
0
# writer.setup(fig, 'DogBones' + '.mp4', dpi=100)
for i in range(data.shape[0]):
    plt.gca().clear()
    plt.imshow(data[i, :, 500:564].T)
    plt.pause(0.1)
#     writer.grab_frame()
# writer.finish()
exit()

# Space variables
vol = list(data.shape)
vol[0] = vol[1]  # recon same as each row width
vol = odl.uniform_partition([-v / sqrt(128) for v in vol],
                            [v / sqrt(128) for v in vol], vol)

vol = odl.uniform_discr_frompartition(vol[:, :, 500:564], dtype='float32')
data = ascontiguousarray(data[:, :, 500:564], dtype='float32')

PSpace = (angles,
          odl.uniform_partition([-v / sqrt(128) for v in data.shape[1:]],
                                [v / sqrt(128) for v in data.shape[1:]],
                                data.shape[1:]))
PSpace = odl.tomo.Parallel3dAxisGeometry(*PSpace, axis=[0, 0, 1])

# Operators
Radon = odl.tomo.RayTransform(vol, PSpace)
grad = odl.Gradient(vol)
op = odl.BroadcastOperator(Radon, grad)
g = odl.solvers.functional.default_functionals.IndicatorNonnegativity(
    op.domain)
fidelity = odl.solvers.L2NormSquared(Radon.range).translated(data)
Example #26
0
import odl
from odl.contrib.datasets.ct import mayo

mayo_dir = ''  # replace with your local folder

# Load reference reconstruction
volume_folder = mayo_dir + '/Training Cases/L067/full_1mm_sharp'
partition, volume = mayo.load_reconstruction(volume_folder)

# Load a subset of the projection data
data_folder = mayo_dir + '/Training Cases/L067/full_DICOM-CT-PD'
geometry, proj_data = mayo.load_projections(data_folder,
                                            indices=slice(20000, 28000))

# Reconstruction space and ray transform
space = odl.uniform_discr_frompartition(partition, dtype='float32')
ray_trafo = odl.tomo.RayTransform(space, geometry)

# Define FBP operator
fbp = odl.tomo.fbp_op(ray_trafo, padding=True)

# Tam-Danielsson window to handle redundant data
td_window = odl.tomo.tam_danielson_window(ray_trafo, n_pi=3)

# Calculate FBP reconstruction
fbp_result = fbp(td_window * proj_data)

# Compare the computed recon to reference reconstruction (coronal slice)
ref = space.element(volume)
fbp_result.show('Recon (coronal)', clim=[0.7, 1.3])
ref.show('Reference (coronal)', clim=[0.7, 1.3])
Example #27
0
    import odl
    from GaussDictCode.dictionary_def import VolSpace, ProjSpace, AtomSpace, ProjElement
    from matplotlib import pyplot as plt

#     # 2D comparison
    ASpace = AtomSpace(2, isotropic=False)
    atoms = ASpace.random(2, seed=1)
    angles = odl.uniform_partition(0, 2 * pi, 360, nodes_on_bdry=True)
    detector = odl.uniform_partition(-1, 1, 256)
    vol = odl.uniform_partition([-1] * 2, [1] * 2, [128] * 2)
    myPSpace = ProjSpace(angles, detector)
    myTomo = GaussTomo(ASpace, VolSpace(vol), myPSpace, device='GPU')
    mySino = myTomo(atoms)
    odlPSpace = odl.tomo.Parallel2dGeometry(angles, detector)
    odlTomo = odl.tomo.RayTransform(
        odl.uniform_discr_frompartition(vol), odlPSpace)
    odlSino = odlTomo(myTomo.discretise(atoms).asarray())
    odlSino = ProjElement(myPSpace, odlSino.asarray())

    mySino.plot(plt.subplot('211'), aspect='auto')
    plt.title('2D Atomic Sinogram (top) and volume-sinogram (bottom)')
    odlSino.plot(plt.subplot('212'), aspect='auto')

#     # 2.5D comparison
    ASpace = AtomSpace(3, isotropic=False)
    atoms = ASpace.random(3, seed=2)
    atoms.I[:] = 1
    atoms.r[:, :3], atoms.r[:, 3:] = 7, 0
    angles = odl.uniform_partition(0, pi, 4, nodes_on_bdry=True)
    detector = odl.uniform_partition([-1] * 2, [1] * 2, [128] * 2)
    vol = odl.uniform_partition([-1] * 3, [1] * 3, [256] * 3)
Example #28
0
    #     angles = angles[2:-1]
    vol = vol[::4, ::4, ::4]
    #     for i in range(0, len(angles)):
    #         plt.gca().clear()
    #         plt.imshow(data[i].T)
    #         plt.title(str(i))
    #         plt.show(block=False)
    #         plt.pause(.3)
    #     plt.show()
    #     exit()

    box = [vol.min_pt, vol.max_pt]
    PSpace = ProjSpace(
        angles,
        odl.uniform_partition(vol.min_pt[1:], vol.max_pt[1:], data.shape[1:]))
    vol = VolSpace(odl.uniform_discr_frompartition(vol, dtype='float32'))

    # Initiate Recon:
    #####
    def newAtoms(n, seed=None):
        tmp = ASpace.random(n, seed=seed)
        c.set(tmp.r, 2, (slice(None), slice(None, 3)))
        c.set(tmp.r, 0, (slice(None), slice(3, None)))
        c.set(tmp.I[:], .1)
        return tmp

    nAtoms = 50
    recon = newAtoms(nAtoms, 1)
    #####
    Radon = GaussTomo(ASpace, vol, PSpace, device='GPU')
    data = ProjElement(PSpace, data / data.max())
from GaussDictCode.transport_loss import l2_squared_loss
from GaussDictCode.regularisation import null
from KL_GaussRadon import doKL_ProjGDStep_iso

with mrc.FileReaderMRC(join('store',
                            'jasenko_1p8A_nonsharpened_absscale.mrc')) as f:
    _, gt = f.read()
    gt[gt < 0] = 0
    gt /= gt.max() / 2
angles = odl.RectGrid(linspace(-pi / 2, pi / 2, 40), linspace(0, pi / 2, 20))
angles = odl.uniform_partition_fromgrid(angles)

vol = list(gt.shape)
vol = odl.uniform_partition([-1] * 3, [1] * 3, vol)

vol = odl.uniform_discr_frompartition(vol, dtype='float32')
gt = ascontiguousarray(gt, dtype='float32')

PSpace = (angles, odl.uniform_partition([-1] * 2, [1] * 2, [64] * 2))
PSpace = odl.tomo.Parallel3dEulerGeometry(*PSpace)

# Operators
Radon = odl.tomo.RayTransform(vol, PSpace)
data = Radon(gt)

with myManager(device='cpu', order='C', fType='float32',
               cType='complex64') as c:
    # Space settings:
    dim = 3
    device = 'GPU'
    ASpace = AtomSpace(dim, isotropic=False)