Skip to content

Commit

Permalink
ENH: Select Forward1DFFTImageFilter backend with object factory
Browse files Browse the repository at this point in the history
  • Loading branch information
tbirdso committed Nov 4, 2021
1 parent 135a814 commit 67762ee
Show file tree
Hide file tree
Showing 15 changed files with 391 additions and 64 deletions.
18 changes: 16 additions & 2 deletions CMake/UseITK.cmake
Expand Up @@ -168,7 +168,6 @@ link_directories(${ITK_LIBRARY_DIRS})
function(_configure_FactoryRegisterManager factory_type formats)
set(LIST_OF_FACTORIES_REGISTRATION "")
set(LIST_OF_FACTORY_NAMES "")

string(TOLOWER ${factory_type} _qualifier)
foreach (format ${formats})
set(_module_name ${${format}_${_qualifier}_module_name})
Expand All @@ -178,6 +177,12 @@ function(_configure_FactoryRegisterManager factory_type formats)
endforeach()

get_filename_component(_selfdir "${CMAKE_CURRENT_LIST_FILE}" PATH)

# Special case: FFT::<format> inputs are for "<format>FFTImageFilter" classes
if(factory_type STREQUAL "FFT")
set(factory_type "FFTImageFilter")
endif()

configure_file(${_selfdir}/itk${factory_type}FactoryRegisterManager.h.in
"${CMAKE_CURRENT_BINARY_DIR}/ITKFactoryRegistration/itk${factory_type}FactoryRegisterManager.h" @ONLY)

Expand All @@ -194,6 +199,12 @@ macro(ADD_FACTORY_REGISTRATION _registration_list_var _names_list_var _module_na
if(${_module_name}_ENABLE_SHARED AND ITK_BUILD_SHARED)
set(_abi "ITK_ABI_IMPORT")
endif()

# Special case: FFT::<format> inputs are for "<format>FFTImageFilter" classes
if(_factory_name STREQUAL "FFT")
set(_factory_name "FFTImageFilter")
endif()

set(${_registration_list_var}
"${${_registration_list_var}}void ${_abi} ${_factory_name}FactoryRegister__Private();")
set(${_names_list_var} "${${_names_list_var}}${_factory_name}FactoryRegister__Private,")
Expand Down Expand Up @@ -228,8 +239,11 @@ foreach(_factory_name ${ITK_FACTORY_LIST})
endforeach()
#-----------------------------------------------------------------------------
if(NOT ITK_NO_IO_FACTORY_REGISTER_MANAGER)

set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS ITK_IO_FACTORY_REGISTER_MANAGER)
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/ITKFactoryRegistration)
endif()

if(NOT ITK_NO_FFT_FACTORY_REGISTER_MANAGER)
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS ITK_FFT_FACTORY_REGISTER_MANAGER)
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/ITKFactoryRegistration)
endif()
56 changes: 56 additions & 0 deletions CMake/itkFFTImageFilterFactoryRegisterManager.h.in
@@ -0,0 +1,56 @@
/*=========================================================================
*
* 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 itkFFTImageFilterFactoryRegisterManager_h
#define itkFFTImageFilterFactoryRegisterManager_h

namespace itk {

class FFTImageFilterFactoryRegisterManager
{
public:
explicit FFTImageFilterFactoryRegisterManager(void (* const list[])(void))
{
for(;*list != nullptr; ++list)
{
(*list)();
}
}
};


//
// The following code is intended to be expanded at the end of the
// itkTransformFileReader.h and itkTransformFileWriter.h files.
//
@LIST_OF_FACTORIES_REGISTRATION@

//
// The code below registers available IO helpers using static initialization in
// application translation units. Note that this code will be expanded in the
// ITK-based applications and not in ITK itself.
//

void (* const FFTImageFilterFactoryRegisterRegisterList[])(void) = {
@LIST_OF_FACTORY_NAMES@
nullptr};
const FFTImageFilterFactoryRegisterManager FFTImageFilterFactoryRegisterManagerInstance(FFTImageFilterFactoryRegisterRegisterList);

}

#endif
1 change: 1 addition & 0 deletions CMakeLists.txt
Expand Up @@ -566,6 +566,7 @@ install(FILES ${ITK_BINARY_DIR}/CMakeFiles/ITKConfig.cmake
${ITK_BINARY_DIR}/ITKConfigVersion.cmake
CMake/ITKModuleAPI.cmake
CMake/UseITK.cmake
CMake/itkFFTImageFilterFactoryRegisterManager.h.in
CMake/itkImageIOFactoryRegisterManager.h.in
CMake/itkTransformIOFactoryRegisterManager.h.in
CMake/itkMeshIOFactoryRegisterManager.h.in
Expand Down
3 changes: 2 additions & 1 deletion Modules/Filtering/FFT/CMakeLists.txt
Expand Up @@ -6,5 +6,6 @@ else()
set(ITKFFT_LIBRARIES ITKFFT)
endif()
set(ITKFFT_SYSTEM_LIBRARY_DIRS ${FFTW_LIBDIR})
set(ITKFFT_INCLUDE_DIRS ${FFTW_INCLUDE})
set(ITKFFT_INCLUDE_DIRS "${FFTW_INCLUDE}")

itk_module_impl()
79 changes: 78 additions & 1 deletion Modules/Filtering/FFT/include/itkFFTWForward1DFFTImageFilter.h
Expand Up @@ -21,6 +21,7 @@
#include "itkForward1DFFTImageFilter.h"
#include "itkFFTWCommonExtended.h"
#include "itkImageRegionSplitterDirection.h"
#include "itkVersion.h"

#include <vector>

Expand All @@ -31,7 +32,8 @@ namespace itk
/** \class FFTWForward1DFFTImageFilter
* \brief only do FFT along one dimension using FFTW as a backend.
*
* \ingroup Ultrasound
* \ingroup FourierTransform
* \ingroup ITKFFT
*/
template <typename TInputImage,
typename TOutputImage = Image<std::complex<typename TInputImage::PixelType>, TInputImage::ImageDimension>>
Expand Down Expand Up @@ -97,6 +99,81 @@ class ITK_TEMPLATE_EXPORT FFTWForward1DFFTImageFilter : public Forward1DFFTImage
PlanBufferPointerType m_OutputBufferArray;
};


/** \class FFTWForward1DFFTImageFilterFactory
*
* \brief Object Factory implementation for FFTWForward1DFFTImageFilter
*
* \ingroup FourierTransform
* \ingroup ITKFFT
*/
class FFTWForward1DFFTImageFilterFactory : public itk::ObjectFactoryBase
{
public:
ITK_DISALLOW_COPY_AND_MOVE(FFTWForward1DFFTImageFilterFactory);

using Self = FFTWForward1DFFTImageFilterFactory;
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
{
return ITK_SOURCE_VERSION;
}
const char *
GetDescription() const override
{
return "A Factory for FFTWForward1DFFTImageFilterFactory";
}

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

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

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

ObjectFactoryBase::RegisterFactory(factory);
}

private:
template <typename InputPixelType, typename OutputPixelType, size_t ImageDimension>
void
OverrideFFTWForward1DFFTImageFilterTypeMacro()
{
using InputImageType = Image<InputPixelType, ImageDimension>;
using OutputImageType = Image<std::complex<OutputPixelType>, ImageDimension>;
this->RegisterOverride(typeid(Forward1DFFTImageFilter<InputImageType, OutputImageType>).name(),
typeid(FFTWForward1DFFTImageFilter<InputImageType, OutputImageType>).name(),
"FFTW Forward 1D FFT Image Filter Override",
true,
CreateObjectFunction<FFTWForward1DFFTImageFilter<InputImageType, OutputImageType>>::New());
}

FFTWForward1DFFTImageFilterFactory()
{
#ifdef ITK_USE_FFTWF
OverrideFFTWForward1DFFTImageFilterTypeMacro<float, float, 1>();
OverrideFFTWForward1DFFTImageFilterTypeMacro<float, float, 2>();
OverrideFFTWForward1DFFTImageFilterTypeMacro<float, float, 3>();
#endif // ITK_USE_FFTWF

#ifdef ITK_USE_FFTWD
OverrideFFTWForward1DFFTImageFilterTypeMacro<double, double, 1>();
OverrideFFTWForward1DFFTImageFilterTypeMacro<double, double, 2>();
OverrideFFTWForward1DFFTImageFilterTypeMacro<double, double, 3>();
#endif // ITK_USE_FFTWD
}
};

} // namespace itk

#ifndef ITK_MANUAL_INSTANTIATION
Expand Down
11 changes: 11 additions & 0 deletions Modules/Filtering/FFT/include/itkForward1DFFTImageFilter.h
Expand Up @@ -28,6 +28,13 @@ namespace itk
* \brief Perform the Fast Fourier Transform, in the forward direction, with
* real inputs, but only along one dimension.
*
* Forward1DFFTImageFilter implements methods for generating output information
* and relies on the ITK object factory to select a viable backend to generate data.
* Forward1DFFTImageFilter does not itself implement FFT.
*
* \sa itkVnlForward1DFFTImageFilter
* \sa itkFFTWForward1DFFTImageFilter
*
* \ingroup FourierTransform
* \ingroup Ultrasound
*/
Expand Down Expand Up @@ -105,4 +112,8 @@ class ITK_TEMPLATE_EXPORT Forward1DFFTImageFilter : public ImageToImageFilter<TI
# endif
#endif

#ifdef ITK_FFT_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterFactoryRegisterManager.h"
#endif

#endif // itkForward1DFFTImageFilter_h
46 changes: 1 addition & 45 deletions Modules/Filtering/FFT/include/itkForward1DFFTImageFilter.hxx
Expand Up @@ -33,59 +33,15 @@ namespace itk
template <typename TInputImage, typename TOutputImage>
class VnlForward1DFFTImageFilter;

template <typename TSelfPointer, typename TInputImage, typename TOutputImage, typename TPixel>
struct Dispatch_1DRealToComplexConjugate_New
{
static TSelfPointer
Apply()
{
return VnlForward1DFFTImageFilter<TInputImage, TOutputImage>::New().GetPointer();
}
};

#ifdef ITK_USE_FFTWD
template <typename TSelfPointer, typename TInputImage, typename TOutputImage>
struct Dispatch_1DRealToComplexConjugate_New<TSelfPointer, TInputImage, TOutputImage, double>
{
static TSelfPointer
Apply()
{
return FFTWForward1DFFTImageFilter<TInputImage, TOutputImage>::New().GetPointer();
}
};
#endif // ITK_USE_FFTWD

#ifdef ITK_USE_FFTWF
template <typename TSelfPointer, typename TInputImage, typename TOutputImage>
struct Dispatch_1DRealToComplexConjugate_New<TSelfPointer, TInputImage, TOutputImage, float>
{
static TSelfPointer
Apply()
{
return FFTWForward1DFFTImageFilter<TInputImage, TOutputImage>::New().GetPointer();
}
};
#endif // ITK_USE_FFTWF

template <typename TInputImage, typename TOutputImage>
typename Forward1DFFTImageFilter<TInputImage, TOutputImage>::Pointer
Forward1DFFTImageFilter<TInputImage, TOutputImage>::New()
{
Pointer smartPtr = ObjectFactory<Self>::Create();

if (smartPtr.IsNull())
{
smartPtr = Dispatch_1DRealToComplexConjugate_New<
Pointer,
TInputImage,
TOutputImage,
typename NumericTraits<typename TOutputImage::PixelType>::ValueType>::Apply();
}
else
if (smartPtr.IsNotNull())
{
smartPtr->UnRegister();
}

return smartPtr;
}

Expand Down
72 changes: 72 additions & 0 deletions Modules/Filtering/FFT/include/itkVnlForward1DFFTImageFilter.h
Expand Up @@ -20,6 +20,7 @@

#include "itkForward1DFFTImageFilter.h"
#include <complex>
#include "itkVersion.h"

namespace itk
{
Expand Down Expand Up @@ -64,6 +65,77 @@ class ITK_TEMPLATE_EXPORT VnlForward1DFFTImageFilter : public Forward1DFFTImageF
private:
};


/** \class VnlForward1DFFTImageFilterFactory
*
* \brief Object Factory implementation for VnlForward1DFFTImageFilter
*
* \ingroup FourierTransform
* \ingroup ITKFFT
*/
class VnlForward1DFFTImageFilterFactory : public itk::ObjectFactoryBase
{
public:
ITK_DISALLOW_COPY_AND_MOVE(VnlForward1DFFTImageFilterFactory);

using Self = VnlForward1DFFTImageFilterFactory;
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
{
return ITK_SOURCE_VERSION;
}
const char *
GetDescription() const override
{
return "A Factory for VnlForward1DFFTImageFilterFactory";
}

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

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

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

ObjectFactoryBase::RegisterFactoryInternal(factory);
}

private:
template <typename InputPixelType, typename OutputPixelType, size_t ImageDimension>
void
OverrideVnlForward1DFFTImageFilterTypeMacro()
{
using InputImageType = Image<InputPixelType, ImageDimension>;
using OutputImageType = Image<std::complex<OutputPixelType>, ImageDimension>;
this->RegisterOverride(typeid(Forward1DFFTImageFilter<InputImageType, OutputImageType>).name(),
typeid(VnlForward1DFFTImageFilter<InputImageType, OutputImageType>).name(),
"Vnl Forward 1D FFT Image Filter Override",
true,
CreateObjectFunction<VnlForward1DFFTImageFilter<InputImageType, OutputImageType>>::New());
}

VnlForward1DFFTImageFilterFactory()
{
OverrideVnlForward1DFFTImageFilterTypeMacro<float, float, 1>();
OverrideVnlForward1DFFTImageFilterTypeMacro<float, float, 2>();
OverrideVnlForward1DFFTImageFilterTypeMacro<float, float, 3>();

OverrideVnlForward1DFFTImageFilterTypeMacro<double, double, 1>();
OverrideVnlForward1DFFTImageFilterTypeMacro<double, double, 2>();
OverrideVnlForward1DFFTImageFilterTypeMacro<double, double, 3>();
}
};

} // end namespace itk

#ifndef ITK_MANUAL_INSTANTIATION
Expand Down

0 comments on commit 67762ee

Please sign in to comment.