source: Sophya/trunk/SophyaLib/HiStats/histos2.cc@ 3060

Last change on this file since 3060 was 3060, checked in by cmv, 19 years ago

amelioration gestion allocations cmv 13/8/2006

File size: 42.5 KB
Line 
1//
2// cmv 05/08/96
3//
4
5#include "sopnamsp.h"
6#include "machdefs.h"
7
8#include <string.h>
9#include <new>
10#include <stdlib.h>
11#include <stdio.h>
12#ifndef NO_VALUES_H
13#include <values.h>
14#endif
15
16#include "histos2.h"
17
18/*!
19 \class SOPHYA::Histo2D
20 \ingroup HiStats
21 Classe d'histogrammes 2D
22 \verbatim
23 Remarque sur les indices:
24 H(i,j) -> i = coord x (0<i<nx), j = coord y (0<j<ny)
25 v(ii,jj) -> ii = ligne (0<i<NRows()), jj = colonne (0<i<NCol())
26 On fait une correspondance directe i<->ii et j<->jj
27 ce qui, en representation classique des histos2D et des matrices
28 entraine une inversion x<->y cad une symetrie / diagonale principale
29 H(0,...) represente ^ mais v(0,...) represente
30 |x....... |xxxxxxxx|
31 |x....... |........|
32 |x....... |........|
33 |x....... |........|
34 |x....... |........|
35 --------->
36 colonne no 1 ligne no 1
37 \endverbatim
38*/
39
40///////////////////////////////////////////////////////////////////
41
42/*!
43 Constructeur par defaut.
44*/
45Histo2D::Histo2D()
46: mData(NULL), mErr2(NULL)
47, nHist(0), nEntries(0)
48, mNx(0), mNy(0), mNxy(0), mXmin(0), mXmax(0), mYmin(0), mYmax(0), mWBinx(0), mWBiny(0)
49, mHprojx(NULL), mHprojy(NULL)
50{
51 for(int_4 i=0;i<3;i++) for(int_4 j=0;j<3;j++) mOver[i][j]=0.;
52 mB_s.H = NULL;
53}
54
55/*!
56 Createur d'un histogramme 2D ayant nxBin,nyBin bins
57 entre xMin,xMax et yMin,yMax.
58*/
59Histo2D::Histo2D(r_8 xMin,r_8 xMax,int_4 nxBin,r_8 yMin,r_8 yMax,int_4 nyBin)
60: mData(NULL), mErr2(NULL), mHprojx(NULL), mHprojy(NULL)
61{
62 CreateOrResize(xMin,xMax,nxBin,yMin,yMax,nyBin);
63}
64
65/*!
66 Createur d'un histogramme 2D ayant nxBin,nyBin bins
67 entre xMin,xMax et yMin,yMax.
68*/
69Histo2D::Histo2D(r_4 xMin,r_4 xMax,int_4 nxBin,r_4 yMin,r_4 yMax,int_4 nyBin)
70: mData(NULL), mErr2(NULL), mHprojx(NULL), mHprojy(NULL)
71{
72 CreateOrResize((r_8)xMin,(r_8)xMax,nxBin,(r_8)yMin,(r_8)yMax,nyBin);
73}
74
75/*!
76 Constructeur par copie.
77*/
78Histo2D::Histo2D(const Histo2D& h)
79{
80int_4 i,j;
81mData = new r_8[h.mNxy];
82memcpy(mData, h.mData, h.mNxy*sizeof(r_8));
83
84mErr2 = NULL;
85if(h.mErr2) {
86 mErr2 = new r_8[h.mNxy];
87 memcpy(mErr2, h.mErr2, h.mNxy*sizeof(r_8));
88}
89
90nHist = h.nHist; nEntries = h.nEntries;
91for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j]=h.mOver[i][j];
92mNx = h.mNx; mNy = h.mNy; mNxy = h.mNxy;
93mXmin = h.mXmin; mXmax = h.mXmax; mYmin = h.mYmin; mYmax = h.mYmax;
94mWBinx = h.mWBinx; mWBiny = h.mWBiny;
95mB_s.H = NULL;
96
97mHprojx = mHprojy = NULL;
98if(h.mHprojx) {SetProjX(); *mHprojx = *(h.mHprojx);}
99if(h.mHprojy) {SetProjY(); *mHprojy = *(h.mHprojy);}
100
101int_4 nb; r_8 min,max;
102nb = h.NSliX();
103if(nb>0) {SetSliX(nb); for(i=0;i<NSliX();i++) *HSliX(i)=*(h.HSliX(i));}
104nb = h.NSliY();
105if(nb>0) {SetSliY(nb); for(i=0;i<NSliY();i++) *HSliY(i)=*(h.HSliY(i));}
106
107nb = h.NBandX();
108if(nb>0) {
109 for(i=0;i<nb;i++)
110 {h.GetBandX(i,min,max); SetBandX(min,max); *HBandX(i)=*(h.HBandX(i));}
111 for(i=0;i<NBandX();i++) *HBandX(i) = *(h.HBandX(i));
112}
113nb = h.NBandY();
114if(nb>0) {
115 for(i=0;i<nb;i++)
116 {h.GetBandY(i,min,max); SetBandY(min,max); *HBandY(i)=*(h.HBandY(i));}
117 for(i=0; i<NBandY();i++) *HBandY(i) = *(h.HBandY(i));
118}
119
120}
121
122/*!
123 Destructeur.
124*/
125Histo2D::~Histo2D()
126{
127 Delete();
128}
129
130///////////////////////////////////////////////////////////////////
131/*!
132 allocation de la place de l'histogramme (fct privee).
133*/
134void Histo2D::CreateOrResize(r_8 xMin,r_8 xMax,int_4 nxBin,r_8 yMin,r_8 yMax,int_4 nyBin)
135{
136 int_8 n = nxBin*nyBin;
137 bool samelen = (n==mNx*mNy)? true: false;
138 if(mData!=NULL && !samelen) {delete[] mData; mData=NULL;}
139 if(mErr2!=NULL) {delete[] mErr2; mErr2=NULL;} // On des-alloue toujours
140 if(n>0 && mData==NULL) mData = new r_8[n];
141 if(mData) memset(mData, 0, n*sizeof(r_8));
142 mNx = nxBin; mNy = nyBin; mNxy = nxBin*nyBin;
143 mXmin = xMin; mXmax = xMax; mYmin = yMin; mYmax = yMax;
144 mWBinx = (nxBin>0) ? (xMax - xMin)/nxBin: 0.;
145 mWBiny = (nyBin>0) ? (yMax - yMin)/nyBin: 0.;
146 nHist = 0; nEntries = 0;
147 for(int_4 i=0;i<3;i++) for(int_4 j=0;j<3;j++) mOver[i][j]=0.;
148 mB_s.H = NULL;
149
150 DelProjX(); DelProjY();
151 DelBandX(); DelBandY();
152 DelSliX(); DelSliY();
153}
154
155/*!
156 Desallocation de la place de l'histogramme (fct privee).
157*/
158void Histo2D::Delete()
159{
160 if( mData != NULL ) { delete[] mData; mData = NULL;}
161 if( mErr2 != NULL ) { delete[] mErr2; mErr2 = NULL;}
162
163 DelProj();
164 DelBandX(); DelBandY();
165 DelSliX(); DelSliY();
166
167 nHist = 0;
168 nEntries = 0;
169 mNx = 0; mNy = 0; mNxy = 0;
170 mXmin = 0; mXmax = 0; mYmin = 0; mYmax = 0;
171 mWBinx = 0; mWBiny = 0;
172 for(int_4 i=0;i<3;i++) for(int_4 j=0;j<3;j++) mOver[i][j]=0.;
173 mB_s.H = NULL; // Ne pas faire de delete!
174}
175
176///////////////////////////////////////////////////////////////////
177/*!
178 Remise a zero du contenu, des erreurs et des valeurs.
179*/
180void Histo2D::Zero()
181{
182 nHist = nEntries = 0;
183 for(int_4 i=0;i<3;i++) for(int_4 j=0;j<3;j++) mOver[i][j]=0.;
184 memset(mData, 0, mNxy*sizeof(r_8));
185 memset(mOver, 0, 9*sizeof(r_8));
186
187 if( mErr2 != NULL ) memset(mErr2, 0, mNxy*sizeof(r_8));
188
189 ZeroProj();
190
191 ZeroBandX(); ZeroBandY();
192
193 ZeroSliX(); ZeroSliY();
194}
195
196///////////////////////////////////////////////////////////////////
197/*!
198 Pour avoir le calcul des erreurs.
199*/
200void Histo2D::Errors()
201{
202 if(mErr2!=NULL) {delete[] mErr2; mErr2 = NULL;}
203 if(mNxy <= 0) return;
204 mErr2 = new r_8[mNxy];
205 memset(mErr2,0,mNxy*sizeof(r_8));
206}
207
208///////////////////////////////////////////////////////////////////
209/*!
210 Operateur H2 = H1
211*/
212Histo2D& Histo2D::operator = (const Histo2D& h)
213{
214 if(this == &h) return *this;
215 CreateOrResize(h.mXmin,h.mXmax,h.mNx,h.mYmin,h.mYmax,h.mNy);
216 if(h.mErr2) Errors();
217 if(mData) memcpy(mData, h.mData, mNxy*sizeof(r_8));
218 if(mErr2) memcpy(mErr2, h.mErr2, mNxy*sizeof(r_8));
219
220 for(int i=0;i<3;i++) for(int j=0;j<3;j++) mOver[i][j] = h.mOver[i][j];
221 nHist = h.nHist; nEntries = h.nEntries;
222
223 if(h.mHprojx) {SetProjX(); *mHprojx = *(h.mHprojx);}
224 if(h.mHprojy) {SetProjY(); *mHprojy = *(h.mHprojy);}
225
226 int_4 nb;
227 nb = h.NSliX();
228 if(nb>0) {
229 SetSliX(nb);
230 for(int i=0; i<NSliX();i++) *HSliX(i) = *(h.HSliX(i));
231 }
232 nb = h.NSliY();
233 if(nb>0) {
234 SetSliY(nb);
235 for(int i=0; i<NSliY();i++) *HSliY(i) = *(h.HSliY(i));
236 }
237
238 nb = h.NBandX();
239 if(nb>0) {
240 for(int i=0; i<nb;i++) {
241 r_8 min,max;
242 h.GetBandX(i,min,max);
243 SetBandX(min,max);
244 *HBandX(i) = *(h.HBandX(i));
245 }
246 for(int i=0; i<NBandX();i++) *HBandX(i) = *(h.HBandX(i));
247 }
248 nb = h.NBandY();
249 if(nb>0) {
250 for(int i=0; i<nb;i++) {
251 r_8 min,max;
252 h.GetBandY(i,min,max);
253 SetBandY(min,max);
254 *HBandY(i) = *(h.HBandY(i));
255 }
256 for(int i=0; i<NBandY();i++) *HBandY(i) = *(h.HBandY(i));
257 }
258
259 return *this;
260}
261
262///////////////////////////////////////////////////////////////////
263/*!
264 Operateur H *= b
265*/
266Histo2D& Histo2D::operator *= (r_8 b)
267{
268int_4 i,j;
269r_8 b2 = b*b;
270for(i=0;i<mNxy;i++) {
271 mData[i] *= b;
272 if(mErr2) mErr2[i] *= b2;
273}
274for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] *= b;
275nHist *= b;
276
277if(mHprojx) *mHprojx *= b;
278if(mHprojy) *mHprojy *= b;
279if(NSliX()>0) for(i=0; i<NSliX();i++) *HSliX(i) *= b;
280if(NSliY()>0) for(i=0; i<NSliY();i++) *HSliY(i) *= b;
281if(NBandX()>0) for(i=0; i<NBandX();i++) *HBandX(i) *= b;
282if(NBandY()>0) for(i=0; i<NBandY();i++) *HBandY(i) *= b;
283
284return *this;
285}
286
287/*!
288 Operateur H /= b
289*/
290Histo2D& Histo2D::operator /= (r_8 b)
291{
292int_4 i,j;
293if (b==0.) throw ParmError("Histo2D::operator / (0) ");
294r_8 b2 = b*b;
295for(i=0;i<mNxy;i++) {
296 mData[i] /= b;
297 if(mErr2) mErr2[i] /= b2;
298}
299for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] /= b;
300nHist /= b;
301
302if(mHprojx) *mHprojx /= b;
303if(mHprojy) *mHprojy /= b;
304if(NSliX()>0) for(i=0; i<NSliX();i++) *HSliX(i) /= b;
305if(NSliY()>0) for(i=0; i<NSliY();i++) *HSliY(i) /= b;
306if(NBandX()>0) for(i=0; i<NBandX();i++) *HBandX(i) /= b;
307if(NBandY()>0) for(i=0; i<NBandY();i++) *HBandY(i) /= b;
308
309return *this;
310}
311
312/*!
313 Operateur H += b
314*/
315Histo2D& Histo2D::operator += (r_8 b)
316{
317int_4 i,j;
318r_8 min,max;
319for(i=0;i<mNxy;i++) mData[i] += b;
320for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] += b;
321nHist += mNxy*b;
322
323if(mHprojx) *mHprojx += b*mNy;
324if(mHprojy) *mHprojy += b*mNx;
325if(NSliX()>0) for(i=0; i<NSliX();i++) *HSliX(i) += b*mNy/NSliX();
326if(NSliY()>0) for(i=0; i<NSliY();i++) *HSliY(i) += b*mNx/NSliY();
327if(NBandX()>0) for(i=0; i<NBandX();i++) {
328 GetBandX(i,min,max);
329 *HBandX(i) += b*(max-min)/(mYmax-mYmin)*mNy;
330}
331if(NBandY()>0) for(i=0; i<NBandY();i++) {
332 GetBandY(i,min,max);
333 *HBandY(i) += b*(max-min)/(mXmax-mXmin)*mNx;
334}
335
336return *this;
337}
338
339/*!
340 Operateur H -= b
341*/
342Histo2D& Histo2D::operator -= (r_8 b)
343{
344int_4 i,j;
345r_8 min,max;
346for(i=0;i<mNxy;i++) mData[i] -= b;
347for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] -= b;
348nHist -= mNxy*b;
349
350if(mHprojx) *mHprojx -= b*mNy;
351if(mHprojy) *mHprojy -= b*mNx;
352if(NSliX()>0) for(i=0; i<NSliX();i++) *HSliX(i) -= b*mNy/NSliX();
353if(NSliY()>0) for(i=0; i<NSliY();i++) *HSliY(i) -= b*mNx/NSliY();
354if(NBandX()>0) for(i=0; i<NBandX();i++) {
355 GetBandX(i,min,max);
356 *HBandX(i) -= b*(max-min)/(mYmax-mYmin)*mNy;
357}
358if(NBandY()>0) for(i=0; i<NBandY();i++) {
359 GetBandY(i,min,max);
360 *HBandY(i) -= b*(max-min)/(mXmax-mXmin)*mNx;
361}
362
363return *this;
364}
365
366///////////////////////////////////////////////////////////////////
367/*!
368 Operateur H += H1
369*/
370Histo2D& Histo2D::operator += (const Histo2D& a)
371{
372int_4 i,j;
373if(mNx!=a.mNx || mNy!=a.mNy) throw SzMismatchError("Histo2D::operator += ");
374for(i=0;i<mNxy;i++) {
375 mData[i] += a.mData[i];
376 if(mErr2 && a.mErr2) mErr2[i] += a.mErr2[i];
377}
378for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] += a.mOver[i][j];
379nHist += a.nHist;
380nEntries += a.nEntries;
381
382if(mHprojx && a.mHprojx) *mHprojx += *(a.mHprojx);
383if(mHprojy && a.mHprojy) *mHprojy += *(a.mHprojy);
384ZeroSliX(); ZeroSliY();
385ZeroBandX(); ZeroBandY();
386
387return *this;
388}
389
390/*!
391 Operateur H -= H1
392*/
393Histo2D& Histo2D::operator -= (const Histo2D& a)
394{
395int_4 i,j;
396if(mNx!=a.mNx || mNy!=a.mNy) throw SzMismatchError("Histo2D::operator -= ");
397for(i=0;i<mNxy;i++) {
398 mData[i] -= a.mData[i];
399 if(mErr2 && a.mErr2) mErr2[i] += a.mErr2[i];
400}
401for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] += a.mOver[i][j];
402nHist -= a.nHist;
403nEntries += a.nEntries;
404
405if(mHprojx && a.mHprojx) *mHprojx -= *(a.mHprojx);
406if(mHprojy && a.mHprojy) *mHprojy -= *(a.mHprojy);
407ZeroSliX(); ZeroSliY();
408ZeroBandX(); ZeroBandY();
409
410return *this;
411}
412
413/*!
414 Operateur H *= H1
415*/
416Histo2D& Histo2D::operator *= (const Histo2D& a)
417{
418int_4 i,j;
419if(mNx!=a.mNx || mNy!=a.mNy) throw SzMismatchError("Histo2D::operator *= ");
420nHist = 0.;
421for(i=0;i<mNxy;i++) {
422 if(mErr2 && a.mErr2)
423 mErr2[i] = a.mData[i]*a.mData[i]*mErr2[i] + mData[i]*mData[i]*a.mErr2[i];
424 mData[i] *= a.mData[i];
425 nHist += mData[i];
426}
427for(i=0;i<3;i++) for(j=0;j<3;j++) mOver[i][j] *= a.mOver[i][j];
428nEntries += a.nEntries;
429
430if(mHprojx && a.mHprojx) *mHprojx *= *(a.mHprojx);
431if(mHprojy && a.mHprojy) *mHprojy *= *(a.mHprojy);
432ZeroSliX(); ZeroSliY();
433ZeroBandX(); ZeroBandY();
434
435return *this;
436}
437
438/*!
439 Operateur H /= H1
440*/
441Histo2D& Histo2D::operator /= (const Histo2D& a)
442{
443int_4 i,j;
444if(mNx!=a.mNx || mNy!=a.mNy) throw SzMismatchError("Histo2D::operator /= ");
445nHist = 0.;
446for(i=0;i<mNxy;i++) {
447 if(a.mData[i]==0.) {
448 mData[i]=0.;
449 if(mErr2) mErr2[i]=0.;
450 continue;
451 }
452 if(mErr2 && a.mErr2)
453 mErr2[i] = (mErr2[i] + mData[i]/a.mData[i]*mData[i]/a.mData[i]*a.mErr2[i])
454 /(a.mData[i]*a.mData[i]);
455 mData[i] /= a.mData[i];
456 nHist += mData[i];
457}
458for(i=0;i<3;i++) for(j=0;j<3;j++)
459 if(a.mOver[i][j]!=0.) mOver[i][j] *= a.mOver[i][j]; else mOver[i][j] = 0.;
460nEntries += a.nEntries;
461
462if(mHprojx && a.mHprojx) *mHprojx /= *(a.mHprojx);
463if(mHprojy && a.mHprojy) *mHprojy /= *(a.mHprojy);
464ZeroSliX(); ZeroSliY();
465ZeroBandX(); ZeroBandY();
466
467return *this;
468}
469
470///////////////////////////////////////////////////////////////////
471/*!
472 Remplissage d'un tableau avec les valeurs des abscisses.
473*/
474void Histo2D::GetXCoor(TVector<r_8> &v) const
475{
476r_8 x,y;
477v.Realloc(mNx);
478for(int_4 i=0;i<mNx;i++) {BinLowEdge(i,0,x,y); v(i) = x;}
479return;
480}
481
482/*!
483 Remplissage d'un tableau avec les valeurs des ordonnees.
484*/
485void Histo2D::GetYCoor(TVector<r_8> &v) const
486{
487r_8 x,y;
488v.Realloc(mNy);
489for(int_4 i=0;i<mNy;i++) {BinLowEdge(0,i,x,y); v(i) = y;}
490return;
491}
492
493/*!
494 Remplissage d'un tableau avec les valeurs du contenu.
495*/
496void Histo2D::GetValue(TMatrix<r_8> &v) const
497{
498v.Realloc(mNx,mNy);
499for(int_4 i=0;i<mNx;i++)
500 for(int_4 j=0;j<mNy;j++) v(i,j) = (*this)(i,j);
501return;
502}
503
504/*!
505 Remplissage d'un tableau avec les valeurs du carre des erreurs.
506*/
507void Histo2D::GetError2(TMatrix<r_8> &v) const
508{
509int_4 i,j;
510v.Realloc(mNx,mNy);
511if(!mErr2)
512 {for(i=0;i<mNx;i++) for(j=0;j<mNy;j++) v(i,j) = 0.; return;}
513for(i=0;i<mNx;i++) for(j=0;j<mNy;j++) v(i,j) = Error2(i,j);
514return;
515}
516
517/*!
518 Remplissage d'un tableau avec les valeurs des erreurs.
519*/
520void Histo2D::GetError(TMatrix<r_8> &v) const
521{
522int_4 i,j;
523v.Realloc(mNx,mNy);
524if(!mErr2)
525 {for(i=0;i<mNx;i++) for(j=0;j<mNy;j++) v(i,j) = 0.; return;}
526for(i=0;i<mNx;i++) for(j=0;j<mNy;j++) v(i,j) = Error(i,j);
527return;
528}
529
530///////////////////////////////////////////////////////////////////
531/*!
532 Remplissage du contenu de l'histo avec les valeurs d'un tableau.
533*/
534void Histo2D::PutValue(TMatrix<r_8> &v, int_4 ierr)
535{
536//if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) throw SzMismatchError("Histo2D::PutValue()");
537uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx;
538uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy;
539if(nnx>0 && nny>0) for(uint_4 i=0;i<nnx;i++) for(uint_4 j=0;j<nny;j++) {
540 (*this)(i,j) = v(i,j);
541 if(mErr2 && ierr) Error2(i,j) = fabs(v(i,j));
542}
543return;
544}
545
546/*!
547 Addition du contenu de l'histo avec les valeurs d'un tableau.
548*/
549void Histo2D::PutValueAdd(TMatrix<r_8> &v, int_4 ierr)
550{
551//if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) throw SzMismatchError("Histo2D::PutValueAdd ");
552uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx;
553uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy;
554if(nnx>0 && nny>0) for(uint_4 i=0;i<nnx;i++) for(uint_4 j=0;j<nny;j++) {
555 (*this)(i,j) += v(i,j);
556 if(mErr2 && ierr) Error2(i,j) += fabs(v(i,j));
557}
558return;
559}
560
561/*!
562 Remplissage des erreurs au carre de l'histo
563 avec les valeurs d'un tableau.
564*/
565void Histo2D::PutError2(TMatrix<r_8> &v)
566{
567//if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) throw SzMismatchError("Histo2D::PutError2 ");
568uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx;
569uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy;
570if(nnx>0 && nny>0) {
571 if(!mErr2) Errors();
572 for(uint_4 i=0;i<nnx;i++) for(uint_4 j=0;j<nny;j++) Error2(i,j) = v(i,j);
573}
574return;
575}
576
577/*!
578 Addition des erreurs au carre de l'histo
579 avec les valeurs d'un tableau.
580*/
581void Histo2D::PutError2Add(TMatrix<r_8> &v)
582{
583//if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) throw SzMismatchError("Histo2D::PutError2Add ");
584uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx;
585uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy;
586if(nnx>0 && nny>0) {
587 if(!mErr2) Errors();
588 for(uint_4 i=0;i<nnx;i++) for(uint_4 j=0;j<nny;j++)
589 if(v(i,j)>0.) Error2(i,j) += v(i,j);
590}
591return;
592}
593
594/*!
595 Remplissage des erreurs de l'histo avec les valeurs d'un tableau.
596*/
597void Histo2D::PutError(TMatrix<r_8> &v)
598{
599//if(v.NRows()!=(uint_4)mNx || v.NCol()!=(uint_4)mNy) throw SzMismatchError("Histo2D::PutError ");
600uint_4 nnx = (v.NRows()<(uint_4)mNx)? v.NRows(): (uint_4)mNx;
601uint_4 nny = (v.NCol() <(uint_4)mNy)? v.NCol() : (uint_4)mNy;
602if(nnx>0 && nny>0) {
603 if(!mErr2) Errors();
604 for(uint_4 i=0;i<nnx;i++) for(uint_4 j=0;j<nny;j++)
605 if(v(i,j)>0.) Error2(i,j)=v(i,j)*v(i,j); else Error2(i,j)= -v(i,j)*v(i,j);
606}
607return;
608}
609
610///////////////////////////////////////////////////////////////////
611/********* Methode *********/
612/*!
613 Addition du contenu de l'histo pour x,y poids w.
614*/
615void Histo2D::Add(r_8 x, r_8 y, r_8 w)
616{
617list<bande_slice>::iterator it;
618int_4 i,j;
619FindBin(x,y,i,j);
620
621if( mHprojx != NULL ) mHprojx->Add(x,w);
622if( mHprojy != NULL ) mHprojy->Add(y,w);
623
624if(mLBandx.size()>0)
625 for( it = mLBandx.begin(); it != mLBandx.end(); it++)
626 if( (*it).min <= y && y < (*it).max ) (*it).H->Add(x,w);
627
628if(mLBandy.size()>0)
629 for( it = mLBandy.begin(); it != mLBandy.end(); it++)
630 if( (*it).min <= x && x < (*it).max ) (*it).H->Add(y,w);
631
632if(mLSlix.size()>0)
633 for( it = mLSlix.begin(); it != mLSlix.end(); it++)
634 if( (*it).min <= y && y < (*it).max ) (*it).H->Add(x,w);
635
636if(mLSliy.size()>0)
637 for( it = mLSliy.begin(); it != mLSliy.end(); it++)
638 if( (*it).min <= x && x < (*it).max ) (*it).H->Add(y,w);
639
640if( i<0 || i>=mNx || j<0 || j>=mNy ) {
641 if(i<0) i=0; else if(i>=mNx) i=2; else i=1;
642 if(j<0) j=0; else if(j>=mNy) j=2; else j=1;
643 mOver[i][j] += w;
644 mOver[1][1] += w;
645 return;
646}
647
648mData[j*mNx+i] += w;
649if(mErr2!=NULL) mErr2[j*mNx+i] += w*w;
650nHist += w;
651nEntries++;
652}
653
654///////////////////////////////////////////////////////////////////
655/*!
656 Recherche du bin du maximum dans le pave [il,ih][jl,jh].
657*/
658void Histo2D::IJMax(int_4& imax,int_4& jmax,int_4 il,int_4 ih,int_4 jl,int_4 jh) const
659{
660if(mNxy<=0) {imax = jmax = -1; return;}
661if( il > ih ) { il = 0; ih = mNx-1; }
662if( jl > jh ) { jl = 0; jh = mNy-1; }
663if( il < 0 ) il = 0;
664if( jl < 0 ) jl = 0;
665if( ih >= mNx ) ih = mNx-1;
666if( jh >= mNy ) jh = mNy-1;
667
668imax = jmax = 0;
669if(mNxy==1) return;
670
671r_8 mx=(*this)(il,jl);
672for (int_4 i=il; i<=ih; i++)
673 for (int_4 j=jl; j<=jh; j++)
674 if ((*this)(i,j)>mx) {imax = i; jmax = j; mx=(*this)(i,j);}
675}
676
677/*!
678 Recherche du bin du minimum dans le pave [il,ih][jl,jh].
679*/
680void Histo2D::IJMin(int_4& imax,int_4& jmax,int_4 il,int_4 ih,int_4 jl,int_4 jh) const
681{
682if(mNxy<=0) {imax = jmax = -1; return;}
683if( il > ih ) { il = 0; ih = mNx-1; }
684if( jl > jh ) { jl = 0; jh = mNy-1; }
685if( il < 0 ) il = 0;
686if( jl < 0 ) jl = 0;
687if( ih >= mNx ) ih = mNx-1;
688if( jh >= mNy ) jh = mNy-1;
689
690imax = jmax = 0;
691if(mNxy==1) return;
692
693r_8 mx=(*this)(il,jl);
694for (int_4 i=il; i<=ih; i++)
695 for (int_4 j=jl; j<=jh; j++)
696 if ((*this)(i,j)<mx) {imax = i; jmax = j; mx=(*this)(i,j);}
697}
698
699
700/*!
701 Recherche du maximum dans le pave [il,ih][jl,jh].
702*/
703r_8 Histo2D::VMax(int_4 il,int_4 ih,int_4 jl,int_4 jh) const
704{
705if(mNxy<=0) return 0.;
706if( il > ih ) { il = 0; ih = mNx-1; }
707if( jl > jh ) { jl = 0; jh = mNy-1; }
708if( il < 0 ) il = 0;
709if( jl < 0 ) jl = 0;
710if( ih >= mNx ) ih = mNx-1;
711if( jh >= mNy ) jh = mNy-1;
712
713r_8 mx=(*this)(il,jl);
714if(mNxy==1) return mx;
715for (int_4 i=il; i<=ih; i++)
716 for (int_4 j=jl; j<=jh; j++)
717 if ((*this)(i,j)>mx) mx=(*this)(i,j);
718return mx;
719}
720
721/*!
722 Recherche du minimum dans le pave [il,ih][jl,jh].
723*/
724r_8 Histo2D::VMin(int_4 il,int_4 ih,int_4 jl,int_4 jh) const
725{
726if(mNxy<=0) return 0.;
727if( il > ih ) { il = 0; ih = mNx-1; }
728if( jl > jh ) { jl = 0; jh = mNy-1; }
729if( il < 0 ) il = 0;
730if( jl < 0 ) jl = 0;
731if( ih >= mNx ) ih = mNx-1;
732if( jh >= mNy ) jh = mNy-1;
733
734r_8 mx=(*this)(il,jl);
735if(mNxy==1) return mx;
736for (int_4 i=il; i<=ih; i++)
737 for (int_4 j=jl; j<=jh; j++)
738 if ((*this)(i,j)<mx) mx=(*this)(i,j);
739return mx;
740}
741
742///////////////////////////////////////////////////////////////////
743/*!
744 Renvoie les under.overflow dans les 8 quadrants.
745 \verbatim
746 mOver[3][3]: 20 | 21 | 22
747 | |
748 --------------
749 | |
750 10 | 11 | 12 11 = all overflow+underflow
751 | |
752 --------------
753 | |
754 00 | 01 | 02
755 \endverbatim
756*/
757r_8 Histo2D::NOver(int_4 i,int_4 j) const
758{
759if( i < 0 || i>=3 || j < 0 || j>=3 ) return mOver[1][1];
760return mOver[i][j];
761}
762
763
764///////////////////////////////////////////////////////////////////
765/*!
766 Retourne le nombre de bins non-nuls.
767*/
768int_4 Histo2D::BinNonNul() const
769{
770if(mNxy<=0) return -1;
771int_4 non=0;
772for (int_4 i=0;i<mNxy;i++) if( mData[i] != 0. ) non++;
773return non;
774}
775
776/*!
777 Retourne le nombre de bins avec erreurs non-nulles.
778*/
779int_4 Histo2D::ErrNonNul() const
780{
781if(mErr2==NULL) return -1;
782int_4 non=0;
783for (int_4 i=0;i<mNxy;i++) if( mErr2[i] != 0. ) non++;
784return non;
785}
786
787///////////////////////////////////////////////////////////////////
788/*!
789 Idem EstimeMax(int...) mais retourne x,y.
790*/
791int_4 Histo2D::EstimeMax(r_8& xm,r_8& ym,int_4 SzPav
792 ,int_4 il,int_4 ih,int_4 jl,int_4 jh) const
793{
794int_4 im,jm;
795IJMax(im,jm,il,ih,jl,jh);
796return EstimeMax(im,jm,xm,ym,SzPav);
797}
798
799/*!
800 Determine les abscisses et ordonnees du maximum donne par im,jm
801 en moyennant dans un pave SzPav x SzPav autour du maximum.
802 \verbatim
803 Return:
804 0 = si fit maximum reussi avec SzPav pixels
805 1 = si fit maximum reussi avec moins que SzPav pixels
806 dans au moins 1 direction
807 2 = si fit maximum echoue et renvoit BinCenter()
808 -1 = si echec: SzPav <= 0 ou im,jm hors limites
809 \endverbatim
810*/
811int_4 Histo2D::EstimeMax(int_4 im,int_4 jm,r_8& xm,r_8& ym,int_4 SzPav) const
812{
813xm = ym = 0;
814if( SzPav <= 0 ) return -1;
815if( im < 0 || im >= mNx ) return -1;
816if( jm < 0 || jm >= mNy ) return -1;
817
818if( SzPav%2 == 0 ) SzPav++;
819SzPav = (SzPav-1)/2;
820
821int_4 rc = 0;
822r_8 dxm = 0, dym = 0, wx = 0;
823for(int_4 i=im-SzPav;i<=im+SzPav;i++) {
824 if( i<0 || i>= mNx ) {rc=1; continue;}
825 for(int_4 j=jm-SzPav;j<=jm+SzPav;j++) {
826 if( j<0 || j>= mNy ) {rc=1; continue;}
827 r_8 x,y;
828 BinCenter(i,j,x,y);
829 dxm += x * (*this)(i,j);
830 dym += y * (*this)(i,j);
831 wx += (*this)(i,j);
832 }
833}
834
835if( wx > 0. ) {
836 xm = dxm/wx;
837 ym = dym/wx;
838 return rc;
839} else {
840 BinCenter(im,jm,xm,ym);
841 return 2;
842}
843
844}
845
846/*!
847 Pour trouver le maximum de l'histogramme en tenant compte
848 des fluctuations.
849 \verbatim
850 Methode:
851 1-/ On recherche le bin maximum MAX de l'histogramme
852 2-/ On considere que tous les pixels compris entre [MAX-Dz,MAX]
853 peuvent etre des pixels maxima.
854 3-/ On identifie le bin maximum en choissisant le pixel du 2-/
855 tel que la somme des pixels dans un pave SzPav x SzPav soit maximale.
856 INPUT:
857 SzPav = taille du pave pour departager
858 Dz = tolerance pour identifier tous les pixels "maximum"
859 OUTPUT:
860 im,jm = pixel maximum trouve
861 RETURN:
862 <0 = Echec
863 >0 = nombre de pixels possibles pour le maximum
864 \endverbatim
865*/
866int_4 Histo2D::FindMax(int_4& im,int_4& jm,int_4 SzPav,r_8 Dz
867 ,int_4 il,int_4 ih,int_4 jl,int_4 jh) const
868{
869if(mNxy<=0) return -1;
870if( il > ih ) { il = 0; ih = mNx-1; }
871if( jl > jh ) { jl = 0; jh = mNy-1; }
872if( il < 0 ) il = 0;
873if( jl < 0 ) jl = 0;
874if( ih >= mNx ) ih = mNx-1;
875if( jh >= mNy ) jh = mNy-1;
876if( SzPav < 0 ) SzPav = 0;
877 else { if( SzPav%2 == 0 ) SzPav++; SzPav = (SzPav-1)/2;}
878if( Dz < 0 ) Dz = 0.;
879r_8 max = VMax(il,ih,jl,jh) - Dz;
880int_4 nmax = 0;
881r_8 sumx = -1.e20;
882for(int_4 i=il;i<=ih;i++) for(int_4 j=jl;j<=jh;j++) {
883 if( (*this)(i,j) < max) continue;
884 nmax++;
885 r_8 sum = 0.;
886 for(int_4 ii=i-SzPav;ii<=i+SzPav;ii++) {
887 if( ii<0 || ii >= mNx ) continue;
888 for(int_4 jj=j-SzPav;jj<=j+SzPav;jj++) {
889 if( jj<0 || jj >= mNy ) continue;
890 sum += (*this)(ii,jj);
891 }
892 }
893 if(nmax==1 || sum>sumx) {im=i; jm=j; sumx=sum;}
894}
895if( nmax <= 0 ) { IJMax(im,jm,il,ih,jl,jh); return 1;}
896return nmax;
897}
898
899///////////////////////////////////////////////////////////////////
900/*!
901 Impression des informations sur l'histogramme.
902*/
903void Histo2D::Show(ostream & os) const
904{
905 os << "Histo2D::Show nHist=" << nHist << " nEntries=" << nEntries;
906 if(HasErrors()) os << " Errors=Y \n"; else os << " Errors=N\n";
907 os << "mOver: [ " ;
908 for(int j=2; j>=0; j--) {
909 for(int i=0; i<3; i++)
910 os << mOver[j][i] << " " ;
911 if (j != 0) os << "// ";
912 }
913 os << "]\n";
914 os << " nx=" << mNx << " xmin=" << mXmin << " xmax=" << mXmax
915 << " binx=" << mWBinx ;
916 os << " ny=" << mNy << " ymin=" << mYmin << " ymax=" << mYmax
917 << " biny=" << mWBiny << endl;
918
919 //printf("mOver: [ %g %g %g // %g %g %g // %g %g %g ]\n"
920 // ,mOver[2][0],mOver[2][1],mOver[2][2]
921 // ,mOver[1][0],mOver[1][1],mOver[1][2]
922 // ,mOver[0][0],mOver[0][1],mOver[0][2]);
923 //printf(" nx=%d xmin=%g xmax=%g binx=%g ",mNx,mXmin,mXmax,mWBinx);
924 //printf(" ny=%d ymin=%g ymax=%g biny=%g\n",mNy,mYmin,mYmax,mWBiny);
925}
926
927///////////////////////////////////////////////////////////////////
928/*!
929 Impression de l'histogramme sur stdout entre [il,ih] et [jl,jh].
930 \verbatim
931 numero d'index: 00000000001111111111222222222233333
932 01234567890123456789012345678901234
933 valeur entiere: 00000000001111111111222222222233333
934 12345678901234567890123456789012345
935 \endverbatim
936*/
937void Histo2D::Print(r_8 min,r_8 max
938 ,int_4 il,int_4 ih,int_4 jl,int_4 jh) const
939{
940if(mNxy<=0) return;
941int_4 ns = 35;
942const char *s = "+23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
943
944if( il > ih ) { il = 0; ih = mNx-1; }
945if( jl > jh ) { jl = 0; jh = mNy-1; }
946if( il < 0 ) il = 0;
947if( jl < 0 ) jl = 0;
948if( ih >= mNx ) ih = mNx-1;
949if( jh >= mNy ) jh = mNy-1;
950
951PrintStatus();
952
953if( il != 0 || ih != mNx-1 || jl != 0 || jh != mNy-1 ) {
954 r_8 xl,xh,yl,yh;
955 BinLowEdge(il,jl,xl,yl);
956 BinHighEdge(ih,jh,xh,yh);
957 printf(" impression");
958 printf(" en X: %d=[%d,%d] xmin=%g xmax=%g "
959 ,ih-il+1,il,ih,xl,xh);
960 printf(" en Y: %d=[%d,%d] ymin=%g ymax=%g\n"
961 ,jh-jl+1,jl,jh,yl,yh);
962}
963
964if(min >= max) { if(min != 0.) min = VMin(il,ih,jl,jh); else min=0.;
965 max = VMax(il,ih,jl,jh); }
966if(min>max) return;
967if(min==max) {min -= 1.; max += 1.;}
968printf(" min=%g max=%g\n",min,max);
969
970// imprime numero de bin en colonne
971printf("\n");
972if( mNx-1 >= 100 ) {
973 printf(" ");
974 for(int_4 i=il;i<=ih;i++) printf("%1d",(int_4) (i%1000)/100);
975 printf("\n");
976}
977if( mNx-1 >= 10 ) {
978 printf(" ");
979 for(int_4 i=il;i<=ih;i++) printf("%1d",(int_4) (i%100)/10);
980 printf("\n");
981}
982printf(" ");
983for(int_4 i=il;i<=ih;i++) printf("%1d",i%10);
984printf("\n");
985printf(" "); {for(int_4 i=il;i<=ih;i++) printf("-"); printf("\n");}
986
987// imprime histogramme
988for(int_4 j=jh;j>=jl;j--) {
989 printf("%3d: ",j);
990 for(int_4 i=il;i<=ih;i++) {
991 int_4 h;
992 if( 1<=max-min && max-min<=35 ) h = (int_4)( (*this)(i,j) - min ) - 1;
993 else h = (int_4)( ((*this)(i,j)-min)/(max-min) * ns ) - 1;
994 char c;
995 if(h<0 && (*this)(i,j)>min) c = '.';
996 else if(h<0) c = ' ';
997 else if(h>=ns) c = '*';
998 else c = s[h];
999 printf("%c",c);
1000 }
1001 printf("\n");
1002}
1003
1004// imprime numero de bin en colonne
1005printf(" "); {for(int_4 i=il;i<=ih;i++) printf("-"); printf("\n");}
1006if( mNx-1 >= 100 ) {
1007 printf(" ");
1008 for(int_4 i=il;i<=ih;i++) printf("%1d",(int_4) (i%1000)/100);
1009 printf("\n");
1010}
1011if( mNx-1 >= 10 ) {
1012 printf(" ");
1013 for(int_4 i=il;i<=ih;i++) printf("%1d",(int_4) (i%100)/10);
1014 printf("\n");
1015}
1016printf(" ");
1017{for(int_4 i=il;i<=ih;i++) printf("%1d",i%10);}
1018printf("\n");
1019
1020}
1021
1022///////////////////////////////////////////////////////////////////
1023// Titre Methodes pour gerer les projections
1024
1025/*!
1026 Pour creer la projection X.
1027*/
1028void Histo2D::SetProjX()
1029{
1030if( mHprojx != NULL ) DelProjX();
1031mHprojx = new Histo(mXmin,mXmax,mNx);
1032if(mErr2 && mHprojx) mHprojx->Errors();
1033}
1034
1035/*!
1036 Pour creer la projection Y.
1037*/
1038void Histo2D::SetProjY()
1039{
1040if( mHprojy != NULL ) DelProjY();
1041mHprojy = new Histo(mYmin,mYmax,mNy);
1042if(mErr2 && mHprojy) mHprojy->Errors();
1043}
1044
1045/*!
1046 Pour creer les projections X et Y.
1047*/
1048void Histo2D::SetProj()
1049{
1050SetProjX();
1051SetProjY();
1052}
1053
1054/*!
1055 Informations sur les projections.
1056*/
1057void Histo2D::ShowProj() const
1058{
1059if( mHprojx != NULL ) cout << ">>>> Projection X set : "<< mHprojx <<endl;
1060 else cout << ">>>> NO Projection X set"<<endl;
1061if( mHprojy != NULL ) cout << ">>>> Projection Y set : "<< mHprojy <<endl;
1062 else cout << ">>>> NO Projection Y set"<<endl;
1063}
1064
1065/*!
1066 Destruction de l'histogramme de la projection selon X.
1067*/
1068void Histo2D::DelProjX()
1069{
1070if( mHprojx == NULL ) return;
1071delete mHprojx;
1072mHprojx = NULL;
1073}
1074
1075/*!
1076 Destruction de l'histogramme de la projection selon X.
1077*/
1078void Histo2D::DelProjY()
1079{
1080if( mHprojy == NULL ) return;
1081delete mHprojy;
1082mHprojy = NULL;
1083}
1084
1085/*!
1086 Destruction des histogrammes des projections selon X et Y.
1087*/
1088void Histo2D::DelProj()
1089{
1090DelProjX();
1091DelProjY();
1092}
1093
1094/*!
1095 Remise a zero de la projection selon X.
1096*/
1097void Histo2D::ZeroProjX()
1098{
1099if( mHprojx == NULL ) return;
1100mHprojx->Zero();
1101}
1102
1103/*!
1104 Remise a zero de la projection selon Y.
1105*/
1106void Histo2D::ZeroProjY()
1107{
1108if( mHprojy == NULL ) return;
1109mHprojy->Zero();
1110}
1111
1112/*!
1113 Remise a zero des projections selon X et Y.
1114*/
1115void Histo2D::ZeroProj()
1116{
1117ZeroProjX();
1118ZeroProjY();
1119}
1120
1121///////////////////////////////////////////////////////////////////
1122// Titre Methodes pour gerer les bandes
1123
1124/*!
1125 Pour creer une bande en X entre ybmin et ybmax.
1126*/
1127int_4 Histo2D::SetBandX(r_8 ybmin,r_8 ybmax)
1128{
1129mB_s.num = mLBandx.size();
1130mB_s.min = ybmin;
1131mB_s.max = ybmax;
1132mB_s.H = new Histo(mXmin,mXmax,mNx);
1133if(mErr2 && mB_s.H) mB_s.H->Errors();
1134mLBandx.push_back(mB_s);
1135mB_s.H = NULL;
1136return mLBandx.size()-1;
1137}
1138
1139/*!
1140 Pour creer une bande en Y entre xbmin et xbmax.
1141*/
1142int_4 Histo2D::SetBandY(r_8 xbmin,r_8 xbmax)
1143{
1144mB_s.num = mLBandy.size();
1145mB_s.min = xbmin;
1146mB_s.max = xbmax;
1147mB_s.H = new Histo(mYmin,mYmax,mNy);
1148if(mErr2 && mB_s.H) mB_s.H->Errors();
1149mLBandy.push_back(mB_s);
1150mB_s.H = NULL;
1151return mLBandy.size()-1;
1152}
1153
1154/*!
1155 Destruction des histogrammes des bandes selon X.
1156*/
1157void Histo2D::DelBandX()
1158{
1159if( mLBandx.size() <= 0 ) return;
1160for(list<bande_slice>::iterator i = mLBandx.begin(); i != mLBandx.end(); i++)
1161 if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
1162mLBandx.erase(mLBandx.begin(),mLBandx.end());
1163}
1164
1165/*!
1166 Destruction des histogrammes des bandes selon Y.
1167*/
1168void Histo2D::DelBandY()
1169{
1170if( mLBandy.size() <= 0 ) return;
1171for(list<bande_slice>::iterator i = mLBandy.begin(); i != mLBandy.end(); i++)
1172 if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
1173mLBandy.erase(mLBandy.begin(),mLBandy.end());
1174}
1175
1176/*!
1177 Remise a zero des bandes selon X.
1178*/
1179void Histo2D::ZeroBandX()
1180{
1181if( mLBandx.size() <= 0 ) return;
1182list<bande_slice>::iterator i;
1183for(i = mLBandx.begin(); i != mLBandx.end(); i++)
1184 (*i).H->Zero();
1185}
1186
1187/*!
1188 Remise a zero des bandes selon Y.
1189*/
1190void Histo2D::ZeroBandY()
1191{
1192if( mLBandy.size() <= 0 ) return;
1193list<bande_slice>::iterator i;
1194for(i = mLBandy.begin(); i != mLBandy.end(); i++)
1195 (*i).H->Zero();
1196}
1197
1198/*!
1199 Retourne un pointeur sur la bande numero `n' selon X.
1200*/
1201Histo* Histo2D::HBandX(int_4 n) const
1202{
1203if( mLBandx.size() <= 0 || n < 0 || n >= (int_4) mLBandx.size() ) return NULL;
1204for(list<bande_slice>::const_iterator i = mLBandx.begin(); i != mLBandx.end(); i++)
1205 if( (*i).num == n ) return (*i).H;
1206return NULL;
1207}
1208
1209/*!
1210 Retourne un pointeur sur la bande numero `n' selon Y.
1211*/
1212Histo* Histo2D::HBandY(int_4 n) const
1213{
1214if( mLBandy.size() <= 0 || n < 0 || n >= (int_4) mLBandy.size() ) return NULL;
1215for(list<bande_slice>::const_iterator i = mLBandy.begin(); i != mLBandy.end(); i++)
1216 if( (*i).num == n ) return (*i).H;
1217return NULL;
1218}
1219
1220/*!
1221 Retourne les limites de la bande numero `n' selon X.
1222*/
1223void Histo2D::GetBandX(int_4 n,r_8& ybmin,r_8& ybmax) const
1224{
1225ybmin = 0.; ybmax = 0.;
1226if( mLBandx.size() <= 0 || n < 0 || n >= (int_4) mLBandx.size() ) return;
1227for(list<bande_slice>::const_iterator i = mLBandx.begin(); i != mLBandx.end(); i++)
1228 if( (*i).num == n ) { ybmin = (*i).min; ybmax = (*i).max; return;}
1229return;
1230}
1231
1232/*!
1233 Retourne les limites de la bande numero `n' selon Y.
1234*/
1235void Histo2D::GetBandY(int_4 n,r_8& xbmin,r_8& xbmax) const
1236{
1237xbmin = 0.; xbmax = 0.;
1238if( mLBandy.size() <= 0 || n < 0 || n >= (int_4) mLBandy.size() ) return;
1239for(list<bande_slice>::const_iterator i = mLBandy.begin(); i != mLBandy.end(); i++)
1240 if( (*i).num == n ) { xbmin = (*i).min; xbmax = (*i).max; return;}
1241return;
1242}
1243
1244/*!
1245 Informations sur les bandes.
1246*/
1247void Histo2D::ShowBand(int_4 lp) const
1248{
1249 cout << ">>>> Nombre de bande X : " << mLBandx.size() << endl;
1250if( lp>0 && mLBandx.size()>0 ) {
1251 list<bande_slice>::const_iterator i;
1252 for(i = mLBandx.begin(); i != mLBandx.end(); i++) {
1253 cout<<" "<<(*i).num<<" de ymin="<<(*i).min<<" a ymax="<<(*i).max;
1254 if(lp>1) cout << " H=" << (*i).H;
1255 cout << endl;
1256 }
1257}
1258
1259cout << ">>>> Nombre de bande Y : " << mLBandy.size() << endl;
1260if( lp>0 && mLBandy.size()>0 ) {
1261 list<bande_slice>::const_iterator i;
1262 for(i = mLBandy.begin(); i != mLBandy.end(); i++) {
1263 cout<<" "<<(*i).num<<" de xmin="<<(*i).min<<" a xmax="<<(*i).max;
1264 if(lp>1) cout << " H=" << (*i).H;
1265 cout << endl;
1266 }
1267}
1268}
1269
1270///////////////////////////////////////////////////////////////////
1271// Titre Methodes pour gerer les bandes equidistantes ou slices
1272
1273/*!
1274 Pour creer `nsli' bandes equidistantes selon X.
1275*/
1276int_4 Histo2D::SetSliX(int_4 nsli)
1277{
1278if( nsli <= 0 ) return -1;
1279if( nsli > mNy ) nsli = mNy;
1280if( mLSlix.size() > 0 ) DelSliX();
1281r_8 w = (mYmax-mYmin)/nsli;
1282
1283for(int_4 i=0; i<nsli; i++ ) {
1284 mB_s.num = i;
1285 mB_s.min = mYmin + i*w;
1286 mB_s.max = mB_s.min + w;
1287 mB_s.H = new Histo(mXmin,mXmax,mNx);
1288 if(mErr2 && mB_s.H) mB_s.H->Errors();
1289 mLSlix.push_back(mB_s);
1290 mB_s.H = NULL;
1291}
1292return (int_4) mLSlix.size();
1293}
1294
1295/*!
1296 Pour creer `nsli' bandes equidistantes selon Y.
1297*/
1298int_4 Histo2D::SetSliY(int_4 nsli)
1299{
1300if( nsli <= 0 ) return -1;
1301if( nsli > mNx ) nsli = mNx;
1302if( mLSliy.size() > 0 ) DelSliY();
1303r_8 w = (mXmax-mXmin)/nsli;
1304
1305for(int_4 i=0; i<nsli; i++ ) {
1306 mB_s.num = i;
1307 mB_s.min = mXmin + i*w;
1308 mB_s.max = mB_s.min + w;
1309 mB_s.H = new Histo(mYmin,mYmax,mNy);
1310 if(mErr2 && mB_s.H) mB_s.H->Errors();
1311 mLSliy.push_back(mB_s);
1312 mB_s.H = NULL;
1313}
1314return (int_4) mLSliy.size();
1315}
1316
1317/*!
1318 Destruction des bandes equidistantes selon X.
1319*/
1320void Histo2D::DelSliX()
1321{
1322if( mLSlix.size() <= 0 ) return;
1323for(list<bande_slice>::iterator i = mLSlix.begin(); i != mLSlix.end(); i++)
1324 if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
1325mLSlix.erase(mLSlix.begin(),mLSlix.end());
1326}
1327
1328/*!
1329 Destruction des bandes equidistantes selon Y.
1330*/
1331void Histo2D::DelSliY()
1332{
1333if( mLSliy.size() <= 0 ) return;
1334for(list<bande_slice>::iterator i = mLSliy.begin(); i != mLSliy.end(); i++)
1335 if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
1336mLSliy.erase(mLSliy.begin(),mLSliy.end());
1337}
1338
1339/*!
1340 Remise a zero des bandes equidistantes selon X.
1341*/
1342void Histo2D::ZeroSliX()
1343{
1344if( mLSlix.size() <= 0 ) return;
1345list<bande_slice>::iterator i;
1346for(i = mLSlix.begin(); i != mLSlix.end(); i++)
1347 (*i).H->Zero();
1348}
1349
1350/*!
1351 Remise a zero des bandes equidistantes selon Y.
1352*/
1353void Histo2D::ZeroSliY()
1354{
1355if( mLSliy.size() <= 0 ) return;
1356list<bande_slice>::iterator i;
1357for(i = mLSliy.begin(); i != mLSliy.end(); i++)
1358 (*i).H->Zero();
1359}
1360
1361/*!
1362 Retourne un pointeur sur la bande equidistante numero `n'
1363 selon X.
1364*/
1365Histo* Histo2D::HSliX(int_4 n) const
1366{
1367if( mLSlix.size() <= 0 || n < 0 || n >= (int_4) mLSlix.size() ) return NULL;
1368for(list<bande_slice>::const_iterator i = mLSlix.begin(); i != mLSlix.end(); i++)
1369 if( (*i).num == n ) return (*i).H;
1370return NULL;
1371}
1372
1373/*!
1374 Retourne un pointeur sur la bande equidistante numero `n'
1375 selon Y.
1376*/
1377Histo* Histo2D::HSliY(int_4 n) const
1378{
1379if( mLSliy.size() <= 0 || n < 0 || n >= (int_4) mLSliy.size() ) return NULL;
1380for(list<bande_slice>::const_iterator i = mLSliy.begin(); i != mLSliy.end(); i++)
1381 if( (*i).num == n ) return (*i).H;
1382return NULL;
1383}
1384
1385/*!
1386 Retourne les limites de la bande equidistante numero `n' selon X.
1387*/
1388void Histo2D::GetSliX(int_4 n,r_8& ybmin,r_8& ybmax) const
1389{
1390ybmin = 0.; ybmax = 0.;
1391if( mLSlix.size() <= 0 || n < 0 || n >= (int_4) mLSlix.size() ) return;
1392for(list<bande_slice>::const_iterator i = mLSlix.begin(); i != mLSlix.end(); i++)
1393 if( (*i).num == n ) { ybmin = (*i).min; ybmax = (*i).max; return;}
1394return;
1395}
1396
1397/*!
1398 Retourne les limites de la bande equidistante numero `n' selon Y.
1399*/
1400void Histo2D::GetSliY(int_4 n,r_8& xbmin,r_8& xbmax) const
1401{
1402xbmin = 0.; xbmax = 0.;
1403if( mLSliy.size() <= 0 || n < 0 || n >= (int_4) mLSliy.size() ) return;
1404for(list<bande_slice>::const_iterator i = mLSliy.begin(); i != mLSliy.end(); i++)
1405 if( (*i).num == n ) { xbmin = (*i).min; xbmax = (*i).max; return;}
1406return;
1407}
1408
1409/*!
1410 Informations sur les bandes equidistantes.
1411*/
1412void Histo2D::ShowSli(int_4 lp) const
1413{
1414list<bande_slice>::const_iterator i;
1415cout << ">>>> Nombre de slice X : " << mLSlix.size() << endl;
1416if( lp>0 && mLSlix.size() > 0 )
1417 for(i = mLSlix.begin(); i != mLSlix.end(); i++) {
1418 cout<<" "<<(*i).num<<" de ymin="<<(*i).min<<" a ymax="<<(*i).max;
1419 if(lp>1) cout << " H=" << (*i).H;
1420 cout << endl;
1421 }
1422
1423cout << ">>>> Nombre de slice Y : " << mLSliy.size() << endl;
1424if( lp>0 && mLSliy.size()>0 )
1425 for(i = mLSliy.begin(); i != mLSliy.end(); i++) {
1426 cout<<" "<<(*i).num<<" de xmin="<<(*i).min<<" a xmax="<<(*i).max;
1427 if(lp>1) cout << " H=" << (*i).H;
1428 cout << endl;
1429 }
1430}
1431
1432///////////////////////////////////////////////////////////
1433// --------------------------------------------------------
1434// Les objets delegues pour la gestion de persistance
1435// --------------------------------------------------------
1436///////////////////////////////////////////////////////////
1437
1438
1439DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
1440void ObjFileIO<Histo2D>::ReadSelf(PInPersist& is)
1441{
1442char strg[256];
1443
1444if(dobj==NULL) dobj=new Histo2D;
1445 else dobj->Delete();
1446
1447r_8 min,max;
1448int_4 errok, projx, projy, nslix, nsliy, nbanx, nbany;
1449
1450// Lecture entete
1451is.GetLine(strg, 255);
1452is.GetLine(strg, 255);
1453is.GetLine(strg, 255);
1454is.GetLine(strg, 255);
1455is.GetLine(strg, 255);
1456is.GetLine(strg, 255);
1457
1458// Lecture variables de definitions
1459is.Get(dobj->mNx);
1460is.Get(dobj->mNy);
1461is.Get(dobj->mNxy);
1462is.Get(errok);
1463is.Get(dobj->nEntries);
1464is.Get(dobj->nHist);
1465
1466is.Get(dobj->mXmin);
1467is.Get(dobj->mXmax);
1468is.Get(dobj->mYmin);
1469is.Get(dobj->mYmax);
1470is.Get(dobj->mWBinx);
1471is.Get(dobj->mWBiny);
1472
1473is.Get(&(dobj->mOver[0][0]),9);
1474
1475is.Get(projx);
1476is.Get(projy);
1477is.Get(nslix);
1478is.Get(nsliy);
1479is.Get(nbanx);
1480is.Get(nbany);
1481
1482// Lecture histo2D
1483dobj->mData = new r_8[dobj->mNxy];
1484is.GetLine(strg, 255);
1485{for(int_4 j=0;j<dobj->mNy;j++) is.Get(dobj->mData+j*dobj->mNx,dobj->mNx);}
1486
1487// Lecture erreurs
1488if(errok) {
1489 is.GetLine(strg, 255);
1490 dobj->mErr2 = new r_8[dobj->mNxy];
1491 for(int_4 j=0;j<dobj->mNy;j++) is.Get(dobj->mErr2+j*dobj->mNx,dobj->mNx);
1492}
1493
1494// Lecture des projections
1495if(projx) {
1496 is.GetLine(strg, 255);
1497 dobj->SetProjX();
1498 ObjFileIO<Histo> fio_h(dobj->mHprojx);
1499 fio_h.Read(is);
1500}
1501if(projy) {
1502 is.GetLine(strg, 255);
1503 dobj->SetProjY();
1504 ObjFileIO<Histo> fio_h(dobj->mHprojy);
1505 fio_h.Read(is);
1506}
1507
1508// Lecture des slices
1509if(nslix>0) {
1510 is.GetLine(strg, 255);
1511 dobj->SetSliX(nslix);
1512 ASSERT (nslix==dobj->NSliX());
1513 for(int_4 j=0;j<dobj->NSliX();j++)
1514 {ObjFileIO<Histo> fio_h(dobj->HSliX(j)); fio_h.Read(is);}
1515}
1516if(nsliy>0) {
1517 is.GetLine(strg, 255);
1518 dobj->SetSliY(nsliy);
1519 ASSERT (nsliy==dobj->NSliY());
1520 for(int_4 j=0;j<dobj->NSliY();j++)
1521 {ObjFileIO<Histo> fio_h(dobj->HSliY(j)); fio_h.Read(is);}
1522}
1523
1524// Lecture des bandes
1525if( nbanx>0 ) {
1526 is.GetLine(strg, 255);
1527 {for(int_4 j=0; j<nbanx; j++) {
1528 is.Get(min); is.Get(max);
1529 dobj->SetBandX(min,max);
1530 }}
1531 ASSERT (nbanx==dobj->NBandX());
1532 {for(int_4 j=0; j<dobj->NBandX(); j++) {
1533 ObjFileIO<Histo> fio_h(dobj->HBandX(j));
1534 fio_h.Read(is);
1535 }}
1536}
1537if( nbany>0 ) {
1538 is.GetLine(strg, 255);
1539 {for(int_4 j=0; j<nbany; j++) {
1540 is.Get(min); is.Get(max);
1541 dobj->SetBandY(min,max);
1542 }}
1543 ASSERT (nbany==dobj->NBandY());
1544 {for(int_4 j=0; j<dobj->NBandY(); j++) {
1545 ObjFileIO<Histo> fio_h(dobj->HBandY(j));
1546 fio_h.Read(is);
1547 }}
1548}
1549
1550return;
1551}
1552
1553DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
1554void ObjFileIO<Histo2D>::WriteSelf(POutPersist& os) const
1555{
1556if (dobj == NULL) return;
1557char strg[256];
1558
1559// Que faut-il ecrire?
1560int_4 errok = (dobj->mErr2) ? 1 : 0;
1561int_4 projx = (dobj->mHprojx) ? 1 : 0;
1562int_4 projy = (dobj->mHprojy) ? 1 : 0;
1563int_4 nslix = dobj->NSliX();
1564int_4 nsliy = dobj->NSliY();
1565int_4 nbanx = dobj->NBandX();
1566int_4 nbany = dobj->NBandY();
1567
1568// Ecriture entete pour identifier facilement
1569sprintf(strg,"nx=%d ny=%d nxy=%d errok=%1d"
1570 ,dobj->mNx,dobj->mNy,dobj->mNxy,errok);
1571os.PutLine(strg);
1572sprintf(strg,"nHist=%g nEntries=%d",dobj->nHist,dobj->nEntries);
1573os.PutLine(strg);
1574sprintf(strg,"wbinx=%g wbiny=%g",dobj->mWBinx,dobj->mWBiny);
1575os.PutLine(strg);
1576sprintf(strg,"xmin=%g xmax=%g ymin=%g ymax=%g"
1577 ,dobj->mXmin,dobj->mXmax,dobj->mYmin,dobj->mYmax);
1578os.PutLine(strg);
1579sprintf(strg,"projx/y=%d %d nbandx/y=%d %d nbslix/y=%d %d"
1580 ,projx,projy,nbanx,nbany,nslix,nsliy);
1581os.PutLine(strg);
1582sprintf(strg,"mOver %g %g %g %g %g %g %g %g %g"
1583 ,dobj->mOver[0][0],dobj->mOver[0][1],dobj->mOver[0][2]
1584 ,dobj->mOver[1][0],dobj->mOver[1][1],dobj->mOver[1][2]
1585 ,dobj->mOver[2][0],dobj->mOver[2][1],dobj->mOver[2][2]);
1586os.PutLine(strg);
1587
1588// Ecriture variables de definitions
1589os.Put(dobj->mNx);
1590os.Put(dobj->mNy);
1591os.Put(dobj->mNxy);
1592os.Put(errok);
1593os.Put(dobj->nEntries);
1594os.Put(dobj->nHist);
1595
1596os.Put(dobj->mXmin);
1597os.Put(dobj->mXmax);
1598os.Put(dobj->mYmin);
1599os.Put(dobj->mYmax);
1600os.Put(dobj->mWBinx);
1601os.Put(dobj->mWBiny);
1602
1603os.Put(&(dobj->mOver[0][0]),9);
1604
1605os.Put(projx);
1606os.Put(projy);
1607os.Put(nslix);
1608os.Put(nsliy);
1609os.Put(nbanx);
1610os.Put(nbany);
1611
1612// Ecriture histo2D
1613sprintf(strg,"Histo2D: Tableau des donnees %d = %d * %d"
1614 ,dobj->mNxy,dobj->mNx,dobj->mNy);
1615os.PutLine(strg);
1616{for(int_4 j=0;j<dobj->mNy;j++) os.Put(dobj->mData+j*dobj->mNx,dobj->mNx);}
1617
1618// Ecriture erreurs
1619if(errok) {
1620 sprintf(strg,"Histo2D: Tableau des erreurs %d = %d * %d"
1621 ,dobj->mNxy,dobj->mNx,dobj->mNy);
1622 os.PutLine(strg);
1623 for(int_4 j=0;j<dobj->mNy;j++) os.Put(dobj->mErr2+j*dobj->mNx,dobj->mNx);
1624}
1625
1626// Ecriture des projections
1627if(projx) {
1628 sprintf(strg,"Histo2D: Projection X");
1629 os.PutLine(strg);
1630 ObjFileIO<Histo> fio_h(dobj->mHprojx); fio_h.Write(os);
1631}
1632if(projy) {
1633 sprintf(strg,"Histo2D: Projection Y");
1634 os.PutLine(strg);
1635 ObjFileIO<Histo> fio_h(dobj->mHprojy); fio_h.Write(os);
1636}
1637
1638// Ecriture des slices
1639if(nslix>0) {
1640 sprintf(strg,"Histo2D: Slices X %d",nslix);
1641 os.PutLine(strg);
1642 for(int_4 j=0;j<nslix;j++) {
1643 Histo* h = dobj->HSliX(j);
1644 ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
1645 }
1646}
1647if(nsliy>0) {
1648 sprintf(strg,"Histo2D: Slices Y %d",nsliy);
1649 os.PutLine(strg);
1650 for(int_4 j=0;j<nsliy;j++) {
1651 Histo* h = dobj->HSliY(j);
1652 ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
1653 }
1654}
1655
1656// Ecriture des bandes
1657if( nbanx>0 ) {
1658 sprintf(strg,"Histo2D: Bandes X %d",nbanx);
1659 os.PutLine(strg);
1660 list<Histo2D::bande_slice>::const_iterator it;
1661 for(it = dobj->mLBandx.begin(); it != dobj->mLBandx.end(); it++) {
1662 r_8 min = (*it).min; r_8 max = (*it).max;
1663 os.Put(min); os.Put(max);
1664 }
1665 for(it = dobj->mLBandx.begin(); it != dobj->mLBandx.end(); it++) {
1666 Histo* h = (*it).H;
1667 ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
1668 }
1669}
1670if( nbany>0 ) {
1671 sprintf(strg,"Histo2D: Bandes Y %d",nbany);
1672 os.PutLine(strg);
1673 list<Histo2D::bande_slice>::const_iterator it;
1674 for(it = dobj->mLBandy.begin(); it != dobj->mLBandy.end(); it++) {
1675 r_8 min = (*it).min; r_8 max = (*it).max;
1676 os.Put(min); os.Put(max);
1677 }
1678 for(it = dobj->mLBandy.begin(); it != dobj->mLBandy.end(); it++) {
1679 Histo* h = (*it).H;
1680 ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
1681 }
1682}
1683
1684return;
1685}
1686
1687
1688#ifdef __CXX_PRAGMA_TEMPLATES__
1689#pragma define_template ObjFileIO<Histo2D>
1690#endif
1691
1692#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
1693template class SOPHYA::ObjFileIO<Histo2D>;
1694#endif
Note: See TracBrowser for help on using the repository browser.