summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Jorgensen, WS at HMXIF <jakob.jorgensen@manchester.ac.uk>2019-04-26 15:53:10 +0100
committerJakob Jorgensen, WS at HMXIF <jakob.jorgensen@manchester.ac.uk>2019-04-26 15:53:10 +0100
commit6f094f37fd2503e104a0477ac01d7a5b825d351a (patch)
treea62d3666505bf6d4ef31da9e7c4df9aa3c54fcaa
parent08ebddb9ef5b6e1061473deb0d1eebe1ed88beb7 (diff)
downloadastra-wrapper-6f094f37fd2503e104a0477ac01d7a5b825d351a.tar.gz
astra-wrapper-6f094f37fd2503e104a0477ac01d7a5b825d351a.tar.bz2
astra-wrapper-6f094f37fd2503e104a0477ac01d7a5b825d351a.tar.xz
astra-wrapper-6f094f37fd2503e104a0477ac01d7a5b825d351a.zip
Reorganise ops, processors and utils as directories
-rw-r--r--Wrappers/Python/ccpi/astra/operators/AstraProjector3DSimple.py75
-rw-r--r--Wrappers/Python/ccpi/astra/operators/AstraProjectorMC.py112
-rw-r--r--Wrappers/Python/ccpi/astra/operators/AstraProjectorSimple.py71
-rw-r--r--Wrappers/Python/ccpi/astra/operators/__init__.py4
-rwxr-xr-xWrappers/Python/ccpi/astra/ops.py249
-rw-r--r--Wrappers/Python/ccpi/astra/processors.py363
-rw-r--r--Wrappers/Python/ccpi/astra/processors/AstraBackProjector.py80
-rw-r--r--Wrappers/Python/ccpi/astra/processors/AstraBackProjector3D.py67
-rw-r--r--Wrappers/Python/ccpi/astra/processors/AstraBackProjectorMC.py40
-rw-r--r--Wrappers/Python/ccpi/astra/processors/AstraForwardProjector.py85
-rw-r--r--Wrappers/Python/ccpi/astra/processors/AstraForwardProjector3D.py72
-rw-r--r--Wrappers/Python/ccpi/astra/processors/AstraForwardProjectorMC.py42
-rw-r--r--Wrappers/Python/ccpi/astra/processors/__init__.py7
-rw-r--r--Wrappers/Python/ccpi/astra/utils/__init__.py2
-rw-r--r--[-rwxr-xr-x]Wrappers/Python/ccpi/astra/utils/convert_geometry_to_astra.py (renamed from Wrappers/Python/ccpi/astra/utils.py)0
-rwxr-xr-xWrappers/Python/setup.py6
-rwxr-xr-xWrappers/Python/wip/demo_astra_mc.py2
-rw-r--r--Wrappers/Python/wip/demo_astra_nexus.py2
-rwxr-xr-xWrappers/Python/wip/demo_astra_simple.py2
-rwxr-xr-xWrappers/Python/wip/demo_astra_sophiabeads.py2
-rw-r--r--Wrappers/Python/wip/demo_astra_sophiabeads3D.py2
-rw-r--r--Wrappers/Python/wip/work_out_adjoint.py2
-rw-r--r--Wrappers/Python/wip/work_out_adjoint3D.py2
-rw-r--r--Wrappers/Python/wip/work_out_adjoint_sophiabeads.py2
24 files changed, 670 insertions, 621 deletions
diff --git a/Wrappers/Python/ccpi/astra/operators/AstraProjector3DSimple.py b/Wrappers/Python/ccpi/astra/operators/AstraProjector3DSimple.py
new file mode 100644
index 0000000..3240ee4
--- /dev/null
+++ b/Wrappers/Python/ccpi/astra/operators/AstraProjector3DSimple.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+# This work is independent part of the Core Imaging Library developed by
+# Visual Analytics and Imaging System Group of the Science Technology
+# Facilities Council, STFC
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from ccpi.optimisation.operators import Operator, LinearOperator
+import numpy
+from ccpi.framework import AcquisitionData, ImageData, DataContainer
+from ccpi.optimisation.ops import PowerMethodNonsquare
+from ccpi.astra.processors import AstraForwardProjector, AstraBackProjector, \
+ AstraForwardProjector3D, AstraBackProjector3D
+
+class AstraProjector3DSimple(LinearOperator):
+ """ASTRA projector modified to use DataSet and geometry."""
+ def __init__(self, geomv, geomp):
+ super(AstraProjector3DSimple, self).__init__()
+
+ # Store volume and sinogram geometries.
+ self.sinogram_geometry = geomp
+ self.volume_geometry = geomv
+
+ self.fp = AstraForwardProjector3D(volume_geometry=geomv,
+ sinogram_geometry=geomp,
+ output_axes_order=['vertical','angle','horizontal'])
+
+ self.bp = AstraBackProjector3D(volume_geometry=geomv,
+ sinogram_geometry=geomp,
+ output_axes_order=['vertical','horizontal_y','horizontal_x'])
+
+ # Initialise empty for singular value.
+ self.s1 = None
+
+ def direct(self, IM):
+ self.fp.set_input(IM)
+ out = self.fp.get_output()
+ return out
+
+ def adjoint(self, DATA):
+ self.bp.set_input(DATA)
+ out = self.bp.get_output()
+ return out
+
+ #def delete(self):
+ # astra.data2d.delete(self.proj_id)
+
+ def get_max_sing_val(self):
+ self.s1, sall, svec = PowerMethodNonsquare(self,10)
+ return self.s1
+
+ def size(self):
+ # Only implemented for 2D
+ return ( (self.sinogram_geometry.angles.size, \
+ self.sinogram_geometry.pixel_num_h, \
+ self.sinogram_geometry.pixel_num_v,), \
+ (self.volume_geometry.voxel_num_x, \
+ self.volume_geometry.voxel_num_y, \
+ self.volume_geometry.voxel_num_z) )
+
+ def create_image_data(self):
+ inputsize = self.size()[1]
+ return DataContainer(numpy.random.randn(inputsize[2],
+ inputsize[1],
+ inputsize[0])) \ No newline at end of file
diff --git a/Wrappers/Python/ccpi/astra/operators/AstraProjectorMC.py b/Wrappers/Python/ccpi/astra/operators/AstraProjectorMC.py
new file mode 100644
index 0000000..51f51ca
--- /dev/null
+++ b/Wrappers/Python/ccpi/astra/operators/AstraProjectorMC.py
@@ -0,0 +1,112 @@
+# -*- coding: utf-8 -*-
+# This work is independent part of the Core Imaging Library developed by
+# Visual Analytics and Imaging System Group of the Science Technology
+# Facilities Council, STFC
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from ccpi.optimisation.operators import Operator, LinearOperator
+from ccpi.framework import AcquisitionData, ImageData, DataContainer
+from ccpi.optimisation.ops import PowerMethodNonsquare
+from ccpi.astra.processors import AstraForwardProjector, AstraBackProjector, \
+ AstraForwardProjectorMC, AstraBackProjectorMC, AstraForwardProjector3D, \
+ AstraBackProjector3D
+
+class AstraProjectorMC(LinearOperator):
+ """ASTRA Multichannel projector"""
+ def __init__(self, geomv, geomp, device):
+ super(AstraProjectorMC, self).__init__()
+
+ # Store volume and sinogram geometries.
+ self.sinogram_geometry = geomp
+ self.volume_geometry = geomv
+
+ self.fp = AstraForwardProjectorMC(volume_geometry=geomv,
+ sinogram_geometry=geomp,
+ proj_id=None,
+ device=device)
+
+ self.bp = AstraBackProjectorMC(volume_geometry=geomv,
+ sinogram_geometry=geomp,
+ proj_id=None,
+ device=device)
+
+ # Initialise empty for singular value.
+ self.s1 = None
+
+# def direct(self, IM):
+# self.fp.set_input(IM)
+# out = self.fp.get_output()
+# return out
+#
+# def adjoint(self, DATA):
+# self.bp.set_input(DATA)
+# out = self.bp.get_output()
+# return out
+
+
+ def direct(self, IM, out=None):
+ self.fp.set_input(IM)
+
+ if out is None:
+ return self.fp.get_output()
+ else:
+ out.fill(self.fp.get_output())
+
+ def adjoint(self, DATA, out=None):
+ self.bp.set_input(DATA)
+
+ if out is None:
+ return self.bp.get_output()
+ else:
+ out.fill(self.bp.get_output())
+
+ #def delete(self):
+ # astra.data2d.delete(self.proj_id)
+
+# def get_max_sing_val(self):
+# if self.s1 is None:
+# self.s1, sall, svec = PowerMethodNonsquare(self,10)
+# return self.s1
+# else:
+# return self.s1
+#
+# def size(self):
+# # Only implemented for 2D
+# return ( (self.sinogram_geometry.angles.size, \
+# self.sinogram_geometry.pixel_num_h), \
+# (self.volume_geometry.voxel_num_x, \
+# self.volume_geometry.voxel_num_y) )
+#
+# def create_image_data(self):
+# inputsize = self.size()[1]
+# return DataContainer(numpy.random.randn(self.volume_geometry.channels,
+# inputsize[0],
+# inputsize[1]))
+
+# def allocate_direct(self):
+# return self.create_image_data()def domain_geometry(self):
+# return self.volume_geometry
+
+ def domain_geometry(self):
+ return self.volume_geometry
+
+ def range_geometry(self):
+ return self.sinogram_geometry
+
+ def norm(self):
+
+ x0 = self.volume_geometry.allocate('random')
+ self.s1, sall, svec = PowerMethodNonsquare(self, 50, x0)
+ return self.s1
+ \ No newline at end of file
diff --git a/Wrappers/Python/ccpi/astra/operators/AstraProjectorSimple.py b/Wrappers/Python/ccpi/astra/operators/AstraProjectorSimple.py
new file mode 100644
index 0000000..b459e82
--- /dev/null
+++ b/Wrappers/Python/ccpi/astra/operators/AstraProjectorSimple.py
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+# This work is independent part of the Core Imaging Library developed by
+# Visual Analytics and Imaging System Group of the Science Technology
+# Facilities Council, STFC
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from ccpi.optimisation.operators import Operator, LinearOperator
+from ccpi.framework import AcquisitionData, ImageData, DataContainer
+from ccpi.optimisation.ops import PowerMethodNonsquare
+from ccpi.astra.processors import AstraForwardProjector, AstraBackProjector
+
+class AstraProjectorSimple(LinearOperator):
+ """ASTRA projector modified to use DataSet and geometry."""
+ def __init__(self, geomv, geomp, device):
+ super(AstraProjectorSimple, self).__init__()
+
+ # Store volume and sinogram geometries.
+ self.sinogram_geometry = geomp
+ self.volume_geometry = geomv
+
+ self.fp = AstraForwardProjector(volume_geometry=geomv,
+ sinogram_geometry=geomp,
+ proj_id=None,
+ device=device)
+
+ self.bp = AstraBackProjector(volume_geometry=geomv,
+ sinogram_geometry=geomp,
+ proj_id=None,
+ device=device)
+
+ # Initialise empty for singular value.
+ self.s1 = None
+
+ def direct(self, IM, out=None):
+ self.fp.set_input(IM)
+
+ if out is None:
+ return self.fp.get_output()
+ else:
+ out.fill(self.fp.get_output())
+
+ def adjoint(self, DATA, out=None):
+ self.bp.set_input(DATA)
+
+ if out is None:
+ return self.bp.get_output()
+ else:
+ out.fill(self.bp.get_output())
+
+ def domain_geometry(self):
+ return self.volume_geometry
+
+ def range_geometry(self):
+ return self.sinogram_geometry
+
+ def norm(self):
+
+ x0 = self.volume_geometry.allocate('random')
+ self.s1, sall, svec = PowerMethodNonsquare(self, 50, x0)
+ return self.s1 \ No newline at end of file
diff --git a/Wrappers/Python/ccpi/astra/operators/__init__.py b/Wrappers/Python/ccpi/astra/operators/__init__.py
new file mode 100644
index 0000000..6848776
--- /dev/null
+++ b/Wrappers/Python/ccpi/astra/operators/__init__.py
@@ -0,0 +1,4 @@
+
+from .AstraProjectorSimple import AstraProjectorSimple
+from .AstraProjector3DSimple import AstraProjector3DSimple
+from .AstraProjectorMC import AstraProjectorMC \ No newline at end of file
diff --git a/Wrappers/Python/ccpi/astra/ops.py b/Wrappers/Python/ccpi/astra/ops.py
deleted file mode 100755
index 3cc8453..0000000
--- a/Wrappers/Python/ccpi/astra/ops.py
+++ /dev/null
@@ -1,249 +0,0 @@
-# -*- coding: utf-8 -*-
-# This work is independent part of the Core Imaging Library developed by
-# Visual Analytics and Imaging System Group of the Science Technology
-# Facilities Council, STFC
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from ccpi.optimisation.operators import Operator, LinearOperator
-import numpy
-from ccpi.framework import AcquisitionData, ImageData, DataContainer
-from ccpi.optimisation.ops import PowerMethodNonsquare
-from ccpi.astra.processors import AstraForwardProjector, AstraBackProjector, \
- AstraForwardProjectorMC, AstraBackProjectorMC, AstraForwardProjector3D, \
- AstraBackProjector3D
-
-class AstraProjectorSimple(LinearOperator):
- """ASTRA projector modified to use DataSet and geometry."""
- def __init__(self, geomv, geomp, device):
- super(AstraProjectorSimple, self).__init__()
-
- # Store volume and sinogram geometries.
- self.sinogram_geometry = geomp
- self.volume_geometry = geomv
-
- self.fp = AstraForwardProjector(volume_geometry=geomv,
- sinogram_geometry=geomp,
- proj_id=None,
- device=device)
-
- self.bp = AstraBackProjector(volume_geometry=geomv,
- sinogram_geometry=geomp,
- proj_id=None,
- device=device)
-
- # Initialise empty for singular value.
- self.s1 = None
-
- def direct(self, IM, out=None):
- self.fp.set_input(IM)
-
- if out is None:
- return self.fp.get_output()
- else:
- out.fill(self.fp.get_output())
-
- def adjoint(self, DATA, out=None):
- self.bp.set_input(DATA)
-
- if out is None:
- return self.bp.get_output()
- else:
- out.fill(self.bp.get_output())
-
-
-
-# def direct(self, IM):
-# self.fp.set_input(IM)
-# out = self.fp.get_output()
-# return out
-#
-# def adjoint(self, DATA):
-# self.bp.set_input(DATA)
-# out = self.bp.get_output()
-# return out
-
- #def delete(self):
- # astra.data2d.delete(self.proj_id)
-
- #def get_max_sing_val(self):
- # self.s1, sall, svec = PowerMethodNonsquare(self,10)
- # return self.s1
-
- def domain_geometry(self):
- return self.volume_geometry
-
- def range_geometry(self):
- return self.sinogram_geometry
-
- def norm(self):
-
- x0 = self.volume_geometry.allocate('random')
- self.s1, sall, svec = PowerMethodNonsquare(self, 50, x0)
- return self.s1
-
- def size(self):
- # Only implemented for 2D
- return ( (self.sinogram_geometry.angles.size, \
- self.sinogram_geometry.pixel_num_h), \
- (self.volume_geometry.voxel_num_x, \
- self.volume_geometry.voxel_num_y) )
-
- #def create_image_data(self):
- # inputsize = self.size()[1]
- # return DataContainer(numpy.random.randn(inputsize[0],
- # inputsize[1]))
-
-class AstraProjector3DSimple(Operator):
- """ASTRA projector modified to use DataSet and geometry."""
- def __init__(self, geomv, geomp):
- super(AstraProjector3DSimple, self).__init__()
-
- # Store volume and sinogram geometries.
- self.sinogram_geometry = geomp
- self.volume_geometry = geomv
-
- self.fp = AstraForwardProjector3D(volume_geometry=geomv,
- sinogram_geometry=geomp,
- output_axes_order=['vertical','angle','horizontal'])
-
- self.bp = AstraBackProjector3D(volume_geometry=geomv,
- sinogram_geometry=geomp,
- output_axes_order=['vertical','horizontal_y','horizontal_x'])
-
- # Initialise empty for singular value.
- self.s1 = None
-
- def direct(self, IM):
- self.fp.set_input(IM)
- out = self.fp.get_output()
- return out
-
- def adjoint(self, DATA):
- self.bp.set_input(DATA)
- out = self.bp.get_output()
- return out
-
- #def delete(self):
- # astra.data2d.delete(self.proj_id)
-
- def get_max_sing_val(self):
- self.s1, sall, svec = PowerMethodNonsquare(self,10)
- return self.s1
-
- def size(self):
- # Only implemented for 2D
- return ( (self.sinogram_geometry.angles.size, \
- self.sinogram_geometry.pixel_num_h, \
- self.sinogram_geometry.pixel_num_v,), \
- (self.volume_geometry.voxel_num_x, \
- self.volume_geometry.voxel_num_y, \
- self.volume_geometry.voxel_num_z) )
-
- def create_image_data(self):
- inputsize = self.size()[1]
- return DataContainer(numpy.random.randn(inputsize[2],
- inputsize[1],
- inputsize[0]))
-
-
-class AstraProjectorMC(LinearOperator):
- """ASTRA Multichannel projector"""
- def __init__(self, geomv, geomp, device):
- super(AstraProjectorMC, self).__init__()
-
- # Store volume and sinogram geometries.
- self.sinogram_geometry = geomp
- self.volume_geometry = geomv
-
- self.fp = AstraForwardProjectorMC(volume_geometry=geomv,
- sinogram_geometry=geomp,
- proj_id=None,
- device=device)
-
- self.bp = AstraBackProjectorMC(volume_geometry=geomv,
- sinogram_geometry=geomp,
- proj_id=None,
- device=device)
-
- # Initialise empty for singular value.
- self.s1 = None
-
-# def direct(self, IM):
-# self.fp.set_input(IM)
-# out = self.fp.get_output()
-# return out
-#
-# def adjoint(self, DATA):
-# self.bp.set_input(DATA)
-# out = self.bp.get_output()
-# return out
-
-
- def direct(self, IM, out=None):
- self.fp.set_input(IM)
-
- if out is None:
- return self.fp.get_output()
- else:
- out.fill(self.fp.get_output())
-
- def adjoint(self, DATA, out=None):
- self.bp.set_input(DATA)
-
- if out is None:
- return self.bp.get_output()
- else:
- out.fill(self.bp.get_output())
-
- #def delete(self):
- # astra.data2d.delete(self.proj_id)
-
-# def get_max_sing_val(self):
-# if self.s1 is None:
-# self.s1, sall, svec = PowerMethodNonsquare(self,10)
-# return self.s1
-# else:
-# return self.s1
-#
-# def size(self):
-# # Only implemented for 2D
-# return ( (self.sinogram_geometry.angles.size, \
-# self.sinogram_geometry.pixel_num_h), \
-# (self.volume_geometry.voxel_num_x, \
-# self.volume_geometry.voxel_num_y) )
-#
-# def create_image_data(self):
-# inputsize = self.size()[1]
-# return DataContainer(numpy.random.randn(self.volume_geometry.channels,
-# inputsize[0],
-# inputsize[1]))
-
-# def allocate_direct(self):
-# return self.create_image_data()def domain_geometry(self):
-# return self.volume_geometry
-
- def domain_geometry(self):
- return self.volume_geometry
-
- def range_geometry(self):
- return self.sinogram_geometry
-
- def norm(self):
-
- x0 = self.volume_geometry.allocate('random')
- self.s1, sall, svec = PowerMethodNonsquare(self, 50, x0)
- return self.s1
-
-
-
diff --git a/Wrappers/Python/ccpi/astra/processors.py b/Wrappers/Python/ccpi/astra/processors.py
deleted file mode 100644
index 855f890..0000000
--- a/Wrappers/Python/ccpi/astra/processors.py
+++ /dev/null
@@ -1,363 +0,0 @@
-from ccpi.framework import DataProcessor, ImageData, AcquisitionData
-from ccpi.astra.utils import convert_geometry_to_astra
-import astra
-
-
-class AstraForwardProjector(DataProcessor):
- '''AstraForwardProjector
-
- Forward project ImageData to AcquisitionData using ASTRA proj_id.
-
- Input: ImageData
- Parameter: proj_id
- Output: AcquisitionData
- '''
-
- def __init__(self,
- volume_geometry=None,
- sinogram_geometry=None,
- proj_id=None,
- device='cpu'):
- kwargs = {
- 'volume_geometry' : volume_geometry,
- 'sinogram_geometry' : sinogram_geometry,
- 'proj_id' : proj_id,
- 'device' : device
- }
-
- #DataProcessor.__init__(self, **kwargs)
- super(AstraForwardProjector, self).__init__(**kwargs)
-
- 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,
- self.sinogram_geometry)
-
- # ASTRA projector, to be stored
- if device == 'cpu':
- # Note that 'line' only one option
- if self.sinogram_geometry.geom_type == 'parallel':
- self.set_projector(astra.create_projector('line', proj_geom, vol_geom) )
- elif self.sinogram_geometry.geom_type == 'cone':
- self.set_projector(astra.create_projector('line_fanflat', proj_geom, vol_geom) )
- else:
- NotImplemented
- elif device == 'gpu':
- self.set_projector(astra.create_projector('cuda', proj_geom, vol_geom) )
- else:
- NotImplemented
-
- def check_input(self, dataset):
- if dataset.number_of_dimensions == 3 or\
- dataset.number_of_dimensions == 2:
- return True
- else:
- raise ValueError("Expected input dimensions is 2 or 3, got {0}"\
- .format(dataset.number_of_dimensions))
-
- def set_projector(self, proj_id):
- self.proj_id = proj_id
-
- def set_ImageGeometry(self, volume_geometry):
- self.volume_geometry = volume_geometry
-
- def set_AcquisitionGeometry(self, sinogram_geometry):
- self.sinogram_geometry = sinogram_geometry
-
- def process(self):
- IM = self.get_input()
- DATA = AcquisitionData(geometry=self.sinogram_geometry)
- #sinogram_id, DATA = astra.create_sino( IM.as_array(),
- # self.proj_id)
- sinogram_id, DATA.array = astra.create_sino(IM.as_array(),
- self.proj_id)
- astra.data2d.delete(sinogram_id)
-
- if self.device == 'cpu':
- return DATA
- else:
- if self.sinogram_geometry.geom_type == 'cone':
- return DATA
- else:
- scaling = 1.0/self.volume_geometry.voxel_size_x
- return scaling*DATA
-
-class AstraBackProjector(DataProcessor):
- '''AstraBackProjector
-
- Back project AcquisitionData to ImageData using ASTRA proj_id.
-
- Input: AcquisitionData
- Parameter: proj_id
- Output: ImageData
- '''
-
- def __init__(self,
- volume_geometry=None,
- sinogram_geometry=None,
- proj_id=None,
- device='cpu'):
- kwargs = {
- 'volume_geometry' : volume_geometry,
- 'sinogram_geometry' : sinogram_geometry,
- 'proj_id' : proj_id,
- 'device' : device
- }
-
- #DataProcessor.__init__(self, **kwargs)
- super(AstraBackProjector, self).__init__(**kwargs)
-
- 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,
- self.sinogram_geometry)
-
- # ASTRA projector, to be stored
- if device == 'cpu':
- # Note that 'line' only one option
- if self.sinogram_geometry.geom_type == 'parallel':
- self.set_projector(astra.create_projector('line', proj_geom, vol_geom) )
- elif self.sinogram_geometry.geom_type == 'cone':
- self.set_projector(astra.create_projector('line_fanflat', proj_geom, vol_geom) )
- else:
- NotImplemented
- elif device == 'gpu':
- self.set_projector(astra.create_projector('cuda', proj_geom, vol_geom) )
- else:
- NotImplemented
-
- def check_input(self, dataset):
- if dataset.number_of_dimensions == 3 or dataset.number_of_dimensions == 2:
- return True
- else:
- raise ValueError("Expected input dimensions is 2 or 3, got {0}"\
- .format(dataset.number_of_dimensions))
-
- def set_projector(self, proj_id):
- self.proj_id = proj_id
-
- def set_ImageGeometry(self, volume_geometry):
- self.volume_geometry = volume_geometry
-
- def set_AcquisitionGeometry(self, sinogram_geometry):
- self.sinogram_geometry = sinogram_geometry
-
- def process(self):
- DATA = self.get_input()
- IM = ImageData(geometry=self.volume_geometry)
- rec_id, IM.array = astra.create_backprojection(DATA.as_array(),
- self.proj_id)
- astra.data2d.delete(rec_id)
-
- if self.device == 'cpu':
- return IM
- else:
- scaling = self.volume_geometry.voxel_size_x**3
- return scaling*IM
-
-class AstraForwardProjectorMC(AstraForwardProjector):
- '''AstraForwardProjector Multi channel
-
- Forward project ImageData to AcquisitionDataSet using ASTRA proj_id.
-
- Input: ImageDataSet
- Parameter: proj_id
- Output: AcquisitionData
- '''
- def check_input(self, dataset):
- if dataset.number_of_dimensions == 2 or \
- dataset.number_of_dimensions == 3 or \
- dataset.number_of_dimensions == 4:
- return True
- else:
- raise ValueError("Expected input dimensions is 2 or 3, got {0}"\
- .format(dataset.number_of_dimensions))
- def process(self):
- IM = self.get_input()
- #create the output AcquisitionData
- DATA = AcquisitionData(geometry=self.sinogram_geometry)
-
- for k in range(DATA.geometry.channels):
- sinogram_id, DATA.as_array()[k] = astra.create_sino(IM.as_array()[k],
- self.proj_id)
- astra.data2d.delete(sinogram_id)
-
- if self.device == 'cpu':
- return DATA
- else:
- if self.sinogram_geometry.geom_type == 'cone':
- return DATA
- else:
- scaling = (1.0/self.volume_geometry.voxel_size_x)
- return scaling*DATA
-
-class AstraBackProjectorMC(AstraBackProjector):
- '''AstraBackProjector Multi channel
-
- Back project AcquisitionData to ImageData using ASTRA proj_id.
-
- Input: AcquisitionData
- Parameter: proj_id
- Output: ImageData
- '''
- def check_input(self, dataset):
- if dataset.number_of_dimensions == 2 or \
- dataset.number_of_dimensions == 3 or \
- dataset.number_of_dimensions == 4:
- return True
- else:
- raise ValueError("Expected input dimensions is 2 or 3, got {0}"\
- .format(dataset.number_of_dimensions))
- def process(self):
- DATA = self.get_input()
-
- IM = ImageData(geometry=self.volume_geometry)
-
- for k in range(IM.geometry.channels):
- rec_id, IM.as_array()[k] = astra.create_backprojection(
- DATA.as_array()[k],
- self.proj_id)
- astra.data2d.delete(rec_id)
-
- if self.device == 'cpu':
- return IM
- else:
- scaling = self.volume_geometry.voxel_size_x**3
- return scaling*IM
-
-class AstraForwardProjector3D(DataProcessor):
- '''AstraForwardProjector3D
-
- Forward project ImageData to AcquisitionData using ASTRA proj_geom and
- vol_geom.
-
- Input: ImageData
- Parameter: proj_geom, vol_geom
- Output: AcquisitionData
- '''
-
- def __init__(self,
- volume_geometry=None,
- sinogram_geometry=None,
- proj_geom=None,
- vol_geom=None,
- output_axes_order=None):
- kwargs = {
- 'volume_geometry' : volume_geometry,
- 'sinogram_geometry' : sinogram_geometry,
- 'proj_geom' : proj_geom,
- 'vol_geom' : vol_geom,
- 'output_axes_order' : output_axes_order
- }
-
- #DataProcessor.__init__(self, **kwargs)
- super(AstraForwardProjector3D, self).__init__(**kwargs)
-
- 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,
- self.sinogram_geometry)
-
- # Also store ASTRA geometries
- self.vol_geom = vol_geom
- self.proj_geom = proj_geom
-
- def check_input(self, dataset):
- if dataset.number_of_dimensions == 3:
- return True
- else:
- raise ValueError("Expected input dimensions 3, got {0}"\
- .format(dataset.number_of_dimensions))
-
- def set_ImageGeometry(self, volume_geometry):
- self.volume_geometry = volume_geometry
-
- def set_AcquisitionGeometry(self, sinogram_geometry):
- self.sinogram_geometry = sinogram_geometry
-
- def set_vol_geom(self, vol_geom):
- self.vol_geom = vol_geom
-
- def set_AcquisitionGeometry(self, sinogram_geometry):
- self.sinogram_geometry = sinogram_geometry
-
- def process(self):
- IM = self.get_input()
- DATA = AcquisitionData(geometry=self.sinogram_geometry,
- dimension_labels=self.output_axes_order)
- sinogram_id, DATA.array = astra.create_sino3d_gpu(IM.as_array(),
- self.proj_geom,
- self.vol_geom)
- astra.data3d.delete(sinogram_id)
- # 3D CUDA FP does not need scaling
- return DATA
-
-class AstraBackProjector3D(DataProcessor):
- '''AstraBackProjector3D
-
- Back project AcquisitionData to ImageData using ASTRA proj_geom, vol_geom.
-
- Input: AcquisitionData
- Parameter: proj_geom, vol_geom
- Output: ImageData
- '''
-
- def __init__(self,
- volume_geometry=None,
- sinogram_geometry=None,
- proj_geom=None,
- vol_geom=None,
- output_axes_order=None):
- kwargs = {
- 'volume_geometry' : volume_geometry,
- 'sinogram_geometry' : sinogram_geometry,
- 'proj_geom' : proj_geom,
- 'vol_geom' : vol_geom,
- 'output_axes_order' : output_axes_order
- }
-
- #DataProcessor.__init__(self, **kwargs)
- super(AstraBackProjector3D, self).__init__(**kwargs)
-
- 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,
- self.sinogram_geometry)
-
- # Also store ASTRA geometries
- self.vol_geom = vol_geom
- self.proj_geom = proj_geom
-
- def check_input(self, dataset):
- if dataset.number_of_dimensions == 3:
- return True
- else:
- raise ValueError("Expected input dimensions is 3, got {0}"\
- .format(dataset.number_of_dimensions))
-
- def set_ImageGeometry(self, volume_geometry):
- self.volume_geometry = volume_geometry
-
- def set_AcquisitionGeometry(self, sinogram_geometry):
- self.sinogram_geometry = sinogram_geometry
-
- def process(self):
- DATA = self.get_input()
- IM = ImageData(geometry=self.volume_geometry,
- dimension_labels=self.output_axes_order)
- rec_id, IM.array = astra.create_backprojection3d_gpu(DATA.as_array(),
- self.proj_geom,
- self.vol_geom)
- astra.data3d.delete(rec_id)
-
- # Scaling of 3D ASTRA backprojector, works both parallel and cone.
- scaling = 1/self.volume_geometry.voxel_size_x**2
- return scaling*IM
diff --git a/Wrappers/Python/ccpi/astra/processors/AstraBackProjector.py b/Wrappers/Python/ccpi/astra/processors/AstraBackProjector.py
new file mode 100644
index 0000000..476523a
--- /dev/null
+++ b/Wrappers/Python/ccpi/astra/processors/AstraBackProjector.py
@@ -0,0 +1,80 @@
+from ccpi.framework import DataProcessor, ImageData, AcquisitionData
+from ccpi.astra.utils import convert_geometry_to_astra
+import astra
+
+
+class AstraBackProjector(DataProcessor):
+ '''AstraBackProjector
+
+ Back project AcquisitionData to ImageData using ASTRA proj_id.
+
+ Input: AcquisitionData
+ Parameter: proj_id
+ Output: ImageData
+ '''
+
+ def __init__(self,
+ volume_geometry=None,
+ sinogram_geometry=None,
+ proj_id=None,
+ device='cpu'):
+ kwargs = {
+ 'volume_geometry' : volume_geometry,
+ 'sinogram_geometry' : sinogram_geometry,
+ 'proj_id' : proj_id,
+ 'device' : device
+ }
+
+ #DataProcessor.__init__(self, **kwargs)
+ super(AstraBackProjector, self).__init__(**kwargs)
+
+ 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,
+ self.sinogram_geometry)
+
+ # ASTRA projector, to be stored
+ if device == 'cpu':
+ # Note that 'line' only one option
+ if self.sinogram_geometry.geom_type == 'parallel':
+ self.set_projector(astra.create_projector('line', proj_geom, vol_geom) )
+ elif self.sinogram_geometry.geom_type == 'cone':
+ self.set_projector(astra.create_projector('line_fanflat', proj_geom, vol_geom) )
+ else:
+ NotImplemented
+ elif device == 'gpu':
+ self.set_projector(astra.create_projector('cuda', proj_geom, vol_geom) )
+ else:
+ NotImplemented
+
+ def check_input(self, dataset):
+ if dataset.number_of_dimensions == 3 or dataset.number_of_dimensions == 2:
+ return True
+ else:
+ raise ValueError("Expected input dimensions is 2 or 3, got {0}"\
+ .format(dataset.number_of_dimensions))
+
+ def set_projector(self, proj_id):
+ self.proj_id = proj_id
+
+ def set_ImageGeometry(self, volume_geometry):
+ self.volume_geometry = volume_geometry
+
+ def set_AcquisitionGeometry(self, sinogram_geometry):
+ self.sinogram_geometry = sinogram_geometry
+
+ def process(self):
+ DATA = self.get_input()
+ IM = ImageData(geometry=self.volume_geometry)
+ rec_id, IM.array = astra.create_backprojection(DATA.as_array(),
+ self.proj_id)
+ astra.data2d.delete(rec_id)
+
+ if self.device == 'cpu':
+ return IM
+ else:
+ scaling = self.volume_geometry.voxel_size_x**3
+ return scaling*IM
+ \ No newline at end of file
diff --git a/Wrappers/Python/ccpi/astra/processors/AstraBackProjector3D.py b/Wrappers/Python/ccpi/astra/processors/AstraBackProjector3D.py
new file mode 100644
index 0000000..b1d139e
--- /dev/null
+++ b/Wrappers/Python/ccpi/astra/processors/AstraBackProjector3D.py
@@ -0,0 +1,67 @@
+from ccpi.framework import DataProcessor, ImageData, AcquisitionData
+from ccpi.astra.utils import convert_geometry_to_astra
+import astra
+
+class AstraBackProjector3D(DataProcessor):
+ '''AstraBackProjector3D
+
+ Back project AcquisitionData to ImageData using ASTRA proj_geom, vol_geom.
+
+ Input: AcquisitionData
+ Parameter: proj_geom, vol_geom
+ Output: ImageData
+ '''
+
+ def __init__(self,
+ volume_geometry=None,
+ sinogram_geometry=None,
+ proj_geom=None,
+ vol_geom=None,
+ output_axes_order=None):
+ kwargs = {
+ 'volume_geometry' : volume_geometry,
+ 'sinogram_geometry' : sinogram_geometry,
+ 'proj_geom' : proj_geom,
+ 'vol_geom' : vol_geom,
+ 'output_axes_order' : output_axes_order
+ }
+
+ #DataProcessor.__init__(self, **kwargs)
+ super(AstraBackProjector3D, self).__init__(**kwargs)
+
+ 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,
+ self.sinogram_geometry)
+
+ # Also store ASTRA geometries
+ self.vol_geom = vol_geom
+ self.proj_geom = proj_geom
+
+ def check_input(self, dataset):
+ if dataset.number_of_dimensions == 3:
+ return True
+ else:
+ raise ValueError("Expected input dimensions is 3, got {0}"\
+ .format(dataset.number_of_dimensions))
+
+ def set_ImageGeometry(self, volume_geometry):
+ self.volume_geometry = volume_geometry
+
+ def set_AcquisitionGeometry(self, sinogram_geometry):
+ self.sinogram_geometry = sinogram_geometry
+
+ def process(self):
+ DATA = self.get_input()
+ IM = ImageData(geometry=self.volume_geometry,
+ dimension_labels=self.output_axes_order)
+ rec_id, IM.array = astra.create_backprojection3d_gpu(DATA.as_array(),
+ self.proj_geom,
+ self.vol_geom)
+ astra.data3d.delete(rec_id)
+
+ # Scaling of 3D ASTRA backprojector, works both parallel and cone.
+ scaling = 1/self.volume_geometry.voxel_size_x**2
+ return scaling*IM
diff --git a/Wrappers/Python/ccpi/astra/processors/AstraBackProjectorMC.py b/Wrappers/Python/ccpi/astra/processors/AstraBackProjectorMC.py
new file mode 100644
index 0000000..d48fb80
--- /dev/null
+++ b/Wrappers/Python/ccpi/astra/processors/AstraBackProjectorMC.py
@@ -0,0 +1,40 @@
+from ccpi.framework import DataProcessor, ImageData, AcquisitionData
+from ccpi.astra.utils import convert_geometry_to_astra
+
+from ccpi.astra.processors import AstraBackProjector
+
+import astra
+
+class AstraBackProjectorMC(AstraBackProjector):
+ '''AstraBackProjector Multi channel
+
+ Back project AcquisitionData to ImageData using ASTRA proj_id.
+
+ Input: AcquisitionData
+ Parameter: proj_id
+ Output: ImageData
+ '''
+ def check_input(self, dataset):
+ if dataset.number_of_dimensions == 2 or \
+ dataset.number_of_dimensions == 3 or \
+ dataset.number_of_dimensions == 4:
+ return True
+ else:
+ raise ValueError("Expected input dimensions is 2 or 3, got {0}"\
+ .format(dataset.number_of_dimensions))
+ def process(self):
+ DATA = self.get_input()
+
+ IM = ImageData(geometry=self.volume_geometry)
+
+ for k in range(IM.geometry.channels):
+ rec_id, IM.as_array()[k] = astra.create_backprojection(
+ DATA.as_array()[k],
+ self.proj_id)
+ astra.data2d.delete(rec_id)
+
+ if self.device == 'cpu':
+ return IM
+ else:
+ scaling = self.volume_geometry.voxel_size_x**3
+ return scaling*IM \ No newline at end of file
diff --git a/Wrappers/Python/ccpi/astra/processors/AstraForwardProjector.py b/Wrappers/Python/ccpi/astra/processors/AstraForwardProjector.py
new file mode 100644
index 0000000..dd5bab4
--- /dev/null
+++ b/Wrappers/Python/ccpi/astra/processors/AstraForwardProjector.py
@@ -0,0 +1,85 @@
+from ccpi.framework import DataProcessor, ImageData, AcquisitionData
+from ccpi.astra.utils import convert_geometry_to_astra
+import astra
+
+
+class AstraForwardProjector(DataProcessor):
+ '''AstraForwardProjector
+
+ Forward project ImageData to AcquisitionData using ASTRA proj_id.
+
+ Input: ImageData
+ Parameter: proj_id
+ Output: AcquisitionData
+ '''
+
+ def __init__(self,
+ volume_geometry=None,
+ sinogram_geometry=None,
+ proj_id=None,
+ device='cpu'):
+ kwargs = {
+ 'volume_geometry' : volume_geometry,
+ 'sinogram_geometry' : sinogram_geometry,
+ 'proj_id' : proj_id,
+ 'device' : device
+ }
+
+ #DataProcessor.__init__(self, **kwargs)
+ super(AstraForwardProjector, self).__init__(**kwargs)
+
+ 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,
+ self.sinogram_geometry)
+
+ # ASTRA projector, to be stored
+ if device == 'cpu':
+ # Note that 'line' only one option
+ if self.sinogram_geometry.geom_type == 'parallel':
+ self.set_projector(astra.create_projector('line', proj_geom, vol_geom) )
+ elif self.sinogram_geometry.geom_type == 'cone':
+ self.set_projector(astra.create_projector('line_fanflat', proj_geom, vol_geom) )
+ else:
+ NotImplemented
+ elif device == 'gpu':
+ self.set_projector(astra.create_projector('cuda', proj_geom, vol_geom) )
+ else:
+ NotImplemented
+
+ def check_input(self, dataset):
+ if dataset.number_of_dimensions == 3 or\
+ dataset.number_of_dimensions == 2:
+ return True
+ else:
+ raise ValueError("Expected input dimensions is 2 or 3, got {0}"\
+ .format(dataset.number_of_dimensions))
+
+ def set_projector(self, proj_id):
+ self.proj_id = proj_id
+
+ def set_ImageGeometry(self, volume_geometry):
+ self.volume_geometry = volume_geometry
+
+ def set_AcquisitionGeometry(self, sinogram_geometry):
+ self.sinogram_geometry = sinogram_geometry
+
+ def process(self):
+ IM = self.get_input()
+ DATA = AcquisitionData(geometry=self.sinogram_geometry)
+ #sinogram_id, DATA = astra.create_sino( IM.as_array(),
+ # self.proj_id)
+ sinogram_id, DATA.array = astra.create_sino(IM.as_array(),
+ self.proj_id)
+ astra.data2d.delete(sinogram_id)
+
+ if self.device == 'cpu':
+ return DATA
+ else:
+ if self.sinogram_geometry.geom_type == 'cone':
+ return DATA
+ else:
+ scaling = 1.0/self.volume_geometry.voxel_size_x
+ return scaling*DATA \ No newline at end of file
diff --git a/Wrappers/Python/ccpi/astra/processors/AstraForwardProjector3D.py b/Wrappers/Python/ccpi/astra/processors/AstraForwardProjector3D.py
new file mode 100644
index 0000000..d18b43e
--- /dev/null
+++ b/Wrappers/Python/ccpi/astra/processors/AstraForwardProjector3D.py
@@ -0,0 +1,72 @@
+from ccpi.framework import DataProcessor, ImageData, AcquisitionData
+from ccpi.astra.utils import convert_geometry_to_astra
+import astra
+
+class AstraForwardProjector3D(DataProcessor):
+ '''AstraForwardProjector3D
+
+ Forward project ImageData to AcquisitionData using ASTRA proj_geom and
+ vol_geom.
+
+ Input: ImageData
+ Parameter: proj_geom, vol_geom
+ Output: AcquisitionData
+ '''
+
+ def __init__(self,
+ volume_geometry=None,
+ sinogram_geometry=None,
+ proj_geom=None,
+ vol_geom=None,
+ output_axes_order=None):
+ kwargs = {
+ 'volume_geometry' : volume_geometry,
+ 'sinogram_geometry' : sinogram_geometry,
+ 'proj_geom' : proj_geom,
+ 'vol_geom' : vol_geom,
+ 'output_axes_order' : output_axes_order
+ }
+
+ #DataProcessor.__init__(self, **kwargs)
+ super(AstraForwardProjector3D, self).__init__(**kwargs)
+
+ 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,
+ self.sinogram_geometry)
+
+ # Also store ASTRA geometries
+ self.vol_geom = vol_geom
+ self.proj_geom = proj_geom
+
+ def check_input(self, dataset):
+ if dataset.number_of_dimensions == 3:
+ return True
+ else:
+ raise ValueError("Expected input dimensions 3, got {0}"\
+ .format(dataset.number_of_dimensions))
+
+ def set_ImageGeometry(self, volume_geometry):
+ self.volume_geometry = volume_geometry
+
+ def set_AcquisitionGeometry(self, sinogram_geometry):
+ self.sinogram_geometry = sinogram_geometry
+
+ def set_vol_geom(self, vol_geom):
+ self.vol_geom = vol_geom
+
+ def set_AcquisitionGeometry(self, sinogram_geometry):
+ self.sinogram_geometry = sinogram_geometry
+
+ def process(self):
+ IM = self.get_input()
+ DATA = AcquisitionData(geometry=self.sinogram_geometry,
+ dimension_labels=self.output_axes_order)
+ sinogram_id, DATA.array = astra.create_sino3d_gpu(IM.as_array(),
+ self.proj_geom,
+ self.vol_geom)
+ astra.data3d.delete(sinogram_id)
+ # 3D CUDA FP does not need scaling
+ return DATA \ No newline at end of file
diff --git a/Wrappers/Python/ccpi/astra/processors/AstraForwardProjectorMC.py b/Wrappers/Python/ccpi/astra/processors/AstraForwardProjectorMC.py
new file mode 100644
index 0000000..5a697ca
--- /dev/null
+++ b/Wrappers/Python/ccpi/astra/processors/AstraForwardProjectorMC.py
@@ -0,0 +1,42 @@
+from ccpi.framework import DataProcessor, ImageData, AcquisitionData
+from ccpi.astra.utils import convert_geometry_to_astra
+
+from ccpi.astra.processors import AstraForwardProjector
+
+import astra
+
+class AstraForwardProjectorMC(AstraForwardProjector):
+ '''AstraForwardProjector Multi channel
+
+ Forward project ImageData to AcquisitionDataSet using ASTRA proj_id.
+
+ Input: ImageDataSet
+ Parameter: proj_id
+ Output: AcquisitionData
+ '''
+ def check_input(self, dataset):
+ if dataset.number_of_dimensions == 2 or \
+ dataset.number_of_dimensions == 3 or \
+ dataset.number_of_dimensions == 4:
+ return True
+ else:
+ raise ValueError("Expected input dimensions is 2 or 3, got {0}"\
+ .format(dataset.number_of_dimensions))
+ def process(self):
+ IM = self.get_input()
+ #create the output AcquisitionData
+ DATA = AcquisitionData(geometry=self.sinogram_geometry)
+
+ for k in range(DATA.geometry.channels):
+ sinogram_id, DATA.as_array()[k] = astra.create_sino(IM.as_array()[k],
+ self.proj_id)
+ astra.data2d.delete(sinogram_id)
+
+ if self.device == 'cpu':
+ return DATA
+ else:
+ if self.sinogram_geometry.geom_type == 'cone':
+ return DATA
+ else:
+ scaling = (1.0/self.volume_geometry.voxel_size_x)
+ return scaling*DATA \ No newline at end of file
diff --git a/Wrappers/Python/ccpi/astra/processors/__init__.py b/Wrappers/Python/ccpi/astra/processors/__init__.py
new file mode 100644
index 0000000..6bfd7f5
--- /dev/null
+++ b/Wrappers/Python/ccpi/astra/processors/__init__.py
@@ -0,0 +1,7 @@
+
+from .AstraForwardProjector import AstraForwardProjector
+from .AstraBackProjector import AstraBackProjector
+from .AstraForwardProjectorMC import AstraForwardProjectorMC
+from .AstraBackProjectorMC import AstraBackProjectorMC
+from .AstraForwardProjector3D import AstraForwardProjector3D
+from .AstraBackProjector3D import AstraBackProjector3D
diff --git a/Wrappers/Python/ccpi/astra/utils/__init__.py b/Wrappers/Python/ccpi/astra/utils/__init__.py
new file mode 100644
index 0000000..c740fba
--- /dev/null
+++ b/Wrappers/Python/ccpi/astra/utils/__init__.py
@@ -0,0 +1,2 @@
+
+from .convert_geometry_to_astra import convert_geometry_to_astra \ No newline at end of file
diff --git a/Wrappers/Python/ccpi/astra/utils.py b/Wrappers/Python/ccpi/astra/utils/convert_geometry_to_astra.py
index 2b19305..2b19305 100755..100644
--- a/Wrappers/Python/ccpi/astra/utils.py
+++ b/Wrappers/Python/ccpi/astra/utils/convert_geometry_to_astra.py
diff --git a/Wrappers/Python/setup.py b/Wrappers/Python/setup.py
index 85dde19..e854dee 100755
--- a/Wrappers/Python/setup.py
+++ b/Wrappers/Python/setup.py
@@ -32,7 +32,11 @@ cil_version='0.12.0'
setup(
name="ccpi-astra",
version=cil_version,
- packages=['ccpi' , 'ccpi.astra'],
+ packages=['ccpi' ,
+ 'ccpi.astra',
+ 'ccpi.astra.operators',
+ 'ccpi.astra.processors',
+ 'ccpi.astra.utils'],
# Project uses reStructuredText, so ensure that the docutils get
# installed or upgraded on the target machine
diff --git a/Wrappers/Python/wip/demo_astra_mc.py b/Wrappers/Python/wip/demo_astra_mc.py
index f09dcb8..e5999de 100755
--- a/Wrappers/Python/wip/demo_astra_mc.py
+++ b/Wrappers/Python/wip/demo_astra_mc.py
@@ -8,7 +8,7 @@
from ccpi.framework import ImageData, AcquisitionData, ImageGeometry, AcquisitionGeometry
from ccpi.optimisation.algs import FISTA
from ccpi.optimisation.funcs import Norm2sq, Norm1
-from ccpi.astra.ops import AstraProjectorMC
+from ccpi.astra.operators import AstraProjectorMC
import numpy
import matplotlib.pyplot as plt
diff --git a/Wrappers/Python/wip/demo_astra_nexus.py b/Wrappers/Python/wip/demo_astra_nexus.py
index 1db44c0..7892d24 100644
--- a/Wrappers/Python/wip/demo_astra_nexus.py
+++ b/Wrappers/Python/wip/demo_astra_nexus.py
@@ -15,7 +15,7 @@ from ccpi.plugins.ops import CCPiProjectorSimple
from ccpi.processors import Normalizer, CenterOfRotationFinder
from ccpi.plugins.processors import AcquisitionDataPadder
from ccpi.io.reader import NexusReader
-from ccpi.astra.ops import AstraProjector3DSimple
+from ccpi.astra.operators import AstraProjector3DSimple
# All external imports
import numpy
diff --git a/Wrappers/Python/wip/demo_astra_simple.py b/Wrappers/Python/wip/demo_astra_simple.py
index c1dd877..57caaee 100755
--- a/Wrappers/Python/wip/demo_astra_simple.py
+++ b/Wrappers/Python/wip/demo_astra_simple.py
@@ -8,7 +8,7 @@
from ccpi.framework import ImageData , ImageGeometry, AcquisitionGeometry
from ccpi.optimisation.algs import FISTA, FBPD, CGLS
from ccpi.optimisation.funcs import Norm2sq, Norm1, TV2D
-from ccpi.astra.ops import AstraProjectorSimple
+from ccpi.astra.operators import AstraProjectorSimple
import numpy as np
import matplotlib.pyplot as plt
diff --git a/Wrappers/Python/wip/demo_astra_sophiabeads.py b/Wrappers/Python/wip/demo_astra_sophiabeads.py
index bcc775e..b72a5f9 100755
--- a/Wrappers/Python/wip/demo_astra_sophiabeads.py
+++ b/Wrappers/Python/wip/demo_astra_sophiabeads.py
@@ -11,7 +11,7 @@ from ccpi.io.reader import XTEKReader
import numpy as np
import matplotlib.pyplot as plt
from ccpi.framework import ImageGeometry, AcquisitionGeometry, AcquisitionData, ImageData
-from ccpi.astra.ops import AstraProjectorSimple
+from ccpi.astra.operators import AstraProjectorSimple
from ccpi.optimisation.algs import CGLS
# Set up reader object and read the data
diff --git a/Wrappers/Python/wip/demo_astra_sophiabeads3D.py b/Wrappers/Python/wip/demo_astra_sophiabeads3D.py
index edfe1b9..8c43657 100644
--- a/Wrappers/Python/wip/demo_astra_sophiabeads3D.py
+++ b/Wrappers/Python/wip/demo_astra_sophiabeads3D.py
@@ -11,7 +11,7 @@ from ccpi.io.reader import XTEKReader
import numpy as np
import matplotlib.pyplot as plt
from ccpi.framework import ImageGeometry, AcquisitionData, ImageData
-from ccpi.astra.ops import AstraProjector3DSimple
+from ccpi.astra.operators import AstraProjector3DSimple
from ccpi.optimisation.algs import CGLS
import numpy
diff --git a/Wrappers/Python/wip/work_out_adjoint.py b/Wrappers/Python/wip/work_out_adjoint.py
index 34d58ff..276fb76 100644
--- a/Wrappers/Python/wip/work_out_adjoint.py
+++ b/Wrappers/Python/wip/work_out_adjoint.py
@@ -8,7 +8,7 @@
from ccpi.framework import ImageData , ImageGeometry, AcquisitionGeometry, AcquisitionData
from ccpi.optimisation.algs import FISTA, FBPD, CGLS
from ccpi.optimisation.funcs import Norm2sq, Norm1, TV2D
-from ccpi.astra.ops import AstraProjectorSimple
+from ccpi.astra.operators import AstraProjectorSimple
import numpy as np
import matplotlib.pyplot as plt
diff --git a/Wrappers/Python/wip/work_out_adjoint3D.py b/Wrappers/Python/wip/work_out_adjoint3D.py
index 162e55a..0e4f847 100644
--- a/Wrappers/Python/wip/work_out_adjoint3D.py
+++ b/Wrappers/Python/wip/work_out_adjoint3D.py
@@ -8,7 +8,7 @@
from ccpi.framework import ImageData , ImageGeometry, AcquisitionGeometry, AcquisitionData
from ccpi.optimisation.algs import FISTA, FBPD, CGLS
from ccpi.optimisation.funcs import Norm2sq, Norm1, TV2D
-from ccpi.astra.ops import AstraProjector3DSimple
+from ccpi.astra.operators import AstraProjector3DSimple
import numpy as np
import matplotlib.pyplot as plt
diff --git a/Wrappers/Python/wip/work_out_adjoint_sophiabeads.py b/Wrappers/Python/wip/work_out_adjoint_sophiabeads.py
index 2492826..7f35a16 100644
--- a/Wrappers/Python/wip/work_out_adjoint_sophiabeads.py
+++ b/Wrappers/Python/wip/work_out_adjoint_sophiabeads.py
@@ -8,7 +8,7 @@
from ccpi.framework import ImageData , ImageGeometry, AcquisitionGeometry, AcquisitionData
from ccpi.optimisation.algs import FISTA, FBPD, CGLS
from ccpi.optimisation.funcs import Norm2sq, Norm1, TV2D
-from ccpi.astra.ops import AstraProjectorSimple
+from ccpi.astra.operators import AstraProjectorSimple
import numpy as np
import matplotlib.pyplot as plt