source: Sophya/trunk/SophyaLib/HiStats/histos.cc@ 1053

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

les friend operator ne marche plus ? passage en inline cmv 30/06/00

File size: 35.8 KB
Line 
1//
2// $Id: histos.cc,v 1.6 2000-06-30 13:21:52 ansari Exp $
3//
4
5#include "machdefs.h"
6#include <string.h>
7#include <stdio.h>
8#include <math.h>
9#include "histos.h"
10#include "perrors.h"
11#include "poly.h"
12#include "strutil.h"
13#include "generalfit.h"
14
15/*!
16 \class SOPHYA::Histo
17 \ingroup HiStats
18 Classe d'histogrammes 1D
19*/
20
21/********* Methode *********/
22/*! Constructeur par defaut */
23Histo::Histo()
24: data(NULL), err2(NULL),
25 under(0), over(0), nHist(0), nEntries(0),
26 bins(0), min(0), max(0),
27 binWidth(0)
28{
29 END_CONSTRUCTOR
30}
31
32/********* Methode *********/
33/*! Constructeur d'un histo de nBin bins allant de xMin a xMax */
34Histo::Histo(float xMin, float xMax, int nBin)
35: data(new float[nBin]), err2(NULL),
36 under(0), over(0), nHist(0), nEntries(0),
37 bins(nBin), min(xMin), max(xMax),
38 binWidth((max - min)/nBin)
39{
40 Zero();
41 END_CONSTRUCTOR
42}
43
44/********* Methode *********/
45/*! Constructeur par copie */
46Histo::Histo(const Histo& H)
47: data(new float[H.bins]), err2(NULL),
48 under(H.under), over(H.over), nHist(H.nHist), nEntries(H.nEntries),
49 bins(H.bins), min(H.min), max(H.max),
50 binWidth(H.binWidth)
51{
52 memcpy(data, H.data, bins*sizeof(float));
53 if( H.err2 != NULL ) {
54 err2 = new double[bins];
55 memcpy(err2, H.err2, bins*sizeof(double));
56 }
57 END_CONSTRUCTOR
58}
59
60/********* Methode *********/
61/*! Gestion de la des-allocation */
62void Histo::Delete()
63{
64 if( data != NULL ) { delete[] data; data = NULL;}
65 if( err2 != NULL ) { delete[] err2; err2 = NULL;}
66 under = over = min = max = binWidth= 0.;
67 nHist = 0.;
68 nEntries = bins = 0;
69}
70
71/********* Methode *********/
72/*! Destructeur */
73Histo::~Histo()
74{
75Delete();
76}
77
78/********* Methode *********/
79/*!
80 Remise a zero
81*/
82void Histo::Zero()
83{
84 memset(data, 0, bins*sizeof(float));
85 under = over = 0;
86 nHist = 0;
87 nEntries = 0;
88 if( err2 != NULL ) memset(err2, 0, bins*sizeof(double));
89}
90
91/********* Methode *********/
92/*!
93 Pour avoir le calcul des erreurs
94*/
95void Histo::Errors()
96{
97 if( bins > 0 ) {
98 if(err2==NULL) err2 = new double[bins];
99 memset(err2, 0, bins*sizeof(double));
100 }
101}
102
103/********* Methode *********/
104/*!
105 Operateur egal
106*/
107Histo& Histo::operator = (const Histo& h)
108{
109 if(this == &h) return *this;
110 if( h.bins > bins ) Delete();
111 if(!data) data = new float[h.bins];
112 if( !h.err2 && err2 ) { delete [] err2; err2=NULL;}
113 if( h.err2 && !err2 ) err2 = new double[h.bins];
114
115 under = h.under;
116 over = h.over;
117 nHist = h.nHist;
118 nEntries = h.nEntries;
119 bins = h.bins;
120 min = h.min;
121 max = h.max;
122 binWidth = h.binWidth;
123
124 memcpy(data, h.data, bins*sizeof(float));
125 if(err2) memcpy(err2, h.err2, bins*sizeof(double));
126
127 return *this;
128}
129
130/********* Methode *********/
131/*!
132 Operateur de multiplication par une constante
133*/
134Histo& Histo::operator *= (double b)
135{
136double b2 = b*b;
137for(int i=0;i<bins;i++) {
138 data[i] *= b;
139 if(err2) err2[i] *= b2;
140}
141under *= b;
142over *= b;
143nHist *= b;
144
145return *this;
146}
147
148/*!
149 Operateur de division par une constante
150*/
151Histo& Histo::operator /= (double b)
152{
153if (b==0.) THROW(inconsistentErr);
154double b2 = b*b;
155for(int i=0;i<bins;i++) {
156 data[i] /= b;
157 if(err2) err2[i] /= b2;
158}
159under /= b;
160over /= b;
161nHist /= b;
162
163return *this;
164}
165
166/*!
167 Operateur d'addition d'une constante
168*/
169Histo& Histo::operator += (double b)
170{
171for(int i=0;i<bins;i++) data[i] += b;
172under += b;
173over += b;
174nHist += bins*b;
175
176return *this;
177}
178
179/*!
180 Operateur de soustraction d'une constante
181*/
182Histo& Histo::operator -= (double b)
183{
184for(int i=0;i<bins;i++) data[i] -= b;
185under -= b;
186over -= b;
187nHist -= bins*b;
188
189return *this;
190}
191
192/********* Methode *********/
193/*!
194 Operateur H += H1
195*/
196Histo& Histo::operator += (const Histo& a)
197{
198if(bins!=a.bins) THROW(sizeMismatchErr);
199for(int i=0;i<bins;i++) {
200 data[i] += a(i);
201 if(err2 && a.err2) err2[i] += a.Error2(i);
202}
203under += a.under;
204over += a.over;
205nHist += a.nHist;
206nEntries += a.nEntries;
207
208return *this;
209}
210
211/*!
212 Operateur H -= H1
213*/
214Histo& Histo::operator -= (const Histo& a)
215{
216if(bins!=a.bins) THROW(sizeMismatchErr);
217for(int i=0;i<bins;i++) {
218 data[i] -= a(i);
219 if(err2 && a.err2) err2[i] += a.Error2(i);
220}
221under -= a.under;
222over -= a.over;
223nHist -= a.nHist;
224nEntries += a.nEntries;
225
226return *this;
227}
228
229/*!
230 Operateur H *= H1
231*/
232Histo& Histo::operator *= (const Histo& a)
233{
234if(bins!=a.bins) THROW(sizeMismatchErr);
235nHist = 0.;
236for(int i=0;i<bins;i++) {
237 if(err2 && a.err2)
238 err2[i] = a(i)*a(i)*err2[i] + data[i]*data[i]*a.Error2(i);
239 data[i] *= a(i);
240 nHist += data[i];
241}
242under *= a.under;
243over *= a.over;
244nEntries += a.nEntries;
245
246return *this;
247}
248
249/*!
250 Operateur H /= H1
251*/
252Histo& Histo::operator /= (const Histo& a)
253{
254if(bins!=a.bins) THROW(sizeMismatchErr);
255nHist = 0.;
256for(int i=0;i<bins;i++) {
257 if(a(i)==0.) {
258 data[i]=0.;
259 if(err2) err2[i]=0.;
260 continue;
261 }
262 if(err2 && a.err2)
263 err2[i] = (err2[i] + data[i]/a(i)*data[i]/a(i)*a.Error2(i))
264 /(a(i)*a(i));
265 data[i] /= a(i);
266 nHist += data[i];
267}
268if(a.under!=0.) under /= a.under; else under = 0.;
269if(a.over!=0.) over /= a.over; else over = 0.;
270nEntries += a.nEntries;
271
272return *this;
273}
274
275/********* Methode *********/
276/*!
277 Remplissage d'un tableau avec la valeur des abscisses
278*/
279void Histo::GetAbsc(TVector<r_8> &v)
280{
281v.Realloc(bins);
282for(int i=0;i<bins;i++) v(i) = BinLowEdge(i);
283return;
284}
285
286/*!
287 Remplissage d'un tableau avec la valeur du contenu
288*/
289void Histo::GetValue(TVector<r_8> &v)
290{
291v.Realloc(bins);
292for(int i=0;i<bins;i++) v(i) = data[i];
293return;
294}
295
296/*!
297 Remplissage d'un tableau avec la valeur des erreurs au carre
298*/
299void Histo::GetError2(TVector<r_8> &v)
300{
301v.Realloc(bins);
302if(!err2) {for(int i=0;i<bins;i++) v(i) = 0.; return;}
303for(int i=0;i<bins;i++) v(i) = err2[i];
304return;
305}
306
307/*!
308 Remplissage d'un tableau avec la valeur des erreurs
309*/
310void Histo::GetError(TVector<r_8> &v)
311{
312v.Realloc(bins);
313if(!err2) {for(int i=0;i<bins;i++) v(i) = 0.; return;}
314for(int i=0;i<bins;i++) v(i) = Error(i);
315return;
316}
317
318/********* Methode *********/
319/*!
320 Remplissage du contenu de l'histo avec les valeurs d'un vecteur
321*/
322void Histo::PutValue(TVector<r_8> &v, int ierr)
323{
324if(v.NElts()<(uint_4) bins) THROW(sizeMismatchErr);
325for(int i=0;i<bins;i++) {
326 data[i] = v(i);
327 if(err2&&ierr) err2[i] = fabs(v(i));
328}
329return;
330}
331
332/*!
333 Addition du contenu de l'histo avec les valeurs d'un vecteur
334*/
335void Histo::PutValueAdd(TVector<r_8> &v, int ierr)
336{
337if(v.NElts()<(uint_4) bins) THROW(sizeMismatchErr);
338for(int i=0;i<bins;i++) {
339 data[i] += v(i);
340 if(err2 && ierr) err2[i] += fabs(v(i));
341}
342return;
343}
344
345/*!
346 Remplissage des erreurs au carre de l'histo avec les valeurs d'un vecteur
347*/
348void Histo::PutError2(TVector<r_8> &v)
349{
350if(v.NElts()<(uint_4) bins) THROW(sizeMismatchErr);
351if(!err2) Errors();
352for(int i=0;i<bins;i++) err2[i] = v(i);
353return;
354}
355
356/*!
357 Addition des erreurs au carre de l'histo avec les valeurs d'un vecteur
358*/
359void Histo::PutError2Add(TVector<r_8> &v)
360{
361if(v.NElts()<(uint_4) bins) THROW(sizeMismatchErr);
362if(!err2) Errors();
363for(int i=0;i<bins;i++) if(v(i)>0.) err2[i] += v(i);
364return;
365}
366
367/*!
368 Remplissage des erreurs de l'histo avec les valeurs d'un vecteur
369*/
370void Histo::PutError(TVector<r_8> &v)
371{
372if(v.NElts()<(uint_4) bins) THROW(sizeMismatchErr);
373if(!err2) Errors();
374for(int i=0;i<bins;i++)
375 if(v(i)>0.) err2[i]=v(i)*v(i); else err2[i]=-v(i)*v(i);
376return;
377}
378
379/********* Methode *********/
380/*!
381 Addition du contenu de l'histo pour abscisse x poids w
382*/
383void Histo::Add(float x, float w)
384{
385 int numBin = FindBin(x);
386 if (numBin<0) under += w;
387 else if (numBin>=bins) over += w;
388 else {
389 data[numBin] += w;
390 if(err2!=NULL) err2[numBin] += w*w;
391 nHist += w;
392 nEntries++;
393 }
394}
395
396/********* Methode *********/
397/*!
398 Addition du contenu de l'histo bin numBin poids w
399*/
400void Histo::AddBin(int numBin, float w)
401{
402 if (numBin<0) under += w;
403 else if (numBin>=bins) over += w;
404 else {
405 data[numBin] += w;
406 if(err2!=NULL) err2[numBin] += w*w;
407 nHist += w;
408 nEntries++;
409 }
410}
411
412/********* Methode *********/
413/*!
414 Remplissage du contenu de l'histo pour abscisse x poids w
415*/
416void Histo::SetBin(float x, float w)
417{
418 int numBin = FindBin(x);
419 SetBin(numBin,w);
420}
421
422/********* Methode *********/
423/*!
424 Remplissage du contenu de l'histo pour numBin poids w
425*/
426void Histo::SetBin(int numBin, float w)
427{
428 if (numBin<0) under = w;
429 else if (numBin>=bins) over = w;
430 else {
431 nHist -= data[numBin];
432 data[numBin] = w;
433 nHist += w;
434 }
435}
436
437/********* Methode *********/
438/*!
439 Remplissage des erreurs au carre pour abscisse x
440*/
441void Histo::SetErr2(float x, double e2)
442{
443 int numBin = FindBin(x);
444 SetErr2(numBin,e2);
445}
446
447/********* Methode *********/
448/*!
449 Remplissage des erreurs au carre pour numBin poids
450*/
451void Histo::SetErr2(int numBin, double e2)
452{
453 if( err2==NULL) return;
454 if ( numBin<0 || numBin>=bins ) return;
455 err2[numBin] = e2;
456}
457
458/********* Methode *********/
459/*!
460 Remplissage des erreurs pour abscisse x
461*/
462void Histo::SetErr(float x, float e)
463{
464SetErr2(x, (double) e*e);
465}
466
467/********* Methode *********/
468/*!
469 Remplissage des erreurs pour numBin
470*/
471void Histo::SetErr(int numBin, float e)
472{
473SetErr2(numBin, (double) e*e);
474}
475
476/********* Methode *********/
477/*!
478 Numero du bin ayant le contenu maximum
479*/
480int Histo::IMax() const
481{
482 int imx=0;
483 if(bins==1) return imx;
484 float mx=data[0];
485 for (int i=1; i<bins; i++)
486 if (data[i]>mx) {imx = i; mx=data[i];}
487 return imx;
488}
489
490/********* Methode *********/
491/*!
492 Numero du bin ayant le contenu minimum
493*/
494int Histo::IMin() const
495{
496 int imx=0;
497 if(bins==1) return imx;
498 float mx=data[0];
499 for (int i=1; i<bins; i++)
500 if (data[i]<mx) {imx = i; mx=data[i];}
501 return imx;
502}
503
504/********* Methode *********/
505/*!
506 Valeur le contenu maximum
507*/
508float Histo::VMax() const
509{
510 float mx=data[0];
511 if(bins==1) return mx;
512 for (int i=1;i<bins;i++) if(data[i]>mx) mx=data[i];
513 return mx;
514}
515
516/********* Methode *********/
517/*!
518 Valeur le contenu minimum
519*/
520float Histo::VMin() const
521{
522 float mx=data[0];
523 if(bins==1) return mx;
524 for (int i=1;i<bins;i++) if(data[i]<mx) mx=data[i];
525 return mx;
526}
527
528/********* Methode *********/
529/*!
530 Valeur moyenne
531*/
532float Histo::Mean() const
533{
534 double n = 0;
535 double sx = 0;
536 for (int i=0; i<bins; i++) {
537 double v = (data[i]>=0.) ? data[i] : -data[i];
538 n += v;
539 sx += BinCenter(i)*v;
540 }
541 if(n>0.) return sx/n; else return min;
542}
543
544/********* Methode *********/
545/*!
546 Valeur du sigma
547*/
548float Histo::Sigma() const
549{
550 double n = 0;
551 double sx = 0;
552 double sx2= 0;
553 for (int i=0; i<bins; i++) {
554 double v = (data[i]>=0.) ? data[i] : -data[i];
555 n += v;
556 sx += BinCenter(i)*v;
557 sx2+= BinCenter(i)*BinCenter(i)*v;
558 }
559 // attention a l'erreur d'arrondi si un seul bin rempli!!
560 if( n == 0 ) return 0.;
561 sx2 = sx2/n - (sx/n)*(sx/n);
562 if( sx2>0. ) return sqrt( sx2 );
563 else return 0.;
564}
565
566/********* Methode *********/
567/*!
568 Valeur de la moyenne calculee entre les bin il et ih
569*/
570float Histo::MeanLH(int il,int ih) const
571{
572 if( ih < il ) { il = 0; ih = bins-1; }
573 if( il < 0 ) il = 0;
574 if( ih >= bins ) ih = bins-1;
575 double n = 0;
576 double sx = 0;
577 for (int i=il; i<=ih; i++) {
578 double v = (data[i]>=0.) ? data[i] : -data[i];
579 n += v;
580 sx += BinCenter(i)*v;
581 }
582 if(n>0.) return sx/n; else return BinLowEdge(il);
583}
584
585/********* Methode *********/
586/*!
587 Valeur de la moyenne calculee entre les bin il et ih
588*/
589float Histo::SigmaLH(int il,int ih) const
590{
591 if( ih < il ) { il = 0; ih = bins - 1; }
592 if( il < 0 ) il = 0;
593 if( ih >= bins ) ih = bins - 1;
594 double n = 0;
595 double sx = 0;
596 double sx2= 0;
597 for (int i=il; i<=ih; i++) {
598 double v = (data[i]>=0.) ? data[i] : -data[i];
599 n += v;
600 sx += BinCenter(i)*v;
601 sx2+= BinCenter(i)*BinCenter(i)*v;
602 }
603 if( n == 0 ) return 0.;
604 sx2 = sx2/n - (sx/n)*(sx/n);
605 if( sx2>0. ) return sqrt( sx2 );
606 else return 0.;
607}
608
609/********* Methode *********/
610/*!
611 Valeur de la moyenne calculee entre x0-dx et x0+dx
612*/
613float Histo::Mean(float x0, float dx) const
614{
615 double sdata = 0;
616 double sx = 0;
617 int iMin = FindBin(x0-dx);
618 if (iMin<0) iMin = 0;
619 int iMax = FindBin(x0+dx);
620 if (iMax>bins) iMax=bins;
621 for (int i=iMin; i<iMax; i++) {
622 double v = (data[i]>=0.) ? data[i] : -data[i];
623 sx += BinCenter(i)*v;
624 sdata += v;
625 }
626 if(sdata>0.) return sx/sdata; else return min;
627}
628
629/********* Methode *********/
630/*!
631 Valeur du sigma calcule entre x0-dx et x0+dx
632*/
633float Histo::Sigma(float x0, float dx) const
634{
635 double sx = 0;
636 double sx2= 0;
637 double sdata = 0;
638 int iMin = FindBin(x0-dx);
639 if (iMin<0) iMin = 0;
640 int iMax = FindBin(x0+dx);
641 if (iMax>bins) iMax=bins;
642 for (int i=iMin; i<iMax; i++) {
643 double v = (data[i]>=0.) ? data[i] : -data[i];
644 sx += BinCenter(i)*v;
645 sx2+= BinCenter(i)*BinCenter(i)*v;
646 sdata += v;
647 }
648 if(sdata>0.) return sqrt( sx2/sdata - (sx/sdata)*(sx/sdata) );
649 else return 0.;
650}
651
652/********* Methode *********/
653/*!
654 Valeur de la moyenne et du sigma nettoyes
655*/
656float Histo::CleanedMean(float& sigma) const
657{
658 if (!nHist) return 0;
659 // on fait ca de facon bete, on pourra raffiner apres...
660 float x0 = Mean();
661 float s = Sigma()+binWidth;
662
663 for (int i=0; i<3; i++) {
664 float xx0 = Mean(x0,5*s);
665 s = Sigma(x0,5*s)+binWidth;
666 x0 = xx0;
667 }
668 sigma = s;
669 return x0;
670}
671
672/********* Methode *********/
673/*!
674 Valeur de la moyenne nettoyee
675*/
676float Histo::CleanedMean() const
677{
678 if (!nHist) return 0;
679 float s=0;
680 return CleanedMean(s);
681}
682
683/********* Methode *********/
684/*!
685 Retourne le nombre de bins non-nul
686*/
687int Histo::BinNonNul() const
688{
689int non=0;
690for (int i=0;i<bins;i++) if( data[i] != 0. ) non++;
691return non;
692}
693
694/********* Methode *********/
695/*!
696 Retourne le nombre de bins ayant une erreur non-nulle
697*/
698int Histo::ErrNonNul() const
699{
700if(err2==NULL) return -1;
701int non=0;
702for (int i=0;i<bins;i++) if( err2[i] != 0. ) non++;
703return non;
704}
705
706/********* Methode *********/
707/*!
708 Renvoie le numero de bin tel que il y ait "per" pourcent entrees
709 entre le bin 0 et ce bin (y compris le contenu de ce bin).
710*/
711int Histo::BinPercent(float per) const
712{
713double n = nHist*per;
714double s = 0.;
715int i;
716for(i=0; i<bins; i++ ) {
717 s += data[i];
718 if( s >= n ) break;
719}
720if( i == bins ) i = bins-1;
721return i;
722}
723
724/********* Methode *********/
725/*!
726 Renvoie les numeros de bins imin,imax (0=<i<bins) tels que:
727 \verbatim
728 notons I = bin contenant l'abscisse x
729 N1 = nombre d'entrees entre bin 0 et I compris
730 N2 = nombre d'entrees entre bin I et bins-1 compris
731 imin = bin tel que nombre d'entrees entre imin et I = N1 * per
732 imax = bin tel que nombre d'entrees entre I et imax = N2 * per
733 Return: <0 si echec
734 min(I-imin,imax-I) si ok
735 \endverbatim
736*/
737int Histo::BinPercent(float x,float per,int& imin,int& imax)
738{
739imin = imax = -1;
740if( per <= 0. ) return -1;
741
742int I = FindBin(x);
743if( I<0 || I>=bins ) return -2;
744
745double N1 = 0.; for(int i=0; i<=I; i++) N1 += data[i]; N1 *= per;
746double N2 = 0.; {for(int i=I; i<bins; i++) N2 += data[i]; N2 *= per;}
747
748double n = 0.;
749for(imin=I; imin>=0; imin--) { n += data[imin]; if(n>=N1) break; }
750if( imin<0 ) imin = 0;
751// cout<<"I="<<I<<" imin="<<imin<<" n="<<n<<" N1="<<N1<<endl;
752
753n = 0.;
754for(imax=I; imax<bins; imax++) { n += data[imax]; if(n>=N2) break; }
755if( imax>=bins ) imax = bins-1;
756// cout<<"I="<<I<<" imax="<<imax<<" n="<<n<<" N2="<<N2<<endl;
757
758return ( imax-I > I-imin ) ? I-imin : imax-I ;
759}
760
761/********* Methode *********/
762/*!
763 Idem precedent mais renvoie xmin et xmax
764*/
765int Histo::BinPercent(float x,float per,float& xmin,float& xmax)
766{
767xmin = xmax = 0.;
768int imin,imax;
769int rc = BinPercent(x,per,imin,imax);
770if( rc >= 0 ) { xmin = BinLowEdge(imin); xmax = BinHighEdge(imax); }
771return rc;
772}
773
774/********* Methode *********/
775/*!
776 Remplace l'histogramme par son integrale normalise a norm:
777 si norm <= 0 : pas de normalisation, integration seule
778*/
779void Histo::HInteg(float norm)
780{
781if(bins>1)
782 for(int i=1; i<bins; i++) {
783 data[i] += data[i-1];
784 if(err2!=NULL) err2[i] += err2[i-1];
785 }
786if( norm <= 0. ) return;
787norm /= data[bins-1];
788for(int i=0; i<bins; i++) {
789 data[i] *= norm;
790 if(err2!=NULL) err2[i] *= norm*norm;
791}
792}
793
794/********* Methode *********/
795/*!
796 Remplace l'histogramme par sa derivee
797*/
798void Histo::HDeriv()
799{
800if( bins <= 1 ) return;
801float *temp = new float[bins];
802memcpy(temp, data, bins*sizeof(float));
803if(bins>=3) for(int i=1; i<bins-1; i++)
804 temp[i] = (data[i+1]-data[i-1])/(2.*binWidth);
805temp[0] = (data[1]-data[0])/binWidth;
806temp[bins-1] = (data[bins-1]-data[bins-2])/binWidth;
807memcpy(data, temp, bins*sizeof(float));
808delete [] temp;
809}
810
811/********* Methode *********/
812/*!
813 Pour rebinner l'histogramme sur nbinew bins
814*/
815void Histo::HRebin(int nbinew)
816{
817 if( nbinew <= 0 ) return;
818
819 // memoraisation de l'histogramme original
820 Histo H(*this);
821
822 // Le nombre de bins est il plus grand ??
823 if( nbinew > bins ) {
824 delete [] data; data = NULL;
825 data = new float[nbinew];
826 if( err2 != NULL ) {
827 delete [] err2; err2 = NULL;
828 err2 = new double[nbinew];
829 }
830 }
831
832 // remise en forme de this
833 bins = nbinew;
834 this->Zero();
835 binWidth = (max-min)/bins;
836 // On recopie les parametres qui n'ont pas changes
837 under = H.under;
838 over = H.over;
839
840
841 // Remplissage
842 for(int i=0;i<bins;i++) {
843 float xmi = BinLowEdge(i);
844 float xma = BinHighEdge(i);
845 int imi = H.FindBin(xmi);
846 if( imi < 0 ) imi = 0;
847 int ima = H.FindBin(xma);
848 if( ima >= H.bins ) ima = H.bins-1;
849 double w = 0.;
850 if( ima == imi ) {
851 w = H(imi) * binWidth/H.binWidth;
852 } else {
853 w += H(imi) * (H.BinHighEdge(imi)-xmi)/H.binWidth;
854 w += H(ima) * (xma -H.BinLowEdge(ima))/H.binWidth;
855 if( ima > imi+1 )
856 for(int ii=imi+1;ii<ima;ii++) w += H(ii);
857 }
858 AddBin(i,(float) w);
859 }
860
861}
862
863/********* Methode *********/
864/*!
865 Retourne le nombre de maxima locaux, la valeur du maximum (maxi)
866 et sa position (imax), ainsi que la valeur du second maximum
867 local (maxn) et sa position (imaxn).
868 Attention: si un maximum a la meme valeur sur plusieurs bins
869 consecutifs, le bin le plus a droite est pris.
870*/
871int Histo::MaxiLocal(float& maxi,int& imax,float& maxn,int& imaxn)
872{
873int nml = 0;
874imax = imaxn = -1;
875maxi = maxn = -1.f;
876
877bool up = true;
878bool down = false;
879for(int i=0;i<bins;i++) {
880 if( !up ) if( data[i] > data[i-1] ) up = true;
881 if( up && !down ) {
882 if( i == bins-1 ) down=true;
883 else if( data[i] > data[i+1] ) down=true;
884 }
885
886 if( up && down ) {
887 nml++;
888 up = down = false;
889 if( imax < 0 ) {
890 imax = i; maxi = data[i];
891 } else if( data[i] >= maxi ) {
892 imaxn = imax; maxn = maxi;
893 imax = i; maxi = data[i];
894 } else {
895 if( imaxn < 0 || data[i] >= maxn ) { imaxn = i; maxn = data[i]; }
896 }
897 }
898
899}
900return nml;
901}
902
903/********* Methode *********/
904/*!
905 Fit de la position du maximum de l'histo par un polynome
906 de degre `degree' a `frac' pourcent du maximum.
907 L'histo est suppose etre remplit de valeurs positives
908*/
909float Histo::FitMax(int degree, float frac, int debug) const
910{
911 if (degree < 2 || degree > 3) degree = 3;
912 if (frac <= 0. || frac >= 1.) frac = 0.5;
913
914 if (debug > 1)
915 cout<<"Histo::FitMax : Nb Entrees histo ="<<NEntries()<<endl;
916
917 if (NEntries() < 1) THROW(inconsistentErr);
918
919 int iMax = IMax();
920 float hmax = (*this)(iMax);
921 float xCenter = BinCenter(iMax);
922
923 if(debug>1)
924 cout<<"Max histo i="<<iMax<<" x="<<xCenter<<" v="<<hmax<<endl;
925
926 /* find limits at frac*hmax */
927
928 float limit = frac*hmax;
929
930 volatile int iLow = iMax;
931 while (iLow>0 && (*this)(iLow)>limit) iLow--;
932
933 volatile int iHigh = iMax;
934 while (iHigh<NBins()-1 && (*this)(iHigh)>limit) iHigh++;
935
936 int nLowHigh;
937 for(;;) {
938 nLowHigh = 0;
939 for (int i=iLow; i<=iHigh; i++) if((*this)(i)>0) {
940 if(!err2) nLowHigh++;
941 else if(Error2(i)>0.) nLowHigh++;
942 }
943 if (debug > 1) cout <<"Limites histo "<<iLow<<" - "<<iHigh
944 <<" ("<<nLowHigh<<" non nuls)"<<endl;
945 if( nLowHigh >= degree+1 ) break;
946 iLow--; iHigh++;
947 if(iLow<0 && iHigh>=NBins()) {
948 if (debug>1)
949 cout<<"Mode histogramme = "<<xCenter
950 <<" BinCenter("<<iMax<<")"<<endl;
951 return xCenter;
952 }
953 if(iLow < 0 ) iLow = 0;
954 if(iHigh >= NBins()) iHigh = NBins()-1;
955 }
956
957 TVector<r_8> xFit(nLowHigh);
958 TVector<r_8> yFit(nLowHigh);
959 TVector<r_8> e2Fit(nLowHigh);
960 TVector<r_8> errcoef(1);
961 int ii = 0;
962 for (int j=iLow; j<=iHigh; j++) {
963 if ((*this)(j)>0) {
964 if(!err2) {
965 xFit(ii) = BinCenter(j)-xCenter;
966 yFit(ii) = (*this)(j);
967 e2Fit(ii) = yFit(ii);
968 ii++;
969 } else if(Error2(j)>0.) {
970 xFit(ii) = BinCenter(j)-xCenter;
971 yFit(ii) = (*this)(j);
972 e2Fit(ii) = Error2(j);
973 ii++;
974 }
975 }
976 }
977 if(debug>4) {
978 int k;
979 for(k=0;k<nLowHigh;k++) cout<<" "<<xFit(k); cout<<endl;
980 for(k=0;k<nLowHigh;k++) cout<<" "<<yFit(k); cout<<endl;
981 for(k=0;k<nLowHigh;k++) cout<<" "<<e2Fit(k); cout<<endl;
982 }
983 if( ii != nLowHigh ) THROW(inconsistentErr);
984 Poly pol(degree);
985 TRY {
986 pol.Fit(xFit, yFit, e2Fit, degree, errcoef);
987 if (debug>1) cout << "resultat fit = " << pol << endl;
988 pol.Derivate();
989 } CATCHALL {
990 THROW_SAME;
991 } ENDTRY
992
993 int DPolDeg = pol.Degre();
994 float fd = 0.;
995
996 if (DPolDeg == 0) {
997 // on est dans le cas d'un fit de droite
998 if( pol[0] > 0. ) {
999 // on a fitte une droite de pente >0.
1000 fd = xFit(nLowHigh-1) + binWidth/2. + xCenter;
1001 } else if( pol[0] < 0. ) {
1002 // on a fitte une droite de pente <0.
1003 fd = xFit(0) - binWidth/2. + xCenter;
1004 } else {
1005 // on a fitte une droite de pente =0. (creneau)
1006 fd = (xFit(0)+xFit(nLowHigh-1))/2. + xCenter;
1007 }
1008 } else if (DPolDeg == 1) {
1009 // on est dans le cas d'un fit de parabole
1010 double r=0;
1011 if (pol.Root1(r)==0) THROW(inconsistentErr);
1012 fd = r + xCenter;
1013 } else if (DPolDeg == 2) {
1014 // on est dans le cas d'un fit de cubique
1015 double r1=0;
1016 double r2=0;
1017 if (pol.Root2(r1,r2) == 0) THROW(inconsistentErr);
1018 pol.Derivate();
1019 fd = (pol(r1)<0) ? r1 + xCenter : r2 + xCenter;
1020 } else {
1021 // on est dans un cas non prevu
1022 THROW(inconsistentErr);
1023 }
1024
1025 if(fd>max) fd = max;
1026 if(fd<min) fd = min;
1027
1028 if (debug>1)
1029 cout << "Mode histogramme = " << fd
1030 << " (DerPol.degre =" << DPolDeg
1031 << " pol.coeff[0] =" << pol[0]
1032 << ")" << endl;
1033
1034 return fd;
1035}
1036
1037
1038/********* Methode *********/
1039/*!
1040 Calcul de la largeur a frac pourcent du maximum
1041 autour du bin du maximum.
1042 L'histo est suppose etre remplit de valeurs positives
1043*/
1044float Histo::FindWidth(float frac, int debug) const
1045{
1046 float xmax = BinCenter( IMax() );
1047 return FindWidth(xmax,frac,debug);
1048}
1049
1050/********* Methode *********/
1051/*!
1052 Calcul de la largeur a frac pourcent de la valeur du bin xmax.
1053 L'histo est suppose etre remplit de valeurs positives
1054*/
1055float Histo::FindWidth(float xmax,float frac, int debug) const
1056{
1057 if (frac <= 0 || frac >= 1.) frac = 0.5;
1058
1059 if (debug > 1)
1060 cout << "Histo::FindWidth a " << frac
1061 << " de xmax= " << xmax
1062 << " , ndata= " << NData()
1063 << " , nent= " << NEntries()
1064 << " , nbin= " << NBins() << endl;
1065
1066 if (NEntries() < 1) THROW(inconsistentErr);
1067 if (NBins() < 3) THROW(inconsistentErr);
1068
1069 int iMax = FindBin(xmax);
1070 if (iMax<0 || iMax>=NBins()) THROW(inconsistentErr);
1071 float hmax = data[iMax];
1072 float limit = frac*hmax;
1073 if (debug > 1)
1074 cout << " Max histo[" << iMax << "] = " << hmax
1075 << ", limite " << limit << endl;
1076
1077 int iLow = iMax;
1078 while (iLow>=0 && data[iLow]>limit) iLow--;
1079 if( iLow < 0 ) iLow = 0;
1080
1081 int iHigh = iMax;
1082 while (iHigh<NBins() && data[iHigh]>limit) iHigh++;
1083 if( iHigh >=NBins() ) iHigh = NBins()-1;
1084
1085 float xlow = BinCenter(iLow);
1086 float ylow = data[iLow];
1087
1088 float xlow1=xlow, ylow1=ylow;
1089 if(iLow+1<NBins()) {
1090 xlow1 = BinCenter(iLow+1);
1091 ylow1 = data[iLow+1];
1092 }
1093
1094 float xhigh = BinCenter(iHigh);
1095 float yhigh = data[iHigh];
1096
1097 float xhigh1=xhigh, yhigh1=yhigh;
1098 if(iHigh-1>=0) {
1099 xhigh1 = BinCenter(iHigh-1);
1100 yhigh1 = data[iHigh-1];
1101 }
1102
1103 float xlpred,xhpred,wd;
1104
1105 if(ylow1>ylow) {
1106 xlpred = xlow + (xlow1-xlow)/(ylow1-ylow)*(limit-ylow);
1107 if(xlpred < xlow) xlpred = xlow;
1108 } else xlpred = xlow;
1109
1110 if(yhigh1>yhigh) {
1111 xhpred = xhigh + (xhigh1-xhigh)/(yhigh1-yhigh)*(limit-yhigh);
1112 if(xhpred > xhigh) xhpred = xhigh;
1113 } else xhpred = xhigh;
1114
1115 wd = xhpred - xlpred;
1116
1117 if (debug > 1) {
1118 cout << "Limites histo: " << " Width " << wd << endl;
1119 cout << " Low: [" << iLow << "]=" << ylow << " pred-> " << xlpred
1120 << " - High: [" << iHigh << "]=" << yhigh << " pred-> " << xhpred
1121 << endl;
1122 }
1123
1124 return wd;
1125}
1126
1127
1128/********* Methode *********/
1129/*!
1130 Cf suivant mais im est le bin du maximum de l'histo
1131*/
1132int Histo::EstimeMax(float& xm,int SzPav)
1133{
1134int im = IMax();
1135return EstimeMax(im,xm,SzPav);
1136}
1137
1138/********* Methode *********/
1139/*!
1140 Determine l'abscisses du maximum donne par im
1141 en moyennant dans un pave SzPav autour du maximum
1142 \verbatim
1143 Return:
1144 0 = si fit maximum reussi avec SzPav pixels
1145 1 = si fit maximum reussi avec moins que SzPav pixels
1146 2 = si fit maximum echoue et renvoit BinCenter()
1147 -1 = si echec: SzPav <= 0 ou im hors limites
1148 \endverbatim
1149*/
1150int Histo::EstimeMax(int& im,float& xm,int SzPav)
1151{
1152xm = 0;
1153if( SzPav <= 0 ) return -1;
1154if( im < 0 || im >= bins ) return -1;
1155
1156if( SzPav%2 == 0 ) SzPav++;
1157SzPav = (SzPav-1)/2;
1158
1159int rc = 0;
1160double dxm = 0, wx = 0;
1161for(int i=im-SzPav;i<=im+SzPav;i++) {
1162 if( i<0 || i>= bins ) {rc=1; continue;}
1163 dxm += BinCenter(i) * (*this)(i);
1164 wx += (*this)(i);
1165}
1166
1167if( wx > 0. ) {
1168 xm = dxm/wx;
1169 return rc;
1170} else {
1171 xm = BinCenter(im);
1172 return 2;
1173}
1174
1175}
1176
1177/********* Methode *********/
1178/*!
1179 Determine la largeur a frac% du maximum a gauche (widthG)
1180 et a droite (widthD)
1181*/
1182void Histo::EstimeWidthS(float frac,float& widthG,float& widthD)
1183{
1184int i;
1185widthG = widthD = -1.;
1186if( bins<=1 || frac<=0. || frac>=1. ) return;
1187
1188int imax = 0;
1189float maxi = data[0];
1190for(i=1;i<bins;i++) if(data[i]>maxi) {imax=i; maxi=data[i];}
1191float xmax = BinCenter(imax);
1192float maxf = maxi * frac;
1193
1194// recherche du sigma a gauche
1195widthG = 0.;
1196for(i=imax;i>=0;i--) if( data[i] <= maxf ) break;
1197if(i<0) i=0;
1198if(i<imax) {
1199 if( data[i+1] != data[i] ) {
1200 widthG = BinCenter(i) + binWidth
1201 * (maxf-data[i])/(data[i+1]-data[i]);
1202 widthG = xmax - widthG;
1203 } else widthG = xmax - BinCenter(i);
1204}
1205
1206// recherche du sigma a droite
1207widthD = 0.;
1208for(i=imax;i<bins;i++) if( data[i] <= maxf ) break;
1209if(i>=bins) i=bins-1;
1210if(i>imax) {
1211 if( data[i] != data[i-1] ) {
1212 widthD = BinCenter(i) - binWidth
1213 * (maxf-data[i])/(data[i-1]-data[i]);
1214 widthD -= xmax;
1215 } else widthD = BinCenter(i) - xmax;
1216}
1217
1218}
1219
1220//////////////////////////////////////////////////////////
1221/*!
1222 Fit de l'histogramme par ``gfit''.
1223 \verbatim
1224 typ_err = 0 :
1225 - erreur attachee au bin si elle existe
1226 - sinon 1
1227 typ_err = 1 :
1228 - erreur attachee au bin si elle existe
1229 - sinon max( sqrt(abs(bin) ,1 )
1230 typ_err = 2 :
1231 - erreur forcee a 1
1232 typ_err = 3 :
1233 - erreur forcee a max( sqrt(abs(bin) ,1 )
1234 typ_err = 4 :
1235 - erreur forcee a 1, nulle si bin a zero.
1236 typ_err = 5 :
1237 - erreur forcee a max( sqrt(abs(bin) ,1 ),
1238 nulle si bin a zero.
1239 \endverbatim
1240*/
1241int Histo::Fit(GeneralFit& gfit,unsigned short typ_err)
1242{
1243if(NBins()<=0) return -1000;
1244if(typ_err>5) typ_err=0;
1245
1246GeneralFitData mydata(1,NBins());
1247
1248for(int i=0;i<NBins();i++) {
1249 double x = (double) BinCenter(i);
1250 double f = (double) (*this)(i);
1251 double saf = sqrt(fabs((double) f)); if(saf<1.) saf=1.;
1252 double e=0.;
1253 if(typ_err==0) {if(HasErrors()) e=Error(i); else e=1.;}
1254 else if(typ_err==1) {if(HasErrors()) e=Error(i); else e=saf;}
1255 else if(typ_err==2) e=1.;
1256 else if(typ_err==3) e=saf;
1257 else if(typ_err==4) e=(f==0.)?0.:1.;
1258 else if(typ_err==5) e=(f==0.)?0.:saf;
1259 mydata.AddData1(x,f,e);
1260}
1261
1262gfit.SetData(&mydata);
1263
1264return gfit.Fit();
1265}
1266
1267/*!
1268 Retourne une classe contenant les residus du fit ``gfit''.
1269*/
1270Histo Histo::FitResidus(GeneralFit& gfit)
1271{
1272if(NBins()<=0)
1273 throw(SzMismatchError("Histo::FitResidus: size mismatch\n"));
1274GeneralFunction* f = gfit.GetFunction();
1275if(f==NULL)
1276 throw(NullPtrError("Histo::FitResidus: NULL pointer\n"));
1277TVector<r_8> par = gfit.GetParm();
1278Histo h(*this);
1279for(int i=0;i<NBins();i++) {
1280 double x = (double) BinCenter(i);
1281 h(i) -= (float) f->Value(&x,par.Data());
1282}
1283return h;
1284}
1285
1286/*!
1287 Retourne une classe contenant la fonction du fit ``gfit''.
1288*/
1289Histo Histo::FitFunction(GeneralFit& gfit)
1290{
1291if(NBins()<=0)
1292 throw(SzMismatchError("Histo::FitFunction: size mismatch\n"));
1293GeneralFunction* f = gfit.GetFunction();
1294if(f==NULL)
1295 throw(NullPtrError("Histo::FitFunction: NULL pointer\n"));
1296TVector<r_8> par = gfit.GetParm();
1297Histo h(*this);
1298for(int i=0;i<NBins();i++) {
1299 double x = (double) BinCenter(i);
1300 h(i) = (float) f->Value(&x,par.Data());
1301}
1302return h;
1303}
1304
1305/********* Methode *********/
1306/*!
1307 Impression de l'histogramme dans le fichier fp
1308 \verbatim
1309 hdyn = nombre de colonnes pour imprimer les etoiles
1310 si =0 alors defaut(100),
1311 si <0 pas de print histo seulement infos
1312 hmin = minimum de la dynamique
1313 hmax = maximum de la dynamique
1314 si hmax<=hmin : hmin=VMin() hmax=VMax()
1315 si hmax<=hmin et hmin=0 : hmin=0 hmax=VMax()
1316 sinon : hmin hmax
1317 pflag < 0 : on imprime les informations (nbin,min,...) sans l'histogramme
1318 = 0 : on imprime "BinCenter(i) data[i]" (note "... ...")
1319 bit 0 on : (v=1): numero_bin "... ..."
1320 bit 1 on : (v=2): "... ..." erreur
1321 \endverbatim
1322*/
1323void Histo::PrintF(FILE * fp, int hdyn,float hmin, float hmax,int pflag,
1324 int il, int ih)
1325{
1326
1327
1328 if( il > ih ) { il = 0; ih = bins-1; }
1329 if( il < 0 ) il = 0;
1330 if( ih >= bins ) ih = bins-1;
1331
1332 double dhmin = (double) hmin;
1333 double dhmax = (double) hmax;
1334 double hb,hbmn,hbmx;
1335
1336 if(hdyn==0) hdyn = 100;
1337
1338 cout << "~Histo::Print "
1339 << " nHist=" << nHist << " nEntries=" << nEntries
1340 << " under=" << under << " over=" << over << endl;
1341 cout << " bins=" << bins
1342 << " min=" << min << " max=" << max
1343 << " binWidth=" << binWidth << endl;
1344 cout << " mean=" << Mean() << " r.m.s=" << Sigma() << endl;
1345
1346 if(hdyn<0 || pflag<0 ) return;
1347
1348 if(dhmax<=dhmin) { if(hmin != 0.) dhmin = (double) VMin(); else dhmin=0.;
1349 dhmax = (double) VMax(); }
1350 if(dhmin>dhmax) return;
1351 if(dhmin==dhmax) {dhmin -= 1.; dhmax += 1.;}
1352 double wb = (dhmax-dhmin) / (double) hdyn;
1353
1354 // determination de la position de la valeur zero
1355 int i0 = (int)(-dhmin/wb);
1356
1357 // si le zero est dans la dynamique,
1358 // il doit imperativement etre une limite de bin
1359 if( 0 <= i0 && i0 < hdyn ) {
1360 hbmn = dhmin + i0*wb;
1361 hbmx = hbmn + wb;
1362 if( hbmn != 0. ) {
1363 hbmn *= -1.;
1364 if( hbmn < hbmx ) {
1365 // le zero est + pres du bord negatif du bin
1366 dhmin += hbmn;
1367 dhmax += hbmn;
1368 } else {
1369 // le zero est + pres du bord positif du bin
1370 dhmin -= hbmx;
1371 dhmax -= hbmx;
1372 }
1373 wb = (dhmax-dhmin) / (double) hdyn;
1374 i0 = (int)(-dhmin/wb);
1375 }
1376 }
1377
1378 cout <<" bin minimum="<<dhmin<<" bin maximum="<<dhmax
1379 <<" binw="<<wb<< endl;
1380
1381 char* s = new char[hdyn+1];
1382 s[hdyn] = '\0';
1383
1384 // premiere ligne
1385 {for(int i=0;i<hdyn;i++) s[i] = '=';}
1386 if( 0 <= i0 && i0 < hdyn ) s[i0] = '0';
1387 if(pflag&1) fprintf( fp, "====");
1388 fprintf( fp, "======================");
1389 if(pflag&2 && err2!=NULL) fprintf( fp, "===========");
1390 fprintf( fp, "==%s\n",s);
1391
1392 // histogramme
1393 {for(int i=il;i<=ih;i++) {
1394 for(int k=0;k<hdyn;k++) s[k] = ' ';
1395 hb = (*this)(i);
1396
1397 //choix du bin (hdyn bin entre [dhmin,dhmax[
1398 int ii = (int)( (hb-dhmin)/wb );
1399 if(ii<0) ii = 0; else if(ii>=hdyn) ii = hdyn-1;
1400
1401 // limite du bin
1402 hbmn = dhmin + ii*wb;
1403 hbmx = hbmn + wb;
1404
1405 // remplissage de s[] en tenant compte des courbes +/-
1406 if(i0<0) {
1407 // courbe entierement positive
1408 for(int k=0;k<=ii;k++) s[k] = 'X';
1409 } else if(i0>=hdyn) {
1410 // courbe entierement negative
1411 for(int k=hdyn-1;k>=ii;k--) s[k] = 'X';
1412 } else {
1413 // courbe positive et negative
1414 s[i0] = '|';
1415 if(ii>i0) for(int k=i0+1;k<=ii;k++) s[k] = 'X';
1416 else if(ii<i0) for(int k=ii;k<i0;k++) s[k] = 'X';
1417 else s[ii] = 'X';
1418 }
1419
1420 // valeur a mettre dans le bin le plus haut/bas
1421 int ib;
1422 if(hb>0.) ib = (int)( 10.*(hb-hbmn)/(hbmx-hbmn) );
1423 else if(hb<0.) ib = (int)( 10.*(hbmx-hb)/(hbmx-hbmn) );
1424 else ib = -1;
1425 if(ib==-1) s[ii] = '|';
1426 else if(ib==0) s[ii] = '.';
1427 else if(ib>0 && ib<10) s[ii] = (char)((int) '0' + ib);
1428
1429 // traitement des saturations +/-
1430 if( hb < dhmin ) s[0] = '*';
1431 else if( hb > dhmax ) s[hdyn-1] = '*';
1432
1433 if(pflag&1) fprintf( fp, "%3d ",i);
1434 fprintf( fp, "%10.4g %10.4g ",BinCenter(i),hb);
1435 if(pflag&2 && err2!=NULL) fprintf( fp, "%10.4g ",Error(i));
1436 fprintf( fp, "= %s\n",s);
1437 }}
1438
1439 // derniere ligne
1440 for(int i=0;i<hdyn;i++) s[i] = '=';
1441 if( 0 <= i0 && i0 < hdyn ) s[i0] = '0';
1442 if(pflag&1) fprintf( fp, "====");
1443 fprintf( fp, "======================");
1444 if(pflag&2 && err2!=NULL) fprintf( fp, "===========");
1445 fprintf( fp, "==%s\n",s);
1446
1447 // valeur basse des bins (sur ["ndig-1" digits + signe] = ndig char (>=3))
1448 const int ndig = 7;
1449 char sn[2*ndig+10];
1450 hb = ( fabs(dhmin) > fabs(dhmax) ) ? fabs(dhmin) : fabs(dhmax);
1451 int n;
1452 if( hb > 0. ) n = (int)(log10(hb*1.00000001)); else n = 1;
1453 double scaledig = pow(10.,(double) ndig-2);
1454 double expo = scaledig/pow(10.,(double) n);
1455 // cout <<"n="<<n<<" hb="<<hb<<" scaledig="<<scaledig<<" expo="<<expo<<endl;
1456 for(int k=0;k<ndig;k++) {
1457 for(int i=0;i<hdyn;i++) s[i] = ' ';
1458 {for(int i=0;i<hdyn;i++) {
1459 n = (int)( (dhmin + i*wb)*expo );
1460 for(int j=0;j<2*ndig+10;j++) sn[j] = ' ';
1461 sprintf(sn,"%d%c",n,'\0');
1462 strip(sn,'B',' ');
1463 // cout <<"n="<<n<<" sn=("<<sn<<") l="<<strlen(sn)<<" k="<<k;
1464 if( (int) strlen(sn) > k ) s[i] = sn[k];
1465 // cout <<" s=("<<s<<")"<<endl;
1466 }}
1467 if(pflag&1) fprintf( fp, " ");
1468 fprintf( fp, " ");
1469 if(pflag&2 && err2!=NULL) fprintf( fp, " ");
1470 fprintf( fp, " %s\n",s);
1471 }
1472 fprintf( fp, " (valeurs a multiplier par %.0e)\n",1./expo);
1473
1474 delete[] s;
1475}
1476
1477/********* Methode *********/
1478/*!
1479 Impression de l'histogramme sur stdout
1480*/
1481void Histo::Print(int hdyn,float hmin, float hmax,int pflag,
1482 int il, int ih)
1483{
1484 Histo::PrintF(stdout, hdyn, hmin, hmax, pflag, il, ih);
1485}
1486
1487
1488///////////////////////////////////////////////////////////
1489// --------------------------------------------------------
1490// Les objets delegues pour la gestion de persistance
1491// --------------------------------------------------------
1492///////////////////////////////////////////////////////////
1493
1494void ObjFileIO<Histo>::ReadSelf(PInPersist& is)
1495{
1496char strg[256];
1497
1498if(dobj==NULL) dobj=new Histo;
1499 else dobj->Delete();
1500
1501// Lecture entete
1502is.GetLine(strg, 255);
1503is.GetLine(strg, 255);
1504is.GetLine(strg, 255);
1505
1506// Lecture des valeurs
1507is.Get(dobj->bins);
1508is.Get(dobj->nEntries);
1509int_4 errok;
1510is.Get(errok);
1511
1512is.Get(dobj->binWidth);
1513is.Get(dobj->min);
1514is.Get(dobj->max);
1515is.Get(dobj->under);
1516is.Get(dobj->over);
1517
1518is.Get(dobj->nHist);
1519
1520// Lecture des donnees Histo 1D
1521dobj->data = new float[dobj->bins];
1522is.GetLine(strg, 255);
1523is.Get(dobj->data, dobj->bins);
1524
1525// Lecture des erreurs
1526if(errok) {
1527 is.GetLine(strg, 255);
1528 dobj->err2 = new double[dobj->bins];
1529 is.Get(dobj->err2, dobj->bins);
1530}
1531
1532return;
1533}
1534
1535void ObjFileIO<Histo>::WriteSelf(POutPersist& os) const
1536{
1537if (dobj == NULL) return;
1538char strg[256];
1539
1540// Que faut-il ecrire?
1541int_4 errok = (dobj->err2) ? 1 : 0;
1542
1543// Ecriture entete pour identifier facilement
1544sprintf(strg,"bins=%6d NEnt=%15d errok=%1d",dobj->bins,dobj->nEntries,errok);
1545os.PutLine(strg);
1546sprintf(strg,"binw=%g min=%g max=%g",dobj->binWidth,dobj->min,dobj->max);
1547os.PutLine(strg);
1548sprintf(strg, "under=%g over=%g nHist=%g",dobj->under,dobj->over,dobj->nHist);
1549os.PutLine(strg);
1550
1551// Ecriture des valeurs
1552os.Put(dobj->bins);
1553os.Put(dobj->nEntries);
1554os.Put(errok);
1555
1556os.Put(dobj->binWidth);
1557os.Put(dobj->min);
1558os.Put(dobj->max);
1559os.Put(dobj->under);
1560os.Put(dobj->over);
1561
1562os.Put(dobj->nHist);
1563
1564// Ecriture des donnees Histo 1D
1565sprintf(strg,"Histo: Tableau des donnees %d",dobj->bins);
1566os.PutLine(strg);
1567os.Put(dobj->data, dobj->bins);
1568
1569// Ecriture des erreurs
1570if(errok) {
1571 sprintf(strg,"Histo: Tableau des erreurs %d",dobj->bins);
1572 os.PutLine(strg);
1573 os.Put(dobj->err2, dobj->bins);
1574}
1575
1576return;
1577}
1578
1579#ifdef __CXX_PRAGMA_TEMPLATES__
1580#pragma define_template ObjFileIO<Histo>
1581#endif
1582
1583#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
1584template class ObjFileIO<Histo>;
1585#endif
Note: See TracBrowser for help on using the repository browser.