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

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

pour PutValues,Error etc ... on prend maintenant le mini

du nbre d'elements du vecteur/matrice et de l'histo.

cmv 11/07/00

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