diff --git a/Modules/Components/Elastix/ModuleElastix.cmake b/Modules/Components/Elastix/ModuleElastix.cmake index 72927257dc086361750fb24c3b25bb6b98de7330..4a999b932ac0e6b5e9c40f575987ce854f799828 100644 --- a/Modules/Components/Elastix/ModuleElastix.cmake +++ b/Modules/Components/Elastix/ModuleElastix.cmake @@ -1,13 +1,6 @@ # Module that exposes old elastix as an ITK filter set( MODULE ModuleElastix ) -if( NOT EXISTS ${ELASTIX_USE_FILE} ) - set( ELASTIX_USE_FILE ) - message( FATAL_ERROR "${MODULE} could not find ELASTIX_USE_FILE. Use the SuperBuild or manually point the ELASTIX_USE_FILE CMake variable to the UseElastix.cmake file in the root of your elastix build tree." ) -endif() - -include( ${ELASTIX_USE_FILE} ) - # If OpenMP is supported, elastix will have beeen compiled with # OpenMP flags, and we need to add them here as well find_package( OpenMP ) @@ -16,13 +9,22 @@ if( OPENMP_FOUND ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}" ) endif() +if( NOT EXISTS ${ELASTIX_USE_FILE} ) + option( ELASTIX_USE_FILE "NOT_FOUND" ) + message( FATAL_ERROR "${MODULE} could not find ELASTIX_USE_FILE. Use the SuperBuild or manually point the ELASTIX_USE_FILE CMake variable to the UseElastix.cmake file in the root of your local elastix build tree." ) +endif() + # Export include files -set( ${MODULE}_INCLUDE_DIRS - ${${MODULE}_SOURCE_DIR}/include -) +include( ${ELASTIX_USE_FILE} ) # Export libraries set( ${MODULE}_LIBRARIES elastix transformix ) + +# Export tests +set( ${MODULE}_TESTS + elxElastixFilterTest.cxx + elxTransformixFilterTest.cxx +) diff --git a/Modules/Components/Elastix/include/elxElastixFilter.h b/Modules/Components/Elastix/include/elxElastixFilter.h deleted file mode 100644 index 61a263c0c26f2ddec07432b73df39552a282e61b..0000000000000000000000000000000000000000 --- a/Modules/Components/Elastix/include/elxElastixFilter.h +++ /dev/null @@ -1,251 +0,0 @@ -#ifndef ElastixFilter_h -#define ElastixFilter_h - -// ITK -#include "itkImageSource.h" - -// Elastix -#include "elxElastixMain.h" - -// SuperElastix -#include "elxMacro.h" -#include "elxParameterObject.h" - -/** - * Elastix registration library exposed as an ITK filter. - */ - -namespace selx { - -// PixelType traits for writing types as strings to parameter files -template < typename T > -struct TypeName -{ - static const char* ToString() - { - itkGenericExceptionMacro( "Pixel type \"" << typeid(T).name() << "\" not supported by elastix." ) - } -}; - -template <> -struct TypeName< char > -{ - static const char* ToString() - { - return "char"; - } -}; - -template <> -struct TypeName< unsigned char > -{ - static const char* ToString() - { - return "unsigned char"; - } -}; - -template <> -struct TypeName< short > -{ - static const char* ToString() - { - return "short"; - } -}; - -template <> -struct TypeName< unsigned short > -{ - static const char* ToString() - { - return "unsigned short"; - } -}; - -template <> -struct TypeName< int > -{ - static const char* ToString() - { - return "int"; - } -}; - -template <> -struct TypeName< unsigned int > -{ - static const char* ToString() - { - return "unsigned int"; - } -}; - -template <> -struct TypeName< long > -{ - static const char* ToString() - { - return "long"; - } -}; - -template <> -struct TypeName< unsigned long > -{ - static const char* ToString() - { - return "unsigned long"; - } -}; - -template <> -struct TypeName< float > -{ - static const char* ToString() - { - return "float"; - } -}; - -template <> -struct TypeName< double > -{ - static const char* ToString() - { - return "double"; - } -}; - -template< typename TFixedImage, - typename TMovingImage > -class ElastixFilter : public itk::ImageSource< TFixedImage > -{ -public: - - elxNewMacro( ElastixFilter, itk::ImageSource ); - - typedef elastix::ElastixMain ElastixMainType; - typedef ElastixMainType::Pointer ElastixMainPointer; - typedef std::vector< ElastixMainPointer > ElastixMainVectorType; - typedef ElastixMainType::ObjectPointer ElastixMainObjectPointer; - - typedef ElastixMainType::FlatDirectionCosinesType FlatDirectionCosinesType; - - typedef ElastixMainType::ArgumentMapType ArgumentMapType; - typedef ArgumentMapType::value_type ArgumentMapEntryType; - - typedef itk::ProcessObject::DataObjectIdentifierType DataObjectIdentifierType; - typedef itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType; - typedef itk::ProcessObject::NameArray InputNameArrayType; - - typedef ElastixMainType::DataObjectContainerType DataObjectContainerType; - typedef ElastixMainType::DataObjectContainerPointer DataObjectContainerPointer; - typedef DataObjectContainerType::Iterator DataObjectContainerIterator; - - typedef ParameterObject::ParameterMapVectorType ParameterMapVectorType; - typedef ParameterObject::ParameterMapType ParameterMapType; - typedef ParameterObject::ParameterValueVectorType ParameterValueVectorType; - typedef ParameterObject::Pointer ParameterObjectPointer; - typedef ParameterObject::ConstPointer ParameterObjectConstPointer; - - typedef typename TFixedImage::Pointer FixedImagePointer; - typedef typename TMovingImage::Pointer MovingImagePointer; - - itkStaticConstMacro( FixedImageDimension, unsigned int, TFixedImage::ImageDimension ); - itkStaticConstMacro( MovingImageDimension, unsigned int, TMovingImage::ImageDimension ); - - void SetFixedImage( FixedImagePointer fixedImage ); - void SetFixedImage( DataObjectContainerPointer fixedImages ); - void AddFixedImage( FixedImagePointer fixedImage ); - - void SetMovingImage( MovingImagePointer movingImages ); - void SetMovingImage( DataObjectContainerPointer movingImages ); - void AddMovingImage( MovingImagePointer movingImage ); - - void SetFixedMask( FixedImagePointer fixedMask ); - void SetFixedMask( DataObjectContainerPointer fixedMasks ); - void AddFixedMask( FixedImagePointer fixedMask ); - void RemoveFixedMask( void ); - - void SetMovingMask( MovingImagePointer movingMask ); - void SetMovingMask( DataObjectContainerPointer movingMasks ); - void AddMovingMask( MovingImagePointer movingMask ); - void RemoveMovingMask( void ); - - void SetParameterObject( ParameterObjectPointer parameterObject ); - ParameterObjectPointer GetTransformParameters( void ); - - itkSetMacro( FixedMeshFileName, std::string ); - itkGetConstMacro( FixedMeshFileName, std::string ); - void RemoveFixedMeshFileName( void ) { this->SetFixedMeshFileName( std::string() ); }; - - itkSetMacro( MovingMeshFileName, std::string ); - itkGetConstMacro( MovingMeshFileName, std::string ); - void RemoveMovingMeshFileName( void ) { this->SetMovingMeshFileName( std::string() ); }; - - itkSetMacro( OutputDirectory, std::string ); - itkGetConstMacro( OutputDirectory, std::string ); - void RemoveOutputDirectory() { this->m_OutputDirectory = std::string(); }; - - void SetLogFileName( std::string logFileName ) - { - this->m_LogFileName = logFileName; - this->LogToFileOn(); - this->Modified(); - } - - itkGetConstMacro( LogFileName, std::string ); - - void RemoveLogFileName( void ) { - this->m_LogFileName = std::string(); - this->LogToFileOff(); - }; - - itkSetMacro( LogToConsole, bool ); - itkGetConstMacro( LogToConsole, bool ); - itkBooleanMacro( LogToConsole ); - - itkSetMacro( LogToFile, bool ); - itkGetConstMacro( LogToFile, bool ); - itkBooleanMacro( LogToFile ); - - FixedImagePointer GetOutput( void ); - -protected: - - void GenerateData( void ) ITK_OVERRIDE; - -private: - - ElastixFilter(); - - void AddInputAutoIncrementName( DataObjectIdentifierType key, itk::DataObject* input ); - - bool IsInputType( DataObjectIdentifierType inputType, DataObjectIdentifierType inputName ); - void RemoveInputType( DataObjectIdentifierType inputName ); - - // TODO: When set to true, ReleaseDataFlag should also touch these containers - DataObjectContainerPointer m_FixedImageContainer; - DataObjectContainerPointer m_MovingImageContainer; - DataObjectContainerPointer m_FixedMaskContainer; - DataObjectContainerPointer m_MovingMaskContainer; - - std::string m_FixedMeshFileName; - std::string m_MovingMeshFileName; - - std::string m_OutputDirectory; - std::string m_LogFileName; - - bool m_LogToConsole; - bool m_LogToFile; - -}; - -} // namespace selx - -#ifndef ITK_MANUAL_INSTANTIATION -#include "elxElastixFilter.hxx" -#endif - -#endif // ElastixFilter_h \ No newline at end of file diff --git a/Modules/Components/Elastix/include/elxElastixFilter.hxx b/Modules/Components/Elastix/include/elxElastixFilter.hxx deleted file mode 100644 index 01132cab8afa11973f1701af653c7257a8114f46..0000000000000000000000000000000000000000 --- a/Modules/Components/Elastix/include/elxElastixFilter.hxx +++ /dev/null @@ -1,542 +0,0 @@ -#ifndef ElastixFilter_hxx -#define ElastixFilter_hxx - -namespace selx { - -template< typename TFixedImage, typename TMovingImage > -ElastixFilter< TFixedImage, TMovingImage > -::ElastixFilter( void ) -{ - this->AddRequiredInputName( "FixedImage" ); - this->AddRequiredInputName( "MovingImage" ); - this->AddRequiredInputName( "ParameterObject"); - - this->SetPrimaryInputName( "FixedImage" ); - this->SetPrimaryOutputName( "ResultImage" ); - - this->m_FixedImageContainer = DataObjectContainerType::New(); - this->m_MovingImageContainer = DataObjectContainerType::New(); - - this->m_FixedMeshFileName = std::string(); - this->m_MovingMeshFileName = std::string(); - - this->m_OutputDirectory = std::string(); - this->m_LogFileName = std::string(); - - this->LogToConsoleOff(); - this->LogToFileOff(); - - ParameterObjectPointer defaultParameterObject = ParameterObject::New(); - defaultParameterObject->AddParameterMap( "rigid" ); - defaultParameterObject->AddParameterMap( "affine" ); - defaultParameterObject->AddParameterMap( "nonrigid" ); - this->SetParameterObject( defaultParameterObject ); -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::GenerateData( void ) -{ - // Initialize variables here so they don't go out of scope between iterations of the main loop - ElastixMainObjectPointer transform = 0; - DataObjectContainerPointer fixedImageContainer = DataObjectContainerType::New(); - DataObjectContainerPointer movingImageContainer = DataObjectContainerType::New(); - DataObjectContainerPointer fixedMaskContainer = 0; - DataObjectContainerPointer movingMaskContainer = 0; - DataObjectContainerPointer resultImageContainer = 0; - ParameterMapVectorType TransformParameterMapVector; - FlatDirectionCosinesType fixedImageOriginalDirection; - - if( this->HasInput( "FixedMask" ) ) - { - fixedMaskContainer = DataObjectContainerType::New(); - } - - if( this->HasInput( "MovingMask" ) ) - { - movingMaskContainer = DataObjectContainerType::New(); - } - - // Split inputs into separate containers - InputNameArrayType inputNames = this->GetInputNames(); - for( unsigned int i = 0; i < inputNames.size(); ++i ) - { - if( this->IsInputType( "FixedImage", inputNames[ i ] ) ) - { - fixedImageContainer->push_back( this->GetInput( inputNames[ i ] ) ); - continue; - } - - if( this->IsInputType( "MovingImage", inputNames[ i ] ) ) - { - movingImageContainer->push_back( this->GetInput( inputNames[ i ] ) ); - continue; - } - - if( this->IsInputType( "FixedMask", inputNames[ i ] ) ) - { - fixedMaskContainer->push_back( this->GetInput( inputNames[ i ] ) ); - continue; - } - - if( this->IsInputType( "Movingmask", inputNames[ i ] ) ) - { - movingMaskContainer->push_back( this->GetInput( inputNames[ i ] ) ); - } - } - - ArgumentMapType argumentMap; - if( this->GetOutputDirectory().empty() ) { - if( this->GetLogToFile() ) - { - itkExceptionMacro( "LogToFileOn() requires an output directory to be specified. Use SetOutputDirectory().") - } - - // There must be an "-out", this is checked later in the code - argumentMap.insert( ArgumentMapEntryType( "-out", "output_path_not_set" ) ); - } - else - { - if( !itksys::SystemTools::FileExists( this->GetOutputDirectory() ) ) - { - itkExceptionMacro( "Output directory \"" << this->GetOutputDirectory() << "\" does not exist." ) - } - - if( this->GetOutputDirectory().back() != '/' || this->GetOutputDirectory().back() != '\\' ) - { - this->SetOutputDirectory( this->GetOutputDirectory() + "/" ); - } - - argumentMap.insert( ArgumentMapEntryType( "-out", this->GetOutputDirectory() ) ); - } - - // Fixed mesh (optional) - if( !this->m_FixedMeshFileName.empty() ) - { - argumentMap.insert( ArgumentMapEntryType( "-fp", std::string( this->m_FixedMeshFileName ) ) ); - } - - // Moving mesh (optional) - if( !this->m_MovingMeshFileName.empty() ) - { - argumentMap.insert( ArgumentMapEntryType( "-mp", std::string( this->m_MovingMeshFileName ) ) ); - } - - // Setup xout - std::string logFileName; - if( this->GetLogToFile() ) - { - if( this->GetLogFileName().empty() ) - { - logFileName = this->GetOutputDirectory() + "transformix.log"; - } - else - { - logFileName = this->GetOutputDirectory() + this->GetLogFileName(); - } - } - - if( elx::xoutSetup( logFileName.c_str(), this->GetLogToFile(), this->GetLogToConsole() ) ) - { - itkExceptionMacro( "ERROR while setting up xout" ); - } - - // Get ParameterMap - ParameterObjectConstPointer parameterObject = static_cast< const ParameterObject* >( this->GetInput( "ParameterObject" ) ); - ParameterMapVectorType parameterMapVector = parameterObject->GetParameterMap(); - - if( parameterMapVector.size() == 0 ) - { - itkExceptionMacro( "Parameter object contains an empty parameter map list." ); - } - - // Elastix must always write result image to guarantee that the ITK pipeline is in a consistent state - parameterMapVector[ parameterMapVector.size()-1 ][ "WriteResultImage" ] = ParameterValueVectorType( 1, "true" ); - - // Run the (possibly multiple) registration(s) - for( unsigned int i = 0; i < parameterMapVector.size(); ++i ) - { - // Elastix reads type information from parameter files. We set this information automatically and overwrite - // user settings in case they are incorrect (elastix will segfault or throw exception when casting) - parameterMapVector[ i ][ "FixedInternalImagePixelType" ] = ParameterValueVectorType( 1, TypeName< typename TFixedImage::PixelType >::ToString() ); - parameterMapVector[ i ][ "FixedImageDimension" ] = ParameterValueVectorType( 1, std::to_string( FixedImageDimension ) ); - parameterMapVector[ i ][ "MovingInternalImagePixelType" ] = ParameterValueVectorType( 1, TypeName< typename TMovingImage::PixelType >::ToString() ); - parameterMapVector[ i ][ "MovingImageDimension" ] = ParameterValueVectorType( 1, std::to_string( MovingImageDimension ) ); - parameterMapVector[ i ][ "ResultImagePixelType" ] = ParameterValueVectorType( 1, TypeName< typename TFixedImage::PixelType >::ToString() ); - - // Create another instance of ElastixMain - ElastixMainPointer elastix = ElastixMainType::New(); - - // Set the current elastix-level - elastix->SetElastixLevel( i ); - elastix->SetTotalNumberOfElastixLevels( parameterMapVector.size() ); - - // Set stuff we get from a previous registration - elastix->SetInitialTransform( transform ); - elastix->SetFixedImageContainer( fixedImageContainer ); - elastix->SetMovingImageContainer( movingImageContainer ); - elastix->SetFixedMaskContainer( fixedMaskContainer ); - elastix->SetMovingMaskContainer( movingMaskContainer ); - elastix->SetResultImageContainer( resultImageContainer ); - elastix->SetOriginalFixedImageDirectionFlat( fixedImageOriginalDirection ); - - // Start registration - unsigned int isError = 0; - try - { - unsigned int isError = elastix->Run( argumentMap, parameterMapVector[ i ] ); - } - catch( itk::ExceptionObject &e ) - { - itkExceptionMacro( << "Errors occurred during registration: " << e.what() ); - } - - if( isError != 0 ) - { - itkExceptionMacro( << "Uncought errors occurred during registration." ); - } - - // Get the transform, the fixedImage and the movingImage - // in order to put it in the next registration - transform = elastix->GetFinalTransform(); - fixedImageContainer = elastix->GetFixedImageContainer(); - movingImageContainer = elastix->GetMovingImageContainer(); - fixedMaskContainer = elastix->GetFixedMaskContainer(); - movingMaskContainer = elastix->GetMovingMaskContainer(); - resultImageContainer = elastix->GetResultImageContainer(); - fixedImageOriginalDirection = elastix->GetOriginalFixedImageDirectionFlat(); - - TransformParameterMapVector.push_back( elastix->GetTransformParametersMap() ); - - // Set initial transform to an index number instead of a parameter filename - if( i > 0 ) - { - std::stringstream index; - index << ( i - 1 ); - TransformParameterMapVector[ i ][ "InitialTransformParametersFileName" ][ 0 ] = index.str(); - } - } // End loop over registrations - - // Save result image - if( resultImageContainer.IsNotNull() && resultImageContainer->Size() > 0 ) - { - this->GraftOutput( "ResultImage", resultImageContainer->ElementAt( 0 ) ); - } - - // Save parameter map - ParameterObject::Pointer TransformParameterObject = ParameterObject::New(); - TransformParameterObject->SetParameterMap( TransformParameterMapVector ); - this->SetOutput( "TransformParameterObject", static_cast< itk::DataObject* >( TransformParameterObject ) ); - - // Close the modules - ElastixMainType::UnloadComponents(); -} - -template< typename TFixedImage, typename TMovingImage > -typename ElastixFilter< TFixedImage, TMovingImage >::FixedImagePointer -ElastixFilter< TFixedImage, TMovingImage > -::GetOutput( void ) -{ - // TODO: This update should not be needed upstream is not updated without it - this->Update(); - - return static_cast< TFixedImage* >( itk::ProcessObject::GetPrimaryOutput() ); -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::SetParameterObject( ParameterObjectPointer parameterObject ) -{ - this->SetInput( "ParameterObject", static_cast< itk::DataObject* >( parameterObject ) ); -} - -template< typename TFixedImage, typename TMovingImage > -typename selx::ElastixFilter< TFixedImage, TMovingImage >::ParameterObjectPointer -ElastixFilter< TFixedImage, TMovingImage > -::GetTransformParameters( void ) -{ - // Make sure the transform parameters are up to date - this->Update(); - - return static_cast< ParameterObject* >( itk::ProcessObject::GetOutput( "TransformParameterObject" ) ); -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::SetFixedImage( FixedImagePointer fixedImage ) -{ - // Free references to fixed images that has already been set - this->RemoveInputType( "FixedImage" ); - - this->SetInput( "FixedImage", static_cast< itk::DataObject* >( fixedImage ) ); -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::SetFixedImage( DataObjectContainerPointer fixedImages ) -{ - if( fixedImages->Size() == 0 ) - { - itkExceptionMacro( "Cannot set fixed images from empty container.") - } - - // Free references to fixed images that has already been set - this->RemoveInputType( "FixedImage" ); - - // The ITK filter requires a "FixedImage" named input. The first image - // will be named "FixedImage" while the rest of the images will - // be appended to the input container suffixed with _1, _2, etc. - // The common prefix allows us to read out only the fixed images - // for elastix fixed image container at a later stage - DataObjectContainerIterator fixedImageIterator = fixedImages->Begin(); - this->SetInput( "FixedImage", fixedImageIterator->Value() ); - ++fixedImageIterator; - - while( fixedImageIterator != fixedImages->End() ) - { - this->AddInputAutoIncrementName( "FixedImage", fixedImageIterator->Value() ); - ++fixedImageIterator; - } -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::AddFixedImage( FixedImagePointer fixedImage ) -{ - if( !this->HasInput( "FixedImage") ) - { - this->SetFixedImage( fixedImage ); - } - else - { - this->AddInputAutoIncrementName( "FixedImage", static_cast< itk::DataObject* >( fixedImage ) ); - } -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::SetMovingImage( MovingImagePointer movingImage ) -{ - // Free references to moving images that has already been set - this->RemoveInputType( "MovingImage" ); - - this->SetInput( "MovingImage", static_cast< itk::DataObject* >( movingImage ) ); -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::SetMovingImage( DataObjectContainerPointer movingImages ) -{ - if( movingImages->Size() == 0 ) - { - itkExceptionMacro( "Cannot set moving images from empty container.") - } - - // Free references to fixed images that has already been set - this->RemoveInputType( "MovingImage" ); - - // The ITK filter requires a "MovingImage" named input. The first image - // will be named "MovingImage" while the rest of the images will - // be appended to the input container suffixed with _1, _2, etc. - // The common prefix allows us to read out only the moving images - // for elastix moving image container at a later stage - DataObjectContainerIterator movingImageIterator = movingImages->Begin(); - this->SetInput( "MovingImage", movingImageIterator->Value() ); - ++movingImageIterator; - - while( movingImageIterator != movingImages->End() ) - { - this->AddInputAutoIncrementName( "MovingImage", static_cast< itk::DataObject* >( movingImageIterator->Value() ) ); - ++movingImageIterator; - } -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::AddMovingImage( MovingImagePointer movingImage ) -{ - if( !this->HasInput( "MovingImage") ) - { - this->SetMovingImage( movingImage ); - } - else - { - this->AddInputAutoIncrementName( "MovingImage", static_cast< itk::DataObject* >( movingImage ) ); - } -} - - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::SetFixedMask( FixedImagePointer fixedMask ) -{ - // Free references to fixed masks that has already been set - this->RemoveInputType( "FixedMask" ); - - this->SetInput( "FixedMask", static_cast< itk::DataObject* >( fixedMask ) ); -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::SetFixedMask( DataObjectContainerPointer fixedMasks ) -{ - if( fixedMasks->Size() == 0 ) - { - itkExceptionMacro( "Cannot set fixed masks from empty container.") - } - - // Free references to fixed images that has already been set - this->RemoveInputType( "FixedMask" ); - - // The first mask will be named "FixedMask" so that HasInput( "FixedMask" ) - // can be used to check if masks are used. The rest of the images will - // be appended to the input container suffixed with _1, _2, etc. - // The common prefix allows us to read out only the fixed masks - // for elastix fixed mask container at a later stage - DataObjectContainerIterator fixedMaskIterator = fixedMasks->Begin(); - this->SetInput( "FixedMask", fixedMaskIterator->Value() ); - ++fixedMaskIterator; - - while( fixedMaskIterator != fixedMasks->End() ) - { - this->AddInputAutoIncrementName( "FixedMask", fixedMaskIterator->Value() ); - ++fixedMaskIterator; - } -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::AddFixedMask( FixedImagePointer fixedMask ) -{ - this->AddInputAutoIncrementName( "FixedMask", static_cast< itk::DataObject* >( fixedMask ) ); -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::RemoveFixedMask( void ) -{ - this->RemoveInputType( "FixedMask" ); - this->m_FixedMaskContainer = 0; -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::SetMovingMask( MovingImagePointer movingMask ) -{ - // Free references to moving masks that has already been set - this->RemoveInputType( "MovingMask" ); - - this->SetInput( "MovingMask", static_cast< itk::DataObject* >( movingMask ) ); -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::SetMovingMask( DataObjectContainerPointer movingMasks ) -{ - if( movingMasks->Size() == 0 ) - { - itkExceptionMacro( "Cannot set moving images from empty container.") - } - - // Free references to moving masks that has already been set - this->RemoveInputType( "MovingMask" ); - - // The first mask will be named "MovingMask" so that HasInput( "MovingMask" ) - // can be used to check if masks are used. The rest of the images will - // be appended to the input container suffixed with _1, _2, etc. - // The common prefix allows us to read out only the moving mask - // for elastix moving mask container at a later stage - DataObjectContainerIterator movingMaskIterator = movingMasks->Begin(); - this->SetInput( "MovingMask", movingMaskIterator->Value() ); - ++movingMaskIterator; - - while( movingMaskIterator != movingMasks->End() ) - { - this->AddInputAutoIncrementName( "MovingMask", movingMaskIterator->Value() ); - ++movingMaskIterator; - } -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::AddMovingMask( MovingImagePointer movingMask ) -{ - this->AddInputAutoIncrementName( "MovingMask", static_cast< itk::DataObject* >( movingMask ) ); -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::RemoveMovingMask( void ) -{ - this->RemoveInputType( "MovingMask" ); - this->m_MovingMaskContainer = 0; -} - -/* - * Adds a named input to the first null position in the input list - * and expands the list memory if necessary - */ -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::AddInputAutoIncrementName( DataObjectIdentifierType inputName, itk::DataObject* input ) -{ - for ( unsigned idx = 0; idx < this->GetNumberOfIndexedInputs(); ++idx ) - { - if ( !this->GetInput( idx ) ) - { - // Append number to name (e.g. '_2' to inputName for idx = 2) - inputName += this->MakeNameFromInputIndex( idx ); - this->SetInput( inputName, input ); - return; - } - } - - inputName += this->MakeNameFromInputIndex( this->GetNumberOfIndexedInputs() ); - this->SetInput( inputName, input ); - return; -} - -template< typename TFixedImage, typename TMovingImage > -bool -ElastixFilter< TFixedImage, TMovingImage > -::IsInputType( DataObjectIdentifierType inputType, DataObjectIdentifierType inputName ) -{ - return std::strncmp( inputType.c_str(), inputName.c_str(), inputType.size() ) == 0; -} - -template< typename TFixedImage, typename TMovingImage > -void -ElastixFilter< TFixedImage, TMovingImage > -::RemoveInputType( DataObjectIdentifierType inputType ) -{ - // Free references to inputType images that has already been set - InputNameArrayType inputNames = this->GetInputNames(); - for( unsigned int i = 0; i < inputNames.size(); ++i ) - { - if( this->IsInputType( inputType, inputNames[ i ] ) ) - { - this->RemoveInput( inputNames[ i ] ); - } - } -} - -} // namespace selx - -#endif // ElastixFilter_hxx \ No newline at end of file diff --git a/Modules/Components/Elastix/include/elxTransformixFilter.h b/Modules/Components/Elastix/include/elxTransformixFilter.h deleted file mode 100644 index 320e037b73891710c4297efc2f40a6f7f57fd1bb..0000000000000000000000000000000000000000 --- a/Modules/Components/Elastix/include/elxTransformixFilter.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef TransformixFilter_h -#define TransformixFilter_h - -// ITK -#include "itkImageSource.h" - -// Transformix -#include "elxTransformixMain.h" - -// SuperElastix -#include "elxMacro.h" -#include "elxParameterObject.h" - -/** - * Transformix library exposed as an ITK filter. - * - * Make sure the compiler can also see itkElastixFilter.h - * for the TypeName trait structs (usually not a problem if - * the files are placed in the same include directory). - */ - -namespace selx { - -template< typename TInputImage > -class TransformixFilter : public itk::ImageSource< TInputImage > -{ -public: - - elxNewMacro( TransformixFilter, itk::ImageSource ); - - typedef elastix::TransformixMain TransformixMainType; - typedef TransformixMainType::Pointer TransformixMainPointer; - typedef TransformixMainType::ArgumentMapType ArgumentMapType; - typedef ArgumentMapType::value_type ArgumentMapEntryType; - - typedef itk::ProcessObject::DataObjectIdentifierType DataObjectIdentifierType; - typedef TransformixMainType::DataObjectContainerType DataObjectContainerType; - typedef TransformixMainType::DataObjectContainerPointer DataObjectContainerPointer; - - typedef ParameterObject::ParameterMapVectorType ParameterMapVectorType; - typedef ParameterObject::ParameterMapType ParameterMapType; - typedef ParameterObject::ParameterValueVectorType ParameterValueVectorType; - typedef typename ParameterObject::Pointer ParameterObjectPointer; - typedef typename ParameterObject::ConstPointer ParameterObjectConstPointer; - - typedef typename TInputImage::Pointer InputImagePointer; - - itkStaticConstMacro( InputImageDimension, unsigned int, TInputImage::ImageDimension ); - - void SetInputImage( InputImagePointer inputImage ); - - void SetTransformParameterObject( ParameterObjectPointer parameterObject ); - ParameterObjectPointer GetTransformParameters( void ); - - itkSetMacro( ComputeSpatialJacobian, bool ); - itkGetConstMacro( ComputeSpatialJacobian, bool ); - itkBooleanMacro( ComputeSpatialJacobian ); - - itkSetMacro( ComputeDeterminantOfSpatialJacobian, bool ); - itkGetConstMacro( ComputeDeterminantOfSpatialJacobian, bool ); - itkBooleanMacro( ComputeDeterminantOfSpatialJacobian ); - - itkSetMacro( ComputeDeformationField, bool ); - itkGetConstMacro( ComputeDeformationField, bool ); - itkBooleanMacro( ComputeDeformationField ); - - itkSetMacro( PointSetFileName, std::string ); - itkGetConstMacro( PointSetFileName, std::string ); - void RemovePointSetFileName() { this->m_PointSetFileName = std::string(); }; - - itkSetMacro( OutputDirectory, std::string ); - itkGetConstMacro( OutputDirectory, std::string ); - void RemoveOutputDirectory() { this->m_OutputDirectory = std::string(); }; - - void SetLogFileName( std::string logFileName ) - { - this->m_LogFileName = logFileName; - this->LogToFileOn(); - this->Modified(); - } - - itkGetConstMacro( LogFileName, std::string ); - - void RemoveLogFileName( void ) { - this->m_LogFileName = std::string(); - this->LogToFileOff(); - }; - - itkSetMacro( LogToConsole, bool ); - itkGetConstMacro( LogToConsole, bool ); - itkBooleanMacro( LogToConsole ); - - itkSetMacro( LogToFile, bool ); - itkGetConstMacro( LogToFile, bool ); - itkBooleanMacro( LogToFile ); - -protected: - - void GenerateData( void ) ITK_OVERRIDE; - -private: - - TransformixFilter(); - - bool m_ComputeSpatialJacobian; - bool m_ComputeDeterminantOfSpatialJacobian; - bool m_ComputeDeformationField; - std::string m_PointSetFileName; - - std::string m_OutputDirectory; - std::string m_LogFileName; - - bool m_LogToConsole; - bool m_LogToFile; - - -}; - -} // namespace selx - -#ifndef ITK_MANUAL_INSTANTIATION -#include "elxTransformixFilter.hxx" -#endif - -#endif // TransformixFilter_h \ No newline at end of file diff --git a/Modules/Components/Elastix/include/elxTransformixFilter.hxx b/Modules/Components/Elastix/include/elxTransformixFilter.hxx deleted file mode 100644 index ef350fab8a12eb64b2545c735253425fb8f226cc..0000000000000000000000000000000000000000 --- a/Modules/Components/Elastix/include/elxTransformixFilter.hxx +++ /dev/null @@ -1,220 +0,0 @@ -#ifndef TransformixFilter_hxx -#define TransformixFilter_hxx - -namespace selx { - -template< typename TInputImage > -TransformixFilter< TInputImage > -::TransformixFilter( void ) -{ - this->AddRequiredInputName( "TransformParameterObject"); - - this->SetPrimaryInputName( "InputImage" ); - this->SetPrimaryOutputName( "ResultImage" ); - - this->ComputeSpatialJacobianOff(); - this->ComputeDeterminantOfSpatialJacobianOff(); - this->ComputeDeformationFieldOff(); - this->m_PointSetFileName = std::string(); - - this->m_OutputDirectory = std::string(); - this->m_LogFileName = std::string(); - - this->LogToConsoleOff(); - this->LogToFileOff(); -} - -template< typename TInputImage > -void -TransformixFilter< TInputImage > -::GenerateData( void ) -{ - // Assert that at least one output has been requested - if( !this->HasInput( "InputImage" ) && - !this->GetComputeSpatialJacobian() && - !this->GetComputeDeterminantOfSpatialJacobian() && - !this->GetComputeDeformationField() && - this->GetPointSetFileName().empty() ) - { - itkExceptionMacro( "Expected at least one of SetInputImage(), ComputeSpatialJacobianOn(), " - << "ComputeDeterminantOfSpatialJacobianOn() or SetPointSetFileName() or " - << "to be set."); - } - - // Check if an output directory is needed - // TODO: Change behaviour upstream to have transformix save all outputs as data objects - if( ( this->GetComputeSpatialJacobian() || - this->GetComputeDeterminantOfSpatialJacobian() || - this->GetComputeDeformationField() || - !this->GetPointSetFileName().empty() || - this->GetLogToFile() ) && - ( this->GetOutputDirectory().empty() ) ) - { - itkExceptionMacro( "The requested outputs require an output directory to be specified." - << "Use SetOutputDirectory()." ) - } - - if( ( this->GetComputeSpatialJacobian() || - this->GetComputeDeterminantOfSpatialJacobian() || - this->GetComputeDeformationField() || - !this->GetPointSetFileName().empty() || - this->GetLogToFile() ) && - !itksys::SystemTools::FileExists( this->GetOutputDirectory() ) ) - { - itkExceptionMacro( "Output directory \"" << this->GetOutputDirectory() << "\" does not exist." ) - } - - // Transformix uses "-def" for path to point sets AND as flag for writing deformatin field - // TODO: Change behaviour upstream: Split into seperate arguments - if( this->GetComputeDeformationField() && !this->GetPointSetFileName().empty() ) - { - itkExceptionMacro( << "For backwards compatibility, only one of ComputeDeformationFieldOn() or SetPointSetFileName() can be " - << "active at any one time." ) - } - - // Setup argument map which transformix uses internally ito figure out what needs to be done - ArgumentMapType argumentMap; - if( this->GetOutputDirectory().empty() ) { - if( this->GetLogToFile() ) - { - itkExceptionMacro( "LogToFileOn() requires an output directory to be specified. Use SetOutputDirectory().") - } - - // There must be an "-out", this is checked later in the code - argumentMap.insert( ArgumentMapEntryType( "-out", "output_path_not_set" ) ); - } - else - { - if( !itksys::SystemTools::FileExists( this->GetOutputDirectory() ) ) - { - itkExceptionMacro( "Output directory \"" << this->GetOutputDirectory() << "\" does not exist." ) - } - - if( this->GetOutputDirectory().back() != '/' || this->GetOutputDirectory().back() != '\\' ) - { - this->SetOutputDirectory( this->GetOutputDirectory() + "/" ); - } - - argumentMap.insert( ArgumentMapEntryType( "-out", this->GetOutputDirectory() ) ); - } - - if( this->GetComputeSpatialJacobian() ) - { - argumentMap.insert( ArgumentMapEntryType( "-jacmat", "all" ) ); - } - - if( this->GetComputeDeterminantOfSpatialJacobian() ) - { - argumentMap.insert( ArgumentMapEntryType( "-jac", "all" ) ); - } - - if( this->GetComputeDeformationField() ) - { - argumentMap.insert( ArgumentMapEntryType( "-def" , "all" ) ); - } - - if( !this->GetPointSetFileName().empty() ) - { - argumentMap.insert( ArgumentMapEntryType( "-def", this->GetPointSetFileName() ) ); - } - - // Setup xout - std::string logFileName; - if( this->GetLogToFile() ) - { - if( this->GetLogFileName().empty() ) - { - logFileName = this->GetOutputDirectory() + "transformix.log"; - } - else - { - logFileName = this->GetOutputDirectory() + this->GetLogFileName(); - } - } - - if( elx::xoutSetup( logFileName.c_str(), this->GetLogToFile(), this->GetLogToConsole() ) ) - { - itkExceptionMacro( "ERROR while setting up xout" ); - } - - // Instantiate transformix - TransformixMainPointer transformix = TransformixMainType::New(); - - // Setup image containers - DataObjectContainerPointer inputImageContainer = 0; - DataObjectContainerPointer resultImageContainer = 0; - - if( this->HasInput( "InputImage" ) ) { - DataObjectContainerPointer inputImageContainer = DataObjectContainerType::New(); - inputImageContainer->CreateElementAt( 0 ) = this->GetInput("InputImage"); - transformix->SetInputImageContainer( inputImageContainer ); - transformix->SetResultImageContainer( resultImageContainer ); - } - - // Get ParameterMap - ParameterObjectConstPointer transformParameterObject = static_cast< const ParameterObject* >( this->GetInput( "TransformParameterObject" ) ); - ParameterMapVectorType transformParameterMapVector = transformParameterObject->GetParameterMap(); - - for( unsigned int i = 0; i < transformParameterMapVector.size(); ++i ) - { - // Transformix reads type information from parameter files. We set this information automatically and overwrite - // user settings in case they are incorrect (elastix will segfault or throw exception when casting) - transformParameterMapVector[ i ][ "MovingInternalImagePixelType" ] = ParameterValueVectorType( 1, TypeName< typename TInputImage::PixelType >::ToString() ); - transformParameterMapVector[ i ][ "MovingImageDimension" ] = ParameterValueVectorType( 1, std::to_string( InputImageDimension ) ); - transformParameterMapVector[ i ][ "ResultImagePixelType" ] = ParameterValueVectorType( 1, TypeName< typename TInputImage::PixelType >::ToString() ); - } - - // Run transformix - unsigned int isError = 0; - try - { - isError = transformix->Run( argumentMap, transformParameterMapVector ); - } - catch( itk::ExceptionObject &e ) - { - itkExceptionMacro( << "Errors occured during registration: " << e.what() ); - } - - if( isError != 0 ) - { - itkExceptionMacro( << "Uncought errors occured during registration." ); - } - - // Save result image - resultImageContainer = transformix->GetResultImageContainer(); - if( resultImageContainer.IsNotNull() && resultImageContainer->Size() > 0 ) - { - this->GraftOutput( "ResultImage", resultImageContainer->ElementAt( 0 ) ); - } - - // Clean up - TransformixMainType::UnloadComponents(); -} - -template< typename TInputImage > -void -TransformixFilter< TInputImage > -::SetInputImage( InputImagePointer inputImage ) -{ - this->SetInput( "InputImage", static_cast< itk::DataObject* >( inputImage ) ); -} - -template< typename TInputImage > -void -TransformixFilter< TInputImage > -::SetTransformParameterObject( ParameterObjectPointer parameterObject ) -{ - this->SetInput( "TransformParameterObject", static_cast< itk::DataObject* >( parameterObject ) ); -} - -template< typename TInputImage > -typename selx::TransformixFilter< TInputImage >::ParameterObjectPointer -TransformixFilter< TInputImage > -::GetTransformParameters( void ) -{ - return static_cast< ParameterObject* >( this->GetInput( "TransformParameterObject" ) ); -} - -} // namespace selx - -#endif // TransformixFilter_hxx \ No newline at end of file diff --git a/Modules/Core/ModuleCore.cmake b/Modules/Core/ModuleCore.cmake index ff83b08c6014e3a757d2abe699eb9ac11891ddc5..c5db88450139bb0e54ec29d3a683cae13c43aa4d 100644 --- a/Modules/Core/ModuleCore.cmake +++ b/Modules/Core/ModuleCore.cmake @@ -13,8 +13,6 @@ file(GLOB ${MODULE}_HEADER_FILES "${${MODULE}_SOURCE_DIR}/*/include/*.*") #@Kasper: file GLOB is generally disencouraged for source files (missing files are not detected and CMake doesn't know if the project has to be updated when due to a checkout extra source files are in the tree), but since this I think is not really an issue for header files... #I read: CMake will figure out that they're headers; it won't try to build them. http://stackoverflow.com/questions/8316104/specify-how-cmake-creates-visual-studio-project - - # Export libraries set( ${MODULE}_LIBRARIES ${MODULE} @@ -23,7 +21,6 @@ set( ${MODULE}_LIBRARIES # Module source files set( ${MODULE}_SOURCE_FILES ${${MODULE}_SOURCE_DIR}/Blueprints/src/elxBlueprint.cxx - ${${MODULE}_SOURCE_DIR}/ParameterObject/src/elxParameterObject.cxx ${${MODULE}_SOURCE_DIR}/ComponentInterface/src/ComponentBase.cxx ${${MODULE}_SOURCE_DIR}/ExampleComponents/src/Example3rdPartyCode.cxx ${${MODULE}_SOURCE_DIR}/ExampleComponents/src/Example4thPartyCode.cxx @@ -38,7 +35,5 @@ set( ${MODULE}_SOURCE_FILES ) # Compile library - -add_library( ${MODULE} STATIC "${${MODULE}_SOURCE_FILES}" ${${MODULE}_HEADER_FILES}) - +add_library( ${MODULE} STATIC "${${MODULE}_SOURCE_FILES}" ${${MODULE}_HEADER_FILES} ) target_link_libraries( ${MODULE} ${ELASTIX_LIBRARIES} ) diff --git a/Modules/Core/ParameterObject/include/elxParameterObject.h b/Modules/Core/ParameterObject/include/elxParameterObject.h deleted file mode 100644 index 71816b062e0fbca45b42dcfd39ff6073f7487156..0000000000000000000000000000000000000000 --- a/Modules/Core/ParameterObject/include/elxParameterObject.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef ParameterObject_h -#define ParameterObject_h - -// ITK -#include "itkObjectFactory.h" -#include "itkDataObject.h" - -// elastix -#include "elxMacro.h" -#include "itkParameterFileParser.h" - -namespace selx { - -class ParameterObject : public itk::DataObject -{ -public: - - elxNewMacro( ParameterObject, itk::DataObject ); - - typedef std::string ParameterKeyType; - typedef std::string ParameterValueType; - typedef std::vector< ParameterValueType > ParameterValueVectorType; - typedef std::map< ParameterKeyType, ParameterValueVectorType > ParameterMapType; - typedef ParameterMapType::iterator ParameterMapIterator; - typedef ParameterMapType::const_iterator ParameterMapConstIterator; - typedef std::vector< ParameterMapType > ParameterMapVectorType; - typedef std::string ParameterFileNameType; - typedef std::vector< ParameterFileNameType > ParameterFileNameVectorType; - typedef ParameterFileNameVectorType::iterator ParameterFileNameVectorIterator; - typedef ParameterFileNameVectorType::const_iterator ParameterFileNameVectorConstIterator; - - typedef itk::ParameterFileParser ParameterFileParserType; - typedef ParameterFileParserType::Pointer ParameterFileParserPointer; - - void SetParameterMap( const ParameterMapType parameterMap ); - void SetParameterMap( const ParameterMapVectorType parameterMapVector ); - void AddParameterMap( const ParameterMapType parameterMap ); - - ParameterMapType& GetParameterMap( unsigned int index ); - ParameterMapVectorType& GetParameterMap( void ); - const ParameterMapVectorType& GetParameterMap( void ) const; - - void ReadParameterFile( const ParameterFileNameType parameterFileName ); - void ReadParameterFile( const ParameterFileNameVectorType parameterFileNameVector ); - void AddParameterFile( const ParameterFileNameType parameterFileName ); - - void WriteParameterFile( const ParameterFileNameType parameterFileName ); - void WriteParameterFile( const ParameterFileNameVectorType parameterFileNameVector ); - - // Default parameter maps - void SetParameterMap( const std::string transformName, const unsigned int numberOfResolutions = 3u, const double finalGridSpacingInPhysicalUnits = 10.0 ); - void AddParameterMap( const std::string transformName, const unsigned int numberOfResolutions = 3u, const double finalGridSpacingInPhysicalUnits = 10.0 ); - ParameterMapType GetParameterMap( const std::string transformName, const unsigned int numberOfResolutions = 3u, const double finalGridSpacingInPhysicalUnits = 10.0 ); - -private: - - ParameterMapVectorType m_ParameterMapVector; - -}; - -} // namespace elx - -#endif // #define ParameterMap_h \ No newline at end of file diff --git a/Modules/Core/ParameterObject/src/elxParameterObject.cxx b/Modules/Core/ParameterObject/src/elxParameterObject.cxx deleted file mode 100644 index 36b393cefda1e0386927f4bd9ca442e71b043a36..0000000000000000000000000000000000000000 --- a/Modules/Core/ParameterObject/src/elxParameterObject.cxx +++ /dev/null @@ -1,274 +0,0 @@ -#ifndef ParameterObject_cxx -#define ParameterObject_cxx - -// ITK -#include "itkFileTools.h" - -// elastix -#include "elxParameterObject.h" - -namespace selx { - -void -ParameterObject -::SetParameterMap( const ParameterMapType parameterMap ) -{ - ParameterMapVectorType parameterMapVector; - parameterMapVector.push_back( parameterMap ); - this->SetParameterMap( parameterMapVector ); -} - -void -ParameterObject -::SetParameterMap( const ParameterMapVectorType parameterMapVector ) -{ - this->m_ParameterMapVector = parameterMapVector; -} - -void -ParameterObject -::AddParameterMap( const ParameterMapType parameterMap ) -{ - this->m_ParameterMapVector.push_back( parameterMap ); -} - -ParameterObject::ParameterMapType& -ParameterObject -::GetParameterMap( unsigned int index ) -{ - this->Modified(); - return this->m_ParameterMapVector[ index ]; -} - -ParameterObject::ParameterMapVectorType& -ParameterObject -::GetParameterMap( void ) -{ - this->Modified(); - return this->m_ParameterMapVector; -} - -const ParameterObject::ParameterMapVectorType& -ParameterObject -::GetParameterMap( void ) const -{ - return this->m_ParameterMapVector; -} - -void -ParameterObject -::ReadParameterFile( const ParameterFileNameType parameterFileName ) -{ - ParameterFileParserPointer parameterFileParser = ParameterFileParserType::New(); - parameterFileParser->SetParameterFileName( parameterFileName ); - parameterFileParser->ReadParameterFile(); - this->m_ParameterMapVector = ParameterMapVectorType( 1, parameterFileParser->GetParameterMap() ); -} - -void -ParameterObject -::ReadParameterFile( const ParameterFileNameVectorType parameterFileNameVector ) -{ - if( parameterFileNameVector.size() == 0 ) - { - itkExceptionMacro( "Parameter filename container is empty." ); - } - - this->m_ParameterMapVector.clear(); - - for( unsigned int i = 0; i < parameterFileNameVector.size(); ++i ) - { - if( !itksys::SystemTools::FileExists( parameterFileNameVector[ i ] ) ) - { - itkExceptionMacro( "Parameter file \"" << parameterFileNameVector[ i ] << "\" does not exist." ) - } - - this->AddParameterFile( parameterFileNameVector[ i ] ); - } -} - -void -ParameterObject -::AddParameterFile( const ParameterFileNameType parameterFileName ) -{ - ParameterFileParserPointer parameterFileParser = ParameterFileParserType::New(); - parameterFileParser->SetParameterFileName( parameterFileName ); - parameterFileParser->ReadParameterFile(); - this->m_ParameterMapVector.push_back( parameterFileParser->GetParameterMap() ); -} - -void -ParameterObject -::WriteParameterFile( const ParameterFileNameType parameterFileName ) -{ - if( this->m_ParameterMapVector.size() != 1 ) - { - itkExceptionMacro( "ParameterObject contains multiple parameter files. Please provide a vector of filenames." ); - } - - this->WriteParameterFile( ParameterFileNameVectorType( 1, parameterFileName ) ); -} - -void -ParameterObject -::WriteParameterFile( const ParameterFileNameVectorType parameterFileNameVector ) -{ - for( unsigned int i = 0; i < parameterFileNameVector.size(); ++i ) - { - ParameterFileNameType fileName = parameterFileNameVector[ i ]; - std::ofstream parameterFile; - parameterFile << std::fixed; - parameterFile.open( fileName.c_str(), std::ofstream::out ); - ParameterMapConstIterator parameterMapIterator = this->m_ParameterMapVector[ i ].begin(); - ParameterMapConstIterator parameterMapIteratorEnd = this->m_ParameterMapVector[ i ].end(); - while( parameterMapIterator != parameterMapIteratorEnd ) - { - parameterFile << "(" << parameterMapIterator->first; - - ParameterValueVectorType parameterMapValueVector = parameterMapIterator->second; - for( unsigned int i = 0; i < parameterMapValueVector.size(); ++i ) - { - std::stringstream stream( parameterMapValueVector[ i ] ); - float number; - stream >> number; - if( stream.fail() || stream.bad() ) { - parameterFile << " \"" << parameterMapValueVector[ i ] << "\""; - } - else - { - parameterFile << " " << number; - } - } - - parameterFile << ")" << std::endl; - parameterMapIterator++; - } - - parameterFile.close(); - } -} - -void -ParameterObject -::SetParameterMap( const std::string transformName, const unsigned int numberOfResolutions, const double finalGridSpacingInPhysicalUnits ) -{ - this->m_ParameterMapVector = ParameterMapVectorType( 1, this->GetParameterMap( transformName, numberOfResolutions, finalGridSpacingInPhysicalUnits ) ); -} - -void -ParameterObject -::AddParameterMap( const std::string transformName, const unsigned int numberOfResolutions, const double finalGridSpacingInPhysicalUnits ) -{ - this->m_ParameterMapVector.push_back( this->GetParameterMap( transformName, numberOfResolutions, finalGridSpacingInPhysicalUnits ) ); -} - -ParameterObject::ParameterMapType -ParameterObject -::GetParameterMap( const std::string transformName, const unsigned int numberOfResolutions, const double finalGridSpacingInPhysicalUnits ) -{ - - // Parameters that depend on size and number of resolutions - ParameterMapType parameterMap = ParameterMapType(); - - // Common Components - parameterMap[ "FixedImagePyramid" ] = ParameterValueVectorType( 1, "FixedSmoothingImagePyramid" ); - parameterMap[ "MovingImagePyramid" ] = ParameterValueVectorType( 1, "MovingSmoothingImagePyramid" ); - parameterMap[ "Interpolator"] = ParameterValueVectorType( 1, "LinearInterpolator"); - parameterMap[ "Optimizer" ] = ParameterValueVectorType( 1, "AdaptiveStochasticGradientDescent" ); - parameterMap[ "Resampler"] = ParameterValueVectorType( 1, "DefaultResampler" ); - parameterMap[ "ResampleInterpolator"] = ParameterValueVectorType( 1, "FinalBSplineInterpolator" ); - parameterMap[ "FinalBSplineInterpolationOrder" ] = ParameterValueVectorType( 1, "3" ); - - std::ostringstream numberOfResolutionsToString; - numberOfResolutionsToString << numberOfResolutions; - parameterMap[ "NumberOfResolutions" ] = ParameterValueVectorType( 1, numberOfResolutionsToString.str() ); - - // Image Sampler - parameterMap[ "ImageSampler" ] = ParameterValueVectorType( 1, "RandomCoordinate" ); - parameterMap[ "NumberOfSpatialSamples"] = ParameterValueVectorType( 1, "2048" ); - parameterMap[ "CheckNumberOfSamples" ] = ParameterValueVectorType( 1, "true" ); - parameterMap[ "MaximumNumberOfSamplingAttempts" ] = ParameterValueVectorType( 1, "8" ); - parameterMap[ "NewSamplesEveryIteration" ] = ParameterValueVectorType( 1, "true"); - - // Optimizer - parameterMap[ "NumberOfSamplesForExactGradient" ] = ParameterValueVectorType( 1, "4096" ); - parameterMap[ "DefaultPixelValue" ] = ParameterValueVectorType( 1, "0" ); - parameterMap[ "AutomaticParameterEstimation" ] = ParameterValueVectorType( 1, "true" ); - - // Output - parameterMap[ "WriteResultImage" ] = ParameterValueVectorType( 1, "true" ); - parameterMap[ "ResultImageFormat" ] = ParameterValueVectorType( 1, "nii" ); - - // transformNames - if( transformName == "translation" ) - { - parameterMap[ "Registration" ] = ParameterValueVectorType( 1, "MultiResolutionRegistration" ); - parameterMap[ "transform" ] = ParameterValueVectorType( 1, "TranslationTransform" ); - parameterMap[ "Metric" ] = ParameterValueVectorType( 1, "AdvancedMattesMutualInformation" ); - parameterMap[ "MaximumNumberOfIterations" ] = ParameterValueVectorType( 1, "128" ); - parameterMap[ "Interpolator"] = ParameterValueVectorType( 1, "LinearInterpolator"); - } - else if( transformName == "rigid" ) - { - parameterMap[ "Registration" ] = ParameterValueVectorType( 1, "MultiResolutionRegistration" ); - parameterMap[ "Transform" ] = ParameterValueVectorType( 1, "EulerTransform" ); - parameterMap[ "Metric" ] = ParameterValueVectorType( 1, "AdvancedMattesMutualInformation" ); - parameterMap[ "MaximumNumberOfIterations" ] = ParameterValueVectorType( 1, "128" ); - parameterMap[ "AutomaticTransformInitialization" ] = ParameterValueVectorType( 1, "true" ); - parameterMap[ "AutomaticTransformInitializationMethod" ] = ParameterValueVectorType( 1, "CenterOfGravity" ); - } - else if( transformName == "affine" ) - { - parameterMap[ "Registration" ] = ParameterValueVectorType( 1, "MultiResolutionRegistration" ); - parameterMap[ "Transform" ] = ParameterValueVectorType( 1, "AffineTransform" ); - parameterMap[ "Metric" ] = ParameterValueVectorType( 1, "AdvancedMattesMutualInformation" ); - parameterMap[ "MaximumNumberOfIterations" ] = ParameterValueVectorType( 1, "256" ); - } - else if( transformName == "nonrigid" ) - { - parameterMap[ "Registration" ] = ParameterValueVectorType( 1, "MultiMetricMultiResolutionRegistration" ); - parameterMap[ "Transform" ] = ParameterValueVectorType( 1, "BSplineTransform" ); - parameterMap[ "Metric" ] = ParameterValueVectorType( 1, "AdvancedMattesMutualInformation" ); - parameterMap[ "Metric" ] .push_back( "TransformBendingEnergyPenalty" ); - parameterMap[ "Metric0Weight" ] = ParameterValueVectorType( 1, "0.0001" ); - parameterMap[ "Metric1Weight" ] = ParameterValueVectorType( 1, "0.9999" ); - parameterMap[ "MaximumNumberOfIterations" ] = ParameterValueVectorType( 1, "512" ); - } - else if( transformName == "groupwise" ) - { - parameterMap[ "Registration" ] = ParameterValueVectorType( 1, "MultiResolutionRegistration" ); - parameterMap[ "Transform" ] = ParameterValueVectorType( 1, "BSplineStackTransform" ); - parameterMap[ "Metric" ] = ParameterValueVectorType( 1, "VarianceOverLastDimensionMetric" ); - parameterMap[ "MaximumNumberOfIterations" ] = ParameterValueVectorType( 1, "512" ); - parameterMap[ "Interpolator"] = ParameterValueVectorType( 1, "ReducedDimensionBSplineInterpolator" ); - parameterMap[ "ResampleInterpolator" ] = ParameterValueVectorType( 1, "FinalReducedDimensionBSplineInterpolator" ); - } - else - { - itkExceptionMacro( "No default parameter map \"" << transformName << "\"." ); - } - - // B-spline transformNames settings - if( transformName == "nonrigid" || transformName == "groupwise" ) - { - ParameterValueVectorType gridSpacingSchedule = ParameterValueVectorType(); - for( unsigned int resolution = 0; resolution < numberOfResolutions; ++resolution ) - { - std::ostringstream resolutionPowerToString; - resolutionPowerToString << pow( 2, resolution ); - gridSpacingSchedule.insert( gridSpacingSchedule.begin(), resolutionPowerToString.str() ); - } - - parameterMap[ "GridSpacingSchedule" ] = gridSpacingSchedule; - - std::ostringstream finalGridSpacingInPhysicalUnitsToString; - finalGridSpacingInPhysicalUnitsToString << finalGridSpacingInPhysicalUnits; - parameterMap[ "FinalGridSpacingInPhysicalUnits" ] = ParameterValueVectorType( 1, finalGridSpacingInPhysicalUnitsToString.str() ); - } - - return parameterMap; -} - -} // namespace selx - -#endif // ParameterObject_cxx