[med-svn] [plastimatch] 02/04: New upstream version 1.7.0+dfsg.1

Greg Sharp gregsharp-guest at moszumanska.debian.org
Mon Dec 18 23:23:42 UTC 2017


This is an automated email from the git hooks/post-receive script.

gregsharp-guest pushed a commit to branch master
in repository plastimatch.

commit ad976fbe9cc8c269bdae7c08800c1a6210dd004a
Author: Gregory C. Sharp <gregsharp.geo at yahoo.com>
Date:   Mon Dec 18 18:14:46 2017 -0500

    New upstream version 1.7.0+dfsg.1
---
 CMakeLists.txt                                    | 531 ++++++++--------------
 SuperBuild/External_DCMTK.cmake                   |  35 ++
 SuperBuild/External_ITK.cmake                     |  32 ++
 Testing/CTestCustom.cmake.in                      |   3 +
 cmake/CheckCharSign.cmake                         |   8 +-
 cmake/CheckEpsilon.cmake                          |   8 +-
 cmake/ExternalITK.cmake                           |  36 --
 cmake/FindCUDA_wrap.cmake                         |  12 +-
 cmake/{FindDCMTK.cmake => FindDCMTK_legacy.cmake} |   0
 cmake/FindDCMTK_wrap.cmake                        |   1 +
 cmake/FindDlib.cmake                              |   6 +-
 cmake/FindOpenMP.cmake                            | 112 +++--
 cmake/HandleITK.cmake                             |  46 ++
 cmake/PlmMacros.cmake                             | 117 ++++-
 cmake/PreventInSourceBuilds.cmake                 |  13 +
 cmake/SuperbuildOptions.cmake                     |  37 ++
 doc/NOTES.TXT                                     |  11 +-
 doc/man/drr.1                                     |   2 +-
 doc/man/fdk.1                                     |  10 +-
 doc/man/landmark_warp.1                           |   2 +-
 doc/man/plastimatch.1                             |  64 ++-
 src/CMakeLists.txt                                | 231 ++--------
 src/plastimatch/CHANGELOG.TXT                     |  14 +
 src/plastimatch/CMakeLists.txt                    | 293 +++++++++---
 src/plastimatch/base/CMakeLists.txt               |   2 +-
 src/plastimatch/base/dcmtk_image.cxx              |  24 +-
 src/plastimatch/base/dcmtk_rt_study.cxx           |   6 -
 src/plastimatch/base/parameter_parser.cxx         |  11 +-
 src/plastimatch/base/parameter_parser.h           |  14 +-
 src/plastimatch/base/plm_image.cxx                |   8 +
 src/plastimatch/base/rpl_volume_lut.cxx           |  32 +-
 src/plastimatch/base/rpl_volume_lut.h             |   4 +-
 src/plastimatch/base/rt_study.cxx                 |  13 +
 src/plastimatch/base/rt_study.h                   |   4 +
 src/plastimatch/base/rt_study_metadata.cxx        |  14 +-
 src/plastimatch/base/rt_study_metadata.h          |   3 +-
 src/plastimatch/cli/CMakeLists.txt                |   2 +-
 src/plastimatch/cli/pcmd_warp.cxx                 |   8 +
 src/plastimatch/dose/CMakeLists.txt               |   2 +-
 src/plastimatch/dose/dose_volume_functions.cxx    |  36 +-
 src/plastimatch/dose/rt_beam.cxx                  |   6 +
 src/plastimatch/dose/rt_beam.h                    |   1 +
 src/plastimatch/dose/rt_mebs.cxx                  | 212 ++++-----
 src/plastimatch/dose/rt_mebs.h                    |   2 +-
 src/plastimatch/dose/rt_plan.cxx                  |   2 +-
 src/plastimatch/opencl/opencl_util.cxx            |   2 +-
 src/plastimatch/qt/CMakeLists.txt                 |  24 +-
 src/plastimatch/reconstruct/CMakeLists.txt        |   2 +-
 src/plastimatch/register/CMakeLists.txt           |   2 +-
 src/plastimatch/script/CMakeLists.txt             |   2 +-
 src/plastimatch/segment/CMakeLists.txt            |   2 +-
 src/plastimatch/segment/mabs.cxx                  |  24 +-
 src/plastimatch/segment/mabs_parms.cxx            |   9 +
 src/plastimatch/standalone/CMakeLists.txt         |  31 +-
 src/plastimatch/standalone/nki2mha_converter.cpp  |  40 +-
 src/plastimatch/sys/CMakeLists.txt                |   2 +-
 src/plastimatch/test/CMakeLists.txt               |  16 +-
 src/plastimatch/test/cpp_template_test.cxx        |   5 +
 src/plastimatch/test/cuda/CMakeLists.txt          |  14 +-
 src/plastimatch/test/qt_test.cxx                  |  22 +-
 src/plastimatch/util/CMakeLists.txt               |   4 +-
 src/plastimatch/util/rt_study_warp.cxx            |  11 +
 src/plastimatch/util/warp_parms.h                 |   6 +-
 63 files changed, 1293 insertions(+), 955 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d52f0a9..47de66c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,10 +5,10 @@
 ##-----------------------------------------------------------------------------
 project (plastimatch)
 
-## The version here should be equal to the "next release"
+## The version here should be equal to the "most recent release"
 set (PLM_VERSION_MAJOR "1")
-set (PLM_VERSION_MINOR "6")
-set (PLM_VERSION_PATCH "6")
+set (PLM_VERSION_MINOR "7")
+set (PLM_VERSION_PATCH "0")
 #set (PLM_RELEASE_VERSION FALSE)
 set (PLM_RELEASE_VERSION TRUE)
 
@@ -27,62 +27,114 @@ endif ()
 if (POLICY CMP0012)
   cmake_policy (SET CMP0012 NEW)
 endif ()
-# Note: it is ok to use CMake FindZLIB for 2.8.4.  Therefore setting 
-# policy CMP0017 to NEW is safe.  But we do want the OLD policy for 
-# older CMake versions.
-cmake_policy (SET CMP0017 NEW)
+# CMP0017: Prefer files from the CMake module directory when including
+# from there.
+if (POLICY CMP0017)
+  cmake_policy (SET CMP0017 NEW)
+endif ()
+# CMP0054: Quoted variables no longer dereferenced
+# GCS 2017-11-02: This is added to suppress Qt warnings
+if (POLICY CMP0054)
+  cmake_policy (SET CMP0054 NEW)
+endif ()
+
+##-----------------------------------------------------------------------------
+##  CMake include files
+##-----------------------------------------------------------------------------
+set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
+
+##-----------------------------------------------------------------------------
+##  Prevent in-source build
+##-----------------------------------------------------------------------------
+include (PreventInSourceBuilds)
+
+##-----------------------------------------------------------------------------
+##  Macros and functions used in this script
+##-----------------------------------------------------------------------------
+include (PlmMacros)
+include (SuperbuildOptions)
 
-# Default to release
+##-----------------------------------------------------------------------------
+##  Define default build type as Release
+##-----------------------------------------------------------------------------
 if (NOT CMAKE_BUILD_TYPE)
   set (CMAKE_BUILD_TYPE "Release" CACHE STRING
     "Choose the type of build, options are: Debug Release
       RelWithDebInfo MinSizeRel." FORCE)
 endif ()
+sb_variable (CMAKE_BUILD_TYPE)
 
 ##-----------------------------------------------------------------------------
 ##  Define plastimatch configuration variables
 ##-----------------------------------------------------------------------------
-option (PLM_CONFIG_DISABLE_CUDA "Set to ON to build without CUDA" OFF)
+sb_option (PLM_CONFIG_DISABLE_CUDA "Set to ON to build without CUDA" OFF)
 option (PLM_CONFIG_DISABLE_DCMTK "Set to ON to build without DCMTK" OFF)
 option (PLM_CONFIG_DISABLE_FATM "Set to ON to build without FATM" ON)
-option (PLM_CONFIG_DISABLE_ISE "Build ISE fluoro program" ON)
 option (PLM_CONFIG_DISABLE_MONDOSHOT "Disable building mondoshot" ON)
-option (PLM_CONFIG_DISABLE_OPENCL "Set to ON to build without OpenCL" OFF)
-option (PLM_CONFIG_DISABLE_OPENMP "Set to ON to build without OpenMP" OFF)
+sb_option (PLM_CONFIG_DISABLE_OPENCL "Set to ON to build without OpenCL" OFF)
+sb_option (PLM_CONFIG_DISABLE_OPENMP "Set to ON to build without OpenMP" OFF)
 option (PLM_CONFIG_DISABLE_PLASTIMATCH "Disable building plastimatch" OFF)
 option (PLM_CONFIG_DISABLE_QT "Set to ON to build without QT" OFF)
-option (PLM_CONFIG_DISABLE_REG23 "Disable building REG-2-3" ON)
-option (PLM_CONFIG_DISABLE_SSE2 "Set to ON to build without SSE" OFF)
+sb_option (PLM_CONFIG_DISABLE_SSE2 "Set to ON to build without SSE" OFF)
 option (PLM_CONFIG_ENABLE_MATLAB "Set to ON to build Matlab plugins" OFF)
 
 option (PLM_CONFIG_BUILD_QT_PLUGINS "Build QT4 Designer Plugins?" OFF)
-option (PLM_CONFIG_DEBIAN_BUILD "Set to ON to configure build for debian" OFF)
+sb_option (PLM_CONFIG_DEBIAN_BUILD "Set to ON to configure build for debian" OFF)
 option (PLM_CONFIG_LIBRARY_BUILD "Set to ON to build only libraries" OFF)
 option (PLM_CONFIG_NOMANIFEST
-    "Set to ON to build windows DLLs without manifests" OFF)
+  "Set to ON to build windows DLLs without manifests" OFF)
+option (PLM_CONFIG_ENABLE_SUPERBUILD
+  "Set to ON to allow src/plastimatch to be built using nested superbuild" ON)
+
+# Plastimatch software configuration options
+option (PLM_CONFIG_CLANG_COMPLETE
+  "Generate .clang_complete for hipster Vim-ers" OFF)
+option (PLM_CONFIG_DISABLE_VISCOUS
+  "Disable experimental viscous fluid registration algorithm" ON)
+option (PLM_CONFIG_ENABLE_PLASTIMATCH_QT
+  "Enable experimental plastimatch_qt executable" OFF)
+sb_option (PLM_CONFIG_PREFER_PATCHED_ITK
+  "Prefer to use the patched version of certain ITK files" ON)
+sb_option (PLM_CONFIG_VOL_LIST
+  "Native support for volumes with irregular slice thicknesses" OFF)
+
+# Plastimatch legacy options
+sb_option (PLM_CONFIG_LEGACY_BSPLINE_EXTEND
+  "Use legacy code for extending b-spline domain" OFF)
+sb_option (PLM_CONFIG_LEGACY_BSPLINE_XFORM_IO
+  "Use legacy code for reading and writing b-spline xform files" OFF)
+sb_option (PLM_CONFIG_LEGACY_MI_METRIC
+  "For ITK metrics, the legacy implementation of the mi metric is Viola-Wells to Mattes" OFF)
+sb_option (PLM_CONFIG_LEGACY_PROJ_GEO
+  "Use legacy method for specifying projection geometry" ON)
 
 # Compile and link options
-option (PLM_SUPERBUILD "Download missing external libraries" OFF)
-option (PLM_PREFER_EXTERNAL_ITK "Prefer external ITK to local one" OFF)
-option (BUILD_SHARED_LIBS "Build plastimatch as shared library" OFF)
-
-# GCS 2016-08-18: Debian now ships dlib, give option to prefer local copy
-option (PLM_PREFER_SYSTEM_DLIB
+sb_option (BUILD_SHARED_LIBS "Build plastimatch as shared library" OFF)
+
+# Choose whether to build against included and/or superbuild libraries
+# instead of system libraries
+sb_option_enum (PLM_SYSTEM_DCMTK "Prefer DCMTK provided by operating system" 
+  PREFERRED
+  NO PREFERRED YES)
+sb_option (PLM_PREFER_SYSTEM_DLIB
     "Prefer the system dlib over the included dlib" ON)
+sb_option_enum (PLM_SYSTEM_ITK "Prefer ITK provided by operating system" 
+  PREFERRED
+  NO PREFERRED YES)
 
 # Testing
-option (PLM_BUILD_TESTING "Enable regression testing" ON)
+sb_option (PLM_BUILD_TESTING "Enable regression testing" ON)
 
 # Installer Options
 option (PLM_INSTALL_RPATH "Add full RPATH to install" OFF)
-option (PLM_CONFIG_INSTALL_LIBRARIES "Include libraries in install" ON)
+sb_option (PLM_CONFIG_INSTALL_LIBRARIES "Include libraries in install" ON)
 
 # Packaging
 option (PLM_PACKAGE_32BIT
     "Set this when building 32-bit packages on a 64-bit machine" OFF)
 option (PLM_PACKAGE_NSIS "Set to ON when packaging binaries with NSIS" OFF)
 option (PLM_PACKAGE_WIX "Set to ON when packaging binaries with WIX" OFF)
-option (PLM_PACKAGE_LEGACY_CMAKE_CONFIG
+sb_option (PLM_PACKAGE_LEGACY_CMAKE_CONFIG
     "Use the old code for creating PlastimatchConfig.cmake and friends" OFF)
 
 # Use legacy packaging if cmake version is < 3.0
@@ -92,17 +144,15 @@ endif ()
 
 # Override some options if library build is selected
 if (PLM_CONFIG_LIBRARY_BUILD)
-  set (PLM_CONFIG_DISABLE_ISE ON)
   set (PLM_CONFIG_DISABLE_FATM ON)
   set (PLM_CONFIG_DISABLE_MONDOSHOT ON)
-  set (PLM_CONFIG_DISABLE_REG23 ON)
 endif ()
-  
+
 ##-----------------------------------------------------------------------------
-##  SETUP IMPORTANT LOCATIONS
+##  Setup important locations
 ##-----------------------------------------------------------------------------
-set (PLM_BUILD_ROOT "${CMAKE_CURRENT_BINARY_DIR}")
-set (PLM_SRC_ROOT   "${CMAKE_CURRENT_SOURCE_DIR}")
+sb_set (PLM_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+sb_set (PLM_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
 
 # Offer the user the choice of overriding the installation directories
 set (PLM_INSTALL_LIB_DIR lib CACHE PATH 
@@ -124,6 +174,7 @@ mark_as_advanced (
   PLM_INSTALL_INCLUDE_DIR 
   PLM_INSTALL_CMAKE_DIR)
 
+
 # GCS 2015-07-08.  The below workflow is described here:
 #   http://www.cmake.org/Wiki/CMake/Tutorials/How_to_create_a_ProjectConfig.cmake_file
 # However, it creates install targets with absolute paths, which is 
@@ -146,15 +197,8 @@ endif ()
 ##-----------------------------------------------------------------------------
 ##  CMake include files
 ##-----------------------------------------------------------------------------
-set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}" ${CMAKE_MODULE_PATH})
-set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
-
-include (cmake/PlmMacros.cmake)
 include (CTest)
 include (CheckFunctionExists)
-include (CheckIncludeFiles)
-include (CheckTypeSize)
-include (TestBigEndian)
 
 # http://www.cmake.org/pipermail/cmake/2008-December/025886.html
 # http://www.cmake.org/Bug/view.php?id=15117
@@ -166,51 +210,7 @@ else ()
 endif ()
 
 # Superbuild
-if (PLM_SUPERBUILD)
-  include (ExternalProject)
-endif ()
-
-# Machine precision
-include (cmake/CheckEpsilon)
-
-# Is char signed or unsigned?
-include (cmake/CheckCharSign)
-
-##-----------------------------------------------------------------------------
-##  Processor and OS characteristics
-##    32-bit or 64-bit machine
-##    Endian-ness
-##    Machine precision
-##    Processor type
-##-----------------------------------------------------------------------------
-if (UNIX) # OS X and Cygwin are both considered UNIX
-  if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
-    set (GNU TRUE)
-  endif ()
-endif()
-
-check_type_size ("unsigned int"   CMAKE_SIZEOF_UINT)
-check_type_size ("unsigned long"  CMAKE_SIZEOF_ULONG)
-check_type_size ("size_t"         CMAKE_SIZEOF_SIZE_T)
-if (NOT APPLE)
-  if (CMAKE_SIZEOF_VOID_P EQUAL 4)
-    set (MACHINE_IS_32_BIT TRUE)
-    set (MACHINE_IS_64_BIT FALSE)
-    message (STATUS "Machine is 32-bit")
-  else ()
-    set (MACHINE_IS_32_BIT FALSE)
-    set (MACHINE_IS_64_BIT TRUE)
-    message (STATUS "Machine is 64-bit")
-  endif ()
-endif ()
-
-test_big_endian (PLM_BIG_ENDIAN)
-check_epsilon (MACHINE_EPS)
-check_char_sign (CHAR_SIGN)
-message (STATUS "Checking host processor: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
-message (STATUS "Checking target processor: ${CMAKE_SYSTEM_PROCESSOR}")
-message (STATUS "Checking epsilon: ${MACHINE_EPS}")
-message (STATUS "Checking sign of char: ${CHAR_SIGN}")
+include (ExternalProject)
 
 ##-----------------------------------------------------------------------------
 ##  Disable spurious warnings on MSVC (version 8 & higher)
@@ -246,27 +246,6 @@ set (PLM_TESTING_DOWNLOAD_DATA_DIR "${CMAKE_BINARY_DIR}/TestData")
 set (PLM_BUILD_TESTING_DIR "${CMAKE_BINARY_DIR}/Testing")
 
 ##-----------------------------------------------------------------------------
-##  Search for include files
-##-----------------------------------------------------------------------------
-check_include_files ("stdint.h" HAVE_STDINT_H)
-check_include_files ("sys/stat.h" HAVE_SYS_STAT_H)
-
-##-----------------------------------------------------------------------------
-##  A few constants used to control build & install
-##-----------------------------------------------------------------------------
-set (INSTALL_NEVER 0)
-set (INSTALL_ALWAYS 1)
-if (PLM_CONFIG_DEBIAN_BUILD)
-  set (INSTALL_IF_NOT_DEBIAN 0)
-else ()
-  set (INSTALL_IF_NOT_DEBIAN 1)
-endif ()
-
-set (BUILD_NEVER 0)
-set (BUILD_ALWAYS 1)
-set (BUILD_IF_NOT_SLICER_EXT 1)
-
-##-----------------------------------------------------------------------------
 ##  Set the math library
 ##-----------------------------------------------------------------------------
 if (UNIX)
@@ -282,29 +261,51 @@ endif ()
 find_library (LIBDL_FOUND dl)
 
 ##-----------------------------------------------------------------------------
-##  Search for libraries
+##  DCMTK
 ##-----------------------------------------------------------------------------
-if (PLM_CONFIG_DISABLE_DCMTK)
-  set (DCMTK_FOUND FALSE)
-else ()
-  find_package (DCMTK_wrap)
-  if (DCMTK_FOUND AND DCMTK_VERSION_STRING VERSION_LESS 3.6.0)
-    set (DCMTK_FOUND FALSE)
+## If it is a modern version of DCMTK, such as found in Slicer build, 
+## it will have a working version of DCMTKConfig.cmake.
+## In this case, we can use the modern find_package variant.
+## Otherwise we use the old hacked version of FindDCMTK.cmake.
+if (NOT PLM_CONFIG_DISABLE_DCMTK)
+  if (PLM_SYSTEM_DCMTK STREQUAL "YES")
+    if (DCMTK_DIR AND EXISTS "${DCMTK_DIR}/DCMTKConfig.cmake")
+      find_package (DCMTK NO_MODULE REQUIRED)
+    else ()
+      find_package (DCMTK_legacy REQUIRED)
+    endif ()
+  elseif (PLM_SYSTEM_DCMTK STREQUAL "PREFERRED")
+    if (DCMTK_DIR AND EXISTS "${DCMTK_DIR}/DCMTKConfig.cmake")
+      find_package (DCMTK NO_MODULE QUIET)
+    else ()
+      find_package (DCMTK_legacy QUIET)
+    endif ()
+  endif ()
+
+  if (NOT DCMTK_FOUND AND NOT PLM_SYSTEM_DCMTK STREQUAL "YES")
+    include (SuperBuild/External_DCMTK.cmake)
+    message (STATUS "DCMTK will be downloaded and built.")
+  else ()
+    if (DCMTK_FOUND)
+      message (STATUS "DCMTK version ${DCMTK_VERSION} found.")
+    else ()
+      message (STATUS "DCMTK not found.")
+    endif ()
   endif ()
 endif ()
-if (PLM_PREFER_SYSTEM_DLIB)
-  # Use this version if you want to use the internal cmake find. 
-  # The internal version has issue finding the correct BLAS library
-  # for Debian, so we prefer Debian version.
-  # find_package (Dlib)
-  
-  # However, the Debian cmake find is broken.  Its breakage can
-  # be worked around by setting dlib_BINARY_DIR.
-  set (dlib_BINARY_DIR 1)
-  find_package (dlib QUIET)
-endif ()
+
+# Workaround for CMake bug in FindDCMTK.  This was fixed some time between 
+# 3.4.3 and 3.7.2
+# if (CMAKE_VERSION VERSION_LESS "3.7.2" AND DCMTK_ofstd_INCLUDE_DIR)
+#   get_filename_component(_tmp ${DCMTK_ofstd_INCLUDE_DIR} PATH)
+#   get_filename_component(_tmp ${_tmp} PATH)
+#   list (APPEND DCMTK_INCLUDE_DIRS ${_tmp})
+# endif ()
+
+##-----------------------------------------------------------------------------
+##  Search for libraries
+##-----------------------------------------------------------------------------
 find_package (Etags)
-#find_package (Fann)
 find_package (FFTW)
 find_package (Git)
 find_package (Kaze)
@@ -319,7 +320,6 @@ find_package (Octave)
 if (NOT PLM_CONFIG_DISABLE_OPENCL)
   find_package (OpenCL)
 endif ()
-## find_package (OpenGL)
 if (NOT PLM_CONFIG_DISABLE_OPENMP)
   find_package (OpenMP)
 endif ()
@@ -341,10 +341,10 @@ find_package (wxWidgets)
 ##-----------------------------------------------------------------------------
 if (NOT LIBLBFGS_FOUND)
   add_subdirectory (libs/liblbfgs-1.9)
-  set (LIBLBFGS_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/libs/liblbfgs-1.9/include")
-  set (LIBLBFGS_LIBRARIES lbfgs)
+  sb_set (LIBLBFGS_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/libs/liblbfgs-1.9/include")
+  sb_set (LIBLBFGS_LIBRARIES lbfgs)
   link_directories (${CMAKE_CURRENT_BINARY_DIR}/libs/liblbfgs-1.9)
-  set (LIBLBFGS_FOUND TRUE)
+  sb_set (LIBLBFGS_FOUND TRUE)
 endif ()
 
 ##-----------------------------------------------------------------------------
@@ -360,29 +360,13 @@ endif ()
 #-----------------------------------------------------------------------------
 ##  Only use local devillard
 ##-----------------------------------------------------------------------------
-set (DEVILLARD_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/libs/devillard")
+sb_set (DEVILLARD_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/libs/devillard")
 add_subdirectory (libs/devillard)
 
 ##-----------------------------------------------------------------------------
-##  If using local dlib
-##-----------------------------------------------------------------------------
-if (dlib_FOUND)
-  set (DLIB_INCLUDE_DIR ${dlib_INCLUDE_DIR})
-  set (DLIB_LIBRARIES ${dlib_LIBRARIES})
-  set (DLIB_FOUND TRUE)
-endif ()
-if (DLIB_FOUND)
-  set (DLIB_HAVE_LIBRARY TRUE)
-else ()
-  set (DLIB_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/libs/dlib-19.1")
-  set (DLIB_LIBRARIES "")
-  set (DLIB_HAVE_LIBRARY FALSE)
-endif ()
-
-##-----------------------------------------------------------------------------
 ##  Only use local inih
 ##-----------------------------------------------------------------------------
-set (INIH_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/libs/inih-r29")
+sb_set (INIH_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/libs/inih-r29")
 add_subdirectory (libs/inih-r29)
 
 ##-----------------------------------------------------------------------------
@@ -400,22 +384,19 @@ add_subdirectory (libs/inih-r29)
 ##-----------------------------------------------------------------------------
 ##  Only use local specfun
 ##-----------------------------------------------------------------------------
-set (SPECFUN_FOUND FALSE)
 add_subdirectory (libs/specfun)
 link_directories (${CMAKE_CURRENT_BINARY_DIR}/libs/specfun)
-set (SPECFUN_FOUND TRUE)
+sb_set (SPECFUN_FOUND TRUE)
 
 ##-----------------------------------------------------------------------------
 ##  Only use local msinttypes
 ##-----------------------------------------------------------------------------
-set (MSINTTYPES_INCLUDE_DIR 
-  "${CMAKE_SOURCE_DIR}/libs" 
-  )
+sb_set (MSINTTYPES_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/libs")
 
 ##-----------------------------------------------------------------------------
 ##  Only use local nkidecompress
 ##-----------------------------------------------------------------------------
-set (NKIDECOMPRESS_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/libs/nkidecompress")
+sb_set (NKIDECOMPRESS_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/libs/nkidecompress")
 add_subdirectory (libs/nkidecompress)
 
 ##-----------------------------------------------------------------------------
@@ -546,59 +527,27 @@ if (EXISTS "${CMAKE_SOURCE_DIR}/.git" AND GIT_FOUND)
     OUTPUT_STRIP_TRAILING_WHITESPACE
     )
   if (${git_result} EQUAL 0)
-    message (STATUS "Looking for version in git - found ${git_version}")
     set (PLASTIMATCH_VERSION_STRING "${PLASTIMATCH_VERSION_STRING} (${git_version})")
-  else ()
-    message (STATUS "Looked for version in git but failed")
   endif ()
+  message (STATUS "Plastimatch version is ${git_version}")
 endif ()
 
 ##-----------------------------------------------------------------------------
 ##  ITK
 ##-----------------------------------------------------------------------------
-find_package (ITK)
-if (PLM_SUPERBUILD)
-  if (NOT ITK_FOUND OR PLM_PREFER_EXTERNAL_ITK)
-    message (STATUS "ITK_DIR = ${ITK_DIR}")
-    include (cmake/ExternalITK.cmake)
-    message (STATUS "ITK_DIR = ${ITK_DIR}")
-    find_package (ITK)
-  endif ()
+if (PLM_SYSTEM_ITK STREQUAL "YES")
+  find_package (ITK REQUIRED)
+elseif (PLM_SYSTEM_ITK STREQUAL "PREFERRED")
+  find_package (ITK QUIET)
+endif ()
+if (NOT ITK_FOUND AND NOT PLM_SYSTEM_ITK STREQUAL "YES")
+  message (STATUS "ITK will be downloaded and built.")
+  include (SuperBuild/External_ITK.cmake)
 endif ()
+
 if (ITK_FOUND)
-  # GCS 2016-10-20
-  # The GDCM USE file spews out copious extraneous warnings on Debian.
-  # If we are not using GDCM, this might be avoided by setting
-  # ITK_USE_SYSTEM_GDCM to FALSE.  However, this has the undesirable
-  # effect of removing gdcm includes from include list and gdcm libraries
-  # from library list.
-  #if (DCMTK_FOUND)
-  # set (ITK_USE_SYSTEM_GDCM FALSE)
-  #endif ()
-  include (${ITK_USE_FILE})
-  set (ITK_VERSION 
-    "${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}.${ITK_VERSION_PATCH}")
-  if (${ITK_VERSION} VERSION_LESS "3.16.0")
-    message (FATAL_ERROR 
-      "Fatal Error. ITK must be version 3.16.0 or higher")
-  endif ()
-  if (${ITK_VERSION_MAJOR} VERSION_EQUAL "3")
-    if (NOT ITK_USE_REVIEW)
-      message (FATAL_ERROR 
-	"Fatal Error. ITK must be compiled with ITK_USE_REVIEW set to ON")
-    endif ()
-    set (ITK_LIBRARIES ${ITK_LIBRARIES} ITKIOReview)
-  elseif (${ITK_VERSION_MAJOR} VERSION_EQUAL "4")
-    if (${ITK_VERSION} VERSION_LESS "4.1")
-      message (FATAL_ERROR 
-	"Fatal Error. ITK 4 must be 4.1 or greater")
-    endif ()
-  else ()
-    message (FATAL_ERROR 
-      "Fatal Error. ITK version should be either 3.X or 4.X")
-  endif ()
+  include (HandleITK)
 endif ()
-message (STATUS "ITK_VERSION = ${ITK_VERSION} found")
 
 ##-----------------------------------------------------------------------------
 ##  GDCM
@@ -642,61 +591,24 @@ else ()
 endif ()
 
 ##-----------------------------------------------------------------------------
-##  Figure out if we should use gdcm or dcmtk
-##-----------------------------------------------------------------------------
-set (PLM_DCM_USE_DCMTK 0)
-set (PLM_DCM_USE_GDCM1 0)
-set (PLM_DCM_USE_GDCM2 0)
-
-if (DCMTK_FOUND)
-    set (PLM_DCM_USE_DCMTK 1)
-elseif (GDCM_VERSION_2)
-    set (PLM_DCM_USE_GDCM2 1)
-else ()
-    set (PLM_DCM_USE_GDCM1 1)
-endif ()
-
-##-----------------------------------------------------------------------------
-##  VTK
-##-----------------------------------------------------------------------------
-if (NOT PLM_CONFIG_DISABLE_REG23)
-  find_package (VTK)
-  if (VTK_FOUND)
-    message (STATUS "VTK version ${VTK_VERSION}")
-  else ()
-    message (STATUS "VTK not found")
-  endif ()
-  # GCS 2012-05-14: Including VTK_USE_FILE causes VTK to pollute the 
-  # include directory list, which causes cuda to fail to compile
-  #if (VTK_FOUND)
-  #  include (${VTK_USE_FILE})
-  #endif ()
-endif ()
-
-##-----------------------------------------------------------------------------
 ##  QT
 ##-----------------------------------------------------------------------------
 if (PLM_CONFIG_DISABLE_QT)
   set (QT4_FOUND false)
+  set (QT5_FOUND false)
 else ()
-  # In VS2013 with win7, QtWebkit was not able to be compiled.(.lib file
-  # is not generated.) QtWebkit is only used by Reg23.
-  if (PLM_CONFIG_DISABLE_REG23)
-    find_package (Qt4 4.6.3 COMPONENTS QtCore QtGui QtDesigner)
-  else ()
-    message (STATUS "In VS2013 w/ Qt4.8.6, QtWebkit couldn't be compiled. Check PLM_CONFIG_DISABLE_REG23 if you don't want REG23 and there is compiling error.")
-    find_package (Qt4 4.6.3 COMPONENTS QtCore QtGui QtWebKit QtDesigner)
-  endif ()
+  find_package (Qt4 4.6.3 QUIET COMPONENTS QtCore QtGui QtDesigner)
+  find_package (Qt5 QUIET COMPONENTS Core Gui Designer Network Widgets)
 endif ()
 
 if (QT4_FOUND)
-   # Test Qt install to make sure it can build and run a test program
-   include (cmake/CheckQt)
-   check_qt (QT_TEST_COMPILE_SUCCEEDED)
-   if (NOT QT_TEST_COMPILE_SUCCEEDED)
-       message (STATUS "Qt failed to compile a test program")
-       set (QT4_FOUND false)
-   endif ()
+  # Test Qt install to make sure it can build and run a test program
+  include (CheckQt)
+  check_qt (QT_TEST_COMPILE_SUCCEEDED)
+  if (NOT QT_TEST_COMPILE_SUCCEEDED)
+    message (STATUS "Qt failed to compile a test program")
+    set (QT4_FOUND false)
+  endif ()
 endif ()
 
 if (QT4_FOUND)
@@ -713,20 +625,16 @@ if (QT4_FOUND)
 	set (QT4_FOUND FALSE)
     else ()
 	message (STATUS "Looking for Qt4 - found")
-	include (${QT_USE_FILE})
+	#include (${QT_USE_FILE})
     endif ()
 else ()
     message (STATUS "Looking for Qt4 - not found")
 endif ()
 
-##-----------------------------------------------------------------------------
-##  Only use local ransac
-##-----------------------------------------------------------------------------
-if (ITK_FOUND)
-  add_subdirectory (libs/ransac)
-  set (RANSAC_INCLUDE_DIRS 
-    "${CMAKE_SOURCE_DIR}/libs/ransac" 
-    "${CMAKE_SOURCE_DIR}/libs/ransac/Common")
+if (Qt5_FOUND)
+  message (STATUS "Looking for Qt5 - found")
+else ()
+  message (STATUS "Looking for Qt5 - not found")
 endif ()
 
 ##-----------------------------------------------------------------------------
@@ -734,10 +642,10 @@ endif ()
 ##-----------------------------------------------------------------------------
 set (RAPIDJSON_DIR "${CMAKE_SOURCE_DIR}/libs/rapidjson-2015-03-22")
 if (EXISTS "${RAPIDJSON_DIR}" AND IS_DIRECTORY "${RAPIDJSON_DIR}")
-    set (RAPIDJSON_INCLUDE_DIR 
-	"${RAPIDJSON_DIR}/include"
-	)
-    set (RAPIDJSON_FOUND true)
+  set (RAPIDJSON_INCLUDE_DIR 
+    "${RAPIDJSON_DIR}/include"
+    )
+  set (RAPIDJSON_FOUND true)
 endif ()
 
 ##-----------------------------------------------------------------------------
@@ -759,84 +667,9 @@ add_subdirectory (src)
 ##  Additional install files
 ##-----------------------------------------------------------------------------
 if (ITK_FOUND)
-    file (GLOB DLLFILES "${ITK_DIR}/bin/release/*.dll")
-    if (DLLFILES)
-      install (FILES ${DLLFILES} DESTINATION bin)
-    endif ()
-endif ()
-
-if (CUDA_FOUND)
-  if (UNIX)
-    set (CUDART_LINUX_VERSION "libcudart.so.3.0.14")
-    set (CUDART_LINUX32 
-      "${CUDA_TOOLKIT_ROOT_DIR}/lib/${CUDART_LINUX_VERSION}")
-    set (CUDART_LINUX64 
-      "${CUDA_TOOLKIT_ROOT_DIR}/lib64/${CUDART_LINUX_VERSION}")
-
-    if (MACHINE_IS_32_BIT AND EXISTS "${CUDART_LINUX32}")
-      set (CUDART_FILE_SRC "${CUDART_LINUX32}")
-    endif ()
-
-    if (MACHINE_IS_64_BIT AND EXISTS "${CUDART_LINUX64}")
-      set (CUDART_FILE_SRC "${CUDART_LINUX64}")
-    endif ()
-
-    # Override for packagers building 32-bit packages on 64-bit machine
-    if (PLM_PACKAGE_32BIT AND EXISTS "${CUDART_LINUX32}")
-      set (CUDART_FILE_SRC "${CUDART_LINUX32}")
-    endif ()
-
-    # Hard code to cuda 3.0 (runtime 3.0.14).  Note, we copy it first, because
-    # otherwise CMake 2.6 will install a broken symbolic link
-    set (CUDART_FILE "${CMAKE_BINARY_DIR}/${CUDART_LINUX_VERSION}")
-    if (EXISTS "${CUDART_FILE_SRC}")
-      execute_process (COMMAND
-        ${CMAKE_COMMAND} "-E" "copy" 
-	    "${CUDART_FILE_SRC}" "${CUDART_FILE}"
-      )
-    endif ()
-  else ()
-#    set (CUDART_WIN32 "${CUDA_TOOLKIT_ROOT_DIR}/bin/cudart32_30_14.dll")
-#    set (CUDART_WIN64 "${CUDA_TOOLKIT_ROOT_DIR}/bin/cudart64_30_14.dll")
-#05/27/2016 YKP (for window users only): will copy dll files to bin for packaging.
-    set (CUDART_WIN32 "${CUDA_TOOLKIT_ROOT_DIR}/bin/cudart32_65.dll")
-    set (CUDART_WIN64 "${CUDA_TOOLKIT_ROOT_DIR}/bin/cudart64_65.dll")
-    set (CUFFT_WIN32 "${CUDA_TOOLKIT_ROOT_DIR}/bin/cufft32_65.dll")
-    set (CUFFT_WIN64 "${CUDA_TOOLKIT_ROOT_DIR}/bin/cufft64_65.dll")
-
-    if (MACHINE_IS_32_BIT AND EXISTS "${CUDART_WIN32}")
-      set (CUDART_FILE "${CUDART_WIN32}")
-    endif ()
-    if (MACHINE_IS_32_BIT AND EXISTS "${CUFFT_WIN32}")
-      set (CUFFT_FILE "${CUFFT_WIN32}")
-    endif ()
-    if (MACHINE_IS_64_BIT AND EXISTS "${CUDART_WIN64}")	
-      set (CUDART_FILE "${CUDART_WIN64}")	  
-    endif ()
-    if (MACHINE_IS_64_BIT AND EXISTS "${CUFFT_WIN64}")		
-      set (CUFFT_FILE "${CUFFT_WIN64}")	  
-    endif ()
-
-    # Override for packagers building 32-bit packages on 64-bit machine
-    if (PLM_PACKAGE_32BIT AND EXISTS "${CUDART_WIN32}")
-      set (CUDART_FILE_SRC "${CUDART_WIN32}")
-    endif ()
-  endif ()
-
-  if (EXISTS "${CUDART_FILE}")
-    if (UNIX)
-      install (FILES "${CUDART_FILE}" DESTINATION lib)
-    else ()
-      install (FILES "${CUDART_FILE}" DESTINATION bin)
-    endif ()
-  endif ()
-
-  if (EXISTS "${CUFFT_FILE}")
-    if (UNIX)
-      install (FILES "${CUFFT_FILE}" DESTINATION lib)
-    else ()
-      install (FILES "${CUFFT_FILE}" DESTINATION bin)
-    endif ()
+  file (GLOB DLLFILES "${ITK_DIR}/bin/release/*.dll")
+  if (DLLFILES)
+    install (FILES ${DLLFILES} DESTINATION bin)
   endif ()
 endif ()
 
@@ -848,10 +681,10 @@ if (QT4_FOUND)
     set (QT4_CORE_DLL_WIN "${QT_LIBRARY_DIR}/QtCore4.dll")
     set (QT4_GUI_DLL_WIN "${QT_LIBRARY_DIR}/QtGui4.dll")
     if (EXISTS "${QT4_CORE_DLL_WIN}")
-		install (FILES "${QT4_CORE_DLL_WIN}" DESTINATION bin)
+      install (FILES "${QT4_CORE_DLL_WIN}" DESTINATION bin)
     endif ()
-	if (EXISTS "${QT4_GUI_DLL_WIN}")
-		install (FILES "${QT4_GUI_DLL_WIN}" DESTINATION bin)
+    if (EXISTS "${QT4_GUI_DLL_WIN}")
+      install (FILES "${QT4_GUI_DLL_WIN}" DESTINATION bin)
     endif ()
   endif ()
 endif ()
@@ -861,7 +694,7 @@ if (FFTW_FOUND)
   if (EXISTS "${FFTW_DIR}/libfftw3-3.dll")
     install (FILES "${FFTW_DIR}/libfftw3-3.dll" DESTINATION bin)	
   endif ()
-    #YKP 05/27/2016: no need of libfftw3f-3.dll and libfftw3l-3.dll?
+  #YKP 05/27/2016: no need of libfftw3f-3.dll and libfftw3l-3.dll?
 endif ()
 
 # Add sample directory/files to Install Only for windows users
@@ -920,17 +753,19 @@ endif ()
 ##    avoid this (i.e. no good suggestions on CMake/CTest email list.  
 ##    This is the purpose of the PATH_HACK code below.
 ##-----------------------------------------------------------------------------
-if (ITK_FOUND)
 if (WIN32 AND NOT CYGWIN AND NOT MINGW)
   set (PLM_PLASTIMATCH_PATH 
-    ${CMAKE_CURRENT_BINARY_DIR}/Release)
+    ${PLM_BINARY_DIR}/Release)
   set (PLM_PLASTIMATCH_TESTING_PATH 
-    ${CMAKE_CURRENT_BINARY_DIR}/Testing/Release)
+    ${PLM_BINARY_DIR}/Testing/Release)
   set (PLM_FFTW_PATH ${FFTW_DIR})
   # At some point in time (presumably around ITK 4.1), ITK stopped 
   # creating the variable ITK_LIBRARY_DIRS.  Therefore, we have to 
   # use another method to find the ITK directory needed to run tests.
-  if (${ITK_VERSION} VERSION_LESS "4.1")
+  if (NOT ITK_FOUND)
+    set (PLM_ITK_LIBRARY_PATH_HACK 
+      -DITK_LIBRARY_PATH=${PLM_BINARY_DIR}/ITK-build/bin/Release)
+  elseif (${ITK_VERSION} VERSION_LESS "4.1")
     set (PLM_ITK_LIBRARY_PATH_HACK 
       -DITK_LIBRARY_PATH=${ITK_LIBRARY_DIRS}/Release)
   else ()
@@ -944,14 +779,13 @@ if (WIN32 AND NOT CYGWIN AND NOT MINGW)
   set (PLM_FFTW_PATH_HACK 
      -DPLM_FFTW_PATH=${PLM_FFTW_PATH})
 else ()
-  set (PLM_PLASTIMATCH_PATH ${CMAKE_CURRENT_BINARY_DIR})
-  set (PLM_PLASTIMATCH_TESTING_PATH ${CMAKE_CURRENT_BINARY_DIR}/Testing)
+  set (PLM_PLASTIMATCH_PATH ${PLM_BINARY_DIR})
+  set (PLM_PLASTIMATCH_TESTING_PATH ${PLM_BINARY_DIR}/Testing)
   set (PLM_FFTW_PATH "${FFTW_DIR}")
   set (PLM_ITK_LIBRARY_PATH_HACK "")
   set (PLM_PLASTIMATCH_PATH_HACK "")
   set (PLM_FFTW_PATH_HACK "")
 endif ()
-endif ()
 
 macro (PLM_ADD_TEST PLM_TEST_NAME PLM_TEST_COMMAND PARMS)
   # Optional extra parameters are passed through ${ARGN}
@@ -975,6 +809,7 @@ macro (PLM_ADD_TEST PLM_TEST_NAME PLM_TEST_COMMAND PARMS)
     ${EXTRA_PARMS}
     -P ${CMAKE_SOURCE_DIR}/cmake/RUN_CTEST.cmake
     )
+#  message (STATUS "${CMAKE_COMMAND} -DPLM_TEST_NAME=${PLM_TEST_NAME} ${PLM_ITK_LIBRARY_PATH_HACK} ${PLM_PLASTIMATCH_PATH_HACK} ${PLM_FFTW_PATH_HACK} -DPLM_TEST_COMMAND=${PLM_TEST_COMMAND} -DPLM_TESTING_SOURCE_DIR=${PLM_TESTING_SOURCE_DIR} -DPLM_BUILD_TESTING_DIR=${PLM_BUILD_TESTING_DIR} \"-DPARMS=${TMP_PARMS}\" ${EXTRA_PARMS} -P ${CMAKE_SOURCE_DIR}/cmake/RUN_CTEST.cmake")
 endmacro ()
 
 # Figure out which tests to ignore
@@ -994,10 +829,12 @@ if (PLM_BUILD_TESTING)
   add_subdirectory (Testing)
 
   # Copy the lconv script
-  configure_file (
-    "${CMAKE_SOURCE_DIR}/extra/devtools/run_lcov.sh" 
-    "${CMAKE_BINARY_DIR}/run_lcov.sh"
-    COPYONLY)
+  if (EXISTS "${CMAKE_SOURCE_DIR}/extra/devtools/run_lcov.sh")
+    configure_file (
+      "${CMAKE_SOURCE_DIR}/extra/devtools/run_lcov.sh" 
+      "${CMAKE_BINARY_DIR}/run_lcov.sh"
+      COPYONLY)
+  endif ()
 endif ()
 
 ##-----------------------------------------------------------------------------
diff --git a/SuperBuild/External_DCMTK.cmake b/SuperBuild/External_DCMTK.cmake
new file mode 100644
index 0000000..045b9d6
--- /dev/null
+++ b/SuperBuild/External_DCMTK.cmake
@@ -0,0 +1,35 @@
+##-----------------------------------------------------------------------------
+##  Download DCMTK from internet and compile
+##-----------------------------------------------------------------------------
+set (proj DCMTK)
+
+set (dcmtk_url ftp://dicom.offis.de/pub/dicom/offis/software/dcmtk/dcmtk362/dcmtk-3.6.2.tar.gz)
+set (dcmtk_md5sum d219a4152772985191c9b89d75302d12)
+
+ExternalProject_Add (${proj}
+  DOWNLOAD_DIR ${proj}-download
+  URL ${dcmtk_url}
+  URL_MD5 ${dcmtk_md5sum}
+  SOURCE_DIR ${proj}
+  BINARY_DIR ${proj}-build
+  CMAKE_GENERATOR ${gen}
+  CMAKE_ARGS
+  -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+  -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
+  -DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS}
+  -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
+  -DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}
+  #  -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD}
+  -DCMAKE_CXX_STANDARD_REQUIRED:BOOL=${CMAKE_CXX_STANDARD_REQUIRED}
+  -DCMAKE_CXX_EXTENSIONS:BOOL=${CMAKE_CXX_EXTENSIONS}
+  -DBUILD_APPS:BOOL=OFF
+  ## GCS 2017-12-14: "Temporarily" force static library to reduce changes 
+  ## needed to run regression tests on Windows.  When time allows, 
+  ## this should be built as a shared library.  
+  #  -DBUILD_SHARED_LIBS:BOOL=ON
+  -DBUILD_SHARED_LIBS:BOOL=OFF
+  -DDCMTK_OVERWRITE_WIN32_COMPILER_FLAGS:BOOL=OFF
+  INSTALL_COMMAND ""
+  )
+
+set (DCMTK_DIR ${CMAKE_BINARY_DIR}/${proj}-build)
diff --git a/SuperBuild/External_ITK.cmake b/SuperBuild/External_ITK.cmake
new file mode 100755
index 0000000..f87fd0a
--- /dev/null
+++ b/SuperBuild/External_ITK.cmake
@@ -0,0 +1,32 @@
+##-----------------------------------------------------------------------------
+##  Download ITK from internet and compile
+##-----------------------------------------------------------------------------
+set (proj ITK)
+
+set (itk_url https://downloads.sourceforge.net/project/itk/itk/4.12/InsightToolkit-4.12.2.tar.gz)
+set (itk_md5sum 758206eeb458d11b7ba2d81d8a3ce212)
+
+ExternalProject_Add (${proj}
+  DOWNLOAD_DIR ${proj}-download
+  URL ${itk_url}
+  URL_MD5 ${itk_md5sum}
+  SOURCE_DIR ${proj}
+  BINARY_DIR ${proj}-build
+  CMAKE_GENERATOR ${gen}
+  CMAKE_ARGS
+  -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+  -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
+  -DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS}
+  -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
+  -DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}
+  #    -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD}
+  -DCMAKE_CXX_STANDARD_REQUIRED:BOOL=${CMAKE_CXX_STANDARD_REQUIRED}
+  -DCMAKE_CXX_EXTENSIONS:BOOL=${CMAKE_CXX_EXTENSIONS}
+  -DBUILD_EXAMPLES:BOOL=OFF
+  -DBUILD_SHARED_LIBS:BOOL=ON
+  -DBUILD_TESTING:BOOL=OFF
+  -DModule_ITKReview:BOOL=ON
+  INSTALL_COMMAND ""
+  )
+
+set (ITK_DIR ${CMAKE_BINARY_DIR}/${proj}-build)
diff --git a/Testing/CTestCustom.cmake.in b/Testing/CTestCustom.cmake.in
index 651a375..28656d8 100644
--- a/Testing/CTestCustom.cmake.in
+++ b/Testing/CTestCustom.cmake.in
@@ -344,6 +344,9 @@ if (PLM_CONFIG_DEBIAN_BUILD)
     "proton-dose-5a"
     "proton-dose-5a-stats"
     "proton-dose-5a-check"
+    "proton-dose-5d"
+    "proton-dose-5d-stats"
+    "proton-dose-5d-check"
     "proton-dose-5g"
     "proton-dose-5g-stats"
     "proton-dose-5g-check"
diff --git a/cmake/CheckCharSign.cmake b/cmake/CheckCharSign.cmake
index 24208bf..bfc0d48 100755
--- a/cmake/CheckCharSign.cmake
+++ b/cmake/CheckCharSign.cmake
@@ -2,9 +2,9 @@
 ## See COPYRIGHT.TXT and LICENSE.TXT for copyright and license information
 ##---------------------------------------------------------------------------
 
-macro (CHECK_CHAR_SIGN OUT_VAR)
+macro (check_char_sign _out_var)
   try_run (RUN_RESULT_VAR COMPILE_RESULT_VAR
-    ${CMAKE_BINARY_DIR}
-    ${CMAKE_SOURCE_DIR}/cmake/char_is_signed.cxx
-    RUN_OUTPUT_VARIABLE ${OUT_VAR})
+    ${PLM_BINARY_DIR}
+    ${PLM_SOURCE_DIR}/cmake/char_is_signed.cxx
+    RUN_OUTPUT_VARIABLE ${_out_var})
 endmacro ()
diff --git a/cmake/CheckEpsilon.cmake b/cmake/CheckEpsilon.cmake
index 0ded097..62274b3 100755
--- a/cmake/CheckEpsilon.cmake
+++ b/cmake/CheckEpsilon.cmake
@@ -2,9 +2,9 @@
 ## See COPYRIGHT.TXT and LICENSE.TXT for copyright and license information
 ##---------------------------------------------------------------------------
 
-macro (CHECK_EPSILON OUT_VAR)
+macro (check_epsilon _out_var)
   try_run (RUN_RESULT_VAR COMPILE_RESULT_VAR
-    ${CMAKE_BINARY_DIR}
-    ${CMAKE_SOURCE_DIR}/cmake/test_eps.cxx
-    RUN_OUTPUT_VARIABLE ${OUT_VAR})
+    ${PLM_BINARY_DIR}
+    ${PLM_SOURCE_DIR}/cmake/test_eps.cxx
+    RUN_OUTPUT_VARIABLE ${_out_var})
 endmacro ()
diff --git a/cmake/ExternalITK.cmake b/cmake/ExternalITK.cmake
deleted file mode 100755
index d4995d1..0000000
--- a/cmake/ExternalITK.cmake
+++ /dev/null
@@ -1,36 +0,0 @@
-##-----------------------------------------------------------------------------
-##  Download ITK from internet and compile
-##-----------------------------------------------------------------------------
-if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_LESS 2.8)
-  return ()
-endif ()
-
-message (STATUS "Hello from ExternalITK")
-
-set (proj_itk ITKv3)
-
-set (itk_url http://sourceforge.net/projects/itk/files/itk/3.20/InsightToolkit-3.20.0.tar.gz)
-
-ExternalProject_Add (${proj_itk}
-  DOWNLOAD_DIR ${proj_itk}-download
-  URL ${itk_url}
-  URL_MD5 5d6b8e6e641624c6a8c06c7f95f05c9e
-  PATCH_COMMAND "${CMAKE_COMMAND}" 
-    -DPLM_SOURCE_DIR=${CMAKE_SOURCE_DIR}
-    -DPLM_TARGET_DIR=${CMAKE_BINARY_DIR}/${proj_itk}
-    -P "${CMAKE_SOURCE_DIR}/cmake/ExternalITKPatch.cmake"
-  SOURCE_DIR ${proj_itk}
-  BINARY_DIR ${proj_itk}-build
-  CMAKE_GENERATOR ${gen}
-  CMAKE_ARGS
-    -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-    -DBUILD_EXAMPLES:BOOL=OFF
-    -DBUILD_SHARED_LIBS:BOOL=ON
-    -DBUILD_TESTING:BOOL=OFF
-    -DITK_USE_REVIEW:BOOL=ON
-    -DITK_USE_REVIEW_STATISTICS:BOOL=ON
-    -DITK_USE_OPTIMIZED_REGISTRATION_METHODS:BOOL=ON
-  INSTALL_COMMAND ""
-  )
-
-set (ITK_DIR ${CMAKE_BINARY_DIR}/${proj_itk}-build)
diff --git a/cmake/FindCUDA_wrap.cmake b/cmake/FindCUDA_wrap.cmake
index 0866bd7..4693ddd 100755
--- a/cmake/FindCUDA_wrap.cmake
+++ b/cmake/FindCUDA_wrap.cmake
@@ -95,14 +95,22 @@ endif ()
 #   This script will modify CUDA_NVCC_FLAGS if system default is not gcc-4.3
 include (nvcc-check)
 
+# GCS 2017-10-24: Let CUDA work with gcc 6 and CUDA 8
+if (CUDA_VERSION_MAJOR EQUAL "8"
+    AND CMAKE_COMPILER_IS_GNUCC
+    AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)
+  list (APPEND CUDA_NVCC_FLAGS 
+    --compiler-options -D__GNUC__=5)
+endif ()
+
 # JAS 2010.12.09
 #   Build code for all known compute capabilities by default.
 #   When developing, it is sometimes nice to turn this off in order
 #   to speed up the build processes (since you only have 1 GPU in your machine).
 set (PLM_CUDA_ALL_DEVICES ON CACHE BOOL 
-    "Generate GPU code for all compute capabilities?")
+  "Generate GPU code for all compute capabilities?")
 if (PLM_CUDA_ALL_DEVICES)
-    message (STATUS "CUDA Build Level: ALL Compute Capabilities")
+  message (STATUS "CUDA Build Level: ALL Compute Capabilities")
 
     if (CUDA_VERSION_MAJOR LESS "7")
 	message (STATUS "  >> Generation 1: [X]")
diff --git a/cmake/FindDCMTK.cmake b/cmake/FindDCMTK_legacy.cmake
similarity index 100%
rename from cmake/FindDCMTK.cmake
rename to cmake/FindDCMTK_legacy.cmake
diff --git a/cmake/FindDCMTK_wrap.cmake b/cmake/FindDCMTK_wrap.cmake
index d9b6b45..d2a927d 100644
--- a/cmake/FindDCMTK_wrap.cmake
+++ b/cmake/FindDCMTK_wrap.cmake
@@ -13,6 +13,7 @@ if (NOT DCMTK_FOUND)
 endif ()
 
 
+
 ## Get the version string (?)
 if (DCMTK_FOUND)
   # Basic version information
diff --git a/cmake/FindDlib.cmake b/cmake/FindDlib.cmake
index f466205..ee108db 100755
--- a/cmake/FindDlib.cmake
+++ b/cmake/FindDlib.cmake
@@ -48,12 +48,8 @@ if (DLIB_LIBRARY)
     endif ()
 endif ()
 
-set (DLIB_HAVE_LIBRARY FALSE)
 if (DLIB_FOUND)
-    set (DLIB_LIBRARIES ${DLIB_LIBRARY})
-    if (DLIB_LIBRARY)
-	set (DLIB_HAVE_LIBRARY TRUE)
-    endif ()
+  set (DLIB_LIBRARIES ${DLIB_LIBRARY})
 else (DLIB_FOUND)
   set (DLIB_LIBRARIES)
 endif (DLIB_FOUND)
diff --git a/cmake/FindOpenMP.cmake b/cmake/FindOpenMP.cmake
index 12f3ae6..de05a94 100755
--- a/cmake/FindOpenMP.cmake
+++ b/cmake/FindOpenMP.cmake
@@ -1,20 +1,38 @@
 ######################################################
 ##  OpenMP
 ######################################################
-INCLUDE(CheckFunctionExists)
-MESSAGE(STATUS "Check for compiler OpenMP support...")
-SET(OPENMP_FLAGS)
-SET(OPENMP_LIBRARIES)
-SET(OPENMP_FOUND FALSE)
+include (CheckFunctionExists)
+include (CheckCXXSourceCompiles)
+message (STATUS "Check for compiler OpenMP support...")
+set (OPENMP_FLAGS)
+set (OPENMP_LIBRARIES)
+set (OPENMP_FOUND FALSE)
+
+# sample openmp source code to test
+set(OpenMP_C_TEST_SOURCE
+"
+#include <omp.h>
+int main() {
+#ifdef _OPENMP
+  return 0;
+#else
+  breaks_on_purpose
+#endif
+}
+")
 
 # Key: CFLAGS##LDFLAGS#LIBRARIES
 # Neither CFLAGS nor LDFLAGS can be empty.  Use NONE instead.
-SET(
+set(
   OPENMP_FLAGS_AND_LIBRARIES
   # gcc
   "-fopenmp##-fopenmp#"
   "-fopenmp##-fopenmp#gomp"
   "-fopenmp##-fopenmp#gomp pthread"
+  # MSVC
+  "/openmp##NONE#"
+  # clang (??)
+  "-fopenmp=libomp##NONE#gomp"
   # icc
   "-openmp##-openmp#"
   "-openmp -parallel##-openmp -parallel#"
@@ -26,45 +44,57 @@ SET(
   "-omp##-omp#"
   # AIX
   "-qsmp=omp##-qsmp=omp#"
-  # MSVC
-  "/openmp##NONE#"
 )
 
 # Massive hack to workaround CMake limitations
-LIST(LENGTH OPENMP_FLAGS_AND_LIBRARIES NUM_FLAGS)
-MATH(EXPR NUM_FLAGS "${NUM_FLAGS} - 1")
-FOREACH(I RANGE 0 ${NUM_FLAGS})
-  IF(NOT OPENMP_FOUND)
-    LIST(GET OPENMP_FLAGS_AND_LIBRARIES ${I} TMP)
-    STRING(REGEX MATCH "([^#]*)" OPENMP_FLAGS ${TMP})
-    STRING(REGEX REPLACE "[^#]*##" "" TMP ${TMP})
-    STRING(REGEX MATCH "([^#]*)" OPENMP_LDFLAGS ${TMP})
-    STRING(REGEX REPLACE "[^#]*#" "" OPENMP_LIBRARIES ${TMP})
-    #MESSAGE(STATUS "OPENMP_FLAGS=${OPENMP_FLAGS}")
-    #MESSAGE(STATUS "OPENMP_LDFLAGS = ${OPENMP_LDFLAGS}")
-    #MESSAGE(STATUS "OPENMP_LIBRARIES = ${OPENMP_LIBRARIES}")
-    #MESSAGE(STATUS "-------")
+list (LENGTH OPENMP_FLAGS_AND_LIBRARIES NUM_FLAGS)
+math (EXPR NUM_FLAGS "${NUM_FLAGS} - 1")
+foreach (I RANGE 0 ${NUM_FLAGS})
+  if (NOT OPENMP_FOUND)
+    list (GET OPENMP_FLAGS_AND_LIBRARIES ${I} TMP)
+    string (REGEX MATCH "([^#]*)" OPENMP_FLAGS ${TMP})
+    string (REGEX REPLACE "[^#]*##" "" TMP ${TMP})
+    string (REGEX MATCH "([^#]*)" OPENMP_LDFLAGS ${TMP})
+    string (REGEX REPLACE "[^#]*#" "" OPENMP_LIBRARIES ${TMP})
+#    message (STATUS "OPENMP_FLAGS=${OPENMP_FLAGS}")
+#    message (STATUS "OPENMP_LDFLAGS = ${OPENMP_LDFLAGS}")
+#    message (STATUS "OPENMP_LIBRARIES = ${OPENMP_LIBRARIES}")
+#    message (STATUS "-------")
+
+    if (OPENMP_LDFLAGS MATCHES "NONE")
+      set (OPENMP_LDFLAGS "")
+    endif ()
+    if (OPENMP_LIBRARIES MATCHES " ")
+      string (REPLACE " " ";" OPENMP_LIBRARIES ${OPENMP_LIBRARIES})
+    endif ()
+
+    # 2017-12-07. If you overwrite CMAKE_REQUIRED_FLAGS, FindCUDA 
+    # does not work correctly.  It gives the wrong set of libraries.
+    # Therefore, we must save and restore the original values.
+    push_vars ("CMAKE_REQUIRED_QUIET" "CMAKE_REQUIRED_FLAGS" 
+        "CMAKE_REQUIRED_LIBRARIES")
+    set (CMAKE_REQUIRED_QUIET TRUE)
+    set (CMAKE_REQUIRED_FLAGS ${OPENMP_FLAGS})
+    set (CMAKE_REQUIRED_LIBRARIES ${OPENMP_LIBRARIES})
+
+    # CMake caches results from test compilations.  We need to unset the 
+    # cache value, or else cached test results gets used after first 
+    # iteration
+    unset (OPENMP_COMPILES CACHE)
 
-    IF(OPENMP_LDFLAGS MATCHES "NONE")
-      SET(OPENMP_LDFLAGS "")
-    ENDIF(OPENMP_LDFLAGS MATCHES "NONE")
-    IF(OPENMP_LIBRARIES MATCHES " ")
-      STRING(REPLACE " " ";" OPENMP_LIBRARIES ${OPENMP_LIBRARIES})
-    ENDIF(OPENMP_LIBRARIES MATCHES " ")
+    check_cxx_source_compiles ("${OpenMP_C_TEST_SOURCE}" OPENMP_COMPILES)
 
-    ## I think I need to do a try-compile
-    SET(CMAKE_REQUIRED_FLAGS ${OPENMP_FLAGS})
-    SET(CMAKE_REQUIRED_LIBRARIES ${OPENMP_LIBRARIES})
-    CHECK_FUNCTION_EXISTS(omp_get_thread_num OPENMP_FOUND${I})
+    pop_vars ("CMAKE_REQUIRED_QUIET" "CMAKE_REQUIRED_FLAGS" 
+        "CMAKE_REQUIRED_LIBRARIES")
 
-    IF(OPENMP_FOUND${I})
-      SET(OPENMP_FOUND TRUE)
-    ENDIF(OPENMP_FOUND${I})
-  ENDIF(NOT OPENMP_FOUND)
-ENDFOREACH(I RANGE 0 ${NUM_FLAGS})
+    if (OPENMP_COMPILES)
+      set (OPENMP_FOUND TRUE)
+    endif ()
+  endif ()
+endforeach ()
 
-IF(OPENMP_FOUND)
-  MESSAGE(STATUS "OpenMP flags \"${OPENMP_FLAGS}\", OpenMP libraries \"${OPENMP_LIBRARIES}\"")
-ELSE(OPENMP_FOUND)
-  MESSAGE(STATUS "Given compiler does not support OpenMP.")
-ENDIF(OPENMP_FOUND)
+if (OPENMP_FOUND)
+  message (STATUS "OpenMP flags \"${OPENMP_FLAGS}\", OpenMP libraries \"${OPENMP_LIBRARIES}\"")
+else ()
+  message (STATUS "Given compiler does not support OpenMP.")
+endif ()
diff --git a/cmake/HandleITK.cmake b/cmake/HandleITK.cmake
new file mode 100644
index 0000000..2d3aa2a
--- /dev/null
+++ b/cmake/HandleITK.cmake
@@ -0,0 +1,46 @@
+##-----------------------------------------------------------------------------
+##  HandleITK.cmake
+##    Check ITK version and optional components
+##    Include use file (for registering IO factories)
+##-----------------------------------------------------------------------------
+##  See COPYRIGHT.TXT and LICENSE.TXT for copyright and license information
+##-----------------------------------------------------------------------------
+
+# GCS 2016-10-20
+# The GDCM USE file spews out copious extraneous warnings on Debian.
+# If we are not using GDCM, this might be avoided by setting
+# ITK_USE_SYSTEM_GDCM to FALSE.  However, this has the undesirable
+# effect of removing gdcm includes from include list and gdcm libraries
+# from library list.
+#if (DCMTK_FOUND)
+# set (ITK_USE_SYSTEM_GDCM FALSE)
+#endif ()
+
+# GCS 2017-12-14 On older ITK version, the use file sets variables such
+# as DCMTK_FOUND, DCMTK_DIR.  Needs more investigation.
+include (${ITK_USE_FILE})
+
+if (NOT ITK_VERSION)
+  set (ITK_VERSION
+    "${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}.${ITK_VERSION_PATCH}")
+endif ()
+if (${ITK_VERSION} VERSION_LESS "3.16.0")
+  message (FATAL_ERROR 
+    "Fatal Error. ITK must be version 3.16.0 or higher")
+endif ()
+if (${ITK_VERSION_MAJOR} VERSION_EQUAL "3")
+  if (NOT ITK_USE_REVIEW)
+    message (FATAL_ERROR 
+      "Fatal Error. ITK must be compiled with ITK_USE_REVIEW set to ON")
+  endif ()
+  set (ITK_LIBRARIES ${ITK_LIBRARIES} ITKIOReview)
+elseif (${ITK_VERSION_MAJOR} VERSION_EQUAL "4")
+  if (${ITK_VERSION} VERSION_LESS "4.1")
+    message (FATAL_ERROR 
+      "Fatal Error. ITK 4 must be 4.1 or greater")
+  endif ()
+else ()
+  message (FATAL_ERROR 
+    "Fatal Error. ITK version should be either 3.X or 4.X")
+endif ()
+message (STATUS "ITK_VERSION = ${ITK_VERSION} found")
diff --git a/cmake/PlmMacros.cmake b/cmake/PlmMacros.cmake
index b99f71c..a02d684 100644
--- a/cmake/PlmMacros.cmake
+++ b/cmake/PlmMacros.cmake
@@ -1,4 +1,57 @@
 ##-----------------------------------------------------------------------------
+##  See COPYRIGHT.TXT and LICENSE.TXT for copyright and license information
+##-----------------------------------------------------------------------------
+##-----------------------------------------------------------------------------
+##  A few constants used to control build & install
+##-----------------------------------------------------------------------------
+set (INSTALL_NEVER 0)
+set (INSTALL_ALWAYS 1)
+if (PLM_CONFIG_DEBIAN_BUILD)
+  set (INSTALL_IF_NOT_DEBIAN 0)
+else ()
+  set (INSTALL_IF_NOT_DEBIAN 1)
+endif ()
+
+set (BUILD_NEVER 0)
+set (BUILD_ALWAYS 1)
+set (BUILD_IF_NOT_SLICER_EXT 1)
+
+##-----------------------------------------------------------------------------
+##  Create enum options
+##-----------------------------------------------------------------------------
+macro (option_enum
+    option_name
+    option_descr
+    option_value
+    )
+  set (${option_name} ${option_value} CACHE STRING ${option_descr})
+  set_property (CACHE ${option_name} PROPERTY STRINGS ${ARGN})
+endmacro ()
+
+##-----------------------------------------------------------------------------
+##  Save and restore variables
+##-----------------------------------------------------------------------------
+macro (push_var _var)
+  set (${_var}_BACKUP ${${_var}})
+endmacro ()
+
+macro (push_vars)
+  foreach (_var IN ITEMS ${ARGN})
+    push_var (${_var})
+  endforeach ()
+endmacro ()
+
+macro (pop_var _var)
+  set (${_var} ${${_var}_BACKUP})
+endmacro ()
+
+macro (pop_vars)
+  foreach (_var IN ITEMS ${ARGN})
+    pop_var (${_var})
+  endforeach ()
+endmacro ()
+
+##-----------------------------------------------------------------------------
 ##  Macros for creating targets
 ##-----------------------------------------------------------------------------
 macro (PLM_ADD_LIBRARY 
@@ -12,9 +65,9 @@ macro (PLM_ADD_LIBRARY
 
   add_library (${TARGET_NAME} ${TARGET_SRC})
   set_target_properties (${TARGET_NAME} PROPERTIES 
-    ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
-    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
-    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+    ARCHIVE_OUTPUT_DIRECTORY "${PLM_BINARY_DIR}"
+    LIBRARY_OUTPUT_DIRECTORY "${PLM_BINARY_DIR}"
+    RUNTIME_OUTPUT_DIRECTORY "${PLM_BINARY_DIR}"
     PUBLIC_HEADER "${TARGET_INCLUDE_FILES}")
   if (PLM_CONFIG_INSTALL_LIBRARIES)
     if (NOT PLM_PACKAGE_LEGACY_CMAKE_CONFIG)
@@ -47,9 +100,9 @@ macro (PLM_ADD_STATIC_LIBRARY
   add_library (${TARGET_NAME} STATIC ${TARGET_SRC})
 
   set_target_properties (${TARGET_NAME} PROPERTIES 
-    ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
-    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
-    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+    ARCHIVE_OUTPUT_DIRECTORY "${PLM_BINARY_DIR}"
+    LIBRARY_OUTPUT_DIRECTORY "${PLM_BINARY_DIR}"
+    RUNTIME_OUTPUT_DIRECTORY "${PLM_BINARY_DIR}"
     PUBLIC_HEADER "${TARGET_INCLUDES}")
 
   if (PLM_CONFIG_INSTALL_LIBRARIES)
@@ -77,9 +130,9 @@ macro (PLM_ADD_GPU_PLUGIN_LIBRARY TARGET_NAME TARGET_SRC)
   # Set output directory.  No PUBLIC_HEADER directory is needed, 
   # because they don't have a public API.
   set_target_properties (${TARGET_NAME} PROPERTIES 
-    ARCHIVE_OUTPUT_DIRECTORY "${PLM_BUILD_ROOT}"
-    LIBRARY_OUTPUT_DIRECTORY "${PLM_BUILD_ROOT}"
-    RUNTIME_OUTPUT_DIRECTORY "${PLM_BUILD_ROOT}")
+    ARCHIVE_OUTPUT_DIRECTORY "${PLM_BINARY_DIR}"
+    LIBRARY_OUTPUT_DIRECTORY "${PLM_BINARY_DIR}"
+    RUNTIME_OUTPUT_DIRECTORY "${PLM_BINARY_DIR}")
 
   # Set installation diretory and export definition.  No PUBLIC_HEADER needed.
   if (PLM_CONFIG_INSTALL_LIBRARIES)
@@ -96,15 +149,49 @@ macro (PLM_ADD_GPU_PLUGIN_LIBRARY TARGET_NAME TARGET_SRC)
       PROPERTIES SOVERSION "${PLM_VERSION_MAJOR}.${PLM_VERSION_MINOR}")
 endmacro ()
 
+## Legacy version, designed before target_include_directories was
+## implemented in cmake 2.8.12
 macro (PLM_ADD_EXECUTABLE 
-    TARGET_NAME TARGET_SRC TARGET_LIBS TARGET_LDFLAGS 
-    TARGET_BUILD TARGET_INSTALL)
+    TARGET_NAME
+    TARGET_SRC
+    TARGET_LIBS
+    TARGET_LDFLAGS 
+    TARGET_BUILD
+    TARGET_INSTALL)
+
+  if (${TARGET_BUILD})
+    add_executable (${TARGET_NAME} ${TARGET_SRC})
+    target_link_libraries (${TARGET_NAME} ${TARGET_LIBS})
+    set_target_properties (${TARGET_NAME} 
+      PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${PLM_BINARY_DIR}")
+    if (NOT ${TARGET_LDFLAGS} STREQUAL "")
+      set_target_properties(${TARGET_NAME} 
+	PROPERTIES LINK_FLAGS ${TARGET_LDFLAGS})
+    endif ()
+    # CXX linkage required for nlopt
+    set_target_properties (${TARGET_NAME} PROPERTIES LINKER_LANGUAGE CXX)
+    if (${TARGET_INSTALL})
+      install (TARGETS ${TARGET_NAME} DESTINATION "${PLM_INSTALL_BIN_DIR}")
+    endif ()
+  endif ()
+endmacro ()
+
+## New version, uses target_include_directories
+macro (plm_add_executable_v2
+    TARGET_NAME
+    TARGET_SRC
+    TARGET_INCLUDES
+    TARGET_LIBS
+    TARGET_LDFLAGS 
+    TARGET_BUILD
+    TARGET_INSTALL)
 
   if (${TARGET_BUILD})
     add_executable (${TARGET_NAME} ${TARGET_SRC})
     target_link_libraries (${TARGET_NAME} ${TARGET_LIBS})
+    target_include_directories (${TARGET_NAME} PRIVATE ${TARGET_INCLUDES})
     set_target_properties (${TARGET_NAME} 
-      PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
+      PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${PLM_BINARY_DIR}")
     if (NOT ${TARGET_LDFLAGS} STREQUAL "")
       set_target_properties(${TARGET_NAME} 
 	PROPERTIES LINK_FLAGS ${TARGET_LDFLAGS})
@@ -120,12 +207,12 @@ endmacro ()
 macro (PLM_ADD_OPENCL_FILE SRCS CL_FILE)
   # I don't yet know how to bundle the .cl file within the executable.
   # Therefore, copy the .cl into binary directory.
-  set (${SRCS} ${${SRCS}} "${CMAKE_BINARY_DIR}/${CL_FILE}")
+  set (${SRCS} ${${SRCS}} "${PLM_BINARY_DIR}/${CL_FILE}")
   add_custom_command (
-    OUTPUT "${CMAKE_BINARY_DIR}/${CL_FILE}"
+    OUTPUT "${PLM_BINARY_DIR}/${CL_FILE}"
     COMMAND ${CMAKE_COMMAND} "-E" "copy" 
     "${CMAKE_CURRENT_SOURCE_DIR}/${CL_FILE}" 
-    "${CMAKE_BINARY_DIR}/${CL_FILE}" 
+    "${PLM_BINARY_DIR}/${CL_FILE}" 
     DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${CL_FILE}")
   # Need in the testing directory too :(
   set (${SRCS} ${${SRCS}} "${PLM_BUILD_TESTING_DIR}/${CL_FILE}")
diff --git a/cmake/PreventInSourceBuilds.cmake b/cmake/PreventInSourceBuilds.cmake
new file mode 100644
index 0000000..f981674
--- /dev/null
+++ b/cmake/PreventInSourceBuilds.cmake
@@ -0,0 +1,13 @@
+# This function will prevent in-source builds. Copied from ITK.
+function(AssureOutOfSourceBuilds)
+  # make sure the user doesn't play dirty with symlinks
+  get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)
+  get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH)
+
+  # disallow in-source builds
+  if("${srcdir}" STREQUAL "${bindir}")
+    message(FATAL_ERROR "Error: Plastimatch should not be built in its source directory")
+  endif()
+endfunction()
+
+AssureOutOfSourceBuilds()
diff --git a/cmake/SuperbuildOptions.cmake b/cmake/SuperbuildOptions.cmake
new file mode 100644
index 0000000..9dbb916
--- /dev/null
+++ b/cmake/SuperbuildOptions.cmake
@@ -0,0 +1,37 @@
+##-----------------------------------------------------------------------------
+##  See COPYRIGHT.TXT and LICENSE.TXT for copyright and license information
+##-----------------------------------------------------------------------------
+##  These macros are used to forward variables defined in the outer build
+##  to the inner build.  The variable values cannot be a list; these
+##  don't expand properly.  
+##-----------------------------------------------------------------------------
+# macro: sb_variable
+# Add a variable to the list of superbuild variables that are passed to the
+# inner build
+macro (sb_variable _var)
+  list (APPEND sb_cmake_vars ${_var})
+endmacro ()
+
+# macro: sb_set
+# Set a variable and add it to the list of superbuild variables
+# that are passed to the inner build
+macro (sb_set _var)
+  set (${_var} ${ARGN})
+  list (APPEND sb_cmake_vars ${_var})
+endmacro ()
+
+# macro: sb_option
+# Create an option in the cmake-gui, and mark the variable as a superbuild
+# variable to be passed to the inner build
+macro (sb_option _var _desc _defval)
+  option (${_var} ${_desc} ${_defval})
+  list (APPEND sb_cmake_vars ${_var})
+endmacro ()
+
+# macro: sb_option_enum
+# Create an enum option in the cmake-gui, and mark the variable as a 
+# superbuild variable to be passed to the inner build
+macro (sb_option_enum _var _desc _defval)
+  option_enum (${_var} ${_desc} ${_defval} ${ARGN})
+  list (APPEND sb_cmake_vars ${_var})
+endmacro ()
diff --git a/doc/NOTES.TXT b/doc/NOTES.TXT
index f0cfe02..cdb7476 100755
--- a/doc/NOTES.TXT
+++ b/doc/NOTES.TXT
@@ -1,7 +1,14 @@
 ******************************************************************************
-Good ideas
+Superbuild test configurations
+
+Standard build: local ITK, local DCMTK
+Standard build: system ITK, system DCMTK
+Superbuild: system ITK, system DCMTK
+Superbuild: download ITK, download DCMTK
+
+******************************************************************************
+Good ideas from Elastix
 
-Elastix:
 A good set of random sampling options
 Schedule of grid spacing allows multiple sub-stages
 Parameter file overwrites
diff --git a/doc/man/drr.1 b/doc/man/drr.1
index c0f44f5..e2f4703 100644
--- a/doc/man/drr.1
+++ b/doc/man/drr.1
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "DRR" "1" "October 11, 2017" "Plastimatch 1.6.6" "Plastimatch"
+.TH "DRR" "1" "Dec 18, 2017" "Plastimatch 1.7.0" "Plastimatch"
 .SH NAME
 drr \- create a digitally reconstructed radiograph
 .
diff --git a/doc/man/fdk.1 b/doc/man/fdk.1
index e3c8515..f9cd2dc 100644
--- a/doc/man/fdk.1
+++ b/doc/man/fdk.1
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "FDK" "1" "October 11, 2017" "Plastimatch 1.6.6" "Plastimatch"
+.TH "FDK" "1" "Dec 18, 2017" "Plastimatch 1.7.0" "Plastimatch"
 .SH NAME
 fdk \- cone-beam reconstruction from projections using the FDK algorithm
 .
@@ -64,15 +64,15 @@ Options:
 .UNINDENT
 .sp
 The usage of the fdk program is best understood by following along
-with the tutorials: \fIfdk_tutorial_i\fP and \fIfdk_tutorial_ii\fP\&.
+with the tutorials: fdk_tutorial_i and fdk_tutorial_ii\&.
 .SH INPUT FILES
 .sp
 Three different formats of input files are supported.  These are:
 .INDENT 0.0
 .IP \(bu 2
-Pfm format image files with geomtry txt files
+Pfm format image files with geometry txt files
 .IP \(bu 2
-Raw format image files with geomtry txt files
+Raw format image files with geometry txt files
 .IP \(bu 2
 Varian hnd files
 .UNINDENT
@@ -87,7 +87,7 @@ with the .txt extension.  For example, if you want to use image_0000.pfm
 in a reconstruction, you should supply another file image_0000.txt
 which contains the geometry.
 A brief description of the geometry file format is given in
-\fIproj_mat_file_format\fP\&.
+proj_mat_file_format\&.
 .sp
 The sequence of files should be stored with the pattern:
 .INDENT 0.0
diff --git a/doc/man/landmark_warp.1 b/doc/man/landmark_warp.1
index 2f65948..aae4cc7 100644
--- a/doc/man/landmark_warp.1
+++ b/doc/man/landmark_warp.1
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "LANDMARK_WARP" "1" "October 11, 2017" "Plastimatch 1.6.6" "Plastimatch"
+.TH "LANDMARK_WARP" "1" "Dec 18, 2017" "Plastimatch 1.7.0" "Plastimatch"
 .SH NAME
 landmark_warp \- warp an image using point landmarks
 .
diff --git a/doc/man/plastimatch.1 b/doc/man/plastimatch.1
index 8aefd7d..361bd79 100644
--- a/doc/man/plastimatch.1
+++ b/doc/man/plastimatch.1
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "PLASTIMATCH" "1" "October 11, 2017" "Plastimatch 1.6.6" "Plastimatch"
+.TH "PLASTIMATCH" "1" "Dec 18, 2017" "Plastimatch 1.7.0" "Plastimatch"
 .SH NAME
 plastimatch \- register, convert, warp, or manipulate images
 .
@@ -47,7 +47,7 @@ without any additional command line arguments:
 .nf
 .ft C
 $ plastimatch
-plastimatch version 1.6.6
+plastimatch version 1.7.0
 Usage: plastimatch command [options]
 Commands:
  add           adjust        average       bbox          boundary
@@ -1134,8 +1134,8 @@ Prior to running the mabs command, you must create a configuration
 file, and you must arrange your training data into the proper
 directory format.
 For a complete description of the command file syntax and
-usage examples, please refer to the \fImabs_guidebook\fP
-and the \fIsegmentation_command_file_reference\fP\&.
+usage examples, please refer to the mabs_guidebook
+and the segmentation_command_file_reference\&.
 .SH PLASTIMATCH MASK
 .sp
 The \fImask\fP command is used to fill an image region with a constant
@@ -1289,7 +1289,7 @@ and each stage begins with a line containing the string "[STAGE]".
 The global section is used to set input files, output files, and
 global parameters, while the each stage section defines a sequential
 stage of processing.  For a complete description of the command file
-syntax, please refer to the \fIregistration_command_file_reference\fP\&.
+syntax, please refer to the registration_command_file_reference\&.
 .SS Examples
 .sp
 If you want to register image_2.mha to match image_1.mha using
@@ -1369,7 +1369,7 @@ res=1 1 1
 .UNINDENT
 .UNINDENT
 .sp
-For more examples, please refer to the \fIimage_registration_guidebook\fP\&.
+For more examples, please refer to the image_registration_guidebook\&.
 .SH PLASTIMATCH RESAMPLE
 .sp
 The \fIresample\fP command can be used to change the geometry of an image.
@@ -1822,24 +1822,44 @@ The \fIthreshold\fP command creates a binary labelmap image from an
 input intensity image.
 .sp
 The command line usage is given as follows:
-.INDENT 0.0
-.INDENT 3.5
 .sp
-.nf
-.ft C
 Usage: plastimatch threshold [options]
 Options:
-   \-\-above <arg>    value above which output has value high
-   \-\-below <arg>    value below which output has value high
-   \-\-input <arg>    input directory or filename
-   \-\-output <arg>   output image
-   \-\-range <arg>    a string that forms a list of threshold ranges
-                     ofthe form "r1\-lo,r1\-hi,r2\-lo,r2\-hi,...",
-                     such thatvoxels with intensities within any
-                     of the ranges ([r1\-lo,r1\-hi], [r2\-lo,r2\-hi],
-                     ...) have output value high
-.ft P
-.fi
+.INDENT 0.0
+.INDENT 3.5
+.INDENT 0.0
+.INDENT 3.5
+.INDENT 0.0
+.TP
+.BI \-\-above \ <arg>
+value above which output has value high
+.TP
+.BI \-\-below \ <arg>
+value below which output has value high
+.UNINDENT
+.UNINDENT
+.UNINDENT
+.INDENT 0.0
+.TP
+.B \-h\fP,\fB  \-\-help
+display this help message
+\-\-input <arg>    input directory or filename
+\-\-output <arg>   output image
+\-\-range <arg>    a string that forms a list of threshold ranges of the
+.INDENT 7.0
+.INDENT 3.5
+form "r1\-lo,r1\-hi,r2\-lo,r2\-hi,...", such that voxels
+with intensities within any of the ranges
+([r1\-lo,r1\-hi], [r2\-lo,r2\-hi], ...) have output value
+high
+.UNINDENT
+.UNINDENT
+.INDENT 7.0
+.TP
+.B \-\-version
+display the program version
+.UNINDENT
+.UNINDENT
 .UNINDENT
 .UNINDENT
 .SS Example
@@ -2056,7 +2076,7 @@ plastimatch warp \e
 .SH PLASTIMATCH XF-CONVERT
 .sp
 The \fIxf\-convert\fP command converts between transform types.
-A tranform can be either a B\-spline transform, or a vector field.
+A transform can be either a B\-spline transform, or a vector field.
 There are two different kinds of B\-spline transform formats:
 the plastimatch native format, and the ITK format.
 In addition to converting the transform type, the \fIxf\-convert\fP command
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
old mode 100644
new mode 100755
index 993e2c8..50bd6c5
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -6,98 +6,11 @@
 project (src)
 
 ##-----------------------------------------------------------------------------
-##  PLASTIMATCH LIBRARIES
-##-----------------------------------------------------------------------------
-set (PLASTIMATCH_LIBS
-  plmclp
-#  plmscript
-  plmsegment
-  plmregister
-  plmreconstruct
-  plmdose
-  plmutil
-  plmbase
-  plmsys
-  ${ITK_LIBRARIES}
-  devillard
-  nkidecompress
-#  lua
-  ${MATH_LIB}
-  )
-
-if (CUDA_FOUND AND NOT PLM_USE_GPU_PLUGINS)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} plmcuda)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} plmreconstructcuda)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} plmregistercuda)
-endif ()
-
-if (DCMTK_FOUND)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${DCMTK_LIBRARIES})
-endif ()
-
-if (DLIB_LIBRARIES)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${DLIB_LIBRARIES})
-endif ()
-
-if (FFTW_FOUND)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${FFTW_LIBRARIES})
-endif ()
-
-if (KAZE_FOUND)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${KAZE_LIBRARIES})
-endif ()
-
-if (LIBDL_FOUND)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} dl)
-endif ()
-
-if (NLOPT_FOUND)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${NLOPT_LIBRARIES})
-endif ()
-
-if (OPENCL_FOUND)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} plmopencl)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${OPENCL_LIBRARIES})
-endif ()
-
-if (OPENMP_FOUND)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${OPENMP_LIBRARIES})
-endif ()
-
-if (SPECFUN_FOUND)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} specfun)
-endif ()
-
-if (QT4_FOUND)
-  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${QT_LIBRARIES})
-endif ()
-
-##-----------------------------------------------------------------------------
-##  DETERMINE LINKER FLAGS
-##-----------------------------------------------------------------------------
-set (PLASTIMATCH_LDFLAGS "${OPENMP_LDFLAGS}")
-if (PLM_USE_GPU_PLUGINS AND WIN32 AND NOT CYGWIN AND NOT MINGW)
-  set (PLASTIMATCH_LDFLAGS
- "${PLASTIMATCH_LDFLAGS} /DELAYLOAD:plmregistercuda.dll /DELAYLOAD:plmreconstructcuda.dll")
-endif ()
-
-if (PLM_CONFIG_NOMANIFEST AND WIN32)
-  set (PLASTIMATCH_LDFLAGS "${PLASTIMATCH_LDFLAGS} /MANIFEST:NO")
-endif ()
-
-##-----------------------------------------------------------------------------
 ##  Add subdirectories
 ##-----------------------------------------------------------------------------
 if (PLM_CONFIG_DEBIAN_BUILD)
-  set (PLM_CONFIG_DISABLE_ISE ON)
   set (PLM_CONFIG_DISABLE_FATM ON)
   set (PLM_CONFIG_DISABLE_MONDOSHOT ON)
-  set (PLM_CONFIG_DISABLE_REG23 ON)
-endif ()
-
-if (NOT PLM_CONFIG_DISABLE_ISE)
-  add_subdirectory (ise)
-  add_subdirectory (fatm)
 endif ()
 
 if (NOT PLM_CONFIG_DISABLE_FATM)
@@ -111,102 +24,56 @@ if (WIN32 AND NOT CYGWIN AND wxWidgets_FOUND AND DCMTK_FOUND
 endif ()
 
 if (NOT PLM_CONFIG_DISABLE_PLASTIMATCH)
-  if (NOT ITK_FOUND)
-    message (STATUS "Plastimatch will not be built (ITK not found)")
+  if (NOT ITK_FOUND OR NOT DCMTK_FOUND)
+    if (PLM_CONFIG_ENABLE_SUPERBUILD)
+      set (proj plastimatch)
+      if(CMAKE_EXTRA_GENERATOR)
+	set(gen "${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}")
+      else()
+	set(gen "${CMAKE_GENERATOR}")
+      endif()
+
+      set (sb_option_list "")
+      foreach (_var ${sb_cmake_vars})
+	list (APPEND sb_option_list "-D${_var}=${${_var}}")
+      endforeach ()
+
+      set (sb_dependencies devillard inih lbfgs nkidecompress specfun sqlite3)
+      if (NOT ITK_FOUND)
+	list (APPEND sb_dependencies ITK)
+      endif ()
+      if (NOT DCMTK_FOUND)
+	list (APPEND sb_dependencies DCMTK)
+      endif ()
+
+      ExternalProject_Add (${proj}
+	DOWNLOAD_COMMAND ""
+	INSTALL_COMMAND ""
+	SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/plastimatch"
+	BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/plastimatch"
+	CMAKE_GENERATOR ${gen}
+	CMAKE_ARGS
+	-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+	-DCMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
+	-DCMAKE_LIBRARY_OUTPUT_DIRECTORY:PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
+	-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY:PATH=${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}
+	-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
+	-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS}
+	-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
+	-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}
+	-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET}
+	-DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT}
+	-DITK_DIR:PATH=${ITK_DIR}
+	-DDCMTK_DIR:PATH=${DCMTK_DIR}
+	-DPLASTIMATCH_VERSION_STRING:STRING=${PLASTIMATCH_VERSION_STRING}
+	${sb_option_list}
+	DEPENDS
+	${sb_dependencies}
+	)
+    else ()
+      message (STATUS "Plastimatch will not be built (ITK or DCMTK not found; superbuild disabled)")
+    endif ()
   else ()
     add_subdirectory (plastimatch)
   endif ()
 endif ()
-
-set (PLM_BUILD_ORAIFUTILS 1)
-set (PLM_BUILD_REG23 1)
-if (PLM_CONFIG_DISABLE_REG23)
-  set (PLM_BUILD_ORAIFUTILS 0)
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23 
-    AND ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_LESS 2.8)
-  message (STATUS "Reg-2-3 will not be built (CMake version)")
-  set (PLM_BUILD_ORAIFUTILS 0)
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23 AND NOT ITK_FOUND)
-  message (STATUS "Reg-2-3 will not be built (ITK not found)")
-  set (PLM_BUILD_ORAIFUTILS 0)
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23 
-    AND ${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR} VERSION_LESS 3.20)
-  message (STATUS "Reg-2-3 will not be built (wrong ITK version)")
-  set (PLM_BUILD_ORAIFUTILS 0)
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23 
-    AND NOT ${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR} VERSION_LESS 4.0)
-  message (STATUS "Reg-2-3 will not be built (wrong ITK version)")
-  set (PLM_BUILD_ORAIFUTILS 0)
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23 AND ITK_USE_REVIEW_STATISTICS)
-  message (STATUS 
-    "Reg-2-3 will not be built (ITK compiled with review statistics)")
-  set (PLM_BUILD_ORAIFUTILS 0)
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23 AND NOT VTK_FOUND)
-  message (STATUS "Reg-2-3 will not be built (VTK not found)")
-  set (PLM_BUILD_ORAIFUTILS 0) ## REMOVE WHEN DONE
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23 AND NOT VTK_USE_QT)
-  message (STATUS "Reg-2-3 will not be built (VTK not built with QT)")
-  set (PLM_BUILD_ORAIFUTILS 0) ## REMOVE WHEN DONE
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23
-    AND ${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION} VERSION_GREATER 5.10)
-  message (STATUS "Reg-2-3 will not be built (wrong VTK version)")
-  set (PLM_BUILD_ORAIFUTILS 0) ## REMOVE WHEN DONE
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23
-    AND ${VTK_MAJOR_VERSION}.${VTK_MINOR_VERSION} VERSION_LESS 5.6)
-  message (STATUS "Reg-2-3 will not be built (wrong VTK version)")
-  set (PLM_BUILD_ORAIFUTILS 0) ## REMOVE WHEN DONE
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23 AND NOT QT_FOUND)
-  message (STATUS "Reg-2-3 will not be built (QT not found)")
-  set (PLM_BUILD_ORAIFUTILS 0) ## REMOVE WHEN DONE
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23 
-    AND ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR} VERSION_LESS 4.6)
-  message (STATUS "Reg-2-3 will not be built (wrong QT version)")
-  set (PLM_BUILD_ORAIFUTILS 0) ## REMOVE WHEN DONE
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23 
-    AND ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR} VERSION_GREATER 4.8)
-  message (STATUS "Reg-2-3 will not be built (wrong QT version)")
-  set (PLM_BUILD_ORAIFUTILS 0) ## REMOVE WHEN DONE
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23 AND NOT QT_QMAKE_EXECUTABLE)
-  message (STATUS "Reg-2-3 will not be built (no qmake executable)")
-  set (PLM_BUILD_ORAIFUTILS 0) ## REMOVE WHEN DONE
-  set (PLM_BUILD_REG23 0)
-endif ()
-if (PLM_BUILD_REG23 AND NOT QT_QTWEBKIT_FOUND)
-  message (STATUS "Reg-2-3 will not be built (QtWebKit not found)")
-  set (PLM_BUILD_ORAIFUTILS 0) ## REMOVE WHEN DONE
-  set (PLM_BUILD_REG23 0)
-endif ()
-
-if (PLM_BUILD_ORAIFUTILS)
-  add_subdirectory (oraifutils)
-endif ()
-if (PLM_BUILD_REG23)
-  add_subdirectory (reg-2-3)
-endif ()
-
diff --git a/src/plastimatch/CHANGELOG.TXT b/src/plastimatch/CHANGELOG.TXT
index cd3279f..7e37fe7 100644
--- a/src/plastimatch/CHANGELOG.TXT
+++ b/src/plastimatch/CHANGELOG.TXT
@@ -1,3 +1,17 @@
+Version 1.7.0 (tag v1.7.0)
+Mon Dec 18 17:38:55 EST 2017
+* Remove reg-2-3 and ise from distribution
+
+Version 1.6.7 (tag v1.6.7)
+Mon Dec 18 17:06:14 EST 2017
+* Implement automatic download and build of ITK, DCMTK
+* Prevent in-source builds
+* Improve library support: DCTMK 3.6.2, ITK 3.20, Windows OpenMP, Qt5, CUDA 8
+* DICOM Series UIDs may be specified on command line
+* Fix a few MABS command file bugs
+* Allow loading of 2D images
+* Last version including reg-2-3 and ise
+
 Version 1.6.6 (tag v1.6.6)
 Wed Oct 11 10:54:34 EDT 2017
 * Support for multi-metric registration
diff --git a/src/plastimatch/CMakeLists.txt b/src/plastimatch/CMakeLists.txt
index 4f2a706..5114746 100644
--- a/src/plastimatch/CMakeLists.txt
+++ b/src/plastimatch/CMakeLists.txt
@@ -4,52 +4,210 @@
 ##  See COPYRIGHT.TXT and LICENSE.TXT for copyright and license information
 ##-----------------------------------------------------------------------------
 project (src_plastimatch)
+cmake_minimum_required (VERSION 2.8.12)
 
 ##-----------------------------------------------------------------------------
-##  Local options
+##  CMake include files
 ##-----------------------------------------------------------------------------
+set (CMAKE_MODULE_PATH "${PLM_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
+include (PlmMacros)
 
-# Plastimatch software configuration options
-option (PLM_CONFIG_CLANG_COMPLETE
-    "Generate .clang_complete for hipster Vim-ers" OFF)
-option (PLM_CONFIG_DISABLE_VISCOUS
-    "Disable experimental viscous fluid registration algorithm" ON)
-option (PLM_CONFIG_ENABLE_PLASTIMATCH_QT
-    "Enable experimental plastimatch_qt executable" OFF)
-option (PLM_CONFIG_PREFER_PATCHED_ITK
-    "Prefer to use the patched version of certain ITK files" ON)
-option (PLM_CONFIG_VOL_LIST
-    "Native support for volumes with irregular slice thicknesses" OFF)
+##-----------------------------------------------------------------------------
+##  Processor and OS characteristics
+##    32-bit or 64-bit machine
+##    Endian-ness
+##    Machine precision
+##    Processor type
+##-----------------------------------------------------------------------------
+include (CheckCharSign)
+include (CheckEpsilon)
+include (CheckTypeSize)
+include (TestBigEndian)
+
+check_type_size ("unsigned int" CMAKE_SIZEOF_UINT)
+check_type_size ("unsigned long" CMAKE_SIZEOF_ULONG)
+check_type_size ("size_t" CMAKE_SIZEOF_SIZE_T)
+if (NOT APPLE)
+  if (CMAKE_SIZEOF_VOID_P EQUAL 4)
+    set (MACHINE_IS_32_BIT TRUE)
+    set (MACHINE_IS_64_BIT FALSE)
+    message (STATUS "Machine is 32-bit")
+  else ()
+    set (MACHINE_IS_32_BIT FALSE)
+    set (MACHINE_IS_64_BIT TRUE)
+    message (STATUS "Machine is 64-bit")
+  endif ()
+endif ()
+
+test_big_endian (PLM_BIG_ENDIAN)
+check_epsilon (MACHINE_EPS)
+check_char_sign (CHAR_SIGN)
+message (STATUS "Checking host processor: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
+message (STATUS "Checking target processor: ${CMAKE_SYSTEM_PROCESSOR}")
+message (STATUS "Checking epsilon: ${MACHINE_EPS}")
+message (STATUS "Checking sign of char: ${CHAR_SIGN}")
+
+include (CheckIncludeFiles)
+check_include_files ("stdint.h" HAVE_STDINT_H)
+check_include_files ("sys/stat.h" HAVE_SYS_STAT_H)
+
+##-----------------------------------------------------------------------------
+##  Figure out if we should use gdcm or dcmtk
+##-----------------------------------------------------------------------------
+if (DCMTK_DIR AND EXISTS "${DCMTK_DIR}/DCMTKConfig.cmake")
+  find_package (DCMTK NO_MODULE)
+else ()
+  find_package (DCMTK_legacy)
+endif ()
 
-# Plastimatch legacy options
-option (PLM_CONFIG_LEGACY_BSPLINE_EXTEND
-  "Use legacy code for extending b-spline domain" OFF)
-option (PLM_CONFIG_LEGACY_BSPLINE_XFORM_IO
-  "Use legacy code for reading and writing b-spline xform files" OFF)
-option (PLM_CONFIG_LEGACY_MI_METRIC
-  "For ITK metrics, the legacy implementation of the mi metric is Viola-Wells to Mattes" OFF)
-option (PLM_CONFIG_LEGACY_PROJ_GEO
-  "Use legacy method for specifying projection geometry" ON)
+set (PLM_DCM_USE_DCMTK 0)
+set (PLM_DCM_USE_GDCM1 0)
+set (PLM_DCM_USE_GDCM2 0)
+
+if (DCMTK_FOUND)
+  set (PLM_DCM_USE_DCMTK 1)
+elseif (GDCM_VERSION_2)
+  set (PLM_DCM_USE_GDCM2 1)
+else ()
+  set (PLM_DCM_USE_GDCM1 1)
+endif ()
 
 ##-----------------------------------------------------------------------------
 ##  Give a warning for obsolete dicom libraries
 ##-----------------------------------------------------------------------------
 # If the user only has gdcm 2.x, give a warning
 if (PLM_DCM_USE_GDCM2)
-    message (WARNING "Plastimatch is being built with GDCM 2.X.  DICOM-RT functions are disabled.")
+  message (WARNING "Plastimatch is being built with GDCM 2.X.  DICOM-RT functions are disabled.")
 elseif (PLM_DCM_USE_GDCM1)
-    message (WARNING "Plastimatch is being built with GDCM 1.X.  Certain features of DICOM-RT are disabled.")
+  message (WARNING "Plastimatch is being built with GDCM 1.X.  Certain features of DICOM-RT are disabled.")
+endif ()
+
+##-----------------------------------------------------------------------------
+##  dlib
+##-----------------------------------------------------------------------------
+if (PLM_PREFER_SYSTEM_DLIB)
+  # Use this version if you want to use the internal cmake find. 
+  # The internal version has issue finding the correct BLAS library
+  # for Debian, so we prefer Debian version.
+  # find_package (Dlib)
+  
+  # However, the Debian cmake find is broken.  Its breakage can
+  # be worked around by setting dlib_BINARY_DIR.
+  set (dlib_BINARY_DIR 1)
+  find_package (dlib QUIET)
+endif ()
+set (DLIB_HAVE_LIBRARY FALSE)
+if (dlib_FOUND)
+  set (DLIB_INCLUDE_DIR ${dlib_INCLUDE_DIR})
+  set (DLIB_LIBRARIES ${dlib_LIBRARIES})
+  set (DLIB_FOUND TRUE)
+  if (DLIB_LIBRARIES)
+    set (DLIB_HAVE_LIBRARY TRUE)
+  endif ()
+else ()
+  set (DLIB_INCLUDE_DIR "${PLM_SOURCE_DIR}/libs/dlib-19.1")
+  set (DLIB_LIBRARIES "")
 endif ()
 
+##-----------------------------------------------------------------------------
+##  ransac
+##-----------------------------------------------------------------------------
+set (RANSAC_INCLUDE_DIRS 
+  "${PLM_SOURCE_DIR}/libs/ransac" 
+  "${PLM_SOURCE_DIR}/libs/ransac/Common")
 
 ##-----------------------------------------------------------------------------
-##  Figure out if we should patch itk
+##  ITK
 ##-----------------------------------------------------------------------------
 set (PLM_CONFIG_USE_PATCHED_ITK 0)
-if (${ITK_VERSION} VERSION_LESS "4.1" AND PLM_CONFIG_PREFER_PATCHED_ITK)
-  set (PLM_CONFIG_USE_PATCHED_ITK 1)
+find_package (ITK REQUIRED)
+include (HandleITK)
+
+##-----------------------------------------------------------------------------
+##  Hack for superbuild
+##-----------------------------------------------------------------------------
+link_directories (${PLM_BINARY_DIR})
+
+##-----------------------------------------------------------------------------
+##  Libraries
+##-----------------------------------------------------------------------------
+set (PLASTIMATCH_LIBS
+  plmclp
+#  plmscript
+  plmsegment
+  plmregister
+  plmreconstruct
+  plmdose
+  plmutil
+  plmbase
+  plmsys
+  ${ITK_LIBRARIES}
+  devillard
+  nkidecompress
+#  lua
+  ${MATH_LIB}
+  )
+
+if (CUDA_FOUND AND NOT PLM_USE_GPU_PLUGINS)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} plmcuda)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} plmreconstructcuda)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} plmregistercuda)
 endif ()
 
+if (DCMTK_FOUND)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${DCMTK_LIBRARIES})
+endif ()
+
+if (DLIB_LIBRARIES)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${DLIB_LIBRARIES})
+endif ()
+
+if (FFTW_FOUND)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${FFTW_LIBRARIES})
+endif ()
+
+if (KAZE_FOUND)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${KAZE_LIBRARIES})
+endif ()
+
+if (LIBDL_FOUND)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} dl)
+endif ()
+
+if (NLOPT_FOUND)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${NLOPT_LIBRARIES})
+endif ()
+
+if (OPENCL_FOUND)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} plmopencl)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${OPENCL_LIBRARIES})
+endif ()
+
+if (OPENMP_FOUND)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${OPENMP_LIBRARIES})
+endif ()
+
+if (SPECFUN_FOUND)
+  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} specfun)
+endif ()
+
+### Let QT applications add this themselves
+#if (QT4_FOUND)
+#  set (PLASTIMATCH_LIBS ${PLASTIMATCH_LIBS} ${QT_LIBRARIES})
+#endif ()
+
+##-----------------------------------------------------------------------------
+##  Linker flags
+##-----------------------------------------------------------------------------
+set (PLASTIMATCH_LDFLAGS "${OPENMP_LDFLAGS}")
+if (PLM_USE_GPU_PLUGINS AND WIN32 AND NOT CYGWIN AND NOT MINGW)
+  set (PLASTIMATCH_LDFLAGS
+ "${PLASTIMATCH_LDFLAGS} /DELAYLOAD:plmregistercuda.dll /DELAYLOAD:plmreconstructcuda.dll")
+endif ()
+
+if (PLM_CONFIG_NOMANIFEST AND WIN32)
+  set (PLASTIMATCH_LDFLAGS "${PLASTIMATCH_LDFLAGS} /MANIFEST:NO")
+endif ()
 
 ##-----------------------------------------------------------------------------
 ##  Include directories
@@ -75,11 +233,12 @@ include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/sys)
 include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/util)
 
 include_directories (BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-include_directories (AFTER ${CMAKE_SOURCE_DIR}/libs/demons_itk_insight)
-include_directories (AFTER ${CMAKE_SOURCE_DIR}/libs/demons_itk_insight/DiffeomorphicDemons)
-include_directories (AFTER ${CMAKE_SOURCE_DIR}/libs/demons_itk_insight/FastSymmetricForces)
-include_directories (AFTER ${CMAKE_SOURCE_DIR}/libs/demons_itk_insight/LOGDomainDemons)
-include_directories (AFTER ${CMAKE_SOURCE_DIR}/libs/nSIFT)
+include_directories (AFTER ${ITK_INCLUDE_DIRS})
+include_directories (AFTER ${PLM_SOURCE_DIR}/libs/demons_itk_insight)
+include_directories (AFTER ${PLM_SOURCE_DIR}/libs/demons_itk_insight/DiffeomorphicDemons)
+include_directories (AFTER ${PLM_SOURCE_DIR}/libs/demons_itk_insight/FastSymmetricForces)
+include_directories (AFTER ${PLM_SOURCE_DIR}/libs/demons_itk_insight/LOGDomainDemons)
+include_directories (AFTER ${PLM_SOURCE_DIR}/libs/nSIFT)
 include_directories (AFTER ${DLIB_INCLUDE_DIR})
 include_directories (AFTER ${LIBLBFGS_INCLUDE_DIR})
 include_directories (AFTER ${MSINTTYPES_INCLUDE_DIR})
@@ -93,7 +252,7 @@ if (CUDA_FOUND)
   include_directories (AFTER ${CUDA_INCLUDE_DIRS})
 endif ()
 if (DCMTK_FOUND)
-  include_directories (AFTER ${DCMTK_INCLUDE_DIR})
+  include_directories (AFTER ${DCMTK_INCLUDE_DIRS})
 endif ()
 if (FFTW_FOUND)
   include_directories (BEFORE ${FFTW_INCLUDE_DIR})
@@ -115,14 +274,14 @@ if (PANTHEIOS_FOUND)
   include_directories (AFTER ${STLSOFT_INCLUDE_DIR})
   include_directories (AFTER ${PANTHEIOS_INCLUDE_DIR})
 endif ()
-if (QT4_FOUND)
-  if (QT_QTGUI_FOUND)
-    include_directories (AFTER ${QT_QTGUI_INCLUDE_DIR})
-  endif ()
-  if (QT_QTSQL_FOUND)
-    include_directories (AFTER ${QT_QTSQL_INCLUDE_DIR})
-  endif ()
-endif ()
+#if (QT4_FOUND)
+#  if (QT_QTGUI_FOUND)
+#    include_directories (AFTER ${QT_QTGUI_INCLUDE_DIR})
+#  endif ()
+#  if (QT_QTSQL_FOUND)
+#    include_directories (AFTER ${QT_QTSQL_INCLUDE_DIR})
+#  endif ()
+#endif ()
 if (RAPIDJSON_FOUND)
     include_directories (AFTER ${RAPIDJSON_INCLUDE_DIR})
 endif ()
@@ -137,21 +296,21 @@ endif ()
 ##  CONFIGURE INCLUDE FILES
 ##-----------------------------------------------------------------------------
 configure_file (${CMAKE_CURRENT_SOURCE_DIR}/sys/plm_config.h.in
-  ${PLM_BUILD_ROOT}/plm_config.h)
+  ${CMAKE_BINARY_DIR}/plm_config.h)
 configure_file (${CMAKE_CURRENT_SOURCE_DIR}/sys/plm_version.h.in
-  ${PLM_BUILD_ROOT}/plm_version.h)
+  ${CMAKE_BINARY_DIR}/plm_version.h)
 
 ##-----------------------------------------------------------------------------
 ## Option to generate .clang_complete for hip Vim users using clang_complete
 ##-----------------------------------------------------------------------------
 if (PLM_CONFIG_CLANG_COMPLETE)
-    get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
-    set (file_clang_complete "${PLM_SRC_ROOT}/src/plastimatch/.clang_complete")
-    foreach (arg ${inc_dirs})
-        set (inc_args "${inc_args} -I${arg}\n")
-    endforeach ()
-    file (WRITE "${file_clang_complete}" "${inc_args}")
-    message (STATUS "Generated ${file_clang_complete}")
+  get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
+  set (file_clang_complete "${CMAKE_SOURCE_DIR}/src/plastimatch/.clang_complete")
+  foreach (arg ${inc_dirs})
+    set (inc_args "${inc_args} -I${arg}\n")
+  endforeach ()
+  file (WRITE "${file_clang_complete}" "${inc_args}")
+  message (STATUS "Generated ${file_clang_complete}")
 endif ()
 
 ##-----------------------------------------------------------------------------
@@ -184,6 +343,31 @@ if (PLMLIB_CONFIG_ENABLE_REGISTER OR PLMLIB_CONFIG_ENABLE_RECONSTRUCT)
   set (PLMLIB_CONFIG_ENABLE_OPENCL true)
 endif ()
 
+
+##-----------------------------------------------------------------------------
+##  SETUP IMPORTANT LOCATIONS
+##-----------------------------------------------------------------------------
+# Offer the user the choice of overriding the installation directories
+set (PLM_INSTALL_LIB_DIR lib CACHE PATH 
+  "Installation directory for libraries")
+set (PLM_INSTALL_BIN_DIR bin CACHE PATH 
+  "Installation directory for executables")
+set (PLM_INSTALL_INCLUDE_DIR include/plastimatch CACHE PATH
+  "Installation directory for header files")
+if (WIN32 AND NOT CYGWIN)
+  set (DEF_INSTALL_CMAKE_DIR CMake)
+else()
+  set (DEF_INSTALL_CMAKE_DIR lib/cmake/plastimatch)
+endif()
+set (PLM_INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH
+  "Installation directory for CMake files")
+mark_as_advanced (
+  PLM_INSTALL_LIB_DIR 
+  PLM_INSTALL_BIN_DIR 
+  PLM_INSTALL_INCLUDE_DIR 
+  PLM_INSTALL_CMAKE_DIR)
+
+
 ## Specify which include directories are needed when
 ## compiling code that links to the libraries
 set (PLASTIMATCH_INCLUDE_DIRECTORIES "")
@@ -332,13 +516,14 @@ if (PLM_PACKAGE_LEGACY_CMAKE_CONFIG)
     )
 
 else (PLM_PACKAGE_LEGACY_CMAKE_CONFIG)
-
+  ## GCS: This is not working
+  #if (COMMENTOUT)
   include (CMakePackageConfigHelpers)
 
   # Make the version file
   write_basic_package_version_file (
     "${CMAKE_CURRENT_BINARY_DIR}/PlastimatchConfigVersion.cmake"
-    VERSION ${PLM_BASIC_VERSION_STRING}
+    VERSION ${PLASTIMATCH_VERSION_STRING}
     COMPATIBILITY AnyNewerVersion
     )
 
@@ -365,21 +550,21 @@ else (PLM_PACKAGE_LEGACY_CMAKE_CONFIG)
     DESTINATION "${PLM_INSTALL_CMAKE_DIR}"
     COMPONENT Devel
     )
-
+  #endif (COMMENTOUT)
 endif (PLM_PACKAGE_LEGACY_CMAKE_CONFIG)
 
 ##-----------------------------------------------------------------------------
 ##  DOXYGEN
 ##-----------------------------------------------------------------------------
 if (DOXYGEN_FOUND)
-  file (MAKE_DIRECTORY "${PLM_BUILD_ROOT}/doc")
+  file (MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/doc")
   configure_file (
     ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in 
     ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 
     @ONLY)
   add_custom_target (doc
     ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
-    WORKING_DIRECTORY "${PLM_BUILD_ROOT}/doc"
+    WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/doc"
     COMMENT "Generating API documentation with Doxygen" VERBATIM
     )
 endif ()
diff --git a/src/plastimatch/base/CMakeLists.txt b/src/plastimatch/base/CMakeLists.txt
index d5149e8..d39824d 100755
--- a/src/plastimatch/base/CMakeLists.txt
+++ b/src/plastimatch/base/CMakeLists.txt
@@ -5,7 +5,7 @@ project (src_plastimatch_base)
 
 configure_file (
     ${CMAKE_CURRENT_SOURCE_DIR}/plmbase_config.h.in
-    ${PLM_BUILD_ROOT}/plmbase_config.h
+    ${CMAKE_BINARY_DIR}/plmbase_config.h
 )
 
 include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/src/plastimatch/base/dcmtk_image.cxx b/src/plastimatch/base/dcmtk_image.cxx
index 9cc64d9..f61db7a 100644
--- a/src/plastimatch/base/dcmtk_image.cxx
+++ b/src/plastimatch/base/dcmtk_image.cxx
@@ -601,6 +601,13 @@ Dcmtk_rt_study::save_image (
     d_ptr->rt_study_metadata->set_image_header (pih);
 
     /* Find slope / offset on a per-volume basis */
+    const Rt_study_metadata::Pointer& rsm = d_ptr->rt_study_metadata;
+    const Metadata::Pointer& image_metadata = rsm->get_image_metadata ();
+    const std::string& meta_intercept
+        = image_metadata->get_metadata (DCM_RescaleIntercept);
+    const std::string& meta_slope
+        = image_metadata->get_metadata (DCM_RescaleSlope);
+    
     float vol_min = FLT_MAX;
     float vol_max = - FLT_MAX;
     float *img = (float*) dsd.vol->img;
@@ -622,8 +629,21 @@ Dcmtk_rt_study::save_image (
          floating point numbers
        - map integers to integers
     */
-    dsd.intercept = floorf (vol_min);
-    if (all_integers) {
+    if (meta_intercept != "") {
+        int rc = sscanf (meta_intercept.c_str(), "%f", &dsd.intercept);
+        if (rc != 1) {
+            dsd.intercept = floorf (vol_min);
+        }
+    } else {
+        dsd.intercept = floorf (vol_min);
+    }
+    if (meta_slope != "") {
+        int rc = sscanf (meta_slope.c_str(), "%f", &dsd.slope);
+        if (rc != 1) {
+            dsd.slope = 1;
+        }
+    }
+    else if (all_integers) {
         dsd.slope = 1;
     }
     else {
diff --git a/src/plastimatch/base/dcmtk_rt_study.cxx b/src/plastimatch/base/dcmtk_rt_study.cxx
index e4200c3..94fa03d 100644
--- a/src/plastimatch/base/dcmtk_rt_study.cxx
+++ b/src/plastimatch/base/dcmtk_rt_study.cxx
@@ -197,12 +197,6 @@ Dcmtk_rt_study::load (const char *dicom_path)
 void 
 Dcmtk_rt_study::save (const char *dicom_dir)
 {
-    /* GCS FIX: If we're writing an image, we always want new metadata;
-       but this should probably be handled by somewhere else in the 
-       code. 
-       GCS FIX MORE: Slicer-RT retains the option to set the study UID.
-       There is, I think (?!), no need to regenerate those at this time.
-    */
     if (d_ptr->img) {
         d_ptr->rt_study_metadata->generate_new_series_uids ();
     }
diff --git a/src/plastimatch/base/parameter_parser.cxx b/src/plastimatch/base/parameter_parser.cxx
index 4097e95..ecf507a 100644
--- a/src/plastimatch/base/parameter_parser.cxx
+++ b/src/plastimatch/base/parameter_parser.cxx
@@ -18,6 +18,7 @@
 
 Parameter_parser::Parameter_parser () {
     key_regularization = true;
+    empty_values_allowed = false;
     default_index = "";
 }
 
@@ -70,7 +71,7 @@ Parameter_parser::parse_config_string (
         /* Process "key=value" */
         std::string key;
         std::string val;
-        if (!split_key_val (buf, key, val)) {
+        if (!split_key_val (buf, key, val) && !this->empty_values_allowed) {
             lprintf ("Parse error: %s\n", buf_ori.c_str());
             return PLM_ERROR;
         }
@@ -124,6 +125,14 @@ Parameter_parser::enable_key_regularization (
 }
 
 void 
+Parameter_parser::allow_empty_values (
+    bool enable
+)
+{
+    this->empty_values_allowed = enable;
+}
+
+void 
 Parameter_parser::set_default_index (
     std::string& default_index)
 {
diff --git a/src/plastimatch/base/parameter_parser.h b/src/plastimatch/base/parameter_parser.h
index 5725abe..6e63807 100644
--- a/src/plastimatch/base/parameter_parser.h
+++ b/src/plastimatch/base/parameter_parser.h
@@ -17,6 +17,7 @@ public:
     Parameter_parser ();
 public:
     bool key_regularization;
+    bool empty_values_allowed;
     std::string default_index;
 public:
     /* Callbacks */
@@ -30,12 +31,21 @@ public:
         const std::string& index, 
         const std::string& val) = 0;
 
-    /* Pass in "true" to enable key regularization, or "false" to 
-       disable it.   Default is "true". */
+    /*! \brief Key regularization convert the key field to lowercase and 
+      changes hyphens to underscores.  Only the key is modified. 
+      Pass in "true" to enable key regularization, or "false" to 
+      disable it.   Default is "true". */
     void enable_key_regularization (
         bool enable
     );
 
+    /*! \brief If a key does not have an equal sign, it will be 
+      considered a syntax error unless empty values are allowed.
+    */
+    void allow_empty_values (
+        bool enable
+    );
+
     /*! \brief Choose what index is passed to set_key_value() 
       when no index is found in the file.  Default is "". */
     void set_default_index (std::string& default_index);
diff --git a/src/plastimatch/base/plm_image.cxx b/src/plastimatch/base/plm_image.cxx
index ee5be1a..42eefe8 100644
--- a/src/plastimatch/base/plm_image.cxx
+++ b/src/plastimatch/base/plm_image.cxx
@@ -300,6 +300,14 @@ Plm_image::load_native (const char* fname)
     itk_image_get_props (fname, &num_dimensions, &pixel_type, 
 	&component_type, &num_components);
 
+    /* Handle RGB images as a special case */
+    if (pixel_type == itk::ImageIOBase::RGB) {
+	this->m_itk_uchar = itk_image_load_uchar (fname, 0);
+	this->m_original_type = PLM_IMG_TYPE_ITK_UCHAR;
+	this->m_type = PLM_IMG_TYPE_ITK_UCHAR;
+	return true;
+    }
+
     /* Handle ss_image as a special case */
     if (num_components > 1 && component_type == itk::ImageIOBase::UCHAR) {
 	this->m_itk_uchar_vec = itk_image_load_uchar_vec (fname);
diff --git a/src/plastimatch/base/rpl_volume_lut.cxx b/src/plastimatch/base/rpl_volume_lut.cxx
index 3258843..317f16d 100755
--- a/src/plastimatch/base/rpl_volume_lut.cxx
+++ b/src/plastimatch/base/rpl_volume_lut.cxx
@@ -56,14 +56,14 @@ Rpl_volume_lut::~Rpl_volume_lut ()
     delete d_ptr;
 }
 
-void 
+void
 Rpl_volume_lut::set_lut_entry (
-    const Ray_data* ray_data, 
-    plm_long vox_idx, 
-    const float *vox_ray, 
-    plm_long ap_idx, 
-    float li_frac, 
-    float step_length, 
+    const Ray_data* ray_data,
+    plm_long vox_idx,
+    const float *vox_ray,
+    plm_long ap_idx,
+    float li_frac,
+    float step_length,
     int lut_entry_idx
 )
 {
@@ -73,7 +73,7 @@ Rpl_volume_lut::set_lut_entry (
     }
 
     // Project voxel vector onto unit vector of aperture ray
-    // This assumes that 
+    // This assumes that
     // d_ptr->rvrts == RAY_TRACE_START_AT_RAY_VOLUME_INTERSECTION
     // We omit the check for speed.
     const double *ap_ray = ray_data[ap_idx].ray;
@@ -89,7 +89,7 @@ Rpl_volume_lut::set_lut_entry (
     if (steps_f >= d_ptr->rv->get_num_steps()) {
         return;
     }
-    
+
     // Compute lut entries
     const Aperture::Pointer ap = d_ptr->rv->get_aperture ();
     plm_long lut_idx = ap_idx + steps_f * ap->get_dim(0) * ap->get_dim(1);
@@ -104,7 +104,7 @@ Rpl_volume_lut::set_lut_entry (
     d_ptr->lut[lut_idx].weight[4+lut_entry_idx] = (1. - dist_frac) * li_frac;
 }
 
-void 
+void
 Rpl_volume_lut::build_lut ()
 {
     const Proj_volume *pv = d_ptr->rv->get_proj_volume ();
@@ -136,7 +136,7 @@ Rpl_volume_lut::build_lut ()
                 {
                     continue;
                 }
-                
+
                 /* Get vector from source to voxel */
                 float vox_ray[3];
                 vec3_sub3 (vox_ray, xyz, src);
@@ -144,19 +144,19 @@ Rpl_volume_lut::build_lut ()
                 /* Solve for interpolation fractions on aperture planes */
                 plm_long ijk_f[3];
                 float li_frac_1[3], li_frac_2[3];
-                float ap_xy_float[2] = { ap_xy[0], ap_xy[1] };
+                float ap_xy_float[2] = { static_cast<float>(ap_xy[0]), static_cast<float>(ap_xy[1]) };
                 li_2d (ijk_f, li_frac_1, li_frac_2, ap_xy_float, ap_dim);
 
-                /* Inspect four interpolant aperture pixels.  
-                   For each pixel, calculate distance to point 
+                /* Inspect four interpolant aperture pixels.
+                   For each pixel, calculate distance to point
                    on ray closest to voxel center */
                 plm_long ap_ij[2], ap_idx;
                 ap_ij[0] = ijk_f[0], ap_ij[1] = ijk_f[1];
                 ap_idx = ap_ij[0] + ap_ij[1] * ap_dim[0];
 
-                set_lut_entry (ray_data, idx, vox_ray, 
+                set_lut_entry (ray_data, idx, vox_ray,
                     ap_idx, li_frac_1[0], li_frac_2[0], 0);
-                
+
             }
         }
     }
diff --git a/src/plastimatch/base/rpl_volume_lut.h b/src/plastimatch/base/rpl_volume_lut.h
index fcc8087..5d53a10 100755
--- a/src/plastimatch/base/rpl_volume_lut.h
+++ b/src/plastimatch/base/rpl_volume_lut.h
@@ -17,9 +17,11 @@ public:
     SMART_POINTER_SUPPORT (Rpl_volume_lut);
     Rpl_volume_lut_private *d_ptr;
 public:
-    Rpl_volume_lut ();
     Rpl_volume_lut (Rpl_volume *rv, Volume *vol);
     ~Rpl_volume_lut ();
+private:
+    /* Should not be called */
+    Rpl_volume_lut ();
 public:
     void build_lut ();
 protected:
diff --git a/src/plastimatch/base/rt_study.cxx b/src/plastimatch/base/rt_study.cxx
index 3dedbdf..85c93cb 100644
--- a/src/plastimatch/base/rt_study.cxx
+++ b/src/plastimatch/base/rt_study.cxx
@@ -543,6 +543,7 @@ Rt_study::set_study_metadata (const std::vector<std::string>& metadata)
 {
     Metadata::Pointer& study_metadata = d_ptr->m_drs->get_study_metadata ();
     study_metadata->set_metadata (metadata);
+
     /* GCS FIX.  This is the wrong place for this. */
     d_ptr->m_xio_transform->set (d_ptr->m_drs->get_image_metadata());
 }
@@ -592,6 +593,18 @@ Rt_study::get_rtstruct_metadata (void)
     return d_ptr->m_drs->get_rtstruct_metadata();
 }
 
+void
+Rt_study::generate_new_study_uids ()
+{
+    d_ptr->m_drs->generate_new_study_uids ();
+}
+
+void
+Rt_study::force_ct_series_uid (const std::string& series_uid)
+{
+    d_ptr->m_drs->force_ct_series_uid (series_uid);
+}
+
 bool
 Rt_study::have_image ()
 {
diff --git a/src/plastimatch/base/rt_study.h b/src/plastimatch/base/rt_study.h
index f979bba..7319965 100644
--- a/src/plastimatch/base/rt_study.h
+++ b/src/plastimatch/base/rt_study.h
@@ -98,6 +98,10 @@ public:
     void set_rtstruct_metadata (const std::vector<std::string>& metadata);
     /*! \brief Get the rtstruct portion of Rt_study_metadata */
     Metadata::Pointer& get_rtstruct_metadata ();
+    /*! \brief Create new StudyInstanceUID and FrameOfReferenceUID for the study */
+    void generate_new_study_uids ();
+    /*! \brief Force the CT series UID to a certain value when saving */
+    void force_ct_series_uid (const std::string& series_uid);
 
     bool have_image ();
     void set_image (ShortImageType::Pointer& itk_image);
diff --git a/src/plastimatch/base/rt_study_metadata.cxx b/src/plastimatch/base/rt_study_metadata.cxx
index 093b959..c48ddb5 100644
--- a/src/plastimatch/base/rt_study_metadata.cxx
+++ b/src/plastimatch/base/rt_study_metadata.cxx
@@ -33,6 +33,7 @@ public:
     std::string rtstruct_instance_uid;
     std::string rtstruct_series_uid;
     Slice_list slice_list;
+    bool ct_series_uid_forced;
 
     Metadata::Pointer study_metadata;
     Metadata::Pointer image_metadata;
@@ -59,6 +60,7 @@ public:
         rtplan_metadata->set_parent (study_metadata);
         sro_metadata->set_parent (study_metadata);
 
+        ct_series_uid_forced = false;
         this->generate_new_study_uids ();
         this->generate_new_series_uids ();
     }
@@ -70,7 +72,9 @@ public:
     }
     void
     generate_new_series_uids () {
-        ct_series_uid = dicom_uid (PLM_UID_PREFIX);
+        if (!ct_series_uid_forced) {
+            ct_series_uid = dicom_uid (PLM_UID_PREFIX);
+        }
         dose_instance_uid = dicom_uid (PLM_UID_PREFIX);
         dose_series_uid = dicom_uid (PLM_UID_PREFIX);
         plan_instance_uid = dicom_uid (PLM_UID_PREFIX);
@@ -116,6 +120,14 @@ Rt_study_metadata::set_ct_series_uid (const char* uid)
     d_ptr->ct_series_uid = uid;
 }
 
+void
+Rt_study_metadata::force_ct_series_uid (const std::string& uid)
+{
+    if (uid == "") return;
+    d_ptr->ct_series_uid = uid;
+    d_ptr->ct_series_uid_forced = true;
+}
+
 const char*
 Rt_study_metadata::get_ct_series_description () const
 {
diff --git a/src/plastimatch/base/rt_study_metadata.h b/src/plastimatch/base/rt_study_metadata.h
index 77e0615..1ddfd7a 100644
--- a/src/plastimatch/base/rt_study_metadata.h
+++ b/src/plastimatch/base/rt_study_metadata.h
@@ -38,6 +38,7 @@ public:
 public:
     const char* get_ct_series_uid () const;
     void set_ct_series_uid (const char* uid);
+    void force_ct_series_uid (const std::string& uid);
     const char* get_ct_series_description () const;
     const std::string& get_dose_instance_uid () const;
     const char* get_dose_series_uid () const;
@@ -94,8 +95,6 @@ public:
     void set_patient_sex (const char* sex);
     void set_patient_sex (const std::string& sex);
 
-
-
     const Plm_image_header* get_image_header () const;
     void set_image_header (const Plm_image::Pointer& pli);
     void set_image_header (const Plm_image_header& pih);
diff --git a/src/plastimatch/cli/CMakeLists.txt b/src/plastimatch/cli/CMakeLists.txt
index f4d245f..efc5f49 100644
--- a/src/plastimatch/cli/CMakeLists.txt
+++ b/src/plastimatch/cli/CMakeLists.txt
@@ -5,7 +5,7 @@ project (src_plastimatch_cli)
 
 configure_file (
     ${CMAKE_CURRENT_SOURCE_DIR}/plmcli_config.h.in
-    ${PLM_BUILD_ROOT}/plmcli_config.h
+    ${CMAKE_BINARY_DIR}/plmcli_config.h
 )
 
 include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/src/plastimatch/cli/pcmd_warp.cxx b/src/plastimatch/cli/pcmd_warp.cxx
index 473bb8c..78aa558 100644
--- a/src/plastimatch/cli/pcmd_warp.cxx
+++ b/src/plastimatch/cli/pcmd_warp.cxx
@@ -173,6 +173,8 @@ parse_fn (
         "series number for dose metadata: integer", 1);
     parser->add_long_option ("", "rtss-series-number",
         "series number for structure metadata: integer", 1);
+    parser->add_long_option ("", "series-uid",
+        "series UID for image metadata: string", 1);
 
     /* Parse options */
     parser->parse (argc,argv);
@@ -390,6 +392,12 @@ parse_fn (
         std::string metadata_string = "0020,0011=" + arg;
         parms->m_rtstruct_metadata.push_back (metadata_string);
     }
+    if (parser->option ("series-uid")) {
+        std::string arg = parser->get_string ("series-uid");
+        std::string metadata_string = "0020,000e=" + arg;
+        parms->m_image_metadata.push_back (metadata_string);
+        parms->image_series_uid_forced = true;
+    }
 }
 
 void
diff --git a/src/plastimatch/dose/CMakeLists.txt b/src/plastimatch/dose/CMakeLists.txt
index 9a0579c..c79e81d 100755
--- a/src/plastimatch/dose/CMakeLists.txt
+++ b/src/plastimatch/dose/CMakeLists.txt
@@ -5,7 +5,7 @@ project (src_plastimatch_dose)
 
 configure_file (
     ${CMAKE_CURRENT_SOURCE_DIR}/plmdose_config.h.in
-    ${PLM_BUILD_ROOT}/plmdose_config.h
+    ${CMAKE_BINARY_DIR}/plmdose_config.h
 )
 
 include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/src/plastimatch/dose/dose_volume_functions.cxx b/src/plastimatch/dose/dose_volume_functions.cxx
index f6bf6bd..4cebd2f 100755
--- a/src/plastimatch/dose/dose_volume_functions.cxx
+++ b/src/plastimatch/dose/dose_volume_functions.cxx
@@ -16,7 +16,7 @@ dose_volume_create (
 {
     /* we want to add extra margins around our volume take into account the dose that will be scattered outside of the rpl_volume */
     /* A 3 sigma margin is applied to the front_back volume, and the size of our volume will be the projection of this shape on the back_clipping_plane */
-    
+
     float ap_ul_pixel[3]; // coordinates in the BEV (rpl_volume) volume
     float proj_pixel[3]; // coordinates of the ap_ul_pixel + 3 sigma margins on the back clipping plane
     float first_pixel[3]; // coordinates of the first_pixel of the volume to be created
@@ -24,8 +24,8 @@ dose_volume_create (
     float origin[3] = {0,0,0};
     float spacing[3] = {0,0,0};
     const float dc[9] = {
-        dose_volume->get_direction_cosines()[0], dose_volume->get_direction_cosines()[1], dose_volume->get_direction_cosines()[2], 
-        dose_volume->get_direction_cosines()[3], dose_volume->get_direction_cosines()[4], dose_volume->get_direction_cosines()[5], 
+        dose_volume->get_direction_cosines()[0], dose_volume->get_direction_cosines()[1], dose_volume->get_direction_cosines()[2],
+        dose_volume->get_direction_cosines()[3], dose_volume->get_direction_cosines()[4], dose_volume->get_direction_cosines()[5],
         dose_volume->get_direction_cosines()[6], dose_volume->get_direction_cosines()[7], dose_volume->get_direction_cosines()[8]};
 
     float sigma_margins = 3 * *sigma_max;
@@ -48,7 +48,7 @@ dose_volume_create (
     {
         origin[i] = first_pixel[i];
         if (i != 2)
-        {   
+        {
             spacing[i] = 1;
             //spacing[i] = volume->get_aperture()->get_spacing(i); // MD Fix
             dim[i] = (plm_long) (2*abs(first_pixel[i]/spacing[i])+1);
@@ -73,12 +73,12 @@ calculate_rpl_coordinates_xyz (
     double vec_antibug_prt[3] = {0.0,0.0,0.0};
 
     const plm_long *dim = rpl_volume->get_vol()->dim;
-    int idx2d = 0;   
+    int idx2d = 0;
     int idx3d = 0;
 
     for (int i = 0; i < rpl_volume->get_vol()->dim[0];i++){
         for (int j = 0; j < rpl_volume->get_vol()->dim[1];j++){
-        
+
             idx2d = j * dim[0] + i;
             Ray_data* ray_data = &rpl_volume->get_ray_data()[idx2d];
 
@@ -103,9 +103,9 @@ calculate_rpl_coordinates_xyz (
     }
 }
 
-void 
+void
 dose_volume_reconstruction (
-    Rpl_volume* dose_rv, 
+    Rpl_volume* dose_rv,
     Volume::Pointer dose_vol
 )
 {
@@ -160,10 +160,10 @@ build_hong_grid (
             (*xy_grid)[2*(i*theta_sample+j)] = ((double) i + 0.5)* dr * sin ((double) j * dt);
             (*xy_grid)[2*(i*theta_sample+j)+1] = ((double) i + 0.5) * dr * cos ((double) j * dt);
         }
-    }	
+    }
 }
 
-void 
+void
 find_ijk_pixel(int* ijk_idx, double* xyz_ray_center, Volume* dose_volume)
 {
     ijk_idx[0] = (int) floor((xyz_ray_center[0] - dose_volume->origin[0]) / dose_volume->spacing[0] + 0.5);
@@ -171,7 +171,7 @@ find_ijk_pixel(int* ijk_idx, double* xyz_ray_center, Volume* dose_volume)
     ijk_idx[2] = (int) floor((xyz_ray_center[2] - dose_volume->origin[2]) / dose_volume->spacing[2] + 0.5);
 }
 
-void 
+void
 find_ijk_pixel(int* ijk_idx, double* xyz_ray_center, Volume::Pointer dose_volume)
 {
     ijk_idx[0] = (int) floor((xyz_ray_center[0] - dose_volume->origin[0]) / dose_volume->spacing[0] + 0.5);
@@ -179,7 +179,7 @@ find_ijk_pixel(int* ijk_idx, double* xyz_ray_center, Volume::Pointer dose_volume
     ijk_idx[2] = (int) floor((xyz_ray_center[2] - dose_volume->origin[2]) / dose_volume->spacing[2] + 0.5);
 }
 
-void 
+void
 find_xyz_center_entrance(double* xyz_ray_center, double* ray, float z_axis_offset)
 {
     xyz_ray_center[0] = z_axis_offset * ray[0];
@@ -187,7 +187,7 @@ find_xyz_center_entrance(double* xyz_ray_center, double* ray, float z_axis_offse
     xyz_ray_center[2] = z_axis_offset * ray[2];
 }
 
-void 
+void
 find_xyz_center(double* xyz_ray_center, double* ray, float z_axis_offset, int k, float z_spacing)
 {
     float alpha = 0.0f;
@@ -199,7 +199,7 @@ find_xyz_center(double* xyz_ray_center, double* ray, float z_axis_offset, int k,
 
 }
 
-void 
+void
 find_xyz_from_ijk(double* xyz, Volume* volume, int* ijk)
 {
     xyz[0] = volume->origin[0] + ijk[0]*volume->spacing[0];
@@ -228,7 +228,7 @@ double_gaussian_interpolation (
     double y1 = pixel_center[1] - 0.5 * spacing[1];
     double y2 = y1 + spacing[1];
 
-    double z = .25 
+    double z = .25
         * (erf_gauss((x2-gaussian_center[0])/(sigma*M_SQRT2)) - erf_gauss((x1-gaussian_center[0])/(sigma*M_SQRT2)))
         * (erf_gauss((y2-gaussian_center[1])/(sigma*M_SQRT2)) - erf_gauss((y1-gaussian_center[1])/(sigma*M_SQRT2)));
     return z;
@@ -271,7 +271,7 @@ void dose_normalization_to_dose(Volume::Pointer dose_volume, double dose, Rt_bea
         {
             img[i] = img[i] / norm * dose;
         }
-        int ap_dim[2] = {beam->get_aperture()->get_dim(0),beam->get_aperture()->get_dim(1)};
+        const plm_long *ap_dim = beam->get_aperture_dim();
         beam->get_mebs()->scale_num_part(dose/norm, ap_dim);
 
         printf("Raw dose at the maximum (%lg, %lg, %lg) : %lg A.U.\nDose normalized at the maximum to ", dose_volume->origin[0] + ijk_max[0] * dose_volume->spacing[0], dose_volume->origin[1] + ijk_max[1] * dose_volume->spacing[1], dose_volume->origin[2] + ijk_max[2] * dose_volume->spacing[2], norm);
@@ -294,8 +294,8 @@ void dose_normalization_to_dose_and_point(Volume::Pointer dose_volume, double do
         {
             img[i] = img[i] / norm * dose;
         }
-        int ap_dim[2] = {beam->get_aperture()->get_dim(0),beam->get_aperture()->get_dim(1)};
-        beam->get_mebs()->scale_num_part(dose/norm, ap_dim);
+        const plm_long *ap_dim = beam->get_aperture_dim();
+        beam->get_mebs()->scale_num_part (dose/norm, ap_dim);
         printf("Raw dose at the reference dose point (%lg, %lg, %lg) : %lg A.U.\nDose normalized at the reference dose point to ", rdp[0], rdp[1], rdp[2], norm);
     }
     else
diff --git a/src/plastimatch/dose/rt_beam.cxx b/src/plastimatch/dose/rt_beam.cxx
index a940ffd..40f2e63 100755
--- a/src/plastimatch/dose/rt_beam.cxx
+++ b/src/plastimatch/dose/rt_beam.cxx
@@ -1153,6 +1153,12 @@ Rt_beam::get_aperture_image () const
     return d_ptr->aperture->get_aperture_image ();
 }
 
+const plm_long*
+Rt_beam::get_aperture_dim () const
+{
+    return d_ptr->aperture->get_dim ();
+}
+
 Plm_image::Pointer&
 Rt_beam::get_range_compensator_image () 
 {
diff --git a/src/plastimatch/dose/rt_beam.h b/src/plastimatch/dose/rt_beam.h
index f6d1a43..848bf2d 100755
--- a/src/plastimatch/dose/rt_beam.h
+++ b/src/plastimatch/dose/rt_beam.h
@@ -178,6 +178,7 @@ public:
     const Aperture::Pointer& get_aperture () const;
     Plm_image::Pointer& get_aperture_image ();
     const Plm_image::Pointer& get_aperture_image () const;
+    const plm_long* get_aperture_dim () const;
     Plm_image::Pointer& get_range_compensator_image ();
     const Plm_image::Pointer& get_range_compensator_image () const;
     void set_aperture_vup (const float[]);
diff --git a/src/plastimatch/dose/rt_mebs.cxx b/src/plastimatch/dose/rt_mebs.cxx
index 3dcb0c8..f769b9f 100755
--- a/src/plastimatch/dose/rt_mebs.cxx
+++ b/src/plastimatch/dose/rt_mebs.cxx
@@ -44,17 +44,17 @@ public:
     /* spread for optimized SOBP, may be changed to a vector for each energy */
     double spread;
 
-    /* p & alpha are parameters that bind depth and energy 
+    /* p & alpha are parameters that bind depth and energy
        according to ICRU */
-    Particle_type particle_type;			
+    Particle_type particle_type;
     double alpha;
     double p;
 
     float photon_energy; // energy for photon mono-energetic beams
 
-    /* When a new sobp is created from an existing sobp, 
-       the peaks are copied (not manual).  Modifications of 
-       an implicitly defined sobp (by adding a peak) will 
+    /* When a new sobp is created from an existing sobp,
+       the peaks are copied (not manual).  Modifications of
+       an implicitly defined sobp (by adding a peak) will
        delete any existing peaks. */
     bool have_copied_peaks;
     bool have_manual_peaks;
@@ -78,7 +78,7 @@ public:
 
     /* debug */
     bool debug;
-    
+
 public:
     Rt_mebs_private ()
     {
@@ -216,7 +216,7 @@ public:
         this->d_lut = (float*) malloc (this->num_samples*sizeof(float));
         this->e_lut = (float*) malloc (this->num_samples*sizeof(float));
         this->f_lut = (float*) malloc (this->num_samples*sizeof(float));
-    
+
         memset (this->d_lut, 0, this->num_samples*sizeof(float));
         memset (this->e_lut, 0, this->num_samples*sizeof(float));
         memset (this->f_lut, 0, this->num_samples*sizeof(float));
@@ -298,7 +298,7 @@ public:
         depth_dose.clear();
         /* stop = depth_dose.size();
            for (int i = 0; i < stop; i++)
-           {   
+           {
            depth_dose.pop_back();
            } */
         stop = depth_dose_weight.size();
@@ -387,7 +387,7 @@ Rt_mebs::add_peak (double E0, double spread, double weight)
         {
             d_ptr->depth_end = depth_dose->dend;
         }
-        printf ("Adding peak to sobp (%f, %f, %f) [%f, %f]\n", 
+        printf ("Adding peak to sobp (%f, %f, %f) [%f, %f]\n",
             (float) E0, (float) spread, (float) weight,
             d_ptr->depth_res, d_ptr->depth_end);
         d_ptr->depth_dose.push_back (depth_dose);
@@ -445,7 +445,7 @@ Rt_mebs::add_peak (double E0, double spread, double weight)
 float
 Rt_mebs::lookup_energy (
     float depth)
-{	
+{
     int i = 0;
     float energy = 0.0f;
 
@@ -466,13 +466,13 @@ Rt_mebs::lookup_energy (
     if (i == d_ptr->num_samples-1) {
         depth = d_ptr->d_lut[i];
     }
-	
+
     /* Use index to lookup and interpolate energy */
     if (i >= 0 || i < d_ptr->num_samples-1) {
         // linear interpolation
         energy = d_ptr->e_lut[i]
             + (depth - d_ptr->d_lut[i])
-            * ((d_ptr->e_lut[i+1] - d_ptr->e_lut[i]) 
+            * ((d_ptr->e_lut[i+1] - d_ptr->e_lut[i])
                 / (d_ptr->d_lut[i+1] - d_ptr->d_lut[i]));
     } else {
         // we went past the end of the lookup table
@@ -487,7 +487,7 @@ Rt_mebs::generate ()
     printf("depth_dose number %d\n", (int)d_ptr->depth_dose.size());
 
     /* Construct the data structure first time through */
-    if (d_ptr->d_lut) delete[] d_ptr->d_lut;    
+    if (d_ptr->d_lut) delete[] d_ptr->d_lut;
     if (d_ptr->e_lut) delete[] d_ptr->e_lut;
     if (d_ptr->f_lut) delete[] d_ptr->f_lut;
     d_ptr->e_lut = new float [d_ptr->num_samples];
@@ -519,7 +519,7 @@ Rt_mebs::generate ()
         /* Go on to next pristine peak */
         it++;
     }
-	
+
     /* build the integrated dose */
     if (d_ptr->f_lut[0] && d_ptr->f_lut[0]) {d_ptr->f_lut[0] = d_ptr->e_lut[0];}
     for (int i = 1; i < d_ptr->num_samples; i++) {
@@ -542,10 +542,10 @@ Rt_mebs::dump (const char* dir)
     fclose (fp);
 
     /* Dump pristine peaks */
-    std::vector<Rt_depth_dose*>::const_iterator it 
+    std::vector<Rt_depth_dose*>::const_iterator it
         = d_ptr->depth_dose.begin();
     while (it != d_ptr->depth_dose.end ()) {
-        std::string fn = string_format ("%s/pristine_%4.2f.txt", dir, 
+        std::string fn = string_format ("%s/pristine_%4.2f.txt", dir,
             (float) (*it)->E0);
         (*it)->dump (fn.c_str());
         it++;
@@ -553,7 +553,7 @@ Rt_mebs::dump (const char* dir)
 }
 
 // return on the command line the parameters of the sobp to be build
-void 
+void
 Rt_mebs::printparameters()
 {
     printf ("\nParticle type : %s, alpha: %lg, p: %lg\n", particle_type_string (d_ptr->particle_type), d_ptr->alpha, d_ptr->p);
@@ -600,8 +600,8 @@ Rt_mebs::reset_mebs_depth_dose_curve()
 
 
 /* set the mebs parameters by introducing the min and max energies */
-void 
-Rt_mebs::set_energies(float new_E_min, float new_E_max) 
+void
+Rt_mebs::set_energies(float new_E_min, float new_E_max)
 {
     if (new_E_max <= 0 || new_E_min <= 0)
     {
@@ -609,7 +609,7 @@ Rt_mebs::set_energies(float new_E_min, float new_E_max)
         printf("Emin = %g, Emax = %g \n", new_E_min, new_E_max);
         return;
     }
-	
+
     if (new_E_max <= new_E_min)
     {
         printf("SOBP: The Energy_max must be superior to the Energy_min.Energies unchanged.\n");
@@ -622,16 +622,16 @@ Rt_mebs::set_energies(float new_E_min, float new_E_max)
     this->update_prescription_depths_from_energies();
 }
 
-void 
-Rt_mebs::set_energies(float new_E_min, float new_E_max, float new_step) 
+void
+Rt_mebs::set_energies(float new_E_min, float new_E_max, float new_step)
 {
    d_ptr->energy_res = new_step;
    this->set_energies(new_E_min, new_E_max);
 }
 
 /* set the mebs parameters by introducing the min and max energies */
-void 
-Rt_mebs::set_target_depths(float new_depth_min, float new_depth_max) 
+void
+Rt_mebs::set_target_depths(float new_depth_min, float new_depth_max)
 {
     if (new_depth_max <= 0 || new_depth_min <= 0)
     {
@@ -639,7 +639,7 @@ Rt_mebs::set_target_depths(float new_depth_min, float new_depth_max)
         printf("depths min = %g, max = %g \n", new_depth_min, new_depth_max);
         return;
     }
-	
+
     if (new_depth_max <= new_depth_min)
     {
         printf("***ERROR*** The Energy_max must be superior to the Energy_min.Energies unchanged.\n");
@@ -662,14 +662,14 @@ Rt_mebs::set_target_depths(float new_depth_min, float new_depth_max)
     this->update_energies_from_prescription();
 }
 
-void 
+void
 Rt_mebs::set_target_depths(float new_z_min, float new_z_max, float new_step)
 {
     d_ptr->depth_res = new_step;
     this->set_target_depths(new_z_min, new_z_max);
 }
 
-void 
+void
 Rt_mebs::set_prescription_depths(float new_prescription_min, float new_prescription_max)
 {
     if (new_prescription_min <= d_ptr->proximal_margin || new_prescription_max <= 0)
@@ -698,7 +698,7 @@ Rt_mebs::set_prescription_depths(float new_prescription_min, float new_prescript
     this->update_energies_from_prescription();
 }
 
-void 
+void
 Rt_mebs::set_margins(float proximal_margin, float distal_margin)
 {
     if (proximal_margin < 0 || distal_margin < 0)
@@ -713,8 +713,8 @@ Rt_mebs::set_margins(float proximal_margin, float distal_margin)
 }
 
 /* update the mebs depths parameters from energy definition */
-void 
-Rt_mebs::update_prescription_depths_from_energies() 
+void
+Rt_mebs::update_prescription_depths_from_energies()
 {
     d_ptr->prescription_depth_min = ((10*d_ptr->alpha)*pow((double)d_ptr->beam_min_energy, d_ptr->p));
     d_ptr->prescription_depth_max = ((10*d_ptr->alpha)*pow((double)d_ptr->beam_max_energy, d_ptr->p));
@@ -732,7 +732,7 @@ Rt_mebs::update_prescription_depths_from_energies()
 }
 
 /* update the mebs energy parameters from prescription definition */
-void 
+void
 Rt_mebs::update_energies_from_prescription()
 {
     int energy_min_index = (int) floor(pow((d_ptr->prescription_depth_min/(10*d_ptr->alpha)),(1/d_ptr->p)) / d_ptr->energy_res);
@@ -754,25 +754,25 @@ Rt_mebs::update_energies_from_prescription()
     this->reset_mebs_depth_dose_curve();
 }
 
-float* 
+float*
 Rt_mebs::get_d_lut()
 {
     return d_ptr->d_lut;
 }
 
-float* 
+float*
 Rt_mebs::get_e_lut()
 {
     return d_ptr->e_lut;
 }
 
-float* 
+float*
 Rt_mebs::get_f_lut()
 {
     return d_ptr->f_lut;
 }
 
-void 
+void
 Rt_mebs::set_particle_type(Particle_type particle_type)
 {
     d_ptr->set_particle_type (particle_type);
@@ -787,25 +787,25 @@ Rt_mebs::get_particle_type()
     return d_ptr->particle_type;
 }
 
-void 
+void
 Rt_mebs::set_alpha(double alpha)
 {
     d_ptr->alpha = alpha;
 }
 
-double 
+double
 Rt_mebs::get_alpha()
 {
     return d_ptr->alpha;
 }
 
-void 
+void
 Rt_mebs::set_p(double p)
 {
     d_ptr->p = p;
 }
 
-double 
+double
 Rt_mebs::get_p()
 {
     return d_ptr->p;
@@ -817,19 +817,19 @@ Rt_mebs::get_energy_number()
     return d_ptr->energy_number;
 }
 
-std::vector<float> 
+std::vector<float>
 Rt_mebs::get_energy()
 {
     return d_ptr->energies;
 }
 
-std::vector<float> 
+std::vector<float>
 Rt_mebs::get_weight()
 {
     return d_ptr->depth_dose_weight;
 }
 
-void 
+void
 Rt_mebs::set_energy_resolution(float eres)
 {
     if (eres > 0)
@@ -837,38 +837,38 @@ Rt_mebs::set_energy_resolution(float eres)
         d_ptr->energy_res = eres;
         d_ptr->energy_number = (int) ceil((d_ptr->beam_max_energy - d_ptr->beam_min_energy) / d_ptr->energy_res) + 1;
     }
-    else 
+    else
     {
         printf("***WARNING*** Energy resolution must be positive. Energy resolution unchanged");
     }
 }
 
-float 
+float
 Rt_mebs::get_energy_resolution()
 {
     return d_ptr->energy_res;
 }
 
-void 
+void
 Rt_mebs::set_energy_min(float E_min)
 {
     if (E_min > 0)
     {
         this->set_energies(E_min, d_ptr->beam_max_energy);
     }
-    else 
+    else
     {
         printf("***WARNING*** Energy min must be positive. Energy min unchanged");
     }
 }
 
-float 
+float
 Rt_mebs::get_energy_min()
 {
     return d_ptr->beam_min_energy;
 }
 
-void 
+void
 Rt_mebs::set_energy_max(float E_max)
 {
     if (E_max > 0)
@@ -881,57 +881,57 @@ Rt_mebs::set_energy_max(float E_max)
     }
 }
 
-float 
+float
 Rt_mebs::get_energy_max()
 {
     return d_ptr->beam_max_energy;
 }
 
-int 
+int
 Rt_mebs::get_num_samples()
 {
     return d_ptr->num_samples;
 }
 
-void 
+void
 Rt_mebs::set_target_min_depth(float dmin)
 {
     if (dmin > 0)
     {
         this->set_target_depths(dmin, d_ptr->target_max_depth);
     }
-    else 
+    else
     {
         printf("***WARNING*** Depth min must be positive. Depth min unchanged");
     }
 }
 
-float 
+float
 Rt_mebs::get_target_min_depth()
 {
     return d_ptr->target_min_depth;
 }
 
-void 
+void
 Rt_mebs::set_target_max_depth(float dmax)
 {
     if (dmax > 0)
     {
         this->set_target_depths(d_ptr->target_min_depth, dmax);
     }
-    else 
+    else
     {
         printf("***WARNING*** Depth max must be positive. Depth max unchanged");
     }
 }
 
-float 
+float
 Rt_mebs::get_target_max_depth()
 {
     return d_ptr->target_max_depth;
 }
 
-void 
+void
 Rt_mebs::set_depth_resolution(float dres)
 {
     if (dres > 0)
@@ -940,7 +940,7 @@ Rt_mebs::set_depth_resolution(float dres)
         d_ptr->num_samples = (int)ceil((d_ptr->depth_end/d_ptr->depth_res))+1;
         this->reset_mebs_depth_dose_curve();
     }
-    else 
+    else
     {
         printf("***WARNING*** Depth resolution must be positive. Depth resolution unchanged");
     }
@@ -952,7 +952,7 @@ Rt_mebs::get_depth_resolution()
     return d_ptr->depth_res;
 }
 
-void 
+void
 Rt_mebs::set_depth_end(float dend)
 {
     if (dend > 0)
@@ -961,7 +961,7 @@ Rt_mebs::set_depth_end(float dend)
         d_ptr->num_samples = (int)ceil((d_ptr->depth_end/d_ptr->depth_res))+1;
         this->reset_mebs_depth_dose_curve();
     }
-    else 
+    else
     {
         printf("***WARNING*** Depth end must be positive. Depth end unchanged");
     }
@@ -973,7 +973,7 @@ Rt_mebs::get_depth_end()
     return d_ptr->depth_end;
 }
 
-float 
+float
 Rt_mebs::get_prescription_min()
 {
     return d_ptr->prescription_depth_min;
@@ -991,7 +991,7 @@ Rt_mebs::set_distal_margin (float distal_margin)
     this->set_margins(d_ptr->proximal_margin, distal_margin);
 }
 
-float 
+float
 Rt_mebs::get_distal_margin()
 {
     return d_ptr->distal_margin;
@@ -1003,13 +1003,13 @@ Rt_mebs::set_proximal_margin (float proximal_margin)
     this->set_margins(proximal_margin, d_ptr->distal_margin);
 }
 
-float 
+float
 Rt_mebs::get_proximal_margin()
 {
     return d_ptr->proximal_margin;
 }
 
-void 
+void
 Rt_mebs::set_spread (double spread)
 {
     d_ptr->spread = spread;
@@ -1021,25 +1021,25 @@ Rt_mebs::get_spread()
     return d_ptr->spread;
 }
 
-void 
+void
 Rt_mebs::set_photon_energy(float energy)
 {
     d_ptr->photon_energy = energy;
 }
 
-float 
+float
 Rt_mebs::get_photon_energy()
 {
     return d_ptr->photon_energy;
 }
 
-std::vector<Rt_depth_dose*> 
+std::vector<Rt_depth_dose*>
 Rt_mebs::get_depth_dose()
 {
     return d_ptr->depth_dose;
 }
 
-std::vector<float>& 
+std::vector<float>&
 Rt_mebs::get_num_particles()
 {
     return d_ptr->num_particles;
@@ -1052,49 +1052,49 @@ Rt_mebs::set_prescription (float prescription_min, float prescription_max)
     this->set_prescription_depths (prescription_min, prescription_max);
 }
 
-void 
+void
 Rt_mebs::set_have_prescription(bool have_prescription)
 {
     d_ptr->have_prescription = have_prescription;
 }
 
-bool 
+bool
 Rt_mebs::get_have_prescription()
 {
     return d_ptr->have_prescription;
 }
 
-void 
+void
 Rt_mebs::set_have_copied_peaks(bool have_copied_peaks)
 {
     d_ptr->have_copied_peaks = have_copied_peaks;
 }
-	
-bool 
+
+bool
 Rt_mebs::get_have_copied_peaks()
 {
     return d_ptr->have_copied_peaks;
 }
 
-void 
+void
 Rt_mebs::set_have_manual_peaks(bool have_manual_peaks)
 {
     d_ptr->have_manual_peaks = have_manual_peaks;
 }
 
-bool 
+bool
 Rt_mebs::get_have_manual_peaks()
 {
     return d_ptr->have_manual_peaks;
 }
 
-void 
+void
 Rt_mebs::set_have_particle_number_map(bool have_particle_number_map)
 {
     d_ptr->have_particle_number_map = have_particle_number_map;
 }
 
-bool 
+bool
 Rt_mebs::get_have_particle_number_map()
 {
     return d_ptr->have_particle_number_map;
@@ -1112,37 +1112,37 @@ Rt_mebs::get_max_wed_map()
     return d_ptr->max_wed_map;
 }
 
-void 
+void
 Rt_mebs::set_particle_number_in (const std::string& str)
 {
     d_ptr->particle_number_in = str;
 }
 
-std::string 
+std::string
 Rt_mebs::get_particle_number_in ()
 {
     return d_ptr->particle_number_in;
 }
 
-void 
+void
 Rt_mebs::set_particle_number_out (const std::string& str)
 {
     d_ptr->particle_number_out = str;
 }
 
-std::string 
+std::string
 Rt_mebs::get_particle_number_out ()
 {
     return d_ptr->particle_number_out;
 }
 
-void 
+void
 Rt_mebs::add_depth_dose_weight(float weight)
 {
     d_ptr->depth_dose_weight.push_back(weight);
 }
 
-/* This function check (and correct if necessary) that E_max is the closest energy (+/- energy_resolution) 
+/* This function check (and correct if necessary) that E_max is the closest energy (+/- energy_resolution)
 	to reach the distal prescription */
 /* This function is designed to return a float value that represents the increase/decrease of energy to correct it
 	this is used by two parts of the program on different members (explaining this particular structure) */
@@ -1179,7 +1179,7 @@ Rt_mebs::check_and_correct_max_energy(float E, float depth)
     return E - E_init;
 }
 
-/* This function check (and correct if necessary) that E_min is the closest energy (+/- energy_resolution) 
+/* This function check (and correct if necessary) that E_min is the closest energy (+/- energy_resolution)
 	to reach the proximal prescription */
 /* This function is designed to return a float value that represents the increase/decrease of energy to correct it
 	this is used by two parts of the program on different members (explaining this particular structure) */
@@ -1218,7 +1218,7 @@ Rt_mebs::check_and_correct_min_energy(float E, float depth)
 
 void
 Rt_mebs::optimize_sobp ()
-{	
+{
     this->update_energies_from_prescription();
     std::vector<float> weight_tmp;
     std::vector<float> energy_tmp;
@@ -1230,7 +1230,7 @@ Rt_mebs::optimize_sobp ()
     }
 }
 
-void 
+void
 Rt_mebs::optimizer (std::vector<float>* weight_tmp, std::vector<float>* energy_tmp)
 {
     printf("prescription min/max: %lg mm, %lg mm.\n", d_ptr->prescription_depth_min, d_ptr->prescription_depth_max);
@@ -1276,7 +1276,7 @@ Rt_mebs::initialize_energy_weight_and_depth_dose_vectors (
     }
 }
 
-void 
+void
 Rt_mebs::generate_part_num_from_weight (const plm_long* ap_dim)
 {
     //int idx = 0;
@@ -1287,8 +1287,8 @@ Rt_mebs::generate_part_num_from_weight (const plm_long* ap_dim)
     }
 }
 
-void 
-Rt_mebs::scale_num_part(double A, int* ap_dim)
+void
+Rt_mebs::scale_num_part (double A, const plm_long* ap_dim)
 {
     for (int i = 0; i < (int) d_ptr->energy_number * ap_dim[0] * ap_dim[1]; i++)
     {
@@ -1296,11 +1296,11 @@ Rt_mebs::scale_num_part(double A, int* ap_dim)
     }
 }
 
-double 
+double
 Rt_mebs::get_particle_number_xyz (
     plm_long* idx, double* rest, int dd_idx, const plm_long* ap_dim)
 {
-    /* The boundaries possible errors like idx = dim are already excluded by 
+    /* The boundaries possible errors like idx = dim are already excluded by
        the test on the aperture. Practically, idx = dim -1 is not possible */
     double A = 0;
     double B = 0;
@@ -1328,7 +1328,7 @@ Rt_mebs::get_particle_number_xyz (
     return A + rest[1] * (B-A);
 }
 
-void 
+void
 Rt_mebs::set_from_spot_map (const Rt_spot_map::Pointer& rsm)
 {
     this->clear_depth_dose ();
@@ -1337,7 +1337,7 @@ Rt_mebs::set_from_spot_map (const Rt_spot_map::Pointer& rsm)
 
 }
 
-void 
+void
 Rt_mebs::load_beamlet_map (Aperture::Pointer& ap)
 {
     /* Confirm file can be read */
@@ -1371,7 +1371,7 @@ Rt_mebs::load_beamlet_map (Aperture::Pointer& ap)
     double part_number = 0;
     double energy;
 
-    while (getline (ss, buf)) 
+    while (getline (ss, buf))
     {
         buf = string_trim (buf);
 
@@ -1415,7 +1415,7 @@ Rt_mebs::load_beamlet_map (Aperture::Pointer& ap)
         val ="";
         val = buf.c_str();
         val = string_trim (val);
-					
+
         token = strtok(&val[0], sep);
         beamlet_number = 0;
 
@@ -1453,8 +1453,8 @@ Rt_mebs::compute_particle_number_matrix_from_target_active (
     std::vector <double>& wepl_max)
 {
     int dim[2] = {
-        rpl_vol->get_aperture()->get_dim()[0],
-        rpl_vol->get_aperture()->get_dim()[1]
+        static_cast<int>(rpl_vol->get_aperture()->get_dim()[0]),
+        static_cast<int>(rpl_vol->get_aperture()->get_dim()[1])
     };
 
     /* vector containing the min and the max of depth of the target */
@@ -1462,7 +1462,7 @@ Rt_mebs::compute_particle_number_matrix_from_target_active (
     float max = 0;
 
     /* Sanity check */
-    if (wepl_min.size() != rpl_vol->get_aperture()->get_dim(0) * rpl_vol->get_aperture()->get_dim(1) 
+    if (wepl_min.size() != rpl_vol->get_aperture()->get_dim(0) * rpl_vol->get_aperture()->get_dim(1)
         || wepl_max.size() != rpl_vol->get_aperture()->get_dim(0) * rpl_vol->get_aperture()->get_dim(1))
     {
         printf("ERROR: the aperture size doesn't correspond to the min and max depth maps of the target.\n");
@@ -1518,10 +1518,10 @@ Rt_mebs::compute_particle_number_matrix_from_target_active (
     }
 }
 
-/* This function returns optimized weighted peaks for passive systems 
-   (SOBP weights) and active systems (beamlet particle numbers 
+/* This function returns optimized weighted peaks for passive systems
+   (SOBP weights) and active systems (beamlet particle numbers
    for each energy) */
-void 
+void
 Rt_mebs::get_optimized_peaks (
     float dmin,
     float dmax,
@@ -1538,11 +1538,11 @@ Rt_mebs::get_optimized_peaks (
     float E_max_sobp = (float) energy_max_index * d_ptr->energy_res;
 
     /* This is useful only for active scanning */
-    /* check that the E_max is sufficiently high for covering the distal 
+    /* check that the E_max is sufficiently high for covering the distal
        part of the prescription */
     E_max_sobp += this->check_and_correct_max_energy(E_max_sobp, dmax);
 
-    /* check that the E_min is sufficiently low for covering the distal 
+    /* check that the E_min is sufficiently low for covering the distal
        part of the prescription */
     E_min_sobp += this->check_and_correct_min_energy(E_min_sobp, dmin);
 
@@ -1599,7 +1599,7 @@ Rt_mebs::get_optimized_peaks (
         {
             e_lut_tmp[j] = 0;
         }
-		
+
         for (int i = i0; i <= imax; i++)
         {
             for (int j = 0; j <  (*depth_dose_tmp)[i]->num_samples; j++)
@@ -1632,11 +1632,11 @@ Rt_mebs::get_optimized_peaks (
     }
 }
 
-void 
+void
 Rt_mebs::export_as_txt(Aperture::Pointer ap)
 {
     make_parent_directories (d_ptr->particle_number_out.c_str());
-	
+
     printf("Trying to write mebs in %s\n", d_ptr->particle_number_out.c_str());
 
     std::ofstream fichier(d_ptr->particle_number_out.c_str());
diff --git a/src/plastimatch/dose/rt_mebs.h b/src/plastimatch/dose/rt_mebs.h
index cf9500f..d5d2c11 100755
--- a/src/plastimatch/dose/rt_mebs.h
+++ b/src/plastimatch/dose/rt_mebs.h
@@ -144,7 +144,7 @@ public:
         std::vector<float>* weight_tmp, std::vector<float>* energy_tmp, 
         std::vector<Rt_depth_dose*>* depth_dose_tmp);
 
-    void scale_num_part (double A, int* ap_dim);
+    void scale_num_part (double A, const plm_long* ap_dim);
     double get_particle_number_xyz (plm_long* idx, double* rest, 
         int idx_beam, const plm_long* ap_dim);
 
diff --git a/src/plastimatch/dose/rt_plan.cxx b/src/plastimatch/dose/rt_plan.cxx
index 415603d..744c825 100755
--- a/src/plastimatch/dose/rt_plan.cxx
+++ b/src/plastimatch/dose/rt_plan.cxx
@@ -475,7 +475,7 @@ Rt_plan::compute_dose (Rt_beam *beam)
     if (!beam->prepare_for_calc (d_ptr->patient_hu,
             d_ptr->patient_psp, d_ptr->target))
     {
-        print_and_exit ("ERROR: Unable to initilize plan.\n");
+        print_and_exit ("ERROR: Unable to initiliaze plan.\n");
     }
     d_ptr->rt_dose_timing->timer_dose_calc.stop ();
 
diff --git a/src/plastimatch/opencl/opencl_util.cxx b/src/plastimatch/opencl/opencl_util.cxx
index 7459b9f..99b6420 100644
--- a/src/plastimatch/opencl/opencl_util.cxx
+++ b/src/plastimatch/opencl/opencl_util.cxx
@@ -512,7 +512,7 @@ opencl_kernel_create (
 )
 {
     ocl_dev->kernels = (cl_kernel*) malloc (
-    ocl_dev->device_count * sizeof(cl_kernel));
+        ocl_dev->device_count * sizeof(cl_kernel));
 
     for (cl_uint i = 0; i < ocl_dev->device_count; i++) {
         cl_int status;
diff --git a/src/plastimatch/qt/CMakeLists.txt b/src/plastimatch/qt/CMakeLists.txt
index 93c9997..930abe5 100644
--- a/src/plastimatch/qt/CMakeLists.txt
+++ b/src/plastimatch/qt/CMakeLists.txt
@@ -5,12 +5,18 @@ project (src_plastimatch_qt)
 
 configure_file (
     ${CMAKE_CURRENT_SOURCE_DIR}/plmqt_config.h.in
-    ${PLM_BUILD_ROOT}/plmqt_config.h
+    ${CMAKE_BINARY_DIR}/plmqt_config.h
 )
 
 include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
 include_directories (BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 
+if (QT4_FOUND)
+  set (QT4_INCLUDE_DIRS ${QT_QTGUI_INCLUDE_DIR}
+    ${QT_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR})
+  set (QT4_LIBRARIES ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY})
+endif ()
+
 ##-----------------------------------------------------------------------------
 ##  SOURCE FILES
 ##-----------------------------------------------------------------------------
@@ -79,18 +85,18 @@ endif ()
 ##-----------------------------------------------------------------------------
 if (ITK_FOUND AND QT4_FOUND)
   set (CRYSTALVIEW_LIBRARIES ${PLASTIMATCH_LIBS} 
-    ${QT_LIBRARIES} ${QT_QTSQL_LIBRARIES})
-  plm_add_executable (cview "${CRYSTALVIEW_SRC}"
-    "${CRYSTALVIEW_LIBRARIES}" "${PLASTIMATCH_LDFLAGS}"
-    ${BUILD_IF_NOT_SLICER_EXT} ${INSTALL_NEVER})
+    ${QT_QTSQL_LIBRARIES} ${QT4_LIBRARIES})
+  plm_add_executable_v2 (cview "${CRYSTALVIEW_SRC}"
+    "${QT4_INCLUDE_DIRS}" "${CRYSTALVIEW_LIBRARIES}"
+    "${PLASTIMATCH_LDFLAGS}" ${BUILD_ALWAYS} ${INSTALL_IF_NOT_DEBIAN})
 endif ()
 if (ITK_FOUND AND QT4_FOUND AND QT_QTSQL_FOUND)
   if (PLM_CONFIG_ENABLE_PLASTIMATCH_QT)
     set (PLASTIMATCH_QT_LIBRARIES ${PLASTIMATCH_LIBS} 
-      ${QT_LIBRARIES} ${QT_QTSQL_LIBRARIES})
-    plm_add_executable (plastimatch_qt "${PLASTIMATCH_QT_SRC}"
-      "${PLASTIMATCH_QT_LIBRARIES}" "${PLASTIMATCH_LDFLAGS}" 
-      ${BUILD_IF_NOT_SLICER_EXT} ${INSTALL_NEVER})
+      ${QT_QTSQL_LIBRARIES} ${QT4_LIBRARIES})
+    plm_add_executable_v2 (plastimatch_qt "${PLASTIMATCH_QT_SRC}"
+      "${QT4_INCLUDE_DIRS}" "${PLASTIMATCH_QT_LIBRARIES}" 
+      "${PLASTIMATCH_LDFLAGS}" ${BUILD_ALWAYS} ${INSTALL_IF_NOT_DEBIAN})
   endif ()
 endif ()
 
diff --git a/src/plastimatch/reconstruct/CMakeLists.txt b/src/plastimatch/reconstruct/CMakeLists.txt
index 66b0bd8..5c319e9 100644
--- a/src/plastimatch/reconstruct/CMakeLists.txt
+++ b/src/plastimatch/reconstruct/CMakeLists.txt
@@ -5,7 +5,7 @@ project (src_plastimatch_reconstruct)
 
 configure_file (
     ${CMAKE_CURRENT_SOURCE_DIR}/plmreconstruct_config.h.in
-    ${PLM_BUILD_ROOT}/plmreconstruct_config.h
+    ${CMAKE_BINARY_DIR}/plmreconstruct_config.h
 )
 
 include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/src/plastimatch/register/CMakeLists.txt b/src/plastimatch/register/CMakeLists.txt
index 1349d30..2b7f80f 100644
--- a/src/plastimatch/register/CMakeLists.txt
+++ b/src/plastimatch/register/CMakeLists.txt
@@ -5,7 +5,7 @@ project (src_plastimatch_register)
 
 configure_file (
     ${CMAKE_CURRENT_SOURCE_DIR}/plmregister_config.h.in
-    ${PLM_BUILD_ROOT}/plmregister_config.h
+    ${CMAKE_BINARY_DIR}/plmregister_config.h
 )
 
 include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/src/plastimatch/script/CMakeLists.txt b/src/plastimatch/script/CMakeLists.txt
index 804c6fd..8465210 100644
--- a/src/plastimatch/script/CMakeLists.txt
+++ b/src/plastimatch/script/CMakeLists.txt
@@ -5,7 +5,7 @@ project (src_plastimatch_script)
 
 configure_file (
     ${CMAKE_CURRENT_SOURCE_DIR}/plmscript_config.h.in
-    ${PLM_BUILD_ROOT}/plmscript_config.h
+    ${CMAKE_BINARY_DIR}/plmscript_config.h
 )
 
 include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/src/plastimatch/segment/CMakeLists.txt b/src/plastimatch/segment/CMakeLists.txt
index c880bea..75e5d60 100644
--- a/src/plastimatch/segment/CMakeLists.txt
+++ b/src/plastimatch/segment/CMakeLists.txt
@@ -5,7 +5,7 @@ project (src_plastimatch_segment)
 
 configure_file (
     ${CMAKE_CURRENT_SOURCE_DIR}/plmsegment_config.h.in
-    ${PLM_BUILD_ROOT}/plmsegment_config.h
+    ${CMAKE_BINARY_DIR}/plmsegment_config.h
 )
 
 include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/src/plastimatch/segment/mabs.cxx b/src/plastimatch/segment/mabs.cxx
index 8624979..01d7403 100644
--- a/src/plastimatch/segment/mabs.cxx
+++ b/src/plastimatch/segment/mabs.cxx
@@ -1972,14 +1972,14 @@ Mabs::run_segmentation (const Mabs_seg_weights_list& seg_weights)
 {
     
     /* Just one atlas and no voting option selected */
-    if (d_ptr->parms->fusion_criteria == "none" && d_ptr->parms->atlases_from_ranking == 1) {
-
+    if (d_ptr->parms->fusion_criteria == "none"
+        && d_ptr->parms->atlases_from_ranking == 1)
+    {
         std::string atlas_id = basename (*d_ptr->atlas_list.begin());
         std::string label_output_dir =
             string_format ("%s/segmentations", d_ptr->output_dir.c_str());
 
-        no_voting(atlas_id, label_output_dir);
-
+        no_voting (atlas_id, label_output_dir);
         return;
     }
 
@@ -2037,14 +2037,14 @@ void
 Mabs::run_segmentation_train (const Mabs_seg_weights& msw)
 {
     /* Just one atlas and no voting option selected */
-    if (d_ptr->parms->fusion_criteria == "none" && d_ptr->parms->atlases_from_ranking == 1) {
-
+    if (d_ptr->parms->fusion_criteria == "none"
+        && d_ptr->parms->atlases_from_ranking == 1)
+    {
         std::string atlas_id = basename (*d_ptr->atlas_list.begin());
         std::string label_output_dir =
             string_format ("%s/segmentations", d_ptr->output_dir.c_str());
 
         no_voting(atlas_id, label_output_dir);
-
         return;
     }
 
@@ -2106,7 +2106,8 @@ Mabs::run_segmentation_train (const Mabs_seg_weights& msw)
         }
     }
     
-    /* If gaussian is chosen (alone or with staple) and its segmentations aren't already present run its code */
+    /* If gaussian is chosen (alone or with staple) and its segmentations 
+       aren't already present run its code */
     if (d_ptr->parms->fusion_criteria.find("gaussian") != std::string::npos
         && gaussian_seg_checkpoint_fn != "")
     {
@@ -2120,7 +2121,8 @@ Mabs::run_segmentation_train (const Mabs_seg_weights& msw)
         /* Clear out internal structure */
         d_ptr->clear_vote_map ();
     }
-    /* If staple is chosen (alone or with gaussian) and its segmentations aren't already present run its code */
+    /* If staple is chosen (alone or with gaussian) and its segmentations 
+       aren't already present run its code */
     if (d_ptr->parms->fusion_criteria.find("staple") != std::string::npos
         && staple_seg_checkpoint_fn != "")
     {
@@ -2139,13 +2141,11 @@ Mabs::run_segmentation_train (const Mabs_seg_weights& msw)
        is complete */
     if (gaussian_seg_checkpoint_fn!="") touch_file (gaussian_seg_checkpoint_fn);
     if (staple_seg_checkpoint_fn!="") touch_file (staple_seg_checkpoint_fn);
-
 }
 
 void
 Mabs::run_segmentation_train_loop ()
 {
-
     Option_range minsim_range, rho_range, sigma_range, confidence_weight_range;
     minsim_range.set_range (d_ptr->parms->minsim_values);
     rho_range.set_range (d_ptr->parms->rho_values);
@@ -2316,6 +2316,8 @@ Mabs::train_internal ()
             d_ptr->parms->registration_config.c_str(),
             d_ptr->parms->optimization_result_reg.c_str());
         this->parse_registration_dir (registration_fn);
+        lprintf ("Training based on optimized registration result: %s\n",
+            registration_fn.c_str());
     } else {
         /* Else, parse directory with registration files */
         this->parse_registration_dir (d_ptr->parms->registration_config);
diff --git a/src/plastimatch/segment/mabs_parms.cxx b/src/plastimatch/segment/mabs_parms.cxx
index 4482fa1..337c056 100644
--- a/src/plastimatch/segment/mabs_parms.cxx
+++ b/src/plastimatch/segment/mabs_parms.cxx
@@ -33,39 +33,48 @@ public:
     {
         if (section == "CONVERT") {
             this->enable_key_regularization (true);
+            this->allow_empty_values (false);
             return PLM_SUCCESS;
         }
         if (section == "PREALIGN" || section == "PREALIGNMENT") {
             this->enable_key_regularization (true);
+            this->allow_empty_values (false);
             return PLM_SUCCESS;
         }
         if (section == "ATLAS-SELECTION") {
             this->enable_key_regularization (true);
+            this->allow_empty_values (false);
             return PLM_SUCCESS;
         }
         if (section == "TRAINING") {
             this->enable_key_regularization (true);
+            this->allow_empty_values (false);
             return PLM_SUCCESS;
         }
         if (section == "REGISTRATION") {
             this->enable_key_regularization (true);
+            this->allow_empty_values (false);
             return PLM_SUCCESS;
         }
         if (section == "STRUCTURES") {
             this->enable_key_regularization (false);
+            this->allow_empty_values (true);
             return PLM_SUCCESS;
         }
         if (section == "LABELING") {
             this->enable_key_regularization (true);
+            this->allow_empty_values (false);
             return PLM_SUCCESS;
         }
         if (section == "OPTIMIZATION-RESULT-REG") {
             this->enable_key_regularization (true);
+            this->allow_empty_values (false);
             return PLM_SUCCESS;
         }
         if (section == "OPTIMIZATION-RESULT-SEG") {
             ors.factory_reset ();
             this->enable_key_regularization (true);
+            this->allow_empty_values (false);
             return PLM_SUCCESS;
         }
 
diff --git a/src/plastimatch/standalone/CMakeLists.txt b/src/plastimatch/standalone/CMakeLists.txt
index 901388b..1c5d2c4 100644
--- a/src/plastimatch/standalone/CMakeLists.txt
+++ b/src/plastimatch/standalone/CMakeLists.txt
@@ -302,21 +302,24 @@ endif ()
 endif ()
 
 if (QT4_FOUND)
-    plm_add_executable (nki2mha_converter "${nki2mha_converter_SRC}" 
-	"${PLASTIMATCH_LIBS};${QT_LIBRARIES}" "${PLASTIMATCH_LDFLAGS}" 
-	${BUILD_ALWAYS} ${INSTALL_IF_NOT_DEBIAN})
-    if (DCMTK_FOUND)
-	plm_add_executable (gamma_gui "${GAMMA_GUI_SRC}" 
-	    "${PLASTIMATCH_LIBS};${QT_LIBRARIES}" "${PLASTIMATCH_LDFLAGS}" 
-	    ${BUILD_ALWAYS} ${INSTALL_IF_NOT_DEBIAN})
+  set (QT4_INCLUDE_DIRS ${QT_QTGUI_INCLUDE_DIR}
+    ${QT_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR})
+  set (QT4_LIBRARIES ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY})
+  plm_add_executable_v2 (nki2mha_converter "${nki2mha_converter_SRC}"
+    "${QT4_INCLUDE_DIRS}" "${PLASTIMATCH_LIBS};${QT4_LIBRARIES}"
+    "${PLASTIMATCH_LDFLAGS}" ${BUILD_ALWAYS} ${INSTALL_IF_NOT_DEBIAN})
+  if (DCMTK_FOUND)
+    plm_add_executable (gamma_gui "${GAMMA_GUI_SRC}"
+      "${QT4_INCLUDE_DIRS}" "${PLASTIMATCH_LIBS};${QT4_LIBRARIES}"
+      "${PLASTIMATCH_LDFLAGS}" ${BUILD_ALWAYS} ${INSTALL_IF_NOT_DEBIAN})
 
-	plm_add_executable (beamdata_gen_gui "${BEAMDATA_GEN_GUI_SRC}" 
-	    "${PLASTIMATCH_LIBS};${QT_LIBRARIES}" "${PLASTIMATCH_LDFLAGS}" 
-	    ${BUILD_ALWAYS} ${INSTALL_IF_NOT_DEBIAN})
-    endif ()
-    plm_add_executable (register_gui "${REGISTER_GUI_SRC}" 
-	"${PLASTIMATCH_LIBS};${QT_LIBRARIES}" "${PLASTIMATCH_LDFLAGS}" 
-	${BUILD_ALWAYS} ${INSTALL_IF_NOT_DEBIAN})
+    plm_add_executable (beamdata_gen_gui "${BEAMDATA_GEN_GUI_SRC}" 
+      "${QT4_INCLUDE_DIRS}" "${PLASTIMATCH_LIBS};${QT4_LIBRARIES}"
+      "${PLASTIMATCH_LDFLAGS}" ${BUILD_ALWAYS} ${INSTALL_IF_NOT_DEBIAN})
+  endif ()
+  plm_add_executable (register_gui "${REGISTER_GUI_SRC}" 
+    "${QT4_INCLUDE_DIRS}" "${PLASTIMATCH_LIBS};${QT4_LIBRARIES}"
+    "${PLASTIMATCH_LDFLAGS}" ${BUILD_ALWAYS} ${INSTALL_IF_NOT_DEBIAN})
 endif()
 
 plm_add_executable (cmd_prompt_launcher "${CMD_PROMPT_LAUNCHER_SRC}" 
diff --git a/src/plastimatch/standalone/nki2mha_converter.cpp b/src/plastimatch/standalone/nki2mha_converter.cpp
index 8bf7fb1..99f14cd 100644
--- a/src/plastimatch/standalone/nki2mha_converter.cpp
+++ b/src/plastimatch/standalone/nki2mha_converter.cpp
@@ -134,25 +134,25 @@ void nki2mha_converter::SLT_Correct_NKI2DCM()
     if (listSize < 1)
         return;
 
-	QString strPatientID = ui.lineEditPatientID->text();
-	QString strPatientName = ui.lineEditPatientName->text();
+    QString strPatientID = ui.lineEditPatientID->text();
+    QString strPatientName = ui.lineEditPatientName->text();
 
-	bool bPatientIDExist = false;
+    bool bPatientIDExist = false;
 
-	if (strPatientID.length() > 1 && strPatientName.length() > 1)
-	{
-	  bPatientIDExist = true;  	  
-	}
+    if (strPatientID.length() > 1 && strPatientName.length() > 1)
+    {
+        bPatientIDExist = true;  	  
+    }
 
 
     int cnt = 0;
     for (int i = 0 ; i<listSize ; i++)
     {
-	  if (listSize > 1)
-	  {
-		int index = i+1;
-		strPatientID = strPatientID + QString("%1").arg(index);
-	  }
+        if (listSize > 1)
+        {
+            int index = i+1;
+            strPatientID = strPatientID + QString("%1").arg(index);
+        }
 
         QString filePath = m_strlistPath.at(i);
 
@@ -162,17 +162,17 @@ void nki2mha_converter::SLT_Correct_NKI2DCM()
 
         if (extName == "scan" || extName == "SCAN")
         {		 
-		  if (bPatientIDExist)
-		  	corrFilePath = CorrectSingle_NKI2DCM(filePath.toLocal8Bit().constData(), strPatientID,strPatientName);		  
-		  else
-			corrFilePath = CorrectSingle_NKI2DCM(filePath.toLocal8Bit().constData());
+            if (bPatientIDExist)
+                corrFilePath = CorrectSingle_NKI2DCM(filePath.toLocal8Bit().constData(), strPatientID,strPatientName);		  
+            else
+                corrFilePath = CorrectSingle_NKI2DCM(filePath.toLocal8Bit().constData());
         }
         else if (extName == "mha" || extName == "MHA")
         {
-		  if (bPatientIDExist)
-			corrFilePath = CorrectSingle_MHA2DCM(filePath.toLocal8Bit().constData(), strPatientID,strPatientName);
-		  else
-            corrFilePath = CorrectSingle_MHA2DCM(filePath.toLocal8Bit().constData());			
+            if (bPatientIDExist)
+                corrFilePath = CorrectSingle_MHA2DCM(filePath.toLocal8Bit().constData(), strPatientID,strPatientName);
+            else
+                corrFilePath = CorrectSingle_MHA2DCM(filePath.toLocal8Bit().constData());			
         }
 
         if (corrFilePath.length() > 0 )
diff --git a/src/plastimatch/sys/CMakeLists.txt b/src/plastimatch/sys/CMakeLists.txt
index dbb1192..30b9183 100644
--- a/src/plastimatch/sys/CMakeLists.txt
+++ b/src/plastimatch/sys/CMakeLists.txt
@@ -5,7 +5,7 @@ project (src_plastimatch_sys)
 
 configure_file (
     ${CMAKE_CURRENT_SOURCE_DIR}/plmsys_config.h.in
-    ${PLM_BUILD_ROOT}/plmsys_config.h
+    ${CMAKE_BINARY_DIR}/plmsys_config.h
 )
 
 include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/src/plastimatch/test/CMakeLists.txt b/src/plastimatch/test/CMakeLists.txt
index 9542dd8..77738a4 100644
--- a/src/plastimatch/test/CMakeLists.txt
+++ b/src/plastimatch/test/CMakeLists.txt
@@ -169,10 +169,20 @@ if (PLM_CONFIG_BUILD_TEST_PROGRAMS)
 	${BUILD_ALWAYS} ${INSTALL_NEVER})
 
     # Test executable -- qt
+    if (Qt5_FOUND)
+      set (QT5_TEST_LIBRARIES Qt5::Network Qt5::Widgets Qt5::Gui Qt5::Core)
+      plm_add_executable (qt5_test qt_test.cxx
+	"${QT5_TEST_LIBRARIES}" "" 
+	${BUILD_ALWAYS} ${INSTALL_NEVER})
+    endif ()
     if (QT4_FOUND)
-	plm_add_executable (qt_test qt_test.cxx
-	    "${QT_LIBRARIES}" "" 
-	    ${BUILD_ALWAYS} ${INSTALL_NEVER})
+      set (QT4_TEST_INCLUDES ${PLASTIMATCH_INCLUDES} ${QT_QTGUI_INCLUDE_DIR}
+	${QT_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR})
+      set (QT4_TEST_LIBRARIES ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY})
+      plm_add_executable_v2 (qt4_test qt_test.cxx
+	"${QT4_TEST_INCLUDES}"
+	"${QT4_TEST_LIBRARIES}" "" 
+	${BUILD_ALWAYS} ${INSTALL_NEVER})
     endif ()
 
     # Test executable -- ransac
diff --git a/src/plastimatch/test/cpp_template_test.cxx b/src/plastimatch/test/cpp_template_test.cxx
index 7c47bd4..2a5c568 100644
--- a/src/plastimatch/test/cpp_template_test.cxx
+++ b/src/plastimatch/test/cpp_template_test.cxx
@@ -37,9 +37,12 @@ template < class G > void d (int x) {
 }
 
 /* Even more complex */
+#if defined (commentout)
+/* This doesn't compile on gcc 6.3 */
 template < class J, template<class J> class I> void h (J x) {
     I<J>::g (x);
 }
+#endif
 
 template < template<class J> class I, class J > void k (J x) {
     I<J>::g (x);
@@ -73,7 +76,9 @@ int main
     a<c>(x);
     G<int>::g (x);
     d< G<int> >(x);
+#if defined (commentout)
     h< int, G >(x);
+#endif
     k< G, int >(x);
 
     M<int> m;
diff --git a/src/plastimatch/test/cuda/CMakeLists.txt b/src/plastimatch/test/cuda/CMakeLists.txt
index 9c6836f..bafea13 100644
--- a/src/plastimatch/test/cuda/CMakeLists.txt
+++ b/src/plastimatch/test/cuda/CMakeLists.txt
@@ -8,12 +8,12 @@ set_directory_properties (PROPERTIES COMPILE_DEFINITIONS "")
 
 # Test executable -- cuda
 if (CUDA_FOUND)
-    cuda_compile (CUDA_TEST_WRAPPERS cuda_test.cu)
-    plm_add_executable (cuda_test "${CUDA_TEST_WRAPPERS}" 
-	"${CUDA_LIBRARIES}" "" 
-	${BUILD_ALWAYS} ${INSTALL_NEVER})
-    set_target_properties (cuda_test PROPERTIES LINKER_LANGUAGE CXX)
+  cuda_compile (CUDA_TEST_WRAPPERS cuda_test.cu)
+  plm_add_executable (cuda_test "${CUDA_TEST_WRAPPERS}" 
+    "${CUDA_LIBRARIES}" "" 
+    ${BUILD_ALWAYS} ${INSTALL_NEVER})
+  set_target_properties (cuda_test PROPERTIES LINKER_LANGUAGE CXX)
 
-    # Test executable -- cuda_tex_test
-    add_subdirectory (CUDA_tex_test)
+  # Test executable -- cuda_tex_test
+  add_subdirectory (CUDA_tex_test)
 endif ()
diff --git a/src/plastimatch/test/qt_test.cxx b/src/plastimatch/test/qt_test.cxx
index ae93022..917a5df 100644
--- a/src/plastimatch/test/qt_test.cxx
+++ b/src/plastimatch/test/qt_test.cxx
@@ -3,19 +3,39 @@
    ----------------------------------------------------------------------- */
 #include "plm_config.h"
 #include <iostream>
+#include <QtGlobal>
 #include <QApplication>
+#include <QDebug>
 #include <QLabel>
+#if QT_VERSION >= QT_VERSION_CHECK (5,0,0)
+#include <QSslSocket>
+#endif
 
 int
 main (int argc, char **argv)
 {
     // Display designer path
-    QStringList paths = QCoreApplication::libraryPaths(); for (QStringList::iterator it = paths.begin(); it!=paths.end(); it++) { std::cout << "Looking for plugins at path: " << it->toStdString() << std::endl; } 
+    QStringList paths = QCoreApplication::libraryPaths();
+    for (QStringList::iterator it = paths.begin(); it!=paths.end(); it++) {
+        std::cout << "Looking for plugins at path: "
+            << it->toStdString() << std::endl;
+    }
 
     QApplication app(argc, argv);
     QLabel *label = new QLabel("Hello World!");
   
     label->show();
 
+    qDebug() << "Qt version is " << qVersion();
+
+#if QT_VERSION >= QT_VERSION_CHECK (5,4,0)
+    qDebug() << "Qt was built with SSL "
+        << QSslSocket::sslLibraryBuildVersionString();
+#endif
+#if QT_VERSION >= QT_VERSION_CHECK (5,0,0)
+    qDebug() << "Qt is linked with SSL "
+        << QSslSocket::sslLibraryVersionString();
+#endif
+    
     return app.exec();
 }
diff --git a/src/plastimatch/util/CMakeLists.txt b/src/plastimatch/util/CMakeLists.txt
index c447de0..56937ec 100644
--- a/src/plastimatch/util/CMakeLists.txt
+++ b/src/plastimatch/util/CMakeLists.txt
@@ -5,11 +5,11 @@ project (src_plastimatch_util)
 
 configure_file (
     ${CMAKE_CURRENT_SOURCE_DIR}/plmutil_config.h.in
-    ${PLM_BUILD_ROOT}/plmutil_config.h
+    ${CMAKE_BINARY_DIR}/plmutil_config.h
 )
 
 include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
-include_directories (AFTER ${CMAKE_SOURCE_DIR}/libs/devillard)
+include_directories (AFTER ${DEVILLARD_INCLUDE_DIR})
 
 ##-----------------------------------------------------------------------------
 ##  SOURCE FILES
diff --git a/src/plastimatch/util/rt_study_warp.cxx b/src/plastimatch/util/rt_study_warp.cxx
index f41a5f6..fc47747 100644
--- a/src/plastimatch/util/rt_study_warp.cxx
+++ b/src/plastimatch/util/rt_study_warp.cxx
@@ -242,6 +242,17 @@ rt_study_warp (Rt_study *rt_study, Plm_file_format file_type, Warp_parms *parms)
     rt_study->set_dose_metadata (parms->m_dose_metadata);
     rt_study->set_rtstruct_metadata (parms->m_rtstruct_metadata);
 
+    // UIDs are handled differently when saving.  Normally they are 
+    // generated fresh, you need to explicitly force
+    if (!parms->retain_study_uids) {
+        rt_study->generate_new_study_uids ();
+    }
+    if (parms->image_series_uid_forced) {
+        const std::string& series_uid =
+            rt_study->get_image_metadata()->get_metadata (0x0020, 0x000e);
+        rt_study->force_ct_series_uid (series_uid);
+    }
+    
     /* Load transform */
     if (parms->xf_in_fn != "") {
         lprintf ("Loading xform (%s)\n", parms->xf_in_fn.c_str());
diff --git a/src/plastimatch/util/warp_parms.h b/src/plastimatch/util/warp_parms.h
index 7d563cb..79c3643 100644
--- a/src/plastimatch/util/warp_parms.h
+++ b/src/plastimatch/util/warp_parms.h
@@ -77,7 +77,9 @@ public:
     std::vector<std::string> m_image_metadata;
     std::vector<std::string> m_dose_metadata;
     std::vector<std::string> m_rtstruct_metadata;
-
+    bool retain_study_uids;
+    bool image_series_uid_forced;
+    
 public:
     Warp_parms () {
 
@@ -103,6 +105,8 @@ public:
 	use_itk = 0;
 	simplify_perc = 0;
 	xor_contours = false;
+        retain_study_uids = false;
+        image_series_uid_forced = false;
     }
 };
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/plastimatch.git



More information about the debian-med-commit mailing list