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