summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Wrappers/Python/ccpi/astra/astra_ops.py4
-rw-r--r--Wrappers/Python/ccpi/astra/astra_processors.py32
-rw-r--r--Wrappers/Python/ccpi/astra/astra_utils.py20
-rw-r--r--Wrappers/Python/ccpi/framework.py12
-rwxr-xr-xWrappers/Python/conda-recipe/run_test.py167
-rwxr-xr-xWrappers/Python/wip/simple_mc_demo.py1
6 files changed, 202 insertions, 34 deletions
diff --git a/Wrappers/Python/ccpi/astra/astra_ops.py b/Wrappers/Python/ccpi/astra/astra_ops.py
index c409529..5f25eec 100644
--- a/Wrappers/Python/ccpi/astra/astra_ops.py
+++ b/Wrappers/Python/ccpi/astra/astra_ops.py
@@ -17,9 +17,11 @@
from ccpi.reconstruction.ops import Operator
import numpy
+import astra
from ccpi.framework import AcquisitionData, ImageData
from ccpi.reconstruction.ops import PowerMethodNonsquare
-from ccpi.astra.astra_processors import *
+from ccpi.astra.astra_processors import AstraForwardProjector, AstraBackProjector, \
+ AstraForwardProjectorMC, AstraBackProjectorMC
class AstraProjectorSimple(Operator):
"""ASTRA projector modified to use DataSet and geometry."""
diff --git a/Wrappers/Python/ccpi/astra/astra_processors.py b/Wrappers/Python/ccpi/astra/astra_processors.py
index bf6048b..3de43bf 100644
--- a/Wrappers/Python/ccpi/astra/astra_processors.py
+++ b/Wrappers/Python/ccpi/astra/astra_processors.py
@@ -28,8 +28,8 @@ class AstraForwardProjector(DataSetProcessor):
#DataSetProcessor.__init__(self, **kwargs)
super(AstraForwardProjector, self).__init__(**kwargs)
- self.setVolumeGeometry(volume_geometry)
- self.setSinogramGeometry(sinogram_geometry)
+ self.set_ImageGeometry(volume_geometry)
+ self.set_AcquisitionGeometry(sinogram_geometry)
# Set up ASTRA Volume and projection geometry, not to be stored in self
vol_geom, proj_geom = convert_geometry_to_astra(self.volume_geometry,
@@ -39,13 +39,13 @@ class AstraForwardProjector(DataSetProcessor):
if device == 'cpu':
# Note that 'line' only one option
if self.sinogram_geometry.geom_type == 'parallel':
- self.setProjector(astra.create_projector('line', proj_geom, vol_geom) )
+ self.set_projector(astra.create_projector('line', proj_geom, vol_geom) )
elif self.sinogram_geometry.geom_type == 'cone':
- self.setProjector(astra.create_projector('line_fanflat', proj_geom, vol_geom) )
+ self.set_projector(astra.create_projector('line_fanflat', proj_geom, vol_geom) )
else:
NotImplemented
elif device == 'gpu':
- self.setProjector(astra.create_projector('cuda', proj_geom, vol_geom) )
+ self.set_projector(astra.create_projector('cuda', proj_geom, vol_geom) )
else:
NotImplemented
@@ -57,13 +57,13 @@ class AstraForwardProjector(DataSetProcessor):
raise ValueError("Expected input dimensions is 2 or 3, got {0}"\
.format(dataset.number_of_dimensions))
- def setProjector(self, proj_id):
+ def set_projector(self, proj_id):
self.proj_id = proj_id
- def setVolumeGeometry(self, volume_geometry):
+ def set_ImageGeometry(self, volume_geometry):
self.volume_geometry = volume_geometry
- def setSinogramGeometry(self, sinogram_geometry):
+ def set_AcquisitionGeometry(self, sinogram_geometry):
self.sinogram_geometry = sinogram_geometry
def process(self):
@@ -102,8 +102,8 @@ class AstraBackProjector(DataSetProcessor):
#DataSetProcessor.__init__(self, **kwargs)
super(AstraBackProjector, self).__init__(**kwargs)
- self.setVolumeGeometry(volume_geometry)
- self.setSinogramGeometry(sinogram_geometry)
+ self.set_ImageGeometry(volume_geometry)
+ self.set_AcquisitionGeometry(sinogram_geometry)
# Set up ASTRA Volume and projection geometry, not to be stored in self
vol_geom, proj_geom = convert_geometry_to_astra(self.volume_geometry,
@@ -113,13 +113,13 @@ class AstraBackProjector(DataSetProcessor):
if device == 'cpu':
# Note that 'line' only one option
if self.sinogram_geometry.geom_type == 'parallel':
- self.setProjector(astra.create_projector('line', proj_geom, vol_geom) )
+ self.set_projector(astra.create_projector('line', proj_geom, vol_geom) )
elif self.sinogram_geometry.geom_type == 'cone':
- self.setProjector(astra.create_projector('line_fanflat', proj_geom, vol_geom) )
+ self.set_projector(astra.create_projector('line_fanflat', proj_geom, vol_geom) )
else:
NotImplemented
elif device == 'gpu':
- self.setProjector(astra.create_projector('cuda', proj_geom, vol_geom) )
+ self.set_projector(astra.create_projector('cuda', proj_geom, vol_geom) )
else:
NotImplemented
@@ -130,13 +130,13 @@ class AstraBackProjector(DataSetProcessor):
raise ValueError("Expected input dimensions is 2 or 3, got {0}"\
.format(dataset.number_of_dimensions))
- def setProjector(self, proj_id):
+ def set_projector(self, proj_id):
self.proj_id = proj_id
- def setVolumeGeometry(self, volume_geometry):
+ def set_ImageGeometry(self, volume_geometry):
self.volume_geometry = volume_geometry
- def setSinogramGeometry(self, sinogram_geometry):
+ def set_AcquisitionGeometry(self, sinogram_geometry):
self.sinogram_geometry = sinogram_geometry
def process(self):
diff --git a/Wrappers/Python/ccpi/astra/astra_utils.py b/Wrappers/Python/ccpi/astra/astra_utils.py
index 8b5043a..dedb4fe 100644
--- a/Wrappers/Python/ccpi/astra/astra_utils.py
+++ b/Wrappers/Python/ccpi/astra/astra_utils.py
@@ -5,10 +5,10 @@ def convert_geometry_to_astra(volume_geometry, sinogram_geometry):
if sinogram_geometry.dimension == '2D':
vol_geom = astra.create_vol_geom(volume_geometry.voxel_num_x,
volume_geometry.voxel_num_y,
- volume_geometry.getMinX(),
- volume_geometry.getMaxX(),
- volume_geometry.getMinY(),
- volume_geometry.getMaxY())
+ volume_geometry.get_min_x(),
+ volume_geometry.get_max_x(),
+ volume_geometry.get_min_y(),
+ volume_geometry.get_max_y())
if sinogram_geometry.geom_type == 'parallel':
proj_geom = astra.create_proj_geom('parallel',
@@ -29,12 +29,12 @@ def convert_geometry_to_astra(volume_geometry, sinogram_geometry):
vol_geom = astra.create_vol_geom(volume_geometry.voxel_num_x,
volume_geometry.voxel_num_y,
volume_geometry.voxel_num_z,
- volume_geometry.getMinX(),
- volume_geometry.getMaxX(),
- volume_geometry.getMinY(),
- volume_geometry.getMaxY(),
- volume_geometry.getMinZ(),
- volume_geometry.getMaxZ())
+ volume_geometry.get_min_x(),
+ volume_geometry.get_max_x(),
+ volume_geometry.get_min_y(),
+ volume_geometry.get_max_y(),
+ volume_geometry.get_min_z(),
+ volume_geometry.get_max_z())
if sinogram_geometry.proj_geom == 'parallel':
proj_geom = astra.create_proj_geom('parallel3d',
diff --git a/Wrappers/Python/ccpi/framework.py b/Wrappers/Python/ccpi/framework.py
index 9b0cf54..877becf 100644
--- a/Wrappers/Python/ccpi/framework.py
+++ b/Wrappers/Python/ccpi/framework.py
@@ -59,25 +59,25 @@ class ImageGeometry:
self.center_z = center_z
self.channels = channels
- def getMinX(self):
+ def get_min_x(self):
return self.center_x - 0.5*self.voxel_num_x*self.voxel_size_x
- def getMaxX(self):
+ def get_max_x(self):
return self.center_x + 0.5*self.voxel_num_x*self.voxel_size_x
- def getMinY(self):
+ def get_min_y(self):
return self.center_y - 0.5*self.voxel_num_y*self.voxel_size_y
- def getMaxY(self):
+ def get_max_y(self):
return self.center_y + 0.5*self.voxel_num_y*self.voxel_size_y
- def getMinZ(self):
+ def get_min_z(self):
if not voxel_num_z == 0:
return self.center_z - 0.5*self.voxel_num_z*self.voxel_size_z
else:
return 0
- def getMaxZ(self):
+ def get_max_z(self):
if not voxel_num_z == 0:
return self.center_z + 0.5*self.voxel_num_z*self.voxel_size_z
else:
diff --git a/Wrappers/Python/conda-recipe/run_test.py b/Wrappers/Python/conda-recipe/run_test.py
new file mode 100755
index 0000000..6a20d05
--- /dev/null
+++ b/Wrappers/Python/conda-recipe/run_test.py
@@ -0,0 +1,167 @@
+import unittest
+import numpy
+from ccpi.framework import DataContainer, ImageData, AcquisitionData, \
+ ImageGeometry, AcquisitionGeometry
+import sys
+
+class TestDataContainer(unittest.TestCase):
+
+ def test_creation_nocopy(self):
+ shape = (2,3,4,5)
+ size = shape[0]
+ for i in range(1, len(shape)):
+ size = size * shape[i]
+ #print("a refcount " , sys.getrefcount(a))
+ a = numpy.asarray([i for i in range( size )])
+ #print("a refcount " , sys.getrefcount(a))
+ a = numpy.reshape(a, shape)
+ #print("a refcount " , sys.getrefcount(a))
+ ds = DataContainer(a, False, ['X', 'Y','Z' ,'W'])
+ #print("a refcount " , sys.getrefcount(a))
+ self.assertEqual(sys.getrefcount(a),3)
+ self.assertEqual(ds.dimension_labels , {0: 'X', 1: 'Y', 2: 'Z', 3: 'W'})
+
+ def test_creation_copy(self):
+ shape = (2,3,4,5)
+ size = shape[0]
+ for i in range(1, len(shape)):
+ size = size * shape[i]
+ #print("a refcount " , sys.getrefcount(a))
+ a = numpy.asarray([i for i in range( size )])
+ #print("a refcount " , sys.getrefcount(a))
+ a = numpy.reshape(a, shape)
+ #print("a refcount " , sys.getrefcount(a))
+ ds = DataContainer(a, True, ['X', 'Y','Z' ,'W'])
+ #print("a refcount " , sys.getrefcount(a))
+ self.assertEqual(sys.getrefcount(a),2)
+
+ def test_subset(self):
+ shape = (4,3,2)
+ a = [i for i in range(2*3*4)]
+ a = numpy.asarray(a)
+ a = numpy.reshape(a, shape)
+ ds = DataContainer(a, True, ['X', 'Y','Z'])
+ sub = ds.subset(['X'])
+ res = True
+ try:
+ numpy.testing.assert_array_equal(sub.as_array(),
+ numpy.asarray([0,6,12,18]))
+ except AssertionError as err:
+ res = False
+ print (err)
+ self.assertTrue(res)
+
+ sub = ds.subset(['X'], Y=2, Z=0)
+ res = True
+ try:
+ numpy.testing.assert_array_equal(sub.as_array(),
+ numpy.asarray([4,10,16,22]))
+ except AssertionError as err:
+ res = False
+ print (err)
+ self.assertTrue(res)
+
+
+ sub = ds.subset(['Y'])
+ try:
+ numpy.testing.assert_array_equal(
+ sub.as_array(), numpy.asarray([0,2,4]))
+ res = True
+ except AssertionError as err:
+ res = False
+ print (err)
+ self.assertTrue(res)
+
+
+ sub = ds.subset(['Z'])
+ try:
+ numpy.testing.assert_array_equal(
+ sub.as_array(), numpy.asarray([0,1]))
+ res = True
+ except AssertionError as err:
+ res = False
+ print (err)
+ self.assertTrue(res)
+ sub = ds.subset(['Z'], X=1, Y=2)
+ try:
+ numpy.testing.assert_array_equal(
+ sub.as_array(), numpy.asarray([10,11]))
+ res = True
+ except AssertionError as err:
+ res = False
+ print (err)
+ self.assertTrue(res)
+
+ print(a)
+ sub = ds.subset(['X', 'Y'] , Z=1)
+ res = True
+ try:
+ numpy.testing.assert_array_equal(sub.as_array(),
+ numpy.asarray([[ 1, 3, 5],
+ [ 7, 9, 11],
+ [13, 15, 17],
+ [19, 21, 23]]))
+ except AssertionError as err:
+ res = False
+ print (err)
+ self.assertTrue(res)
+
+ def test_ImageData(self):
+ # create ImageData from geometry
+ vgeometry = ImageGeometry(voxel_num_x=4, voxel_num_y=3, channels=2)
+ vol = ImageData(geometry=vgeometry)
+ self.assertEqual(vol.shape , (2,3,4))
+
+ vol1 = vol + 1
+ self.assertNumpyArrayEqual(vol1.as_array(), numpy.ones(vol.shape))
+
+ vol1 = vol - 1
+ self.assertNumpyArrayEqual(vol1.as_array(), -numpy.ones(vol.shape))
+
+ vol1 = 2 * (vol + 1)
+ self.assertNumpyArrayEqual(vol1.as_array(), 2 * numpy.ones(vol.shape))
+
+ vol1 = (vol + 1) / 2
+ self.assertNumpyArrayEqual(vol1.as_array(), numpy.ones(vol.shape) / 2 )
+
+ vol1 = vol + 1
+ self.assertEqual(vol1.sum() , 2*3*4)
+ vol1 = ( vol + 2 ) ** 2
+ self.assertNumpyArrayEqual(vol1.as_array(), numpy.ones(vol.shape) * 4 )
+
+
+
+ def test_AcquisitionData(self):
+ sgeometry = AcquisitionGeometry(dimension=2, angles=numpy.linspace(0, 180, num=10),
+ geom_type='parallel', pixel_num_v=3,
+ pixel_num_h=5 , channels=2)
+ sino = AcquisitionData(geometry=sgeometry)
+ self.assertEqual(sino.shape , (2,10,3,5))
+
+
+ def assertNumpyArrayEqual(self, first, second):
+ res = True
+ try:
+ numpy.testing.assert_array_equal(first, second)
+ except AssertionError as err:
+ res = False
+ print (err)
+ self.assertTrue(res)
+# =============================================================================
+# def test_upper(self):
+# self.assertEqual('foo'.upper(), 'FOO')
+#
+# def test_isupper(self):
+# self.assertTrue('FOO'.isupper())
+# self.assertFalse('Foo'.isupper())
+#
+# def test_split(self):
+# s = 'hello world'
+# self.assertEqual(s.split(), ['hello', 'world'])
+# # check that s.split fails when the separator is not a string
+# with self.assertRaises(TypeError):
+# s.split(2)
+# =============================================================================
+
+if __name__ == '__main__':
+ unittest.main() \ No newline at end of file
diff --git a/Wrappers/Python/wip/simple_mc_demo.py b/Wrappers/Python/wip/simple_mc_demo.py
index f15e704..f77a678 100755
--- a/Wrappers/Python/wip/simple_mc_demo.py
+++ b/Wrappers/Python/wip/simple_mc_demo.py
@@ -5,7 +5,6 @@ from ccpi.framework import ImageData, AcquisitionData, ImageGeometry, Acquisitio
from ccpi.reconstruction.algs import FISTA
from ccpi.reconstruction.funcs import Norm2sq, Norm1
from ccpi.astra.astra_ops import AstraProjectorMC
-from ccpi.reconstruction.geoms import VolumeGeometry, SinogramGeometry
import numpy
import matplotlib.pyplot as plt