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

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

documentation cmv 13/4/00

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