Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 "TError.h"
17#include "TClass.h"
18#include "TProfileHelper.h"
19#include "Rebin2DHelpers.h"
20
21#include <algorithm>
22#include <iostream>
23#include <vector>
24
26
27
28/** \class TProfile2D
29 \ingroup Histograms
30 Profile2D histograms are used to display the mean
31 value of Z and its error for each cell in X,Y.
32 Profile2D histograms are in many cases an
33 elegant replacement of three-dimensional histograms : the inter-relation of three
34 measured quantities X, Y and Z can always be visualized by a three-dimensional
35 histogram or scatter-plot; its representation on the line-printer is not particularly
36 satisfactory, except for sparse data. If Z is an unknown (but single-valued)
37 approximate function of X,Y this function is displayed by a profile2D histogram with
38 much better precision than by a scatter-plot.
39
40 The following formulae show the cumulated contents (capital letters) and the values
41 displayed by the printing or plotting routines (small letters) of the elements for cell i, j.
42 \f[
43 \begin{align}
44 H(i,j) &= \sum w \cdot Z \\
45 E(i,j) &= \sum w \cdot Z^2 \\
46 W(i,j) &= \sum w \\
47 h(i,j) &= \frac{H(i,j)}{W(i,j)} \\
48 s(i,j) &= \sqrt{E(i,j)/W(i,j)- h(i,j)^2} \\
49 e(i,j) &= \frac{s(i,j)}{\sqrt{W(i,j)}}
50 \end{align}
51 \f]
52 The bin content is always the mean of the Z values, but errors change depending on options:
53 \f[
54 \begin{align}
55 \text{GetBinContent}(i,j) &= h(i,j) \\
56 \text{GetBinError}(i,j) &=
57 \begin{cases}
58 e(i,j) &\text{if option="" (default). Error of the mean of all z values.} \\
59 s(i,j) &\text{if option="s". Standard deviation of z values.} \\
60 \begin{cases} e(j) &\text{if } h(i,j) \ne 0 \\ 1/\sqrt{12 N} &\text{if } h(i,j)=0 \end{cases} &\text{if option="i". This is useful for storing integers such as ADC counts.} \\
61 1/\sqrt{W(i,j)} &\text{if option="g". Error of a weighted mean when combining measurements with variances of } w. \\
62 \end{cases}
63 \end{align}
64 \f]
65
66 In the special case where s(I,J) is zero (eg, case of 1 entry only in one cell)
67 the bin error e(I,J) is computed from the average of the s(I,J) for all cells
68 if the static function TProfile2D::Approximate has been called.
69 This simple/crude approximation was suggested in order to keep the cell
70 during a fit operation. But note that this approximation is not the default behaviour.
71
72 ### Creating and drawing a 2D profile
73 ~~~~{.cpp}
74 {
75 auto c1 = new TCanvas("c1","Profile histogram example",200,10,700,500);
76 auto hprof2d = new TProfile2D("hprof2d","Profile of pz versus px and py",40,-4,4,40,-4,4,0,20);
77 Float_t px, py, pz;
78 for ( Int_t i=0; i<25000; i++) {
79 gRandom->Rannor(px,py);
80 pz = px*px + py*py;
81 hprof2d->Fill(px,py,pz,1);
82 }
83 hprof2d->Draw();
84 }
85 ~~~~
86*/
87
88////////////////////////////////////////////////////////////////////////////////
89/// Default constructor for Profile2D histograms.
90
92{
93 fTsumwz = fTsumwz2 = 0;
95 BuildOptions(0,0,"");
96}
97
98////////////////////////////////////////////////////////////////////////////////
99/// Default destructor for Profile2D histograms.
100
104
105////////////////////////////////////////////////////////////////////////////////
106/// Normal Constructor for Profile histograms.
107///
108/// The first eight parameters are similar to TH2D::TH2D.
109/// All values of z are accepted at filling time.
110/// To fill a profile2D histogram, one must use TProfile2D::Fill function.
111///
112/// Note that when filling the profile histogram the function Fill
113/// checks if the variable z is between fZmin and fZmax.
114/// If a minimum or maximum value is set for the Z scale before filling,
115/// then all values below zmin or above zmax will be discarded.
116/// Setting the minimum or maximum value for the Z scale before filling
117/// has the same effect as calling the special TProfile2D constructor below
118/// where zmin and zmax are specified.
119///
120/// H(I,J) is printed as the cell contents. The errors computed are s(I,J) if CHOPT='S'
121/// (spread option), or e(I,J) if CHOPT=' ' (error on mean).
122///
123/// See TProfile2D::BuildOptions for explanation of parameters
124///
125/// see other constructors below with all possible combinations of
126/// fix and variable bin size like in TH2D.
127
128TProfile2D::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)
129: TH2D(name,title,nx,xlow,xup,ny,ylow,yup)
130{
131 BuildOptions(0,0,option);
132 if (xlow >= xup || ylow >= yup) SetBuffer(fgBufferSize);
133}
134
135////////////////////////////////////////////////////////////////////////////////
136/// Create a 2-D Profile with variable bins in X and fix bins in Y.
137
138TProfile2D::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)
139: TH2D(name,title,nx,xbins,ny,ylow,yup)
140{
141 BuildOptions(0,0,option);
142}
143
144////////////////////////////////////////////////////////////////////////////////
145/// Create a 2-D Profile with fix bins in X and variable bins in Y.
146
147TProfile2D::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)
148: TH2D(name,title,nx,xlow,xup,ny,ybins)
149{
150 BuildOptions(0,0,option);
151}
152
153////////////////////////////////////////////////////////////////////////////////
154/// Create a 2-D Profile with variable bins in X and variable bins in Y.
155
156TProfile2D::TProfile2D(const char *name,const char *title,Int_t nx,const Double_t *xbins,Int_t ny,const Double_t *ybins,Option_t *option)
157: TH2D(name,title,nx,xbins,ny,ybins)
158{
159 BuildOptions(0,0,option);
160}
161
162////////////////////////////////////////////////////////////////////////////////
163/// Constructor for Profile2D histograms with range in z.
164///
165/// The first eight parameters are similar to TH2D::TH2D.
166/// Only the values of Z between ZMIN and ZMAX will be considered at filling time.
167/// zmin and zmax will also be the maximum and minimum values
168/// on the z scale when drawing the profile2D.
169///
170/// See TProfile2D::BuildOptions for more explanations on errors
171
173: TH2D(name,title,nx,xlow,xup,ny,ylow,yup)
174{
176 if (xlow >= xup || ylow >= yup) SetBuffer(fgBufferSize);
177}
178
179
180////////////////////////////////////////////////////////////////////////////////
181/// Set Profile2D histogram structure and options.
182///
183/// - zmin: minimum value allowed for z
184/// - zmax: maximum value allowed for z
185/// if (zmin = zmax = 0) there are no limits on the allowed z values (zmin = -inf, zmax = +inf)
186///
187/// - option: this is the option for the computation of the t error of the profile ( TProfile2D::GetBinError )
188/// possible values for the options are documented in TProfile2D::SetErrorOption
189///
190/// See TProfile::BuildOptions for a detailed description
191
193{
194
196
197 // create extra profile data structure (bin entries/ y^2 and sum of weight square)
199
200 fZmin = zmin;
201 fZmax = zmax;
203 fTsumwz = fTsumwz2 = 0;
204}
205
206////////////////////////////////////////////////////////////////////////////////
207/// Copy constructor.
208
210{
211 profile2d.TProfile2D::Copy(*this);
212}
213
215{
216 if (this != &profile2d)
217 profile2d.TProfile2D::Copy(*this);
218 return *this;
219}
220
221////////////////////////////////////////////////////////////////////////////////
222/// Performs the operation: `this = this + c1*f1` .
223
225{
226 Error("Add","Function not implemented for TProfile2D");
227 return kFALSE;
228}
229
230////////////////////////////////////////////////////////////////////////////////
231/// Performs the operation: `this = this + c1*h1` .
232
234{
235 if (!h1) {
236 Error("Add","Attempt to add a non-existing profile");
237 return kFALSE;
238 }
240 Error("Add","Attempt to add a non-profile2D object");
241 return kFALSE;
242 }
243
244 return TProfileHelper::Add(this, this, h1, 1, c1);
245}
246
247////////////////////////////////////////////////////////////////////////////////
248/// Replace contents of this profile2D by the addition of h1 and h2.
249///
250/// `this = c1*h1 + c2*h2`
251
253{
254 if (!h1 || !h2) {
255 Error("Add","Attempt to add a non-existing profile");
256 return kFALSE;
257 }
259 Error("Add","Attempt to add a non-profile2D object");
260 return kFALSE;
261 }
262 if (!h2->InheritsFrom(TProfile2D::Class())) {
263 Error("Add","Attempt to add a non-profile2D object");
264 return kFALSE;
265 }
266 return TProfileHelper::Add(this, h1, h2, c1, c2);
267}
268
269////////////////////////////////////////////////////////////////////////////////
270/// Static function, set the fgApproximate flag.
271///
272/// When the flag is true, the function GetBinError
273/// will approximate the bin error with the average profile error on all bins
274/// in the following situation only
275/// - the number of bins in the profile2D is less than 10404 (eg 100x100)
276/// - the bin number of entries is small ( <5)
277/// - the estimated bin error is extremely small compared to the bin content
278/// (see TProfile2D::GetBinError)
279
284
285////////////////////////////////////////////////////////////////////////////////
286/// Fill histogram with all entries in the buffer.
287///
288/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
289/// - action = 0 histogram is filled from the buffer
290/// - action = 1 histogram is filled and buffer is deleted
291/// The buffer is automatically deleted when the number of entries
292/// in the buffer is greater than the number of entries in the histogram
293
295{
296 // do we need to compute the bin size?
297 if (!fBuffer) return 0;
299 if (!nbentries) return 0;
300 Double_t *buffer = fBuffer;
301 if (nbentries < 0) {
302 if (action == 0) return 0;
304 fBuffer=nullptr;
305 Reset("ICES"); // reset without deleting the functions
306 fBuffer = buffer;
307 }
309 //find min, max of entries in buffer
310 Double_t xmin = fBuffer[2];
312 Double_t ymin = fBuffer[3];
314 for (Int_t i=1;i<nbentries;i++) {
315 Double_t x = fBuffer[4*i+2];
316 if (x < xmin) xmin = x;
317 if (x > xmax) xmax = x;
318 Double_t y = fBuffer[4*i+3];
319 if (y < ymin) ymin = y;
320 if (y > ymax) ymax = y;
321 }
322 if (fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin()) {
323 THLimitsFinder::GetLimitsFinder()->FindGoodLimitsXY(this, xmin, xmax, ymin, ymax);
324 } else {
325 fBuffer = nullptr;
331 fBuffer = buffer;
333 }
334 }
335
336 fBuffer = nullptr;
337 for (Int_t i=0;i<nbentries;i++) {
338 Fill(buffer[4*i+2],buffer[4*i+3],buffer[4*i+4],buffer[4*i+1]);
339 }
340 fBuffer = buffer;
341
342 if (action > 0) { delete [] fBuffer; fBuffer = nullptr; fBufferSize = 0;}
343 else {
345 else fBuffer[0] = 0;
346 }
347 return nbentries;
348}
349
350////////////////////////////////////////////////////////////////////////////////
351/// Accumulate arguments in buffer.
352///
353/// When buffer is full, empty the buffer.
354///
355/// - fBuffer[0] = number of entries in buffer
356/// - fBuffer[1] = w of first entry
357/// - fBuffer[2] = x of first entry
358/// - fBuffer[3] = y of first entry
359/// - fBuffer[4] = z of first entry
360
362{
363 if (!fBuffer) return -3;
365 if (nbentries < 0) {
367 fBuffer[0] = nbentries;
368 if (fEntries > 0) {
369 Double_t *buffer = fBuffer; fBuffer=nullptr;
370 Reset("ICES"); // reset without deleting the functions
371 fBuffer = buffer;
372 }
373 }
374 if (4*nbentries+4 >= fBufferSize) {
375 BufferEmpty(1);
376 return Fill(x,y,z,w);
377 }
378 fBuffer[4*nbentries+1] = w;
379 fBuffer[4*nbentries+2] = x;
380 fBuffer[4*nbentries+3] = y;
381 fBuffer[4*nbentries+4] = z;
382 fBuffer[0] += 1;
383 return -2;
384}
385
386////////////////////////////////////////////////////////////////////////////////
387/// Run a Chi2Test between a TProfile2D and another histogram.
388/// If the argument is also a TProfile2D, this calls TH1::Chi2Test() with the option "WW".
389/// \see TH1::Chi2Test()
390
392{
393 TString opt = option;
394 opt.ToUpper();
395
396 if (auto other = dynamic_cast<const TProfile2D *>(h2); other) {
397 if (fErrorMode != kERRORMEAN || other->fErrorMode != kERRORMEAN) {
398 Error("Chi2Test", "Chi2 tests need TProfiles in 'error of mean' mode.");
399 return 0;
400 }
401
402 opt += "WW";
403 opt.ReplaceAll("UU", "WW");
404 opt.ReplaceAll("UW", "WW");
405 } else if (!opt.Contains("WW")) {
406 Error("Chi2Test", "TProfiles need to be tested with the 'W' option. Either use option 'WW' or use "
407 "histogram.Chi2Test(<profile>, 'UW')");
408 return 0;
409 }
410
411 return TH1::Chi2Test(h2, opt, res);
412}
413
414////////////////////////////////////////////////////////////////////////////////
415/// Copy a Profile2D histogram to a new profile2D histogram.
416
417void TProfile2D::Copy(TObject &obj) const
418{
419 try {
420 TProfile2D &pobj = dynamic_cast<TProfile2D &>(obj);
421
423 fBinEntries.Copy(pobj.fBinEntries);
424 fBinSumw2.Copy(pobj.fBinSumw2);
425 for (int bin=0;bin<fNcells;bin++) {
426 pobj.fArray[bin] = fArray[bin];
427 pobj.fSumw2.fArray[bin] = fSumw2.fArray[bin];
428 }
429 pobj.fZmin = fZmin;
430 pobj.fZmax = fZmax;
431 pobj.fScaling = fScaling;
432 pobj.fErrorMode = fErrorMode;
433 pobj.fTsumwz = fTsumwz;
434 pobj.fTsumwz2 = fTsumwz2;
435
436 } catch(...) {
437 Fatal("Copy","Cannot copy a TProfile2D in a %s",obj.IsA()->GetName());
438 }
439
440}
441
442////////////////////////////////////////////////////////////////////////////////
443/// Performs the operation: `this = this/(c1*f1)` .
444/// This function is not implemented
445
447{
448 Error("Divide","Function not implemented for TProfile2D");
449 return kFALSE;
450}
451
452////////////////////////////////////////////////////////////////////////////////
453/// Divide this profile2D by h1.
454///
455/// `this = this/h1`
456///
457///This function return kFALSE if the divide operation failed
458
460{
461
462 if (!h1) {
463 Error("Divide","Attempt to divide a non-existing profile2D");
464 return kFALSE;
465 }
467 Error("Divide","Attempt to divide a non-profile2D object");
468 return kFALSE;
469 }
471
472 // delete buffer if it is there since it will become invalid
473 if (fBuffer) BufferEmpty(1);
474
475 // Check profile compatibility
476 Int_t nx = GetNbinsX();
477 if (nx != p1->GetNbinsX()) {
478 Error("Divide","Attempt to divide profiles with different number of bins");
479 return kFALSE;
480 }
481 Int_t ny = GetNbinsY();
482 if (ny != p1->GetNbinsY()) {
483 Error("Divide","Attempt to divide profiles with different number of bins");
484 return kFALSE;
485 }
486
487 // Reset statistics
489
490 // Loop on bins (including underflows/overflows)
492 Double_t *cu1 = p1->GetW();
493 Double_t *er1 = p1->GetW2();
494 Double_t *en1 = p1->GetB();
495 Double_t c0,c1,w,z,x,y;
496 for (binx =0;binx<=nx+1;binx++) {
497 for (biny =0;biny<=ny+1;biny++) {
498 bin = biny*(fXaxis.GetNbins()+2) + binx;
499 c0 = fArray[bin];
500 c1 = cu1[bin];
501 if (c1) w = c0/c1;
502 else w = 0;
503 fArray[bin] = w;
504 z = TMath::Abs(w);
507 fEntries++;
508 fTsumw += z;
509 fTsumw2 += z*z;
510 fTsumwx += z*x;
511 fTsumwx2 += z*x*x;
512 fTsumwy += z*y;
513 fTsumwy2 += z*y*y;
514 fTsumwxy += z*x*y;
515 fTsumwz += z;
516 fTsumwz2 += z*z;
518 Double_t e1 = er1[bin];
519 Double_t c12= c1*c1;
520 if (!c1) fSumw2.fArray[bin] = 0;
521 else fSumw2.fArray[bin] = (e0*c1*c1 + e1*c0*c0)/(c12*c12);
522 if (!en1[bin]) fBinEntries.fArray[bin] = 0;
523 else fBinEntries.fArray[bin] /= en1[bin];
524 }
525 }
526 // maintaining the correct sum of weights square is not supported when dividing
527 // bin error resulting from division of profile needs to be checked
528 if (fBinSumw2.fN) {
529 Warning("Divide","Cannot preserve during the division of profiles the sum of bin weight square");
530 fBinSumw2 = TArrayD();
531 }
532 return kTRUE;
533}
534
535////////////////////////////////////////////////////////////////////////////////
536/// Replace contents of this profile2D by the division of h1 by h2.
537///
538/// `this = c1*h1/(c2*h2)`
539///
540/// This function return kFALSE if the divide operation failed
541
543{
544 TString opt = option;
545 opt.ToLower();
546 Bool_t binomial = kFALSE;
547 if (opt.Contains("b")) binomial = kTRUE;
548 if (!h1 || !h2) {
549 Error("Divide","Attempt to divide a non-existing profile2D");
550 return kFALSE;
551 }
553 Error("Divide","Attempt to divide a non-profile2D object");
554 return kFALSE;
555 }
557 if (!h2->InheritsFrom(TProfile2D::Class())) {
558 Error("Divide","Attempt to divide a non-profile2D object");
559 return kFALSE;
560 }
561 TProfile2D *p2 = (TProfile2D*)h2;
562
563 // delete buffer if it is there since it will become invalid
564 if (fBuffer) BufferEmpty(1);
565
566 // Check histogram compatibility
567 Int_t nx = GetNbinsX();
568 if (nx != p1->GetNbinsX() || nx != p2->GetNbinsX()) {
569 Error("Divide","Attempt to divide profiles with different number of bins");
570 return kFALSE;
571 }
572 Int_t ny = GetNbinsY();
573 if (ny != p1->GetNbinsY() || ny != p2->GetNbinsY()) {
574 Error("Divide","Attempt to divide profiles with different number of bins");
575 return kFALSE;
576 }
577 if (!c2) {
578 Error("Divide","Coefficient of dividing profile cannot be zero");
579 return kFALSE;
580 }
581
582 // Reset statistics
584
585 // Loop on bins (including underflows/overflows)
587 Double_t *cu1 = p1->GetW();
588 Double_t *cu2 = p2->GetW();
589 Double_t *er1 = p1->GetW2();
590 Double_t *er2 = p2->GetW2();
591 Double_t *en1 = p1->GetB();
592 Double_t *en2 = p2->GetB();
593 Double_t b1,b2,w,z,x,y,ac1,ac2;
594 ac1 = TMath::Abs(c1);
595 ac2 = TMath::Abs(c2);
596 for (binx =0;binx<=nx+1;binx++) {
597 for (biny =0;biny<=ny+1;biny++) {
598 bin = biny*(fXaxis.GetNbins()+2) + binx;
599 b1 = cu1[bin];
600 b2 = cu2[bin];
601 if (b2) w = c1*b1/(c2*b2);
602 else w = 0;
603 fArray[bin] = w;
604 z = TMath::Abs(w);
607 fEntries++;
608 fTsumw += z;
609 fTsumw2 += z*z;
610 fTsumwx += z*x;
611 fTsumwx2 += z*x*x;
612 fTsumwy += z*y;
613 fTsumwy2 += z*y*y;
614 fTsumwxy += z*x*y;
615 fTsumwz += z;
616 fTsumwz2 += z*z;
617 Double_t e1 = er1[bin];
618 Double_t e2 = er2[bin];
619 //Double_t b22= b2*b2*d2;
620 Double_t b22= b2*b2*TMath::Abs(c2);
621 if (!b2) fSumw2.fArray[bin] = 0;
622 else {
623 if (binomial) {
624 fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));
625 } else {
626 fSumw2.fArray[bin] = ac1*ac2*(e1*b2*b2 + e2*b1*b1)/(b22*b22);
627 }
628 }
629 if (!en2[bin]) fBinEntries.fArray[bin] = 0;
630 else fBinEntries.fArray[bin] = en1[bin]/en2[bin];
631 }
632 }
633 return kTRUE;
634}
635
636////////////////////////////////////////////////////////////////////////////////
637/// Fill a Profile2D histogram (no weights).
638
640{
641 if (fBuffer) return BufferFill(x,y,z,1);
642
644
645 if (fZmin != fZmax) {
646 if (z <fZmin || z> fZmax || TMath::IsNaN(z) ) return -1;
647 }
648
649 fEntries++;
652 if (binx <0 || biny <0) return -1;
653 bin = GetBin(binx, biny);
654 fArray[bin] += z;
655 fSumw2.fArray[bin] += z*z;
656 fBinEntries.fArray[bin] += 1;
657 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
658 if (binx == 0 || binx > fXaxis.GetNbins()) {
659 if (!GetStatOverflowsBehaviour()) return -1;
660 }
661 if (biny == 0 || biny > fYaxis.GetNbins()) {
662 if (!GetStatOverflowsBehaviour()) return -1;
663 }
664 ++fTsumw;
665 ++fTsumw2;
666 fTsumwx += x;
667 fTsumwx2 += x*x;
668 fTsumwy += y;
669 fTsumwy2 += y*y;
670 fTsumwxy += x*y;
671 fTsumwz += z;
672 fTsumwz2 += z*z;
673 return bin;
674}
675
676////////////////////////////////////////////////////////////////////////////////
677/// Fill a Profile2D histogram with weights.
678
680{
681 if (fBuffer) return BufferFill(x, y, z, w);
682
683 Int_t bin, binx, biny;
684
685 if (fZmin != fZmax) {
686 if (z < fZmin || z > fZmax || TMath::IsNaN(z)) return -1;
687 }
688
689 Double_t u = w;
690 fEntries++;
691 binx = fXaxis.FindBin(x);
692 biny = fYaxis.FindBin(y);
693 if (binx < 0 || biny < 0) return -1;
694 bin = biny * (fXaxis.GetNbins() + 2) + binx;
695 AddBinContent(bin, u * z);
696 fSumw2.fArray[bin] += u * z * z;
697 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW))
698 Sumw2(); // must be called before accumulating the entries
699 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u * u;
701
702 if (binx == 0 || binx > fXaxis.GetNbins()) {
703 if (!GetStatOverflowsBehaviour()) return -1;
704 }
705 if (biny == 0 || biny > fYaxis.GetNbins()) {
706 if (!GetStatOverflowsBehaviour()) return -1;
707 }
708 fTsumw += u;
709 fTsumw2 += u * u;
710 fTsumwx += u * x;
711 fTsumwx2 += u * x * x;
712 fTsumwy += u * y;
713 fTsumwy2 += u * y * y;
714 fTsumwxy += u * x * y;
715 fTsumwz += u * z;
716 fTsumwz2 += u * z * z;
717 return bin;
718}
719////////////////////////////////////////////////////////////////////////////////
720/// Fill a Profile2D histogram (no weights).
721
723{
725
726 if (fZmin != fZmax) {
727 if (z <fZmin || z> fZmax || TMath::IsNaN(z)) return -1;
728 }
729
730 Double_t u = w;
731 fEntries++;
734 if (binx <0 || biny <0) return -1;
735 bin = biny*(fXaxis.GetNbins()+2) + binx;
736 AddBinContent(bin, u * z);
737 fSumw2.fArray[bin] += u * z * z;
738 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW))
739 Sumw2(); // must be called before accumulating the entries
740 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u * u;
742
743 if (binx == 0 || binx > fXaxis.GetNbins()) {
744 if (!GetStatOverflowsBehaviour()) return -1;
745 }
746 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
747
750
751 fTsumw += u;
752 fTsumw2 += u * u;
753 fTsumwx += u * x;
754 fTsumwx2 += u * x * x;
755 fTsumwy += u * y;
756 fTsumwy2 += u * y * y;
757 fTsumwxy += u * x * y;
758 fTsumwz += u * z;
759 fTsumwz2 += u * z * z;
760
761 return bin;
762}
763
764////////////////////////////////////////////////////////////////////////////////
765/// Fill a Profile2D histogram (no weights).
766
767Int_t TProfile2D::Fill(const char *namex, const char *namey, Double_t z, Double_t w)
768{
770
771 if (fZmin != fZmax) {
772 if (z <fZmin || z> fZmax || TMath::IsNaN(z) ) return -1;
773 }
774
775 Double_t u = w;
776 fEntries++;
779 if (binx < 0 || biny < 0)
780 return -1;
781 bin = biny * (fXaxis.GetNbins() + 2) + binx;
782 AddBinContent(bin, u * z);
783 fSumw2.fArray[bin] += u * z * z;
784 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW))
785 Sumw2(); // must be called before accumulating the entries
786 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u * u;
788
789 if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
790 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
791
795
796 fTsumw += u;
797 fTsumw2 += u * u;
798 fTsumwx += u * x;
799 fTsumwx2 += u * x * x;
800 fTsumwy += u * y;
801 fTsumwy2 += u * y * y;
802 fTsumwxy += u * x * y;
803 fTsumwz += u * z;
804 fTsumwz2 += u * z * z;
805
806 return bin;
807}
808
809////////////////////////////////////////////////////////////////////////////////
810/// Fill a Profile2D histogram (no weights).
811
813{
815
816 if (fZmin != fZmax) {
817 if (z <fZmin || z> fZmax || TMath::IsNaN(z)) return -1;
818 }
819
820 Double_t u = w;
821 fEntries++;
824 if (binx <0 || biny <0) return -1;
825 bin = biny*(fXaxis.GetNbins()+2) + binx;
826
827 AddBinContent(bin, u * z);
828 fSumw2.fArray[bin] += u * z * z;
829 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW))
830 Sumw2(); // must be called before accumulating the entries
831 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u * u;
833
834 if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
835 if (biny == 0 || biny > fYaxis.GetNbins()) {
836 if (!GetStatOverflowsBehaviour()) return -1;
837 }
838
841
842 fTsumw += u;
843 fTsumw2 += u * u;
844 fTsumwx += u * x;
845 fTsumwx2 += u * x * x;
846 fTsumwy += u * y;
847 fTsumwy2 += u * y * y;
848 fTsumwxy += u * x * y;
849 fTsumwz += u * z;
850 fTsumwz2 += u * z * z;
851
852 return bin;
853}
854
855
856
857////////////////////////////////////////////////////////////////////////////////
858/// Return bin content of a Profile2D histogram.
859
861{
862 if (fBuffer) ((TProfile2D*)this)->BufferEmpty();
863
864 if (bin < 0 || bin >= fNcells) return 0;
865 if (fBinEntries.fArray[bin] == 0) return 0;
866 if (!fArray) return 0;
868}
869
870////////////////////////////////////////////////////////////////////////////////
871/// Return bin entries of a Profile2D histogram.
872
874{
875 if (fBuffer) ((TProfile2D*)this)->BufferEmpty();
876
877 if (bin < 0 || bin >= fNcells) return 0;
878 return fBinEntries.fArray[bin];
879}
880
881////////////////////////////////////////////////////////////////////////////////
882/// Return bin effective entries for a weighted filled Profile histogram.
883/// In case of an unweighted profile, it is equivalent to the number of entries per bin
884/// The effective entries is defined as the square of the sum of the weights divided by the
885/// sum of the weights square.
886/// TProfile::Sumw2() must be called before filling the profile with weights.
887/// Only by calling this method the sum of the square of the weights per bin is stored.
888
893
894////////////////////////////////////////////////////////////////////////////////
895/// Return bin error of a Profile2D histogram.
896///
897/// ### Computing errors: A moving field
898///
899/// The computation of errors for a TProfile2D has evolved with the versions
900/// of ROOT. The difficulty is in computing errors for bins with low statistics.
901/// - prior to version 3.10, we had no special treatment of low statistic bins.
902/// As a result, these bins had huge errors. The reason is that the
903/// expression eprim2 is very close to 0 (rounding problems) or 0.
904/// - The algorithm is modified/protected for the case
905/// when a TProfile2D is projected (ProjectionX). The previous algorithm
906/// generated a N^2 problem when projecting a TProfile2D with a large number of
907/// bins (eg 100000).
908/// - in version 3.10/02, a new static function TProfile::Approximate
909/// is introduced to enable or disable (default) the approximation.
910/// (see also comments in TProfile::GetBinError)
911
916
917////////////////////////////////////////////////////////////////////////////////
918/// Return option to compute profile2D errors.
919
921{
922 if (fErrorMode == kERRORSPREAD) return "s";
923 if (fErrorMode == kERRORSPREADI) return "i";
924 if (fErrorMode == kERRORSPREADG) return "g";
925 return "";
926}
927
928////////////////////////////////////////////////////////////////////////////////
929/// Fill the array stats from the contents of this profile.
930/// The array stats must be correctly dimensioned in the calling program.
931///
932/// - stats[0] = sumw
933/// - stats[1] = sumw2
934/// - stats[2] = sumwx
935/// - stats[3] = sumwx2
936/// - stats[4] = sumwy
937/// - stats[5] = sumwy2
938/// - stats[6] = sumwxy
939/// - stats[7] = sumwz
940/// - stats[8] = sumwz2
941///
942/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
943/// is simply a copy of the statistics quantities computed at filling time.
944/// If a sub-range is specified, the function recomputes these quantities
945/// from the bin contents in the current axis range.
946
948{
949 if (fBuffer) ((TProfile2D*)this)->BufferEmpty();
950
951 // check for labels axis . In that case corresponding statistics do not make sense and it is set to zero
952 Bool_t labelXaxis = ((const_cast<TAxis&>(fXaxis)).GetLabels() && fXaxis.CanExtend() );
953 Bool_t labelYaxis = ((const_cast<TAxis&>(fYaxis)).GetLabels() && fYaxis.CanExtend() );
954
955 // Loop on bins
956 if ( (fTsumw == 0 /* && fEntries > 0 */) || fXaxis.TestBit(TAxis::kAxisRange) || fYaxis.TestBit(TAxis::kAxisRange)) {
957 Int_t bin, binx, biny;
958 Double_t w, w2;
959 Double_t x,y;
960 for (bin=0;bin<9;bin++) stats[bin] = 0;
961 if (!fBinEntries.fArray) return;
966 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
969 if (firstBinX == 1) firstBinX = 0;
970 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
971 }
973 if (firstBinY == 1) firstBinY = 0;
974 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
975 }
976 }
977 for (biny = firstBinY; biny <= lastBinY; biny++) {
978 y = (!labelYaxis) ? fYaxis.GetBinCenter(biny) : 0;
979 for (binx = firstBinX; binx <= lastBinX; binx++) {
980 bin = GetBin(binx,biny);
982 w2 = (fBinSumw2.fN ? fBinSumw2.fArray[bin] : w );
983 x = (!labelXaxis) ? fXaxis.GetBinCenter(binx) : 0;
984 stats[0] += w;
985 stats[1] += w2;
986 stats[2] += w*x;
987 stats[3] += w*x*x;
988 stats[4] += w*y;
989 stats[5] += w*y*y;
990 stats[6] += w*x*y;
991 stats[7] += fArray[bin];
992 stats[8] += fSumw2.fArray[bin];
993 }
994 }
995 } else {
996 stats[0] = fTsumw;
997 stats[1] = fTsumw2;
998 stats[2] = fTsumwx;
999 stats[3] = fTsumwx2;
1000 stats[4] = fTsumwy;
1001 stats[5] = fTsumwy2;
1002 stats[6] = fTsumwxy;
1003 stats[7] = fTsumwz;
1004 stats[8] = fTsumwz2;
1005 }
1006}
1007
1008////////////////////////////////////////////////////////////////////////////////
1009/// Reduce the number of bins for this axis to the number of bins having a label.
1010
1015
1016////////////////////////////////////////////////////////////////////////////////
1017/// Double the number of bins for axis.
1018/// Refill histogram
1019/// This function is called by TAxis::FindBin(const char *label)
1020
1025
1026////////////////////////////////////////////////////////////////////////////////
1027/// Set option(s) to draw axis with labels.
1028///
1029/// option might have the following values:
1030///
1031/// - "a" sort by alphabetic order
1032/// - ">" sort by decreasing values
1033/// - "<" sort by increasing values
1034/// - "h" draw labels horizontal
1035/// - "v" draw labels vertical
1036/// - "u" draw labels up (end of label right adjusted)
1037/// - "d" draw labels down (start of label left adjusted)
1038
1040{
1041
1042 TAxis *axis = GetXaxis();
1043 if (ax[0] == 'y' || ax[0] == 'Y') axis = GetYaxis();
1044 THashList *labels = axis->GetLabels();
1045 if (!labels) {
1046 Warning("LabelsOption","Cannot sort. No labels");
1047 return;
1048 }
1049 TString opt = option;
1050 opt.ToLower();
1051 if (opt.Contains("h")) {
1056 }
1057 if (opt.Contains("v")) {
1062 }
1063 if (opt.Contains("u")) {
1064 axis->SetBit(TAxis::kLabelsUp);
1068 }
1069 if (opt.Contains("d")) {
1074 }
1075 Int_t sort = -1;
1076 if (opt.Contains("a")) sort = 0;
1077 if (opt.Contains(">")) sort = 1;
1078 if (opt.Contains("<")) sort = 2;
1079 if (sort < 0) return;
1080
1081 // support only cases where each bin has a labels (should be when axis is alphanumeric)
1082 Int_t n = labels->GetSize();
1083 if (n != axis->GetNbins()) {
1084 // check if labels are all consecutive and starts from the first bin
1085 // in that case the current code will work fine
1086 Int_t firstLabelBin = axis->GetNbins() + 1;
1087 Int_t lastLabelBin = -1;
1088 for (Int_t i = 0; i < n; ++i) {
1089 Int_t bin = labels->At(i)->GetUniqueID();
1090 if (bin < firstLabelBin)
1092 if (bin > lastLabelBin)
1093 lastLabelBin = bin;
1094 }
1095 if (firstLabelBin != 1 || lastLabelBin - firstLabelBin + 1 != n) {
1096 Error("LabelsOption",
1097 "%s of TProfile2D %s contains bins without labels. Sorting will not work correctly - return",
1098 axis->GetName(), GetName());
1099 return;
1100 }
1101 // case where label bins are consecutive starting from first bin will work
1102 Warning(
1103 "LabelsOption",
1104 "axis %s of TProfile2D %s has extra following bins without labels. Sorting will work only for first label bins",
1105 axis->GetName(), GetName());
1106 }
1107
1108 std::vector<Int_t> a(n);
1109 Int_t i, j, k, ibin, bin;
1110 std::vector<Double_t> sumw(fNcells);
1111 std::vector<Double_t> errors(fNcells);
1112 std::vector<Double_t> ent(fNcells);
1113 std::vector<Double_t> binsw2;
1114 if (fBinSumw2.fN)
1115 binsw2.resize(fNcells);
1116
1117 // delete buffer if it is there since bins will be reordered.
1118 if (fBuffer)
1119 BufferEmpty(1);
1120
1121 // number of bins to loop
1122 Int_t nx = (axis == GetXaxis()) ? n + 1 : fXaxis.GetNbins() + 2;
1123 Int_t ny = (axis == GetYaxis()) ? n + 1 : fYaxis.GetNbins() + 2;
1124
1125 // make a labelold list but ordered with bins
1126 // (re-ordered original label list)
1127 std::vector<TObject *> labold(n);
1128 for (i = 0; i < n; i++)
1129 labold[i] = nullptr;
1130 TIter nextold(labels);
1131 TObject *obj;
1132 while ((obj = nextold())) {
1133 bin = obj->GetUniqueID();
1134 if (bin>=1 && bin<=n)
1135 labold[bin-1] = obj;
1136 }
1137 // order now labold according to bin content
1138
1139 labels->Clear();
1140
1141 std::vector<Double_t> pcont;
1142 std::vector<Double_t> econt;
1143 if (sort > 0) {
1144 pcont.resize(n);
1145 econt.resize(n);
1146 }
1147
1148 for (i = 0; i < nx; i++) {
1149 for (j = 0; j < ny; j++) {
1150 bin = GetBin(i, j);
1151 sumw[bin] = fArray[bin];
1154 if (fBinSumw2.fN)
1156 if (axis == GetXaxis())
1157 k = i - 1;
1158 else
1159 k = j - 1;
1160 //---when sorting by values of bins
1161 if (sort > 0 && fBinEntries.fArray[bin] != 0 && k > 0 && k < n) {
1162 pcont[k] += fArray[bin];
1163 econt[k] += fBinEntries.fArray[bin];
1164 }
1165 }
1166 }
1167 // compute average of slize for ordering
1168 if (sort > 0) {
1169 for (k = 0; k < n; ++k) {
1170 a[k] = k;
1171 if (econt[k] > 0)
1172 pcont[k] /= econt[k];
1173 }
1174 if (sort == 1)
1175 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
1176 else
1177 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
1178 } else {
1179 //---alphabetic sort
1180 // sort labels using vector of strings and TMath::Sort
1181 // I need to array because labels order in list is not necessary that of the bins
1182 std::vector<std::string> vecLabels(n);
1183 for (i = 0; i < n; i++) {
1184 vecLabels[i] = labold[i]->GetName();
1185 a[i] = i;
1186 }
1187 // sort in ascending order for strings
1188 TMath::Sort(n, vecLabels.data(), a.data(), kFALSE);
1189 }
1190
1191 // set the new labels
1192 for (i = 0; i < n; i++) {
1193 obj = labold[a[i]];
1194 labels->Add(obj);
1195 // set the corresponding bin. NB bin starts from 1
1196 obj->SetUniqueID(i + 1);
1197 if (gDebug)
1198 std::cout << "bin " << i + 1 << " setting new labels for axis " << labold.at(a[i])->GetName() << " from "
1199 << a[i] << std::endl;
1200 }
1201 // set the new content
1202 for (i = 0; i < nx; i++) {
1203 for (j = 0; j < ny; j++) {
1204 bin = GetBin(i, j);
1205 if (axis == GetXaxis()) {
1206 if (i == 0) break; // skip underflow in x
1207 ibin = GetBin(a[i - 1] + 1, j);
1208 } else {
1209 if (j == 0) continue; // skip underflow in y
1210 ibin = GetBin(i, a[j-1] + 1);
1211 }
1212 fArray[bin] = sumw[ibin];
1215 if (fBinSumw2.fN)
1217 }
1218 }
1219 // need to set to zero the statistics if axis has been sorted
1220 // see for example TH3::PutStats for definition of s vector
1221 bool labelsAreSorted = kFALSE;
1222 for (i = 0; i < n; ++i) {
1223 if (a[i] != i) {
1225 break;
1226 }
1227 }
1228 if (labelsAreSorted) {
1229 double s[TH1::kNstat];
1230 GetStats(s);
1231 if (axis == GetXaxis()) {
1232 s[2] = 0; // fTsumwx
1233 s[3] = 0; // fTsumwx2
1234 s[6] = 0; // fTsumwxy
1235 } else {
1236 s[4] = 0; // fTsumwy
1237 s[5] = 0; // fTsumwy2
1238 s[6] = 0; // fTsumwxy
1239 }
1240 PutStats(s);
1241 }
1242}
1243
1244////////////////////////////////////////////////////////////////////////////////
1245/// Merge all histograms in the collection in this histogram.
1246/// This function computes the min/max for the axes,
1247/// compute a new number of bins, if necessary,
1248/// add bin contents, errors and statistics.
1249/// If overflows are present and limits are different the function will fail.
1250/// The function returns the total number of entries in the result histogram
1251/// if the merge is successful, -1 otherwise.
1252///
1253/// IMPORTANT remark. The 2 axis x and y may have different number
1254/// of bins and different limits, BUT the largest bin width must be
1255/// a multiple of the smallest bin width and the upper limit must also
1256/// be a multiple of the bin width.
1257
1262
1263////////////////////////////////////////////////////////////////////////////////
1264/// Performs the operation: this = this*c1*f1
1265
1267{
1268 Error("Multiply","Function not implemented for TProfile2D");
1269 return kFALSE;
1270}
1271
1272////////////////////////////////////////////////////////////////////////////////
1273/// Multiply this profile2D by h1.
1274///
1275/// `this = this*h1`
1276
1278{
1279 Error("Multiply","Multiplication of profile2D histograms not implemented");
1280 return kFALSE;
1281}
1282
1283////////////////////////////////////////////////////////////////////////////////
1284/// Replace contents of this profile2D by multiplication of h1 by h2.
1285///
1286/// `this = (c1*h1)*(c2*h2)`
1287
1289{
1290 Error("Multiply","Multiplication of profile2D histograms not implemented");
1291 return kFALSE;
1292}
1293
1294////////////////////////////////////////////////////////////////////////////////
1295/// Project this profile2D into a 2-D histogram along X,Y.
1296///
1297/// The projection is always of the type TH2D.
1298///
1299/// - if option "E" is specified the errors of the projected histogram are computed and set
1300/// to be equal to the errors of the profile.
1301/// Option "E" is defined as the default one in the header file.
1302/// - if option "" is specified the histogram errors are simply the sqrt of its content
1303/// - if option "B" is specified, the content of bin of the returned histogram
1304/// will be equal to the GetBinEntries(bin) of the profile,
1305/// - if option "C=E" the bin contents of the projection are set to the
1306/// bin errors of the profile
1307/// - if option "W" is specified the bin content of the projected histogram is set to the
1308/// product of the bin content of the profile and the entries.
1309/// With this option the returned histogram will be equivalent to the one obtained by
1310/// filling directly a TH2D using the 3-rd value as a weight.
1311/// This option makes sense only for profile filled with all weights =1.
1312/// When the profile is weighted (filled with weights different than 1) the
1313/// bin error of the projected histogram (obtained using this option "W") cannot be
1314/// correctly computed from the information stored in the profile. In that case the
1315/// obtained histogram contains as bin error square the weighted sum of the square of the
1316/// profiled observable (TProfile2D::fSumw2[bin] )
1317
1319{
1320
1321 TString opt = option;
1322 opt.ToLower();
1323
1324 // Create the projection histogram
1325 // name of projected histogram is by default name of original histogram + _pxy
1327 if (pname.IsNull() || pname == "_pxy")
1328 pname = TString(GetName() ) + TString("_pxy");
1329
1330
1331 Int_t nx = fXaxis.GetNbins();
1332 Int_t ny = fYaxis.GetNbins();
1333 const TArrayD *xbins = fXaxis.GetXbins();
1334 const TArrayD *ybins = fYaxis.GetXbins();
1335 TH2D * h1 = nullptr;
1336 if (xbins->fN == 0 && ybins->fN == 0) {
1338 } else if (xbins->fN == 0) {
1339 h1 = new TH2D(pname,GetTitle(),nx,fXaxis.GetXmin(),fXaxis.GetXmax(),ny, ybins->GetArray() );
1340 } else if (ybins->fN == 0) {
1341 h1 = new TH2D(pname,GetTitle(),nx,xbins->GetArray(),ny,fYaxis.GetXmin(),fYaxis.GetXmax());
1342 } else {
1343 h1 = new TH2D(pname,GetTitle(),nx,xbins->GetArray(),ny,ybins->GetArray() );
1344 }
1345 fXaxis.Copy(*h1->GetXaxis());
1346 fYaxis.Copy(*h1->GetYaxis());
1351 if (opt.Contains("b")) binEntries = kTRUE;
1352 if (opt.Contains("e")) computeErrors = kTRUE;
1353 if (opt.Contains("w")) binWeight = kTRUE;
1354 if (opt.Contains("c=e")) {cequalErrors = kTRUE; computeErrors=kFALSE;}
1356
1357 // Fill the projected histogram
1358 Int_t bin,binx, biny;
1359 Double_t cont;
1360 for (binx =0;binx<=nx+1;binx++) {
1361 for (biny =0;biny<=ny+1;biny++) {
1362 bin = GetBin(binx,biny);
1363
1365 else if (cequalErrors) cont = GetBinError(bin);
1367 else cont = GetBinContent(bin); // default case
1368
1370
1371 // if option E projected histogram errors are same as profile
1373 // in case of option W bin error is deduced from bin sum of z**2 values of profile
1374 // this is correct only if the profile is unweighted
1375 if (binWeight) h1->GetSumw2()->fArray[bin] = fSumw2.fArray[bin];
1376 // in case of bin entries and profile is weighted, we need to set also the bin error
1377 if (binEntries && fBinSumw2.fN ) {
1378 R__ASSERT( h1->GetSumw2() );
1379 h1->GetSumw2()->fArray[bin] = fBinSumw2.fArray[bin];
1380 }
1381 }
1382 }
1384 return h1;
1385}
1386
1387////////////////////////////////////////////////////////////////////////////////
1388/// Project a 2-D histogram into a profile histogram along X.
1389///
1390/// The projection is made from the channels along the Y axis
1391/// ranging from firstybin to lastybin included.
1392/// The result is a 1D profile which contains the combination of all the considered bins along Y
1393/// By default, bins 1 to ny are included
1394/// When all bins are included, the number of entries in the projection
1395/// is set to the number of entries of the 2-D histogram, otherwise
1396/// the number of entries is incremented by 1 for all non empty cells.
1397///
1398/// The option can also be used to specify the projected profile error type.
1399/// Values which can be used are 's', 'i', or 'g'. See TProfile::BuildOptions for details
1400
1405
1406////////////////////////////////////////////////////////////////////////////////
1407/// Project a 2-D histogram into a profile histogram along X
1408///
1409/// The projection is made from the channels along the X axis
1410/// ranging from firstybin to lastybin included.
1411/// The result is a 1D profile which contains the combination of all the considered bins along X
1412/// By default, bins 1 to ny are included
1413/// When all bins are included, the number of entries in the projection
1414/// is set to the number of entries of the 2-D histogram, otherwise
1415/// the number of entries is incremented by 1 for all non empty cells.
1416///
1417/// The option can also be used to specify the projected profile error type.
1418/// Values which can be used are 's', 'i', or 'g'. See TProfile::BuildOptions for details
1419
1424
1425////////////////////////////////////////////////////////////////////////////////
1426/// Implementation of ProfileX or ProfileY for a TProfile2D.
1427///
1428/// Do correctly the combination of the bin averages when doing the projection
1429
1431 TString opt = option;
1432 opt.ToLower();
1433 bool originalRange = opt.Contains("o");
1434
1435 TString expectedName = ( onX ? "_pfx" : "_pfy" );
1436
1438 if (pname.IsNull() || name == expectedName)
1440
1441 const TAxis& outAxis = ( onX ? fXaxis : fYaxis );
1442 const TArrayD *bins = outAxis.GetXbins();
1443 Int_t firstOutBin = outAxis.GetFirst();
1444 Int_t lastOutBin = outAxis.GetLast();
1445
1446 TProfile * p1 = nullptr;
1447 // case of fixed bins
1448 if (bins->fN == 0) {
1449 if (originalRange)
1450 p1 = new TProfile(pname,GetTitle(), outAxis.GetNbins(), outAxis.GetXmin(), outAxis.GetXmax(), opt );
1451 else
1453 outAxis.GetBinLowEdge(firstOutBin),outAxis.GetBinUpEdge(lastOutBin), opt);
1454 } else {
1455 // case of variable bins
1456 if (originalRange )
1457 p1 = new TProfile(pname,GetTitle(),outAxis.GetNbins(),bins->fArray,opt);
1458 else
1460
1461 }
1462
1463 if (fBinSumw2.fN) p1->Sumw2();
1464
1465 // make projection in a 2D first
1466 TH2D * h2dW = ProjectionXY("h2temp-W","W");
1467 TH2D * h2dN = ProjectionXY("h2temp-N","B");
1468
1469 h2dW->SetDirectory(nullptr); h2dN->SetDirectory(nullptr);
1470
1471
1472 TString opt1 = (originalRange) ? "o" : "";
1473 TH1D * h1W = (onX) ? h2dW->ProjectionX("h1temp-W",firstbin,lastbin,opt1) : h2dW->ProjectionY("h1temp-W",firstbin,lastbin,opt1);
1474 TH1D * h1N = (onX) ? h2dN->ProjectionX("h1temp-N",firstbin,lastbin,opt1) : h2dN->ProjectionY("h1temp-N",firstbin,lastbin,opt1);
1475 h1W->SetDirectory(nullptr); h1N->SetDirectory(nullptr);
1476
1477
1478 // fill the bin content
1479 R__ASSERT( h1W->fN == p1->fN );
1480 R__ASSERT( h1N->fN == p1->fN );
1481 R__ASSERT( h1W->GetSumw2()->fN != 0); // h1W should always be a weighted histogram since h2dW is
1482 for (int i = 0; i < p1->fN ; ++i) {
1483 p1->fArray[i] = h1W->GetBinContent(i); // array of profile is sum of all values
1484 p1->GetSumw2()->fArray[i] = h1W->GetSumw2()->fArray[i]; // array of content square of profile is weight square of the W projected histogram
1485 p1->SetBinEntries(i, h1N->GetBinContent(i) );
1486 if (fBinSumw2.fN) p1->GetBinSumw2()->fArray[i] = h1N->GetSumw2()->fArray[i]; // sum of weight squares are stored to compute errors in h1N histogram
1487 }
1488 // delete the created histograms
1489 delete h2dW;
1490 delete h2dN;
1491 delete h1W;
1492 delete h1N;
1493
1494 // Also we need to set the entries since they have not been correctly calculated during the projection
1495 // we can only set them to the effective entries
1496 p1->SetEntries( p1->GetEffectiveEntries() );
1497
1498 return p1;
1499}
1500
1501
1502////////////////////////////////////////////////////////////////////////////////
1503/// Replace current statistics with the values in array stats
1504
1506{
1507 fTsumw = stats[0];
1508 fTsumw2 = stats[1];
1509 fTsumwx = stats[2];
1510 fTsumwx2 = stats[3];
1511 fTsumwy = stats[4];
1512 fTsumwy2 = stats[5];
1513 fTsumwxy = stats[6];
1514 fTsumwz = stats[7];
1515 fTsumwz2 = stats[8];
1516}
1517
1518////////////////////////////////////////////////////////////////////////////////
1519/// Reset contents of a Profile2D histogram.
1520
1522{
1525 fBinSumw2.Reset();
1526 TString opt = option;
1527 opt.ToUpper();
1528 if (opt.Contains("ICE") && !opt.Contains("S")) return;
1529 fTsumwz = fTsumwz2 = 0;
1530}
1531
1532
1533////////////////////////////////////////////////////////////////////////////////
1534/// Profile histogram is resized along axis such that x is in the axis range.
1535///
1536/// The new axis limits are recomputed by doubling iteratively
1537/// the current axis range until the specified value x is within the limits.
1538/// The algorithm makes a copy of the histogram, then loops on all bins
1539/// of the old histogram to fill the extended histogram.
1540/// Takes into account errors (Sumw2) if any.
1541/// The axis must be extendable before invoking this function.
1542///
1543/// Ex: `h->GetXaxis()->SetCanExtend(kTRUE)`
1544
1546{
1548 if ( hold ) {
1549 fTsumwz = hold->fTsumwz;
1550 fTsumwz2 = hold->fTsumwz2;
1551 delete hold;
1552 }
1553}
1554
1555////////////////////////////////////////////////////////////////////////////////
1556/// Rebin this histogram grouping nxgroup/nygroup bins along the xaxis/yaxis together.
1557///
1558/// ## case 1 `xbins`=0 || `ybins`=0
1559///
1560/// if `newname` is not blank a new profile hnew is created.
1561/// else the current histogram is modified (default)
1562/// The parameters `nxgroup`/`nygroup` indicate how many bins along the xaxis/yaxis of this
1563/// have to be merged into one bin of hnew
1564/// If the original profile has errors stored (via Sumw2), the resulting
1565/// profile has new errors correctly calculated.
1566///
1567/// examples: if hpxpy is an existing TProfile2D profile with 40 x 40 bins
1568/// ~~~ {.cpp}
1569/// hpxpy->Rebin2D(); // merges two bins along the xaxis and yaxis in one
1570/// // Carefull: previous contents of hpxpy are lost
1571/// hpxpy->Rebin2D(3,5); // merges 3 bins along the xaxis and 5 bins along the yaxis in one
1572/// // Carefull: previous contents of hpxpy are lost
1573/// hpxpy->RebinX(5); //merges five bins along the xaxis in one in hpxpy
1574/// TProfile2D *hnew = hpxpy->RebinY(5,"hnew"); // creates a new profile hnew
1575/// // merging 5 bins of hpxpy along the yaxis in one bin
1576/// ~~~
1577///
1578/// \note If `nxgroup`/`nygroup` is not an exact divider of the number of bins,
1579/// along the xaxis/yaxis the top limit(s) of the rebinned profile
1580/// is changed to the upper edge of the xbin=newxbins*nxgroup resp.
1581/// ybin=newybins*nygroup and the remaining bins are added to
1582/// the overflow bin.
1583/// Statistics will be recomputed from the new bin contents.
1584///
1585/// ## case 2 `xbins`!=0 || `ybins`!=0
1586///
1587/// A new profile is created and `newname` must be specified.
1588/// For an axis with a non-null bin-edges array, `nxgroup` (`nygroup`) is the
1589/// number of bins of the new x-axis (y-axis) and `xbins` (`ybins`) must hold
1590/// the `nxgroup+1` (`nygroup+1`) edges of the new bins. An axis without an
1591/// array is rebinned in constant groups as in case 1.
1592/// The data of each old bin are added to the new bin containing its center;
1593/// old bins outside the range of the new axes end up in the under-/overflow
1594/// bins.
1595///
1596/// \note The new bin edges should line up with old bin edges: the entries of
1597/// an old bin that is split between two new bins are all transferred to the
1598/// bin containing the old bin center, and a warning is emitted.
1599///
1600/// example: rebinning a TProfile2D with 100 x 100 bins into 24 x 24 variable bins
1601/// ~~~ {.cpp}
1602/// Double_t xbins[25] = {...}; // low-edges plus upper edge of last bin
1603/// Double_t ybins[25] = {...};
1604/// TProfile2D *hpnew = hp->Rebin2D(24, 24, "hpnew", xbins, ybins);
1605/// ~~~
1606
1607TProfile2D *
1609{
1610 //something to do?
1611 if ((nxgroup == 1) && (nygroup == 1) && !xbins && !ybins) {
1612 if (newname && (strlen(newname) > 0))
1613 return (TProfile2D *)Clone(newname);
1614 else
1615 return this;
1616 }
1617
1618 if ((!newname || strlen(newname) == 0) && (xbins || ybins)) {
1619 Error("Rebin2D", "if xbins or ybins are specified, newname must be given");
1620 return nullptr;
1621 }
1622
1623 const Int_t nxbins = fXaxis.GetNbins();
1624 const Int_t nybins = fYaxis.GetNbins();
1625
1626 // validate the parameters and define the axes of the rebinned profile and
1627 // the mapping of old to new bins
1629 if (!ROOT::Internal::SetupRebinnedAxis(fXaxis, nxgroup, xbins, 'x', *this, "Rebin2D", infoX) ||
1630 !ROOT::Internal::SetupRebinnedAxis(fYaxis, nygroup, ybins, 'y', *this, "Rebin2D", infoY)) {
1631 return nullptr;
1632 }
1633 const Int_t newxbins = infoX.nNewBins;
1634 const Int_t newybins = infoY.nNewBins;
1635
1636 // save old bin contents in new arrays
1637 const Int_t ncells = (nxbins + 2) * (nybins + 2);
1638 std::vector<Double_t> oldBins(GetW(), GetW() + ncells);
1639 std::vector<Double_t> oldErrors(GetW2(), GetW2() + ncells);
1640 std::vector<Double_t> oldCount(GetB(), GetB() + ncells);
1641 std::vector<Double_t> oldBinw2;
1642 if (fBinSumw2.fN)
1643 oldBinw2.assign(GetB2(), GetB2() + ncells);
1644
1645 // rebinning will not redistribute under-/overflow content into the range
1646 // of new axes that extend beyond the old ones
1648 *this, "Rebin2D");
1650 *this, "Rebin2D");
1651
1652 // create a clone of the old profile if newname is specified (guaranteed
1653 // when bin edges are passed)
1654 TProfile2D *hnew = this;
1655 if (newname && strlen(newname) > 0) {
1657 }
1658
1659 // when the group count does not divide the old bin count, the top bins
1660 // move to the overflow and the stats must be recomputed
1661 if (infoX.truncated || infoY.truncated)
1662 hnew->fTsumw = 0;
1663
1664 // rebin the axes
1666
1667 // merge bins: add the content of each old cell (including under- and
1668 // overflow) to the new cell that contains its bin center
1669 const Int_t newncells = (newxbins + 2) * (newybins + 2);
1670 Double_t *cu2 = hnew->GetW();
1671 Double_t *er2 = hnew->GetW2();
1672 Double_t *en2 = hnew->GetB();
1673 std::fill(cu2, cu2 + newncells, 0.);
1674 std::fill(er2, er2 + newncells, 0.);
1675 std::fill(en2, en2 + newncells, 0.);
1676 if (fBinSumw2.fN) {
1677 Double_t *ew2 = hnew->GetB2();
1678 std::fill(ew2, ew2 + newncells, 0.);
1680 nxbins, nybins, newxbins, infoX.binMap, infoY.binMap,
1681 {{oldBins.data(), cu2}, {oldErrors.data(), er2}, {oldCount.data(), en2}, {oldBinw2.data(), ew2}});
1682 } else {
1684 {{oldBins.data(), cu2}, {oldErrors.data(), er2}, {oldCount.data(), en2}});
1685 }
1686
1687 return hnew;
1688}
1689
1690////////////////////////////////////////////////////////////////////////////////
1691/// Rebin only the X axis.
1692/// see Rebin2D
1693
1695 return Rebin2D(ngroup,1,newname);
1696}
1697
1698////////////////////////////////////////////////////////////////////////////////
1699/// Rebin only the Y axis.
1700/// see Rebin2D
1701
1703 return Rebin2D(1,ngroup,newname);
1704}
1705
1706////////////////////////////////////////////////////////////////////////////////
1707/// Save primitive as a C++ statement(s) on output stream out.
1708
1709void TProfile2D::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1710{
1712
1714
1715 out << " \n";
1716
1717 // Check if the profile has equidistant X bins or not. If not, we
1718 // create an array holding the bins.
1719 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray)
1720 sxaxis = SavePrimitiveVector(out, hname + "_x", GetXaxis()->GetXbins()->fN, GetXaxis()->GetXbins()->fArray);
1721
1722 // Check if the profile has equidistant y bins or not. If not, we
1723 // create an array holding the bins.
1724 if (GetYaxis()->GetXbins()->fN && GetYaxis()->GetXbins()->fArray)
1725 syaxis = SavePrimitiveVector(out, hname + "_y", GetYaxis()->GetXbins()->fN, GetYaxis()->GetXbins()->fArray);
1726
1727 out << " " << ClassName() << " *" << hname << " = new " << ClassName() << "(\"" << TString(GetName()).ReplaceSpecialCppChars() << "\", \""
1728 << TString(GetTitle()).ReplaceSpecialCppChars() << "\", " << GetXaxis()->GetNbins() << ", ";
1729 if (!sxaxis.IsNull())
1730 out << sxaxis << ".data()";
1731 else
1732 out << GetXaxis()->GetXmin() << ", " << GetXaxis()->GetXmax();
1733
1734 out << ", " << GetYaxis()->GetNbins() << ", ";
1735 if (!syaxis.IsNull())
1736 out << syaxis << ".data()";
1737 else
1738 out << GetYaxis()->GetXmin() << ", " << GetYaxis()->GetXmax();
1739
1740 if (sxaxis.IsNull() && syaxis.IsNull())
1741 out << ", " << fZmin << ", " << fZmax;
1742
1743 out << ", \"" << TString(GetErrorOption()).ReplaceSpecialCppChars() << "\");\n";
1744
1746 Int_t numentries = 0, numcontent = 0, numerrors = 0;
1747
1748 std::vector<Double_t> entries(fNcells), content(fNcells), errors(save_errors ? fNcells : 0);
1749 for (Int_t bin = 0; bin < fNcells; bin++) {
1751 if (entries[bin])
1752 numentries++;
1753 content[bin] = fArray[bin];
1754 if (content[bin])
1755 numcontent++;
1756 if (save_errors) {
1758 if (errors[bin])
1759 numerrors++;
1760 }
1761 }
1762
1763 if ((numentries < 100) && (numcontent < 100) && (numerrors < 100)) {
1764 // in case of few non-empty bins store them as before
1765 for (Int_t bin = 0; bin < fNcells; bin++) {
1766 if (entries[bin])
1767 out << " " << hname << "->SetBinEntries(" << bin << "," << entries[bin] << ");\n";
1768 }
1769 for (Int_t bin = 0; bin < fNcells; bin++) {
1770 if (content[bin])
1771 out << " " << hname << "->SetBinContent(" << bin << "," << content[bin] << ");\n";
1772 }
1773 if (save_errors)
1774 for (Int_t bin = 0; bin < fNcells; bin++) {
1775 if (errors[bin])
1776 out << " " << hname << "->SetBinError(" << bin << "," << errors[bin] << ");\n";
1777 }
1778 } else {
1779 if (numentries > 0) {
1781 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
1782 out << " if (" << vect << "[bin])\n";
1783 out << " " << hname << "->SetBinEntries(bin, " << vect << "[bin]);\n";
1784 }
1785 if (numcontent > 0) {
1787 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
1788 out << " if (" << vect << "[bin])\n";
1789 out << " " << hname << "->SetBinContent(bin, " << vect << "[bin]);\n";
1790 }
1791 if (numerrors > 0) {
1793 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
1794 out << " if (" << vect << "[bin])\n";
1795 out << " " << hname << "->SetBinError(bin, " << vect << "[bin]);\n";
1796 }
1797 }
1798
1800}
1801
1802////////////////////////////////////////////////////////////////////////////////
1803/// Multiply this profile2D by a constant c1.
1804///
1805/// `this = c1*this
1806///
1807/// This function uses the services of TProfile2D::Add
1808
1813
1814////////////////////////////////////////////////////////////////////////////////
1815/// Set the number of entries in bin.
1816
1821
1822////////////////////////////////////////////////////////////////////////////////
1823/// Redefine x and y axis parameters.
1824
1831
1832////////////////////////////////////////////////////////////////////////////////
1833/// Redefine x and y axis parameters for variable bin sizes.
1834
1841
1842////////////////////////////////////////////////////////////////////////////////
1843/// Set total number of bins including under/overflow.
1844/// Reallocate bin contents array
1845
1851
1852////////////////////////////////////////////////////////////////////////////////
1853/// Set the buffer size in units of 8 bytes (double).
1854
1856{
1857 if (fBuffer) {
1858 BufferEmpty();
1859 delete [] fBuffer;
1860 fBuffer = nullptr;
1861 }
1862 if (bufsize <= 0) {
1863 fBufferSize = 0;
1864 return;
1865 }
1866 if (bufsize < 100) bufsize = 100;
1867 fBufferSize = 1 + 4*bufsize;
1870}
1871
1872////////////////////////////////////////////////////////////////////////////////
1873/// Set option to compute profile2D errors.
1874///
1875/// The computation of the bin errors is based on the parameter option:
1876/// - ' ' (Default) The bin errors are the standard error on the mean of the bin profiled values (Z),
1877/// i.e. the standard error of the bin contents.
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/// - 's' The bin errors are the standard deviations of the Z bin values
1881/// Note that if TProfile::Approximate() is called, an approximation is used when
1882/// the spread in Z is 0 and the number of bin entries is > 0
1883/// - 'i' Errors are as in default case (standard errors of the bin contents)
1884/// The only difference is for the case when the spread in Z is zero.
1885/// In this case for N > 0 the error is 1./SQRT(12.*N)
1886/// - 'g' Errors are 1./SQRT(W) for W not equal to 0 and 0 for W = 0.
1887/// W is the sum in the bin of the weights of the profile.
1888/// This option is for combining measurements z +/- dz,
1889/// and the profile is filled with values y and weights z = 1/dz**2
1890///
1891/// See TProfile::BuildOptions for a detailed explanation of all options
1892
1897
1898////////////////////////////////////////////////////////////////////////////////
1899/// Stream an object of class TProfile2D.
1900
1902{
1903 if (R__b.IsReading()) {
1904 UInt_t R__s, R__c;
1905 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1906 if (R__v > 2) {
1907 R__b.ReadClassBuffer(TProfile2D::Class(), this, R__v, R__s, R__c);
1908 return;
1909 }
1910 //====process old versions before automatic schema evolution
1914 R__b >> errorMode;
1916 if (R__v < 2) {
1917 Float_t zmin,zmax;
1918 R__b >> zmin; fZmin = zmin;
1919 R__b >> zmax; fZmax = zmax;
1920 } else {
1921 R__b >> fZmin;
1922 R__b >> fZmax;
1923 }
1924 R__b.CheckByteCount(R__s, R__c, TProfile2D::IsA());
1925 //====end of old versions
1926
1927 } else {
1928 R__b.WriteClassBuffer(TProfile2D::Class(),this);
1929 }
1930}
1931
1932////////////////////////////////////////////////////////////////////////////////
1933/// Create/Delete structure to store sum of squares of weights per bin.
1934///
1935/// This is needed to compute the correct statistical quantities
1936/// of a profile filled with weights
1937///
1938/// This function is automatically called when the histogram is created
1939/// if the static function TH1::SetDefaultSumw2 has been called before.
1940/// If flag is false the structure is deleted
1941
#define a(i)
Definition RSha256.hxx:99
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:78
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
short Version_t
Class version identifier (short)
Definition RtypesCore.h:80
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:72
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:130
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Definition TError.cxx:267
Option_t Option_t option
char name[80]
Definition TGX11.cxx:142
float xmin
float ymin
float xmax
float ymax
EErrorType
Definition TProfile.h:28
@ kERRORSPREAD
Definition TProfile.h:28
@ kERRORSPREADG
Definition TProfile.h:28
@ kERRORSPREADI
Definition TProfile.h:28
@ kERRORMEAN
Definition TProfile.h:28
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:792
Array of doubles (64 bits per element).
Definition TArrayD.h:27
Double_t * fArray
Definition TArrayD.h:30
void Streamer(TBuffer &) override
Stream a TArrayD object.
Definition TArrayD.cxx:148
void Copy(TArrayD &array) const
Definition TArrayD.h:42
void Set(Int_t n) override
Set size of this array to n doubles.
Definition TArrayD.cxx:105
TArrayD()
Default TArrayD ctor.
Definition TArrayD.cxx:25
void Reset()
Definition TArrayD.h:47
Int_t fN
Definition TArray.h:38
Class to manage histogram axis.
Definition TAxis.h:32
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:482
Bool_t CanExtend() const
Definition TAxis.h:88
const TArrayD * GetXbins() const
Definition TAxis.h:138
void Copy(TObject &axis) const override
Copy axis structure to another axis.
Definition TAxis.cxx:211
Double_t GetXmax() const
Definition TAxis.h:142
@ kLabelsUp
Definition TAxis.h:75
@ kLabelsDown
Definition TAxis.h:74
@ kLabelsHori
Definition TAxis.h:72
@ kAxisRange
Definition TAxis.h:66
@ kLabelsVert
Definition TAxis.h:73
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:293
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:473
Double_t GetXmin() const
Definition TAxis.h:141
Int_t GetNbins() const
Definition TAxis.h:127
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:462
THashList * GetLabels() const
Definition TAxis.h:123
Buffer base class used for serializing objects.
Definition TBuffer.h:43
Collection abstract base class.
Definition TCollection.h:65
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
1-Dim function class
Definition TF1.h:182
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:926
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
Double_t * fBuffer
[fBufferSize] entry buffer
Definition TH1.h:169
Int_t fNcells
Number of bins(1D), cells (2D) +U/Overflows.
Definition TH1.h:150
Double_t fTsumw
Total Sum of weights.
Definition TH1.h:157
Double_t fTsumw2
Total Sum of squares of weights.
Definition TH1.h:158
Double_t fTsumwx2
Total Sum of weight*X*X.
Definition TH1.h:160
virtual Int_t GetNbinsY() const
Definition TH1.h:542
@ kIsNotW
Histogram is forced to be not weighted even when the histogram is filled with weighted.
Definition TH1.h:410
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition TH1.cxx:6847
TAxis * GetXaxis()
Definition TH1.h:571
virtual Int_t GetNbinsX() const
Definition TH1.h:541
Int_t fBufferSize
fBuffer size
Definition TH1.h:168
TString ProvideSaveName(Option_t *option, Bool_t testfdir=kFALSE)
Provide variable name for histogram for saving as primitive Histogram pointer has by default the hist...
Definition TH1.cxx:7463
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:9436
static Int_t fgBufferSize
! Default buffer size for automatic histograms
Definition TH1.h:176
TAxis * GetYaxis()
Definition TH1.h:572
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:7590
UInt_t GetAxisLabelStatus() const
Internal function used in TH1::Fill to see which axis is full alphanumeric, i.e.
Definition TH1.cxx:6886
@ kNstat
Size of statistics data (up to TProfile3D)
Definition TH1.h:422
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:9452
virtual Double_t Chi2Test(const TH1 *h2, Option_t *option="UU", Double_t *res=nullptr) const
test for comparing weighted and unweighted histograms.
Definition TH1.cxx:2041
Double_t fEntries
Number of entries.
Definition TH1.h:156
virtual TArrayD * GetSumw2()
Definition TH1.h:560
TAxis fXaxis
X axis descriptor.
Definition TH1.h:151
TArrayD fSumw2
Array of sum of squares of weights.
Definition TH1.h:165
Bool_t GetStatOverflowsBehaviour() const
Definition TH1.h:391
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx:2882
TAxis fYaxis
Y axis descriptor.
Definition TH1.h:152
@ kXaxis
Definition TH1.h:123
@ kYaxis
Definition TH1.h:124
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition TH1.cxx:9000
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:9253
virtual void SetEntries(Double_t n)
Definition TH1.h:639
Double_t fTsumwx
Total Sum of weight*X.
Definition TH1.h:159
2-D histogram with a double per channel (see TH1 documentation)
Definition TH2.h:400
void Streamer(TBuffer &) override
Stream an object of class TH2D.
Definition TH2.cxx:4230
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH2.cxx:4219
void Copy(TObject &hnew) const override
Copy.
Definition TH2.cxx:4199
TH2D()
Constructor.
Definition TH2.cxx:4082
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH2.h:420
Double_t fTsumwxy
Total Sum of weight*X*Y.
Definition TH2.h:36
Double_t fTsumwy2
Total Sum of weight*Y*Y.
Definition TH2.h:35
Int_t GetBin(Int_t binx, Int_t biny, Int_t binz=0) const override
Return Global bin number corresponding to binx,y,z.
Definition TH2.cxx:1060
Double_t fTsumwy
Total Sum of weight*Y.
Definition TH2.h:34
static THLimitsFinder * GetLimitsFinder()
Return pointer to the current finder.
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="") override
Remove all objects from the list.
void Add(TObject *obj) override
Definition TList.h:81
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:487
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
Mother of all ROOT objects.
Definition TObject.h:42
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:479
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:886
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:548
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:897
virtual TClass * IsA() const
Definition TObject.h:248
static TString SavePrimitiveVector(std::ostream &out, const char *prefix, Int_t len, Double_t *arr, Int_t flag=0)
Save array in the output stream "out" as vector.
Definition TObject.cxx:795
void ResetBit(UInt_t f)
Definition TObject.h:203
Profile2D histograms are used to display the mean value of Z and its error for each cell in X,...
Definition TProfile2D.h:27
Long64_t Merge(TCollection *list) override
Merge all histograms in the collection in this histogram.
void PutStats(Double_t *stats) override
Replace current statistics with the values in array stats.
Int_t BufferFill(Double_t, Double_t) override
accumulate arguments in buffer.
Definition TProfile2D.h:44
Double_t fTsumwz
Total Sum of weight*Z.
Definition TProfile2D.h:39
Int_t Fill(const Double_t *v)
Definition TProfile2D.h:51
TClass * IsA() const override
Definition TProfile2D.h:154
TH2D * ProjectionXY(const char *name="_pxy", Option_t *option="e") const
Project this profile2D into a 2-D histogram along X,Y.
Bool_t Multiply(TF1 *h1, Double_t c1=1) override
Performs the operation: this = this*c1*f1.
void LabelsDeflate(Option_t *axis="X") override
Reduce the number of bins for this axis to the number of bins having a label.
Double_t GetBinError(Int_t bin) const override
Return bin error of a Profile2D histogram.
static void Approximate(Bool_t approx=kTRUE)
Static function, set the fgApproximate flag.
EErrorType fErrorMode
Option to compute errors.
Definition TProfile2D.h:35
Double_t fZmin
Lower limit in Z (if set)
Definition TProfile2D.h:36
TProfile2D * RebinX(Int_t ngroup=2, const char *newname="") override
Rebin only the X axis.
Double_t * GetW2()
Definition TProfile2D.h:66
void SetBuffer(Int_t bufsize, Option_t *option="") override
Set the buffer size in units of 8 bytes (double).
Bool_t fScaling
! True when TProfile2D::Scale is called
Definition TProfile2D.h:38
virtual Double_t GetBinEffectiveEntries(Int_t bin)
Return bin effective entries for a weighted filled Profile histogram.
Option_t * GetErrorOption() const
Return option to compute profile2D errors.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
TArrayD fBinSumw2
Array of sum of squares of weights per bin.
Definition TProfile2D.h:41
Double_t * GetB2()
Definition TProfile2D.h:64
static TClass * Class()
TProfile2D * Rebin2D(Int_t nxgroup=2, Int_t nygroup=2, const char *newname="", const Double_t *xbins=nullptr, const Double_t *ybins=nullptr) override
Rebin this histogram grouping nxgroup/nygroup bins along the xaxis/yaxis together.
void ExtendAxis(Double_t x, TAxis *axis) override
Profile histogram is resized along axis such that x is in the axis range.
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.
TProfile2D * RebinY(Int_t ngroup=2, const char *newname="") override
Rebin only the Y axis.
Double_t * GetW()
Definition TProfile2D.h:65
void Scale(Double_t c1=1, Option_t *option="") override
Multiply this profile2D by a constant c1.
virtual void SetBinEntries(Int_t bin, Double_t w)
Set the number of entries in bin.
void Copy(TObject &hnew) const override
Copy a Profile2D histogram to a new profile2D histogram.
TProfile * DoProfile(bool onX, const char *name, Int_t firstbin, Int_t lastbin, Option_t *option) const override
Implementation of ProfileX or ProfileY for a TProfile2D.
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.
void LabelsOption(Option_t *option="h", Option_t *axis="X") override
Set option(s) to draw axis with labels.
TProfile2D()
Default constructor for Profile2D histograms.
void Sumw2(Bool_t flag=kTRUE) override
Create/Delete structure to store sum of squares of weights per bin.
TArrayD fBinEntries
Number of entries per bin.
Definition TProfile2D.h:34
void SetBins(const Int_t *nbins, const Double_t *range)
Definition TProfile2D.h:49
~TProfile2D() override
Default destructor for Profile2D histograms.
void Streamer(TBuffer &) override
Stream an object of class TProfile2D.
static Bool_t fgApproximate
Bin error approximation option.
Definition TProfile2D.h:42
Bool_t Divide(TF1 *h1, Double_t c1=1) override
Performs the operation: this = this/(c1*f1) .
Int_t BufferEmpty(Int_t action=0) override
Fill histogram with all entries in the buffer.
void LabelsInflate(Option_t *axis="X") override
Double the number of bins for axis.
void GetStats(Double_t *stats) const override
Fill the array stats from the contents of this profile.
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile2D histogram.
Double_t fZmax
Upper limit in Z (if set)
Definition TProfile2D.h:37
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow.
void BuildOptions(Double_t zmin, Double_t zmax, Option_t *option)
Set Profile2D histogram structure and options.
Bool_t Add(TF1 *h1, Double_t c1=1, Option_t *option="") override
Performs the operation: this = this + c1*f1 .
TProfile2D & operator=(const TProfile2D &profile)
Double_t fTsumwz2
Total Sum of weight*Z*Z.
Definition TProfile2D.h:40
Double_t Chi2Test(const TH1 *h2, Option_t *option="WW", Double_t *res=nullptr) const override
Run a Chi2Test between a TProfile2D and another histogram.
Double_t * GetB()
Definition TProfile2D.h:63
virtual void SetErrorOption(Option_t *option="")
Set option to compute profile2D errors.
Double_t GetBinContent(Int_t bin) const override
Return bin content of a Profile2D histogram.
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
Basic string class.
Definition TString.h:137
void ToLower()
Change string to lower-case.
Definition TString.cxx:1190
TString & ReplaceSpecialCppChars()
Find special characters which are typically used in printf() calls and replace them by appropriate es...
Definition TString.cxx:1122
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:714
void ToUpper()
Change string to upper case.
Definition TString.cxx:1203
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:642
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
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
void WarnAboutUnusedFlowContent(const TAxis &oldAxis, const RebinnedAxisInfo &info, const Double_t *userBins, char axisName, const Double_t *bins, Int_t stride, Int_t nOther, Int_t otherStride, TH1 &hist, const char *where)
Warn when the range of the new axis extends beyond the old one while the corresponding flow bins hold...
void SetRebinnedBins2D(TH1 &hnew, const TAxis &newXaxis, const TAxis &newYaxis)
Apply the axes of the rebinned histogram, using explicit bin edges if any of the two axes has non-uni...
void MergeRebinnedCells(Int_t nOldX, Int_t nOldY, Int_t nNewX, const std::vector< Int_t > &mapX, const std::vector< Int_t > &mapY, std::initializer_list< std::pair< const Double_t *, Double_t * > > arrays)
Accumulate every old cell (including under- and overflow) into the new cell given by the per-axis bin...
bool SetupRebinnedAxis(const TAxis &oldAxis, Int_t ngroup, const Double_t *userBins, char axisName, TH1 &hist, const char *where, RebinnedAxisInfo &info)
Validate the rebinning parameters for one axis and fill the definition of the rebinned axis and the m...
Bool_t IsNaN(Double_t x)
Definition TMath.h:905
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:675
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Sort the n elements of the array a of generic templated type Element.
Definition TMathBase.h:413
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
The definition of one axis of the rebinned histogram.