# Copyright 2021 United Kingdom Research and Innovation# Copyright 2021 The University of Manchester## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.## Authors:# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txtfromcil.frameworkimportImageDatafromcil.framework.labelsimportImageDimensionimporttomophantomfromtomophantomimportTomoP2D,TomoP3Dimportosimportnumpyasnpimportctypes,platformfromctypesimportutil# check for the extensionifplatform.system()=='Linux':dll='libctomophantom.so'elifplatform.system()=='Windows':dll_file='ctomophantom.dll'dll=util.find_library(dll_file)elifplatform.system()=='Darwin':dll='libctomophantom.dylib'else:raiseValueError('Not supported platform, ',platform.system())libtomophantom=ctypes.cdll.LoadLibrary(dll)path=os.path.dirname(tomophantom.__file__)path_library2D=os.path.join(path,"Phantom2DLibrary.dat")path_library3D=os.path.join(path,"Phantom3DLibrary.dat")defis_model_temporal(num_model,num_dims=2):'''Returns whether a model in the TomoPhantom library is temporal This will go to check the installed library files from TomoPhantom https://github.com/dkazanc/TomoPhantom/tree/master/PhantomLibrary/models :param num_model: model number :type num_model: int :param num_dims: dimensionality of the phantom, 2D or 3D :type num_dims: int, default 2 '''returnget_model_num_channels(num_model,num_dims)>1defget_model_num_channels(num_model,num_dims=2):'''Returns number of temporal steps (channels) the model has This will go to check the installed library files from TomoPhantom https://github.com/dkazanc/TomoPhantom/tree/master/PhantomLibrary/models https://github.com/dkazanc/TomoPhantom/blob/v1.4.9/Core/utils.c#L27 https://github.com/dkazanc/TomoPhantom/blob/v1.4.9/Core/utils.c#L269 :param num_model: model number :type num_model: int :param num_dims: dimensionality of the phantom, 2D or 3D :type num_dims: int, default 2 '''returncheck_model_params(num_model,num_dims=num_dims)[3]defcheck_model_params(num_model,num_dims=2):'''Returns params_switch array from the C TomoPhantom library in function checkParams2D or checkParams3D This will go to check the installed library files from TomoPhantom https://github.com/dkazanc/TomoPhantom/tree/master/PhantomLibrary/models https://github.com/dkazanc/TomoPhantom/blob/v1.4.9/Core/utils.c#L27 https://github.com/dkazanc/TomoPhantom/blob/v1.4.9/Core/utils.c#L269 :param num_model: model number :type num_model: int :param num_dims: dimensionality of the phantom, 2D or 3D :type num_dims: int, default 2 '''ifnum_dims==2:libtomophantom.checkParams2D.argtypes=[ctypes.POINTER(ctypes.c_int),# pointer to the params arrayctypes.c_int,# model number selector (int)ctypes.c_char_p]# string to the library fileparams=np.zeros([10],dtype=np.int32)params_p=params.ctypes.data_as(ctypes.POINTER(ctypes.c_int))lib2d_p=str(path_library2D).encode('utf-8')libtomophantom.checkParams2D(params_p,num_model,lib2d_p)returnparamselifnum_dims==3:libtomophantom.checkParams3D.argtypes=[ctypes.POINTER(ctypes.c_int),# pointer to the params arrayctypes.c_int,# model number selector (int)ctypes.c_char_p]# string to the library fileparams=np.zeros([11],dtype=np.int32)params_p=params.ctypes.data_as(ctypes.POINTER(ctypes.c_int))lib2d_p=str(path_library3D).encode('utf-8')libtomophantom.checkParams3D(params_p,num_model,lib2d_p)returnparamselse:raiseValueError('Unsupported dimensionality. Expected 2 or 3, got {}'.format(dims))
[docs]defget_ImageData(num_model,geometry):'''Returns an ImageData relative to geometry with the model num_model from tomophantom :param num_model: model number :type num_model: int :param geometry: geometrical info that describes the phantom :type geometry: ImageGeometry Example usage: .. code-block:: python ndim = 2 N=128 angles = np.linspace(0, 360, 50, True, dtype=np.float32) offset = 0.4 channels = 3 if ndim == 2: ag = AcquisitionGeometry.create_Cone2D((offset,-100), (offset,100)) ag.set_panel(N) else: ag = AcquisitionGeometry.create_Cone3D((offset,-100, 0), (offset,100,0)) ag.set_panel((N,N-2)) ag.set_channels(channels) ag.set_angles(angles, angle_unit=AngleUnit.DEGREE) ig = ag.get_ImageGeometry() num_model = 1 phantom = TomoPhantom.get_ImageData(num_model=num_model, geometry=ig) '''ig=geometry.copy()ig.set_labels(ImageDimension.get_order_for_engine('cil'))num_dims=len(ig.dimension_labels)ifImageDimension.CHANNELinig.dimension_labels:ifnotis_model_temporal(num_model):raiseValueError('Selected model {} is not a temporal model, please change your selection'.format(num_model))ifnum_dims==4:# 3D+time for tomophantom# output dimensions channel and then spatial,# e.g. [ 'channel', 'vertical', 'horizontal_y', 'horizontal_x' ]num_model=num_modelshape=tuple(ig.shape[1:])phantom_arr=TomoP3D.ModelTemporal(num_model,shape,path_library3D)elifnum_dims==3:# 2D+time for tomophantom# output dimensions channel and then spatial,# e.g. [ 'channel', 'horizontal_y', 'horizontal_x' ]N=ig.shape[1]num_model=num_modelphantom_arr=TomoP2D.ModelTemporal(num_model,ig.shape[1],path_library2D)else:raiseValueError('Wrong ImageGeometry')ifig.channels!=phantom_arr.shape[0]:raiseValueError('The required model {} has {} channels. The ImageGeometry you passed has {}. Please update your ImageGeometry.'\
.format(num_model,ig.channels,phantom_arr.shape[0]))else:ifnum_dims==3:# 3Dnum_model=num_modelphantom_arr=TomoP3D.Model(num_model,ig.shape,path_library3D)elifnum_dims==2:# 2Difig.shape[0]!=ig.shape[1]:raiseValueError('Can only handle square ImageData, got shape'.format(ig.shape))N=ig.shape[0]num_model=num_modelphantom_arr=TomoP2D.Model(num_model,N,path_library2D)else:raiseValueError('Wrong ImageGeometry')im_data=ImageData(phantom_arr,geometry=ig,suppress_warning=True)im_data.reorder(list(geometry.dimension_labels))returnim_data