source: Sophya/trunk/SophyaLib/NTools/histos2.cc@ 753

Last change on this file since 753 was 514, checked in by ansari, 26 years ago

elimination des OVector/OMatrix au profit des TVector/TMatrix cmv 25/10/99

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