Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TProfile3D.cxx
Go to the documentation of this file.
1// @(#)root/hist:$Id$
2// Author: Rene Brun 17/05/2006
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 "TProfile3D.h"
13#include "TProfile2D.h"
14#include "THashList.h"
15#include "TMath.h"
16#include "THLimitsFinder.h"
17#include <iostream>
18#include "TError.h"
19#include "TClass.h"
20
21#include "TProfileHelper.h"
22
24
25
26/** \class TProfile3D
27 \ingroup Histograms
28 Profile3D histograms are used to display the mean
29 value of T and its RMS for each cell in X,Y,Z.
30 Profile3D histograms are in many cases an
31 The inter-relation of three measured quantities X, Y, Z and T can always
32 be visualized by a four-dimensional histogram or scatter-plot;
33 its representation on the line-printer is not particularly
34 satisfactory, except for sparse data. If T is an unknown (but single-valued)
35 approximate function of X,Y,Z this function is displayed by a profile3D histogram with
36 much better precision than by a scatter-plot.
37
38 The following formulae show the cumulated contents (capital letters) and the values
39 displayed by the printing or plotting routines (small letters) of the elements for cell I, J.
40
41 2
42 H(I,J,K) = sum T E(I,J,K) = sum T
43 l(I,J,K) = sum l L(I,J,K) = sum l
44 h(I,J,K) = H(I,J,K)/L(I,J,K) s(I,J,K) = sqrt(E(I,J,K)/L(I,J,K)- h(I,J,K)**2)
45 e(I,J,K) = s(I,J,K)/sqrt(L(I,J,K))
46
47 In the special case where s(I,J,K) is zero (eg, case of 1 entry only in one cell)
48 e(I,J,K) is computed from the average of the s(I,J,K) for all cells,
49 if the static function TProfile3D::Approximate has been called.
50 This simple/crude approximation was suggested in order to keep the cell
51 during a fit operation. But note that this approximation is not the default behaviour.
52
53 Example of a profile3D histogram
54~~~~{.cpp}
55{
56 auto c1 = new TCanvas("c1","Profile histogram example",200,10,700,500);
57 auto hprof3d = new TProfile3D("hprof3d","Profile of pt versus px, py and pz",40,-4,4,40,-4,4,40,0,20);
58 Double_t px, py, pz, pt;
59 TRandom3 r(0);
60 for ( Int_t i=0; i<25000; i++) {
61 r.Rannor(px,py);
62 pz = px*px + py*py;
63 pt = r.Landau(0,1);
64 hprof3d->Fill(px,py,pz,pt,1);
65 }
66 hprof3d->Draw();
67}
68~~~~
69 NOTE: A TProfile3D is drawn as it was a simple TH3
70*/
71
72////////////////////////////////////////////////////////////////////////////////
73/// Default constructor for Profile3D histograms.
74
76{
77 fTsumwt = fTsumwt2 = 0;
79 BuildOptions(0,0,"");
80}
81
82////////////////////////////////////////////////////////////////////////////////
83/// Default destructor for Profile3D histograms.
84
88
89////////////////////////////////////////////////////////////////////////////////
90/// Normal Constructor for Profile histograms.
91///
92/// The first eleven parameters are similar to TH3D::TH3D.
93/// All values of t are accepted at filling time.
94/// To fill a profile3D histogram, one must use TProfile3D::Fill function.
95///
96/// Note that when filling the profile histogram the function Fill
97/// checks if the variable t is between fTmin and fTmax.
98/// If a minimum or maximum value is set for the T scale before filling,
99/// then all values below tmin or above tmax will be discarded.
100/// Setting the minimum or maximum value for the T scale before filling
101/// has the same effect as calling the special TProfile3D constructor below
102/// where tmin and tmax are specified.
103///
104/// H(I,J,K) is printed as the cell contents. The errors computed are s(I,J,K) if CHOPT='S'
105/// (spread option), or e(I,J,K) if CHOPT=' ' (error on mean).
106///
107/// See TProfile3D::BuildOptions for explanation of parameters
108///
109/// see other constructors below with all possible combinations of
110/// fix and variable bin size like in TH3D.
111
113 : TH3D(name,title,nx,xlow,xup,ny,ylow,yup,nz,zlow,zup)
114{
115 BuildOptions(0,0,option);
116 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
117}
118
119////////////////////////////////////////////////////////////////////////////////
120/// Create a 3-D Profile with variable bins in X , Y and Z.
121
122TProfile3D::TProfile3D(const char *name,const char *title,Int_t nx,const Double_t *xbins,Int_t ny,const Double_t *ybins,Int_t nz,const Double_t *zbins,Option_t *option)
123 : TH3D(name,title,nx,xbins,ny,ybins,nz,zbins)
124{
125 BuildOptions(0,0,option);
126}
127
128////////////////////////////////////////////////////////////////////////////////
129/// Set Profile3D histogram structure and options.
130///
131/// - tmin: minimum value allowed for t
132/// - tmax: maximum value allowed for t
133/// if (tmin = tmax = 0) there are no limits on the allowed t values (tmin = -inf, tmax = +inf)
134///
135/// - option: this is the option for the computation of the t error of the profile ( TProfile3D::GetBinError )
136/// possible values for the options are documented in TProfile3D::SetErrorOption
137///
138/// see also TProfile::BuildOptions for a detailed description
139
141{
143
144 // create extra profile data structure (bin entries/ y^2 and sum of weight square)
146
147 fTmin = tmin;
148 fTmax = tmax;
150 fTsumwt = fTsumwt2 = 0;
151}
152
153////////////////////////////////////////////////////////////////////////////////
154/// Copy constructor.
155
157{
158 profile3d.TProfile3D::Copy(*this);
159}
160
162{
163 if (this != &profile3d)
164 profile3d.TProfile3D::Copy(*this);
165 return *this;
166}
167
168////////////////////////////////////////////////////////////////////////////////
169/// Performs the operation: `this = this + c1*f1` .
170
172{
173 Error("Add","Function not implemented for TProfile3D");
174 return kFALSE;
175}
176
177////////////////////////////////////////////////////////////////////////////////
178/// Performs the operation: `this = this + c1*h1` .
179
181{
182 if (!h1) {
183 Error("Add","Attempt to add a non-existing profile");
184 return kFALSE;
185 }
187 Error("Add","Attempt to add a non-profile2D object");
188 return kFALSE;
189 }
190
191 return TProfileHelper::Add(this, this, h1, 1, c1);
192}
193
194////////////////////////////////////////////////////////////////////////////////
195/// Replace contents of this profile3D by the addition of h1 and h2.
196///
197/// `this = c1*h1 + c2*h2`
198
200{
201 if (!h1 || !h2) {
202 Error("Add","Attempt to add a non-existing profile");
203 return kFALSE;
204 }
206 Error("Add","Attempt to add a non-profile3D object");
207 return kFALSE;
208 }
209 if (!h2->InheritsFrom(TProfile3D::Class())) {
210 Error("Add","Attempt to add a non-profile3D object");
211 return kFALSE;
212 }
213
214 return TProfileHelper::Add(this, h1, h2, c1, c2);
215}
216
217
218////////////////////////////////////////////////////////////////////////////////
219/// Set the fgApproximate flag.
220///
221/// When the flag is true, the function GetBinError
222/// will approximate the bin error with the average profile error on all bins
223/// in the following situation only
224///
225/// - the number of bins in the profile3D is less than 10404 (eg 100x100x100)
226/// - the bin number of entries is small ( <5)
227/// - the estimated bin error is extremely small compared to the bin content
228/// (see TProfile3D::GetBinError)
229
234
235
236////////////////////////////////////////////////////////////////////////////////
237/// Fill histogram with all entries in the buffer.
238///
239/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
240/// - action = 0 histogram is filled from the buffer
241/// - action = 1 histogram is filled and buffer is deleted
242/// The buffer is automatically deleted when the number of entries
243/// in the buffer is greater than the number of entries in the histogram
244
246{
247 // do we need to compute the bin size?
248 if (!fBuffer) return 0;
250 if (!nbentries) return 0;
251 Double_t *buffer = fBuffer;
252 if (nbentries < 0) {
253 if (action == 0) return 0;
255 fBuffer=nullptr;
256 Reset("ICES"); // reset without deleting the functions
257 fBuffer = buffer;
258 }
260 //find min, max of entries in buffer
261 Double_t xmin = fBuffer[2];
263 Double_t ymin = fBuffer[3];
265 Double_t zmin = fBuffer[4];
266 Double_t zmax = zmin;
267 for (Int_t i=1;i<nbentries;i++) {
268 Double_t x = fBuffer[5*i+2];
269 if (x < xmin) xmin = x;
270 if (x > xmax) xmax = x;
271 Double_t y = fBuffer[5*i+3];
272 if (y < ymin) ymin = y;
273 if (y > ymax) ymax = y;
274 Double_t z = fBuffer[5*i+4];
275 if (z < zmin) zmin = z;
276 if (z > zmax) zmax = z;
277 }
279 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax,ymin,ymax,zmin,zmax);
280 } else {
281 fBuffer = nullptr;
287 if (zmin < fZaxis.GetXmin()) ExtendAxis(zmin,&fZaxis);
288 if (zmax >= fZaxis.GetXmax()) ExtendAxis(zmax,&fZaxis);
289 fBuffer = buffer;
291 }
292 }
293
294 fBuffer = nullptr;
295 for (Int_t i=0;i<nbentries;i++) {
296 Fill(buffer[5*i+2],buffer[5*i+3],buffer[5*i+4],buffer[5*i+5],buffer[5*i+1]);
297 }
298 fBuffer = buffer;
299
300 if (action > 0) { delete [] fBuffer; fBuffer = nullptr; fBufferSize = 0;}
301 else {
303 else fBuffer[0] = 0;
304 }
305 return nbentries;
306}
307
308////////////////////////////////////////////////////////////////////////////////
309/// Accumulate arguments in buffer.
310///
311/// When buffer is full, empty the buffer
312///
313/// - fBuffer[0] = number of entries in buffer
314/// - fBuffer[1] = w of first entry
315/// - fBuffer[2] = x of first entry
316/// - fBuffer[3] = y of first entry
317/// - fBuffer[4] = z of first entry
318/// - fBuffer[5] = t of first entry
319
321{
322 if (!fBuffer) return -3;
324 if (nbentries < 0) {
326 fBuffer[0] = nbentries;
327 if (fEntries > 0) {
328 Double_t *buffer = fBuffer; fBuffer=nullptr;
329 Reset("ICES"); // reset without deleting the functions
330 fBuffer = buffer;
331 }
332 }
333 if (5*nbentries+5 >= fBufferSize) {
334 BufferEmpty(1);
335 return Fill(x,y,z,t,w);
336 }
337 fBuffer[5*nbentries+1] = w;
338 fBuffer[5*nbentries+2] = x;
339 fBuffer[5*nbentries+3] = y;
340 fBuffer[5*nbentries+4] = z;
341 fBuffer[5*nbentries+5] = t;
342 fBuffer[0] += 1;
343 return -2;
344}
345
346////////////////////////////////////////////////////////////////////////////////
347/// Run a Chi2Test between a TProfile3D and another histogram.
348/// If the argument is also a TProfile3D, this calls TH1::Chi2Test() with the option "WW".
349/// \see TH1::Chi2Test()
350
352{
353 TString opt = option;
354 opt.ToUpper();
355
356 if (auto other = dynamic_cast<const TProfile3D *>(h2); other) {
357 if (fErrorMode != kERRORMEAN || other->fErrorMode != kERRORMEAN) {
358 Error("Chi2Test", "Chi2 tests need TProfiles in 'error of mean' mode.");
359 return 0;
360 }
361
362 opt += "WW";
363 opt.ReplaceAll("UU", "WW");
364 opt.ReplaceAll("UW", "WW");
365 } else if (!opt.Contains("WW")) {
366 Error("Chi2Test", "TProfiles need to be tested with the 'W' option. Either use option 'WW' or use "
367 "histogram.Chi2Test(<profile>, 'UW')");
368 return 0;
369 }
370
371 return TH1::Chi2Test(h2, opt, res);
372}
373
374////////////////////////////////////////////////////////////////////////////////
375/// Copy a Profile3D histogram to a new profile2D histogram.
376
377void TProfile3D::Copy(TObject &obj) const
378{
379 try {
380 TProfile3D &pobj = dynamic_cast<TProfile3D &>(obj);
381
383 fBinEntries.Copy(pobj.fBinEntries);
384 fBinSumw2.Copy(pobj.fBinSumw2);
385 for (int bin=0;bin<fNcells;bin++) {
386 pobj.fArray[bin] = fArray[bin];
387 pobj.fSumw2.fArray[bin] = fSumw2.fArray[bin];
388 }
389 pobj.fTmin = fTmin;
390 pobj.fTmax = fTmax;
391 pobj.fScaling = fScaling;
392 pobj.fErrorMode = fErrorMode;
393 pobj.fTsumwt = fTsumwt;
394 pobj.fTsumwt2 = fTsumwt2;
395
396 } catch(...) {
397 Fatal("Copy","Cannot copy a TProfile3D in a %s",obj.IsA()->GetName());
398 }
399}
400
401////////////////////////////////////////////////////////////////////////////////
402/// Performs the operation: `this = this/(c1*f1)` .
403///
404/// This function is not implemented
405
407{
408 Error("Divide","Function not implemented for TProfile3D");
409 return kFALSE;
410}
411
412////////////////////////////////////////////////////////////////////////////////
413/// Divide this profile2D by h1.
414///
415/// `this = this/h1`
416///
417/// This function return kFALSE if the divide operation failed
418
420{
421 if (!h1) {
422 Error("Divide","Attempt to divide a non-existing profile2D");
423 return kFALSE;
424 }
426 Error("Divide","Attempt to divide a non-profile3D object");
427 return kFALSE;
428 }
430
431 // delete buffer if it is there since it will become invalid
432 if (fBuffer) BufferEmpty(1);
433
434// Check profile compatibility
435 Int_t nx = GetNbinsX();
436 if (nx != p1->GetNbinsX()) {
437 Error("Divide","Attempt to divide profiles with different number of bins");
438 return kFALSE;
439 }
440 Int_t ny = GetNbinsY();
441 if (ny != p1->GetNbinsY()) {
442 Error("Divide","Attempt to divide profiles with different number of bins");
443 return kFALSE;
444 }
445 Int_t nz = GetNbinsZ();
446 if (nz != p1->GetNbinsZ()) {
447 Error("Divide","Attempt to divide profiles with different number of bins");
448 return kFALSE;
449 }
450
451// Reset statistics
453
454// Loop on bins (including underflows/overflows)
455 Int_t bin,binx,biny,binz;
456 Double_t *cu1 = p1->GetW();
457 Double_t *er1 = p1->GetW2();
458 Double_t *en1 = p1->GetB();
459 Double_t c0,c1,w,u,x,y,z;
460 for (binx =0;binx<=nx+1;binx++) {
461 for (biny =0;biny<=ny+1;biny++) {
462 for (binz =0;binz<=nz+1;binz++) {
463 bin = GetBin(binx,biny,binz);
464 c0 = fArray[bin];
465 c1 = cu1[bin];
466 if (c1) w = c0/c1;
467 else w = 0;
468 fArray[bin] = w;
469 u = TMath::Abs(w);
473 fEntries++;
474 fTsumw += u;
475 fTsumw2 += u*u;
476 fTsumwx += u*x;
477 fTsumwx2 += u*x*x;
478 fTsumwy += u*y;
479 fTsumwy2 += u*y*y;
480 fTsumwxy += u*x*y;
481 fTsumwz += u;
482 fTsumwz2 += u*z;
483 fTsumwxz += u*x*z;
484 fTsumwyz += u*y*z;
485 fTsumwt += u;
486 fTsumwt2 += u*u;
487 Double_t e0 = fSumw2.fArray[bin];
488 Double_t e1 = er1[bin];
489 Double_t c12= c1*c1;
490 if (!c1) fSumw2.fArray[bin] = 0;
491 else fSumw2.fArray[bin] = (e0*c1*c1 + e1*c0*c0)/(c12*c12);
492 if (!en1[bin]) fBinEntries.fArray[bin] = 0;
493 else fBinEntries.fArray[bin] /= en1[bin];
494 }
495 }
496 }
497 // maintaining the correct sum of weights square is not supported when dividing
498 // bin error resulting from division of profile needs to be checked
499 if (fBinSumw2.fN) {
500 Warning("Divide","Cannot preserve during the division of profiles the sum of bin weight square");
501 fBinSumw2 = TArrayD();
502 }
503 return kTRUE;
504}
505
506////////////////////////////////////////////////////////////////////////////////
507/// Replace contents of this profile2D by the division of h1 by h2.
508///
509/// `this = c1*h1/(c2*h2)`
510///
511/// This function return kFALSE if the divide operation failed
512
514{
515 TString opt = option;
516 opt.ToLower();
517 Bool_t binomial = kFALSE;
518 if (opt.Contains("b")) binomial = kTRUE;
519 if (!h1 || !h2) {
520 Error("Divide","Attempt to divide a non-existing profile2D");
521 return kFALSE;
522 }
524 Error("Divide","Attempt to divide a non-profile2D object");
525 return kFALSE;
526 }
528 if (!h2->InheritsFrom(TProfile3D::Class())) {
529 Error("Divide","Attempt to divide a non-profile2D object");
530 return kFALSE;
531 }
532 TProfile3D *p2 = (TProfile3D*)h2;
533
534// Check histogram compatibility
535 Int_t nx = GetNbinsX();
536 if (nx != p1->GetNbinsX() || nx != p2->GetNbinsX()) {
537 Error("Divide","Attempt to divide profiles with different number of bins");
538 return kFALSE;
539 }
540 Int_t ny = GetNbinsY();
541 if (ny != p1->GetNbinsY() || ny != p2->GetNbinsY()) {
542 Error("Divide","Attempt to divide profiles with different number of bins");
543 return kFALSE;
544 }
545 Int_t nz = GetNbinsZ();
546 if (nz != p1->GetNbinsZ() || nz != p2->GetNbinsZ()) {
547 Error("Divide","Attempt to divide profiles with different number of bins");
548 return kFALSE;
549 }
550 if (!c2) {
551 Error("Divide","Coefficient of dividing profile cannot be zero");
552 return kFALSE;
553 }
554
555// Reset statistics
557
558// Loop on bins (including underflows/overflows)
559 Int_t bin,binx,biny,binz;
560 Double_t *cu1 = p1->GetW();
561 Double_t *cu2 = p2->GetW();
562 Double_t *er1 = p1->GetW2();
563 Double_t *er2 = p2->GetW2();
564 Double_t *en1 = p1->GetB();
565 Double_t *en2 = p2->GetB();
566 Double_t b1,b2,w,u,x,y,z,ac1,ac2;
567 ac1 = TMath::Abs(c1);
568 ac2 = TMath::Abs(c2);
569 for (binx =0;binx<=nx+1;binx++) {
570 for (biny =0;biny<=ny+1;biny++) {
571 for (binz =0;binz<=nz+1;binz++) {
572 bin = GetBin(binx,biny,binz);
573 b1 = cu1[bin];
574 b2 = cu2[bin];
575 if (b2) w = c1*b1/(c2*b2);
576 else w = 0;
577 fArray[bin] = w;
578 u = TMath::Abs(w);
582 fEntries++;
583 fTsumw += u;
584 fTsumw2 += u*u;
585 fTsumwx += u*x;
586 fTsumwx2 += u*x*x;
587 fTsumwy += u*y;
588 fTsumwy2 += u*y*y;
589 fTsumwxy += u*x*y;
590 fTsumwz += u*z;
591 fTsumwz2 += u*z*z;
592 fTsumwxz += u*x*z;
593 fTsumwyz += u*y*z;
594 fTsumwt += u;
595 fTsumwt2 += u*u;
596 Double_t e1 = er1[bin];
597 Double_t e2 = er2[bin];
598 //Double_t b22= b2*b2*d2;
599 Double_t b22= b2*b2*TMath::Abs(c2);
600 if (!b2) fSumw2.fArray[bin] = 0;
601 else {
602 if (binomial) {
603 fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));
604 } else {
605 fSumw2.fArray[bin] = ac1*ac2*(e1*b2*b2 + e2*b1*b1)/(b22*b22);
606 }
607 }
608 if (!en2[bin]) fBinEntries.fArray[bin] = 0;
609 else fBinEntries.fArray[bin] = en1[bin]/en2[bin];
610 }
611 }
612 }
613 return kTRUE;
614}
615
616////////////////////////////////////////////////////////////////////////////////
617/// Fill a Profile3D histogram (no weights).
618
620{
621 if (fBuffer) return BufferFill(x,y,z,t,1);
622
623 Int_t bin,binx,biny,binz;
624
625 if (fTmin != fTmax) {
626 if (t <fTmin || t> fTmax || TMath::IsNaN(t) ) return -1;
627 }
628
629 fEntries++;
632 binz =fZaxis.FindBin(z);
633 if (binx <0 || biny <0 || binz<0) return -1;
634 bin = GetBin(binx,biny,binz);
635 AddBinContent(bin, t);
636 fSumw2.fArray[bin] += (Double_t)t*t;
637 fBinEntries.fArray[bin] += 1;
638 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
639 if (binx == 0 || binx > fXaxis.GetNbins()) {
640 if (!GetStatOverflowsBehaviour()) return -1;
641 }
642 if (biny == 0 || biny > fYaxis.GetNbins()) {
643 if (!GetStatOverflowsBehaviour()) return -1;
644 }
645 if (binz == 0 || binz > fZaxis.GetNbins()) {
646 if (!GetStatOverflowsBehaviour()) return -1;
647 }
648//printf("x=%g, y=%g, z=%g, t=%g, binx=%d, biny=%d, binz=%d, bin=%d\n",x,y,z,t,binx,biny,binz,bin);
649 ++fTsumw;
650 ++fTsumw2;
651 fTsumwx += x;
652 fTsumwx2 += x*x;
653 fTsumwy += y;
654 fTsumwy2 += y*y;
655 fTsumwxy += x*y;
656 fTsumwz += z;
657 fTsumwz2 += z*z;
658 fTsumwxz += x*z;
659 fTsumwyz += y*z;
660 fTsumwt += t;
661 fTsumwt2 += t*t;
662 return bin;
663}
664
665////////////////////////////////////////////////////////////////////////////////
666/// Fill a Profile3D histogram with weights.
667
669{
670 if (fBuffer) return BufferFill(x,y,z,t,w);
671
672 Int_t bin,binx,biny,binz;
673
674 if (fTmin != fTmax) {
675 if (t <fTmin || t> fTmax || TMath::IsNaN(t) ) return -1;
676 }
677
678 Double_t u= w; // (w > 0 ? w : -w);
679 fEntries++;
682 binz =fZaxis.FindBin(z);
683 if (binx <0 || biny <0 || binz<0) return -1;
684 bin = GetBin(binx,biny,binz);
685 AddBinContent(bin, u*t);
686 fSumw2.fArray[bin] += u*t*t;
687 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2(); // must be called before accumulating the entries
688 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u*u;
689 fBinEntries.fArray[bin] += u;
690 if (binx == 0 || binx > fXaxis.GetNbins()) {
691 if (!GetStatOverflowsBehaviour()) return -1;
692 }
693 if (biny == 0 || biny > fYaxis.GetNbins()) {
694 if (!GetStatOverflowsBehaviour()) return -1;
695 }
696 if (binz == 0 || binz > fZaxis.GetNbins()) {
697 if (!GetStatOverflowsBehaviour()) return -1;
698 }
699 fTsumw += u;
700 fTsumw2 += u*u;
701 fTsumwx += u*x;
702 fTsumwx2 += u*x*x;
703 fTsumwy += u*y;
704 fTsumwy2 += u*y*y;
705 fTsumwxy += u*x*y;
706 fTsumwz += u*z;
707 fTsumwz2 += u*z*z;
708 fTsumwxz += u*x*z;
709 fTsumwyz += u*y*z;
710 fTsumwt += u*t;
711 fTsumwt2 += u*t*t;
712 return bin;
713}
714
715////////////////////////////////////////////////////////////////////////////////
716/// Return bin content of a Profile3D histogram.
717
719{
720 if (fBuffer) ((TProfile3D*)this)->BufferEmpty();
721
722 if (bin < 0 || bin >= fNcells) return 0;
723 if (fBinEntries.fArray[bin] == 0) return 0;
724 if (!fArray) return 0;
725 return fArray[bin]/fBinEntries.fArray[bin];
726}
727
728////////////////////////////////////////////////////////////////////////////////
729/// Return bin entries of a Profile3D histogram.
730
732{
733 if (fBuffer) ((TProfile3D*)this)->BufferEmpty();
734
735 if (bin < 0 || bin >= fNcells) return 0;
736 return fBinEntries.fArray[bin];
737}
738
739////////////////////////////////////////////////////////////////////////////////
740/// Return bin effective entries for a weighted filled Profile histogram.
741///
742/// In case of an unweighted profile, it is equivalent to the number of entries per bin
743/// The effective entries is defined as the square of the sum of the weights divided by the
744/// sum of the weights square.
745/// TProfile::Sumw2() must be called before filling the profile with weights.
746/// Only by calling this method the sum of the square of the weights per bin is stored.
747
752
753////////////////////////////////////////////////////////////////////////////////
754/// Return bin error of a Profile3D histogram.
755///
756/// ### Computing errors: A moving field
757///
758/// The computation of errors for a TProfile3D has evolved with the versions
759/// of ROOT. The difficulty is in computing errors for bins with low statistics.
760///
761/// - prior to version 3.10, we had no special treatment of low statistic bins.
762/// As a result, these bins had huge errors. The reason is that the
763/// expression eprim2 is very close to 0 (rounding problems) or 0.
764/// - The algorithm is modified/protected for the case
765/// when a TProfile3D is projected (ProjectionX). The previous algorithm
766/// generated a N^2 problem when projecting a TProfile3D with a large number of
767/// bins (eg 100000).
768/// - in version 3.10/02, a new static function TProfile::Approximate
769/// is introduced to enable or disable (default) the approximation.
770/// (see also comments in TProfile::GetBinError)
771
776
777////////////////////////////////////////////////////////////////////////////////
778/// Return option to compute profile2D errors.
779
781{
782 if (fErrorMode == kERRORSPREAD) return "s";
783 if (fErrorMode == kERRORSPREADI) return "i";
784 if (fErrorMode == kERRORSPREADG) return "g";
785 return "";
786}
787
788////////////////////////////////////////////////////////////////////////////////
789/// fill the array stats from the contents of this profile.
790///
791/// The array stats must be correctly dimensioned in the calling program.
792///
793/// - stats[0] = sumw
794/// - stats[1] = sumw2
795/// - stats[2] = sumwx
796/// - stats[3] = sumwx2
797/// - stats[4] = sumwy
798/// - stats[5] = sumwy2
799/// - stats[6] = sumwxy
800/// - stats[7] = sumwz
801/// - stats[8] = sumwz2
802/// - stats[9] = sumwxz
803/// - stats[10]= sumwyz
804/// - stats[11]= sumwt
805/// - stats[12]= sumwt2
806///
807/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
808/// is simply a copy of the statistics quantities computed at filling time.
809/// If a sub-range is specified, the function recomputes these quantities
810/// from the bin contents in the current axis range.
811
813{
814 if (fBuffer) ((TProfile3D*)this)->BufferEmpty();
815
816 // Loop on bins
817 if ( (fTsumw == 0 /* && fEntries > 0 */) || fXaxis.TestBit(TAxis::kAxisRange) || fYaxis.TestBit(TAxis::kAxisRange)) {
818
819 // check for labels axis . In that case corresponding statistics do not make sense and it is set to zero
820 Bool_t labelXaxis = ((const_cast<TAxis &>(fXaxis)).GetLabels() && fXaxis.CanExtend());
821 Bool_t labelYaxis = ((const_cast<TAxis &>(fYaxis)).GetLabels() && fYaxis.CanExtend());
822 Bool_t labelZaxis = ((const_cast<TAxis &>(fZaxis)).GetLabels() && fZaxis.CanExtend());
823
824 Int_t bin, binx, biny,binz;
825 Double_t w, w2;
826 Double_t x,y,z;
827 for (bin=0;bin<kNstat;bin++) stats[bin] = 0;
828 if (!fBinEntries.fArray) return;
829 for (binz=fZaxis.GetFirst();binz<=fZaxis.GetLast();binz++) {
830 z = (!labelZaxis) ? fZaxis.GetBinCenter(binz) : 0;
831 for (biny=fYaxis.GetFirst();biny<=fYaxis.GetLast();biny++) {
832 y = (!labelYaxis) ? fYaxis.GetBinCenter(biny) : 0;
833 for (binx=fXaxis.GetFirst();binx<=fXaxis.GetLast();binx++) {
834 bin = GetBin(binx,biny,binz);
835 w = fBinEntries.fArray[bin];
836 w2 = (fBinSumw2.fN ? fBinSumw2.fArray[bin] : w );
837 x = (!labelXaxis) ? fXaxis.GetBinCenter(binx) : 0;
838 stats[0] += w;
839 stats[1] += w2;
840 stats[2] += w*x;
841 stats[3] += w*x*x;
842 stats[4] += w*y;
843 stats[5] += w*y*y;
844 stats[6] += w*x*y;
845 stats[7] += w*z;
846 stats[8] += w*z*z;
847 stats[9] += w*x*z;
848 stats[10] += w*y*z;
849 stats[11] += fArray[bin];
850 stats[12] += fSumw2.fArray[bin];
851 }
852 }
853 }
854 } else {
855 stats[0] = fTsumw;
856 stats[1] = fTsumw2;
857 stats[2] = fTsumwx;
858 stats[3] = fTsumwx2;
859 stats[4] = fTsumwy;
860 stats[5] = fTsumwy2;
861 stats[6] = fTsumwxy;
862 stats[7] = fTsumwz;
863 stats[8] = fTsumwz2;
864 stats[9] = fTsumwxz;
865 stats[10] = fTsumwyz;
866 stats[11] = fTsumwt;
867 stats[12] = fTsumwt2;
868 }
869}
870
871////////////////////////////////////////////////////////////////////////////////
872/// Reduce the number of bins for this axis to the number of bins having a label.
873
878
879////////////////////////////////////////////////////////////////////////////////
880/// Double the number of bins for axis.
881/// Refill histogram
882/// This function is called by TAxis::FindBin(const char *label)
883
888
889////////////////////////////////////////////////////////////////////////////////
890/// Set option(s) to draw axis with labels.
891///
892/// option might have the following values:
893///
894/// - "a" sort by alphabetic order
895/// - ">" sort by decreasing values
896/// - "<" sort by increasing values
897/// - "h" draw labels horizontal
898/// - "v" draw labels vertical
899/// - "u" draw labels up (end of label right adjusted)
900/// - "d" draw labels down (start of label left adjusted)
901
902void TProfile3D::LabelsOption(Option_t * /* option */, Option_t * /* ax */)
903{
904 Error("LabelsOption","Labels option function is not implemented for a TProfile3D");
905}
906////////////////////////////////////////////////////////////////////////////////
907/// Merge all histograms in the collection in this histogram.
908///
909/// This function computes the min/max for the axes,
910/// compute a new number of bins, if necessary,
911/// add bin contents, errors and statistics.
912/// If overflows are present and limits are different the function will fail.
913/// The function returns the total number of entries in the result histogram
914/// if the merge is successful, -1 otherwise.
915///
916/// IMPORTANT remark. The 2 axis x and y may have different number
917/// of bins and different limits, BUT the largest bin width must be
918/// a multiple of the smallest bin width and the upper limit must also
919/// be a multiple of the bin width.
920
925
926////////////////////////////////////////////////////////////////////////////////
927/// Performs the operation: `this = this*c1*f1` .
928
930{
931 Error("Multiply","Function not implemented for TProfile3D");
932 return kFALSE;
933}
934
935////////////////////////////////////////////////////////////////////////////////
936/// Multiply this profile2D by h1.
937///
938/// `this = this*h1`
939
941{
942 Error("Multiply","Multiplication of profile2D histograms not implemented");
943 return kFALSE;
944}
945
946////////////////////////////////////////////////////////////////////////////////
947/// Replace contents of this profile2D by multiplication of h1 by h2.
948///
949/// `this = (c1*h1)*(c2*h2)`
950
952{
953 Error("Multiply","Multiplication of profile2D histograms not implemented");
954 return kFALSE;
955}
956
957////////////////////////////////////////////////////////////////////////////////
958/// Project this profile3D into a 3-D histogram along X,Y,Z.
959///
960/// The projection is always of the type TH3D.
961///
962/// - if option "E" is specified, the errors are computed. (default)
963/// - if option "B" is specified, the content of bin of the returned histogram
964/// will be equal to the GetBinEntries(bin) of the profile,
965/// - if option "C=E" the bin contents of the projection are set to the
966/// bin errors of the profile
967/// - if option "E" is specified the errors of the projected histogram are computed and set
968/// to be equal to the errors of the profile.
969/// Option "E" is defined as the default one in the header file.
970/// - if option "" is specified the histogram errors are simply the sqrt of its content
971/// - if option "B" is specified, the content of bin of the returned histogram
972/// will be equal to the GetBinEntries(bin) of the profile,
973/// - if option "C=E" the bin contents of the projection are set to the
974/// bin errors of the profile
975/// - if option "W" is specified the bin content of the projected histogram is set to the
976/// product of the bin content of the profile and the entries.
977/// With this option the returned histogram will be equivalent to the one obtained by
978/// filling directly a TH2D using the 3-rd value as a weight.
979/// This option makes sense only for profile filled with all weights =1.
980/// When the profile is weighted (filled with weights different than 1) the
981/// bin error of the projected histogram (obtained using this option "W") cannot be
982/// correctly computed from the information stored in the profile. In that case the
983/// obtained histogram contains as bin error square the weighted sum of the square of the
984/// profiled observable (TProfile2D::fSumw2[bin] )
985///
986/// Note that the axis range is not considered when doing the projection
987
989{
990
991 TString opt = option;
992 opt.ToLower();
996 const TArrayD *xbins = fXaxis.GetXbins();
997 const TArrayD *ybins = fYaxis.GetXbins();
998 const TArrayD *zbins = fZaxis.GetXbins();
999
1000 // Create the projection histogram
1001 TString pname = name;
1002 if (pname == "_px") {
1003 pname = GetName(); pname.Append("_pxyz");
1004 }
1005 TH3D *h1 = nullptr ;
1006 if (xbins->fN == 0 && ybins->fN == 0 && zbins->fN == 0)
1008 else if ( xbins->fN != 0 && ybins->fN != 0 && zbins->fN != 0)
1009 h1 = new TH3D(pname,GetTitle(),nx,xbins->GetArray(),ny,ybins->GetArray(), nz,zbins->GetArray() );
1010 else {
1011 Error("ProjectionXYZ","Histogram has an axis with variable bins and an axis with fixed bins. This case is not supported - return a null pointer");
1012 return nullptr;
1013 }
1014
1015
1020
1021 if (opt.Contains("b")) binEntries = kTRUE;
1022 if (opt.Contains("e")) computeErrors = kTRUE;
1023 if (opt.Contains("w")) binWeight = kTRUE;
1024 if (opt.Contains("c=e")) {cequalErrors = kTRUE; computeErrors=kFALSE;}
1026
1027 // Fill the projected histogram
1028 Int_t bin,binx,biny,binz;
1029 Double_t cont;
1030 for (binx =0;binx<=nx+1;binx++) {
1031 for (biny =0;biny<=ny+1;biny++) {
1032 for (binz =0;binz<=nz+1;binz++) {
1033 bin = GetBin(binx,biny,binz);
1034
1035 if (binEntries) cont = GetBinEntries(bin);
1036 else if (cequalErrors) cont = GetBinError(bin);
1037 else if (binWeight) cont = GetBinContent(bin) * GetBinEntries(bin);
1038 else cont = GetBinContent(bin); // default case
1039
1040 h1->SetBinContent(bin ,cont);
1041
1042 // if option E projected histogram errors are same as profile
1043 if (computeErrors ) h1->SetBinError(bin , GetBinError(bin) );
1044 // in case of option W bin error is deduced from bin sum of z**2 values of profile
1045 // this is correct only if the profile is unweighted
1046 if (binWeight) h1->GetSumw2()->fArray[bin] = fSumw2.fArray[bin];
1047 // in case of bin entries and profile is weighted, we need to set also the bin error
1048 if (binEntries && fBinSumw2.fN ) {
1049 R__ASSERT( h1->GetSumw2() );
1050 h1->GetSumw2()->fArray[bin] = fBinSumw2.fArray[bin];
1051 }
1052 }
1053 }
1054 }
1056 return h1;
1057}
1058////////////////////////////////////////////////////////////////////////////////
1059/// Project a 3-D profile into a 2D-profile histogram depending on the option parameter.
1060///
1061/// option may contain a combination of the characters x,y,z:
1062///
1063/// - option = "xy" return the x versus y projection into a TProfile2D histogram
1064/// - option = "yx" return the y versus x projection into a TProfile2D histogram
1065/// - option = "xz" return the x versus z projection into a TProfile2D histogram
1066/// - option = "zx" return the z versus x projection into a TProfile2D histogram
1067/// - option = "yz" return the y versus z projection into a TProfile2D histogram
1068/// - option = "zy" return the z versus y projection into a TProfile2D histogram
1069///
1070/// NB: the notation "a vs b" means "a" vertical and "b" horizontal along X
1071///
1072/// The resulting profile contains the combination of all the considered bins along X
1073/// By default, all bins are included considering also underflow/overflows
1074///
1075/// The option can also be used to specify the projected profile error type.
1076/// Values which can be used are 's', 'i', or 'g'. See TProfile::BuildOptions for details
1077///
1078/// To select a bin range along an axis, use TAxis::SetRange, eg
1079/// `h3.GetYaxis()->SetRange(23,56);`
1080
1082{
1083 // can call TH3 method which will call the virtual method :DoProjectProfile2D re-implemented below
1084 // but need to add underflow/overflow
1085 TString opt(option);
1086 opt.Append(" UF OF");
1087 return TH3::Project3DProfile(opt);
1088}
1089
1090////////////////////////////////////////////////////////////////////////////////
1091/// Internal method to project to a 2D Profile.
1092///
1093/// Called from TH3::Project3DProfile but re-implemented in case of the TPRofile3D
1094/// since what is done is different.
1095
1096TProfile2D *TProfile3D::DoProjectProfile2D(const char* name, const char * title, const TAxis* projX, const TAxis* projY,
1097 bool originalRange, bool useUF, bool useOF) const
1098{
1099 // Get the ranges where we will work.
1100 Int_t ixmin = projX->GetFirst();
1101 Int_t ixmax = projX->GetLast();
1102 Int_t iymin = projY->GetFirst();
1103 Int_t iymax = projY->GetLast();
1104 if (ixmin == 0 && ixmax == 0) { ixmin = 1; ixmax = projX->GetNbins(); }
1105 if (iymin == 0 && iymax == 0) { iymin = 1; iymax = projY->GetNbins(); }
1106 Int_t nx = ixmax-ixmin+1;
1107 Int_t ny = iymax-iymin+1;
1108
1109 // Create the projected profiles
1110 TProfile2D *p2 = nullptr;
1111 // Create always a new TProfile2D (not as in the case of TH3 projection)
1112
1113 const TArrayD *xbins = projX->GetXbins();
1114 const TArrayD *ybins = projY->GetXbins();
1115 // assume all axis have variable bins or have fixed bins
1116 if ( originalRange ) {
1117 if (xbins->fN == 0 && ybins->fN == 0) {
1118 p2 = new TProfile2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
1119 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
1120 } else {
1121 p2 = new TProfile2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1],projX->GetNbins(),&xbins->fArray[ixmin-1]);
1122 }
1123 } else {
1124 if (xbins->fN == 0 && ybins->fN == 0) {
1125 p2 = new TProfile2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
1126 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
1127 } else {
1128 p2 = new TProfile2D(name,title,ny,&ybins->fArray[iymin-1],nx,&xbins->fArray[ixmin-1]);
1129 }
1130 }
1131
1132 // weights
1133 bool useWeights = (fBinSumw2.fN != 0);
1134 if (useWeights) p2->Sumw2();
1135
1136 // make projection in a 3D first
1137 TH3D * h3dW = ProjectionXYZ("h3temp-W","W");
1138 TH3D * h3dN = ProjectionXYZ("h3temp-N","B");
1139
1140 h3dW->SetDirectory(nullptr); h3dN->SetDirectory(nullptr);
1141
1142 // Since no axis range is considered when doing the projection TProfile3D->TH3D
1143 // the resulting histogram will have the same axis as the parent one
1144 // we need afterwards to set the range in the 3D histogram to considered it later
1145 // when doing the projection in a Profile2D
1147 h3dW->GetXaxis()->SetRange(fXaxis.GetFirst(),fXaxis.GetLast());
1148 h3dN->GetXaxis()->SetRange(fXaxis.GetFirst(),fXaxis.GetLast());
1149 }
1151 h3dW->GetYaxis()->SetRange(fYaxis.GetFirst(),fYaxis.GetLast());
1152 h3dN->GetYaxis()->SetRange(fYaxis.GetFirst(),fYaxis.GetLast());
1153 }
1155 h3dW->GetZaxis()->SetRange(fZaxis.GetFirst(),fZaxis.GetLast());
1156 h3dN->GetZaxis()->SetRange(fZaxis.GetFirst(),fZaxis.GetLast());
1157 }
1158
1159 // note that h3dW is always a weighted histogram - so we need to compute error in the projection
1160 TAxis * projX_hW = h3dW->GetXaxis();
1161 TAxis * projX_hN = h3dN->GetXaxis();
1162 if (projX == GetYaxis() ) { projX_hW = h3dW->GetYaxis(); projX_hN = h3dN->GetYaxis(); }
1163 if (projX == GetZaxis() ) { projX_hW = h3dW->GetZaxis(); projX_hN = h3dN->GetZaxis(); }
1164 TAxis * projY_hW = h3dW->GetYaxis();
1165 TAxis * projY_hN = h3dN->GetYaxis();
1166 if (projY == GetXaxis() ) { projY_hW = h3dW->GetXaxis(); projY_hN = h3dN->GetXaxis(); }
1167 if (projY == GetZaxis() ) { projY_hW = h3dW->GetZaxis(); projY_hN = h3dN->GetZaxis(); }
1168
1169 TH2D * h2W = TH3::DoProject2D(*h3dW,"htemp-W","",projX_hW, projY_hW, true, originalRange, useUF, useOF);
1171 h2W->SetDirectory(nullptr); h2N->SetDirectory(nullptr);
1172
1173
1174 // fill the bin content
1175 R__ASSERT( h2W->fN == p2->fN );
1176 R__ASSERT( h2N->fN == p2->fN );
1177 R__ASSERT( h2W->GetSumw2()->fN != 0); // h2W should always be a weighted histogram since h3dW is weighted
1178 for (int i = 0; i < p2->fN ; ++i) {
1179 //std::cout << " proj bin " << i << " " << h2W->fArray[i] << " " << h2N->fArray[i] << std::endl;
1180 p2->fArray[i] = h2W->fArray[i]; // array of profile is sum of all values
1181 p2->GetSumw2()->fArray[i] = h2W->GetSumw2()->fArray[i]; // array of content square of profile is weight square of the W projected histogram
1182 p2->SetBinEntries(i, h2N->fArray[i] );
1183 if (useWeights) p2->GetBinSumw2()->fArray[i] = h2N->GetSumw2()->fArray[i]; // sum of weight squares are stored to compute errors in h1N histogram
1184 }
1185 // delete the created histograms
1186 delete h3dW;
1187 delete h3dN;
1188 delete h2W;
1189 delete h2N;
1190
1191 // Also we need to set the entries since they have not been correctly calculated during the projection
1192 // we can only set them to the effective entries
1193 p2->SetEntries( p2->GetEffectiveEntries() );
1194
1195 return p2;
1196
1197}
1198
1199////////////////////////////////////////////////////////////////////////////////
1200/// Replace current statistics with the values in array stats.
1201
1203{
1205 fTsumwt = stats[11];
1206 fTsumwt2 = stats[12];
1207}
1208
1209////////////////////////////////////////////////////////////////////////////////
1210/// Reset contents of a Profile3D histogram.
1211
1213{
1215 fBinSumw2.Reset();
1217 TString opt = option;
1218 opt.ToUpper();
1219 if (opt.Contains("ICE") && !opt.Contains("S")) return;
1220 fTsumwt = fTsumwt2 = 0;
1221}
1222
1223////////////////////////////////////////////////////////////////////////////////
1224/// Profile histogram is resized along axis such that x is in the axis range.
1225/// The new axis limits are recomputed by doubling iteratively
1226/// the current axis range until the specified value x is within the limits.
1227/// The algorithm makes a copy of the histogram, then loops on all bins
1228/// of the old histogram to fill the rebinned histogram.
1229/// Takes into account errors (Sumw2) if any.
1230/// The axis must be rebinnable before invoking this function.
1231/// Ex: `h->GetXaxis()->SetCanExtend(kTRUE)`
1232
1234{
1236 if ( hold ) {
1237 fTsumwt = hold->fTsumwt;
1238 fTsumwt2 = hold->fTsumwt2;
1239 delete hold;
1240 }
1241}
1242
1243////////////////////////////////////////////////////////////////////////////////
1244/// Save primitive as a C++ statement(s) on output stream out.
1245
1246void TProfile3D::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1247{
1249
1251
1252 out << " \n";
1253
1254 // Check if custom X/Y/Z axes are configured.
1255 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray && GetYaxis()->GetXbins()->fN &&
1256 GetYaxis()->GetXbins()->fArray && GetZaxis()->GetXbins()->fN && GetZaxis()->GetXbins()->fArray) {
1257 sxaxis = SavePrimitiveVector(out, hname + "_x", GetXaxis()->GetXbins()->fN, GetXaxis()->GetXbins()->fArray);
1258 syaxis = SavePrimitiveVector(out, hname + "_y", GetYaxis()->GetXbins()->fN, GetYaxis()->GetXbins()->fArray);
1259 szaxis = SavePrimitiveVector(out, hname + "_z", GetZaxis()->GetXbins()->fN, GetZaxis()->GetXbins()->fArray);
1260 }
1261
1262 out << " " << ClassName() << " *" << hname << " = new " << ClassName() << "(\"" << hname << "\", \""
1263 << TString(GetTitle()).ReplaceSpecialCppChars() << "\", " << GetXaxis()->GetNbins() << ", ";
1264 if (!sxaxis.IsNull())
1265 out << sxaxis << ".data()";
1266 else
1267 out << GetXaxis()->GetXmin() << ", " << GetXaxis()->GetXmax();
1268
1269 out << ", " << GetYaxis()->GetNbins() << ", ";
1270 if (!syaxis.IsNull())
1271 out << syaxis << ".data()";
1272 else
1273 out << GetYaxis()->GetXmin() << ", " << GetYaxis()->GetXmax();
1274
1275 out << ", " << GetZaxis()->GetNbins() << ", ";
1276 if (!szaxis.IsNull())
1277 out << szaxis << ".data()";
1278 else
1279 out << GetZaxis()->GetXmin() << ", " << GetZaxis()->GetXmax();
1280
1281 out << ", \"" << TString(GetErrorOption()).ReplaceSpecialCppChars() << "\");\n";
1282
1284 Int_t numentries = 0, numcontent = 0, numerrors = 0;
1285
1286 std::vector<Double_t> entries(fNcells), content(fNcells), errors(save_errors ? fNcells : 0);
1287 for (Int_t bin = 0; bin < fNcells; bin++) {
1288 entries[bin] = GetBinEntries(bin);
1289 if (entries[bin])
1290 numentries++;
1291 content[bin] = fArray[bin];
1292 if (content[bin])
1293 numcontent++;
1294 if (save_errors) {
1295 errors[bin] = TMath::Sqrt(fSumw2.fArray[bin]);
1296 if (errors[bin])
1297 numerrors++;
1298 }
1299 }
1300
1301 if ((numentries < 100) && (numcontent < 100) && (numerrors < 100)) {
1302 // in case of few non-empty bins store them as before
1303 for (Int_t bin = 0; bin < fNcells; bin++) {
1304 if (entries[bin])
1305 out << " " << hname << "->SetBinEntries(" << bin << "," << entries[bin] << ");\n";
1306 }
1307 for (Int_t bin = 0; bin < fNcells; bin++) {
1308 if (content[bin])
1309 out << " " << hname << "->SetBinContent(" << bin << "," << content[bin] << ");\n";
1310 }
1311 if (save_errors)
1312 for (Int_t bin = 0; bin < fNcells; bin++) {
1313 if (errors[bin])
1314 out << " " << hname << "->SetBinError(" << bin << "," << errors[bin] << ");\n";
1315 }
1316 } else {
1317 if (numentries > 0) {
1318 TString vect = SavePrimitiveVector(out, hname, fNcells, entries.data());
1319 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
1320 out << " if (" << vect << "[bin])\n";
1321 out << " " << hname << "->SetBinEntries(bin, " << vect << "[bin]);\n";
1322 }
1323 if (numcontent > 0) {
1325 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
1326 out << " if (" << vect << "[bin])\n";
1327 out << " " << hname << "->SetBinContent(bin, " << vect << "[bin]);\n";
1328 }
1329 if (numerrors > 0) {
1331 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
1332 out << " if (" << vect << "[bin])\n";
1333 out << " " << hname << "->SetBinError(bin, " << vect << "[bin]);\n";
1334 }
1335 }
1336
1338}
1339
1340////////////////////////////////////////////////////////////////////////////////
1341/// Multiply this profile2D by a constant c1.
1342///
1343/// `this = c1*this`
1344///
1345/// This function uses the services of TProfile3D::Add
1346
1351
1352////////////////////////////////////////////////////////////////////////////////
1353///Set the number of entries in bin.
1354
1359
1360////////////////////////////////////////////////////////////////////////////////
1361/// Redefine x, y and z axis parameters.
1362
1369
1370////////////////////////////////////////////////////////////////////////////////
1371/// Redefine x, y and z axis parameters with variable bin sizes
1372
1379
1380////////////////////////////////////////////////////////////////////////////////
1381/// Set total number of bins including under/overflow.
1382///
1383/// Reallocate bin contents array
1384
1390
1391////////////////////////////////////////////////////////////////////////////////
1392/// Set the buffer size in units of 8 bytes (double).
1393
1395{
1396 if (fBuffer) {
1397 BufferEmpty();
1398 delete [] fBuffer;
1399 fBuffer = nullptr;
1400 }
1401 if (bufsize <= 0) {
1402 fBufferSize = 0;
1403 return;
1404 }
1405 if (bufsize < 100) bufsize = 100;
1406 fBufferSize = 1 + 5*bufsize;
1409}
1410
1411////////////////////////////////////////////////////////////////////////////////
1412/// Set option to compute profile3D errors.
1413///
1414/// The computation of the bin errors is based on the parameter option:
1415/// - ' ' (Default) The bin errors are the standard error on the mean of the bin profiled values (T),
1416/// i.e. the standard error of the bin contents.
1417/// Note that if TProfile3D::Approximate() is called, an approximation is used when
1418/// the spread in T is 0 and the number of bin entries is > 0
1419/// - 's' The bin errors are the standard deviations of the T bin values
1420/// Note that if TProfile3D::Approximate() is called, an approximation is used when
1421/// the spread in T is 0 and the number of bin entries is > 0
1422/// - 'i' Errors are as in default case (standard errors of the bin contents)
1423/// The only difference is for the case when the spread in T is zero.
1424/// In this case for N > 0 the error is 1./SQRT(12.*N)
1425/// - 'g' Errors are 1./SQRT(W) for W not equal to 0 and 0 for W = 0.
1426/// W is the sum in the bin of the weights of the profile.
1427/// This option is for combining measurements t +/- dt,
1428/// and the profile is filled with values t and weights w = 1/dt**2
1429///
1430/// See TProfile::BuildOptions for explanation of all options
1431
1436
1437////////////////////////////////////////////////////////////////////////////////
1438/// Create/Delete structure to store sum of squares of weights per bin
1439/// This is needed to compute the correct statistical quantities
1440/// of a profile filled with weights
1441///
1442/// This function is automatically called when the histogram is created
1443/// if the static function TH1::SetDefaultSumw2 has been called before.
1444/// If flag = false the structure is deleted
1445
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
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
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
@ kERRORSPREAD
Definition TProfile.h:28
@ kERRORSPREADG
Definition TProfile.h:28
@ kERRORSPREADI
Definition TProfile.h:28
@ kERRORMEAN
Definition TProfile.h:28
Array of doubles (64 bits per element).
Definition TArrayD.h:27
Double_t * fArray
Definition TArrayD.h:30
void Copy(TArrayD &array) const
Definition TArrayD.h:42
void Set(Int_t n) 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
Double_t GetXmax() const
Definition TAxis.h:142
@ kAxisRange
Definition TAxis.h:66
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:292
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
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:461
Collection abstract base class.
Definition TCollection.h:65
1-Dim function class
Definition TF1.h:182
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
TAxis * GetZaxis()
Definition TH1.h:574
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
virtual Int_t GetNbinsZ() const
Definition TH1.h:544
@ 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
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
TAxis fZaxis
Z axis descriptor.
Definition TH1.h:153
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
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:356
3-D histogram with a double per channel (see TH1 documentation)
Definition TH3.h:371
TH3D()
Constructor.
Definition TH3.cxx:4681
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH3.cxx:4775
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:4754
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH3.h:388
Double_t fTsumwy
Total Sum of weight*Y.
Definition TH3.h:43
Double_t fTsumwy2
Total Sum of weight*Y*Y.
Definition TH3.h:44
virtual TH2D * DoProject2D(const char *name, const char *title, const TAxis *projX, const TAxis *projY, bool computeErrors, bool originalRange, bool useUF, bool useOF) const
internal method performing the projection to a 2D histogram called from TH3::Project3D
Definition TH3.cxx:2121
Double_t fTsumwxz
Total Sum of weight*X*Z.
Definition TH3.h:48
virtual TProfile2D * Project3DProfile(Option_t *option="xy") const
Project a 3-d histogram into a 2-d profile histograms depending on the option parameter option may co...
Definition TH3.cxx:2824
Double_t fTsumwz2
Total Sum of weight*Z*Z.
Definition TH3.h:47
Double_t fTsumwxy
Total Sum of weight*X*Y.
Definition TH3.h:45
Double_t fTsumwz
Total Sum of weight*Z.
Definition TH3.h:46
Double_t fTsumwyz
Total Sum of weight*Y*Z.
Definition TH3.h:49
Int_t GetBin(Int_t binx, Int_t biny, Int_t binz) const override
See comments in TH1::GetBin.
Definition TH3.cxx:1133
void PutStats(Double_t *stats) override
Replace current statistics with the values in array stats.
Definition TH3.cxx:2907
static THLimitsFinder * GetLimitsFinder()
Return pointer to the current finder.
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
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
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:543
virtual TClass * IsA() const
Definition TObject.h:246
Profile2D histograms are used to display the mean value of Z and its error for each cell in X,...
Definition TProfile2D.h:27
Profile3D histograms are used to display the mean value of T and its RMS for each cell in X,...
Definition TProfile3D.h:27
TProfile3D & operator=(const TProfile3D &profile)
TProfile2D * DoProjectProfile2D(const char *name, const char *title, const TAxis *projX, const TAxis *projY, bool originalRange, bool useUF, bool useOF) const override
Internal method to project to a 2D Profile.
Long64_t Merge(TCollection *list) override
Merge all histograms in the collection in this histogram.
static Bool_t fgApproximate
Bin error approximation option.
Definition TProfile3D.h:42
Option_t * GetErrorOption() const
Return option to compute profile2D errors.
Bool_t fScaling
! True when TProfile3D::Scale is called
Definition TProfile3D.h:38
void SetBins(const Int_t *nbins, const Double_t *range)
Definition TProfile3D.h:50
void PutStats(Double_t *stats) override
Replace current statistics with the values in array stats.
Double_t Chi2Test(const TH1 *h2, Option_t *option="WW", Double_t *res=nullptr) const override
Run a Chi2Test between a TProfile3D and another histogram.
void Copy(TObject &hnew) const override
Copy a Profile3D histogram to a new profile2D histogram.
Int_t BufferFill(Double_t, Double_t) override
accumulate arguments in buffer.
Definition TProfile3D.h:44
void SetBuffer(Int_t bufsize, Option_t *opt="") override
Set the buffer size in units of 8 bytes (double).
Double_t fTsumwt2
Total Sum of weight*T*T.
Definition TProfile3D.h:40
virtual Double_t GetBinEffectiveEntries(Int_t bin)
Return bin effective entries for a weighted filled Profile histogram.
void GetStats(Double_t *stats) const override
fill the array stats from the contents of this profile.
Bool_t Multiply(TF1 *h1, Double_t c1=1) override
Performs the operation: this = this*c1*f1 .
void LabelsOption(Option_t *option="h", Option_t *axis="X") override
Set option(s) to draw axis with labels.
TProfile3D()
Default constructor for Profile3D histograms.
TArrayD fBinEntries
Number of entries per bin.
Definition TProfile3D.h:34
void LabelsDeflate(Option_t *axis="X") override
Reduce the number of bins for this axis to the number of bins having a label.
~TProfile3D() override
Default destructor for Profile3D histograms.
void ExtendAxis(Double_t x, TAxis *axis) override
Profile histogram is resized along axis such that x is in the axis range.
Double_t fTmin
Lower limit in T (if set)
Definition TProfile3D.h:36
void Scale(Double_t c1=1, Option_t *option="") override
Multiply this profile2D by a constant c1.
void Sumw2(Bool_t flag=kTRUE) override
Create/Delete structure to store sum of squares of weights per bin This is needed to compute the corr...
void LabelsInflate(Option_t *axis="X") override
Double the number of bins for axis.
TProfile2D * Project3DProfile(Option_t *option="xy") const override
Project a 3-D profile into a 2D-profile histogram depending on the option parameter.
virtual void SetBinEntries(Int_t bin, Double_t w)
Set the number of entries in bin.
void BuildOptions(Double_t tmin, Double_t tmax, Option_t *option)
Set Profile3D histogram structure and options.
static TClass * Class()
Int_t Fill(const Double_t *v)
Definition TProfile3D.h:53
TArrayD fBinSumw2
Array of sum of squares of weights per bin.
Definition TProfile3D.h:41
Int_t BufferEmpty(Int_t action=0) override
Fill histogram with all entries in the buffer.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
virtual void SetErrorOption(Option_t *option="")
Set option to compute profile3D errors.
virtual TH3D * ProjectionXYZ(const char *name="_pxyz", Option_t *option="e") const
Project this profile3D into a 3-D histogram along X,Y,Z.
Bool_t Add(TF1 *h1, Double_t c1=1, Option_t *option="") override
Performs the operation: this = this + c1*f1 .
Double_t GetBinContent(Int_t bin) const override
Return bin content of a Profile3D histogram.
EErrorType fErrorMode
Option to compute errors.
Definition TProfile3D.h:35
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow.
virtual Double_t GetBinEntries(Int_t bin) const
Return bin entries of a Profile3D histogram.
Bool_t Divide(TF1 *h1, Double_t c1=1) override
Performs the operation: this = this/(c1*f1) .
Double_t fTsumwt
Total Sum of weight*T.
Definition TProfile3D.h:39
static void Approximate(Bool_t approx=kTRUE)
Set the fgApproximate flag.
Double_t fTmax
Upper limit in T (if set)
Definition TProfile3D.h:37
Double_t GetBinError(Int_t bin) const override
Return bin error of a Profile3D 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 *)
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
TString & Append(const char *cs)
Definition TString.h:580
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
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124