source: Sophya/trunk/SophyaLib/NTools/histos.cc@ 433

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

FIO_... + grosses modifs cmv 19/5/99

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