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

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

cmv 7/7/2000

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