Skip to content

Commit

Permalink
ENH: Split SetInput functions in two-steps spectral filters
Browse files Browse the repository at this point in the history
Separate SetInputDecomposedProjections and SetInputMeasuredProjections
into two parts, based on their input type (either itk::VectorImage, the
default input type, or itk::Image<itk::Vector<>>, the newly supported type)
as requested in RTKConsortium#688 (comment)
Add a warning when SetInputDecomposedProjections or SetInputMeasuredProjections
fails to cast the input to one of the supported types, as requested in
RTKConsortium#688 (comment)
  • Loading branch information
cyrilmory committed Feb 27, 2025
1 parent 8a759ea commit 8af69d8
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 152 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ class ITK_TEMPLATE_EXPORT SimplexSpectralProjectionsDecompositionImageFilter

/** Set/Get the input material-decomposed stack of projections (only used for initialization) */
void
SetInputDecomposedProjections(const DecomposedProjectionsType * DecomposedProjections);
void
SetInputDecomposedProjections(
const typename itk::ImageBase<DecomposedProjectionsType::ImageDimension> * DecomposedProjections);
template <unsigned int VNumberOfMaterials>
Expand All @@ -97,6 +99,8 @@ class ITK_TEMPLATE_EXPORT SimplexSpectralProjectionsDecompositionImageFilter

/** Set/Get the input stack of measured projections (to be decomposed in materials) */
void
SetInputMeasuredProjections(const MeasuredProjectionsType * MeasuredProjections);
void
SetInputMeasuredProjections(
const typename itk::ImageBase<MeasuredProjectionsType::ImageDimension> * MeasuredProjections);
template <unsigned int VNumberOfSpectralBins>
Expand Down
174 changes: 98 additions & 76 deletions include/rtkSimplexSpectralProjectionsDecompositionImageFilter.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,22 @@ SimplexSpectralProjectionsDecompositionImageFilter<
#endif
}

template <typename DecomposedProjectionsType,
typename MeasuredProjectionsType,
typename IncidentSpectrumImageType,
typename DetectorResponseImageType,
typename MaterialAttenuationsImageType>
void
SimplexSpectralProjectionsDecompositionImageFilter<
DecomposedProjectionsType,
MeasuredProjectionsType,
IncidentSpectrumImageType,
DetectorResponseImageType,
MaterialAttenuationsImageType>::SetInputDecomposedProjections(const DecomposedProjectionsType * DecomposedProjections)
{
this->SetNthInput(0, const_cast<DecomposedProjectionsType *>(DecomposedProjections));
}

template <typename DecomposedProjectionsType,
typename MeasuredProjectionsType,
typename IncidentSpectrumImageType,
Expand All @@ -91,45 +107,40 @@ SimplexSpectralProjectionsDecompositionImageFilter<DecomposedProjectionsType,
const typename itk::ImageBase<DecomposedProjectionsType::ImageDimension> * DecomposedProjections)
{
// Attempt to dynamic_cast DecomposedProjections into one of the supported types
const DecomposedProjectionsType * ptr = dynamic_cast<const DecomposedProjectionsType *>(DecomposedProjections);
if (ptr)
typedef itk::Image<itk::Vector<DecomposedProjectionsDataType, 1>, DecomposedProjectionsType::ImageDimension> Type1;
typedef itk::Image<itk::Vector<DecomposedProjectionsDataType, 2>, DecomposedProjectionsType::ImageDimension> Type2;
typedef itk::Image<itk::Vector<DecomposedProjectionsDataType, 3>, DecomposedProjectionsType::ImageDimension> Type3;
typedef itk::Image<itk::Vector<DecomposedProjectionsDataType, 4>, DecomposedProjectionsType::ImageDimension> Type4;
typedef itk::Image<itk::Vector<DecomposedProjectionsDataType, 5>, DecomposedProjectionsType::ImageDimension> Type5;
const Type1 * ptr1 = dynamic_cast<const Type1 *>(DecomposedProjections);
const Type2 * ptr2 = dynamic_cast<const Type2 *>(DecomposedProjections);
const Type3 * ptr3 = dynamic_cast<const Type3 *>(DecomposedProjections);
const Type4 * ptr4 = dynamic_cast<const Type4 *>(DecomposedProjections);
const Type5 * ptr5 = dynamic_cast<const Type5 *>(DecomposedProjections);

if (ptr1)
{
this->SetInputFixedVectorLengthDecomposedProjections<1>(ptr1);
}
else if (ptr2)
{
this->SetInputFixedVectorLengthDecomposedProjections<2>(ptr2);
}
else if (ptr3)
{
this->SetInputFixedVectorLengthDecomposedProjections<3>(ptr3);
}
else if (ptr4)
{
this->SetInputFixedVectorLengthDecomposedProjections<4>(ptr4);
}
else if (ptr5)
{
this->SetNthInput(0, const_cast<DecomposedProjectionsType *>(ptr));
this->SetInputFixedVectorLengthDecomposedProjections<5>(ptr5);
}
else
{
// Perform all possible dynamic_casts
typedef itk::Image<itk::Vector<DecomposedProjectionsDataType, 1>, DecomposedProjectionsType::ImageDimension> Type1;
typedef itk::Image<itk::Vector<DecomposedProjectionsDataType, 2>, DecomposedProjectionsType::ImageDimension> Type2;
typedef itk::Image<itk::Vector<DecomposedProjectionsDataType, 3>, DecomposedProjectionsType::ImageDimension> Type3;
typedef itk::Image<itk::Vector<DecomposedProjectionsDataType, 4>, DecomposedProjectionsType::ImageDimension> Type4;
typedef itk::Image<itk::Vector<DecomposedProjectionsDataType, 5>, DecomposedProjectionsType::ImageDimension> Type5;
const Type1 * ptr1 = dynamic_cast<const Type1 *>(DecomposedProjections);
const Type2 * ptr2 = dynamic_cast<const Type2 *>(DecomposedProjections);
const Type3 * ptr3 = dynamic_cast<const Type3 *>(DecomposedProjections);
const Type4 * ptr4 = dynamic_cast<const Type4 *>(DecomposedProjections);
const Type5 * ptr5 = dynamic_cast<const Type5 *>(DecomposedProjections);

if (ptr1)
{
this->SetInputFixedVectorLengthDecomposedProjections<1>(ptr1);
}
else if (ptr2)
{
this->SetInputFixedVectorLengthDecomposedProjections<2>(ptr2);
}
else if (ptr3)
{
this->SetInputFixedVectorLengthDecomposedProjections<3>(ptr3);
}
else if (ptr4)
{
this->SetInputFixedVectorLengthDecomposedProjections<4>(ptr4);
}
else if (ptr5)
{
this->SetInputFixedVectorLengthDecomposedProjections<5>(ptr5);
}
itkWarningMacro("The input does not match any of the supported types, and has been ignored");
}
}

Expand Down Expand Up @@ -158,6 +169,22 @@ SimplexSpectralProjectionsDecompositionImageFilter<DecomposedProjectionsType,
this->SetNthInput(0, const_cast<DecomposedProjectionsType *>(castPointer->GetOutput()));
}

template <typename DecomposedProjectionsType,
typename MeasuredProjectionsType,
typename IncidentSpectrumImageType,
typename DetectorResponseImageType,
typename MaterialAttenuationsImageType>
void
SimplexSpectralProjectionsDecompositionImageFilter<
DecomposedProjectionsType,
MeasuredProjectionsType,
IncidentSpectrumImageType,
DetectorResponseImageType,
MaterialAttenuationsImageType>::SetInputMeasuredProjections(const MeasuredProjectionsType * MeasuredProjections)
{
this->SetInput("MeasuredProjections", const_cast<MeasuredProjectionsType *>(MeasuredProjections));
}

template <typename DecomposedProjectionsType,
typename MeasuredProjectionsType,
typename IncidentSpectrumImageType,
Expand All @@ -173,51 +200,46 @@ SimplexSpectralProjectionsDecompositionImageFilter<DecomposedProjectionsType,
const typename itk::ImageBase<MeasuredProjectionsType::ImageDimension> * MeasuredProjections)
{
// Attempt to dynamic_cast MeasuredProjections into one of the supported types
const MeasuredProjectionsType * ptr = dynamic_cast<const MeasuredProjectionsType *>(MeasuredProjections);
if (ptr)
typedef itk::Image<itk::Vector<MeasuredProjectionsDataType, 1>, MeasuredProjectionsType::ImageDimension> Type1;
typedef itk::Image<itk::Vector<MeasuredProjectionsDataType, 2>, MeasuredProjectionsType::ImageDimension> Type2;
typedef itk::Image<itk::Vector<MeasuredProjectionsDataType, 3>, MeasuredProjectionsType::ImageDimension> Type3;
typedef itk::Image<itk::Vector<MeasuredProjectionsDataType, 4>, MeasuredProjectionsType::ImageDimension> Type4;
typedef itk::Image<itk::Vector<MeasuredProjectionsDataType, 5>, MeasuredProjectionsType::ImageDimension> Type5;
typedef itk::Image<itk::Vector<MeasuredProjectionsDataType, 6>, MeasuredProjectionsType::ImageDimension> Type6;
const Type1 * ptr1 = dynamic_cast<const Type1 *>(MeasuredProjections);
const Type2 * ptr2 = dynamic_cast<const Type2 *>(MeasuredProjections);
const Type3 * ptr3 = dynamic_cast<const Type3 *>(MeasuredProjections);
const Type4 * ptr4 = dynamic_cast<const Type4 *>(MeasuredProjections);
const Type5 * ptr5 = dynamic_cast<const Type5 *>(MeasuredProjections);
const Type6 * ptr6 = dynamic_cast<const Type6 *>(MeasuredProjections);

if (ptr1)
{
this->SetInputFixedVectorLengthMeasuredProjections<1>(ptr1);
}
else if (ptr2)
{
this->SetInputFixedVectorLengthMeasuredProjections<2>(ptr2);
}
else if (ptr3)
{
this->SetInputFixedVectorLengthMeasuredProjections<3>(ptr3);
}
else if (ptr4)
{
this->SetInputFixedVectorLengthMeasuredProjections<4>(ptr4);
}
else if (ptr5)
{
this->SetInputFixedVectorLengthMeasuredProjections<5>(ptr5);
}
else if (ptr6)
{
this->SetInput("MeasuredProjections", const_cast<MeasuredProjectionsType *>(ptr));
this->SetInputFixedVectorLengthMeasuredProjections<6>(ptr6);
}
else
{
// Perform all possible dynamic_casts
typedef itk::Image<itk::Vector<MeasuredProjectionsDataType, 1>, MeasuredProjectionsType::ImageDimension> Type1;
typedef itk::Image<itk::Vector<MeasuredProjectionsDataType, 2>, MeasuredProjectionsType::ImageDimension> Type2;
typedef itk::Image<itk::Vector<MeasuredProjectionsDataType, 3>, MeasuredProjectionsType::ImageDimension> Type3;
typedef itk::Image<itk::Vector<MeasuredProjectionsDataType, 4>, MeasuredProjectionsType::ImageDimension> Type4;
typedef itk::Image<itk::Vector<MeasuredProjectionsDataType, 5>, MeasuredProjectionsType::ImageDimension> Type5;
typedef itk::Image<itk::Vector<MeasuredProjectionsDataType, 6>, MeasuredProjectionsType::ImageDimension> Type6;
const Type1 * ptr1 = dynamic_cast<const Type1 *>(MeasuredProjections);
const Type2 * ptr2 = dynamic_cast<const Type2 *>(MeasuredProjections);
const Type3 * ptr3 = dynamic_cast<const Type3 *>(MeasuredProjections);
const Type4 * ptr4 = dynamic_cast<const Type4 *>(MeasuredProjections);
const Type5 * ptr5 = dynamic_cast<const Type5 *>(MeasuredProjections);
const Type6 * ptr6 = dynamic_cast<const Type6 *>(MeasuredProjections);

if (ptr1)
{
this->SetInputFixedVectorLengthMeasuredProjections<1>(ptr1);
}
else if (ptr2)
{
this->SetInputFixedVectorLengthMeasuredProjections<2>(ptr2);
}
else if (ptr3)
{
this->SetInputFixedVectorLengthMeasuredProjections<3>(ptr3);
}
else if (ptr4)
{
this->SetInputFixedVectorLengthMeasuredProjections<4>(ptr4);
}
else if (ptr5)
{
this->SetInputFixedVectorLengthMeasuredProjections<5>(ptr5);
}
else if (ptr6)
{
this->SetInputFixedVectorLengthMeasuredProjections<6>(ptr6);
}
itkWarningMacro("The input does not match any of the supported types, and has been ignored");
}
}

Expand Down
4 changes: 4 additions & 0 deletions include/rtkSpectralForwardModelImageFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class ITK_TEMPLATE_EXPORT SpectralForwardModelImageFilter

/** Set/Get the input material-decomposed stack of projections (only used for initialization) */
void
SetInputDecomposedProjections(const DecomposedProjectionsType * DecomposedProjections);
void
SetInputDecomposedProjections(
const typename itk::ImageBase<DecomposedProjectionsType::ImageDimension> * DecomposedProjections);
template <unsigned int VNumberOfMaterials>
Expand All @@ -113,6 +115,8 @@ class ITK_TEMPLATE_EXPORT SpectralForwardModelImageFilter

/** Set/Get the input stack of measured projections (to be decomposed in materials) */
void
SetInputMeasuredProjections(const MeasuredProjectionsType * MeasuredProjections);
void
SetInputMeasuredProjections(
const typename itk::ImageBase<MeasuredProjectionsType::ImageDimension> * MeasuredProjections);
template <unsigned int VNumberOfSpectralBins>
Expand Down
Loading

0 comments on commit 8af69d8

Please sign in to comment.