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

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

cmv 7/7/2000

hisprof.cc,h:

fonction IsOk()
GetMean -> GetValue (mauvais nom)
float Error2() -> double Error2()
nouveau: GetError(TVector<r_8>& v)
HProf::PrintF() sur-ecriture de Histo::PrintF
protection dans createur par copie dans alloc

SumY... pour le cas ou H.bins==0

protection dans UpdateHisto pour HProf cree par defaut (bins==0)
Dans WriteSelf UpdateHisto appele que si necessaire (IsOk()?)

histos2.cc : le Print() dit si les erreurs ont ete demandees
histos.cc,h:

protection dans createur par copie dans alloc

pour le cas ou H.bins==0

protection dans Zero() pour Histo cree par defaut (bins==0)
protection dans operator=() pour Histo cree par defaut (bins==0)
le Print() dit si les erreurs ont ete demandees

cmv 7/7/2000

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