From 2aa72d55525739d3a25a2477443eabb1e6b7a7c0 Mon Sep 17 00:00:00 2001 From: Edoardo Pasca Date: Tue, 3 Apr 2018 15:43:54 +0100 Subject: renamed processors ops and utils fixed examples --- Wrappers/Python/ccpi/astra/astra_ops.py | 6 +- Wrappers/Python/ccpi/astra/astra_processors.py | 2 +- Wrappers/Python/ccpi/astra/astra_utils.py | 61 -------- Wrappers/Python/ccpi/astra/ops.py | 132 ++++++++++++++++ Wrappers/Python/ccpi/astra/processors.py | 205 +++++++++++++++++++++++++ Wrappers/Python/ccpi/astra/utils.py | 61 ++++++++ Wrappers/Python/conda-recipe/meta.yaml | 2 +- Wrappers/Python/wip/demo_sophiabeads.py | 4 +- Wrappers/Python/wip/simple_demo_astra.py | 6 +- Wrappers/Python/wip/simple_mc_demo.py | 6 +- 10 files changed, 411 insertions(+), 74 deletions(-) delete mode 100644 Wrappers/Python/ccpi/astra/astra_utils.py create mode 100755 Wrappers/Python/ccpi/astra/ops.py create mode 100755 Wrappers/Python/ccpi/astra/processors.py create mode 100755 Wrappers/Python/ccpi/astra/utils.py (limited to 'Wrappers') diff --git a/Wrappers/Python/ccpi/astra/astra_ops.py b/Wrappers/Python/ccpi/astra/astra_ops.py index 45b8238..cd0ef9e 100644 --- a/Wrappers/Python/ccpi/astra/astra_ops.py +++ b/Wrappers/Python/ccpi/astra/astra_ops.py @@ -15,12 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from ccpi.reconstruction.ops import Operator +from ccpi.optimisation.ops import Operator import numpy import astra from ccpi.framework import AcquisitionData, ImageData, DataContainer -from ccpi.reconstruction.ops import PowerMethodNonsquare -from ccpi.astra.astra_processors import AstraForwardProjector, AstraBackProjector, \ +from ccpi.optimisation.ops import PowerMethodNonsquare +from ccpi.astra.processors import AstraForwardProjector, AstraBackProjector, \ AstraForwardProjectorMC, AstraBackProjectorMC class AstraProjectorSimple(Operator): diff --git a/Wrappers/Python/ccpi/astra/astra_processors.py b/Wrappers/Python/ccpi/astra/astra_processors.py index 3de43bf..16c1f78 100644 --- a/Wrappers/Python/ccpi/astra/astra_processors.py +++ b/Wrappers/Python/ccpi/astra/astra_processors.py @@ -1,5 +1,5 @@ from ccpi.framework import DataSetProcessor, ImageData, AcquisitionData -from ccpi.astra.astra_utils import convert_geometry_to_astra +from ccpi.astra.utils import convert_geometry_to_astra import astra diff --git a/Wrappers/Python/ccpi/astra/astra_utils.py b/Wrappers/Python/ccpi/astra/astra_utils.py deleted file mode 100644 index 9f8fe46..0000000 --- a/Wrappers/Python/ccpi/astra/astra_utils.py +++ /dev/null @@ -1,61 +0,0 @@ -import astra - -def convert_geometry_to_astra(volume_geometry, sinogram_geometry): - # Set up ASTRA Volume and projection geometry, not stored - if sinogram_geometry.dimension == '2D': - vol_geom = astra.create_vol_geom(volume_geometry.voxel_num_x, - volume_geometry.voxel_num_y, - 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', - sinogram_geometry.pixel_size_h, - sinogram_geometry.pixel_num_h, - sinogram_geometry.angles) - elif sinogram_geometry.geom_type == 'cone': - proj_geom = astra.create_proj_geom('fanflat', - sinogram_geometry.pixel_size_h, - sinogram_geometry.pixel_num_h, - sinogram_geometry.angles, - sinogram_geometry.dist_source_center, - sinogram_geometry.dist_center_detector) - else: - NotImplemented - - elif sinogram_geometry.dimension == '3D': - vol_geom = astra.create_vol_geom(volume_geometry.voxel_num_x, - volume_geometry.voxel_num_y, - volume_geometry.voxel_num_z, - 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.geom_type == 'parallel': - proj_geom = astra.create_proj_geom('parallel3d', - sinogram_geometry.pixel_size_h, - sinogram_geometry.pixel_size_v, - sinogram_geometry.pixel_num_v, - sinogram_geometry.pixel_num_h, - sinogram_geometry.angles) - elif sinogram_geometry.geom_type == 'cone': - proj_geom = astra.create_proj_geom('cone', - sinogram_geometry.pixel_size_h, - sinogram_geometry.pixel_size_v, - sinogram_geometry.pixel_num_v, - sinogram_geometry.pixel_num_h, - sinogram_geometry.angles, - sinogram_geometry.dist_source_center, - sinogram_geometry.dist_center_detector) - else: - NotImplemented - - else: - NotImplemented - - return vol_geom, proj_geom \ No newline at end of file diff --git a/Wrappers/Python/ccpi/astra/ops.py b/Wrappers/Python/ccpi/astra/ops.py new file mode 100755 index 0000000..cd0ef9e --- /dev/null +++ b/Wrappers/Python/ccpi/astra/ops.py @@ -0,0 +1,132 @@ +# -*- 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 . + +from ccpi.optimisation.ops import Operator +import numpy +import astra +from ccpi.framework import AcquisitionData, ImageData, DataContainer +from ccpi.optimisation.ops import PowerMethodNonsquare +from ccpi.astra.processors import AstraForwardProjector, AstraBackProjector, \ + AstraForwardProjectorMC, AstraBackProjectorMC + +class AstraProjectorSimple(Operator): + """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): + 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.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 AstraProjectorMC(Operator): + """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 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])) + diff --git a/Wrappers/Python/ccpi/astra/processors.py b/Wrappers/Python/ccpi/astra/processors.py new file mode 100755 index 0000000..16c1f78 --- /dev/null +++ b/Wrappers/Python/ccpi/astra/processors.py @@ -0,0 +1,205 @@ +from ccpi.framework import DataSetProcessor, ImageData, AcquisitionData +from ccpi.astra.utils import convert_geometry_to_astra +import astra + + +class AstraForwardProjector(DataSetProcessor): + '''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 + } + + #DataSetProcessor.__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) + #return AcquisitionData(array=DATA, geometry=self.sinogram_geometry) + return DATA + +class AstraBackProjector(DataSetProcessor): + '''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 + } + + #DataSetProcessor.__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) + return 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) + return 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) + return IM \ No newline at end of file diff --git a/Wrappers/Python/ccpi/astra/utils.py b/Wrappers/Python/ccpi/astra/utils.py new file mode 100755 index 0000000..9f8fe46 --- /dev/null +++ b/Wrappers/Python/ccpi/astra/utils.py @@ -0,0 +1,61 @@ +import astra + +def convert_geometry_to_astra(volume_geometry, sinogram_geometry): + # Set up ASTRA Volume and projection geometry, not stored + if sinogram_geometry.dimension == '2D': + vol_geom = astra.create_vol_geom(volume_geometry.voxel_num_x, + volume_geometry.voxel_num_y, + 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', + sinogram_geometry.pixel_size_h, + sinogram_geometry.pixel_num_h, + sinogram_geometry.angles) + elif sinogram_geometry.geom_type == 'cone': + proj_geom = astra.create_proj_geom('fanflat', + sinogram_geometry.pixel_size_h, + sinogram_geometry.pixel_num_h, + sinogram_geometry.angles, + sinogram_geometry.dist_source_center, + sinogram_geometry.dist_center_detector) + else: + NotImplemented + + elif sinogram_geometry.dimension == '3D': + vol_geom = astra.create_vol_geom(volume_geometry.voxel_num_x, + volume_geometry.voxel_num_y, + volume_geometry.voxel_num_z, + 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.geom_type == 'parallel': + proj_geom = astra.create_proj_geom('parallel3d', + sinogram_geometry.pixel_size_h, + sinogram_geometry.pixel_size_v, + sinogram_geometry.pixel_num_v, + sinogram_geometry.pixel_num_h, + sinogram_geometry.angles) + elif sinogram_geometry.geom_type == 'cone': + proj_geom = astra.create_proj_geom('cone', + sinogram_geometry.pixel_size_h, + sinogram_geometry.pixel_size_v, + sinogram_geometry.pixel_num_v, + sinogram_geometry.pixel_num_h, + sinogram_geometry.angles, + sinogram_geometry.dist_source_center, + sinogram_geometry.dist_center_detector) + else: + NotImplemented + + else: + NotImplemented + + return vol_geom, proj_geom \ No newline at end of file diff --git a/Wrappers/Python/conda-recipe/meta.yaml b/Wrappers/Python/conda-recipe/meta.yaml index 12e83e2..ca91ed0 100755 --- a/Wrappers/Python/conda-recipe/meta.yaml +++ b/Wrappers/Python/conda-recipe/meta.yaml @@ -19,7 +19,7 @@ requirements: - python - numpy - scipy - - ccpi-common + - ccpi-framework - astra-toolbox about: diff --git a/Wrappers/Python/wip/demo_sophiabeads.py b/Wrappers/Python/wip/demo_sophiabeads.py index e3c7f3a..33ce9ec 100755 --- a/Wrappers/Python/wip/demo_sophiabeads.py +++ b/Wrappers/Python/wip/demo_sophiabeads.py @@ -3,8 +3,8 @@ 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.astra_ops import AstraProjectorSimple -from ccpi.reconstruction.algs import CGLS +from ccpi.astra.ops import AstraProjectorSimple +from ccpi.optimisation.algs import CGLS # Set up reader object and read the data datareader = XTEKReader("C:/Users/mbbssjj2/Documents/SophiaBeads_256_averaged/SophiaBeads_256_averaged.xtekct") diff --git a/Wrappers/Python/wip/simple_demo_astra.py b/Wrappers/Python/wip/simple_demo_astra.py index 3365504..26f3ff4 100755 --- a/Wrappers/Python/wip/simple_demo_astra.py +++ b/Wrappers/Python/wip/simple_demo_astra.py @@ -2,9 +2,9 @@ #sys.path.append("..") from ccpi.framework import ImageData , ImageGeometry, AcquisitionGeometry -from ccpi.reconstruction.algs import FISTA, FBPD, CGLS -from ccpi.reconstruction.funcs import Norm2sq, Norm1 , TV2D -from ccpi.astra.astra_ops import AstraProjectorSimple +from ccpi.optimisation.algs import FISTA, FBPD, CGLS +from ccpi.optimisation.funcs import Norm2sq, Norm1 , TV2D +from ccpi.astra.ops import AstraProjectorSimple import numpy as np import matplotlib.pyplot as plt diff --git a/Wrappers/Python/wip/simple_mc_demo.py b/Wrappers/Python/wip/simple_mc_demo.py index f77a678..7369d8f 100755 --- a/Wrappers/Python/wip/simple_mc_demo.py +++ b/Wrappers/Python/wip/simple_mc_demo.py @@ -2,9 +2,9 @@ #sys.path.append("..") from ccpi.framework import ImageData, AcquisitionData, ImageGeometry, AcquisitionGeometry -from ccpi.reconstruction.algs import FISTA -from ccpi.reconstruction.funcs import Norm2sq, Norm1 -from ccpi.astra.astra_ops import AstraProjectorMC +from ccpi.optimisation.algs import FISTA +from ccpi.optimisation.funcs import Norm2sq, Norm1 +from ccpi.astra.ops import AstraProjectorMC import numpy import matplotlib.pyplot as plt -- cgit v1.2.3 From bf2da3ac3484a671815e95d7f4d622586301ba7d Mon Sep 17 00:00:00 2001 From: Edoardo Pasca Date: Tue, 3 Apr 2018 15:45:25 +0100 Subject: removed duplicated files --- Wrappers/Python/ccpi/astra/astra_ops.py | 132 ---------------- Wrappers/Python/ccpi/astra/astra_processors.py | 205 ------------------------- 2 files changed, 337 deletions(-) delete mode 100644 Wrappers/Python/ccpi/astra/astra_ops.py delete mode 100644 Wrappers/Python/ccpi/astra/astra_processors.py (limited to 'Wrappers') diff --git a/Wrappers/Python/ccpi/astra/astra_ops.py b/Wrappers/Python/ccpi/astra/astra_ops.py deleted file mode 100644 index cd0ef9e..0000000 --- a/Wrappers/Python/ccpi/astra/astra_ops.py +++ /dev/null @@ -1,132 +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 . - -from ccpi.optimisation.ops import Operator -import numpy -import astra -from ccpi.framework import AcquisitionData, ImageData, DataContainer -from ccpi.optimisation.ops import PowerMethodNonsquare -from ccpi.astra.processors import AstraForwardProjector, AstraBackProjector, \ - AstraForwardProjectorMC, AstraBackProjectorMC - -class AstraProjectorSimple(Operator): - """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): - 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.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 AstraProjectorMC(Operator): - """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 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])) - diff --git a/Wrappers/Python/ccpi/astra/astra_processors.py b/Wrappers/Python/ccpi/astra/astra_processors.py deleted file mode 100644 index 16c1f78..0000000 --- a/Wrappers/Python/ccpi/astra/astra_processors.py +++ /dev/null @@ -1,205 +0,0 @@ -from ccpi.framework import DataSetProcessor, ImageData, AcquisitionData -from ccpi.astra.utils import convert_geometry_to_astra -import astra - - -class AstraForwardProjector(DataSetProcessor): - '''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 - } - - #DataSetProcessor.__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) - #return AcquisitionData(array=DATA, geometry=self.sinogram_geometry) - return DATA - -class AstraBackProjector(DataSetProcessor): - '''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 - } - - #DataSetProcessor.__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) - return 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) - return 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) - return IM \ No newline at end of file -- cgit v1.2.3 From 72331fa53209ee3504073c8038a7372619b63be4 Mon Sep 17 00:00:00 2001 From: Jakob Jorgensen Date: Thu, 12 Apr 2018 16:26:36 +0100 Subject: Removed astra_test --- Wrappers/Python/wip/astra_test.py | 87 --------------------------------------- 1 file changed, 87 deletions(-) delete mode 100755 Wrappers/Python/wip/astra_test.py (limited to 'Wrappers') diff --git a/Wrappers/Python/wip/astra_test.py b/Wrappers/Python/wip/astra_test.py deleted file mode 100755 index c0a7359..0000000 --- a/Wrappers/Python/wip/astra_test.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Wed Mar 7 15:07:16 2018 - -@author: ofn77899 -""" - -# ----------------------------------------------------------------------- -# Copyright: 2010-2018, imec Vision Lab, University of Antwerp -# 2013-2018, CWI, Amsterdam -# -# Contact: astra@astra-toolbox.com -# Website: http://www.astra-toolbox.com/ -# -# This file is part of the ASTRA Toolbox. -# -# -# The ASTRA Toolbox 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. -# -# The ASTRA Toolbox 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 the ASTRA Toolbox. If not, see . -# -# ----------------------------------------------------------------------- - -import astra -import numpy as np - -vol_geom = astra.create_vol_geom(256, 256) -proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False)) - -# For CPU-based algorithms, a "projector" object specifies the projection -# model used. In this case, we use the "strip" model. -proj_id = astra.create_projector('strip', proj_geom, vol_geom) - -# Create a sinogram from a phantom -import scipy.io -P = scipy.io.loadmat('phantom.mat')['phantom256'] -sinogram_id, sinogram = astra.create_sino(P, proj_id) - -import pylab -pylab.gray() -pylab.figure(1) -pylab.imshow(P) -pylab.figure(2) -pylab.imshow(sinogram) - -# Create a data object for the reconstruction -rec_id = astra.data2d.create('-vol', vol_geom) - -# Set up the parameters for a reconstruction algorithm using the CPU -# The main difference with the configuration of a GPU algorithm is the -# extra ProjectorId setting. -cfg = astra.astra_dict('SIRT') -cfg['ReconstructionDataId'] = rec_id -cfg['ProjectionDataId'] = sinogram_id -cfg['ProjectorId'] = proj_id - -# Available algorithms: -# ART, SART, SIRT, CGLS, FBP - - -# Create the algorithm object from the configuration structure -alg_id = astra.algorithm.create(cfg) - -# Run 20 iterations of the algorithm -# This will have a runtime in the order of 10 seconds. -astra.algorithm.run(alg_id, 20) - -# Get the result -rec = astra.data2d.get(rec_id) -pylab.figure(3) -pylab.imshow(rec) -pylab.show() - -# Clean up. -astra.algorithm.delete(alg_id) -astra.data2d.delete(rec_id) -astra.data2d.delete(sinogram_id) -astra.projector.delete(proj_id) -- cgit v1.2.3 From 4dc1a8bdd6918b46db3da6c1fc1afb387727e961 Mon Sep 17 00:00:00 2001 From: Jakob Jorgensen Date: Thu, 12 Apr 2018 16:30:05 +0100 Subject: Removed desktop.ini as not demo --- Wrappers/Python/wip/desktop.ini | 4 ---- 1 file changed, 4 deletions(-) delete mode 100755 Wrappers/Python/wip/desktop.ini (limited to 'Wrappers') diff --git a/Wrappers/Python/wip/desktop.ini b/Wrappers/Python/wip/desktop.ini deleted file mode 100755 index bb9f3d6..0000000 --- a/Wrappers/Python/wip/desktop.ini +++ /dev/null @@ -1,4 +0,0 @@ -[ViewState] -Mode= -Vid= -FolderType=Generic -- cgit v1.2.3