primatologist-gpl 6.0.4
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
29namespace 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>
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>
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