diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index f5887d974a6498e3c10a78013c19834fade86a0b..0000000000000000000000000000000000000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "Testing/GoogleTest"] - path = Testing/GoogleTest - url = https://github.com/kaspermarstal/GoogleTest - tag = release-1.7.0 diff --git a/.travis.yml b/.travis.yml index 8519f8302c78d7103fbe53cbe1a1d66a5a2fd4ff..80eb02fe4056453cbf255c088725c411ff96fd89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ -sudo: false +sudo: required +dist: trusty language: cpp @@ -26,8 +27,8 @@ before_script: script: - cmake ../SuperElastix/SuperBuild - - make --jobs=2 | grep -v '^--' | grep -v '^Installing' + - make --jobs=2 | grep -v '^--' | grep -v '^Installing' | grep -v '^common' -after_sucess: +after_success: - cd Elastix-build - ctest diff --git a/CMake/elxComponent.cmake b/CMake/elxComponent.cmake deleted file mode 100644 index 4fd04dfb6e043411fce6ac20509b97a215444347..0000000000000000000000000000000000000000 --- a/CMake/elxComponent.cmake +++ /dev/null @@ -1,10 +0,0 @@ -macro( ElastixComponent COMPONENT ) - ElastixModuleCheckName( ${COMPONENT} ) - set( ELASTIX_COMPONENT_{$COMPONENT}_DEFINED TRUE ) -endmacro() - -macro( ElastixComponentCheckName COMPONENT ) - if( NOT "${_name}" MATCHES "^[a-zA-Z][a-zA-Z0-9]*$" ) - message( FATAL_ERROR "Invalid component name: ${COMPONENT}" ) - endif() -endmacro() \ No newline at end of file diff --git a/CMake/elxModules.cmake b/CMake/elxModules.cmake index 0b993b9570fca4351a47dacadb59c42e476d1f3b..7ba40b4dcd590ce7de87e6203ca71fef82ffdd5f 100644 --- a/CMake/elxModules.cmake +++ b/CMake/elxModules.cmake @@ -6,7 +6,7 @@ macro( _elxmodule_check_name MODULE ) message( FATAL_ERROR "Invalid module name: ${MODULE}" ) endif() - list( FIND ELXMODULE_ALL "${MODULE}" MODULE_FOUND ) + list( FIND ELASTIX_MODULES "${MODULE}" MODULE_FOUND ) if( ${MODULE_FOUND} EQUAL -1 ) message( FATAL_ERROR "Module not found: ${MODULE}") endif() @@ -16,7 +16,7 @@ macro( _elxmodule_enable MODULE ) _elxmodule_check_name( ${MODULE} ) if( NOT ${MODULE}_ENABLED ) - set( USE_${MODULE} ON ) + set( ELASTIX_USE_${MODULE} ON ) include( ${${MODULE}_FILE} ) @@ -24,14 +24,9 @@ macro( _elxmodule_enable MODULE ) include_directories( ${${MODULE}_INCLUDE_DIRS} ) endif() - add_subdirectory( ${${MODULE}_SOURCE_DIR} ) - if( ${MODULE}_LIBRARIES ) link_directories( ${${MODULE}_LIBRARY_DIRS} ) - - list( APPEND ELASTIX_LIBRARIES - ${${MODULE}_LIBRARIES} - ) + list( APPEND ELASTIX_LIBRARIES ${${MODULE}_LIBRARIES} ) endif() # TODO: Add recursive dependency walk @@ -43,30 +38,32 @@ macro( _elxmodule_disable MODULE ) endmacro() macro( _elxmodules_initialize ) - set( ELXMODULE_ALL ) + set( ELASTIX_LIBRARIES ) + set( ELASTIX_MODULES ) - file( GLOB MODULE_FILES RELATIVE "${CMAKE_SOURCE_DIR}" + file( GLOB_RECURSE MODULE_FILES RELATIVE "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/Modules/*/elxModule*.cmake" ) message( STATUS "Found the following elastix modules:") foreach( MODULE_FILE ${MODULE_FILES}) - get_filename_component( MODULE_PATH ${MODULE_FILE} PATH ) - get_filename_component( MODULE ${MODULE_FILE} NAME_WE ) - message( STATUS " ${MODULE}" ) + get_filename_component( MODULE_NAME ${MODULE_FILE} NAME_WE ) + get_filename_component( ${MODULE_NAME}_PATH ${MODULE_FILE} PATH ) + + message( STATUS " ${MODULE_NAME}" ) - option( "USE_${MODULE}" OFF ) - set( "${MODULE}_FILE" ${CMAKE_SOURCE_DIR}/${MODULE_FILE} ) - set( "${MODULE}_ENABLED" OFF ) + option( "ELASTIX_USE_${MODULE_NAME}" OFF ) + set( "${MODULE_NAME}_FILE" ${CMAKE_SOURCE_DIR}/${MODULE_FILE} ) + set( "${MODULE_NAME}_ENABLED" OFF ) - set( ${MODULE}_SOURCE_DIR ${CMAKE_SOURCE_DIR}/${MODULE_PATH} ) - set( ${MODULE}_BINARY_DIR ${CMAKE_BINARY_DIR}/${MODULE_PATH} ) + set( ${MODULE_NAME}_SOURCE_DIR ${CMAKE_SOURCE_DIR}/${${MODULE_NAME}_PATH} ) + set( ${MODULE_NAME}_BINARY_DIR ${CMAKE_BINARY_DIR}/${${MODULE_NAME}_PATH} ) - set( ${MODULE}_INCLUDE_DIRS ) - set( ${MODULE}_LIBRARY_DIRS ) - set( ${MODULE}_LIBRARIES ) + set( ${MODULE_NAME}_INCLUDE_DIRS ) + set( ${MODULE_NAME}_LIBRARY_DIRS ) + set( ${MODULE_NAME}_LIBRARIES ) - list(APPEND ELXMODULE_ALL ${MODULE} ) + list(APPEND ELASTIX_MODULES ${MODULE_NAME} ) endforeach() endmacro() @@ -79,9 +76,3 @@ macro( elxmodule_enable MODULE ) _elxmodule_enable( ${MODULE} ) endmacro() -macro( elxmodule_compile MODULE ) - project( "${MODULE}" ) - add_library( ${MODULE} STATIC "${${MODULE}_SOURCE_FILES}" ) - target_link_libraries( ${MODULE} ${ELASTIX_LIBRARIES} ) - list( APPEND ${MODULE}_LIBRARIES ${MODULE} ) -endmacro() diff --git a/CMake/elxWinConfig.cmake b/CMake/elxWinConfig.cmake index 6f83da4f2ce11f43a2e5a2e9e965a94b91743e76..e0b1b38c129f9632c7c919475551c72a54c8bdf7 100644 --- a/CMake/elxWinConfig.cmake +++ b/CMake/elxWinConfig.cmake @@ -1,25 +1,18 @@ # Visual Studio complains if paths are too long +string( LENGTH "${CMAKE_CURRENT_SOURCE_DIR}" n ) +if( n GREATER 50 ) +message( + FATAL_ERROR + "Source code directory path length is too long for MSVC (${n} > 50)." + "Please move the source code directory to a directory with a shorter path." + ) +endif() -if( MSVC ) - string( LENGTH "${CMAKE_CURRENT_SOURCE_DIR}" n ) - if( n GREATER 50 ) - message( - FATAL_ERROR - "Source code directory path length is too long for MSVC (${n} > 50)." - "Please move the source code directory to a directory with a shorter path." - ) - endif() - - string( LENGTH "${CMAKE_CURRENT_BINARY_DIR}" n ) - if( n GREATER 50 ) - message( - FATAL_ERROR - "Build directory path length is too long for MSVC (${n} > 50)." - "Please move the build directory to a directory with a shorter path." - ) - endif() - - set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj" ) - set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /bigobj" ) - set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /bigobj" ) +string( LENGTH "${CMAKE_CURRENT_BINARY_DIR}" n ) +if( n GREATER 50 ) +message( + FATAL_ERROR + "Build directory path length is too long for MSVC (${n} > 50)." + "Please move the build directory to a directory with a shorter path." + ) endif() \ No newline at end of file diff --git a/CMake/elxWinConfigGoogleTest.cmake b/CMake/elxWinConfigGoogleTest.cmake deleted file mode 100644 index 75a5ac06f7db5c2020b3c4e11e85b572e07abf3f..0000000000000000000000000000000000000000 --- a/CMake/elxWinConfigGoogleTest.cmake +++ /dev/null @@ -1,6 +0,0 @@ -# GoogleTest needs static linking - -include( elxCompilerFlags.cmake ) -foreach( CompilerFlag ${CompilerFlags} ) - string( REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}" ) -endforeach() diff --git a/CMakeLists.txt b/CMakeLists.txt index eea7b29716863cb1db0a6dd49cd4fbc9f6ef7f3d..16133df8f210d8e872ad3a6c1fb7189227c75fc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required( VERSION 2.8 ) # Explicitly add INCREMENTAL linking option to command lines. # http://www.cmake.org/pipermail/cmake/2010-February/035174.html -set( MSVC_INCREMENTAL_DEFAULT ON ) +#set( MSVC_INCREMENTAL_DEFAULT ON ) # --------------------------------------------------------------------- project( Elastix ) @@ -13,13 +13,10 @@ set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ) # Include SuperElastix CMake scripts -set( CMAKE_MODULE_PATH - "${CMAKE_CURRENT_SOURCE_DIR}/CMake" - ${CMAKE_MODULE_PATH} -) +list( APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake" ) -if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC" ) - include( elxWinConfig.cmake ) +if( ${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC ) + include( elxWinConfig ) endif() # --------------------------------------------------------------------- @@ -31,14 +28,13 @@ include( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/elxITKRequiredModules.cmake" ) # --------------------------------------------------------------------- # Boost Graph Library -find_package( Boost REQUIRED graph ) +find_package( Boost ) include_directories( ${Boost_INCLUDE_DIRS} ) # --------------------------------------------------------------------- -# Build Elastix - +# Build SuperElastix # For now we just enable all modules -include( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/elxModules.cmake" ) +include( elxModules ) elxmodule_enable( elxModuleCore ) # --------------------------------------------------------------------- @@ -46,14 +42,14 @@ elxmodule_enable( elxModuleCore ) # Testing requires CMake version 2.8.11 to download test data if( CMAKE_VERSION VERSION_LESS 2.8.11 ) - set( ELASTIX_BUILD_TESTING_DEFAULT OFF ) + set( SUPERELASTIX_BUILD_TESTING_DEFAULT OFF ) message( STATUS "ELASTIX_BUILD_TESTING is set to OFF because CMake version is less than 2.8.11" ) else() - set( ELASTIX BUILD_TESTING_DEFAULT ON ) + set( SUPERELASTIX_BUILD_TESTING_DEFAULT ON ) endif() -option( ELASTIX_BUILD_TESTING "Enable building tests." ${ELASTIX_BUILD_TESTING_DEFAULT} ) -if( ${ELASTIX_BUILD_TESTING} ) +option( SUPERELASTIX_BUILD_TESTING "Enable building tests." ${SUPERELASTIX_BUILD_TESTING_DEFAULT} ) +if( ${SUPERELASTIX_BUILD_TESTING} ) enable_testing() add_subdirectory( Testing ) endif() @@ -61,9 +57,9 @@ endif() # --------------------------------------------------------------------- # Build Documentation -mark_as_advanced( ELASTIX_BUILD_DOXYGEN ) -option( ELASTIX_BUILD_DOXYGEN "Enable building Doxygen documentation." OFF ) +mark_as_advanced( SUPERELASTIX_BUILD_DOXYGEN ) +option( SUPERELASTIX_BUILD_DOXYGEN "Enable building Doxygen documentation." OFF ) -mark_as_advanced( ELASTIX_BUILD_READTHEDOCS ) -option( ELASTIX_BUILD_READTHEDOCS "Enable building readthedocs.org documentation." OFF ) +mark_as_advanced( SUPERELASTIX_BUILD_READTHEDOCS ) +option( SUPERELASTIX_BUILD_READTHEDOCS "Enable building readthedocs.org documentation." OFF ) diff --git a/Modules/Core/Blueprints/include/elxBlueprint.h b/Modules/Core/Blueprints/include/elxBlueprint.h index 8b42694b8227d2e0881a67b086f7af79147c2090..f0a9d19df23ee68bb071f4b27439226cc546eff0 100644 --- a/Modules/Core/Blueprints/include/elxBlueprint.h +++ b/Modules/Core/Blueprints/include/elxBlueprint.h @@ -1,57 +1,101 @@ #ifndef __Blueprint_h #define __Blueprint_h +#include "boost/graph/graph_traits.hpp" +#include "boost/graph/directed_graph.hpp" + #include "itkObjectFactory.h" #include "itkDataObject.h" #include "elxMacro.h" -#include "elxComponentDescriptor.h" - -#include "boost/graph/graph_traits.hpp" -#include "boost/graph/directed_graph.hpp" namespace elx { -template< class TComponentDescriptor > class Blueprint : public itk::DataObject { public: elxNewMacro( Blueprint, itk::DataObject ); - typedef TComponentDescriptor ComponentDescriptorType; - typedef typename TComponentDescriptor::ComponentNameType ComponentNameType; + typedef std::string ParameterKeyType; + typedef std::vector< std::string > ParameterValueType; + typedef std::map< ParameterKeyType, ParameterValueType > ParameterMapType; + + // Component parameter map that sits on a node in the graph + // and holds component configuration settings + struct ComponentPropertyType { + ParameterMapType parameterMap; + }; + + // Component parameter map that sits on an edge in the graph + // and holds component configuration settings + struct ConnectionPropertyType { + ParameterMapType parameterMap; + }; typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, - ComponentDescriptorType > GraphType; - - typedef typename boost::graph_traits< GraphType >::vertex_descriptor ComponentType; - typedef typename boost::graph_traits< GraphType >::vertex_iterator ComponentIterator, ComponentIteratorEnd; - - typedef boost::vertex_index_t ComponentIndexType; - typedef typename boost::property_map< GraphType, ComponentIndexType >::type ComponentIndexMapType; - - typedef typename boost::graph_traits< GraphType >::edge_descriptor ConnectionDescriptorType; - typedef typename boost::graph_traits< GraphType >::edge_iterator ConnectionIterator, ConnectionIteratorEnd; - - typedef typename boost::graph_traits< GraphType >::in_edge_iterator InputIterator, InputIteratorEnd; - typedef typename boost::graph_traits< GraphType >::out_edge_iterator OutputIterator, OutputIteratorEnd; - - int TestFunction( void ); - bool AddComponent( ComponentDescriptorType component ); - bool SetComponent( ComponentIndexType componentIndex, ComponentDescriptorType component ); - ComponentDescriptorType GetComponent( ComponentIndexType componentIndex ); - bool RemoveComponent( ComponentDescriptorType component ); - - bool SetConnection( ComponentIndexType upstream, ComponentIndexType downstream ); - ConnectionDescriptorType GetConnection( ConnectionDescriptorType Connection ); - bool RemoveConnection( ConnectionDescriptorType connection ); - - void PrintGraph( void ); + ComponentPropertyType, + ConnectionPropertyType > GraphType; + + typedef boost::graph_traits< GraphType >::vertex_descriptor ComponentIndexType; + typedef boost::graph_traits< GraphType >::vertex_iterator ComponentIteratorType; + typedef std::pair< ComponentIteratorType, ComponentIteratorType > ComponentIteratorPairType; + + typedef boost::graph_traits< GraphType >::edge_descriptor ConnectionIndexType; + typedef boost::graph_traits< GraphType >::edge_iterator ConnectionIteratorType; + typedef std::pair< ConnectionIteratorType, ConnectionIteratorType > ConnectionIteratorPairType; + + typedef boost::graph_traits< GraphType >::in_edge_iterator InputIteratorType; + typedef std::pair< InputIteratorType, InputIteratorType > InputIteratorPairType; + + typedef boost::graph_traits< GraphType >::out_edge_iterator OutputIteratorType; + typedef std::pair< OutputIteratorType, OutputIteratorType > OutputIteratorPairType; + + // Interface for managing components + ComponentIndexType AddComponent( void ); + ComponentIndexType AddComponent( ParameterMapType parameterMap ); + ParameterMapType GetComponent( ComponentIndexType index ); + void SetComponent( ComponentIndexType, ParameterMapType parameterMap ); + + // TODO: Let user delete component. Before we do this, we need a proper way of + // checking that a vertex exist. Otherwise a call to GetComponent() on + // a deleted vertex will result in segfault. It is not really a in issue + // _before_ release since typically we (the developers) will use blueprint + // interface procedurally. + // void DeleteComponent( ComponentIndexType ); + + ComponentIteratorPairType GetComponentIterator( void ) { + return boost::vertices( this->m_Graph ); + } + + // Interface for managing connections between components in which we + // deliberately avoid using connection indexes, but instead force + // the user to think in terms of components (which is conceptually simpler) + bool AddConnection( ComponentIndexType upstream, ComponentIndexType downstream ); + bool AddConnection( ComponentIndexType upstream, ComponentIndexType downstream, ParameterMapType parameterMap ); + ParameterMapType GetConnection( ComponentIndexType upstream, ComponentIndexType downstream ); + bool SetConnection( ComponentIndexType upstream, ComponentIndexType downstream, ParameterMapType parameterMap ); + bool DeleteConnection( ComponentIndexType upstream, ComponentIndexType downstream ); + bool ConnectionExists( ComponentIndexType upstream, ComponentIndexType downstream ); + + // Returns iterator for all connections in the graph + ConnectionIteratorPairType GetConnectionIterator( void ) { + return boost::edges(this->m_Graph); + } + + // Returns the outgoing connections from a component in the graph, + // i.e. all components that reads data from given component + OutputIteratorPairType GetOutputIterator( const ComponentIndexType index ) { + return boost::out_edges( index, this->m_Graph ); + } + + void WriteBlueprint( const std::string filename ); private: + + ConnectionIndexType GetConnectionIndex( ComponentIndexType upsteam, ComponentIndexType downstream ); GraphType m_Graph; diff --git a/Modules/Core/Blueprints/include/elxComponentDescriptor.h b/Modules/Core/Blueprints/include/elxComponentDescriptor.h deleted file mode 100644 index 8f5402e4526532088cc8089d4af95d775a848b33..0000000000000000000000000000000000000000 --- a/Modules/Core/Blueprints/include/elxComponentDescriptor.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __ComponentDescriptor_h -#define __ComponentDescriptor_h - -#include "elxMacro.h" -#include "itkObjectFactory.h" -#include "itkDataObject.h" - -namespace elx { - -class ComponentDescriptor : public itk::DataObject -{ -public: - - elxNewMacro( ComponentDescriptor, itk::DataObject ); - - // Identifier to find component in the component database - typedef std::string ComponentNameType; - - ComponentDescriptor( void ) { this->SetComponentName( ComponentNameType() ); } - ComponentDescriptor( const ComponentNameType componentName ); - - // TODO: Setter should validate ComponentName exists in ComponentDatabase - itkSetMacro( ComponentName, ComponentNameType ); - itkGetMacro( ComponentName, ComponentNameType ); - -private: - - ComponentNameType m_ComponentName; - -}; - -} - -#endif // __ComponentDescriptor_h diff --git a/Modules/Core/Blueprints/src/elxBlueprint.cxx b/Modules/Core/Blueprints/src/elxBlueprint.cxx index b3319d01551325a82b0926f0f1a33fd4fd3f7abf..d78d2ce6882287d6a42176310b6afea3c2cb0ff4 100644 --- a/Modules/Core/Blueprints/src/elxBlueprint.cxx +++ b/Modules/Core/Blueprints/src/elxBlueprint.cxx @@ -1,77 +1,160 @@ -#ifndef __Blueprint_hxx -#define __Blueprint_hxx +#ifndef __Blueprint_cxx +#define __Blueprint_cxx -#include <boost/graph/graphviz.hpp> +#include "boost/graph/graphviz.hpp" #include "elxBlueprint.h" namespace elx { -/* -Blueprint< ComponentDescriptor >::ComponentDescriptorType -Blueprint< ComponentDescriptor > -::AddComponent( ComponentDescriptorType component ) +Blueprint::ComponentIndexType +Blueprint +::AddComponent( void ) { - // TODO: Check that the component is in the ComponentDatabase this->Modified(); - return this->m_Graph->add_vertex( component ); + + ComponentIndexType index = boost::add_vertex( this->m_Graph ); + + // Return component index so component can retrieved at a later time + return index; } -bool -Blueprint< ComponentDescriptor > -::SetComponent( ComponentDescriptorType component ) +Blueprint::ComponentIndexType +Blueprint +::AddComponent( ParameterMapType parameterMap ) +{ + this->Modified(); + + ComponentIndexType index = boost::add_vertex( this->m_Graph ); + this->m_Graph[index].parameterMap = parameterMap; + + // Return component index so component can retrieved at a later time + return index; +} + +Blueprint::ParameterMapType +Blueprint +::GetComponent( ComponentIndexType index ) { this->Modified(); - return this->m_Graph->remove_vertex( connection ); + + return this->m_Graph[ index ].parameterMap; +} + +void +Blueprint +::SetComponent( ComponentIndexType index, ParameterMapType parameterMap ) +{ + this->Modified(); + this->m_Graph[ index ].parameterMap = parameterMap; } +// TODO: See explanation in elxBlueprint.h +// void +// Blueprint +// ::DeleteComponent( const ComponentIndexType index ) +// { +// this->Modified(); +// +// clear_vertex( index, this->m_Graph ); +// remove_vertex( index, this->m_Graph ); +// } + bool -Blueprint< ComponentDescriptor > -::RemoveComponent( ComponentDescriptorType component ) +Blueprint +::AddConnection( ComponentIndexType upstream, ComponentIndexType downstream ) { this->Modified(); - return this->m_Graph->remove_vertex( connection ); + + if( this->ConnectionExists( upstream, downstream) ) { + return false; + } + + // Adds directed connection from upstream component to downstream component + return boost::add_edge( upstream, downstream, this->m_Graph ).second; } bool -Blueprint< ComponentDescriptor > -::AddConnection( ComponentDescriptorType upsteam, ComponentDescriptorType downstream ) +Blueprint +::AddConnection( ComponentIndexType upstream, ComponentIndexType downstream, ParameterMapType parameterMap ) +{ + this->Modified(); + + if( !this->ConnectionExists( upstream, downstream ) ) { + ConnectionIndexType index = boost::add_edge( upstream, downstream, this->m_Graph ).first; + this->m_Graph[ index ].parameterMap = parameterMap; + return true; + } + + // If the connection does not exist don't do anything because previous settings + // will be overwritten. If the user do want to overwrite current settings, + // she should use SetConnection() instead where the intent is explicit. + return false; +} + +Blueprint::ParameterMapType +Blueprint +::GetConnection( ComponentIndexType upstream, ComponentIndexType downstream ) { this->Modified(); - return this->m_Graph->add_edge( upstream, downstream ); + + return this->m_Graph[ this->GetConnectionIndex( upstream, downstream ) ].parameterMap; } -ConnectionDescriptorType -Blueprint< ComponentDescriptor > -::GetConnection( ConnectionDescriptorType Connection ) +bool +Blueprint +::SetConnection( ComponentIndexType upstream, ComponentIndexType downstream, ParameterMapType parameterMap ) { this->Modified(); + + if( !this->ConnectionExists( upstream, downstream ) ) { + return this->AddConnection( upstream, downstream, parameterMap ); + } else { + this->m_Graph[ this->GetConnectionIndex( upstream, downstream ) ].parameterMap = parameterMap; + return true; + } } -void -Blueprint< ComponentDescriptor > -::RemoveConnection( ConnectionType connection ) +bool +Blueprint +::DeleteConnection( ComponentIndexType upstream, ComponentIndexType downstream ) { this->Modified(); - this->m_Graph->remove_edge( connection ); + + if( this->ConnectionExists( upstream, downstream ) ) { + this->m_Graph.remove_edge( this->GetConnectionIndex( upstream, downstream ) ); + } + + return !this->ConnectionExists( upstream, downstream ); } -void -Blueprint< ComponentDescriptor > -::PrintGraph( void ) +bool +Blueprint +::ConnectionExists( ComponentIndexType upstream, ComponentIndexType downstream ) { - // TODO: Link to graphviz library - // boost::write_graphviz(std::cout, this->m_Graph); - std::cout << "Printed graph" << std::endl; + return boost::edge( upstream, downstream, this->m_Graph).second; } -*/ -template<> -int -Blueprint< ComponentDescriptor > -::TestFunction( void ) -{ return 0; } +Blueprint::ConnectionIndexType +Blueprint +::GetConnectionIndex( ComponentIndexType upstream, ComponentIndexType downstream ) +{ + // This function is part of the internal API and should fail hard if we use it incorrectly + if( !this->ConnectionExists( upstream, downstream ) ) { + itkExceptionMacro( "Blueprint does not contain connection from component " << upstream << " to " << downstream ); + } + + return boost::edge( upstream, downstream, this->m_Graph).first; +} + +void +Blueprint +::WriteBlueprint( const std::string filename ) +{ + std::ofstream dotfile( filename.c_str() ); + boost::write_graphviz( dotfile, this->m_Graph ); +} } // namespace elx -#endif // __Blueprint_hxx \ No newline at end of file +#endif // __Blueprint_cxx diff --git a/Modules/Core/Blueprints/src/elxComponentDescriptor.cxx b/Modules/Core/Blueprints/src/elxComponentDescriptor.cxx deleted file mode 100644 index 9589451733f5f3b2c14b45e990f70711bab241e5..0000000000000000000000000000000000000000 --- a/Modules/Core/Blueprints/src/elxComponentDescriptor.cxx +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __ComponentDescriptor_cxx -#define __ComponentDescriptor_cxx - -#include "elxComponentDescriptor.h" - -// TODO: Need enum for component name? - -namespace elx { - -ComponentDescriptor -::ComponentDescriptor( const ComponentNameType componentName ) -{ - this->SetComponentName( componentName ); -} - -} // namespace elx - -#endif // __ComponentDescriptor_cxx \ No newline at end of file diff --git a/Modules/Core/CMakeLists.txt b/Modules/Core/CMakeLists.txt deleted file mode 100644 index 50296aa3c753ddf0818b1b78653383350f700b40..0000000000000000000000000000000000000000 --- a/Modules/Core/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -elxmodule_compile( ${MODULE} ) diff --git a/Modules/Core/elxModuleCore.cmake b/Modules/Core/elxModuleCore.cmake index eaebd893405d56be9b9edeb671461538b04cca09..24e93a5aced2900241b50cb7df509fa9c1c03b00 100644 --- a/Modules/Core/elxModuleCore.cmake +++ b/Modules/Core/elxModuleCore.cmake @@ -1,13 +1,22 @@ +set( MODULE elxModuleCore ) + +# Export include files set( ${MODULE}_INCLUDE_DIRS - ${CMAKE_SOURCE_DIR}/${MODULE_PATH}/Common/include - ${CMAKE_SOURCE_DIR}/${MODULE_PATH}/Blueprints/include + ${${MODULE}_SOURCE_DIR}/Common/include + ${${MODULE}_SOURCE_DIR}/Blueprints/include +) + +# Export libraries +set( ${MODULE}_LIBRARIES + ${MODULE} ) +# Module source files set( ${MODULE}_SOURCE_FILES - ${CMAKE_SOURCE_DIR}/${MODULE_PATH}/Blueprints/src/elxComponentDescriptor.cxx - ${CMAKE_SOURCE_DIR}/${MODULE_PATH}/Blueprints/src/elxBlueprint.cxx + ${${MODULE}_SOURCE_DIR}/Blueprints/src/elxBlueprint.cxx ) -set( ${MODULE}_LIBRARIES - elxModuleCore -) \ No newline at end of file +# Compile library + +add_library( ${MODULE} STATIC "${${MODULE}_SOURCE_FILES}" ) +target_link_libraries( ${MODULE} ${ELASTIX_LIBRARIES} ) diff --git a/SuperBuild/CMakeLists.txt b/SuperBuild/CMakeLists.txt index 0eb91de3a6f2cccb4fd546af8fb89ce8ff0777aa..42f3f9f5df469a6cd04b17183168b264ac363433 100644 --- a/SuperBuild/CMakeLists.txt +++ b/SuperBuild/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required( VERSION 2.8 ) # --------------------------------------------------------------------- -project( ElastixSuperBuild ) +project( SuperElastixSuperBuild ) find_package( Git REQUIRED ) @@ -25,24 +25,24 @@ endif() # Build examples by default # Examples will be build as an external project to verify the installation of elastix -option( ELASTIX_BUILD_EXAMPLES "Enable building examples." ON ) +option( SUPERELASTIX_BUILD_EXAMPLES "Enable building examples." ON ) # Build tests by default -option( ELASTIX_BUILD_TESTING "Enable building tests." ON ) -if( ELASTIX_BUILD_TESTING ) - option( ELASTIX_BUILD_BENCHMARKING "Enable building benchmarks." ON ) - option( ELASTIX_BUILD_DASHBOARD "Enable building benchmarks." ON ) +option( SUPERELASTIX_BUILD_TESTING "Enable building tests." ON ) +if( SUPERELASTIX_BUILD_TESTING ) + option( SUPERELASTIX_BUILD_BENCHMARKING "Enable building benchmarks." ON ) + option( SUPERELASTIX_BUILD_DASHBOARD "Enable building benchmarks." ON ) endif() # Do not build dashboard by default -option( ELASTIX_BUILD_DASHBOARD "Enable building dashboard." OFF ) +option( SUPERELASTIX_BUILD_DASHBOARD "Enable building dashboard." OFF ) # --------------------------------------------------------------------- # Build ITK set( ITK_VERSION_MAJOR "4" ) -set( ITK_VERSION_MINOR "7" ) +set( ITK_VERSION_MINOR "8" ) set( ITK_VERSION_PATCH "1" ) set( ITK_VERSION_STRING "${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}.${ITK_VERSION_PATCH}" ) @@ -51,10 +51,9 @@ option( USE_SYSTEM_ITK "Use an installed version of ITK" OFF ) if( USE_SYSTEM_ITK ) find_package( ITK ${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR} REQUIRED ) - include( "${CMAKE_CURRENT_SOURCE_DIR}/../CMake/elxRequiredITKModules.cmake" ) + include( elxRequiredITKModules ) else() include( ExternalITK ) - list( APPEND ELASTIX_DEPENDENCIES ITK ) endif() # --------------------------------------------------------------------- @@ -66,13 +65,35 @@ if( USE_SYSTEM_BOOST ) find_package( BOOST REQUIRED graph ) else() include( ExternalBoost ) - list( APPEND ELASTIX_DEPENDENCIES BOOST ) endif() +# --------------------------------------------------------------------- +# Build GoogleTest + +option( USE_SYSTEM_GOOGLETEST "Use a pre-compiled version of GoogleTest. " OFF ) +mark_as_advanced(USE_SYSTEM_GOOGLETEST) +if ( SUPERELASTIX_BUILD_TESTING ) + if ( USE_SYSTEM_GOOGLETEST ) + find_package( GTest REQUIRED ) + else() + include( ExternalGoogleTest ) + endif() +endif() + # --------------------------------------------------------------------- # Build Elastix -include( Elastix ) +# TODO: Add USE_SYSTEM_ELASTICLEGACY option +mark_as_advanced( SUPERELASTIX_BUILD_ELASTIX ) +option( SUPERELASTIX_BUILD_ELASTIX ON ) +if( SUPERELASTIX_BUILD_ELASTIX ) + include( ExternalElastix ) +endif() + +# --------------------------------------------------------------------- +# Build SuperElastix + +include( SuperElastix ) diff --git a/SuperBuild/Elastix.cmake b/SuperBuild/Elastix.cmake deleted file mode 100644 index 1f1d739399df9111afa2df1d2577b2b4e6e91472..0000000000000000000000000000000000000000 --- a/SuperBuild/Elastix.cmake +++ /dev/null @@ -1,17 +0,0 @@ -set( proj Elastix ) - -ExternalProject_Add( ${proj} - DOWNLOAD_COMMAND "" - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/.. - BINARY_DIR ${proj}-build - CMAKE_ARGS - --no-warn-unused-cli - -DELASTIX_BUILD_EXAMPLES:BOOL=${ELASTIX_BUILD_EXAMPLES} - -DELASTIX_BUILD_TESTING:BOOL=${ELASTIX_BUILD_TESTING} - -DELASTIX_BUILD_BENCHMARKING:BOOL=${ELASTIX_BUILD_BENCHMARKING} - -DELASTIX_BUILD_DASHBOARD:BOOL=${ELASTIX_BUILD_DASHBOARD} - -DITK_DIR:PATH=${ITK_DIR} - -DBOOST_ROOT:PATH=${BOOST_ROOT} - DEPENDS ${ELASTIX_DEPENDENCIES} - INSTALL_COMMAND "" -) diff --git a/SuperBuild/ExternalBoost.cmake b/SuperBuild/ExternalBoost.cmake index e1f1286e9995efa98dce2649cc9aa79a41bebdbf..1047e94c5ae73d1dd77b115bf81ecfddc858ffec 100644 --- a/SuperBuild/ExternalBoost.cmake +++ b/SuperBuild/ExternalBoost.cmake @@ -1,4 +1,4 @@ -set( PROJECT BOOST ) +set( proj BOOST ) # Note: It IS important to download different files on different OS's: # on Unix-like systems, we need the file persmissions (only available in the .tar.gz), @@ -19,7 +19,7 @@ else() endif() endif() -set( BOOST_BUILD_DIR "${CMAKE_INSTALL_PREFIX}/${PROJECT}-build/" ) +set( BOOST_BUILD_DIR "${CMAKE_INSTALL_PREFIX}/${proj}-build/" ) ExternalProject_Add( BOOST BUILD_IN_SOURCE 1 @@ -27,13 +27,10 @@ ExternalProject_Add( BOOST URL_MD5 ${BOOST_MD5} UPDATE_COMMAND "" CONFIGURE_COMMAND ${BOOST_CONFIGURE_COMMAND} - --prefix=${BOOST_BUILD_DIR}/lib - BUILD_COMMAND ${BOOST_BUILD_COMMAND} install - --prefix=${BOOST_BUILD_DIR} - --with-graph - --variant=release - --jobs=4 + BUILD_COMMAND "" INSTALL_COMMAND "" ) -set( BOOST_ROOT ${BOOST_BUILD_DIR} ) +set( BOOST_ROOT "${CMAKE_INSTALL_PREFIX}/${proj}-prefix/src/BOOST" ) + +list( APPEND ELASTIX_DEPENDENCIES ${proj} ) diff --git a/SuperBuild/ExternalElastix.cmake b/SuperBuild/ExternalElastix.cmake new file mode 100644 index 0000000000000000000000000000000000000000..f99860c9de6e3a144909a695553ef200055ec313 --- /dev/null +++ b/SuperBuild/ExternalElastix.cmake @@ -0,0 +1,102 @@ +set( proj Elastix ) + +set( ELASTIX_REPOSITORY git://github.com/mstaring/elastix.git ) +set( ELASTIX_TAG 6eb6fc7e0d86bafdfdffb1b8bbd125f2a56a486e ) + +ExternalProject_Add( ${proj} + GIT_REPOSITORY ${ELASTIX_REPOSITORY} + GIT_TAG ${ELASTIX_TAG} + UPDATE_COMMAND "" + SOURCE_DIR ${proj} + BINARY_DIR ${proj}-build + CMAKE_GENERATOR ${gen} + CMAKE_ARGS + --no-warn-unused-cli + -DELASTIX_BUILD_TESTING:BOOL=OFF + -DELASTIX_BUILD_EXECUTABLE:BOOL=OFF + -DELASTIX_BUILD_SHARED_LIBS:BOOL=${BUILD_SHARED_LIBS} + -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> + -DITK_DIR:PATH=${ITK_DIR} + # Elastix components configuration + -DUSE_AdaptiveStochasticGradientDescent:BOOL=ON + -DUSE_AdvancedAffineTransformElastix:BOOL=ON + -DUSE_AdvancedBSplineTransform:BOOL=ON + -DUSE_AdvancedKappaStatisticMetric:BOOL=ON + -DUSE_AdvancedMattesMutualInformationMetric:BOOL=ON + -DUSE_AdvancedMeanSquaresMetric:BOOL=ON + -DUSE_AdvancedNormalizedCorrelationMetric:BOOL=ON + -DUSE_AffineDTITransformElastix:BOOL=ON + -DUSE_BSplineInterpolator:BOOL=ON + -DUSE_BSplineInterpolatorFloat:BOOL=ON + -DUSE_BSplineResampleInterpolator:BOOL=ON + -DUSE_BSplineResampleInterpolatorFloat:BOOL=ON + -DUSE_BSplineStackTransform:BOOL=ON + -DUSE_BSplineTransformWithDiffusion:BOOL=ON + -DUSE_CMAEvolutionStrategy:BOOL=ON + -DUSE_CUDAResampler:BOOL=OFF + -DUSE_ConjugateGradient:BOOL=ON + -DUSE_ConjugateGradientFRPR:BOOL=ON + -DUSE_CorrespondingPointsEuclideanDistanceMetric:BOOL=ON + -DUSE_DeformationFieldTransform:BOOL=ON + -DUSE_DisplacementMagnitudePenalty:BOOL=ON + -DUSE_DistancePreservingRigidityPenalty:BOOL=ON + -DUSE_EulerTransformElastix:BOOL=ON + -DUSE_FiniteDifferenceGradientDescent:BOOL=ON + -DUSE_FixedGenericPyramid:BOOL=ON + -DUSE_FixedRecursivePyramid:BOOL=ON + -DUSE_FixedShrinkingPyramid:BOOL=ON + -DUSE_FixedSmoothingPyramid:BOOL=ON + -DUSE_FullSampler:BOOL=ON + -DUSE_FullSearch:BOOL=ON + -DUSE_GradientDifferenceMetric:BOOL=ON + -DUSE_GridSampler:BOOL=ON + -DUSE_KNNGraphAlphaMutualInformationMetric:BOOL=OFF + -DUSE_LinearInterpolator:BOOL=ON + -DUSE_LinearResampleInterpolator:BOOL=ON + -DUSE_MissingStructurePenalty:BOOL=ON + -DUSE_MovingRecursivePyramid:BOOL=ON + -DUSE_MovingShrinkingPyramid:BOOL=ON + -DUSE_MovingSmoothingPyramid:BOOL=ON + -DUSE_MultiBSplineTransformWithNormal:BOOL=ON + -DUSE_MultiInputRandomCoordinateSampler:BOOL=ON + -DUSE_MultiMetricMultiResolutionRegistration:BOOL=ON + -DUSE_MultiResolutionRegistration:BOOL=ON + -DUSE_MultiResolutionRegistrationWithFeatures:BOOL=ON + -DUSE_MutualInformationHistogramMetric:BOOL=ON + -DUSE_MyStandardResampler:BOOL=ON + -DUSE_NearestNeighborInterpolator:BOOL=ON + -DUSE_NearestNeighborResampleInterpolator:BOOL=ON + -DUSE_NormalizedGradientCorrelationMetric:BOOL=ON + -DUSE_NormalizedMutualInformationMetric:BOOL=ON + -DUSE_PatternIntensityMetric:BOOL=ON + -DUSE_PolydataDummyPenalty:BOOL=ON + -DUSE_Powell:BOOL=ON + -DUSE_QuasiNewtonLBFGS:BOOL=ON + -DUSE_RSGDEachParameterApart:BOOL=ON + -DUSE_RandomCoordinateSampler:BOOL=ON + -DUSE_RandomSampler:BOOL=ON + -DUSE_RandomSamplerSparseMask:BOOL=ON + -DUSE_RayCastInterpolator:BOOL=ON + -DUSE_RayCastResampleInterpolator:BOOL=ON + -DUSE_ReducedDimensionBSplineInterpolator:BOOL=ON + -DUSE_ReducedDimensionBSplineResampleInterpolator:BOOL=ON + -DUSE_RegularStepGradientDescent:BOOL=ON + -DUSE_SimilarityTransformElastix:BOOL=ON + -DUSE_Simplex:BOOL=ON + -DUSE_SimultaneousPerturbation:BOOL=ON + -DUSE_SplineKernelTransform:BOOL=ON + -DUSE_StandardGradientDescent:BOOL=ON + -DUSE_StatisticalShapePenalty:BOOL=ON + -DUSE_TransformBendingEnergyPenanalty:BOOL=ON + -DUSE_TransformRigidityPenalty:BOOL=ON + -DUSE_TranslationTransformElastix:BOOL=ON + -DUSE_VarianceOverLastDimensionMetric:BOOL=ON + -DUSE_ViolaWellsMutualInformationMetric:BOOL=ON + -DUSE_WeightedCombinationTransformElastix:BOOL=ON + DEPENDS ITK +) + +ExternalProject_Get_Property( Elastix binary_dir ) +set( ELASTIX_USE_FILE "${binary_dir}/src/UseElastix.cmake" ) + +list( APPEND ELASTIX_DEPENDENCIES ${proj} ) diff --git a/SuperBuild/ExternalGoogleTest.cmake b/SuperBuild/ExternalGoogleTest.cmake new file mode 100644 index 0000000000000000000000000000000000000000..dbdd33a10430de35bd4ce3a267a9114a34ad3e11 --- /dev/null +++ b/SuperBuild/ExternalGoogleTest.cmake @@ -0,0 +1,42 @@ +set( proj GoogleTest ) + +set( GTEST_TARGET_VERSION 1.7.0 ) +set( GTEST_DOWNLOAD_SOURCE_HASH "2d6ec8ccdf5c46b05ba54a9fd1d130d7" ) + +set( GTEST_binary_dir ${CMAKE_CURRENT_BINARY_DIR}/${proj}-prefix/src/${proj}-build ) +set( GTEST_source_dir ${CMAKE_CURRENT_BINARY_DIR}/${proj}-prefix/src/${proj} ) +set( GTEST_install_dir ${CMAKE_CURRENT_BINARY_DIR}/${proj} ) + +set( ${proj}_ARCHIVE_OUTPUT_DIRECTORY "<BINARY_DIR>/lib" ) +if( MSVC ) + set( ${proj}_ARCHIVE_OUTPUT_DIRECTORY "<BINARY_DIR>/lib/$<CONFIGURATION>" ) +endif() + +set( MSVS_ARGS ) +if(MSVC_VERSION EQUAL 1700) + set(MSVS_ARGS ${MSVS_ARGS} -D CMAKE_CXX_FLAGS=-DGTEST_HAS_TR1_TUPLE=0 ${CMAKE_CXX_FLAGS}) +endif() + +if( MSVC) + set( MSVS_ARGS ${MSVS_ARGS} -D gtest_force_shared_crt:BOOL=ON ) +endif() + +ExternalProject_Add(${proj} + URL http://midas3.kitware.com/midas/api/rest?method=midas.bitstream.download&checksum=${GTEST_DOWNLOAD_SOURCE_HASH}&name=swig-${GTEST_TARGET_VERSION}.zip + URL_MD5 ${GTEST_DOWNLOAD_SOURCE_HASH} + INSTALL_DIR ${GTEST_install_dir} + CMAKE_GENERATOR ${gen} + CMAKE_ARGS + --no-warn-unused-cli + ${MSVS_ARGS} + -D BUILD_SHARED_LIBS:BOOL=OFF + -D CMAKE_ARCHIVE_OUTPUT_DIRECTORY:PATH=<BINARY_DIR>/lib + INSTALL_COMMAND + ${CMAKE_COMMAND} -E copy_directory ${${proj}_ARCHIVE_OUTPUT_DIRECTORY} <INSTALL_DIR>/lib + COMMAND + ${CMAKE_COMMAND} -E copy_directory <SOURCE_DIR>/include <INSTALL_DIR>/include +) + +set( GTEST_ROOT ${GTEST_install_dir} ) +list( APPEND ELASTIX_DEPENDENCIES ${proj} ) + diff --git a/SuperBuild/ExternalITK.cmake b/SuperBuild/ExternalITK.cmake index 0ee77affea1569d7f946b128e1a7de2756189959..6ab8438bc3a503fb8777c5710fcf79ce2eee8264 100644 --- a/SuperBuild/ExternalITK.cmake +++ b/SuperBuild/ExternalITK.cmake @@ -1,24 +1,25 @@ -set( PROJECT ITK ) +set( proj ITK ) set( ITK_REPOSITORY https://github.com/InsightSoftwareConsortium/ITK.git ) set( ITK_TAG "v${ITK_VERSION_STRING}") -ExternalProject_Add( ${PROJECT} +ExternalProject_Add( ${proj} GIT_REPOSITORY ${ITK_REPOSITORY} GIT_TAG ${ITK_TAG} UPDATE_COMMAND "" - SOURCE_DIR ${PROJECT} - BINARY_DIR ${PROJECT}-build + SOURCE_DIR ${proj} + BINARY_DIR ${proj}-build CMAKE_ARGS --no-warn-unused-cli -DBUILD_EXAMPLES:BOOL=OFF -DBUILD_TESTING:BOOL=OFF -DITK_BUILD_DEFAULT_MODULES:BOOL=ON -DModule_ITKReview:BOOL=ON - -DBUILD_SHARED_LIBS:BOOL=${BUILD_SHARED_LIBS} -DCMAKE_SKIP_RPATH:BOOL=ON -DITK_LEGACY_REMOVE:BOOL=ON -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> ) -ExternalProject_Get_Property( ITK install_dir ) +ExternalProject_Get_Property( ${proj} install_dir ) set( ITK_DIR "${install_dir}/lib/cmake/ITK-${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}" ) + +list( APPEND ELASTIX_DEPENDENCIES ${proj} ) diff --git a/SuperBuild/SuperElastix.cmake b/SuperBuild/SuperElastix.cmake new file mode 100644 index 0000000000000000000000000000000000000000..38c6ed2feb058a1b8cb09851e208f1a348071696 --- /dev/null +++ b/SuperBuild/SuperElastix.cmake @@ -0,0 +1,19 @@ +set( proj SuperElastix ) + +ExternalProject_Add( ${proj} + DOWNLOAD_COMMAND "" + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/.. + BINARY_DIR ${proj}-build + CMAKE_ARGS + --no-warn-unused-cli + -DSUPERELASTIX_BUILD_EXAMPLES:BOOL=${SUPERELASTIX_BUILD_EXAMPLES} + -DSUPERELASTIX_BUILD_TESTING:BOOL=${SUPERELASTIX_BUILD_TESTING} + -DSUPERELASTIX_BUILD_BENCHMARKING:BOOL=${SUPERELASTIX_BUILD_BENCHMARKING} + -DSUPERELASTIX_BUILD_DASHBOARD:BOOL=${SUPERELASTIX_BUILD_DASHBOARD} + -DITK_DIR:PATH=${ITK_DIR} + -DBOOST_ROOT:PATH=${BOOST_ROOT} + -DGTEST_ROOT:PATH=${GTEST_ROOT} + -DELASTIX_USE_FILE:PATH=${ELASTIX_USE_FILE} + DEPENDS ${ELASTIX_DEPENDENCIES} + INSTALL_COMMAND "" +) diff --git a/Testing/CMakeLists.txt b/Testing/CMakeLists.txt index 9598ac8c17113e6a582022ec82d0d1b53eef530e..71f3fea9c73a24d50f491a6825edcaeadc57ac8d 100644 --- a/Testing/CMakeLists.txt +++ b/Testing/CMakeLists.txt @@ -30,50 +30,23 @@ endforeach() ExternalData_Add_Target( ElastixData ) # --------------------------------------------------------------------- -# Add GoogleTest +# Find GoogleTest library -find_package( Git ) -if( NOT EXISTS "${CMAKE_SOURCE_DIR}/Testing/GoogleTest/.git" AND GIT_EXECUTABLE ) - execute_process( - COMMAND ${GIT_EXECUTABLE} submodule update --init - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - OUTPUT_QUIET - ) -endif() - -if( NOT EXISTS ${CMAKE_SOURCE_DIR}/Testing/GoogleTest/.git ) - message( - FATAL_ERROR "Could not find GoogleTest submodule. Please run - git submodule update --init in the source directory to compile tests." - ) -endif() - -if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC" ) - include( elxWinConfigGoogleTest.cmake ) -endif() - -add_subdirectory( GoogleTest ) - -include_directories( - ${gtest_SOURCE_DIR}/include -) +find_package( GTest REQUIRED ) +include_directories( ${GTEST_INCLUDE_DIRS} ) set( TEST_LIBRARIES - gtest_main + ${GTEST_BOTH_LIBRARIES} ) # --------------------------------------------------------------------- # Build test suite +set( CTEST_CONFIGURATION_TYPE Debug ) + # Unit tests add_subdirectory( Unit ) -# Benchmarks -option( ELASTIX_BUILD_BENCHMARKING "Enable building benchmarks." OFF ) -if( ${ELASTIX_BUILD_BENCHMARKING} ) - add_subdirectory( Benchmark ) -endif() - # --------------------------------------------------------------------- # Configure dashboard mark_as_advanced( ELASTIX_BUILD_DASHBOARD ) diff --git a/Testing/Dashboard/CMakeLists.txt b/Testing/Dashboard/CMakeLists.txt index 202478325aeea62261d1c8dd11773e54eb1ba132..45902125adcd5c2d4ec3d116479335a5034ac430 100644 --- a/Testing/Dashboard/CMakeLists.txt +++ b/Testing/Dashboard/CMakeLists.txt @@ -15,10 +15,6 @@ set( ELASTIX_DASHBOARD_LOGSTASH_RSA_PRIVATE_KEY "elxLogstash.key" ) mark_as_advanced( ELASTIX_DASHBOARD_VOLUME ) if( NOT EXISTS "${ELASTIX_DASHBOARD_VOLUME}" ) - message( STATUS - "ELASTIX_DASHBOARD_VOLUME points to the folder ${CMAKE_BINARY_DIR}/Testing/Dashboard/Data in your build directory. In production you should point this variable to a safe directory outside the build tree." - ) - set( ELASTIX_DASHBOARD_VOLUME "${ELASTIX_DASHBOARD_BINARY_DIR}/Data" ) file( MAKE_DIRECTORY "${ELASTIX_DASHBOARD_VOLUME}" ) endif() @@ -46,4 +42,9 @@ configure_file( configure_file( ${ELASTIX_DASHBOARD_SOURCE_DIR}/elxLogstashForwarder.json.in ${ELASTIX_DASHBOARD_BINARY_DIR}/elxLogstashForwarder.json -) \ No newline at end of file +) + +# --------------------------------------------------------------------- +# SSL certificates +# Use the following OpenSSL command to generate a test certificate and key if needed +# openssl req -subj '/CN=*/' -x509 -batch -nodes -days 9999 -newkey rsa:2048 -keyout elxLogstash.key -out elxLogstash.crt diff --git a/Testing/Dashboard/elxLogstash.crt b/Testing/Dashboard/elxLogstash.crt index 56ef6e0dcf697be1be407db7ca75cf31112821d0..f677ecb5798ea52056694f954a80fa9a524ada80 100644 --- a/Testing/Dashboard/elxLogstash.crt +++ b/Testing/Dashboard/elxLogstash.crt @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDGjCCAgKgAwIBAgIJAMF8GSVtnyB6MA0GCSqGSIb3DQEBBQUAMBIxEDAOBgNV -BAMTB2VsYXN0aXgwHhcNMTUwODEyMTQxNjE1WhcNMTUwOTExMTQxNjE1WjASMRAw -DgYDVQQDEwdlbGFzdGl4MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -01P404f+W/aBLxlQTFyHy1o7m07edUmFIjJuN9JjGTzZtlhAEc7dXJ8fUwr/hnLq -HUeaGRbNcpFDj+/Xq2W9jH7/VyxivA8Ib7ycLNxywgmheZVxXetPIeYmK+Rqovyd -GhMcU0WMv/3OslFjf92PLegFgRYbmJa7rEH+I0MD1hE1rn1AIJeU4nVCUrtQON6g -icDEZSNwVSuLfdiuHCMcAVWx+pQIyHji6EoyIBjNsF8LoBZoMY5N+qRph8tt9k1N -GemQoaZWd926jWgrsSSrAfgtMxw43TXwCFe8RiL8L+pZlN4xxYjQj1/PtTowqjzL -dYqWAT0o5zwlqkrNgjTuYwIDAQABo3MwcTAdBgNVHQ4EFgQU8onFqrecR/J81ZFi -gonexjVf8yAwQgYDVR0jBDswOYAU8onFqrecR/J81ZFigonexjVf8yChFqQUMBIx -EDAOBgNVBAMTB2VsYXN0aXiCCQDBfBklbZ8gejAMBgNVHRMEBTADAQH/MA0GCSqG -SIb3DQEBBQUAA4IBAQCYalhVZpN/F/Cux/KRBuOyyVxD+tOM7PDlXuuGMcxZ8PTH -sYK3MLBUvGnn90R6YIF+pmZC40hkau12xGRnlyNLa0EpnAd77SGlaB/y9Ix6RCDd -PRvdEZodknXzS5sDw+A9pA0JtZANrAXHrELPXjfp5vdf4EUH/o7TTh3XzTEIokwp -VY6557E17BYsTHHebWPSiDzCeS9y6PtdiZczuHrd7+K+vWgVcgmQ0fdudWwcMOEC -8s6O8uQGrc1v9nSyT93C9MPCWnuZ2McFX4JPSwaqAaKCTcnc8GAcqk4O5ruQ/8u/ -xSNQsoYpFi2BawOdPDqyMKn4khkREWTq0+T+7Kq2 +MIIDCDCCAfCgAwIBAgIJANZVoY3O+DQaMA0GCSqGSIb3DQEBBQUAMAwxCjAIBgNV +BAMUASowHhcNMTUxMDEzMjEyNzEwWhcNNDMwMjI3MjEyNzEwWjAMMQowCAYDVQQD +FAEqMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvtF4l3oqDRL/4m7C +kCnzE6colB1Ii7KHoRuFyyL7PrZiyrKelRVDr6yDB0lIJevOxuuSJlA+BNccyI0h +08/c3SRDkKb83MwQnABpDPS4/EhLGOJdTKutSo0FzCrn+uT470EYfCFvLLKMSnIO +ECf5st3EN+VJoSu80B9sZ4TEfdO4Gedy0vlL3iNGGDn1TqconTDjB5HKHteEjZ1Z +XzqBJUXITjzfD1VpYbSsj/wcFvurmaOMliqvsl1uFN7wXPjd1L8fAqcsAU5yBwLJ +88NFqJrlgqTXnuHeMCqhiVwOOFUeBbvEk/Faw3P3BKgppl7P01WXzUky0CVyegG7 +qagK7QIDAQABo20wazAdBgNVHQ4EFgQUtsodBU4f6bCvbrYc+ix21auh7mowPAYD +VR0jBDUwM4AUtsodBU4f6bCvbrYc+ix21auh7mqhEKQOMAwxCjAIBgNVBAMUASqC +CQDWVaGNzvg0GjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAOPEH1 +Otzm6Eu8FNQoppXKBuVW0kqRi6/CM7JxJ0f21YajEu1+vb0BdlNAoCpmcmxCY9Hf +cbmzeKyu/6wIXOOdqmTu/CGvEThtLNmrgjkj9sTe4i0C0H5fkOlkD6aSCHSVUwCv +9nOmPMsu9snEhU+UMXIDqFJzCpN3TSXu/J+V4xV5TYGj0SfbIZXLsw4QcB+iwind +oC1OorwxPsXVYnlMQeZAi7qaScOlq/82A3erXLKW7dRHIyXbgScs4VZ6kjg+YTH2 +YZW7y3xgUowj7xeWaoH9YciDfqV2SbxK4RoP2NeesuW0On0YebVQ5Z3qLeYb5fkV +CiA5NpyBDPdElzWW -----END CERTIFICATE----- diff --git a/Testing/Dashboard/elxLogstash.key b/Testing/Dashboard/elxLogstash.key index 9537cddd201e50e6d661444da8e85c5294b617c3..cebc457b0cc2589ab6d8ef08bd1980f88948a173 100644 --- a/Testing/Dashboard/elxLogstash.key +++ b/Testing/Dashboard/elxLogstash.key @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- diff --git a/Testing/GoogleTest b/Testing/GoogleTest deleted file mode 160000 index 7c508e6611f14cbc0da048c0e726870b93b1cc00..0000000000000000000000000000000000000000 --- a/Testing/GoogleTest +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7c508e6611f14cbc0da048c0e726870b93b1cc00 diff --git a/Testing/Unit/CMakeLists.txt b/Testing/Unit/CMakeLists.txt index 1ed2189daf32f2fab2f429e3bdb080dd276c3e77..06f783c2367e33d4d65317703aa29297a624bbe4 100644 --- a/Testing/Unit/CMakeLists.txt +++ b/Testing/Unit/CMakeLists.txt @@ -5,9 +5,8 @@ set( ElastixUnitTestFilenames elxExampleUnitTest.cxx - elxBluePrintTest.cxx - itkRegistration.cxx -) + elxBlueprintTest.cxx +) # --------------------------------------------------------------------- # Set data directories @@ -45,11 +44,9 @@ list( APPEND TEST_LIBRARIES foreach( ElastixUnitTestFilename ${ElastixUnitTestFilenames} ) # Build tests executables string( REPLACE ".cxx" "" ElastixUnitTest ${ElastixUnitTestFilename} ) - add_executable( "${ElastixUnitTest}" ${ElastixUnitTestFilename} ) + add_executable( ${ElastixUnitTest} ${ElastixUnitTestFilename} ) target_link_libraries( "${ElastixUnitTest}" ${ELASTIX_LIBRARIES} ${ITK_LIBRARIES} ${TEST_LIBRARIES} ) - ExternalData_Add_Test( ElastixData - NAME ${ElastixUnitTest} - COMMAND ${ElastixUnitTest} "--gtest_output=xml:${CMAKE_BINARY_DIR}/Testing/Unit/${ElastixUnitTest}.xml" - ) + # Add GoogleTest to CTest + GTEST_ADD_TESTS( ${ElastixUnitTest} "--gtest_output=xml:${CMAKE_BINARY_DIR}/Testing/Unit/${ElastixUnitTest}.xml" ${ElastixUnitTestFilename} ) endforeach() diff --git a/Testing/Unit/elxBluePrintTest.cxx b/Testing/Unit/elxBluePrintTest.cxx index 8aa289fc4201a92af8d6c185905855bd58c5ab4e..15ffde06c38d85233944c28cf7bb837597e2f651 100644 --- a/Testing/Unit/elxBluePrintTest.cxx +++ b/Testing/Unit/elxBluePrintTest.cxx @@ -1,27 +1,174 @@ #include "elxBlueprint.h" -#include "elxComponentDescriptor.h" + #include "gtest/gtest.h" namespace elx { -TEST( Blueprint, Instantiation ) +class BlueprintTest : public ::testing::Test { +public: + + typedef Blueprint::Pointer BlueprintPointerType; + typedef Blueprint::ComponentIndexType ComponentIndexType; + typedef Blueprint::ParameterMapType ParameterMapType; + typedef Blueprint::ParameterValueType ParameterValueType; + + virtual void SetUp() { + parameterMap["ComponentName"] = ParameterValueType(1, "TestName"); + } + + ParameterMapType parameterMap; +}; + +TEST_F( BlueprintTest, AddComponent ) +{ + BlueprintPointerType blueprint; + EXPECT_NO_THROW( blueprint = Blueprint::New() ); + + ComponentIndexType index0; + EXPECT_NO_THROW( index0 = blueprint->AddComponent() ); + + ComponentIndexType index1; + EXPECT_NO_THROW( index1 = blueprint->AddComponent( parameterMap ) ); +} + +TEST_F( BlueprintTest, GetComponent ) +{ + BlueprintPointerType blueprint = Blueprint::New(); + ComponentIndexType index = blueprint->AddComponent( parameterMap ); + + ParameterMapType parameterMapTest; + EXPECT_NO_THROW( parameterMapTest = blueprint->GetComponent( index ) ); + EXPECT_EQ( parameterMap["ComponentName"], parameterMapTest["ComponentName"] ); +} + +TEST_F( BlueprintTest, SetComponent ) +{ + BlueprintPointerType blueprint = Blueprint::New(); + ComponentIndexType index = blueprint->AddComponent( parameterMap ); + + ParameterMapType parameterMapTest; + EXPECT_NO_THROW( blueprint->SetComponent( index, parameterMap ) ); + EXPECT_NO_THROW( parameterMapTest = blueprint->GetComponent( index ) ); + EXPECT_EQ( parameterMap["ComponentName"], parameterMapTest["ComponentName"] ); +} + +// TODO: The final line segfaults because GetComponent does not check that the index actually +// actually exist. How can we do that? See also explanation in elxBlueprint.h +// TEST_F( BlueprintTest, DeleteComponent ) +// { +// BlueprintPointerType blueprint = Blueprint::New(); +// ComponentIndexType index = blueprint->AddComponent( parameterMap ); +// +// ParameterMapType parameterMapTest; +// EXPECT_NO_THROW( parameterMapTest = blueprint->GetComponent( index ) ); +// EXPECT_EQ( parameterMap["ComponentName"], parameterMapTest["ComponentName"] ); +// +// EXPECT_NO_THROW( blueprint->DeleteComponent( index ) ); +// EXPECT_ANY_THROW( parameterMapTest = blueprint->GetComponent( index ) ); +// } + +TEST_F( BlueprintTest, AddConnection ) +{ + BlueprintPointerType blueprint = Blueprint::New(); + + ComponentIndexType index0 = blueprint->AddComponent(); + ComponentIndexType index1 = blueprint->AddComponent(); + ComponentIndexType index2 = blueprint->AddComponent(); + + // Connection should not exist + EXPECT_FALSE( blueprint->ConnectionExists( index0, index1 ) ); + + // Connection should be added + EXPECT_TRUE( blueprint->AddConnection( index0, index1 ) ); + + // Connection should exist + EXPECT_TRUE( blueprint->ConnectionExists( index0, index1 ) ); + + // Another connection between same components should not be added + // (user should use SetComponent() instead) + EXPECT_FALSE( blueprint->AddConnection( index0, index1 ) ); + + // Connection should be empty + ParameterMapType parameterMapTest0; + EXPECT_NO_THROW( parameterMapTest0 = blueprint->GetConnection( index0, index1 ) ); + EXPECT_EQ( 0u, parameterMapTest0.size() ); + + // Connection with properties should be added. Testing if properties was + // properly set requires a call to GetConnection() which is the responsibility + // of the next test. + ParameterMapType parameterMapTest1; + EXPECT_TRUE( blueprint->AddConnection( index1, index2, parameterMap ) ); + + // It is not be possible to add connection between components that do not exist + // because you do not have necessary indexes +} + +TEST_F( BlueprintTest, GetConnection ) +{ + BlueprintPointerType blueprint = Blueprint::New(); + + ComponentIndexType index0 = blueprint->AddComponent(); + ComponentIndexType index1 = blueprint->AddComponent(); + + ParameterMapType parameterMapTest0; + EXPECT_TRUE( blueprint->AddConnection( index0, index1, parameterMap ) ); + EXPECT_NO_THROW( parameterMapTest0 = blueprint->GetConnection( index0, index1 ) ); + EXPECT_EQ( parameterMap["ComponentName"], parameterMapTest0["ComponentName"] ); +} + +TEST_F( BlueprintTest, SetConnection ) +{ + BlueprintPointerType blueprint = Blueprint::New(); + + ComponentIndexType index0 = blueprint->AddComponent(); + ComponentIndexType index1 = blueprint->AddComponent(); + blueprint->AddConnection( index0, index1, parameterMap ); + + ParameterMapType parameterMapTest0; + parameterMapTest0 = blueprint->GetConnection( index0, index1 ); + EXPECT_EQ( parameterMap["ComponentName"], parameterMapTest0["ComponentName"] ); + + ParameterMapType parameterMapTest1; + parameterMapTest1["ComponentName"] = ParameterValueType(1, "OtherName"); + EXPECT_TRUE( blueprint->SetConnection( index0, index1, parameterMapTest1 ) ); + + ParameterMapType parameterMapTest2; + EXPECT_NO_THROW( parameterMapTest2 = blueprint->GetConnection( index0, index1 ) ); + EXPECT_EQ( parameterMapTest1["ComponentName"], parameterMapTest2["ComponentName"] ); +} + +TEST_F( BlueprintTest, DeleteConnection ) { - typedef Blueprint< ComponentDescriptor > BlueprintType; - BlueprintType::Pointer blueprint; - EXPECT_NO_THROW( blueprint = BlueprintType::New() ); + BlueprintPointerType blueprint = Blueprint::New(); - typedef BlueprintType::ComponentDescriptorType ComponentDescriptorType; - ComponentDescriptorType::Pointer componentDescriptor; - EXPECT_NO_THROW( componentDescriptor = ComponentDescriptorType::New() ); + ComponentIndexType index0 = blueprint->AddComponent(); + ComponentIndexType index1 = blueprint->AddComponent(); + blueprint->AddConnection( index0, index1 ); + + // Connection should exist + EXPECT_TRUE( blueprint->ConnectionExists( index0, index1 ) ); + + // Connection be deleted + EXPECT_TRUE( blueprint->DeleteConnection( index0, index1 ) ); + + // Connection should not exist + EXPECT_FALSE( blueprint->ConnectionExists( index0, index1 ) ); +} + +TEST_F( BlueprintTest, WriteBlueprint ) +{ + BlueprintPointerType blueprint = Blueprint::New(); - typedef ComponentDescriptorType::ComponentNameType ComponentNameType; - ComponentNameType componentName; - EXPECT_NO_THROW( componentName = ComponentNameType("Metric") ); - EXPECT_NO_THROW( componentDescriptor->SetComponentName( componentName ) ); + ComponentIndexType index0 = blueprint->AddComponent(); + ComponentIndexType index1 = blueprint->AddComponent(); + ComponentIndexType index2 = blueprint->AddComponent(); + ComponentIndexType index3 = blueprint->AddComponent(); - EXPECT_NO_THROW( blueprint->TestFunction() ); + blueprint->AddConnection( index0, index1 ); + blueprint->AddConnection( index0, index2 ); + blueprint->AddConnection( index2, index3 ); - ASSERT_TRUE( true ); + EXPECT_NO_THROW( blueprint->WriteBlueprint( "blueprint.dot" ) ); } } // namespace elx diff --git a/Testing/Unit/itkRegistration.cxx b/Testing/Unit/itkRegistration.cxx deleted file mode 100644 index 3988f3089daaff475b4d1a4b359286d75eb6995d..0000000000000000000000000000000000000000 --- a/Testing/Unit/itkRegistration.cxx +++ /dev/null @@ -1,86 +0,0 @@ -#include "itkImage.h" -#include "itkImageFileReader.h" -#include "elxDataManager.h" -#include "gtest/gtest.h" - -#include "itkImageRegistrationMethod.h" -#include "itkTranslationTransform.h" -#include "itkMeanSquaresImageToImageMetric.h" -#include "itkLinearInterpolateImageFunction.h" -#include "itkRegularStepGradientDescentOptimizer.h" -#include "itkImage.h" -#include "itkImageFileReader.h" -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" - -class itkRegistration : public ::testing::Test { -public: - virtual void SetUp() - { - // TODO: Loading images here result in segfault - } - - typedef itk::Image< unsigned short, 2 > ImageType; - - typedef itk::ImageFileReader< ImageType > FixedImageReaderType; - typedef itk::ImageFileReader< ImageType > MovingImageReaderType; - - FixedImageReaderType::Pointer fixedImageReader; - MovingImageReaderType::Pointer movingImageReader; - -}; - -TEST_F( itkRegistration, ImageRegistration3 ) -{ - - typedef itk::TranslationTransform< double, ImageType::ImageDimension > TransformType; - typedef itk::RegularStepGradientDescentOptimizer OptimizerType; - typedef itk::LinearInterpolateImageFunction< ImageType, double > InterpolatorType; - typedef itk::ImageRegistrationMethod< ImageType, ImageType > RegistrationType; - - - typedef itk::MeanSquaresImageToImageMetric< ImageType, ImageType > MetricType; - - TransformType::Pointer transform = TransformType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - - MetricType::Pointer metric = MetricType::New(); - registration->SetMetric( metric ); - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetInterpolator( interpolator ); - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - DataManager::Pointer dataManager = DataManager::New(); - - fixedImageReader->SetFileName( dataManager->GetInputFullPath( "BrainProtonDensitySlice.png" ) ); - movingImageReader->SetFileName( dataManager->GetInputFullPath( "BrainProtonDensitySliceR10X13Y17.png" ) ); - - registration->SetFixedImage( fixedImageReader->GetOutput() ); - registration->SetMovingImage( movingImageReader->GetOutput() ); - - fixedImageReader->Update(); // This is needed to make the BufferedRegion valid. - registration->SetFixedImageRegion( fixedImageReader->GetOutput()->GetBufferedRegion() ); - - typedef RegistrationType::ParametersType ParametersType; - ParametersType initialParameters( transform->GetNumberOfParameters() ); - - initialParameters[0] = 0.0; // Initial offset in mm along X - initialParameters[1] = 0.0; // Initial offset in mm along Y - - registration->SetInitialTransformParameters( initialParameters ); - - optimizer->SetMaximumStepLength( 4.00 ); - optimizer->SetMinimumStepLength( 0.01 ); - optimizer->SetNumberOfIterations( 200 ); - - optimizer->MaximizeOff(); - - EXPECT_NO_THROW( registration->Update() ); - RecordProperty( "MetricValue", optimizer->GetValue() ); -} -