18#ifndef itkStackTransform_h
19#define itkStackTransform_h
39template <
class TScalarType,
unsigned int NInputDimensions,
unsigned int NOutputDimensions>
61 using typename Superclass::ScalarType;
62 using typename Superclass::ParametersType;
63 using typename Superclass::FixedParametersType;
64 using typename Superclass::NumberOfParametersType;
65 using typename Superclass::ParametersValueType;
66 using typename Superclass::JacobianType;
72 using typename Superclass::InputPointType;
73 using typename Superclass::InputVectorType;
74 using typename Superclass::OutputVectorType;
75 using typename Superclass::InputVnlVectorType;
76 using typename Superclass::OutputVnlVectorType;
77 using typename Superclass::OutputCovariantVectorType;
78 using typename Superclass::InputCovariantVectorType;
79 using typename Superclass::OutputPointType;
80 using typename Superclass::OutputVectorPixelType;
81 using typename Superclass::InputVectorPixelType;
115 const ParametersType &
122 const auto numberOfFixedParameters = fixedParameters.size();
123 if (numberOfFixedParameters < NumberOfGeneralFixedParametersOfStack)
125 itkExceptionMacro(
"The number of FixedParameters (" << numberOfFixedParameters <<
") should be at least "
126 << NumberOfGeneralFixedParametersOfStack);
129 if (Superclass::m_FixedParameters != fixedParameters)
131 Superclass::m_FixedParameters = fixedParameters;
133 CreateSubTransforms(FixedParametersType(fixedParameters.data_block() + NumberOfGeneralFixedParametersOfStack,
134 numberOfFixedParameters - NumberOfGeneralFixedParametersOfStack));
135 UpdateStackSpacingAndOrigin();
142 NumberOfParametersType
145 if (this->m_SubTransformContainer.empty())
151 return this->m_SubTransformContainer.size() * m_SubTransformContainer[0]->GetNumberOfParameters();
160 if (this->m_SubTransformContainer.size() != num)
162 this->m_SubTransformContainer.clear();
163 this->m_SubTransformContainer.resize(num);
172 return static_cast<unsigned>(m_SubTransformContainer.size());
186 this->m_SubTransformContainer[i] = transform;
197 m_SubTransformContainer.empty() ? nullptr : m_SubTransformContainer.front();
198 this->UpdateFixedParametersInternally((subTransform ==
nullptr) ? FixedParametersType()
199 : subTransform->GetFixedParameters());
207 const auto & fixedParametersOfSubTransform = transform.GetFixedParameters();
208 const auto & parametersOfSubTransform = transform.GetParameters();
210 UpdateFixedParametersInternally(fixedParametersOfSubTransform);
212 for (
auto & subTransform : m_SubTransformContainer)
216 transformcopy->SetFixedParameters(fixedParametersOfSubTransform);
217 transformcopy->SetParameters(parametersOfSubTransform);
219 subTransform = transformcopy;
228 return this->m_SubTransformContainer[i];
233 NumberOfParametersType
246 NumberOfGeneralFixedParametersOfStack
252 assert(Superclass::m_FixedParameters.size() >= NumberOfGeneralFixedParametersOfStack);
253 const auto numberOfSubTransforms = Superclass::m_FixedParameters[IndexOfNumberOfSubTransforms];
255 if (numberOfSubTransforms >= 0.0 && numberOfSubTransforms <= UINT_MAX &&
256 static_cast<double>(
static_cast<unsigned>(numberOfSubTransforms)) == numberOfSubTransforms)
258 m_SubTransformContainer.resize(
static_cast<unsigned>(numberOfSubTransforms));
262 itkExceptionMacro(
"The FixedParameters element (" << numberOfSubTransforms
263 <<
") should be a valid number (the number of subtransforms).");
266 for (
auto & subTransform : m_SubTransformContainer)
268 subTransform = this->CreateSubTransform();
269 subTransform->SetFixedParameters(fixedParametersOfSubTransform);
276 assert(Superclass::m_FixedParameters.size() >= NumberOfGeneralFixedParametersOfStack);
277 m_StackSpacing = Superclass::m_FixedParameters[IndexOfStackSpacing];
278 m_StackOrigin = Superclass::m_FixedParameters[IndexOfStackOrigin];
287 const auto numberOfFixedParametersOfSubTransform = fixedParametersOfSubTransform.size();
289 FixedParametersType & fixedParametersOfStack = this->Superclass::m_FixedParameters;
291 const auto minimumNumberOfFixedParametersOfStack =
292 NumberOfGeneralFixedParametersOfStack + numberOfFixedParametersOfSubTransform;
294 if (fixedParametersOfStack.size() < minimumNumberOfFixedParametersOfStack)
296 fixedParametersOfStack.set_size(minimumNumberOfFixedParametersOfStack);
298 fixedParametersOfStack[IndexOfNumberOfSubTransforms] = m_SubTransformContainer.size();
299 fixedParametersOfStack[IndexOfStackOrigin] = m_StackOrigin;
300 fixedParametersOfStack[IndexOfStackSpacing] = m_StackSpacing;
301 std::copy_n(fixedParametersOfSubTransform.begin(),
302 numberOfFixedParametersOfSubTransform,
303 fixedParametersOfStack.begin() + NumberOfGeneralFixedParametersOfStack);
308 using Superclass::TransformCovariantVector;
309 using Superclass::TransformVector;
314 virtual SubTransformPointer
318 static constexpr const char * unimplementedOverrideMessage =
"Not implemented for StackTransform";
324 itkExceptionMacro(<< unimplementedOverrideMessage);
330 itkExceptionMacro(<< unimplementedOverrideMessage);
333 OutputCovariantVectorType
336 itkExceptionMacro(<< unimplementedOverrideMessage);
344 itkExceptionMacro(<< unimplementedOverrideMessage);
350 itkExceptionMacro(<< unimplementedOverrideMessage);
358 itkExceptionMacro(<< unimplementedOverrideMessage);
367 itkExceptionMacro(<< unimplementedOverrideMessage);
375 itkExceptionMacro(<< unimplementedOverrideMessage);
385 itkExceptionMacro(<< unimplementedOverrideMessage);
390 std::vector<SubTransformPointer> m_SubTransformContainer{};
399#ifndef ITK_MANUAL_INSTANTIATION
400# include "itkStackTransform.hxx"