source: Sophya/trunk/SophyaLib/NTools/hisprof.cc@ 220

Last change on this file since 220 was 220, checked in by ansari, 26 years ago

Creation module DPC/NTools Reza 09/04/99

File size: 8.1 KB
Line 
1#include "defs.h"
2#include <string.h>
3#include <stdio.h>
4#include <math.h>
5#include "hisprof.h"
6#include "perrors.h"
7#include "cvector.h"
8
9//++
10// Class HProf
11// Lib Outils++
12// include hisprof.h
13//
14// Classe de profil d'histogrammes.
15//--
16
17//++
18// Titre Constructeurs
19//--
20
21/********* Methode *********/
22//++
23HProf::HProf()
24//
25// Constructeur par defaut.
26//--
27: Histo()
28, SumY(NULL), SumY2(NULL), SumW(NULL), Ok(false), YMin(1.), YMax(-1.), Opt(0)
29{
30 END_CONSTRUCTOR
31}
32
33/********* Methode *********/
34//++
35HProf::HProf(float xMin, float xMax, int nBin, float yMin, float yMax)
36//
37// Constructeur. Histogramme de profil de ``nBin'' bins entre ``xMin''
38// et ``xMax'' avec coupure d'acceptance sur y entre ``yMin'' et ``yMax''.
39// Si yMin>=yMax alors pas de coupure d'acceptance sur y.
40// Par defaut l'erreur du profil represente la dispersion dans le bin,
41// SetErrOpt(1) permet de demander de calculer l'erreur sur la moyenne.
42//--
43: Histo(xMin,xMax,nBin)
44, SumY(new double[nBin]), SumY2(new double[nBin]), SumW(new double[nBin])
45, Ok(false), YMin(yMin), YMax(yMax), Opt(0)
46{
47 Histo::Errors();
48 Zero();
49 END_CONSTRUCTOR
50}
51
52/********* Methode *********/
53//++
54HProf::HProf(char *flnm)
55//
56// Constructeur a partir d'un fichier ppersist.
57//--
58: Histo()
59, SumY(NULL), SumY2(NULL), SumW(NULL), Ok(false), YMin(1.), YMax(-1.), Opt(0)
60{
61 PInPersist s(flnm);
62 Read(s);
63 END_CONSTRUCTOR
64}
65
66/********* Methode *********/
67//++
68HProf::HProf(const HProf& H)
69//
70// Constructeur par copie.
71//--
72: Histo(H)
73, SumY(new double[H.bins]), SumY2(new double[H.bins]), SumW(new double[H.bins])
74, Ok(H.Ok), YMin(H.YMin), YMax(H.YMax), Opt(H.Opt)
75{
76 memcpy(SumY, H.SumY, bins*sizeof(double));
77 memcpy(SumY2, H.SumY2, bins*sizeof(double));
78 memcpy(SumW, H.SumW, bins*sizeof(double));
79 END_CONSTRUCTOR
80}
81
82/********* Methode *********/
83void HProf::Delete()
84{
85 if( SumY != NULL ) { delete[] SumY; SumY = NULL;}
86 if( SumY2 != NULL ) { delete[] SumY2; SumY2 = NULL;}
87 if( SumW != NULL ) { delete[] SumW; SumW = NULL;}
88 Ok = false;
89}
90
91/********* Methode *********/
92HProf::~HProf()
93{
94Delete();
95}
96
97//++
98// Titre Methodes
99//--
100
101/********* Methode *********/
102//++
103void HProf::Zero()
104//
105// Remise a zero
106//--
107{
108 memset(SumY, 0, bins*sizeof(double));
109 memset(SumY2, 0, bins*sizeof(double));
110 memset(SumW, 0, bins*sizeof(double));
111 Ok = false;
112 Histo::Zero();
113}
114
115/********* Methode *********/
116//++
117void HProf::SetErrOpt(bool spread)
118//
119// Pour changer l'option de calcul de l'erreur du profile.
120// Si ``spread'' = true alors l'erreur represente la dispersion
121// des donnees dans le bin, si = false elle represente l'erreur
122// sur la moyenne du bin.
123//| - Pour le bin (j):
124//| H(j) = sum(y), E(j) = sum(y^2), L(j) = sum(w)
125//| -> s(j) = sqrt(E(j)/L(j) - (H(j)/L(j))^2) dispersion
126//| -> e(j) = s(j)/sqrt(L(j)) erreur sur la moyenne
127//| spread=true: opt=0 : dispersion des donnees dans le bin = s(j)
128//| spread=false: opt=1 : erreur sur la moyenne du bin = e(j)
129//--
130{
131int opt = (spread) ? 0 : 1;
132if(opt!=Opt) {Opt=opt; Ok=false;}
133}
134
135/********* Methode *********/
136//++
137void HProf::UpdateHisto() const
138//
139// Pour mettre a jour l'histogramme de profil.
140// Il est important d'appeler cette methode si on veut
141// utiliser les methodes de la classe Histo qui ne sont
142// pas redefinies dans la classe HProf.
143// En effet, pour des raisons de precision la classe
144// HProf travaille avec des tableaux en double precision
145// et seulement au moment ou l'on a besoin de l'histogramme
146// ce dernier est rempli avec les valeurs demandees (moyenne
147// et dispersion/erreur sur la moyenne).
148//--
149{
150
151float m,e2;
152for(int i=0;i<bins;i++) {
153 if(SumW[i]<=0.) {
154 m = e2 = 0.;
155 } else {
156 m = SumY[i]/SumW[i];
157 e2 = SumY2[i]/SumW[i] - m*m;
158 if(Opt) e2 /= SumW[i];
159 }
160 data[i] = m;
161 err2[i] = e2;
162}
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//++
171void HProf::Add(float x, float y, float w)
172//
173// Addition au contenu de l'histo pour abscisse x de la valeur y et poids w
174//--
175{
176 if(YMax>YMin && (y<YMin || YMax<y)) return;
177 int numBin = FindBin(x);
178 if (numBin<0) under += w;
179 else if (numBin>=bins) over += w;
180 else {
181 Ok = false;
182 SumY[numBin] += y;
183 SumY2[numBin] += y*y;
184 SumW[numBin] += w;
185 nHist += w;
186 nEntries++;
187 }
188}
189
190/********* Methode *********/
191//++
192void HProf::AddBin(int numBin, float y, float w)
193//
194// Addition au contenu de l'histo bin numBin de la valeur y poids w
195//--
196{
197 if(YMax>YMin && (y<YMin || YMax<y)) return;
198 if (numBin<0) under += w;
199 else if (numBin>=bins) over += w;
200 else {
201 Ok = false;
202 SumY[numBin] += y;
203 SumY2[numBin] += y*y;
204 SumW[numBin] += w;
205 nHist += w;
206 nEntries++;
207 }
208}
209
210/********* Methode *********/
211//++
212HProf& HProf::operator = (const HProf& h)
213//
214//--
215{
216if(this == &h) return *this;
217if( h.bins > bins ) Delete();
218Histo *hthis = (Histo *) this;
219*hthis = (Histo) h;
220if(!SumY) SumY = new double[bins];
221if(!SumY2) SumY2 = new double[bins];
222if(!SumW) SumW = new double[bins];
223memcpy(SumY, h.SumY, bins*sizeof(double));
224memcpy(SumY2, h.SumY2, bins*sizeof(double));
225memcpy(SumW, h.SumW, bins*sizeof(double));
226Ok = h.Ok;
227YMin = h.YMin;
228YMax = h.YMax;
229Opt = h.Opt;
230
231return *this;
232}
233
234/********* Methode *********/
235//++
236HProf& HProf::operator += (const HProf& a)
237//
238// Attention dans cette addition il n'y a pas de gestion
239// des YMin et YMax. L'addition est faite meme si les limites
240// en Y de ``a'' sont differentes de celles de ``this''.
241//--
242{
243if(bins!=a.bins) THROW(sizeMismatchErr);
244Histo *hthis = (Histo *) this;
245*hthis += (Histo) a;
246for(int i=0;i<bins;i++) {
247 SumY[i] += a.SumY[i];
248 SumY2[i] += a.SumY2[i];
249 SumW[i] += a.SumW[i];
250}
251Ok = false;
252
253return *this;
254}
255
256/********* Methode *********/
257//++
258HProf operator + (const HProf& a, const HProf& b)
259//
260// Meme commentaire que pour l'operateur +=
261//--
262{
263if (b.bins!=a.bins) THROW(sizeMismatchErr);
264HProf c(a);
265return (c += b);
266}
267
268/********* Methode *********/
269//++
270void HProf::WriteSelf(POutPersist& s) const
271//
272// Ecriture ppersist
273//--
274{
275char strg[256];
276
277UpdateHisto();
278
279// Ecriture entete pour identifier facilement
280sprintf(strg,"HProf: YMin=%f YMax=%f Opt=%1d",YMin,YMax,Opt);
281s.PutLine(strg);
282
283// Ecriture des valeurs
284s.PutI4(bins);
285s.PutR4(YMin);
286s.PutR4(YMax);
287s.PutU2(Opt);
288
289// Ecriture des donnees propres a l'histogramme de profil.
290sprintf(strg,"HProf: SumY SumY2 SumW");
291s.PutLine(strg);
292s.PutR8s(SumY, bins);
293s.PutR8s(SumY2, bins);
294s.PutR8s(SumW, bins);
295
296// Ecriture de l'histogramme
297Histo::WriteSelf(s);
298
299return;
300}
301
302/********* Methode *********/
303//++
304void HProf::ReadSelf(PInPersist& s)
305//
306// Lecture ppersist
307//--
308{
309char strg[256];
310
311Delete();
312
313// Lecture entete
314s.GetLine(strg,255);
315
316// Ecriture des valeurs
317s.GetI4(bins);
318s.GetR4(YMin);
319s.GetR4(YMax);
320s.GetU2(Opt);
321Ok = true;
322
323// Ecriture des donnees propres a l'histogramme de profil.
324s.GetLine(strg,255);
325SumY = new double[bins];
326SumY2 = new double[bins];
327SumW = new double[bins];
328s.GetR8s(SumY, bins);
329s.GetR8s(SumY2, bins);
330s.GetR8s(SumW, bins);
331
332// Ecriture de l'histogramme
333Histo::ReadSelf(s);
334
335return;
336}
337
338
339// Rappel des inlines functions pour commentaires
340//++
341// inline Histo GetHisto()
342// Retourne l'histogramme de profil.
343//--
344//++
345// inline void GetMean(Vector& v)
346// Retourne le contenu de la moyenne dans le vecteur v
347//--
348//++
349// inline void GetError2(Vector& v)
350// Retourne le contenu au carre de la dispersion/erreur dans le vecteur v
351//--
352//++
353// inline float operator()(int i) const
354// Retourne le contenu du bin i
355//--
356//++
357// inline float Error2(int i) const
358// Retourne le carre de la dispersion/erreur du bin i
359//--
360//++
361// inline float Error(int i) const
362// Retourne la dispersion/erreur du bin i
363//--
364//++
365// inline int Fit(GeneralFit& gfit)
366// Fit du profile par ``gfit''.
367//--
368//++
369// inline Histo* FitResidus(GeneralFit& gfit)
370// Retourne l'Histogramme des residus par ``gfit''.
371//--
372//++
373// inline Histo* FitFunction(GeneralFit& gfit)
374// Retourne l'Histogramme de la fonction fittee par ``gfit''.
375//--
376//++
377// inline void Print(int dyn,float hmin,float hmax,int pflag,int il,int ih)
378// Print, voir detail dans Histo::Print
379//--
Note: See TracBrowser for help on using the repository browser.