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

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

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