diff options
-rw-r--r-- | Wrappers/Python/ccpi/common.py | 143 | ||||
-rw-r--r-- | Wrappers/Python/setup.py | 76 | ||||
-rw-r--r-- | recipes/python/bld.bat | 13 | ||||
-rw-r--r-- | recipes/python/build.sh | 9 | ||||
-rw-r--r-- | recipes/python/meta.yaml | 36 |
5 files changed, 277 insertions, 0 deletions
diff --git a/Wrappers/Python/ccpi/common.py b/Wrappers/Python/ccpi/common.py new file mode 100644 index 0000000..6450951 --- /dev/null +++ b/Wrappers/Python/ccpi/common.py @@ -0,0 +1,143 @@ +# -*- coding: utf-8 -*- +# This work is part of the Core Imaging Library developed by +# Visual Analytics and Imaging System Group of the Science Technology +# Facilities Council, STFC + +# Copyright 2018 Edoardo Pasca + +# 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. +import abc +import numpy +import os +import sys +import time + +if sys.version_info[0] >= 3 and sys.version_info[1] >= 4: + ABC = abc.ABC +else: + ABC = abc.ABCMeta('ABC', (), {}) + +def find_key(dic, val): + """return the key of dictionary dic given the value""" + return [k for k, v in dic.items() if v == val][0] + +class CCPiBaseClass(object): + def __init__(self, **kwargs): + self.acceptedInputKeywords = [] + self.pars = {} + self.debug = True + + def setParameter(self, **kwargs): + '''set named parameter for the reconstructor engine + + raises Exception if the named parameter is not recognized + + ''' + for key , value in kwargs.items(): + if key in self.acceptedInputKeywords: + self.pars[key] = value + else: + raise KeyError('Wrong parameter "{0}" for {1}'.format(key, + self.__class__.__name__ )) + # setParameter + + def getParameter(self, key): + if type(key) is str: + if key in self.acceptedInputKeywords: + return self.pars[key] + else: + raise KeyError('Unrecongnised parameter: {0} '.format(key) ) + elif type(key) is list: + outpars = [] + for k in key: + outpars.append(self.getParameter(k)) + return outpars + else: + raise Exception('Unhandled input {0}' .format(str(type(key)))) + #getParameter + + def log(self, msg): + if self.debug: + print ("{0}: {1}".format(self.__class__.__name__, msg)) + +class DataSet(ABC): + '''Abstract class to hold data''' + + def __init__ (self, array, deep_copy=True, dimension_labels=None, + **kwargs): + '''Holds the data''' + + self.shape = numpy.shape(array) + self.number_of_dimensions = len (self.shape) + self.dimension_labels = {} + + if dimension_labels is not None and \ + len (dimension_labels) == self.number_of_dimensions: + for i in range(self.number_of_dimensions): + self.dimension_labels[i] = dimension_labels[i] + else: + for i in range(self.number_of_dimensions): + self.dimension_labels[i] = 'dimension_{0:02}'.format(i) + + if deep_copy: + self.array = array[:] + else: + self.array = array + + def as_array(self, dimensions=None): + if dimensions is None: + return self.array + else: + # check that all the requested dimensions are in the array + # this is done by checking the dimension_labels + proceed = True + axis_order = [] + if type(dimensions) == list: + for dl in dimensions: + if dl not in self.dimension_labels.values(): + proceed = False + break + else: + axis_order.append(find_key(self.dimension_labels, dl)) + print (axis_order) + # transpose the array and slice away the unwanted data + unwanted_dimensions = self.dimension_labels.copy() + for ax in axis_order: + unwanted_dimensions.pop(ax) + new_shape = [] + #for i in range(axis_order): + # new_shape.append(self.shape(axis_order[i])) + new_shape = [self.shape[ax] for ax in axis_order] + return numpy.reshape( + numpy.delete( self.array , unwanted_dimensions.keys() ) , + new_shape + ) + #return numpy.transpose(self.array, new_shape) + + + + + +if __name__ == '__main__': + shape = (2,3,4,5) + size = shape[0] + for i in range(1, len(shape)): + size = size * shape[i] + a = numpy.asarray([i for i in range( size )]) + a = numpy.reshape(a, shape) + ds = DataSet(a, False, ['X', 'Y','Z' ,'W']) + b = ds.as_array(['Z' ,'W']) + + + +
\ No newline at end of file diff --git a/Wrappers/Python/setup.py b/Wrappers/Python/setup.py new file mode 100644 index 0000000..31fe195 --- /dev/null +++ b/Wrappers/Python/setup.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python + +import setuptools +from distutils.core import setup +from distutils.extension import Extension +from Cython.Distutils import build_ext + +import os +import numpy +import platform +import sys + +cil_version=os.environ['CIL_VERSION'] +if cil_version == '': + print("Please set the environmental variable CIL_VERSION") + sys.exit(1) + +library_include_path = [] +library_lib_path = [] +try: + library_include_path = [ os.environ['LIBRARY_INC'] ] + library_lib_path = [ os.environ['LIBRARY_LIB'] ] +except: + if platform.system() == 'Windows': + pass + else: + try: + library_include_path = [ os.environ['PREFIX']+'/include' ] + library_lib_path = [ os.environ['PREFiX']+'/lib' ] + except: + pass + pass +extra_include_dirs = [numpy.get_include()] +extra_library_dirs = [] +extra_compile_args = [] +extra_link_args = [] +extra_libraries = [] + +if platform.system() == 'Windows': + extra_compile_args += ['/DWIN32','/EHsc','/DBOOST_ALL_NO_LIB', + '/openmp','/DHAS_TIFF','/DCCPiReconstructionIterative_EXPORTS'] + extra_include_dirs += ["..\\..\\Core\\src\\","..\\..\\Core\\src\\Algorithms","..\\..\\Core\\src\\Readers", "."] + extra_include_dirs += library_include_path + extra_library_dirs += library_lib_path + extra_libraries += ['tiff' , 'cilrec'] + if sys.version_info.major == 3 : + extra_libraries += ['boost_python3-vc140-mt-1_64', 'boost_numpy3-vc140-mt-1_64'] + else: + extra_libraries += ['boost_python-vc90-mt-1_64', 'boost_numpy-vc90-mt-1_64'] +else: + extra_include_dirs += ["../../Core/src/","../../Core/src/Algorithms","../../Core/src/Readers", "."] + extra_include_dirs += library_include_path + extra_compile_args += ['-fopenmp','-O2', '-funsigned-char', '-Wall','-Wl,--no-undefined','-DHAS_TIFF','-DCCPiReconstructionIterative_EXPORTS'] + extra_libraries += ['tiff' , 'cilrec'] + if sys.version_info.major == 3 : + extra_libraries += ['boost_python3', 'boost_numpy3','gomp'] + else: + extra_libraries += ['boost_python', 'boost_numpy','gomp'] + + +setup( + name='ccpi-reconstruction', + description='This is a CCPi Core Imaging Library package for Iterative Reconstruction codes', + version=cil_version, + cmdclass = {'build_ext': build_ext}, + ext_modules = [Extension("ccpi.reconstruction.parallelbeam", + sources=[ "src/diamond_module.cpp", + "src/diamond_wrapper.cpp"], + include_dirs=extra_include_dirs, library_dirs=extra_library_dirs, extra_compile_args=extra_compile_args, libraries=extra_libraries, extra_link_args=extra_link_args ), + Extension("ccpi.reconstruction.conebeam", + sources=[ "src/conebeam_module.cpp", + "src/conebeam_wrapper.cpp"], + include_dirs=extra_include_dirs, library_dirs=extra_library_dirs, extra_compile_args=extra_compile_args, libraries=extra_libraries ) ], + zip_safe = False, + packages = {'ccpi','ccpi.reconstruction'} +) diff --git a/recipes/python/bld.bat b/recipes/python/bld.bat new file mode 100644 index 0000000..f4c395c --- /dev/null +++ b/recipes/python/bld.bat @@ -0,0 +1,13 @@ +IF NOT DEFINED CIL_VERSION ( +ECHO CIL_VERSION Not Defined. +exit 1 +) + +mkdir "%SRC_DIR%\ccpi" +xcopy /e "%RECIPE_DIR%\..\..\.." "%SRC_DIR%\ccpi" +cd ccpi\Wrappers\python + +%PYTHON% setup.py build_ext +if errorlevel 1 exit 1 +%PYTHON% setup.py install +if errorlevel 1 exit 1 diff --git a/recipes/python/build.sh b/recipes/python/build.sh new file mode 100644 index 0000000..0c6ad30 --- /dev/null +++ b/recipes/python/build.sh @@ -0,0 +1,9 @@ +if [ -z "$CIL_VERSION" ]; then + echo "Need to set CIL_VERSION" + exit 1 +fi +mkdir ${SRC_DIR}/ccpi +cp -r "${RECIPE_DIR}/../../../" ${SRC_DIR}/ccpi + +cd ${SRC_DIR}/ccpi/Wrappers/python +$PYTHON setup.py install diff --git a/recipes/python/meta.yaml b/recipes/python/meta.yaml new file mode 100644 index 0000000..63a5a3a --- /dev/null +++ b/recipes/python/meta.yaml @@ -0,0 +1,36 @@ +package: + name: ccpi-reconstruction + version: {{ environ['CIL_VERSION'] }} + + +build: + preserve_egg_dir: False + script_env: + - CIL_VERSION +# number: 0 + +requirements: + build: + - python + - numpy + - setuptools + - boost ==1.64.0 + - boost-cpp ==1.64.0 + - cython + - libtiff + - cil_reconstruction + + run: + - python + - numpy + - boost ==1.64 + - libtiff + - h5py + - scipy + - cil_reconstruction + + +about: + home: http://www.ccpi.ac.uk + license: BSD license + summary: 'CCPi Toolbox' |