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