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

Last change on this file since 3181 was 3156, checked in by cmv, 19 years ago

add write and read in/from ASCII file cmv 22/01/2007

File size: 7.7 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 Operateur egal HistoErr = HistoErr
196*/
197HistoErr& HistoErr::operator = (const HistoErr& h)
198{
199 if(this==&h) return *this;
200 CreateOrResize(h.xmin_,h.xmax_,h.nx_);
201 data_ = h.data_;
202 err2_ = h.err2_;
203 ndata_ = h.ndata_;
204 mMean = h.mMean;
205 return *this;
206}
207
208/********* Methode *********/
209/*!
210 Operateur de multiplication par une constante
211*/
212HistoErr& HistoErr::operator *= (r_8 b)
213{
214r_8 b2 = b*b;
215for(int_4 i=0;i<nx_;i++) {
216 data_(i) *= b;
217 err2_(i) *= b2;
218}
219return *this;
220}
221
222/********* Methode *********/
223/*!
224 Print info
225*/
226void HistoErr::Show(ostream & os) const
227{
228 os <<"HistoErr(nmean="<<mMean<<")"
229 <<" nx="<<nx_<<" ["<<xmin_<<","<<xmax_<<"] dx="<<dx_<<endl;
230}
231
232/********* Methode *********/
233/*!
234 Write to an ASCII file
235*/
236int HistoErr::WriteASCII(string fname)
237{
238 FILE *file = fopen(fname.c_str(),"w");
239 if(file==NULL) {
240 cout<<"HistoErr::WriteASCII_Error: error opening "<<fname<<endl;
241 return -1;
242 }
243
244 if(NBins()<=0) {
245 cout<<"HistoErr::WriteASCII_Error: nbin= "<<NBins()<<endl;
246 return -2;
247 }
248
249 fprintf(file,"%ld %.17e %.17e %d\n",(long)NBins(),XMin(),XMax(),NMean());
250 for(long i=0;i<NBins();i++) {
251 fprintf(file,"%d %.17e %.17e %.17e %.0f\n"
252 ,i,BinCenter(i),(*this)(i),Error2(i),NEntBin(i));
253 }
254
255 fclose(file);
256 return 0;
257}
258
259/*!
260 Read from an ASCII file
261*/
262#define __LENLINE_HistoErr_ReadASCII__ 2048
263int HistoErr::ReadASCII(string fname)
264{
265 FILE *file = fopen(fname.c_str(),"r");
266 if(file==NULL) {
267 cout<<"HistoErr::ReadASCII_Error: error opening "<<fname<<endl;
268 return -1;
269 }
270
271 char line[__LENLINE_HistoErr_ReadASCII__];
272 long n=0, nbin=0;
273
274 while ( fgets(line,__LENLINE_HistoErr_ReadASCII__,file) != NULL ) {
275
276 if(n==0) {
277
278 r_8 xmin,xmax; long mnmean=1;
279 sscanf(line,"%d %lf %lf %d",&nbin,&xmin,&xmax,&mnmean);
280 if(nbin<=0) {
281 cout<<"HistoErr::ReadASCII_Error: nbin= "<<nbin<<endl;
282 return -2;
283 }
284 CreateOrResize(xmin,xmax,nbin);
285 SetMean(mnmean);
286
287 } else {
288
289 long i; r_8 x,v,e2,nb;
290 sscanf(line,"%d %lf %lf %lf %lf",&i,&x,&v,&e2,&nb);
291 SetBin(i,v);
292 SetErr2(i,e2);
293 SetNentB(i,nb);
294
295 }
296
297 n++;
298 }
299
300 fclose(file);
301 return 0;
302}
303
304
305///////////////////////////////////////////////////////////
306// --------------------------------------------------------
307// Les objets delegues pour la gestion de persistance
308// --------------------------------------------------------
309///////////////////////////////////////////////////////////
310
311DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
312void ObjFileIO<HistoErr>::ReadSelf(PInPersist& is)
313{
314string strg;
315
316if(dobj==NULL) dobj = new HistoErr;
317
318// Lecture entete
319is.GetStr(strg);
320
321// Nombre d'appels a ToMean/FromMean
322is.Get(dobj->mMean);
323
324// Lecture des parametres HistoErr
325is.Get(dobj->xmin_);
326is.Get(dobj->xmax_);
327is.Get(dobj->nx_);
328is.Get(dobj->dx_);
329
330// Lecture des donnees
331if(dobj->nx_>0) {
332 is >> dobj->data_;
333 is >> dobj->err2_;
334 is >> dobj->ndata_;
335}
336
337return;
338}
339
340DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
341void ObjFileIO<HistoErr>::WriteSelf(POutPersist& os) const
342{
343if(dobj == NULL) return;
344string strg;
345
346// Ecriture entete
347strg = "HistErr";
348os.PutStr(strg);
349
350// Nombre d'appels a ToMean/FromMean
351os.Put(dobj->mMean);
352
353// Ecriture des parametres HistoErr
354os.Put(dobj->xmin_);
355os.Put(dobj->xmax_);
356os.Put(dobj->nx_);
357os.Put(dobj->dx_);
358
359// Ecriture des donnees
360if(dobj->nx_>0) {
361 os << dobj->data_;
362 os << dobj->err2_;
363 os << dobj->ndata_;
364}
365
366return;
367}
368
369#ifdef __CXX_PRAGMA_TEMPLATES__
370#pragma define_template ObjFileIO<HistoErr>
371#endif
372
373#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
374template class SOPHYA::ObjFileIO<HistoErr>;
375#endif
Note: See TracBrowser for help on using the repository browser.