source: Sophya/trunk/SophyaLib/HiStats/hist2err.cc@ 3851

Last change on this file since 3851 was 3338, checked in by cmv, 18 years ago

mise a zero de mMean dans ::Zero() cmv 04/10/2007

File size: 9.9 KB
RevLine 
[3121]1#include "machdefs.h"
2#include <string.h>
3#include <stdio.h>
4#include <math.h>
5#include "perrors.h"
6#include "fioarr.h"
7#include "hist2err.h"
8
[3236]9namespace SOPHYA {
10
[3121]11/*!
[3236]12 \class Histo2DErr
[3121]13 \ingroup HiStats
14 Classe d'histogrammes 1D avec erreurs donnees par l'utilisateur
15*/
16
17/********* Methode *********/
18/*! Constructeur par defaut */
19Histo2DErr::Histo2DErr(void)
[3338]20: xmin_(1.), xmax_(-1.), dx_(0.) , ymin_(1.), ymax_(-1.), dy_(0.)
21 , nx_(0), ny_(0), mMean(0)
[3121]22{
23}
24
25/********* Methode *********/
26/*! Constructeur d'un histo */
27Histo2DErr::Histo2DErr(r_8 xmin,r_8 xmax,int_4 nx,r_8 ymin,r_8 ymax,int_4 ny)
28{
[3338]29 CreateOrResize(xmin,xmax,nx,ymin,ymax,ny);
[3121]30}
31
32/********* Methode *********/
33/*! Constructeur par copie */
34Histo2DErr::Histo2DErr(const Histo2DErr& H)
[3338]35: xmin_(1.), xmax_(-1.), dx_(0.) , ymin_(1.), ymax_(-1.), dy_(0.)
36 , nx_(0), ny_(0), mMean(0)
[3121]37{
38 if(H.nx_<=0 || H.ny_<=0) return;
39 CreateOrResize(H.xmin_,H.xmax_,H.nx_,H.ymin_,H.ymax_,H.ny_);
40 data_ = H.data_;
41 err2_ = H.err2_;
42 ndata_ = H.ndata_;
[3147]43 mMean = H.mMean;
[3121]44}
45
46/********* Methode *********/
47/*! Destructeur */
48Histo2DErr::~Histo2DErr(void)
49{
[3147]50 mMean = 0;
[3121]51}
52
53/********* Methode *********/
54/*! Gestion de l'allocation */
55void Histo2DErr::CreateOrResize(r_8 xmin,r_8 xmax,int_4 nx,r_8 ymin,r_8 ymax,int_4 ny)
56{
57 xmin_ = xmin; xmax_ = xmax; nx_ = nx; dx_=0.;
58 ymin_ = ymin; ymax_ = ymax; ny_ = ny; dy_=0.;
59 if(nx_>0 && ny_>0) {
60 data_.ReSize(nx_,ny_); data_ = 0.;
61 err2_.ReSize(nx_,ny_); err2_ = 0.;
62 ndata_.ReSize(nx_,ny_); ndata_ = 0.;
63 dx_ = (xmax_-xmin_)/nx_;
64 dy_ = (ymax_-ymin_)/ny_;
65 }
[3147]66 mMean = 0;
[3121]67}
68
69/********* Methode *********/
70/*!
71 Remise a zero
72*/
73void Histo2DErr::Zero(void)
74{
75 if(nx_<=0 || ny_<=0) return;
76 data_ = 0.;
77 err2_ = 0.;
78 ndata_ = 0.;
[3338]79 mMean = 0;
[3121]80}
81
82/********* Methode *********/
83/*!
84 Recompute XMin (YMin) and XMax (YMax) so that
85 the CENTER of the first bin is exactly XMin (YMin) and
86 the CENTER of the last bin is exactly XMax (YMax).
87 Remember that otherwise
88 XMin (YMin) is the beginning of the first bin
89 and XMax (YMax) is the end of the last bin
[3307]90 WARNING: number of bins is kept, bin width is changed
[3121]91*/
92void Histo2DErr::ReCenterBinX(void)
93{
94 if(nx_<=1) return;
95 double dx = (xmax_-xmin_)/(nx_-1);
96 xmin_ -= dx/2.;
97 xmax_ += dx/2.;
98 dx_ = (xmax_-xmin_)/nx_;
99}
100
101void Histo2DErr::ReCenterBinY(void)
102{
103 if(ny_<=1) return;
104 double dy = (ymax_-ymin_)/(ny_-1);
105 ymin_ -= dy/2.;
106 ymax_ += dy/2.;
107 dy_ = (ymax_-ymin_)/ny_;
108}
109
110void Histo2DErr::ReCenterBin(void)
111{
112 ReCenterBinX();
113 ReCenterBinY();
114}
115
116/********* Methode *********/
117/*!
[3307]118 Recompute XMin (YMin) and XMax (YMax) so that
119 the CENTER of the first bin is exactly XMin (YMin) and
120 the CENTER of the last bin is exactly XMax (YMax).
121 Remember that otherwise
122 XMin (YMin) is the beginning of the first bin
123 and XMax (YMax) is the end of the last bin
124 WARNING: bin widths are kept, numbers of bins are increased by 1
125*/
126void Histo2DErr::ReCenterBinW(void)
127{
128 CreateOrResize(xmin_-dx_/2.,xmax_+dx_/2.,nx_+1,ymin_-dy_/2.,ymax_+dy_/2.,ny_+1);
129}
130
131/********* Methode *********/
132/*!
[3147]133 Compute the mean histogram.
134 Each bin content is divided by the number of entries in the bin.
135 Each squared error is divided by the number of entries in the bin.
136 The number of entries by bin is NOT set to 1
137 (calling ToMean many time will change the histogram !)
[3121]138*/
[3147]139void Histo2DErr::ToMean(void)
[3121]140{
141 if(nx_<1 || ny_<1) return;
[3147]142 mMean++;
[3121]143 for(int_4 i=0;i<nx_;i++) {
144 for(int_4 j=0;j<ny_;j++) {
145 if(ndata_(i,j)<1.) continue;
146 data_(i,j) /= ndata_(i,j);
147 err2_(i,j) /= ndata_(i,j);
148 }
149 }
150 return;
151}
152
153/********* Methode *********/
154/*!
[3147]155 Recompute back the original Histo2DErr after ToMean action
[3121]156*/
[3147]157void Histo2DErr::FromMean(void)
[3121]158{
159 if(nx_<1 || ny_<1) return;
[3147]160 mMean--;
[3121]161 for(int_4 i=0;i<nx_;i++) {
162 for(int_4 j=0;j<ny_;j++) {
163 if(ndata_(i,j)<1.) continue;
164 data_(i,j) *= ndata_(i,j);
165 err2_(i,j) *= ndata_(i,j);
166 }
167 }
168 return;
169}
170
171/********* Methode *********/
172/*!
[3147]173 Compute the mean histogram and replace the "error table" by the variance.
174 This should be done if Add(x,w,w) has been used.
175 The "value table" is divided by the number of entries to get the mean
176 The "error table" is replace by the variance
177 The number of entries by bin is NOT set to 1
178 (calling ToMean many time will change the histogram !)
179 Mixing ToMean and ToVariance leads to unpredictable results
180*/
181void Histo2DErr::ToVariance(void)
182{
183 if(nx_<1 || ny_<1) return;
184 mMean++;
185 for(int_4 i=0;i<nx_;i++) {
186 for(int_4 j=0;j<ny_;j++) {
187 if(ndata_(i,j)<1.) continue;
188 data_(i,j) /= ndata_(i,j);
189 err2_(i,j) = err2_(i,j)/ndata_(i,j) - data_(i,j)*data_(i,j);
190 }
191 }
192 return;
193}
194
195/********* Methode *********/
196/*!
197 Recompute back the original HistoErr after ToVariance action
198 Mixing FromMean and FromVariance leads to unpredictable results
199*/
200void Histo2DErr::FromVariance(void)
201{
202 if(nx_<1 || ny_<1) return;
203 mMean--;
204 for(int_4 i=0;i<nx_;i++) {
205 for(int_4 j=0;j<ny_;j++) {
206 if(ndata_(i,j)<1.) continue;
207 err2_(i,j) = ndata_(i,j)*(err2_(i,j) + data_(i,j)*data_(i,j));
208 data_(i,j) *= ndata_(i,j);
209 }
210 }
211 return;
212}
213
214/********* Methode *********/
215/*!
[3121]216 Fill the histogram with an other histogram
217*/
218void Histo2DErr::FillFrHErr(Histo2DErr& hfrom)
219{
220 if(nx_<=0 || ny_<=0) return;
221 if(hfrom.nx_<=0 || hfrom.ny_<=0) return;
222
223 Zero();
224
225 for(int_4 i=0;i<hfrom.nx_;i++) {
226 for(int_4 j=0;j<hfrom.ny_;j++) {
227 r_8 x,y; hfrom.BinCenter(i,j,x,y);
228 int ii,jj; FindBin(x,y,ii,jj);
229 if(jj<0 || jj>=ny_ || ii<0 || ii>=nx_) continue;
230 data_(ii,jj) += hfrom.data_(ii,jj);
231 err2_(ii,jj) += hfrom.err2_(ii,jj);
232 ndata_(ii,jj) += hfrom.ndata_(ii,jj);
233 }
234 }
[3147]235 mMean = hfrom.mMean;
[3121]236
237}
238
239/********* Methode *********/
240/*!
241 Operateur egal Histo2DErr = Histo2DErr
242*/
243Histo2DErr& Histo2DErr::operator = (const Histo2DErr& h)
244{
245 if(this==&h) return *this;
246 CreateOrResize(h.xmin_,h.xmax_,h.nx_,h.ymin_,h.ymax_,h.ny_);
247 data_ = h.data_;
248 err2_ = h.err2_;
249 ndata_ = h.ndata_;
[3147]250 mMean = h.mMean;
[3121]251 return *this;
252}
253
254/********* Methode *********/
255/*!
[3136]256 Operateur de multiplication par une constante
257*/
258Histo2DErr& Histo2DErr::operator *= (r_8 b)
259{
260r_8 b2 = b*b;
261for(int_4 i=0;i<nx_;i++) {
262 for(int_4 j=0;j<ny_;j++) {
263 data_(i,j) *= b;
264 err2_(i,j) *= b2;
265 }
266}
267return *this;
268}
269
270/********* Methode *********/
271/*!
[3121]272 Print info
273*/
274void Histo2DErr::Show(ostream & os) const
275{
[3147]276 os <<"Histo2DErr(nmean="<<mMean<<")"<<endl
[3121]277 <<" nx="<<nx_<<" ["<<xmin_<<","<<xmax_<<"] dx="<<dx_<<endl
278 <<" ny="<<ny_<<" ["<<ymin_<<","<<ymax_<<"] dy="<<dy_<<endl;
279}
280
[3184]281/********* Methode *********/
282/*!
283 Write to an ASCII file
284*/
285int Histo2DErr::WriteASCII(string fname)
286{
287 FILE *file = fopen(fname.c_str(),"w");
288 if(file==NULL) {
289 cout<<"Histo2DErr::WriteASCII_Error: error opening "<<fname<<endl;
290 return -1;
291 }
292
293 if(NBinX()<=0 || NBinY()<=0) {
294 cout<<"Histo2DErr::WriteASCII_Error: wrong number of bins"<<endl;
295 return -2;
296 }
297
298 fprintf(file,"%ld %.17e %.17e %.17e %ld %.17e %.17e %.17e %d\n"
299 ,(long)NBinX(),XMin(),XMax(),WBinX()
300 ,(long)NBinY(),YMin(),YMax(),WBinY()
301 ,NMean());
302 for(long i=0;i<NBinX();i++) for(long j=0;j<NBinY();j++) {
303 // ligne = i*NY+j
[3247]304 fprintf(file,"%ld %ld %.17e %.17e %.0f\n"
[3184]305 ,i,j,(*this)(i,j),Error2(i,j),NEntBin(i,j));
306 }
307
308 fclose(file);
309 return 0;
310}
311
312/*!
313 Read from an ASCII file
314*/
315#define __LENLINE_Histo2DErr_ReadASCII__ 2048
316int Histo2DErr::ReadASCII(string fname)
317{
318 FILE *file = fopen(fname.c_str(),"r");
319 if(file==NULL) {
320 cout<<"Histo2DErr::ReadASCII_Error: error opening "<<fname<<endl;
321 return -1;
322 }
323
324 char line[__LENLINE_Histo2DErr_ReadASCII__];
325 long n=0, nbinx=0, nbiny=0;
326
327 while ( fgets(line,__LENLINE_Histo2DErr_ReadASCII__,file) != NULL ) {
328
329 if(n==0) {
330
331 r_8 xmin,xmax,wx, ymin,ymax,wy; long mnmean=1;
[3247]332 sscanf(line,"%ld %lf %lf %lf %ld %lf %lf %lf %ld"
[3184]333 ,&nbinx,&xmin,&xmax,&wx
334 ,&nbiny,&ymin,&ymax,&wy
335 ,&mnmean);
336 if(nbinx<=0 || nbiny<=0) {
337 cout<<"Histo2Err::ReadASCII_Error: wrong number of bins"<<endl;
338 return -2;
339 }
340 CreateOrResize(xmin,xmax,nbinx,ymin,ymax,nbiny);
341 SetMean(mnmean);
342
343 } else {
344
345 long i,j; r_8 v,e2,nb;
[3247]346 sscanf(line,"%ld %ld %lf %lf %lf",&i,&j,&v,&e2,&nb);
[3184]347 SetBin(i,j,v);
348 SetErr2(i,j,e2);
349 SetNentB(i,j,nb);
350
351 }
352
353 n++;
354 }
355
356 fclose(file);
357 return 0;
358}
359
[3121]360///////////////////////////////////////////////////////////
361// --------------------------------------------------------
362// Les objets delegues pour la gestion de persistance
363// --------------------------------------------------------
364///////////////////////////////////////////////////////////
365
366DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
367void ObjFileIO<Histo2DErr>::ReadSelf(PInPersist& is)
368{
369string strg;
370
371if(dobj==NULL) dobj = new Histo2DErr;
372
373// Lecture entete
374is.GetStr(strg);
375
[3147]376// Nombre d'appels a ToMean/FromMean
377is.Get(dobj->mMean);
[3121]378
379// Lecture des parametres Histo2DErr
380is.Get(dobj->xmin_);
381is.Get(dobj->xmax_);
382is.Get(dobj->nx_);
383is.Get(dobj->dx_);
384is.Get(dobj->ymin_);
385is.Get(dobj->ymax_);
386is.Get(dobj->ny_);
387is.Get(dobj->dy_);
388
389// Lecture des donnees
390if(dobj->nx_>0 && dobj->ny_>0) {
391 is >> dobj->data_;
392 is >> dobj->err2_;
393 is >> dobj->ndata_;
394}
395
396return;
397}
398
399DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
400void ObjFileIO<Histo2DErr>::WriteSelf(POutPersist& os) const
401{
402if(dobj == NULL) return;
403string strg;
404
405// Ecriture entete
406strg = "Hist2DErr";
407os.PutStr(strg);
408
[3147]409// Nombre d'appels a ToMean/FromMean
410os.Put(dobj->mMean);
[3121]411
412// Ecriture des parametres Histo2DErr
413os.Put(dobj->xmin_);
414os.Put(dobj->xmax_);
415os.Put(dobj->nx_);
416os.Put(dobj->dx_);
417os.Put(dobj->ymin_);
418os.Put(dobj->ymax_);
419os.Put(dobj->ny_);
420os.Put(dobj->dy_);
421
422// Ecriture des donnees
423if(dobj->nx_>0 && dobj->ny_>0) {
424 os << dobj->data_;
425 os << dobj->err2_;
426 os << dobj->ndata_;
427}
428
429return;
430}
431
432#ifdef __CXX_PRAGMA_TEMPLATES__
433#pragma define_template ObjFileIO<Histo2DErr>
434#endif
435
436#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
[3236]437template class ObjFileIO<Histo2DErr>;
[3121]438#endif
[3236]439
440} // FIN namespace SOPHYA
Note: See TracBrowser for help on using the repository browser.