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

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

Merge avec PEIDA++ (~V 3.8) et nettoyage pour nouveau PPersist Reza+cmv 21/10/99

File size: 45.2 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{
47ASSERT(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)
666 {for(i=0;i<nx;i++) for(j=0;j<ny;j++) v(i,j) = 0.; return;}
667for(i=0;i<nx;i++) for(j=0;j<ny;j++) v(i,j) = Error2(i,j);
668return;
669}
670
671//++
672void Histo2D::GetError(Matrix &v)
673//
674// Remplissage d'un tableau avec les valeurs des erreurs.
675//--
676{
677int i,j;
678v.Realloc(nx,ny);
679if(!err2)
680 {for(i=0;i<nx;i++) for(j=0;j<ny;j++) v(i,j) = 0.; return;}
681for(i=0;i<nx;i++) for(j=0;j<ny;j++) v(i,j) = Error(i,j);
682return;
683}
684
685///////////////////////////////////////////////////////////////////
686//++
687void Histo2D::PutValue(Matrix &v, int ierr)
688//
689// Remplissage du contenu de l'histo avec les valeurs d'un tableau.
690//--
691{
692int i,j;
693if(v.NRows()!=nx || v.NCol()!=ny) THROW(sizeMismatchErr);
694for(i=0;i<nx;i++) for(j=0;j<ny;j++) {
695 (*this)(i,j) = v(i,j);
696 if(err2 && ierr) Error2(i,j) = fabs(v(i,j));
697}
698return;
699}
700
701//++
702void Histo2D::PutValueAdd(Matrix &v, int ierr)
703//
704// Addition du contenu de l'histo avec les valeurs d'un tableau.
705//--
706{
707int i,j;
708if(v.NRows()!=nx || v.NCol()!=ny) THROW(sizeMismatchErr);
709for(i=0;i<nx;i++) for(j=0;j<ny;j++) {
710 (*this)(i,j) += v(i,j);
711 if(err2 && ierr) Error2(i,j) += fabs(v(i,j));
712}
713return;
714}
715
716//++
717void Histo2D::PutError2(Matrix &v)
718//
719// Remplissage des erreurs au carre de l'histo
720// avec les valeurs d'un tableau.
721//--
722{
723int i,j;
724if(v.NRows()!=nx || v.NCol()!=ny) THROW(sizeMismatchErr);
725if(!err2) Errors();
726for(i=0;i<nx;i++) for(j=0;j<ny;j++) Error2(i,j) = v(i,j);
727return;
728}
729
730//++
731void Histo2D::PutError2Add(Matrix &v)
732//
733// Addition des erreurs au carre de l'histo
734// avec les valeurs d'un tableau.
735//--
736{
737int i,j;
738if(v.NRows()!=nx || v.NCol()!=ny) THROW(sizeMismatchErr);
739if(!err2) Errors();
740for(i=0;i<nx;i++) for(j=0;j<ny;j++)
741 if(v(i,j)>0.) Error2(i,j) += v(i,j);
742return;
743}
744
745//++
746void Histo2D::PutError(Matrix &v)
747//
748// Remplissage des erreurs de l'histo avec les valeurs d'un tableau.
749//--
750{
751int i,j;
752if(v.NRows()!=nx || v.NCol()!=ny) THROW(sizeMismatchErr);
753if(!err2) Errors();
754for(i=0;i<nx;i++) for(j=0;j<ny;j++)
755 if(v(i,j)>0.) Error2(i,j)=v(i,j)*v(i,j); else Error2(i,j)= -v(i,j)*v(i,j);
756return;
757}
758
759///////////////////////////////////////////////////////////////////
760/********* Methode *********/
761//++
762void Histo2D::Add(float x, float y, float w)
763//
764// Addition du contenu de l'histo pour x,y poids w.
765//--
766{
767list<bande_slice>::iterator it;
768int i,j;
769FindBin(x,y,i,j);
770
771if( hprojx != NULL ) hprojx->Add(x,w);
772if( hprojy != NULL ) hprojy->Add(y,w);
773
774if(lbandx.size()>0)
775 for( it = lbandx.begin(); it != lbandx.end(); it++)
776 if( (*it).min <= y && y < (*it).max ) (*it).H->Add(x,w);
777
778if(lbandy.size()>0)
779 for( it = lbandy.begin(); it != lbandy.end(); it++)
780 if( (*it).min <= x && x < (*it).max ) (*it).H->Add(y,w);
781
782if(lslix.size()>0)
783 for( it = lslix.begin(); it != lslix.end(); it++)
784 if( (*it).min <= y && y < (*it).max ) (*it).H->Add(x,w);
785
786if(lsliy.size()>0)
787 for( it = lsliy.begin(); it != lsliy.end(); it++)
788 if( (*it).min <= x && x < (*it).max ) (*it).H->Add(y,w);
789
790if( i<0 || i>=nx || j<0 || j>=ny ) {
791 if(i<0) i=0; else if(i>=nx) i=2; else i=1;
792 if(j<0) j=0; else if(j>=ny) j=2; else j=1;
793 over[i][j] += w;
794 over[1][1] += w;
795 return;
796}
797
798data[j*nx+i] += w;
799if(err2!=NULL) err2[j*nx+i] += w*w;
800nHist += w;
801nEntries++;
802}
803
804///////////////////////////////////////////////////////////////////
805//++
806void Histo2D::IJMax(int& imax,int& jmax,int il,int ih,int jl,int jh)
807//
808// Recherche du bin du maximum dans le pave [il,ih][jl,jh].
809//--
810{
811if( il > ih ) { il = 0; ih = nx-1; }
812if( jl > jh ) { jl = 0; jh = ny-1; }
813if( il < 0 ) il = 0;
814if( jl < 0 ) jl = 0;
815if( ih >= nx ) ih = nx-1;
816if( jh >= ny ) jh = ny-1;
817
818imax = jmax = 0;
819if(nxy==1) return;
820
821float mx=(*this)(il,jl);
822for (int i=il; i<=ih; i++)
823 for (int j=jl; j<=jh; j++)
824 if ((*this)(i,j)>mx) {imax = i; jmax = j; mx=(*this)(i,j);}
825}
826
827//++
828void Histo2D::IJMin(int& imax,int& jmax,int il,int ih,int jl,int jh)
829//
830// Recherche du bin du minimum dans le pave [il,ih][jl,jh].
831//--
832{
833if( il > ih ) { il = 0; ih = nx-1; }
834if( jl > jh ) { jl = 0; jh = ny-1; }
835if( il < 0 ) il = 0;
836if( jl < 0 ) jl = 0;
837if( ih >= nx ) ih = nx-1;
838if( jh >= ny ) jh = ny-1;
839
840imax = jmax = 0;
841if(nxy==1) return;
842
843float mx=(*this)(il,jl);
844for (int i=il; i<=ih; i++)
845 for (int j=jl; j<=jh; j++)
846 if ((*this)(i,j)<mx) {imax = i; jmax = j; mx=(*this)(i,j);}
847}
848
849
850//++
851float Histo2D::VMax(int il,int ih,int jl,int jh) const
852//
853// Recherche du maximum dans le pave [il,ih][jl,jh].
854//--
855{
856if( il > ih ) { il = 0; ih = nx-1; }
857if( jl > jh ) { jl = 0; jh = ny-1; }
858if( il < 0 ) il = 0;
859if( jl < 0 ) jl = 0;
860if( ih >= nx ) ih = nx-1;
861if( jh >= ny ) jh = ny-1;
862
863float mx=(*this)(il,jl);
864if(nxy==1) return mx;
865for (int i=il; i<=ih; i++)
866 for (int j=jl; j<=jh; j++)
867 if ((*this)(i,j)>mx) mx=(*this)(i,j);
868return mx;
869}
870
871//++
872float Histo2D::VMin(int il,int ih,int jl,int jh) const
873//
874// Recherche du minimum dans le pave [il,ih][jl,jh].
875//--
876{
877if( il > ih ) { il = 0; ih = nx-1; }
878if( jl > jh ) { jl = 0; jh = ny-1; }
879if( il < 0 ) il = 0;
880if( jl < 0 ) jl = 0;
881if( ih >= nx ) ih = nx-1;
882if( jh >= ny ) jh = ny-1;
883
884float mx=(*this)(il,jl);
885if(nxy==1) return mx;
886for (int i=il; i<=ih; i++)
887 for (int j=jl; j<=jh; j++)
888 if ((*this)(i,j)<mx) mx=(*this)(i,j);
889return mx;
890}
891
892///////////////////////////////////////////////////////////////////
893//++
894float Histo2D::NOver(int i,int j) const
895//
896// Renvoie les under.overflow dans les 8 quadrants.
897//| over[3][3]: 20 | 21 | 22
898//| | |
899//| --------------
900//| | |
901//| 10 | 11 | 12 11 = all overflow+underflow
902//| | |
903//| --------------
904//| | |
905//| 00 | 01 | 02
906//--
907{
908if( i < 0 || i>=3 || j < 0 || j>=3 ) return over[1][1];
909return over[i][j];
910}
911
912
913///////////////////////////////////////////////////////////////////
914//++
915int Histo2D::BinNonNul() const
916//
917// Retourne le nombre de bins non-nuls.
918//--
919{
920int non=0;
921for (int i=0;i<nxy;i++) if( data[i] != 0. ) non++;
922return non;
923}
924
925//++
926int Histo2D::ErrNonNul() const
927//
928// Retourne le nombre de bins avec erreurs non-nulles.
929//--
930{
931if(err2==NULL) return -1;
932int non=0;
933for (int i=0;i<nxy;i++) if( err2[i] != 0. ) non++;
934return non;
935}
936
937///////////////////////////////////////////////////////////////////
938//++
939int Histo2D::EstimeMax(float& xm,float& ym,int SzPav
940 ,int il,int ih,int jl,int jh)
941//
942// Idem EstimeMax(int...) mais retourne x,y.
943//--
944{
945int im,jm;
946IJMax(im,jm,il,ih,jl,jh);
947return EstimeMax(im,jm,xm,ym,SzPav);
948}
949
950//++
951int Histo2D::EstimeMax(int im,int jm,float& xm,float& ym,int SzPav)
952//
953// Determine les abscisses et ordonnees du maximum donne par im,jm
954// en moyennant dans un pave SzPav x SzPav autour du maximum.
955//| Return:
956//| 0 = si fit maximum reussi avec SzPav pixels
957//| 1 = si fit maximum reussi avec moins que SzPav pixels
958//| dans au moins 1 direction
959//| 2 = si fit maximum echoue et renvoit BinCenter()
960//| -1 = si echec: SzPav <= 0 ou im,jm hors limites
961//--
962{
963xm = ym = 0;
964if( SzPav <= 0 ) return -1;
965if( im < 0 || im >= nx ) return -1;
966if( jm < 0 || jm >= ny ) return -1;
967
968if( SzPav%2 == 0 ) SzPav++;
969SzPav = (SzPav-1)/2;
970
971int rc = 0;
972double dxm = 0, dym = 0, wx = 0;
973for(int i=im-SzPav;i<=im+SzPav;i++) {
974 if( i<0 || i>= nx ) {rc=1; continue;}
975 for(int j=jm-SzPav;j<=jm+SzPav;j++) {
976 if( j<0 || j>= ny ) {rc=1; continue;}
977 float x,y;
978 BinCenter(i,j,x,y);
979 dxm += x * (*this)(i,j);
980 dym += y * (*this)(i,j);
981 wx += (*this)(i,j);
982 }
983}
984
985if( wx > 0. ) {
986 xm = dxm/wx;
987 ym = dym/wx;
988 return rc;
989} else {
990 BinCenter(im,jm,xm,ym);
991 return 2;
992}
993
994}
995
996//++
997int Histo2D::FindMax(int& im,int& jm,int SzPav,float Dz
998 ,int il,int ih,int jl,int jh)
999//
1000// Pour trouver le maximum de l'histogramme en tenant compte
1001// des fluctuations.
1002//| Methode:
1003//| 1-/ On recherche le bin maximum MAX de l'histogramme
1004//| 2-/ On considere que tous les pixels compris entre [MAX-Dz,MAX]
1005//| peuvent etre des pixels maxima.
1006//| 3-/ On identifie le bin maximum en choissisant le pixel du 2-/
1007//| tel que la somme des pixels dans un pave SzPav x SzPav soit maximale.
1008//| INPUT:
1009//| SzPav = taille du pave pour departager
1010//| Dz = tolerance pour identifier tous les pixels "maximum"
1011//| OUTPUT:
1012//| im,jm = pixel maximum trouve
1013//| RETURN:
1014//| <0 = Echec
1015//| >0 = nombre de pixels possibles pour le maximum
1016//--
1017{
1018if( il > ih ) { il = 0; ih = nx-1; }
1019if( jl > jh ) { jl = 0; jh = ny-1; }
1020if( il < 0 ) il = 0;
1021if( jl < 0 ) jl = 0;
1022if( ih >= nx ) ih = nx-1;
1023if( jh >= ny ) jh = ny-1;
1024if( SzPav < 0 ) SzPav = 0;
1025 else { if( SzPav%2 == 0 ) SzPav++; SzPav = (SzPav-1)/2;}
1026if( Dz < 0 ) Dz = 0.;
1027float max = VMax(il,ih,jl,jh) - Dz;
1028int nmax = 0;
1029float sumx = -MAXFLOAT;
1030for(int i=il;i<=ih;i++) for(int j=jl;j<=jh;j++) {
1031 if( (*this)(i,j) < max) continue;
1032 nmax++;
1033 float sum = 0.;
1034 for(int ii=i-SzPav;ii<=i+SzPav;ii++) {
1035 if( ii<0 || ii >= nx ) continue;
1036 for(int jj=j-SzPav;jj<=j+SzPav;jj++) {
1037 if( jj<0 || jj >= ny ) continue;
1038 sum += (*this)(ii,jj);
1039 }
1040 }
1041 if( sum > sumx ) { im = i; jm = j; sumx = sum;}
1042}
1043if( nmax <= 0 ) { IJMax(im,jm,il,ih,jl,jh); return 1;}
1044return nmax;
1045}
1046
1047//////////////////////////////////////////////////////////
1048
1049//////////////////////////////////////////////////////////
1050//++
1051int Histo2D::Fit(GeneralFit& gfit,unsigned short typ_err)
1052//
1053// Fit de l'histogramme par ``gfit''.
1054//| typ_err = 0 :
1055//| - erreur attachee au bin si elle existe
1056//| - sinon 1
1057//| typ_err = 1 :
1058//| - erreur attachee au bin si elle existe
1059//| - sinon max( sqrt(abs(bin) ,1 )
1060//| typ_err = 2 :
1061//| - erreur forcee a 1
1062//| typ_err = 3 :
1063//| - erreur forcee a max( sqrt(abs(bin) ,1 )
1064//| typ_err = 4 :
1065//| - erreur forcee a 1, nulle si bin a zero.
1066//| typ_err = 5 :
1067//| - erreur forcee a max( sqrt(abs(bin) ,1 ),
1068//| nulle si bin a zero.
1069//--
1070{
1071if(NBinX()*NBinY()<=0) return -1000;
1072if(typ_err>5) typ_err=0;
1073
1074GeneralFitData mydata(2,NBinX()*NBinY());
1075
1076for(int i=0;i<NBinX();i++) for(int j=0;j<NBinY();j++) {
1077 float x,y;
1078 BinCenter(i,j,x,y);
1079 double f = (double) (*this)(i,j);
1080 double saf = sqrt(fabs(f)); if(saf<1.) saf=1.;
1081 double e;
1082 if(typ_err==0) {if(HasErrors()) e=Error(i,j); else e=1.;}
1083 else if(typ_err==1) {if(HasErrors()) e=Error(i,j); else e=saf;}
1084 else if(typ_err==2) e=1.;
1085 else if(typ_err==3) e=saf;
1086 else if(typ_err==4) e=(f==0.)?0.:1.;
1087 else if(typ_err==5) e=(f==0.)?0.:saf;
1088 mydata.AddData2((double) x,(double) y,f,e);
1089}
1090
1091gfit.SetData(&mydata);
1092
1093return gfit.Fit();
1094}
1095
1096//++
1097Histo2D Histo2D::FitResidus(GeneralFit& gfit)
1098//
1099// Retourne une classe contenant les residus du fit ``gfit''.
1100//--
1101{
1102if(NBinX()<=0 || NBinY()<=0)
1103 throw(SzMismatchError("Histo2D::FitResidus: size mismatch\n"));
1104GeneralFunction* f = gfit.GetFunction();
1105if(f==NULL)
1106 throw(NullPtrError("Histo2D::FitResidus: NULL pointer\n"));
1107Vector par = gfit.GetParm();
1108Histo2D h2(*this);
1109for(int i=0;i<NBinX();i++) for(int j=0;j<NBinY();j++) {
1110 float xc,yc;
1111 BinCenter(i,j,xc,yc);
1112 double x[2] = {(double)xc,(double)yc};
1113 h2(i,j) -= (float) f->Value(x,par.Data());
1114}
1115return h2;
1116}
1117
1118//++
1119Histo2D Histo2D::FitFunction(GeneralFit& gfit)
1120//
1121// Retourne une classe contenant la fonction du fit ``gfit''.
1122//--
1123{
1124if(NBinX()<=0 || NBinY()<=0)
1125 throw(SzMismatchError("Histo2D::FitFunction: size mismatch\n"));
1126GeneralFunction* f = gfit.GetFunction();
1127if(f==NULL)
1128 throw(NullPtrError("Histo2D::FitFunction: NULL pointer\n"));
1129Vector par = gfit.GetParm();
1130Histo2D h2(*this);
1131for(int i=0;i<NBinX();i++) for(int j=0;j<NBinY();j++) {
1132 float xc,yc;
1133 BinCenter(i,j,xc,yc);
1134 double x[2] = {(double)xc,(double)yc};
1135 h2(i,j) = (float) f->Value(x,par.Data());
1136}
1137return h2;
1138}
1139
1140///////////////////////////////////////////////////////////////////
1141//++
1142void Histo2D::PrintStatus()
1143//
1144// Impression des informations sur l'histogramme.
1145//--
1146{
1147printf("~Histo::Print nHist=%g nEntries=%d\n",nHist,nEntries);
1148printf("over: [ %g %g %g // %g %g %g // %g %g %g ]\n"
1149 ,over[2][0],over[2][1],over[2][2]
1150 ,over[1][0],over[1][1],over[1][2]
1151 ,over[0][0],over[0][1],over[0][2]);
1152printf(" nx=%d xmin=%g xmax=%g binx=%g ",nx,xmin,xmax,wbinx);
1153printf(" ny=%d ymin=%g ymax=%g biny=%g\n",ny,ymin,ymax,wbiny);
1154}
1155
1156///////////////////////////////////////////////////////////////////
1157//++
1158void Histo2D::Print(float min,float max
1159 ,int il,int ih,int jl,int jh)
1160//
1161// Impression de l'histogramme sur stdout entre [il,ih] et [jl,jh].
1162//--
1163{
1164int ns = 35;
1165// numero d'index: 00000000001111111111222222222233333
1166// 01234567890123456789012345678901234
1167// valeur entiere: 00000000001111111111222222222233333
1168// 12345678901234567890123456789012345
1169const char *s = "+23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1170
1171if( il > ih ) { il = 0; ih = nx-1; }
1172if( jl > jh ) { jl = 0; jh = ny-1; }
1173if( il < 0 ) il = 0;
1174if( jl < 0 ) jl = 0;
1175if( ih >= nx ) ih = nx-1;
1176if( jh >= ny ) jh = ny-1;
1177
1178PrintStatus();
1179
1180if( il != 0 || ih != nx-1 || jl != 0 || jh != ny-1 ) {
1181 float xl,xh,yl,yh;
1182 BinLowEdge(il,jl,xl,yl);
1183 BinHighEdge(ih,jh,xh,yh);
1184 printf(" impression");
1185 printf(" en X: %d=[%d,%d] xmin=%g xmax=%g "
1186 ,ih-il+1,il,ih,xl,xh);
1187 printf(" en Y: %d=[%d,%d] ymin=%g ymax=%g\n"
1188 ,jh-jl+1,jl,jh,yl,yh);
1189}
1190
1191if(min >= max) { if(min != 0.) min = VMin(il,ih,jl,jh); else min=0.;
1192 max = VMax(il,ih,jl,jh); }
1193if(min>max) return;
1194if(min==max) {min -= 1.; max += 1.;}
1195printf(" min=%g max=%g\n",min,max);
1196
1197// imprime numero de bin en colonne
1198printf("\n");
1199if( nx-1 >= 100 ) {
1200 printf(" ");
1201 for(int i=il;i<=ih;i++) printf("%1d",(int) (i%1000)/100);
1202 printf("\n");
1203}
1204if( nx-1 >= 10 ) {
1205 printf(" ");
1206 for(int i=il;i<=ih;i++) printf("%1d",(int) (i%100)/10);
1207 printf("\n");
1208}
1209printf(" ");
1210for(int i=il;i<=ih;i++) printf("%1d",i%10);
1211printf("\n");
1212printf(" "); {for(int i=il;i<=ih;i++) printf("-"); printf("\n");}
1213
1214// imprime histogramme
1215for(int j=jh;j>=jl;j--) {
1216 printf("%3d: ",j);
1217 for(int i=il;i<=ih;i++) {
1218 int h;
1219 if( 1<=max-min && max-min<=35 ) h = (int)( (*this)(i,j) - min ) - 1;
1220 else h = (int)( ((*this)(i,j)-min)/(max-min) * ns ) - 1;
1221 char c;
1222 if(h<0 && (*this)(i,j)>min) c = '.';
1223 else if(h<0) c = ' ';
1224 else if(h>=ns) c = '*';
1225 else c = s[h];
1226 printf("%c",c);
1227 }
1228 printf("\n");
1229}
1230
1231// imprime numero de bin en colonne
1232printf(" "); {for(int i=il;i<=ih;i++) printf("-"); printf("\n");}
1233if( nx-1 >= 100 ) {
1234 printf(" ");
1235 for(int i=il;i<=ih;i++) printf("%1d",(int) (i%1000)/100);
1236 printf("\n");
1237}
1238if( nx-1 >= 10 ) {
1239 printf(" ");
1240 for(int i=il;i<=ih;i++) printf("%1d",(int) (i%100)/10);
1241 printf("\n");
1242}
1243printf(" ");
1244{for(int i=il;i<=ih;i++) printf("%1d",i%10);}
1245printf("\n");
1246
1247}
1248
1249// Rappel des inline functions pour commentaires
1250//++
1251// inline float XMin()
1252// Retourne l'abscisse minimum.
1253//--
1254//++
1255// inline float XMax()
1256// Retourne l'abscisse maximum.
1257//--
1258//++
1259// inline float YMin()
1260// Retourne l'ordonnee minimum.
1261//--
1262//++
1263// inline float YMax()
1264// Retourne l'ordonnee maximum.
1265//--
1266//++
1267// inline int NBinX()
1268// Retourne le nombre de bins selon X.
1269//--
1270//++
1271// inline int NBinY()
1272// Retourne le nombre de bins selon Y.
1273//--
1274//++
1275// inline float WBinX()
1276// Retourne la largeur du bin selon X.
1277//--
1278//++
1279// inline float WBinY()
1280// Retourne la largeur du bin selon Y.
1281//--
1282//++
1283// inline float* Bins() const
1284// Retourne le pointeur sur le tableaux des contenus.
1285//--
1286//++
1287// inline float operator()(int i,int j) const
1288// Retourne le contenu du bin i,j.
1289//--
1290//++
1291// inline float& operator()(int i,int j)
1292// Remplit le contenu du bin i,j.
1293//--
1294//++
1295// inline float Error(int i,int j) const
1296// Retourne l'erreur du bin i,j.
1297//--
1298//++
1299// inline double Error2(int i,int j) const
1300// Retourne l'erreur au carre du bin i,j.
1301//--
1302//++
1303// inline double& Error2(int i,int j)
1304// Remplit l'erreur au carre du bin i,j.
1305//--
1306//++
1307// inline float NData() const
1308// Retourne la somme ponderee.
1309//--
1310//++
1311// inline int NEntries() const
1312// Retourne le nombre d'entrees.
1313//--
1314//++
1315// inline void BinLowEdge(int i,int j,float& x,float& y)
1316// Retourne l'abscisse et l'ordonnee du coin inferieur du bin i,j.
1317//--
1318//++
1319// inline void BinCenter(int i,int j,float& x,float& y)
1320// Retourne l'abscisse et l'ordonnee du centre du bin i,j.
1321//--
1322//++
1323// inline void BinHighEdge(int i,int j,float& x,float& y)
1324// Retourne l'abscisse et l'ordonnee du coin superieur du bin i,j.
1325//--
1326//++
1327// inline void FindBin(float x,float y,int& i,int& j)
1328// Retourne les numeros du bin contenant l'abscisse et l'ordonnee x,y.
1329//--
1330
1331///////////////////////////////////////////////////////////////////
1332//++
1333// Titre Methodes pour gerer les projections
1334//--
1335
1336//++
1337void Histo2D::SetProjX()
1338//
1339// Pour creer la projection X.
1340//--
1341{
1342if( hprojx != NULL ) DelProjX();
1343hprojx = new Histo(xmin,xmax,nx);
1344if( err2 != NULL && hprojx != NULL ) hprojx->Errors();
1345}
1346
1347//++
1348void Histo2D::SetProjY()
1349//
1350// Pour creer la projection Y.
1351//--
1352{
1353if( hprojy != NULL ) DelProjY();
1354hprojy = new Histo(ymin,ymax,ny);
1355if( err2 != NULL && hprojy != NULL ) hprojy->Errors();
1356}
1357
1358//++
1359void Histo2D::SetProj()
1360//
1361// Pour creer les projections X et Y.
1362//--
1363{
1364SetProjX();
1365SetProjY();
1366}
1367
1368//++
1369void Histo2D::ShowProj()
1370//
1371// Informations sur les projections.
1372//--
1373{
1374if( hprojx != NULL ) cout << ">>>> Projection X set : "<< hprojx <<endl;
1375 else cout << ">>>> NO Projection X set"<<endl;
1376if( hprojy != NULL ) cout << ">>>> Projection Y set : "<< hprojy <<endl;
1377 else cout << ">>>> NO Projection Y set"<<endl;
1378}
1379
1380//++
1381void Histo2D::DelProjX()
1382//
1383// Destruction de l'histogramme de la projection selon X.
1384//--
1385{
1386if( hprojx == NULL ) return;
1387delete hprojx;
1388hprojx = NULL;
1389}
1390
1391//++
1392void Histo2D::DelProjY()
1393//
1394// Destruction de l'histogramme de la projection selon X.
1395//--
1396{
1397if( hprojy == NULL ) return;
1398delete hprojy;
1399hprojy = NULL;
1400}
1401
1402//++
1403void Histo2D::DelProj()
1404//
1405// Destruction des histogrammes des projections selon X et Y.
1406//--
1407{
1408DelProjX();
1409DelProjY();
1410}
1411
1412//++
1413void Histo2D::ZeroProjX()
1414//
1415// Remise a zero de la projection selon X.
1416//--
1417{
1418if( hprojx == NULL ) return;
1419hprojx->Zero();
1420}
1421
1422//++
1423void Histo2D::ZeroProjY()
1424//
1425// Remise a zero de la projection selon Y.
1426//--
1427{
1428if( hprojy == NULL ) return;
1429hprojy->Zero();
1430}
1431
1432//++
1433void Histo2D::ZeroProj()
1434//
1435// Remise a zero des projections selon X et Y.
1436//--
1437{
1438ZeroProjX();
1439ZeroProjY();
1440}
1441
1442// Rappel des inline functions pour commentaires
1443//++
1444// inline Histo* HProjX()
1445// Retourne le pointeur sur l'histo 1D de la projection selon X.
1446//--
1447//++
1448// inline Histo* HProjY()
1449// Retourne le pointeur sur l'histo 1D de la projection selon Y.
1450//--
1451
1452///////////////////////////////////////////////////////////////////
1453//++
1454// Titre Methodes pour gerer les bandes
1455//--
1456
1457//++
1458int Histo2D::SetBandX(float ybmin,float ybmax)
1459//
1460// Pour creer une bande en X entre ybmin et ybmax.
1461//--
1462{
1463b_s.num = lbandx.size();
1464b_s.min = ybmin;
1465b_s.max = ybmax;
1466b_s.H = new Histo(xmin,xmax,nx);
1467lbandx.push_back(b_s);
1468b_s.H = NULL;
1469return lbandx.size()-1;
1470}
1471
1472//++
1473int Histo2D::SetBandY(float xbmin,float xbmax)
1474//
1475// Pour creer une bande en Y entre xbmin et xbmax.
1476//--
1477{
1478b_s.num = lbandy.size();
1479b_s.min = xbmin;
1480b_s.max = xbmax;
1481b_s.H = new Histo(ymin,ymax,ny);
1482lbandy.push_back(b_s);
1483b_s.H = NULL;
1484return lbandy.size()-1;
1485}
1486
1487//++
1488void Histo2D::DelBandX()
1489//
1490// Destruction des histogrammes des bandes selon X.
1491//--
1492{
1493if( lbandx.size() <= 0 ) return;
1494for(list<bande_slice>::iterator i = lbandx.begin(); i != lbandx.end(); i++)
1495 if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
1496lbandx.erase(lbandx.begin(),lbandx.end());
1497}
1498
1499//++
1500void Histo2D::DelBandY()
1501//
1502// Destruction des histogrammes des bandes selon Y.
1503//--
1504{
1505if( lbandy.size() <= 0 ) return;
1506for(list<bande_slice>::iterator i = lbandy.begin(); i != lbandy.end(); i++)
1507 if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
1508lbandy.erase(lbandy.begin(),lbandy.end());
1509}
1510
1511//++
1512void Histo2D::ZeroBandX()
1513//
1514// Remise a zero des bandes selon X.
1515//--
1516{
1517if( lbandx.size() <= 0 ) return;
1518list<bande_slice>::iterator i;
1519for(i = lbandx.begin(); i != lbandx.end(); i++)
1520 (*i).H->Zero();
1521}
1522
1523//++
1524void Histo2D::ZeroBandY()
1525//
1526// Remise a zero des bandes selon Y.
1527//--
1528{
1529if( lbandy.size() <= 0 ) return;
1530list<bande_slice>::iterator i;
1531for(i = lbandy.begin(); i != lbandy.end(); i++)
1532 (*i).H->Zero();
1533}
1534
1535//++
1536Histo* Histo2D::HBandX(int n) const
1537//
1538// Retourne un pointeur sur la bande numero `n' selon X.
1539//--
1540{
1541if( lbandx.size() <= 0 || n < 0 || n >= (int) lbandx.size() ) return NULL;
1542for(list<bande_slice>::const_iterator i = lbandx.begin(); i != lbandx.end(); i++)
1543 if( (*i).num == n ) return (*i).H;
1544return NULL;
1545}
1546
1547//++
1548Histo* Histo2D::HBandY(int n) const
1549//
1550// Retourne un pointeur sur la bande numero `n' selon Y.
1551//--
1552{
1553if( lbandy.size() <= 0 || n < 0 || n >= (int) lbandy.size() ) return NULL;
1554for(list<bande_slice>::const_iterator i = lbandy.begin(); i != lbandy.end(); i++)
1555 if( (*i).num == n ) return (*i).H;
1556return NULL;
1557}
1558
1559//++
1560void Histo2D::GetBandX(int n,float& ybmin,float& ybmax) const
1561//
1562// Retourne les limites de la bande numero `n' selon X.
1563//--
1564{
1565ybmin = 0.; ybmax = 0.;
1566if( lbandx.size() <= 0 || n < 0 || n >= (int) lbandx.size() ) return;
1567for(list<bande_slice>::const_iterator i = lbandx.begin(); i != lbandx.end(); i++)
1568 if( (*i).num == n ) { ybmin = (*i).min; ybmax = (*i).max; return;}
1569return;
1570}
1571
1572//++
1573void Histo2D::GetBandY(int n,float& xbmin,float& xbmax) const
1574//
1575// Retourne les limites de la bande numero `n' selon Y.
1576//--
1577{
1578xbmin = 0.; xbmax = 0.;
1579if( lbandy.size() <= 0 || n < 0 || n >= (int) lbandy.size() ) return;
1580for(list<bande_slice>::const_iterator i = lbandy.begin(); i != lbandy.end(); i++)
1581 if( (*i).num == n ) { xbmin = (*i).min; xbmax = (*i).max; return;}
1582return;
1583}
1584
1585//++
1586void Histo2D::ShowBand(int lp)
1587//
1588// Informations sur les bandes.
1589//--
1590{
1591 cout << ">>>> Nombre de bande X : " << lbandx.size() << endl;
1592if( lp>0 && lbandx.size()>0 ) {
1593 list<bande_slice>::iterator i;
1594 for(i = lbandx.begin(); i != lbandx.end(); i++) {
1595 cout<<" "<<(*i).num<<" de ymin="<<(*i).min<<" a ymax="<<(*i).max;
1596 if(lp>1) cout << " H=" << (*i).H;
1597 cout << endl;
1598 }
1599}
1600
1601cout << ">>>> Nombre de bande Y : " << lbandy.size() << endl;
1602if( lp>0 && lbandy.size()>0 ) {
1603 list<bande_slice>::iterator i;
1604 for(i = lbandy.begin(); i != lbandy.end(); i++) {
1605 cout<<" "<<(*i).num<<" de xmin="<<(*i).min<<" a xmax="<<(*i).max;
1606 if(lp>1) cout << " H=" << (*i).H;
1607 cout << endl;
1608 }
1609}
1610}
1611
1612// Rappel des inline functions pour commentaires
1613//++
1614// inline int NBandX()
1615// Retourne le nombre de bandes selon X
1616//--
1617//++
1618// inline int NBandY()
1619// Retourne le nombre de bandes selon Y
1620//--
1621
1622///////////////////////////////////////////////////////////////////
1623//++
1624// Titre Methodes pour gerer les bandes equidistantes
1625//--
1626
1627//++
1628int Histo2D::SetSliX(int nsli)
1629//
1630// Pour creer `nsli' bandes equidistantes selon X.
1631//--
1632{
1633if( nsli <= 0 ) return -1;
1634if( nsli > ny ) nsli = ny;
1635if( lslix.size() > 0 ) DelSliX();
1636float w = (ymax-ymin)/nsli;
1637
1638for(int i=0; i<nsli; i++ ) {
1639 b_s.num = i;
1640 b_s.min = ymin + i*w;
1641 b_s.max = b_s.min + w;
1642 b_s.H = new Histo(xmin,xmax,nx);
1643 lslix.push_back(b_s);
1644 b_s.H = NULL;
1645}
1646return (int) lslix.size();
1647}
1648
1649//++
1650int Histo2D::SetSliY(int nsli)
1651//
1652// Pour creer `nsli' bandes equidistantes selon Y.
1653//--
1654{
1655if( nsli <= 0 ) return -1;
1656if( nsli > nx ) nsli = nx;
1657if( lsliy.size() > 0 ) DelSliY();
1658float w = (xmax-xmin)/nsli;
1659
1660for(int i=0; i<nsli; i++ ) {
1661 b_s.num = i;
1662 b_s.min = xmin + i*w;
1663 b_s.max = b_s.min + w;
1664 b_s.H = new Histo(ymin,ymax,ny);
1665 lsliy.push_back(b_s);
1666 b_s.H = NULL;
1667}
1668return (int) lsliy.size();
1669}
1670
1671//++
1672void Histo2D::DelSliX()
1673//
1674// Destruction des bandes equidistantes selon X.
1675//--
1676{
1677if( lslix.size() <= 0 ) return;
1678for(list<bande_slice>::iterator i = lslix.begin(); i != lslix.end(); i++)
1679 if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
1680lslix.erase(lslix.begin(),lslix.end());
1681}
1682
1683//++
1684void Histo2D::DelSliY()
1685//
1686// Destruction des bandes equidistantes selon Y.
1687//--
1688{
1689if( lsliy.size() <= 0 ) return;
1690for(list<bande_slice>::iterator i = lsliy.begin(); i != lsliy.end(); i++)
1691 if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
1692lsliy.erase(lsliy.begin(),lsliy.end());
1693}
1694
1695//++
1696void Histo2D::ZeroSliX()
1697//
1698// Remise a zero des bandes equidistantes selon X.
1699//--
1700{
1701if( lslix.size() <= 0 ) return;
1702list<bande_slice>::iterator i;
1703for(i = lslix.begin(); i != lslix.end(); i++)
1704 (*i).H->Zero();
1705}
1706
1707//++
1708void Histo2D::ZeroSliY()
1709//
1710// Remise a zero des bandes equidistantes selon Y.
1711//--
1712{
1713if( lsliy.size() <= 0 ) return;
1714list<bande_slice>::iterator i;
1715for(i = lsliy.begin(); i != lsliy.end(); i++)
1716 (*i).H->Zero();
1717}
1718
1719//++
1720Histo* Histo2D::HSliX(int n) const
1721//
1722// Retourne un pointeur sur la bande equidistante numero `n'
1723// selon X.
1724//--
1725{
1726if( lslix.size() <= 0 || n < 0 || n >= (int) lslix.size() ) return NULL;
1727for(list<bande_slice>::const_iterator i = lslix.begin(); i != lslix.end(); i++)
1728 if( (*i).num == n ) return (*i).H;
1729return NULL;
1730}
1731
1732//++
1733Histo* Histo2D::HSliY(int n) const
1734//
1735// Retourne un pointeur sur la bande equidistante numero `n'
1736// selon Y.
1737//--
1738{
1739if( lsliy.size() <= 0 || n < 0 || n >= (int) lsliy.size() ) return NULL;
1740for(list<bande_slice>::const_iterator i = lsliy.begin(); i != lsliy.end(); i++)
1741 if( (*i).num == n ) return (*i).H;
1742return NULL;
1743}
1744
1745//++
1746void Histo2D::ShowSli(int lp)
1747//
1748// Informations sur les bandes equidistantes.
1749//--
1750{
1751list<bande_slice>::iterator i;
1752cout << ">>>> Nombre de slice X : " << lslix.size() << endl;
1753if( lp>0 && lslix.size() > 0 )
1754 for(i = lslix.begin(); i != lslix.end(); i++) {
1755 cout<<" "<<(*i).num<<" de ymin="<<(*i).min<<" a ymax="<<(*i).max;
1756 if(lp>1) cout << " H=" << (*i).H;
1757 cout << endl;
1758 }
1759
1760cout << ">>>> Nombre de slice Y : " << lsliy.size() << endl;
1761if( lp>0 && lsliy.size()>0 )
1762 for(i = lsliy.begin(); i != lsliy.end(); i++) {
1763 cout<<" "<<(*i).num<<" de xmin="<<(*i).min<<" a xmax="<<(*i).max;
1764 if(lp>1) cout << " H=" << (*i).H;
1765 cout << endl;
1766 }
1767}
1768
1769// Rappel des inline functions pour commentaires
1770//++
1771// inline int NSliX()
1772// Retourne le nombre de slices selon X
1773//--
1774//++
1775// inline int NSliY()
1776// Retourne le nombre de slices selon Y
1777//--
1778
1779
1780///////////////////////////////////////////////////////////
1781// --------------------------------------------------------
1782// Les objets delegues pour la gestion de persistance
1783// --------------------------------------------------------
1784///////////////////////////////////////////////////////////
1785
1786
1787void ObjFileIO<Histo2D>::ReadSelf(PInPersist& is)
1788{
1789char strg[256];
1790
1791if(dobj==NULL) dobj=new Histo2D;
1792 else dobj->Delete();
1793
1794float min,max;
1795int_4 errok, projx, projy, nslix, nsliy, nbanx, nbany;
1796
1797// Lecture entete
1798is.GetLine(strg, 255);
1799is.GetLine(strg, 255);
1800is.GetLine(strg, 255);
1801is.GetLine(strg, 255);
1802is.GetLine(strg, 255);
1803is.GetLine(strg, 255);
1804
1805// Lecture variables de definitions
1806is.Get(dobj->nx);
1807is.Get(dobj->ny);
1808is.Get(dobj->nxy);
1809is.Get(errok);
1810is.Get(dobj->nEntries);
1811is.Get(dobj->nHist);
1812
1813is.Get(dobj->xmin);
1814is.Get(dobj->xmax);
1815is.Get(dobj->ymin);
1816is.Get(dobj->ymax);
1817is.Get(dobj->wbinx);
1818is.Get(dobj->wbiny);
1819
1820is.Get(&(dobj->over[0][0]),9);
1821
1822is.Get(projx);
1823is.Get(projy);
1824is.Get(nslix);
1825is.Get(nsliy);
1826is.Get(nbanx);
1827is.Get(nbany);
1828
1829// Lecture histo2D
1830dobj->data = new float[dobj->nxy];
1831is.GetLine(strg, 255);
1832{for(int j=0;j<dobj->ny;j++) is.Get(dobj->data+j*dobj->nx,dobj->nx);}
1833
1834// Lecture erreurs
1835if(errok) {
1836 is.GetLine(strg, 255);
1837 dobj->err2 = new double[dobj->nxy];
1838 for(int j=0;j<dobj->ny;j++) is.Get(dobj->err2+j*dobj->nx,dobj->nx);
1839}
1840
1841// Lecture des projections
1842if(projx) {
1843 is.GetLine(strg, 255);
1844 dobj->SetProjX();
1845 ObjFileIO<Histo> fio_h(dobj->hprojx);
1846 fio_h.Read(is);
1847}
1848if(projy) {
1849 is.GetLine(strg, 255);
1850 dobj->SetProjY();
1851 ObjFileIO<Histo> fio_h(dobj->hprojy);
1852 fio_h.Read(is);
1853}
1854
1855// Lecture des slices
1856if(nslix>0) {
1857 is.GetLine(strg, 255);
1858 dobj->SetSliX(nslix);
1859 ASSERT (nslix==dobj->NSliX());
1860 for(int j=0;j<dobj->NSliX();j++)
1861 {ObjFileIO<Histo> fio_h(dobj->HSliX(j)); fio_h.Read(is);}
1862}
1863if(nsliy>0) {
1864 is.GetLine(strg, 255);
1865 dobj->SetSliY(nsliy);
1866 ASSERT (nsliy==dobj->NSliY());
1867 for(int j=0;j<dobj->NSliY();j++)
1868 {ObjFileIO<Histo> fio_h(dobj->HSliY(j)); fio_h.Read(is);}
1869}
1870
1871// Lecture des bandes
1872if( nbanx>0 ) {
1873 is.GetLine(strg, 255);
1874 {for(int j=0; j<nbanx; j++) {
1875 is.Get(min); is.Get(max);
1876 dobj->SetBandX(min,max);
1877 }}
1878 ASSERT (nbanx==dobj->NBandX());
1879 {for(int j=0; j<dobj->NBandX(); j++) {
1880 ObjFileIO<Histo> fio_h(dobj->HBandX(j));
1881 fio_h.Read(is);
1882 }}
1883}
1884if( nbany>0 ) {
1885 is.GetLine(strg, 255);
1886 {for(int j=0; j<nbany; j++) {
1887 is.Get(min); is.Get(max);
1888 dobj->SetBandY(min,max);
1889 }}
1890 ASSERT (nbany==dobj->NBandY());
1891 {for(int j=0; j<dobj->NBandY(); j++) {
1892 ObjFileIO<Histo> fio_h(dobj->HBandY(j));
1893 fio_h.Read(is);
1894 }}
1895}
1896
1897return;
1898}
1899
1900void ObjFileIO<Histo2D>::WriteSelf(POutPersist& os) const
1901{
1902if (dobj == NULL) return;
1903char strg[256];
1904
1905// Que faut-il ecrire?
1906int_4 errok = (dobj->err2) ? 1 : 0;
1907int_4 projx = (dobj->hprojx) ? 1 : 0;
1908int_4 projy = (dobj->hprojy) ? 1 : 0;
1909int_4 nslix = dobj->NSliX();
1910int_4 nsliy = dobj->NSliY();
1911int_4 nbanx = dobj->NBandX();
1912int_4 nbany = dobj->NBandY();
1913
1914// Ecriture entete pour identifier facilement
1915sprintf(strg,"nx=%d ny=%d nxy=%d errok=%1d"
1916 ,dobj->nx,dobj->ny,dobj->nxy,errok);
1917os.PutLine(strg);
1918sprintf(strg,"nHist=%g nEntries=%d",dobj->nHist,dobj->nEntries);
1919os.PutLine(strg);
1920sprintf(strg,"wbinx=%g wbiny=%g",dobj->wbinx,dobj->wbiny);
1921os.PutLine(strg);
1922sprintf(strg,"xmin=%g xmax=%g ymin=%g ymax=%g"
1923 ,dobj->xmin,dobj->xmax,dobj->ymin,dobj->ymax);
1924os.PutLine(strg);
1925sprintf(strg,"projx/y=%d %d nbandx/y=%d %d nbslix/y=%d %d"
1926 ,projx,projy,nbanx,nbany,nslix,nsliy);
1927os.PutLine(strg);
1928sprintf(strg,"over %g %g %g %g %g %g %g %g %g"
1929 ,dobj->over[0][0],dobj->over[0][1],dobj->over[0][2]
1930 ,dobj->over[1][0],dobj->over[1][1],dobj->over[1][2]
1931 ,dobj->over[2][0],dobj->over[2][1],dobj->over[2][2]);
1932os.PutLine(strg);
1933
1934// Ecriture variables de definitions
1935os.Put(dobj->nx);
1936os.Put(dobj->ny);
1937os.Put(dobj->nxy);
1938os.Put(errok);
1939os.Put(dobj->nEntries);
1940os.Put(dobj->nHist);
1941
1942os.Put(dobj->xmin);
1943os.Put(dobj->xmax);
1944os.Put(dobj->ymin);
1945os.Put(dobj->ymax);
1946os.Put(dobj->wbinx);
1947os.Put(dobj->wbiny);
1948
1949os.Put(&(dobj->over[0][0]),9);
1950
1951os.Put(projx);
1952os.Put(projy);
1953os.Put(nslix);
1954os.Put(nsliy);
1955os.Put(nbanx);
1956os.Put(nbany);
1957
1958// Ecriture histo2D
1959sprintf(strg,"Histo2D: Tableau des donnees %d = %d * %d"
1960 ,dobj->nxy,dobj->nx,dobj->ny);
1961os.PutLine(strg);
1962{for(int j=0;j<dobj->ny;j++) os.Put(dobj->data+j*dobj->nx,dobj->nx);}
1963
1964// Ecriture erreurs
1965if(errok) {
1966 sprintf(strg,"Histo2D: Tableau des erreurs %d = %d * %d"
1967 ,dobj->nxy,dobj->nx,dobj->ny);
1968 os.PutLine(strg);
1969 for(int j=0;j<dobj->ny;j++) os.Put(dobj->err2+j*dobj->nx,dobj->nx);
1970}
1971
1972// Ecriture des projections
1973if(projx) {
1974 sprintf(strg,"Histo2D: Projection X");
1975 os.PutLine(strg);
1976 ObjFileIO<Histo> fio_h(dobj->hprojx); fio_h.Write(os);
1977}
1978if(projy) {
1979 sprintf(strg,"Histo2D: Projection Y");
1980 os.PutLine(strg);
1981 ObjFileIO<Histo> fio_h(dobj->hprojy); fio_h.Write(os);
1982}
1983
1984// Ecriture des slices
1985if(nslix>0) {
1986 sprintf(strg,"Histo2D: Slices X %d",nslix);
1987 os.PutLine(strg);
1988 for(int j=0;j<nslix;j++) {
1989 Histo* h = dobj->HSliX(j);
1990 ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
1991 }
1992}
1993if(nsliy>0) {
1994 sprintf(strg,"Histo2D: Slices Y %d",nsliy);
1995 os.PutLine(strg);
1996 for(int j=0;j<nsliy;j++) {
1997 Histo* h = dobj->HSliY(j);
1998 ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
1999 }
2000}
2001
2002// Ecriture des bandes
2003if( nbanx>0 ) {
2004 sprintf(strg,"Histo2D: Bandes X %d",nbanx);
2005 os.PutLine(strg);
2006 list<Histo2D::bande_slice>::const_iterator it;
2007 for(it = dobj->lbandx.begin(); it != dobj->lbandx.end(); it++) {
2008 float min = (*it).min; float max = (*it).max;
2009 os.Put(min); os.Put(max);
2010 }
2011 for(it = dobj->lbandx.begin(); it != dobj->lbandx.end(); it++) {
2012 Histo* h = (*it).H;
2013 ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
2014 }
2015}
2016if( nbany>0 ) {
2017 sprintf(strg,"Histo2D: Bandes Y %d",nbany);
2018 os.PutLine(strg);
2019 list<Histo2D::bande_slice>::const_iterator it;
2020 for(it = dobj->lbandy.begin(); it != dobj->lbandy.end(); it++) {
2021 float min = (*it).min; float max = (*it).max;
2022 os.Put(min); os.Put(max);
2023 }
2024 for(it = dobj->lbandy.begin(); it != dobj->lbandy.end(); it++) {
2025 Histo* h = (*it).H;
2026 ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
2027 }
2028}
2029
2030return;
2031}
2032
2033
2034#ifdef __CXX_PRAGMA_TEMPLATES__
2035#pragma define_template ObjFileIO<Histo2D>
2036#endif
2037
2038#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
2039template class ObjFileIO<Histo2D>;
2040#endif
Note: See TracBrowser for help on using the repository browser.