Beispiel #1
0
def test_init(exponent):
    # Validate that the different init patterns work and do not crash.
    space = odl.FunctionSpace(odl.Interval(0, 1))
    part = odl.uniform_partition_fromintv(space.domain, 10)
    rn = odl.Rn(10, exponent=exponent)
    odl.DiscreteLp(space, part, rn, exponent=exponent)
    odl.DiscreteLp(space, part, rn, exponent=exponent, interp='linear')

    # Normal discretization of unit interval with complex
    complex_space = odl.FunctionSpace(odl.Interval(0, 1),
                                      field=odl.ComplexNumbers())
    cn = odl.Cn(10, exponent=exponent)
    odl.DiscreteLp(complex_space, part, cn, exponent=exponent)

    space = odl.FunctionSpace(odl.Rectangle([0, 0], [1, 1]))
    part = odl.uniform_partition_fromintv(space.domain, (10, 10))
    rn = odl.Rn(100, exponent=exponent)
    odl.DiscreteLp(space, part, rn, exponent=exponent,
                   interp=['nearest', 'linear'])

    # Real space should not work with complex
    with pytest.raises(ValueError):
        odl.DiscreteLp(space, part, cn)

    # Complex space should not work with reals
    with pytest.raises(ValueError):
        odl.DiscreteLp(complex_space, part, rn)

    # Wrong size of underlying space
    rn_wrong_size = odl.Rn(20)
    with pytest.raises(ValueError):
        odl.DiscreteLp(space, part, rn_wrong_size)
Beispiel #2
0
def test_dspace_type_cuda():
    # Plain function set -> Ntuples-like
    fset = odl.FunctionSet(odl.Interval(0, 1), odl.Strings(2))
    assert dspace_type(fset, 'cuda') == odl.CudaNtuples
    assert dspace_type(fset, 'cuda', np.int) == odl.CudaNtuples

    # Real space
    rspc = odl.FunctionSpace(odl.Interval(0, 1), field=odl.RealNumbers())
    assert dspace_type(rspc, 'cuda') == odl.CudaFn
    assert dspace_type(rspc, 'cuda', np.float64) == odl.CudaFn
    assert dspace_type(rspc, 'cuda', np.int) == odl.CudaFn
    with pytest.raises(TypeError):
        dspace_type(rspc, 'cuda', np.complex)
    with pytest.raises(TypeError):
        dspace_type(rspc, 'cuda', np.dtype('<U2'))

    # Complex space (not implemented)
    cspc = odl.FunctionSpace(odl.Interval(0, 1), field=odl.ComplexNumbers())
    with pytest.raises(NotImplementedError):
        dspace_type(cspc, 'cuda')
    with pytest.raises(NotImplementedError):
        dspace_type(cspc, 'cuda', np.complex64)
    with pytest.raises(TypeError):
        dspace_type(cspc, 'cuda', np.float)
    with pytest.raises(TypeError):
        assert dspace_type(cspc, 'cuda', np.int)
Beispiel #3
0
def test_dspace_type_numpy():
    # Plain function set -> Ntuples-like
    fset = odl.FunctionSet(odl.Interval(0, 1), odl.Strings(2))
    assert dspace_type(fset, 'numpy') == odl.Ntuples, None
    assert dspace_type(fset, 'numpy', np.int) == odl.Ntuples

    # Real space
    rspc = odl.FunctionSpace(odl.Interval(0, 1), field=odl.RealNumbers())
    assert dspace_type(rspc, 'numpy') == odl.Fn
    assert dspace_type(rspc, 'numpy', np.float32) == odl.Fn
    assert dspace_type(rspc, 'numpy', np.int) == odl.Fn
    with pytest.raises(TypeError):
        dspace_type(rspc, 'numpy', np.complex)
    with pytest.raises(TypeError):
        dspace_type(rspc, 'numpy', np.dtype('<U2'))

    # Complex space
    cspc = odl.FunctionSpace(odl.Interval(0, 1), field=odl.ComplexNumbers())
    assert dspace_type(cspc, 'numpy') == odl.Fn
    assert dspace_type(cspc, 'numpy', np.complex64) == odl.Fn
    with pytest.raises(TypeError):
        dspace_type(cspc, 'numpy', np.float)
    with pytest.raises(TypeError):
        assert dspace_type(cspc, 'numpy', np.int)
    with pytest.raises(TypeError):
        dspace_type(cspc, 'numpy', np.dtype('<U2'))
Beispiel #4
0
def test_fspace_equality():
    intv = odl.Interval(0, 1)
    intv2 = odl.Interval(-1, 1)
    fspace = FunctionSpace(intv)
    fspace_r = FunctionSpace(intv, field=odl.RealNumbers())
    fspace_c = FunctionSpace(intv, field=odl.ComplexNumbers())
    fspace_intv2 = FunctionSpace(intv2)

    assert fspace == fspace_r
    assert fspace != fspace_c
    assert fspace != fspace_intv2
Beispiel #5
0
def test_fspace_vector_init():
    # 1d, real
    intv = odl.Interval(0, 1)
    fspace = FunctionSpace(intv)
    fspace.element(func_1d_oop)
    fspace.element(func_1d_oop, vectorized=False)
    fspace.element(func_1d_oop, vectorized=True)
    fspace.element(func_1d_ip, vectorized=True)
    fspace.element(func_1d_dual, vectorized=True)

    # 2d, real
    rect = odl.Rectangle([0, 0], [1, 2])
    fspace = FunctionSpace(rect)
    fspace.element(func_2d_novec, vectorized=False)
    fspace.element(func_2d_vec_oop)
    fspace.element(func_2d_vec_oop, vectorized=True)
    fspace.element(func_2d_vec_ip, vectorized=True)
    fspace.element(func_2d_vec_dual, vectorized=True)

    # 2d, complex
    fspace = FunctionSpace(rect, field=odl.ComplexNumbers())
    fspace.element(cfunc_2d_novec, vectorized=False)
    fspace.element(cfunc_2d_vec_oop)
    fspace.element(cfunc_2d_vec_oop, vectorized=True)
    fspace.element(cfunc_2d_vec_ip, vectorized=True)
    fspace.element(cfunc_2d_vec_dual, vectorized=True)
Beispiel #6
0
def make_projector(n):
    # Discrete reconstruction space
    discr_reco_space = odl.uniform_discr([-20, -20, -20], [20, 20, 20],
                                         [n] * 3,
                                         dtype='float32')

    # Geometry
    src_rad = 1000
    det_rad = 100
    angle_intvl = odl.Interval(0, 2 * np.pi)
    dparams = odl.Rectangle([-50, -50], [50, 50])
    agrid = odl.uniform_sampling(angle_intvl, n)
    dgrid = odl.uniform_sampling(dparams, [n] * 2)
    geom = odl.tomo.CircularConeFlatGeometry(angle_intvl, dparams, src_rad,
                                             det_rad, agrid, dgrid)

    # X-ray transform
    projector = odl.tomo.XrayTransform(discr_reco_space,
                                       geom,
                                       backend='astra_cuda')
    phantom = projector.domain.one()
    projector._adjoint *= projector(phantom).inner(
        projector(phantom)) / phantom.inner(
            projector.adjoint(projector(phantom)))
    return 0.08 * projector
Beispiel #7
0
def test_nearest_interpolation_1d_complex():
    intv = odl.Interval(0, 1)
    part = odl.uniform_partition_fromintv(intv, 5, nodes_on_bdry=False)
    # Coordinate vectors are:
    # [0.1, 0.3, 0.5, 0.7, 0.9]

    space = odl.FunctionSpace(intv, field=odl.ComplexNumbers())
    dspace = odl.Cn(part.size)
    interp_op = NearestInterpolation(space, part, dspace)
    function = interp_op([0 + 1j, 1 + 2j, 2 + 3j, 3 + 4j, 4 + 5j])

    # Evaluate at single point
    val = function(0.35)  # closest to index 1 -> 1 + 2j
    assert val == 1.0 + 2.0j
    # Input array, with and without output array
    pts = np.array([0.4, 0.0, 0.65, 0.95])
    true_arr = [1 + 2j, 0 + 1j, 3 + 4j, 4 + 5j]
    assert all_equal(function(pts), true_arr)
    # Should also work with a (1, N) array
    pts = pts[None, :]
    assert all_equal(function(pts), true_arr)
    out = np.empty(4, dtype='complex128')
    function(pts, out=out)
    assert all_equal(out, true_arr)
    # Input meshgrid, with and without output array
    # Same as array for 1d
    mg = sparse_meshgrid([0.4, 0.0, 0.65, 0.95])
    true_mg = [1 + 2j, 0 + 1j, 3 + 4j, 4 + 5j]
    assert all_equal(function(mg), true_mg)
    function(mg, out=out)
    assert all_equal(out, true_mg)
Beispiel #8
0
def test_nearest_interpolation_1d_variants():
    intv = odl.Interval(0, 1)
    part = odl.uniform_partition_fromintv(intv, 5, nodes_on_bdry=False)
    # Coordinate vectors are:
    # [0.1, 0.3, 0.5, 0.7, 0.9]

    space = odl.FunctionSpace(intv)
    dspace = odl.Rn(part.size)

    # 'left' variant
    interp_op = NearestInterpolation(space, part, dspace, variant='left')
    function = interp_op([0, 1, 2, 3, 4])

    # Testing two midpoints and the extreme values
    pts = np.array([0.4, 0.8, 0.0, 1.0])
    true_arr = [1, 3, 0, 4]
    assert all_equal(function(pts), true_arr)

    # 'right' variant
    interp_op = NearestInterpolation(space, part, dspace, variant='right')
    function = interp_op([0, 1, 2, 3, 4])

    # Testing two midpoints and the extreme values
    pts = np.array([0.4, 0.8, 0.0, 1.0])
    true_arr = [2, 4, 0, 4]
    assert all_equal(function(pts), true_arr)
def test_bwt1d(wbasis):
    # Verify that the operator works as axpected
    # 1D test
    n = 16
    x = np.zeros(n)
    x[5:10] = 1
    nscales = 2

    # Define a discretized domain
    domain = odl.FunctionSpace(odl.Interval([-1], [1]))
    nPoints = np.array([n])
    disc_domain = odl.uniform_discr_fromspace(domain, nPoints)
    disc_phantom = disc_domain.element(x)

    # Create the discrete wavelet transform operator.
    # Only the domain of the operator needs to be defined
    Wop = BiorthWaveletTransform(disc_domain, nscales, wbasis)

    # Compute the discrete wavelet transform of discrete imput image
    coeffs = Wop(disc_phantom)

    # Compute the inverse wavelet transform
    reconstruction = Wop.inverse(coeffs)

    # Verify that reconstructions lie in correct discretized domain
    assert reconstruction in disc_domain
    assert all_almost_equal(reconstruction.asarray(), x)
Beispiel #10
0
def test_fspace_astype():

    rspace = FunctionSpace(odl.Interval(0, 1))
    cspace = FunctionSpace(odl.Interval(0, 1), field=odl.ComplexNumbers())
    rspace_s = FunctionSpace(odl.Interval(0, 1), out_dtype='float32')
    cspace_s = FunctionSpace(odl.Interval(0, 1), out_dtype='complex64')

    assert rspace.astype('complex64') == cspace_s
    assert rspace.astype('complex128') == cspace
    assert rspace.astype('complex128') is rspace._complex_space
    assert rspace.astype('float32') == rspace_s
    assert rspace.astype('float64') is rspace._real_space

    assert cspace.astype('float32') == rspace_s
    assert cspace.astype('float64') == rspace
    assert cspace.astype('float64') is cspace._real_space
    assert cspace.astype('complex64') == cspace_s
    assert cspace.astype('complex128') is cspace._complex_space
Beispiel #11
0
def test_fspace_simple_attributes():
    intv = odl.Interval(0, 1)
    fspace = FunctionSpace(intv)
    fspace_r = FunctionSpace(intv, field=odl.RealNumbers())
    fspace_c = FunctionSpace(intv, field=odl.ComplexNumbers())

    assert fspace.domain == intv
    assert fspace.range == odl.RealNumbers()
    assert fspace_r.range == odl.RealNumbers()
    assert fspace_c.range == odl.ComplexNumbers()
Beispiel #12
0
def test_fspace_vector_ufunc():
    intv = odl.Interval(0, 1)
    points = _points(intv, num=5)
    mg = _meshgrid(intv, shape=(5, ))

    fspace = FunctionSpace(intv)
    f_vec = fspace.element(np.sin)

    assert f_vec(0.5) == np.sin(0.5)
    assert all_equal(f_vec(points), np.sin(points.squeeze()))
    assert all_equal(f_vec(mg), np.sin(mg[0]))
Beispiel #13
0
def test_partition_init():
    vec1 = np.array([2, 4, 5, 7])
    vec2 = np.array([-4, -3, 0, 1, 4])
    begin = [2, -5]
    end = [10, 4]

    # Simply test if code runs
    odl.RectPartition(odl.Rectangle(begin, end), odl.TensorGrid(vec1, vec2))
    odl.RectPartition(odl.Interval(begin[0], end[0]), odl.TensorGrid(vec1))

    # Degenerate dimensions should work, too
    vec2 = np.array([1.0])
    odl.RectPartition(odl.Rectangle(begin, end), odl.TensorGrid(vec1, vec2))
Beispiel #14
0
def test_astra_projection_geometry():
    """Create ASTRA projection geometry from geometry objects."""

    with pytest.raises(TypeError):
        odl.tomo.astra_projection_geometry(None)

    apart = odl.uniform_partition(0, 2 * np.pi, 5)
    dpart = odl.uniform_partition(-40, 40, 10)

    # motion sampling grid, detector sampling grid but not RegularGrid
    dpart_0 = odl.RectPartition(odl.Interval(0, 0), odl.TensorGrid([0]))
    geom_p2d = odl.tomo.Parallel2dGeometry(apart, dpart=dpart_0)
    with pytest.raises(ValueError):
        odl.tomo.astra_projection_geometry(geom_p2d)

    # detector sampling grid, motion sampling grid
    geom_p2d = odl.tomo.Parallel2dGeometry(apart, dpart)
    odl.tomo.astra_projection_geometry(geom_p2d)

    # Parallel 2D geometry
    geom_p2d = odl.tomo.Parallel2dGeometry(apart, dpart)
    astra_geom = odl.tomo.astra_projection_geometry(geom_p2d)
    assert astra_geom['type'] == 'parallel'

    # Fan flat
    src_rad = 10
    det_rad = 5
    geom_ff = odl.tomo.FanFlatGeometry(apart, dpart, src_rad, det_rad)
    astra_geom = odl.tomo.astra_projection_geometry(geom_ff)
    assert astra_geom['type'] == 'fanflat_vec'

    dpart = odl.uniform_partition([-40, -3], [40, 3], (10, 5))

    # Parallel 3D geometry
    geom_p3d = odl.tomo.Parallel3dAxisGeometry(apart, dpart)
    odl.tomo.astra_projection_geometry(geom_p3d)
    astra_geom = odl.tomo.astra_projection_geometry(geom_p3d)
    assert astra_geom['type'] == 'parallel3d_vec'

    # Circular conebeam flat
    geom_ccf = odl.tomo.CircularConeFlatGeometry(apart, dpart, src_rad,
                                                 det_rad)
    astra_geom = odl.tomo.astra_projection_geometry(geom_ccf)
    assert astra_geom['type'] == 'cone_vec'

    # Helical conebeam flat
    pitch = 1
    geom_hcf = odl.tomo.HelicalConeFlatGeometry(apart, dpart, src_rad, det_rad,
                                                pitch)
    astra_geom = odl.tomo.astra_projection_geometry(geom_hcf)
    assert astra_geom['type'] == 'cone_vec'
Beispiel #15
0
def test_proj():

    # `DiscreteLp` volume space
    vol_shape = (100,) * 3
    discr_vol_space = odl.uniform_discr([-50] * 3, [50] * 3, vol_shape,
                                        dtype='float32')

    # Angles: 0 and pi/2
    angle_intvl = odl.Interval(0, np.pi / 2)
    angle_grid = odl.uniform_sampling(angle_intvl, 2, as_midp=False)
    # agrid = angle_grid.points() / np.pi

    # Detector
    dparams = odl.Rectangle([-50] * 2, [50] * 2)
    det_grid = odl.uniform_sampling(dparams, (100, 100))

    def projector(index):

        axis = np.roll(np.array([1, 0, 0]), index)
        axis2 = np.roll(axis, 1)

        geom = odl.tomo.Parallel3dGeometry(angle_intvl, dparams, angle_grid,
                                           det_grid, axis=axis,
                                           origin_to_det=axis2)
        # Projection space
        proj_space = odl.FunctionSpace(geom.params)
        discr_data = odl.util.phantom.indicate_proj_axis(discr_vol_space, 0.5)

        # `DiscreteLp` projection space
        proj_shape = geom.grid.shape
        discr_proj_space = odl.uniform_discr_fromspace(proj_space, proj_shape,
                                                       dtype='float32')
        # Forward
        proj_data = odl.tomo.astra_cuda_forward_projector(
            discr_data, geom, discr_proj_space)
        return proj_data

    proj_data = projector(0)
    proj_data.show(indices=(0, np.s_[:], np.s_[:]))
    proj_data.show(indices=(1, np.s_[:], np.s_[:]))

    proj_data = projector(1)
    proj_data.show(indices=(0, np.s_[:], np.s_[:]))
    proj_data.show(indices=(1, np.s_[:], np.s_[:]))

    proj_data = projector(2)
    proj_data.show(indices=(0, np.s_[:], np.s_[:]))
    proj_data.show(indices=(1, np.s_[:], np.s_[:]))

    plt.show(block=True)
Beispiel #16
0
def test_fspace_vector_copy():
    fspace = FunctionSpace(odl.Interval(0, 1))

    f_novec = fspace.element(func_1d_oop, vectorized=False)
    f_vec_ip = fspace.element(func_1d_ip, vectorized=True)
    f_vec_dual = fspace.element(func_1d_dual, vectorized=True)

    f_out = f_novec.copy()
    assert f_out == f_novec

    f_out = f_vec_ip.copy()
    assert f_out == f_vec_ip

    f_out = f_vec_dual.copy()
    assert f_out == f_vec_dual
Beispiel #17
0
def test_fwd_diff():
    # Continuous definition of problem
    space = odl.FunctionSpace(odl.Interval(0, 1))

    # Discretization
    n = 6
    d = odl.uniform_discr(space, n, impl='cuda')
    fun = d.element([1, 2, 5, 3, 2, 1])

    # Create operator
    diff = ForwardDiff(d)

    assert all_almost_equal(diff(fun), [0, 3, -2, -1, -1, 0])
    assert all_almost_equal(diff.adjoint(fun), [0, -1, -3, 2, 1, 0])
    assert all_almost_equal(diff.adjoint(diff(fun)), [0, -3, 5, -1, 0, 0])
Beispiel #18
0
def test_norm_interval(exponent):
    # Test the function f(x) = x^2 on the interval (0, 1). Its
    # L^p-norm is (1 + 2*p)^(-1/p) for finite p and 1 for p=inf
    p = exponent
    fspace = odl.FunctionSpace(odl.Interval(0, 1))
    lpdiscr = odl.uniform_discr_fromspace(fspace, 10, exponent=p)

    testfunc = fspace.element(lambda x: x ** 2)
    discr_testfunc = lpdiscr.element(testfunc)

    if p == float('inf'):
        assert discr_testfunc.norm() <= 1  # Max at boundary not hit
    else:
        true_norm = (1 + 2 * p) ** (-1 / p)
        assert almost_equal(discr_testfunc.norm(), true_norm, places=2)
Beispiel #19
0
def test_linear_interpolation_1d():
    intv = odl.Interval(0, 1)
    part = odl.uniform_partition_fromintv(intv, 5, nodes_on_bdry=False)
    # Coordinate vectors are:
    # [0.1, 0.3, 0.5, 0.7, 0.9]

    space = odl.FunctionSpace(intv)
    dspace = odl.Rn(part.size)
    interp_op = LinearInterpolation(space, part, dspace)
    function = interp_op([1, 2, 3, 4, 5])

    # Evaluate at single point
    val = function(0.35)
    true_val = 0.75 * 2 + 0.25 * 3
    assert almost_equal(val, true_val)

    # Input array, with and without output array
    pts = np.array([0.4, 0.0, 0.65, 0.95])
    true_arr = [2.5, 0.5, 3.75, 3.75]
    assert all_almost_equal(function(pts), true_arr)
Beispiel #20
0
def test_fspace_init():
    intv = odl.Interval(0, 1)
    FunctionSpace(intv)
    FunctionSpace(intv, field=odl.RealNumbers())
    FunctionSpace(intv, field=odl.ComplexNumbers())

    rect = odl.Rectangle([0, 0], [1, 2])
    FunctionSpace(rect)
    FunctionSpace(rect, field=odl.RealNumbers())
    FunctionSpace(rect, field=odl.ComplexNumbers())

    cube = odl.Cuboid([0, 0, 0], [1, 2, 3])
    FunctionSpace(cube)
    FunctionSpace(cube, field=odl.RealNumbers())
    FunctionSpace(cube, field=odl.ComplexNumbers())

    ndbox = odl.IntervalProd([0] * 10, np.arange(1, 11))
    FunctionSpace(ndbox)
    FunctionSpace(ndbox, field=odl.RealNumbers())
    FunctionSpace(ndbox, field=odl.ComplexNumbers())
Beispiel #21
0
def test_yzproj():
    # `DiscreteLp` volume space
    vol_shape = (100,) * 3
    discr_vol_space = odl.uniform_discr([-50] * 3, [50] * 3, vol_shape,
                                        dtype='float32')

    # Angles: 0 and pi/2
    angle_intvl = odl.Interval(0, np.pi / 2)
    angle_grid = odl.uniform_sampling(angle_intvl, 2, as_midp=False)
    # agrid = angle_grid.points() / np.pi

    # Detector
    dparams = odl.Rectangle([-50] * 2, [50] * 2)
    det_grid = odl.uniform_sampling(dparams, (100, 100))

    axis = (0, 1, 0)
    origin_to_det = (0, 0, 1)
    geom = odl.tomo.Parallel3dGeometry(angle_intvl, dparams,
                                       angle_grid,
                                       det_grid, axis=axis,
                                       origin_to_det=origin_to_det)
    # Projection space
    proj_space = odl.FunctionSpace(geom.params)
    discr_data = odl.util.phantom.indicate_proj_axis(discr_vol_space, 0.5)

    # `DiscreteLp` projection space
    proj_shape = geom.grid.shape
    discr_proj_space = odl.uniform_discr_fromspace(proj_space,
                                                   proj_shape,
                                                   dtype='float32')
    # Forward
    proj_data = odl.tomo.astra_cuda_forward_projector(discr_data,
                                                      geom,

                                                      discr_proj_space)

    plt.switch_backend('qt4agg')
    proj_data.show(indices=np.s_[0, :, :])
    plt.show()
            scale1.lincomb(1, scale1, I * mu1(E), tmp)

        return odl.ReductionOperator(odl.MultiplyOperator(scale0),
                                     odl.MultiplyOperator(scale1))


n = 200

# Discrete reconstruction space
discr_reco_space = odl.uniform_discr([-20, -20, -20], [20, 20, 20],
                                     [n]*3, dtype='float32')

# Geometry
src_rad = 1000
det_rad = 100
angle_intvl = odl.Interval(0, 2 * np.pi)
dparams = odl.Rectangle([-50, -50], [50, 50])
agrid = odl.uniform_sampling(angle_intvl, n)
dgrid = odl.uniform_sampling(dparams, [n]*2)
geom = odl.tomo.CircularConeFlatGeometry(angle_intvl, dparams,
                                         src_rad, det_rad,
                                         agrid, dgrid)

# X-ray transform
proj = odl.tomo.DiscreteXrayTransform(discr_reco_space, geom,
                                      backend='astra_cuda')


# Create phantom
phantom0 = odl.util.shepp_logan(discr_reco_space, True)
phantom1 = odl.util.derenzo_sources(discr_reco_space)
Beispiel #23
0
        super().__init__(self.space, self.space, linear=True)

    def _call(self, rhs, out):
        ndimage.convolve(rhs.ntuple.data, self.kernel.ntuple.data,
                         output=out.ntuple.data, mode='wrap')

    @property
    def adjoint(self):
        return Convolution(self.adjkernel, self.kernel)

    def opnorm(self):
        return self.norm


# Continuous definition of the problem
cont_space = odl.FunctionSpace(odl.Interval(0, 10))

# Complicated functions to check performance
cont_kernel = cont_space.element(lambda x: np.exp(x / 2) * np.cos(x * 1.172))
cont_phantom = cont_space.element(lambda x: x ** 2 * np.sin(x) ** 2 * (x > 5))

# Discretization
discr_space = odl.uniform_discr_fromspace(cont_space, 500, impl='numpy')
kernel = discr_space.element(cont_kernel)
phantom = discr_space.element(cont_phantom)

# Create operator
conv = Convolution(kernel)

# Dampening parameter for landweber
iterations = 100
Beispiel #24
0
def test_dwt():
    # Verify that the operator works as axpected
    # 1D test
    n = 16
    x = np.zeros(n)
    x[5:10] = 1
    wbasis = pywt.Wavelet('db1')
    nscales = 2
    mode = 'sym'
    size_list = coeff_size_list((n,), nscales, wbasis, mode)

    # Define a discretized domain
    domain = odl.FunctionSpace(odl.Interval([-1], [1]))
    nPoints = np.array([n])
    disc_domain = odl.uniform_discr_fromspace(domain, nPoints)
    disc_phantom = disc_domain.element(x)

    # Create the discrete wavelet transform operator.
    # Only the domain of the operator needs to be defined
    Wop = WaveletTransform(disc_domain, nscales, wbasis, mode)

    # Compute the discrete wavelet transform of discrete imput image
    coeffs = Wop(disc_phantom)

    # Determine the correct range for Wop and verify that coeffs
    # is an element of it
    ran_size = np.prod(size_list[0])
    ran_size += sum(np.prod(shape) for shape in size_list[1:-1])
    disc_range = disc_domain.dspace_type(ran_size, dtype=disc_domain.dtype)
    assert coeffs in disc_range

    # Compute the inverse wavelet transform
    reconstruction1 = Wop.inverse(coeffs)
    # With othogonal wavelets the inverse is the adjoint
    reconstruction2 = Wop.adjoint(coeffs)
    # Verify that the output of Wop.inverse and Wop.adjoint are the same
    assert all_almost_equal(reconstruction1.asarray(),
                            reconstruction2.asarray())

    # Verify that reconstructions lie in correct discretized domain
    assert reconstruction1 in disc_domain
    assert reconstruction2 in disc_domain
    assert all_almost_equal(reconstruction1.asarray(), x)
    assert all_almost_equal(reconstruction2.asarray(), x)

    # ---------------------------------------------------------------
    # 2D test
    n = 16
    x = np.zeros((n, n))
    x[5:10, 5:10] = 1
    wbasis = pywt.Wavelet('db1')
    nscales = 2
    mode = 'sym'
    size_list = coeff_size_list((n, n), nscales, wbasis, mode)

    # Define a discretized domain
    domain = odl.FunctionSpace(odl.Rectangle([-1, -1], [1, 1]))
    nPoints = np.array([n, n])
    disc_domain = odl.uniform_discr_fromspace(domain, nPoints)
    disc_phantom = disc_domain.element(x)

    # Create the discrete wavelet transform operator.
    # Only the domain of the operator needs to be defined
    Wop = WaveletTransform(disc_domain, nscales, wbasis, mode)

    # Compute the discrete wavelet transform of discrete imput image
    coeffs = Wop(disc_phantom)

    # Determine the correct range for Wop and verify that coeffs
    # is an element of it
    ran_size = np.prod(size_list[0])
    ran_size += sum(3 * np.prod(shape) for shape in size_list[1:-1])
    disc_range = disc_domain.dspace_type(ran_size, dtype=disc_domain.dtype)
    assert coeffs in disc_range

    # Compute the inverse wavelet transform
    reconstruction1 = Wop.inverse(coeffs)
    # With othogonal wavelets the inverse is the adjoint
    reconstruction2 = Wop.adjoint(coeffs)
    # Verify that the output of Wop.inverse and Wop.adjoint are the same
    assert all_almost_equal(reconstruction1.asarray(),
                            reconstruction2.asarray())

    # Verify that reconstructions lie in correct discretized domain
    assert reconstruction1 in disc_domain
    assert reconstruction2 in disc_domain
    assert all_almost_equal(reconstruction1.asarray(), x)
    assert all_almost_equal(reconstruction2.asarray(), x)

    # -------------------------------------------------------------
    # 3D test
    n = 16
    x = np.zeros((n, n, n))
    x[5:10, 5:10, 5:10] = 1
    wbasis = pywt.Wavelet('db2')
    nscales = 1
    mode = 'per'
    size_list = coeff_size_list((n, n, n), nscales, wbasis, mode)

    # Define a discretized domain
    domain = odl.FunctionSpace(odl.Cuboid([-1, -1, -1], [1, 1, 1]))
    nPoints = np.array([n, n, n])
    disc_domain = odl.uniform_discr_fromspace(domain, nPoints)
    disc_phantom = disc_domain.element(x)

    # Create the discrete wavelet transform operator related to 3D transform.
    Wop = WaveletTransform(disc_domain, nscales, wbasis, mode)
    # Compute the discrete wavelet transform of discrete imput image
    coeffs = Wop(disc_phantom)
    # Determine the correct range for Wop and verify that coeffs
    # is an element of it
    ran_size = np.prod(size_list[0])
    ran_size += sum(7 * np.prod(shape) for shape in size_list[1:-1])
    disc_range = disc_domain.dspace_type(ran_size, dtype=disc_domain.dtype)
    assert coeffs in disc_range

    # Compute the inverse wavelet transform
    reconstruction1 = Wop.inverse(coeffs)
    # With othogonal wavelets the inverse is the adjoint
    reconstruction2 = Wop.adjoint(coeffs)

    # Verify that the output of Wop.inverse and Wop.adjoint are the same
    assert all_almost_equal(reconstruction1, reconstruction2)

    # Verify that reconstructions lie in correct discretized domain
    assert reconstruction1 in disc_domain
    assert reconstruction2 in disc_domain
    assert all_almost_equal(reconstruction1.asarray(), x)
    assert all_almost_equal(reconstruction2, disc_phantom)
Beispiel #25
0
def test_init_cuda(exponent):
    # Normal discretization of unit interval
    space = odl.FunctionSpace(odl.Interval(0, 1), out_dtype='float32')
    part = odl.uniform_partition_fromintv(space.domain, 10)
    rn = odl.CudaRn(10, exponent=exponent)
    odl.DiscreteLp(space, part, rn, exponent=exponent)
Beispiel #26
0
def test_xray_trafo_parallel2d():
    """3D parallel-beam discrete X-ray transform with ASTRA CUDA."""

    # Discrete reconstruction space
    xx = 5
    nn = 5
    # xx = 5.5
    # nn = 11
    discr_vol_space = odl.uniform_discr([-xx] * 2, [xx] * 2, [nn] * 2,
                                        dtype='float32')

    # Angle
    angle_intvl = odl.Interval(0, 2 * np.pi) - np.pi / 4
    agrid = odl.uniform_sampling(angle_intvl, 4)

    # Detector
    yy = 11
    mm = 11
    # yy = 10.5
    # mm = 21
    dparams = odl.Interval(-yy, yy)
    dgrid = odl.uniform_sampling(dparams, mm)

    # Geometry
    geom = odl.tomo.Parallel2dGeometry(angle_intvl, dparams, agrid, dgrid)

    # Projection space
    proj_space = odl.FunctionSpace(geom.params)

    # `DiscreteLp` projection space
    proj_shape = geom.grid.shape
    discr_proj_space = odl.uniform_discr_fromspace(proj_space, proj_shape,
                                                   dtype='float32')

    # X-ray transform
    A = odl.tomo.XrayTransform(discr_vol_space, geom,
                               backend='astra_cuda')

    # Domain element
    f = A.domain.one()

    # Forward projection
    Af = A(f)
    A0f = odl.tomo.astra_cuda_forward_projector(f, geom,
                                                discr_proj_space)

    # Range element
    g = A.range.one()

    # Back projection
    Adg = A.adjoint(g)
    Adg0 = odl.tomo.astra_cuda_back_projector(g, geom,
                                              discr_vol_space)

    print('\nvol stride', discr_vol_space.grid.stride)
    print('proj stride', geom.grid.stride)
    print('angle intv:', angle_intvl.size)
    # f = discr_vol_space3.one()
    # print(f.asarray()[:, :, np.round(f.shape[2]/2)])
    print('forward')
    print(Af.asarray()[0])
    print(A0f.asarray()[0])
    print('backward')
    print(Adg.asarray() / float(agrid.stride) / agrid.ntotal)
    print(Adg0.asarray() / agrid.ntotal)
Beispiel #27
0
def projector(request):

    n_angles = 200

    geom, impl, angle = request.param.split()

    if angle == 'uniform':
        apart = odl.uniform_partition(0, 2 * np.pi, n_angles)
    elif angle == 'random':
        # Linearly spaced with random noise
        min_pt = 2 * (2.0 * np.pi) / n_angles
        max_pt = (2.0 * np.pi) - 2 * (2.0 * np.pi) / n_angles
        points = np.linspace(min_pt, max_pt, n_angles)
        points += np.random.rand(n_angles) * (max_pt - min_pt) / (5 * n_angles)
        agrid = odl.TensorGrid(points)
        apart = odl.RectPartition(odl.Interval(0, 2 * np.pi), agrid)
    elif angle == 'nonuniform':
        # Angles spaced quadratically
        min_pt = 2 * (2.0 * np.pi) / n_angles
        max_pt = (2.0 * np.pi) - 2 * (2.0 * np.pi) / n_angles
        points = np.linspace(min_pt**0.5, max_pt**0.5, n_angles)**2
        agrid = odl.TensorGrid(points)
        apart = odl.RectPartition(odl.Interval(0, 2 * np.pi), agrid)
    else:
        raise ValueError('angle not valid')

    if geom == 'par2d':
        # Discrete reconstruction space
        discr_reco_space = odl.uniform_discr([-20, -20], [20, 20], [100, 100],
                                             dtype='float32')

        # Geometry
        dpart = odl.uniform_partition(-30, 30, 200)
        geom = tomo.Parallel2dGeometry(apart, dpart)

        # Ray transform
        return tomo.RayTransform(discr_reco_space, geom, impl=impl)

    elif geom == 'par3d':
        # Discrete reconstruction space
        discr_reco_space = odl.uniform_discr([-20, -20, -20], [20, 20, 20],
                                             [100, 100, 100],
                                             dtype='float32')

        # Geometry
        dpart = odl.uniform_partition([-30, -30], [30, 30], [200, 200])
        geom = tomo.Parallel3dAxisGeometry(apart, dpart, axis=[1, 0, 0])

        # Ray transform
        return tomo.RayTransform(discr_reco_space, geom, impl=impl)

    elif geom == 'cone2d':
        # Discrete reconstruction space
        discr_reco_space = odl.uniform_discr([-20, -20], [20, 20], [100, 100],
                                             dtype='float32')

        # Geometry
        dpart = odl.uniform_partition(-30, 30, 200)
        geom = tomo.FanFlatGeometry(apart,
                                    dpart,
                                    src_radius=200,
                                    det_radius=100)

        # Ray transform
        return tomo.RayTransform(discr_reco_space, geom, impl=impl)

    elif geom == 'cone3d':
        # Discrete reconstruction space
        discr_reco_space = odl.uniform_discr([-20, -20, -20], [20, 20, 20],
                                             [100, 100, 100],
                                             dtype='float32')

        # Geometry
        dpart = odl.uniform_partition([-30, -30], [30, 30], [200, 200])
        geom = tomo.CircularConeFlatGeometry(apart,
                                             dpart,
                                             src_radius=200,
                                             det_radius=100,
                                             axis=[1, 0, 0])

        # Ray transform
        return tomo.RayTransform(discr_reco_space, geom, impl=impl)

    elif geom == 'helical':
        # Discrete reconstruction space
        discr_reco_space = odl.uniform_discr([-20, -20, 0], [20, 20, 40],
                                             [100, 100, 100],
                                             dtype='float32')

        # Geometry
        # TODO: angles
        n_angle = 700
        apart = odl.uniform_partition(0, 8 * 2 * np.pi, n_angle)
        dpart = odl.uniform_partition([-30, -3], [30, 3], [200, 20])
        geom = tomo.HelicalConeFlatGeometry(apart,
                                            dpart,
                                            pitch=5.0,
                                            src_radius=200,
                                            det_radius=100)

        # Ray transform
        return tomo.RayTransform(discr_reco_space, geom, impl=impl)
    else:
        raise ValueError('param not valid')
Beispiel #28
0
    plt.close()


# Create `DiscreteLp` space for volume data
vol_shape = (100, 110)
discr_vol_space = odl.uniform_discr([-1, -1.1], [1, 1.1],
                                    vol_shape,
                                    dtype='float32')

# Create an element in the volume space
discr_vol_data = odl.util.phantom.cuboid(discr_vol_space, 0.2, 0.3)

save_slice(discr_vol_data, 'phantom 2d cpu')

# Angles
angle_intvl = odl.Interval(0, 2 * np.pi)
angle_grid = odl.uniform_sampling(angle_intvl, 180)

# Detector
dparams = odl.Interval(-2, 2)
det_grid = odl.uniform_sampling(dparams, 100)

# Create geometry instances for the projection space parameter
geom = odl.tomo.Parallel2dGeometry(angle_intvl, dparams, angle_grid, det_grid)

# Projection space
proj_space = odl.FunctionSpace(geom.params)

# `DiscreteLp` projection space
discr_proj_space = odl.uniform_discr_fromspace(proj_space,
                                               geom.grid.shape,