Skip to content

Commit

Permalink
ENH: Load factories in Python at runtime
Browse files Browse the repository at this point in the history
Load IO and FFT factories at runtime based on the itk-module.cmake
FACTORY_NAMES metadata, as is done with C++ static binary
initialization.

This enables run-time discovery of all Python IO or FFT implementations.
Some may be added with remote module Python packages.

This also addresses Slicer's use case where Slice is performing
initialization of IO factories with static initialization. Only
one static binary initialization is intended to be supported per
application. Do not perform static binary initialization in the Python
modules.

FFTImageFilter consolidation was finalized, and the required
corresponding VnlFFTImageFilterFactory and FFTWFFTImageFilterFactory
classes created and wrapped.

Add the missing required TransformIO wrapping.
  • Loading branch information
thewtex committed Feb 3, 2022
1 parent 2c94866 commit a8cd38a
Show file tree
Hide file tree
Showing 26 changed files with 341 additions and 70 deletions.
2 changes: 1 addition & 1 deletion CMake/ITKFactoryRegistration.cmake
Expand Up @@ -52,7 +52,7 @@
# Setting variable `ITK_NO_<factory_name_uc>_FACTORY_REGISTER_MANAGER` to `ON` prior calling
# `include(${ITK_USE_FILE})` disables the static registration.
# Here <factory_name_uc> is the upper case name of the factory. For example,
# `IMAGEIO`, `MESHIO`, `TRANSFORMIO`, or `FFT`.
# `IMAGEIO`, `MESHIO`, `TRANSFORMIO`, or `FFTIMAGEFILTER`.
#
# All factories can be disabled with the following CMake code:
# foreach(_factory_name ${ITK_FACTORY_LIST})
Expand Down
70 changes: 70 additions & 0 deletions Modules/Filtering/FFT/include/itkFFTWFFTImageFilterFactory.h
@@ -0,0 +1,70 @@
/*=========================================================================
*
* Copyright NumFOCUS
*
* 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 itkFFTWFFTImageFilterFactory_h
#define itkFFTWFFTImageFilterFactory_h
#include "ITKFFTExport.h"

#include "itkObjectFactoryBase.h"

namespace itk
{
/**
*\class FFTWFFTImageFilterFactory
* \brief Create instances of FFTW FFT ImageFilter objects using an object factory.
* \ingroup ITKFFT
*/
class ITKFFT_EXPORT FFTWFFTImageFilterFactory : public ObjectFactoryBase
{
public:
ITK_DISALLOW_COPY_AND_MOVE(FFTWFFTImageFilterFactory);

/** Standard class type aliases. */
using Self = FFTWFFTImageFilterFactory;
using Superclass = ObjectFactoryBase;
using Pointer = SmartPointer<Self>;
using ConstPointer = SmartPointer<const Self>;

/** Class methods used to interface with the registered factories. */
const char *
GetITKSourceVersion() const override;

const char *
GetDescription() const override;

/** Method for class instantiation. */
itkFactorylessNewMacro(Self);

/** Run-time type information (and related methods). */
itkTypeMacro(FFTWFFTImageFilterFactory, ObjectFactoryBase);

/** Register one factory of this type */
static void
RegisterOneFactory()
{
auto factory = FFTWFFTImageFilterFactory::New();

ObjectFactoryBase::RegisterFactoryInternal(factory);
}

protected:
FFTWFFTImageFilterFactory();
~FFTWFFTImageFilterFactory() override;
};
} // end namespace itk

#endif
70 changes: 70 additions & 0 deletions Modules/Filtering/FFT/include/itkVnlFFTImageFilterFactory.h
@@ -0,0 +1,70 @@
/*=========================================================================
*
* Copyright NumFOCUS
*
* 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 itkVnlFFTImageFilterFactory_h
#define itkVnlFFTImageFilterFactory_h
#include "ITKFFTExport.h"

#include "itkObjectFactoryBase.h"

namespace itk
{
/**
*\class VnlFFTImageFilterFactory
* \brief Create instances of Vnl FFT ImageFilter objects using an object factory.
* \ingroup ITKFFT
*/
class ITKFFT_EXPORT VnlFFTImageFilterFactory : public ObjectFactoryBase
{
public:
ITK_DISALLOW_COPY_AND_MOVE(VnlFFTImageFilterFactory);

/** Standard class type aliases. */
using Self = VnlFFTImageFilterFactory;
using Superclass = ObjectFactoryBase;
using Pointer = SmartPointer<Self>;
using ConstPointer = SmartPointer<const Self>;

/** Class methods used to interface with the registered factories. */
const char *
GetITKSourceVersion() const override;

const char *
GetDescription() const override;

/** Method for class instantiation. */
itkFactorylessNewMacro(Self);

/** Run-time type information (and related methods). */
itkTypeMacro(VnlFFTImageFilterFactory, ObjectFactoryBase);

/** Register one factory of this type */
static void
RegisterOneFactory()
{
auto factory = VnlFFTImageFilterFactory::New();

ObjectFactoryBase::RegisterFactoryInternal(factory);
}

protected:
VnlFFTImageFilterFactory();
~VnlFFTImageFilterFactory() override;
};
} // end namespace itk

#endif
4 changes: 2 additions & 2 deletions Modules/Filtering/FFT/itk-module.cmake
Expand Up @@ -5,10 +5,10 @@ computations of Fast Fourier Transforms based on
<a href=\"http://www.fftw.org\">FFTW</a>. Note that when using the FFTW
implementation you must comply with the GPL license.")

set(_fft_backends "FFT::VnlComplexToComplex1D;FFT::VnlComplexToComplex;FFT::VnlForward1D;FFT::VnlForward;FFT::VnlHalfHermitianToRealInverse;FFT::VnlInverse1D;FFT::VnlInverse;FFT::VnlRealToHalfHermitianForward")
set(_fft_backends "FFTImageFilter::Vnl")
if(ITK_USE_FFTWF OR ITK_USE_FFTWD)
# Prepend so that FFTW constructor is preferred
list(PREPEND _fft_backends "FFT::FFTWComplexToComplex1D;FFT::FFTWComplexToComplex;FFT::FFTWForward1D;FFT::FFTWForward;FFT::FFTWHalfHermitianToRealInverse;FFT::FFTWInverse1D;FFT::FFTWInverse;FFT::FFTWRealToHalfHermitianForward")
list(PREPEND _fft_backends "FFTImageFilter::FFTW")
endif()

itk_module(ITKFFT
Expand Down
4 changes: 2 additions & 2 deletions Modules/Filtering/FFT/src/CMakeLists.txt
@@ -1,10 +1,10 @@
set(ITKFFT_SRCS
itkComplexToComplexFFTImageFilter.cxx
itkVnlFFTImageFilterFactories.cxx)
itkVnlFFTImageFilterFactory.cxx)

if( ITK_USE_FFTWF OR ITK_USE_FFTWD AND NOT ITK_USE_CUFFTW)
list(APPEND ITKFFT_SRCS itkFFTWGlobalConfiguration.cxx )
list(APPEND ITKFFT_SRCS itkFFTWFFTImageFilterFactories.cxx )
list(APPEND ITKFFT_SRCS itkFFTWFFTImageFilterFactory.cxx )
endif()

itk_module_add_library(ITKFFT ${ITKFFT_SRCS})
Expand Down
Expand Up @@ -19,7 +19,7 @@

#if defined(ITK_USE_FFTWF) || defined(ITK_USE_FFTWD)

# include "ITKFFTExport.h"
# include "ITKFFTWFFTImageFilterFactory.h"

# include "itkFFTWComplexToComplex1DFFTImageFilter.h"
# include "itkFFTWComplexToComplexFFTImageFilter.h"
Expand All @@ -36,55 +36,47 @@

namespace itk
{
// Undocumented API used to register during static initialization.
// DO NOT CALL DIRECTLY.
void ITKFFT_EXPORT
FFTWComplexToComplex1DFFTFactoryRegister__Private()
FFTWFFTImageFilterFactory::FFTWFFTImageFilterFactory()
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWComplexToComplex1DFFTImageFilter>>();
}

void ITKFFT_EXPORT
FFTWComplexToComplexFFTFactoryRegister__Private()
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWComplexToComplexFFTImageFilter>>();
}

void ITKFFT_EXPORT
FFTWForward1DFFTFactoryRegister__Private()
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWForward1DFFTImageFilter>>();
}

void ITKFFT_EXPORT
FFTWForwardFFTFactoryRegister__Private()
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWForwardFFTImageFilter>>();
}

void ITKFFT_EXPORT
FFTWHalfHermitianToRealInverseFFTFactoryRegister__Private()
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWHalfHermitianToRealInverseFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWInverse1DFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWInverseFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWRealToHalfHermitianForwardFFTImageFilter>>();
}

void ITKFFT_EXPORT
FFTWInverse1DFFTFactoryRegister__Private()
FFTWFFTImageFilterFactory::~FFTWFFTImageFilterFactory() = default;

const char *
FFTWFFTImageFilterFactory::GetITKSourceVersion() const
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWInverse1DFFTImageFilter>>();
return ITK_SOURCE_VERSION;
}

void ITKFFT_EXPORT
FFTWInverseFFTFactoryRegister__Private()
const char *
FFTWFFTImageFilterFactory::GetDescription() const
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWInverseFFTImageFilter>>();
return "FFTW FFT Image Filter Factory, allows running FFTW backed FFT image filters in Insight";
}

// Undocumented API used to register during static initialization.
// DO NOT CALL DIRECTLY.
void ITKFFT_EXPORT
FFTWRealToHalfHermitianForwardFFTFactoryRegister__Private()
FFTWFFTImageFilterFactoryRegister__Private()
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWComplexToComplex1DFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWComplexToComplexFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWForward1DFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWForwardFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWHalfHermitianToRealInverseFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWInverse1DFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWInverseFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<FFTWRealToHalfHermitianForwardFFTImageFilter>>();
}

} // end namespace itk

#endif // defined(ITK_USE_FFTWF) || defined(ITK_USE_FFTWD)
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*
*=========================================================================*/
#include "ITKFFTExport.h"
#include "itkVnlFFTImageFilterFactory.h"

#include "itkVnlComplexToComplex1DFFTImageFilter.h"
#include "itkVnlComplexToComplexFFTImageFilter.h"
Expand All @@ -32,53 +32,45 @@

namespace itk
{
// Undocumented API used to register during static initialization.
// DO NOT CALL DIRECTLY.
void ITKFFT_EXPORT
VnlComplexToComplex1DFFTFactoryRegister__Private()
VnlFFTImageFilterFactory::VnlFFTImageFilterFactory()
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlComplexToComplex1DFFTImageFilter>>();
}

void ITKFFT_EXPORT
VnlComplexToComplexFFTFactoryRegister__Private()
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlComplexToComplexFFTImageFilter>>();
}

void ITKFFT_EXPORT
VnlForward1DFFTFactoryRegister__Private()
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlForward1DFFTImageFilter>>();
}

void ITKFFT_EXPORT
VnlForwardFFTFactoryRegister__Private()
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlForwardFFTImageFilter>>();
}

void ITKFFT_EXPORT
VnlHalfHermitianToRealInverseFFTFactoryRegister__Private()
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlHalfHermitianToRealInverseFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlInverse1DFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlInverseFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlRealToHalfHermitianForwardFFTImageFilter>>();
}

void ITKFFT_EXPORT
VnlInverse1DFFTFactoryRegister__Private()
VnlFFTImageFilterFactory::~VnlFFTImageFilterFactory() = default;

const char *
VnlFFTImageFilterFactory::GetITKSourceVersion() const
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlInverse1DFFTImageFilter>>();
return ITK_SOURCE_VERSION;
}

void ITKFFT_EXPORT
VnlInverseFFTFactoryRegister__Private()
const char *
VnlFFTImageFilterFactory::GetDescription() const
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlInverseFFTImageFilter>>();
return "Vnl FFT Image Filter Factory, allows running VNL backed FFT image filters in Insight";
}

// Undocumented API used to register during static initialization.
// DO NOT CALL DIRECTLY.
void ITKFFT_EXPORT
VnlRealToHalfHermitianForwardFFTFactoryRegister__Private()
VnlFFTImageFilterFactoryRegister__Private()
{
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlComplexToComplex1DFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlComplexToComplexFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlForward1DFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlForwardFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlHalfHermitianToRealInverseFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlInverse1DFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlInverseFFTImageFilter>>();
ObjectFactoryBase::RegisterInternalFactoryOnce<FFTImageFilterFactory<VnlRealToHalfHermitianForwardFFTImageFilter>>();
}

} // end namespace itk
@@ -0,0 +1,3 @@
if(ITK_USE_FFTWF OR ITK_USE_FFTWD)
itk_wrap_simple_class("itk::FFTWFFTImageFilterFactory" POINTER)
endif()
@@ -0,0 +1 @@
itk_wrap_simple_class("itk::VnlFFTImageFilterFactory" POINTER)
3 changes: 3 additions & 0 deletions Modules/IO/TransformHDF5/wrapping/CMakeLists.txt
@@ -0,0 +1,3 @@
itk_wrap_module(ITKIOTransformHDF5)
itk_auto_load_submodules()
itk_end_wrap_module()
12 changes: 12 additions & 0 deletions Modules/IO/TransformHDF5/wrapping/itkHDF5TransformIO.wrap
@@ -0,0 +1,12 @@
UNIQUE(types "D;${WRAP_ITK_REAL}")

set(WRAPPER_AUTO_INCLUDE_HEADERS OFF)
itk_wrap_include("itkHDF5TransformIO.h")
itk_wrap_class("itk::HDF5TransformIOTemplate" POINTER)
foreach(t ${types})
itk_wrap_template("${ITKM_${t}}" "${ITKT_${t}}")
endforeach()
itk_end_wrap_class()
set(WRAPPER_AUTO_INCLUDE_HEADERS ON)

itk_wrap_simple_class("itk::HDF5TransformIOFactory" POINTER)
3 changes: 3 additions & 0 deletions Modules/IO/TransformInsightLegacy/wrapping/CMakeLists.txt
@@ -0,0 +1,3 @@
itk_wrap_module(ITKIOTransformInsightLegacy)
itk_auto_load_submodules()
itk_end_wrap_module()
12 changes: 12 additions & 0 deletions Modules/IO/TransformInsightLegacy/wrapping/itkTxtTransformIO.wrap
@@ -0,0 +1,12 @@
UNIQUE(types "D;${WRAP_ITK_REAL}")

set(WRAPPER_AUTO_INCLUDE_HEADERS OFF)
itk_wrap_include("itkTxtTransformIO.h")
itk_wrap_class("itk::TxtTransformIOTemplate" POINTER)
foreach(t ${types})
itk_wrap_template("${ITKM_${t}}" "${ITKT_${t}}")
endforeach()
itk_end_wrap_class()
set(WRAPPER_AUTO_INCLUDE_HEADERS ON)

itk_wrap_simple_class("itk::TxtTransformIOFactory" POINTER)
3 changes: 3 additions & 0 deletions Modules/IO/TransformMINC/wrapping/CMakeLists.txt
@@ -0,0 +1,3 @@
itk_wrap_module(ITKIOTransformMINC)
itk_auto_load_submodules()
itk_end_wrap_module()

0 comments on commit a8cd38a

Please sign in to comment.