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

Last change on this file since 1096 was 1092, checked in by ansari, 25 years ago

Histos/Hprof/Histo2D en r_8 cmv 26/7/00

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