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

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

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

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