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

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

intro de ReCenterBin/X/Y() cmv 21/12/06

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