Commit 94e32345 authored by Kasper Marstal's avatar Kasper Marstal
Browse files

WIP: Blueprint Tests

parent 3c7b9261
......@@ -31,19 +31,27 @@ Blueprint
::~Blueprint( void ) = default;
bool
Blueprint
::SetComponent( ComponentNameType name, ParameterMapType parameterMap )
{
return this->m_Pimple->SetComponent( name, parameterMap );
}
Blueprint::ParameterMapType
Blueprint
::GetComponent( ComponentNameType name ) const
::GetComponent( ComponentNameType componentName ) const
{
return this->m_Pimple->GetComponent( name );
return this->m_Pimple->GetComponent( componentName );
}
bool
Blueprint
::SetComponent( ComponentNameType name, ParameterMapType parameterMap )
::DeleteComponent( ComponentNameType componentName )
{
return this->m_Pimple->SetComponent( name, parameterMap );
return this->m_Pimple->DeleteComponent( componentName );
}
......@@ -54,19 +62,19 @@ Blueprint::GetComponentNames( void ) const
}
Blueprint::ParameterMapType
bool
Blueprint
::GetConnection( ComponentNameType upstream, ComponentNameType downstream ) const
::SetConnection( ComponentNameType upstream, ComponentNameType downstream, ParameterMapType parameterMap )
{
return this->m_Pimple->GetConnection( upstream, downstream );
return this->m_Pimple->SetConnection( upstream, downstream, parameterMap );
}
bool
Blueprint::ParameterMapType
Blueprint
::SetConnection( ComponentNameType upstream, ComponentNameType downstream, ParameterMapType parameterMap )
::GetConnection( ComponentNameType upstream, ComponentNameType downstream ) const
{
return this->m_Pimple->SetConnection( upstream, downstream, parameterMap );
return this->m_Pimple->GetConnection( upstream, downstream );
}
......
......@@ -17,15 +17,16 @@
*
*=========================================================================*/
#include "selxBlueprint.h"
#include "selxBlueprintImpl.h"
#include <stdexcept>
namespace selx
{
bool
BlueprintImpl
Blueprint::BlueprintImpl
::SetComponent( ComponentNameType name, ParameterMapType parameterMap )
{
if( this->ComponentExists( name ) )
......@@ -41,7 +42,7 @@ BlueprintImpl
Blueprint::ParameterMapType
BlueprintImpl
Blueprint::BlueprintImpl
::GetComponent( ComponentNameType name ) const
{
if( !this->ComponentExists( name ) )
......@@ -56,21 +57,21 @@ BlueprintImpl
bool
BlueprintImpl
Blueprint::BlueprintImpl
::DeleteComponent( ComponentNameType name )
{
if( !this->ComponentExists( name ) )
{
clear_vertex( name, this->m_Graph );
remove_vertex( name, this->m_Graph );
this->m_Graph.remove_vertex( name );
return true;
}
return false;
}
BlueprintImpl::ComponentNamesType
BlueprintImpl::GetComponentNames( void ) const
Blueprint::ComponentNamesType
Blueprint::BlueprintImpl
::GetComponentNames( void ) const
{
ComponentNamesType container;
for( auto it = boost::vertices( this->m_Graph.graph() ).first; it != boost::vertices( this->m_Graph.graph() ).second; ++it )
......@@ -82,10 +83,10 @@ BlueprintImpl::GetComponentNames( void ) const
bool
BlueprintImpl
Blueprint::BlueprintImpl
::SetConnection( ComponentNameType upstream, ComponentNameType downstream, ParameterMapType parameterMap )
{
if( !this->ComponentExists( upstream ) || !this->ComponentExists( downstream )
if( !this->ComponentExists( upstream ) || !this->ComponentExists( downstream ) )
{
return false;
}
......@@ -104,7 +105,7 @@ BlueprintImpl
Blueprint::ParameterMapType
BlueprintImpl
Blueprint::BlueprintImpl
::GetConnection( ComponentNameType upstream, ComponentNameType downstream ) const
{
return this->m_Graph[ this->GetConnectionIndex( upstream, downstream ) ].parameterMap;
......@@ -112,8 +113,8 @@ BlueprintImpl
bool
BlueprintImpl
::DeleteConnection( ComponentNameType upstream, ComponentNameType downstream )
Blueprint::BlueprintImpl
::DeleteConnection( Blueprint::ComponentNameType upstream, Blueprint::ComponentNameType downstream )
{
if( this->ConnectionExists( upstream, downstream ) )
{
......@@ -125,7 +126,7 @@ BlueprintImpl
bool
BlueprintImpl
Blueprint::BlueprintImpl
::ComponentExists( ComponentNameType componentName ) const
{
const GraphType::vertex_descriptor descriptor = this->m_Graph.vertex( componentName );
......@@ -134,7 +135,7 @@ BlueprintImpl
bool
BlueprintImpl
Blueprint::BlueprintImpl
::ConnectionExists( ComponentNameType upstream, ComponentNameType downstream ) const
{
if( !this->ComponentExists( upstream ) )
......@@ -150,46 +151,46 @@ BlueprintImpl
}
BlueprintImpl::ComponentNamesType
BlueprintImpl
::GetOutputNames( const ComponentNameType name ) const
Blueprint::ComponentNamesType
Blueprint::BlueprintImpl
::GetInputNames( const ComponentNameType name ) const
{
ComponentNamesType container;
OutputIteratorPairType outputIteratorPair = boost::out_edges( this->m_Graph.vertex( name ), this->m_Graph );
for( auto it = outputIteratorPair.first; it != outputIteratorPair.second; ++it )
ComponentNamesType container;
//auto vertex = this->m_Graph.vertex(name);
//boost::in_edges(vertex, this->m_Graph);
InputIteratorPairType inputIteratorPair = boost::in_edges( this->m_Graph.vertex( name ), this->m_Graph );
for( auto it = inputIteratorPair.first; it != inputIteratorPair.second; ++it )
{
container.push_back( this->m_Graph.graph()[ it->m_target ].name );
container.push_back( this->m_Graph.graph()[ it->m_source ].name );
}
return container;
}
BlueprintImpl::ComponentNamesType
BlueprintImpl
::GetInputNames( const ComponentNameType name ) const
Blueprint::ComponentNamesType
Blueprint::BlueprintImpl
::GetOutputNames( const ComponentNameType name ) const
{
ComponentNamesType container;
//auto vertex = this->m_Graph.vertex(name);
//boost::in_edges(vertex, this->m_Graph);
InputIteratorPairType inputIteratorPair = boost::in_edges( this->m_Graph.vertex( name ), this->m_Graph );
for( auto it = inputIteratorPair.first; it != inputIteratorPair.second; ++it )
ComponentNamesType container;
OutputIteratorPairType outputIteratorPair = boost::out_edges( this->m_Graph.vertex( name ), this->m_Graph );
for( auto it = outputIteratorPair.first; it != outputIteratorPair.second; ++it )
{
container.push_back( this->m_Graph.graph()[ it->m_source ].name );
container.push_back( this->m_Graph.graph()[ it->m_target ].name );
}
return container;
}
BlueprintImpl::ConnectionIndexType
BlueprintImpl
Blueprint::BlueprintImpl::ConnectionIndexType
Blueprint::BlueprintImpl
::GetConnectionIndex( ComponentNameType upstream, ComponentNameType downstream ) const
{
// 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 );
throw std::runtime_error( "Blueprint does not contain connection from component " + upstream + " to " + downstream );
}
return boost::edge_by_label( upstream, downstream, this->m_Graph ).first;
......@@ -197,7 +198,7 @@ BlueprintImpl
void
BlueprintImpl
Blueprint::BlueprintImpl
::Write( const std::string filename )
{
std::ofstream dotfile( filename.c_str() );
......
......@@ -27,178 +27,111 @@ class BlueprintTest : public ::testing::Test
{
public:
typedef Blueprint::Pointer BlueprintPointerType;
typedef Blueprint::ParameterMapType ParameterMapType;
typedef Blueprint::ParameterValueType ParameterValueType;
virtual void SetUp()
{
parameterMap[ "NameOfClass" ] = ParameterValueType( 1, "TestClassName" );
anotherParameterMap["NameOfClass"] = ParameterValueType( 1, "AnotherTestClassName" );
}
ParameterMapType parameterMap;
ParameterMapType anotherParameterMap;
};
TEST_F( BlueprintTest, AddComponent )
TEST_F( BlueprintTest, SetGetDeleteComponent )
{
BlueprintPointerType blueprint;
EXPECT_NO_THROW( blueprint = Blueprint::New() );
std::unique_ptr< Blueprint > blueprint;
EXPECT_NO_THROW( blueprint = std::unique_ptr< Blueprint >( new Blueprint() ) );
bool success0;
EXPECT_NO_THROW( success0 = blueprint->AddComponent( "MyComponentName" ) );
EXPECT_NO_THROW( success0 = blueprint->SetComponent( "MyComponentName", parameterMap ) );
EXPECT_TRUE( success0 );
bool success1;
EXPECT_NO_THROW( success1 = blueprint->AddComponent( "MyComponentName", parameterMap ) );
}
TEST_F( BlueprintTest, GetComponent )
{
BlueprintPointerType blueprint = Blueprint::New();
blueprint->AddComponent( "MyComponentName", parameterMap );
ParameterMapType parameterMapTest;
EXPECT_NO_THROW( parameterMapTest = blueprint->GetComponent( "MyComponentName" ) );
EXPECT_EQ( parameterMap[ "NameOfClass" ], parameterMapTest[ "NameOfClass" ] );
}
TEST_F( BlueprintTest, SetComponent )
{
BlueprintPointerType blueprint = Blueprint::New();
blueprint->AddComponent( "MyComponentName", parameterMap );
ParameterMapType parameterMapTest;
EXPECT_NO_THROW( blueprint->SetComponent( "MyComponentName", parameterMap ) );
EXPECT_NO_THROW( parameterMapTest = blueprint->GetComponent( "MyComponentName" ) );
EXPECT_EQ( parameterMap[ "NameOfClass" ], parameterMapTest[ "NameOfClass" ] );
EXPECT_NO_THROW( success1 = blueprint->SetComponent( "MyComponentName", anotherParameterMap ) );
EXPECT_TRUE( success1 );
EXPECT_EQ( anotherParameterMap, blueprint->GetComponent( "MyComponentName" ) );
}
// TODO: The final line segfaults because GetComponent does not check that the index actually
// actually exist. See explanation in selxBlueprint.h
// TEST_F( BlueprintTest, DeleteComponent )
// {
// BlueprintPointerType blueprint = Blueprint::New();
// blueprint->AddComponent( parameterMap );
//
// ParameterMapType parameterMapTest;
// EXPECT_NO_THROW( parameterMapTest = blueprint->GetComponent( index ) );
// EXPECT_EQ( parameterMap["NameOfClass"], parameterMapTest["NameOfClass"] );
//
// EXPECT_NO_THROW( blueprint->DeleteComponent( index ) );
// EXPECT_ANY_THROW( parameterMapTest = blueprint->GetComponent( index ) );
// }
TEST_F( BlueprintTest, AddConnection )
TEST_F( BlueprintTest, SetGetDeleteConnection )
{
BlueprintPointerType blueprint = Blueprint::New();
std::unique_ptr< Blueprint > blueprint;
EXPECT_NO_THROW( blueprint = std::unique_ptr< Blueprint >( new Blueprint() ) );
blueprint->AddComponent( "Component0" );
blueprint->AddComponent( "Component1" );
blueprint->AddComponent( "Component2" );
blueprint->SetComponent( "Component0", parameterMap );
blueprint->SetComponent( "Component1", parameterMap );
blueprint->SetComponent( "Component2", parameterMap );
// Connection should not exist
EXPECT_FALSE( blueprint->ConnectionExists( "Component0", "Component1" ) );
// Connection should be added
EXPECT_TRUE( blueprint->AddConnection( "Component0", "Component1" ) );
// Connection should exist
EXPECT_TRUE( blueprint->ConnectionExists( "Component0", "Component1" ) );
// Another connection between same components should not be added
// (user should use SetComponent() instead)
EXPECT_FALSE( blueprint->AddConnection( "Component0", "Component1" ) );
bool connectionExists;
EXPECT_NO_THROW( connectionExists = blueprint->ConnectionExists( "Component0", "Component1" ) );
EXPECT_FALSE( connectionExists );
// Connection should be set
bool connectionSet;
EXPECT_NO_THROW( connectionSet = blueprint->SetConnection( "Component0", "Component1", parameterMap ) );
EXPECT_TRUE( connectionSet );
// Connection should now exist
bool connectionNowExists;
EXPECT_NO_THROW( connectionNowExists = blueprint->ConnectionExists( "Component0", "Component1" ) );
EXPECT_TRUE( connectionNowExists );
// Connection should have parameter map
ParameterMapType parameterMap0;
EXPECT_NO_THROW( parameterMap0 = blueprint->GetConnection( "Component0", "Component1") );
EXPECT_EQ( parameterMap["NameOfClass"], parameterMap0["NameOfClass"] );
// Another parameter map should transparently added
bool anotherParameterMapSet;
EXPECT_NO_THROW( anotherParameterMapSet = blueprint->SetConnection( "Component0", "Component1", anotherParameterMap ) );
EXPECT_TRUE( anotherParameterMapSet );
EXPECT_EQ( anotherParameterMap, blueprint->GetConnection( "Component0", "Component1" ) );
// Connection should be deleted
bool connectionDeleted;
EXPECT_NO_THROW( connectionDeleted = blueprint->DeleteConnection( "Component0", "Component1" ) );
EXPECT_TRUE( connectionDeleted );
// Connection should be empty
ParameterMapType parameterMapTest0;
EXPECT_NO_THROW( parameterMapTest0 = blueprint->GetConnection( "Component0", "Component1" ) );
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( "Component1", "Component2", parameterMap ) );
}
TEST_F( BlueprintTest, GetConnection )
{
BlueprintPointerType blueprint = Blueprint::New();
blueprint->AddComponent( "Component0" );
blueprint->AddComponent( "Component1" );
ParameterMapType parameterMapTest0;
EXPECT_TRUE( blueprint->AddConnection( "Component0", "Component1", parameterMap ) );
EXPECT_NO_THROW( parameterMapTest0 = blueprint->GetConnection( "Component0", "Component1" ) );
EXPECT_EQ( parameterMap[ "NameOfClass" ], parameterMapTest0[ "NameOfClass" ] );
}
TEST_F( BlueprintTest, SetConnection )
{
BlueprintPointerType blueprint = Blueprint::New();
blueprint->AddComponent( "Component0" );
blueprint->AddComponent( "Component1" );
blueprint->AddConnection( "Component0", "Component1", parameterMap );
ParameterMapType parameterMapTest0;
parameterMapTest0 = blueprint->GetConnection( "Component0", "Component1" );
EXPECT_EQ( parameterMap[ "NameOfClass" ], parameterMapTest0[ "NameOfClass" ] );
ParameterMapType parameterMapTest1;
parameterMapTest1[ "NameOfClass" ] = ParameterValueType( 1, "OtherName" );
EXPECT_TRUE( blueprint->SetConnection( "Component0", "Component1", parameterMapTest1 ) );
ParameterMapType parameterMapTest2;
EXPECT_NO_THROW( parameterMapTest2 = blueprint->GetConnection( "Component0", "Component1" ) );
EXPECT_EQ( parameterMapTest1[ "NameOfClass" ], parameterMapTest2[ "NameOfClass" ] );
}
TEST_F( BlueprintTest, DeleteConnection )
{
BlueprintPointerType blueprint = Blueprint::New();
blueprint->AddComponent( "Component0" );
blueprint->AddComponent( "Component1" );
blueprint->AddConnection( "Component0", "Component1" );
// Connection should not exist
EXPECT_FALSE( blueprint->ConnectionExists( "Component0", "Component1" ) );
// Connection should exist
EXPECT_TRUE( blueprint->ConnectionExists( "Component0", "Component1" ) );
EXPECT_THROW( blueprint->GetConnection( "Component0", "Component1" ), std::runtime_error );
// Connection be deleted
EXPECT_TRUE( blueprint->DeleteConnection( "Component0", "Component1" ) );
// Connection should not exist
EXPECT_FALSE( blueprint->ConnectionExists( "Component0", "Component1" ) );
}
TEST_F( BlueprintTest, WriteBlueprint )
{
BlueprintPointerType blueprint = Blueprint::New();
std::unique_ptr< Blueprint > blueprint;
EXPECT_NO_THROW( blueprint = std::unique_ptr< Blueprint >( new Blueprint() ) );
// create some made up configuration to show graphviz output
ParameterMapType component0Parameters;
component0Parameters[ "NameOfClass" ] = { "MyMetric" };
component0Parameters[ "Dimensionality" ] = { "3" };
component0Parameters[ "Kernel" ] = { "5", "5", "5" };
blueprint->AddComponent( "Metric", component0Parameters );
blueprint->SetComponent( "Metric", component0Parameters );
ParameterMapType component1Parameters;
component1Parameters[ "NameOfClass" ] = { "MyFiniteDifferenceCalculator" };
component1Parameters[ "Delta" ] = { "0.01" };
blueprint->AddComponent( "MetricGradient", component1Parameters );
blueprint->SetComponent( "MetricGradient", component1Parameters );
ParameterMapType component2Parameters;
component2Parameters[ "NameOfClass" ] = { "MyOptimizer" };
blueprint->AddComponent( "Optimizer", component2Parameters );
blueprint->SetComponent( "Optimizer", component2Parameters );
ParameterMapType component3Parameters;
component3Parameters[ "NameOfClass" ] = { "MyTransform" };
blueprint->AddComponent( "Transform", component3Parameters );
blueprint->SetComponent( "Transform", component3Parameters );
blueprint->AddConnection( "Metric", "MetricGradient" );
blueprint->AddConnection( "MetricGradient", "Optimizer" );
blueprint->SetConnection( "Metric", "MetricGradient", parameterMap );
blueprint->SetConnection( "MetricGradient", "Optimizer", parameterMap );
ParameterMapType connection0Parameters;
// Example use case: The connection between the metric and optimizer should
......@@ -208,11 +141,11 @@ TEST_F( BlueprintTest, WriteBlueprint )
// which "MetricDerivative" to connect to the optimizer.
connection0Parameters[ "NameOfInterface" ] = { "MetricValue" };
blueprint->AddConnection( "Metric", "Optimizer", connection0Parameters );
blueprint->SetConnection( "Metric", "Optimizer", connection0Parameters );
blueprint->AddConnection( "MetricGradient", "Optimizer" );
blueprint->AddConnection( "Optimizer", "Transform" );
blueprint->AddConnection( "Transform", "Metric" );
blueprint->SetConnection( "MetricGradient", "Optimizer", parameterMap );
blueprint->SetConnection( "Optimizer", "Transform", parameterMap );
blueprint->SetConnection( "Transform", "Metric", parameterMap );
EXPECT_NO_THROW( blueprint->WriteBlueprint( "blueprint.dot" ) );
EXPECT_NO_THROW( blueprint->Write( "blueprint.dot" ) );
}
......@@ -43,7 +43,7 @@ TEST_F( ConfigurationReaderTest, ReadXML )
ConfigurationReader::BlueprintPointerType blueprint;
EXPECT_NO_THROW( blueprint = ConfigurationReader::FromXML( this->dataManager->GetConfigurationFile( "itkv4_SVF_ANTsCC.xml" ) ) );
blueprint->WriteBlueprint( this->dataManager->GetOutputFile( "configurationReaderTest_itkv4_SVF_ANTsCC.xml.dot" ) );
blueprint->Write( this->dataManager->GetOutputFile( "configurationReaderTest_itkv4_SVF_ANTsCC.xml.dot" ) );
}
TEST_F( ConfigurationReaderTest, ReadJson )
......@@ -51,5 +51,5 @@ TEST_F( ConfigurationReaderTest, ReadJson )
ConfigurationReader::BlueprintPointerType blueprint;
EXPECT_NO_THROW( blueprint = ConfigurationReader::FromJson( this->dataManager->GetConfigurationFile( "itkv4_SVF_ANTsCC.json" ) ) );
blueprint->WriteBlueprint( this->dataManager->GetOutputFile( "configurationReaderTest_itkv4_SVF_ANTsCC.json.dot" ) );
blueprint->Write( this->dataManager->GetOutputFile( "configurationReaderTest_itkv4_SVF_ANTsCC.json.dot" ) );
}
......@@ -25,6 +25,7 @@
#include "selxOverlord.h"
#include "selxAnyFileReader.h"
#include "selxAnyFileWriter.h"
#include "itkAutoPointerDataObjectDecorator.h"
/**
* \class SuperElastixFilter
......@@ -56,6 +57,8 @@ public:
typedef AnyFileReader AnyFileReaderType;
typedef AnyFileWriter AnyFileWriterType;
typedef typename itk::AutoPointerDataObjectDecorator< Blueprint > BlueprintType;
//TODO make const correct
//itkSetConstObjectMacro(Blueprint,Blueprint)
itkSetObjectMacro( Blueprint, Blueprint );
......@@ -87,8 +90,7 @@ protected:
private:
//TODO make const correct
//Blueprint::ConstPointer m_Blueprint;
Blueprint::Pointer m_Blueprint;
BlueprintType::Pointer m_Blueprint;
std::unique_ptr< Overlord > m_Overlord;
bool m_InputConnectionModified;
bool m_OutputConnectionModified;
......
......@@ -34,7 +34,7 @@ SuperElastixFilter< ComponentTypeList >
::SuperElastixFilter( void ) : m_InputConnectionModified( true ), m_OutputConnectionModified( true ), m_BlueprintConnectionModified( true ),
m_IsConnected( false )
{
this->m_Overlord = std::unique_ptr< Overlord >( new Overlord() );
this->m_Overlord = std::unique_ptr< Overlord >( new Overlord( this->m_Blueprint.Get() ) );
RegisterFactoriesByTypeList< ComponentTypeList >::Register();
......
......@@ -54,6 +54,8 @@ set( ${MODULE}_TESTS
# Module source files
set( ${MODULE}_SOURCE_FILES
${${MODULE}_SOURCE_DIR}/Blueprints/src/selxBlueprint.cxx
${${MODULE}_SOURCE_DIR}/Blueprints/src/selxBlueprintImpl.h
${${MODULE}_SOURCE_DIR}/Blueprints/src/selxBlueprintImpl.cxx
${${MODULE}_SOURCE_DIR}/ComponentInterface/src/selxComponentBase.cxx
${${MODULE}_SOURCE_DIR}/ComponentInterface/src/selxOverlord.cxx
${${MODULE}_SOURCE_DIR}/ComponentInterface/src/selxComponentSelector.cxx
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment