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 <iostream>
20
22
23
24/** \class TProfile2D
25 \ingroup Histograms
26 Profile2D histograms are used to display the mean
27 value of Z and its error for each cell in X,Y.
28 Profile2D histograms are in many cases an
29 elegant replacement of three-dimensional histograms : the inter-relation of three
30 measured quantities X, Y and Z can always be visualized by a three-dimensional
31 histogram or scatter-plot; its representation on the line-printer is not particularly
32 satisfactory, except for sparse data. If Z is an unknown (but single-valued)
33 approximate function of X,Y this function is displayed by a profile2D histogram with
34 much better precision than by a scatter-plot.
35
36 The following formulae show the cumulated contents (capital letters) and the values
37 displayed by the printing or plotting routines (small letters) of the elements for cell i, j.
38 \f[
39 \begin{align}
40 H(i,j) &= \sum w \cdot Z \\
41 E(i,j) &= \sum w \cdot Z^2 \\
42 W(i,j) &= \sum w \\
43 h(i,j) &= \frac{H(i,j)}{W(i,j)} \\
44 s(i,j) &= \sqrt{E(i,j)/W(i,j)- h(i,j)^2} \\
45 e(i,j) &= \frac{s(i,j)}{\sqrt{W(i,j)}}
46 \end{align}
47 \f]
48 The bin content is always the mean of the Z values, but errors change depending on options:
49 \f[
50 \begin{align}
51 \text{GetBinContent}(i,j) &= h(i,j) \\
52 \text{GetBinError}(i,j) &=
53 \begin{cases}
54 e(i,j) &\text{if option="" (default). Error of the mean of all z values.} \\
55 s(i,j) &\text{if option="s". Standard deviation of z values.} \\
56 \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.} \\
57 1/\sqrt{W(i,j)} &\text{if option="g". Error of a weighted mean when combining measurements with variances of } w. \\
58 \end{cases}
59 \end{align}
60 \f]
61
62 In the special case where s(I,J) is zero (eg, case of 1 entry only in one cell)
63 the bin error e(I,J) is computed from the average of the s(I,J) for all cells
64 if the static function TProfile2D::Approximate has been called.
65 This simple/crude approximation was suggested in order to keep the cell
66 during a fit operation. But note that this approximation is not the default behaviour.
67
68 ### Creating and drawing a 2D profile
69 ~~~~{.cpp}
70 {
71 auto c1 = new TCanvas("c1","Profile histogram example",200,10,700,500);
72 auto hprof2d = new TProfile2D("hprof2d","Profile of pz versus px and py",40,-4,4,40,-4,4,0,20);
73 Float_t px, py, pz;
74 for ( Int_t i=0; i<25000; i++) {
75 gRandom->Rannor(px,py);
76 pz = px*px + py*py;
77 hprof2d->Fill(px,py,pz,1);
78 }
79 hprof2d->Draw();
80 }
81 ~~~~
82*/
83
84////////////////////////////////////////////////////////////////////////////////
85/// Default constructor for Profile2D histograms.
86
88{
89 fTsumwz = fTsumwz2 = 0;
91 BuildOptions(0,0,"");
92}
93
94////////////////////////////////////////////////////////////////////////////////
95/// Default destructor for Profile2D histograms.
96
100
101////////////////////////////////////////////////////////////////////////////////
102/// Normal Constructor for Profile histograms.
103///
104/// The first eight parameters are similar to TH2D::TH2D.
105/// All values of z are accepted at filling time.
106/// To fill a profile2D histogram, one must use TProfile2D::Fill function.
107///
108/// Note that when filling the profile histogram the function Fill
109/// checks if the variable z is between fZmin and fZmax.
110/// If a minimum or maximum value is set for the Z scale before filling,
111/// then all values below zmin or above zmax will be discarded.
112/// Setting the minimum or maximum value for the Z scale before filling
113/// has the same effect as calling the special TProfile2D constructor below
114/// where zmin and zmax are specified.
115///
116/// H(I,J) is printed as the cell contents. The errors computed are s(I,J) if CHOPT='S'
117/// (spread option), or e(I,J) if CHOPT=' ' (error on mean).
118///
119/// See TProfile2D::BuildOptions for explanation of parameters
120///
121/// see other constructors below with all possible combinations of
122/// fix and variable bin size like in TH2D.
123
124TProfile2D::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)
125: TH2D(name,title,nx,xlow,xup,ny,ylow,yup)
126{
127 BuildOptions(0,0,option);
128 if (xlow >= xup || ylow >= yup) SetBuffer(fgBufferSize);
129}
130
131////////////////////////////////////////////////////////////////////////////////
132/// Create a 2-D Profile with variable bins in X and fix bins in Y.
133
134TProfile2D::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)
135: TH2D(name,title,nx,xbins,ny,ylow,yup)
136{
137 BuildOptions(0,0,option);
138}
139
140////////////////////////////////////////////////////////////////////////////////
141/// Create a 2-D Profile with fix bins in X and variable bins in Y.
142
143TProfile2D::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)
144: TH2D(name,title,nx,xlow,xup,ny,ybins)
145{
146 BuildOptions(0,0,option);
147}
148
149////////////////////////////////////////////////////////////////////////////////
150/// Create a 2-D Profile with variable bins in X and variable bins in Y.
151
152TProfile2D::TProfile2D(const char *name,const char *title,Int_t nx,const Double_t *xbins,Int_t ny,const Double_t *ybins,Option_t *option)
153: TH2D(name,title,nx,xbins,ny,ybins)
154{
155 BuildOptions(0,0,option);
156}
157
158////////////////////////////////////////////////////////////////////////////////
159/// Constructor for Profile2D histograms with range in z.
160///
161/// The first eight parameters are similar to TH2D::TH2D.
162/// Only the values of Z between ZMIN and ZMAX will be considered at filling time.
163/// zmin and zmax will also be the maximum and minimum values
164/// on the z scale when drawing the profile2D.
165///
166/// See TProfile2D::BuildOptions for more explanations on errors
167
169: TH2D(name,title,nx,xlow,xup,ny,ylow,yup)
170{
172 if (xlow >= xup || ylow >= yup) SetBuffer(fgBufferSize);
173}
174
175
176////////////////////////////////////////////////////////////////////////////////
177/// Set Profile2D histogram structure and options.
178///
179/// - zmin: minimum value allowed for z
180/// - zmax: maximum value allowed for z
181/// if (zmin = zmax = 0) there are no limits on the allowed z values (zmin = -inf, zmax = +inf)
182///
183/// - option: this is the option for the computation of the t error of the profile ( TProfile2D::GetBinError )
184/// possible values for the options are documented in TProfile2D::SetErrorOption
185///
186/// See TProfile::BuildOptions for a detailed description
187
189{
190
192
193 // create extra profile data structure (bin entries/ y^2 and sum of weight square)
195
196 fZmin = zmin;
197 fZmax = zmax;
199 fTsumwz = fTsumwz2 = 0;
200}
201
202////////////////////////////////////////////////////////////////////////////////
203/// Copy constructor.
204
206{
207 profile2d.TProfile2D::Copy(*this);
208}
209
211{
212 if (this != &profile2d)
213 profile2d.TProfile2D::Copy(*this);
214 return *this;
215}
216
217////////////////////////////////////////////////////////////////////////////////
218/// Performs the operation: `this = this + c1*f1` .
219
221{
222 Error("Add","Function not implemented for TProfile2D");
223 return kFALSE;
224}
225
226////////////////////////////////////////////////////////////////////////////////
227/// Performs the operation: `this = this + c1*h1` .
228
230{
231 if (!h1) {
232 Error("Add","Attempt to add a non-existing profile");
233 return kFALSE;
234 }
236 Error("Add","Attempt to add a non-profile2D object");
237 return kFALSE;
238 }
239
240 return TProfileHelper::Add(this, this, h1, 1, c1);
241}
242
243////////////////////////////////////////////////////////////////////////////////
244/// Replace contents of this profile2D by the addition of h1 and h2.
245///
246/// `this = c1*h1 + c2*h2`
247
249{
250 if (!h1 || !h2) {
251 Error("Add","Attempt to add a non-existing profile");
252 return kFALSE;
253 }
255 Error("Add","Attempt to add a non-profile2D object");
256 return kFALSE;
257 }
258 if (!h2->InheritsFrom(TProfile2D::Class())) {
259 Error("Add","Attempt to add a non-profile2D object");
260 return kFALSE;
261 }
262 return TProfileHelper::Add(this, h1, h2, c1, c2);
263}
264
265////////////////////////////////////////////////////////////////////////////////
266/// Static function, set the fgApproximate flag.
267///
268/// When the flag is true, the function GetBinError
269/// will approximate the bin error with the average profile error on all bins
270/// in the following situation only
271/// - the number of bins in the profile2D is less than 10404 (eg 100x100)
272/// - the bin number of entries is small ( <5)
273/// - the estimated bin error is extremely small compared to the bin content
274/// (see TProfile2D::GetBinError)
275
280
281////////////////////////////////////////////////////////////////////////////////
282/// Fill histogram with all entries in the buffer.
283///
284/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
285/// - action = 0 histogram is filled from the buffer
286/// - action = 1 histogram is filled and buffer is deleted
287/// The buffer is automatically deleted when the number of entries
288/// in the buffer is greater than the number of entries in the histogram
289
291{
292 // do we need to compute the bin size?
293 if (!fBuffer) return 0;
295 if (!nbentries) return 0;
296 Double_t *buffer = fBuffer;
297 if (nbentries < 0) {
298 if (action == 0) return 0;
300 fBuffer=nullptr;
301 Reset("ICES"); // reset without deleting the functions
302 fBuffer = buffer;
303 }
305 //find min, max of entries in buffer
306 Double_t xmin = fBuffer[2];
308 Double_t ymin = fBuffer[3];
310 for (Int_t i=1;i<nbentries;i++) {
311 Double_t x = fBuffer[4*i+2];
312 if (x < xmin) xmin = x;
313 if (x > xmax) xmax = x;
314 Double_t y = fBuffer[4*i+3];
315 if (y < ymin) ymin = y;
316 if (y > ymax) ymax = y;
317 }
318 if (fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin()) {
319 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax,ymin,ymax);
320 } else {
321 fBuffer = nullptr;
327 fBuffer = buffer;
329 }
330 }
331
332 fBuffer = nullptr;
333 for (Int_t i=0;i<nbentries;i++) {
334 Fill(buffer[4*i+2],buffer[4*i+3],buffer[4*i+4],buffer[4*i+1]);
335 }
336 fBuffer = buffer;
337
338 if (action > 0) { delete [] fBuffer; fBuffer = nullptr; fBufferSize = 0;}
339 else {
341 else fBuffer[0] = 0;
342 }
343 return nbentries;
344}
345
346////////////////////////////////////////////////////////////////////////////////
347/// Accumulate arguments in buffer.
348///
349/// When buffer is full, empty the buffer.
350///
351/// - fBuffer[0] = number of entries in buffer
352/// - fBuffer[1] = w of first entry
353/// - fBuffer[2] = x of first entry
354/// - fBuffer[3] = y of first entry
355/// - fBuffer[4] = z of first entry
356
358{
359 if (!fBuffer) return -3;
361 if (nbentries < 0) {
363 fBuffer[0] = nbentries;
364 if (fEntries > 0) {
365 Double_t *buffer = fBuffer; fBuffer=nullptr;
366 Reset("ICES"); // reset without deleting the functions
367 fBuffer = buffer;
368 }
369 }
370 if (4*nbentries+4 >= fBufferSize) {
371 BufferEmpty(1);
372 return Fill(x,y,z,w);
373 }
374 fBuffer[4*nbentries+1] = w;
375 fBuffer[4*nbentries+2] = x;
376 fBuffer[4*nbentries+3] = y;
377 fBuffer[4*nbentries+4] = z;
378 fBuffer[0] += 1;
379 return -2;
380}
381
382////////////////////////////////////////////////////////////////////////////////
383/// Run a Chi2Test between a TProfile2D and another histogram.
384/// If the argument is also a TProfile2D, this calls TH1::Chi2Test() with the option "WW".
385/// \see TH1::Chi2Test()
386
388{
389 TString opt = option;
390 opt.ToUpper();
391
392 if (auto other = dynamic_cast<const TProfile2D *>(h2); other) {
393 if (fErrorMode != kERRORMEAN || other->fErrorMode != kERRORMEAN) {
394 Error("Chi2Test", "Chi2 tests need TProfiles in 'error of mean' mode.");
395 return 0;
396 }
397
398 opt += "WW";
399 opt.ReplaceAll("UU", "WW");
400 opt.ReplaceAll("UW", "WW");
401 } else if (!opt.Contains("WW")) {
402 Error("Chi2Test", "TProfiles need to be tested with the 'W' option. Either use option 'WW' or use "
403 "histogram.Chi2Test(<profile>, 'UW')");
404 return 0;
405 }
406
407 return TH1::Chi2Test(h2, opt, res);
408}
409
410////////////////////////////////////////////////////////////////////////////////
411/// Copy a Profile2D histogram to a new profile2D histogram.
412
413void TProfile2D::Copy(TObject &obj) const
414{
415 try {
416 TProfile2D &pobj = dynamic_cast<TProfile2D &>(obj);
417
419 fBinEntries.Copy(pobj.fBinEntries);
420 fBinSumw2.Copy(pobj.fBinSumw2);
421 for (int bin=0;bin<fNcells;bin++) {
422 pobj.fArray[bin] = fArray[bin];
423 pobj.fSumw2.fArray[bin] = fSumw2.fArray[bin];
424 }
425 pobj.fZmin = fZmin;
426 pobj.fZmax = fZmax;
427 pobj.fScaling = fScaling;
428 pobj.fErrorMode = fErrorMode;
429 pobj.fTsumwz = fTsumwz;
430 pobj.fTsumwz2 = fTsumwz2;
431
432 } catch(...) {
433 Fatal("Copy","Cannot copy a TProfile2D in a %s",obj.IsA()->GetName());
434 }
435
436}
437
438////////////////////////////////////////////////////////////////////////////////
439/// Performs the operation: `this = this/(c1*f1)` .
440/// This function is not implemented
441
443{
444 Error("Divide","Function not implemented for TProfile2D");
445 return kFALSE;
446}
447
448////////////////////////////////////////////////////////////////////////////////
449/// Divide this profile2D by h1.
450///
451/// `this = this/h1`
452///
453///This function return kFALSE if the divide operation failed
454
456{
457
458 if (!h1) {
459 Error("Divide","Attempt to divide a non-existing profile2D");
460 return kFALSE;
461 }
463 Error("Divide","Attempt to divide a non-profile2D object");
464 return kFALSE;
465 }
467
468 // delete buffer if it is there since it will become invalid
469 if (fBuffer) BufferEmpty(1);
470
471 // Check profile compatibility
472 Int_t nx = GetNbinsX();
473 if (nx != p1->GetNbinsX()) {
474 Error("Divide","Attempt to divide profiles with different number of bins");
475 return kFALSE;
476 }
477 Int_t ny = GetNbinsY();
478 if (ny != p1->GetNbinsY()) {
479 Error("Divide","Attempt to divide profiles with different number of bins");
480 return kFALSE;
481 }
482
483 // Reset statistics
485
486 // Loop on bins (including underflows/overflows)
487 Int_t bin,binx,biny;
488 Double_t *cu1 = p1->GetW();
489 Double_t *er1 = p1->GetW2();
490 Double_t *en1 = p1->GetB();
491 Double_t c0,c1,w,z,x,y;
492 for (binx =0;binx<=nx+1;binx++) {
493 for (biny =0;biny<=ny+1;biny++) {
494 bin = biny*(fXaxis.GetNbins()+2) + binx;
495 c0 = fArray[bin];
496 c1 = cu1[bin];
497 if (c1) w = c0/c1;
498 else w = 0;
499 fArray[bin] = w;
500 z = TMath::Abs(w);
503 fEntries++;
504 fTsumw += z;
505 fTsumw2 += z*z;
506 fTsumwx += z*x;
507 fTsumwx2 += z*x*x;
508 fTsumwy += z*y;
509 fTsumwy2 += z*y*y;
510 fTsumwxy += z*x*y;
511 fTsumwz += z;
512 fTsumwz2 += z*z;
513 Double_t e0 = fSumw2.fArray[bin];
514 Double_t e1 = er1[bin];
515 Double_t c12= c1*c1;
516 if (!c1) fSumw2.fArray[bin] = 0;
517 else fSumw2.fArray[bin] = (e0*c1*c1 + e1*c0*c0)/(c12*c12);
518 if (!en1[bin]) fBinEntries.fArray[bin] = 0;
519 else fBinEntries.fArray[bin] /= en1[bin];
520 }
521 }
522 // maintaining the correct sum of weights square is not supported when dividing
523 // bin error resulting from division of profile needs to be checked
524 if (fBinSumw2.fN) {
525 Warning("Divide","Cannot preserve during the division of profiles the sum of bin weight square");
526 fBinSumw2 = TArrayD();
527 }
528 return kTRUE;
529}
530
531////////////////////////////////////////////////////////////////////////////////
532/// Replace contents of this profile2D by the division of h1 by h2.
533///
534/// `this = c1*h1/(c2*h2)`
535///
536/// This function return kFALSE if the divide operation failed
537
539{
540 TString opt = option;
541 opt.ToLower();
542 Bool_t binomial = kFALSE;
543 if (opt.Contains("b")) binomial = kTRUE;
544 if (!h1 || !h2) {
545 Error("Divide","Attempt to divide a non-existing profile2D");
546 return kFALSE;
547 }
549 Error("Divide","Attempt to divide a non-profile2D object");
550 return kFALSE;
551 }
553 if (!h2->InheritsFrom(TProfile2D::Class())) {
554 Error("Divide","Attempt to divide a non-profile2D object");
555 return kFALSE;
556 }
557 TProfile2D *p2 = (TProfile2D*)h2;
558
559 // delete buffer if it is there since it will become invalid
560 if (fBuffer) BufferEmpty(1);
561
562 // Check histogram compatibility
563 Int_t nx = GetNbinsX();
564 if (nx != p1->GetNbinsX() || nx != p2->GetNbinsX()) {
565 Error("Divide","Attempt to divide profiles with different number of bins");
566 return kFALSE;
567 }
568 Int_t ny = GetNbinsY();
569 if (ny != p1->GetNbinsY() || ny != p2->GetNbinsY()) {
570 Error("Divide","Attempt to divide profiles with different number of bins");
571 return kFALSE;
572 }
573 if (!c2) {
574 Error("Divide","Coefficient of dividing profile cannot be zero");
575 return kFALSE;
576 }
577
578 // Reset statistics
580
581 // Loop on bins (including underflows/overflows)
582 Int_t bin,binx,biny;
583 Double_t *cu1 = p1->GetW();
584 Double_t *cu2 = p2->GetW();
585 Double_t *er1 = p1->GetW2();
586 Double_t *er2 = p2->GetW2();
587 Double_t *en1 = p1->GetB();
588 Double_t *en2 = p2->GetB();
589 Double_t b1,b2,w,z,x,y,ac1,ac2;
590 ac1 = TMath::Abs(c1);
591 ac2 = TMath::Abs(c2);
592 for (binx =0;binx<=nx+1;binx++) {
593 for (biny =0;biny<=ny+1;biny++) {
594 bin = biny*(fXaxis.GetNbins()+2) + binx;
595 b1 = cu1[bin];
596 b2 = cu2[bin];
597 if (b2) w = c1*b1/(c2*b2);
598 else w = 0;
599 fArray[bin] = w;
600 z = TMath::Abs(w);
603 fEntries++;
604 fTsumw += z;
605 fTsumw2 += z*z;
606 fTsumwx += z*x;
607 fTsumwx2 += z*x*x;
608 fTsumwy += z*y;
609 fTsumwy2 += z*y*y;
610 fTsumwxy += z*x*y;
611 fTsumwz += z;
612 fTsumwz2 += z*z;
613 Double_t e1 = er1[bin];
614 Double_t e2 = er2[bin];
615 //Double_t b22= b2*b2*d2;
616 Double_t b22= b2*b2*TMath::Abs(c2);
617 if (!b2) fSumw2.fArray[bin] = 0;
618 else {
619 if (binomial) {
620 fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));
621 } else {
622 fSumw2.fArray[bin] = ac1*ac2*(e1*b2*b2 + e2*b1*b1)/(b22*b22);
623 }
624 }
625 if (!en2[bin]) fBinEntries.fArray[bin] = 0;
626 else fBinEntries.fArray[bin] = en1[bin]/en2[bin];
627 }
628 }
629 return kTRUE;
630}
631
632////////////////////////////////////////////////////////////////////////////////
633/// Fill a Profile2D histogram (no weights).
634
636{
637 if (fBuffer) return BufferFill(x,y,z,1);
638
639 Int_t bin,binx,biny;
640
641 if (fZmin != fZmax) {
642 if (z <fZmin || z> fZmax || TMath::IsNaN(z) ) return -1;
643 }
644
645 fEntries++;
648 if (binx <0 || biny <0) return -1;
649 bin = GetBin(binx, biny);
650 fArray[bin] += z;
651 fSumw2.fArray[bin] += z*z;
652 fBinEntries.fArray[bin] += 1;
653 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
654 if (binx == 0 || binx > fXaxis.GetNbins()) {
655 if (!GetStatOverflowsBehaviour()) return -1;
656 }
657 if (biny == 0 || biny > fYaxis.GetNbins()) {
658 if (!GetStatOverflowsBehaviour()) return -1;
659 }
660 ++fTsumw;
661 ++fTsumw2;
662 fTsumwx += x;
663 fTsumwx2 += x*x;
664 fTsumwy += y;
665 fTsumwy2 += y*y;
666 fTsumwxy += x*y;
667 fTsumwz += z;
668 fTsumwz2 += z*z;
669 return bin;
670}
671
672////////////////////////////////////////////////////////////////////////////////
673/// Fill a Profile2D histogram with weights.
674
676{
677 if (fBuffer) return BufferFill(x, y, z, w);
678
679 Int_t bin, binx, biny;
680
681 if (fZmin != fZmax) {
682 if (z < fZmin || z > fZmax || TMath::IsNaN(z)) return -1;
683 }
684
685 Double_t u = w;
686 fEntries++;
687 binx = fXaxis.FindBin(x);
688 biny = fYaxis.FindBin(y);
689 if (binx < 0 || biny < 0) return -1;
690 bin = biny * (fXaxis.GetNbins() + 2) + binx;
691 AddBinContent(bin, u * z);
692 fSumw2.fArray[bin] += u * z * z;
693 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW))
694 Sumw2(); // must be called before accumulating the entries
695 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u * u;
696 fBinEntries.fArray[bin] += u;
697
698 if (binx == 0 || binx > fXaxis.GetNbins()) {
699 if (!GetStatOverflowsBehaviour()) return -1;
700 }
701 if (biny == 0 || biny > fYaxis.GetNbins()) {
702 if (!GetStatOverflowsBehaviour()) return -1;
703 }
704 fTsumw += u;
705 fTsumw2 += u * u;
706 fTsumwx += u * x;
707 fTsumwx2 += u * x * x;
708 fTsumwy += u * y;
709 fTsumwy2 += u * y * y;
710 fTsumwxy += u * x * y;
711 fTsumwz += u * z;
712 fTsumwz2 += u * z * z;
713 return bin;
714}
715////////////////////////////////////////////////////////////////////////////////
716/// Fill a Profile2D histogram (no weights).
717
719{
720 Int_t bin,binx,biny;
721
722 if (fZmin != fZmax) {
723 if (z <fZmin || z> fZmax || TMath::IsNaN(z)) return -1;
724 }
725
726 Double_t u = w;
727 fEntries++;
730 if (binx <0 || biny <0) return -1;
731 bin = biny*(fXaxis.GetNbins()+2) + binx;
732 AddBinContent(bin, u * z);
733 fSumw2.fArray[bin] += u * z * z;
734 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW))
735 Sumw2(); // must be called before accumulating the entries
736 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u * u;
737 fBinEntries.fArray[bin] += u;
738
739 if (binx == 0 || binx > fXaxis.GetNbins()) {
740 if (!GetStatOverflowsBehaviour()) return -1;
741 }
742 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
743
746
747 fTsumw += u;
748 fTsumw2 += u * u;
749 fTsumwx += u * x;
750 fTsumwx2 += u * x * x;
751 fTsumwy += u * y;
752 fTsumwy2 += u * y * y;
753 fTsumwxy += u * x * y;
754 fTsumwz += u * z;
755 fTsumwz2 += u * z * z;
756
757 return bin;
758}
759
760////////////////////////////////////////////////////////////////////////////////
761/// Fill a Profile2D histogram (no weights).
762
763Int_t TProfile2D::Fill(const char *namex, const char *namey, Double_t z, Double_t w)
764{
765 Int_t bin,binx,biny;
766
767 if (fZmin != fZmax) {
768 if (z <fZmin || z> fZmax || TMath::IsNaN(z) ) return -1;
769 }
770
771 Double_t u = w;
772 fEntries++;
775 if (binx < 0 || biny < 0)
776 return -1;
777 bin = biny * (fXaxis.GetNbins() + 2) + binx;
778 AddBinContent(bin, u * z);
779 fSumw2.fArray[bin] += u * z * z;
780 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW))
781 Sumw2(); // must be called before accumulating the entries
782 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u * u;
783 fBinEntries.fArray[bin] += u;
784
785 if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
786 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
787
791
792 fTsumw += u;
793 fTsumw2 += u * u;
794 fTsumwx += u * x;
795 fTsumwx2 += u * x * x;
796 fTsumwy += u * y;
797 fTsumwy2 += u * y * y;
798 fTsumwxy += u * x * y;
799 fTsumwz += u * z;
800 fTsumwz2 += u * z * z;
801
802 return bin;
803}
804
805////////////////////////////////////////////////////////////////////////////////
806/// Fill a Profile2D histogram (no weights).
807
809{
810 Int_t bin,binx,biny;
811
812 if (fZmin != fZmax) {
813 if (z <fZmin || z> fZmax || TMath::IsNaN(z)) return -1;
814 }
815
816 Double_t u = w;
817 fEntries++;
820 if (binx <0 || biny <0) return -1;
821 bin = biny*(fXaxis.GetNbins()+2) + binx;
822
823 AddBinContent(bin, u * z);
824 fSumw2.fArray[bin] += u * z * z;
825 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW))
826 Sumw2(); // must be called before accumulating the entries
827 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u * u;
828 fBinEntries.fArray[bin] += u;
829
830 if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
831 if (biny == 0 || biny > fYaxis.GetNbins()) {
832 if (!GetStatOverflowsBehaviour()) return -1;
833 }
834
837
838 fTsumw += u;
839 fTsumw2 += u * u;
840 fTsumwx += u * x;
841 fTsumwx2 += u * x * x;
842 fTsumwy += u * y;
843 fTsumwy2 += u * y * y;
844 fTsumwxy += u * x * y;
845 fTsumwz += u * z;
846 fTsumwz2 += u * z * z;
847
848 return bin;
849}
850
851
852
853////////////////////////////////////////////////////////////////////////////////
854/// Return bin content of a Profile2D histogram.
855
857{
858 if (fBuffer) ((TProfile2D*)this)->BufferEmpty();
859
860 if (bin < 0 || bin >= fNcells) return 0;
861 if (fBinEntries.fArray[bin] == 0) return 0;
862 if (!fArray) return 0;
863 return fArray[bin]/fBinEntries.fArray[bin];
864}
865
866////////////////////////////////////////////////////////////////////////////////
867/// Return bin entries of a Profile2D histogram.
868
870{
871 if (fBuffer) ((TProfile2D*)this)->BufferEmpty();
872
873 if (bin < 0 || bin >= fNcells) return 0;
874 return fBinEntries.fArray[bin];
875}
876
877////////////////////////////////////////////////////////////////////////////////
878/// Return bin effective entries for a weighted filled Profile histogram.
879/// In case of an unweighted profile, it is equivalent to the number of entries per bin
880/// The effective entries is defined as the square of the sum of the weights divided by the
881/// sum of the weights square.
882/// TProfile::Sumw2() must be called before filling the profile with weights.
883/// Only by calling this method the sum of the square of the weights per bin is stored.
884
889
890////////////////////////////////////////////////////////////////////////////////
891/// Return bin error of a Profile2D histogram.
892///
893/// ### Computing errors: A moving field
894///
895/// The computation of errors for a TProfile2D has evolved with the versions
896/// of ROOT. The difficulty is in computing errors for bins with low statistics.
897/// - prior to version 3.10, we had no special treatment of low statistic bins.
898/// As a result, these bins had huge errors. The reason is that the
899/// expression eprim2 is very close to 0 (rounding problems) or 0.
900/// - The algorithm is modified/protected for the case
901/// when a TProfile2D is projected (ProjectionX). The previous algorithm
902/// generated a N^2 problem when projecting a TProfile2D with a large number of
903/// bins (eg 100000).
904/// - in version 3.10/02, a new static function TProfile::Approximate
905/// is introduced to enable or disable (default) the approximation.
906/// (see also comments in TProfile::GetBinError)
907
912
913////////////////////////////////////////////////////////////////////////////////
914/// Return option to compute profile2D errors.
915
917{
918 if (fErrorMode == kERRORSPREAD) return "s";
919 if (fErrorMode == kERRORSPREADI) return "i";
920 if (fErrorMode == kERRORSPREADG) return "g";
921 return "";
922}
923
924////////////////////////////////////////////////////////////////////////////////
925/// Fill the array stats from the contents of this profile.
926/// The array stats must be correctly dimensioned in the calling program.
927///
928/// - stats[0] = sumw
929/// - stats[1] = sumw2
930/// - stats[2] = sumwx
931/// - stats[3] = sumwx2
932/// - stats[4] = sumwy
933/// - stats[5] = sumwy2
934/// - stats[6] = sumwxy
935/// - stats[7] = sumwz
936/// - stats[8] = sumwz2
937///
938/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
939/// is simply a copy of the statistics quantities computed at filling time.
940/// If a sub-range is specified, the function recomputes these quantities
941/// from the bin contents in the current axis range.
942
944{
945 if (fBuffer) ((TProfile2D*)this)->BufferEmpty();
946
947 // check for labels axis . In that case corresponding statistics do not make sense and it is set to zero
948 Bool_t labelXaxis = ((const_cast<TAxis&>(fXaxis)).GetLabels() && fXaxis.CanExtend() );
949 Bool_t labelYaxis = ((const_cast<TAxis&>(fYaxis)).GetLabels() && fYaxis.CanExtend() );
950
951 // Loop on bins
952 if ( (fTsumw == 0 /* && fEntries > 0 */) || fXaxis.TestBit(TAxis::kAxisRange) || fYaxis.TestBit(TAxis::kAxisRange)) {
953 Int_t bin, binx, biny;
954 Double_t w, w2;
955 Double_t x,y;
956 for (bin=0;bin<9;bin++) stats[bin] = 0;
957 if (!fBinEntries.fArray) return;
962 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
965 if (firstBinX == 1) firstBinX = 0;
966 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
967 }
969 if (firstBinY == 1) firstBinY = 0;
970 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
971 }
972 }
973 for (biny = firstBinY; biny <= lastBinY; biny++) {
974 y = (!labelYaxis) ? fYaxis.GetBinCenter(biny) : 0;
975 for (binx = firstBinX; binx <= lastBinX; binx++) {
976 bin = GetBin(binx,biny);
977 w = fBinEntries.fArray[bin];
978 w2 = (fBinSumw2.fN ? fBinSumw2.fArray[bin] : w );
979 x = (!labelXaxis) ? fXaxis.GetBinCenter(binx) : 0;
980 stats[0] += w;
981 stats[1] += w2;
982 stats[2] += w*x;
983 stats[3] += w*x*x;
984 stats[4] += w*y;
985 stats[5] += w*y*y;
986 stats[6] += w*x*y;
987 stats[7] += fArray[bin];
988 stats[8] += fSumw2.fArray[bin];
989 }
990 }
991 } else {
992 stats[0] = fTsumw;
993 stats[1] = fTsumw2;
994 stats[2] = fTsumwx;
995 stats[3] = fTsumwx2;
996 stats[4] = fTsumwy;
997 stats[5] = fTsumwy2;
998 stats[6] = fTsumwxy;
999 stats[7] = fTsumwz;
1000 stats[8] = fTsumwz2;
1001 }
1002}
1003
1004////////////////////////////////////////////////////////////////////////////////
1005/// Reduce the number of bins for this axis to the number of bins having a label.
1006
1011
1012////////////////////////////////////////////////////////////////////////////////
1013/// Double the number of bins for axis.
1014/// Refill histogram
1015/// This function is called by TAxis::FindBin(const char *label)
1016
1021
1022////////////////////////////////////////////////////////////////////////////////
1023/// Set option(s) to draw axis with labels.
1024///
1025/// option might have the following values:
1026///
1027/// - "a" sort by alphabetic order
1028/// - ">" sort by decreasing values
1029/// - "<" sort by increasing values
1030/// - "h" draw labels horizontal
1031/// - "v" draw labels vertical
1032/// - "u" draw labels up (end of label right adjusted)
1033/// - "d" draw labels down (start of label left adjusted)
1034
1036{
1037
1038 TAxis *axis = GetXaxis();
1039 if (ax[0] == 'y' || ax[0] == 'Y') axis = GetYaxis();
1040 THashList *labels = axis->GetLabels();
1041 if (!labels) {
1042 Warning("LabelsOption","Cannot sort. No labels");
1043 return;
1044 }
1045 TString opt = option;
1046 opt.ToLower();
1047 if (opt.Contains("h")) {
1052 }
1053 if (opt.Contains("v")) {
1058 }
1059 if (opt.Contains("u")) {
1060 axis->SetBit(TAxis::kLabelsUp);
1064 }
1065 if (opt.Contains("d")) {
1070 }
1071 Int_t sort = -1;
1072 if (opt.Contains("a")) sort = 0;
1073 if (opt.Contains(">")) sort = 1;
1074 if (opt.Contains("<")) sort = 2;
1075 if (sort < 0) return;
1076
1077 // support only cases where each bin has a labels (should be when axis is alphanumeric)
1078 Int_t n = labels->GetSize();
1079 if (n != axis->GetNbins()) {
1080 // check if labels are all consecutive and starts from the first bin
1081 // in that case the current code will work fine
1082 Int_t firstLabelBin = axis->GetNbins() + 1;
1083 Int_t lastLabelBin = -1;
1084 for (Int_t i = 0; i < n; ++i) {
1085 Int_t bin = labels->At(i)->GetUniqueID();
1086 if (bin < firstLabelBin)
1087 firstLabelBin = bin;
1088 if (bin > lastLabelBin)
1089 lastLabelBin = bin;
1090 }
1091 if (firstLabelBin != 1 || lastLabelBin - firstLabelBin + 1 != n) {
1092 Error("LabelsOption",
1093 "%s of TProfile2D %s contains bins without labels. Sorting will not work correctly - return",
1094 axis->GetName(), GetName());
1095 return;
1096 }
1097 // case where label bins are consecutive starting from first bin will work
1098 Warning(
1099 "LabelsOption",
1100 "axis %s of TProfile2D %s has extra following bins without labels. Sorting will work only for first label bins",
1101 axis->GetName(), GetName());
1102 }
1103
1104 std::vector<Int_t> a(n);
1105 Int_t i, j, k, ibin, bin;
1106 std::vector<Double_t> sumw(fNcells);
1107 std::vector<Double_t> errors(fNcells);
1108 std::vector<Double_t> ent(fNcells);
1109 std::vector<Double_t> binsw2;
1110 if (fBinSumw2.fN)
1111 binsw2.resize(fNcells);
1112
1113 // delete buffer if it is there since bins will be reordered.
1114 if (fBuffer)
1115 BufferEmpty(1);
1116
1117 // number of bins to loop
1118 Int_t nx = (axis == GetXaxis()) ? n + 1 : fXaxis.GetNbins() + 2;
1119 Int_t ny = (axis == GetYaxis()) ? n + 1 : fYaxis.GetNbins() + 2;
1120
1121 // make a labelold list but ordered with bins
1122 // (re-ordered original label list)
1123 std::vector<TObject *> labold(n);
1124 for (i = 0; i < n; i++)
1125 labold[i] = nullptr;
1126 TIter nextold(labels);
1127 TObject *obj;
1128 while ((obj = nextold())) {
1129 bin = obj->GetUniqueID();
1130 if (bin>=1 && bin<=n)
1131 labold[bin-1] = obj;
1132 }
1133 // order now labold according to bin content
1134
1135 labels->Clear();
1136
1137 std::vector<Double_t> pcont;
1138 std::vector<Double_t> econt;
1139 if (sort > 0) {
1140 pcont.resize(n);
1141 econt.resize(n);
1142 }
1143
1144 for (i = 0; i < nx; i++) {
1145 for (j = 0; j < ny; j++) {
1146 bin = GetBin(i, j);
1147 sumw[bin] = fArray[bin];
1148 errors[bin] = fSumw2.fArray[bin];
1149 ent[bin] = fBinEntries.fArray[bin];
1150 if (fBinSumw2.fN)
1151 binsw2[bin] = fBinSumw2.fArray[bin];
1152 if (axis == GetXaxis())
1153 k = i - 1;
1154 else
1155 k = j - 1;
1156 //---when sorting by values of bins
1157 if (sort > 0 && fBinEntries.fArray[bin] != 0 && k > 0 && k < n) {
1158 pcont[k] += fArray[bin];
1159 econt[k] += fBinEntries.fArray[bin];
1160 }
1161 }
1162 }
1163 // compute average of slize for ordering
1164 if (sort > 0) {
1165 for (k = 0; k < n; ++k) {
1166 a[k] = k;
1167 if (econt[k] > 0)
1168 pcont[k] /= econt[k];
1169 }
1170 if (sort == 1)
1171 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
1172 else
1173 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
1174 } else {
1175 //---alphabetic sort
1176 // sort labels using vector of strings and TMath::Sort
1177 // I need to array because labels order in list is not necessary that of the bins
1178 std::vector<std::string> vecLabels(n);
1179 for (i = 0; i < n; i++) {
1180 vecLabels[i] = labold[i]->GetName();
1181 a[i] = i;
1182 }
1183 // sort in ascending order for strings
1184 TMath::Sort(n, vecLabels.data(), a.data(), kFALSE);
1185 }
1186
1187 // set the new labels
1188 for (i = 0; i < n; i++) {
1189 obj = labold[a[i]];
1190 labels->Add(obj);
1191 // set the corresponding bin. NB bin starts from 1
1192 obj->SetUniqueID(i + 1);
1193 if (gDebug)
1194 std::cout << "bin " << i + 1 << " setting new labels for axis " << labold.at(a[i])->GetName() << " from "
1195 << a[i] << std::endl;
1196 }
1197 // set the new content
1198 for (i = 0; i < nx; i++) {
1199 for (j = 0; j < ny; j++) {
1200 bin = GetBin(i, j);
1201 if (axis == GetXaxis()) {
1202 if (i == 0) break; // skip underflow in x
1203 ibin = GetBin(a[i - 1] + 1, j);
1204 } else {
1205 if (j == 0) continue; // skip underflow in y
1206 ibin = GetBin(i, a[j-1] + 1);
1207 }
1208 fArray[bin] = sumw[ibin];
1209 fSumw2.fArray[bin] = errors[ibin];
1210 fBinEntries.fArray[bin] = ent[ibin];
1211 if (fBinSumw2.fN)
1212 fBinSumw2.fArray[bin] = binsw2[ibin];
1213 }
1214 }
1215 // need to set to zero the statistics if axis has been sorted
1216 // see for example TH3::PutStats for definition of s vector
1217 bool labelsAreSorted = kFALSE;
1218 for (i = 0; i < n; ++i) {
1219 if (a[i] != i) {
1221 break;
1222 }
1223 }
1224 if (labelsAreSorted) {
1225 double s[TH1::kNstat];
1226 GetStats(s);
1227 if (axis == GetXaxis()) {
1228 s[2] = 0; // fTsumwx
1229 s[3] = 0; // fTsumwx2
1230 s[6] = 0; // fTsumwxy
1231 } else {
1232 s[4] = 0; // fTsumwy
1233 s[5] = 0; // fTsumwy2
1234 s[6] = 0; // fTsumwxy
1235 }
1236 PutStats(s);
1237 }
1238}
1239
1240////////////////////////////////////////////////////////////////////////////////
1241/// Merge all histograms in the collection in this histogram.
1242/// This function computes the min/max for the axes,
1243/// compute a new number of bins, if necessary,
1244/// add bin contents, errors and statistics.
1245/// If overflows are present and limits are different the function will fail.
1246/// The function returns the total number of entries in the result histogram
1247/// if the merge is successful, -1 otherwise.
1248///
1249/// IMPORTANT remark. The 2 axis x and y may have different number
1250/// of bins and different limits, BUT the largest bin width must be
1251/// a multiple of the smallest bin width and the upper limit must also
1252/// be a multiple of the bin width.
1253
1258
1259////////////////////////////////////////////////////////////////////////////////
1260/// Performs the operation: this = this*c1*f1
1261
1263{
1264 Error("Multiply","Function not implemented for TProfile2D");
1265 return kFALSE;
1266}
1267
1268////////////////////////////////////////////////////////////////////////////////
1269/// Multiply this profile2D by h1.
1270///
1271/// `this = this*h1`
1272
1274{
1275 Error("Multiply","Multiplication of profile2D histograms not implemented");
1276 return kFALSE;
1277}
1278
1279////////////////////////////////////////////////////////////////////////////////
1280/// Replace contents of this profile2D by multiplication of h1 by h2.
1281///
1282/// `this = (c1*h1)*(c2*h2)`
1283
1285{
1286 Error("Multiply","Multiplication of profile2D histograms not implemented");
1287 return kFALSE;
1288}
1289
1290////////////////////////////////////////////////////////////////////////////////
1291/// Project this profile2D into a 2-D histogram along X,Y.
1292///
1293/// The projection is always of the type TH2D.
1294///
1295/// - if option "E" is specified the errors of the projected histogram are computed and set
1296/// to be equal to the errors of the profile.
1297/// Option "E" is defined as the default one in the header file.
1298/// - if option "" is specified the histogram errors are simply the sqrt of its content
1299/// - if option "B" is specified, the content of bin of the returned histogram
1300/// will be equal to the GetBinEntries(bin) of the profile,
1301/// - if option "C=E" the bin contents of the projection are set to the
1302/// bin errors of the profile
1303/// - if option "W" is specified the bin content of the projected histogram is set to the
1304/// product of the bin content of the profile and the entries.
1305/// With this option the returned histogram will be equivalent to the one obtained by
1306/// filling directly a TH2D using the 3-rd value as a weight.
1307/// This option makes sense only for profile filled with all weights =1.
1308/// When the profile is weighted (filled with weights different than 1) the
1309/// bin error of the projected histogram (obtained using this option "W") cannot be
1310/// correctly computed from the information stored in the profile. In that case the
1311/// obtained histogram contains as bin error square the weighted sum of the square of the
1312/// profiled observable (TProfile2D::fSumw2[bin] )
1313
1315{
1316
1317 TString opt = option;
1318 opt.ToLower();
1319
1320 // Create the projection histogram
1321 // name of projected histogram is by default name of original histogram + _pxy
1323 if (pname.IsNull() || pname == "_pxy")
1324 pname = TString(GetName() ) + TString("_pxy");
1325
1326
1327 Int_t nx = fXaxis.GetNbins();
1328 Int_t ny = fYaxis.GetNbins();
1329 const TArrayD *xbins = fXaxis.GetXbins();
1330 const TArrayD *ybins = fYaxis.GetXbins();
1331 TH2D * h1 = nullptr;
1332 if (xbins->fN == 0 && ybins->fN == 0) {
1334 } else if (xbins->fN == 0) {
1335 h1 = new TH2D(pname,GetTitle(),nx,fXaxis.GetXmin(),fXaxis.GetXmax(),ny, ybins->GetArray() );
1336 } else if (ybins->fN == 0) {
1337 h1 = new TH2D(pname,GetTitle(),nx,xbins->GetArray(),ny,fYaxis.GetXmin(),fYaxis.GetXmax());
1338 } else {
1339 h1 = new TH2D(pname,GetTitle(),nx,xbins->GetArray(),ny,ybins->GetArray() );
1340 }
1341 fXaxis.Copy(*h1->GetXaxis());
1342 fYaxis.Copy(*h1->GetYaxis());
1347 if (opt.Contains("b")) binEntries = kTRUE;
1348 if (opt.Contains("e")) computeErrors = kTRUE;
1349 if (opt.Contains("w")) binWeight = kTRUE;
1350 if (opt.Contains("c=e")) {cequalErrors = kTRUE; computeErrors=kFALSE;}
1352
1353 // Fill the projected histogram
1354 Int_t bin,binx, biny;
1355 Double_t cont;
1356 for (binx =0;binx<=nx+1;binx++) {
1357 for (biny =0;biny<=ny+1;biny++) {
1358 bin = GetBin(binx,biny);
1359
1360 if (binEntries) cont = GetBinEntries(bin);
1361 else if (cequalErrors) cont = GetBinError(bin);
1362 else if (binWeight) cont = GetBinContent(bin) * GetBinEntries(bin);
1363 else cont = GetBinContent(bin); // default case
1364
1365 h1->SetBinContent(bin ,cont);
1366
1367 // if option E projected histogram errors are same as profile
1368 if (computeErrors ) h1->SetBinError(bin , GetBinError(bin) );
1369 // in case of option W bin error is deduced from bin sum of z**2 values of profile
1370 // this is correct only if the profile is unweighted
1371 if (binWeight) h1->GetSumw2()->fArray[bin] = fSumw2.fArray[bin];
1372 // in case of bin entries and profile is weighted, we need to set also the bin error
1373 if (binEntries && fBinSumw2.fN ) {
1374 R__ASSERT( h1->GetSumw2() );
1375 h1->GetSumw2()->fArray[bin] = fBinSumw2.fArray[bin];
1376 }
1377 }
1378 }
1380 return h1;
1381}
1382
1383////////////////////////////////////////////////////////////////////////////////
1384/// Project a 2-D histogram into a profile histogram along X.
1385///
1386/// The projection is made from the channels along the Y axis
1387/// ranging from firstybin to lastybin included.
1388/// The result is a 1D profile which contains the combination of all the considered bins along Y
1389/// By default, bins 1 to ny are included
1390/// When all bins are included, the number of entries in the projection
1391/// is set to the number of entries of the 2-D histogram, otherwise
1392/// the number of entries is incremented by 1 for all non empty cells.
1393///
1394/// The option can also be used to specify the projected profile error type.
1395/// Values which can be used are 's', 'i', or 'g'. See TProfile::BuildOptions for details
1396
1401
1402////////////////////////////////////////////////////////////////////////////////
1403/// Project a 2-D histogram into a profile histogram along X
1404///
1405/// The projection is made from the channels along the X axis
1406/// ranging from firstybin to lastybin included.
1407/// The result is a 1D profile which contains the combination of all the considered bins along X
1408/// By default, bins 1 to ny are included
1409/// When all bins are included, the number of entries in the projection
1410/// is set to the number of entries of the 2-D histogram, otherwise
1411/// the number of entries is incremented by 1 for all non empty cells.
1412///
1413/// The option can also be used to specify the projected profile error type.
1414/// Values which can be used are 's', 'i', or 'g'. See TProfile::BuildOptions for details
1415
1420
1421////////////////////////////////////////////////////////////////////////////////
1422/// Implementation of ProfileX or ProfileY for a TProfile2D.
1423///
1424/// Do correctly the combination of the bin averages when doing the projection
1425
1427 TString opt = option;
1428 opt.ToLower();
1429 bool originalRange = opt.Contains("o");
1430
1431 TString expectedName = ( onX ? "_pfx" : "_pfy" );
1432
1434 if (pname.IsNull() || name == expectedName)
1436
1437 const TAxis& outAxis = ( onX ? fXaxis : fYaxis );
1438 const TArrayD *bins = outAxis.GetXbins();
1439 Int_t firstOutBin = outAxis.GetFirst();
1440 Int_t lastOutBin = outAxis.GetLast();
1441
1442 TProfile * p1 = nullptr;
1443 // case of fixed bins
1444 if (bins->fN == 0) {
1445 if (originalRange)
1446 p1 = new TProfile(pname,GetTitle(), outAxis.GetNbins(), outAxis.GetXmin(), outAxis.GetXmax(), opt );
1447 else
1449 outAxis.GetBinLowEdge(firstOutBin),outAxis.GetBinUpEdge(lastOutBin), opt);
1450 } else {
1451 // case of variable bins
1452 if (originalRange )
1453 p1 = new TProfile(pname,GetTitle(),outAxis.GetNbins(),bins->fArray,opt);
1454 else
1456
1457 }
1458
1459 if (fBinSumw2.fN) p1->Sumw2();
1460
1461 // make projection in a 2D first
1462 TH2D * h2dW = ProjectionXY("h2temp-W","W");
1463 TH2D * h2dN = ProjectionXY("h2temp-N","B");
1464
1465 h2dW->SetDirectory(nullptr); h2dN->SetDirectory(nullptr);
1466
1467
1468 TString opt1 = (originalRange) ? "o" : "";
1469 TH1D * h1W = (onX) ? h2dW->ProjectionX("h1temp-W",firstbin,lastbin,opt1) : h2dW->ProjectionY("h1temp-W",firstbin,lastbin,opt1);
1470 TH1D * h1N = (onX) ? h2dN->ProjectionX("h1temp-N",firstbin,lastbin,opt1) : h2dN->ProjectionY("h1temp-N",firstbin,lastbin,opt1);
1471 h1W->SetDirectory(nullptr); h1N->SetDirectory(nullptr);
1472
1473
1474 // fill the bin content
1475 R__ASSERT( h1W->fN == p1->fN );
1476 R__ASSERT( h1N->fN == p1->fN );
1477 R__ASSERT( h1W->GetSumw2()->fN != 0); // h1W should always be a weighted histogram since h2dW is
1478 for (int i = 0; i < p1->fN ; ++i) {
1479 p1->fArray[i] = h1W->GetBinContent(i); // array of profile is sum of all values
1480 p1->GetSumw2()->fArray[i] = h1W->GetSumw2()->fArray[i]; // array of content square of profile is weight square of the W projected histogram
1481 p1->SetBinEntries(i, h1N->GetBinContent(i) );
1482 if (fBinSumw2.fN) p1->GetBinSumw2()->fArray[i] = h1N->GetSumw2()->fArray[i]; // sum of weight squares are stored to compute errors in h1N histogram
1483 }
1484 // delete the created histograms
1485 delete h2dW;
1486 delete h2dN;
1487 delete h1W;
1488 delete h1N;
1489
1490 // Also we need to set the entries since they have not been correctly calculated during the projection
1491 // we can only set them to the effective entries
1492 p1->SetEntries( p1->GetEffectiveEntries() );
1493
1494 return p1;
1495}
1496
1497
1498////////////////////////////////////////////////////////////////////////////////
1499/// Replace current statistics with the values in array stats
1500
1502{
1503 fTsumw = stats[0];
1504 fTsumw2 = stats[1];
1505 fTsumwx = stats[2];
1506 fTsumwx2 = stats[3];
1507 fTsumwy = stats[4];
1508 fTsumwy2 = stats[5];
1509 fTsumwxy = stats[6];
1510 fTsumwz = stats[7];
1511 fTsumwz2 = stats[8];
1512}
1513
1514////////////////////////////////////////////////////////////////////////////////
1515/// Reset contents of a Profile2D histogram.
1516
1518{
1521 fBinSumw2.Reset();
1522 TString opt = option;
1523 opt.ToUpper();
1524 if (opt.Contains("ICE") && !opt.Contains("S")) return;
1525 fTsumwz = fTsumwz2 = 0;
1526}
1527
1528
1529////////////////////////////////////////////////////////////////////////////////
1530/// Profile histogram is resized along axis such that x is in the axis range.
1531///
1532/// The new axis limits are recomputed by doubling iteratively
1533/// the current axis range until the specified value x is within the limits.
1534/// The algorithm makes a copy of the histogram, then loops on all bins
1535/// of the old histogram to fill the extended histogram.
1536/// Takes into account errors (Sumw2) if any.
1537/// The axis must be extendable before invoking this function.
1538///
1539/// Ex: `h->GetXaxis()->SetCanExtend(kTRUE)`
1540
1542{
1544 if ( hold ) {
1545 fTsumwz = hold->fTsumwz;
1546 fTsumwz2 = hold->fTsumwz2;
1547 delete hold;
1548 }
1549}
1550
1551////////////////////////////////////////////////////////////////////////////////
1552/// Rebin this histogram grouping nxgroup/nygroup bins along the xaxis/yaxis together.
1553///
1554/// if newname is not blank a new profile hnew is created.
1555/// else the current histogram is modified (default)
1556/// The parameter nxgroup/nygroup indicate how many bins along the xaxis/yaxis of this
1557/// have to be merged into one bin of hnew
1558/// If the original profile has errors stored (via Sumw2), the resulting
1559/// profile has new errors correctly calculated.
1560///
1561/// examples: if hpxpy is an existing TProfile2D profile with 40 x 40 bins
1562/// ~~~ {.cpp}
1563/// hpxpy->Rebin2D(); // merges two bins along the xaxis and yaxis in one
1564/// // Carefull: previous contents of hpxpy are lost
1565/// hpxpy->Rebin2D(3,5); // merges 3 bins along the xaxis and 5 bins along the yaxis in one
1566/// // Carefull: previous contents of hpxpy are lost
1567/// hpxpy->RebinX(5); //merges five bins along the xaxis in one in hpxpy
1568/// TProfile2D *hnew = hpxpy->RebinY(5,"hnew"); // creates a new profile hnew
1569/// // merging 5 bins of hpxpy along the yaxis in one bin
1570/// ~~~
1571///
1572/// NOTE : If nxgroup/nygroup is not an exact divider of the number of bins,
1573/// along the xaxis/yaxis the top limit(s) of the rebinned profile
1574/// is changed to the upper edge of the xbin=newxbins*nxgroup resp.
1575/// ybin=newybins*nygroup and the remaining bins are added to
1576/// the overflow bin.
1577/// Statistics will be recomputed from the new bin contents.
1578
1580 //something to do?
1581 if((nxgroup != 1) || (nygroup != 1)){
1588 if ((nxgroup <= 0) || (nxgroup > nxbins)) {
1589 Error("Rebin", "Illegal value of nxgroup=%d",nxgroup);
1590 return nullptr;
1591 }
1592 if ((nygroup <= 0) || (nygroup > nybins)) {
1593 Error("Rebin", "Illegal value of nygroup=%d",nygroup);
1594 return nullptr;
1595 }
1596
1599
1600 //warning if bins are added to the overflow bin
1601 if(newxbins*nxgroup != nxbins) {
1602 Warning("Rebin", "nxgroup=%d should be an exact divider of nxbins=%d",nxgroup,nxbins);
1603 }
1604 if(newybins*nygroup != nybins) {
1605 Warning("Rebin", "nygroup=%d should be an exact divider of nybins=%d",nygroup,nybins);
1606 }
1607
1608 //save old bin contents in new arrays
1609 Double_t *oldBins = new Double_t[(nxbins+2)*(nybins+2)];
1610 Double_t *oldCount = new Double_t[(nxbins+2)*(nybins+2)];
1611 Double_t *oldErrors = new Double_t[(nxbins+2)*(nybins+2)];
1612 Double_t *oldBinw2 = (fBinSumw2.fN ? new Double_t[(nxbins+2)*(nybins+2)] : nullptr );
1613 Double_t *cu1 = GetW();
1614 Double_t *er1 = GetW2();
1615 Double_t *en1 = GetB();
1616 Double_t *ew1 = GetB2();
1617 for(Int_t ibin=0; ibin < (nxbins+2)*(nybins+2); ibin++){
1618 oldBins[ibin] = cu1[ibin];
1619 oldCount[ibin] = en1[ibin];
1620 oldErrors[ibin] = er1[ibin];
1621 if (ew1 && fBinSumw2.fN) oldBinw2[ibin] = ew1[ibin];
1622 }
1623
1624 // create a clone of the old profile if newname is specified
1625 TProfile2D *hnew = this;
1626 if(newname && strlen(newname) > 0) {
1628 }
1629
1630 // in case of nxgroup/nygroup not an exact divider of nxbins/nybins,
1631 // top limit is changed (see NOTE in method comment)
1632 if(newxbins*nxgroup != nxbins) {
1634 hnew->fTsumw = 0; //stats must be reset because top bins will be moved to overflow bin
1635 }
1636 if(newybins*nygroup != nybins) {
1638 hnew->fTsumw = 0; //stats must be reset because top bins will be moved to overflow bin
1639 }
1640
1641 //rebin the axis
1642 if((fXaxis.GetXbins()->GetSize() > 0) || (fYaxis.GetXbins()->GetSize() > 0)){
1643 Double_t* xbins = new Double_t[newxbins+1];
1644 Double_t* ybins = new Double_t[newybins+1];
1645 for(Int_t i=0; i < newxbins+1; i++)
1646 xbins[i] = fXaxis.GetBinLowEdge(1+i*nxgroup);
1647 for(Int_t j=0; j < newybins+1; j++)
1649 hnew->SetBins(newxbins,xbins,newybins,ybins);
1650 delete [] xbins;
1651 delete [] ybins;
1652 }
1653 //fixed bin size
1654 else{
1656 }
1657
1658 //merge bins
1659 Double_t *cu2 = hnew->GetW();
1660 Double_t *er2 = hnew->GetW2();
1661 Double_t *en2 = hnew->GetB();
1662 Double_t *ew2 = hnew->GetB2();
1664 //connection between x and y bin number and linear global bin number:
1665 //global bin = xbin + (nxbins+2) * ybin
1666 Int_t oldxbin = 1;
1667 Int_t oldybin = 1;
1668 //global bin number
1669 Int_t bin;
1670 for(Int_t xbin = 1; xbin <= newxbins; xbin++){
1671 oldybin = 1;
1672 for(Int_t ybin = 1; ybin <= newybins; ybin++){
1673 binContent = 0;
1674 binCount = 0;
1675 binError = 0;
1676 binSumw2 = 0;
1677 for(Int_t i=0; i < nxgroup; i++){
1678 if(oldxbin + i > nxbins) break;
1679 for(Int_t j=0; j < nygroup; j++){
1680 if(oldybin + j > nybins) break;
1681 bin = oldxbin + i + (nxbins+2)*(oldybin+j);
1682 binContent += oldBins[bin];
1683 binCount += oldCount[bin];
1684 binError += oldErrors[bin];
1685 if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
1686 }
1687 }
1688 bin = xbin + (newxbins + 2)*ybin;
1689 cu2[bin] = binContent;
1690 er2[bin] = binError;
1691 en2[bin] = binCount;
1692 if(fBinSumw2.fN) ew2[bin] = binSumw2;
1693 oldybin += nygroup;
1694 }
1695 oldxbin += nxgroup;
1696 }
1697
1698 //copy the underflow bin in x and y (0,0)
1699 cu2[0] = oldBins[0];
1700 er2[0] = oldErrors[0];
1701 en2[0] = oldCount[0];
1702 if(fBinSumw2.fN) ew2[0] = oldBinw2[0];
1703 //calculate overflow bin in x and y (newxbins+1,newybins+1)
1704 //therefore the oldxbin and oldybin from above are needed!
1705 binContent = 0;
1706 binCount = 0;
1707 binError = 0;
1708 binSumw2 = 0;
1709 for(Int_t i=oldxbin; i <= nxbins+1; i++){
1710 for(Int_t j=oldybin; j <= nybins+1; j++){
1711 //global bin number
1712 bin = i + (nxbins+2)*j;
1713 binContent += oldBins[bin];
1714 binCount += oldCount[bin];
1715 binError += oldErrors[bin];
1716 if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
1717 }
1718 }
1719 bin = (newxbins+2)*(newybins+2)-1;
1720 cu2[bin] = binContent;
1721 er2[bin] = binError;
1722 en2[bin] = binCount;
1723 if(fBinSumw2.fN) ew2[bin] = binSumw2;
1724 //calculate overflow bin in x and underflow bin in y (newxbins+1,0)
1725 binContent = 0;
1726 binCount = 0;
1727 binError = 0;
1728 binSumw2 = 0;
1729 for(Int_t i=oldxbin; i <= nxbins+1; i++){
1730 bin = i;
1731 binContent += oldBins[bin];
1732 binCount += oldCount[bin];
1733 binError += oldErrors[bin];
1734 if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
1735 }
1736 bin = newxbins + 1;
1737 cu2[bin] = binContent;
1738 er2[bin] = binError;
1739 en2[bin] = binCount;
1740 if(fBinSumw2.fN) ew2[bin] = binSumw2;
1741 //calculate underflow bin in x and overflow bin in y (0,newybins+1)
1742 binContent = 0;
1743 binCount = 0;
1744 binError = 0;
1745 binSumw2 = 0;
1746 for(Int_t i=oldybin; i <= nybins+1; i++){
1747 bin = i*(nxbins + 2);
1748 binContent += oldBins[bin];
1749 binCount += oldCount[bin];
1750 binError += oldErrors[bin];
1751 if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
1752 }
1753 bin = (newxbins + 2)*(newybins + 1);
1754 cu2[bin] = binContent;
1755 er2[bin] = binError;
1756 en2[bin] = binCount;
1757 if(fBinSumw2.fN) ew2[bin] = binSumw2;
1758 //calculate under/overflow contents in y for the new x bins
1761 Int_t ufbin, ofbin;
1762 Int_t oldxbin2 = 1;
1763 for(Int_t xbin = 1; xbin <= newxbins; xbin++){
1764 binContentuf = 0;
1765 binCountuf = 0;
1766 binErroruf = 0;
1767 binSumw2uf = 0;
1768 binContentof = 0;
1769 binCountof = 0;
1770 binErrorof = 0;
1771 binSumw2of = 0;
1772 for(Int_t i = 0; i < nxgroup; i++){
1773 //index of under/overflow bin for y in old binning
1774 ufbin = (oldxbin2 + i);
1779 for(Int_t j = oldybin; j <= nybins+1; j++)
1780 {
1781 ofbin = ufbin + j*(nxbins + 2);
1786 }
1787 }
1788 //index of under/overflow bin for y in new binning
1789 ufbin = xbin;
1790 ofbin = ufbin + (newybins + 1)*(newxbins + 2);
1792 er2[ufbin] = binErroruf;
1793 en2[ufbin] = binCountuf;
1796 er2[ofbin] = binErrorof;
1797 en2[ofbin] = binCountof;
1799
1800 oldxbin2 += nxgroup;
1801 }
1802 //calculate under/overflow contents in x for the new y bins
1803 Int_t oldybin2 = 1;
1804 for(Int_t ybin = 1; ybin <= newybins; ybin++){
1805 binContentuf = 0;
1806 binCountuf = 0;
1807 binErroruf = 0;
1808 binSumw2uf = 0;
1809 binContentof = 0;
1810 binCountof = 0;
1811 binErrorof = 0;
1812 binSumw2of = 0;
1813 for(Int_t i = 0; i < nygroup; i++){
1814 //index of under/overflow bin for x in old binning
1815 ufbin = (oldybin2 + i)*(nxbins+2);
1820 for(Int_t j = oldxbin; j <= nxbins+1; j++)
1821 {
1822 ofbin = j + ufbin;
1827 }
1828 }
1829 //index of under/overflow bin for x in new binning
1830 ufbin = ybin * (newxbins + 2);
1831 ofbin = newxbins + 1 + ufbin;
1833 er2[ufbin] = binErroruf;
1834 en2[ufbin] = binCountuf;
1837 er2[ofbin] = binErrorof;
1838 en2[ofbin] = binCountof;
1840
1841 oldybin2 += nygroup;
1842 }
1843
1844 delete [] oldBins;
1845 delete [] oldCount;
1846 delete [] oldErrors;
1847 if (oldBinw2) delete [] oldBinw2;
1848
1849 return hnew;
1850 }
1851 //nxgroup == nygroup == 1
1852 else{
1853 if(newname && (strlen(newname) > 0))
1854 return (TProfile2D*)Clone(newname);
1855 else
1856 return this;
1857 }
1858}
1859
1860////////////////////////////////////////////////////////////////////////////////
1861/// Rebin only the X axis.
1862/// see Rebin2D
1863
1865 return Rebin2D(ngroup,1,newname);
1866}
1867
1868////////////////////////////////////////////////////////////////////////////////
1869/// Rebin only the Y axis.
1870/// see Rebin2D
1871
1873 return Rebin2D(1,ngroup,newname);
1874}
1875
1876////////////////////////////////////////////////////////////////////////////////
1877/// Save primitive as a C++ statement(s) on output stream out.
1878
1879void TProfile2D::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1880{
1882
1884
1885 out << " \n";
1886
1887 // Check if the profile has equidistant X bins or not. If not, we
1888 // create an array holding the bins.
1889 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray)
1890 sxaxis = SavePrimitiveVector(out, hname + "_x", GetXaxis()->GetXbins()->fN, GetXaxis()->GetXbins()->fArray);
1891
1892 // Check if the profile has equidistant y bins or not. If not, we
1893 // create an array holding the bins.
1894 if (GetYaxis()->GetXbins()->fN && GetYaxis()->GetXbins()->fArray)
1895 syaxis = SavePrimitiveVector(out, hname + "_y", GetYaxis()->GetXbins()->fN, GetYaxis()->GetXbins()->fArray);
1896
1897 out << " " << ClassName() << " *" << hname << " = new " << ClassName() << "(\"" << hname << "\", \""
1898 << TString(GetTitle()).ReplaceSpecialCppChars() << "\", " << GetXaxis()->GetNbins() << ", ";
1899 if (!sxaxis.IsNull())
1900 out << sxaxis << ".data()";
1901 else
1902 out << GetXaxis()->GetXmin() << ", " << GetXaxis()->GetXmax();
1903
1904 out << ", " << GetYaxis()->GetNbins() << ", ";
1905 if (!syaxis.IsNull())
1906 out << syaxis << ".data()";
1907 else
1908 out << GetYaxis()->GetXmin() << ", " << GetYaxis()->GetXmax();
1909
1910 if (sxaxis.IsNull() && syaxis.IsNull())
1911 out << ", " << fZmin << ", " << fZmax;
1912
1913 out << ", \"" << TString(GetErrorOption()).ReplaceSpecialCppChars() << "\");\n";
1914
1916 Int_t numentries = 0, numcontent = 0, numerrors = 0;
1917
1918 std::vector<Double_t> entries(fNcells), content(fNcells), errors(save_errors ? fNcells : 0);
1919 for (Int_t bin = 0; bin < fNcells; bin++) {
1920 entries[bin] = GetBinEntries(bin);
1921 if (entries[bin])
1922 numentries++;
1923 content[bin] = fArray[bin];
1924 if (content[bin])
1925 numcontent++;
1926 if (save_errors) {
1927 errors[bin] = TMath::Sqrt(fSumw2.fArray[bin]);
1928 if (errors[bin])
1929 numerrors++;
1930 }
1931 }
1932
1933 if ((numentries < 100) && (numcontent < 100) && (numerrors < 100)) {
1934 // in case of few non-empty bins store them as before
1935 for (Int_t bin = 0; bin < fNcells; bin++) {
1936 if (entries[bin])
1937 out << " " << hname << "->SetBinEntries(" << bin << "," << entries[bin] << ");\n";
1938 }
1939 for (Int_t bin = 0; bin < fNcells; bin++) {
1940 if (content[bin])
1941 out << " " << hname << "->SetBinContent(" << bin << "," << content[bin] << ");\n";
1942 }
1943 if (save_errors)
1944 for (Int_t bin = 0; bin < fNcells; bin++) {
1945 if (errors[bin])
1946 out << " " << hname << "->SetBinError(" << bin << "," << errors[bin] << ");\n";
1947 }
1948 } else {
1949 if (numentries > 0) {
1950 TString vect = SavePrimitiveVector(out, hname, fNcells, entries.data());
1951 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
1952 out << " if (" << vect << "[bin])\n";
1953 out << " " << hname << "->SetBinEntries(bin, " << vect << "[bin]);\n";
1954 }
1955 if (numcontent > 0) {
1957 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
1958 out << " if (" << vect << "[bin])\n";
1959 out << " " << hname << "->SetBinContent(bin, " << vect << "[bin]);\n";
1960 }
1961 if (numerrors > 0) {
1963 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
1964 out << " if (" << vect << "[bin])\n";
1965 out << " " << hname << "->SetBinError(bin, " << vect << "[bin]);\n";
1966 }
1967 }
1968
1970}
1971
1972////////////////////////////////////////////////////////////////////////////////
1973/// Multiply this profile2D by a constant c1.
1974///
1975/// `this = c1*this
1976///
1977/// This function uses the services of TProfile2D::Add
1978
1983
1984////////////////////////////////////////////////////////////////////////////////
1985/// Set the number of entries in bin.
1986
1991
1992////////////////////////////////////////////////////////////////////////////////
1993/// Redefine x and y axis parameters.
1994
2001
2002////////////////////////////////////////////////////////////////////////////////
2003/// Redefine x and y axis parameters for variable bin sizes.
2004
2006{
2007 TH1::SetBins(nx,xbins,ny,ybins);
2010}
2011
2012////////////////////////////////////////////////////////////////////////////////
2013/// Set total number of bins including under/overflow.
2014/// Reallocate bin contents array
2015
2021
2022////////////////////////////////////////////////////////////////////////////////
2023/// Set the buffer size in units of 8 bytes (double).
2024
2026{
2027 if (fBuffer) {
2028 BufferEmpty();
2029 delete [] fBuffer;
2030 fBuffer = nullptr;
2031 }
2032 if (bufsize <= 0) {
2033 fBufferSize = 0;
2034 return;
2035 }
2036 if (bufsize < 100) bufsize = 100;
2037 fBufferSize = 1 + 4*bufsize;
2040}
2041
2042////////////////////////////////////////////////////////////////////////////////
2043/// Set option to compute profile2D errors.
2044///
2045/// The computation of the bin errors is based on the parameter option:
2046/// - ' ' (Default) The bin errors are the standard error on the mean of the bin profiled values (Z),
2047/// i.e. the standard error of the bin contents.
2048/// Note that if TProfile::Approximate() is called, an approximation is used when
2049/// the spread in Z is 0 and the number of bin entries is > 0
2050/// - 's' The bin errors are the standard deviations of the Z bin values
2051/// Note that if TProfile::Approximate() is called, an approximation is used when
2052/// the spread in Z is 0 and the number of bin entries is > 0
2053/// - 'i' Errors are as in default case (standard errors of the bin contents)
2054/// The only difference is for the case when the spread in Z is zero.
2055/// In this case for N > 0 the error is 1./SQRT(12.*N)
2056/// - 'g' Errors are 1./SQRT(W) for W not equal to 0 and 0 for W = 0.
2057/// W is the sum in the bin of the weights of the profile.
2058/// This option is for combining measurements z +/- dz,
2059/// and the profile is filled with values y and weights z = 1/dz**2
2060///
2061/// See TProfile::BuildOptions for a detailed explanation of all options
2062
2067
2068////////////////////////////////////////////////////////////////////////////////
2069/// Stream an object of class TProfile2D.
2070
2072{
2073 if (R__b.IsReading()) {
2074 UInt_t R__s, R__c;
2075 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
2076 if (R__v > 2) {
2077 R__b.ReadClassBuffer(TProfile2D::Class(), this, R__v, R__s, R__c);
2078 return;
2079 }
2080 //====process old versions before automatic schema evolution
2084 R__b >> errorMode;
2086 if (R__v < 2) {
2087 Float_t zmin,zmax;
2088 R__b >> zmin; fZmin = zmin;
2089 R__b >> zmax; fZmax = zmax;
2090 } else {
2091 R__b >> fZmin;
2092 R__b >> fZmax;
2093 }
2094 R__b.CheckByteCount(R__s, R__c, TProfile2D::IsA());
2095 //====end of old versions
2096
2097 } else {
2098 R__b.WriteClassBuffer(TProfile2D::Class(),this);
2099 }
2100}
2101
2102////////////////////////////////////////////////////////////////////////////////
2103/// Create/Delete structure to store sum of squares of weights per bin.
2104///
2105/// This is needed to compute the correct statistical quantities
2106/// of a profile filled with weights
2107///
2108/// This function is automatically called when the histogram is created
2109/// if the static function TH1::SetDefaultSumw2 has been called before.
2110/// If flag is false the structure is deleted
2111
#define a(i)
Definition RSha256.hxx:99
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Version_t
Class version identifier (short)
Definition RtypesCore.h:79
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
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:125
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:110
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:627
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:481
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:210
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:292
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:521
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:472
Double_t GetXmin() const
Definition TAxis.h:141
Int_t GetNbins() const
Definition TAxis.h:127
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:531
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:461
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:927
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
@ kXaxis
Definition TH1.h:123
@ kYaxis
Definition TH1.h:124
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:543
@ kIsNotW
Histogram is forced to be not weighted even when the histogram is filled with weighted.
Definition TH1.h:411
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition TH1.cxx:6684
TAxis * GetXaxis()
Definition TH1.h:572
virtual Int_t GetNbinsX() const
Definition TH1.h:542
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:7290
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:9244
static Int_t fgBufferSize
! Default buffer size for automatic histograms
Definition TH1.h:176
TAxis * GetYaxis()
Definition TH1.h:573
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:7417
UInt_t GetAxisLabelStatus() const
Internal function used in TH1::Fill to see which axis is full alphanumeric, i.e.
Definition TH1.cxx:6723
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:9260
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:1979
@ kNstat
Size of statistics data (up to TProfile3D)
Definition TH1.h:423
Double_t fEntries
Number of entries.
Definition TH1.h:156
virtual TArrayD * GetSumw2()
Definition TH1.h:561
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:392
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx:2734
TAxis fYaxis
Y axis descriptor.
Definition TH1.h:152
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition TH1.cxx:8808
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:9061
virtual void SetEntries(Double_t n)
Definition TH1.h:640
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:4224
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH2.cxx:4213
void Copy(TObject &hnew) const override
Copy.
Definition TH2.cxx:4193
TH2D()
Constructor.
Definition TH2.cxx:4076
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:1046
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:354
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:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:475
static TString SavePrimitiveVector(std::ostream &out, const char *prefix, Int_t len, Double_t *arr, Bool_t empty_line=kFALSE)
Save array in the output stream "out" as vector.
Definition TObject.cxx:788
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:864
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:543
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:875
virtual TClass * IsA() const
Definition TObject.h:246
void ResetBit(UInt_t f)
Definition TObject.h:201
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()
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) .
TProfile2D * Rebin2D(Int_t nxgroup=2, Int_t nygroup=2, const char *newname="") override
Rebin this histogram grouping nxgroup/nygroup bins along the xaxis/yaxis together.
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:138
void ToLower()
Change string to lower-case.
Definition TString.cxx:1189
TString & ReplaceSpecialCppChars()
Find special characters which are typically used in printf() calls and replace them by appropriate es...
Definition TString.cxx:1121
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:712
void ToUpper()
Change string to upper case.
Definition TString.cxx:1202
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:640
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
Bool_t IsNaN(Double_t x)
Definition TMath.h:903
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
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:432
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124