From 33eb0918a28769bc1cc5f326a189bb28311ca2e0 Mon Sep 17 00:00:00 2001 From: Edoardo Pasca Date: Wed, 14 Mar 2018 14:34:48 +0000 Subject: moved astra_ops --- Wrappers/Python/ccpi/astra/astra_ops.py | 195 +++++++++++++++++++++++ Wrappers/Python/ccpi/reconstruction/astra_ops.py | 195 ----------------------- 2 files changed, 195 insertions(+), 195 deletions(-) create mode 100644 Wrappers/Python/ccpi/astra/astra_ops.py delete mode 100644 Wrappers/Python/ccpi/reconstruction/astra_ops.py diff --git a/Wrappers/Python/ccpi/astra/astra_ops.py b/Wrappers/Python/ccpi/astra/astra_ops.py new file mode 100644 index 0000000..c409529 --- /dev/null +++ b/Wrappers/Python/ccpi/astra/astra_ops.py @@ -0,0 +1,195 @@ +# -*- 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.reconstruction.ops import Operator +import numpy +from ccpi.framework import AcquisitionData, ImageData +from ccpi.reconstruction.ops import PowerMethodNonsquare +from ccpi.astra.astra_processors import * + +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) ) + +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 = 50 + + 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) ) + + +class AstraProjector(Operator): + """A simple 2D/3D parallel/fan beam projection/backprojection class based + on ASTRA toolbox""" + def __init__(self, DetWidth, DetectorsDim, SourceOrig, OrigDetec, + AnglesVec, ObjSize, projtype, device): + super(AstraProjector, self).__init__() + self.DetectorsDim = DetectorsDim + self.AnglesVec = AnglesVec + self.ProjNumb = len(AnglesVec) + self.ObjSize = ObjSize + if projtype == 'parallel': + self.proj_geom = astra.create_proj_geom('parallel', DetWidth, + DetectorsDim, AnglesVec) + elif projtype == 'fanbeam': + self.proj_geom = astra.create_proj_geom('fanflat', DetWidth, + DetectorsDim, AnglesVec, + SourceOrig, OrigDetec) + else: + print ("Please select for projtype between 'parallel' and 'fanbeam'") + self.vol_geom = astra.create_vol_geom(ObjSize, ObjSize) + if device == 'cpu': + self.proj_id = astra.create_projector('line', self.proj_geom, + self.vol_geom) # for CPU + self.device = 1 + elif device == 'gpu': + self.proj_id = astra.create_projector('cuda', self.proj_geom, + self.vol_geom) # for GPU + self.device = 0 + else: + print ("Select between 'cpu' or 'gpu' for device") + self.s1 = None + def direct(self, IM): + """Applying forward projection to IM [2D or 3D array]""" + if numpy.ndim(IM.as_array()) == 3: + slices = numpy.size(IM.as_array(),numpy.ndim(IM.as_array())-1) + DATA = numpy.zeros((self.ProjNumb,self.DetectorsDim,slices), + 'float32') + for i in range(0,slices): + sinogram_id, DATA[:,:,i] = \ + astra.create_sino(IM[:,:,i].as_array(), self.proj_id) + astra.data2d.delete(sinogram_id) + astra.data2d.delete(self.proj_id) + else: + sinogram_id, DATA = astra.create_sino(IM.as_array(), self.proj_id) + astra.data2d.delete(sinogram_id) + astra.data2d.delete(self.proj_id) + return AcquisitionData(DATA) + def adjoint(self, DATA): + """Applying backprojection to DATA [2D or 3D]""" + if numpy.ndim(DATA) == 3: + slices = numpy.size(DATA.as_array(),numpy.ndim(DATA.as_array())-1) + IM = numpy.zeros((self.ObjSize,self.ObjSize,slices), 'float32') + for i in range(0,slices): + rec_id, IM[:,:,i] = \ + astra.create_backprojection(DATA[:,:,i].as_array(), + self.proj_id) + astra.data2d.delete(rec_id) + astra.data2d.delete(self.proj_id) + else: + rec_id, IM = astra.create_backprojection(DATA.as_array(), + self.proj_id) + astra.data2d.delete(rec_id) + astra.data2d.delete(self.proj_id) + return ImageData(IM) + + 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): + return ( (self.AnglesVec.size, self.DetectorsDim), \ + (self.ObjSize, self.ObjSize) ) + diff --git a/Wrappers/Python/ccpi/reconstruction/astra_ops.py b/Wrappers/Python/ccpi/reconstruction/astra_ops.py deleted file mode 100644 index 1346f22..0000000 --- a/Wrappers/Python/ccpi/reconstruction/astra_ops.py +++ /dev/null @@ -1,195 +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.reconstruction.ops import Operator -import numpy -from ccpi.framework import SinogramData, VolumeData -from ccpi.reconstruction.ops import PowerMethodNonsquare -from ccpi.astra.astra_processors import * - -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.setInput(IM) - out = self.fp.getOutput() - return out - - def adjoint(self, DATA): - self.bp.setInput(DATA) - out = self.bp.getOutput() - 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) ) - -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 = 50 - - def direct(self, IM): - self.fp.setInput(IM) - out = self.fp.getOutput() - return out - - def adjoint(self, DATA): - self.bp.setInput(DATA) - out = self.bp.getOutput() - 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) ) - - -class AstraProjector(Operator): - """A simple 2D/3D parallel/fan beam projection/backprojection class based - on ASTRA toolbox""" - def __init__(self, DetWidth, DetectorsDim, SourceOrig, OrigDetec, - AnglesVec, ObjSize, projtype, device): - super(AstraProjector, self).__init__() - self.DetectorsDim = DetectorsDim - self.AnglesVec = AnglesVec - self.ProjNumb = len(AnglesVec) - self.ObjSize = ObjSize - if projtype == 'parallel': - self.proj_geom = astra.create_proj_geom('parallel', DetWidth, - DetectorsDim, AnglesVec) - elif projtype == 'fanbeam': - self.proj_geom = astra.create_proj_geom('fanflat', DetWidth, - DetectorsDim, AnglesVec, - SourceOrig, OrigDetec) - else: - print ("Please select for projtype between 'parallel' and 'fanbeam'") - self.vol_geom = astra.create_vol_geom(ObjSize, ObjSize) - if device == 'cpu': - self.proj_id = astra.create_projector('line', self.proj_geom, - self.vol_geom) # for CPU - self.device = 1 - elif device == 'gpu': - self.proj_id = astra.create_projector('cuda', self.proj_geom, - self.vol_geom) # for GPU - self.device = 0 - else: - print ("Select between 'cpu' or 'gpu' for device") - self.s1 = None - def direct(self, IM): - """Applying forward projection to IM [2D or 3D array]""" - if numpy.ndim(IM.as_array()) == 3: - slices = numpy.size(IM.as_array(),numpy.ndim(IM.as_array())-1) - DATA = numpy.zeros((self.ProjNumb,self.DetectorsDim,slices), - 'float32') - for i in range(0,slices): - sinogram_id, DATA[:,:,i] = \ - astra.create_sino(IM[:,:,i].as_array(), self.proj_id) - astra.data2d.delete(sinogram_id) - astra.data2d.delete(self.proj_id) - else: - sinogram_id, DATA = astra.create_sino(IM.as_array(), self.proj_id) - astra.data2d.delete(sinogram_id) - astra.data2d.delete(self.proj_id) - return SinogramData(DATA) - def adjoint(self, DATA): - """Applying backprojection to DATA [2D or 3D]""" - if numpy.ndim(DATA) == 3: - slices = numpy.size(DATA.as_array(),numpy.ndim(DATA.as_array())-1) - IM = numpy.zeros((self.ObjSize,self.ObjSize,slices), 'float32') - for i in range(0,slices): - rec_id, IM[:,:,i] = \ - astra.create_backprojection(DATA[:,:,i].as_array(), - self.proj_id) - astra.data2d.delete(rec_id) - astra.data2d.delete(self.proj_id) - else: - rec_id, IM = astra.create_backprojection(DATA.as_array(), - self.proj_id) - astra.data2d.delete(rec_id) - astra.data2d.delete(self.proj_id) - return VolumeData(IM) - - 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): - return ( (self.AnglesVec.size, self.DetectorsDim), \ - (self.ObjSize, self.ObjSize) ) - -- cgit v1.2.3 From 80e9ee7df105ded9aa3cf3f84032033f7fb2f1d4 Mon Sep 17 00:00:00 2001 From: Edoardo Pasca Date: Wed, 14 Mar 2018 14:43:03 +0000 Subject: renaming according to CCPPETMR conventions Renamed VolumeData to ImageData Renamed SinogramData to AcquisitionData NOT renamed DataSetProcessor methods are now lower_case not camelCase Moved astra_processor to package astra Updated the demos --- Wrappers/Python/ccpi/astra/astra_processors.py | 60 ++++---- Wrappers/Python/ccpi/framework.py | 186 ++++++++++++------------- Wrappers/Python/ccpi/reconstruction/algs.py | 1 - Wrappers/Python/ccpi/reconstruction/ops.py | 10 +- Wrappers/Python/wip/simple_demo.py | 12 +- Wrappers/Python/wip/simple_mc_demo.py | 10 +- 6 files changed, 139 insertions(+), 140 deletions(-) diff --git a/Wrappers/Python/ccpi/astra/astra_processors.py b/Wrappers/Python/ccpi/astra/astra_processors.py index f51aec9..bf6048b 100644 --- a/Wrappers/Python/ccpi/astra/astra_processors.py +++ b/Wrappers/Python/ccpi/astra/astra_processors.py @@ -1,17 +1,16 @@ -from ccpi.framework import DataSetProcessor, DataSet, VolumeData, SinogramData +from ccpi.framework import DataSetProcessor, ImageData, AcquisitionData from ccpi.astra.astra_utils import convert_geometry_to_astra import astra -import numpy class AstraForwardProjector(DataSetProcessor): '''AstraForwardProjector - Forward project VolumeDataSet to SinogramDataSet using ASTRA proj_id. + Forward project ImageData to AcquisitionData using ASTRA proj_id. - Input: VolumeDataSet + Input: ImageData Parameter: proj_id - Output: SinogramDataSet + Output: AcquisitionData ''' def __init__(self, @@ -50,7 +49,7 @@ class AstraForwardProjector(DataSetProcessor): else: NotImplemented - def checkInput(self, dataset): + def check_input(self, dataset): if dataset.number_of_dimensions == 3 or\ dataset.number_of_dimensions == 2: return True @@ -68,24 +67,24 @@ class AstraForwardProjector(DataSetProcessor): self.sinogram_geometry = sinogram_geometry def process(self): - IM = self.getInput() - DATA = SinogramData(geometry=self.sinogram_geometry) + 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 SinogramData(array=DATA, geometry=self.sinogram_geometry) + #return AcquisitionData(array=DATA, geometry=self.sinogram_geometry) return DATA class AstraBackProjector(DataSetProcessor): '''AstraBackProjector - Back project SinogramDataSet to VolumeDataSet using ASTRA proj_id. + Back project AcquisitionData to ImageData using ASTRA proj_id. - Input: SinogramDataSet + Input: AcquisitionData Parameter: proj_id - Output: VolumeDataSet + Output: ImageData ''' def __init__(self, @@ -124,7 +123,7 @@ class AstraBackProjector(DataSetProcessor): else: NotImplemented - def checkInput(self, dataset): + def check_input(self, dataset): if dataset.number_of_dimensions == 3 or dataset.number_of_dimensions == 2: return True else: @@ -141,8 +140,8 @@ class AstraBackProjector(DataSetProcessor): self.sinogram_geometry = sinogram_geometry def process(self): - DATA = self.getInput() - IM = VolumeData(geometry=self.volume_geometry) + 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) @@ -151,13 +150,13 @@ class AstraBackProjector(DataSetProcessor): class AstraForwardProjectorMC(AstraForwardProjector): '''AstraForwardProjector Multi channel - Forward project VolumeDataSet to SinogramDataSet using ASTRA proj_id. + Forward project ImageData to AcquisitionDataSet using ASTRA proj_id. - Input: VolumeDataSet + Input: ImageDataSet Parameter: proj_id - Output: SinogramDataSet + Output: AcquisitionData ''' - def checkInput(self, dataset): + def check_input(self, dataset): if dataset.number_of_dimensions == 2 or \ dataset.number_of_dimensions == 3 or \ dataset.number_of_dimensions == 4: @@ -166,9 +165,9 @@ class AstraForwardProjectorMC(AstraForwardProjector): raise ValueError("Expected input dimensions is 2 or 3, got {0}"\ .format(dataset.number_of_dimensions)) def process(self): - IM = self.getInput() - #create the output Sinogram - DATA = SinogramData(geometry=self.sinogram_geometry) + 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], @@ -179,13 +178,13 @@ class AstraForwardProjectorMC(AstraForwardProjector): class AstraBackProjectorMC(AstraBackProjector): '''AstraBackProjector Multi channel - Back project SinogramDataSet to VolumeDataSet using ASTRA proj_id. + Back project AcquisitionData to ImageData using ASTRA proj_id. - Input: SinogramDataSet + Input: AcquisitionData Parameter: proj_id - Output: VolumeDataSet + Output: ImageData ''' - def checkInput(self, dataset): + def check_input(self, dataset): if dataset.number_of_dimensions == 2 or \ dataset.number_of_dimensions == 3 or \ dataset.number_of_dimensions == 4: @@ -194,12 +193,13 @@ class AstraBackProjectorMC(AstraBackProjector): raise ValueError("Expected input dimensions is 2 or 3, got {0}"\ .format(dataset.number_of_dimensions)) def process(self): - DATA = self.getInput() + DATA = self.get_input() - IM = VolumeData(geometry=self.volume_geometry) + 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) + 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/framework.py b/Wrappers/Python/ccpi/framework.py index b2f8a7e..3409611 100644 --- a/Wrappers/Python/ccpi/framework.py +++ b/Wrappers/Python/ccpi/framework.py @@ -94,7 +94,7 @@ class CCPiBaseClass(ABC): if self.debug: print ("{0}: {1}".format(self.__class__.__name__, msg)) -class DataSet(object): +class DataContainer(object): '''Generic class to hold data Data is currently held in a numpy arrays''' @@ -106,7 +106,7 @@ class DataSet(object): self.shape = numpy.shape(array) self.number_of_dimensions = len (self.shape) self.dimension_labels = {} - self.geometry = None # Only relevant for SinogramData and VolumeData + self.geometry = None # Only relevant for AcquisitionData and ImageData if dimension_labels is not None and \ len (dimension_labels) == self.number_of_dimensions: @@ -134,10 +134,10 @@ class DataSet(object): def as_array(self, dimensions=None): - '''Returns the DataSet as Numpy Array + '''Returns the DataContainer as Numpy Array Returns the pointer to the array if dimensions is not set. - If dimensions is set, it first creates a new DataSet with the subset + If dimensions is set, it first creates a new DataContainer with the subset and then it returns the pointer to the array''' if dimensions is not None: return self.subset(dimensions).as_array() @@ -145,7 +145,7 @@ class DataSet(object): def subset(self, dimensions=None, **kw): - '''Creates a DataSet containing a subset of self according to the + '''Creates a DataContainer containing a subset of self according to the labels in dimensions''' if dimensions is None: return self.array.copy() @@ -155,7 +155,7 @@ class DataSet(object): proceed = True unknown_key = '' # axis_order contains the order of the axis that the user wants - # in the output DataSet + # in the output DataContainer axis_order = [] if type(dimensions) == list: for dl in dimensions: @@ -221,12 +221,12 @@ class DataSet(object): numpy.shape(array))) self.array = array[:] - def checkDimensions(self, other): + def check_dimensions(self, other): return self.shape == other.shape def __add__(self, other): - if issubclass(type(other), DataSet): - if self.checkDimensions(other): + if issubclass(type(other), DataContainer): + if self.check_dimensions(other): out = self.as_array() + other.as_array() return type(self)(out, deep_copy=True, @@ -242,13 +242,13 @@ class DataSet(object): dimension_labels=self.dimension_labels, geometry=self.geometry) else: - raise TypeError('Cannot {0} DataSet with {1}'.format("add" , + raise TypeError('Cannot {0} DataContainer with {1}'.format("add" , type(other))) # __add__ def __sub__(self, other): - if issubclass(type(other), DataSet): - if self.checkDimensions(other): + if issubclass(type(other), DataContainer): + if self.check_dimensions(other): out = self.as_array() - other.as_array() return type(self)(out, deep_copy=True, @@ -263,7 +263,7 @@ class DataSet(object): dimension_labels=self.dimension_labels, geometry=self.geometry) else: - raise TypeError('Cannot {0} DataSet with {1}'.format("subtract" , + raise TypeError('Cannot {0} DataContainer with {1}'.format("subtract" , type(other))) # __sub__ def __truediv__(self,other): @@ -271,8 +271,8 @@ class DataSet(object): def __div__(self, other): print ("calling __div__") - if issubclass(type(other), DataSet): - if self.checkDimensions(other): + if issubclass(type(other), DataContainer): + if self.check_dimensions(other): out = self.as_array() / other.as_array() return type(self)(out, deep_copy=True, @@ -287,13 +287,13 @@ class DataSet(object): dimension_labels=self.dimension_labels, geometry=self.geometry) else: - raise TypeError('Cannot {0} DataSet with {1}'.format("divide" , + raise TypeError('Cannot {0} DataContainer with {1}'.format("divide" , type(other))) # __div__ def __pow__(self, other): - if issubclass(type(other), DataSet): - if self.checkDimensions(other): + if issubclass(type(other), DataContainer): + if self.check_dimensions(other): out = self.as_array() ** other.as_array() return type(self)(out, deep_copy=True, @@ -308,13 +308,13 @@ class DataSet(object): dimension_labels=self.dimension_labels, geometry=self.geometry) else: - raise TypeError('Cannot {0} DataSet with {1}'.format("power" , + raise TypeError('Cannot {0} DataContainer with {1}'.format("power" , type(other))) # __pow__ def __mul__(self, other): - if issubclass(type(other), DataSet): - if self.checkDimensions(other): + if issubclass(type(other), DataContainer): + if self.check_dimensions(other): out = self.as_array() * other.as_array() return type(self)(out, deep_copy=True, @@ -329,7 +329,7 @@ class DataSet(object): dimension_labels=self.dimension_labels, geometry=self.geometry) else: - raise TypeError('Cannot {0} DataSet with {1}'.format("multiply" , + raise TypeError('Cannot {0} DataContainer with {1}'.format("multiply" , type(other))) # __mul__ @@ -386,8 +386,8 @@ class DataSet(object): return type(self)(fother ** self.array , dimension_labels=self.dimension_labels, geometry=self.geometry) - elif issubclass(other, DataSet): - if self.checkDimensions(other): + elif issubclass(other, DataContainer): + if self.check_dimensions(other): return type(self)(other.as_array() ** self.array , dimension_labels=self.dimension_labels, geometry=self.geometry) @@ -437,8 +437,8 @@ class DataSet(object): -class VolumeData(DataSet): - '''DataSet for holding 2D or 3D dataset''' +class ImageData(DataContainer): + '''DataContainer for holding 2D or 3D DataContainer''' def __init__(self, array = None, deep_copy=True, @@ -476,24 +476,24 @@ class VolumeData(DataSet): 'horizontal_x'] array = numpy.zeros( shape , dtype=numpy.float32) - super(VolumeData, self).__init__(array, deep_copy, + super(ImageData, self).__init__(array, deep_copy, dim_labels, **kwargs) else: - raise ValueError('Please pass either a DataSet, ' +\ + raise ValueError('Please pass either a DataContainer, ' +\ 'a numpy array or a geometry') else: - if type(array) == DataSet: - # if the array is a DataSet get the info from there + if type(array) == DataContainer: + # if the array is a DataContainer get the info from there if not ( array.number_of_dimensions == 2 or \ array.number_of_dimensions == 3 or \ array.number_of_dimensions == 4): raise ValueError('Number of dimensions are not 2 or 3 or 4: {0}'\ .format(array.number_of_dimensions)) - #DataSet.__init__(self, array.as_array(), deep_copy, + #DataContainer.__init__(self, array.as_array(), deep_copy, # array.dimension_labels, **kwargs) - super(VolumeData, self).__init__(array.as_array(), deep_copy, + super(ImageData, self).__init__(array.as_array(), deep_copy, array.dimension_labels, **kwargs) elif type(array) == numpy.ndarray: if not ( array.ndim == 2 or array.ndim == 3 or array.ndim == 4 ): @@ -512,8 +512,8 @@ class VolumeData(DataSet): dimension_labels = ['horizontal_y' , 'horizontal_x'] - #DataSet.__init__(self, array, deep_copy, dimension_labels, **kwargs) - super(VolumeData, self).__init__(array, deep_copy, + #DataContainer.__init__(self, array, deep_copy, dimension_labels, **kwargs) + super(ImageData, self).__init__(array, deep_copy, dimension_labels, **kwargs) # load metadata from kwargs if present @@ -526,8 +526,8 @@ class VolumeData(DataSet): self.spacing = value -class SinogramData(DataSet): - '''DataSet for holding 2D or 3D sinogram''' +class AcquisitionData(DataContainer): + '''DataContainer for holding 2D or 3D sinogram''' def __init__(self, array = None, deep_copy=True, @@ -565,21 +565,21 @@ class SinogramData(DataSet): 'horizontal'] array = numpy.zeros( shape , dtype=numpy.float32) - super(SinogramData, self).__init__(array, deep_copy, + super(AcquisitionData, self).__init__(array, deep_copy, dim_labels, **kwargs) else: - if type(array) == DataSet: - # if the array is a DataSet get the info from there + if type(array) == DataContainer: + # if the array is a DataContainer get the info from there if not ( array.number_of_dimensions == 2 or \ array.number_of_dimensions == 3 or \ array.number_of_dimensions == 4): raise ValueError('Number of dimensions are not 2 or 3 or 4: {0}'\ .format(array.number_of_dimensions)) - #DataSet.__init__(self, array.as_array(), deep_copy, + #DataContainer.__init__(self, array.as_array(), deep_copy, # array.dimension_labels, **kwargs) - super(SinogramData, self).__init__(array.as_array(), deep_copy, + super(AcquisitionData, self).__init__(array.as_array(), deep_copy, array.dimension_labels, **kwargs) elif type(array) == numpy.ndarray: if not ( array.ndim == 2 or array.ndim == 3 or array.ndim == 4 ): @@ -598,16 +598,16 @@ class SinogramData(DataSet): dimension_labels = ['angle' , 'horizontal'] - #DataSet.__init__(self, array, deep_copy, dimension_labels, **kwargs) - super(SinogramData, self).__init__(array, deep_copy, + #DataContainer.__init__(self, array, deep_copy, dimension_labels, **kwargs) + super(AcquisitionData, self).__init__(array, deep_copy, dimension_labels, **kwargs) class DataSetProcessor(object): - '''Defines a generic DataSet processor + '''Defines a generic DataContainer processor - accepts DataSet as inputs and - outputs DataSet + accepts DataContainer as inputs and + outputs DataContainer additional attributes can be defined with __setattr__ ''' @@ -624,7 +624,7 @@ class DataSetProcessor(object): def __setattr__(self, name, value): if name == 'input': - self.setInput(value) + self.set_input(value) elif name in self.__dict__.keys(): self.__dict__[name] = value self.__dict__['mTime'] = datetime.now() @@ -632,23 +632,23 @@ class DataSetProcessor(object): raise KeyError('Attribute {0} not found'.format(name)) #pass - def setInput(self, dataset): - if issubclass(type(dataset), DataSet): - if self.checkInput(dataset): + def set_input(self, dataset): + if issubclass(type(dataset), DataContainer): + if self.check_input(dataset): self.__dict__['input'] = dataset else: raise TypeError("Input type mismatch: got {0} expecting {1}"\ - .format(type(dataset), DataSet)) + .format(type(dataset), DataContainer)) - def checkInput(self, dataset): - '''Checks parameters of the input DataSet + def check_input(self, dataset): + '''Checks parameters of the input DataContainer - Should raise an Error if the DataSet does not match expectation, e.g. - if the expected input DataSet is 3D and the Processor expects 2D. + Should raise an Error if the DataContainer does not match expectation, e.g. + if the expected input DataContainer is 3D and the Processor expects 2D. ''' - raise NotImplementedError('Implement basic checks for input DataSet') + raise NotImplementedError('Implement basic checks for input DataContainer') - def getOutput(self): + def get_output(self): if None in self.__dict__.values(): raise ValueError('Not all parameters have been passed') shouldRun = False @@ -665,21 +665,21 @@ class DataSetProcessor(object): self.runTime = datetime.now() return self.process() - def setInputProcessor(self, processor): + def set_input_processor(self, processor): if issubclass(type(processor), DataSetProcessor): self.__dict__['input'] = processor else: raise TypeError("Input type mismatch: got {0} expecting {1}"\ .format(type(processor), DataSetProcessor)) - def getInput(self): - '''returns the input DataSet + def get_input(self): + '''returns the input DataContainer It is useful in the case the user has provided a DataSetProcessor as input ''' if issubclass(type(self.input), DataSetProcessor): - dsi = self.input.getOutput() + dsi = self.input.get_output() else: dsi = self.input return dsi @@ -691,8 +691,8 @@ class DataSetProcessor23D(DataSetProcessor): '''Regularizers DataSetProcessor ''' - def checkInput(self, dataset): - '''Checks number of dimensions input DataSet + def check_input(self, dataset): + '''Checks number of dimensions input DataContainer Expected input is 2D or 3D ''' @@ -714,7 +714,7 @@ class AX(DataSetProcessor): a is a scalar - x a DataSet. + x a DataContainer. ''' def __init__(self): @@ -725,15 +725,15 @@ class AX(DataSetProcessor): #DataSetProcessor.__init__(self, **kwargs) super(AX, self).__init__(**kwargs) - def checkInput(self, dataset): + def check_input(self, dataset): return True def process(self): - dsi = self.getInput() + dsi = self.get_input() a = self.scalar - y = DataSet( a * dsi.as_array() , True, + y = DataContainer( a * dsi.as_array() , True, dimension_labels=dsi.dimension_labels ) #self.setParameter(output_dataset=y) return y @@ -744,7 +744,7 @@ class AX(DataSetProcessor): class PixelByPixelDataSetProcessor(DataSetProcessor): '''Example DataSetProcessor - This processor applies a python function to each pixel of the DataSet + This processor applies a python function to each pixel of the DataContainer f is a python function @@ -758,18 +758,18 @@ class PixelByPixelDataSetProcessor(DataSetProcessor): #DataSetProcessor.__init__(self, **kwargs) super(PixelByPixelDataSetProcessor, self).__init__(**kwargs) - def checkInput(self, dataset): + def check_input(self, dataset): return True def process(self): pyfunc = self.pyfunc - dsi = self.getInput() + dsi = self.get_input() eval_func = numpy.frompyfunc(pyfunc,1,1) - y = DataSet( eval_func( dsi.as_array() ) , True, + y = DataContainer( eval_func( dsi.as_array() ) , True, dimension_labels=dsi.dimension_labels ) return y @@ -786,7 +786,7 @@ if __name__ == '__main__': print("a refcount " , sys.getrefcount(a)) a = numpy.reshape(a, shape) print("a refcount " , sys.getrefcount(a)) - ds = DataSet(a, False, ['X', 'Y','Z' ,'W']) + ds = DataContainer(a, False, ['X', 'Y','Z' ,'W']) print("a refcount " , sys.getrefcount(a)) print ("ds label {0}".format(ds.dimension_labels)) subset = ['W' ,'X'] @@ -797,34 +797,34 @@ if __name__ == '__main__': c = ds.subset(['Z','W','X']) print("a refcount " , sys.getrefcount(a)) - # Create a VolumeData sharing the array with c - volume0 = VolumeData(c.as_array(), False, dimensions = c.dimension_labels) - volume1 = VolumeData(c, False) + # Create a ImageData sharing the array with c + volume0 = ImageData(c.as_array(), False, dimensions = c.dimension_labels) + volume1 = ImageData(c, False) print ("volume0 {0} volume1 {1}".format(id(volume0.array), id(volume1.array))) - # Create a VolumeData copying the array from c - volume2 = VolumeData(c.as_array(), dimensions = c.dimension_labels) - volume3 = VolumeData(c) + # Create a ImageData copying the array from c + volume2 = ImageData(c.as_array(), dimensions = c.dimension_labels) + volume3 = ImageData(c) print ("volume2 {0} volume3 {1}".format(id(volume2.array), id(volume3.array))) # single number DataSet - sn = DataSet(numpy.asarray([1])) + sn = DataContainer(numpy.asarray([1])) ax = AX() ax.scalar = 2 - ax.setInput(c) + ax.set_input(c) #ax.apply() print ("ax in {0} out {1}".format(c.as_array().flatten(), - ax.getOutput().as_array().flatten())) + ax.get_output().as_array().flatten())) axm = AX() axm.scalar = 0.5 - axm.setInput(c) + axm.set_input(c) #axm.apply() - print ("axm in {0} out {1}".format(c.as_array(), axm.getOutput().as_array())) + print ("axm in {0} out {1}".format(c.as_array(), axm.get_output().as_array())) # create a PixelByPixelDataSetProcessor @@ -832,20 +832,20 @@ if __name__ == '__main__': pyfunc = lambda x: -x if x > 20 else x clip = PixelByPixelDataSetProcessor() clip.pyfunc = pyfunc - clip.setInput(c) + clip.set_input(c) #clip.apply() - print ("clip in {0} out {1}".format(c.as_array(), clip.getOutput().as_array())) + print ("clip in {0} out {1}".format(c.as_array(), clip.get_output().as_array())) #dsp = DataSetProcessor() - #dsp.setInput(ds) + #dsp.set_input(ds) #dsp.input = a # pipeline chain = AX() chain.scalar = 0.5 - chain.setInputProcessor(ax) - print ("chain in {0} out {1}".format(ax.getOutput().as_array(), chain.getOutput().as_array())) + chain.set_input_processor(ax) + print ("chain in {0} out {1}".format(ax.get_output().as_array(), chain.get_output().as_array())) # testing arithmetic operations @@ -875,14 +875,14 @@ if __name__ == '__main__': s = [i for i in range(3 * 4 * 4)] s = numpy.reshape(numpy.asarray(s), (3,4,4)) - sino = SinogramData( s ) + sino = AcquisitionData( s ) shape = (4,3,2) a = [i for i in range(2*3*4)] a = numpy.asarray(a) a = numpy.reshape(a, shape) print (numpy.shape(a)) - ds = DataSet(a, True, ['X', 'Y','Z']) + ds = DataContainer(a, True, ['X', 'Y','Z']) # this means that I expect the X to be of length 2 , # y of length 3 and z of length 4 subset = ['Y' ,'Z'] @@ -896,13 +896,13 @@ if __name__ == '__main__': print ("shape b 2,3? {0}".format(numpy.shape(b1.as_array()))) - # create VolumeData from geometry + # create ImageData from geometry vgeometry = geoms.VolumeGeometry(voxel_num_x=2, voxel_num_y=3, channels=2) - vol = VolumeData(geometry=vgeometry) + vol = ImageData(geometry=vgeometry) sgeometry = geoms.SinogramGeometry(dimension=2, angles=numpy.linspace(0, 180, num=20), geom_type='parallel', pixel_num_v=3, pixel_num_h=5 , channels=2) - sino = SinogramData(geometry=sgeometry) + sino = AcquisitionData(geometry=sgeometry) sino2 = sino.clone() \ No newline at end of file diff --git a/Wrappers/Python/ccpi/reconstruction/algs.py b/Wrappers/Python/ccpi/reconstruction/algs.py index 088b36e..ec52fee 100644 --- a/Wrappers/Python/ccpi/reconstruction/algs.py +++ b/Wrappers/Python/ccpi/reconstruction/algs.py @@ -21,7 +21,6 @@ import numpy import time from ccpi.reconstruction.funcs import BaseFunction -from ccpi.framework import SinogramData, VolumeData def FISTA(x_init, f=None, g=None, opt=None): diff --git a/Wrappers/Python/ccpi/reconstruction/ops.py b/Wrappers/Python/ccpi/reconstruction/ops.py index c21ff06..d6f31eb 100644 --- a/Wrappers/Python/ccpi/reconstruction/ops.py +++ b/Wrappers/Python/ccpi/reconstruction/ops.py @@ -19,10 +19,10 @@ import numpy from scipy.sparse.linalg import svds -from ccpi.framework import DataSet, VolumeData, SinogramData, DataSetProcessor +from ccpi.framework import DataContainer # Maybe operators need to know what types they take as inputs/outputs -# to not just use generic DataSet +# to not just use generic DataContainer class Operator(object): @@ -60,10 +60,10 @@ class LinearOperatorMatrix(Operator): super(LinearOperatorMatrix, self).__init__() def direct(self,x): - return DataSet(numpy.dot(self.A,x.as_array())) + return DataContainer(numpy.dot(self.A,x.as_array())) def adjoint(self,x): - return DataSet(numpy.dot(self.A.transpose(),x.as_array())) + return DataContainer(numpy.dot(self.A.transpose(),x.as_array())) def size(self): return self.A.shape @@ -130,7 +130,7 @@ class FiniteDiff2D(Operator): def PowerMethodNonsquare(op,numiters): # Initialise random inputsize = op.size()[1] - x0 = DataSet(numpy.random.randn(inputsize[0],inputsize[1])) + x0 = DataContainer(numpy.random.randn(inputsize[0],inputsize[1])) s = numpy.zeros(numiters) # Loop for it in numpy.arange(numiters): diff --git a/Wrappers/Python/wip/simple_demo.py b/Wrappers/Python/wip/simple_demo.py index 766e448..99109a6 100644 --- a/Wrappers/Python/wip/simple_demo.py +++ b/Wrappers/Python/wip/simple_demo.py @@ -1,10 +1,10 @@ #import sys #sys.path.append("..") -from ccpi.framework import VolumeData -from ccpi.reconstruction.algs import * +from ccpi.framework import ImageData +from ccpi.reconstruction.algs import FISTA, FBPD, CGLS from ccpi.reconstruction.funcs import Norm2sq, Norm1 -from ccpi.reconstruction.astra_ops import AstraProjectorSimple +from ccpi.astra.astra_ops import AstraProjectorSimple from ccpi.reconstruction.geoms import VolumeGeometry, SinogramGeometry import numpy as np @@ -16,7 +16,7 @@ test_case = 1 # 1=parallel2D, 2=cone2D N = 128 vg = VolumeGeometry(voxel_num_x=N,voxel_num_y=N) -Phantom = VolumeData(geometry=vg) +Phantom = ImageData(geometry=vg) x = Phantom.as_array() x[round(N/4):round(3*N/4),round(N/4):round(3*N/4)] = 1.0 @@ -77,7 +77,7 @@ plt.show() f = Norm2sq(Aop,b,c=0.5) # Initial guess -x_init = VolumeData(np.zeros(x.shape),geometry=vg) +x_init = ImageData(np.zeros(x.shape),geometry=vg) # Run FISTA for least squares without regularization x_fista0, it0, timing0, criter0 = FISTA(x_init, f, None) @@ -131,7 +131,7 @@ current = 1 fig = plt.figure() # projections row a=fig.add_subplot(rows,cols,current) -a.set_title('phantom {0}'.format(numpy.shape(Phantom.as_array()))) +a.set_title('phantom {0}'.format(np.shape(Phantom.as_array()))) imgplot = plt.imshow(Phantom.as_array()) current = current + 1 diff --git a/Wrappers/Python/wip/simple_mc_demo.py b/Wrappers/Python/wip/simple_mc_demo.py index 0d976d7..0bd48dd 100755 --- a/Wrappers/Python/wip/simple_mc_demo.py +++ b/Wrappers/Python/wip/simple_mc_demo.py @@ -1,10 +1,10 @@ #import sys #sys.path.append("..") -from ccpi.framework import VolumeData, SinogramData +from ccpi.framework import ImageData, AcquisitionData from ccpi.reconstruction.algs import FISTA from ccpi.reconstruction.funcs import Norm2sq, Norm1 -from ccpi.reconstruction.astra_ops import AstraProjectorMC +from ccpi.astra.astra_ops import AstraProjectorMC from ccpi.reconstruction.geoms import VolumeGeometry, SinogramGeometry import numpy @@ -18,7 +18,7 @@ M = 100 numchannels = 3 vg = VolumeGeometry(voxel_num_x=N,voxel_num_y=N,channels=numchannels) -Phantom = VolumeData(geometry=vg) +Phantom = ImageData(geometry=vg) x = Phantom.as_array() x[0 , round(N/4):round(3*N/4) , round(N/4):round(3*N/4) ] = 1.0 @@ -49,7 +49,7 @@ plt.show() #vg = VolumeGeometry(N,N,None, 1,1,None,channels=numchannels) -#Phantom = VolumeData(x,geometry=vg) +#Phantom = ImageData(x,geometry=vg) # Set up measurement geometry angles_num = 20; # angles number @@ -107,7 +107,7 @@ plt.show() f = Norm2sq(Aop,b,c=0.5) # Initial guess -x_init = VolumeData(numpy.zeros(x.shape),geometry=vg) +x_init = ImageData(numpy.zeros(x.shape),geometry=vg) # FISTA options opt = {'tol': 1e-4, 'iter': 200} -- cgit v1.2.3 From 98bf31eaa4b2d46a53dd4520114f84a914606f6d Mon Sep 17 00:00:00 2001 From: Edoardo Pasca Date: Wed, 14 Mar 2018 15:02:50 +0000 Subject: use lower_case and new naming --- Wrappers/Python/ccpi/processors.py | 59 +++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/Wrappers/Python/ccpi/processors.py b/Wrappers/Python/ccpi/processors.py index 87acf92..3010053 100755 --- a/Wrappers/Python/ccpi/processors.py +++ b/Wrappers/Python/ccpi/processors.py @@ -17,7 +17,8 @@ # See the License for the specific language governing permissions and # limitations under the License -from ccpi.framework import DataSetProcessor, DataSet, VolumeData, SinogramData, ImageGeometry, AcquisitionGeometry +from ccpi.framework import DataSetProcessor, DataSet, AcquisitionData,\ + AcquisitionGeometry import numpy import h5py from scipy import ndimage @@ -25,13 +26,13 @@ from scipy import ndimage class Normalizer(DataSetProcessor): '''Normalization based on flat and dark - This processor read in a SinogramDataSet and normalises it based on + This processor read in a AcquisitionData and normalises it based on the instrument reading with and without incident photons or neutrons. - Input: SinogramDataSet + Input: AcquisitionData Parameter: 2D projection with flat field (or stack) 2D projection with dark field (or stack) - Output: SinogramDataSetn + Output: AcquisitionDataSetn ''' def __init__(self, flat_field = None, dark_field = None, tolerance = 1e-5): @@ -45,37 +46,37 @@ class Normalizer(DataSetProcessor): #DataSetProcessor.__init__(self, **kwargs) super(Normalizer, self).__init__(**kwargs) if not flat_field is None: - self.setFlatField(flat_field) + self.set_flat_field(flat_field) if not dark_field is None: - self.setDarkField(dark_field) + self.set_dark_field(dark_field) - def checkInput(self, dataset): + def check_input(self, dataset): if dataset.number_of_dimensions == 3: return True else: raise ValueError("Expected input dimensions is 2 or 3, got {0}"\ .format(dataset.number_of_dimensions)) - def setDarkField(self, df): + def set_dark_field(self, df): if type(df) is numpy.ndarray: if len(numpy.shape(df)) == 3: raise ValueError('Dark Field should be 2D') elif len(numpy.shape(df)) == 2: self.dark_field = df elif issubclass(type(df), DataSet): - self.dark_field = self.setDarkField(df.as_array()) + self.dark_field = self.set_dark_field(df.as_array()) - def setFlatField(self, df): + def set_flat_field(self, df): if type(df) is numpy.ndarray: if len(numpy.shape(df)) == 3: raise ValueError('Flat Field should be 2D') elif len(numpy.shape(df)) == 2: self.flat_field = df elif issubclass(type(df), DataSet): - self.flat_field = self.setDarkField(df.as_array()) + self.flat_field = self.set_flat_field(df.as_array()) @staticmethod - def normalizeProjection(projection, flat, dark, tolerance): + def normalize_projection(projection, flat, dark, tolerance): a = (projection - dark) b = (flat-dark) with numpy.errstate(divide='ignore', invalid='ignore'): @@ -85,7 +86,7 @@ class Normalizer(DataSetProcessor): def process(self): - projections = self.getInput() + projections = self.get_input() dark = self.dark_field flat = self.flat_field @@ -95,7 +96,7 @@ class Normalizer(DataSetProcessor): a = numpy.asarray( - [ Normalizer.normalizeProjection( + [ Normalizer.normalize_projection( projection, flat, dark, self.tolerance) \ for projection in projections.as_array() ] ) @@ -108,10 +109,10 @@ class Normalizer(DataSetProcessor): class CenterOfRotationFinder(DataSetProcessor): '''Processor to find the center of rotation in a parallel beam experiment - This processor read in a SinogramDataSet and finds the center of rotation + This processor read in a AcquisitionDataSet and finds the center of rotation based on Nghia Vo's method. https://doi.org/10.1364/OE.22.019078 - Input: SinogramDataSet + Input: AcquisitionDataSet Output: float. center of rotation in pixel coordinate ''' @@ -124,7 +125,7 @@ class CenterOfRotationFinder(DataSetProcessor): #DataSetProcessor.__init__(self, **kwargs) super(CenterOfRotationFinder, self).__init__(**kwargs) - def checkInput(self, dataset): + def check_input(self, dataset): if dataset.number_of_dimensions == 3: if dataset.geometry.geom_type == 'parallel': return True @@ -378,7 +379,7 @@ class CenterOfRotationFinder(DataSetProcessor): def process(self): - projections = self.getInput() + projections = self.get_input() cor = CenterOfRotationFinder.find_center_vo(projections.as_array()) @@ -436,25 +437,25 @@ if __name__ == '__main__': pixel_num_h=numpy.shape(proj)[2], pixel_num_v=numpy.shape(proj)[1], ) - sino = SinogramData( proj , geometry=parallelbeam) + sino = AcquisitionData( proj , geometry=parallelbeam) normalizer = Normalizer() - normalizer.setInput(sino) - normalizer.setFlatField(flat) - normalizer.setDarkField(dark) - norm = normalizer.getOutput() + normalizer.set_input(sino) + normalizer.set_flat_field(flat) + normalizer.set_dark_field(dark) + norm = normalizer.get_output() print ("Processor min {0} max {1}".format(norm.as_array().min(), norm.as_array().max())) norm1 = numpy.asarray( - [Normalizer.normalizeProjection( p, flat, dark, 1e-5 ) + [Normalizer.normalize_projection( p, flat, dark, 1e-5 ) for p in proj] ) print ("Numpy min {0} max {1}".format(norm1.min(), norm1.max())) cor_finder = CenterOfRotationFinder() - cor_finder.setInput(sino) - cor = cor_finder.getOutput() + cor_finder.set_input(sino) + cor = cor_finder.get_output() print ("center of rotation {0} == 86.25?".format(cor)) conebeam = AcquisitionGeometry('cone', '3D' , @@ -462,9 +463,9 @@ if __name__ == '__main__': pixel_num_h=numpy.shape(proj)[2], pixel_num_v=numpy.shape(proj)[1], ) - sino = SinogramData( proj , geometry=conebeam) + sino = AcquisitionData( proj , geometry=conebeam) try: - cor_finder.setInput(sino) - cor = cor_finder.getOutput() + cor_finder.set_input(sino) + cor = cor_finder.get_output() except ValueError as err: print (err) \ No newline at end of file -- cgit v1.2.3 From 6b0f7ec43aa623faa7c2497929890bf1098f774c Mon Sep 17 00:00:00 2001 From: Edoardo Pasca Date: Wed, 14 Mar 2018 15:23:41 +0000 Subject: changed naming --- Wrappers/Python/wip/simple_demo.py | 12 ++++-------- Wrappers/Python/wip/simple_mc_demo.py | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Wrappers/Python/wip/simple_demo.py b/Wrappers/Python/wip/simple_demo.py index 655b68d..b183794 100644 --- a/Wrappers/Python/wip/simple_demo.py +++ b/Wrappers/Python/wip/simple_demo.py @@ -1,11 +1,10 @@ #import sys #sys.path.append("..") -from ccpi.framework import ImageData , VolumeGeometry, SinogramGeometry +from ccpi.framework import ImageData , ImageGeometry, AcquisitionGeometry from ccpi.reconstruction.algs import FISTA, FBPD, CGLS -from ccpi.reconstruction.funcs import Norm2sq, Norm1 +from ccpi.reconstruction.funcs import Norm2sq, Norm1 , TV2D from ccpi.astra.astra_ops import AstraProjectorSimple -from ccpi.reconstruction.geoms import import numpy as np import matplotlib.pyplot as plt @@ -17,7 +16,7 @@ N = 128 vg = ImageGeometry(voxel_num_x=N,voxel_num_y=N) -Phantom = VolumeData(geometry=vg) +Phantom = ImageData(geometry=vg) x = Phantom.as_array() x[round(N/4):round(3*N/4),round(N/4):round(3*N/4)] = 1.0 @@ -148,11 +147,8 @@ fig = plt.figure() # projections row a=fig.add_subplot(rows,cols,current) a.set_title('phantom {0}'.format(np.shape(Phantom.as_array()))) -<<<<<<< HEAD -imgplot = plt.imshow(Phantom.as_array()) -======= + imgplot = plt.imshow(Phantom.as_array(),vmin=clims[0],vmax=clims[1]) ->>>>>>> origin current = current + 1 a=fig.add_subplot(rows,cols,current) diff --git a/Wrappers/Python/wip/simple_mc_demo.py b/Wrappers/Python/wip/simple_mc_demo.py index bb74c09..f15e704 100755 --- a/Wrappers/Python/wip/simple_mc_demo.py +++ b/Wrappers/Python/wip/simple_mc_demo.py @@ -18,7 +18,7 @@ M = 100 numchannels = 3 vg = ImageGeometry(voxel_num_x=N,voxel_num_y=N,channels=numchannels) -Phantom = VolumeData(geometry=vg) +Phantom = ImageData(geometry=vg) x = Phantom.as_array() x[0 , round(N/4):round(3*N/4) , round(N/4):round(3*N/4) ] = 1.0 -- cgit v1.2.3