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 itkSubsample_hxx
19 #define itkSubsample_hxx
20 
21 #include "itkSubsample.h"
22 
23 #include "itkObject.h"
24 
25 namespace itk
26 {
27 namespace Statistics
28 {
29 template< typename TSample >
30 Subsample< TSample >
Subsample()31 ::Subsample()
32 {
33   m_Sample = nullptr;
34   m_TotalFrequency = NumericTraits< AbsoluteFrequencyType >::ZeroValue();
35   m_ActiveDimension = 0;
36 }
37 
38 template< typename TSample >
39 void
40 Subsample< TSample >
PrintSelf(std::ostream & os,Indent indent) const41 ::PrintSelf(std::ostream & os, Indent indent) const
42 {
43   Superclass::PrintSelf(os, indent);
44 
45   os << indent << "Sample: ";
46   if ( m_Sample != nullptr )
47     {
48     os << m_Sample << std::endl;
49     }
50   else
51     {
52     os << "not set." << std::endl;
53     }
54 
55   os << indent << "TotalFrequency: " << m_TotalFrequency << std::endl;
56   os << indent << "ActiveDimension: " << m_ActiveDimension << std::endl;
57   os << indent << "InstanceIdentifierHolder : " << &m_IdHolder << std::endl;
58 }
59 
60 template< typename TSample >
61 void
62 Subsample< TSample >
SetSample(const TSample * sample)63 ::SetSample(const TSample *sample)
64 {
65   m_Sample = sample;
66   this->SetMeasurementVectorSize( m_Sample->GetMeasurementVectorSize() );
67   this->Modified();
68 }
69 
70 template< typename TSample >
71 const TSample *
72 Subsample< TSample >
GetSample() const73 ::GetSample() const
74 {
75   return m_Sample;
76 }
77 
78 template< typename TSample >
79 void
80 Subsample< TSample >
InitializeWithAllInstances()81 ::InitializeWithAllInstances()
82 {
83   m_IdHolder.resize( m_Sample->Size() );
84   auto idIter = m_IdHolder.begin();
85   typename TSample::ConstIterator iter = m_Sample->Begin();
86   typename TSample::ConstIterator last = m_Sample->End();
87   m_TotalFrequency = NumericTraits< AbsoluteFrequencyType >::ZeroValue();
88   while ( iter != last )
89     {
90     *idIter++ = iter.GetInstanceIdentifier();
91     m_TotalFrequency += iter.GetFrequency();
92     ++iter;
93     }
94   this->Modified();
95 }
96 
97 template< typename TSample >
98 void
99 Subsample< TSample >
AddInstance(InstanceIdentifier id)100 ::AddInstance(InstanceIdentifier id)
101 {
102   if ( id > m_Sample->Size() )
103     {
104     itkExceptionMacro("MeasurementVector " << id << " does not exist in the Sample");
105     }
106 
107   m_IdHolder.push_back(id);
108   m_TotalFrequency += m_Sample->GetFrequency(id);
109   this->Modified();
110 }
111 
112 template< typename TSample >
113 typename Subsample< TSample >::InstanceIdentifier
114 Subsample< TSample >
Size() const115 ::Size() const
116 {
117   return static_cast< unsigned int >( m_IdHolder.size() );
118 }
119 
120 template< typename TSample >
121 void
122 Subsample< TSample >
Clear()123 ::Clear()
124 {
125   m_IdHolder.clear();
126   m_TotalFrequency = NumericTraits< AbsoluteFrequencyType >::ZeroValue();
127   this->Modified();
128 }
129 
130 template< typename TSample >
131 const typename Subsample< TSample >::MeasurementVectorType &
132 Subsample< TSample >
GetMeasurementVector(InstanceIdentifier id) const133 ::GetMeasurementVector(InstanceIdentifier id) const
134 {
135   if ( id >= m_IdHolder.size() )
136     {
137     itkExceptionMacro("MeasurementVector " << id << " does not exist");
138     }
139 
140   // translate the id to its Sample container id
141   InstanceIdentifier idInTheSample = m_IdHolder[id];
142   return m_Sample->GetMeasurementVector(idInTheSample);
143 }
144 
145 template< typename TSample >
146 inline typename Subsample< TSample >::AbsoluteFrequencyType
147 Subsample< TSample >
GetFrequency(InstanceIdentifier id) const148 ::GetFrequency(InstanceIdentifier id) const
149 {
150   if ( id >= m_IdHolder.size() )
151     {
152     itkExceptionMacro("MeasurementVector " << id << " does not exist");
153     }
154 
155   // translate the id to its Sample container id
156   InstanceIdentifier idInTheSample = m_IdHolder[id];
157   return m_Sample->GetFrequency(idInTheSample);
158 }
159 
160 template< typename TSample >
161 inline typename Subsample< TSample >::TotalAbsoluteFrequencyType
162 Subsample< TSample >
GetTotalFrequency() const163 ::GetTotalFrequency() const
164 {
165   return m_TotalFrequency;
166 }
167 
168 template< typename TSample >
169 inline void
170 Subsample< TSample >
Swap(unsigned int index1,unsigned int index2)171 ::Swap(unsigned int index1, unsigned int index2)
172 {
173   if ( index1 >= m_IdHolder.size()
174        || index2 >= m_IdHolder.size() )
175     {
176     itkExceptionMacro("Index out of range");
177     }
178 
179   InstanceIdentifier temp = m_IdHolder[index1];
180   m_IdHolder[index1] = m_IdHolder[index2];
181   m_IdHolder[index2] = temp;
182   this->Modified();
183 }
184 
185 template< typename TSample >
186 inline const typename Subsample< TSample >::MeasurementVectorType &
187 Subsample< TSample >
GetMeasurementVectorByIndex(unsigned int index) const188 ::GetMeasurementVectorByIndex(unsigned int index) const
189 {
190   if ( index >= m_IdHolder.size() )
191     {
192     itkExceptionMacro("Index out of range");
193     }
194   return m_Sample->GetMeasurementVector(m_IdHolder[index]);
195 }
196 
197 template< typename TSample >
198 inline typename Subsample< TSample >::AbsoluteFrequencyType
199 Subsample< TSample >
GetFrequencyByIndex(unsigned int index) const200 ::GetFrequencyByIndex(unsigned int index) const
201 {
202   if ( index >= m_IdHolder.size() )
203     {
204     itkExceptionMacro("Index out of range");
205     }
206 
207   return m_Sample->GetFrequency(m_IdHolder[index]);
208 }
209 
210 template< typename TSample >
211 typename Subsample< TSample >::InstanceIdentifier
212 Subsample< TSample >
GetInstanceIdentifier(unsigned int index)213 ::GetInstanceIdentifier(unsigned int index)
214 {
215   if ( index >= m_IdHolder.size() )
216     {
217     itkExceptionMacro("Index out of range");
218     }
219   return m_IdHolder[index];
220 }
221 
222 template< typename TSample >
223 void
224 Subsample< TSample >
Graft(const DataObject * thatObject)225 ::Graft(const DataObject *thatObject)
226 {
227   this->Superclass::Graft(thatObject);
228 
229   // Most of what follows is really a deep copy, rather than grafting of
230   // output. Wish it were managed by pointers to bulk data. Sigh !
231 
232   const auto * thatConst = dynamic_cast< const Self * >( thatObject );
233   if ( thatConst )
234     {
235     auto * that = const_cast< Self * >( thatConst );
236     this->SetSample( that->GetSample() );
237     this->m_IdHolder          = that->m_IdHolder;
238     this->m_ActiveDimension   = that->m_ActiveDimension;
239     this->m_TotalFrequency    = that->m_TotalFrequency;
240     }
241 }
242 } // end of namespace Statistics
243 } // end of namespace itk
244 
245 #endif
246