#include "machdefs.h" #include #include #include #include "hisprof.h" #include "perrors.h" /*! \class SOPHYA::HProf \ingroup HiStats Classe de profil d'histogrammes. */ /********* Methode *********/ /*! Constructeur par defaut. */ HProf::HProf() : Histo() , SumY(NULL), SumY2(NULL), SumW(NULL), Ok(false), YMin(1.), YMax(-1.), Opt(0) { END_CONSTRUCTOR } /********* Methode *********/ /*! Constructeur. Histogramme de profil de ``nBin'' bins entre ``xMin'' et ``xMax'' avec coupure d'acceptance sur y entre ``yMin'' et ``yMax''. Si yMin>=yMax alors pas de coupure d'acceptance sur y. Par defaut l'erreur du profil represente la dispersion dans le bin, SetErrOpt(1) permet de demander de calculer l'erreur sur la moyenne. */ HProf::HProf(float xMin, float xMax, int nBin, float yMin, float yMax) : Histo(xMin,xMax,nBin) , SumY(new double[nBin]), SumY2(new double[nBin]), SumW(new double[nBin]) , Ok(false), YMin(yMin), YMax(yMax), Opt(0) { Histo::Errors(); Zero(); END_CONSTRUCTOR } /********* Methode *********/ /*! Constructeur par copie. */ HProf::HProf(const HProf& H) : Histo(H) , SumY(new double[H.bins]), SumY2(new double[H.bins]), SumW(new double[H.bins]) , Ok(H.Ok), YMin(H.YMin), YMax(H.YMax), Opt(H.Opt) { memcpy(SumY, H.SumY, bins*sizeof(double)); memcpy(SumY2, H.SumY2, bins*sizeof(double)); memcpy(SumW, H.SumW, bins*sizeof(double)); END_CONSTRUCTOR } /********* Methode *********/ /*! Des-allocation */ void HProf::Delete() { if( SumY != NULL ) { delete[] SumY; SumY = NULL;} if( SumY2 != NULL ) { delete[] SumY2; SumY2 = NULL;} if( SumW != NULL ) { delete[] SumW; SumW = NULL;} Ok = false; } /********* Methode *********/ /*! Destructeur */ HProf::~HProf() { Delete(); } /********* Methode *********/ /*! Remise a zero */ void HProf::Zero() { memset(SumY, 0, bins*sizeof(double)); memset(SumY2, 0, bins*sizeof(double)); memset(SumW, 0, bins*sizeof(double)); Ok = false; Histo::Zero(); } /********* Methode *********/ /*! Pour changer l'option de calcul de l'erreur du profile. Si ``spread'' = true alors l'erreur represente la dispersion des donnees dans le bin, si = false elle represente l'erreur sur la moyenne du bin. \verbatim - Pour le bin (j): H(j) = sum(y), E(j) = sum(y^2), L(j) = sum(w) -> s(j) = sqrt(E(j)/L(j) - (H(j)/L(j))^2) dispersion -> e(j) = s(j)/sqrt(L(j)) erreur sur la moyenne spread=true: opt=0 : dispersion des donnees dans le bin = s(j) spread=false: opt=1 : erreur sur la moyenne du bin = e(j) \endverbatim */ void HProf::SetErrOpt(bool spread) { int opt = (spread) ? 0 : 1; if(opt!=Opt) {Opt=opt; Ok=false;} } /********* Methode *********/ /*! Pour mettre a jour l'histogramme de profil. Il est important d'appeler cette methode si on veut utiliser les methodes de la classe Histo qui ne sont pas redefinies dans la classe HProf. En effet, pour des raisons de precision la classe HProf travaille avec des tableaux en double precision et seulement au moment ou l'on a besoin de l'histogramme ce dernier est rempli avec les valeurs demandees (moyenne et dispersion/erreur sur la moyenne). */ void HProf::UpdateHisto() const { float m,e2; for(int i=0;iOk = true; } /********* Methode *********/ /*! Addition au contenu de l'histo pour abscisse x de la valeur y et poids w */ void HProf::Add(float x, float y, float w) { if(YMax>YMin && (y=bins) over += w; else { Ok = false; SumY[numBin] += y; SumY2[numBin] += y*y; SumW[numBin] += w; nHist += w; nEntries++; } } /********* Methode *********/ /*! Addition au contenu de l'histo bin numBin de la valeur y poids w */ void HProf::AddBin(int numBin, float y, float w) { if(YMax>YMin && (y=bins) over += w; else { Ok = false; SumY[numBin] += y; SumY2[numBin] += y*y; SumW[numBin] += w; nHist += w; nEntries++; } } /********* Methode *********/ /*! Operateur H = H1 */ HProf& HProf::operator = (const HProf& h) { if(this == &h) return *this; if( h.bins > bins ) Delete(); Histo *hthis = (Histo *) this; *hthis = (Histo) h; if(!SumY) SumY = new double[bins]; if(!SumY2) SumY2 = new double[bins]; if(!SumW) SumW = new double[bins]; memcpy(SumY, h.SumY, bins*sizeof(double)); memcpy(SumY2, h.SumY2, bins*sizeof(double)); memcpy(SumW, h.SumW, bins*sizeof(double)); Ok = h.Ok; YMin = h.YMin; YMax = h.YMax; Opt = h.Opt; return *this; } /********* Methode *********/ /*! Operateur H += H1 Attention dans cette addition il n'y a pas de gestion des YMin et YMax. L'addition est faite meme si les limites en Y de ``a'' sont differentes de celles de ``this''. */ HProf& HProf::operator += (const HProf& a) { if(bins!=a.bins) THROW(sizeMismatchErr); Histo *hthis = (Histo *) this; *hthis += (Histo) a; for(int i=0;i::ReadSelf(PInPersist& is) { char strg[256]; if(dobj==NULL) dobj=new HProf; else dobj->Delete(); // Lecture entete is.GetLine(strg,255); // Ecriture des valeurs is.Get(dobj->bins); is.Get(dobj->YMin); is.Get(dobj->YMax); is.Get(dobj->Opt); dobj->Ok = true; // Ecriture des donnees propres a l'histogramme de profil. is.GetLine(strg,255); dobj->SumY = new double[dobj->bins]; dobj->SumY2 = new double[dobj->bins]; dobj->SumW = new double[dobj->bins]; is.Get(dobj->SumY, dobj->bins); is.Get(dobj->SumY2, dobj->bins); is.Get(dobj->SumW, dobj->bins); // Ecriture de l'histogramme is >> (Histo&)(*dobj); return; } void ObjFileIO::WriteSelf(POutPersist& os) const { if (dobj == NULL) return; char strg[256]; dobj->UpdateHisto(); // Ecriture entete pour identifier facilement sprintf(strg,"HProf: YMin=%f YMax=%f Opt=%1d",dobj->YMin,dobj->YMax,dobj->Opt); os.PutLine(strg); // Ecriture des valeurs os.Put(dobj->bins); os.Put(dobj->YMin); os.Put(dobj->YMax); os.Put(dobj->Opt); // Ecriture des donnees propres a l'histogramme de profil. sprintf(strg,"HProf: SumY SumY2 SumW"); os.PutLine(strg); os.Put(dobj->SumY, dobj->bins); os.Put(dobj->SumY2, dobj->bins); os.Put(dobj->SumW, dobj->bins); // Ecriture de l'histogramme // FIO_Histo fio_h((Histo&)*dobj); // fio_h.Write(os); os << (Histo&)(*dobj); return; } #ifdef __CXX_PRAGMA_TEMPLATES__ #pragma define_template ObjFileIO #endif #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES) template class ObjFileIO; #endif