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

Last change on this file since 424 was 308, checked in by ansari, 26 years ago

cmv 19/5/99

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