/*========================================================================= * * 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 * * https://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 itkMeasurementVectorTraits_h #define itkMeasurementVectorTraits_h #include "itkVariableLengthVector.h" #include "vnl/vnl_vector_fixed.h" #include "itkRGBPixel.h" #include "itkMatrix.h" #include "itkVariableSizeMatrix.h" #include "itkNumericTraits.h" #include "itkNumericTraitsStdVector.h" #include "itkSize.h" #include namespace itk { namespace Statistics { /** \class MeasurementVectorTraits * \brief * \ingroup Statistics * \ingroup ITKStatistics */ class MeasurementVectorTraits { public: /** In the old framework, the FrequencyType is set to float. The problem is for large histograms the total frequency can be more than 1e+7, than increasing the frequency by one does not change the total frequency (because of lack of precision). Using double type will also ultimately fall into the same problem. Hence in the new statistics framework, InstanceIdentifier/FrequencyTypes are set to the largest possible integer on the machine */ using InstanceIdentifier = IdentifierType; /** Type defined for representing the frequency of measurement vectors */ using AbsoluteFrequencyType = InstanceIdentifier; using RelativeFrequencyType = NumericTraits::RealType; using TotalAbsoluteFrequencyType = NumericTraits::AccumulateType; using TotalRelativeFrequencyType = NumericTraits::AccumulateType; using MeasurementVectorLength = size_t; template static bool IsResizable(const TVectorType &) { // Test whether the vector type is resizable or not // // If the default constructor creates a vector of // length zero, we assume that it is resizable, // otherwise that is a pretty useless measurement vector. MeasurementVectorLength len = NumericTraits::GetLength({}); return (len == 0); } template static MeasurementVectorLength Assert(const FixedArray &, const FixedArray &, const char * errMsg = "Length Mismatch") { if (VLength != VLength2) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const FixedArray *, const FixedArray *, const char * errMsg = "Length Mismatch") { if (VLength != VLength2) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const Array & a, const Array & b, const char * errMsg = "Length Mismatch") { if (b.Size() != a.Size()) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const Array * a, const Array * b, const char * errMsg = "Length Mismatch") { if (b->Size() != a->Size()) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const VariableLengthVector & a, const VariableLengthVector & b, const char * errMsg = "Length Mismatch") { if (b.Size() != a.Size()) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const VariableLengthVector * a, const VariableLengthVector * b, const char * errMsg = "Length Mismatch") { if (b->Size() != a->Size()) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const std::vector & a, const std::vector & b, const char * errMsg = "Length Mismatch") { if (b.size() != a.size()) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const std::vector * a, const std::vector * b, const char * errMsg = "Length Mismatch") { if (b->size() != a->size()) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const FixedArray &, const Array & b, const char * errMsg = "Length Mismatch") { if (b.Size() == 0) { return VLength; } if (b.Size() != 0) { if (b.Size() != VLength) { itkGenericExceptionMacro(<< errMsg); } } return 0; } template static MeasurementVectorLength Assert(const FixedArray *, const Array * b, const char * errMsg = "Length Mismatch") { if (b->Size() == 0) { return VLength; } else if (b->Size() != VLength) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const FixedArray &, const VariableLengthVector & b, const char * errMsg = "Length Mismatch") { if (b.Size() == 0) { return VLength; } if (b.Size() != 0) { if (b.Size() != VLength) { itkGenericExceptionMacro(<< errMsg); } } return 0; } template static MeasurementVectorLength Assert(const FixedArray *, const VariableLengthVector * b, const char * errMsg = "Length Mismatch") { if (b->Size() == 0) { return VLength; } else if (b->Size() != VLength) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const FixedArray &, const std::vector & b, const char * errMsg = "Length Mismatch") { if (b.empty()) { return VLength; } if (!b.empty()) { if (b.size() != VLength) { itkGenericExceptionMacro(<< errMsg); } } return 0; } template static MeasurementVectorLength Assert(const FixedArray *, const std::vector * b, const char * errMsg = "Length Mismatch") { if (b->size() == 0) { return VLength; } else if (b->size() != VLength) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const FixedArray &, const MeasurementVectorLength l, const char * errMsg = "Length Mismatch") { if (l == 0) { return VLength; } else if (l != VLength) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const FixedArray *, const MeasurementVectorLength l, const char * errMsg = "Length Mismatch") { if (l == 0) { return VLength; } else if (l != VLength) { itkGenericExceptionMacro(<< errMsg); } return 0; } template static MeasurementVectorLength Assert(const Array & a, const MeasurementVectorLength l, const char * errMsg = "Length Mismatch") { if (((l != 0) && (a.Size() != l)) || (a.Size() == 0)) { itkGenericExceptionMacro(<< errMsg); } else if (l == 0) { return a.Size(); } return 0; } template static MeasurementVectorLength Assert(const Array * a, const MeasurementVectorLength l, const char * errMsg = "Length Mismatch") { if (((l != 0) && (a->Size() != l)) || (a->Size() == 0)) { itkGenericExceptionMacro(<< errMsg); } else if (l == 0) { return a->Size(); } return 0; } template static MeasurementVectorLength Assert(const VariableLengthVector & a, const MeasurementVectorLength l, const char * errMsg = "Length Mismatch") { if (((l != 0) && (a.Size() != l)) || (a.Size() == 0)) { itkGenericExceptionMacro(<< errMsg); } else if (l == 0) { return a.Size(); } return 0; } template static MeasurementVectorLength Assert(const VariableLengthVector * a, const MeasurementVectorLength l, const char * errMsg = "Length Mismatch") { if (((l != 0) && (a->Size() != l)) || (a->Size() == 0)) { itkGenericExceptionMacro(<< errMsg); } else if (l == 0) { return a->Size(); } return 0; } template static MeasurementVectorLength Assert(const std::vector & a, const MeasurementVectorLength l, const char * errMsg = "Length Mismatch") { if (((l != 0) && (a.size() != l)) || (a.empty())) { itkGenericExceptionMacro(<< errMsg); } else if (l == 0) { return static_cast(a.size()); } return 0; } template static MeasurementVectorLength Assert(const std::vector * a, const MeasurementVectorLength l, const char * errMsg = "Length Mismatch") { if (((l != 0) && (a->size() != l)) || (a->size() == 0)) { itkGenericExceptionMacro(<< errMsg); } else if (l == 0) { return a->size(); } return 0; } template static void Assign(TArrayType & m, const TArrayType & v) { m = v; } template static void Assign(FixedArray & m, const TValue & v) { m[0] = v; } }; /** \class MeasurementVectorTraitsTypes * \brief * \ingroup Statistics * \ingroup ITKStatistics */ template class MeasurementVectorTraitsTypes { public: using ValueType = typename TMeasurementVector::ValueType; }; template class MeasurementVectorTraitsTypes> { public: using ValueType = T; }; /** Traits for generating the MeasurementVectorType that best matches a * particular pixel type. */ template class MeasurementVectorPixelTraits { public: /* type of the vector that matches this pixel type */ using MeasurementVectorType = TPixelType; }; /// \cond HIDE_SPECIALIZATION_DOCUMENTATION /** * \class MeasurementVectorPixelTraits * \ingroup ITKStatistics */ template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; template <> class MeasurementVectorPixelTraits { public: using MeasurementVectorType = FixedArray; }; /// \endcond } // namespace Statistics } // namespace itk #endif // itkMeasurementVectorTraits_h