// // cmv 05/08/96 // #include "machdefs.h" #include #include #include #include #ifndef NO_VALUES_H #include #endif #include "histos2.h" /*! \class SOPHYA::Histo2D \ingroup HiStats Classe d'histogrammes 2D \verbatim Remarque sur les indices: H(i,j) -> i = coord x (0 ii = ligne (0ii et j<->jj ce qui, en representation classique des histos2D et des matrices entraine une inversion x<->y cad une symetrie / diagonale principale H(0,...) represente ^ mais v(0,...) represente |x....... |xxxxxxxx| |x....... |........| |x....... |........| |x....... |........| |x....... |........| ---------> colonne no 1 ligne no 1 \endverbatim */ /////////////////////////////////////////////////////////////////// /*! Createur d'un histogramme 2D ayant nxBin,nyBin bins entre xMin,xMax et yMin,yMax. */ Histo2D::Histo2D(r_8 xMin,r_8 xMax,int_4 nxBin,r_8 yMin,r_8 yMax,int_4 nyBin) : mData(new r_8[nxBin*nyBin]), mErr2(NULL) , nHist(0), nEntries(0) , mNx(nxBin), mNy(nyBin), mNxy(nxBin*nyBin) , mXmin(xMin), mXmax(xMax), mYmin(yMin), mYmax(yMax) , mWBinx((xMax - xMin)/nxBin), mWBiny((yMax - yMin)/nyBin) , mHprojx(NULL), mHprojy(NULL) { ASSERT(nxBin>0 && nyBin>0 && xMin0 && nyBin>0 && xMin0) { SetSliX(nb); for(i=0; i0) { SetSliY(nb); for(i=0; i0) { for(i=0; i0) { for(i=0; i 0 ) { if(mErr2==NULL) mErr2 = new r_8[mNxy]; memset(mErr2, 0, mNxy*sizeof(r_8)); } } /////////////////////////////////////////////////////////////////// /*! Operateur H2 = H1 */ Histo2D& Histo2D::operator = (const Histo2D& h) { int_4 i,j,nb; r_8 min,max; if(this == &h) return *this; if( h.mNxy > mNxy ) Delete(); if(!mData) mData = new r_8[h.mNxy]; if( !h.mErr2 && mErr2 ) { delete [] mErr2; mErr2=NULL;} if( h.mErr2 && !mErr2 ) mErr2 = new r_8[h.mNxy]; for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] = h.mOver[i][j]; nHist = h.nHist; nEntries = h.nEntries; mNx = h.mNx; mNy = h.mNy; mNxy = h.mNxy; mXmin = h.mXmin; mXmax = h.mXmax; mWBinx = h.mWBinx; mYmin = h.mYmin; mYmax = h.mYmax; mWBiny = h.mWBiny; memcpy(mData, h.mData, mNxy*sizeof(r_8)); if(mErr2) memcpy(mErr2, h.mErr2, mNxy*sizeof(r_8)); DelProjX(); if(h.mHprojx) { SetProjX(); *mHprojx = *(h.mHprojx); } DelProjY(); if(h.mHprojy) { SetProjY(); *mHprojy = *(h.mHprojy); } DelSliX(); nb = h.NSliX(); if(nb>0) { SetSliX(nb); for(i=0; i0) { SetSliY(nb); for(i=0; i0) { for(i=0; i0) { for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i0) for(i=0; i &v) const { r_8 x,y; v.Realloc(mNx); for(int_4 i=0;i &v) const { r_8 x,y; v.Realloc(mNy); for(int_4 i=0;i &v) const { v.Realloc(mNx,mNy); for(int_4 i=0;i &v) const { int_4 i,j; v.Realloc(mNx,mNy); if(!mErr2) {for(i=0;i &v) const { int_4 i,j; v.Realloc(mNx,mNy); if(!mErr2) {for(i=0;i &v, int_4 ierr) { //if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) THROW(sizeMismatchErr); uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx; uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy; if(nnx>0 && nny>0) for(uint_4 i=0;i &v, int_4 ierr) { //if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) THROW(sizeMismatchErr); uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx; uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy; if(nnx>0 && nny>0) for(uint_4 i=0;i &v) { //if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) THROW(sizeMismatchErr); uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx; uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy; if(nnx>0 && nny>0) { if(!mErr2) Errors(); for(uint_4 i=0;i &v) { //if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) THROW(sizeMismatchErr); uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx; uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy; if(nnx>0 && nny>0) { if(!mErr2) Errors(); for(uint_4 i=0;i0.) Error2(i,j) += v(i,j); } return; } /*! Remplissage des erreurs de l'histo avec les valeurs d'un tableau. */ void Histo2D::PutError(TMatrix &v) { //if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) THROW(sizeMismatchErr); uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx; uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy; if(nnx>0 && nny>0) { if(!mErr2) Errors(); for(uint_4 i=0;i0.) Error2(i,j)=v(i,j)*v(i,j); else Error2(i,j)= -v(i,j)*v(i,j); } return; } /////////////////////////////////////////////////////////////////// /********* Methode *********/ /*! Addition du contenu de l'histo pour x,y poids w. */ void Histo2D::Add(r_8 x, r_8 y, r_8 w) { list::iterator it; int_4 i,j; FindBin(x,y,i,j); if( mHprojx != NULL ) mHprojx->Add(x,w); if( mHprojy != NULL ) mHprojy->Add(y,w); if(mLBandx.size()>0) for( it = mLBandx.begin(); it != mLBandx.end(); it++) if( (*it).min <= y && y < (*it).max ) (*it).H->Add(x,w); if(mLBandy.size()>0) for( it = mLBandy.begin(); it != mLBandy.end(); it++) if( (*it).min <= x && x < (*it).max ) (*it).H->Add(y,w); if(mLSlix.size()>0) for( it = mLSlix.begin(); it != mLSlix.end(); it++) if( (*it).min <= y && y < (*it).max ) (*it).H->Add(x,w); if(mLSliy.size()>0) for( it = mLSliy.begin(); it != mLSliy.end(); it++) if( (*it).min <= x && x < (*it).max ) (*it).H->Add(y,w); if( i<0 || i>=mNx || j<0 || j>=mNy ) { if(i<0) i=0; else if(i>=mNx) i=2; else i=1; if(j<0) j=0; else if(j>=mNy) j=2; else j=1; mOver[i][j] += w; mOver[1][1] += w; return; } mData[j*mNx+i] += w; if(mErr2!=NULL) mErr2[j*mNx+i] += w*w; nHist += w; nEntries++; } /////////////////////////////////////////////////////////////////// /*! Recherche du bin du maximum dans le pave [il,ih][jl,jh]. */ void Histo2D::IJMax(int_4& imax,int_4& jmax,int_4 il,int_4 ih,int_4 jl,int_4 jh) const { if( il > ih ) { il = 0; ih = mNx-1; } if( jl > jh ) { jl = 0; jh = mNy-1; } if( il < 0 ) il = 0; if( jl < 0 ) jl = 0; if( ih >= mNx ) ih = mNx-1; if( jh >= mNy ) jh = mNy-1; imax = jmax = 0; if(mNxy==1) return; r_8 mx=(*this)(il,jl); for (int_4 i=il; i<=ih; i++) for (int_4 j=jl; j<=jh; j++) if ((*this)(i,j)>mx) {imax = i; jmax = j; mx=(*this)(i,j);} } /*! Recherche du bin du minimum dans le pave [il,ih][jl,jh]. */ void Histo2D::IJMin(int_4& imax,int_4& jmax,int_4 il,int_4 ih,int_4 jl,int_4 jh) const { if( il > ih ) { il = 0; ih = mNx-1; } if( jl > jh ) { jl = 0; jh = mNy-1; } if( il < 0 ) il = 0; if( jl < 0 ) jl = 0; if( ih >= mNx ) ih = mNx-1; if( jh >= mNy ) jh = mNy-1; imax = jmax = 0; if(mNxy==1) return; r_8 mx=(*this)(il,jl); for (int_4 i=il; i<=ih; i++) for (int_4 j=jl; j<=jh; j++) if ((*this)(i,j) ih ) { il = 0; ih = mNx-1; } if( jl > jh ) { jl = 0; jh = mNy-1; } if( il < 0 ) il = 0; if( jl < 0 ) jl = 0; if( ih >= mNx ) ih = mNx-1; if( jh >= mNy ) jh = mNy-1; r_8 mx=(*this)(il,jl); if(mNxy==1) return mx; for (int_4 i=il; i<=ih; i++) for (int_4 j=jl; j<=jh; j++) if ((*this)(i,j)>mx) mx=(*this)(i,j); return mx; } /*! Recherche du minimum dans le pave [il,ih][jl,jh]. */ r_8 Histo2D::VMin(int_4 il,int_4 ih,int_4 jl,int_4 jh) const { if( il > ih ) { il = 0; ih = mNx-1; } if( jl > jh ) { jl = 0; jh = mNy-1; } if( il < 0 ) il = 0; if( jl < 0 ) jl = 0; if( ih >= mNx ) ih = mNx-1; if( jh >= mNy ) jh = mNy-1; r_8 mx=(*this)(il,jl); if(mNxy==1) return mx; for (int_4 i=il; i<=ih; i++) for (int_4 j=jl; j<=jh; j++) if ((*this)(i,j)=3 || j < 0 || j>=3 ) return mOver[1][1]; return mOver[i][j]; } /////////////////////////////////////////////////////////////////// /*! Retourne le nombre de bins non-nuls. */ int_4 Histo2D::BinNonNul() const { int_4 non=0; for (int_4 i=0;i= mNx ) return -1; if( jm < 0 || jm >= mNy ) return -1; if( SzPav%2 == 0 ) SzPav++; SzPav = (SzPav-1)/2; int_4 rc = 0; r_8 dxm = 0, dym = 0, wx = 0; for(int_4 i=im-SzPav;i<=im+SzPav;i++) { if( i<0 || i>= mNx ) {rc=1; continue;} for(int_4 j=jm-SzPav;j<=jm+SzPav;j++) { if( j<0 || j>= mNy ) {rc=1; continue;} r_8 x,y; BinCenter(i,j,x,y); dxm += x * (*this)(i,j); dym += y * (*this)(i,j); wx += (*this)(i,j); } } if( wx > 0. ) { xm = dxm/wx; ym = dym/wx; return rc; } else { BinCenter(im,jm,xm,ym); return 2; } } /*! Pour trouver le maximum de l'histogramme en tenant compte des fluctuations. \verbatim Methode: 1-/ On recherche le bin maximum MAX de l'histogramme 2-/ On considere que tous les pixels compris entre [MAX-Dz,MAX] peuvent etre des pixels maxima. 3-/ On identifie le bin maximum en choissisant le pixel du 2-/ tel que la somme des pixels dans un pave SzPav x SzPav soit maximale. INPUT: SzPav = taille du pave pour departager Dz = tolerance pour identifier tous les pixels "maximum" OUTPUT: im,jm = pixel maximum trouve RETURN: <0 = Echec >0 = nombre de pixels possibles pour le maximum \endverbatim */ int_4 Histo2D::FindMax(int_4& im,int_4& jm,int_4 SzPav,r_8 Dz ,int_4 il,int_4 ih,int_4 jl,int_4 jh) const { if( il > ih ) { il = 0; ih = mNx-1; } if( jl > jh ) { jl = 0; jh = mNy-1; } if( il < 0 ) il = 0; if( jl < 0 ) jl = 0; if( ih >= mNx ) ih = mNx-1; if( jh >= mNy ) jh = mNy-1; if( SzPav < 0 ) SzPav = 0; else { if( SzPav%2 == 0 ) SzPav++; SzPav = (SzPav-1)/2;} if( Dz < 0 ) Dz = 0.; r_8 max = VMax(il,ih,jl,jh) - Dz; int_4 nmax = 0; r_8 sumx = -1.e20; for(int_4 i=il;i<=ih;i++) for(int_4 j=jl;j<=jh;j++) { if( (*this)(i,j) < max) continue; nmax++; r_8 sum = 0.; for(int_4 ii=i-SzPav;ii<=i+SzPav;ii++) { if( ii<0 || ii >= mNx ) continue; for(int_4 jj=j-SzPav;jj<=j+SzPav;jj++) { if( jj<0 || jj >= mNy ) continue; sum += (*this)(ii,jj); } } if(nmax==1 || sum>sumx) {im=i; jm=j; sumx=sum;} } if( nmax <= 0 ) { IJMax(im,jm,il,ih,jl,jh); return 1;} return nmax; } /////////////////////////////////////////////////////////////////// /*! Impression des informations sur l'histogramme. */ void Histo2D::Show(ostream & os) const { os << "Histo2D::Show nHist=" << nHist << " nEntries=" << nEntries; if(HasErrors()) os << " Errors=Y \n"; else os << " Errors=N\n"; os << "mOver: [ " ; for(int j=2; j>=0; j--) { for(int i=0; i<3; i++) os << mOver[j][i] << " " ; if (j != 0) os << "// "; } os << "]\n"; os << " nx=" << mNx << " xmin=" << mXmin << " xmax=" << mXmax << " binx=" << mWBinx ; os << " ny=" << mNy << " ymin=" << mYmin << " ymax=" << mYmax << " biny=" << mWBiny << endl; //printf("mOver: [ %g %g %g // %g %g %g // %g %g %g ]\n" // ,mOver[2][0],mOver[2][1],mOver[2][2] // ,mOver[1][0],mOver[1][1],mOver[1][2] // ,mOver[0][0],mOver[0][1],mOver[0][2]); //printf(" nx=%d xmin=%g xmax=%g binx=%g ",mNx,mXmin,mXmax,mWBinx); //printf(" ny=%d ymin=%g ymax=%g biny=%g\n",mNy,mYmin,mYmax,mWBiny); } /////////////////////////////////////////////////////////////////// /*! Impression de l'histogramme sur stdout entre [il,ih] et [jl,jh]. \verbatim numero d'index: 00000000001111111111222222222233333 01234567890123456789012345678901234 valeur entiere: 00000000001111111111222222222233333 12345678901234567890123456789012345 \endverbatim */ void Histo2D::Print(r_8 min,r_8 max ,int_4 il,int_4 ih,int_4 jl,int_4 jh) const { int_4 ns = 35; const char *s = "+23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if( il > ih ) { il = 0; ih = mNx-1; } if( jl > jh ) { jl = 0; jh = mNy-1; } if( il < 0 ) il = 0; if( jl < 0 ) jl = 0; if( ih >= mNx ) ih = mNx-1; if( jh >= mNy ) jh = mNy-1; PrintStatus(); if( il != 0 || ih != mNx-1 || jl != 0 || jh != mNy-1 ) { r_8 xl,xh,yl,yh; BinLowEdge(il,jl,xl,yl); BinHighEdge(ih,jh,xh,yh); printf(" impression"); printf(" en X: %d=[%d,%d] xmin=%g xmax=%g " ,ih-il+1,il,ih,xl,xh); printf(" en Y: %d=[%d,%d] ymin=%g ymax=%g\n" ,jh-jl+1,jl,jh,yl,yh); } if(min >= max) { if(min != 0.) min = VMin(il,ih,jl,jh); else min=0.; max = VMax(il,ih,jl,jh); } if(min>max) return; if(min==max) {min -= 1.; max += 1.;} printf(" min=%g max=%g\n",min,max); // imprime numero de bin en colonne printf("\n"); if( mNx-1 >= 100 ) { printf(" "); for(int_4 i=il;i<=ih;i++) printf("%1d",(int_4) (i%1000)/100); printf("\n"); } if( mNx-1 >= 10 ) { printf(" "); for(int_4 i=il;i<=ih;i++) printf("%1d",(int_4) (i%100)/10); printf("\n"); } printf(" "); for(int_4 i=il;i<=ih;i++) printf("%1d",i%10); printf("\n"); printf(" "); {for(int_4 i=il;i<=ih;i++) printf("-"); printf("\n");} // imprime histogramme for(int_4 j=jh;j>=jl;j--) { printf("%3d: ",j); for(int_4 i=il;i<=ih;i++) { int_4 h; if( 1<=max-min && max-min<=35 ) h = (int_4)( (*this)(i,j) - min ) - 1; else h = (int_4)( ((*this)(i,j)-min)/(max-min) * ns ) - 1; char c; if(h<0 && (*this)(i,j)>min) c = '.'; else if(h<0) c = ' '; else if(h>=ns) c = '*'; else c = s[h]; printf("%c",c); } printf("\n"); } // imprime numero de bin en colonne printf(" "); {for(int_4 i=il;i<=ih;i++) printf("-"); printf("\n");} if( mNx-1 >= 100 ) { printf(" "); for(int_4 i=il;i<=ih;i++) printf("%1d",(int_4) (i%1000)/100); printf("\n"); } if( mNx-1 >= 10 ) { printf(" "); for(int_4 i=il;i<=ih;i++) printf("%1d",(int_4) (i%100)/10); printf("\n"); } printf(" "); {for(int_4 i=il;i<=ih;i++) printf("%1d",i%10);} printf("\n"); } /////////////////////////////////////////////////////////////////// // Titre Methodes pour gerer les projections /*! Pour creer la projection X. */ void Histo2D::SetProjX() { if( mHprojx != NULL ) DelProjX(); mHprojx = new Histo(mXmin,mXmax,mNx); if( mErr2 != NULL && mHprojx != NULL ) mHprojx->Errors(); } /*! Pour creer la projection Y. */ void Histo2D::SetProjY() { if( mHprojy != NULL ) DelProjY(); mHprojy = new Histo(mYmin,mYmax,mNy); if( mErr2 != NULL && mHprojy != NULL ) mHprojy->Errors(); } /*! Pour creer les projections X et Y. */ void Histo2D::SetProj() { SetProjX(); SetProjY(); } /*! Informations sur les projections. */ void Histo2D::ShowProj() const { if( mHprojx != NULL ) cout << ">>>> Projection X set : "<< mHprojx <>>> NO Projection X set"<>>> Projection Y set : "<< mHprojy <>>> NO Projection Y set"<Zero(); } /*! Remise a zero de la projection selon Y. */ void Histo2D::ZeroProjY() { if( mHprojy == NULL ) return; mHprojy->Zero(); } /*! Remise a zero des projections selon X et Y. */ void Histo2D::ZeroProj() { ZeroProjX(); ZeroProjY(); } /////////////////////////////////////////////////////////////////// // Titre Methodes pour gerer les bandes /*! Pour creer une bande en X entre ybmin et ybmax. */ int_4 Histo2D::SetBandX(r_8 ybmin,r_8 ybmax) { mB_s.num = mLBandx.size(); mB_s.min = ybmin; mB_s.max = ybmax; mB_s.H = new Histo(mXmin,mXmax,mNx); mLBandx.push_back(mB_s); mB_s.H = NULL; return mLBandx.size()-1; } /*! Pour creer une bande en Y entre xbmin et xbmax. */ int_4 Histo2D::SetBandY(r_8 xbmin,r_8 xbmax) { mB_s.num = mLBandy.size(); mB_s.min = xbmin; mB_s.max = xbmax; mB_s.H = new Histo(mYmin,mYmax,mNy); mLBandy.push_back(mB_s); mB_s.H = NULL; return mLBandy.size()-1; } /*! Destruction des histogrammes des bandes selon X. */ void Histo2D::DelBandX() { if( mLBandx.size() <= 0 ) return; for(list::iterator i = mLBandx.begin(); i != mLBandx.end(); i++) if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;} mLBandx.erase(mLBandx.begin(),mLBandx.end()); } /*! Destruction des histogrammes des bandes selon Y. */ void Histo2D::DelBandY() { if( mLBandy.size() <= 0 ) return; for(list::iterator i = mLBandy.begin(); i != mLBandy.end(); i++) if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;} mLBandy.erase(mLBandy.begin(),mLBandy.end()); } /*! Remise a zero des bandes selon X. */ void Histo2D::ZeroBandX() { if( mLBandx.size() <= 0 ) return; list::iterator i; for(i = mLBandx.begin(); i != mLBandx.end(); i++) (*i).H->Zero(); } /*! Remise a zero des bandes selon Y. */ void Histo2D::ZeroBandY() { if( mLBandy.size() <= 0 ) return; list::iterator i; for(i = mLBandy.begin(); i != mLBandy.end(); i++) (*i).H->Zero(); } /*! Retourne un pointeur sur la bande numero `n' selon X. */ Histo* Histo2D::HBandX(int_4 n) const { if( mLBandx.size() <= 0 || n < 0 || n >= (int_4) mLBandx.size() ) return NULL; for(list::const_iterator i = mLBandx.begin(); i != mLBandx.end(); i++) if( (*i).num == n ) return (*i).H; return NULL; } /*! Retourne un pointeur sur la bande numero `n' selon Y. */ Histo* Histo2D::HBandY(int_4 n) const { if( mLBandy.size() <= 0 || n < 0 || n >= (int_4) mLBandy.size() ) return NULL; for(list::const_iterator i = mLBandy.begin(); i != mLBandy.end(); i++) if( (*i).num == n ) return (*i).H; return NULL; } /*! Retourne les limites de la bande numero `n' selon X. */ void Histo2D::GetBandX(int_4 n,r_8& ybmin,r_8& ybmax) const { ybmin = 0.; ybmax = 0.; if( mLBandx.size() <= 0 || n < 0 || n >= (int_4) mLBandx.size() ) return; for(list::const_iterator i = mLBandx.begin(); i != mLBandx.end(); i++) if( (*i).num == n ) { ybmin = (*i).min; ybmax = (*i).max; return;} return; } /*! Retourne les limites de la bande numero `n' selon Y. */ void Histo2D::GetBandY(int_4 n,r_8& xbmin,r_8& xbmax) const { xbmin = 0.; xbmax = 0.; if( mLBandy.size() <= 0 || n < 0 || n >= (int_4) mLBandy.size() ) return; for(list::const_iterator i = mLBandy.begin(); i != mLBandy.end(); i++) if( (*i).num == n ) { xbmin = (*i).min; xbmax = (*i).max; return;} return; } /*! Informations sur les bandes. */ void Histo2D::ShowBand(int_4 lp) const { cout << ">>>> Nombre de bande X : " << mLBandx.size() << endl; if( lp>0 && mLBandx.size()>0 ) { list::const_iterator i; for(i = mLBandx.begin(); i != mLBandx.end(); i++) { cout<<" "<<(*i).num<<" de ymin="<<(*i).min<<" a ymax="<<(*i).max; if(lp>1) cout << " H=" << (*i).H; cout << endl; } } cout << ">>>> Nombre de bande Y : " << mLBandy.size() << endl; if( lp>0 && mLBandy.size()>0 ) { list::const_iterator i; for(i = mLBandy.begin(); i != mLBandy.end(); i++) { cout<<" "<<(*i).num<<" de xmin="<<(*i).min<<" a xmax="<<(*i).max; if(lp>1) cout << " H=" << (*i).H; cout << endl; } } } /////////////////////////////////////////////////////////////////// // Titre Methodes pour gerer les bandes equidistantes ou slices /*! Pour creer `nsli' bandes equidistantes selon X. */ int_4 Histo2D::SetSliX(int_4 nsli) { if( nsli <= 0 ) return -1; if( nsli > mNy ) nsli = mNy; if( mLSlix.size() > 0 ) DelSliX(); r_8 w = (mYmax-mYmin)/nsli; for(int_4 i=0; i mNx ) nsli = mNx; if( mLSliy.size() > 0 ) DelSliY(); r_8 w = (mXmax-mXmin)/nsli; for(int_4 i=0; i::iterator i = mLSlix.begin(); i != mLSlix.end(); i++) if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;} mLSlix.erase(mLSlix.begin(),mLSlix.end()); } /*! Destruction des bandes equidistantes selon Y. */ void Histo2D::DelSliY() { if( mLSliy.size() <= 0 ) return; for(list::iterator i = mLSliy.begin(); i != mLSliy.end(); i++) if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;} mLSliy.erase(mLSliy.begin(),mLSliy.end()); } /*! Remise a zero des bandes equidistantes selon X. */ void Histo2D::ZeroSliX() { if( mLSlix.size() <= 0 ) return; list::iterator i; for(i = mLSlix.begin(); i != mLSlix.end(); i++) (*i).H->Zero(); } /*! Remise a zero des bandes equidistantes selon Y. */ void Histo2D::ZeroSliY() { if( mLSliy.size() <= 0 ) return; list::iterator i; for(i = mLSliy.begin(); i != mLSliy.end(); i++) (*i).H->Zero(); } /*! Retourne un pointeur sur la bande equidistante numero `n' selon X. */ Histo* Histo2D::HSliX(int_4 n) const { if( mLSlix.size() <= 0 || n < 0 || n >= (int_4) mLSlix.size() ) return NULL; for(list::const_iterator i = mLSlix.begin(); i != mLSlix.end(); i++) if( (*i).num == n ) return (*i).H; return NULL; } /*! Retourne un pointeur sur la bande equidistante numero `n' selon Y. */ Histo* Histo2D::HSliY(int_4 n) const { if( mLSliy.size() <= 0 || n < 0 || n >= (int_4) mLSliy.size() ) return NULL; for(list::const_iterator i = mLSliy.begin(); i != mLSliy.end(); i++) if( (*i).num == n ) return (*i).H; return NULL; } /*! Informations sur les bandes equidistantes. */ void Histo2D::ShowSli(int_4 lp) const { list::const_iterator i; cout << ">>>> Nombre de slice X : " << mLSlix.size() << endl; if( lp>0 && mLSlix.size() > 0 ) for(i = mLSlix.begin(); i != mLSlix.end(); i++) { cout<<" "<<(*i).num<<" de ymin="<<(*i).min<<" a ymax="<<(*i).max; if(lp>1) cout << " H=" << (*i).H; cout << endl; } cout << ">>>> Nombre de slice Y : " << mLSliy.size() << endl; if( lp>0 && mLSliy.size()>0 ) for(i = mLSliy.begin(); i != mLSliy.end(); i++) { cout<<" "<<(*i).num<<" de xmin="<<(*i).min<<" a xmax="<<(*i).max; if(lp>1) cout << " H=" << (*i).H; cout << endl; } } /////////////////////////////////////////////////////////// // -------------------------------------------------------- // Les objets delegues pour la gestion de persistance // -------------------------------------------------------- /////////////////////////////////////////////////////////// void ObjFileIO::ReadSelf(PInPersist& is) { char strg[256]; if(dobj==NULL) dobj=new Histo2D; else dobj->Delete(); r_8 min,max; int_4 errok, projx, projy, nslix, nsliy, nbanx, nbany; // Lecture entete is.GetLine(strg, 255); is.GetLine(strg, 255); is.GetLine(strg, 255); is.GetLine(strg, 255); is.GetLine(strg, 255); is.GetLine(strg, 255); // Lecture variables de definitions is.Get(dobj->mNx); is.Get(dobj->mNy); is.Get(dobj->mNxy); is.Get(errok); is.Get(dobj->nEntries); is.Get(dobj->nHist); is.Get(dobj->mXmin); is.Get(dobj->mXmax); is.Get(dobj->mYmin); is.Get(dobj->mYmax); is.Get(dobj->mWBinx); is.Get(dobj->mWBiny); is.Get(&(dobj->mOver[0][0]),9); is.Get(projx); is.Get(projy); is.Get(nslix); is.Get(nsliy); is.Get(nbanx); is.Get(nbany); // Lecture histo2D dobj->mData = new r_8[dobj->mNxy]; is.GetLine(strg, 255); {for(int_4 j=0;jmNy;j++) is.Get(dobj->mData+j*dobj->mNx,dobj->mNx);} // Lecture erreurs if(errok) { is.GetLine(strg, 255); dobj->mErr2 = new r_8[dobj->mNxy]; for(int_4 j=0;jmNy;j++) is.Get(dobj->mErr2+j*dobj->mNx,dobj->mNx); } // Lecture des projections if(projx) { is.GetLine(strg, 255); dobj->SetProjX(); ObjFileIO fio_h(dobj->mHprojx); fio_h.Read(is); } if(projy) { is.GetLine(strg, 255); dobj->SetProjY(); ObjFileIO fio_h(dobj->mHprojy); fio_h.Read(is); } // Lecture des slices if(nslix>0) { is.GetLine(strg, 255); dobj->SetSliX(nslix); ASSERT (nslix==dobj->NSliX()); for(int_4 j=0;jNSliX();j++) {ObjFileIO fio_h(dobj->HSliX(j)); fio_h.Read(is);} } if(nsliy>0) { is.GetLine(strg, 255); dobj->SetSliY(nsliy); ASSERT (nsliy==dobj->NSliY()); for(int_4 j=0;jNSliY();j++) {ObjFileIO fio_h(dobj->HSliY(j)); fio_h.Read(is);} } // Lecture des bandes if( nbanx>0 ) { is.GetLine(strg, 255); {for(int_4 j=0; jSetBandX(min,max); }} ASSERT (nbanx==dobj->NBandX()); {for(int_4 j=0; jNBandX(); j++) { ObjFileIO fio_h(dobj->HBandX(j)); fio_h.Read(is); }} } if( nbany>0 ) { is.GetLine(strg, 255); {for(int_4 j=0; jSetBandY(min,max); }} ASSERT (nbany==dobj->NBandY()); {for(int_4 j=0; jNBandY(); j++) { ObjFileIO fio_h(dobj->HBandY(j)); fio_h.Read(is); }} } return; } void ObjFileIO::WriteSelf(POutPersist& os) const { if (dobj == NULL) return; char strg[256]; // Que faut-il ecrire? int_4 errok = (dobj->mErr2) ? 1 : 0; int_4 projx = (dobj->mHprojx) ? 1 : 0; int_4 projy = (dobj->mHprojy) ? 1 : 0; int_4 nslix = dobj->NSliX(); int_4 nsliy = dobj->NSliY(); int_4 nbanx = dobj->NBandX(); int_4 nbany = dobj->NBandY(); // Ecriture entete pour identifier facilement sprintf(strg,"nx=%d ny=%d nxy=%d errok=%1d" ,dobj->mNx,dobj->mNy,dobj->mNxy,errok); os.PutLine(strg); sprintf(strg,"nHist=%g nEntries=%d",dobj->nHist,dobj->nEntries); os.PutLine(strg); sprintf(strg,"wbinx=%g wbiny=%g",dobj->mWBinx,dobj->mWBiny); os.PutLine(strg); sprintf(strg,"xmin=%g xmax=%g ymin=%g ymax=%g" ,dobj->mXmin,dobj->mXmax,dobj->mYmin,dobj->mYmax); os.PutLine(strg); sprintf(strg,"projx/y=%d %d nbandx/y=%d %d nbslix/y=%d %d" ,projx,projy,nbanx,nbany,nslix,nsliy); os.PutLine(strg); sprintf(strg,"mOver %g %g %g %g %g %g %g %g %g" ,dobj->mOver[0][0],dobj->mOver[0][1],dobj->mOver[0][2] ,dobj->mOver[1][0],dobj->mOver[1][1],dobj->mOver[1][2] ,dobj->mOver[2][0],dobj->mOver[2][1],dobj->mOver[2][2]); os.PutLine(strg); // Ecriture variables de definitions os.Put(dobj->mNx); os.Put(dobj->mNy); os.Put(dobj->mNxy); os.Put(errok); os.Put(dobj->nEntries); os.Put(dobj->nHist); os.Put(dobj->mXmin); os.Put(dobj->mXmax); os.Put(dobj->mYmin); os.Put(dobj->mYmax); os.Put(dobj->mWBinx); os.Put(dobj->mWBiny); os.Put(&(dobj->mOver[0][0]),9); os.Put(projx); os.Put(projy); os.Put(nslix); os.Put(nsliy); os.Put(nbanx); os.Put(nbany); // Ecriture histo2D sprintf(strg,"Histo2D: Tableau des donnees %d = %d * %d" ,dobj->mNxy,dobj->mNx,dobj->mNy); os.PutLine(strg); {for(int_4 j=0;jmNy;j++) os.Put(dobj->mData+j*dobj->mNx,dobj->mNx);} // Ecriture erreurs if(errok) { sprintf(strg,"Histo2D: Tableau des erreurs %d = %d * %d" ,dobj->mNxy,dobj->mNx,dobj->mNy); os.PutLine(strg); for(int_4 j=0;jmNy;j++) os.Put(dobj->mErr2+j*dobj->mNx,dobj->mNx); } // Ecriture des projections if(projx) { sprintf(strg,"Histo2D: Projection X"); os.PutLine(strg); ObjFileIO fio_h(dobj->mHprojx); fio_h.Write(os); } if(projy) { sprintf(strg,"Histo2D: Projection Y"); os.PutLine(strg); ObjFileIO fio_h(dobj->mHprojy); fio_h.Write(os); } // Ecriture des slices if(nslix>0) { sprintf(strg,"Histo2D: Slices X %d",nslix); os.PutLine(strg); for(int_4 j=0;jHSliX(j); ObjFileIO fio_h(h); fio_h.Write(os); } } if(nsliy>0) { sprintf(strg,"Histo2D: Slices Y %d",nsliy); os.PutLine(strg); for(int_4 j=0;jHSliY(j); ObjFileIO fio_h(h); fio_h.Write(os); } } // Ecriture des bandes if( nbanx>0 ) { sprintf(strg,"Histo2D: Bandes X %d",nbanx); os.PutLine(strg); list::const_iterator it; for(it = dobj->mLBandx.begin(); it != dobj->mLBandx.end(); it++) { r_8 min = (*it).min; r_8 max = (*it).max; os.Put(min); os.Put(max); } for(it = dobj->mLBandx.begin(); it != dobj->mLBandx.end(); it++) { Histo* h = (*it).H; ObjFileIO fio_h(h); fio_h.Write(os); } } if( nbany>0 ) { sprintf(strg,"Histo2D: Bandes Y %d",nbany); os.PutLine(strg); list::const_iterator it; for(it = dobj->mLBandy.begin(); it != dobj->mLBandy.end(); it++) { r_8 min = (*it).min; r_8 max = (*it).max; os.Put(min); os.Put(max); } for(it = dobj->mLBandy.begin(); it != dobj->mLBandy.end(); it++) { Histo* h = (*it).H; ObjFileIO fio_h(h); fio_h.Write(os); } } return; } #ifdef __CXX_PRAGMA_TEMPLATES__ #pragma define_template ObjFileIO #endif #if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES) template class ObjFileIO; #endif