Commit b65eb44e authored by Floris Berendsen's avatar Floris Berendsen

Merge branch 'develop' into SELX-150-Blueprint-reader-cannot-handle-two-connections

parents 20076dbd 9bd78006
..\SuperElastix.exe --conf ..\Configuration\itkv4_SVF_MSD_missingController.json --graphout 2B_graph_itkv4_MSD_missingController.dot --in FixedImage=..\Data\coneA2d64.mhd MovingImage=..\Data\coneB2d64.mhd --out ResultImage=2B_image_itkv4_MSD_missingController.mhd ResultDisplacementField=2B_deformation_itkv4_MSD_missingController.mhd
CALL graphviz_to_png 2B_graph_itkv4_MSD.dot
\ No newline at end of file
......@@ -436,6 +436,24 @@ BlueprintImpl
return container;
}
BlueprintImpl::ComponentNamesType
BlueprintImpl
::GetUpdateOrder() const
{
ComponentNamesType container;
std::vector< ComponentIndexType > indexContainer;
boost::topological_sort(this->m_Graph, std::back_inserter(indexContainer));
for (std::vector< ComponentIndexType >::reverse_iterator ii = indexContainer.rbegin(); ii != indexContainer.rend(); ++ii)
{
container.push_back(boost::get(boost::vertex_all, this->m_Graph, *ii).name);
}
return container;
}
BlueprintImpl::ConnectionNamesType
BlueprintImpl
::GetConnectionNames(const ComponentNameType upstream, const ComponentNameType downstream) const
......
......@@ -25,6 +25,9 @@
#include "boost/graph/directed_graph.hpp"
#include "boost/graph/labeled_graph.hpp"
// for UpdateOrder
#include <boost/graph/topological_sort.hpp>
// for ComposeWith
#include "boost/graph/copy.hpp"
......@@ -139,6 +142,8 @@ public:
// Returns a vector of the connection names between upstream and downstream
ComponentNamesType GetConnectionNames(const ComponentNameType upstream, const ComponentNameType downstream) const;
ComponentNamesType GetUpdateOrder() const;
void Write( const std::string filename );
void MergeFromFile(const std::string & filename);
......
......@@ -41,6 +41,7 @@ const char * const CoordRepType = "CoordRepType";
const char * const SourceInterface = "SourceInterface"; // Special interface that connects to the outside of the SuperElastixFilter
const char * const SinkInterface = "SinkInterface"; // Special interface that connects to the outside of the SuperElastixFilter
const char * const RegistrationControllerStartInterface = "RegistrationControllerStartInterface"; //Special interface by which all algorithms are started
const char * const UpdateInterface = "UpdateInterface"; //Special interface by which any component can be executed in the correct pipeline order.
}
}
#endif //selxKeys_h
#=========================================================================
#
# Copyright Leiden University Medical Center, Erasmus University Medical
# Center and contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#=========================================================================
set( ${MODULE}_INCLUDE_DIRS
${${MODULE}_SOURCE_DIR}/include
)
# This module is header-only and does not contain any source files
set( ${MODULE}_SOURCE_FILES
)
# This module is header-only and does not export any libraries
set( ${MODULE}_LIBRARIES
)
set( ${MODULE}_TEST_SOURCE_FILES
)
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* Center and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#include "selxTypeList.h"
//Component group Controller
#include "selxRegistrationControllerComponent.h"
namespace selx
{
using ModuleControllerComponents = selx::TypeList<
RegistrationControllerComponent< >
>;
}
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* Center and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef selxRegistrationControllerComponent_h
#define selxRegistrationControllerComponent_h
#include "selxSuperElastixComponent.h"
//#include "selxInterfaces.h"
#include <string.h>
#include <set>
namespace selx
{
template< bool dummy = true >
class RegistrationControllerComponent :
public SuperElastixComponent<
Accepting< RunRegistrationInterface, ReconnectTransformInterface, AfterRegistrationInterface >,
Providing< RegistrationControllerStartInterface >
>
{
// RegistrationControllerComponent is a work-around for broken itk-pipelines.
// Both the elastix and itkv4 require to connect their transforms *after* execution of the registration.
// This controller explicitly performs these steps
// TODO: see if signals-and-slots paradigm is appropriate here.
public:
/** Standard ITK typedefs. */
typedef RegistrationControllerComponent Self;
typedef SuperElastixComponent<
Accepting< RunRegistrationInterface, ReconnectTransformInterface, AfterRegistrationInterface >,
Providing< RegistrationControllerStartInterface >
> Superclass;
typedef std::shared_ptr< Self > Pointer;
typedef std::shared_ptr< const Self > ConstPointer;
RegistrationControllerComponent(const std::string &name, LoggerImpl &logger);
virtual ~RegistrationControllerComponent();
// Accepting Interfaces:
virtual int Accept( RunRegistrationInterface::Pointer ) override;
virtual int Accept( ReconnectTransformInterface::Pointer ) override;
virtual int Accept( AfterRegistrationInterface::Pointer ) override;
// Providing Interfaces:
virtual void RegistrationControllerStart( void ) override;
virtual bool MeetsCriterion( const ComponentBase::CriterionType & criterion ) override;
// override default by not checking accepting connections and always return true.
// TODO: the controller is a bit odd since it accepts connections, but the providing components require the connections. See if we can reverse the direction of the connection.
virtual bool ConnectionsSatisfied() override { return true; }
static const char * GetDescription() { return "RegistrationController Component"; }
private:
std::set< RunRegistrationInterface::Pointer > m_RunRegistrationInterfaces;
std::set< ReconnectTransformInterface::Pointer > m_ReconnectTransformInterfaces;
std::set< AfterRegistrationInterface::Pointer > m_AfterRegistrationInterfaces;
protected:
// return the class name and the template arguments to uniquely identify this component.
static inline const std::map< std::string, std::string > TemplateProperties()
{
return { { keys::NameOfClass, "RegistrationControllerComponent" } };
}
};
} //end namespace selx
#ifndef ITK_MANUAL_INSTANTIATION
#include "selxRegistrationControllerComponent.hxx"
#endif
#endif // #define selxRegistrationControllerComponent_h
......@@ -42,7 +42,7 @@ class ElastixComponent :
>,
Providing<
itkImageInterface< Dimensionality, TPixel >,
RunRegistrationInterface
UpdateInterface
>
>
{
......@@ -59,7 +59,7 @@ public:
>,
Providing<
itkImageInterface< Dimensionality, TPixel >,
RunRegistrationInterface
UpdateInterface
>
> Superclass;
typedef std::shared_ptr< Self > Pointer;
......@@ -92,7 +92,7 @@ public:
virtual ItkImagePointer GetItkImage() override;
virtual void RunRegistration() override;
virtual void Update() override;
virtual bool MeetsCriterion( const CriterionType & criterion ) override;
......
......@@ -101,7 +101,7 @@ ElastixComponent< Dimensionality, TPixel >::GetItkImage()
template< int Dimensionality, class TPixel >
void
ElastixComponent< Dimensionality, TPixel >::RunRegistration( void )
ElastixComponent< Dimensionality, TPixel >::Update( void )
{
// TODO currently, the pipeline with elastix and tranformix can only be created after the update of elastix
this->m_elastixFilter->Update();
......
......@@ -43,7 +43,7 @@ class MonolithicElastixComponent :
Providing<
elastixTransformParameterObjectInterface< itk::Image< TPixel, Dimensionality >, itk::Image< TPixel, Dimensionality >>,
itkImageInterface< Dimensionality, TPixel >,
RunRegistrationInterface
UpdateInterface
>
>
{
......@@ -61,7 +61,7 @@ public:
Providing<
elastixTransformParameterObjectInterface< itk::Image< TPixel, Dimensionality >, itk::Image< TPixel, Dimensionality >>,
itkImageInterface< Dimensionality, TPixel >,
RunRegistrationInterface
UpdateInterface
>
> Superclass;
typedef std::shared_ptr< Self > Pointer;
......@@ -99,7 +99,7 @@ public:
virtual ItkImagePointer GetItkImage() override;
virtual void RunRegistration() override;
virtual void Update() override;
virtual bool MeetsCriterion( const CriterionType & criterion ) override;
......
......@@ -85,7 +85,7 @@ TPixel >::elastixTransformParameterObject * MonolithicElastixComponent< Dimensio
template< int Dimensionality, class TPixel >
void
MonolithicElastixComponent< Dimensionality, TPixel >::RunRegistration( void )
MonolithicElastixComponent< Dimensionality, TPixel >::Update( void )
{
this->m_elastixFilter->Update();
}
......
......@@ -45,7 +45,7 @@ class MonolithicTransformixComponent :
Providing<
itkImageInterface< Dimensionality, TPixel >,
DisplacementFieldItkImageSourceInterface< Dimensionality, TPixel >,
ReconnectTransformInterface
UpdateInterface
>
>
{
......@@ -64,7 +64,7 @@ public:
Providing<
itkImageInterface< Dimensionality, TPixel >,
DisplacementFieldItkImageSourceInterface< Dimensionality, TPixel >,
ReconnectTransformInterface
UpdateInterface
>
> Superclass;
typedef std::shared_ptr< Self > Pointer;
......@@ -100,7 +100,7 @@ public:
virtual typename DisplacementFieldImageType::Pointer GetDisplacementFieldItkImage() override;
virtual void ReconnectTransform() override;
virtual void Update() override;
virtual bool MeetsCriterion( const CriterionType & criterion ) override;
......
......@@ -145,7 +145,7 @@ MonolithicTransformixComponent< Dimensionality, TPixel >::GetDisplacementFieldIt
template< int Dimensionality, class TPixel >
void
MonolithicTransformixComponent< Dimensionality, TPixel >::ReconnectTransform( void )
MonolithicTransformixComponent< Dimensionality, TPixel >::Update( void )
{
// TODO currently, the pipeline with elastix and tranformix can only be created after the update of elastix
this->m_transformixFilter->SetTransformParameterObject( this->m_TransformParameterObjectInterface->GetTransformParameterObject() );
......
......@@ -27,8 +27,6 @@
#include "selxItkImageSourceComponent.h"
#include "selxDisplacementFieldItkImageFilterSinkComponent.h"
#include "selxRegistrationControllerComponent.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
......@@ -54,8 +52,7 @@ public:
ItkImageSinkComponent< 2, float >,
DisplacementFieldItkImageFilterSinkComponent< 2, float >,
ItkImageSourceComponent< 2, float >,
ItkImageSourceComponent< 3, double >,
RegistrationControllerComponent< >> RegisterComponents;
ItkImageSourceComponent< 3, double >> RegisterComponents;
typedef itk::Image< float, 2 > Image2DType;
typedef itk::ImageFileReader< Image2DType > ImageReader2DType;
......@@ -119,8 +116,6 @@ TEST_F( ElastixComponentTest, ImagesOnly )
component3Parameters[ "Dimensionality" ] = { "2" }; // should be derived from the inputs
blueprint->SetComponent( "ResultImageSink", component3Parameters );
blueprint->SetComponent( "Controller", { { "NameOfClass", { "RegistrationControllerComponent" } } } );
ParameterMapType connection1Parameters;
//connection1Parameters["NameOfInterface"] = { "itkImageFixedInterface" };
blueprint->SetConnection( "FixedImageSource", "RegistrationMethod", connection1Parameters );
......@@ -133,9 +128,6 @@ TEST_F( ElastixComponentTest, ImagesOnly )
//connection3Parameters["NameOfInterface"] = { "GetItkImageInterface" };
blueprint->SetConnection( "RegistrationMethod", "ResultImageSink", connection3Parameters );
blueprint->SetConnection( "RegistrationMethod", "Controller", { {} } ); //
blueprint->SetConnection( "ResultImageSink", "Controller", { {} } ); //
// Set up the readers and writers
ImageReader2DType::Pointer fixedImageReader = ImageReader2DType::New();
fixedImageReader->SetFileName( dataManager->GetInputFile( "BrainProtonDensitySliceBorder20.png" ) );
......@@ -177,8 +169,6 @@ TEST_F( ElastixComponentTest, MonolithicElastixTransformix )
blueprint->SetComponent( "ResultDisplacementFieldSink", { { "NameOfClass", { "DisplacementFieldItkImageFilterSinkComponent" } }, { "Dimensionality", { "2" } } });
blueprint->SetComponent( "Controller", { { "NameOfClass", { "RegistrationControllerComponent" } } } );
blueprint->SetConnection( "FixedImageSource", "RegistrationMethod", { { "NameOfInterface", { "itkImageFixedInterface" } } } ); // ;
blueprint->SetConnection( "MovingImageSource", "RegistrationMethod", { { "NameOfInterface", { "itkImageMovingInterface" } } } ); // ;
......@@ -193,10 +183,6 @@ TEST_F( ElastixComponentTest, MonolithicElastixTransformix )
blueprint->SetConnection( "TransformDisplacementField", "ResultDisplacementFieldSink", { { "NameOfInterface", { "DisplacementFieldItkImageSourceInterface" } } }); // ;
blueprint->SetConnection( "RegistrationMethod", "Controller", { {} } ); //
blueprint->SetConnection( "TransformDisplacementField", "Controller", { {} } ); //
blueprint->SetConnection( "ResultImageSink", "Controller", { {} } ); //
blueprint->SetConnection( "ResultDisplacementFieldSink", "Controller", { {} }); //
// Set up the readers and writers
ImageReader2DType::Pointer fixedImageReader = ImageReader2DType::New();
......
......@@ -37,7 +37,7 @@ class IdentityTransformRegistrationComponent :
itkImageFixedInterface< Dimensionality, TPixel >,
itkImageMovingInterface< Dimensionality, TPixel >
>,
Providing< RunRegistrationInterface,
Providing< UpdateInterface,
DisplacementFieldItkImageSourceInterface< Dimensionality, TPixel >
>
>
......@@ -53,7 +53,7 @@ public:
itkImageFixedInterface< Dimensionality, TPixel >,
itkImageMovingInterface< Dimensionality, TPixel >
>,
Providing< RunRegistrationInterface,
Providing< UpdateInterface,
DisplacementFieldItkImageSourceInterface< Dimensionality, TPixel >
>
> Superclass;
......@@ -79,7 +79,7 @@ public:
// Providing Interfaces:
virtual typename DisplacementFieldImageType::Pointer GetDisplacementFieldItkImage() override;
virtual void RunRegistration() override;
virtual void Update() override;
virtual bool MeetsCriterion( const CriterionType & criterion ) override;
......
......@@ -81,7 +81,7 @@ IdentityTransformRegistrationComponent< Dimensionality, TPixel >::GetDisplacemen
template< int Dimensionality, class TPixel >
void
IdentityTransformRegistrationComponent< Dimensionality, TPixel >::RunRegistration( void )
IdentityTransformRegistrationComponent< Dimensionality, TPixel >::Update( void )
{
auto fixed = this->m_ImageFixedInterface->GetItkImageFixed();
auto moving = this->m_ImageMovingInterface->GetItkImageMoving();
......
......@@ -39,7 +39,7 @@ template< int Dimensionality, class TPixel >
class DisplacementFieldNiftiToItkImageSinkComponent :
public SuperElastixComponent<
Accepting< NiftyregDisplacementFieldImageInterface< TPixel >, itkImageDomainFixedInterface< Dimensionality >>,
Providing< SinkInterface, AfterRegistrationInterface >
Providing< SinkInterface, UpdateInterface >
>
{
public:
......@@ -48,7 +48,7 @@ public:
typedef DisplacementFieldNiftiToItkImageSinkComponent< Dimensionality, TPixel > Self;
typedef SuperElastixComponent<
Accepting< NiftyregDisplacementFieldImageInterface< TPixel >, itkImageDomainFixedInterface< Dimensionality >>,
Providing< SinkInterface, AfterRegistrationInterface >
Providing< SinkInterface, UpdateInterface >
> Superclass;
typedef std::shared_ptr< Self > Pointer;
typedef std::shared_ptr< const Self > ConstPointer;
......@@ -82,7 +82,7 @@ public:
virtual itk::DataObject::Pointer GetInitializedOutput( void ) override;
virtual void AfterRegistration() override;
virtual void Update() override;
virtual bool MeetsCriterion( const ComponentBase::CriterionType & criterion ) override;
......
......@@ -106,7 +106,7 @@ DisplacementFieldNiftiToItkImageSinkComponent< Dimensionality, TPixel >::GetInit
template< int Dimensionality, class TPixel >
void
DisplacementFieldNiftiToItkImageSinkComponent< Dimensionality, TPixel >::AfterRegistration()
DisplacementFieldNiftiToItkImageSinkComponent< Dimensionality, TPixel >::Update()
{
auto displacementFieldNiftiImage = this->m_DisplacementFieldInterface->GetDisplacementFieldNiftiImage();
auto displacementFieldItkImage = NiftiToItkImage< ItkDisplacementFieldType, TPixel >::Convert( displacementFieldNiftiImage );
......
......@@ -39,7 +39,7 @@ template< int Dimensionality, class TPixel >
class NiftiToItkImageSinkComponent :
public SuperElastixComponent<
Accepting< NiftyregWarpedImageInterface< TPixel >, itkImageDomainFixedInterface< Dimensionality >>,
Providing< SinkInterface, AfterRegistrationInterface >
Providing< SinkInterface, UpdateInterface >
>
{
public:
......@@ -48,7 +48,7 @@ public:
typedef NiftiToItkImageSinkComponent< Dimensionality, TPixel > Self;
typedef SuperElastixComponent<
Accepting< NiftyregWarpedImageInterface< TPixel >, itkImageDomainFixedInterface< Dimensionality >>,
Providing< SinkInterface, AfterRegistrationInterface >
Providing< SinkInterface, UpdateInterface >
> Superclass;
typedef std::shared_ptr< Self > Pointer;
typedef std::shared_ptr< const Self > ConstPointer;
......@@ -79,7 +79,7 @@ public:
virtual itk::DataObject::Pointer GetInitializedOutput( void ) override;
virtual void AfterRegistration() override;
virtual void Update() override;
virtual bool MeetsCriterion( const ComponentBase::CriterionType & criterion ) override;
......
......@@ -106,7 +106,7 @@ NiftiToItkImageSinkComponent< Dimensionality, TPixel >::GetInitializedOutput()
template< int Dimensionality, class TPixel >
void
NiftiToItkImageSinkComponent< Dimensionality, TPixel >::AfterRegistration()
NiftiToItkImageSinkComponent< Dimensionality, TPixel >::Update()
{
auto warpedNiftiImage = this->m_WarpedImageInterface->GetWarpedNiftiImage();
auto warpedItkImage = NiftiToItkImage< ItkImageType, TPixel >::Convert( warpedNiftiImage );
......
......@@ -34,7 +34,7 @@ template< class TPixel >
class NiftyregAladinComponent :
public SuperElastixComponent<
Accepting< NiftyregReferenceImageInterface< TPixel >, NiftyregFloatingImageInterface< TPixel >>,
Providing< NiftyregWarpedImageInterface< TPixel >, NiftyregAffineMatrixInterface< TPixel >, RunRegistrationInterface >
Providing< NiftyregWarpedImageInterface< TPixel >, NiftyregAffineMatrixInterface< TPixel >, UpdateInterface >
>
{
public:
......@@ -43,7 +43,7 @@ public:
typedef NiftyregAladinComponent< TPixel > Self;
typedef SuperElastixComponent<
Accepting< NiftyregReferenceImageInterface< TPixel >, NiftyregFloatingImageInterface< TPixel >>,
Providing< NiftyregWarpedImageInterface< TPixel >, NiftyregAffineMatrixInterface< TPixel >, RunRegistrationInterface >
Providing< NiftyregWarpedImageInterface< TPixel >, NiftyregAffineMatrixInterface< TPixel >, UpdateInterface >
> Superclass;
typedef std::shared_ptr< Self > Pointer;
typedef std::shared_ptr< const Self > ConstPointer;
......@@ -59,7 +59,7 @@ public:
virtual mat44 * GetAffineNiftiMatrix() override;
virtual void RunRegistration() override;
virtual void Update() override;
virtual bool MeetsCriterion( const ComponentBase::CriterionType & criterion ) override;
......
......@@ -81,9 +81,9 @@ NiftyregAladinComponent< TPixel >
template< class TPixel >
void
NiftyregAladinComponent< TPixel >
::RunRegistration()
::Update()
{
this->m_Logger.Log(LogLevel::TRC, "RunRegistration");
this->m_Logger.Log(LogLevel::TRC, "Update: run registration");
this->m_reg_aladin->Run();
nifti_image * outputWarpedImage = m_reg_aladin->GetFinalWarpedImage();
memset( outputWarpedImage->descrip, 0, 80 );
......
......@@ -33,7 +33,7 @@ template< class TPixel >
class NiftyregSplineToDisplacementFieldComponent :
public SuperElastixComponent<
Accepting< NiftyregControlPointPositionImageInterface< TPixel >, NiftyregReferenceImageInterface< TPixel > >,
Providing< NiftyregDisplacementFieldImageInterface< TPixel >, ReconnectTransformInterface >
Providing< NiftyregDisplacementFieldImageInterface< TPixel >, UpdateInterface >
>
{
public:
......@@ -42,7 +42,7 @@ public:
typedef NiftyregSplineToDisplacementFieldComponent< TPixel > Self;
typedef SuperElastixComponent<
Accepting< NiftyregControlPointPositionImageInterface< TPixel >, NiftyregReferenceImageInterface< TPixel >>,
Providing< NiftyregDisplacementFieldImageInterface< TPixel >, ReconnectTransformInterface >
Providing< NiftyregDisplacementFieldImageInterface< TPixel >, UpdateInterface >
> Superclass;
typedef std::shared_ptr< Self > Pointer;
typedef std::shared_ptr< const Self > ConstPointer;
......@@ -59,8 +59,8 @@ public:
// Providing NiftyregWarpedImageInterface
virtual std::shared_ptr< nifti_image > GetDisplacementFieldNiftiImage() override;
// Providing ReconnectTransformInterface
virtual void ReconnectTransform() override;
// Providing UpdateInterface
virtual void Update() override;