From f06195106256fbb05f8c06e5a54c0c917a277530 Mon Sep 17 00:00:00 2001 From: Edoardo Pasca Date: Fri, 27 Oct 2017 15:51:17 +0100 Subject: Added DeviceModel and AstraDevice these classes are to abstract the calls to forward/backprojection so that the FISTA implementation is independent of ASTRA and we may use CCPi code from CGLS. --- src/Python/ccpi/reconstruction/AstraDevice.py | 67 +++++++++++++++++++++++++++ src/Python/ccpi/reconstruction/DeviceModel.py | 57 +++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 src/Python/ccpi/reconstruction/AstraDevice.py create mode 100644 src/Python/ccpi/reconstruction/DeviceModel.py (limited to 'src/Python/ccpi') diff --git a/src/Python/ccpi/reconstruction/AstraDevice.py b/src/Python/ccpi/reconstruction/AstraDevice.py new file mode 100644 index 0000000..d854183 --- /dev/null +++ b/src/Python/ccpi/reconstruction/AstraDevice.py @@ -0,0 +1,67 @@ +import astra +from DeviceModel import DeviceModel + +class AstraDevice(DeviceModel): + '''Concrete class for Astra Device''' + + def __init__(self, + device_type, + data_aquisition_geometry, + reconstructed_volume_geometry): + + + self.proj_geom = astra.creators.create_proj_geom( + device_type, + self.acquisition_data_geometry['detectorSpacingX'], + self.acquisition_data_geometry['detectorSpacingX'], + self.acquisition_data_geometry['cameraX'], + self.acquisition_data_geometry['cameraY'], + self.acquisition_data_geometry['angles'], + angles_rad + ) + + self.vol_geom = astra.creators.create_vol_geom( + self.reconstructed_volume_geometry['X'], + self.reconstructed_volume_geometry['Y'], + self.reconstructed_volume_geometry['Z'] + ) + + def doForwardProject(self, volume): + '''Forward projects the volume according to the device geometry + +Uses Astra-toolbox +''' + sino_id, y = astra.creators.create_sino3d_gpu( + volume, self.proj_geom, self.vol_geom) + astra.matlab.data3d('delete', sino_id) + return y + + def doBackwardProject(self, projections): + '''Backward projects the projections according to the device geometry + +Uses Astra-toolbox +''' + idx, volume = \ + astra.creators.create_backprojection3d_gpu( + projections, + self.proj_geom, + self.vol_geom) + astra.matlab.data3d('delete', idx) + return volume + + def createReducedDevice(self): + return AstraDevice(self.proj_geom['type'], + {'detectorSpacingX' : self.proj_geom['DetectorSpacingX'] , + 'detectorSpacingY' : self.proj_geom['DetectorSpacingY'] , + 'cameraX' : self.proj_geom['DetectorColCount'] , + 'cameraY' : 1 , + 'angles' : self.proj_geom['ProjectionAngles'] } , + { + 'X' : self.vol_geom['GridColCount'], + 'Y' : self.vol_geom['GridRowCount'] + 'Z' : 1} ) + +if __name__=="main": + a = AstraDevice() + + diff --git a/src/Python/ccpi/reconstruction/DeviceModel.py b/src/Python/ccpi/reconstruction/DeviceModel.py new file mode 100644 index 0000000..1717321 --- /dev/null +++ b/src/Python/ccpi/reconstruction/DeviceModel.py @@ -0,0 +1,57 @@ +from abc import ABCMeta, abstractmethod +from enum import Enum + +class DeviceModel(metaclass=ABCMeta): + '''Abstract class that defines the device for projection and backprojection + +This class defines the methods that must be implemented by concrete classes. + + ''' + + class DeviceType(Enum): + '''Type of device +PARALLEL BEAM +PARALLEL BEAM 3D +CONE BEAM +HELICAL''' + + PARALLEL = 'parallel' + PARALLEL3D = 'parallel3d' + CONE_BEAM = 'cone-beam' + HELICAL = 'helical' + + def __init__(self, + device_type, + data_aquisition_geometry, + reconstructed_volume_geometry): + '''Initializes the class + +Mandatory parameters are: +device_type from DeviceType Enum +data_acquisition_geometry: tuple (camera_X, camera_Y) +reconstructed_volume_geometry: tuple (dimX,dimY,dimZ) +''' + self.device_geometry = device_type + self.acquisition_data_geometry = { + 'cameraX': data_aquisition_geometry[0], + 'cameraY': data_aquisition_geometry[1], + 'detectorSpacingX' : data_aquisition_geometry[2], + 'detectorSpacingY' : data_aquisition_geometry[3], + 'angles' : data_aquisition_geometry[4],} + self.reconstructed_volume_geometry = { + 'X': reconstructed_volume_geometry[0] , + 'Y': reconstructed_volume_geometry[1] , + 'Z': reconstructed_volume_geometry[2] } + + @abstractmethod + def doFowardProject(self, volume): + '''Forward projects the volume according to the device geometry''' + return NotImplemented + + + @abstractmethod + def doBackwardProject(self, projections): + '''Backward projects the projections according to the device geometry''' + return NotImplemented + + -- cgit v1.2.3