From a98459d9d10ad819d2f64219e17d14704d00d29f Mon Sep 17 00:00:00 2001 From: Francois Budin Date: Wed, 11 May 2016 14:26:50 -0400 Subject: [PATCH 1/3] ENH: Addition of ctk_cli ctk_cli [1] is a command line parsing python package that parses arguments the same way SlicerExecutionModel does. Using ctk_cli allows in Python scripts allows to have the same user interface in Python or in C++. [1] https://github.com/commontk/ctk-cli --- SuperBuild.cmake | 2 +- SuperBuild/External_python-ctk_cli.cmake | 36 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 SuperBuild/External_python-ctk_cli.cmake diff --git a/SuperBuild.cmake b/SuperBuild.cmake index c1c40204dc3..c5da79be547 100644 --- a/SuperBuild.cmake +++ b/SuperBuild.cmake @@ -100,7 +100,7 @@ if(Slicer_USE_SimpleITK) endif() if(Slicer_BUILD_CLI_SUPPORT) - list(APPEND Slicer_DEPENDENCIES SlicerExecutionModel) + list(APPEND Slicer_DEPENDENCIES SlicerExecutionModel python-ctk_cli) endif() if(Slicer_BUILD_EXTENSIONMANAGER_SUPPORT) diff --git a/SuperBuild/External_python-ctk_cli.cmake b/SuperBuild/External_python-ctk_cli.cmake new file mode 100644 index 00000000000..64c37751c2f --- /dev/null +++ b/SuperBuild/External_python-ctk_cli.cmake @@ -0,0 +1,36 @@ +set(proj python-ctk_cli) + +# Set dependency list +set(${proj}_DEPENDENCIES python python-setuptools) + +# Include dependent projects if any +ExternalProject_Include_Dependencies(${proj} PROJECT_VAR proj DEPENDS_VAR ${proj}_DEPENDENCIES) + +if(${CMAKE_PROJECT_NAME}_USE_SYSTEM_${proj}) + # XXX - Add a test checking if is available +endif() + +if(NOT DEFINED ${CMAKE_PROJECT_NAME}_USE_SYSTEM_${proj}) + set(${CMAKE_PROJECT_NAME}_USE_SYSTEM_${proj} ${${CMAKE_PROJECT_NAME}_USE_SYSTEM_python}) +endif() + +set(ctk_cli_REPOSITORY ${git_protocol}://github.com/commontk/ctk-cli.git) +set(ctk_cli_GIT_TAG 4346a22618b299c8eff84c6a179067ca68db43b9) + +if(NOT ${CMAKE_PROJECT_NAME}_USE_SYSTEM_${proj}) + + ExternalProject_Add(${proj} + ${${proj}_EP_ARGS} + GIT_REPOSITORY ${ctk_cli_REPOSITORY} + GIT_TAG ${ctk_cli_GIT_TAG} + SOURCE_DIR ${proj} + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND ${PYTHON_EXECUTABLE} setup.py install + DEPENDS + ${${proj}_DEPENDENCIES} + ) +else() + ExternalProject_Add_Empty(${proj} DEPENDS ${${proj}_DEPENDENCIES}) +endif() From 80a5a9b2331fc205330f003852f21eb7612a7618 Mon Sep 17 00:00:00 2001 From: Francois Budin Date: Fri, 13 May 2016 11:23:31 -0400 Subject: [PATCH 2/3] BUG: Template argument name was modified in template declaration Template argument name was modified in template declaration but not when using it in the templated function. --- .../CLIModuleTemplate/CLIModuleTemplate.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplate/CLIModuleTemplate.cxx b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplate/CLIModuleTemplate.cxx index 28f2121d40c..f0cc177539d 100644 --- a/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplate/CLIModuleTemplate.cxx +++ b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplate/CLIModuleTemplate.cxx @@ -15,7 +15,7 @@ namespace { template -int DoIt( int argc, char * argv[], T ) +int DoIt( int argc, char * argv[], TPixel ) { PARSE_ARGS; From e3a73d06b11b6670caee2df0f8f400fbd7ab44a8 Mon Sep 17 00:00:00 2001 From: Francois Budin Date: Fri, 13 May 2016 11:34:42 -0400 Subject: [PATCH 3/3] ENH: Addition of an example to use ctk_cli ctk_cli allows to parse python scripts command lines the same way they would be parsed with SlicerExecutionModel. This commit adds an example to show how to use this package. --- .../CLIModuleTemplatePython.py | 36 +++++++++++++ .../CLIModuleTemplatePython.xml | 52 +++++++++++++++++++ .../CLIModuleTemplatePython/CMakeLists.txt | 12 +++++ .../Baseline/CLIModuleTemplateTest.nhdr.md5 | 1 + .../Baseline/CLIModuleTemplateTest.raw.md5 | 1 + .../Data/Input/CTHeadAxial.nhdr.md5 | 1 + .../Data/Input/CTHeadAxial.raw.gz.md5 | 1 + .../Testing/CMakeLists.txt | 1 + .../Testing/Python/CMakeLists.txt | 17 ++++++ .../CLIExtensionTemplate/CMakeLists.txt | 1 + 10 files changed, 123 insertions(+) create mode 100644 Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/CLIModuleTemplatePython.py create mode 100644 Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/CLIModuleTemplatePython.xml create mode 100644 Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/CMakeLists.txt create mode 100644 Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Baseline/CLIModuleTemplateTest.nhdr.md5 create mode 100644 Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Baseline/CLIModuleTemplateTest.raw.md5 create mode 100644 Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Input/CTHeadAxial.nhdr.md5 create mode 100644 Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Input/CTHeadAxial.raw.gz.md5 create mode 100644 Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Testing/CMakeLists.txt create mode 100644 Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Testing/Python/CMakeLists.txt diff --git a/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/CLIModuleTemplatePython.py b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/CLIModuleTemplatePython.py new file mode 100644 index 00000000000..841dd166246 --- /dev/null +++ b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/CLIModuleTemplatePython.py @@ -0,0 +1,36 @@ +import itk +from ctk_cli import * +import sys +import logging + +def SmoothingRecursiveGaussianImageFilter(inputVolume, outputVolume, sigma): + reader = itk.ImageFileReader.New(FileName=inputVolume) + filter = itk.SmoothingRecursiveGaussianImageFilter.New(reader) + filter.SetSigma(sigma) + writer = itk.ImageFileWriter.New(filter,FileName=outputVolume) + writer.SetUseCompression(True) + writer.Update() + return 1 + + +def main(): + """Parsing command line arguments and reading input files.""" + logging.basicConfig(level=logging.INFO) + args=CLIArgumentParser().parse_args() + # Run processing + SmoothingRecursiveGaussianImageFilter(args.inputVolume,args.outputVolume,args.sigma) + # Compare output with baseline + reader1 = itk.ImageFileReader.New(FileName=args.outputVolume) + reader2 = itk.ImageFileReader.New(FileName=args.baselineVolume) + compareFilter=itk.ComparisonImageFilter.New(reader1) + compareFilter.SetTestInput(reader1) + compareFilter.SetValidInput(reader2) + diff=compareFilter.GetTotalDifference() + if diff < args.tolerance: + return 0 + return 1 + +if __name__ == "__main__": + ret=main() + if ret: + sys.exit(ret) diff --git a/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/CLIModuleTemplatePython.xml b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/CLIModuleTemplatePython.xml new file mode 100644 index 00000000000..d646ee7c4ca --- /dev/null +++ b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/CLIModuleTemplatePython.xml @@ -0,0 +1,52 @@ + + + Examples + CLIPythonModuleTemplate + + 0.0.1 + http://www.example.com/Slicer/Modules/CLIPythonModuleTemplate + Slicer + FirstName LastName (Institution), FirstName LastName (Institution) + This work was partially funded by NIH grant NXNNXXNNNNNN-NNXN + + + + + sigma + sigma + s + + + 1.0 + + + inputVolume + + input + 0 + + + + outputVolume + + output + 1 + + + + baselineVolume + + input + 2 + + + + tolerance + tolerance + t + + + 0.0001 + + + diff --git a/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/CMakeLists.txt b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/CMakeLists.txt new file mode 100644 index 00000000000..617808fa81b --- /dev/null +++ b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/CMakeLists.txt @@ -0,0 +1,12 @@ + +#----------------------------------------------------------------------------- +set(MODULE_NAME CLIModuleTemplate) + +#----------------------------------------------------------------------------- + +set(PYTHON_MODULE_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_NAME}Python.py) + +#----------------------------------------------------------------------------- +if(BUILD_TESTING) + add_subdirectory(Testing) +endif() diff --git a/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Baseline/CLIModuleTemplateTest.nhdr.md5 b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Baseline/CLIModuleTemplateTest.nhdr.md5 new file mode 100644 index 00000000000..e3f7f4074cd --- /dev/null +++ b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Baseline/CLIModuleTemplateTest.nhdr.md5 @@ -0,0 +1 @@ +fc6170ceeff3d8217a9dd6a1add2ec8c diff --git a/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Baseline/CLIModuleTemplateTest.raw.md5 b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Baseline/CLIModuleTemplateTest.raw.md5 new file mode 100644 index 00000000000..6e640c3071f --- /dev/null +++ b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Baseline/CLIModuleTemplateTest.raw.md5 @@ -0,0 +1 @@ +0749d4d3f07a217030f9ae33d94c4559 \ No newline at end of file diff --git a/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Input/CTHeadAxial.nhdr.md5 b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Input/CTHeadAxial.nhdr.md5 new file mode 100644 index 00000000000..734a0467eee --- /dev/null +++ b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Input/CTHeadAxial.nhdr.md5 @@ -0,0 +1 @@ +6e5c289c73e14ba7a1b0f8aaf6ed249a \ No newline at end of file diff --git a/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Input/CTHeadAxial.raw.gz.md5 b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Input/CTHeadAxial.raw.gz.md5 new file mode 100644 index 00000000000..f555cb43501 --- /dev/null +++ b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Data/Input/CTHeadAxial.raw.gz.md5 @@ -0,0 +1 @@ +3ebd710c9cf9d75750f4569b8caf6d07 \ No newline at end of file diff --git a/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Testing/CMakeLists.txt b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Testing/CMakeLists.txt new file mode 100644 index 00000000000..655007a0aab --- /dev/null +++ b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Testing/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(Python) diff --git a/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Testing/Python/CMakeLists.txt b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Testing/Python/CMakeLists.txt new file mode 100644 index 00000000000..7267f62eefa --- /dev/null +++ b/Extensions/Testing/CLIExtensionTemplate/CLIModuleTemplatePython/Testing/Python/CMakeLists.txt @@ -0,0 +1,17 @@ +#----------------------------------------------------------------------------- +set(BASELINE ${CMAKE_CURRENT_SOURCE_DIR}/../../Data/Baseline) +set(INPUT ${CMAKE_CURRENT_SOURCE_DIR}/../../Data/Input) +set(TEMP "${CMAKE_BINARY_DIR}/Testing/Temporary") + +set(CLP ${MODULE_NAME}) + +#----------------------------------------------------------------------------- +set(testname ${CLP}PythonTest) +ExternalData_add_test(${CLP}PythonData NAME ${testname} COMMAND ${Slicer_LAUNCHER_EXECUTABLE} ${PYTHON_MODULE_SCRIPT} + --sigma 2.5 DATA{${INPUT}/CTHeadAxial.nhdr,CTHeadAxial.raw.gz} ${TEMP}/${CLP}Test.nhdr + DATA{${BASELINE}/${CLP}Test.nhdr,${CLP}Test.raw} + ) +set_property(TEST ${testname} PROPERTY LABELS ${CLP}) + +#----------------------------------------------------------------------------- +ExternalData_add_target(${CLP}PythonData) diff --git a/Extensions/Testing/CLIExtensionTemplate/CMakeLists.txt b/Extensions/Testing/CLIExtensionTemplate/CMakeLists.txt index f32f2661026..ee2c3f56221 100644 --- a/Extensions/Testing/CLIExtensionTemplate/CMakeLists.txt +++ b/Extensions/Testing/CLIExtensionTemplate/CMakeLists.txt @@ -19,6 +19,7 @@ include(${Slicer_USE_FILE}) #----------------------------------------------------------------------------- # Extension modules add_subdirectory(CLIModuleTemplate) +add_subdirectory(CLIModuleTemplatePython) ## NEXT_MODULE #-----------------------------------------------------------------------------