1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkMeasurementVectorTraits_h
19 #define itkMeasurementVectorTraits_h
20 
21 #include "itkVariableLengthVector.h"
22 #include "vnl/vnl_vector_fixed.h"
23 #include "itkRGBPixel.h"
24 #include "itkMatrix.h"
25 #include "itkVariableSizeMatrix.h"
26 #include "itkNumericTraits.h"
27 #include "itkNumericTraitsStdVector.h"
28 #include "itkSize.h"
29 #include <vector>
30 
31 namespace itk
32 {
33 namespace Statistics
34 {
35 /** \class MeasurementVectorTraits
36  * \brief
37  * \ingroup Statistics
38  * \ingroup ITKStatistics
39  */
40 
41 class MeasurementVectorTraits
42 {
43 public:
44 
45   /** In the old framework, the FrequencyType is set to float. The problem is for
46       large histograms the total frequency can be more than 1e+7, than increasing
47       the frequency by one does not change the total frequency (because of lack of
48       precision). Using double type will also ultimately fall into the same problem.
49       Hence in the new statistics framework, InstanceIdentifier/FrequencyTypes are
50       set to the the largest possible integer on the machine */
51   using InstanceIdentifier = IdentifierType;
52 
53   /** Type defined for representing the frequency of measurement vectors */
54   using AbsoluteFrequencyType = InstanceIdentifier;
55   using RelativeFrequencyType = NumericTraits< AbsoluteFrequencyType >::RealType;
56   using TotalAbsoluteFrequencyType = NumericTraits< AbsoluteFrequencyType >::AccumulateType;
57   using TotalRelativeFrequencyType = NumericTraits< RelativeFrequencyType >::AccumulateType;
58 
59   using MeasurementVectorLength = unsigned int;
60 
61   template< typename TVectorType >
IsResizable(const TVectorType &)62   static bool IsResizable(const TVectorType &)
63   {
64     // Test whether the vector type is resizable or not
65     //
66     // If the default constructor creates a vector of
67     // length zero, we assume that it is resizable,
68     // otherwise that is a pretty useless measurement vector.
69     TVectorType             m;
70     MeasurementVectorLength len = NumericTraits<TVectorType>::GetLength(m);
71 
72     return ( len == 0 );
73   }
74 
75   template< typename TValue1, unsigned int VLength, typename TValue2, unsigned int VLength2 >
76   static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > &,
77                                         const FixedArray< TValue2, VLength2 > &,
78                                         const char *errMsg = "Length Mismatch")
79   {
80     if ( VLength != VLength2 )
81       {
82       itkGenericExceptionMacro(<< errMsg);
83       }
84     return 0;
85   }
86 
87   template< typename TValue1, unsigned int VLength, typename TValue2, unsigned int VLength2 >
88   static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > *,
89                                         const FixedArray< TValue2, VLength2 > *,
90                                         const char *errMsg = "Length Mismatch")
91   {
92     if ( VLength != VLength2 )
93       {
94       itkGenericExceptionMacro(<< errMsg);
95       }
96     return 0;
97   }
98 
99   template< typename TValue1, typename TValue2 >
100   static MeasurementVectorLength Assert(const Array< TValue1 > & a,
101                                         const Array< TValue2 > & b, const char *errMsg = "Length Mismatch")
102   {
103     if ( b.Size() != a.Size() )
104       {
105       itkGenericExceptionMacro(<< errMsg);
106       }
107     return 0;
108   }
109 
110   template< typename TValue1, typename TValue2 >
111   static MeasurementVectorLength Assert(const Array< TValue1 > *a,
112                                         const Array< TValue2 > *b, const char *errMsg = "Length Mismatch")
113   {
114     if ( b->Size() != a->Size() )
115       {
116       itkGenericExceptionMacro(<< errMsg);
117       }
118     return 0;
119   }
120 
121   template< typename TValue1, typename TValue2 >
122   static MeasurementVectorLength Assert(const VariableLengthVector< TValue1 > & a,
123                                         const VariableLengthVector< TValue2 > & b,
124                                         const char *errMsg = "Length Mismatch")
125   {
126     if ( b.Size() != a.Size() )
127       {
128       itkGenericExceptionMacro(<< errMsg);
129       }
130     return 0;
131   }
132 
133   template< typename TValue1, typename TValue2 >
134   static MeasurementVectorLength Assert(const VariableLengthVector< TValue1 > *a,
135                                         const VariableLengthVector< TValue2 > *b,
136                                         const char *errMsg = "Length Mismatch")
137   {
138     if ( b->Size() != a->Size() )
139       {
140       itkGenericExceptionMacro(<< errMsg);
141       }
142     return 0;
143   }
144 
145   template< typename TValue1, typename TValue2 >
146   static MeasurementVectorLength Assert(const std::vector< TValue1 > & a,
147                                         const std::vector< TValue2 > & b, const char *errMsg = "Length Mismatch")
148   {
149     if ( b.size() != a.size() )
150       {
151       itkGenericExceptionMacro(<< errMsg);
152       }
153     return 0;
154   }
155 
156   template< typename TValue1, typename TValue2 >
157   static MeasurementVectorLength Assert(const std::vector< TValue1 > *a,
158                                         const std::vector< TValue2 > *b, const char *errMsg = "Length Mismatch")
159   {
160     if ( b->size() != a->size() )
161       {
162       itkGenericExceptionMacro(<< errMsg);
163       }
164     return 0;
165   }
166 
167   template< typename TValue1, unsigned int VLength, typename TValue2 >
168   static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > &,
169                                         const Array< TValue2 > & b, const char *errMsg = "Length Mismatch")
170   {
171     if ( b.Size() == 0 )
172       {
173       return VLength;
174       }
175     if ( b.Size() != 0 )
176       {
177       if ( b.Size() != VLength )
178         {
179         itkGenericExceptionMacro(<< errMsg);
180         }
181       }
182     return 0;
183   }
184 
185   template< typename TValue1, unsigned int VLength, typename TValue2 >
186   static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > *,
187                                         const Array< TValue2 > *b, const char *errMsg = "Length Mismatch")
188   {
189     if ( b->Size() == 0 )
190       {
191       return VLength;
192       }
193     else if ( b->Size() != VLength )
194       {
195       itkGenericExceptionMacro(<< errMsg);
196       }
197     return 0;
198   }
199 
200   template< typename TValue1, unsigned int VLength, typename TValue2 >
201   static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > &,
202                                         const VariableLengthVector< TValue2 > & b,
203                                         const char *errMsg = "Length Mismatch")
204   {
205     if ( b.Size() == 0 )
206       {
207       return VLength;
208       }
209     if ( b.Size() != 0 )
210       {
211       if ( b.Size() != VLength )
212         {
213         itkGenericExceptionMacro(<< errMsg);
214         }
215       }
216     return 0;
217   }
218 
219   template< typename TValue1, unsigned int VLength, typename TValue2 >
220   static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > *,
221                                         const VariableLengthVector< TValue2 > *b,
222                                         const char *errMsg = "Length Mismatch")
223   {
224     if ( b->Size() == 0 )
225       {
226       return VLength;
227       }
228     else if ( b->Size() != VLength )
229       {
230       itkGenericExceptionMacro(<< errMsg);
231       }
232     return 0;
233   }
234 
235   template< typename TValue1, unsigned int VLength, typename TValue2 >
236   static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > &,
237                                         const std::vector< TValue2 > & b, const char *errMsg = "Length Mismatch")
238   {
239     if ( b.empty() )
240       {
241       return VLength;
242       }
243     if ( !b.empty() )
244       {
245       if ( b.size() != VLength )
246         {
247         itkGenericExceptionMacro(<< errMsg);
248         }
249       }
250     return 0;
251   }
252 
253   template< typename TValue1, unsigned int VLength, typename TValue2 >
254   static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > *,
255                                         const std::vector< TValue2 > *b, const char *errMsg = "Length Mismatch")
256   {
257     if ( b->size() == 0 )
258       {
259       return VLength;
260       }
261     else if ( b->size() != VLength )
262       {
263       itkGenericExceptionMacro(<< errMsg);
264       }
265     return 0;
266   }
267 
268   template< typename TValue1, unsigned int VLength >
269   static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > &,
270                                         const MeasurementVectorLength l, const char *errMsg = "Length Mismatch")
271   {
272     if ( l == 0 )
273       {
274       return VLength;
275       }
276     else if ( l != VLength )
277       {
278       itkGenericExceptionMacro(<< errMsg);
279       }
280     return 0;
281   }
282 
283   template< typename TValue1, unsigned int VLength >
284   static MeasurementVectorLength Assert(const FixedArray< TValue1, VLength > *,
285                                         const MeasurementVectorLength l, const char *errMsg = "Length Mismatch")
286   {
287     if ( l == 0 )
288       {
289       return VLength;
290       }
291     else if ( l != VLength )
292       {
293       itkGenericExceptionMacro(<< errMsg);
294       }
295     return 0;
296   }
297 
298   template< typename TValue >
299   static MeasurementVectorLength Assert(const Array< TValue > & a,
300                                         const MeasurementVectorLength l, const char *errMsg = "Length Mismatch")
301   {
302     if ( ( ( l != 0 ) && ( a.Size() != l ) ) || ( a.Size() == 0 ) )
303       {
304       itkGenericExceptionMacro(<< errMsg);
305       }
306     else if ( l == 0 )
307       {
308       return a.Size();
309       }
310     return 0;
311   }
312 
313   template< typename TValue >
314   static MeasurementVectorLength Assert(const Array< TValue > *a,
315                                         const MeasurementVectorLength l, const char *errMsg = "Length Mismatch")
316   {
317     if ( ( ( l != 0 ) && ( a->Size() != l ) ) || ( a->Size() == 0 ) )
318       {
319       itkGenericExceptionMacro(<< errMsg);
320       }
321     else if ( l == 0 )
322       {
323       return a->Size();
324       }
325     return 0;
326   }
327 
328   template< typename TValue >
329   static MeasurementVectorLength Assert(const VariableLengthVector< TValue > & a,
330                                         const MeasurementVectorLength l, const char *errMsg = "Length Mismatch")
331   {
332     if ( ( ( l != 0 ) && ( a.Size() != l ) ) || ( a.Size() == 0 ) )
333       {
334       itkGenericExceptionMacro(<< errMsg);
335       }
336     else if ( l == 0 )
337       {
338       return a.Size();
339       }
340     return 0;
341   }
342 
343   template< typename TValue >
344   static MeasurementVectorLength Assert(const VariableLengthVector< TValue > *a,
345                                         const MeasurementVectorLength l, const char *errMsg = "Length Mismatch")
346   {
347     if ( ( ( l != 0 ) && ( a->Size() != l ) ) || ( a->Size() == 0 ) )
348       {
349       itkGenericExceptionMacro(<< errMsg);
350       }
351     else if ( l == 0 )
352       {
353       return a->Size();
354       }
355     return 0;
356   }
357 
358   template< typename TValue >
359   static MeasurementVectorLength Assert(const std::vector< TValue > & a,
360                                         const MeasurementVectorLength l, const char *errMsg = "Length Mismatch")
361   {
362     if ( ( ( l != 0 ) && ( a.size() != l ) ) || ( a.empty() ) )
363       {
364       itkGenericExceptionMacro(<< errMsg);
365       }
366     else if ( l == 0 )
367       {
368       return static_cast<MeasurementVectorLength>( a.size() );
369       }
370     return 0;
371   }
372 
373   template< typename TValue >
374   static MeasurementVectorLength Assert(const std::vector< TValue > *a,
375                                         const MeasurementVectorLength l, const char *errMsg = "Length Mismatch")
376   {
377     if ( ( ( l != 0 ) && ( a->size() != l ) ) || ( a->size() == 0 ) )
378       {
379       itkGenericExceptionMacro(<< errMsg);
380       }
381     else if ( l == 0 )
382       {
383       return a->size();
384       }
385     return 0;
386   }
387 
388   template< typename TArrayType >
Assign(TArrayType & m,const TArrayType & v)389   static void  Assign(TArrayType & m, const TArrayType & v)
390   {
391     m = v;
392   }
393 
394   template< typename TValue, unsigned int VLength >
Assign(FixedArray<TValue,VLength> & m,const TValue & v)395   static void  Assign(FixedArray< TValue, VLength > & m, const TValue & v)
396   {
397     m[0] = v;
398   }
399 };
400 
401 /** \class MeasurementVectorTraitsTypes
402  * \brief
403  * \ingroup Statistics
404  * \ingroup ITKStatistics
405  */
406 
407 template< typename TMeasurementVector >
408 class MeasurementVectorTraitsTypes
409 {
410 public:
411   using ValueType = typename TMeasurementVector::ValueType;
412 };
413 
414 template< typename T >
415 class MeasurementVectorTraitsTypes< std::vector< T > >
416 {
417 public:
418   using ValueType = T;
419 };
420 
421 /** Traits for generating the MeasurementVectorType that best matches a
422  * particular pixel type. */
423 
424 template< typename TPixelType >
425 class MeasurementVectorPixelTraits
426 {
427 public:
428   /* type of the vector that matches this pixel type */
429   using MeasurementVectorType = TPixelType;
430 };
431 
432 /// \cond HIDE_SPECIALIZATION_DOCUMENTATION
433 /**
434  * \class MeasurementVectorPixelTraits
435  * \ingroup ITKStatistics
436  */
437 template< >
438 class MeasurementVectorPixelTraits< char >
439 {
440 public:
441   using MeasurementVectorType = FixedArray< char, 1 >;
442 };
443 
444 template< >
445 class MeasurementVectorPixelTraits< unsigned char >
446 {
447 public:
448   using MeasurementVectorType = FixedArray< unsigned char, 1 >;
449 };
450 
451 template< >
452 class MeasurementVectorPixelTraits< signed char >
453 {
454 public:
455   using MeasurementVectorType = FixedArray< signed char, 1 >;
456 };
457 
458 template< >
459 class MeasurementVectorPixelTraits< unsigned short >
460 {
461 public:
462   using MeasurementVectorType = FixedArray< unsigned short, 1 >;
463 };
464 
465 template< >
466 class MeasurementVectorPixelTraits< signed short >
467 {
468 public:
469   using MeasurementVectorType = FixedArray< signed short, 1 >;
470 };
471 
472 template< >
473 class MeasurementVectorPixelTraits< unsigned int >
474 {
475 public:
476   using MeasurementVectorType = FixedArray< unsigned int, 1 >;
477 };
478 
479 template< >
480 class MeasurementVectorPixelTraits< signed int >
481 {
482 public:
483   using MeasurementVectorType = FixedArray< signed int, 1 >;
484 };
485 
486 template< >
487 class MeasurementVectorPixelTraits< unsigned long >
488 {
489 public:
490   using MeasurementVectorType = FixedArray< unsigned long, 1 >;
491 };
492 
493 template< >
494 class MeasurementVectorPixelTraits< signed long >
495 {
496 public:
497   using MeasurementVectorType = FixedArray< signed long, 1 >;
498 };
499 
500 template< >
501 class MeasurementVectorPixelTraits< unsigned long long >
502 {
503 public:
504   using MeasurementVectorType = FixedArray< unsigned long long, 1 >;
505 };
506 
507 template< >
508 class MeasurementVectorPixelTraits< signed long long >
509 {
510 public:
511   using MeasurementVectorType = FixedArray< signed long long, 1 >;
512 };
513 
514 template< >
515 class MeasurementVectorPixelTraits< float >
516 {
517 public:
518   using MeasurementVectorType = FixedArray< float, 1 >;
519 };
520 
521 template< >
522 class MeasurementVectorPixelTraits< double >
523 {
524 public:
525   using MeasurementVectorType = FixedArray< double, 1 >;
526 };
527 
528 /// \endcond
529 
530 } // namespace Statistics
531 } // namespace itk
532 
533 #endif  // itkMeasurementVectorTraits_h
534