primatologist-gpl  5.1.2
normal_d.h
Go to the documentation of this file.
1 /* Copyright (C) 2000-2013 CEA
2  *
3  * This software and supporting documentation were developed by
4  * bioPICSEL
5  * CEA/DSV/I²BM/MIRCen/LMN, Batiment 61,
6  * 18, route du Panorama
7  * 92265 Fontenay-aux-Roses
8  * France
9  */
10 
11 #ifndef PRIMATOLOGIST_PROBA_NORMAL_D_H
12 #define PRIMATOLOGIST_PROBA_NORMAL_D_H
13 
14 
15 //--- primatologist ----------------------------------------------------------
17 //--- aims -------------------------------------------------------------------
18 #include <aims/math/mathelem.h>
19 //--- cartodata --------------------------------------------------------------
20 #include <cartodata/volume/volume.h>
21 //--- cartobase --------------------------------------------------------------
22 #include <cartobase/exception/assert.h>
23 //--- std --------------------------------------------------------------------
24 #include <cmath>
25 #include <vector>
26 //----------------------------------------------------------------------------
27 
28 
29 namespace aims {
30 
31  //==========================================================================
32  //
33  // NORMAL ESTIMATION
34  //
35  //==========================================================================
36 
37  template <typename DataType, typename WeightType, typename MaskType>
39  _distrib(1),
40  _data((carto::Volume<DataType>*)0),
41  _weight((carto::Volume<WeightType>*)0),
42  _mask((carto::Volume<MaskType>*)0),
43  _bessel(false),
44  _robust(false),
45  _multi(false),
46  _vs_data(4,1.),
47  _vs_mask(4,1.)
48  {}
49 
50  template <typename DataType, typename WeightType, typename MaskType>
52  {}
53 
54 
55  //--- set volumes ----------------------------------------------------------
56 
57  template <typename DataType, typename WeightType, typename MaskType>
59  const carto::VolumeRef<DataType> & data )
60  {
61  _data = data;
62  if( _data.get() ) {
63  _vs_data.assign(4, 1.);
64  _data.header().getProperty("voxel_size", _vs_data);
65  }
66  }
67 
68  template <typename DataType, typename WeightType, typename MaskType>
70  const carto::VolumeRef<WeightType> & weight )
71  {
72  _weight = weight;
73  }
74 
75  template <typename DataType, typename WeightType, typename MaskType>
77  const carto::VolumeRef<MaskType> & mask )
78  {
79  _mask = mask;
80  if( _mask.get() ) {
81  _vs_mask.assign(4, 1.);
82  _mask.header().getProperty("voxel_size", _vs_mask);
83  }
84  }
85 
86  //--- options --------------------------------------------------------------
87 
88  template <typename DataType, typename WeightType, typename MaskType>
90  {
91  _bessel = bessel;
92  }
93 
94  template <typename DataType, typename WeightType, typename MaskType>
96  {
97  _robust = robust;
98  }
99 
100  template <typename DataType, typename WeightType, typename MaskType>
102  {
103  _multi = multi;
104  }
105 
106  //--- results --------------------------------------------------------------
107 
108  template <typename DataType, typename WeightType, typename MaskType>
110  {
111  return _distrib[0].getMu();
112  }
113 
114  template <typename DataType, typename WeightType, typename MaskType>
116  {
117  return _distrib[0].getSigma();
118  }
119 
120  template <typename DataType, typename WeightType, typename MaskType>
123  {
124  return _distrib[0];
125  }
126 
127  template <typename DataType, typename WeightType, typename MaskType>
128  std::vector<NormalDistribution>
130  {
131  return _distrib;
132  }
133 
134  //--- helper --------------------------------------------------------------
135 
136  template <typename DataType, typename WeightType, typename MaskType>
138  long x, long y, long z, long t )
139  {
140  if( !_mask.get() )
141  return true;
142 
143  if(x)
144  x = (long)((double)x * _vs_data[0] / _vs_mask[0]);
145  if(y)
146  y = (long)((double)y * _vs_data[1] / _vs_mask[1]);
147  if(z)
148  z = (long)((double)z * _vs_data[2] / _vs_mask[2]);
149  if(t)
150  t = (long)((double)t * _vs_data[3] / _vs_mask[3]);
151 
152  return 0 <= x && x < _mask.getSizeX() &&
153  0 <= y && y < _mask.getSizeY() &&
154  0 <= z && z < _mask.getSizeZ() &&
155  0 <= t && ( ( t < _mask.getSizeT() && _mask(x, y, z, t) ) ||
156  ( _mask.getSizeT() == 1 && _mask(x, y, z) ) );
157  }
158 
159  //--- fit ------------------------------------------------------------------
160 
161  template <typename DataType, typename WeightType, typename MaskType>
163  {
164  if( _multi )
165  {
166  if( _weight.get() )
167  _distrib.resize( _weight.getSizeT() );
168  else
169  _distrib.resize(1);
170  for( int t = 0; t < ( _weight.get() ? _weight.getSizeT() : 1 ); ++t )
171  fitOne( _weight.view( Point4di(0, 0, 0, t),
172  Point4di( _weight.getSizeX(),
173  _weight.getSizeY(),
174  _weight.getSizeZ(), 1 ) ),
175  _distrib[t] );
176  }
177  else
178  {
179  _distrib.resize(1);
180  fitOne( _weight, _distrib[0] );
181  }
182  }
183 
184  template <typename DataType, typename WeightType, typename MaskType>
186  const carto::VolumeRef<WeightType> & volweight,
187  NormalDistribution & distrib )
188  {
189  if( _weight.get() ) {
190  ASSERT( _data.getSizeX() <= volweight.getSizeX() );
191  ASSERT( _data.getSizeY() <= volweight.getSizeY() );
192  ASSERT( _data.getSizeZ() <= volweight.getSizeZ() );
193  ASSERT( _data.getSizeT() <= volweight.getSizeT() );
194  }
195 
196  double data, weight, sum_weight = 0.;
197  long count = 0;
198  double mu = 0.;
199  double sigma = 0.;
200 
201  for( int t = 0; t < _data.getSizeT(); ++t )
202  for( int z = 0; z < _data.getSizeZ(); ++z )
203  for( int y = 0; y < _data.getSizeY(); ++y )
204  for( int x = 0; x < _data.getSizeX(); ++x )
205  if( inMask(x, y, z, t) )
206  {
207  data = (double)_data(x, y, z, t);
208  weight = ( _weight ? (double)volweight(x, y, z, t) : 1. );
209  sum_weight += weight;
210  mu += weight * data;
211  sigma += weight * sqr( data );
212  ++count;
213  }
214 
215  mu /= sum_weight;
216  sigma /= sum_weight;
217  sigma -= sqr( mu );
218  sigma = std::sqrt( sigma );
219 
220  if( _bessel ) {
221  double mean_weight = sum_weight / count;
222  sigma *= sum_weight / ( sum_weight - mean_weight );
223  }
224 
225  if( _robust )
226  {
227  double prev_mu = mu, prev_sigma = sigma;
228  mu = 0.;
229  sigma = 0.;
230  sum_weight = 0.;
231 
232  for( int t = 0; t < _data.getSizeT(); ++t )
233  for( int z = 0; z < _data.getSizeZ(); ++z )
234  for( int y = 0; y < _data.getSizeY(); ++y )
235  for( int x = 0; x < _data.getSizeX(); ++x )
236  if( inMask(x, y, z, t) )
237  {
238  data = (double)_data(x, y, z, t);
239  if( std::abs( prev_mu - data ) < prev_sigma * 3. )
240  {
241  weight = ( _weight ? (double)volweight(x, y, z, t) : 1. );
242  sum_weight += weight;
243  mu += weight * data;
244  sigma += weight * aims::sqr( data );
245  }
246  }
247 
248  mu /= sum_weight;
249  sigma /= sum_weight;
250  sigma -= aims::sqr( mu );
251  sigma = std::sqrt( sigma );
252 
253  if( _bessel ) {
254  double mean_weight = sum_weight /
255  ( _data.getSizeT() * _data.getSizeZ() *
256  _data.getSizeY() * _data.getSizeX() );
257  sigma *= sum_weight / ( sum_weight - mean_weight );
258  }
259  }
260 
261  distrib.setMu( mu );
262  distrib.setSigma( sigma );
263  }
264 
265  //==========================================================================
266  //
267  // NORMAL ESTIMATION
268  //
269  //==========================================================================
270 
271 #define instantiate_normalestim_3( DataType, WeightType, MaskType ) \
272  template class NormalEstimation<DataType,WeightType,MaskType>;
273 
274 #define instantiate_normalestim_2( DataType, WeightType ) \
275  instantiate_normalestim_3( DataType, WeightType, int8_t ) \
276  instantiate_normalestim_3( DataType, WeightType, uint8_t ) \
277  instantiate_normalestim_3( DataType, WeightType, int16_t ) \
278  instantiate_normalestim_3( DataType, WeightType, uint16_t ) \
279  instantiate_normalestim_3( DataType, WeightType, int32_t ) \
280  instantiate_normalestim_3( DataType, WeightType, uint32_t ) \
281  instantiate_normalestim_3( DataType, WeightType, int64_t ) \
282  instantiate_normalestim_3( DataType, WeightType, uint64_t ) \
283  instantiate_normalestim_3( DataType, WeightType, float ) \
284  instantiate_normalestim_3( DataType, WeightType, double )
285 
286 #define instantiate_normalestim_1( DataType ) \
287  instantiate_normalestim_2( DataType, int8_t ) \
288  instantiate_normalestim_2( DataType, uint8_t ) \
289  instantiate_normalestim_2( DataType, int16_t ) \
290  instantiate_normalestim_2( DataType, uint16_t ) \
291  instantiate_normalestim_2( DataType, int32_t ) \
292  instantiate_normalestim_2( DataType, uint32_t ) \
293  instantiate_normalestim_2( DataType, int64_t ) \
294  instantiate_normalestim_2( DataType, uint64_t ) \
295  instantiate_normalestim_2( DataType, float ) \
296  instantiate_normalestim_2( DataType, double )
297 
298 } // namespace aims
299 
300 #endif // PRIMATOLOGIST_PROBA_NORMAL_D_H
void setMu(double mu)
void setSigma(double sigma)
void setMask(const carto::VolumeRef< MaskType > &mask=vol::empty< MaskType >())
Definition: normal_d.h:76
double getMu() const
Definition: normal_d.h:109
void setMultiWeights(bool multi=true)
Definition: normal_d.h:101
void setWeight(const carto::VolumeRef< WeightType > &weight=vol::empty< WeightType >())
Definition: normal_d.h:69
void fitOne(const carto::VolumeRef< WeightType > &volweight, NormalDistribution &distrib)
Definition: normal_d.h:185
bool inMask(long x=0, long y=0, long z=0, long t=0)
Definition: normal_d.h:137
std::vector< NormalDistribution > getDistributionVector() const
Definition: normal_d.h:129
double getSigma() const
Definition: normal_d.h:115
void setBessel(bool bessel=true)
Definition: normal_d.h:89
void setRobust(bool robust=true)
Definition: normal_d.h:95
NormalDistribution getDistribution() const
Definition: normal_d.h:122
void setData(const carto::VolumeRef< DataType > &data=vol::empty< DataType >())
Definition: normal_d.h:58