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

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

Methode Show et operateur << pour Histos - Reza 20/2/2001

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