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

Last change on this file since 3308 was 3307, checked in by cmv, 18 years ago

methode ReCenterBinW binwidth kept, number of bin incresed cmv 22/08/2007

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