ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TProfile2D.cxx
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 // Author: Rene Brun 16/04/2000
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TProfile2D.h"
13 #include "TBuffer.h"
14 #include "TMath.h"
15 #include "THLimitsFinder.h"
16 #include "Riostream.h"
17 #include "TVirtualPad.h"
18 #include "TError.h"
19 #include "TClass.h"
20 
21 #include "TProfileHelper.h"
22 
24 
26 
27 /** \class TProfile2D
28  \ingroup Hist
29  Profile2D histograms are used to display the mean
30  value of Z and its RMS for each cell in X,Y.
31  Profile2D histograms are in many cases an
32  elegant replacement of three-dimensional histograms : the inter-relation of three
33  measured quantities X, Y and Z can always be visualized by a three-dimensional
34  histogram or scatter-plot; its representation on the line-printer is not particularly
35  satisfactory, except for sparse data. If Z is an unknown (but single-valued)
36  approximate function of X,Y this function is displayed by a profile2D histogram with
37  much better precision than by a scatter-plot.
38 
39  The following formulae show the cumulated contents (capital letters) and the values
40  displayed by the printing or plotting routines (small letters) of the elements for cell I, J.
41 
42  2
43  H(I,J) = sum Z E(I,J) = sum Z
44  l(I,J) = sum l L(I,J) = sum l
45  h(I,J) = H(I,J)/L(I,J) s(I,J) = sqrt(E(I,J)/L(I,J)- h(I,J)**2)
46  e(I,J) = s(I,J)/sqrt(L(I,J))
47 
48  In the special case where s(I,J) is zero (eg, case of 1 entry only in one cell)
49  the bin error e(I,J) is computed from the average of the s(I,J) for all cells
50  if the static function TProfile2D::Approximate has been called.
51  This simple/crude approximation was suggested in order to keep the cell
52  during a fit operation. But note that this approximation is not the default behaviour.
53 
54  Example of a profile2D histogram
55  ~~~~{.cpp}
56  {
57  TCanvas *c1 = new TCanvas("c1","Profile histogram example",200,10,700,500);
58  hprof2d = new TProfile2D("hprof2d","Profile of pz versus px and py",40,-4,4,40,-4,4,0,20);
59  Float_t px, py, pz;
60  for ( Int_t i=0; i<25000; i++) {
61  gRandom->Rannor(px,py);
62  pz = px*px + py*py;
63  hprof2d->Fill(px,py,pz,1);
64  }
65  hprof2d->Draw();
66  }
67  ~~~~
68 */
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// Default constructor for Profile2D histograms
72 
74 {
75  fTsumwz = fTsumwz2 = 0;
76  fScaling = kFALSE;
77  BuildOptions(0,0,"");
78 }
79 
80 ////////////////////////////////////////////////////////////////////////////////
81 /// Default destructor for Profile2D histograms
82 
84 {
85 }
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 /// Normal Constructor for Profile histograms -*
89 ///
90 /// The first eight parameters are similar to TH2D::TH2D.
91 /// All values of z are accepted at filling time.
92 /// To fill a profile2D histogram, one must use TProfile2D::Fill function.
93 ///
94 /// Note that when filling the profile histogram the function Fill
95 /// checks if the variable z is betyween fZmin and fZmax.
96 /// If a minimum or maximum value is set for the Z scale before filling,
97 /// then all values below zmin or above zmax will be discarded.
98 /// Setting the minimum or maximum value for the Z scale before filling
99 /// has the same effect as calling the special TProfile2D constructor below
100 /// where zmin and zmax are specified.
101 ///
102 /// H(I,J) is printed as the cell contents. The errors computed are s(I,J) if CHOPT='S'
103 /// (spread option), or e(I,J) if CHOPT=' ' (error on mean).
104 ///
105 /// See TProfile2D::BuildOptions for explanation of parameters
106 ///
107 /// see other constructors below with all possible combinations of
108 /// fix and variable bin size like in TH2D.
109 
110 TProfile2D::TProfile2D(const char *name,const char *title,Int_t nx,Double_t xlow,Double_t xup,Int_t ny,Double_t ylow,Double_t yup,Option_t *option)
111 : TH2D(name,title,nx,xlow,xup,ny,ylow,yup)
112 {
113  BuildOptions(0,0,option);
114  if (xlow >= xup || ylow >= yup) SetBuffer(fgBufferSize);
115 }
116 
117 ////////////////////////////////////////////////////////////////////////////////
118 /// Create a 2-D Profile with variable bins in X and fix bins in Y
119 
120 TProfile2D::TProfile2D(const char *name,const char *title,Int_t nx,const Double_t *xbins,Int_t ny,Double_t ylow,Double_t yup,Option_t *option)
121 : TH2D(name,title,nx,xbins,ny,ylow,yup)
122 {
123  BuildOptions(0,0,option);
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// Create a 2-D Profile with fix bins in X and variable bins in Y
128 
129 TProfile2D::TProfile2D(const char *name,const char *title,Int_t nx,Double_t xlow,Double_t xup,Int_t ny,const Double_t *ybins,Option_t *option)
130 : TH2D(name,title,nx,xlow,xup,ny,ybins)
131 {
132  BuildOptions(0,0,option);
133 }
134 
135 ////////////////////////////////////////////////////////////////////////////////
136 /// Create a 2-D Profile with variable bins in X and variable bins in Y
137 
138 TProfile2D::TProfile2D(const char *name,const char *title,Int_t nx,const Double_t *xbins,Int_t ny,const Double_t *ybins,Option_t *option)
139 : TH2D(name,title,nx,xbins,ny,ybins)
140 {
141  BuildOptions(0,0,option);
142 }
143 
144 
145 ////////////////////////////////////////////////////////////////////////////////
146 /// Constructor for Profile2D histograms with range in z
147 /// The first eight parameters are similar to TH2D::TH2D.
148 /// Only the values of Z between ZMIN and ZMAX will be considered at filling time.
149 /// zmin and zmax will also be the maximum and minimum values
150 /// on the z scale when drawing the profile2D.
151 ///
152 /// See TProfile2D::BuildOptions for more explanations on errors
153 ///
154 
155 TProfile2D::TProfile2D(const char *name,const char *title,Int_t nx,Double_t xlow,Double_t xup,Int_t ny, Double_t ylow,Double_t yup,Double_t zlow,Double_t zup,Option_t *option)
156 : TH2D(name,title,nx,xlow,xup,ny,ylow,yup)
157 {
158  BuildOptions(zlow,zup,option);
159  if (xlow >= xup || ylow >= yup) SetBuffer(fgBufferSize);
160 }
161 
162 
163 ////////////////////////////////////////////////////////////////////////////////
164 /// Set Profile2D histogram structure and options
165 ///
166 /// zmin: minimum value allowed for z
167 /// zmax: maximum value allowed for z
168 /// if (zmin = zmax = 0) there are no limits on the allowed z values (zmin = -inf, zmax = +inf)
169 ///
170 /// option: this is the option for the computation of the t error of the profile ( TProfile2D::GetBinError )
171 /// possible values for the options are documented in TProfile2D::SetErrorOption
172 
174 {
175  // See TProfile::BuildOptions for a detailed deescription
176  //
177  //
178 
179  SetErrorOption(option);
180 
181  // create extra profile data structire (bin entries/ y^2 and sum of weight square)
183 
184  fZmin = zmin;
185  fZmax = zmax;
186  fScaling = kFALSE;
187  fTsumwz = fTsumwz2 = 0;
188 }
189 
190 ////////////////////////////////////////////////////////////////////////////////
191 /// Copy constructor.
192 
194 {
195  ((TProfile2D&)profile).Copy(*this);
196 }
197 
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 /// Performs the operation: this = this + c1*f1
201 
203 {
204  Error("Add","Function not implemented for TProfile2D");
205  return kFALSE;
206 }
207 
208 
209 ////////////////////////////////////////////////////////////////////////////////
210 /// Performs the operation: this = this + c1*h1
211 
213 {
214  if (!h1) {
215  Error("Add","Attempt to add a non-existing profile");
216  return kFALSE;
217  }
218  if (!h1->InheritsFrom(TProfile2D::Class())) {
219  Error("Add","Attempt to add a non-profile2D object");
220  return kFALSE;
221  }
222 
223  return TProfileHelper::Add(this, this, h1, 1, c1);
224 }
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 /// Replace contents of this profile2D by the addition of h1 and h2*
228 ///
229 /// this = c1*h1 + c2*h2
230 
232 {
233  if (!h1 || !h2) {
234  Error("Add","Attempt to add a non-existing profile");
235  return kFALSE;
236  }
237  if (!h1->InheritsFrom(TProfile2D::Class())) {
238  Error("Add","Attempt to add a non-profile2D object");
239  return kFALSE;
240  }
241  if (!h2->InheritsFrom(TProfile2D::Class())) {
242  Error("Add","Attempt to add a non-profile2D object");
243  return kFALSE;
244  }
245  return TProfileHelper::Add(this, h1, h2, c1, c2);
246 }
247 
248 
249 ////////////////////////////////////////////////////////////////////////////////
250 /// static function
251 /// set the fgApproximate flag. When the flag is true, the function GetBinError
252 /// will approximate the bin error with the average profile error on all bins
253 /// in the following situation only
254 /// - the number of bins in the profile2D is less than 10404 (eg 100x100)
255 /// - the bin number of entries is small ( <5)
256 /// - the estimated bin error is extremely small compared to the bin content
257 /// (see TProfile2D::GetBinError)
258 
260 {
261  fgApproximate = approx;
262 }
263 
264 
265 ////////////////////////////////////////////////////////////////////////////////
266 /// Fill histogram with all entries in the buffer.
267 /// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
268 /// - action = 0 histogram is filled from the buffer
269 /// - action = 1 histogram is filled and buffer is deleted
270 /// The buffer is automatically deleted when the number of entries
271 /// in the buffer is greater than the number of entries in the histogram
272 
274 {
275  // do we need to compute the bin size?
276  if (!fBuffer) return 0;
277  Int_t nbentries = (Int_t)fBuffer[0];
278  if (!nbentries) return 0;
280  if (nbentries < 0) {
281  if (action == 0) return 0;
282  nbentries = -nbentries;
283  fBuffer=0;
284  Reset("ICES"); // reset without deleting the functions
285  fBuffer = buffer;
286  }
288  //find min, max of entries in buffer
289  Double_t xmin = fBuffer[2];
290  Double_t xmax = xmin;
291  Double_t ymin = fBuffer[3];
292  Double_t ymax = ymin;
293  for (Int_t i=1;i<nbentries;i++) {
294  Double_t x = fBuffer[4*i+2];
295  if (x < xmin) xmin = x;
296  if (x > xmax) xmax = x;
297  Double_t y = fBuffer[4*i+3];
298  if (y < ymin) ymin = y;
299  if (y > ymax) ymax = y;
300  }
301  if (fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin()) {
302  THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax,ymin,ymax);
303  } else {
304  fBuffer = 0;
305  Int_t keep = fBufferSize; fBufferSize = 0;
306  if (xmin < fXaxis.GetXmin()) ExtendAxis(xmin,&fXaxis);
307  if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax,&fXaxis);
308  if (ymin < fYaxis.GetXmin()) ExtendAxis(ymin,&fYaxis);
309  if (ymax >= fYaxis.GetXmax()) ExtendAxis(ymax,&fYaxis);
310  fBuffer = buffer;
311  fBufferSize = keep;
312  }
313  }
314 
315  fBuffer = 0;
316  for (Int_t i=0;i<nbentries;i++) {
317  Fill(buffer[4*i+2],buffer[4*i+3],buffer[4*i+4],buffer[4*i+1]);
318  }
319  fBuffer = buffer;
320 
321  if (action > 0) { delete [] fBuffer; fBuffer = 0; fBufferSize = 0;}
322  else {
323  if (nbentries == (Int_t)fEntries) fBuffer[0] = -nbentries;
324  else fBuffer[0] = 0;
325  }
326  return nbentries;
327 }
328 
329 ////////////////////////////////////////////////////////////////////////////////
330 /// accumulate arguments in buffer. When buffer is full, empty the buffer
331 /// fBuffer[0] = number of entries in buffer
332 /// fBuffer[1] = w of first entry
333 /// fBuffer[2] = x of first entry
334 /// fBuffer[3] = y of first entry
335 /// fBuffer[4] = z of first entry
336 
338 {
339  if (!fBuffer) return -3;
340  Int_t nbentries = (Int_t)fBuffer[0];
341  if (nbentries < 0) {
342  nbentries = -nbentries;
343  fBuffer[0] = nbentries;
344  if (fEntries > 0) {
346  Reset("ICES"); // reset without deleting the functions
347  fBuffer = buffer;
348  }
349  }
350  if (4*nbentries+4 >= fBufferSize) {
351  BufferEmpty(1);
352  return Fill(x,y,z,w);
353  }
354  fBuffer[4*nbentries+1] = w;
355  fBuffer[4*nbentries+2] = x;
356  fBuffer[4*nbentries+3] = y;
357  fBuffer[4*nbentries+4] = z;
358  fBuffer[0] += 1;
359  return -2;
360 }
361 
362 ////////////////////////////////////////////////////////////////////////////////
363 /// Copy a Profile2D histogram to a new profile2D histogram*
364 
366 {
367  try {
368  TProfile2D & pobj = dynamic_cast<TProfile2D&>(obj);
369 
370  TH2D::Copy(pobj);
372  fBinSumw2.Copy(pobj.fBinSumw2);
373  for (int bin=0;bin<fNcells;bin++) {
374  pobj.fArray[bin] = fArray[bin];
375  pobj.fSumw2.fArray[bin] = fSumw2.fArray[bin];
376  }
377  pobj.fZmin = fZmin;
378  pobj.fZmax = fZmax;
379  pobj.fScaling = fScaling;
380  pobj.fErrorMode = fErrorMode;
381  pobj.fTsumwz = fTsumwz;
382  pobj.fTsumwz2 = fTsumwz2;
383 
384  } catch(...) {
385  Fatal("Copy","Cannot copy a TProfile2D in a %s",obj.IsA()->GetName());
386  }
387 
388 }
389 
390 
391 ////////////////////////////////////////////////////////////////////////////////
392 /// Performs the operation: this = this/(c1*f1)
393 /// This function is not implemented
394 
396 {
397  Error("Divide","Function not implemented for TProfile2D");
398  return kFALSE;
399 }
400 
401 ////////////////////////////////////////////////////////////////////////////////
402 /// Divide this profile2D by h1
403 ///
404 /// this = this/h1
405 ///
406 /// This function return kFALSE if the divide operation failed
407 
409 {
410 
411  if (!h1) {
412  Error("Divide","Attempt to divide a non-existing profile2D");
413  return kFALSE;
414  }
415  if (!h1->InheritsFrom(TProfile2D::Class())) {
416  Error("Divide","Attempt to divide a non-profile2D object");
417  return kFALSE;
418  }
419  TProfile2D *p1 = (TProfile2D*)h1;
420 
421  // delete buffer if it is there since it will become invalid
422  if (fBuffer) BufferEmpty(1);
423 
424  //*-*- Check profile compatibility
425  Int_t nx = GetNbinsX();
426  if (nx != p1->GetNbinsX()) {
427  Error("Divide","Attempt to divide profiles with different number of bins");
428  return kFALSE;
429  }
430  Int_t ny = GetNbinsY();
431  if (ny != p1->GetNbinsY()) {
432  Error("Divide","Attempt to divide profiles with different number of bins");
433  return kFALSE;
434  }
435 
436  //*-*- Reset statistics
437  fEntries = fTsumw = fTsumw2 = fTsumwx = fTsumwx2 = 0;
438 
439  //*-*- Loop on bins (including underflows/overflows)
440  Int_t bin,binx,biny;
441  Double_t *cu1 = p1->GetW();
442  Double_t *er1 = p1->GetW2();
443  Double_t *en1 = p1->GetB();
444  Double_t c0,c1,w,z,x,y;
445  for (binx =0;binx<=nx+1;binx++) {
446  for (biny =0;biny<=ny+1;biny++) {
447  bin = biny*(fXaxis.GetNbins()+2) + binx;
448  c0 = fArray[bin];
449  c1 = cu1[bin];
450  if (c1) w = c0/c1;
451  else w = 0;
452  fArray[bin] = w;
453  z = TMath::Abs(w);
454  x = fXaxis.GetBinCenter(binx);
455  y = fYaxis.GetBinCenter(biny);
456  fEntries++;
457  fTsumw += z;
458  fTsumw2 += z*z;
459  fTsumwx += z*x;
460  fTsumwx2 += z*x*x;
461  fTsumwy += z*y;
462  fTsumwy2 += z*y*y;
463  fTsumwxy += z*x*y;
464  fTsumwz += z;
465  fTsumwz2 += z*z;
466  Double_t e0 = fSumw2.fArray[bin];
467  Double_t e1 = er1[bin];
468  Double_t c12= c1*c1;
469  if (!c1) fSumw2.fArray[bin] = 0;
470  else fSumw2.fArray[bin] = (e0*c1*c1 + e1*c0*c0)/(c12*c12);
471  if (!en1[bin]) fBinEntries.fArray[bin] = 0;
472  else fBinEntries.fArray[bin] /= en1[bin];
473  }
474  }
475  // mantaining the correct sum of weights square is not supported when dividing
476  // bin error resulting from division of profile needs to be checked
477  if (fBinSumw2.fN) {
478  Warning("Divide","Cannot preserve during the division of profiles the sum of bin weight square");
479  fBinSumw2 = TArrayD();
480  }
481  return kTRUE;
482 }
483 
484 
485 ////////////////////////////////////////////////////////////////////////////////
486 /// Replace contents of this profile2D by the division of h1 by h2
487 ///
488 /// this = c1*h1/(c2*h2)
489 ///
490 /// This function return kFALSE if the divide operation failed
491 
493 {
494  TString opt = option;
495  opt.ToLower();
496  Bool_t binomial = kFALSE;
497  if (opt.Contains("b")) binomial = kTRUE;
498  if (!h1 || !h2) {
499  Error("Divide","Attempt to divide a non-existing profile2D");
500  return kFALSE;
501  }
502  if (!h1->InheritsFrom(TProfile2D::Class())) {
503  Error("Divide","Attempt to divide a non-profile2D object");
504  return kFALSE;
505  }
506  TProfile2D *p1 = (TProfile2D*)h1;
507  if (!h2->InheritsFrom(TProfile2D::Class())) {
508  Error("Divide","Attempt to divide a non-profile2D object");
509  return kFALSE;
510  }
511  TProfile2D *p2 = (TProfile2D*)h2;
512 
513  // delete buffer if it is there since it will become invalid
514  if (fBuffer) BufferEmpty(1);
515 
516  //*-*- Check histogram compatibility
517  Int_t nx = GetNbinsX();
518  if (nx != p1->GetNbinsX() || nx != p2->GetNbinsX()) {
519  Error("Divide","Attempt to divide profiles with different number of bins");
520  return kFALSE;
521  }
522  Int_t ny = GetNbinsY();
523  if (ny != p1->GetNbinsY() || ny != p2->GetNbinsY()) {
524  Error("Divide","Attempt to divide profiles with different number of bins");
525  return kFALSE;
526  }
527  if (!c2) {
528  Error("Divide","Coefficient of dividing profile cannot be zero");
529  return kFALSE;
530  }
531 
532  //*-*- Reset statistics
533  fEntries = fTsumw = fTsumw2 = fTsumwx = fTsumwx2 = 0;
534 
535  //*-*- Loop on bins (including underflows/overflows)
536  Int_t bin,binx,biny;
537  Double_t *cu1 = p1->GetW();
538  Double_t *cu2 = p2->GetW();
539  Double_t *er1 = p1->GetW2();
540  Double_t *er2 = p2->GetW2();
541  Double_t *en1 = p1->GetB();
542  Double_t *en2 = p2->GetB();
543  Double_t b1,b2,w,z,x,y,ac1,ac2;
544  ac1 = TMath::Abs(c1);
545  ac2 = TMath::Abs(c2);
546  for (binx =0;binx<=nx+1;binx++) {
547  for (biny =0;biny<=ny+1;biny++) {
548  bin = biny*(fXaxis.GetNbins()+2) + binx;
549  b1 = cu1[bin];
550  b2 = cu2[bin];
551  if (b2) w = c1*b1/(c2*b2);
552  else w = 0;
553  fArray[bin] = w;
554  z = TMath::Abs(w);
555  x = fXaxis.GetBinCenter(binx);
556  y = fYaxis.GetBinCenter(biny);
557  fEntries++;
558  fTsumw += z;
559  fTsumw2 += z*z;
560  fTsumwx += z*x;
561  fTsumwx2 += z*x*x;
562  fTsumwy += z*y;
563  fTsumwy2 += z*y*y;
564  fTsumwxy += z*x*y;
565  fTsumwz += z;
566  fTsumwz2 += z*z;
567  Double_t e1 = er1[bin];
568  Double_t e2 = er2[bin];
569  //Double_t b22= b2*b2*d2;
570  Double_t b22= b2*b2*TMath::Abs(c2);
571  if (!b2) fSumw2.fArray[bin] = 0;
572  else {
573  if (binomial) {
574  fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));
575  } else {
576  fSumw2.fArray[bin] = ac1*ac2*(e1*b2*b2 + e2*b1*b1)/(b22*b22);
577  }
578  }
579  if (!en2[bin]) fBinEntries.fArray[bin] = 0;
580  else fBinEntries.fArray[bin] = en1[bin]/en2[bin];
581  }
582  }
583  return kTRUE;
584 }
585 
586 ////////////////////////////////////////////////////////////////////////////////
587 /// Fill a Profile2D histogram (no weights)
588 ///*-* =======================================
589 
591 {
592  if (fBuffer) return BufferFill(x,y,z,1);
593 
594  Int_t bin,binx,biny;
595 
596  if (fZmin != fZmax) {
597  if (z <fZmin || z> fZmax || TMath::IsNaN(z) ) return -1;
598  }
599 
600  fEntries++;
601  binx =fXaxis.FindBin(x);
602  biny =fYaxis.FindBin(y);
603  if (binx <0 || biny <0) return -1;
604  bin = GetBin(binx, biny);
605  fArray[bin] += z;
606  fSumw2.fArray[bin] += z*z;
607  fBinEntries.fArray[bin] += 1;
608  if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
609  if (binx == 0 || binx > fXaxis.GetNbins()) {
610  if (!fgStatOverflows) return -1;
611  }
612  if (biny == 0 || biny > fYaxis.GetNbins()) {
613  if (!fgStatOverflows) return -1;
614  }
615  ++fTsumw;
616  ++fTsumw2;
617  fTsumwx += x;
618  fTsumwx2 += x*x;
619  fTsumwy += y;
620  fTsumwy2 += y*y;
621  fTsumwxy += x*y;
622  fTsumwz += z;
623  fTsumwz2 += z*z;
624  return bin;
625 }
626 
627 ////////////////////////////////////////////////////////////////////////////////
628 /// Fill a Profile2D histogram (no weights)
629 ///
630 
632 {
633  Int_t bin,binx,biny;
634 
635  if (fZmin != fZmax) {
636  if (z <fZmin || z> fZmax || TMath::IsNaN(z)) return -1;
637  }
638 
639  fEntries++;
640  binx =fXaxis.FindBin(x);
641  biny =fYaxis.FindBin(namey);
642  if (binx <0 || biny <0) return -1;
643  bin = biny*(fXaxis.GetNbins()+2) + binx;
644  AddBinContent(bin, z);
645  fSumw2.fArray[bin] += (Double_t)z*z;
646  fBinEntries.fArray[bin] += 1;
647  if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
648  if (binx == 0 || binx > fXaxis.GetNbins()) {
649  if (!fgStatOverflows) return -1;
650  }
651  if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
652  Double_t y = fYaxis.GetBinCenter(biny);
653  ++fTsumw;
654  ++fTsumw2;
655  fTsumwx += x;
656  fTsumwx2 += x*x;
657  fTsumwy += y;
658  fTsumwy2 += y*y;
659  fTsumwxy += x*y;
660  fTsumwz += z;
661  fTsumwz2 += z*z;
662  return bin;
663 }
664 
665 ////////////////////////////////////////////////////////////////////////////////
666 /// Fill a Profile2D histogram (no weights)
667 ///
668 
669 Int_t TProfile2D::Fill(const char *namex, const char *namey, Double_t z)
670 {
671  Int_t bin,binx,biny;
672 
673  if (fZmin != fZmax) {
674  if (z <fZmin || z> fZmax || TMath::IsNaN(z) ) return -1;
675  }
676 
677  fEntries++;
678  binx =fXaxis.FindBin(namex);
679  biny =fYaxis.FindBin(namey);
680  if (binx <0 || biny <0) return -1;
681  bin = biny*(fXaxis.GetNbins()+2) + binx;
682  AddBinContent(bin, z);
683  fSumw2.fArray[bin] += (Double_t)z*z;
684  fBinEntries.fArray[bin] += 1;
685  if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
686  if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
687  if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
688  Double_t x = fYaxis.GetBinCenter(binx);
689  Double_t y = fYaxis.GetBinCenter(biny);
690  ++fTsumw;
691  ++fTsumw2;
692  fTsumwx += x;
693  fTsumwx2 += x*x;
694  fTsumwy += y;
695  fTsumwy2 += y*y;
696  fTsumwxy += x*y;
697  fTsumwz += z;
698  fTsumwz2 += z*z;
699  return bin;
700 }
701 
702 ////////////////////////////////////////////////////////////////////////////////
703 /// Fill a Profile2D histogram (no weights)
704 ///
705 
707 {
708  Int_t bin,binx,biny;
709 
710  if (fZmin != fZmax) {
711  if (z <fZmin || z> fZmax || TMath::IsNaN(z)) return -1;
712  }
713 
714  fEntries++;
715  binx =fXaxis.FindBin(namex);
716  biny =fYaxis.FindBin(y);
717  if (binx <0 || biny <0) return -1;
718  bin = biny*(fXaxis.GetNbins()+2) + binx;
719  AddBinContent(bin, z);
720  fSumw2.fArray[bin] += (Double_t)z*z;
721  fBinEntries.fArray[bin] += 1;
722  if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
723  if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
724  if (biny == 0 || biny > fYaxis.GetNbins()) {
725  if (!fgStatOverflows) return -1;
726  }
727  Double_t x = fYaxis.GetBinCenter(binx);
728  ++fTsumw;
729  ++fTsumw2;
730  fTsumwx += x;
731  fTsumwx2 += x*x;
732  fTsumwy += y;
733  fTsumwy2 += y*y;
734  fTsumwxy += x*y;
735  fTsumwz += z;
736  fTsumwz2 += z*z;
737  return bin;
738 }
739 
740 ////////////////////////////////////////////////////////////////////////////////
741 /// Fill a Profile2D histogram with weights
742 
744 {
745  if (fBuffer) return BufferFill(x,y,z,w);
746 
747  Int_t bin,binx,biny;
748 
749  if (fZmin != fZmax) {
750  if (z <fZmin || z> fZmax || TMath::IsNaN(z)) return -1;
751  }
752 
753  Double_t u= w;
754  fEntries++;
755  binx =fXaxis.FindBin(x);
756  biny =fYaxis.FindBin(y);
757  if (binx <0 || biny <0) return -1;
758  bin = biny*(fXaxis.GetNbins()+2) + binx;
759  AddBinContent(bin, u*z);
760  fSumw2.fArray[bin] += u*z*z;
761  if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2(); // must be called before accumulating the entries
762  if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u*u;
763  fBinEntries.fArray[bin] += u;
764  if (binx == 0 || binx > fXaxis.GetNbins()) {
765  if (!fgStatOverflows) return -1;
766  }
767  if (biny == 0 || biny > fYaxis.GetNbins()) {
768  if (!fgStatOverflows) return -1;
769  }
770  fTsumw += u;
771  fTsumw2 += u*u;
772  fTsumwx += u*x;
773  fTsumwx2 += u*x*x;
774  fTsumwy += u*y;
775  fTsumwy2 += u*y*y;
776  fTsumwxy += u*x*y;
777  fTsumwz += u*z;
778  fTsumwz2 += u*z*z;
779  return bin;
780 }
781 
782 ////////////////////////////////////////////////////////////////////////////////
783 /// Return bin content of a Profile2D histogram
784 
786 {
787  if (fBuffer) ((TProfile2D*)this)->BufferEmpty();
788 
789  if (bin < 0 || bin >= fNcells) return 0;
790  if (fBinEntries.fArray[bin] == 0) return 0;
791  if (!fArray) return 0;
792  return fArray[bin]/fBinEntries.fArray[bin];
793 }
794 
795 ////////////////////////////////////////////////////////////////////////////////
796 /// Return bin entries of a Profile2D histogram
797 
799 {
800  if (fBuffer) ((TProfile2D*)this)->BufferEmpty();
801 
802  if (bin < 0 || bin >= fNcells) return 0;
803  return fBinEntries.fArray[bin];
804 }
805 
806 ////////////////////////////////////////////////////////////////////////////////
807 /// Return bin effective entries for a weighted filled Profile histogram.
808 /// In case of an unweighted profile, it is equivalent to the number of entries per bin
809 /// The effective entries is defined as the square of the sum of the weights divided by the
810 /// sum of the weights square.
811 /// TProfile::Sumw2() must be called before filling the profile with weights.
812 /// Only by calling this method the sum of the square of the weights per bin is stored.
813 ///
814 ///*-* =========================================
815 
817 {
818  return TProfileHelper::GetBinEffectiveEntries(this, bin);
819 }
820 
821 ////////////////////////////////////////////////////////////////////////////////
822 /// -*Return bin error of a Profile2D histogram
823 ///
824 /// Computing errors: A moving field
825 /// =================================
826 /// The computation of errors for a TProfile2D has evolved with the versions
827 /// of ROOT. The difficulty is in computing errors for bins with low statistics.
828 /// - prior to version 3.10, we had no special treatment of low statistic bins.
829 /// As a result, these bins had huge errors. The reason is that the
830 /// expression eprim2 is very close to 0 (rounding problems) or 0.
831 /// - The algorithm is modified/protected for the case
832 /// when a TProfile2D is projected (ProjectionX). The previous algorithm
833 /// generated a N^2 problem when projecting a TProfile2D with a large number of
834 /// bins (eg 100000).
835 /// - in version 3.10/02, a new static function TProfile::Approximate
836 /// is introduced to enable or disable (default) the approximation.
837 /// (see also comments in TProfile::GetBinError)
838 
840 {
841  return TProfileHelper::GetBinError((TProfile2D*)this, bin);
842 }
843 
844 ////////////////////////////////////////////////////////////////////////////////
845 /// -*Return option to compute profile2D errors
846 ///*-* =========================================
847 
849 {
850  if (fErrorMode == kERRORSPREAD) return "s";
851  if (fErrorMode == kERRORSPREADI) return "i";
852  if (fErrorMode == kERRORSPREADG) return "g";
853  return "";
854 }
855 
856 ////////////////////////////////////////////////////////////////////////////////
857 /// fill the array stats from the contents of this profile
858 /// The array stats must be correctly dimensionned in the calling program.
859 /// stats[0] = sumw
860 /// stats[1] = sumw2
861 /// stats[2] = sumwx
862 /// stats[3] = sumwx2
863 /// stats[4] = sumwy
864 /// stats[5] = sumwy2
865 /// stats[6] = sumwxy
866 /// stats[7] = sumwz
867 /// stats[8] = sumwz2
868 ///
869 /// If no axis-subrange is specified (via TAxis::SetRange), the array stats
870 /// is simply a copy of the statistics quantities computed at filling time.
871 /// If a sub-range is specified, the function recomputes these quantities
872 /// from the bin contents in the current axis range.
873 
874 void TProfile2D::GetStats(Double_t *stats) const
875 {
876  if (fBuffer) ((TProfile2D*)this)->BufferEmpty();
877 
878  // Loop on bins
880  Int_t bin, binx, biny;
881  Double_t w, w2;
882  Double_t x,y;
883  for (bin=0;bin<9;bin++) stats[bin] = 0;
884  if (!fBinEntries.fArray) return;
885  Int_t firstBinX = fXaxis.GetFirst();
886  Int_t lastBinX = fXaxis.GetLast();
887  Int_t firstBinY = fYaxis.GetFirst();
888  Int_t lastBinY = fYaxis.GetLast();
889  // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
890  if (fgStatOverflows) {
891  if ( !fXaxis.TestBit(TAxis::kAxisRange) ) {
892  if (firstBinX == 1) firstBinX = 0;
893  if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
894  }
895  if ( !fYaxis.TestBit(TAxis::kAxisRange) ) {
896  if (firstBinY == 1) firstBinY = 0;
897  if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
898  }
899  }
900  for (biny = firstBinY; biny <= lastBinY; biny++) {
901  y = fYaxis.GetBinCenter(biny);
902  for (binx = firstBinX; binx <= lastBinX; binx++) {
903  bin = GetBin(binx,biny);
904  w = fBinEntries.fArray[bin];
905  w2 = (fBinSumw2.fN ? fBinSumw2.fArray[bin] : w );
906  x = fXaxis.GetBinCenter(binx);
907  stats[0] += w;
908  stats[1] += w2;
909  stats[2] += w*x;
910  stats[3] += w*x*x;
911  stats[4] += w*y;
912  stats[5] += w*y*y;
913  stats[6] += w*x*y;
914  stats[7] += fArray[bin];
915  stats[8] += fSumw2.fArray[bin];
916  }
917  }
918  } else {
919  stats[0] = fTsumw;
920  stats[1] = fTsumw2;
921  stats[2] = fTsumwx;
922  stats[3] = fTsumwx2;
923  stats[4] = fTsumwy;
924  stats[5] = fTsumwy2;
925  stats[6] = fTsumwxy;
926  stats[7] = fTsumwz;
927  stats[8] = fTsumwz2;
928  }
929 }
930 
931 ////////////////////////////////////////////////////////////////////////////////
932 /// Reduce the number of bins for this axis to the number of bins having a label.
933 
935 {
937 }
938 
939 ////////////////////////////////////////////////////////////////////////////////
940 /// Double the number of bins for axis.
941 /// Refill histogram
942 /// This function is called by TAxis::FindBin(const char *label)
943 
945 {
947 }
948 
949 ////////////////////////////////////////////////////////////////////////////////
950 /// Set option(s) to draw axis with labels
951 /// option = "a" sort by alphabetic order
952 /// = ">" sort by decreasing values
953 /// = "<" sort by increasing values
954 /// = "h" draw labels horizonthal
955 /// = "v" draw labels vertical
956 /// = "u" draw labels up (end of label right adjusted)
957 /// = "d" draw labels down (start of label left adjusted)
958 
960 {
961 
962  TAxis *axis = GetXaxis();
963  if (ax[0] == 'y' || ax[0] == 'Y') axis = GetYaxis();
964  THashList *labels = axis->GetLabels();
965  if (!labels) {
966  Warning("LabelsOption","Cannot sort. No labels");
967  return;
968  }
969  TString opt = option;
970  opt.ToLower();
971  if (opt.Contains("h")) {
972  axis->SetBit(TAxis::kLabelsHori);
975  axis->ResetBit(TAxis::kLabelsUp);
976  }
977  if (opt.Contains("v")) {
978  axis->SetBit(TAxis::kLabelsVert);
981  axis->ResetBit(TAxis::kLabelsUp);
982  }
983  if (opt.Contains("u")) {
984  axis->SetBit(TAxis::kLabelsUp);
988  }
989  if (opt.Contains("d")) {
990  axis->SetBit(TAxis::kLabelsDown);
993  axis->ResetBit(TAxis::kLabelsUp);
994  }
995  Int_t sort = -1;
996  if (opt.Contains("a")) sort = 0;
997  if (opt.Contains(">")) sort = 1;
998  if (opt.Contains("<")) sort = 2;
999  if (sort < 0) return;
1000 
1001  Int_t nx = fXaxis.GetNbins()+2;
1002  Int_t ny = fYaxis.GetNbins()+2;
1003  Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
1004  Int_t *a = new Int_t[n+2];
1005  Int_t i,j,k,bin;
1006  Double_t *sumw = new Double_t[nx*ny];
1007  Double_t *errors = new Double_t[nx*ny];
1008  Double_t *ent = new Double_t[nx*ny];
1009  THashList *labold = new THashList(labels->GetSize(),1);
1010  TIter nextold(labels);
1011  TObject *obj;
1012  while ((obj=nextold())) {
1013  labold->Add(obj);
1014  }
1015  labels->Clear();
1016  if (sort > 0) {
1017  //---sort by values of bins
1018  Double_t *pcont = new Double_t[n+2];
1019  for (i=0;i<=n;i++) pcont[i] = 0;
1020  for (i=1;i<nx;i++) {
1021  for (j=1;j<ny;j++) {
1022  bin = i+nx*j;
1023  sumw[bin] = fArray[bin];
1024  errors[bin] = fSumw2.fArray[bin];
1025  ent[bin] = fBinEntries.fArray[bin];
1026  if (axis == GetXaxis()) k = i;
1027  else k = j;
1028  if (fBinEntries.fArray[bin] != 0) pcont[k-1] += fArray[bin]/fBinEntries.fArray[bin];
1029  }
1030  }
1031  if (sort ==1) TMath::Sort(n,pcont,a,kTRUE); //sort by decreasing values
1032  else TMath::Sort(n,pcont,a,kFALSE); //sort by increasing values
1033  delete [] pcont;
1034  for (i=0;i<n;i++) {
1035  obj = labold->At(a[i]);
1036  labels->Add(obj);
1037  obj->SetUniqueID(i+1);
1038  }
1039  for (i=1;i<nx;i++) {
1040  for (j=1;j<ny;j++) {
1041  bin = i+nx*j;
1042  if (axis == GetXaxis()) {
1043  fArray[bin] = sumw[a[i-1]+1+nx*j];
1044  fSumw2.fArray[bin] = errors[a[i-1]+1+nx*j];
1045  fBinEntries.fArray[bin] = ent[a[i-1]+1+nx*j];
1046  } else {
1047  fArray[bin] = sumw[i+nx*(a[j-1]+1)];
1048  fSumw2.fArray[bin] = errors[i+nx*(a[j-1]+1)];
1049  fBinEntries.fArray[bin] = ent[i+nx*(a[j-1]+1)];
1050  }
1051  }
1052  }
1053  } else {
1054  //---alphabetic sort
1055  const UInt_t kUsed = 1<<18;
1056  TObject *objk=0;
1057  a[0] = 0;
1058  a[n+1] = n+1;
1059  for (i=1;i<=n;i++) {
1060  const char *label = "zzzzzzzzzzzz";
1061  for (j=1;j<=n;j++) {
1062  obj = labold->At(j-1);
1063  if (!obj) continue;
1064  if (obj->TestBit(kUsed)) continue;
1065  //use strcasecmp for case non-sensitive sort (may be an option)
1066  if (strcmp(label,obj->GetName()) < 0) continue;
1067  objk = obj;
1068  a[i] = j;
1069  label = obj->GetName();
1070  }
1071  if (objk) {
1072  objk->SetUniqueID(i);
1073  labels->Add(objk);
1074  objk->SetBit(kUsed);
1075  }
1076  }
1077  for (i=1;i<=n;i++) {
1078  obj = labels->At(i-1);
1079  if (!obj) continue;
1080  obj->ResetBit(kUsed);
1081  }
1082  for (i=0;i<nx;i++) {
1083  for (j=0;j<ny;j++) {
1084  bin = i+nx*j;
1085  sumw[bin] = fArray[bin];
1086  errors[bin] = fSumw2.fArray[bin];
1087  ent[bin] = fBinEntries.fArray[bin];
1088  }
1089  }
1090  for (i=0;i<nx;i++) {
1091  for (j=0;j<ny;j++) {
1092  bin = i+nx*j;
1093  if (axis == GetXaxis()) {
1094  fArray[bin] = sumw[a[i]+nx*j];
1095  fSumw2.fArray[bin] = errors[a[i]+nx*j];
1096  fBinEntries.fArray[bin] = ent[a[i]+nx*j];
1097  } else {
1098  fArray[bin] = sumw[i+nx*a[j]];
1099  fSumw2.fArray[bin] = errors[i+nx*a[j]];
1100  fBinEntries.fArray[bin] = ent[i+nx*a[j]];
1101  }
1102  }
1103  }
1104  }
1105  delete labold;
1106  if (a) delete [] a;
1107  if (sumw) delete [] sumw;
1108  if (errors) delete [] errors;
1109  if (ent) delete [] ent;
1110 }
1111 
1112 ////////////////////////////////////////////////////////////////////////////////
1113 ///Merge all histograms in the collection in this histogram.
1114 ///This function computes the min/max for the axes,
1115 ///compute a new number of bins, if necessary,
1116 ///add bin contents, errors and statistics.
1117 ///If overflows are present and limits are different the function will fail.
1118 ///The function returns the total number of entries in the result histogram
1119 ///if the merge is successfull, -1 otherwise.
1120 ///
1121 ///IMPORTANT remark. The 2 axis x and y may have different number
1122 ///of bins and different limits, BUT the largest bin width must be
1123 ///a multiple of the smallest bin width and the upper limit must also
1124 ///be a multiple of the bin width.
1125 
1127 {
1128  return TProfileHelper::Merge(this, li);
1129 }
1130 
1131 ////////////////////////////////////////////////////////////////////////////////
1132 /// Performs the operation: this = this*c1*f1
1133 
1135 {
1136  Error("Multiply","Function not implemented for TProfile2D");
1137  return kFALSE;
1138 }
1139 
1140 ////////////////////////////////////////////////////////////////////////////////
1141 /// Multiply this profile2D by h1 -
1142 ///*-* =============================
1143 ///
1144 /// this = this*h1
1145 ///
1146 
1148 {
1149  Error("Multiply","Multiplication of profile2D histograms not implemented");
1150  return kFALSE;
1151 }
1152 
1153 
1154 ////////////////////////////////////////////////////////////////////////////////
1155 ///*-*Replace contents of this profile2D by multiplication of h1 by h2*-*
1156 ///*-* ================================================================
1157 ///
1158 /// this = (c1*h1)*(c2*h2)
1159 ///
1160 
1162 {
1163  Error("Multiply","Multiplication of profile2D histograms not implemented");
1164  return kFALSE;
1165 }
1166 
1167 ////////////////////////////////////////////////////////////////////////////////
1168 ///*-*Project this profile2D into a 2-D histogram along X,Y -*
1169 ///*-* =====================================================
1170 ///
1171 /// The projection is always of the type TH2D.
1172 ///
1173 /// if option "E" is specified the errors of the projected histogram are computed and set
1174 /// to be equal to the errors of the profile.
1175 /// Option "E" is defined as the default one in the header file.
1176 /// if option "" is specified the histogram errors are simply the sqrt of its content
1177 /// if option "B" is specified, the content of bin of the returned histogram
1178 /// will be equal to the GetBinEntries(bin) of the profile,
1179 /// if option "C=E" the bin contents of the projection are set to the
1180 /// bin errors of the profile
1181 /// if option "W" is specified the bin content of the projected histogram is set to the
1182 /// product of the bin content of the profile and the entries.
1183 /// With this option the returned histogram will be equivalent to the one obtained by
1184 /// filling directly a TH2D using the 3-rd value as a weight.
1185 /// This option makes sense only for profile filled with all weights =1.
1186 /// When the profile is weighted (filled with weights different than 1) the
1187 /// bin error of the projected histogram (obtained using this option "W") cannot be
1188 /// correctly computed from the information stored in the profile. In that case the
1189 /// obtained histogram contains as bin error square the weighted sum of the square of the
1190 /// profiled observable (TProfile2D::fSumw2[bin] )
1191 
1192 TH2D *TProfile2D::ProjectionXY(const char *name, Option_t *option) const
1193 {
1194 
1195  TString opt = option;
1196  opt.ToLower();
1197 
1198  // Create the projection histogram
1199  // name of projected histogram is by default name of orginal histogram + _pxy
1200  TString pname(name);
1201  if (pname.IsNull() || pname == "_pxy")
1202  pname = TString(GetName() ) + TString("_pxy");
1203 
1204 
1205  Int_t nx = fXaxis.GetNbins();
1206  Int_t ny = fYaxis.GetNbins();
1207  const TArrayD *xbins = fXaxis.GetXbins();
1208  const TArrayD *ybins = fYaxis.GetXbins();
1209  TH2D * h1 = 0;
1210  if (xbins->fN == 0 && ybins->fN == 0) {
1211  h1 = new TH2D(pname,GetTitle(),nx,fXaxis.GetXmin(),fXaxis.GetXmax(),ny,fYaxis.GetXmin(),fYaxis.GetXmax());
1212  } else if (xbins->fN == 0) {
1213  h1 = new TH2D(pname,GetTitle(),nx,fXaxis.GetXmin(),fXaxis.GetXmax(),ny, ybins->GetArray() );
1214  } else if (ybins->fN == 0) {
1215  h1 = new TH2D(pname,GetTitle(),nx,xbins->GetArray(),ny,fYaxis.GetXmin(),fYaxis.GetXmax());
1216  } else {
1217  h1 = new TH2D(pname,GetTitle(),nx,xbins->GetArray(),ny,ybins->GetArray() );
1218  }
1219  Bool_t computeErrors = kFALSE;
1220  Bool_t cequalErrors = kFALSE;
1221  Bool_t binEntries = kFALSE;
1222  Bool_t binWeight = kFALSE;
1223  if (opt.Contains("b")) binEntries = kTRUE;
1224  if (opt.Contains("e")) computeErrors = kTRUE;
1225  if (opt.Contains("w")) binWeight = kTRUE;
1226  if (opt.Contains("c=e")) {cequalErrors = kTRUE; computeErrors=kFALSE;}
1227  if (computeErrors || binWeight || (binEntries && fBinSumw2.fN) ) h1->Sumw2();
1228 
1229  // Fill the projected histogram
1230  Int_t bin,binx, biny;
1231  Double_t cont;
1232  for (binx =0;binx<=nx+1;binx++) {
1233  for (biny =0;biny<=ny+1;biny++) {
1234  bin = GetBin(binx,biny);
1235 
1236  if (binEntries) cont = GetBinEntries(bin);
1237  else if (cequalErrors) cont = GetBinError(bin);
1238  else if (binWeight) cont = GetBinContent(bin) * GetBinEntries(bin);
1239  else cont = GetBinContent(bin); // default case
1240 
1241  h1->SetBinContent(bin ,cont);
1242 
1243  // if option E projected histogram errors are same as profile
1244  if (computeErrors ) h1->SetBinError(bin , GetBinError(bin) );
1245  // in case of option W bin error is deduced from bin sum of z**2 values of profile
1246  // this is correct only if the profile is unweighted
1247  if (binWeight) h1->GetSumw2()->fArray[bin] = fSumw2.fArray[bin];
1248  // in case of bin entries and profile is weighted, we need to set also the bin error
1249  if (binEntries && fBinSumw2.fN ) {
1250  R__ASSERT( h1->GetSumw2() );
1251  h1->GetSumw2()->fArray[bin] = fBinSumw2.fArray[bin];
1252  }
1253  }
1254  }
1255  h1->SetEntries(fEntries);
1256  return h1;
1257 }
1258 
1259 ////////////////////////////////////////////////////////////////////////////////
1260 /// *-*Project a 2-D histogram into a profile histogram along X
1261 /// *-* ========================================================
1262 ///
1263 /// The projection is made from the channels along the Y axis
1264 /// ranging from firstybin to lastybin included.
1265 /// The result is a 1D profile which contains the combination of all the considered bins along Y
1266 /// By default, bins 1 to ny are included
1267 /// When all bins are included, the number of entries in the projection
1268 /// is set to the number of entries of the 2-D histogram, otherwise
1269 /// the number of entries is incremented by 1 for all non empty cells.
1270 ///
1271 /// The option can also be used to specify the projected profile error type.
1272 /// Values which can be used are 's', 'i', or 'g'. See TProfile::BuildOptions for details
1273 ///
1274 ///
1275 
1276 TProfile *TProfile2D::ProfileX(const char *name, Int_t firstybin, Int_t lastybin, Option_t *option) const
1277 {
1278  return DoProfile(true, name, firstybin, lastybin, option);
1279 }
1280 
1281 ////////////////////////////////////////////////////////////////////////////////
1282 /// *-*Project a 2-D histogram into a profile histogram along X
1283 /// *-* ========================================================
1284 ///
1285 /// The projection is made from the channels along the X axis
1286 /// ranging from firstybin to lastybin included.
1287 /// The result is a 1D profile which contains the combination of all the considered bins along X
1288 /// By default, bins 1 to ny are included
1289 /// When all bins are included, the number of entries in the projection
1290 /// is set to the number of entries of the 2-D histogram, otherwise
1291 /// the number of entries is incremented by 1 for all non empty cells.
1292 ///
1293 /// The option can also be used to specify the projected profile error type.
1294 /// Values which can be used are 's', 'i', or 'g'. See TProfile::BuildOptions for details
1295 ///
1296 ///
1297 ///
1298 
1299 TProfile *TProfile2D::ProfileY(const char *name, Int_t firstxbin, Int_t lastxbin, Option_t *option) const
1300 {
1301  return DoProfile(false, name, firstxbin, lastxbin, option);
1302 }
1303 
1304 ////////////////////////////////////////////////////////////////////////////////
1305 /// implementation of ProfileX or ProfileY for a TProfile2D
1306 /// Do correctly the combination of the bin averages when doing the projection
1307 
1308 TProfile * TProfile2D::DoProfile(bool onX, const char *name, Int_t firstbin, Int_t lastbin, Option_t *option) const {
1309  TString opt = option;
1310  opt.ToLower();
1311  bool originalRange = opt.Contains("o");
1312 
1313  TString expectedName = ( onX ? "_pfx" : "_pfy" );
1314 
1315  TString pname(name);
1316  if (pname.IsNull() || name == expectedName)
1317  pname = TString(GetName() ) + expectedName;
1318 
1319  const TAxis& outAxis = ( onX ? fXaxis : fYaxis );
1320  const TArrayD *bins = outAxis.GetXbins();
1321  Int_t firstOutBin = outAxis.GetFirst();
1322  Int_t lastOutBin = outAxis.GetLast();
1323 
1324  TProfile * p1 = 0;
1325  // case of fixed bins
1326  if (bins->fN == 0) {
1327  if (originalRange)
1328  p1 = new TProfile(pname,GetTitle(), outAxis.GetNbins(), outAxis.GetXmin(), outAxis.GetXmax(), opt );
1329  else
1330  p1 = new TProfile(pname,GetTitle(), lastOutBin-firstOutBin+1,
1331  outAxis.GetBinLowEdge(firstOutBin),outAxis.GetBinUpEdge(lastOutBin), opt);
1332  } else {
1333  // case of variable bins
1334  if (originalRange )
1335  p1 = new TProfile(pname,GetTitle(),outAxis.GetNbins(),bins->fArray,opt);
1336  else
1337  p1 = new TProfile(pname,GetTitle(),lastOutBin-firstOutBin+1,&bins->fArray[firstOutBin-1],opt);
1338 
1339  }
1340 
1341  if (fBinSumw2.fN) p1->Sumw2();
1342 
1343  // make projection in a 2D first
1344  TH2D * h2dW = ProjectionXY("h2temp-W","W");
1345  TH2D * h2dN = ProjectionXY("h2temp-N","B");
1346 
1347  h2dW->SetDirectory(0); h2dN->SetDirectory(0);
1348 
1349 
1350  TString opt1 = (originalRange) ? "o" : "";
1351  TH1D * h1W = (onX) ? h2dW->ProjectionX("h1temp-W",firstbin,lastbin,opt1) : h2dW->ProjectionY("h1temp-W",firstbin,lastbin,opt1);
1352  TH1D * h1N = (onX) ? h2dN->ProjectionX("h1temp-N",firstbin,lastbin,opt1) : h2dN->ProjectionY("h1temp-N",firstbin,lastbin,opt1);
1353  h1W->SetDirectory(0); h1N->SetDirectory(0);
1354 
1355 
1356  // fill the bin content
1357  R__ASSERT( h1W->fN == p1->fN );
1358  R__ASSERT( h1N->fN == p1->fN );
1359  R__ASSERT( h1W->GetSumw2()->fN != 0); // h1W should always be a weighted histogram since h2dW is
1360  for (int i = 0; i < p1->fN ; ++i) {
1361  p1->fArray[i] = h1W->GetBinContent(i); // array of profile is sum of all values
1362  p1->GetSumw2()->fArray[i] = h1W->GetSumw2()->fArray[i]; // array of content square of profile is weight square of the W projected histogram
1363  p1->SetBinEntries(i, h1N->GetBinContent(i) );
1364  if (fBinSumw2.fN) p1->GetBinSumw2()->fArray[i] = h1N->GetSumw2()->fArray[i]; // sum of weight squares are stored to compute errors in h1N histogram
1365  }
1366  // delete the created histograms
1367  delete h2dW;
1368  delete h2dN;
1369  delete h1W;
1370  delete h1N;
1371 
1372  // Also we need to set the entries since they have not been correctly calculated during the projection
1373  // we can only set them to the effective entries
1374  p1->SetEntries( p1->GetEffectiveEntries() );
1375 
1376  return p1;
1377 }
1378 
1379 
1380 ////////////////////////////////////////////////////////////////////////////////
1381 /// Replace current statistics with the values in array stats
1382 
1384 {
1385  fTsumw = stats[0];
1386  fTsumw2 = stats[1];
1387  fTsumwx = stats[2];
1388  fTsumwx2 = stats[3];
1389  fTsumwy = stats[4];
1390  fTsumwy2 = stats[5];
1391  fTsumwxy = stats[6];
1392  fTsumwz = stats[7];
1393  fTsumwz2 = stats[8];
1394 }
1395 
1396 ////////////////////////////////////////////////////////////////////////////////
1397 /// -*Reset contents of a Profile2D histogram
1398 ///*-* =======================================
1399 
1401 {
1402  TH2D::Reset(option);
1403  fBinEntries.Reset();
1404  fBinSumw2.Reset();
1405  TString opt = option;
1406  opt.ToUpper();
1407  if (opt.Contains("ICE") && !opt.Contains("S")) return;
1408  fTsumwz = fTsumwz2 = 0;
1409 }
1410 
1411 
1412 ////////////////////////////////////////////////////////////////////////////////
1413 /// Profile histogram is resized along axis such that x is in the axis range.
1414 /// The new axis limits are recomputed by doubling iteratively
1415 /// the current axis range until the specified value x is within the limits.
1416 /// The algorithm makes a copy of the histogram, then loops on all bins
1417 /// of the old histogram to fill the extended histogram.
1418 /// Takes into account errors (Sumw2) if any.
1419 /// The axis must be extendable before invoking this function.
1420 /// Ex: h->GetXaxis()->SetCanExtend(kTRUE)
1421 
1423 {
1424  TProfile2D* hold = TProfileHelper::ExtendAxis(this, x, axis);
1425  if ( hold ) {
1426  fTsumwz = hold->fTsumwz;
1427  fTsumwz2 = hold->fTsumwz2;
1428  delete hold;
1429  }
1430 }
1431 
1432 ////////////////////////////////////////////////////////////////////////////////
1433 /// Rebin this histogram grouping nxgroup/nygroup bins along the xaxis/yaxis together.
1434 /// if newname is not blank a new profile hnew is created.
1435 /// else the current histogram is modified (default)
1436 /// The parameter nxgroup/nygroup indicate how many bins along the xaxis/yaxis of this
1437 /// have to be merged into one bin of hnew
1438 /// If the original profile has errors stored (via Sumw2), the resulting
1439 /// profile has new errors correctly calculated.
1440 ///
1441 /// examples: if hpxpy is an existing TProfile2D profile with 40 x 40 bins
1442 /// hpxpy->Rebin2D(); // merges two bins along the xaxis and yaxis in one
1443 /// // Carefull: previous contents of hpxpy are lost
1444 /// hpxpy->Rebin2D(3,5); // merges 3 bins along the xaxis and 5 bins along the yaxis in one
1445 /// // Carefull: previous contents of hpxpy are lost
1446 /// hpxpy->RebinX(5); //merges five bins along the xaxis in one in hpxpy
1447 /// TProfile2D *hnew = hpxpy->RebinY(5,"hnew"); // creates a new profile hnew
1448 /// // merging 5 bins of hpxpy along the yaxis in one bin
1449 ///
1450 /// NOTE : If nxgroup/nygroup is not an exact divider of the number of bins,
1451 /// along the xaxis/yaxis the top limit(s) of the rebinned profile
1452 /// is changed to the upper edge of the xbin=newxbins*nxgroup resp.
1453 /// ybin=newybins*nygroup and the remaining bins are added to
1454 /// the overflow bin.
1455 /// Statistics will be recomputed from the new bin contents.
1456 
1457 TProfile2D * TProfile2D::Rebin2D(Int_t nxgroup ,Int_t nygroup,const char * newname ) {
1458  //something to do?
1459  if((nxgroup != 1) || (nygroup != 1)){
1460  Int_t nxbins = fXaxis.GetNbins();
1461  Int_t nybins = fYaxis.GetNbins();
1466  if ((nxgroup <= 0) || (nxgroup > nxbins)) {
1467  Error("Rebin", "Illegal value of nxgroup=%d",nxgroup);
1468  return 0;
1469  }
1470  if ((nygroup <= 0) || (nygroup > nybins)) {
1471  Error("Rebin", "Illegal value of nygroup=%d",nygroup);
1472  return 0;
1473  }
1474 
1475  Int_t newxbins = nxbins/nxgroup;
1476  Int_t newybins = nybins/nygroup;
1477 
1478  //warning if bins are added to the overflow bin
1479  if(newxbins*nxgroup != nxbins) {
1480  Warning("Rebin", "nxgroup=%d should be an exact divider of nxbins=%d",nxgroup,nxbins);
1481  }
1482  if(newybins*nygroup != nybins) {
1483  Warning("Rebin", "nygroup=%d should be an exact divider of nybins=%d",nygroup,nybins);
1484  }
1485 
1486  //save old bin contents in new arrays
1487  Double_t *oldBins = new Double_t[(nxbins+2)*(nybins+2)];
1488  Double_t *oldCount = new Double_t[(nxbins+2)*(nybins+2)];
1489  Double_t *oldErrors = new Double_t[(nxbins+2)*(nybins+2)];
1490  Double_t *oldBinw2 = (fBinSumw2.fN ? new Double_t[(nxbins+2)*(nybins+2)] : 0 );
1491  Double_t *cu1 = GetW();
1492  Double_t *er1 = GetW2();
1493  Double_t *en1 = GetB();
1494  Double_t *ew1 = GetB2();
1495  for(Int_t ibin=0; ibin < (nxbins+2)*(nybins+2); ibin++){
1496  oldBins[ibin] = cu1[ibin];
1497  oldCount[ibin] = en1[ibin];
1498  oldErrors[ibin] = er1[ibin];
1499  if (ew1 && fBinSumw2.fN) oldBinw2[ibin] = ew1[ibin];
1500  }
1501 
1502  // create a clone of the old profile if newname is specified
1503  TProfile2D *hnew = this;
1504  if(newname && strlen(newname) > 0) {
1505  hnew = (TProfile2D*)Clone(newname);
1506  }
1507 
1508  // in case of nxgroup/nygroup not an exact divider of nxbins/nybins,
1509  // top limit is changed (see NOTE in method comment)
1510  if(newxbins*nxgroup != nxbins) {
1511  xmax = fXaxis.GetBinUpEdge(newxbins*nxgroup);
1512  hnew->fTsumw = 0; //stats must be reset because top bins will be moved to overflow bin
1513  }
1514  if(newybins*nygroup != nybins) {
1515  ymax = fYaxis.GetBinUpEdge(newybins*nygroup);
1516  hnew->fTsumw = 0; //stats must be reset because top bins will be moved to overflow bin
1517  }
1518 
1519  //rebin the axis
1520  if((fXaxis.GetXbins()->GetSize() > 0) || (fYaxis.GetXbins()->GetSize() > 0)){
1521  Double_t* xbins = new Double_t[newxbins+1];
1522  Double_t* ybins = new Double_t[newybins+1];
1523  for(Int_t i=0; i < newxbins+1; i++)
1524  xbins[i] = fXaxis.GetBinLowEdge(1+i*nxgroup);
1525  for(Int_t j=0; j < newybins+1; j++)
1526  ybins[j] = fYaxis.GetBinLowEdge(1+j*nygroup);
1527  hnew->SetBins(newxbins,xbins,newybins,ybins);
1528  delete [] xbins;
1529  delete [] ybins;
1530  }
1531  //fixed bin size
1532  else{
1533  hnew->SetBins(newxbins,xmin,xmax,newybins,ymin,ymax);
1534  }
1535 
1536  //merge bins
1537  Double_t *cu2 = hnew->GetW();
1538  Double_t *er2 = hnew->GetW2();
1539  Double_t *en2 = hnew->GetB();
1540  Double_t *ew2 = hnew->GetB2();
1541  Double_t binContent, binCount, binError, binSumw2;
1542  //connection between x and y bin number and linear global bin number:
1543  //global bin = xbin + (nxbins+2) * ybin
1544  Int_t oldxbin = 1;
1545  Int_t oldybin = 1;
1546  //global bin number
1547  Int_t bin;
1548  for(Int_t xbin = 1; xbin <= newxbins; xbin++){
1549  oldybin = 1;
1550  for(Int_t ybin = 1; ybin <= newybins; ybin++){
1551  binContent = 0;
1552  binCount = 0;
1553  binError = 0;
1554  binSumw2 = 0;
1555  for(Int_t i=0; i < nxgroup; i++){
1556  if(oldxbin + i > nxbins) break;
1557  for(Int_t j=0; j < nygroup; j++){
1558  if(oldybin + j > nybins) break;
1559  bin = oldxbin + i + (nxbins+2)*(oldybin+j);
1560  binContent += oldBins[bin];
1561  binCount += oldCount[bin];
1562  binError += oldErrors[bin];
1563  if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
1564  }
1565  }
1566  bin = xbin + (newxbins + 2)*ybin;
1567  cu2[bin] = binContent;
1568  er2[bin] = binError;
1569  en2[bin] = binCount;
1570  if(fBinSumw2.fN) ew2[bin] = binSumw2;
1571  oldybin += nygroup;
1572  }
1573  oldxbin += nxgroup;
1574  }
1575 
1576  //copy the underflow bin in x and y (0,0)
1577  cu2[0] = oldBins[0];
1578  er2[0] = oldErrors[0];
1579  en2[0] = oldCount[0];
1580  if(fBinSumw2.fN) ew2[0] = oldBinw2[0];
1581  //calculate overflow bin in x and y (newxbins+1,newybins+1)
1582  //therefore the oldxbin and oldybin from above are needed!
1583  binContent = 0;
1584  binCount = 0;
1585  binError = 0;
1586  binSumw2 = 0;
1587  for(Int_t i=oldxbin; i <= nxbins+1; i++){
1588  for(Int_t j=oldybin; j <= nybins+1; j++){
1589  //global bin number
1590  bin = i + (nxbins+2)*j;
1591  binContent += oldBins[bin];
1592  binCount += oldCount[bin];
1593  binError += oldErrors[bin];
1594  if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
1595  }
1596  }
1597  bin = (newxbins+2)*(newybins+2)-1;
1598  cu2[bin] = binContent;
1599  er2[bin] = binError;
1600  en2[bin] = binCount;
1601  if(fBinSumw2.fN) ew2[bin] = binSumw2;
1602  //calculate overflow bin in x and underflow bin in y (newxbins+1,0)
1603  binContent = 0;
1604  binCount = 0;
1605  binError = 0;
1606  binSumw2 = 0;
1607  for(Int_t i=oldxbin; i <= nxbins+1; i++){
1608  bin = i;
1609  binContent += oldBins[bin];
1610  binCount += oldCount[bin];
1611  binError += oldErrors[bin];
1612  if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
1613  }
1614  bin = newxbins + 1;
1615  cu2[bin] = binContent;
1616  er2[bin] = binError;
1617  en2[bin] = binCount;
1618  if(fBinSumw2.fN) ew2[bin] = binSumw2;
1619  //calculate underflow bin in x and overflow bin in y (0,newybins+1)
1620  binContent = 0;
1621  binCount = 0;
1622  binError = 0;
1623  binSumw2 = 0;
1624  for(Int_t i=oldybin; i <= nybins+1; i++){
1625  bin = i*(nxbins + 2);
1626  binContent += oldBins[bin];
1627  binCount += oldCount[bin];
1628  binError += oldErrors[bin];
1629  if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
1630  }
1631  bin = (newxbins + 2)*(newybins + 1);
1632  cu2[bin] = binContent;
1633  er2[bin] = binError;
1634  en2[bin] = binCount;
1635  if(fBinSumw2.fN) ew2[bin] = binSumw2;
1636  //calculate under/overflow contents in y for the new x bins
1637  Double_t binContentuf, binCountuf, binErroruf, binSumw2uf;
1638  Double_t binContentof, binCountof, binErrorof, binSumw2of;
1639  Int_t ufbin, ofbin;
1640  Int_t oldxbin2 = 1;
1641  for(Int_t xbin = 1; xbin <= newxbins; xbin++){
1642  binContentuf = 0;
1643  binCountuf = 0;
1644  binErroruf = 0;
1645  binSumw2uf = 0;
1646  binContentof = 0;
1647  binCountof = 0;
1648  binErrorof = 0;
1649  binSumw2of = 0;
1650  for(Int_t i = 0; i < nxgroup; i++){
1651  //index of under/overflow bin for y in old binning
1652  ufbin = (oldxbin2 + i);
1653  binContentuf += oldBins[ufbin];
1654  binCountuf += oldCount[ufbin];
1655  binErroruf += oldErrors[ufbin];
1656  if(fBinSumw2.fN) binSumw2uf += oldBinw2[ufbin];
1657  for(Int_t j = oldybin; j <= nybins+1; j++)
1658  {
1659  ofbin = ufbin + j*(nxbins + 2);
1660  binContentof += oldBins[ofbin];
1661  binCountof += oldCount[ofbin];
1662  binErrorof += oldErrors[ofbin];
1663  if(fBinSumw2.fN) binSumw2of += oldBinw2[ofbin];
1664  }
1665  }
1666  //index of under/overflow bin for y in new binning
1667  ufbin = xbin;
1668  ofbin = ufbin + (newybins + 1)*(newxbins + 2);
1669  cu2[ufbin] = binContentuf;
1670  er2[ufbin] = binErroruf;
1671  en2[ufbin] = binCountuf;
1672  if(fBinSumw2.fN) ew2[ufbin] = binSumw2uf;
1673  cu2[ofbin] = binContentof;
1674  er2[ofbin] = binErrorof;
1675  en2[ofbin] = binCountof;
1676  if(fBinSumw2.fN) ew2[ofbin] = binSumw2of;
1677 
1678  oldxbin2 += nxgroup;
1679  }
1680  //calculate under/overflow contents in x for the new y bins
1681  Int_t oldybin2 = 1;
1682  for(Int_t ybin = 1; ybin <= newybins; ybin++){
1683  binContentuf = 0;
1684  binCountuf = 0;
1685  binErroruf = 0;
1686  binSumw2uf = 0;
1687  binContentof = 0;
1688  binCountof = 0;
1689  binErrorof = 0;
1690  binSumw2of = 0;
1691  for(Int_t i = 0; i < nygroup; i++){
1692  //index of under/overflow bin for x in old binning
1693  ufbin = (oldybin2 + i)*(nxbins+2);
1694  binContentuf += oldBins[ufbin];
1695  binCountuf += oldCount[ufbin];
1696  binErroruf += oldErrors[ufbin];
1697  if(fBinSumw2.fN) binSumw2uf += oldBinw2[ufbin];
1698  for(Int_t j = oldxbin; j <= nxbins+1; j++)
1699  {
1700  ofbin = j + ufbin;
1701  binContentof += oldBins[ofbin];
1702  binCountof += oldCount[ofbin];
1703  binErrorof += oldErrors[ofbin];
1704  if(fBinSumw2.fN) binSumw2of += oldBinw2[ofbin];
1705  }
1706  }
1707  //index of under/overflow bin for x in new binning
1708  ufbin = ybin * (newxbins + 2);
1709  ofbin = newxbins + 1 + ufbin;
1710  cu2[ufbin] = binContentuf;
1711  er2[ufbin] = binErroruf;
1712  en2[ufbin] = binCountuf;
1713  if(fBinSumw2.fN) ew2[ufbin] = binSumw2uf;
1714  cu2[ofbin] = binContentof;
1715  er2[ofbin] = binErrorof;
1716  en2[ofbin] = binCountof;
1717  if(fBinSumw2.fN) ew2[ofbin] = binSumw2of;
1718 
1719  oldybin2 += nygroup;
1720  }
1721 
1722  delete [] oldBins;
1723  delete [] oldCount;
1724  delete [] oldErrors;
1725  if (oldBinw2) delete [] oldBinw2;
1726 
1727  return hnew;
1728  }
1729  //nxgroup == nygroup == 1
1730  else{
1731  if((newname) && (strlen(newname) > 0))
1732  return (TProfile2D*)Clone(newname);
1733  else
1734  return this;
1735  }
1736 }
1737 
1738 ////////////////////////////////////////////////////////////////////////////////
1739 /// Rebin only the X axis
1740 /// see Rebin2D
1741 
1742 TProfile2D * TProfile2D::RebinX(Int_t ngroup,const char * newname ) {
1743  return Rebin2D(ngroup,1,newname);
1744 }
1745 
1746 ////////////////////////////////////////////////////////////////////////////////
1747 /// Rebin only the Y axis
1748 /// see Rebin2D
1749 
1750 TProfile2D * TProfile2D::RebinY(Int_t ngroup,const char * newname ) {
1751  return Rebin2D(1,ngroup,newname);
1752 }
1753 
1754 ////////////////////////////////////////////////////////////////////////////////
1755 /// Save primitive as a C++ statement(s) on output stream out
1756 
1757 void TProfile2D::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1758 {
1759  //Note the following restrictions in the code generated:
1760  // - variable bin size not implemented
1761  // - SetErrorOption not implemented
1762 
1763 
1764  char quote = '"';
1765  out <<" "<<std::endl;
1766  out <<" "<<ClassName()<<" *";
1767 
1768  out << GetName() << " = new " << ClassName() << "(" << quote
1769  << GetName() << quote << "," << quote<< GetTitle() << quote
1770  << "," << GetXaxis()->GetNbins();
1771  out << "," << GetXaxis()->GetXmin()
1772  << "," << GetXaxis()->GetXmax();
1773  out << "," << GetYaxis()->GetNbins();
1774  out << "," << GetYaxis()->GetXmin()
1775  << "," << GetYaxis()->GetXmax();
1776  out << "," << fZmin
1777  << "," << fZmax;
1778  out << ");" << std::endl;
1779 
1780 
1781  // save bin entries
1782  Int_t bin;
1783  for (bin=0;bin<fNcells;bin++) {
1784  Double_t bi = GetBinEntries(bin);
1785  if (bi) {
1786  out<<" "<<GetName()<<"->SetBinEntries("<<bin<<","<<bi<<");"<<std::endl;
1787  }
1788  }
1789  //save bin contents
1790  for (bin=0;bin<fNcells;bin++) {
1791  Double_t bc = fArray[bin];
1792  if (bc) {
1793  out<<" "<<GetName()<<"->SetBinContent("<<bin<<","<<bc<<");"<<std::endl;
1794  }
1795  }
1796  // save bin errors
1797  if (fSumw2.fN) {
1798  for (bin=0;bin<fNcells;bin++) {
1799  Double_t be = TMath::Sqrt(fSumw2.fArray[bin]);
1800  if (be) {
1801  out<<" "<<GetName()<<"->SetBinError("<<bin<<","<<be<<");"<<std::endl;
1802  }
1803  }
1804  }
1805 
1806  TH1::SavePrimitiveHelp(out, GetName(), option);
1807 }
1808 
1809 ////////////////////////////////////////////////////////////////////////////////
1810 /// Multiply this profile2D by a constant c1
1811 ///
1812 /// this = c1*this
1813 ///
1814 /// This function uses the services of TProfile2D::Add
1815 
1817 {
1818  TProfileHelper::Scale(this, c1, option);
1819 }
1820 
1821 ////////////////////////////////////////////////////////////////////////////////
1822 /// Set the number of entries in bin -
1823 
1825 {
1826  TProfileHelper::SetBinEntries(this, bin, w);
1827 }
1828 
1829 ////////////////////////////////////////////////////////////////////////////////
1830 /// Redefine x and y axis parameters -
1831 
1833 {
1834  TH1::SetBins(nx,xmin, xmax,ny, ymin,ymax);
1837 }
1838 
1839 ////////////////////////////////////////////////////////////////////////////////
1840 /// Redefine x and y axis parameters for variable bin sizes - -*
1841 
1842 void TProfile2D::SetBins(Int_t nx, const Double_t *xbins, Int_t ny, const Double_t *ybins)
1843 {
1844  TH1::SetBins(nx,xbins,ny,ybins);
1847 }
1848 
1849 ////////////////////////////////////////////////////////////////////////////////
1850 /// Set total number of bins including under/overflow
1851 /// Reallocate bin contents array
1852 
1854 {
1857 }
1858 
1859 ////////////////////////////////////////////////////////////////////////////////
1860 /// set the buffer size in units of 8 bytes (double)
1861 
1863 {
1864  if (fBuffer) {
1865  BufferEmpty();
1866  delete [] fBuffer;
1867  fBuffer = 0;
1868  }
1869  if (buffersize <= 0) {
1870  fBufferSize = 0;
1871  return;
1872  }
1873  if (buffersize < 100) buffersize = 100;
1874  fBufferSize = 1 + 4*buffersize;
1875  fBuffer = new Double_t[fBufferSize];
1876  memset(fBuffer,0,sizeof(Double_t)*fBufferSize);
1877 }
1878 
1879 ////////////////////////////////////////////////////////////////////////////////
1880 /// Set option to compute profile2D errors
1881 /// The computation of the bin errors is based on the parameter option:
1882 /// - ' ' (Default) The bin errors are the standard error on the mean of the bin profiled values (Z),
1883 /// i.e. the standard error of the bin contents.
1884 /// Note that if TProfile::Approximate() is called, an approximation is used when
1885 /// the spread in Z is 0 and the number of bin entries is > 0
1886 /// - 's' The bin errors are the standard deviations of the Z bin values
1887 /// Note that if TProfile::Approximate() is called, an approximation is used when
1888 /// the spread in Z is 0 and the number of bin entries is > 0
1889 /// - 'i' Errors are as in default case (standard errors of the bin contents)
1890 /// The only difference is for the case when the spread in Z is zero.
1891 /// In this case for N > 0 the error is 1./SQRT(12.*N)
1892 /// - 'g' Errors are 1./SQRT(W) for W not equal to 0 and 0 for W = 0.
1893 /// W is the sum in the bin of the weights of the profile.
1894 /// This option is for combining measurements z +/- dz,
1895 /// and the profile is filled with values y and weights z = 1/dz**2
1896 ///
1897 /// See TProfile::BuildOptions for a detailed explanation of all options
1898 
1900 {
1901  TProfileHelper::SetErrorOption(this, option);
1902 }
1903 
1904 ////////////////////////////////////////////////////////////////////////////////
1905 /// Stream an object of class TProfile2D.
1906 
1907 void TProfile2D::Streamer(TBuffer &R__b)
1908 {
1909  if (R__b.IsReading()) {
1910  UInt_t R__s, R__c;
1911  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1912  if (R__v > 2) {
1913  R__b.ReadClassBuffer(TProfile2D::Class(), this, R__v, R__s, R__c);
1914  return;
1915  }
1916  //====process old versions before automatic schema evolution
1917  TH2D::Streamer(R__b);
1918  fBinEntries.Streamer(R__b);
1919  Int_t errorMode;
1920  R__b >> errorMode;
1921  fErrorMode = (EErrorType)errorMode;
1922  if (R__v < 2) {
1923  Float_t zmin,zmax;
1924  R__b >> zmin; fZmin = zmin;
1925  R__b >> zmax; fZmax = zmax;
1926  } else {
1927  R__b >> fZmin;
1928  R__b >> fZmax;
1929  }
1930  R__b.CheckByteCount(R__s, R__c, TProfile2D::IsA());
1931  //====end of old versions
1932 
1933  } else {
1934  R__b.WriteClassBuffer(TProfile2D::Class(),this);
1935  }
1936 }
1937 
1938 ////////////////////////////////////////////////////////////////////////////////
1939 /// Create/Delete structure to store sum of squares of weights per bin
1940 /// This is needed to compute the correct statistical quantities
1941 /// of a profile filled with weights
1942 ///
1943 /// This function is automatically called when the histogram is created
1944 /// if the static function TH1::SetDefaultSumw2 has been called before.
1945 /// If flag is false the structure is deleted
1946 
1948 {
1949  TProfileHelper::Sumw2(this, flag);
1950 }
const int nx
Definition: kalman.C:16
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH2.cxx:4046
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:429
virtual Long64_t Merge(TCollection *list)
Merge all histograms in the collection in this histogram.
tuple labels
Definition: mrt.py:18
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
static void SetBinEntries(T *p, Int_t bin, Double_t w)
static void Scale(T *p, Double_t c1, Option_t *option)
float xmin
Definition: THbookFile.cxx:93
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
tuple buffer
Definition: tree.py:99
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4629
long long Long64_t
Definition: RtypesCore.h:69
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile2D histogram.
Definition: TProfile2D.cxx:798
Bool_t IsReading() const
Definition: TBuffer.h:83
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:487
virtual void Sumw2(Bool_t flag=kTRUE)
Create/Delete structure to store sum of squares of weights per bin This is needed to compute the corr...
short Version_t
Definition: RtypesCore.h:61
static Double_t GetBinError(T *p, Int_t bin)
float Float_t
Definition: RtypesCore.h:53
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8266
const char Option_t
Definition: RtypesCore.h:62
TCanvas * c1
Definition: legend1.C:2
void Reset()
Definition: TArrayD.h:49
virtual void ExtendAxis(Double_t x, TAxis *axis)
Profile histogram is resized along axis such that x is in the axis range.
float ymin
Definition: THbookFile.cxx:93
TAxis fYaxis
Definition: TH1.h:103
static void SetErrorOption(T *p, Option_t *opt)
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition: TH1.cxx:8090
static void LabelsInflate(T *p, Option_t *)
static Bool_t fgStatOverflows
flag to add histograms to the directory
Definition: TH1.h:128
virtual void Copy(TObject &hnew) const
Copy a Profile2D histogram to a new profile2D histogram*.
Definition: TProfile2D.cxx:365
tuple pname
Definition: tree.py:131
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1088
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:489
#define R__ASSERT(e)
Definition: TError.h:98
static THLimitsFinder * GetLimitsFinder()
Return pointer to the current finder.
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
virtual TProfile2D * RebinY(Int_t ngroup=2, const char *newname="")
Rebin only the Y axis see Rebin2D.
Basic string class.
Definition: TString.h:137
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1075
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual TProfile2D * Rebin2D(Int_t nxgroup=2, Int_t nygroup=2, const char *newname="")
Rebin this histogram grouping nxgroup/nygroup bins along the xaxis/yaxis together.
TArrayD fSumw2
Definition: TH1.h:116
virtual ~TProfile2D()
Default destructor for Profile2D histograms.
Definition: TProfile2D.cxx:83
virtual Int_t GetNbinsX() const
Definition: TH1.h:296
const TKDTreeBinning * bins
Profile Historam.
Definition: TProfile.h:34
void Copy(TArrayD &array) const
Definition: TArrayD.h:44
virtual Int_t FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax)
compute the best axis limits for the X axis.
Double_t * GetB()
Definition: TProfile2D.h:66
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:311
virtual Bool_t Multiply(TF1 *h1, Double_t c1=1)
Performs the operation: this = this*c1*f1.
EErrorType
Definition: TProfile.h:30
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
Double_t fTsumwx2
Definition: TH1.h:111
TObject * Clone(const char *newname=0) const
Make a complete copy of the underlying object.
Definition: TH1.cxx:2565
static void BuildArray(T *p)
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:946
static Bool_t fgApproximate
Definition: TProfile2D.h:45
virtual TProfile * DoProfile(bool onX, const char *name, Int_t firstbin, Int_t lastbin, Option_t *option) const
implementation of ProfileX or ProfileY for a TProfile2D Do correctly the combination of the bin avera...
Int_t Fill(const Double_t *v)
Definition: TProfile2D.h:54
Double_t x[n]
Definition: legend1.C:17
virtual Bool_t Divide(TF1 *h1, Double_t c1=1)
Performs the operation: this = this/(c1*f1) This function is not implemented.
Definition: TProfile2D.cxx:395
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:36
void Class()
Definition: Class.C:29
void BuildOptions(Double_t zmin, Double_t zmax, Option_t *option)
Set Profile2D histogram structure and options.
Definition: TProfile2D.cxx:173
const int ny
Definition: kalman.C:17
Double_t * GetB2()
Definition: TProfile2D.h:67
TProfile * ProfileX(const char *name="_pfx", Int_t firstybin=0, Int_t lastybin=-1, Option_t *option="") const
*-*Project a 2-D histogram into a profile histogram along X *-* =====================================...
TArrayD fBinEntries
Definition: TProfile2D.h:37
virtual void SetErrorOption(Option_t *option="")
Set option to compute profile2D errors The computation of the bin errors is based on the parameter op...
virtual TArrayD * GetBinSumw2()
Definition: TProfile.h:111
static double p2(double t, double a, double b, double c)
static void LabelsDeflate(T *p, Option_t *)
static void Approximate(Bool_t approx=kTRUE)
static function set the fgApproximate flag.
Definition: TProfile2D.cxx:259
TH1D * ProjectionX(const char *name="_px", Int_t firstybin=0, Int_t lastybin=-1, Option_t *option="") const
Project a 2-D histogram into a 1-D histogram along X.
Definition: TH2.cxx:2523
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Definition: TMath.h:1002
Double_t * fArray
Definition: TArrayD.h:32
static T * ExtendAxis(T *p, Double_t x, TAxis *axis)
Double_t fTsumwy2
Definition: TH2.h:41
TH2D * h2
Definition: fit2dHist.C:45
virtual void LabelsDeflate(Option_t *axis="X")
Reduce the number of bins for this axis to the number of bins having a label.
Definition: TProfile2D.cxx:934
TH1D * ProjectionY(const char *name="_py", Int_t firstxbin=0, Int_t lastxbin=-1, Option_t *option="") const
Project a 2-D histogram into a 1-D histogram along Y.
Definition: TH2.cxx:2563
virtual TArrayD * GetSumw2()
Definition: TH1.h:312
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
TH1F * h1
Definition: legend1.C:5
Float_t z[5]
Definition: Ifit.C:16
virtual void SetBinError(Int_t bin, Double_t error)
see convention for numbering bins in TH1::GetBin
Definition: TH1.cxx:8528
Double_t GetXmin() const
Definition: TAxis.h:137
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this profile2D by a constant c1.
char * out
Definition: TBase64.cxx:29
Double_t fTsumwx
Definition: TH1.h:110
Double_t fZmin
Definition: TProfile2D.h:39
virtual Double_t GetEffectiveEntries() const
number of effective entries of the histogram, neff = (Sum of weights )^2 / (Sum of weight^2 ) In case...
Definition: TH1.cxx:4073
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:743
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH2.h:314
Int_t fN
Definition: TArray.h:40
void Clear(Option_t *option="")
Remove all objects from the list.
Definition: THashList.cxx:168
virtual Bool_t Add(TF1 *h1, Double_t c1=1, Option_t *option="")
Performs the operation: this = this + c1*f1.
Definition: TProfile2D.cxx:202
float ymax
Definition: THbookFile.cxx:93
virtual void Copy(TObject &hnew) const
Copy.
Definition: TH2.cxx:4026
virtual Double_t GetBinContent(Int_t bin) const
Return bin content of a Profile2D histogram.
Definition: TProfile2D.cxx:785
Class to manage histogram axis.
Definition: TAxis.h:36
TPaveLabel title(3, 27.1, 15, 28.7,"ROOT Environment and Tools")
Int_t GetNbins() const
Definition: TAxis.h:125
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:499
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
Double_t fTsumwxy
Definition: TH2.h:42
Double_t fTsumwy
Definition: TH2.h:40
Collection abstract base class.
Definition: TCollection.h:48
TClass * IsA() const
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition: TProfile2D.cxx:273
static Int_t fgBufferSize
Definition: TH1.h:126
Double_t fZmax
Definition: TProfile2D.h:40
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Double_t fEntries
Definition: TH1.h:107
unsigned int UInt_t
Definition: RtypesCore.h:42
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
Double_t fTsumwz2
Definition: TProfile2D.h:43
virtual TProfile2D * RebinX(Int_t ngroup=2, const char *newname="")
Rebin only the X axis see Rebin2D.
tuple w
Definition: qtexample.py:51
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
virtual void LabelsOption(Option_t *option="h", Option_t *axis="X")
Set option(s) to draw axis with labels option = "a" sort by alphabetic order = ">" sort by decreasing...
Definition: TProfile2D.cxx:959
TAxis * GetYaxis()
Definition: TH1.h:320
virtual Double_t GetBinError(Int_t bin) const
-*Return bin error of a Profile2D histogram
Definition: TProfile2D.cxx:839
static double p1(double t, double a, double b)
float xmax
Definition: THbookFile.cxx:93
virtual void SetBuffer(Int_t buffersize, Option_t *option="")
set the buffer size in units of 8 bytes (double)
virtual void LabelsInflate(Option_t *axis="X")
Double the number of bins for axis.
Definition: TProfile2D.cxx:944
Bool_t IsNull() const
Definition: TString.h:387
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:613
virtual void GetStats(Double_t *stats) const
fill the array stats from the contents of this profile The array stats must be correctly dimensionned...
Definition: TProfile2D.cxx:874
virtual Int_t GetBin(Int_t binx, Int_t biny, Int_t binz=0) const
Return Global bin number corresponding to binx,y,z.
Definition: TH2.cxx:961
const Double_t * GetArray() const
Definition: TArrayD.h:45
Int_t GetSize() const
Definition: TArray.h:49
Double_t * GetW()
Definition: TProfile2D.h:68
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:264
static Bool_t Add(T *p, const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2=1)
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
Double_t fTsumw2
Definition: TH1.h:109
virtual Int_t BufferFill(Double_t, Double_t)
accumulate arguments in buffer.
Definition: TProfile2D.h:47
virtual Int_t GetSize() const
Definition: TCollection.h:95
return c2
Definition: legend2.C:14
#define ClassImp(name)
Definition: Rtypes.h:279
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
double Double_t
Definition: RtypesCore.h:55
virtual void SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option="")
helper function for the SavePrimitive functions from TH1 or classes derived from TH1, eg TProfile, TProfile2D.
Definition: TH1.cxx:6864
virtual Double_t GetBinEffectiveEntries(Int_t bin)
Return bin effective entries for a weighted filled Profile histogram.
Definition: TProfile2D.cxx:816
Double_t fTsumw
Definition: TH1.h:108
static Double_t GetBinEffectiveEntries(T *p, Int_t bin)
Double_t GetXmax() const
Definition: TAxis.h:138
Double_t y[n]
Definition: legend1.C:17
TH2D * ProjectionXY(const char *name="_pxy", Option_t *option="e") const
*-*Project this profile2D into a 2-D histogram along X,Y -* *-* =====================================...
The TH1 histogram class.
Definition: TH1.h:80
virtual void SetBinEntries(Int_t bin, Double_t w)
Set the number of entries in bin -.
Profile2D histograms are used to display the mean value of Z and its RMS for each cell in X...
Definition: TProfile2D.h:31
Array of doubles (64 bits per element).
Definition: TArrayD.h:29
#define name(a, b)
Definition: linkTestLib0.cpp:5
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:440
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:449
Mother of all ROOT objects.
Definition: TObject.h:58
virtual void SetBinEntries(Int_t bin, Double_t w)
Set the number of entries in bin.
Definition: TProfile.cxx:1605
virtual Int_t GetNbinsY() const
Definition: TH1.h:297
THashList * GetLabels() const
Definition: TAxis.h:122
Bool_t axis
Definition: geodemo.C:37
virtual void Add(TObject *obj)
Definition: TList.h:81
Int_t fBufferSize
Definition: TH1.h:119
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
1-Dim function class
Definition: TF1.h:149
Int_t IsNaN(Double_t x)
Definition: TMath.h:617
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition: TH1.cxx:8350
virtual Bool_t CanExtendAllAxes() const
returns true if all axes are extendable
Definition: TH1.cxx:6197
TArrayD fBinSumw2
Definition: TProfile2D.h:44
virtual void SetEntries(Double_t n)
Definition: TH1.h:382
std::vector< double > errors
Definition: TwoHistoFit2D.C:33
TAxis fXaxis
Definition: TH1.h:102
static void Sumw2(T *p, Bool_t flag)
const TArrayD * GetXbins() const
Definition: TAxis.h:134
Option_t * GetErrorOption() const
-*Return option to compute profile2D errors *-* ========================================= ...
Definition: TProfile2D.cxx:848
void ResetBit(UInt_t f)
Definition: TObject.h:172
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content.
Definition: TH2.cxx:2699
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual void Sumw2(Bool_t flag=kTRUE)
Create/delete structure to store sum of squares of weights per bin — This is needed to compute the co...
Definition: TProfile.cxx:1730
const Bool_t kTRUE
Definition: Rtypes.h:91
TObject * obj
void SetBins(const Int_t *nbins, const Double_t *range)
Definition: TProfile2D.h:52
Double_t * fBuffer
Definition: TH1.h:120
EErrorType fErrorMode
Definition: TProfile2D.h:38
void Set(Int_t n)
Set size of this array to n doubles.
Definition: TArrayD.cxx:105
Double_t fTsumwz
True when TProfile2D::Scale is called.
Definition: TProfile2D.h:42
const Int_t n
Definition: legend1.C:16
static Long64_t Merge(T *p, TCollection *list)
Double_t * GetW2()
Definition: TProfile2D.h:69
TProfile * ProfileY(const char *name="_pfy", Int_t firstxbin=0, Int_t lastxbin=-1, Option_t *option="") const
*-*Project a 2-D histogram into a profile histogram along X *-* =====================================...
Bool_t fScaling
Definition: TProfile2D.h:41
TAxis * GetXaxis()
Definition: TH1.h:319
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
Int_t fNcells
Definition: TH1.h:101
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:297
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904