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

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

add methods Sum(),Sum2(),SumN() in HistoErr cmv 03/04/2007

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