text: #ifndef __sitktransformiximagefilterimpl_cxx_
  #define __sitktransformiximagefilterimpl_cxx_
  
  #include "sitkTransformixImageFilter.h"
  #include "sitkTransformixImageFilterImpl.h"
  #include "sitkCastImageFilter.h"
  
  namespace itk {
    namespace simple {
  
  TransformixImageFilter::TransformixImageFilterImpl
  ::TransformixImageFilterImpl( void )
  {
    // Register this class with SimpleITK
    this->m_MemberFactory.reset( new detail::MemberFunctionFactory< MemberFunctionType >( this ) );
    this->m_MemberFactory->RegisterMemberFunctions< FloatPixelIDTypeList, 2 >();
    this->m_MemberFactory->RegisterMemberFunctions< FloatPixelIDTypeList, 3 >();
  
  #ifdef SITK_4D_IMAGES
    m_MemberFactory->RegisterMemberFunctions< FloatPixelIDTypeList, 4 >();
  #endif
  
    this->m_MovingImage = Image();
    this->m_ResultImage = Image();
  
    this->m_TransformParameterMapVector = ParameterMapVectorType();
  
    this->m_ComputeSpatialJacobian = false;
    this->m_ComputeDeterminantOfSpatialJacobian = false;
    this->m_ComputeDeformationField = false;
    this->m_MovingPointSetFileName = "";
  
    this->m_OutputDirectory = ".";
    this->m_LogFileName = "";
    
    this->m_LogToFile = false;
    this->m_LogToConsole = true;
  }
  
  TransformixImageFilter::TransformixImageFilterImpl
  ::~TransformixImageFilterImpl( void )
  {
  }
  
  Image
  TransformixImageFilter::TransformixImageFilterImpl
  ::Execute( void )
  {
    const PixelIDValueEnum MovingImagePixelEnum = this->m_MovingImage.GetPixelID();
    const unsigned int MovingImageDimension = this->m_MovingImage.GetDimension();
  
    if( this->m_MemberFactory->HasMemberFunction( sitkFloat32, MovingImageDimension ) )
    {
      return this->m_MemberFactory->GetMemberFunction( sitkFloat32, MovingImageDimension )();
    }
  
    sitkExceptionMacro( << "TransformixImageFilter does not support the combination of image type "
                        << GetPixelIDValueAsElastixParameter( MovingImagePixelEnum ) << " and dimension "
                        << MovingImageDimension << ". This a serious error. "
                        << "Contact developers at https://github.com/kaspermarstal/SimpleElastix/issues." );
  }
  
  template< typename TMovingImage >
  Image
  TransformixImageFilter::TransformixImageFilterImpl
  ::ExecuteInternal( void )
  {
    typedef elastix::TransformixFilter< TMovingImage > TransformixFilterType;
    typedef typename TransformixFilterType::Pointer TransforimxFilterPointer;
  
    try
    {
      TransforimxFilterPointer transformixFilter = TransformixFilterType::New();
  
      if( !this->IsEmpty( this->m_MovingImage ) ) {
        transformixFilter->SetMovingImage( itkDynamicCastInDebugMode< TMovingImage* >( Cast( this->GetMovingImage(), static_cast< PixelIDValueEnum >( GetPixelIDValueFromElastixString( "float" ) ) ).GetITKBase() ) );
      }
  
      transformixFilter->SetFixedPointSetFileName( this->GetFixedPointSetFileName() );
      transformixFilter->SetComputeSpatialJacobian( this->GetComputeSpatialJacobian() );
      transformixFilter->SetComputeDeterminantOfSpatialJacobian( this->GetComputeDeterminantOfSpatialJacobian() );
      transformixFilter->SetComputeDeformationField( this->GetComputeDeformationField() );
  
      transformixFilter->SetOutputDirectory( this->GetOutputDirectory() );
      transformixFilter->SetLogFileName( this->GetLogFileName() );
      transformixFilter->SetLogToFile( this->GetLogToFile() );
      transformixFilter->SetLogToConsole( this->GetLogToConsole() );
  
      ParameterMapVectorType transformParameterMapVector = this->m_TransformParameterMapVector;
      for( unsigned int i = 0; i < transformParameterMapVector.size(); i++ )
      {
        transformParameterMapVector[ i ][ "FixedInternalImagePixelType" ] = ParameterValueVectorType( 1, "float" );
        transformParameterMapVector[ i ][ "MovingInternalImagePixelType" ] = ParameterValueVectorType( 1, "float" );
      }
  
      ParameterObjectPointer parameterObject = ParameterObjectType::New();
      parameterObject->SetParameterMap( transformParameterMapVector );
      transformixFilter->SetTransformParameterObject( parameterObject );
      transformixFilter->Update();
  
      if( !this->IsEmpty( this->GetMovingImage() ) )
      {
        this->m_ResultImage = Image( itkDynamicCastInDebugMode< TMovingImage * >( transformixFilter->GetOutput() ) );
        this->m_ResultImage.MakeUnique();
      }
    }
    catch( itk::ExceptionObject &e )
    {
      sitkExceptionMacro( << e );
    }
  
    return this->m_ResultImage;
  }
  
  const std::string 
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetName( void )
  { 
    const std::string name = std::string( "TransformixImageFilter" );
    return name;
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetMovingImage( const Image& movingImage )
  {
    this->m_MovingImage = movingImage;
  }
  
  Image&
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetMovingImage( void )
  {
    return this->m_MovingImage;
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::RemoveMovingImage( void )
  {
    this->SetMovingImage( Image() );
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetFixedPointSetFileName( const std::string movingPointSetFileName )
  {
    this->m_MovingPointSetFileName = movingPointSetFileName;
  }
  
  std::string 
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetFixedPointSetFileName( void )
  {
    return this->m_MovingPointSetFileName;
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::RemoveFixedPointSetFileName( void )
  {
    this->m_MovingPointSetFileName = std::string();
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetComputeSpatialJacobian( const bool computeSpatialJacobian )
  {
    this->m_ComputeSpatialJacobian = computeSpatialJacobian;
  }
  
  bool 
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetComputeSpatialJacobian( void )
  {
    return this->m_ComputeSpatialJacobian;
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::ComputeSpatialJacobianOn( void )
  {
    this->SetComputeSpatialJacobian( true );
    
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::ComputeSpatialJacobianOff( void )
  {
    this->SetComputeSpatialJacobian( false );
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetComputeDeterminantOfSpatialJacobian( const bool computeDeterminantOfSpatialJacobian )
  {
    this->m_ComputeDeterminantOfSpatialJacobian = computeDeterminantOfSpatialJacobian;
  }
  
  bool 
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetComputeDeterminantOfSpatialJacobian( void )
  {
    return this->m_ComputeDeterminantOfSpatialJacobian;
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::ComputeDeterminantOfSpatialJacobianOn( void )
  {
    this->SetComputeDeterminantOfSpatialJacobian( true );
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::ComputeDeterminantOfSpatialJacobianOff( void )
  {
    this->SetComputeDeterminantOfSpatialJacobian( false );
    
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetComputeDeformationField( const bool computeDeformationField )
  {
    this->m_ComputeDeformationField = computeDeformationField;
  }
  
  bool
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetComputeDeformationField( void )
  {
    return this->m_ComputeDeformationField;
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::ComputeDeformationFieldOn( void )
  {
    this->SetComputeDeformationField( true );
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::ComputeDeformationFieldOff( void )
  {
    this->SetComputeDeformationField( false );
    
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetOutputDirectory( const std::string outputDirectory )
  {
    this->m_OutputDirectory = outputDirectory;
  }
  
  std::string
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetOutputDirectory( void )
  {
    return this->m_OutputDirectory;
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::RemoveOutputDirectory( void )
  {
    this->m_OutputDirectory = std::string();
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetLogFileName( std::string logFileName )
  {
    this->m_LogFileName = logFileName;
  }
  
  std::string
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetLogFileName( void )
  {
    return this->m_LogFileName;
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::RemoveLogFileName( void )
  {
    this->m_LogFileName = std::string();
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetLogToFile( bool logToFile )
  {
    this->m_LogToFile = logToFile;
    
  }
  
  bool
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetLogToFile( void )
  {
    return this->m_LogToFile;
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::LogToFileOn()
  {
    this->SetLogToFile( true );
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::LogToFileOff()
  {
    this->SetLogToFile( false );
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetLogToConsole( bool logToConsole )
  {
    this->m_LogToConsole = logToConsole;
  }
  
  bool
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetLogToConsole( void )
  {
    return this->m_LogToConsole;
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::LogToConsoleOn()
  {
    this->SetLogToConsole( true );
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::LogToConsoleOff()
  {
    this->SetLogToConsole( false );
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetTransformParameterMap( const ParameterMapVectorType parameterMapVector )
  {
    this->m_TransformParameterMapVector = parameterMapVector;
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetTransformParameterMap( const ParameterMapType parameterMap )
  {
    ParameterMapVectorType parameterMapVector;
    parameterMapVector.push_back( parameterMap );
    this->SetTransformParameterMap( parameterMapVector );
    
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::AddTransformParameterMap( const ParameterMapType parameterMap )
  {
    this->m_TransformParameterMapVector.push_back( parameterMap );
  }
  
  TransformixImageFilter::TransformixImageFilterImpl::ParameterMapVectorType
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetTransformParameterMap( void )
  {
    return this->m_TransformParameterMapVector;
  }
  
  unsigned int
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetNumberOfTransformParameterMaps( void )
  {
    return this->m_TransformParameterMapVector.size();
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetTransformParameter( const ParameterKeyType key, const ParameterValueType value )
  {
    for( unsigned int i = 0; i < this->m_TransformParameterMapVector.size(); i++ )
    {
      this->SetTransformParameter( i, key, value );
    }
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetTransformParameter( const ParameterKeyType key, const ParameterValueVectorType value )
  {
    for( unsigned int i = 0; i < this->m_TransformParameterMapVector.size(); i++ )
    {
      this->SetTransformParameter( i, key, value );
    }
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetTransformParameter( const unsigned int index, const ParameterKeyType key, const ParameterValueType value )
  {
    if( index >= this->m_TransformParameterMapVector.size() )
    {
      sitkExceptionMacro( "Parameter map index is out of range (index: " << index << "; number of transform parameters maps: " << this->m_TransformParameterMapVector.size() << "). Note that indexes are zero-based." );
    }
  
    this->m_TransformParameterMapVector[ index ][ key ] = ParameterValueVectorType( 1, value );
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::SetTransformParameter( const unsigned int index, const ParameterKeyType key, const ParameterValueVectorType value )
  {
    if( index >= this->m_TransformParameterMapVector.size() )
    {
      sitkExceptionMacro( "Parameter map index is out of range (index: " << index << ", number of transform parameters maps: " << this->m_TransformParameterMapVector.size() << "). Note that indexes are zero-based." );
    }
  
    this->m_TransformParameterMapVector[ index ][ key ] = value;
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::AddTransformParameter( const ParameterKeyType key, const ParameterValueType value )
  {
    for( unsigned int i = 0; i < this->m_TransformParameterMapVector.size(); i++ )
    {
      this->AddTransformParameter( i, key, value );
    }
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::AddTransformParameter( const unsigned int index, const ParameterKeyType key, const ParameterValueType value )
  {
    if( index >= this->m_TransformParameterMapVector.size() )
    {
      sitkExceptionMacro( "Parameter map index is out of range (index: " << index << ", number of transform parameters maps: " << this->m_TransformParameterMapVector.size() << "). Note that indexes are zero-based." );
    }
  
    if( this->m_TransformParameterMapVector[ index ].find( key ) == this->m_TransformParameterMapVector[ index ].end() )
    {
      this->SetTransformParameter( index, key, value );
    }
    else
    {
      this->m_TransformParameterMapVector[ index ][ key ].push_back( value );
    }
  }
  
  TransformixImageFilter::TransformixImageFilterImpl::ParameterValueVectorType
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetTransformParameter( const ParameterKeyType key )
  {
    if( this->m_TransformParameterMapVector.size() > 0 )
    {
      sitkExceptionMacro( "An index is needed when more than one transform parameter map is present. Please specify the parameter map number as the first argument." );
    }
  
    return this->GetTransformParameter( 0, key );
  }
  
  TransformixImageFilter::TransformixImageFilterImpl::ParameterValueVectorType
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetTransformParameter( const unsigned int index, const ParameterKeyType key )
  {
    if( index >= this->m_TransformParameterMapVector.size() )
    {
      sitkExceptionMacro( "Parameter map index is out of range (index: " << index << ", number of transform parameters maps: " << this->m_TransformParameterMapVector.size() << "). Note that indexes are zero-based." );
    }
  
    return this->m_TransformParameterMapVector[ index ][ key ];
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::RemoveTransformParameter( const ParameterKeyType key )
  {
    for( unsigned int i = 0; i < this->m_TransformParameterMapVector.size(); i++ )
    {
      this->RemoveTransformParameter( i, key );
    } 
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::RemoveTransformParameter( const unsigned int index, const ParameterKeyType key )
  {
    if( index >= this->m_TransformParameterMapVector.size() )
    {
      sitkExceptionMacro( "Parameter map index is out of range (index: " << index << ", number of transform parameters maps: " << this->m_TransformParameterMapVector.size() << "). Note that indexes are zero-based." );
    }
  
    this->m_TransformParameterMapVector[ index ].erase( key );
  }
  
  TransformixImageFilter::TransformixImageFilterImpl::ParameterMapType 
  TransformixImageFilter::TransformixImageFilterImpl
  ::ReadParameterFile( const std::string filename )
  {
    ParameterFileParserPointer parser = ParameterFileParserType::New();
    parser->SetParameterFileName( filename );
    try
    {
      parser->ReadParameterFile();
    }
    catch( itk::ExceptionObject &e )
    {
      std::cout << e.what() << std::endl;
    }
  
    return parser->GetParameterMap();
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::WriteParameterFile( const ParameterMapType parameterMap, const std::string parameterFileName )
  {
    ParameterObjectPointer parameterObject = ParameterObjectType::New();
    parameterObject->WriteParameterFile( parameterMap, parameterFileName );
  }
  
  void
  TransformixImageFilter::TransformixImageFilterImpl
  ::PrintParameterMap( void )
  {
    this->PrintParameterMap( this->GetTransformParameterMap() );
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::PrintParameterMap( const ParameterMapType parameterMap )
  {
    ParameterMapVectorType parameterMapVector = ParameterMapVectorType( 1 );
    parameterMapVector[ 0 ] = parameterMap;
    this->PrintParameterMap( parameterMapVector );
  }
  
  void 
  TransformixImageFilter::TransformixImageFilterImpl
  ::PrintParameterMap( const ParameterMapVectorType parameterMapVector )
  {
    ParameterObjectPointer parameterObject = ParameterObjectType::New();
    parameterObject->SetParameterMap( parameterMapVector );
    parameterObject->Print( std::cout );
    
  }
  
  Image
  TransformixImageFilter::TransformixImageFilterImpl
  ::GetResultImage( void )
  {
    if( this->IsEmpty( this->m_ResultImage ) )
    {
      sitkExceptionMacro( "No result image was found. Has transformix run yet?" )
    }
  
    return this->m_ResultImage;
  }
  
  
  bool
  TransformixImageFilter::TransformixImageFilterImpl
  ::IsEmpty( const Image& image )
  {
    bool isEmpty = image.GetWidth() == 0 && image.GetHeight() == 0;
    return isEmpty;
  }
  
  } // end namespace simple
  } // end namespace itk
  
  #endif // __sitktransformiximagefilterimpl_cxx_