source: Sophya/trunk/SophyaLib/HiStats/histerr.cc@ 3247

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

correction erreur format dans sscanf cmv 15/05/2007

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