diff --git a/CMake/ITKSetStandardCompilerFlags.cmake b/CMake/ITKSetStandardCompilerFlags.cmake index 4f0bf6f..449b5d2 100644 --- a/CMake/ITKSetStandardCompilerFlags.cmake +++ b/CMake/ITKSetStandardCompilerFlags.cmake @@ -281,13 +281,7 @@ endmacro()#End the platform check function #----------------------------------------------------------------------------- #Check the set of warning flags the compiler supports -check_compiler_warning_flags(C_WARNING_FLAGS CXX_WARNING_FLAGS) - -# Append ITK warnings to the CMake flags. -# We do not set them in ITK_REQUIRED FLAGS because all project which -# use ITK don't require these flags . -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_WARNING_FLAGS}") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_WARNING_FLAGS}") +check_compiler_warning_flags(ITK_C_WARNING_FLAGS ITK_CXX_WARNING_FLAGS) #----------------------------------------------------------------------------- #Check the set of platform flags the compiler supports diff --git a/CMakeLists.txt b/CMakeLists.txt index d950f0e..ec09a89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,4 @@ -cmake_minimum_required(VERSION 2.8.9) -cmake_policy(VERSION 2.8.9) +cmake_minimum_required(VERSION 3.5) set(LOCAL_PROJECT_NAME DTIPrepTools) project(${LOCAL_PROJECT_NAME}) diff --git a/Common.cmake b/Common.cmake index 53b6c7e..2774f19 100644 --- a/Common.cmake +++ b/Common.cmake @@ -29,9 +29,6 @@ if(${ITK_VERSION_MAJOR} STREQUAL "3") set(USE_ITKv4 OFF) endif() -#CMAKE_DEPENDENT_OPTION( -# USE_DTIPrep "Build DTIPrep" ON "${LOCAL_PROJECT_NAME}_USE_QT" ON) - set(${LOCAL_PROJECT_NAME}_USE_QT ON) if(${LOCAL_PROJECT_NAME}_USE_QT AND NOT DTIPrep_BUILD_SLICER_EXTENSION ) if(NOT QT4_FOUND) @@ -121,22 +118,14 @@ SETIFEMPTY(DTIPrepTools_CLI_INSTALL_RUNTIME_DESTINATION ${CMAKE_INSTALL_RUNTIME_ #------------------------------------------------------------------------- include(ITKSetStandardCompilerFlags) if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_DEBUG_DESIRED_FLAGS}" ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_DEBUG_DESIRED_FLAGS}" ) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_INIT} ${ITK_C_WARNING_FLAGS} ${C_DEBUG_DESIRED_FLAGS}" ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_INIT} ${ITK_CXX_WARNING_FLAGS} ${CXX_DEBUG_DESIRED_FLAGS}" ) else() # Release, or anything else - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_RELEASE_DESIRED_FLAGS}" ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_RELEASE_DESIRED_FLAGS}" ) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_INIT} ${ITK_C_WARNING_FLAGS} ${C_RELEASE_DESIRED_FLAGS}" ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_INIT} ${ITK_CXX_WARNING_FLAGS} ${CXX_RELEASE_DESIRED_FLAGS}" ) endif() -#----------------------------------------------------------------------------- -# Add needed flag for gnu on linux like enviroments to build static common libs -# suitable for linking with shared object libs. -if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") - if(NOT "${CMAKE_CXX_FLAGS}" MATCHES "-fPIC") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") - endif() - if(NOT "${CMAKE_C_FLAGS}" MATCHES "-fPIC") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") - endif() -endif() +set(CMAKE_POSITION_INDEPENDENT_CODE 1) +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) diff --git a/DTIPrepTools.cmake b/DTIPrepTools.cmake index 202722f..913b421 100644 --- a/DTIPrepTools.cmake +++ b/DTIPrepTools.cmake @@ -42,7 +42,6 @@ set( ITKModules ITKRegistrationCommon ITKOptimizersv4 ITKConnectedComponents - ITKV3Compatibility ITKMathematicalMorphology ITKBinaryMathematicalMorphology ITKRegionGrowing @@ -193,7 +192,7 @@ if( DTIPrep_BUILD_SLICER_EXTENSION ) set(EXTENSION_HOMEPAGE "https://www.nitrc.org/projects/dtiprep/") set(EXTENSION_CATEGORY "DWI/DTI Quality Control") set(EXTENSION_CONTRIBUTORS "Joy Matsui, Zhexing Liu, Clement Vachet, David Welch, Guido Gerig, kent williams, Mahshid Farzinfar, Sylvain Gouttard, Vincent Magnotta, Hans Johnson, Martin Styner, Francois Budin, Juan Prieto") - set(EXTENSION_DESCRIPTION "DTIPrep performs a "Study-specific Protocol" based automatic pipeline for DWI/DTI quality control and preparation") + set(EXTENSION_DESCRIPTION "DTIPrep performs a 'Study-specific Protocol' based automatic pipeline for DWI/DTI quality control and preparation") set(EXTENSION_ICONURL "http://www.nitrc.org/project/screenshot.php?group_id=283&screenshot_id=608") set(EXTENSION_SCREENSHOTURLS "http://www.nitrc.org/project/screenshot.php?group_id=283&screenshot_id=609 http://www.nitrc.org/project/screenshot.php?group_id=283&screenshot_id=610") set(EXTENSION_DEPENDS "NA") # Specified as a space separated list or 'NA' if any @@ -222,7 +221,8 @@ if(USE_DTIProcess) ) list( APPEND ToolsPaths ${SUPERBUILD_BINARY_DIR}/DTIProcess-install/bin/ ) endif() -if(USE_NIRALUtilities) + +if(USE_niral_utilities) list(APPEND NotCLIToolsList ImageMath convertITKformats @@ -235,8 +235,7 @@ if( DTIPrep_BUILD_SLICER_EXTENSION ) INSTALL_EXECUTABLE( OUTPUT_DIR ${NOCLI_INSTALL_DIR} LIST_EXEC ${NotCLIToolsList} PATHS ${ToolsPaths} ) set(CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_INSTALL_CMAKE_PROJECTS};${CMAKE_BINARY_DIR};${EXTENSION_NAME};ALL;/") include(${Slicer_EXTENSION_CPACK}) -endif() -if( SUPERBUILD_NOT_EXTENSION ) +else() if( NOT APPLE ) INSTALL_EXECUTABLE( OUTPUT_DIR bin LIST_EXEC ${NotCLIToolsList} PATHS ${ToolsPaths} ) else() diff --git a/SuperBuild.cmake b/SuperBuild.cmake index e6c241c..fce0d1a 100644 --- a/SuperBuild.cmake +++ b/SuperBuild.cmake @@ -19,25 +19,57 @@ include(CTest) include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake) +option(USE_niral_utilities "Build niral_utilities" ON) + if( DTIPrep_BUILD_SLICER_EXTENSION ) set( EXTERNAL_SOURCE_IN_BINARY_DIR ON) set( USE_SYSTEM_VTK ON CACHE BOOL "Use system VTK" FORCE ) + set( USE_SYSTEM_ITK ON CACHE BOOL "Use system ITK" FORCE ) + set( USE_SYSTEM_SlicerExecutionModel ON CACHE BOOL "Use system SlicerExecutionModel" FORCE ) #VTK_VERSION_MAJOR is define but not a CACHE variable set( VTK_VERSION_MAJOR ${VTK_VERSION_MAJOR} CACHE STRING "Choose the expected VTK major version to build Slicer (5, 6, 7).") set( USE_SYSTEM_DCMTK ON CACHE BOOL "Use system DCMTK" FORCE ) set( USE_SYSTEM_Teem ON CACHE BOOL "Use system Teem" FORCE ) + set( USE_SYSTEM_DTIProcess ON CACHE BOOL "Use system DTIProcess" FORCE ) set( BUILD_SHARED_LIBS OFF CACHE BOOL "Use shared libraries" FORCE) - unsetForSlicer(NAMES CMAKE_MODULE_PATH CMAKE_C_COMPILER CMAKE_CXX_COMPILER DCMTK_DIR ITK_DIR SlicerExecutionModel_DIR VTK_DIR QT_QMAKE_EXECUTABLE ITK_VERSION_MAJOR CMAKE_CXX_FLAGS CMAKE_C_FLAGS Teem_DIR) + unsetForSlicer(NAMES + BRAINSCommonLib_DIR + CMAKE_MODULE_PATH + CMAKE_C_COMPILER + CMAKE_CXX_COMPILER + DCMTK_DIR + ITK_DIR + SlicerExecutionModel_DIR + VTK_DIR + QT_QMAKE_EXECUTABLE + ITK_VERSION_MAJOR + CMAKE_CXX_FLAGS + CMAKE_C_FLAGS + Teem_DIR + ) find_package(Slicer REQUIRED) - unsetAllForSlicerBut( NAMES VTK_DIR QT_QMAKE_EXECUTABLE DCMTK_DIR Teem_DIR ) - resetForSlicer(NAMES CMAKE_MODULE_PATH CMAKE_C_COMPILER CMAKE_CXX_COMPILER CMAKE_CXX_FLAGS CMAKE_C_FLAGS ITK_DIR SlicerExecutionModel_DIR ITK_VERSION_MAJOR ) + unsetAllForSlicerBut( NAMES + BRAINSCommonLib_DIR + SlicerExecutionModel_DIR + ITK_DIR + VTK_DIR + QT_QMAKE_EXECUTABLE + DCMTK_DIR + Teem_DIR + ) + resetForSlicer(NAMES + CMAKE_MODULE_PATH + CMAKE_C_COMPILER + CMAKE_CXX_COMPILER + CMAKE_CXX_FLAGS + CMAKE_C_FLAGS + ) if( APPLE ) set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath,@loader_path/../../../../../") endif() find_package(Subversion REQUIRED ) else() set( USE_ITK_Module_MGHIO ON ) - set( SUPERBUILD_NOT_EXTENSION TRUE ) option(USE_DTIProcess "Build DTIProcess" ON) endif() @@ -141,7 +173,12 @@ option(USE_SYSTEM_niral_utilities "Build using external niral_utilities" OFF) #------------------------------------------------------------------------------ # ${LOCAL_PROJECT_NAME} dependency list #------------------------------------------------------------------------------ -set( ${LOCAL_PROJECT_NAME}_DEPENDENCIES DCMTK ITKv4 SlicerExecutionModel VTK DTIProcess niral_utilities BRAINSTools) +set( ${LOCAL_PROJECT_NAME}_DEPENDENCIES VTK DCMTK ITKv4 SlicerExecutionModel DTIProcess niral_utilities) +if( NOT DTIPrep_BUILD_SLICER_EXTENSION ) + list(APPEND ${LOCAL_PROJECT_NAME}_DEPENDENCIES + BRAINSTools + ) +endif() set( ${PROJECT_NAME}_BUILD_DICOM_SUPPORT ON ) set( ${PROJECT_NAME}_BUILD_ZLIB_SUPPORT ON ) if( UNIX ) @@ -237,6 +274,12 @@ if(${LOCAL_PROJECT_NAME}_USE_QT) ) endif() +# Disable the "You are in 'detached HEAD' state." warning. +set(git_config_arg) +if(CMAKE_VERSION VERSION_GREATER "3.7.2") + set(git_config_arg GIT_CONFIG "advice.detachedHead=false") +endif() + _expand_external_project_vars() set(COMMON_EXTERNAL_PROJECT_ARGS ${${CMAKE_PROJECT_NAME}_SUPERBUILD_EP_ARGS}) set(extProjName ${LOCAL_PROJECT_NAME}) @@ -290,10 +333,6 @@ if( DTIPrep_BUILD_SLICER_EXTENSION ) Slicer_DIR:PATH DTIPrep_BUILD_SLICER_EXTENSION:BOOL ) -else() - list(APPEND ${CMAKE_PROJECT_NAME}_SUPERBUILD_EP_VARS - SUPERBUILD_NOT_EXTENSION:BOOL - ) endif() _expand_external_project_vars() set(COMMON_EXTERNAL_PROJECT_ARGS ${${CMAKE_PROJECT_NAME}_SUPERBUILD_EP_ARGS}) @@ -322,7 +361,7 @@ ExternalProject_Add(${proj} DEPENDS ${${LOCAL_PROJECT_NAME}_DEPENDENCIES} DOWNLOAD_COMMAND "" SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} - BINARY_DIR ${LOCAL_PROJECT_NAME}-build + BINARY_DIR ${LOCAL_PROJECT_NAME}-build CMAKE_GENERATOR ${gen} CMAKE_ARGS --no-warn-unused-cli # HACK Only expected variables should be passed down. @@ -330,7 +369,10 @@ ExternalProject_Add(${proj} ${COMMON_EXTERNAL_PROJECT_ARGS} -D${LOCAL_PROJECT_NAME}_SUPERBUILD:BOOL=OFF -DBUILD_TESTING:BOOL=${BUILD_TESTING} - INSTALL_COMMAND "" + -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/${LOCAL_PROJECT_NAME}-install + -DUSE_niral_utilities=${USE_niral_utilities} + -DUSE_DTIProcess=${USE_DTIProcess} + #INSTALL_COMMAND "" ) ## Force rebuilding of the main subproject every time building from super structure diff --git a/SuperBuild/External_ANTs.cmake b/SuperBuild/External_ANTs.cmake index 36ddfe8..6c17dc5 100644 --- a/SuperBuild/External_ANTs.cmake +++ b/SuperBuild/External_ANTs.cmake @@ -86,6 +86,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_BRAINSTools.cmake b/SuperBuild/External_BRAINSTools.cmake index 92bf070..6b327b2 100644 --- a/SuperBuild/External_BRAINSTools.cmake +++ b/SuperBuild/External_BRAINSTools.cmake @@ -242,6 +242,7 @@ if(NOT ( DEFINED "${extProjName}_SOURCE_DIR" OR ( DEFINED "USE_SYSTEM_${extProjN ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_BatchMake.cmake b/SuperBuild/External_BatchMake.cmake index 60d342c..dbd3416 100644 --- a/SuperBuild/External_BatchMake.cmake +++ b/SuperBuild/External_BatchMake.cmake @@ -69,6 +69,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_Cppcheck.cmake b/SuperBuild/External_Cppcheck.cmake index 2108ab7..2282110 100644 --- a/SuperBuild/External_Cppcheck.cmake +++ b/SuperBuild/External_Cppcheck.cmake @@ -60,6 +60,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BUILD_IN_SOURCE 1 LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_DCMTK.cmake b/SuperBuild/External_DCMTK.cmake index 150ea5e..837742d 100644 --- a/SuperBuild/External_DCMTK.cmake +++ b/SuperBuild/External_DCMTK.cmake @@ -119,6 +119,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${EXTERNAL_BINARY_DIRECTORY}/${proj}-build INSTALL_DIR ${EXTERNAL_BINARY_DIRECTORY}/${proj}-install diff --git a/SuperBuild/External_DTIProcess.cmake b/SuperBuild/External_DTIProcess.cmake index 7c41037..fa5f5f0 100644 --- a/SuperBuild/External_DTIProcess.cmake +++ b/SuperBuild/External_DTIProcess.cmake @@ -85,6 +85,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${EXTERNAL_BINARY_DIRECTORY}/${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_DTIReg.cmake b/SuperBuild/External_DTIReg.cmake index cbb7510..8c2d0c4 100644 --- a/SuperBuild/External_DTIReg.cmake +++ b/SuperBuild/External_DTIReg.cmake @@ -73,6 +73,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${EXTERNAL_BINARY_DIRECTORY}/${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_DTI_Tract_Stat.cmake b/SuperBuild/External_DTI_Tract_Stat.cmake index 62e34a7..98a1d52 100644 --- a/SuperBuild/External_DTI_Tract_Stat.cmake +++ b/SuperBuild/External_DTI_Tract_Stat.cmake @@ -70,6 +70,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${EXTERNAL_BINARY_DIRECTORY}/${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_JPEG.cmake b/SuperBuild/External_JPEG.cmake index e04bf7e..7f9ec36 100644 --- a/SuperBuild/External_JPEG.cmake +++ b/SuperBuild/External_JPEG.cmake @@ -72,6 +72,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${EXTERNAL_BINARY_DIRECTORY}/${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_KWStyle.cmake b/SuperBuild/External_KWStyle.cmake index 24c4b57..f466674 100644 --- a/SuperBuild/External_KWStyle.cmake +++ b/SuperBuild/External_KWStyle.cmake @@ -64,6 +64,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_OpenCV.cmake b/SuperBuild/External_OpenCV.cmake index d3dea71..fd32026 100644 --- a/SuperBuild/External_OpenCV.cmake +++ b/SuperBuild/External_OpenCV.cmake @@ -107,6 +107,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_SlicerExecutionModel.cmake b/SuperBuild/External_SlicerExecutionModel.cmake index 057837a..4bb821e 100644 --- a/SuperBuild/External_SlicerExecutionModel.cmake +++ b/SuperBuild/External_SlicerExecutionModel.cmake @@ -82,6 +82,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_Uncrustify.cmake b/SuperBuild/External_Uncrustify.cmake index 2cb55b3..bf0bd61 100644 --- a/SuperBuild/External_Uncrustify.cmake +++ b/SuperBuild/External_Uncrustify.cmake @@ -62,6 +62,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_VTK.cmake b/SuperBuild/External_VTK.cmake index ebbf630..e24fb8d 100644 --- a/SuperBuild/External_VTK.cmake +++ b/SuperBuild/External_VTK.cmake @@ -167,6 +167,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${proj}-build BUILD_COMMAND ${VTK_BUILD_STEP} diff --git a/SuperBuild/External_niral_utilities.cmake b/SuperBuild/External_niral_utilities.cmake index 33a46c5..8f33acc 100644 --- a/SuperBuild/External_niral_utilities.cmake +++ b/SuperBuild/External_niral_utilities.cmake @@ -55,6 +55,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ### --- Project specific additions here set(${proj}_CMAKE_OPTIONS + -DBUILD_TESTING:BOOL=OFF -DCOMPILE_CONVERTITKFORMATS:BOOL=ON -DCOMPILE_CORREVAL:BOOL=OFF -DCOMPILE_CROPTOOLS:BOOL=OFF @@ -79,10 +80,11 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ### --- End Project specific additions set( ${proj}_REPOSITORY ${git_protocol}://github.com/NIRALUser/niral_utilities.git ) - set( ${proj}_GIT_TAG 6924bab40c14705e67da0b0fe6292a0253b241c5) + set( ${proj}_GIT_TAG release) ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${EXTERNAL_BINARY_DIRECTORY}/${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_teem.cmake b/SuperBuild/External_teem.cmake index bb2c183..fd3387c 100644 --- a/SuperBuild/External_teem.cmake +++ b/SuperBuild/External_teem.cmake @@ -80,6 +80,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${proj}-build LOG_CONFIGURE 0 # Wrap configure in script to ignore log output from dashboards diff --git a/SuperBuild/External_zlib.cmake b/SuperBuild/External_zlib.cmake index e060028..4060efc 100644 --- a/SuperBuild/External_zlib.cmake +++ b/SuperBuild/External_zlib.cmake @@ -86,6 +86,7 @@ if(NOT ( DEFINED "USE_SYSTEM_${extProjName}" AND "${USE_SYSTEM_${extProjName}}" ExternalProject_Add(${proj} GIT_REPOSITORY ${${proj}_REPOSITORY} GIT_TAG ${${proj}_GIT_TAG} + ${git_config_arg} SOURCE_DIR ${EXTERNAL_SOURCE_DIRECTORY}/${proj} BINARY_DIR ${proj}-build INSTALL_DIR ${proj}-install diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f2af4ca..014ff81 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -132,6 +132,17 @@ if( DTIPrep_BUILD_SLICER_EXTENSION ) ) target_link_libraries( DTIPrep ${DTIPrep_Libs} ) add_executable( DTIPrepLauncher Launcher.cxx ${DTIPrep_SRCS_CLP} ) + + set(launcher_libraries ) + if(DEFINED SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES) + list(APPEND launcher_libraries ${SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES}) + endif() + if(NOT "${DEFAULT_SEM_TARGET_LIBRARIES}" STREQUAL "") + list(APPEND launcher_libraries ${DEFAULT_SEM_TARGET_LIBRARIES}) + endif() + if(launcher_libraries) + target_link_libraries(DTIPrepLauncher ${launcher_libraries}) + endif() set(HIDDEN_CLI_INSTALL_DIR ${Slicer_INSTALL_CLIMODULES_BIN_DIR}/../hidden-cli-modules ) install(TARGETS DTIPrep DESTINATION ${HIDDEN_CLI_INSTALL_DIR} ) @@ -221,6 +232,8 @@ else() # To Create a package, one can run "cpack -G DragNDrop CPackConfig.cmake" on Mac OS X # where CPackConfig.cmake is created by including CPack # And then there's ways to customize this as well - set(CPACK_BINARY_DRAGNDROP ON) + if(APPLE) + set(CPACK_BINARY_DRAGNDROP ON) + endif() include(CPack) endif() diff --git a/src/DTIPrep.xml b/src/DTIPrep.xml index 787030f..c10e22c 100644 --- a/src/DTIPrep.xml +++ b/src/DTIPrep.xml @@ -5,7 +5,7 @@ The DWI/DTI Quality Control Processes from dicom data to qualified dwi image. - 1.2.8 + 1.2.9 Mahshid Farzinfar (1), Zhexing Liu (1), Martin Styner(1),Hans Johnson(2,3,4), Joy Matsui(2), Kent Williams(2); (1=Department of Psychiatry, University of North Carolina at Chapel Hill, 2=University of Iowa Department of Psychiatry, 3=University of Iowa Department of Biomedical Engineering, 4=University of Iowa Department of Electrical and Computer Engineering) diff --git a/src/ImageView2DPanelWithControls.cxx b/src/ImageView2DPanelWithControls.cxx index ff3c018..4d61c65 100644 --- a/src/ImageView2DPanelWithControls.cxx +++ b/src/ImageView2DPanelWithControls.cxx @@ -703,14 +703,16 @@ void ImageView2DPanelWithControls::SliceIndexChanged(vtkObject *obj, { vtkImagePlaneWidget *planeWidget = reinterpret_cast( obj ); - int *whichwindow; - - whichwindow = (int *)client_data; short index = planeWidget->GetSliceIndex(); + + // int *whichwindow; + // whichwindow = (int *)client_data; // std::cout<<"orient"<<*whichwindow<<" "<<*whichwindow<<" // "<<*whichwindow<lineEdit_SliceIndex->setText( str.sprintf("%d", index) ); this->horizontalSlider_SliceIndex->setValue(index); @@ -728,9 +730,6 @@ void ImageView2DPanelWithControls::WindowLevelChanged(vtkObject *obj, { vtkImagePlaneWidget *planeWidget = reinterpret_cast( obj ); - int *whichwindow; - - whichwindow = (int *)client_data; double wl[2]; planeWidget->GetWindowLevel(wl); @@ -738,9 +737,12 @@ void ImageView2DPanelWithControls::WindowLevelChanged(vtkObject *obj, int windowLocal = (int)wl[0]; int level = (int)wl[1]; + // int *whichwindow; + // whichwindow = (int *)client_data; // std::cout<<"orient"<<*whichwindow<<" "<<*whichwindow<<" // "<<*whichwindow<ImageViewer2->SetColorWindow(windowLocal); this->ImageViewer2->SetColorLevel(level); diff --git a/src/IntensityMotionCheck.cxx b/src/IntensityMotionCheck.cxx index 8641fba..e398a5e 100644 --- a/src/IntensityMotionCheck.cxx +++ b/src/IntensityMotionCheck.cxx @@ -484,8 +484,7 @@ void CIntensityMotionCheck::GetImagesInformation() GradientContainer->clear(); DwiImageType::DirectionType direction = m_DwiOriginalImage->GetDirection(); - - int space; + // int space; for( ; itKey != imgMetaKeys.end(); itKey++ ) { // double x,y,z; @@ -502,21 +501,21 @@ void CIntensityMotionCheck::GetImagesInformation() m_readb0 = true; m_b0 = atof( metaString.c_str() ); } - else if( itKey->find("space") != std::string::npos ) - { - if( metaString.compare("right-anterior-superior") ) - { - space = Protocol::SPACE_RAS; - } - else if( metaString.compare("left-posterior-inferior") ) - { - space = Protocol::SPACE_LPI; - } - else - { - space = Protocol::SPACE_UNKNOWN; - } - } + // else if( itKey->find("space") != std::string::npos ) + // { + // if( metaString.compare("right-anterior-superior") ) + // { + // space = Protocol::SPACE_RAS; + // } + // else if( metaString.compare("left-posterior-inferior") ) + // { + // space = Protocol::SPACE_LPI; + // } + // else + // { + // space = Protocol::SPACE_UNKNOWN; + // } + // } else if( itKey->find("modality") != std::string::npos ) { if( metaString != "DWMRI" ) @@ -5837,8 +5836,8 @@ bool CIntensityMotionCheck::DiffusionCheck( DwiImageType::Pointer dwi) bool bColinear = false; // double gradientMinAngle = 90.0; double gradientMinAngle = 0.0; - double gradMagnitude = 0.0; - double gradProtocolMagnitude = 0.0; + // double gradMagnitude = 0.0; + // double gradProtocolMagnitude = 0.0; // if ( vcl_abs(protocol->GetDiffusionProtocol().gradients[i][0] // - GradContainer->ElementAt(i)[0]) < 0.00001 // && vcl_abs(protocol->GetDiffusionProtocol().gradients[i][1] @@ -5905,8 +5904,8 @@ bool CIntensityMotionCheck::DiffusionCheck( DwiImageType::Pointer dwi) = vcl_min( gradientAngle, vcl_abs(180.0 - gradientAngle) ); // Now see if the gradients are colinear in opposite directions; - gradMagnitude = gradientFromImage.magnitude(); - gradProtocolMagnitude = gradientFromProtocol.magnitude(); + // gradMagnitude = gradientFromImage.magnitude(); + // gradProtocolMagnitude = gradientFromProtocol.magnitude(); // std::cout << "gradProtocolMagnitude: " // << gradProtocolMagnitude << std::endl; if( gradientMinAngle < gradientToleranceForSameness ) @@ -6609,7 +6608,6 @@ bool CIntensityMotionCheck::GetInterlaceProtocolParameters_B( componentExtractor->SetIndex( j ); componentExtractor->Update(); - typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType iterateGradient( componentExtractor->GetOutput(), componentExtractor->GetOutput()->GetLargestPossibleRegion() ); diff --git a/src/IntensityMotionCheckPanel.cxx b/src/IntensityMotionCheckPanel.cxx index e4a7863..bbf0878 100644 --- a/src/IntensityMotionCheckPanel.cxx +++ b/src/IntensityMotionCheckPanel.cxx @@ -1995,7 +1995,6 @@ bool IntensityMotionCheckPanel::GetInterlaceProtocolParameters( componentExtractor->SetIndex( j ); componentExtractor->Update(); - typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType iterateGradient( componentExtractor->GetOutput(), componentExtractor->GetOutput()->GetLargestPossibleRegion() ); @@ -3976,10 +3975,14 @@ void IntensityMotionCheckPanel::ResultUpdate() overallInterlaceWiseCheck->setText( 1, tr("Not Set") ); } - if( ( ( (!qcResult.Get_result() & InterlaceWiseCheckBit) == InterlaceWiseCheckBit ) || - (!(this->GetProtocol().GetSliceCheckProtocol().bQuitOnCheckFailure || - this->GetProtocol().GetInterlaceCheckProtocol().bQuitOnCheckFailure) ) ) && - this->GetProtocol().GetGradientCheckProtocol().bCheck ) + bool doInterlaceWiseCheck = (qcResult.Get_result() & InterlaceWiseCheckBit) == InterlaceWiseCheckBit; + bool doQuitOnCheckFailure = + this->GetProtocol().GetSliceCheckProtocol().bQuitOnCheckFailure || + this->GetProtocol().GetInterlaceCheckProtocol().bQuitOnCheckFailure; + if( + ( !doInterlaceWiseCheck || !doQuitOnCheckFailure ) + && this->GetProtocol().GetGradientCheckProtocol().bCheck + ) { if( (qcResult.Get_result() & GradientWiseCheckBit) == 0 ) { diff --git a/src/MultiImageMetric.h b/src/MultiImageMetric.h index f9103b0..7523f15 100644 --- a/src/MultiImageMetric.h +++ b/src/MultiImageMetric.h @@ -27,7 +27,7 @@ #include "itkImageMaskSpatialObject.h" // Project specific headers -#include "itkBSplineDeformableTransform.h" +#include "itkNiralBSplineDeformableTransform.h" #include "UserMacro.h" #include @@ -150,8 +150,8 @@ class MultiImageMetric : public SingleValuedCostFunction /** Get the region over which the metric will be computed */ itkGetConstReferenceMacro( FixedImageRegion, ImageRegionType ); - typedef itk::BSplineDeformableTransform BSplineTransformType; + typedef itk::niral::BSplineDeformableTransform BSplineTransformType; typedef typename BSplineTransformType::Pointer BSplineTransformTypePointer; /** Set/Get the i'th Bspline Transform */ diff --git a/src/UnivariateEntropyMultiImageMetric.h b/src/UnivariateEntropyMultiImageMetric.h index ab04685..82b4de5 100644 --- a/src/UnivariateEntropyMultiImageMetric.h +++ b/src/UnivariateEntropyMultiImageMetric.h @@ -21,7 +21,7 @@ #include "itkPoint.h" #include "itkIndex.h" -#include "itkKernelFunction.h" +#include "itkKernelFunctionBase.h" #include "itkCentralDifferenceImageFunction.h" #include "itkGradientImageFilter.h" @@ -221,8 +221,8 @@ class UnivariateEntropyMultiImageMetric : mutable std::vector m_DerivativeCalculator; mutable std::vector > m_DerivativesArray; - double m_ImageStandardDeviation; - std::vector m_KernelFunction; + double m_ImageStandardDeviation; + std::vector::Pointer> m_KernelFunction; bool m_ReseedIterator; int m_RandomSeed; diff --git a/src/UnivariateEntropyMultiImageMetric.hxx b/src/UnivariateEntropyMultiImageMetric.hxx index 68f5b96..b412187 100644 --- a/src/UnivariateEntropyMultiImageMetric.hxx +++ b/src/UnivariateEntropyMultiImageMetric.hxx @@ -76,7 +76,7 @@ throw ( ExceptionObject ) typename GaussianKernelFunctionType::Pointer gaussianKF = GaussianKernelFunctionType::New(); m_KernelFunction[i] = - dynamic_cast(gaussianKF.GetPointer() ); + dynamic_cast *>(gaussianKF.GetPointer() ); } // check whether there is a mask for( unsigned int j = 0; j < this->m_NumberOfImages; j++ ) @@ -549,7 +549,7 @@ void UnivariateEntropyMultiImageMetric typename ParametersImageType::Pointer parametersImage = ParametersImageType::New(); parametersImage->SetRegions( this->m_BSplineTransformArray[0]->GetGridRegion() ); - parametersImage->CopyInformation( this->m_BSplineTransformArray[0]->GetCoefficientImage()[0] ); + parametersImage->CopyInformation( this->m_BSplineTransformArray[0]->GetCoefficientImages()[0] ); parametersImage->Allocate(); // gaussian filter diff --git a/src/VarianceMultiImageMetric.hxx b/src/VarianceMultiImageMetric.hxx index b8c95dd..0cbb3af 100644 --- a/src/VarianceMultiImageMetric.hxx +++ b/src/VarianceMultiImageMetric.hxx @@ -286,7 +286,7 @@ void VarianceMultiImageMetric typename ParametersImageType::Pointer parametersImage = ParametersImageType::New(); parametersImage->SetRegions( this->m_BSplineTransformArray[0]->GetGridRegion() ); - parametersImage->CopyInformation( this->m_BSplineTransformArray[0]->GetCoefficientImage()[0] ); + parametersImage->CopyInformation( this->m_BSplineTransformArray[0]->GetCoefficientImages()[0] ); parametersImage->Allocate(); // gaussian filter diff --git a/src/itkDWIBaselineAverager.h b/src/itkDWIBaselineAverager.h index 648b98a..72fb091 100644 --- a/src/itkDWIBaselineAverager.h +++ b/src/itkDWIBaselineAverager.h @@ -17,6 +17,7 @@ Author: Zhexing Liu (liuzhexing@gmail.com) #include "vnl/vnl_matrix_fixed.h" #include "itkVectorContainer.h" #include "itkVersorRigid3DTransform.h" +#include "itkNumberToString.h" #if (ITK_VERSION_MAJOR < 4) typedef int ThreadIdType; @@ -255,6 +256,8 @@ class DWIBaselineAverager : /** container to hold gradient to base wise registration */ // std::vector > GradientToBaselineReg; + NumberToString float_converter; + void parseGradientDirections(); void collectDiffusionStatistics(); diff --git a/src/itkDWIBaselineAverager.hxx b/src/itkDWIBaselineAverager.hxx index 622c8e2..b0c143d 100644 --- a/src/itkDWIBaselineAverager.hxx +++ b/src/itkDWIBaselineAverager.hxx @@ -227,14 +227,9 @@ DWIBaselineAverager std::ostringstream ossKey; ossKey << "DWMRI_gradient_0000"; std::ostringstream ossMetaString; - ossMetaString << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << 0.0 << " " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << 0.0 << " " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << 0.0; + ossMetaString << float_converter(0.0) << " " + << float_converter(0.0) << " " + << float_converter(0.0); itk::EncapsulateMetaData( outputMetaDictionary, ossKey.str(), ossMetaString.str() ); @@ -257,11 +252,11 @@ DWIBaselineAverager '0') << temp; std::ostringstream ossLocalGradientMetaString; - ossLocalGradientMetaString << std::setiosflags(std::ios::scientific) << std::setprecision(17) - << this->m_GradientDirectionContainer->ElementAt(i)[0] + ossLocalGradientMetaString << float_converter(this->m_GradientDirectionContainer->ElementAt(i)[0]) << " " - << this->m_GradientDirectionContainer->ElementAt(i)[1] << " " - << this->m_GradientDirectionContainer->ElementAt(i)[2]; + << float_converter(this->m_GradientDirectionContainer->ElementAt(i)[1]) + << " " + << float_converter(this->m_GradientDirectionContainer->ElementAt(i)[2]); itk::EncapsulateMetaData( outputMetaDictionary, ossLocalGradientKey.str(), @@ -279,12 +274,11 @@ DWIBaselineAverager ossKey << "DWMRI_gradient_" << std::setw(4) << std::setfill('0') << i; std::ostringstream ossMetaString; - ossMetaString << std::setiosflags(std::ios::scientific) << std::setprecision(17) - << this->m_GradientDirectionContainer->ElementAt(i)[0] + ossMetaString << float_converter(this->m_GradientDirectionContainer->ElementAt(i)[0]) << " " - << this->m_GradientDirectionContainer->ElementAt(i)[1] + << float_converter(this->m_GradientDirectionContainer->ElementAt(i)[1]) << " " - << this->m_GradientDirectionContainer->ElementAt(i)[2]; + << float_converter(this->m_GradientDirectionContainer->ElementAt(i)[2]); itk::EncapsulateMetaData( outputMetaDictionary, ossKey.str(), ossMetaString.str() ); @@ -613,16 +607,10 @@ DWIBaselineAverager temp = 0; if( getBaselineNumber() > 0 ) { - outfile << "\t" << temp << "\t[ " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << 0.0 << ", " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << 0.0 << ", " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << 0.0 << " ]" + outfile << "\t" << temp << "\t[ " + << float_converter(0.0) << ", " + << float_converter(0.0) << ", " + << float_converter(0.0) << " ]" << std::endl; temp = 1; } @@ -634,15 +622,9 @@ DWIBaselineAverager } outfile << "\t" << temp << "\t[ " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[0] << ", " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[1] << ", " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[2] << " ]" + << float_converter(m_GradientDirectionContainer->ElementAt(i)[0]) << ", " + << float_converter(m_GradientDirectionContainer->ElementAt(i)[1]) << ", " + << float_converter(m_GradientDirectionContainer->ElementAt(i)[2]) << " ]" << std::endl; temp++; } @@ -708,16 +690,10 @@ DWIBaselineAverager outfile << std::endl << "\t#" << "\tDirVector" << std::endl; for( unsigned int i = 0; i < this->m_GradientDirectionContainer->size(); i++ ) { - outfile << "\t" << i << "\t[ " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[0] << ", " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[1] << ", " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[2] << " ]" + outfile << "\t" << i << "\t[ " + << float_converter(m_GradientDirectionContainer->ElementAt(i)[0]) << ", " + << float_converter(m_GradientDirectionContainer->ElementAt(i)[1]) << ", " + << float_converter(m_GradientDirectionContainer->ElementAt(i)[2]) << " ]" << std::endl; } @@ -729,16 +705,10 @@ DWIBaselineAverager temp = 0; if( getBaselineNumber() > 0 ) { - outfile << "\t" << temp << "\t[ " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << 0.0 << ", " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << 0.0 << ", " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << 0.0 << " ]" + outfile << "\t" << temp << "\t[ " + << float_converter(0.0) << ", " + << float_converter(0.0) << ", " + << float_converter(0.0) << " ]" << std::endl; temp = 1; } @@ -749,16 +719,10 @@ DWIBaselineAverager continue; } - outfile << "\t" << temp << "\t[ " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[0] << ", " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[1] << ", " - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[2] << " ]" + outfile << "\t" << temp << "\t[ " + << float_converter(m_GradientDirectionContainer->ElementAt(i)[0]) << ", " + << float_converter(m_GradientDirectionContainer->ElementAt(i)[1]) << ", " + << float_converter(m_GradientDirectionContainer->ElementAt(i)[2]) << " ]" << std::endl; temp++; } @@ -816,16 +780,10 @@ DWIBaselineAverager outfile << std::endl << "Pre_baseline_avg\tGradientNum " << "\tx\ty\tz" << std::endl; for( unsigned int i = 0; i < this->m_GradientDirectionContainer->size(); i++ ) { - outfile << "Pre_baseline_avg\t" << i << "\t" - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[0] << "\t" - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[1] << "\t" - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[2] + outfile << "Pre_baseline_avg\t" << i << "\t" + << float_converter(m_GradientDirectionContainer->ElementAt(i)[0]) << "\t" + << float_converter(m_GradientDirectionContainer->ElementAt(i)[1]) << "\t" + << float_converter(m_GradientDirectionContainer->ElementAt(i)[2]) << std::endl; } @@ -837,16 +795,10 @@ DWIBaselineAverager temp = 0; if( getBaselineNumber() > 0 ) { - outfile << "Post_baseline_avg\t" << temp << "\t" - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << 0.0 << "\t" - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << 0.0 << "\t" - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << 0.0 << std::endl; + outfile << "Post_baseline_avg\t" << temp << "\t" + << float_converter(0.0) << "\t" + << float_converter(0.0) << "\t" + << float_converter(0.0) << std::endl; temp = 1; } for( unsigned int i = 0; i < this->m_GradientDirectionContainer->size(); i++ ) @@ -856,16 +808,10 @@ DWIBaselineAverager continue; } - outfile << "Post_baseline_avg\t" << temp << "\t" - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[0] << "\t" - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[1] << "\t" - << std::setw(9) << std::setiosflags(std::ios::fixed) - << std::setprecision(17) << std::setiosflags( std::ios::right | std::ios::scientific ) - << m_GradientDirectionContainer->ElementAt(i)[2] + outfile << "Post_baseline_avg\t" << temp << "\t" + << float_converter(m_GradientDirectionContainer->ElementAt(i)[0]) << "\t" + << float_converter(m_GradientDirectionContainer->ElementAt(i)[1]) << "\t" + << float_converter(m_GradientDirectionContainer->ElementAt(i)[2]) << std::endl; temp++; } diff --git a/src/itkDWICropper.hxx b/src/itkDWICropper.hxx index 8563a3c..9bd43fd 100644 --- a/src/itkDWICropper.hxx +++ b/src/itkDWICropper.hxx @@ -522,7 +522,6 @@ DWICropper InputImageConstPointer inputPtr = this->GetInput(); OutputImagePointer outputPtr = this->GetOutput(); - typedef ImageRegionConstIterator constDWIIterator; typedef ImageRegionIterator DWIIterator; DWIIterator iOutput( outputPtr, outputRegionForThread); diff --git a/src/itkDWIEddyCurrentHeadMotionCorrector.hxx b/src/itkDWIEddyCurrentHeadMotionCorrector.hxx index 640fd2e..8d628bd 100644 --- a/src/itkDWIEddyCurrentHeadMotionCorrector.hxx +++ b/src/itkDWIEddyCurrentHeadMotionCorrector.hxx @@ -237,11 +237,11 @@ DWIEddyCurrentHeadMotionCorrector { collectLeftDiffusionStatistics(); - int DWICount, BaselineCount; - BaselineCount = getBaselineLeftNumber(); - DWICount = getGradientLeftNumber(); - // std::cout <<"BaselineCount: "< << std::endl; collectLeftDiffusionStatistics(); // update - int DWICount, BaselineCount; - BaselineCount = getBaselineNumber(); - DWICount = getGradientNumber(); + // int DWICount, BaselineCount; + // BaselineCount = getBaselineLeftNumber(); + // DWICount = getGradientLeftNumber(); + // std::cout <<"BaselineCount: "< typedef itk::ImageRegistrationMethod RegistrationType; - typedef GradientImageType::SpacingType - SpacingType; - typedef GradientImageType::PointType - OriginType; - typedef GradientImageType::RegionType - RegionType; - typedef GradientImageType::SizeType - SizeType; - MetricType::Pointer metric = MetricType::New(); OptimizerType::Pointer optimizer = OptimizerType::New(); InterpolatorType::Pointer interpolator = InterpolatorType::New(); diff --git a/src/itkDWIQCInterlaceChecker.hxx b/src/itkDWIQCInterlaceChecker.hxx index 54b1e38..7de4379 100644 --- a/src/itkDWIQCInterlaceChecker.hxx +++ b/src/itkDWIQCInterlaceChecker.hxx @@ -260,15 +260,6 @@ DWIQCInterlaceChecker typedef itk::ImageRegistrationMethod RegistrationType; - typedef GradientImageType::SpacingType - SpacingType; - typedef GradientImageType::PointType - OriginType; - typedef GradientImageType::RegionType - RegionType; - typedef GradientImageType::SizeType - SizeType; - MetricType::Pointer metric = MetricType::New(); OptimizerType::Pointer optimizer = OptimizerType::New(); InterpolatorType::Pointer interpolator = InterpolatorType::New(); @@ -492,7 +483,6 @@ DWIQCInterlaceChecker componentExtractor->SetIndex( j ); componentExtractor->Update(); - typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType iterateGradient( componentExtractor->GetOutput(), componentExtractor->GetOutput()->GetLargestPossibleRegion() ); @@ -855,7 +845,7 @@ DWIQCInterlaceChecker outfile.open( GetReportFileName().c_str() ); } - int DWICount, BaselineCount; + // int DWICount, BaselineCount; switch( m_ReportType ) { @@ -961,8 +951,8 @@ DWIQCInterlaceChecker << std::endl; collectLeftDiffusionStatistics(); // update - BaselineCount = getBaselineNumber(); - DWICount = getGradientNumber(); + // BaselineCount = getBaselineNumber(); + // DWICount = getGradientNumber(); for( unsigned int i = 0; i < this->ResultsContainer.size(); i++ ) { outfile.precision(6); @@ -1125,8 +1115,8 @@ DWIQCInterlaceChecker << std::endl; collectLeftDiffusionStatistics(); // update - BaselineCount = getBaselineNumber(); - DWICount = getGradientNumber(); + // BaselineCount = getBaselineNumber(); + // DWICount = getGradientNumber(); for( unsigned int i = 0; i < this->ResultsContainer.size(); i++ ) { outfile.precision(6); diff --git a/src/itkDWIQCSliceChecker.hxx b/src/itkDWIQCSliceChecker.hxx index d884985..53ee8ff 100644 --- a/src/itkDWIQCSliceChecker.hxx +++ b/src/itkDWIQCSliceChecker.hxx @@ -344,9 +344,9 @@ DWIQCSliceChecker 2> ShortSliceImageType; typedef itk::DiscreteGaussianImageFilter FilterType; - typename FilterType::Pointer smoother1 = FilterType::New(); - typename FilterType::Pointer smoother2 = FilterType::New(); + ShortSliceImageType> SmootherFilterType; + typename SmootherFilterType::Pointer smoother1 = SmootherFilterType::New(); + typename SmootherFilterType::Pointer smoother2 = SmootherFilterType::New(); smoother1->SetInput( filter1->GetOutput() ); smoother1->SetVariance( m_GaussianVariance ); @@ -1490,12 +1490,12 @@ DWIQCSliceChecker // to check int badcount = 0; - int baselineBadcount = 0; + // int baselineBadcount = 0; InputImageConstPointer inputPtr = this->GetInput(); // check region0 for( unsigned int i = 0; i < ResultsContainer0.size(); i++ ) { - baselineBadcount = 0; + // baselineBadcount = 0; badcount = 0; if( this->qcResults[i] ) // only check the left gradients { @@ -1574,7 +1574,7 @@ DWIQCSliceChecker // check region1 for( unsigned int i = 0; i < ResultsContainer1.size(); i++ ) { - baselineBadcount = 0; + // baselineBadcount = 0; badcount = 0; if( this->qcResults[i] ) // only check the left gradients { @@ -1653,7 +1653,7 @@ DWIQCSliceChecker // check region2 for( unsigned int i = 0; i < ResultsContainer2.size(); i++ ) { - baselineBadcount = 0; + // baselineBadcount = 0; badcount = 0; if( this->qcResults[i] ) // only check the left gradients { @@ -1732,7 +1732,7 @@ DWIQCSliceChecker // check region3 for( unsigned int i = 0; i < ResultsContainer3.size(); i++ ) { - baselineBadcount = 0; + // baselineBadcount = 0; badcount = 0; if( this->qcResults[i] ) // only check the left gradients { @@ -1806,7 +1806,7 @@ DWIQCSliceChecker // check region4 for( unsigned int i = 0; i < ResultsContainer4.size(); i++ ) { - baselineBadcount = 0; + // baselineBadcount = 0; badcount = 0; if( this->qcResults[i] ) // only check the left gradients { @@ -2411,7 +2411,7 @@ DWIQCSliceChecker outfile.open( GetReportFileName().c_str() ); } - int DWICount, BaselineCount; + // int DWICount, BaselineCount; SliceWiseCheckResult m_SliceWiseCheckResult; @@ -2583,8 +2583,8 @@ DWIQCSliceChecker outfile << std::endl; collectLeftDiffusionStatistics(); // update - BaselineCount = getBaselineNumber(); - DWICount = getGradientNumber(); + // BaselineCount = getBaselineNumber(); + // DWICount = getGradientNumber(); for( unsigned int j = 0; j < this->ResultsContainer[0].size(); j++ ) { // double baselinemean=0.0, DWImean=0.0, baselinedeviation=0.0, @@ -2942,8 +2942,8 @@ DWIQCSliceChecker outfile << std::endl; collectLeftDiffusionStatistics(); // update - BaselineCount = getBaselineNumber(); - DWICount = getGradientNumber(); + // BaselineCount = getBaselineNumber(); + // DWICount = getGradientNumber(); for( unsigned int j = 0; j < this->ResultsContainer.size(); j++ ) { // double baselinemean=0.0, DWImean=0.0, baselinedeviation=0.0, @@ -4031,9 +4031,9 @@ DWIQCSliceChecker 2> ShortSliceImageType; typedef itk::DiscreteGaussianImageFilter FilterType; - typename FilterType::Pointer smoother1 = FilterType::New(); - typename FilterType::Pointer smoother2 = FilterType::New(); + ShortSliceImageType> SmootherFilterType; + typename SmootherFilterType::Pointer smoother1 = SmootherFilterType::New(); + typename SmootherFilterType::Pointer smoother2 = SmootherFilterType::New(); smoother1->SetInput( filter1->GetOutput() ); smoother1->SetVariance( GaussianVariance ); diff --git a/src/itkLinearHeadEddy3DCorrection.hxx b/src/itkLinearHeadEddy3DCorrection.hxx index 57a15c3..c9508d2 100644 --- a/src/itkLinearHeadEddy3DCorrection.hxx +++ b/src/itkLinearHeadEddy3DCorrection.hxx @@ -54,7 +54,7 @@ LinearHeadEddy3DCorrection unsigned int i, j; os << indent << "Versor Matrix: " << std::endl; - MatrixType rigid_Matrix = m_head_motion_transform->GetRotationMatrix(); + MatrixType rigid_Matrix = m_head_motion_transform->GetMatrix(); for( i = 0; i < NInputDimensions; i++ ) { os << indent.GetNextIndent(); @@ -171,7 +171,7 @@ const typename LinearHeadEddy3DCorrection ::GetHeadMotionRotationMatrix(void) const { - return m_head_motion_transform->GetRotationMatrix(); + return m_head_motion_transform->GetMatrix(); } /**/ diff --git a/src/itkMultiImageRegistrationFilter.h b/src/itkMultiImageRegistrationFilter.h index 73b6328..6af14a9 100644 --- a/src/itkMultiImageRegistrationFilter.h +++ b/src/itkMultiImageRegistrationFilter.h @@ -7,8 +7,8 @@ #include "UnivariateEntropyMultiImageMetric.h" #include "itkAffineTransform.h" -#include "itkBSplineDeformableTransform.h" -#include "itkBSplineDeformableTransformInitializer.h" +#include "itkNiralBSplineDeformableTransform.h" +#include "itkNiralBSplineDeformableTransformInitializer.h" #include "itkGradientDescentOptimizer.h" #include "GradientDescentLineSearchOptimizer.h" @@ -237,9 +237,9 @@ class MultiImageRegistrationFilter : typedef CenterPointType::ValueType CoordRepType; typedef ContinuousIndex ContinuousIndexType; typedef ContinuousIndexType::ValueType ContinuousIndexValueType; - typedef BSplineDeformableTransform + typedef niral::BSplineDeformableTransform BSplineTransformType; - typedef BSplineDeformableTransformInitializer BSplineInitializerType; + typedef niral::BSplineDeformableTransformInitializer BSplineInitializerType; typedef RegistrationType::ParametersType ParametersType; typedef ResampleImageFilter ResampleFilterType; diff --git a/src/itkNiralBSplineDeformableTransform.h b/src/itkNiralBSplineDeformableTransform.h new file mode 100644 index 0000000..ad87bb7 --- /dev/null +++ b/src/itkNiralBSplineDeformableTransform.h @@ -0,0 +1,379 @@ +/*========================================================================= + * + * Copyright Insight Software Consortium + * + * 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.txt + * + * 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. + * + *=========================================================================*/ +#ifndef itkNiralBSplineDeformableTransform_h +#define itkNiralBSplineDeformableTransform_h + +#include "itkConfigure.h" // Needed to determine value of ITKV3_COMPATIBILITY +#include "itkBSplineBaseTransform.h" + +namespace itk +{ +namespace niral +{ +/** \class BSplineDeformableTransform + * + * \brief Deformable transform using a BSpline representation + * + * \note BSplineTransform is a newer version of this class, and it is + * preferred. + * + * This class encapsulates a deformable transform of points from one + * N-dimensional space to another N-dimensional space. + * The deformation field is modelled using B-splines. + * A deformation is defined on a sparse regular grid of control points + * \f$ \vec{\lambda}_j \f$ and is varied by defining a deformation + * \f$ \vec{g}(\vec{\lambda}_j) \f$ of each control point. + * The deformation \f$ D(\vec{x}) \f$ at any point \f$ \vec{x} \f$ + * is obtained by using a B-spline interpolation kernel. + * + * The deformation field grid is defined by a user specified GridRegion, + * GridSpacing and GridOrigin. Each grid/control point has associated with it + * N deformation coefficients \f$ \vec{\delta}_j \f$, representing the N + * directional components of the deformation. Deformation outside the grid + * plus support region for the BSpline interpolation is assumed to be zero. + * + * Additionally, the user can specified an addition bulk transform \f$ B \f$ + * such that the transformed point is given by: + * \f[ \vec{y} = B(\vec{x}) + D(\vec{x}) \f] + * + * The parameters for this transform is an N x N-D grid of spline coefficients. + * The user specifies the parameters as one flat array: each N-D grid + * is represented by an array in the same way an N-D image is represented + * in the buffer; the N arrays are then concatentated together on form + * a single array. + * + * For efficiency, this transform does not make a copy of the parameters. + * It only keeps a pointer to the input parameters and assumes that the memory + * is managed by the caller. + * + * The following illustrates the typical usage of this class: + * \verbatim + * typedef BSplineDeformableTransform TransformType; + * TransformType::Pointer transform = TransformType::New(); + * + * transform->SetGridRegion( region ); + * transform->SetGridSpacing( spacing ); + * transform->SetGridOrigin( origin ); + * + * // NB: the region must be set first before setting the parameters + * + * TransformType::ParametersType parameters( + * transform->GetNumberOfParameters() ); + * + * // Fill the parameters with values + * + * transform->SetParameters( parameters ) + * + * outputPoint = transform->TransformPoint( inputPoint ); + * + * \endverbatim + * + * An alternative way to set the B-spline coefficients is via array of + * images. The grid region, spacing and origin information is taken + * directly from the first image. It is assumed that the subsequent images + * are the same buffered region. The following illustrates the API: + * \verbatim + * + * TransformType::ImageConstPointer images[2]; + * + * // Fill the images up with values + * + * transform->SetCoefficientImages( images ); + * outputPoint = transform->TransformPoint( inputPoint ); + * + * \endverbatim + * + * Warning: use either the SetParameters() or SetCoefficientImages() + * API. Mixing the two modes may results in unexpected results. + * + * The class is templated coordinate representation type (float or double), + * the space dimension and the spline order. + * + * \ingroup ITKTransform + * + * \sa BSplineTransform + * + * \wiki + * \wikiexample{Registration/ImageRegistrationMethodBSpline,A global registration of two images} + * \endwiki + */ +template +class ITK_TEMPLATE_EXPORT BSplineDeformableTransform : + public BSplineBaseTransform +{ +public: + /** Standard class typedefs. */ + typedef BSplineDeformableTransform Self; + typedef BSplineBaseTransform Superclass; + typedef SmartPointer Pointer; + typedef SmartPointer ConstPointer; + + /** New macro for creation of through the object factory. */ + // Explicit New() method, used here because we need to split the itkNewMacro() + // in order to overload the CreateAnother() method so that we can copy the m_BulkTransform + // explicitly. + // TODO: shouldn't it be done with the Clone() method? + itkSimpleNewMacro(Self); + virtual ::itk::LightObject::Pointer CreateAnother(void) const ITK_OVERRIDE + { + ::itk::LightObject::Pointer smartPtr; + Pointer copyPtr = Self::New().GetPointer(); + //THE FOLLOWING LINE IS DIFFERENT FROM THE DEFAULT MACRO! + copyPtr->m_BulkTransform = this->GetBulkTransform(); + smartPtr = static_cast( copyPtr ); + return smartPtr; + } + + /** implement type-specific clone method*/ + itkCloneMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro( BSplineDeformableTransform, BSplineBaseTransform ); + + /** Dimension of the domain space. */ + itkStaticConstMacro( SpaceDimension, unsigned int, NDimensions ); + + /** The BSpline order. */ + itkStaticConstMacro( SplineOrder, unsigned int, VSplineOrder ); + + /** Standard scalar type for this class. */ + typedef TParametersValueType ScalarType; + + /** Standard parameters container. */ + typedef typename Superclass::ParametersType ParametersType; + typedef typename Superclass::ParametersValueType ParametersValueType; + typedef typename Superclass::FixedParametersType FixedParametersType; + typedef typename Superclass::FixedParametersValueType FixedParametersValueType; + + /** Standard Jacobian container. */ + typedef typename Superclass::JacobianType JacobianType; + + /** The number of parameters defininig this transform. */ + typedef typename Superclass::NumberOfParametersType NumberOfParametersType; + + /** Standard vector type for this class. */ + typedef typename Superclass::InputVectorType InputVectorType; + typedef typename Superclass::OutputVectorType OutputVectorType; + + /** Standard covariant vector type for this class. */ + typedef typename Superclass::InputCovariantVectorType InputCovariantVectorType; + typedef typename Superclass::OutputCovariantVectorType OutputCovariantVectorType; + + /** Standard vnl_vector type for this class. */ + typedef typename Superclass::InputVnlVectorType InputVnlVectorType; + typedef typename Superclass::OutputVnlVectorType OutputVnlVectorType; + + /** Standard coordinate point type for this class. */ + typedef Point InputPointType; + typedef Point OutputPointType; + + + /** This method sets the fixed parameters of the transform. + * For a BSpline deformation transform, the parameters are the following: + * Grid Size, Grid Origin, and Grid Spacing + * + * The fixed parameters are the three times the size of the templated + * dimensions. + * This function has the effect of make the following calls: + * transform->SetGridSpacing( spacing ); + * transform->SetGridOrigin( origin ); + * transform->SetGridDirection( direction ); + * transform->SetGridRegion( bsplineRegion ); + * + * This function was added to allow the transform to work with the + * itkTransformReader/Writer I/O filters. + * + */ + virtual void SetFixedParameters( const FixedParametersType & parameters ) ITK_OVERRIDE; + + /** Parameters as SpaceDimension number of images. */ + typedef typename Superclass::ImageType ImageType; + typedef typename Superclass::ImagePointer ImagePointer; + typedef typename Superclass::CoefficientImageArray CoefficientImageArray; + + /** Set the array of coefficient images. + * + * This is an alternative API for setting the BSpline coefficients + * as an array of SpaceDimension images. The fixed parameters are + * taken from the first image. It is assumed that + * the buffered region of all the subsequent images are the same + * as the first image. Note that no error checking is done. + * + * Warning: use either the SetParameters() or SetCoefficientImages() + * API. Mixing the two modes may results in unexpected results. + */ + virtual void SetCoefficientImages( const CoefficientImageArray & images ) ITK_OVERRIDE; + +#ifdef ITKV3_COMPATIBILITY + virtual void SetCoefficientImage( const CoefficientImageArray & images ) + { + this->SetCoefficientImages( images ); + } + /* Only for backwards compatibility with ITKv3. */ + CoefficientImageArray GetCoefficientImage() + { + return this->GetCoefficientImages(); + } +#endif + + /** Typedefs for specifying the extent of the grid. */ + typedef typename Superclass::RegionType RegionType; + + typedef typename Superclass::IndexType IndexType; + typedef typename Superclass::SizeType SizeType; + typedef typename Superclass::SpacingType SpacingType; + typedef typename Superclass::DirectionType DirectionType; + typedef typename Superclass::OriginType OriginType; + + /** Interpolation weights function type. */ + typedef typename Superclass::WeightsFunctionType WeightsFunctionType; + + typedef typename Superclass::WeightsType WeightsType; + typedef typename Superclass::ContinuousIndexType ContinuousIndexType; + + /** Parameter index array type. */ + typedef typename Superclass::ParameterIndexArrayType ParameterIndexArrayType; + + /** + * Transform points by a BSpline deformable transformation. + * On return, weights contains the interpolation weights used to compute the + * deformation and indices of the x (zeroth) dimension coefficient parameters + * in the support region used to compute the deformation. + * Parameter indices for the i-th dimension can be obtained by adding + * ( i * this->GetNumberOfParametersPerDimension() ) to the indices array. + */ + using Superclass::TransformPoint; + virtual void TransformPoint( const InputPointType & inputPoint, OutputPointType & outputPoint, + WeightsType & weights, ParameterIndexArrayType & indices, bool & inside ) const ITK_OVERRIDE; + + virtual void ComputeJacobianWithRespectToParameters( const InputPointType &, JacobianType & ) const ITK_OVERRIDE; + + /** Return the number of parameters that completely define the Transfom */ + virtual NumberOfParametersType GetNumberOfParameters() const ITK_OVERRIDE; + + /** Return the number of parameters per dimension */ + NumberOfParametersType GetNumberOfParametersPerDimension() const ITK_OVERRIDE; + + typedef typename Superclass::SpacingType PhysicalDimensionsType; + typedef typename Superclass::PixelType PixelType; + + typedef typename Superclass::MeshSizeType MeshSizeType; + + /** Function to specify the transform domain origin. */ + virtual void SetGridOrigin( const OriginType & ); + + /** Function to retrieve the transform domain origin. */ + itkGetConstMacro( GridOrigin, OriginType ); + + /** This method specifies the grid spacing or resolution. */ + virtual void SetGridSpacing( const SpacingType & ); + + /** This method retrieve the grid spacing or resolution. */ + itkGetConstMacro( GridSpacing, SpacingType ); + + /** Function to specify the transform domain direction. */ + virtual void SetGridDirection( const DirectionType & ); + + /** Function to retrieve the transform domain direction. */ + itkGetConstMacro( GridDirection, DirectionType ); + + /** Function to specify the transform domain mesh size. */ + virtual void SetGridRegion( const RegionType & ); + + /** Function to retrieve the transform domain mesh size. */ + itkGetConstMacro( GridRegion, RegionType ); + + typedef Transform BulkTransformType; + typedef typename BulkTransformType::ConstPointer BulkTransformPointer; + /** This method specifies the bulk transform to be applied. + * The default is the identity transform. + */ + itkSetConstObjectMacro(BulkTransform, BulkTransformType); + itkGetConstObjectMacro(BulkTransform, BulkTransformType); + + /** Return the region of the grid wholly within the support region */ + itkGetConstReferenceMacro(ValidRegion, RegionType); + +protected: + /** Print contents of an BSplineDeformableTransform. */ + void PrintSelf( std::ostream & os, Indent indent ) const ITK_OVERRIDE; + + BSplineDeformableTransform(); + virtual ~BSplineDeformableTransform(); + +private: + + /** Construct control point grid size from transform domain information */ + virtual void SetFixedParametersGridSizeFromTransformDomainInformation() const ITK_OVERRIDE; + + /** Construct control point grid origin from transform domain information */ + virtual void SetFixedParametersGridOriginFromTransformDomainInformation() const ITK_OVERRIDE; + + /** Construct control point grid spacing from transform domain information */ + virtual void SetFixedParametersGridSpacingFromTransformDomainInformation() const ITK_OVERRIDE; + + /** Construct control point grid direction from transform domain information */ + virtual void SetFixedParametersGridDirectionFromTransformDomainInformation() const ITK_OVERRIDE; + + /** Construct control point grid size from transform domain information */ + virtual void SetCoefficientImageInformationFromFixedParameters() ITK_OVERRIDE; + + ITK_DISALLOW_COPY_AND_ASSIGN(BSplineDeformableTransform); + + /** Check if a continuous index is inside the valid region. */ + virtual bool InsideValidRegion( ContinuousIndexType & ) const ITK_OVERRIDE; + + /** The variables defining the coefficient grid domain for the + * InternalParametersBuffer are taken from the m_CoefficientImages[0] + * image, and must be kept in sync with them. by using + * references to that instance, this is more naturally enforced + * and does not introduce a speed penalty of dereferencing + * through the pointers (although it does enforce some + * internal class synchronization). + */ + const RegionType & m_GridRegion; + const OriginType & m_GridOrigin; + const SpacingType & m_GridSpacing; + const DirectionType & m_GridDirection; + + /** The bulk transform. */ + BulkTransformPointer m_BulkTransform; + + RegionType m_ValidRegion; + + /** Variables defining the interpolation support region. */ + unsigned long m_Offset; + bool m_SplineOrderOdd; + IndexType m_ValidRegionLast; + IndexType m_ValidRegionFirst; + + void UpdateValidGridRegion(); + +}; // class BSplineDeformableTransform +} // namespace niral +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +#include "itkNiralBSplineDeformableTransform.hxx" +#endif + +#endif /* itkNiralBSplineDeformableTransform_h */ diff --git a/src/itkNiralBSplineDeformableTransform.hxx b/src/itkNiralBSplineDeformableTransform.hxx new file mode 100644 index 0000000..9d9deef --- /dev/null +++ b/src/itkNiralBSplineDeformableTransform.hxx @@ -0,0 +1,656 @@ +/*========================================================================= + * + * Copyright Insight Software Consortium + * + * 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.txt + * + * 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. + * + *=========================================================================*/ +#ifndef itkNiralBSplineDeformableTransform_hxx +#define itkNiralBSplineDeformableTransform_hxx + +#include "itkNiralBSplineDeformableTransform.h" +#include "itkContinuousIndex.h" +#include "itkImageScanlineConstIterator.h" +#include "itkImageRegionConstIteratorWithIndex.h" +#include "itkIdentityTransform.h" + +namespace itk +{ +namespace niral +{ + +// Constructor with default arguments +template +BSplineDeformableTransform +::BSplineDeformableTransform() : + m_GridRegion(Superclass::m_CoefficientImages[0]->GetLargestPossibleRegion() ), + m_GridOrigin(Superclass::m_CoefficientImages[0]->GetOrigin() ), + m_GridSpacing(Superclass::m_CoefficientImages[0]->GetSpacing() ), + m_GridDirection(Superclass::m_CoefficientImages[0]->GetDirection() ) +{ + + // Instantiate an identity transform + typedef IdentityTransform IdentityTransformType; + typename IdentityTransformType::Pointer id = IdentityTransformType::New(); + this->m_BulkTransform = id; + + // Setup variables for computing interpolation + this->m_Offset = SplineOrder / 2; + if( SplineOrder % 2 ) + { + this->m_SplineOrderOdd = true; + } + else + { + this->m_SplineOrderOdd = false; + } + this->m_ValidRegion = this->m_GridRegion; // HACK: Perhaps this->m_ValidRegion is redundant also. + this->m_ValidRegionFirst.Fill( 0 ); + this->m_ValidRegionLast.Fill( 1 ); + + /** Fixed Parameters store the following information: + * Grid Size + * Grid Origin + * Grid Spacing + * Grid Direction + * The size of these is equal to the NInputDimensions + */ + // For example 3D image has FixedParameters of: + // [size[0],size[1],size[2], + // origin[0],origin[1],origin[2], + // spacing[0],spacing[1],spacing[2], + // dir[0][0],dir[1][0],dir[2][0], + // dir[0][1],dir[1][1],dir[2][1], + // dir[0][2],dir[1][2],dir[2][2]] + + this->SetFixedParametersFromTransformDomainInformation(); +} + +template +BSplineDeformableTransform +::~BSplineDeformableTransform() +{ +} + +// Get the number of parameters +template +typename BSplineDeformableTransform::NumberOfParametersType +BSplineDeformableTransform +::GetNumberOfParameters() const +{ + // The number of parameters equal SpaceDimension * number of + // of pixels in the grid region. + return static_cast( SpaceDimension * this->m_GridRegion.GetNumberOfPixels() ); +} + +// Get the number of parameters per dimension +template +typename BSplineDeformableTransform::NumberOfParametersType +BSplineDeformableTransform +::GetNumberOfParametersPerDimension() const +{ + // The number of parameters per dimension equal number of + // of pixels in the grid region. + return static_cast( this->m_GridRegion.GetNumberOfPixels() ); +} + +// Set the grid region +template +void +BSplineDeformableTransform +::UpdateValidGridRegion() +{ + // Set the valid region + // If the grid spans the interval [start, last]. + // The valid interval for evaluation is [start+offset, last-offset] + // when spline order is even. + // The valid interval for evaluation is [start+offset, last-offset) + // when spline order is odd. + // Where offset = floor(spline / 2 ). + // Note that the last pixel is not included in the valid region + // with odd spline orders. + typename RegionType::SizeType size; + typename RegionType::IndexType index; + for( unsigned int j = 0; j < NDimensions; ++j ) + { + index[j] = this->m_GridRegion.GetIndex()[j]; + size[j] = this->m_GridRegion.GetSize()[j]; + index[j] += static_cast( this->m_Offset ); + size[j] -= static_cast( 2 * this->m_Offset ); + this->m_ValidRegionFirst[j] = index[j]; + this->m_ValidRegionLast[j] = index[j] + static_cast( size[j] ) - 1; + } + this->m_ValidRegion.SetSize(size); + this->m_ValidRegion.SetIndex(index); +} + +// Set the grid region +template +void +BSplineDeformableTransform +::SetGridRegion(const RegionType & region) +{ + if( this->m_GridRegion != region ) + { + this->m_CoefficientImages[0]->SetRegions(region); + // set regions for each coefficient image + for( unsigned int j = 1; j < SpaceDimension; j++ ) + { + this->m_CoefficientImages[j]->SetRegions(region); + } + + this->UpdateValidGridRegion(); + // + // If we are using the default parameters, update their size and set to + // identity. + // + + // Check if we need to resize the default parameter buffer. + if( this->m_InternalParametersBuffer.GetSize() != this->GetNumberOfParameters() ) + { + this->m_InternalParametersBuffer.SetSize( this->GetNumberOfParameters() ); + // Fill with zeros for identity. + this->m_InternalParametersBuffer.Fill( 0 ); + } + this->SetFixedParametersGridSizeFromTransformDomainInformation(); + this->Modified(); + } +} + +// Set the grid spacing +template +void +BSplineDeformableTransform +::SetGridSpacing(const SpacingType & spacing) +{ + if( this->m_GridSpacing != spacing ) + { + this->m_CoefficientImages[0]->SetSpacing(spacing); + // set spacing for each coefficient image + for( unsigned int j = 1; j < SpaceDimension; j++ ) + { + this->m_CoefficientImages[j]->SetSpacing( spacing ); + } + this->SetFixedParametersGridSpacingFromTransformDomainInformation(); + this->Modified(); + } +} + +// Set the grid direction +template +void +BSplineDeformableTransform +::SetGridDirection(const DirectionType & direction) +{ + if( this->m_GridDirection != direction ) + { + this->m_CoefficientImages[0]->SetDirection(direction); + // set direction for each coefficient image + for( unsigned int j = 1; j < SpaceDimension; j++ ) + { + this->m_CoefficientImages[j]->SetDirection(direction); + } + this->SetFixedParametersGridDirectionFromTransformDomainInformation(); + this->Modified(); + } +} + +// Set the grid origin +template +void +BSplineDeformableTransform +::SetGridOrigin(const OriginType & origin) +{ + if( this->m_GridOrigin != origin ) + { + this->m_CoefficientImages[0]->SetOrigin( origin ); + // set spacing for each coefficient image + for( unsigned int j = 1; j < SpaceDimension; j++ ) + { + this->m_CoefficientImages[j]->SetOrigin( origin ); + } + this->SetFixedParametersGridOriginFromTransformDomainInformation(); + this->Modified(); + } +} + +template +void +BSplineDeformableTransform +::SetCoefficientImageInformationFromFixedParameters() +{ + + // Fixed Parameters store the following information: + // grid size + // grid origin + // grid spacing + // grid direction + // The size of these is equal to the NInputDimensions + { + // set the grid size parameters + SizeType gridSize; + for( unsigned int i = 0; i < NDimensions; i++ ) + { + gridSize[i] = static_cast( this->m_FixedParameters[i] ); + } + RegionType bsplineRegion; + bsplineRegion.SetSize(gridSize); + this->SetGridRegion(bsplineRegion); + } + + { + // Set the origin parameters + OriginType origin; + for( unsigned int i = 0; i < NDimensions; i++ ) + { + origin[i] = this->m_FixedParameters[NDimensions + i]; + } + this->SetGridOrigin(origin); + } + + { + // Set the spacing parameters + SpacingType spacing; + for( unsigned int i = 0; i < NDimensions; i++ ) + { + spacing[i] = this->m_FixedParameters[2 * NDimensions + i]; + } + this->SetGridSpacing(spacing); + } + + { + // Set the direction parameters + DirectionType direction; + for( unsigned int di = 0; di < NDimensions; di++ ) + { + for( unsigned int dj = 0; dj < NDimensions; dj++ ) + { + direction[di][dj] = this->m_FixedParameters[3 * NDimensions + ( di * NDimensions + dj )]; + } + } + this->SetGridDirection(direction); + } +} + +template +void +BSplineDeformableTransform +::SetFixedParametersGridSizeFromTransformDomainInformation() const +{ + // Set the grid size parameters + const SizeType & gridSize = this->m_CoefficientImages[0]->GetLargestPossibleRegion().GetSize(); + for( unsigned int i = 0; i < NDimensions; i++ ) + { + this->m_FixedParameters[i] = static_cast( + gridSize[i] ); + } +} + +template +void +BSplineDeformableTransform +::SetFixedParametersGridOriginFromTransformDomainInformation() const +{ + // Set the origin parameters + + const OriginType & origin = this->m_CoefficientImages[0]->GetOrigin(); + + for( unsigned int i = 0; i < NDimensions; i++ ) + { + this->m_FixedParameters[NDimensions + i] = static_cast( + origin[i] ); + } +} + +template +void +BSplineDeformableTransform +::SetFixedParametersGridSpacingFromTransformDomainInformation() const +{ + // Set the spacing parameters + const SpacingType & spacing = this->m_CoefficientImages[0]->GetSpacing(); + for( unsigned int i = 0; i < NDimensions; i++ ) + { + this->m_FixedParameters[2 * NDimensions + i] = static_cast( spacing[i] ); + } +} + +template +void +BSplineDeformableTransform +::SetFixedParametersGridDirectionFromTransformDomainInformation() const +{ + /** Set the direction parameters */ + const DirectionType & direction = this->m_CoefficientImages[0]->GetDirection(); + for( unsigned int di = 0; di < NDimensions; di++ ) + { + for( unsigned int dj = 0; dj < NDimensions; dj++ ) + { + this->m_FixedParameters[3 * NDimensions + ( di * NDimensions + dj )] = + static_cast( direction[di][dj] ); + } + } +} + + +// Set the Fixed Parameters +template +void +BSplineDeformableTransform +::SetFixedParameters( const FixedParametersType & passedParameters ) +{ + // check if the number of passedParameters match the + // expected number of this->m_FixedParameters + if( passedParameters.Size() == this->m_FixedParameters.Size() ) + { + for( unsigned int i = 0; i < NDimensions * ( 3 + NDimensions ); ++i ) + { + this->m_FixedParameters[i] = passedParameters[i]; + } + } + else if( passedParameters.Size() == NDimensions * 3 ) + { + // This option was originally valid for backwards compatibility + // with BSplines saved to disk from before image orientation was used. + // Those transforms would no longer be valid with respect to images + // with explicit directions. + itkExceptionMacro( << "Mismatched between parameters size " + << passedParameters.size() + << " and required number of fixed parameters " + << this->m_FixedParameters.Size() + << ". Implicit setting of identity direction is no longer supported." ); + } + else + { + itkExceptionMacro( << "Mismatched between parameters size " + << passedParameters.size() + << " and the required number of fixed parameters " + << this->m_FixedParameters.Size() ); + } + this->SetCoefficientImageInformationFromFixedParameters(); +} + +// Set the B-Spline coefficients using input images +template +void +BSplineDeformableTransform +::SetCoefficientImages( const CoefficientImageArray & images ) +{ + bool validArrayOfImages = true; + + for( unsigned int j = 0; j < SpaceDimension; j++ ) + { + validArrayOfImages &= ( images[0].IsNotNull() ); + } + + if( validArrayOfImages ) + { + // The BufferedRegion MUST equal the LargestPossibleRegion. + this->SetGridRegion( images[0]->GetLargestPossibleRegion() ); + this->SetGridOrigin( images[0]->GetOrigin() ); + this->SetGridSpacing( images[0]->GetSpacing() ); + this->SetGridDirection( images[0]->GetDirection() ); + + const SizeValueType totalParameters = this->GetNumberOfParameters(); + this->m_InternalParametersBuffer.SetSize(totalParameters); + for( unsigned int j = 0; j < SpaceDimension; j++ ) + { + const SizeValueType numberOfPixels = + images[j]->GetLargestPossibleRegion().GetNumberOfPixels(); + if( numberOfPixels * SpaceDimension != totalParameters ) + { + itkExceptionMacro( << "SetCoefficientImage() has array of images that are " + << "not the correct size. " + << numberOfPixels * SpaceDimension << " != " << totalParameters + << " for image at index " << j << " \n" << images[j] + ); + } + const ParametersValueType * const baseImagePointer = + images[j]->GetBufferPointer(); + + ParametersValueType *dataPointer = this->m_InternalParametersBuffer.data_block(); + std::copy(baseImagePointer, + baseImagePointer+numberOfPixels, + dataPointer); + } + this->SetParameters( this->m_InternalParametersBuffer ); + } + else + { + itkExceptionMacro( << "SetCoefficientImage() requires that an array of " + << "correctly sized images be supplied."); + } +} + +// Print self +template +void +BSplineDeformableTransform +::PrintSelf( std::ostream & os, Indent indent ) const +{ + this->Superclass::PrintSelf(os, indent); + + os << indent << "ValidRegion: " << this->m_ValidRegion << std::endl; + os << indent << "BulkTransform: "; + os << this->m_BulkTransform.GetPointer() << std::endl; + os << indent << "WeightsFunction: "; + os << this->m_WeightsFunction.GetPointer() << std::endl; + + if( this->m_BulkTransform ) + { + os << indent << "BulkTransformType: " + << this->m_BulkTransform->GetNameOfClass() << std::endl; + } + os << indent << "GridOrigin: " + << this->m_GridOrigin << std::endl; + os << indent << "GridSpacing: " + << this->m_GridSpacing << std::endl; + os << indent << "GridDirection: " + << this->m_GridDirection << std::endl; + os << indent << "GridRegion: " + << this->m_GridRegion << std::endl; + +} + +template +bool +BSplineDeformableTransform +::InsideValidRegion( ContinuousIndexType & index ) const +{ + bool inside = true; + + if( inside && this->m_SplineOrderOdd ) + { + typedef typename ContinuousIndexType::ValueType ValueType; + for( unsigned int j = 0; j < SpaceDimension; j++ ) + { + if( index[j] >= static_cast( this->m_ValidRegionLast[j] ) ) + { + inside = false; + break; + } + if( index[j] < static_cast( this->m_ValidRegionFirst[j] ) ) + { + inside = false; + break; + } + } + } + return inside; +} + +template +void +BSplineDeformableTransform +::TransformPoint( const InputPointType & inputPoint, OutputPointType & outputPoint, + WeightsType & weights, ParameterIndexArrayType & indices, bool & inside ) const +{ + inside = true; + + InputPointType point=inputPoint; + if( this->m_BulkTransform ) + { + point = this->m_BulkTransform->TransformPoint(point); + } + else + { + point = point; + } + + // if no coefficients are set, this isn't a proper BSpline Transform + if( this->m_CoefficientImages[0]->GetBufferPointer() == ITK_NULLPTR) + { + itkExceptionMacro( "B-spline coefficients have not been set" ); + } + + ContinuousIndexType index; + this->m_CoefficientImages[0]->TransformPhysicalPointToContinuousIndex( inputPoint, index ); + + // NOTE: if the support region does not lie totally within the grid + // we assume zero displacement and return the input point + inside = this->InsideValidRegion( index ); + if( !inside ) + { + outputPoint = point; + return; + } + + IndexType supportIndex; + // Compute interpolation weights + this->m_WeightsFunction->Evaluate( index, weights, supportIndex ); + + // For each dimension, correlate coefficient with weights + RegionType supportRegion; + SizeType supportSize = this->m_WeightsFunction->GetSupportSize(); + supportRegion.SetSize( supportSize ); + supportRegion.SetIndex(supportIndex); + + outputPoint.Fill( NumericTraits::ZeroValue() ); + + typedef ImageScanlineConstIterator IteratorType; + IteratorType coeffIterator[SpaceDimension]; + unsigned long counter = 0; + const ParametersValueType *basePointer = + this->m_CoefficientImages[0]->GetBufferPointer(); + for( unsigned int j = 0; j < SpaceDimension; j++ ) + { + coeffIterator[j] = + IteratorType( this->m_CoefficientImages[j], supportRegion ); + } + + while( !coeffIterator[0].IsAtEnd() ) + { + while( !coeffIterator[0].IsAtEndOfLine() ) + { + // multiply weigth with coefficient + for( unsigned int j = 0; j < SpaceDimension; j++ ) + { + outputPoint[j] += static_cast( + weights[counter] * coeffIterator[j].Get() ); + } + + // populate the indices array + indices[counter] = &( coeffIterator[0].Value() ) - basePointer; + + // go to next coefficient in the support region + ++counter; + for( unsigned int j = 0; j < SpaceDimension; j++ ) + { + ++( coeffIterator[j] ); + } + } // end of scanline + + for( unsigned int j = 0; j < SpaceDimension; j++ ) + { + coeffIterator[j].NextLine(); + } + } + // return results + for( unsigned int j = 0; j < SpaceDimension; j++ ) + { + outputPoint[j] += point[j]; + } +} + +// Compute the Jacobian in one position +template +void +BSplineDeformableTransform +::ComputeJacobianWithRespectToParameters( const InputPointType & point, + JacobianType & jacobian ) const +{ + // Zero all components of jacobian + jacobian.SetSize( SpaceDimension, this->GetNumberOfParameters() ); + jacobian.Fill( 0.0 ); + RegionType supportRegion; + SizeType supportSize; + supportSize.Fill( SplineOrder + 1 ); + supportRegion.SetSize( supportSize ); + + ContinuousIndexType index; + this->m_CoefficientImages[0]-> + TransformPhysicalPointToContinuousIndex( point, index ); + + // NOTE: if the support region does not lie totally within the grid we assume + // zero displacement and do no computations beyond zeroing out the value + // return the input point + if( !this->InsideValidRegion( index ) ) + { + return; + } + + // Compute interpolation weights + WeightsType weights( this->m_WeightsFunction->GetNumberOfWeights() ); + + IndexType supportIndex; + this->m_WeightsFunction->Evaluate( index, weights, supportIndex ); + + supportRegion.SetIndex( supportIndex ); + + IndexType startIndex = + this->m_CoefficientImages[0]->GetLargestPossibleRegion().GetIndex(); + + const SizeType &MeshGridSize=this->m_GridRegion.GetSize(); + SizeType cumulativeGridSizes; + cumulativeGridSizes[0] = ( MeshGridSize[0] ); + for( unsigned int d = 1; d < SpaceDimension; d++ ) + { + cumulativeGridSizes[d] = cumulativeGridSizes[d-1] * MeshGridSize[d]; + } + + SizeValueType numberOfParametersPerDimension = this->GetNumberOfParametersPerDimension(); + + ImageRegionConstIteratorWithIndex It( this->m_CoefficientImages[0], supportRegion ); + unsigned long counter = 0; + for( It.GoToBegin(); !It.IsAtEnd(); ++It ) + { + typename ImageType::OffsetType currentIndex = It.GetIndex() - startIndex; + + unsigned long number = currentIndex[0]; + for( unsigned int d = 1; d < SpaceDimension; d++ ) + { + number += ( currentIndex[d] * cumulativeGridSizes[d-1] ); + } + + for( unsigned int d = 0; d < SpaceDimension; d++ ) + { + jacobian( d, number + d * numberOfParametersPerDimension ) = weights[counter]; + } + counter++; + } +} + +} // namespace niral +} // namespace itk + +#endif diff --git a/src/itkNiralBSplineDeformableTransformInitializer.h b/src/itkNiralBSplineDeformableTransformInitializer.h new file mode 100644 index 0000000..ca6a8d5 --- /dev/null +++ b/src/itkNiralBSplineDeformableTransformInitializer.h @@ -0,0 +1,138 @@ +/*========================================================================= + * + * Copyright Insight Software Consortium + * + * 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.txt + * + * 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. + * + *=========================================================================*/ +#ifndef itkNiralBSplineDeformableTransformInitializer_h +#define itkNiralBSplineDeformableTransformInitializer_h + +//#include "itkConfigure.h" //Needed to determine value of ITKV3_COMPATIBILITY +//#ifdef ITKV3_COMPATIBILITY + +#include "itkObject.h" +#include "itkObjectFactory.h" + +#include + +namespace itk +{ +namespace niral +{ +/** \class BSplineDeformableTransformInitializer + * \brief BSplineDeformableTransformInitializer is a helper class intended to + * initialize the grid parameters of a BSplineDeformableTransform based on the + * parameters of an image. + * + * In the context of image registration, the image to be used are reference will + * be the fixed image. The BSpline grid will use the fixed image as a base for + * computing the grid spacing, orientation and origin, among other things. + * + * This code was contributed in the Insight Journal paper: + * + * "Helper class for initializing the grid parameters of + * a BSpline deformable transform by using an image as reference" + * + * http://www.insight-journal.org/browse/publication/216 + * https://hdl.handle.net/1926/1338 + * + * \ingroup ITKTransform + */ +template< typename TTransform, typename TImage > +class ITK_TEMPLATE_EXPORT BSplineDeformableTransformInitializer:public Object +{ +public: + /** Standard class typedefs. */ + typedef BSplineDeformableTransformInitializer Self; + typedef Object Superclass; + typedef SmartPointer< Self > Pointer; + typedef SmartPointer< const Self > ConstPointer; + + /** New macro for creation of through a Smart Pointer. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(BSplineDeformableTransformInitializer, Object); + + /** Type of the transform to initialize */ + typedef TTransform TransformType; + + /** Types defined from transform traits */ + typedef typename TransformType::Pointer TransformPointer; + typedef typename TransformType::RegionType TransformRegionType; + typedef typename TransformRegionType::SizeType TransformSizeType; + + /** Dimension of parameters. */ + itkStaticConstMacro(SpaceDimension, unsigned int, + TransformType::InputSpaceDimension); + + /** Image Types to use in the initialization of the transform */ + typedef TImage ImageType; + typedef typename ImageType::ConstPointer ImagePointer; + + /** Set the transform to be initialized */ + itkSetObjectMacro(Transform, TransformType); + + /** Set the fixed image used in the registration process */ + itkSetConstObjectMacro(Image, ImageType); + + /** Set the number of grid nodes that we want to place inside the image. This + * method will override the settings of any previous call to + * SetNumberOfGridNodesInsideTheImage(). */ + itkSetMacro(GridSizeInsideTheImage, TransformSizeType); + + /** Set the number of grid nodes that we want to place inside the image. This + * number of node is used along one dimension of the image. Therefore, if + * you pass the number 5 as argument of this method, in a 3D space, then the + * total number of grid nodes inside the image will be \$ 5 x 5 x 5 \$ . + * This method will override the settings of any previous call to + * SetGridSizeInsideTheImage(). */ + void SetNumberOfGridNodesInsideTheImage(unsigned int numberOfNodes) + { + this->m_GridSizeInsideTheImage.Fill(numberOfNodes); + this->Modified(); + } + + /** Initialize the transform using data from the images */ + virtual void InitializeTransform() const; + +protected: + BSplineDeformableTransformInitializer(); + ~BSplineDeformableTransformInitializer(){} + + void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE; + +private: + ITK_DISALLOW_COPY_AND_ASSIGN(BSplineDeformableTransformInitializer); + + TransformPointer m_Transform; + + ImagePointer m_Image; + + TransformSizeType m_GridSizeInsideTheImage; + + unsigned int m_NumberOfGridNodesInsideTheImage; +}; //class BSplineDeformableTransformInitializer +} // namespace niral +} // namespace itk + +#ifndef ITK_MANUAL_INSTANTIATION +#include "itkNiralBSplineDeformableTransformInitializer.hxx" +#endif + +//#else // def ITKV3_COMPATIBILITY +//#error "itkBSplineDeformableTransformInitializer.h should only be included for ITKv3 compatibility. Build with ITKV3_COMPATIBILITY=ON to use this" +//#endif // def ITKV3_COMPATIBILITY + +#endif /* itkNiralBSplineDeformableTransformInitializer_h */ diff --git a/src/itkNiralBSplineDeformableTransformInitializer.hxx b/src/itkNiralBSplineDeformableTransformInitializer.hxx new file mode 100644 index 0000000..e8a1688 --- /dev/null +++ b/src/itkNiralBSplineDeformableTransformInitializer.hxx @@ -0,0 +1,151 @@ +/*========================================================================= + * + * Copyright Insight Software Consortium + * + * 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.txt + * + * 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. + * + *=========================================================================*/ +#ifndef itkNiralBSplineDeformableTransformInitializer_hxx +#define itkNiralBSplineDeformableTransformInitializer_hxx + +#include "itkNiralBSplineDeformableTransformInitializer.h" + +namespace itk +{ +namespace niral +{ +template< typename TTransform, typename TImage > +BSplineDeformableTransformInitializer< TTransform, TImage > +::BSplineDeformableTransformInitializer() +{ + this->m_GridSizeInsideTheImage.Fill(5); +} + +template< typename TTransform, typename TImage > +void +BSplineDeformableTransformInitializer< TTransform, TImage > +::InitializeTransform() const +{ + // Sanity check + if ( !this->m_Image ) + { + itkExceptionMacro( << "Reference Image has not been set"); + return; + } + + if ( !this->m_Transform ) + { + itkExceptionMacro( << "Transform has not been set"); + return; + } + + // If the image come from a filter, then update that filter. + if ( this->m_Image->GetSource() ) + { + this->m_Image->GetSource()->Update(); + } + + typedef typename TransformType::RegionType RegionType; + + typename RegionType::SizeType numberOfGridNodesOutsideTheImageSupport; + typename RegionType::SizeType totalGridSize; + + numberOfGridNodesOutsideTheImageSupport.Fill(TransformType::SplineOrder); + + totalGridSize = this->m_GridSizeInsideTheImage; + totalGridSize += numberOfGridNodesOutsideTheImageSupport; + + RegionType gridRegion; + gridRegion.SetSize(totalGridSize); + + typedef typename TransformType::SpacingType SpacingType; + const SpacingType & imageSpacing = this->m_Image->GetSpacing(); + + typedef typename TransformType::OriginType OriginType; + const OriginType & imageOrigin = this->m_Image->GetOrigin(); + + const typename TransformType::RegionType & imageRegion = + this->m_Image->GetLargestPossibleRegion(); + + typename ImageType::SizeType fixedImageSize = imageRegion.GetSize(); + + SpacingType gridSpacing; + SpacingType gridOriginShift; + + const unsigned int orderShift = TransformType::SplineOrder / 2; + + for ( unsigned int r = 0; r < SpaceDimension; r++ ) + { + const unsigned int numberOfGridCells = this->m_GridSizeInsideTheImage[r] - 1; + const unsigned int numberOfImagePixels = fixedImageSize[r]; + + gridSpacing[r] = imageSpacing[r] + * static_cast< double >( numberOfImagePixels ) + / static_cast< double >( numberOfGridCells ); + + // Shift half image pixel to cover the image support + const double imageSupportShift = -imageSpacing[r] / 2.0; + + // Shift by the number of extra grid cells required by + // the BSpline order. + const double gridSupportShift = -1.0 * gridSpacing[r] * orderShift; + + // Combine both shifts. They are both aligned with the coordinate + // system of the grid. Direction has not been considered so far. + gridOriginShift[r] = gridSupportShift + imageSupportShift; + } + + typename ImageType::DirectionType gridDirection = this->m_Image->GetDirection(); + SpacingType gridOriginOffset = gridDirection * gridOriginShift; + + OriginType gridOrigin = imageOrigin + gridOriginOffset; + + this->m_Transform->SetGridRegion(gridRegion); + this->m_Transform->SetGridOrigin(gridOrigin); + this->m_Transform->SetGridSpacing(gridSpacing); + this->m_Transform->SetGridDirection(gridDirection); +} + +template< typename TTransform, typename TImage > +void +BSplineDeformableTransformInitializer< TTransform, TImage > +::PrintSelf(std::ostream & os, Indent indent) const +{ + Superclass::PrintSelf(os, indent); + + os << indent << "Transform = " << std::endl; + if ( this->m_Transform ) + { + os << indent << this->m_Transform << std::endl; + } + else + { + os << indent << "None" << std::endl; + } + + os << indent << "Image = " << std::endl; + if ( this->m_Image ) + { + os << indent << this->m_Image << std::endl; + } + else + { + os << indent << "None" << std::endl; + } + os << "Grid size inside the image " << this->m_GridSizeInsideTheImage << std::endl; + os << "Number of grid nodes inside the image " << this->m_NumberOfGridNodesInsideTheImage << std::endl; +} +} // namespace niral +} // namespace itk + +#endif