From b7f909f6f6c37085bb05debd27c375c826c1ce74 Mon Sep 17 00:00:00 2001 From: frog Date: Wed, 15 Jan 2003 21:48:33 +0000 Subject: [PATCH] * gdcmPython/setup.py and distutilsSwigCPlusPlus.py added. The distutils installer is operational. * - gdcmPython/__init__.py now properly loads the swig generated shadow classes (from gdcm.py). - gdcmPython/demo/*.py changed to import the package gdcmPython instead of gdcmPython/demo/load.py. - gdcmPython/testSuite.py changed to import the package gdcmPython. --- .cvsignore | 2 +- ChangeLog | 8 ++ distutilsSwigCPlusPlus.py | 131 ++++++++++++++++++++++ gdcmPython/__init__.py | 59 ++++++++++ gdcmPython/demo/explore.py | 5 +- gdcmPython/demo/load.py | 33 ------ gdcmPython/demo/printGroupedPublicDict.py | 4 +- gdcmPython/demo/test.py | 4 +- gdcmPython/demo/testAll.py | 10 +- gdcmPython/testSuite.py | 31 +---- setup.py | 58 ++++++++++ 11 files changed, 270 insertions(+), 75 deletions(-) create mode 100644 distutilsSwigCPlusPlus.py create mode 100644 gdcmPython/__init__.py delete mode 100644 gdcmPython/demo/load.py create mode 100644 setup.py diff --git a/.cvsignore b/.cvsignore index cba7efc8..0d20b648 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -a.out +*.pyc diff --git a/ChangeLog b/ChangeLog index eeee478b..ae252d3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2003-01-15 Eric Boix * python subdir moved to gdcmPython (preparation of distutils packaging). + * gdcmPython/setup.py and distutilsSwigCPlusPlus.py added. The + distutils installer is operational. + * - gdcmPython/__init__.py now properly loads the swig generated + shadow classes (from gdcm.py). + - gdcmPython/demo/*.py changed to import the package gdcmPython + instead of gdcmPython/demo/load.py. + - gdcmPython/testSuite.py changed to import the package gdcmPython. + 2002-12-16 Eric Boix * src/gdcm.h, src/gdcmHeader.cxx: added GetPubTagNames() resp. diff --git a/distutilsSwigCPlusPlus.py b/distutilsSwigCPlusPlus.py new file mode 100644 index 00000000..3a840a19 --- /dev/null +++ b/distutilsSwigCPlusPlus.py @@ -0,0 +1,131 @@ +from distutils.command.build_ext import build_ext +from distutils.core import Extension +from types import ListType +import os + +class mybuild_ext(build_ext): + """ + This distutils command is meant to be used with MyExtension extension, which + defines a swig_include attribute. + """ + build_ext.user_options.append(('swig-include=','S', + "list of directories for swig to search in" + + "for header files")) + + def initialize_options (self): + build_ext.initialize_options(self) + self.swig_include = None + + def finalize_options (self): + build_ext.finalize_options(self) + if self.swig_include!=None: + self.swig_include=self.swig_include.split(":") + + def build_extension(self, ext): + # command-line arguments prevail over extension arguments + # but if no command-line argument is defined, extension argument is + # taken into account + if self.swig_include==None:self.swig_include=ext.swig_include + if self.swig_cpp==None:self.swig_cpp=ext.swig_cpp + + build_ext.build_extension(self,ext) + + def swig_sources (self, sources): + + """Walk the list of source files in 'sources', looking for SWIG + interface (.i) files. Run SWIG on all that are found, and + return a modified 'sources' list with SWIG source files replaced + by the generated C (or C++) files. + """ + + new_sources = [] + swig_sources = [] + swig_targets = {} + + # XXX this drops generated C/C++ files into the source tree, which + # is fine for developers who want to distribute the generated + # source -- but there should be an option to put SWIG output in + # the temp dir. + + ## Modified lines (compared to buil_exts.wig_sources original method) + if self.swig_cpp: + target_ext = '_wrap.cpp' + else: + target_ext = '_wrap.c' + ## End of modification + + for source in sources: + (base, ext) = os.path.splitext(source) + if ext == ".i": # SWIG interface file + new_sources.append(base + target_ext) + swig_sources.append(source) + swig_targets[source] = new_sources[-1] + else: + new_sources.append(source) + + if not swig_sources: + return new_sources + + swig = self.find_swig() + + ## Modified lines (compared to buil_exts.wig_sources original method) + swig_cmd = [swig, "-python"] + if self.swig_cpp: + swig_cmd.append("-c++") + + if self.swig_include: + for pth in self.swig_include: + swig_cmd.append("-I%s"%pth) + ## End of modification + + for source in swig_sources: + target = swig_targets[source] + self.announce("swigging %s to %s" % (source, target)) + self.spawn(swig_cmd + ["-o", target, source]) + print swig_cmd + ["-o", target, source] + + return new_sources + +class MyExtension(Extension): + """ + This class extends basic distutils Extension class, adding two keyword + arguments : + * swig_cpp, which triggers -c++ mode when swigging + * swig_include, which specifies -I flag when swigging + This class is meant to be build with mybuild_ext distutils command. + """ + def __init__(self,swig_include=None,swig_cpp=None,**args): + Extension.__init__(self,**args) + + assert ((swig_include==None or type(swig_include) is ListType), + "swig_include must be a list of strings") + + self.swig_include = swig_include or [] + self.swig_cpp = swig_cpp + +""" +Example of use of these classes in distutils setup method : + +from Transfert.tcDistUtils import mybuild_ext,MyExtension +setup(name="xxx", + version="X.Y", + description="blah blah blah", + author="John Doe", + author_email="i.hate@spam.com", + url="http://www.fakeurl.com", + packages=["yyy"], + cmdclass={'build_ext':mybuild_ext}, # redirects default build_ext + ext_modules=[MyExtension(name="src/xxx, # instance of our Extension class + sources=["src/xxx.cpp", + "src/xxx.i"], + include_dirs=["/usr/include/python2.1", + "/usr/include/vtk"], + libraries=["vtkGraphics"], + swig_cpp=1, # C++ support + swig_include=["src"] # SWIG include dirs + ) + ] + ) + +and then run "python setup.py build"... +""" diff --git a/gdcmPython/__init__.py b/gdcmPython/__init__.py new file mode 100644 index 00000000..363c0bd5 --- /dev/null +++ b/gdcmPython/__init__.py @@ -0,0 +1,59 @@ +import os, sys + +### Setup the path to the dictionaries. WARNING: this needs to be done +# BEFORE importation of gdcm. We consider we found the dictionaries +# path when we encounter the standard dictionary i.e. the file dicomV3.dic. +# 1/ first consider the environnement variable. +# 2/ when this fails consider the package installation mode i.e. when the +# layout is such that the directory containing the dictionaries is +# BELOW (the root is at the top) the current directory. +# 3/ eventually consider the pre-installation mode i.e. when the +# layout is such that the directory containing the dictionaries is +# ABOVE (the root is at the top) the current directory. +# +try: + os.environ["GDCM_DICT_PATH"] + if not os.path.isfile(os.path.join(os.environ["GDCM_DICT_PATH"], + "dicomV3.dic")): + raise KeyError +except KeyError: + # Those pathes have to be relative to the package (hence we use __path__): + InstallModePath = os.path.join(__path__[0], "Dicts/") + if os.path.isfile(os.path.join(InstallModePath, "dicomV3.dic")): + os.environ["GDCM_DICT_PATH"] = InstallModePath + PreInstallModePath = None + else: + PreInstallModePath = os.path.join(__path__[0], "..", "Dicts/") + if os.path.isfile(os.path.join(PreInstallModePath, "dicomV3.dic")): + os.environ["GDCM_DICT_PATH"] = PreInstallModePath + InstallModePath = None + else: + print "Unfound gdcm dictionaries path" + sys.exit(1) + +### Import the swig generated shadow classes. +try: + from gdcm import * +except ImportError,e: + print e + raise ImportError, "gdcm extension not imported." + +### Set up the path to the data images (for examples and test suite) +if InstallModePath: + GDCM_DATA_PATH = os.path.join(__path__[0], "Data") +else: + if PreInstallModePath: + GDCM_DATA_PATH = os.path.join(__path__[0], "..", "Data") + else: + print "Unfound data path" + sys.exit(1) + +### Get filename from command line or default it +try: + FileName = sys.argv[1] +except IndexError: + FileName = os.path.join(GDCM_DATA_PATH, "test.acr") + +if not os.path.isfile(FileName): + print "Cannot open file ", FileName + sys.exit() diff --git a/gdcmPython/demo/explore.py b/gdcmPython/demo/explore.py index c11a9aeb..6ca9200b 100644 --- a/gdcmPython/demo/explore.py +++ b/gdcmPython/demo/explore.py @@ -1,7 +1,6 @@ -from load import * +from gdcmPython import * -########## Real usage of Pygdcm starts here -toRead = gdcm.gdcmHeader(FileName) +toRead = gdcmHeader(FileName) toRead.LoadElements() ValDict = toRead.GetPubElVal() ExploreElements = ["Patient Name", "Patient ID", diff --git a/gdcmPython/demo/load.py b/gdcmPython/demo/load.py deleted file mode 100644 index 0b13db8d..00000000 --- a/gdcmPython/demo/load.py +++ /dev/null @@ -1,33 +0,0 @@ -import os, sys - -### Defaulting the path to the dictionaries -# WARNING: this needs to be done before importation of gdcm ! -# FIXME: this needs to be put in a wrapper of the swig generated -# shadow classes (say Pygdcm.py?) -try: - os.environ["GDCM_DICT_PATH"] -except KeyError: - os.environ["GDCM_DICT_PATH"]="../../Dicts/" - -### When not properly installed (like in a cvs hierachy) try -# to handle properly the import of gdcm -try: - import gdcm -except ImportError: - import sys, os - PreInstallPath = os.path.join(os.getcwd(), "..") - sys.path.append(PreInstallPath) - try: - import gdcm - except ImportError,e: - raise ImportError, "gdcm extension module not found" - sys.exit() - -### Get filename from command line or default it -try: - FileName = sys.argv[1] -except IndexError: - FileName = os.path.join("..", "..", "Test", "test.acr") -if not os.path.isfile(FileName): - print "Cannot open file ", FileName - sys.exit() diff --git a/gdcmPython/demo/printGroupedPublicDict.py b/gdcmPython/demo/printGroupedPublicDict.py index 86a086b6..1dcd2f79 100644 --- a/gdcmPython/demo/printGroupedPublicDict.py +++ b/gdcmPython/demo/printGroupedPublicDict.py @@ -1,5 +1,5 @@ -from load import * -toRead = gdcm.gdcmHeader(FileName) +from gdcmPython import * +toRead = gdcmHeader(FileName) toRead.LoadElements() print "##############################################################" diff --git a/gdcmPython/demo/test.py b/gdcmPython/demo/test.py index 6a854291..c5d9da43 100644 --- a/gdcmPython/demo/test.py +++ b/gdcmPython/demo/test.py @@ -1,5 +1,5 @@ -from load import * -toRead = gdcm.gdcmHeader(FileName) +from gdcmPython import * +toRead = gdcmHeader(FileName) toRead.LoadElements() print "##############################################################" diff --git a/gdcmPython/demo/testAll.py b/gdcmPython/demo/testAll.py index 68274262..e46fda06 100644 --- a/gdcmPython/demo/testAll.py +++ b/gdcmPython/demo/testAll.py @@ -1,7 +1,6 @@ -from load import * +from gdcmPython import * -# Where all the test images are -TestFileDir = os.path.join("..", "..", "Data") +# Test each file of the Data directory AllFiles = [ "CR-MONO1-10-chest.dcm", @@ -28,11 +27,10 @@ AllFiles = [ if __name__ == '__main__': for file in AllFiles: - fileName = os.path.join(TestFileDir, file) + fileName = os.path.join(GDCM_DATA_PATH, file) print "############## file :", fileName - toRead = gdcm.gdcmHeader(fileName) + toRead = gdcmHeader(fileName) toRead.LoadElements() ValDict = toRead.GetPubElVal() for key in ValDict.keys(): print " [%s] = [%s]" %(key, ValDict[key]) - diff --git a/gdcmPython/testSuite.py b/gdcmPython/testSuite.py index d6c4dd2c..e053d655 100644 --- a/gdcmPython/testSuite.py +++ b/gdcmPython/testSuite.py @@ -1,31 +1,6 @@ import unittest import os - -# Where all the test images are -TestFileDir = os.path.join("..", "Data") - -### Defaulting the path to the dictionaries -# WARNING: this needs to be done before importation of gdcm ! -# FIXME: this needs to be put in a wrapper of the swig generated -# shadow classes (say Pygdcm.py?) -try: - os.environ["GDCM_DICT_PATH"] -except KeyError: - os.environ["GDCM_DICT_PATH"] = os.path.join("..", "Dicts/") - -### When not properly installed (like in a cvs hierachy) try -# to handle properly the import of gdcm -try: - import gdcm -except ImportError: - import sys, os - PreInstallPath = os.path.join(os.getcwd(), "..") - sys.path.append(PreInstallPath) - try: - import gdcm - except ImportError,e: - raise ImportError, "gdcm extension module not found" - sys.exit() +from gdcmPython import * class gdcmTestCase(unittest.TestCase): # The files whose name starts with a modality (e.g. CR-MONO1-10-chest.dcm) @@ -502,8 +477,8 @@ class gdcmTestCase(unittest.TestCase): def _BaseTest(self, FileSet): for entry in FileSet: - fileName = os.path.join(TestFileDir, entry[0]) - toRead = gdcm.gdcmHeader(fileName) + fileName = os.path.join(GDCM_DATA_PATH, entry[0]) + toRead = gdcmHeader(fileName) toRead.LoadElements() valDict = toRead.GetPubElVal() for subEntry in entry[1]: diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..983c54fc --- /dev/null +++ b/setup.py @@ -0,0 +1,58 @@ +from distutils.core import setup +import glob, os, sys +from distutilsSwigCPlusPlus import * + +PythonIncludes=os.path.join(sys.exec_prefix, 'include') +PythonIncludes=os.path.join(PythonIncludes, 'python' + sys.version[:3]) + +ThisModule='gdcmPython' + +gdcmSrcDir="src" +gdcmPythonSrcDir=ThisModule + +# Due to a disutil oddity on Unices : see +# http://aspn.activestate.com/ASPN/Mail/Message/distutils-sig/588325 +if(os.name=='posix'): + targetDir=os.path.join('lib', 'python' + sys.version[:3]) + targetDir=os.path.join(targetDir, 'site-packages') + ExtraPath=ThisModule +else: + targetDir='Lib' + ExtraPath=os.path.join(targetDir,ThisModule) + +targetDir=os.path.join(targetDir, ThisModule) + +setup(name=ThisModule, + version="0.1", + description="...", + author="frog", + author_email="frog@creatis.insa-lyon.fr", + url="http://www.creatis.insa-lyon.fr/", + packages=[ gdcmPythonSrcDir, + gdcmPythonSrcDir + '.demo', + ], + #package_dir={'':'python'}, + #extra_path = "zob", + cmdclass={'build_ext':mybuild_ext}, # redirects default build_ext + ext_modules=[MyExtension( + name='_gdcm', + sources=[os.path.join(gdcmSrcDir, "gdcmDict.cxx"), + os.path.join(gdcmSrcDir, "gdcmDictEntry.cxx"), + os.path.join(gdcmSrcDir, "gdcmDictSet.cxx"), + os.path.join(gdcmSrcDir, "gdcmElValSet.cxx"), + os.path.join(gdcmSrcDir, "gdcmElValue.cxx"), + os.path.join(gdcmSrcDir, "gdcmFile.cxx"), + os.path.join(gdcmSrcDir, "gdcmHeader.cxx"), + os.path.join(gdcmSrcDir, "gdcmUtil.cxx"), + os.path.join(gdcmPythonSrcDir, "gdcm.i")], + include_dirs=[gdcmSrcDir, PythonIncludes], + libraries=["stdc++"], + #library_dirs=[VTK_LIB_DIR], + swig_cpp=1, + swig_include=[gdcmSrcDir] ) ], + data_files=[(os.path.join(targetDir,"Data"), + glob.glob(os.path.join("Data","*.*"))), + (os.path.join(targetDir,"Dicts"), + glob.glob(os.path.join("Dicts","*.*"))), + ] + ) -- 2.45.1