diff --git a/Code/Algorithms/Plastimatch/CMakeLists.txt b/Code/Algorithms/Plastimatch/CMakeLists.txt index b89f3ba..dec557a 100644 --- a/Code/Algorithms/Plastimatch/CMakeLists.txt +++ b/Code/Algorithms/Plastimatch/CMakeLists.txt @@ -1,13 +1,14 @@ MAP_CREATE_MODULE(MAPAlgorithmsPlastimatch DEPENDS MAPAlgorithms MAPUtilities MAPIO) MAP_CREATE_MODULE_TESTS(MAPAlgorithmsPlastimatch DEPENDS MAPAlgorithmsITK PACKAGE_DEPENDS Litmus HEADER_TESTS) IF (BUILD_TESTING) ADD_EXECUTABLE(mapDummyPlastimatch "test/mapDummyPlastimatch.cpp") SET_TARGET_PROPERTIES(mapDummyPlastimatch PROPERTIES OUTPUT_NAME "plastimatch") TARGET_LINK_LIBRARIES(mapDummyPlastimatch MAPCore MAPAlgorithmsPlastimatch LitmusCommon) ENDIF (BUILD_TESTING) MAP_DEFINE_DEPLOYED_ALGORITHM(PlmParameterFileCLI2DRegistration PROFILE "deployed/PlmParameterFileCLI2DRegistration.profile" FILES "deployed/mapPlmParameterFileCLI2DRegistration.cpp" MODULE_DEPENDS MAPAlgorithmsPlastimatch MAPDeployment) MAP_DEFINE_DEPLOYED_ALGORITHM(PlmParameterFileCLI3DRegistration PROFILE "deployed/PlmParameterFileCLI3DRegistration.profile" FILES "deployed/mapPlmParameterFileCLI3DRegistration.cpp" MODULE_DEPENDS MAPAlgorithmsPlastimatch MAPDeployment) MAP_DEFINE_DEPLOYED_ALGORITHM(PlmBSplineCLI2DRegistration PROFILE "deployed/PlmBSplineCLI2DRegistration.profile" FILES "deployed/mapPlmBSplineCLI2DRegistration.cpp" MODULE_DEPENDS MAPAlgorithmsPlastimatch MAPDeployment) MAP_DEFINE_DEPLOYED_ALGORITHM(PlmBSplineCLI3DRegistration PROFILE "deployed/PlmBSplineCLI3DRegistration.profile" FILES "deployed/mapPlmBSplineCLI3DRegistration.cpp" MODULE_DEPENDS MAPAlgorithmsPlastimatch MAPDeployment) +MAP_DEFINE_DEPLOYED_ALGORITHM(PlmJOMBSplineCLI3DRegistration PROFILE "deployed/PlmJOMBSplineCLI3DRegistration.profile" FILES "deployed/mapJOMPlmBSplineCLI3DRegistration.cpp" MODULE_DEPENDS MAPAlgorithmsPlastimatch MAPDeployment) diff --git a/Code/Algorithms/Plastimatch/boxed/mapJOMPlmBSplineCLIRegistrationAlgorithm.h b/Code/Algorithms/Plastimatch/boxed/mapJOMPlmBSplineCLIRegistrationAlgorithm.h new file mode 100644 index 0000000..0f14a32 --- /dev/null +++ b/Code/Algorithms/Plastimatch/boxed/mapJOMPlmBSplineCLIRegistrationAlgorithm.h @@ -0,0 +1,119 @@ +// ----------------------------------------------------------------------- +// MatchPoint - DKFZ translational registration framework +// +// Copyright (c) German Cancer Research Center (DKFZ), +// Software development for Integrated Diagnostics and Therapy (SIDT). +// ALL RIGHTS RESERVED. +// See mapCopyright.txt or +// http://www.dkfz.de/en/sidt/projects/MatchPoint/copyright.html +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notices for more information. +// +//------------------------------------------------------------------------ + + +#ifndef __JOM_PLM_BSPLINE_CLI_REGISTRATION_ALGORITHM_H +#define __JOM_PLM_BSPLINE_CLI_REGISTRATION_ALGORITHM_H + +//MatchPoint +#include "mapContinuous.h" + +#include "mapPlmCLIRegistrationAlgorithmBase.h" +#include "mapClassMacros.h" + +namespace map +{ + namespace algorithm + { + namespace boxed + { + + /*! @class JOMPlmBSplineCLIRegistrationAlgorithm + @brief The class is a boxed plastimatch BSpline registration algorithm (using CLI, in many aspects similar to the SLICER PLastimatch BSpline plugin). + The algorithm has three stages (1. rigid registration, 2./3. BSpline registration). It uses plastimatch via CLI and uses auto + generated parameter files. + @ingroup Algorithms + @ingroup Plastimatch + @ingroup Boxed + */ + template + class JOMPlmBSplineCLIRegistrationAlgorithm : public + plastimatch::CLIRegistrationAlgorithmBase + { + public: + typedef JOMPlmBSplineCLIRegistrationAlgorithm Self; + typedef plastimatch::CLIRegistrationAlgorithmBase + Superclass; + + typedef ::itk::SmartPointer Pointer; + typedef ::itk::SmartPointer ConstPointer; + itkTypeMacro(JOMPlmBSplineCLIRegistrationAlgorithm, CLIRegistrationAlgorithmBase); + mapNewAlgorithmMacro(Self); + + typedef typename Superclass::UIDType UIDType; + typedef typename Superclass::UIDPointer UIDPointer; + + typedef typename Superclass::TargetImageType TargetImageType; + typedef typename Superclass::MovingImageType MovingImageType; + typedef typename Superclass::MovingRepresentationDescriptorType MovingRepresentationDescriptorType; + typedef typename Superclass::TargetRepresentationDescriptorType TargetRepresentationDescriptorType; + + typedef typename Superclass::RegistrationPointer RegistrationPointer; + typedef typename Superclass::RegistrationType RegistrationType; + typedef typename Superclass::FieldRepRequirement FieldRepRequirement; + + typedef typename Superclass::MetaPropertyType MetaPropertyType; + typedef typename Superclass::MetaPropertyPointer MetaPropertyPointer; + typedef typename Superclass::MetaPropertyNameType MetaPropertyNameType; + typedef typename Superclass::MetaPropertyVectorType MetaPropertyVectorType; + + protected: + JOMPlmBSplineCLIRegistrationAlgorithm(); + virtual ~JOMPlmBSplineCLIRegistrationAlgorithm(); + + /*! @reimplemented*/ + virtual void configureAlgorithm(); + + /*! @reimplemented */ + virtual void prepConfigurationPLM(); + + // MetaPropertyAlgorithmBase + /*! @reimplemented*/ + virtual void compileInfos(MetaPropertyVectorType& infos) const; + + /*! @reimplemented*/ + virtual MetaPropertyPointer doGetProperty(const MetaPropertyNameType& name) const; + + /*! @reimplemented*/ + virtual void doSetProperty(const MetaPropertyNameType& name, const MetaPropertyType* pProperty); + + bool _alignCenter; + unsigned int _s1_maxIterations; + ::map::core::String _s1_subsampling; + unsigned int _s2_maxIterations; + ::map::core::String _s2_subsampling; + ::map::core::String _s2_gridSpacing; + double _s2_regularization; + bool _doStage3; + unsigned int _s3_maxIterations; + ::map::core::String _s3_subsampling; + ::map::core::String _s3_gridSpacing; + double _s3_regularization; + + private: + + JOMPlmBSplineCLIRegistrationAlgorithm(const Self& source); //purposely not implemented + void operator=(const Self&); //purposely not implemented + }; + + } + } +} + +#ifndef MatchPoint_MANUAL_TPP +#include "mapJOMPlmBSplineCLIRegistrationAlgorithm.tpp" +#endif + +#endif diff --git a/Code/Algorithms/Plastimatch/boxed/mapJOMPlmBSplineCLIRegistrationAlgorithm.tpp b/Code/Algorithms/Plastimatch/boxed/mapJOMPlmBSplineCLIRegistrationAlgorithm.tpp new file mode 100644 index 0000000..7b88605 --- /dev/null +++ b/Code/Algorithms/Plastimatch/boxed/mapJOMPlmBSplineCLIRegistrationAlgorithm.tpp @@ -0,0 +1,306 @@ +// ----------------------------------------------------------------------- +// MatchPoint - DKFZ translational registration framework +// +// Copyright (c) German Cancer Research Center (DKFZ), +// Software development for Integrated Diagnostics and Therapy (SIDT). +// ALL RIGHTS RESERVED. +// See mapCopyright.txt or +// http://www.dkfz.de/en/sidt/projects/MatchPoint/copyright.html +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notices for more information. +// +//------------------------------------------------------------------------ + + +#ifndef __JOM_PLM_BSPLINE_CLI_REGISTRATION_ALGORITHM_TPP +#define __JOM_PLM_BSPLINE_CLI_REGISTRATION_ALGORITHM_TPP + +namespace map +{ + namespace algorithm + { + namespace boxed + { + + template + JOMPlmBSplineCLIRegistrationAlgorithm:: + JOMPlmBSplineCLIRegistrationAlgorithm() + { + }; + + template + JOMPlmBSplineCLIRegistrationAlgorithm:: + ~JOMPlmBSplineCLIRegistrationAlgorithm() + { + }; + + template + void + JOMPlmBSplineCLIRegistrationAlgorithm:: + configureAlgorithm() + { + Superclass::configureAlgorithm(); + if (this->isFirstConfiguration()) + { + _alignCenter = true; + _s1_maxIterations = 30; + _s1_subsampling = "4 4 2"; + _s2_maxIterations = 50; + _s2_subsampling = "4 4 4"; + _s2_gridSpacing = "35 35 35"; + _s2_regularization = 0.005; + _doStage3 = true; + _s3_maxIterations = 100; + _s3_subsampling = "2 2 2"; + _s3_gridSpacing = "11 11 11"; + _s3_regularization = 0.005; + } + }; + + template + void + JOMPlmBSplineCLIRegistrationAlgorithm:: + compileInfos(MetaPropertyVectorType& infos) const + { + Superclass::compileInfos(infos); + +#ifndef MAP_SEAL_ALGORITHMS + infos.push_back(map::algorithm::MetaPropertyInfo::New("EnableStage_0", typeid(bool), true, + true)); + infos.push_back(map::algorithm::MetaPropertyInfo::New("Stage1.MaxIterations", typeid(unsigned int), true, + true)); + infos.push_back(map::algorithm::MetaPropertyInfo::New("Stage1.SubsamplingFactor", typeid(map::core::String), + true, true)); + infos.push_back(map::algorithm::MetaPropertyInfo::New("Stage2.MaxIterations", typeid(unsigned int), true, + true)); + infos.push_back(map::algorithm::MetaPropertyInfo::New("Stage2.SubsamplingFactor", typeid(map::core::String), + true, true)); + infos.push_back(map::algorithm::MetaPropertyInfo::New("Stage2.GridSpacing", typeid(map::core::String), + true, true)); + infos.push_back(map::algorithm::MetaPropertyInfo::New("Stage2.RegularizationLambda", typeid(double), + true, true)); + infos.push_back(map::algorithm::MetaPropertyInfo::New("EnableStage_3", typeid(bool), true, + true)); + infos.push_back(map::algorithm::MetaPropertyInfo::New("Stage3.MaxIterations", typeid(unsigned int), true, + true)); + infos.push_back(map::algorithm::MetaPropertyInfo::New("Stage3.SubsamplingFactor", typeid(map::core::String), + true, true)); + infos.push_back(map::algorithm::MetaPropertyInfo::New("Stage3.GridSpacing", typeid(map::core::String), + true, true)); + infos.push_back(map::algorithm::MetaPropertyInfo::New("Stage3.RegularizationLambda", typeid(double), + true, true)); +#endif + }; + + template + typename JOMPlmBSplineCLIRegistrationAlgorithm::MetaPropertyPointer + JOMPlmBSplineCLIRegistrationAlgorithm:: + doGetProperty(const MetaPropertyNameType& name) const + { + MetaPropertyPointer spResult; + + if (name == "EnableStage_0") + { + spResult = map::core::MetaProperty::New(this->_alignCenter); + } + else if (name == "Stage1.MaxIterations") + { + spResult = map::core::MetaProperty::New(this->_s1_maxIterations); + } + else if (name == "Stage1.SubsamplingFactor") + { + spResult = map::core::MetaProperty::New(this->_s1_subsampling); + } + else if (name == "Stage2.MaxIterations") + { + spResult = map::core::MetaProperty::New(this->_s2_maxIterations); + } + else if (name == "Stage2.SubsamplingFactor") + { + spResult = map::core::MetaProperty::New(this->_s2_subsampling); + } + else if (name == "Stage2.GridSpacing") + { + spResult = map::core::MetaProperty::New(this->_s2_gridSpacing); + } + else if (name == "Stage2.RegularizationLambda") + { + spResult = map::core::MetaProperty::New(this->_s2_regularization); + } + else if (name == "EnableStage_3") + { + spResult = map::core::MetaProperty::New(this->_doStage3); + } + else if (name == "Stage3.MaxIterations") + { + spResult = map::core::MetaProperty::New(this->_s3_maxIterations); + } + else if (name == "Stage3.SubsamplingFactor") + { + spResult = map::core::MetaProperty::New(this->_s3_subsampling); + } + else if (name == "Stage3.GridSpacing") + { + spResult = map::core::MetaProperty::New(this->_s3_gridSpacing); + } + else if (name == "Stage3.RegularizationLambda") + { + spResult = map::core::MetaProperty::New(this->_s3_regularization); + } + else + { + spResult = Superclass::doGetProperty(name); + } + + return spResult; + }; + + template + void + JOMPlmBSplineCLIRegistrationAlgorithm:: + doSetProperty(const MetaPropertyNameType& name, const MetaPropertyType* pProperty) + { + if (name == "EnableStage_0") + { + bool enable; + map::core::unwrapMetaProperty(pProperty, enable); + this->_alignCenter = enable; + } + else if (name == "Stage1.MaxIterations") + { + unsigned int iterations; + map::core::unwrapMetaProperty(pProperty, iterations); + this->_s1_maxIterations = iterations; + } + else if (name == "Stage1.SubsamplingFactor") + { + core::String factorStr; + map::core::unwrapMetaProperty(pProperty, factorStr); + this->_s1_subsampling = factorStr; + } + else if (name == "Stage2.MaxIterations") + { + unsigned int iterations; + map::core::unwrapMetaProperty(pProperty, iterations); + this->_s2_maxIterations = iterations; + } + else if (name == "Stage2.SubsamplingFactor") + { + core::String factorStr; + map::core::unwrapMetaProperty(pProperty, factorStr); + this->_s2_subsampling = factorStr; + } + else if (name == "Stage2.GridSpacing") + { + core::String gridStr; + map::core::unwrapMetaProperty(pProperty, gridStr); + this->_s2_gridSpacing = gridStr; + } + else if (name == "Stage2.RegularizationLambda") + { + double lambda; + map::core::unwrapMetaProperty(pProperty, lambda); + this->_s2_regularization = lambda; + } + else if (name == "EnableStage_3") + { + bool enable; + map::core::unwrapMetaProperty(pProperty, enable); + this->_doStage3 = enable; + } + else if (name == "Stage3.MaxIterations") + { + unsigned int iterations; + map::core::unwrapMetaProperty(pProperty, iterations); + this->_s2_maxIterations = iterations; + } + else if (name == "Stage3.SubsamplingFactor") + { + core::String factorStr; + map::core::unwrapMetaProperty(pProperty, factorStr); + this->_s3_subsampling = factorStr; + } + else if (name == "Stage3.GridSpacing") + { + core::String gridStr; + map::core::unwrapMetaProperty(pProperty, gridStr); + this->_s3_gridSpacing = gridStr; + } + else if (name == "Stage3.RegularizationLambda") + { + double lambda; + map::core::unwrapMetaProperty(pProperty, lambda); + this->_s3_regularization = lambda; + } + else + { + Superclass::doSetProperty(name,pProperty); + } + } + + template + void + JOMPlmBSplineCLIRegistrationAlgorithm:: + prepConfigurationPLM() + { + this->_configurationPLM.clear(); + this->_configurationPLM.push_back( + algorithm::plastimatch::ParameterStageType()); //add global section, will be filled by base class + + algorithm::plastimatch::ParameterStageType map; + ///////////////////////////////// + //Setup Stage 0: align center + ///////////////////////////////// + if (this->_alignCenter) + { + map["xform"] = plastimatch::ParamGenerator().add("align_center"); + this->_configurationPLM.push_back(map); + } + ///////////////////////////////// + //Setup Stage 1: rigid + ///////////////////////////////// + map.clear(); + map["metric"] = plastimatch::ParamGenerator().add("mse"); + map["xform"] = plastimatch::ParamGenerator().add("rigid"); + map["optim"] = plastimatch::ParamGenerator().add("versor"); + map["impl"] = plastimatch::ParamGenerator().add("itk"); + map["max_its"] = plastimatch::ParamGenerator().add(this->_s1_maxIterations); + map["res"] = plastimatch::ParamGenerator().add(this->_s1_subsampling); + this->_configurationPLM.push_back(map); + + ///////////////////////////////// + //Setup Stage 2: BSpline + ///////////////////////////////// + map.clear(); + map["xform"] = plastimatch::ParamGenerator().add("bspline"); + map["optim"] = plastimatch::ParamGenerator().add("lbfgsb"); + map["impl"] = plastimatch::ParamGenerator().add("plastimatch"); + map["threading"] = plastimatch::ParamGenerator().add("openmp"); + map["metric"] = plastimatch::ParamGenerator().add("mse"); + map["max_its"] = plastimatch::ParamGenerator().add(this->_s2_maxIterations); + map["regularization_lambda"] = plastimatch::ParamGenerator().add(this->_s2_regularization); + map["res"] = plastimatch::ParamGenerator().add(this->_s2_subsampling); + map["grid_spac"] = plastimatch::ParamGenerator().add(this->_s2_gridSpacing); + this->_configurationPLM.push_back(map); + + ///////////////////////////////// + //Setup Stage 3: BSpline 2 + ///////////////////////////////// + if(this->_doStage3) + { + map.clear(); + map["max_its"] = plastimatch::ParamGenerator().add(this->_s3_maxIterations); + map["regularization_lambda"] = plastimatch::ParamGenerator().add(this->_s3_regularization); + map["res"] = plastimatch::ParamGenerator().add(this->_s3_subsampling); + map["grid_spac"] = plastimatch::ParamGenerator().add(this->_s3_gridSpacing); + this->_configurationPLM.push_back(map); + } + } + + } // end namespace boxed + } // end namespace algorithm +} // end namespace map + +#endif diff --git a/Code/Algorithms/Plastimatch/deployed/PlmJOMBSplineCLI3DRegistration.profile b/Code/Algorithms/Plastimatch/deployed/PlmJOMBSplineCLI3DRegistration.profile new file mode 100644 index 0000000..6291e11 --- /dev/null +++ b/Code/Algorithms/Plastimatch/deployed/PlmJOMBSplineCLI3DRegistration.profile @@ -0,0 +1,16 @@ +SET(ALGORITHM_PROFILE_UID_Namespace "de.dkfz.matchpoint.plastimatch.cli.jom") +SET(ALGORITHM_PROFILE_UID_Name "JOM.Plastimatch.BSpline.3D") +SET(ALGORITHM_PROFILE_UID_Version "1.0.0") + +SET(ALGORITHM_PROFILE_Description "This is a MatchPoint wrapper for the registration tool Plastimatch for 3D images for the joint organ motion meeting. The algorithm is in many aspects similar to the SLICER PLastimatch BSpline plugin. The algorithm has four stages (0. center alignment, 1. rigid registration, 2./3. BSpline registration) It is configured to preform a B-Spline registration on the image. REMARK: You need the plastimatch command line tool installed on this computer to run this algorithm. You can specify the plastimatch location 1) via the algorithm property PlastimatchDirectory or 2) via setting the environment variable MAP_PLASTIMATCH_PATH..") +SET(ALGORITHM_PROFILE_Contact "Ralf Floca (MatchPoint wrapper)\; sbr@dkfz-heidelberg.de") +SET(ALGORITHM_PROFILE_Contact "Plastimatch project homepage: www.plastimatch.org") + +SET(ALGORITHM_PROFILE_DataType "Image") +SET(ALGORITHM_PROFILE_DimMoving "3") +SET(ALGORITHM_PROFILE_ModalityMoving "any (mono modal)") +SET(ALGORITHM_PROFILE_DimTarget "3") +SET(ALGORITHM_PROFILE_ModalityTarget "any (mono modal)") +SET(ALGORITHM_PROFILE_TransformModel "B-Spline") +SET(ALGORITHM_PROFILE_TransformDomain "local") +SET(ALGORITHM_PROFILE_Keywords "plastimatch" "wrapper" "mono modal" "bspline") \ No newline at end of file diff --git a/Code/Algorithms/Plastimatch/deployed/mapJOMPlmBSplineCLI3DRegistration.cpp b/Code/Algorithms/Plastimatch/deployed/mapJOMPlmBSplineCLI3DRegistration.cpp new file mode 100644 index 0000000..b772f3f --- /dev/null +++ b/Code/Algorithms/Plastimatch/deployed/mapJOMPlmBSplineCLI3DRegistration.cpp @@ -0,0 +1,30 @@ +// ----------------------------------------------------------------------- +// MatchPoint - DKFZ translational registration framework +// +// Copyright (c) German Cancer Research Center (DKFZ), +// Software development for Integrated Diagnostics and Therapy (SIDT). +// ALL RIGHTS RESERVED. +// See mapCopyright.txt or +// http://www.dkfz.de/en/sidt/projects/MatchPoint/copyright.html +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notices for more information. +// +//------------------------------------------------------------------------ + +#include "mapDeploymentDLLHelper.h" +#include "mapDiscreteElements.h" +#include "mapContinuousElements.h" +#include "mapConfigure.h" + +#include "mapJOMPlmBSplineCLIRegistrationAlgorithm.h" + +#include "PlmJOMBSplineCLI3DRegistration_ProfileResource.h" + +typedef map::core::discrete::Elements<3>::InternalImageType ImageType; +typedef map::core::continuous::Elements<3>::InternalPointSetType PointSetType; +typedef map::algorithm::boxed::JOMPlmBSplineCLIRegistrationAlgorithm +AlgorithmType; + +mapDeployAlgorithmMacro(AlgorithmType); \ No newline at end of file diff --git a/Code/Algorithms/Plastimatch/files.cmake b/Code/Algorithms/Plastimatch/files.cmake index 192b4f2..a69a7aa 100644 --- a/Code/Algorithms/Plastimatch/files.cmake +++ b/Code/Algorithms/Plastimatch/files.cmake @@ -1,21 +1,23 @@ SET(CPP_FILES source/mapPlmAlgorithmHelper.cpp ) SET(H_FILES include/mapPlmCLIRegistrationAlgorithmBase.h include/mapPlmParameterFileRegistrationAlgorithm.h include/mapPlmAlgorithmHelper.h boxed/mapPlmBSplineCLIRegistrationAlgorithm.h +boxed/mapJOMPlmBSplineCLIRegistrationAlgorithm.h ) SET(TPP_FILES include/mapPlmCLIRegistrationAlgorithmBase.tpp include/mapPlmParameterFileRegistrationAlgorithm.tpp boxed/mapPlmBSplineCLIRegistrationAlgorithm.tpp +boxed/mapJOMPlmBSplineCLIRegistrationAlgorithm.tpp ) SET(TEST_CPP_FILES test/mapAlgorithmsPlastimatchTests.cpp test/mapPlmParameterFileRegistrationAlgorithmTest.cpp ) \ No newline at end of file