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

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

les friend operator ne marche plus ? passage en inline cmv 30/06/00

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\n",nHist,nEntries);
1005printf("over: [ %g %g %g // %g %g %g // %g %g %g ]\n"
1006 ,over[2][0],over[2][1],over[2][2]
1007 ,over[1][0],over[1][1],over[1][2]
1008 ,over[0][0],over[0][1],over[0][2]);
1009printf(" nx=%d xmin=%g xmax=%g binx=%g ",nx,xmin,xmax,wbinx);
1010printf(" ny=%d ymin=%g ymax=%g biny=%g\n",ny,ymin,ymax,wbiny);
1011}
1012
1013///////////////////////////////////////////////////////////////////
1014/*!
1015 Impression de l'histogramme sur stdout entre [il,ih] et [jl,jh].
1016 \verbatim
1017 numero d'index: 00000000001111111111222222222233333
1018 01234567890123456789012345678901234
1019 valeur entiere: 00000000001111111111222222222233333
1020 12345678901234567890123456789012345
1021 \endverbatim
1022*/
1023void Histo2D::Print(float min,float max
1024 ,int il,int ih,int jl,int jh)
1025{
1026int ns = 35;
1027const char *s = "+23456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1028
1029if( il > ih ) { il = 0; ih = nx-1; }
1030if( jl > jh ) { jl = 0; jh = ny-1; }
1031if( il < 0 ) il = 0;
1032if( jl < 0 ) jl = 0;
1033if( ih >= nx ) ih = nx-1;
1034if( jh >= ny ) jh = ny-1;
1035
1036PrintStatus();
1037
1038if( il != 0 || ih != nx-1 || jl != 0 || jh != ny-1 ) {
1039 float xl,xh,yl,yh;
1040 BinLowEdge(il,jl,xl,yl);
1041 BinHighEdge(ih,jh,xh,yh);
1042 printf(" impression");
1043 printf(" en X: %d=[%d,%d] xmin=%g xmax=%g "
1044 ,ih-il+1,il,ih,xl,xh);
1045 printf(" en Y: %d=[%d,%d] ymin=%g ymax=%g\n"
1046 ,jh-jl+1,jl,jh,yl,yh);
1047}
1048
1049if(min >= max) { if(min != 0.) min = VMin(il,ih,jl,jh); else min=0.;
1050 max = VMax(il,ih,jl,jh); }
1051if(min>max) return;
1052if(min==max) {min -= 1.; max += 1.;}
1053printf(" min=%g max=%g\n",min,max);
1054
1055// imprime numero de bin en colonne
1056printf("\n");
1057if( nx-1 >= 100 ) {
1058 printf(" ");
1059 for(int i=il;i<=ih;i++) printf("%1d",(int) (i%1000)/100);
1060 printf("\n");
1061}
1062if( nx-1 >= 10 ) {
1063 printf(" ");
1064 for(int i=il;i<=ih;i++) printf("%1d",(int) (i%100)/10);
1065 printf("\n");
1066}
1067printf(" ");
1068for(int i=il;i<=ih;i++) printf("%1d",i%10);
1069printf("\n");
1070printf(" "); {for(int i=il;i<=ih;i++) printf("-"); printf("\n");}
1071
1072// imprime histogramme
1073for(int j=jh;j>=jl;j--) {
1074 printf("%3d: ",j);
1075 for(int i=il;i<=ih;i++) {
1076 int h;
1077 if( 1<=max-min && max-min<=35 ) h = (int)( (*this)(i,j) - min ) - 1;
1078 else h = (int)( ((*this)(i,j)-min)/(max-min) * ns ) - 1;
1079 char c;
1080 if(h<0 && (*this)(i,j)>min) c = '.';
1081 else if(h<0) c = ' ';
1082 else if(h>=ns) c = '*';
1083 else c = s[h];
1084 printf("%c",c);
1085 }
1086 printf("\n");
1087}
1088
1089// imprime numero de bin en colonne
1090printf(" "); {for(int i=il;i<=ih;i++) printf("-"); printf("\n");}
1091if( nx-1 >= 100 ) {
1092 printf(" ");
1093 for(int i=il;i<=ih;i++) printf("%1d",(int) (i%1000)/100);
1094 printf("\n");
1095}
1096if( nx-1 >= 10 ) {
1097 printf(" ");
1098 for(int i=il;i<=ih;i++) printf("%1d",(int) (i%100)/10);
1099 printf("\n");
1100}
1101printf(" ");
1102{for(int i=il;i<=ih;i++) printf("%1d",i%10);}
1103printf("\n");
1104
1105}
1106
1107///////////////////////////////////////////////////////////////////
1108// Titre Methodes pour gerer les projections
1109
1110/*!
1111 Pour creer la projection X.
1112*/
1113void Histo2D::SetProjX()
1114{
1115if( hprojx != NULL ) DelProjX();
1116hprojx = new Histo(xmin,xmax,nx);
1117if( err2 != NULL && hprojx != NULL ) hprojx->Errors();
1118}
1119
1120/*!
1121 Pour creer la projection Y.
1122*/
1123void Histo2D::SetProjY()
1124{
1125if( hprojy != NULL ) DelProjY();
1126hprojy = new Histo(ymin,ymax,ny);
1127if( err2 != NULL && hprojy != NULL ) hprojy->Errors();
1128}
1129
1130/*!
1131 Pour creer les projections X et Y.
1132*/
1133void Histo2D::SetProj()
1134{
1135SetProjX();
1136SetProjY();
1137}
1138
1139/*!
1140 Informations sur les projections.
1141*/
1142void Histo2D::ShowProj()
1143{
1144if( hprojx != NULL ) cout << ">>>> Projection X set : "<< hprojx <<endl;
1145 else cout << ">>>> NO Projection X set"<<endl;
1146if( hprojy != NULL ) cout << ">>>> Projection Y set : "<< hprojy <<endl;
1147 else cout << ">>>> NO Projection Y set"<<endl;
1148}
1149
1150/*!
1151 Destruction de l'histogramme de la projection selon X.
1152*/
1153void Histo2D::DelProjX()
1154{
1155if( hprojx == NULL ) return;
1156delete hprojx;
1157hprojx = NULL;
1158}
1159
1160/*!
1161 Destruction de l'histogramme de la projection selon X.
1162*/
1163void Histo2D::DelProjY()
1164{
1165if( hprojy == NULL ) return;
1166delete hprojy;
1167hprojy = NULL;
1168}
1169
1170/*!
1171 Destruction des histogrammes des projections selon X et Y.
1172*/
1173void Histo2D::DelProj()
1174{
1175DelProjX();
1176DelProjY();
1177}
1178
1179/*!
1180 Remise a zero de la projection selon X.
1181*/
1182void Histo2D::ZeroProjX()
1183{
1184if( hprojx == NULL ) return;
1185hprojx->Zero();
1186}
1187
1188/*!
1189 Remise a zero de la projection selon Y.
1190*/
1191void Histo2D::ZeroProjY()
1192{
1193if( hprojy == NULL ) return;
1194hprojy->Zero();
1195}
1196
1197/*!
1198 Remise a zero des projections selon X et Y.
1199*/
1200void Histo2D::ZeroProj()
1201{
1202ZeroProjX();
1203ZeroProjY();
1204}
1205
1206///////////////////////////////////////////////////////////////////
1207// Titre Methodes pour gerer les bandes
1208
1209/*!
1210 Pour creer une bande en X entre ybmin et ybmax.
1211*/
1212int Histo2D::SetBandX(float ybmin,float ybmax)
1213{
1214b_s.num = lbandx.size();
1215b_s.min = ybmin;
1216b_s.max = ybmax;
1217b_s.H = new Histo(xmin,xmax,nx);
1218lbandx.push_back(b_s);
1219b_s.H = NULL;
1220return lbandx.size()-1;
1221}
1222
1223/*!
1224 Pour creer une bande en Y entre xbmin et xbmax.
1225*/
1226int Histo2D::SetBandY(float xbmin,float xbmax)
1227{
1228b_s.num = lbandy.size();
1229b_s.min = xbmin;
1230b_s.max = xbmax;
1231b_s.H = new Histo(ymin,ymax,ny);
1232lbandy.push_back(b_s);
1233b_s.H = NULL;
1234return lbandy.size()-1;
1235}
1236
1237/*!
1238 Destruction des histogrammes des bandes selon X.
1239*/
1240void Histo2D::DelBandX()
1241{
1242if( lbandx.size() <= 0 ) return;
1243for(list<bande_slice>::iterator i = lbandx.begin(); i != lbandx.end(); i++)
1244 if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
1245lbandx.erase(lbandx.begin(),lbandx.end());
1246}
1247
1248/*!
1249 Destruction des histogrammes des bandes selon Y.
1250*/
1251void Histo2D::DelBandY()
1252{
1253if( lbandy.size() <= 0 ) return;
1254for(list<bande_slice>::iterator i = lbandy.begin(); i != lbandy.end(); i++)
1255 if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
1256lbandy.erase(lbandy.begin(),lbandy.end());
1257}
1258
1259/*!
1260 Remise a zero des bandes selon X.
1261*/
1262void Histo2D::ZeroBandX()
1263{
1264if( lbandx.size() <= 0 ) return;
1265list<bande_slice>::iterator i;
1266for(i = lbandx.begin(); i != lbandx.end(); i++)
1267 (*i).H->Zero();
1268}
1269
1270/*!
1271 Remise a zero des bandes selon Y.
1272*/
1273void Histo2D::ZeroBandY()
1274{
1275if( lbandy.size() <= 0 ) return;
1276list<bande_slice>::iterator i;
1277for(i = lbandy.begin(); i != lbandy.end(); i++)
1278 (*i).H->Zero();
1279}
1280
1281/*!
1282 Retourne un pointeur sur la bande numero `n' selon X.
1283*/
1284Histo* Histo2D::HBandX(int n) const
1285{
1286if( lbandx.size() <= 0 || n < 0 || n >= (int) lbandx.size() ) return NULL;
1287for(list<bande_slice>::const_iterator i = lbandx.begin(); i != lbandx.end(); i++)
1288 if( (*i).num == n ) return (*i).H;
1289return NULL;
1290}
1291
1292/*!
1293 Retourne un pointeur sur la bande numero `n' selon Y.
1294*/
1295Histo* Histo2D::HBandY(int n) const
1296{
1297if( lbandy.size() <= 0 || n < 0 || n >= (int) lbandy.size() ) return NULL;
1298for(list<bande_slice>::const_iterator i = lbandy.begin(); i != lbandy.end(); i++)
1299 if( (*i).num == n ) return (*i).H;
1300return NULL;
1301}
1302
1303/*!
1304 Retourne les limites de la bande numero `n' selon X.
1305*/
1306void Histo2D::GetBandX(int n,float& ybmin,float& ybmax) const
1307{
1308ybmin = 0.; ybmax = 0.;
1309if( lbandx.size() <= 0 || n < 0 || n >= (int) lbandx.size() ) return;
1310for(list<bande_slice>::const_iterator i = lbandx.begin(); i != lbandx.end(); i++)
1311 if( (*i).num == n ) { ybmin = (*i).min; ybmax = (*i).max; return;}
1312return;
1313}
1314
1315/*!
1316 Retourne les limites de la bande numero `n' selon Y.
1317*/
1318void Histo2D::GetBandY(int n,float& xbmin,float& xbmax) const
1319{
1320xbmin = 0.; xbmax = 0.;
1321if( lbandy.size() <= 0 || n < 0 || n >= (int) lbandy.size() ) return;
1322for(list<bande_slice>::const_iterator i = lbandy.begin(); i != lbandy.end(); i++)
1323 if( (*i).num == n ) { xbmin = (*i).min; xbmax = (*i).max; return;}
1324return;
1325}
1326
1327/*!
1328 Informations sur les bandes.
1329*/
1330void Histo2D::ShowBand(int lp)
1331{
1332 cout << ">>>> Nombre de bande X : " << lbandx.size() << endl;
1333if( lp>0 && lbandx.size()>0 ) {
1334 list<bande_slice>::iterator i;
1335 for(i = lbandx.begin(); i != lbandx.end(); i++) {
1336 cout<<" "<<(*i).num<<" de ymin="<<(*i).min<<" a ymax="<<(*i).max;
1337 if(lp>1) cout << " H=" << (*i).H;
1338 cout << endl;
1339 }
1340}
1341
1342cout << ">>>> Nombre de bande Y : " << lbandy.size() << endl;
1343if( lp>0 && lbandy.size()>0 ) {
1344 list<bande_slice>::iterator i;
1345 for(i = lbandy.begin(); i != lbandy.end(); i++) {
1346 cout<<" "<<(*i).num<<" de xmin="<<(*i).min<<" a xmax="<<(*i).max;
1347 if(lp>1) cout << " H=" << (*i).H;
1348 cout << endl;
1349 }
1350}
1351}
1352
1353///////////////////////////////////////////////////////////////////
1354// Titre Methodes pour gerer les bandes equidistantes ou slices
1355
1356/*!
1357 Pour creer `nsli' bandes equidistantes selon X.
1358*/
1359int Histo2D::SetSliX(int nsli)
1360{
1361if( nsli <= 0 ) return -1;
1362if( nsli > ny ) nsli = ny;
1363if( lslix.size() > 0 ) DelSliX();
1364float w = (ymax-ymin)/nsli;
1365
1366for(int i=0; i<nsli; i++ ) {
1367 b_s.num = i;
1368 b_s.min = ymin + i*w;
1369 b_s.max = b_s.min + w;
1370 b_s.H = new Histo(xmin,xmax,nx);
1371 lslix.push_back(b_s);
1372 b_s.H = NULL;
1373}
1374return (int) lslix.size();
1375}
1376
1377/*!
1378 Pour creer `nsli' bandes equidistantes selon Y.
1379*/
1380int Histo2D::SetSliY(int nsli)
1381{
1382if( nsli <= 0 ) return -1;
1383if( nsli > nx ) nsli = nx;
1384if( lsliy.size() > 0 ) DelSliY();
1385float w = (xmax-xmin)/nsli;
1386
1387for(int i=0; i<nsli; i++ ) {
1388 b_s.num = i;
1389 b_s.min = xmin + i*w;
1390 b_s.max = b_s.min + w;
1391 b_s.H = new Histo(ymin,ymax,ny);
1392 lsliy.push_back(b_s);
1393 b_s.H = NULL;
1394}
1395return (int) lsliy.size();
1396}
1397
1398/*!
1399 Destruction des bandes equidistantes selon X.
1400*/
1401void Histo2D::DelSliX()
1402{
1403if( lslix.size() <= 0 ) return;
1404for(list<bande_slice>::iterator i = lslix.begin(); i != lslix.end(); i++)
1405 if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
1406lslix.erase(lslix.begin(),lslix.end());
1407}
1408
1409/*!
1410 Destruction des bandes equidistantes selon Y.
1411*/
1412void Histo2D::DelSliY()
1413{
1414if( lsliy.size() <= 0 ) return;
1415for(list<bande_slice>::iterator i = lsliy.begin(); i != lsliy.end(); i++)
1416 if( (*i).H != NULL ) {delete (*i).H; (*i).H=NULL;}
1417lsliy.erase(lsliy.begin(),lsliy.end());
1418}
1419
1420/*!
1421 Remise a zero des bandes equidistantes selon X.
1422*/
1423void Histo2D::ZeroSliX()
1424{
1425if( lslix.size() <= 0 ) return;
1426list<bande_slice>::iterator i;
1427for(i = lslix.begin(); i != lslix.end(); i++)
1428 (*i).H->Zero();
1429}
1430
1431/*!
1432 Remise a zero des bandes equidistantes selon Y.
1433*/
1434void Histo2D::ZeroSliY()
1435{
1436if( lsliy.size() <= 0 ) return;
1437list<bande_slice>::iterator i;
1438for(i = lsliy.begin(); i != lsliy.end(); i++)
1439 (*i).H->Zero();
1440}
1441
1442/*!
1443 Retourne un pointeur sur la bande equidistante numero `n'
1444 selon X.
1445*/
1446Histo* Histo2D::HSliX(int n) const
1447{
1448if( lslix.size() <= 0 || n < 0 || n >= (int) lslix.size() ) return NULL;
1449for(list<bande_slice>::const_iterator i = lslix.begin(); i != lslix.end(); i++)
1450 if( (*i).num == n ) return (*i).H;
1451return NULL;
1452}
1453
1454/*!
1455 Retourne un pointeur sur la bande equidistante numero `n'
1456 selon Y.
1457*/
1458Histo* Histo2D::HSliY(int n) const
1459{
1460if( lsliy.size() <= 0 || n < 0 || n >= (int) lsliy.size() ) return NULL;
1461for(list<bande_slice>::const_iterator i = lsliy.begin(); i != lsliy.end(); i++)
1462 if( (*i).num == n ) return (*i).H;
1463return NULL;
1464}
1465
1466/*!
1467 Informations sur les bandes equidistantes.
1468*/
1469void Histo2D::ShowSli(int lp)
1470{
1471list<bande_slice>::iterator i;
1472cout << ">>>> Nombre de slice X : " << lslix.size() << endl;
1473if( lp>0 && lslix.size() > 0 )
1474 for(i = lslix.begin(); i != lslix.end(); i++) {
1475 cout<<" "<<(*i).num<<" de ymin="<<(*i).min<<" a ymax="<<(*i).max;
1476 if(lp>1) cout << " H=" << (*i).H;
1477 cout << endl;
1478 }
1479
1480cout << ">>>> Nombre de slice Y : " << lsliy.size() << endl;
1481if( lp>0 && lsliy.size()>0 )
1482 for(i = lsliy.begin(); i != lsliy.end(); i++) {
1483 cout<<" "<<(*i).num<<" de xmin="<<(*i).min<<" a xmax="<<(*i).max;
1484 if(lp>1) cout << " H=" << (*i).H;
1485 cout << endl;
1486 }
1487}
1488
1489///////////////////////////////////////////////////////////
1490// --------------------------------------------------------
1491// Les objets delegues pour la gestion de persistance
1492// --------------------------------------------------------
1493///////////////////////////////////////////////////////////
1494
1495
1496void ObjFileIO<Histo2D>::ReadSelf(PInPersist& is)
1497{
1498char strg[256];
1499
1500if(dobj==NULL) dobj=new Histo2D;
1501 else dobj->Delete();
1502
1503float min,max;
1504int_4 errok, projx, projy, nslix, nsliy, nbanx, nbany;
1505
1506// Lecture entete
1507is.GetLine(strg, 255);
1508is.GetLine(strg, 255);
1509is.GetLine(strg, 255);
1510is.GetLine(strg, 255);
1511is.GetLine(strg, 255);
1512is.GetLine(strg, 255);
1513
1514// Lecture variables de definitions
1515is.Get(dobj->nx);
1516is.Get(dobj->ny);
1517is.Get(dobj->nxy);
1518is.Get(errok);
1519is.Get(dobj->nEntries);
1520is.Get(dobj->nHist);
1521
1522is.Get(dobj->xmin);
1523is.Get(dobj->xmax);
1524is.Get(dobj->ymin);
1525is.Get(dobj->ymax);
1526is.Get(dobj->wbinx);
1527is.Get(dobj->wbiny);
1528
1529is.Get(&(dobj->over[0][0]),9);
1530
1531is.Get(projx);
1532is.Get(projy);
1533is.Get(nslix);
1534is.Get(nsliy);
1535is.Get(nbanx);
1536is.Get(nbany);
1537
1538// Lecture histo2D
1539dobj->data = new float[dobj->nxy];
1540is.GetLine(strg, 255);
1541{for(int j=0;j<dobj->ny;j++) is.Get(dobj->data+j*dobj->nx,dobj->nx);}
1542
1543// Lecture erreurs
1544if(errok) {
1545 is.GetLine(strg, 255);
1546 dobj->err2 = new double[dobj->nxy];
1547 for(int j=0;j<dobj->ny;j++) is.Get(dobj->err2+j*dobj->nx,dobj->nx);
1548}
1549
1550// Lecture des projections
1551if(projx) {
1552 is.GetLine(strg, 255);
1553 dobj->SetProjX();
1554 ObjFileIO<Histo> fio_h(dobj->hprojx);
1555 fio_h.Read(is);
1556}
1557if(projy) {
1558 is.GetLine(strg, 255);
1559 dobj->SetProjY();
1560 ObjFileIO<Histo> fio_h(dobj->hprojy);
1561 fio_h.Read(is);
1562}
1563
1564// Lecture des slices
1565if(nslix>0) {
1566 is.GetLine(strg, 255);
1567 dobj->SetSliX(nslix);
1568 ASSERT (nslix==dobj->NSliX());
1569 for(int j=0;j<dobj->NSliX();j++)
1570 {ObjFileIO<Histo> fio_h(dobj->HSliX(j)); fio_h.Read(is);}
1571}
1572if(nsliy>0) {
1573 is.GetLine(strg, 255);
1574 dobj->SetSliY(nsliy);
1575 ASSERT (nsliy==dobj->NSliY());
1576 for(int j=0;j<dobj->NSliY();j++)
1577 {ObjFileIO<Histo> fio_h(dobj->HSliY(j)); fio_h.Read(is);}
1578}
1579
1580// Lecture des bandes
1581if( nbanx>0 ) {
1582 is.GetLine(strg, 255);
1583 {for(int j=0; j<nbanx; j++) {
1584 is.Get(min); is.Get(max);
1585 dobj->SetBandX(min,max);
1586 }}
1587 ASSERT (nbanx==dobj->NBandX());
1588 {for(int j=0; j<dobj->NBandX(); j++) {
1589 ObjFileIO<Histo> fio_h(dobj->HBandX(j));
1590 fio_h.Read(is);
1591 }}
1592}
1593if( nbany>0 ) {
1594 is.GetLine(strg, 255);
1595 {for(int j=0; j<nbany; j++) {
1596 is.Get(min); is.Get(max);
1597 dobj->SetBandY(min,max);
1598 }}
1599 ASSERT (nbany==dobj->NBandY());
1600 {for(int j=0; j<dobj->NBandY(); j++) {
1601 ObjFileIO<Histo> fio_h(dobj->HBandY(j));
1602 fio_h.Read(is);
1603 }}
1604}
1605
1606return;
1607}
1608
1609void ObjFileIO<Histo2D>::WriteSelf(POutPersist& os) const
1610{
1611if (dobj == NULL) return;
1612char strg[256];
1613
1614// Que faut-il ecrire?
1615int_4 errok = (dobj->err2) ? 1 : 0;
1616int_4 projx = (dobj->hprojx) ? 1 : 0;
1617int_4 projy = (dobj->hprojy) ? 1 : 0;
1618int_4 nslix = dobj->NSliX();
1619int_4 nsliy = dobj->NSliY();
1620int_4 nbanx = dobj->NBandX();
1621int_4 nbany = dobj->NBandY();
1622
1623// Ecriture entete pour identifier facilement
1624sprintf(strg,"nx=%d ny=%d nxy=%d errok=%1d"
1625 ,dobj->nx,dobj->ny,dobj->nxy,errok);
1626os.PutLine(strg);
1627sprintf(strg,"nHist=%g nEntries=%d",dobj->nHist,dobj->nEntries);
1628os.PutLine(strg);
1629sprintf(strg,"wbinx=%g wbiny=%g",dobj->wbinx,dobj->wbiny);
1630os.PutLine(strg);
1631sprintf(strg,"xmin=%g xmax=%g ymin=%g ymax=%g"
1632 ,dobj->xmin,dobj->xmax,dobj->ymin,dobj->ymax);
1633os.PutLine(strg);
1634sprintf(strg,"projx/y=%d %d nbandx/y=%d %d nbslix/y=%d %d"
1635 ,projx,projy,nbanx,nbany,nslix,nsliy);
1636os.PutLine(strg);
1637sprintf(strg,"over %g %g %g %g %g %g %g %g %g"
1638 ,dobj->over[0][0],dobj->over[0][1],dobj->over[0][2]
1639 ,dobj->over[1][0],dobj->over[1][1],dobj->over[1][2]
1640 ,dobj->over[2][0],dobj->over[2][1],dobj->over[2][2]);
1641os.PutLine(strg);
1642
1643// Ecriture variables de definitions
1644os.Put(dobj->nx);
1645os.Put(dobj->ny);
1646os.Put(dobj->nxy);
1647os.Put(errok);
1648os.Put(dobj->nEntries);
1649os.Put(dobj->nHist);
1650
1651os.Put(dobj->xmin);
1652os.Put(dobj->xmax);
1653os.Put(dobj->ymin);
1654os.Put(dobj->ymax);
1655os.Put(dobj->wbinx);
1656os.Put(dobj->wbiny);
1657
1658os.Put(&(dobj->over[0][0]),9);
1659
1660os.Put(projx);
1661os.Put(projy);
1662os.Put(nslix);
1663os.Put(nsliy);
1664os.Put(nbanx);
1665os.Put(nbany);
1666
1667// Ecriture histo2D
1668sprintf(strg,"Histo2D: Tableau des donnees %d = %d * %d"
1669 ,dobj->nxy,dobj->nx,dobj->ny);
1670os.PutLine(strg);
1671{for(int j=0;j<dobj->ny;j++) os.Put(dobj->data+j*dobj->nx,dobj->nx);}
1672
1673// Ecriture erreurs
1674if(errok) {
1675 sprintf(strg,"Histo2D: Tableau des erreurs %d = %d * %d"
1676 ,dobj->nxy,dobj->nx,dobj->ny);
1677 os.PutLine(strg);
1678 for(int j=0;j<dobj->ny;j++) os.Put(dobj->err2+j*dobj->nx,dobj->nx);
1679}
1680
1681// Ecriture des projections
1682if(projx) {
1683 sprintf(strg,"Histo2D: Projection X");
1684 os.PutLine(strg);
1685 ObjFileIO<Histo> fio_h(dobj->hprojx); fio_h.Write(os);
1686}
1687if(projy) {
1688 sprintf(strg,"Histo2D: Projection Y");
1689 os.PutLine(strg);
1690 ObjFileIO<Histo> fio_h(dobj->hprojy); fio_h.Write(os);
1691}
1692
1693// Ecriture des slices
1694if(nslix>0) {
1695 sprintf(strg,"Histo2D: Slices X %d",nslix);
1696 os.PutLine(strg);
1697 for(int j=0;j<nslix;j++) {
1698 Histo* h = dobj->HSliX(j);
1699 ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
1700 }
1701}
1702if(nsliy>0) {
1703 sprintf(strg,"Histo2D: Slices Y %d",nsliy);
1704 os.PutLine(strg);
1705 for(int j=0;j<nsliy;j++) {
1706 Histo* h = dobj->HSliY(j);
1707 ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
1708 }
1709}
1710
1711// Ecriture des bandes
1712if( nbanx>0 ) {
1713 sprintf(strg,"Histo2D: Bandes X %d",nbanx);
1714 os.PutLine(strg);
1715 list<Histo2D::bande_slice>::const_iterator it;
1716 for(it = dobj->lbandx.begin(); it != dobj->lbandx.end(); it++) {
1717 float min = (*it).min; float max = (*it).max;
1718 os.Put(min); os.Put(max);
1719 }
1720 for(it = dobj->lbandx.begin(); it != dobj->lbandx.end(); it++) {
1721 Histo* h = (*it).H;
1722 ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
1723 }
1724}
1725if( nbany>0 ) {
1726 sprintf(strg,"Histo2D: Bandes Y %d",nbany);
1727 os.PutLine(strg);
1728 list<Histo2D::bande_slice>::const_iterator it;
1729 for(it = dobj->lbandy.begin(); it != dobj->lbandy.end(); it++) {
1730 float min = (*it).min; float max = (*it).max;
1731 os.Put(min); os.Put(max);
1732 }
1733 for(it = dobj->lbandy.begin(); it != dobj->lbandy.end(); it++) {
1734 Histo* h = (*it).H;
1735 ObjFileIO<Histo> fio_h(h); fio_h.Write(os);
1736 }
1737}
1738
1739return;
1740}
1741
1742
1743#ifdef __CXX_PRAGMA_TEMPLATES__
1744#pragma define_template ObjFileIO<Histo2D>
1745#endif
1746
1747#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
1748template class ObjFileIO<Histo2D>;
1749#endif
Note: See TracBrowser for help on using the repository browser.