source: Sophya/trunk/SophyaLib/HiStats/hisprof.cc@ 1096

Last change on this file since 1096 was 1092, checked in by ansari, 25 years ago

Histos/Hprof/Histo2D en r_8 cmv 26/7/00

File size: 9.5 KB
Line 
1#include "machdefs.h"
2#include <string.h>
3#include <stdio.h>
4#include <math.h>
5#include "hisprof.h"
6#include "perrors.h"
7
8/*!
9 \class SOPHYA::HProf
10 \ingroup HiStats
11 Classe de profil d'histogrammes.
12*/
13
14/********* Methode *********/
15/*!
16 Constructeur par defaut.
17*/
18HProf::HProf()
19: Histo()
20, SumY(NULL), SumY2(NULL), SumW(NULL), Ok(false), YMin(1.), YMax(-1.), Opt(0)
21{
22 END_CONSTRUCTOR
23}
24
25/********* Methode *********/
26/*!
27 Constructeur. Histogramme de profil de ``nBin'' bins entre ``xMin''
28 et ``xMax'' avec coupure d'acceptance sur y entre ``yMin'' et ``yMax''.
29 Si yMin>=yMax alors pas de coupure d'acceptance sur y.
30 Par defaut l'erreur du profil represente la dispersion dans le bin,
31 SetErrOpt(1) permet de demander de calculer l'erreur sur la moyenne.
32*/
33HProf::HProf(r_8 xMin, r_8 xMax, int_4 nBin, r_8 yMin, r_8 yMax)
34: Histo(xMin,xMax,nBin)
35, SumY( (nBin>0) ? new r_8[nBin] : NULL)
36, SumY2((nBin>0) ? new r_8[nBin] : NULL)
37, SumW( (nBin>0) ? new r_8[nBin] : NULL)
38, Ok(false), YMin(yMin), YMax(yMax), Opt(0)
39{
40 Histo::Errors();
41 Zero();
42 END_CONSTRUCTOR
43}
44
45/********* Methode *********/
46/*!
47 Constructeur.
48*/
49HProf::HProf(r_4 xMin, r_4 xMax, int_4 nBin, r_4 yMin, r_4 yMax)
50: Histo((r_8)xMin,(r_8)xMax,nBin)
51, SumY( (nBin>0) ? new r_8[nBin] : NULL)
52, SumY2((nBin>0) ? new r_8[nBin] : NULL)
53, SumW( (nBin>0) ? new r_8[nBin] : NULL)
54, Ok(false), YMin((r_8)yMin), YMax((r_8)yMax), Opt(0)
55{
56 Histo::Errors();
57 Zero();
58 END_CONSTRUCTOR
59}
60
61/********* Methode *********/
62/*!
63 Constructeur par copie.
64*/
65HProf::HProf(const HProf& H)
66: Histo(H)
67, SumY((H.mBins>0) ? new r_8[H.mBins] : NULL)
68, SumY2((H.mBins>0) ? new r_8[H.mBins] : NULL)
69, SumW((H.mBins>0) ? new r_8[H.mBins] : NULL)
70, Ok(H.Ok), YMin(H.YMin), YMax(H.YMax), Opt(H.Opt)
71{
72 if(mBins>0) {
73 memcpy(SumY, H.SumY, mBins*sizeof(r_8));
74 memcpy(SumY2, H.SumY2, mBins*sizeof(r_8));
75 memcpy(SumW, H.SumW, mBins*sizeof(r_8));
76 }
77 UpdateHisto();
78 END_CONSTRUCTOR
79}
80
81/********* Methode *********/
82/*!
83 Des-allocation
84*/
85void HProf::Delete()
86{
87 if( SumY != NULL ) { delete[] SumY; SumY = NULL;}
88 if( SumY2 != NULL ) { delete[] SumY2; SumY2 = NULL;}
89 if( SumW != NULL ) { delete[] SumW; SumW = NULL;}
90 Ok = false;
91}
92
93/********* Methode *********/
94/*!
95 Destructeur
96*/
97HProf::~HProf()
98{
99Delete();
100}
101
102/********* Methode *********/
103/*!
104 Remise a zero
105*/
106void HProf::Zero()
107{
108 memset(SumY, 0, mBins*sizeof(r_8));
109 memset(SumY2, 0, mBins*sizeof(r_8));
110 memset(SumW, 0, mBins*sizeof(r_8));
111 Ok = false;
112 Histo::Zero();
113}
114
115/********* Methode *********/
116/*!
117 Pour changer l'option de calcul de l'erreur du profile.
118 Si ``spread'' = true alors l'erreur represente la dispersion
119 des donnees dans le bin, si = false elle represente l'erreur
120 sur la moyenne du bin.
121 \verbatim
122 - Pour le bin (j):
123 H(j) = sum(y), E(j) = sum(y^2), L(j) = sum(w)
124 -> s(j) = sqrt(E(j)/L(j) - (H(j)/L(j))^2) dispersion
125 -> e(j) = s(j)/sqrt(L(j)) erreur sur la moyenne
126 spread=true: opt=0 : dispersion des donnees dans le bin = s(j)
127 spread=false: opt=1 : erreur sur la moyenne du bin = e(j)
128 \endverbatim
129*/
130void HProf::SetErrOpt(bool spread)
131{
132uint_2 opt = (spread) ? 0 : 1;
133if(opt!=Opt) {Opt=opt; Ok=false;}
134}
135
136/********* Methode *********/
137/*!
138 Pour mettre a jour l'histogramme de profil.
139 Il est important d'appeler cette methode si on veut
140 utiliser les methodes de la classe Histo qui ne sont
141 pas redefinies dans la classe HProf.
142 En effet, pour des raisons de precision la classe
143 HProf travaille avec des tableaux en double precision
144 et seulement au moment ou l'on a besoin de l'histogramme
145 ce dernier est rempli avec les valeurs demandees (moyenne
146 et dispersion/erreur sur la moyenne).
147*/
148void HProf::updatehisto() const
149{
150r_8 m,e2;
151if(mBins>0) for(int_4 i=0;i<mBins;i++) {
152 if(SumW[i]<=0.) {
153 m = e2 = 0.;
154 } else {
155 m = SumY[i]/SumW[i];
156 e2 = SumY2[i]/SumW[i] - m*m;
157 if(Opt) e2 /= SumW[i];
158 }
159 mData[i] = m;
160 mErr2[i] = e2;
161}
162Ok = true;
163// Attention, a cause de "WriteSelf const" updatehisto doit etre "const".
164// Comme on veut modifier Ok, on est oblige de faire cette entourloupe:
165HProf *buff = (HProf *) this;
166buff->Ok = true;
167}
168
169/********* Methode *********/
170/*!
171 Addition au contenu de l'histo pour abscisse x de la valeur y et poids w
172*/
173void HProf::Add(r_8 x, r_8 y, r_8 w)
174{
175 if(YMax>YMin && (y<YMin || YMax<y)) return;
176 int_4 numBin = FindBin(x);
177 if (numBin<0) mUnder += w;
178 else if (numBin>=mBins) mOver += w;
179 else {
180 Ok = false;
181 SumY[numBin] += y;
182 SumY2[numBin] += y*y;
183 SumW[numBin] += w;
184 nHist += w;
185 nEntries++;
186 }
187}
188
189/********* Methode *********/
190/*!
191 Addition au contenu de l'histo bin numBin de la valeur y poids w
192*/
193void HProf::AddBin(int_4 numBin, r_8 y, r_8 w)
194{
195 if(YMax>YMin && (y<YMin || YMax<y)) return;
196 if (numBin<0) mUnder += w;
197 else if (numBin>=mBins) mOver += w;
198 else {
199 Ok = false;
200 SumY[numBin] += y;
201 SumY2[numBin] += y*y;
202 SumW[numBin] += w;
203 nHist += w;
204 nEntries++;
205 }
206}
207
208/********* Methode *********/
209/*!
210 Operateur HProf H = H1
211*/
212HProf& HProf::operator = (const HProf& h)
213{
214if(this == &h) return *this;
215if( h.mBins > mBins ) Delete();
216Histo *hthis = (Histo *) this;
217*hthis = (Histo) h;
218if(!SumY) SumY = new r_8[mBins];
219if(!SumY2) SumY2 = new r_8[mBins];
220if(!SumW) SumW = new r_8[mBins];
221memcpy(SumY, h.SumY, mBins*sizeof(r_8));
222memcpy(SumY2, h.SumY2, mBins*sizeof(r_8));
223memcpy(SumW, h.SumW, mBins*sizeof(r_8));
224Ok = h.Ok;
225YMin = h.YMin;
226YMax = h.YMax;
227Opt = h.Opt;
228
229return *this;
230}
231
232/********* Methode *********/
233/*!
234 Operateur HProf H += H1
235
236 Attention dans cette addition il n'y a pas de gestion
237 des YMin et YMax. L'addition est faite meme si les limites
238 en Y de ``a'' sont differentes de celles de ``this''.
239*/
240HProf& HProf::operator += (const HProf& a)
241{
242if(mBins!=a.mBins) THROW(sizeMismatchErr);
243Histo *hthis = (Histo *) this;
244*hthis += (Histo) a;
245if(mBins>0) for(int_4 i=0;i<mBins;i++) {
246 SumY[i] += a.SumY[i];
247 SumY2[i] += a.SumY2[i];
248 SumW[i] += a.SumW[i];
249}
250updatehisto();
251
252return *this;
253}
254
255/********* Methode *********/
256/*!
257 Pour rebinner l'histogramme de profile sur nbinew bins
258*/
259void HProf::HRebin(int_4 nbinew)
260{
261 if( mBins <= 0 ) return; // createur par default
262 if( nbinew <= 0 ) return;
263
264 // memorisation de l'HProf original
265 HProf H(*this);
266
267 // Rebin de la partie Histo
268 int_4 binold = mBins;
269 Histo::HRebin(nbinew);
270
271 // Le nombre de bins est il plus grand ??
272 if( mBins > binold ) {
273 delete [] SumY; SumY = new r_8[nbinew]; memset(SumY, 0,mBins*sizeof(r_8));
274 delete [] SumY2; SumY2 = new r_8[nbinew]; memset(SumY2,0,mBins*sizeof(r_8));
275 delete [] SumW; SumW = new r_8[nbinew]; memset(SumW, 0,mBins*sizeof(r_8));
276 }
277
278 // Remplissage des parties propres au HPprof
279 for(int_4 i=0;i<mBins;i++) {
280 r_8 xmi = BinLowEdge(i);
281 r_8 xma = BinHighEdge(i);
282 int_4 imi = H.FindBin(xmi);
283 if( imi < 0 ) imi = 0;
284 int_4 ima = H.FindBin(xma);
285 if( ima >= H.mBins ) ima = H.mBins-1;
286 r_8 wY = 0., wY2 = 0., wW = 0.;
287 if( ima == imi ) {
288 wY = H.SumY[imi] * binWidth/H.binWidth;
289 wY2 = H.SumY2[imi] * binWidth/H.binWidth;
290 wW = H.SumW[imi] * binWidth/H.binWidth;
291 } else {
292 wY += H.SumY[imi] * (H.BinHighEdge(imi)-xmi)/H.binWidth;
293 wY += H.SumY[ima] * (xma -H.BinLowEdge(ima))/H.binWidth;
294 wY2 += H.SumY2[imi] * (H.BinHighEdge(imi)-xmi)/H.binWidth;
295 wY2 += H.SumY2[ima] * (xma -H.BinLowEdge(ima))/H.binWidth;
296 wW += H.SumW[imi] * (H.BinHighEdge(imi)-xmi)/H.binWidth;
297 wW += H.SumW[ima] * (xma -H.BinLowEdge(ima))/H.binWidth;
298 if(ima>imi+1) for(int_4 ii=imi+1;ii<ima;ii++)
299 {wY += H.SumY[ii]; wY2 += H.SumY2[ii]; wW += H.SumW[ii];}
300 }
301 SumY[i] += wY; SumY2[i] += wY2; SumW[i] += wW;
302 }
303 // On synchronise les tableaux Sum?? et l'Histogramme
304 updatehisto();
305}
306
307///////////////////////////////////////////////////////////
308// --------------------------------------------------------
309// Les objets delegues pour la gestion de persistance
310// --------------------------------------------------------
311///////////////////////////////////////////////////////////
312
313
314void ObjFileIO<HProf>::ReadSelf(PInPersist& is)
315{
316char strg[256];
317
318if(dobj==NULL) dobj=new HProf;
319 else dobj->Delete();
320
321// Lecture entete
322is.GetLine(strg,255);
323
324// Lecture des valeurs
325is.Get(dobj->mBins);
326is.Get(dobj->YMin);
327is.Get(dobj->YMax);
328is.Get(dobj->Opt);
329dobj->Ok = true;
330
331// Lecture des donnees propres a l'histogramme de profil.
332is.GetLine(strg,255);
333dobj->SumY = new r_8[dobj->mBins];
334dobj->SumY2 = new r_8[dobj->mBins];
335dobj->SumW = new r_8[dobj->mBins];
336is.Get(dobj->SumY, dobj->mBins);
337is.Get(dobj->SumY2, dobj->mBins);
338is.Get(dobj->SumW, dobj->mBins);
339
340// Lecture de l'histogramme
341is >> (Histo&)(*dobj);
342return;
343}
344
345void ObjFileIO<HProf>::WriteSelf(POutPersist& os) const
346{
347if (dobj == NULL) return;
348char strg[256];
349
350dobj->UpdateHisto();
351
352// Ecriture entete pour identifier facilement
353sprintf(strg,"HProf: YMin=%f YMax=%f Opt=%1d",dobj->YMin,dobj->YMax,dobj->Opt);
354os.PutLine(strg);
355
356// Ecriture des valeurs
357os.Put(dobj->mBins);
358os.Put(dobj->YMin);
359os.Put(dobj->YMax);
360os.Put(dobj->Opt);
361
362// Ecriture des donnees propres a l'histogramme de profil.
363sprintf(strg,"HProf: SumY SumY2 SumW");
364os.PutLine(strg);
365os.Put(dobj->SumY, dobj->mBins);
366os.Put(dobj->SumY2, dobj->mBins);
367os.Put(dobj->SumW, dobj->mBins);
368
369// Ecriture de l'histogramme
370// FIO_Histo fio_h((Histo&)*dobj);
371// fio_h.Write(os);
372os << (Histo&)(*dobj);
373
374return;
375}
376
377#ifdef __CXX_PRAGMA_TEMPLATES__
378#pragma define_template ObjFileIO<HProf>
379#endif
380
381#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
382template class ObjFileIO<HProf>;
383#endif
Note: See TracBrowser for help on using the repository browser.