Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TH3.cxx
Go to the documentation of this file.
1// @(#)root/hist:$Id$
2// Author: Rene Brun 27/10/95
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 "TROOT.h"
13#include "TBuffer.h"
14#include "TClass.h"
15#include "THashList.h"
16#include "TH3.h"
17#include "TProfile2D.h"
18#include "TH2.h"
19#include "TF3.h"
20#include "TVirtualPad.h"
21#include "TVirtualHistPainter.h"
22#include "THLimitsFinder.h"
23#include "TRandom.h"
24#include "TError.h"
25#include "TMath.h"
26#include "TObjString.h"
27
28#include <atomic>
29#include <stdexcept>
30
31
32/** \addtogroup Histograms
33@{
34\class TH3C
35\brief 3-D histogram with a byte per channel (see TH1 documentation)
36\class TH3S
37\brief 3-D histogram with a short per channel (see TH1 documentation)
38\class TH3I
39\brief 3-D histogram with an int per channel (see TH1 documentation)
40\class TH3L
41\brief 3-D histogram with a long64 per channel (see TH1 documentation)
42\class TH3F
43\brief 3-D histogram with a float per channel (see TH1 documentation)
44\class TH3D
45\brief 3-D histogram with a double per channel (see TH1 documentation)
46@}
47*/
48
49/** \class TH3
50 \ingroup Histograms
51The 3-D histogram classes derived from the 1-D histogram classes.
52All operations are supported (fill, fit).
53Drawing is currently restricted to one single option.
54A cloud of points is drawn. The number of points is proportional to
55cell content.
56
57- TH3C a 3-D histogram with one byte per cell (char). Maximum bin content = 127
58- TH3S a 3-D histogram with two bytes per cell (short integer). Maximum bin content = 32767
59- TH3I a 3-D histogram with four bytes per cell (32 bit integer). Maximum bin content = INT_MAX (\ref intmax3 "*")
60- TH3L a 3-D histogram with eight bytes per cell (64 bit integer). Maximum bin content = LLONG_MAX (\ref llongmax3 "**")
61- TH3F a 3-D histogram with four bytes per cell (float). Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax3 "***")
62- TH3D a 3-D histogram with eight bytes per cell (double). Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax3 "****")
63
64<sup>
65\anchor intmax3 (*) INT_MAX = 2147483647 is the [maximum value for a variable of type int.](https://docs.microsoft.com/en-us/cpp/c-language/cpp-integer-limits)<br>
66\anchor llongmax3 (**) LLONG_MAX = 9223372036854775807 is the [maximum value for a variable of type long64.](https://docs.microsoft.com/en-us/cpp/c-language/cpp-integer-limits)<br>
67\anchor floatmax3 (***) 2^24 = 16777216 is the [maximum integer that can be properly represented by a float32 with 23-bit mantissa.](https://stackoverflow.com/a/3793950/7471760)<br>
68\anchor doublemax3 (****) 2^53 = 9007199254740992 is the [maximum integer that can be properly represented by a double64 with 52-bit mantissa.](https://stackoverflow.com/a/3793950/7471760)
69</sup>
70*/
71
72
73////////////////////////////////////////////////////////////////////////////////
74/// Default constructor.
75
77{
78 fDimension = 3;
81}
82
83
84////////////////////////////////////////////////////////////////////////////////
85/// Constructor for fix bin size 3-D histograms.
86/// Creates the main histogram structure.
87///
88/// \param[in] name name of histogram (avoid blanks)
89/// \param[in] title histogram title.
90/// If title is of the form `stringt;stringx;stringy;stringz`,
91/// the histogram title is set to `stringt`,
92/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
93/// \param[in] nbinsx number of bins along the X axis
94/// \param[in] xlow low edge of the X axis first bin
95/// \param[in] xup upper edge of the X axis last bin (not included in last bin)
96/// \param[in] nbinsy number of bins along the Y axis
97/// \param[in] ylow low edge of the Y axis first bin
98/// \param[in] yup upper edge of the Y axis last bin (not included in last bin)
99/// \param[in] nbinsz number of bins along the Z axis
100/// \param[in] zlow low edge of the Z axis first bin
101/// \param[in] zup upper edge of the Z axis last bin (not included in last bin)
103TH3::TH3(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
106 :TH1(name,title,nbinsx,xlow,xup)
107{
108 fDimension = 3;
109 if (nbinsy <= 0) {
110 Warning("TH3","nbinsy is <=0 - set to nbinsy = 1");
111 nbinsy = 1;
112 }
113 if (nbinsz <= 0) {
114 Warning("TH3","nbinsz is <=0 - set to nbinsz = 1");
115 nbinsz = 1;
116 }
117 fYaxis.Set(nbinsy,ylow,yup);
119 fNcells = (nbinsx+2)*(nbinsy+2)*(nbinsz+2);
120 fTsumwy = fTsumwy2 = fTsumwxy = 0;
122}
123
124
125////////////////////////////////////////////////////////////////////////////////
126/// Constructor for variable bin size (along X, Y and Z axis) 3-D histograms using input
127/// arrays of type float.
128///
129/// \param[in] name name of histogram (avoid blanks)
130/// \param[in] title histogram title.
131/// If title is of the form `stringt;stringx;stringy;stringz`
132/// the histogram title is set to `stringt`,
133/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
134/// \param[in] nbinsx number of bins
135/// \param[in] xbins array of low-edges for each bin.
136/// This is an array of type float and size nbinsx+1
137/// \param[in] nbinsy number of bins
138/// \param[in] ybins array of low-edges for each bin.
139/// This is an array of type float and size nbinsy+1
140/// \param[in] nbinsz number of bins
141/// \param[in] zbins array of low-edges for each bin.
142/// This is an array of type float and size nbinsz+1
143
144TH3::TH3(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
145 ,Int_t nbinsy,const Float_t *ybins
146 ,Int_t nbinsz,const Float_t *zbins)
147 :TH1(name,title,nbinsx,xbins)
148{
149 fDimension = 3;
150 if (nbinsy <= 0) {Warning("TH3","nbinsy is <=0 - set to nbinsy = 1"); nbinsy = 1; }
151 if (nbinsz <= 0) nbinsz = 1;
153 else fYaxis.Set(nbinsy,0,1);
155 else fZaxis.Set(nbinsz,0,1);
156 fNcells = (nbinsx+2)*(nbinsy+2)*(nbinsz+2);
157 fTsumwy = fTsumwy2 = fTsumwxy = 0;
159}
160
161
162////////////////////////////////////////////////////////////////////////////////
163/// Constructor for variable bin size (along X, Y and Z axis) 3-D histograms using input
164/// arrays of type double.
165///
166/// \param[in] name name of histogram (avoid blanks)
167/// \param[in] title histogram title.
168/// If title is of the form `stringt;stringx;stringy;stringz`
169/// the histogram title is set to `stringt`,
170/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
171/// \param[in] nbinsx number of bins
172/// \param[in] xbins array of low-edges for each bin.
173/// This is an array of type double and size nbinsx+1
174/// \param[in] nbinsy number of bins
175/// \param[in] ybins array of low-edges for each bin.
176/// This is an array of type double and size nbinsy+1
177/// \param[in] nbinsz number of bins
178/// \param[in] zbins array of low-edges for each bin.
179/// This is an array of type double and size nbinsz+1
180
181TH3::TH3(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
182 ,Int_t nbinsy,const Double_t *ybins
183 ,Int_t nbinsz,const Double_t *zbins)
184 :TH1(name,title,nbinsx,xbins)
185{
186 fDimension = 3;
187 if (nbinsy <= 0) {Warning("TH3","nbinsy is <=0 - set to nbinsy = 1"); nbinsy = 1; }
188 if (nbinsz <= 0) nbinsz = 1;
190 else fYaxis.Set(nbinsy,0,1);
192 else fZaxis.Set(nbinsz,0,1);
193 fNcells = (nbinsx+2)*(nbinsy+2)*(nbinsz+2);
194 fTsumwy = fTsumwy2 = fTsumwxy = 0;
196}
197
198
199////////////////////////////////////////////////////////////////////////////////
200/// Destructor.
201
203{
204}
205
206
207////////////////////////////////////////////////////////////////////////////////
208/// Copy.
209
210void TH3::Copy(TObject &obj) const
211{
212 TH1::Copy(obj);
213 ((TH3&)obj).fTsumwy = fTsumwy;
214 ((TH3&)obj).fTsumwy2 = fTsumwy2;
215 ((TH3&)obj).fTsumwxy = fTsumwxy;
216 ((TH3&)obj).fTsumwz = fTsumwz;
217 ((TH3&)obj).fTsumwz2 = fTsumwz2;
218 ((TH3&)obj).fTsumwxz = fTsumwxz;
219 ((TH3&)obj).fTsumwyz = fTsumwyz;
220}
221
222////////////////////////////////////////////////////////////////////////////////
223/// Fill histogram with all entries in the buffer.
224/// action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
225/// action = 0 histogram is filled from the buffer
226/// action = 1 histogram is filled and buffer is deleted
227/// The buffer is automatically deleted when the number of entries
228/// in the buffer is greater than the number of entries in the histogram
229
231{
232 // do we need to compute the bin size?
233 if (!fBuffer) return 0;
235 if (!nbentries) return 0;
236 Double_t *buffer = fBuffer;
237 if (nbentries < 0) {
238 if (action == 0) return 0;
240 fBuffer=nullptr;
241 Reset("ICES");
242 fBuffer = buffer;
243 }
244 if (CanExtendAllAxes() || fXaxis.GetXmax() <= fXaxis.GetXmin() ||
245 fYaxis.GetXmax() <= fYaxis.GetXmin() ||
246 fZaxis.GetXmax() <= fZaxis.GetXmin()) {
247 //find min, max of entries in buffer
248 Double_t xmin = fBuffer[2];
250 Double_t ymin = fBuffer[3];
252 Double_t zmin = fBuffer[4];
253 Double_t zmax = zmin;
254 for (Int_t i=1;i<nbentries;i++) {
255 Double_t x = fBuffer[4*i+2];
256 if (x < xmin) xmin = x;
257 if (x > xmax) xmax = x;
258 Double_t y = fBuffer[4*i+3];
259 if (y < ymin) ymin = y;
260 if (y > ymax) ymax = y;
261 Double_t z = fBuffer[4*i+4];
262 if (z < zmin) zmin = z;
263 if (z > zmax) zmax = z;
264 }
266 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax,ymin,ymax,zmin,zmax);
267 } else {
268 fBuffer = nullptr;
274 if (zmin < fZaxis.GetXmin()) ExtendAxis(zmin,&fZaxis);
275 if (zmax >= fZaxis.GetXmax()) ExtendAxis(zmax,&fZaxis);
276 fBuffer = buffer;
278 }
279 }
280 fBuffer = nullptr;
281
282 for (Int_t i=0;i<nbentries;i++) {
283 Fill(buffer[4*i+2],buffer[4*i+3],buffer[4*i+4],buffer[4*i+1]);
284 }
285 fBuffer = buffer;
286
287 if (action > 0) { delete [] fBuffer; fBuffer = nullptr; fBufferSize = 0;}
288 else {
290 else fBuffer[0] = 0;
291 }
292 return nbentries;
293}
294
295
296////////////////////////////////////////////////////////////////////////////////
297/// Accumulate arguments in buffer. When buffer is full, empty the buffer
298///
299/// - `fBuffer[0]` = number of entries in buffer
300/// - `fBuffer[1]` = w of first entry
301/// - `fBuffer[2]` = x of first entry
302/// - `fBuffer[3]` = y of first entry
303/// - `fBuffer[4]` = z of first entry
304
306{
307 if (!fBuffer) return -3;
309 if (nbentries < 0) {
311 fBuffer[0] = nbentries;
312 if (fEntries > 0) {
313 Double_t *buffer = fBuffer; fBuffer=nullptr;
314 Reset("ICES");
315 fBuffer = buffer;
316 }
317 }
318 if (4*nbentries+4 >= fBufferSize) {
319 BufferEmpty(1);
320 return Fill(x,y,z,w);
321 }
322 fBuffer[4*nbentries+1] = w;
323 fBuffer[4*nbentries+2] = x;
324 fBuffer[4*nbentries+3] = y;
325 fBuffer[4*nbentries+4] = z;
326 fBuffer[0] += 1;
327 return -3;
328}
329
330
331////////////////////////////////////////////////////////////////////////////////
332/// Invalid Fill method
333
335{
336 Error("Fill", "Invalid signature - do nothing");
337 return -1;
338}
339
340
341////////////////////////////////////////////////////////////////////////////////
342/// Increment cell defined by x,y,z by 1 .
343///
344/// The function returns the corresponding global bin number which has its content
345/// incremented by 1
346
348{
349 if (fBuffer) return BufferFill(x,y,z,1);
350
351 Int_t binx, biny, binz, bin;
352 fEntries++;
353 binx = fXaxis.FindBin(x);
354 biny = fYaxis.FindBin(y);
355 binz = fZaxis.FindBin(z);
356 if (binx <0 || biny <0 || binz<0) return -1;
357 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
358 if (fSumw2.fN) ++fSumw2.fArray[bin];
359 AddBinContent(bin);
360 if (binx == 0 || binx > fXaxis.GetNbins()) {
361 if (!GetStatOverflowsBehaviour()) return -1;
362 }
363
364 if (biny == 0 || biny > fYaxis.GetNbins()) {
365 if (!GetStatOverflowsBehaviour()) return -1;
366 }
367 if (binz == 0 || binz > fZaxis.GetNbins()) {
368 if (!GetStatOverflowsBehaviour()) return -1;
369 }
370 ++fTsumw;
371 ++fTsumw2;
372 fTsumwx += x;
373 fTsumwx2 += x*x;
374 fTsumwy += y;
375 fTsumwy2 += y*y;
376 fTsumwxy += x*y;
377 fTsumwz += z;
378 fTsumwz2 += z*z;
379 fTsumwxz += x*z;
380 fTsumwyz += y*z;
381 return bin;
382}
383
384
385////////////////////////////////////////////////////////////////////////////////
386/// Increment cell defined by x,y,z by a weight w.
387///
388/// If the weight is not equal to 1, the storage of the sum of squares of
389/// weights is automatically triggered and the sum of the squares of weights is incremented
390/// by w^2 in the cell corresponding to x,y,z.
391///
392/// The function returns the corresponding global bin number which has its content
393/// incremented by w
394
396{
397 if (fBuffer) return BufferFill(x,y,z,w);
398
399 Int_t binx, biny, binz, bin;
400 fEntries++;
401 binx = fXaxis.FindBin(x);
402 biny = fYaxis.FindBin(y);
403 binz = fZaxis.FindBin(z);
404 if (binx <0 || biny <0 || binz<0) return -1;
405 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
406 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2(); // must be called before AddBinContent
407 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
408 AddBinContent(bin,w);
409 if (binx == 0 || binx > fXaxis.GetNbins()) {
410 if (!GetStatOverflowsBehaviour()) return -1;
411 }
412 if (biny == 0 || biny > fYaxis.GetNbins()) {
413 if (!GetStatOverflowsBehaviour()) return -1;
414 }
415 if (binz == 0 || binz > fZaxis.GetNbins()) {
416 if (!GetStatOverflowsBehaviour()) return -1;
417 }
418 fTsumw += w;
419 fTsumw2 += w*w;
420 fTsumwx += w*x;
421 fTsumwx2 += w*x*x;
422 fTsumwy += w*y;
423 fTsumwy2 += w*y*y;
424 fTsumwxy += w*x*y;
425 fTsumwz += w*z;
426 fTsumwz2 += w*z*z;
427 fTsumwxz += w*x*z;
428 fTsumwyz += w*y*z;
429 return bin;
430}
431
432#ifdef __cpp_lib_atomic_ref
433////////////////////////////////////////////////////////////////////////////////
434/// Atomically increment cell defined by x,y,z by a weight w.
435///
436/// This function is thread safe, but it cannot be called concurrently with any
437/// other function of the histogram.
438/// \note This function requires compiling with c++20
439/// \note If the weight is not equal to 1, Sumw2() must have been called before starting to fill.
440/// \note In contrast to Fill(double,double,double,double), the histogram is not able
441/// to extend its own axes, so out-of-range fills will go into overflow.
442/// \note Automatic binning is not supported.
443void TH3D::FillThreadSafe(Double_t x, Double_t y, Double_t z, Double_t w)
444{
445 if (fBuffer)
446 throw std::logic_error("TH3 cannot be filled atomically when buffer is active.");
447 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW))
448 throw std::logic_error(
449 "Weighted filling 'Sumw2()' needs to be activated before FillThreadSafe is called with weights");
450
451 std::atomic_ref<decltype(fEntries)> atomicEntries{fEntries};
452 atomicEntries += 1.;
453
454 const auto binx = fXaxis.FindFixBin(x);
455 const auto biny = fYaxis.FindFixBin(y);
456 const auto binz = fZaxis.FindFixBin(z);
457 if (binx < 0 || biny < 0 || binz < 0)
458 return;
459 const auto bin = binx + (fXaxis.GetNbins() + 2) * (biny + (fYaxis.GetNbins() + 2) * binz);
460 if (fSumw2.fN) {
461 std::atomic_ref{fSumw2.fArray[bin]} += w * w;
462 }
463
464 std::atomic_ref{fArray[bin]} += w;
465
466 if (binx == 0 || binx > fXaxis.GetNbins() || biny == 0 || biny > fYaxis.GetNbins() || binz == 0 ||
467 binz > fZaxis.GetNbins()) {
469 return;
470 }
471
472 std::atomic_ref{fTsumw} += w;
473 std::atomic_ref{fTsumw2} += w * w;
474 std::atomic_ref{fTsumwx} += w * x;
475 std::atomic_ref{fTsumwx2} += w * x * x;
476 std::atomic_ref{fTsumwy} += w * y;
477 std::atomic_ref{fTsumwy2} += w * y * y;
478 std::atomic_ref{fTsumwxy} += w * x * y;
479 std::atomic_ref{fTsumwz} += w * z;
480 std::atomic_ref{fTsumwz2} += w * z * z;
481 std::atomic_ref{fTsumwxz} += w * x * z;
482 std::atomic_ref{fTsumwyz} += w * y * z;
483}
484#endif
485
486////////////////////////////////////////////////////////////////////////////////
487/// Increment cell defined by namex,namey,namez by a weight w
488///
489/// If the weight is not equal to 1, the storage of the sum of squares of
490/// weights is automatically triggered and the sum of the squares of weights is incremented
491/// by w^2 in the corresponding cell.
492/// The function returns the corresponding global bin number which has its content
493/// incremented by w
494
495Int_t TH3::Fill(const char *namex, const char *namey, const char *namez, Double_t w)
496{
497 Int_t binx, biny, binz, bin;
498 fEntries++;
502 if (binx <0 || biny <0 || binz<0) return -1;
503 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
504 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2(); // must be called before AddBinContent
505 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
506 AddBinContent(bin,w);
507 if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
508 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
509 if (binz == 0 || binz > fZaxis.GetNbins()) return -1;
510
511 Double_t v = w;
512 fTsumw += v;
513 fTsumw2 += v*v;
514 // skip computation of the statistics along axis that have labels (can be extended and are alphanumeric)
520 fTsumwx += v * x;
521 fTsumwx2 += v * x * x;
522 fTsumwy += v * y;
523 fTsumwy2 += v * y * y;
524 fTsumwxy += v * x * y;
525 fTsumwz += v * z;
526 fTsumwz2 += v * z * z;
527 fTsumwxz += v * x * z;
528 fTsumwyz += v * y * z;
529 }
530 return bin;
531}
532
533
534////////////////////////////////////////////////////////////////////////////////
535/// Increment cell defined by namex,y,namez by a weight w
536///
537/// If the weight is not equal to 1, the storage of the sum of squares of
538/// weights is automatically triggered and the sum of the squares of weights is incremented
539/// by w^2 in the corresponding cell.
540/// The function returns the corresponding global bin number which has its content
541/// incremented by w
542
543Int_t TH3::Fill(const char *namex, Double_t y, const char *namez, Double_t w)
544{
545 Int_t binx, biny, binz, bin;
546 fEntries++;
548 biny = fYaxis.FindBin(y);
550 if (binx <0 || biny <0 || binz<0) return -1;
551 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
552 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2(); // must be called before AddBinContent
553 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
554 AddBinContent(bin,w);
555 if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
556 if (biny == 0 || biny > fYaxis.GetNbins()) {
557 if (!GetStatOverflowsBehaviour()) return -1;
558 }
559 if (binz == 0 || binz > fZaxis.GetNbins()) return -1;
560 Double_t v = w;
561 fTsumw += v;
562 fTsumw2 += v*v;
563 fTsumwy += v*y;
564 fTsumwy2 += v*y*y;
565 // skip computation of the statistics along axis that have labels (can be extended and are alphanumeric)
570 fTsumwx += v * x;
571 fTsumwx2 += v * x * x;
572 fTsumwxy += v * x * y;
573 fTsumwz += v * z;
574 fTsumwz2 += v * z * z;
575 fTsumwxz += v * x * z;
576 fTsumwyz += v * y * z;
577 }
578 return bin;
579}
580
581
582////////////////////////////////////////////////////////////////////////////////
583/// Increment cell defined by namex,namey,z by a weight w
584///
585/// If the weight is not equal to 1, the storage of the sum of squares of
586/// weights is automatically triggered and the sum of the squares of weights is incremented
587/// by w^2 in the corresponding cell.
588/// The function returns the corresponding global bin number which has its content
589/// incremented by w
590
591Int_t TH3::Fill(const char *namex, const char *namey, Double_t z, Double_t w)
592{
593 Int_t binx, biny, binz, bin;
594 fEntries++;
597 binz = fZaxis.FindBin(z);
598 if (binx <0 || biny <0 || binz<0) return -1;
599 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
600 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2(); // must be called before AddBinContent
601 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
602 AddBinContent(bin,w);
603 if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
604 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
605 if (binz == 0 || binz > fZaxis.GetNbins()) {
606 if (!GetStatOverflowsBehaviour()) return -1;
607 }
608 Double_t v = w;
609 fTsumw += v;
610 fTsumw2 += v*v;
611 fTsumwz += v*z;
612 fTsumwz2 += v*z*z;
613 // skip computation of the statistics along axis that have labels (can be extended and are alphanumeric)
618 fTsumwx += v * x;
619 fTsumwx2 += v * x * x;
620 fTsumwy += v * y;
621 fTsumwy2 += v * y * y;
622 fTsumwxy += v * x * y;
623 fTsumwxz += v * x * z;
624 fTsumwyz += v * y * z;
625 }
626 return bin;
627}
628
629
630////////////////////////////////////////////////////////////////////////////////
631/// Increment cell defined by x,namey,namez by a weight w
632///
633/// If the weight is not equal to 1, the storage of the sum of squares of
634/// weights is automatically triggered and the sum of the squares of weights is incremented
635/// by w^2 in the corresponding cell.
636/// The function returns the corresponding global bin number which has its content
637/// incremented by w
638
639Int_t TH3::Fill(Double_t x, const char *namey, const char *namez, Double_t w)
640{
641 Int_t binx, biny, binz, bin;
642 fEntries++;
643 binx = fXaxis.FindBin(x);
646 if (binx <0 || biny <0 || binz<0) return -1;
647 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
648 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2(); // must be called before AddBinContent
649 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
650 AddBinContent(bin,w);
651 if (binx == 0 || binx > fXaxis.GetNbins()) {
652 if (!GetStatOverflowsBehaviour()) return -1;
653 }
654 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
655 if (binz == 0 || binz > fZaxis.GetNbins()) return -1;
656
657 Double_t v = w;
658 fTsumw += v;
659 fTsumw2 += v * v;
660 fTsumwx += v * x;
661 fTsumwx2 += v * x * x;
662 // skip computation of the statistics along axis that have labels (can be extended and are alphanumeric)
667 fTsumwy += v * y;
668 fTsumwy2 += v * y * y;
669 fTsumwxy += v * x * y;
670 fTsumwz += v * z;
671 fTsumwz2 += v * z * z;
672 fTsumwxz += v * x * z;
673 fTsumwyz += v * y * z;
674 }
675 return bin;
676}
677
678////////////////////////////////////////////////////////////////////////////////
679/// Increment cell defined by namex , y ,z by a weight w
680///
681/// If the weight is not equal to 1, the storage of the sum of squares of
682/// weights is automatically triggered and the sum of the squares of weights is incremented
683/// by w^2 in the corresponding cell.
684/// The function returns the corresponding global bin number which has its content
685/// incremented by w
686
688{
689 Int_t binx, biny, binz, bin;
690 fEntries++;
692 biny = fYaxis.FindBin(y);
693 binz = fZaxis.FindBin(z);
694 if (binx < 0 || biny < 0 || binz < 0)
695 return -1;
696 bin = binx + (fXaxis.GetNbins() + 2) * (biny + (fYaxis.GetNbins() + 2) * binz);
697 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW))
698 Sumw2(); // must be called before AddBinContent
699 if (fSumw2.fN)
700 fSumw2.fArray[bin] += w * w;
701 AddBinContent(bin, w);
702 if (binx == 0 || binx > fXaxis.GetNbins()) {
703 return -1;
704 }
705 if (biny == 0 || biny > fYaxis.GetNbins()) {
707 return -1;
708 }
709 if (binz == 0 || binz > fZaxis.GetNbins()) {
711 return -1;
712 }
713 Double_t v = w;
714 fTsumw += v;
715 fTsumw2 += v * v;
716 fTsumwy += v * y;
717 fTsumwy2 += v * y * y;
718 fTsumwz += v * z;
719 fTsumwz2 += v * z * z;
720 fTsumwyz += v * y * z;
721 // skip computation for x axis : for only one axis no need to use bit mask
722 if (!fXaxis.CanExtend() || !fXaxis.IsAlphanumeric()) {
724 fTsumwx += v * x;
725 fTsumwx2 += v * x * x;
726 fTsumwxy += v * x * y;
727 fTsumwxz += v * x * z;
728 }
729 return bin;
730}
731
732////////////////////////////////////////////////////////////////////////////////
733/// Increment cell defined by x,namey,z by a weight w
734///
735/// If the weight is not equal to 1, the storage of the sum of squares of
736/// weights is automatically triggered and the sum of the squares of weights is incremented
737/// by w^2 in the corresponding cell.
738/// The function returns the corresponding global bin number which has its content
739/// incremented by w
740
742{
743 Int_t binx, biny, binz, bin;
744 fEntries++;
745 binx = fXaxis.FindBin(x);
747 binz = fZaxis.FindBin(z);
748 if (binx <0 || biny <0 || binz<0) return -1;
749 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
750 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2(); // must be called before AddBinContent
751 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
752 AddBinContent(bin,w);
753 if (binx == 0 || binx > fXaxis.GetNbins()) {
754 if (!GetStatOverflowsBehaviour()) return -1;
755 }
756 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
757 if (binz == 0 || binz > fZaxis.GetNbins()) {
758 if (!GetStatOverflowsBehaviour()) return -1;
759 }
760 Double_t v = w;
761 fTsumw += v;
762 fTsumw2 += v*v;
763 fTsumwx += v*x;
764 fTsumwx2 += v*x*x;
765 fTsumwz += v*z;
766 fTsumwz2 += v*z*z;
767 fTsumwxz += v*x*z;
768 // skip computation for y axis : for only one axis no need to use bit mask
769 if (!fYaxis.CanExtend() || !fYaxis.IsAlphanumeric()) {
771 fTsumwy += v*y;
772 fTsumwy2 += v*y*y;
773 fTsumwxy += v*x*y;
774 fTsumwyz += v*y*z;
775 }
776
777 return bin;
778}
779
780
781////////////////////////////////////////////////////////////////////////////////
782/// Increment cell defined by x,y,namez by a weight w
783///
784/// If the weight is not equal to 1, the storage of the sum of squares of
785/// weights is automatically triggered and the sum of the squares of weights is incremented
786/// by w^2 in the corresponding cell.
787/// The function returns the corresponding global bin number which has its content
788/// incremented by w
789
791{
792 Int_t binx, biny, binz, bin;
793 fEntries++;
794 binx = fXaxis.FindBin(x);
795 biny = fYaxis.FindBin(y);
797 if (binx <0 || biny <0 || binz<0) return -1;
798 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
799 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2(); // must be called before AddBinContent
800 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
801 AddBinContent(bin,w);
802 if (binx == 0 || binx > fXaxis.GetNbins()) {
803 if (!GetStatOverflowsBehaviour()) return -1;
804 }
805 if (biny == 0 || biny > fYaxis.GetNbins()) {
806 if (!GetStatOverflowsBehaviour()) return -1;
807 }
808 if (binz == 0 || binz > fZaxis.GetNbins()) return -1;
809
810 Double_t v = w;
811 fTsumw += v;
812 fTsumw2 += v*v;
813 fTsumwx += v*x;
814 fTsumwx2 += v*x*x;
815 fTsumwy += v*y;
816 fTsumwy2 += v*y*y;
817 fTsumwxy += v*x*y;
818
819 // skip computation for z axis : for only one axis no need to use bit mask
820 if (!fZaxis.CanExtend() || !fZaxis.IsAlphanumeric()) {
822 fTsumwz += v*z;
823 fTsumwz2 += v*z*z;
824 fTsumwxz += v*x*z;
825 fTsumwyz += v*y*z;
826 }
827 return bin;
828}
829
830
831////////////////////////////////////////////////////////////////////////////////
832/// Fill histogram following distribution in function fname.
833///
834/// @param fname : Function name used for filling the histogram
835/// @param ntimes : number of times the histogram is filled
836/// @param rng : (optional) Random number generator used to sample
837///
838/// The distribution contained in the function fname (TF1) is integrated
839/// over the channel contents.
840/// It is normalized to 1.
841/// Getting one random number implies:
842/// - Generating a random number between 0 and 1 (say r1)
843/// - Look in which bin in the normalized integral r1 corresponds to
844/// - Fill histogram channel
845/// ntimes random numbers are generated
846///
847/// N.B. By dfault this methods approximates the integral of the function in each bin with the
848/// function value at the center of the bin, multiplied by the bin width
849///
850/// One can also call TF1::GetRandom to get a random variate from a function.
851
853{
854 Int_t bin, binx, biny, binz, ibin, loop;
855 Double_t r1, x, y,z, xv[3];
856 TF3 *f1 = dynamic_cast<TF3*>( fobj );
857 if (!f1) { Error("FillRandom", "Function: %s is not a TF3, is a %s",fobj->GetName(),fobj->IsA()->GetName()); return; }
858
859 TAxis & xAxis = fXaxis;
860 TAxis & yAxis = fYaxis;
861 TAxis & zAxis = fZaxis;
862
863 // in case axes of histogram are not defined use the function axis
865 Double_t xmin,xmax,ymin,ymax,zmin,zmax;
866 f1->GetRange(xmin,ymin,zmin,xmax,ymax,zmax);
867 Info("FillRandom","Using function axis and range ([%g,%g],[%g,%g],[%g,%g])",xmin, xmax,ymin,ymax,zmin,zmax);
868 xAxis = *(f1->GetHistogram()->GetXaxis());
869 yAxis = *(f1->GetHistogram()->GetYaxis());
870 zAxis = *(f1->GetHistogram()->GetZaxis());
871 }
872
873 // Allocate temporary space to store the integral and compute integral
874 Int_t nbinsx = xAxis.GetNbins();
875 Int_t nbinsy = yAxis.GetNbins();
876 Int_t nbinsz = zAxis.GetNbins();
878 Int_t nbins = nbinsx*nbinsy*nbinsz;
879
880 Double_t *integral = new Double_t[nbins+1];
881 ibin = 0;
882 integral[ibin] = 0;
883 // approximate integral with function value at bin center
884 for (binz=1;binz<=nbinsz;binz++) {
885 xv[2] = zAxis.GetBinCenter(binz);
886 for (biny=1;biny<=nbinsy;biny++) {
887 xv[1] = yAxis.GetBinCenter(biny);
888 for (binx=1;binx<=nbinsx;binx++) {
889 xv[0] = xAxis.GetBinCenter(binx);
890 ibin++;
891 Double_t fint = f1->EvalPar(xv, nullptr);
892 // uncomment this line to have the integral computation in a bin
893 // Double_t fint = f1->Integral(xAxis.GetBinLowEdge(binx), xAxis.GetBinUpEdge(binx),
894 // yAxis.GetBinLowEdge(biny), yAxis.GetBinUpEdge(biny),
895 // zAxis.GetBinLowEdge(binz), zAxis.GetBinUpEdge(binz));
896 integral[ibin] = integral[ibin-1] + fint;
897 }
898 }
899 }
900
901 // Normalize integral to 1
902 if (integral[nbins] == 0 ) {
903 delete [] integral;
904 Error("FillRandom", "Integral = zero"); return;
905 }
906 for (bin=1;bin<=nbins;bin++) integral[bin] /= integral[nbins];
907
908 // Start main loop ntimes
909 if (fDimension < 2) nbinsy = -1;
910 if (fDimension < 3) nbinsz = -1;
911 for (loop=0;loop<ntimes;loop++) {
912 r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
913 ibin = TMath::BinarySearch(nbins,&integral[0],r1);
914 binz = ibin/nxy;
915 biny = (ibin - nxy*binz)/nbinsx;
916 binx = 1 + ibin - nbinsx*(biny + nbinsy*binz);
917 if (nbinsz) binz++;
918 if (nbinsy) biny++;
919 x = xAxis.GetBinCenter(binx);
920 y = yAxis.GetBinCenter(biny);
921 z = zAxis.GetBinCenter(binz);
922 Fill(x,y,z, 1.);
923 }
924 delete [] integral;
925}
926
927
928////////////////////////////////////////////////////////////////////////////////
929/// Fill histogram following distribution in histogram h.
930///
931/// @param h : Histogram pointer used for sampling random number
932/// @param ntimes : number of times the histogram is filled
933/// @param rng : (optional) Random number generator used for sampling
934///
935/// The distribution contained in the histogram h (TH3) is integrated
936/// over the channel contents.
937/// It is normalized to 1.
938/// Getting one random number implies:
939/// - Generating a random number between 0 and 1 (say r1)
940/// - Look in which bin in the normalized integral r1 corresponds to
941/// - Fill histogram channel
942/// ntimes random numbers are generated
943
945{
946 if (!h) { Error("FillRandom", "Null histogram"); return; }
947 if (fDimension != h->GetDimension()) {
948 Error("FillRandom", "Histograms with different dimensions"); return;
949 }
950
951 if (h->ComputeIntegral() == 0) return;
952
953 TH3 *h3 = (TH3*)h;
954 Int_t loop;
955 Double_t x,y,z;
956 for (loop=0;loop<ntimes;loop++) {
957 h3->GetRandom3(x,y,z,rng);
958 Fill(x,y,z);
959 }
960}
961
962////////////////////////////////////////////////////////////////////////////////
963/// Project slices along Z in case of a 3-D histogram, then fit each slice
964/// with function f1 and make a 2-d histogram for each fit parameter
965/// Only cells in the bin range [binminx,binmaxx] and [binminy,binmaxy] are considered.
966/// if f1=0, a gaussian is assumed
967/// Before invoking this function, one can set a subrange to be fitted along Z
968/// via f1->SetRange(zmin,zmax)
969/// The argument option (default="QNR") can be used to change the fit options.
970/// "Q" means Quiet mode
971/// "N" means do not show the result of the fit
972/// "R" means fit the function in the specified function range
973///
974/// Note that the generated histograms are added to the list of objects
975/// in the current directory. It is the user's responsibility to delete
976/// these histograms.
977///
978/// Example: Assume a 3-d histogram h3
979/// Root > h3->FitSlicesZ(); produces 4 TH2D histograms
980/// with h3_0 containing parameter 0(Constant) for a Gaus fit
981/// of each cell in X,Y projected along Z
982/// with h3_1 containing parameter 1(Mean) for a gaus fit
983/// with h3_2 containing parameter 2(StdDev) for a gaus fit
984/// with h3_chi2 containing the chisquare/number of degrees of freedom for a gaus fit
985///
986/// Root > h3->Fit(0,15,22,0,0,10);
987/// same as above, but only for bins 15 to 22 along X
988/// and only for cells in X,Y for which the corresponding projection
989/// along Z has more than cut bins filled.
990///
991/// NOTE: To access the generated histograms in the current directory, do eg:
992/// TH2D *h3_1 = (TH2D*)gDirectory->Get("h3_1");
993
995{
996 //Int_t nbinsz = fZaxis.GetNbins();
997
998 // get correct first and last bins for outer axes used in the loop doing the slices
999 // when using default values (0,-1) check if an axis range is set in outer axis
1000 // do same as in DoProjection for inner axis
1002 Int_t nbins = outerAxis.GetNbins();
1003 if ( lastbin < firstbin && outerAxis.TestBit(TAxis::kAxisRange) ) {
1004 firstbin = outerAxis.GetFirst();
1005 lastbin = outerAxis.GetLast();
1006 // For special case of TAxis::SetRange, when first == 1 and last
1007 // = N and the range bit has been set, the TAxis will return 0
1008 // for both.
1009 if (firstbin == 0 && lastbin == 0) {
1010 firstbin = 1;
1011 lastbin = nbins;
1012 }
1013 }
1014 if (firstbin < 0) firstbin = 0;
1015 if (lastbin < 0 || lastbin > nbins + 1) lastbin = nbins + 1;
1016 if (lastbin < firstbin) {firstbin = 0; lastbin = nbins + 1;}
1017 };
1018
1021
1022 // limits for the axis of the fit results histograms are different
1024 Int_t &nBins, Double_t &xMin, Double_t & xMax) {
1025 Int_t firstOutBin = std::max(firstbin,1);
1026 Int_t lastOutBin = std::min(lastbin,outerAxis.GetNbins() ) ;
1027 nBins = lastOutBin-firstOutBin+1;
1028 xMin = outerAxis.GetBinLowEdge(firstOutBin);
1029 xMax = outerAxis.GetBinUpEdge(lastOutBin);
1030 // return first bin that is used in case of variable bin size axis
1031 return firstOutBin;
1032 };
1033 Int_t nbinsX = 0;
1034 Double_t xMin, xMax = 0;
1036 Int_t nbinsY = 0;
1037 Double_t yMin, yMax = 0;
1039
1040 //default is to fit with a gaussian
1041 if (f1 == nullptr) {
1042 f1 = (TF1*)gROOT->GetFunction("gaus");
1043 if (f1 == nullptr) f1 = new TF1("gaus","gaus",fZaxis.GetXmin(),fZaxis.GetXmax());
1045 }
1046 const char *fname = f1->GetName();
1047 Int_t npar = f1->GetNpar();
1048 Double_t *parsave = new Double_t[npar];
1050
1051 //Create one 2-d histogram for each function parameter
1052 Int_t ipar;
1053 TString name;
1054 TString title;
1055 std::vector<TH1*> hlist(npar+1); // include also chi2 histogram
1056 const TArrayD *xbins = fXaxis.GetXbins();
1057 const TArrayD *ybins = fYaxis.GetXbins();
1058 for (ipar=0;ipar<= npar;ipar++) {
1059 if (ipar < npar) {
1060 // fitted parameter histograms
1061 name = TString::Format("%s_%d",GetName(),ipar);
1062 title = TString::Format("Fitted value of par[%d]=%s",ipar,f1->GetParName(ipar));
1063 } else {
1064 // chi2 histograms
1065 name = TString::Format("%s_chi2",GetName());
1066 title = "chisquare";
1067 }
1068 if (xbins->fN == 0 && ybins->fN == 0) {
1069 hlist[ipar] = new TH2D(name, title,
1070 nbinsX, xMin, xMax,
1071 nbinsY, yMin, yMax);
1072 } else if (xbins->fN > 0 && ybins->fN > 0 ) {
1073 hlist[ipar] = new TH2D(name, title,
1074 nbinsX, &xbins->fArray[firstBinXaxis],
1075 nbinsY, &ybins->fArray[firstBinYaxis]);
1076 }
1077 // mixed case do not exist for TH3
1078 R__ASSERT(hlist[ipar]);
1079
1080 hlist[ipar]->GetXaxis()->SetTitle(fXaxis.GetTitle());
1081 hlist[ipar]->GetYaxis()->SetTitle(fYaxis.GetTitle());
1082 }
1083 TH1 * hchi2 = hlist.back();
1084
1085 //Loop on all cells in X,Y generate a projection along Z
1086 TH1D *hpz = nullptr;
1087 TString opt(option);
1088 // add option "N" when fitting the 2D histograms
1089 opt += " N ";
1090
1091 for (Int_t biny=binminy; biny<=binmaxy; biny++) {
1092 for (Int_t binx=binminx; binx<=binmaxx; binx++) {
1093 // use TH3::ProjectionZ
1094 hpz = ProjectionZ("R_temp",binx,binx,biny,biny);
1095
1096 Double_t nentries = hpz->GetEntries();
1097 if ( nentries <= 0 || nentries < cut) {
1098 if (!opt.Contains("Q"))
1099 Info("FitSlicesZ","Slice (%d,%d) skipped, the number of entries is zero or smaller than the given cut value, n=%f",binx,biny,nentries);
1100 continue;
1101 }
1103 Int_t bin = hlist[0]->FindBin( fXaxis.GetBinCenter(binx), fYaxis.GetBinCenter(biny) );
1104 if (!opt.Contains("Q")) {
1105 int ibx,iby,ibz = 0;
1106 hlist[0]->GetBinXYZ(bin,ibx,iby,ibz);
1107 Info("DoFitSlices","Slice fit [(%f,%f),(%f,%f)]",hlist[0]->GetXaxis()->GetBinLowEdge(ibx), hlist[0]->GetXaxis()->GetBinUpEdge(ibx),
1108 hlist[0]->GetYaxis()->GetBinLowEdge(iby), hlist[0]->GetYaxis()->GetBinUpEdge(iby));
1109 }
1110 hpz->Fit(fname,opt.Data());
1112 if (npfits > npar && npfits >= cut) {
1113 for (ipar=0;ipar<npar;ipar++) {
1114 hlist[ipar]->SetBinContent(bin,f1->GetParameter(ipar));
1115 hlist[ipar]->SetBinError(bin,f1->GetParError(ipar));
1116 }
1117 hchi2->SetBinContent(bin,f1->GetChisquare()/(npfits-npar));
1118 }
1119 else {
1120 if (!opt.Contains("Q"))
1121 Info("FitSlicesZ","Fitted slice (%d,%d) skipped, the number of fitted points is too small, n=%d",binx,biny,npfits);
1122 }
1123 }
1124 }
1125 delete [] parsave;
1126 delete hpz;
1127}
1128
1129
1130////////////////////////////////////////////////////////////////////////////////
1131/// See comments in TH1::GetBin
1132
1134{
1135 Int_t ofy = fYaxis.GetNbins() + 1; // code duplication unavoidable because TH3 does not inherit from TH2
1136 if (biny < 0) biny = 0;
1137 if (biny > ofy) biny = ofy;
1138
1139 Int_t ofz = fZaxis.GetNbins() + 1; // overflow bin
1140 if (binz < 0) binz = 0;
1141 if (binz > ofz) binz = ofz;
1142
1143 return TH1::GetBin(binx) + (fXaxis.GetNbins() + 2) * (biny + (fYaxis.GetNbins() + 2) * binz);
1144}
1145
1146
1147////////////////////////////////////////////////////////////////////////////////
1148/// Compute first cell (binx,biny,binz) in the range [firstx,lastx](firsty,lasty][firstz,lastz] for which
1149/// diff = abs(cell_content-c) <= maxdiff
1150/// In case several cells in the specified range with diff=0 are found
1151/// the first cell found is returned in binx,biny,binz.
1152/// In case several cells in the specified range satisfy diff <=maxdiff
1153/// the cell with the smallest difference is returned in binx,biny,binz.
1154/// In all cases the function returns the smallest difference.
1155///
1156/// NOTE1: if firstx <= 0, firstx is set to bin 1
1157/// if (lastx < firstx then firstx is set to the number of bins in X
1158/// ie if firstx=0 and lastx=0 (default) the search is on all bins in X.
1159/// if firsty <= 0, firsty is set to bin 1
1160/// if (lasty < firsty then firsty is set to the number of bins in Y
1161/// ie if firsty=0 and lasty=0 (default) the search is on all bins in Y.
1162/// if firstz <= 0, firstz is set to bin 1
1163/// if (lastz < firstz then firstz is set to the number of bins in Z
1164/// ie if firstz=0 and lastz=0 (default) the search is on all bins in Z.
1165/// NOTE2: if maxdiff=0 (default), the first cell with content=c is returned.
1166
1171 Double_t maxdiff) const
1172{
1173 if (fDimension != 3) {
1174 binx = 0;
1175 biny = 0;
1176 binz = 0;
1177 Error("GetBinWithContent3","function is only valid for 3-D histograms");
1178 return 0;
1179 }
1180 if (firstx <= 0) firstx = 1;
1181 if (lastx < firstx) lastx = fXaxis.GetNbins();
1182 if (firsty <= 0) firsty = 1;
1183 if (lasty < firsty) lasty = fYaxis.GetNbins();
1184 if (firstz <= 0) firstz = 1;
1185 if (lastz < firstz) lastz = fZaxis.GetNbins();
1186 Int_t binminx = 0, binminy=0, binminz=0;
1187 Double_t diff, curmax = 1.e240;
1188 for (Int_t k=firstz;k<=lastz;k++) {
1189 for (Int_t j=firsty;j<=lasty;j++) {
1190 for (Int_t i=firstx;i<=lastx;i++) {
1192 if (diff <= 0) {binx = i; biny=j; binz=k; return diff;}
1193 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i; binminy=j;binminz=k;}
1194 }
1195 }
1196 }
1197 binx = binminx;
1198 biny = binminy;
1199 binz = binminz;
1200 return curmax;
1201}
1202
1203
1204////////////////////////////////////////////////////////////////////////////////
1205/// Return correlation factor between axis1 and axis2.
1206
1208{
1209 if (axis1 < 1 || axis2 < 1 || axis1 > 3 || axis2 > 3) {
1210 Error("GetCorrelationFactor","Wrong parameters");
1211 return 0;
1212 }
1213 if (axis1 == axis2) return 1;
1215 if (stddev1 == 0) return 0;
1217 if (stddev2 == 0) return 0;
1219}
1220
1221
1222////////////////////////////////////////////////////////////////////////////////
1223/// Return covariance between axis1 and axis2.
1224
1226{
1227 if (axis1 < 1 || axis2 < 1 || axis1 > 3 || axis2 > 3) {
1228 Error("GetCovariance","Wrong parameters");
1229 return 0;
1230 }
1232 GetStats(stats);
1233 Double_t sumw = stats[0];
1234 Double_t sumwx = stats[2];
1235 Double_t sumwx2 = stats[3];
1236 Double_t sumwy = stats[4];
1237 Double_t sumwy2 = stats[5];
1238 Double_t sumwxy = stats[6];
1239 Double_t sumwz = stats[7];
1240 Double_t sumwz2 = stats[8];
1241 Double_t sumwxz = stats[9];
1242 Double_t sumwyz = stats[10];
1243
1244 if (sumw == 0) return 0;
1245 if (axis1 == 1 && axis2 == 1) {
1247 }
1248 if (axis1 == 2 && axis2 == 2) {
1250 }
1251 if (axis1 == 3 && axis2 == 3) {
1253 }
1254 if ((axis1 == 1 && axis2 == 2) || (axis1 == 2 && axis2 == 1)) {
1255 return sumwxy/sumw - sumwx*sumwy/(sumw*sumw);
1256 }
1257 if ((axis1 == 1 && axis2 == 3) || (axis1 == 3 && axis2 == 1)) {
1258 return sumwxz/sumw - sumwx*sumwz/(sumw*sumw);
1259 }
1260 if ((axis1 == 2 && axis2 == 3) || (axis1 == 3 && axis2 == 2)) {
1261 return sumwyz/sumw - sumwy*sumwz/(sumw*sumw);
1262 }
1263 return 0;
1264}
1265
1266
1267////////////////////////////////////////////////////////////////////////////////
1268/// Return 3 random numbers along axis x , y and z distributed according
1269/// to the cell-contents of this 3-dim histogram
1270/// @param[out] x reference to random generated x value
1271/// @param[out] y reference to random generated y value
1272/// @param[out] z reference to random generated z value
1273/// @param[in] rng (optional) Random number generator pointer used (default is gRandom)
1274
1276{
1281 Int_t nbins = nxy*nbinsz;
1282 Double_t integral;
1283 // compute integral checking that all bins have positive content (see ROOT-5894)
1284 if (fIntegral) {
1285 if (fIntegral[nbins+1] != fEntries) integral = ComputeIntegral(true);
1286 else integral = fIntegral[nbins];
1287 } else {
1288 integral = ComputeIntegral(true);
1289 }
1290 if (integral == 0 ) { x = 0; y = 0; z = 0; return;}
1291 // case histogram has negative bins
1292 if (integral == TMath::QuietNaN() ) { x = TMath::QuietNaN(); y = TMath::QuietNaN(); z = TMath::QuietNaN(); return;}
1293
1294 if (!rng) rng = gRandom;
1295 Double_t r1 = rng->Rndm();
1297 Int_t binz = ibin/nxy;
1298 Int_t biny = (ibin - nxy*binz)/nbinsx;
1301 if (r1 > fIntegral[ibin]) x +=
1303 y = fYaxis.GetBinLowEdge(biny+1) + fYaxis.GetBinWidth(biny+1)*rng->Rndm();
1304 z = fZaxis.GetBinLowEdge(binz+1) + fZaxis.GetBinWidth(binz+1)*rng->Rndm();
1305}
1306
1307
1308////////////////////////////////////////////////////////////////////////////////
1309/// Fill the array stats from the contents of this histogram
1310/// The array stats must be correctly dimensioned in the calling program.
1311/// stats[0] = sumw
1312/// stats[1] = sumw2
1313/// stats[2] = sumwx
1314/// stats[3] = sumwx2
1315/// stats[4] = sumwy
1316/// stats[5] = sumwy2
1317/// stats[6] = sumwxy
1318/// stats[7] = sumwz
1319/// stats[8] = sumwz2
1320/// stats[9] = sumwxz
1321/// stats[10]= sumwyz
1322
1324{
1325 if (fBuffer) ((TH3*)this)->BufferEmpty();
1326
1327 Int_t bin, binx, biny, binz;
1328 Double_t w,err;
1329 Double_t x,y,z;
1331 for (bin=0;bin<11;bin++) stats[bin] = 0;
1332
1339 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
1342 if (firstBinX == 1) firstBinX = 0;
1343 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
1344 }
1346 if (firstBinY == 1) firstBinY = 0;
1347 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
1348 }
1350 if (firstBinZ == 1) firstBinZ = 0;
1351 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
1352 }
1353 }
1354
1355 // check for labels axis . In that case corresponsing statistics do not make sense and it is set to zero
1356 Bool_t labelXaxis = ((const_cast<TAxis&>(fXaxis)).GetLabels() && fXaxis.CanExtend() );
1357 Bool_t labelYaxis = ((const_cast<TAxis&>(fYaxis)).GetLabels() && fYaxis.CanExtend() );
1358 Bool_t labelZaxis = ((const_cast<TAxis&>(fZaxis)).GetLabels() && fZaxis.CanExtend() );
1359
1360 for (binz = firstBinZ; binz <= lastBinZ; binz++) {
1361 z = (!labelZaxis) ? fZaxis.GetBinCenter(binz) : 0;
1362 for (biny = firstBinY; biny <= lastBinY; biny++) {
1363 y = (!labelYaxis) ? fYaxis.GetBinCenter(biny) : 0;
1364 for (binx = firstBinX; binx <= lastBinX; binx++) {
1365 bin = GetBin(binx,biny,binz);
1366 x = (!labelXaxis) ? fXaxis.GetBinCenter(binx) : 0;
1367 //w = TMath::Abs(GetBinContent(bin));
1368 w = RetrieveBinContent(bin);
1369 err = TMath::Abs(GetBinError(bin));
1370 stats[0] += w;
1371 stats[1] += err*err;
1372 stats[2] += w*x;
1373 stats[3] += w*x*x;
1374 stats[4] += w*y;
1375 stats[5] += w*y*y;
1376 stats[6] += w*x*y;
1377 stats[7] += w*z;
1378 stats[8] += w*z*z;
1379 stats[9] += w*x*z;
1380 stats[10]+= w*y*z;
1381 }
1382 }
1383 }
1384 } else {
1385 stats[0] = fTsumw;
1386 stats[1] = fTsumw2;
1387 stats[2] = fTsumwx;
1388 stats[3] = fTsumwx2;
1389 stats[4] = fTsumwy;
1390 stats[5] = fTsumwy2;
1391 stats[6] = fTsumwxy;
1392 stats[7] = fTsumwz;
1393 stats[8] = fTsumwz2;
1394 stats[9] = fTsumwxz;
1395 stats[10]= fTsumwyz;
1396 }
1397}
1398
1399
1400////////////////////////////////////////////////////////////////////////////////
1401/// Return integral of bin contents. Only bins in the bins range are considered.
1402/// By default the integral is computed as the sum of bin contents in the range.
1403/// if option "width" is specified, the integral is the sum of
1404/// the bin contents multiplied by the bin width in x, y and in z.
1405
1412
1413
1414////////////////////////////////////////////////////////////////////////////////
1415/// Return integral of bin contents in range [binx1,binx2],[biny1,biny2],[binz1,binz2]
1416/// for a 3-D histogram
1417/// By default the integral is computed as the sum of bin contents in the range.
1418/// if option "width" is specified, the integral is the sum of
1419/// the bin contents multiplied by the bin width in x, y and in z.
1420
1427
1428
1429////////////////////////////////////////////////////////////////////////////////
1430/// Return integral of bin contents in range [binx1,binx2],[biny1,biny2],[binz1,binz2]
1431/// for a 3-D histogram. Calculates also the integral error using error propagation
1432/// from the bin errors assuming that all the bins are uncorrelated.
1433/// By default the integral is computed as the sum of bin contents in the range.
1434/// if option "width" is specified, the integral is the sum of
1435/// the bin contents multiplied by the bin width in x, y and in z.
1436
1443
1444////////////////////////////////////////////////////////////////////////////////
1445///Not yet implemented
1446
1448{
1449 Error("Interpolate","This function must be called with 3 arguments for a TH3");
1450 return 0;
1451}
1452
1453
1454////////////////////////////////////////////////////////////////////////////////
1455///Not yet implemented
1456
1458{
1459 Error("Interpolate","This function must be called with 3 arguments for a TH3");
1460 return 0;
1461}
1462
1463
1464////////////////////////////////////////////////////////////////////////////////
1465/// Given a point P(x,y,z), Interpolate approximates the value via trilinear interpolation
1466/// based on the 8 nearest bin center points (corner of the cube surrounding the points)
1467/// The Algorithm is described in http://en.wikipedia.org/wiki/Trilinear_interpolation
1468/// The given values (x,y,z) must be between first bin center and last bin center for each coordinate:
1469///
1470/// fXAxis.GetBinCenter(1) < x < fXaxis.GetBinCenter(nbinX) AND
1471/// fYAxis.GetBinCenter(1) < y < fYaxis.GetBinCenter(nbinY) AND
1472/// fZAxis.GetBinCenter(1) < z < fZaxis.GetBinCenter(nbinZ)
1473
1475{
1477 if ( x < fXaxis.GetBinCenter(ubx) ) ubx -= 1;
1478 Int_t obx = ubx + 1;
1479
1481 if ( y < fYaxis.GetBinCenter(uby) ) uby -= 1;
1482 Int_t oby = uby + 1;
1483
1485 if ( z < fZaxis.GetBinCenter(ubz) ) ubz -= 1;
1486 Int_t obz = ubz + 1;
1487
1488
1489// if ( IsBinUnderflow(GetBin(ubx, uby, ubz)) ||
1490// IsBinOverflow (GetBin(obx, oby, obz)) ) {
1491 if (ubx <=0 || uby <=0 || ubz <= 0 ||
1492 obx > fXaxis.GetNbins() || oby > fYaxis.GetNbins() || obz > fZaxis.GetNbins() ) {
1493 Error("Interpolate","Cannot interpolate outside histogram domain.");
1494 return 0;
1495 }
1496
1500
1503 Double_t zd = (z - fZaxis.GetBinCenter(ubz)) / zw;
1504
1505
1510
1511
1512 Double_t i1 = v[0] * (1 - zd) + v[1] * zd;
1513 Double_t i2 = v[2] * (1 - zd) + v[3] * zd;
1514 Double_t j1 = v[4] * (1 - zd) + v[5] * zd;
1515 Double_t j2 = v[6] * (1 - zd) + v[7] * zd;
1516
1517
1518 Double_t w1 = i1 * (1 - yd) + i2 * yd;
1519 Double_t w2 = j1 * (1 - yd) + j2 * yd;
1520
1521
1522 Double_t result = w1 * (1 - xd) + w2 * xd;
1523
1524 return result;
1525}
1526
1527
1528////////////////////////////////////////////////////////////////////////////////
1529/// Statistical test of compatibility in shape between
1530/// THIS histogram and h2, using Kolmogorov test.
1531/// Default: Ignore under- and overflow bins in comparison
1532///
1533/// option is a character string to specify options
1534/// "U" include Underflows in test
1535/// "O" include Overflows
1536/// "N" include comparison of normalizations
1537/// "D" Put out a line of "Debug" printout
1538/// "M" Return the Maximum Kolmogorov distance instead of prob
1539///
1540/// The returned function value is the probability of test
1541/// (much less than one means NOT compatible)
1542///
1543/// The KS test uses the distance between the pseudo-CDF's obtained
1544/// from the histogram. Since in more than 1D the order for generating the pseudo-CDF is
1545/// arbitrary, we use the pseudo-CDF's obtained from all the possible 6 combinations of the 3 axis.
1546/// The average of all the maximum distances obtained is used in the tests.
1547
1549{
1550 TString opt = option;
1551 opt.ToUpper();
1552
1553 Double_t prb = 0;
1554 TH1 *h1 = (TH1*)this;
1555 if (h2 == nullptr) return 0;
1556 const TAxis *xaxis1 = h1->GetXaxis();
1557 const TAxis *xaxis2 = h2->GetXaxis();
1558 const TAxis *yaxis1 = h1->GetYaxis();
1559 const TAxis *yaxis2 = h2->GetYaxis();
1560 const TAxis *zaxis1 = h1->GetZaxis();
1561 const TAxis *zaxis2 = h2->GetZaxis();
1562 Int_t ncx1 = xaxis1->GetNbins();
1563 Int_t ncx2 = xaxis2->GetNbins();
1564 Int_t ncy1 = yaxis1->GetNbins();
1565 Int_t ncy2 = yaxis2->GetNbins();
1566 Int_t ncz1 = zaxis1->GetNbins();
1567 Int_t ncz2 = zaxis2->GetNbins();
1568
1569 // Check consistency of dimensions
1570 if (h1->GetDimension() != 3 || h2->GetDimension() != 3) {
1571 Error("KolmogorovTest","Histograms must be 3-D\n");
1572 return 0;
1573 }
1574
1575 // Check consistency in number of channels
1576 if (ncx1 != ncx2) {
1577 Error("KolmogorovTest","Number of channels in X is different, %d and %d\n",ncx1,ncx2);
1578 return 0;
1579 }
1580 if (ncy1 != ncy2) {
1581 Error("KolmogorovTest","Number of channels in Y is different, %d and %d\n",ncy1,ncy2);
1582 return 0;
1583 }
1584 if (ncz1 != ncz2) {
1585 Error("KolmogorovTest","Number of channels in Z is different, %d and %d\n",ncz1,ncz2);
1586 return 0;
1587 }
1588
1589 // Check consistency in channel edges
1592 Double_t difprec = 1e-5;
1593 Double_t diff1 = TMath::Abs(xaxis1->GetXmin() - xaxis2->GetXmin());
1594 Double_t diff2 = TMath::Abs(xaxis1->GetXmax() - xaxis2->GetXmax());
1595 if (diff1 > difprec || diff2 > difprec) {
1596 Error("KolmogorovTest","histograms with different binning along X");
1597 return 0;
1598 }
1599 diff1 = TMath::Abs(yaxis1->GetXmin() - yaxis2->GetXmin());
1600 diff2 = TMath::Abs(yaxis1->GetXmax() - yaxis2->GetXmax());
1601 if (diff1 > difprec || diff2 > difprec) {
1602 Error("KolmogorovTest","histograms with different binning along Y");
1603 return 0;
1604 }
1605 diff1 = TMath::Abs(zaxis1->GetXmin() - zaxis2->GetXmin());
1606 diff2 = TMath::Abs(zaxis1->GetXmax() - zaxis2->GetXmax());
1607 if (diff1 > difprec || diff2 > difprec) {
1608 Error("KolmogorovTest","histograms with different binning along Z");
1609 return 0;
1610 }
1611
1612 // Should we include Uflows, Oflows?
1613 Int_t ibeg = 1, jbeg = 1, kbeg = 1;
1614 Int_t iend = ncx1, jend = ncy1, kend = ncz1;
1615 if (opt.Contains("U")) {ibeg = 0; jbeg = 0; kbeg = 0;}
1616 if (opt.Contains("O")) {iend = ncx1+1; jend = ncy1+1; kend = ncz1+1;}
1617
1618 Int_t i,j,k,bin;
1619 Double_t sum1 = 0;
1620 Double_t sum2 = 0;
1621 Double_t w1 = 0;
1622 Double_t w2 = 0;
1623 for (i = ibeg; i <= iend; i++) {
1624 for (j = jbeg; j <= jend; j++) {
1625 for (k = kbeg; k <= kend; k++) {
1626 bin = h1->GetBin(i,j,k);
1627 sum1 += h1->GetBinContent(bin);
1628 sum2 += h2->GetBinContent(bin);
1629 Double_t ew1 = h1->GetBinError(bin);
1630 Double_t ew2 = h2->GetBinError(bin);
1631 w1 += ew1*ew1;
1632 w2 += ew2*ew2;
1633 }
1634 }
1635 }
1636
1637
1638 // Check that both scatterplots contain events
1639 if (sum1 == 0) {
1640 Error("KolmogorovTest","Integral is zero for h1=%s\n",h1->GetName());
1641 return 0;
1642 }
1643 if (sum2 == 0) {
1644 Error("KolmogorovTest","Integral is zero for h2=%s\n",h2->GetName());
1645 return 0;
1646 }
1647 // calculate the effective entries.
1648 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
1649 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
1650 Double_t esum1 = 0, esum2 = 0;
1651 if (w1 > 0)
1652 esum1 = sum1 * sum1 / w1;
1653 else
1654 afunc1 = kTRUE; // use later for calculating z
1655
1656 if (w2 > 0)
1657 esum2 = sum2 * sum2 / w2;
1658 else
1659 afunc2 = kTRUE; // use later for calculating z
1660
1661 if (afunc2 && afunc1) {
1662 Error("KolmogorovTest","Errors are zero for both histograms\n");
1663 return 0;
1664 }
1665
1666 // Find Kolmogorov distance
1667 // order is arbitrary take average of all possible 6 starting orders x,y,z
1668 int order[3] = {0,1,2};
1669 int binbeg[3];
1670 int binend[3];
1671 int ibin[3];
1672 binbeg[0] = ibeg; binbeg[1] = jbeg; binbeg[2] = kbeg;
1673 binend[0] = iend; binend[1] = jend; binend[2] = kend;
1674 Double_t vdfmax[6]; // there are in total 6 combinations
1675 int icomb = 0;
1676 Double_t s1 = 1./(6.*sum1);
1677 Double_t s2 = 1./(6.*sum2);
1678 Double_t rsum1=0, rsum2=0;
1679 do {
1680 // loop on bins
1681 Double_t dmax = 0;
1682 for (i = binbeg[order[0] ]; i <= binend[order[0] ]; i++) {
1683 for ( j = binbeg[order[1] ]; j <= binend[order[1] ]; j++) {
1684 for ( k = binbeg[order[2] ]; k <= binend[order[2] ]; k++) {
1685 ibin[ order[0] ] = i;
1686 ibin[ order[1] ] = j;
1687 ibin[ order[2] ] = k;
1688 bin = h1->GetBin(ibin[0],ibin[1],ibin[2]);
1689 rsum1 += s1*h1->GetBinContent(bin);
1690 rsum2 += s2*h2->GetBinContent(bin);
1692 }
1693 }
1694 }
1695 vdfmax[icomb] = dmax;
1696 icomb++;
1697 } while (TMath::Permute(3,order) );
1698
1699
1700 // get average of distances
1702
1703 // Get Kolmogorov probability
1705 if (afunc1) factnm = TMath::Sqrt(sum2);
1706 else if (afunc2) factnm = TMath::Sqrt(sum1);
1707 else factnm = TMath::Sqrt(sum1*sum2/(sum1+sum2));
1708 Double_t z = dfmax*factnm;
1709
1711
1712 Double_t prb1 = 0, prb2 = 0;
1713 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
1714 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
1715 // Combine probabilities for shape and normalization
1716 prb1 = prb;
1719 prb2 = TMath::Prob(chi2,1);
1720 // see Eadie et al., section 11.6.2
1721 if (prb > 0 && prb2 > 0) prb = prb*prb2*(1-TMath::Log(prb*prb2));
1722 else prb = 0;
1723 }
1724
1725 // debug printout
1726 if (opt.Contains("D")) {
1727 printf(" Kolmo Prob h1 = %s, sum1=%g\n",h1->GetName(),sum1);
1728 printf(" Kolmo Prob h2 = %s, sum2=%g\n",h2->GetName(),sum2);
1729 printf(" Kolmo Probabil = %f, Max Dist = %g\n",prb,dfmax);
1730 if (opt.Contains("N"))
1731 printf(" Kolmo Probabil = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
1732 }
1733 // This numerical error condition should never occur:
1734 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
1735 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
1736
1737 if (opt.Contains("M")) return dfmax; // return average of max distance
1738
1739 return prb;
1740}
1741
1742
1743////////////////////////////////////////////////////////////////////////////////
1744/// Project a 3-D histogram into a 1-D histogram along X.
1745///
1746/// The projection is always of the type TH1D.
1747/// The projection is made from the cells along the X axis
1748/// ranging from iymin to iymax and izmin to izmax included.
1749/// By default, underflow and overflows are included in both the Y and Z axis.
1750/// By Setting iymin=1 and iymax=NbinsY the underflow and/or overflow in Y will be excluded
1751/// By setting izmin=1 and izmax=NbinsZ the underflow and/or overflow in Z will be excluded
1752///
1753/// if option "e" is specified, the errors are computed.
1754/// if option "d" is specified, the projection is drawn in the current pad.
1755/// if option "o" original axis range of the target axes will be
1756/// kept, but only bins inside the selected range will be filled.
1757///
1758/// NOTE that if a TH1D named "name" exists in the current directory or pad
1759/// the histogram is reset and filled again with the projected contents of the TH3.
1760///
1761/// implemented using Project3D
1762
1765{
1766 // in case of default name append the parent name
1767 TString hname = name;
1768 if (hname == "_px") hname = TString::Format("%s%s", GetName(), name);
1769 TString title = TString::Format("%s ( Projection X )",GetTitle());
1770
1771 // when projecting in Z outer axis are Y and Z (order is important. It is defined in the DoProject1D function)
1772 return DoProject1D(hname, title, iymin, iymax, izmin, izmax, &fXaxis, &fYaxis, &fZaxis, option);
1773}
1774
1775
1776////////////////////////////////////////////////////////////////////////////////
1777/// Project a 3-D histogram into a 1-D histogram along Y.
1778///
1779/// The projection is always of the type TH1D.
1780/// The projection is made from the cells along the Y axis
1781/// ranging from ixmin to ixmax and izmin to izmax included.
1782/// By default, underflow and overflow are included in both the X and Z axis.
1783/// By setting ixmin=1 and ixmax=NbinsX the underflow and/or overflow in X will be excluded
1784/// By setting izmin=1 and izmax=NbinsZ the underflow and/or overflow in Z will be excluded
1785///
1786/// if option "e" is specified, the errors are computed.
1787/// if option "d" is specified, the projection is drawn in the current pad.
1788/// if option "o" original axis range of the target axes will be
1789/// kept, but only bins inside the selected range will be filled.
1790///
1791/// NOTE that if a TH1D named "name" exists in the current directory or pad,
1792/// the histogram is reset and filled again with the projected contents of the TH3.
1793///
1794/// implemented using Project3D
1795
1798{
1799 TString hname = name;
1800 if (hname == "_py") hname = TString::Format("%s%s", GetName(), name);
1801 TString title = TString::Format("%s ( Projection Y )",GetTitle());
1802
1803 // when projecting in Z outer axis are X and Y (order is important. It is defined in the DoProject1D function)
1804 return DoProject1D(hname, title, ixmin, ixmax, izmin, izmax, &fYaxis, &fXaxis, &fZaxis, option);
1805}
1806
1807////////////////////////////////////////////////////////////////////////////////
1808/// Project a 3-D histogram into a 1-D histogram along Z.
1809///
1810/// The projection is always of the type TH1D.
1811/// The projection is made from the cells along the Z axis
1812/// ranging from ixmin to ixmax and iymin to iymax included.
1813/// By default, bins 1 to nx and 1 to ny are included
1814/// By default, underflow and overflow are included in both the X and Y axis.
1815/// By Setting ixmin=1 and ixmax=NbinsX the underflow and/or overflow in X will be excluded
1816/// By setting iymin=1 and/or iymax=NbinsY the underflow and/or overflow in Y will be excluded
1817///
1818/// if option "e" is specified, the errors are computed.
1819/// if option "d" is specified, the projection is drawn in the current pad.
1820/// if option "o" original axis range of the target axes will be
1821/// kept, but only bins inside the selected range will be filled.
1822///
1823/// NOTE that if a TH1D named "name" exists in the current directory or pad,
1824/// the histogram is reset and filled again with the projected contents of the TH3.
1825///
1826/// implemented using Project3D
1827
1830{
1831
1832 TString hname = name;
1833 if (hname == "_pz") hname = TString::Format("%s%s", GetName(), name);
1834 TString title = TString::Format("%s ( Projection Z )",GetTitle());
1835
1836 // when projecting in Z outer axis are X and Y (order is important. It is defined in the DoProject1D function)
1837 return DoProject1D(hname, title, ixmin, ixmax, iymin, iymax, &fZaxis, &fXaxis, &fYaxis, option);
1838}
1839
1840
1841////////////////////////////////////////////////////////////////////////////////
1842/// internal method performing the projection to 1D histogram
1843/// called from TH3::Project3D
1844
1845TH1D *TH3::DoProject1D(const char* name, const char * title, int imin1, int imax1, int imin2, int imax2,
1846 const TAxis* projAxis, const TAxis * axis1, const TAxis * axis2, Option_t * option) const
1847{
1848
1849 TString opt = option;
1850 opt.ToLower();
1851
1852 // save previous axis range and bits
1853 // Int_t iminOld1 = axis1->GetFirst();
1854 // Int_t imaxOld1 = axis1->GetLast();
1855 // Int_t iminOld2 = axis2->GetFirst();
1856 // Int_t imaxOld2 = axis2->GetLast();
1857 // Bool_t hadRange1 = axis1->TestBit(TAxis::kAxisRange);
1858 // Bool_t hadRange2 = axis2->TestBit(TAxis::kAxisRange);
1859
1860 // need to cast-away constness to set range
1861 TAxis out1(*axis1);
1862 TAxis out2(*axis2);
1863 // const_cast<TAxis *>(axis1)->SetRange(imin1, imax1);
1864 // const_cast<TAxis*>(axis2)->SetRange(imin2,imax2);
1865 out1.SetRange(imin1, imax1);
1866 out2.SetRange(imin2, imax2);
1867
1869 if (opt.Contains("e") ) {
1871 opt.Remove(opt.First("e"),1);
1872 }
1874 if (opt.Contains('o') ) {
1876 opt.Remove(opt.First("o"),1);
1877 }
1878
1879 TH1D * h1 = DoProject1D(name, title, projAxis, &out1, &out2, computeErrors, originalRange,true,true);
1880
1881 // // restore original range
1882 // if (axis1->TestBit(TAxis::kAxisRange)) {
1883 // if (hadRange1) const_cast<TAxis*>(axis1)->SetRange(iminOld1,imaxOld1);
1884 // if (axis2->TestBit(TAxis::kAxisRange)) const_cast<TAxis*>(axis2)->SetRange(iminOld2,imaxOld2);
1885 // // we need also to restore the original bits
1886
1887 // draw in current pad
1888 if (h1 && opt.Contains("d")) {
1889 opt.Remove(opt.First("d"),1);
1890 TVirtualPad::TContext ctxt(gROOT->GetSelectedPad(), true, true);
1891 if (!gPad || !gPad->FindObject(h1)) {
1892 h1->Draw(opt);
1893 } else {
1894 h1->Paint(opt);
1895 }
1896 }
1897
1898 return h1;
1899}
1900
1901////////////////////////////////////////////////////////////////////////////////
1902/// internal methdod performing the projection to 1D histogram
1903/// called from other TH3::DoProject1D
1904
1905TH1D *TH3::DoProject1D(const char* name, const char * title, const TAxis* projX,
1906 const TAxis * out1, const TAxis * out2,
1907 bool computeErrors, bool originalRange,
1908 bool useUF, bool useOF) const
1909{
1910 // Create the projection histogram
1911 TH1D *h1 = nullptr;
1912
1913 // Get range to use as well as bin limits
1914 // Projected range must be inside and not outside original one (ROOT-8781)
1915 Int_t ixmin = std::max(projX->GetFirst(),1);
1916 Int_t ixmax = std::min(projX->GetLast(),projX->GetNbins());
1917 Int_t nx = ixmax-ixmin+1;
1918
1919 // Create the histogram, either reseting a preexisting one
1920 TObject *h1obj = gROOT->FindObject(name);
1921 if (h1obj && h1obj->InheritsFrom(TH1::Class())) {
1922 if (h1obj->IsA() != TH1D::Class() ) {
1923 Error("DoProject1D","Histogram with name %s must be a TH1D and is a %s",name,h1obj->ClassName());
1924 return nullptr;
1925 }
1926 h1 = (TH1D*)h1obj;
1927 // reset histogram and re-set the axis in any case
1928 h1->Reset();
1929 const TArrayD *bins = projX->GetXbins();
1930 if ( originalRange )
1931 {
1932 if (bins->fN == 0) {
1933 h1->SetBins(projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
1934 } else {
1935 h1->SetBins(projX->GetNbins(),bins->fArray);
1936 }
1937 } else {
1938 if (bins->fN == 0) {
1939 h1->SetBins(nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
1940 } else {
1941 h1->SetBins(nx,&bins->fArray[ixmin-1]);
1942 }
1943 }
1944 }
1945
1946 if (!h1) {
1947 const TArrayD *bins = projX->GetXbins();
1948 if ( originalRange )
1949 {
1950 if (bins->fN == 0) {
1951 h1 = new TH1D(name,title,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
1952 } else {
1953 h1 = new TH1D(name,title,projX->GetNbins(),bins->fArray);
1954 }
1955 } else {
1956 if (bins->fN == 0) {
1957 h1 = new TH1D(name,title,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
1958 } else {
1959 h1 = new TH1D(name,title,nx,&bins->fArray[ixmin-1]);
1960 }
1961 }
1962 }
1963
1964 // Copy the axis attributes and the axis labels if needed.
1966 THashList* labels = projX->GetLabels();
1967 if (labels) {
1968 TIter iL(labels);
1969 TObjString* lb;
1970 Int_t i = 1;
1971 while ((lb=(TObjString*)iL())) {
1972 h1->GetXaxis()->SetBinLabel(i,lb->String().Data());
1973 i++;
1974 }
1975 }
1976 h1->SetLineColor(this->GetLineColor());
1977 h1->SetFillColor(this->GetFillColor());
1978 h1->SetMarkerColor(this->GetMarkerColor());
1979 h1->SetMarkerStyle(this->GetMarkerStyle());
1980
1981 // Activate errors
1982 if ( computeErrors && (h1->GetSumw2N() != h1->GetNcells() ) ) h1->Sumw2();
1983
1984 // Set references to the axies in case out1 or out2 ar enot provided
1985 // and one can use the histogram axis given projX
1986 if (out1 == nullptr && out2 == nullptr) {
1987 if (projX == GetXaxis()) {
1988 out1 = GetYaxis();
1989 out2 = GetZaxis();
1990 } else if (projX == GetYaxis()) {
1991 out1 = GetXaxis();
1992 out2 = GetZaxis();
1993 } else {
1994 out1 = GetXaxis();
1995 out2 = GetYaxis();
1996 }
1997 }
1998 R__ASSERT(out1 != nullptr && out2 != nullptr);
1999
2000 Int_t *refX = nullptr, *refY = nullptr, *refZ = nullptr;
2002 if (projX == GetXaxis()) {
2003 refX = &ixbin;
2004 refY = &out1bin;
2005 refZ = &out2bin;
2006 }
2007 if (projX == GetYaxis()) {
2008 refX = &out1bin;
2009 refY = &ixbin;
2010 refZ = &out2bin;
2011 }
2012 if (projX == GetZaxis()) {
2013 refX = &out1bin;
2014 refY = &out2bin;
2015 refZ = &ixbin;
2016 }
2017 R__ASSERT (refX != nullptr && refY != nullptr && refZ != nullptr);
2018
2019 // Fill the projected histogram excluding underflow/overflows if considered in the option
2020 // if specified in the option (by default they considered)
2021 Double_t totcont = 0;
2022
2023 Int_t out1min = out1->GetFirst();
2024 Int_t out1max = out1->GetLast();
2025 // GetFirst(), GetLast() can return (0,0) when the range bit is set artificially (see TAxis::SetRange)
2026 //if (out1min == 0 && out1max == 0) { out1min = 1; out1max = out1->GetNbins(); }
2027 // correct for underflow/overflows
2028 if (useUF && !out1->TestBit(TAxis::kAxisRange) ) out1min -= 1;
2029 if (useOF && !out1->TestBit(TAxis::kAxisRange) ) out1max += 1;
2030 Int_t out2min = out2->GetFirst();
2031 Int_t out2max = out2->GetLast();
2032// if (out2min == 0 && out2max == 0) { out2min = 1; out2max = out2->GetNbins(); }
2033 if (useUF && !out2->TestBit(TAxis::kAxisRange) ) out2min -= 1;
2034 if (useOF && !out2->TestBit(TAxis::kAxisRange) ) out2max += 1;
2035
2036 // if the out axis has labels and is extendable, temporary make it non-extendable to avoid adding extra bins
2037 Bool_t extendable = projX->CanExtend();
2038 if ( labels && extendable ) h1->GetXaxis()->SetCanExtend(kFALSE);
2039 for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++) {
2040 if ( projX->TestBit(TAxis::kAxisRange) && ( ixbin < ixmin || ixbin > ixmax )) continue;
2041
2042 Double_t cont = 0;
2043 Double_t err2 = 0;
2044
2045 // loop on the bins to be integrated (outbin should be called inbin)
2046 for (out1bin = out1min; out1bin <= out1max; out1bin++) {
2047 for (out2bin = out2min; out2bin <= out2max; out2bin++) {
2048
2049 Int_t bin = GetBin(*refX, *refY, *refZ);
2050
2051 // sum the bin contents and errors if needed
2052 cont += RetrieveBinContent(bin);
2053 if (computeErrors) {
2054 Double_t exyz = GetBinError(bin);
2055 err2 += exyz*exyz;
2056 }
2057 }
2058 }
2059 Int_t ix = h1->FindBin( projX->GetBinCenter(ixbin) );
2060 h1->SetBinContent(ix ,cont);
2062 // sum all content
2063 totcont += cont;
2064
2065 }
2066 if ( labels ) h1->GetXaxis()->SetCanExtend(extendable);
2067
2068 // since we use a combination of fill and SetBinError we need to reset and recalculate the statistics
2069 // for weighted histograms otherwise sumw2 will be wrong.
2070 // We can keep the original statistics from the TH3 if the projected sumw is consistent with original one
2071 // i.e. when no events are thrown away
2072 bool resetStats = true;
2073 double eps = 1.E-12;
2074 if (IsA() == TH3F::Class() ) eps = 1.E-6;
2075 if (fTsumw != 0 && TMath::Abs( fTsumw - totcont) < TMath::Abs(fTsumw) * eps) resetStats = false;
2076
2077 bool resetEntries = resetStats;
2078 // entries are calculated using underflow/overflow. If excluded entries must be reset
2079 resetEntries |= !useUF || !useOF;
2080
2081
2082 if (!resetStats) {
2084 GetStats(stats);
2085 if ( projX == GetYaxis() ) {
2086 stats[2] = stats[4];
2087 stats[3] = stats[5];
2088 }
2089 else if ( projX == GetZaxis() ) {
2090 stats[2] = stats[7];
2091 stats[3] = stats[8];
2092 }
2093 h1->PutStats(stats);
2094 }
2095 else {
2096 // reset statistics
2097 h1->ResetStats();
2098 }
2099 if (resetEntries) {
2100 // in case of error calculation (i.e. when Sumw2() is set)
2101 // use the effective entries for the entries
2102 // since this is the only way to estimate them
2103 Double_t entries = TMath::Floor( totcont + 0.5); // to avoid numerical rounding
2104 if (computeErrors) entries = h1->GetEffectiveEntries();
2105 h1->SetEntries( entries );
2106 }
2107 else {
2109 }
2110
2111 return h1;
2112}
2113
2114
2115////////////////////////////////////////////////////////////////////////////////
2116/// internal method performing the projection to a 2D histogram
2117/// called from TH3::Project3D
2118
2119TH2D *TH3::DoProject2D(const char* name, const char * title, const TAxis* projX, const TAxis* projY,
2120 bool computeErrors, bool originalRange,
2121 bool useUF, bool useOF) const
2122{
2123 TH2D *h2 = nullptr;
2124
2125 // Get range to use as well as bin limits
2126 Int_t ixmin = std::max(projX->GetFirst(),1);
2127 Int_t ixmax = std::min(projX->GetLast(),projX->GetNbins());
2128 Int_t iymin = std::max(projY->GetFirst(),1);
2129 Int_t iymax = std::min(projY->GetLast(),projY->GetNbins());
2130
2131 Int_t nx = ixmax-ixmin+1;
2132 Int_t ny = iymax-iymin+1;
2133
2134 // Create the histogram, either reseting a preexisting one
2135 // or creating one from scratch.
2136 // Does an object with the same name exists?
2137 TObject *h2obj = gROOT->FindObject(name);
2138 if (h2obj && h2obj->InheritsFrom(TH1::Class())) {
2139 if ( h2obj->IsA() != TH2D::Class() ) {
2140 Error("DoProject2D","Histogram with name %s must be a TH2D and is a %s",name,h2obj->ClassName());
2141 return nullptr;
2142 }
2143 h2 = (TH2D*)h2obj;
2144 // reset histogram and its axes
2145 h2->Reset();
2146 const TArrayD *xbins = projX->GetXbins();
2147 const TArrayD *ybins = projY->GetXbins();
2148 if ( originalRange ) {
2149 h2->SetBins(projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
2150 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
2151 // set bins for mixed axis do not exists - need to set afterwards the variable bins
2152 if (ybins->fN != 0)
2153 h2->GetXaxis()->Set(projY->GetNbins(),&ybins->fArray[iymin-1]);
2154 if (xbins->fN != 0)
2155 h2->GetYaxis()->Set(projX->GetNbins(),&xbins->fArray[ixmin-1]);
2156 } else {
2157 h2->SetBins(ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
2158 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
2159 if (ybins->fN != 0)
2160 h2->GetXaxis()->Set(ny,&ybins->fArray[iymin-1]);
2161 if (xbins->fN != 0)
2162 h2->GetYaxis()->Set(nx,&xbins->fArray[ixmin-1]);
2163 }
2164 }
2165
2166
2167 if (!h2) {
2168 const TArrayD *xbins = projX->GetXbins();
2169 const TArrayD *ybins = projY->GetXbins();
2170 if ( originalRange )
2171 {
2172 if (xbins->fN == 0 && ybins->fN == 0) {
2173 h2 = new TH2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
2174 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
2175 } else if (ybins->fN == 0) {
2176 h2 = new TH2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
2177 ,projX->GetNbins(),&xbins->fArray[ixmin-1]);
2178 } else if (xbins->fN == 0) {
2179 h2 = new TH2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1]
2180 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
2181 } else {
2182 h2 = new TH2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1],projX->GetNbins(),&xbins->fArray[ixmin-1]);
2183 }
2184 } else {
2185 if (xbins->fN == 0 && ybins->fN == 0) {
2186 h2 = new TH2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
2187 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
2188 } else if (ybins->fN == 0) {
2189 h2 = new TH2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
2190 ,nx,&xbins->fArray[ixmin-1]);
2191 } else if (xbins->fN == 0) {
2192 h2 = new TH2D(name,title,ny,&ybins->fArray[iymin-1]
2193 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
2194 } else {
2195 h2 = new TH2D(name,title,ny,&ybins->fArray[iymin-1],nx,&xbins->fArray[ixmin-1]);
2196 }
2197 }
2198 }
2199
2200 // Copy the axis attributes and the axis labels if needed.
2201 THashList* labels1 = nullptr;
2202 THashList* labels2 = nullptr;
2203 // "xy"
2204 h2->GetXaxis()->ImportAttributes(projY);
2205 h2->GetYaxis()->ImportAttributes(projX);
2206 labels1 = projY->GetLabels();
2207 labels2 = projX->GetLabels();
2208 if (labels1) {
2209 TIter iL(labels1);
2210 TObjString* lb;
2211 Int_t i = 1;
2212 while ((lb=(TObjString*)iL())) {
2213 h2->GetXaxis()->SetBinLabel(i,lb->String().Data());
2214 i++;
2215 }
2216 }
2217 if (labels2) {
2218 TIter iL(labels2);
2219 TObjString* lb;
2220 Int_t i = 1;
2221 while ((lb=(TObjString*)iL())) {
2222 h2->GetYaxis()->SetBinLabel(i,lb->String().Data());
2223 i++;
2224 }
2225 }
2226 h2->SetLineColor(this->GetLineColor());
2227 h2->SetFillColor(this->GetFillColor());
2228 h2->SetMarkerColor(this->GetMarkerColor());
2229 h2->SetMarkerStyle(this->GetMarkerStyle());
2230
2231 // Activate errors
2232 if ( computeErrors && (h2->GetSumw2N() != h2->GetNcells()) ) h2->Sumw2();
2233
2234 // Set references to the axis, so that the bucle has no branches.
2235 const TAxis* out = nullptr;
2236 if ( projX != GetXaxis() && projY != GetXaxis() ) {
2237 out = GetXaxis();
2238 } else if ( projX != GetYaxis() && projY != GetYaxis() ) {
2239 out = GetYaxis();
2240 } else {
2241 out = GetZaxis();
2242 }
2243
2244 Int_t *refX = nullptr, *refY = nullptr, *refZ = nullptr;
2246 if ( projX == GetXaxis() && projY == GetYaxis() ) { refX = &ixbin; refY = &iybin; refZ = &outbin; }
2247 if ( projX == GetYaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &ixbin; refZ = &outbin; }
2248 if ( projX == GetXaxis() && projY == GetZaxis() ) { refX = &ixbin; refY = &outbin; refZ = &iybin; }
2249 if ( projX == GetZaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &outbin; refZ = &ixbin; }
2250 if ( projX == GetYaxis() && projY == GetZaxis() ) { refX = &outbin; refY = &ixbin; refZ = &iybin; }
2251 if ( projX == GetZaxis() && projY == GetYaxis() ) { refX = &outbin; refY = &iybin; refZ = &ixbin; }
2252 R__ASSERT (refX != nullptr && refY != nullptr && refZ != nullptr);
2253
2254 // Fill the projected histogram excluding underflow/overflows if considered in the option
2255 // if specified in the option (by default they considered)
2256 Double_t totcont = 0;
2257
2258 Int_t outmin = out->GetFirst();
2259 Int_t outmax = out->GetLast();
2260 // GetFirst(), GetLast() can return (0,0) when the range bit is set artificially (see TAxis::SetRange)
2261 if (outmin == 0 && outmax == 0) { outmin = 1; outmax = out->GetNbins(); }
2262 // correct for underflow/overflows
2263 if (useUF && !out->TestBit(TAxis::kAxisRange) ) outmin -= 1;
2264 if (useOF && !out->TestBit(TAxis::kAxisRange) ) outmax += 1;
2265
2266 for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++) {
2267 if ( projX->TestBit(TAxis::kAxisRange) && ( ixbin < ixmin || ixbin > ixmax )) continue;
2268 Int_t ix = h2->GetYaxis()->FindBin( projX->GetBinCenter(ixbin) );
2269
2270 for (iybin=0;iybin<=1+projY->GetNbins();iybin++) {
2271 if ( projY->TestBit(TAxis::kAxisRange) && ( iybin < iymin || iybin > iymax )) continue;
2272 Int_t iy = h2->GetXaxis()->FindBin( projY->GetBinCenter(iybin) );
2273
2274 Double_t cont = 0;
2275 Double_t err2 = 0;
2276
2277 // loop on the bins to be integrated (outbin should be called inbin)
2278 for (outbin = outmin; outbin <= outmax; outbin++) {
2279
2280 Int_t bin = GetBin(*refX,*refY,*refZ);
2281
2282 // sum the bin contents and errors if needed
2283 cont += RetrieveBinContent(bin);
2284 if (computeErrors) {
2285 Double_t exyz = GetBinError(bin);
2286 err2 += exyz*exyz;
2287 }
2288
2289 }
2290
2291 // remember axis are inverted
2292 h2->SetBinContent(iy , ix, cont);
2293 if (computeErrors) h2->SetBinError(iy, ix, TMath::Sqrt(err2) );
2294 // sum all content
2295 totcont += cont;
2296
2297 }
2298 }
2299
2300 // since we use fill we need to reset and recalculate the statistics (see comment in DoProject1D )
2301 // or keep original statistics if consistent sumw2
2302 bool resetStats = true;
2303 double eps = 1.E-12;
2304 if (IsA() == TH3F::Class() ) eps = 1.E-6;
2305 if (fTsumw != 0 && TMath::Abs( fTsumw - totcont) < TMath::Abs(fTsumw) * eps) resetStats = false;
2306
2307 bool resetEntries = resetStats;
2308 // entries are calculated using underflow/overflow. If excluded entries must be reset
2309 resetEntries |= !useUF || !useOF;
2310
2311 if (!resetStats) {
2313 Double_t oldst[kNstat]; // old statistics
2314 for (Int_t i = 0; i < kNstat; ++i) { oldst[i] = 0; }
2315 GetStats(oldst);
2316 std::copy(oldst,oldst+kNstat,stats);
2317 // not that projX refer to Y axis and projX refer to the X axis of projected histogram
2318 // nothing to do for projection in Y vs X
2319 if ( projY == GetXaxis() && projX == GetZaxis() ) { // case XZ
2320 stats[4] = oldst[7];
2321 stats[5] = oldst[8];
2322 stats[6] = oldst[9];
2323 }
2324 if ( projY == GetYaxis() ) {
2325 stats[2] = oldst[4];
2326 stats[3] = oldst[5];
2327 if ( projX == GetXaxis() ) { // case YX
2328 stats[4] = oldst[2];
2329 stats[5] = oldst[3];
2330 }
2331 if ( projX == GetZaxis() ) { // case YZ
2332 stats[4] = oldst[7];
2333 stats[5] = oldst[8];
2334 stats[6] = oldst[10];
2335 }
2336 }
2337 else if ( projY == GetZaxis() ) {
2338 stats[2] = oldst[7];
2339 stats[3] = oldst[8];
2340 if ( projX == GetXaxis() ) { // case ZX
2341 stats[4] = oldst[2];
2342 stats[5] = oldst[3];
2343 stats[6] = oldst[9];
2344 }
2345 if ( projX == GetYaxis() ) { // case ZY
2346 stats[4] = oldst[4];
2347 stats[5] = oldst[5];
2348 stats[6] = oldst[10];
2349 }
2350 }
2351 // set the new statistics
2352 h2->PutStats(stats);
2353 }
2354 else {
2355 // recalculate the statistics
2356 h2->ResetStats();
2357 }
2358
2359 if (resetEntries) {
2360 // use the effective entries for the entries
2361 // since this is the only way to estimate them
2362 Double_t entries = h2->GetEffectiveEntries();
2363 if (!computeErrors) entries = TMath::Floor( entries + 0.5); // to avoid numerical rounding
2364 h2->SetEntries( entries );
2365 }
2366 else {
2367 h2->SetEntries( fEntries );
2368 }
2369
2370
2371 return h2;
2372}
2373
2374
2375////////////////////////////////////////////////////////////////////////////////
2376/// Project a 3-d histogram into 1 or 2-d histograms depending on the
2377/// option parameter, which may contain a combination of the characters x,y,z,e
2378/// - option = "x" return the x projection into a TH1D histogram
2379/// - option = "y" return the y projection into a TH1D histogram
2380/// - option = "z" return the z projection into a TH1D histogram
2381/// - option = "xy" return the x versus y projection into a TH2D histogram
2382/// - option = "yx" return the y versus x projection into a TH2D histogram
2383/// - option = "xz" return the x versus z projection into a TH2D histogram
2384/// - option = "zx" return the z versus x projection into a TH2D histogram
2385/// - option = "yz" return the y versus z projection into a TH2D histogram
2386/// - option = "zy" return the z versus y projection into a TH2D histogram
2387///
2388/// NB: the notation "a vs b" means "a" vertical and "b" horizontal
2389///
2390/// option = "o" original axis range of the target axes will be
2391/// kept, but only bins inside the selected range will be filled.
2392///
2393/// If option contains the string "e", errors are computed
2394///
2395/// The projection is made for the selected bins only.
2396/// To select a bin range along an axis, use TAxis::SetRange, eg
2397/// h3.GetYaxis()->SetRange(23,56);
2398///
2399/// NOTE 1: The generated histogram is named th3name + option
2400/// eg if the TH3* h histogram is named "myhist", then
2401/// h->Project3D("xy"); produces a TH2D histogram named "myhist_xy"
2402/// if a histogram of the same type already exists, it is overwritten.
2403/// The following sequence
2404/// h->Project3D("xy");
2405/// h->Project3D("xy2");
2406/// will generate two TH2D histograms named "myhist_xy" and "myhist_xy2"
2407/// A different name can be generated by attaching a string to the option
2408/// For example h->Project3D("name_xy") will generate an histogram with the name: h3dname_name_xy.
2409///
2410/// NOTE 2: If an histogram of the same type and with the same name already exists in current Directory,
2411/// the histogram is reset and filled again with the projected contents of the TH3.
2412///
2413/// NOTE 3: The number of entries in the projected histogram is estimated from the number of
2414/// effective entries for all the cells included in the projection.
2415///
2416/// NOTE 4: underflow/overflow are included by default in the projection
2417/// To exclude underflow and/or overflow (for both axis in case of a projection to a 1D histogram) use option "NUF" and/or "NOF"
2418/// With SetRange() you can have all bins except underflow/overflow only if you set the axis bit range as
2419/// following after having called SetRange: axis->SetRange(1, axis->GetNbins());
2420///
2421/// NOTE 5: If TH1::AddDirectory is set to false, a new histogram is always created and the ownership of the
2422/// returned pointer is delegated to the user. Be sure in this case to call `delete` on it after it's no longer needed,
2423/// to avoid memory leaks.
2424
2426{
2427 TString opt = option;
2429 Int_t underscore = extra_name.Last('_');
2430 if (underscore > 0) {
2431 extra_name.Remove(underscore,extra_name.Length()-underscore);
2432 opt.Remove(0,underscore+1);
2433 }
2434 opt.ToLower();
2435
2436 Int_t pcase = 0;
2437 TString ptype;
2438 if (opt.Contains("x")) { pcase = 1; ptype = "x"; }
2439 if (opt.Contains("y")) { pcase = 2; ptype = "y"; }
2440 if (opt.Contains("z")) { pcase = 3; ptype = "z"; }
2441 if (opt.Contains("xy")) { pcase = 4; ptype = "xy"; }
2442 if (opt.Contains("yx")) { pcase = 5; ptype = "yx"; }
2443 if (opt.Contains("xz")) { pcase = 6; ptype = "xz"; }
2444 if (opt.Contains("zx")) { pcase = 7; ptype = "zx"; }
2445 if (opt.Contains("yz")) { pcase = 8; ptype = "yz"; }
2446 if (opt.Contains("zy")) { pcase = 9; ptype = "zy"; }
2447
2448 if (pcase == 0) {
2449 Error("Project3D","No projection axis specified - return a NULL pointer");
2450 return nullptr;
2451 }
2452 // do not remove ptype from opt to use later in the projected histo name
2453
2455 if (opt.Contains("e") ) {
2457 opt.Remove(opt.First("e"),1);
2458 }
2459
2460 Bool_t useUF = kTRUE;
2461 Bool_t useOF = kTRUE;
2462 if (opt.Contains("nuf") ) {
2463 useUF = kFALSE;
2464 opt.Remove(opt.Index("nuf"),3);
2465 }
2466 if (opt.Contains("nof") ) {
2467 useOF = kFALSE;
2468 opt.Remove(opt.Index("nof"),3);
2469 }
2470
2472 if (opt.Contains('o') ) {
2474 opt.Remove(opt.First("o"),1);
2475 }
2476
2477
2478 // Create the projection histogram
2479 TH1 *h = nullptr;
2480
2481 TString name = GetName();
2482 TString title = GetTitle();
2483 if (underscore > 0) {
2484 name += "_";
2485 name += extra_name;
2486 }
2487 name += "_"; name += opt;
2488 title += " "; title += ptype; title += " projection";
2489
2490 switch (pcase) {
2491 case 1:
2492 // "x"
2493 h = DoProject1D(name, title, this->GetXaxis(), nullptr, nullptr,
2494 computeErrors, originalRange, useUF, useOF);
2495 break;
2496
2497 case 2:
2498 // "y"
2499 h = DoProject1D(name, title, this->GetYaxis(), nullptr, nullptr,
2500 computeErrors, originalRange, useUF, useOF);
2501 break;
2502
2503 case 3:
2504 // "z"
2505 h = DoProject1D(name, title, this->GetZaxis(), nullptr, nullptr,
2506 computeErrors, originalRange, useUF, useOF);
2507 break;
2508
2509 case 4:
2510 // "xy"
2511 h = DoProject2D(name, title, this->GetXaxis(),this->GetYaxis(),
2512 computeErrors, originalRange, useUF, useOF);
2513 break;
2514
2515 case 5:
2516 // "yx"
2517 h = DoProject2D(name, title, this->GetYaxis(),this->GetXaxis(),
2518 computeErrors, originalRange, useUF, useOF);
2519 break;
2520
2521 case 6:
2522 // "xz"
2523 h = DoProject2D(name, title, this->GetXaxis(),this->GetZaxis(),
2524 computeErrors, originalRange, useUF, useOF);
2525 break;
2526
2527 case 7:
2528 // "zx"
2529 h = DoProject2D(name, title, this->GetZaxis(),this->GetXaxis(),
2530 computeErrors, originalRange, useUF, useOF);
2531 break;
2532
2533 case 8:
2534 // "yz"
2535 h = DoProject2D(name, title, this->GetYaxis(),this->GetZaxis(),
2536 computeErrors, originalRange, useUF, useOF);
2537 break;
2538
2539 case 9:
2540 // "zy"
2541 h = DoProject2D(name, title, this->GetZaxis(),this->GetYaxis(),
2542 computeErrors, originalRange, useUF, useOF);
2543 break;
2544
2545 }
2546
2547 // draw in current pad
2548 if (h && opt.Contains("d")) {
2549 opt.Remove(opt.First("d"),1);
2550 TVirtualPad::TContext ctxt(gROOT->GetSelectedPad(), true, true);
2551 if (!gPad || !gPad->FindObject(h)) {
2552 h->Draw(opt);
2553 } else {
2554 h->Paint(opt);
2555 }
2556 }
2557
2558 return h;
2559}
2560
2561
2562////////////////////////////////////////////////////////////////////////////////
2563/// internal function to fill the bins of the projected profile 2D histogram
2564/// called from DoProjectProfile2D
2565
2567 const TAxis & a1, const TAxis & a2, const TAxis & a3,
2569 Int_t inBin, Bool_t useWeights ) const {
2571 if (!cont) return;
2572 TArrayD & binSumw2 = *(p2->GetBinSumw2());
2573 if (useWeights && binSumw2.fN <= 0) useWeights = false;
2574 if (!useWeights) p2->SetBit(TH1::kIsNotW); // to use Fill for setting the bin contents of the Profile
2575 // the following fill update wrongly the fBinSumw2- need to save it before
2576 Double_t u = a1.GetBinCenter(bin1);
2577 Double_t v = a2.GetBinCenter(bin2);
2578 Double_t w = a3.GetBinCenter(bin3);
2579 Int_t outBin = p2->FindBin(u, v);
2580 if (outBin <0) return;
2581 Double_t tmp = 0;
2582 if ( useWeights ) tmp = binSumw2.fArray[outBin];
2583 p2->Fill( u , v, w, cont);
2584 if (useWeights ) binSumw2.fArray[outBin] = tmp + fSumw2.fArray[inBin];
2585}
2586
2587
2588////////////////////////////////////////////////////////////////////////////////
2589/// internal method to project to a 2D Profile
2590/// called from TH3::Project3DProfile
2591
2592TProfile2D *TH3::DoProjectProfile2D(const char* name, const char * title, const TAxis* projX, const TAxis* projY,
2593 bool originalRange, bool useUF, bool useOF) const
2594{
2595 // Get the ranges where we will work.
2596 Int_t ixmin = std::max(projX->GetFirst(),1);
2597 Int_t ixmax = std::min(projX->GetLast(),projX->GetNbins());
2598 Int_t iymin = std::max(projY->GetFirst(),1);
2599 Int_t iymax = std::min(projY->GetLast(),projY->GetNbins());
2600
2601 Int_t nx = ixmax-ixmin+1;
2602 Int_t ny = iymax-iymin+1;
2603
2604 // Create the projected profiles
2605 TProfile2D *p2 = nullptr;
2606
2607 // Create the histogram, either reseting a preexisting one
2608 // Does an object with the same name exists?
2609 TObject *p2obj = gROOT->FindObject(name);
2610 if (p2obj && p2obj->InheritsFrom(TH1::Class())) {
2611 if (p2obj->IsA() != TProfile2D::Class() ) {
2612 Error("DoProjectProfile2D","Histogram with name %s must be a TProfile2D and is a %s",name,p2obj->ClassName());
2613 return nullptr;
2614 }
2615 p2 = (TProfile2D*)p2obj;
2616 // reset existing profile and re-set bins
2617 p2->Reset();
2618 const TArrayD *xbins = projX->GetXbins();
2619 const TArrayD *ybins = projY->GetXbins();
2620 if ( originalRange ) {
2621 p2->SetBins(projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
2622 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
2623 // set bins for mixed axis do not exists - need to set afterwards the variable bins
2624 if (ybins->fN != 0)
2625 p2->GetXaxis()->Set(projY->GetNbins(),&ybins->fArray[iymin-1]);
2626 if (xbins->fN != 0)
2627 p2->GetYaxis()->Set(projX->GetNbins(),&xbins->fArray[ixmin-1]);
2628 } else {
2629 p2->SetBins(ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
2630 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
2631 if (ybins->fN != 0)
2632 p2->GetXaxis()->Set(ny,&ybins->fArray[iymin-1]);
2633 if (xbins->fN != 0)
2634 p2->GetYaxis()->Set(nx,&xbins->fArray[ixmin-1]);
2635 }
2636 }
2637
2638 if (!p2) {
2639 const TArrayD *xbins = projX->GetXbins();
2640 const TArrayD *ybins = projY->GetXbins();
2641 if ( originalRange ) {
2642 if (xbins->fN == 0 && ybins->fN == 0) {
2643 p2 = new TProfile2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
2644 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
2645 } else if (ybins->fN == 0) {
2646 p2 = new TProfile2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
2647 ,projX->GetNbins(),&xbins->fArray[ixmin-1]);
2648 } else if (xbins->fN == 0) {
2649 p2 = new TProfile2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1]
2650 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
2651 } else {
2652 p2 = new TProfile2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1],projX->GetNbins(),&xbins->fArray[ixmin-1]);
2653 }
2654 } else {
2655 if (xbins->fN == 0 && ybins->fN == 0) {
2656 p2 = new TProfile2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
2657 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
2658 } else if (ybins->fN == 0) {
2659 p2 = new TProfile2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
2660 ,nx,&xbins->fArray[ixmin-1]);
2661 } else if (xbins->fN == 0) {
2662 p2 = new TProfile2D(name,title,ny,&ybins->fArray[iymin-1]
2663 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
2664 } else {
2665 p2 = new TProfile2D(name,title,ny,&ybins->fArray[iymin-1],nx,&xbins->fArray[ixmin-1]);
2666 }
2667 }
2668 }
2669
2670 // Copy the axis attributes and the axis labels if needed
2671 p2->GetXaxis()->ImportAttributes(projY);
2672 p2->GetYaxis()->ImportAttributes(projX);
2673 THashList* labelsX = projY->GetLabels();
2674 if (labelsX) {
2675 TIter iL(labelsX);
2676 TObjString* lb;
2677 Int_t i = 1;
2678 while ((lb=(TObjString*)iL())) {
2679 p2->GetXaxis()->SetBinLabel(i,lb->String().Data());
2680 ++i;
2681 }
2682 }
2683 THashList* labelsY = projX->GetLabels();
2684 if (labelsY) {
2685 TIter iL(labelsY);
2686 TObjString* lb;
2687 Int_t i = 1;
2688 while ((lb=(TObjString*)iL())) {
2689 p2->GetYaxis()->SetBinLabel(i,lb->String().Data());
2690 ++i;
2691 }
2692 }
2693
2694 // Set references to the axis, so that the loop has no branches.
2695 const TAxis* outAxis = nullptr;
2696 if ( projX != GetXaxis() && projY != GetXaxis() ) {
2697 outAxis = GetXaxis();
2698 } else if ( projX != GetYaxis() && projY != GetYaxis() ) {
2699 outAxis = GetYaxis();
2700 } else {
2701 outAxis = GetZaxis();
2702 }
2703
2704 // Weights management
2705 bool useWeights = (GetSumw2N() > 0);
2706 // store sum of w2 in profile if histo is weighted
2707 if (useWeights && (p2->GetBinSumw2()->fN != p2->GetNcells() ) ) p2->Sumw2();
2708
2709 // Set references to the bins, so that the loop has no branches.
2710 Int_t *refX = nullptr, *refY = nullptr, *refZ = nullptr;
2712 if ( projX == GetXaxis() && projY == GetYaxis() ) { refX = &ixbin; refY = &iybin; refZ = &outbin; }
2713 if ( projX == GetYaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &ixbin; refZ = &outbin; }
2714 if ( projX == GetXaxis() && projY == GetZaxis() ) { refX = &ixbin; refY = &outbin; refZ = &iybin; }
2715 if ( projX == GetZaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &outbin; refZ = &ixbin; }
2716 if ( projX == GetYaxis() && projY == GetZaxis() ) { refX = &outbin; refY = &ixbin; refZ = &iybin; }
2717 if ( projX == GetZaxis() && projY == GetYaxis() ) { refX = &outbin; refY = &iybin; refZ = &ixbin; }
2718 R__ASSERT (refX != nullptr && refY != nullptr && refZ != nullptr);
2719
2720 Int_t outmin = outAxis->GetFirst();
2721 Int_t outmax = outAxis->GetLast();
2722 // GetFirst, GetLast can return underflow or overflow bins
2723 // correct for underflow/overflows
2724 if (useUF && !outAxis->TestBit(TAxis::kAxisRange) ) outmin -= 1;
2725 if (useOF && !outAxis->TestBit(TAxis::kAxisRange) ) outmax += 1;
2726
2727 TArrayD & binSumw2 = *(p2->GetBinSumw2());
2728 if (useWeights && binSumw2.fN <= 0) useWeights = false;
2729 if (!useWeights) p2->SetBit(TH1::kIsNotW);
2730
2731 // Call specific method for the projection
2732 for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++) {
2733 if ( (ixbin < ixmin || ixbin > ixmax) && projX->TestBit(TAxis::kAxisRange)) continue;
2734 for ( iybin=0;iybin<=1+projY->GetNbins();iybin++) {
2735 if ( (iybin < iymin || iybin > iymax) && projX->TestBit(TAxis::kAxisRange)) continue;
2736
2737 // profile output bin
2738 Int_t poutBin = p2->FindBin(projY->GetBinCenter(iybin), projX->GetBinCenter(ixbin));
2739 if (poutBin <0) continue;
2740 // loop on the bins to be integrated (outbin should be called inbin)
2741 for (outbin = outmin; outbin <= outmax; outbin++) {
2742
2743 Int_t bin = GetBin(*refX,*refY,*refZ);
2744
2745 //DoFillProfileProjection(p2, *projY, *projX, *outAxis, iybin, ixbin, outbin, bin, useWeights);
2746
2748 if (!cont) continue;
2749
2750 Double_t tmp = 0;
2751 // the following fill update wrongly the fBinSumw2- need to save it before
2752 if ( useWeights ) tmp = binSumw2.fArray[poutBin];
2753 p2->Fill( projY->GetBinCenter(iybin) , projX->GetBinCenter(ixbin), outAxis->GetBinCenter(outbin), cont);
2754 if (useWeights ) binSumw2.fArray[poutBin] = tmp + fSumw2.fArray[bin];
2755
2756 }
2757 }
2758 }
2759
2760 // recompute statistics for the projected profiles
2761 // forget about preserving old statistics
2762 bool resetStats = true;
2764 // reset statistics
2765 if (resetStats)
2766 for (Int_t i=0;i<kNstat;i++) stats[i] = 0;
2767
2768 p2->PutStats(stats);
2769 Double_t entries = fEntries;
2770 // recalculate the statistics
2771 if (resetStats) {
2772 entries = p2->GetEffectiveEntries();
2773 if (!useWeights) entries = TMath::Floor( entries + 0.5); // to avoid numerical rounding
2774 p2->SetEntries( entries );
2775 }
2776
2777 p2->SetEntries(entries);
2778
2779 return p2;
2780}
2781
2782
2783////////////////////////////////////////////////////////////////////////////////
2784/// Project a 3-d histogram into a 2-d profile histograms depending
2785/// on the option parameter
2786/// option may contain a combination of the characters x,y,z
2787/// option = "xy" return the x versus y projection into a TProfile2D histogram
2788/// option = "yx" return the y versus x projection into a TProfile2D histogram
2789/// option = "xz" return the x versus z projection into a TProfile2D histogram
2790/// option = "zx" return the z versus x projection into a TProfile2D histogram
2791/// option = "yz" return the y versus z projection into a TProfile2D histogram
2792/// option = "zy" return the z versus y projection into a TProfile2D histogram
2793/// NB: the notation "a vs b" means "a" vertical and "b" horizontal
2794///
2795/// option = "o" original axis range of the target axes will be
2796/// kept, but only bins inside the selected range will be filled.
2797///
2798/// The projection is made for the selected bins only.
2799/// To select a bin range along an axis, use TAxis::SetRange, eg
2800/// h3.GetYaxis()->SetRange(23,56);
2801///
2802/// NOTE 1: The generated histogram is named th3name + "_p" + option
2803/// eg if the TH3* h histogram is named "myhist", then
2804/// h->Project3D("xy"); produces a TProfile2D histogram named "myhist_pxy".
2805/// The following sequence
2806/// h->Project3DProfile("xy");
2807/// h->Project3DProfile("xy2");
2808/// will generate two TProfile2D histograms named "myhist_pxy" and "myhist_pxy2"
2809/// So, passing additional characters in the option string one can customize the name.
2810///
2811/// NOTE 2: If a profile of the same type already exists with compatible axes,
2812/// the profile is reset and filled again with the projected contents of the TH3.
2813/// In the case of axes incompatibility, an error is reported and a NULL pointer is returned.
2814///
2815/// NOTE 3: The number of entries in the projected profile is estimated from the number of
2816/// effective entries for all the cells included in the projection.
2817///
2818/// NOTE 4: underflow/overflow are by default excluded from the projection
2819/// (Note that this is a different default behavior compared to the projection to an histogram)
2820/// To include the underflow and/or overflow use option "UF" and/or "OF"
2821
2823{
2824 TString opt = option; opt.ToLower();
2825 Int_t pcase = 0;
2826 TString ptype;
2827 if (opt.Contains("xy")) { pcase = 4; ptype = "xy"; }
2828 if (opt.Contains("yx")) { pcase = 5; ptype = "yx"; }
2829 if (opt.Contains("xz")) { pcase = 6; ptype = "xz"; }
2830 if (opt.Contains("zx")) { pcase = 7; ptype = "zx"; }
2831 if (opt.Contains("yz")) { pcase = 8; ptype = "yz"; }
2832 if (opt.Contains("zy")) { pcase = 9; ptype = "zy"; }
2833
2834 if (pcase == 0) {
2835 Error("Project3D","No projection axis specified - return a NULL pointer");
2836 return nullptr;
2837 }
2838 // do not remove ptype from opt to use later in the projected histo name
2839
2841 if (opt.Contains("uf") ) {
2842 useUF = kTRUE;
2843 opt.Remove(opt.Index("uf"),2);
2844 }
2846 if (opt.Contains("of") ) {
2847 useOF = kTRUE;
2848 opt.Remove(opt.Index("of"),2);
2849 }
2850
2852 if (opt.Contains('o') ) {
2854 opt.Remove(opt.First("o"),1);
2855 }
2856
2857 // Create the projected profile
2858 TProfile2D *p2 = nullptr;
2859 TString name = GetName();
2860 TString title = GetTitle();
2861 name += "_p"; name += opt; // opt may include a user defined name
2862 title += " profile "; title += ptype; title += " projection";
2863
2864 // Call the method with the specific projected axes.
2865 switch (pcase) {
2866 case 4:
2867 // "xy"
2869 break;
2870
2871 case 5:
2872 // "yx"
2874 break;
2875
2876 case 6:
2877 // "xz"
2879 break;
2880
2881 case 7:
2882 // "zx"
2884 break;
2885
2886 case 8:
2887 // "yz"
2889 break;
2890
2891 case 9:
2892 // "zy"
2894 break;
2895
2896 }
2897
2898 return p2;
2899}
2900
2901
2902////////////////////////////////////////////////////////////////////////////////
2903/// Replace current statistics with the values in array stats
2904
2906{
2908 fTsumwy = stats[4];
2909 fTsumwy2 = stats[5];
2910 fTsumwxy = stats[6];
2911 fTsumwz = stats[7];
2912 fTsumwz2 = stats[8];
2913 fTsumwxz = stats[9];
2914 fTsumwyz = stats[10];
2915}
2916
2917
2918////////////////////////////////////////////////////////////////////////////////
2919/// Rebin only the X axis
2920/// see Rebin3D
2921
2923{
2924 return Rebin3D(ngroup, 1, 1, newname);
2925}
2926
2927
2928////////////////////////////////////////////////////////////////////////////////
2929/// Rebin only the Y axis
2930/// see Rebin3D
2931
2933{
2934 return Rebin3D(1, ngroup, 1, newname);
2935}
2936
2937
2938////////////////////////////////////////////////////////////////////////////////
2939/// Rebin only the Z axis
2940/// see Rebin3D
2941
2943{
2944 return Rebin3D(1, 1, ngroup, newname);
2945
2946}
2947
2948
2949////////////////////////////////////////////////////////////////////////////////
2950/// Rebin this histogram grouping nxgroup/nygroup/nzgroup bins along the xaxis/yaxis/zaxis together.
2951///
2952/// if newname is not blank a new temporary histogram hnew is created.
2953/// else the current histogram is modified (default)
2954/// The parameter nxgroup/nygroup indicate how many bins along the xaxis/yaxis of this
2955/// have to me merged into one bin of hnew
2956/// If the original histogram has errors stored (via Sumw2), the resulting
2957/// histograms has new errors correctly calculated.
2958///
2959/// examples: if hpxpy is an existing TH3 histogram with 40 x 40 x 40 bins
2960/// hpxpypz->Rebin3D(); // merges two bins along the xaxis and yaxis in one in hpxpypz
2961/// // Carefull: previous contents of hpxpy are lost
2962/// hpxpypz->RebinX(5); //merges five bins along the xaxis in one in hpxpypz
2963/// TH3 *hnew = hpxpypz->RebinY(5,"hnew"); // creates a new histogram hnew
2964/// // merging 5 bins of h1 along the yaxis in one bin
2965///
2966/// NOTE : If nxgroup/nygroup is not an exact divider of the number of bins,
2967/// along the xaxis/yaxis the top limit(s) of the rebinned histogram
2968/// is changed to the upper edge of the xbin=newxbins*nxgroup resp.
2969/// ybin=newybins*nygroup and the corresponding bins are added to
2970/// the overflow bin.
2971/// Statistics will be recomputed from the new bin contents.
2972
2974{
2975 Int_t i,j,k,xbin,ybin,zbin;
2983 Double_t zmin = fZaxis.GetXmin();
2984 Double_t zmax = fZaxis.GetXmax();
2985 if ((nxgroup <= 0) || (nxgroup > nxbins)) {
2986 Error("Rebin", "Illegal value of nxgroup=%d",nxgroup);
2987 return nullptr;
2988 }
2989 if ((nygroup <= 0) || (nygroup > nybins)) {
2990 Error("Rebin", "Illegal value of nygroup=%d",nygroup);
2991 return nullptr;
2992 }
2993 if ((nzgroup <= 0) || (nzgroup > nzbins)) {
2994 Error("Rebin", "Illegal value of nzgroup=%d",nzgroup);
2995 return nullptr;
2996 }
2997
3001
3002 // Save old bin contents into a new array
3003 Double_t entries = fEntries;
3005 for (Int_t ibin = 0; ibin < fNcells; ibin++) {
3007 }
3008 Double_t *oldSumw2 = nullptr;
3009 if (fSumw2.fN != 0) {
3010 oldSumw2 = new Double_t[fNcells];
3011 for (Int_t ibin = 0; ibin < fNcells; ibin++) {
3013 }
3014 }
3015
3016 // create a clone of the old histogram if newname is specified
3017 TH3 *hnew = this;
3018 if (newname && strlen(newname)) {
3019 hnew = (TH3*)Clone();
3020 hnew->SetName(newname);
3021 }
3022
3023 // save original statistics
3024 Double_t stat[kNstat];
3025 GetStats(stat);
3026 bool resetStat = false;
3027
3028
3029 // change axis specs and rebuild bin contents array
3030 if (newxbins*nxgroup != nxbins) {
3032 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
3033 }
3034 if (newybins*nygroup != nybins) {
3036 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
3037 }
3038 if (newzbins*nzgroup != nzbins) {
3040 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
3041 }
3042 // save the TAttAxis members (reset by SetBins) for x axis
3054 // save the TAttAxis members (reset by SetBins) for y axis
3066 // save the TAttAxis members (reset by SetBins) for z axis
3078
3079 // copy merged bin contents (ignore under/overflows)
3080 if (nxgroup != 1 || nygroup != 1 || nzgroup != 1) {
3081 if (fXaxis.GetXbins()->GetSize() > 0 || fYaxis.GetXbins()->GetSize() > 0 || fZaxis.GetXbins()->GetSize() > 0) {
3082 // variable bin sizes in x or y, don't treat both cases separately
3083 Double_t *xbins = new Double_t[newxbins+1];
3084 for (i = 0; i <= newxbins; ++i) xbins[i] = fXaxis.GetBinLowEdge(1+i*nxgroup);
3085 Double_t *ybins = new Double_t[newybins+1];
3086 for (i = 0; i <= newybins; ++i) ybins[i] = fYaxis.GetBinLowEdge(1+i*nygroup);
3087 Double_t *zbins = new Double_t[newzbins+1];
3088 for (i = 0; i <= newzbins; ++i) zbins[i] = fZaxis.GetBinLowEdge(1+i*nzgroup);
3089 hnew->SetBins(newxbins,xbins, newybins, ybins, newzbins, zbins);//changes also errors array (if any)
3090 delete [] xbins;
3091 delete [] ybins;
3092 delete [] zbins;
3093 } else {
3094 hnew->SetBins(newxbins, xmin, xmax, newybins, ymin, ymax, newzbins, zmin, zmax);//changes also errors array
3095 }
3096
3098 Int_t oldxbin = 1;
3099 Int_t oldybin = 1;
3100 Int_t oldzbin = 1;
3101 Int_t bin;
3102 for (xbin = 1; xbin <= newxbins; xbin++) {
3103 oldybin=1;
3104 oldzbin=1;
3105 for (ybin = 1; ybin <= newybins; ybin++) {
3106 oldzbin=1;
3107 for (zbin = 1; zbin <= newzbins; zbin++) {
3108 binContent = 0;
3109 binSumw2 = 0;
3110 for (i = 0; i < nxgroup; i++) {
3111 if (oldxbin+i > nxbins) break;
3112 for (j =0; j < nygroup; j++) {
3113 if (oldybin+j > nybins) break;
3114 for (k =0; k < nzgroup; k++) {
3115 if (oldzbin+k > nzbins) break;
3116 //get global bin (same conventions as in TH1::GetBin(xbin,ybin)
3117 bin = oldxbin + i + (oldybin + j)*(nxbins + 2) + (oldzbin + k)*(nxbins + 2)*(nybins + 2);
3118 binContent += oldBins[bin];
3119 if (oldSumw2) binSumw2 += oldSumw2[bin];
3120 }
3121 }
3122 }
3123 Int_t ibin = hnew->GetBin(xbin,ybin,zbin); // new bin number
3124 hnew->SetBinContent(ibin, binContent);
3125 if (oldSumw2) hnew->fSumw2.fArray[ibin] = binSumw2;
3126 oldzbin += nzgroup;
3127 }
3128 oldybin += nygroup;
3129 }
3130 oldxbin += nxgroup;
3131 }
3132
3133 // compute new underflow/overflows for the 8 vertices
3134 for (Int_t xover = 0; xover <= 1; xover++) {
3135 for (Int_t yover = 0; yover <= 1; yover++) {
3136 for (Int_t zover = 0; zover <= 1; zover++) {
3137 binContent = 0;
3138 binSumw2 = 0;
3139 // make loop in case of only underflow/overflow
3140 for (xbin = xover*oldxbin; xbin <= xover*(nxbins+1); xbin++) {
3141 for (ybin = yover*oldybin; ybin <= yover*(nybins+1); ybin++) {
3142 for (zbin = zover*oldzbin; zbin <= zover*(nzbins+1); zbin++) {
3143 bin = GetBin(xbin,ybin,zbin);
3144 binContent += oldBins[bin];
3145 if (oldSumw2) binSumw2 += oldSumw2[bin];
3146 }
3147 }
3148 }
3149 Int_t binNew = hnew->GetBin( xover *(newxbins+1),
3150 yover*(newybins+1), zover*(newzbins+1) );
3151 hnew->SetBinContent(binNew,binContent);
3152 if (oldSumw2) hnew->fSumw2.fArray[binNew] = binSumw2;
3153 }
3154 }
3155 }
3156
3161
3162 // recompute under/overflow contents in y for the new x and z bins
3163 oldxbin2 = 1;
3164 oldybin2 = 1;
3165 oldzbin2 = 1;
3166 for (xbin = 1; xbin<=newxbins; xbin++) {
3167 oldzbin2 = 1;
3168 for (zbin = 1; zbin<=newzbins; zbin++) {
3170 binError0 = binError2 = 0;
3171 for (i=0; i<nxgroup; i++) {
3172 if (oldxbin2+i > nxbins) break;
3173 for (k=0; k<nzgroup; k++) {
3174 if (oldzbin2+k > nzbins) break;
3175 //old underflow bin (in y)
3176 ufbin = oldxbin2 + i + (nxbins+2)*(nybins+2)*(oldzbin2+k);
3179 for (ybin = oldybin; ybin <= nybins + 1; ybin++) {
3180 //old overflow bin (in y)
3181 ofbin = ufbin + ybin*(nxbins+2);
3184 }
3185 }
3186 }
3187 hnew->SetBinContent(xbin,0,zbin,binContent0);
3188 hnew->SetBinContent(xbin,newybins+1,zbin,binContent2);
3189 if (oldSumw2) {
3190 hnew->SetBinError(xbin,0,zbin,TMath::Sqrt(binError0));
3191 hnew->SetBinError(xbin,newybins+1,zbin,TMath::Sqrt(binError2) );
3192 }
3193 oldzbin2 += nzgroup;
3194 }
3195 oldxbin2 += nxgroup;
3196 }
3197
3198 // recompute under/overflow contents in x for the new y and z bins
3199 oldxbin2 = 1;
3200 oldybin2 = 1;
3201 oldzbin2 = 1;
3202 for (ybin = 1; ybin<=newybins; ybin++) {
3203 oldzbin2 = 1;
3204 for (zbin = 1; zbin<=newzbins; zbin++) {
3206 binError0 = binError2 = 0;
3207 for (j=0; j<nygroup; j++) {
3208 if (oldybin2+j > nybins) break;
3209 for (k=0; k<nzgroup; k++) {
3210 if (oldzbin2+k > nzbins) break;
3211 //old underflow bin (in y)
3212 ufbin = (oldybin2 + j)*(nxbins+2) + (nxbins+2)*(nybins+2)*(oldzbin2+k);
3215 for (xbin = oldxbin; xbin <= nxbins + 1; xbin++) {
3216 //old overflow bin (in x)
3217 ofbin = ufbin + xbin;
3220 }
3221 }
3222 }
3223 hnew->SetBinContent(0,ybin,zbin,binContent0);
3224 hnew->SetBinContent(newxbins+1,ybin,zbin,binContent2);
3225 if (oldSumw2) {
3226 hnew->SetBinError(0,ybin,zbin,TMath::Sqrt(binError0));
3227 hnew->SetBinError(newxbins+1,ybin,zbin,TMath::Sqrt(binError2) );
3228 }
3229 oldzbin2 += nzgroup;
3230 }
3231 oldybin2 += nygroup;
3232 }
3233
3234 // recompute under/overflow contents in z for the new x and y bins
3235 oldxbin2 = 1;
3236 oldybin2 = 1;
3237 oldzbin2 = 1;
3238 for (xbin = 1; xbin<=newxbins; xbin++) {
3239 oldybin2 = 1;
3240 for (ybin = 1; ybin<=newybins; ybin++) {
3242 binError0 = binError2 = 0;
3243 for (i=0; i<nxgroup; i++) {
3244 if (oldxbin2+i > nxbins) break;
3245 for (j=0; j<nygroup; j++) {
3246 if (oldybin2+j > nybins) break;
3247 //old underflow bin (in z)
3248 ufbin = oldxbin2 + i + (nxbins+2)*(oldybin2+j);
3251 for (zbin = oldzbin; zbin <= nzbins + 1; zbin++) {
3252 //old overflow bin (in z)
3253 ofbin = ufbin + (nxbins+2)*(nybins+2)*zbin;
3256 }
3257 }
3258 }
3259 hnew->SetBinContent(xbin,ybin,0,binContent0);
3260 hnew->SetBinContent(xbin,ybin,newzbins+1,binContent2);
3261 if (oldSumw2) {
3262 hnew->SetBinError(xbin,ybin,0,TMath::Sqrt(binError0));
3263 hnew->SetBinError(xbin,ybin,newzbins+1,TMath::Sqrt(binError2) );
3264 }
3265 oldybin2 += nygroup;
3266 }
3267 oldxbin2 += nxgroup;
3268 }
3269
3270 // recompute under/overflow contents in y, z for the new x
3271 oldxbin2 = 1;
3272 oldybin2 = 1;
3273 oldzbin2 = 1;
3274 for (xbin = 1; xbin<=newxbins; xbin++) {
3275 binContent0 = 0;
3276 binContent2 = 0;
3277 binContent3 = 0;
3278 binContent4 = 0;
3279 binError0 = 0;
3280 binError2 = 0;
3281 binError3 = 0;
3282 binError4 = 0;
3283 for (i=0; i<nxgroup; i++) {
3284 if (oldxbin2+i > nxbins) break;
3285 ufbin = oldxbin2 + i; //
3288 for (ybin = oldybin; ybin <= nybins + 1; ybin++) {
3289 ofbin3 = ufbin+ybin*(nxbins+2);
3292 for (zbin = oldzbin; zbin <= nzbins + 1; zbin++) {
3293 //old overflow bin (in z)
3294 ofbin4 = oldxbin2 + i + ybin*(nxbins+2) + (nxbins+2)*(nybins+2)*zbin;
3297 }
3298 }
3299 for (zbin = oldzbin; zbin <= nzbins + 1; zbin++) {
3300 ofbin2 = ufbin+zbin*(nxbins+2)*(nybins+2);
3303 }
3304 }
3305 hnew->SetBinContent(xbin,0,0,binContent0);
3306 hnew->SetBinContent(xbin,0,newzbins+1,binContent2);
3307 hnew->SetBinContent(xbin,newybins+1,0,binContent3);
3308 hnew->SetBinContent(xbin,newybins+1,newzbins+1,binContent4);
3309 if (oldSumw2) {
3310 hnew->SetBinError(xbin,0,0,TMath::Sqrt(binError0));
3311 hnew->SetBinError(xbin,0,newzbins+1,TMath::Sqrt(binError2) );
3312 hnew->SetBinError(xbin,newybins+1,0,TMath::Sqrt(binError3) );
3313 hnew->SetBinError(xbin,newybins+1,newzbins+1,TMath::Sqrt(binError4) );
3314 }
3315 oldxbin2 += nxgroup;
3316 }
3317
3318 // recompute under/overflow contents in x, y for the new z
3319 oldxbin2 = 1;
3320 oldybin2 = 1;
3321 oldzbin2 = 1;
3322 for (zbin = 1; zbin<=newzbins; zbin++) {
3323 binContent0 = 0;
3324 binContent2 = 0;
3325 binContent3 = 0;
3326 binContent4 = 0;
3327 binError0 = 0;
3328 binError2 = 0;
3329 binError3 = 0;
3330 binError4 = 0;
3331 for (i=0; i<nzgroup; i++) {
3332 if (oldzbin2+i > nzbins) break;
3333 ufbin = (oldzbin2 + i)*(nxbins+2)*(nybins+2); //
3336 for (ybin = oldybin; ybin <= nybins + 1; ybin++) {
3337 ofbin3 = ufbin+ybin*(nxbins+2);
3340 for (xbin = oldxbin; xbin <= nxbins + 1; xbin++) {
3341 //old overflow bin (in z)
3342 ofbin4 = ufbin + xbin + ybin*(nxbins+2);
3345 }
3346 }
3347 for (xbin = oldxbin; xbin <= nxbins + 1; xbin++) {
3348 ofbin2 = xbin +(oldzbin2+i)*(nxbins+2)*(nybins+2);
3351 }
3352 }
3353 hnew->SetBinContent(0,0,zbin,binContent0);
3354 hnew->SetBinContent(0,newybins+1,zbin,binContent3);
3355 hnew->SetBinContent(newxbins+1,0,zbin,binContent2);
3356 hnew->SetBinContent(newxbins+1,newybins+1,zbin,binContent4);
3357 if (oldSumw2) {
3358 hnew->SetBinError(0,0,zbin,TMath::Sqrt(binError0));
3359 hnew->SetBinError(0,newybins+1,zbin,TMath::Sqrt(binError3) );
3360 hnew->SetBinError(newxbins+1,0,zbin,TMath::Sqrt(binError2) );
3361 hnew->SetBinError(newxbins+1,newybins+1,zbin,TMath::Sqrt(binError4) );
3362 }
3363 oldzbin2 += nzgroup;
3364 }
3365
3366 // recompute under/overflow contents in x, z for the new y
3367 oldxbin2 = 1;
3368 oldybin2 = 1;
3369 oldzbin2 = 1;
3370 for (ybin = 1; ybin<=newybins; ybin++) {
3371 binContent0 = 0;
3372 binContent2 = 0;
3373 binContent3 = 0;
3374 binContent4 = 0;
3375 binError0 = 0;
3376 binError2 = 0;
3377 binError3 = 0;
3378 binError4 = 0;
3379 for (i=0; i<nygroup; i++) {
3380 if (oldybin2+i > nybins) break;
3381 ufbin = (oldybin2 + i)*(nxbins+2); //
3384 for (xbin = oldxbin; xbin <= nxbins + 1; xbin++) {
3385 ofbin3 = ufbin+xbin;
3388 for (zbin = oldzbin; zbin <= nzbins + 1; zbin++) {
3389 //old overflow bin (in z)
3390 ofbin4 = xbin + (nxbins+2)*(nybins+2)*zbin+(oldybin2+i)*(nxbins+2);
3393 }
3394 }
3395 for (zbin = oldzbin; zbin <= nzbins + 1; zbin++) {
3396 ofbin2 = (oldybin2+i)*(nxbins+2)+zbin*(nxbins+2)*(nybins+2);
3399 }
3400 }
3401 hnew->SetBinContent(0,ybin,0,binContent0);
3402 hnew->SetBinContent(0,ybin,newzbins+1,binContent2);
3403 hnew->SetBinContent(newxbins+1,ybin,0,binContent3);
3404 hnew->SetBinContent(newxbins+1,ybin,newzbins+1,binContent4);
3405 if (oldSumw2) {
3406 hnew->SetBinError(0,ybin,0,TMath::Sqrt(binError0));
3407 hnew->SetBinError(0,ybin,newzbins+1,TMath::Sqrt(binError2) );
3408 hnew->SetBinError(newxbins+1,ybin,0,TMath::Sqrt(binError3) );
3409 hnew->SetBinError(newxbins+1,ybin,newzbins+1,TMath::Sqrt(binError4) );
3410 }
3411 oldybin2 += nygroup;
3412 }
3413 }
3414
3415 // Restore x axis attributes
3427 // Restore y axis attributes
3439 // Restore z axis attributes
3451
3452 //restore statistics and entries modified by SetBinContent
3453 hnew->SetEntries(entries);
3454 if (!resetStat) hnew->PutStats(stat);
3455
3456 delete [] oldBins;
3457 if (oldSumw2) delete [] oldSumw2;
3458 return hnew;
3459}
3460
3461
3462////////////////////////////////////////////////////////////////////////////////
3463/// Reset this histogram: contents, errors, etc.
3464
3466{
3468 TString opt = option;
3469 opt.ToUpper();
3470 if (opt.Contains("ICE") && !opt.Contains("S")) return;
3471 fTsumwy = 0;
3472 fTsumwy2 = 0;
3473 fTsumwxy = 0;
3474 fTsumwz = 0;
3475 fTsumwz2 = 0;
3476 fTsumwxz = 0;
3477 fTsumwyz = 0;
3478}
3479
3480
3481////////////////////////////////////////////////////////////////////////////////
3482/// Set bin content.
3483
3485{
3486 fEntries++;
3487 fTsumw = 0;
3488 if (bin < 0) return;
3489 if (bin >= fNcells) return;
3491}
3492
3493
3494////////////////////////////////////////////////////////////////////////////////
3495/// Stream an object of class TH3.
3496
3498{
3499 if (R__b.IsReading()) {
3500 UInt_t R__s, R__c;
3501 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3502 if (R__v > 2) {
3503 R__b.ReadClassBuffer(TH3::Class(), this, R__v, R__s, R__c);
3504 return;
3505 }
3506 //====process old versions before automatic schema evolution
3509 R__b.CheckByteCount(R__s, R__c, TH3::IsA());
3510 //====end of old versions
3511
3512 } else {
3513 R__b.WriteClassBuffer(TH3::Class(),this);
3514 }
3515}
3516
3517////////////////////////////////////////////////////////////////////////////////
3518/// static methdod performing the projection to 1D histogram
3519
3520TH1D *TH3::DoProject1D(const TH3 &h, const char *name, const char *title, const TAxis *projX, bool computeErrors,
3521 bool originalRange, bool useUF, bool useOF)
3522{
3523 return h.DoProject1D(name, title, projX, nullptr, nullptr, computeErrors, originalRange, useUF, useOF);
3524}
3525
3526////////////////////////////////////////////////////////////////////////////////
3527/// static methdod performing the projection to 2D histogram
3528
3529TH2D *TH3::DoProject2D(const TH3 &h, const char *name, const char *title, const TAxis *projX, const TAxis *projY,
3530 bool computeErrors, bool originalRange, bool useUF, bool useOF)
3531{
3532 return h.DoProject2D(name, title, projX, projY, computeErrors, originalRange, useUF, useOF);
3533}
3534
3535//______________________________________________________________________________
3536// TH3C methods
3537// TH3C a 3-D histogram with one byte per cell (char)
3538//______________________________________________________________________________
3539
3540
3541
3542////////////////////////////////////////////////////////////////////////////////
3543/// Constructor.
3544
3546{
3547 SetBinsLength(27);
3548 if (fgDefaultSumw2) Sumw2();
3549}
3550
3551
3552////////////////////////////////////////////////////////////////////////////////
3553/// Destructor.
3554
3556{
3557}
3558
3559
3560////////////////////////////////////////////////////////////////////////////////
3561/// Constructor for fix bin size 3-D histograms
3562/// (see TH3::TH3 for explanation of parameters)
3563
3564TH3C::TH3C(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
3565 ,Int_t nbinsy,Double_t ylow,Double_t yup
3567 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
3568{
3570 if (fgDefaultSumw2) Sumw2();
3571
3572 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
3573}
3574
3575
3576////////////////////////////////////////////////////////////////////////////////
3577/// Constructor for variable bin size 3-D histograms.
3578/// (see TH3::TH3 for explanation of parameters)
3579
3580TH3C::TH3C(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
3581 ,Int_t nbinsy,const Float_t *ybins
3582 ,Int_t nbinsz,const Float_t *zbins)
3583 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
3584{
3586 if (fgDefaultSumw2) Sumw2();
3587}
3588
3589
3590////////////////////////////////////////////////////////////////////////////////
3591/// Constructor for variable bin size 3-D histograms.
3592/// (see TH3::TH3 for explanation of parameters)
3593
3594TH3C::TH3C(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
3595 ,Int_t nbinsy,const Double_t *ybins
3596 ,Int_t nbinsz,const Double_t *zbins)
3597 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
3598{
3600 if (fgDefaultSumw2) Sumw2();
3601}
3602
3603
3604////////////////////////////////////////////////////////////////////////////////
3605/// Copy constructor.
3606/// The list of functions is not copied. (Use Clone() if needed)
3607
3609{
3610 h3c.TH3C::Copy(*this);
3611}
3612
3613
3614////////////////////////////////////////////////////////////////////////////////
3615/// Increment bin content by 1.
3616/// Passing an out-of-range bin leads to undefined behavior
3617
3619{
3620 if (fArray[bin] < 127) fArray[bin]++;
3621}
3622
3623
3624////////////////////////////////////////////////////////////////////////////////
3625/// Increment bin content by w.
3626/// \warning The value of w is cast to `Int_t` before being added.
3627/// Passing an out-of-range bin leads to undefined behavior
3628
3630{
3631 Int_t newval = fArray[bin] + Int_t(w);
3632 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
3633 if (newval < -127) fArray[bin] = -127;
3634 if (newval > 127) fArray[bin] = 127;
3635}
3636
3637
3638////////////////////////////////////////////////////////////////////////////////
3639/// Copy this 3-D histogram structure to newth3.
3640
3642{
3644}
3645
3646
3647////////////////////////////////////////////////////////////////////////////////
3648/// Reset this histogram: contents, errors, etc.
3649
3651{
3654 // should also reset statistics once statistics are implemented for TH3
3655}
3656
3657
3658////////////////////////////////////////////////////////////////////////////////
3659/// Set total number of bins including under/overflow
3660/// Reallocate bin contents array
3661
3663{
3664 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
3665 fNcells = n;
3666 TArrayC::Set(n);
3667}
3668
3669
3670////////////////////////////////////////////////////////////////////////////////
3671/// When the mouse is moved in a pad containing a 3-d view of this histogram
3672/// a second canvas shows a projection type given as option.
3673/// To stop the generation of the projections, delete the canvas
3674/// containing the projection.
3675/// option may contain a combination of the characters x,y,z,e
3676/// option = "x" return the x projection into a TH1D histogram
3677/// option = "y" return the y projection into a TH1D histogram
3678/// option = "z" return the z projection into a TH1D histogram
3679/// option = "xy" return the x versus y projection into a TH2D histogram
3680/// option = "yx" return the y versus x projection into a TH2D histogram
3681/// option = "xz" return the x versus z projection into a TH2D histogram
3682/// option = "zx" return the z versus x projection into a TH2D histogram
3683/// option = "yz" return the y versus z projection into a TH2D histogram
3684/// option = "zy" return the z versus y projection into a TH2D histogram
3685/// option can also include the drawing option for the projection, eg to draw
3686/// the xy projection using the draw option "box" do
3687/// myhist.SetShowProjection("xy box");
3688/// This function is typically called from the context menu.
3689/// NB: the notation "a vs b" means "a" vertical and "b" horizontal
3690
3691void TH3::SetShowProjection(const char *option,Int_t nbins)
3692{
3693 GetPainter();
3694
3696}
3697
3698
3699////////////////////////////////////////////////////////////////////////////////
3700/// Stream an object of class TH3C.
3701
3703{
3704 if (R__b.IsReading()) {
3705 UInt_t R__s, R__c;
3706 if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
3707 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3708 if (R__v > 2) {
3709 R__b.ReadClassBuffer(TH3C::Class(), this, R__v, R__s, R__c);
3710 return;
3711 }
3712 //====process old versions before automatic schema evolution
3713 if (R__v < 2) {
3714 R__b.ReadVersion();
3717 R__b.ReadVersion(&R__s, &R__c);
3719 } else {
3722 R__b.CheckByteCount(R__s, R__c, TH3C::IsA());
3723 }
3724 //====end of old versions
3725
3726 } else {
3727 R__b.WriteClassBuffer(TH3C::Class(),this);
3728 }
3729}
3730
3731
3732////////////////////////////////////////////////////////////////////////////////
3733/// Operator =
3734
3736{
3737 if (this != &h3c)
3738 h3c.TH3C::Copy(*this);
3739 return *this;
3740}
3741
3742
3743////////////////////////////////////////////////////////////////////////////////
3744/// Operator *
3745
3747{
3748 TH3C hnew = h3c;
3749 hnew.Scale(c1);
3750 hnew.SetDirectory(nullptr);
3751 return hnew;
3752}
3753
3754
3755////////////////////////////////////////////////////////////////////////////////
3756/// Operator +
3757
3758TH3C operator+(TH3C const &h1, TH3C const &h2)
3759{
3760 TH3C hnew = h1;
3761 hnew.Add(&h2,1);
3762 hnew.SetDirectory(nullptr);
3763 return hnew;
3764}
3765
3766
3767////////////////////////////////////////////////////////////////////////////////
3768/// Operator -
3769
3770TH3C operator-(TH3C const &h1, TH3C const &h2)
3771{
3772 TH3C hnew = h1;
3773 hnew.Add(&h2,-1);
3774 hnew.SetDirectory(nullptr);
3775 return hnew;
3776}
3777
3778
3779////////////////////////////////////////////////////////////////////////////////
3780/// Operator *
3781
3782TH3C operator*(TH3C const &h1, TH3C const &h2)
3783{
3784 TH3C hnew = h1;
3785 hnew.Multiply(&h2);
3786 hnew.SetDirectory(nullptr);
3787 return hnew;
3788}
3789
3790
3791////////////////////////////////////////////////////////////////////////////////
3792/// Operator /
3793
3794TH3C operator/(TH3C const &h1, TH3C const &h2)
3795{
3796 TH3C hnew = h1;
3797 hnew.Divide(&h2);
3798 hnew.SetDirectory(nullptr);
3799 return hnew;
3800}
3801
3802
3803//______________________________________________________________________________
3804// TH3S methods
3805// TH3S a 3-D histogram with two bytes per cell (short integer)
3806//______________________________________________________________________________
3807
3808
3809
3810////////////////////////////////////////////////////////////////////////////////
3811/// Constructor.
3812
3814{
3815 SetBinsLength(27);
3816 if (fgDefaultSumw2) Sumw2();
3817}
3818
3819
3820////////////////////////////////////////////////////////////////////////////////
3821/// Destructor.
3822
3824{
3825}
3826
3827
3828////////////////////////////////////////////////////////////////////////////////
3829/// Constructor for fix bin size 3-D histograms.
3830/// (see TH3::TH3 for explanation of parameters)
3831
3832TH3S::TH3S(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
3833 ,Int_t nbinsy,Double_t ylow,Double_t yup
3835 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
3836{
3838 if (fgDefaultSumw2) Sumw2();
3839
3840 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
3841}
3842
3843
3844////////////////////////////////////////////////////////////////////////////////
3845/// Constructor for variable bin size 3-D histograms.
3846/// (see TH3::TH3 for explanation of parameters)
3847
3848TH3S::TH3S(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
3849 ,Int_t nbinsy,const Float_t *ybins
3850 ,Int_t nbinsz,const Float_t *zbins)
3851 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
3852{
3854 if (fgDefaultSumw2) Sumw2();
3855}
3856
3857
3858////////////////////////////////////////////////////////////////////////////////
3859/// Constructor for variable bin size 3-D histograms.
3860/// (see TH3::TH3 for explanation of parameters)
3861
3862TH3S::TH3S(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
3863 ,Int_t nbinsy,const Double_t *ybins
3864 ,Int_t nbinsz,const Double_t *zbins)
3865 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
3866{
3868 if (fgDefaultSumw2) Sumw2();
3869}
3870
3871
3872////////////////////////////////////////////////////////////////////////////////
3873/// Copy Constructor.
3874/// The list of functions is not copied. (Use Clone() if needed)
3875
3877{
3878 h3s.TH3S::Copy(*this);
3879}
3880
3881
3882////////////////////////////////////////////////////////////////////////////////
3883/// Increment bin content by 1.
3884/// Passing an out-of-range bin leads to undefined behavior
3885
3887{
3888 if (fArray[bin] < 32767) fArray[bin]++;
3889}
3890
3891
3892////////////////////////////////////////////////////////////////////////////////
3893/// Increment bin content by w.
3894/// \warning The value of w is cast to `Int_t` before being added.
3895/// Passing an out-of-range bin leads to undefined behavior
3896
3898{
3899 Int_t newval = fArray[bin] + Int_t(w);
3900 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
3901 if (newval < -32767) fArray[bin] = -32767;
3902 if (newval > 32767) fArray[bin] = 32767;
3903}
3904
3905
3906////////////////////////////////////////////////////////////////////////////////
3907/// Copy this 3-D histogram structure to newth3.
3908
3910{
3912}
3913
3914
3915////////////////////////////////////////////////////////////////////////////////
3916/// Reset this histogram: contents, errors, etc.
3917
3919{
3922 // should also reset statistics once statistics are implemented for TH3
3923}
3924
3925
3926////////////////////////////////////////////////////////////////////////////////
3927/// Set total number of bins including under/overflow
3928/// Reallocate bin contents array
3929
3931{
3932 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
3933 fNcells = n;
3934 TArrayS::Set(n);
3935}
3936
3937
3938////////////////////////////////////////////////////////////////////////////////
3939/// Stream an object of class TH3S.
3940
3942{
3943 if (R__b.IsReading()) {
3944 UInt_t R__s, R__c;
3945 if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
3946 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3947 if (R__v > 2) {
3948 R__b.ReadClassBuffer(TH3S::Class(), this, R__v, R__s, R__c);
3949 return;
3950 }
3951 //====process old versions before automatic schema evolution
3952 if (R__v < 2) {
3953 R__b.ReadVersion();
3956 R__b.ReadVersion(&R__s, &R__c);
3958 } else {
3961 R__b.CheckByteCount(R__s, R__c, TH3S::IsA());
3962 }
3963 //====end of old versions
3964
3965 } else {
3966 R__b.WriteClassBuffer(TH3S::Class(),this);
3967 }
3968}
3969
3970
3971////////////////////////////////////////////////////////////////////////////////
3972/// Operator =
3973
3975{
3976 if (this != &h3s)
3977 h3s.TH3S::Copy(*this);
3978 return *this;
3979}
3980
3981
3982////////////////////////////////////////////////////////////////////////////////
3983/// Operator *
3984
3986{
3987 TH3S hnew = h3s;
3988 hnew.Scale(c1);
3989 hnew.SetDirectory(nullptr);
3990 return hnew;
3991}
3992
3993
3994////////////////////////////////////////////////////////////////////////////////
3995/// Operator +
3996
3997TH3S operator+(TH3S const &h1, TH3S const &h2)
3998{
3999 TH3S hnew = h1;
4000 hnew.Add(&h2,1);
4001 hnew.SetDirectory(nullptr);
4002 return hnew;
4003}
4004
4005
4006////////////////////////////////////////////////////////////////////////////////
4007/// Operator -
4008
4009TH3S operator-(TH3S const &h1, TH3S const &h2)
4010{
4011 TH3S hnew = h1;
4012 hnew.Add(&h2,-1);
4013 hnew.SetDirectory(nullptr);
4014 return hnew;
4015}
4016
4017
4018////////////////////////////////////////////////////////////////////////////////
4019/// Operator *
4020
4021TH3S operator*(TH3S const &h1, TH3S const &h2)
4022{
4023 TH3S hnew = h1;
4024 hnew.Multiply(&h2);
4025 hnew.SetDirectory(nullptr);
4026 return hnew;
4027}
4028
4029
4030////////////////////////////////////////////////////////////////////////////////
4031/// Operator /
4032
4033TH3S operator/(TH3S const &h1, TH3S const &h2)
4034{
4035 TH3S hnew = h1;
4036 hnew.Divide(&h2);
4037 hnew.SetDirectory(nullptr);
4038 return hnew;
4039}
4040
4041
4042//______________________________________________________________________________
4043// TH3I methods
4044// TH3I a 3-D histogram with four bytes per cell (32 bit integer)
4045//______________________________________________________________________________
4046
4047
4048
4049////////////////////////////////////////////////////////////////////////////////
4050/// Constructor.
4051
4053{
4054 SetBinsLength(27);
4055 if (fgDefaultSumw2) Sumw2();
4056}
4057
4058
4059////////////////////////////////////////////////////////////////////////////////
4060/// Destructor.
4061
4063{
4064}
4065
4066
4067////////////////////////////////////////////////////////////////////////////////
4068/// Constructor for fix bin size 3-D histograms
4069/// (see TH3::TH3 for explanation of parameters)
4070
4071TH3I::TH3I(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
4072 ,Int_t nbinsy,Double_t ylow,Double_t yup
4074 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
4075{
4077 if (fgDefaultSumw2) Sumw2();
4078
4079 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
4080}
4081
4082
4083////////////////////////////////////////////////////////////////////////////////
4084/// Constructor for variable bin size 3-D histograms
4085/// (see TH3::TH3 for explanation of parameters)
4086
4087TH3I::TH3I(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
4088 ,Int_t nbinsy,const Float_t *ybins
4089 ,Int_t nbinsz,const Float_t *zbins)
4090 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4091{
4093 if (fgDefaultSumw2) Sumw2();
4094}
4095
4096
4097////////////////////////////////////////////////////////////////////////////////
4098/// Constructor for variable bin size 3-D histograms
4099/// (see TH3::TH3 for explanation of parameters)
4100
4101TH3I::TH3I(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
4102 ,Int_t nbinsy,const Double_t *ybins
4103 ,Int_t nbinsz,const Double_t *zbins)
4104 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4105{
4107 if (fgDefaultSumw2) Sumw2();
4108}
4109
4110
4111////////////////////////////////////////////////////////////////////////////////
4112/// Copy constructor.
4113/// The list of functions is not copied. (Use Clone() if needed)
4114
4116{
4117 h3i.TH3I::Copy(*this);
4118}
4119
4120
4121////////////////////////////////////////////////////////////////////////////////
4122/// Increment bin content by 1.
4123/// Passing an out-of-range bin leads to undefined behavior
4124
4126{
4127 if (fArray[bin] < INT_MAX) fArray[bin]++;
4128}
4129
4130
4131////////////////////////////////////////////////////////////////////////////////
4132/// Increment bin content by w.
4133/// \warning The value of w is cast to `Long64_t` before being added.
4134/// Passing an out-of-range bin leads to undefined behavior
4135
4137{
4138 Long64_t newval = fArray[bin] + Long64_t(w);
4139 if (newval > -INT_MAX && newval < INT_MAX) {fArray[bin] = Int_t(newval); return;}
4140 if (newval < -INT_MAX) fArray[bin] = -INT_MAX;
4141 if (newval > INT_MAX) fArray[bin] = INT_MAX;
4142}
4143
4144
4145////////////////////////////////////////////////////////////////////////////////
4146/// Copy this 3-D histogram structure to newth3.
4147
4149{
4151}
4152
4153
4154////////////////////////////////////////////////////////////////////////////////
4155/// Reset this histogram: contents, errors, etc.
4156
4158{
4161 // should also reset statistics once statistics are implemented for TH3
4162}
4163
4164
4165////////////////////////////////////////////////////////////////////////////////
4166/// Set total number of bins including under/overflow
4167/// Reallocate bin contents array
4168
4170{
4171 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
4172 fNcells = n;
4173 TArrayI::Set(n);
4174}
4175
4176
4177////////////////////////////////////////////////////////////////////////////////
4178/// Operator =
4179
4181{
4182 if (this != &h3i)
4183 h3i.TH3I::Copy(*this);
4184 return *this;
4185}
4186
4187
4188////////////////////////////////////////////////////////////////////////////////
4189/// Operator *
4190
4192{
4193 TH3I hnew = h3i;
4194 hnew.Scale(c1);
4195 hnew.SetDirectory(nullptr);
4196 return hnew;
4197}
4198
4199
4200////////////////////////////////////////////////////////////////////////////////
4201/// Operator +
4202
4203TH3I operator+(TH3I const &h1, TH3I const &h2)
4204{
4205 TH3I hnew = h1;
4206 hnew.Add(&h2,1);
4207 hnew.SetDirectory(nullptr);
4208 return hnew;
4209}
4210
4211
4212////////////////////////////////////////////////////////////////////////////////
4213/// Operator _
4214
4215TH3I operator-(TH3I const &h1, TH3I const &h2)
4216{
4217 TH3I hnew = h1;
4218 hnew.Add(&h2,-1);
4219 hnew.SetDirectory(nullptr);
4220 return hnew;
4221}
4222
4223
4224////////////////////////////////////////////////////////////////////////////////
4225/// Operator *
4226
4227TH3I operator*(TH3I const &h1, TH3I const &h2)
4228{
4229 TH3I hnew = h1;
4230 hnew.Multiply(&h2);
4231 hnew.SetDirectory(nullptr);
4232 return hnew;
4233}
4234
4235
4236////////////////////////////////////////////////////////////////////////////////
4237/// Operator /
4238
4239TH3I operator/(TH3I const &h1, TH3I const &h2)
4240{
4241 TH3I hnew = h1;
4242 hnew.Divide(&h2);
4243 hnew.SetDirectory(nullptr);
4244 return hnew;
4245}
4246
4247
4248//______________________________________________________________________________
4249// TH3L methods
4250// TH3L a 3-D histogram with eight bytes per cell (64 bit integer)
4251//______________________________________________________________________________
4252
4253
4254
4255////////////////////////////////////////////////////////////////////////////////
4256/// Constructor.
4257
4259{
4260 SetBinsLength(27);
4261 if (fgDefaultSumw2) Sumw2();
4262}
4263
4264
4265////////////////////////////////////////////////////////////////////////////////
4266/// Destructor.
4267
4269{
4270}
4271
4272
4273////////////////////////////////////////////////////////////////////////////////
4274/// Constructor for fix bin size 3-D histograms
4275/// (see TH3::TH3 for explanation of parameters)
4276
4277TH3L::TH3L(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
4278 ,Int_t nbinsy,Double_t ylow,Double_t yup
4280 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
4281{
4283 if (fgDefaultSumw2) Sumw2();
4284
4285 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
4286}
4287
4288
4289////////////////////////////////////////////////////////////////////////////////
4290/// Constructor for variable bin size 3-D histograms
4291/// (see TH3::TH3 for explanation of parameters)
4292
4293TH3L::TH3L(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
4294 ,Int_t nbinsy,const Float_t *ybins
4295 ,Int_t nbinsz,const Float_t *zbins)
4296 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4297{
4299 if (fgDefaultSumw2) Sumw2();
4300}
4301
4302
4303////////////////////////////////////////////////////////////////////////////////
4304/// Constructor for variable bin size 3-D histograms
4305/// (see TH3::TH3 for explanation of parameters)
4306
4307TH3L::TH3L(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
4308 ,Int_t nbinsy,const Double_t *ybins
4309 ,Int_t nbinsz,const Double_t *zbins)
4310 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4311{
4313 if (fgDefaultSumw2) Sumw2();
4314}
4315
4316
4317////////////////////////////////////////////////////////////////////////////////
4318/// Copy constructor.
4319/// The list of functions is not copied. (Use Clone() if needed)
4320
4322{
4323 h3l.TH3L::Copy(*this);
4324}
4325
4326
4327////////////////////////////////////////////////////////////////////////////////
4328/// Increment bin content by 1.
4329/// Passing an out-of-range bin leads to undefined behavior
4330
4332{
4333 if (fArray[bin] < LLONG_MAX) fArray[bin]++;
4334}
4335
4336
4337////////////////////////////////////////////////////////////////////////////////
4338/// Increment bin content by w.
4339/// \warning The value of w is cast to `Long64_t` before being added.
4340/// Passing an out-of-range bin leads to undefined behavior
4341
4343{
4344 Long64_t newval = fArray[bin] + Long64_t(w);
4345 if (newval > -LLONG_MAX && newval < LLONG_MAX) {fArray[bin] = Int_t(newval); return;}
4346 if (newval < -LLONG_MAX) fArray[bin] = -LLONG_MAX;
4347 if (newval > LLONG_MAX) fArray[bin] = LLONG_MAX;
4348}
4349
4350
4351////////////////////////////////////////////////////////////////////////////////
4352/// Copy this 3-D histogram structure to newth3.
4353
4355{
4357}
4358
4359
4360////////////////////////////////////////////////////////////////////////////////
4361/// Reset this histogram: contents, errors, etc.
4362
4364{
4367 // should also reset statistics once statistics are implemented for TH3
4368}
4369
4370
4371////////////////////////////////////////////////////////////////////////////////
4372/// Set total number of bins including under/overflow
4373/// Reallocate bin contents array
4374
4376{
4377 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
4378 fNcells = n;
4380}
4381
4382
4383////////////////////////////////////////////////////////////////////////////////
4384/// Operator =
4385
4387{
4388 if (this != &h3l)
4389 h3l.TH3L::Copy(*this);
4390 return *this;
4391}
4392
4393
4394////////////////////////////////////////////////////////////////////////////////
4395/// Operator *
4396
4398{
4399 TH3L hnew = h3l;
4400 hnew.Scale(c1);
4401 hnew.SetDirectory(nullptr);
4402 return hnew;
4403}
4404
4405
4406////////////////////////////////////////////////////////////////////////////////
4407/// Operator +
4408
4409TH3L operator+(TH3L const &h1, TH3L const &h2)
4410{
4411 TH3L hnew = h1;
4412 hnew.Add(&h2,1);
4413 hnew.SetDirectory(nullptr);
4414 return hnew;
4415}
4416
4417
4418////////////////////////////////////////////////////////////////////////////////
4419/// Operator _
4420
4421TH3L operator-(TH3L const &h1, TH3L const &h2)
4422{
4423 TH3L hnew = h1;
4424 hnew.Add(&h2,-1);
4425 hnew.SetDirectory(nullptr);
4426 return hnew;
4427}
4428
4429
4430////////////////////////////////////////////////////////////////////////////////
4431/// Operator *
4432
4433TH3L operator*(TH3L const &h1, TH3L const &h2)
4434{
4435 TH3L hnew = h1;
4436 hnew.Multiply(&h2);
4437 hnew.SetDirectory(nullptr);
4438 return hnew;
4439}
4440
4441
4442////////////////////////////////////////////////////////////////////////////////
4443/// Operator /
4444
4445TH3L operator/(TH3L const &h1, TH3L const &h2)
4446{
4447 TH3L hnew = h1;
4448 hnew.Divide(&h2);
4449 hnew.SetDirectory(nullptr);
4450 return hnew;
4451}
4452
4453
4454//______________________________________________________________________________
4455// TH3F methods
4456// TH3F a 3-D histogram with four bytes per cell (float). Maximum precision 7 digits, maximum integer bin content = +/-16777216
4457//______________________________________________________________________________
4458
4459
4460
4461////////////////////////////////////////////////////////////////////////////////
4462/// Constructor.
4463
4465{
4466 SetBinsLength(27);
4467 if (fgDefaultSumw2) Sumw2();
4468}
4469
4470
4471////////////////////////////////////////////////////////////////////////////////
4472/// Destructor.
4473
4475{
4476}
4477
4478
4479////////////////////////////////////////////////////////////////////////////////
4480/// Constructor for fix bin size 3-D histograms
4481/// (see TH3::TH3 for explanation of parameters)
4482
4483TH3F::TH3F(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
4484 ,Int_t nbinsy,Double_t ylow,Double_t yup
4486 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
4487{
4489 if (fgDefaultSumw2) Sumw2();
4490
4491 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
4492}
4493
4494
4495////////////////////////////////////////////////////////////////////////////////
4496/// Constructor for variable bin size 3-D histograms
4497/// (see TH3::TH3 for explanation of parameters)
4498
4499TH3F::TH3F(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
4500 ,Int_t nbinsy,const Float_t *ybins
4501 ,Int_t nbinsz,const Float_t *zbins)
4502 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4503{
4505 if (fgDefaultSumw2) Sumw2();
4506}
4507
4508
4509////////////////////////////////////////////////////////////////////////////////
4510/// Constructor for variable bin size 3-D histograms
4511/// (see TH3::TH3 for explanation of parameters)
4512
4513TH3F::TH3F(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
4514 ,Int_t nbinsy,const Double_t *ybins
4515 ,Int_t nbinsz,const Double_t *zbins)
4516 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4517{
4519 if (fgDefaultSumw2) Sumw2();
4520}
4521
4522
4523////////////////////////////////////////////////////////////////////////////////
4524/// Copy constructor.
4525/// The list of functions is not copied. (Use Clone() if needed)
4526
4528{
4529 h3f.TH3F::Copy(*this);
4530}
4531
4532
4533////////////////////////////////////////////////////////////////////////////////
4534/// Copy this 3-D histogram structure to newth3.
4535
4537{
4539}
4540
4541
4542////////////////////////////////////////////////////////////////////////////////
4543/// Reset this histogram: contents, errors, etc.
4544
4546{
4549 // should also reset statistics once statistics are implemented for TH3
4550}
4551
4552
4553////////////////////////////////////////////////////////////////////////////////
4554/// Set total number of bins including under/overflow
4555/// Reallocate bin contents array
4556
4558{
4559 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
4560 fNcells = n;
4561 TArrayF::Set(n);
4562}
4563
4564
4565////////////////////////////////////////////////////////////////////////////////
4566/// Stream an object of class TH3F.
4567
4569{
4570 if (R__b.IsReading()) {
4571 UInt_t R__s, R__c;
4572 if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
4573 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
4574 if (R__v > 2) {
4575 R__b.ReadClassBuffer(TH3F::Class(), this, R__v, R__s, R__c);
4576 return;
4577 }
4578 //====process old versions before automatic schema evolution
4579 if (R__v < 2) {
4580 R__b.ReadVersion();
4583 R__b.ReadVersion(&R__s, &R__c);
4585 } else {
4588 R__b.CheckByteCount(R__s, R__c, TH3F::IsA());
4589 }
4590 //====end of old versions
4591
4592 } else {
4593 R__b.WriteClassBuffer(TH3F::Class(),this);
4594 }
4595}
4596
4597
4598////////////////////////////////////////////////////////////////////////////////
4599/// Operator =
4600
4602{
4603 if (this != &h3f)
4604 h3f.TH3F::Copy(*this);
4605 return *this;
4606}
4607
4608
4609////////////////////////////////////////////////////////////////////////////////
4610/// Operator *
4611
4613{
4614 TH3F hnew = h3f;
4615 hnew.Scale(c1);
4616 hnew.SetDirectory(nullptr);
4617 return hnew;
4618}
4619
4620
4621////////////////////////////////////////////////////////////////////////////////
4622/// Operator +
4623
4624TH3F operator+(TH3F const &h1, TH3F const &h2)
4625{
4626 TH3F hnew = h1;
4627 hnew.Add(&h2,1);
4628 hnew.SetDirectory(nullptr);
4629 return hnew;
4630}
4631
4632
4633////////////////////////////////////////////////////////////////////////////////
4634/// Operator -
4635
4636TH3F operator-(TH3F const &h1, TH3F const &h2)
4637{
4638 TH3F hnew = h1;
4639 hnew.Add(&h2,-1);
4640 hnew.SetDirectory(nullptr);
4641 return hnew;
4642}
4643
4644
4645////////////////////////////////////////////////////////////////////////////////
4646/// Operator *
4647
4648TH3F operator*(TH3F const &h1, TH3F const &h2)
4649{
4650 TH3F hnew = h1;
4651 hnew.Multiply(&h2);
4652 hnew.SetDirectory(nullptr);
4653 return hnew;
4654}
4655
4656
4657////////////////////////////////////////////////////////////////////////////////
4658/// Operator /
4659
4660TH3F operator/(TH3F const &h1, TH3F const &h2)
4661{
4662 TH3F hnew = h1;
4663 hnew.Divide(&h2);
4664 hnew.SetDirectory(nullptr);
4665 return hnew;
4666}
4667
4668
4669//______________________________________________________________________________
4670// TH3D methods
4671// TH3D a 3-D histogram with eight bytes per cell (double). Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992
4672//______________________________________________________________________________
4673
4674
4675
4676////////////////////////////////////////////////////////////////////////////////
4677/// Constructor.
4678
4680{
4681 SetBinsLength(27);
4682 if (fgDefaultSumw2) Sumw2();
4683}
4684
4685
4686////////////////////////////////////////////////////////////////////////////////
4687/// Destructor.
4688
4690{
4691}
4692
4693
4694////////////////////////////////////////////////////////////////////////////////
4695/// Constructor for fix bin size 3-D histograms
4696/// (see TH3::TH3 for explanation of parameters)
4697
4698TH3D::TH3D(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
4699 ,Int_t nbinsy,Double_t ylow,Double_t yup
4701 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
4702{
4704 if (fgDefaultSumw2) Sumw2();
4705
4706 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
4707}
4708
4709
4710////////////////////////////////////////////////////////////////////////////////
4711/// Constructor for variable bin size 3-D histograms
4712/// (see TH3::TH3 for explanation of parameters)
4713
4714TH3D::TH3D(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
4715 ,Int_t nbinsy,const Float_t *ybins
4716 ,Int_t nbinsz,const Float_t *zbins)
4717 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4718{
4720 if (fgDefaultSumw2) Sumw2();
4721}
4722
4723
4724////////////////////////////////////////////////////////////////////////////////
4725/// Constructor for variable bin size 3-D histograms
4726/// (see TH3::TH3 for explanation of parameters)
4727
4728TH3D::TH3D(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
4729 ,Int_t nbinsy,const Double_t *ybins
4730 ,Int_t nbinsz,const Double_t *zbins)
4731 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4732{
4734 if (fgDefaultSumw2) Sumw2();
4735}
4736
4737
4738////////////////////////////////////////////////////////////////////////////////
4739/// Copy constructor.
4740/// The list of functions is not copied. (Use Clone() if needed)
4741
4743{
4744 // intentially call virtual Copy method to warn if TProfile3D is copied
4745 h3d.Copy(*this);
4746}
4747
4748
4749////////////////////////////////////////////////////////////////////////////////
4750/// Copy this 3-D histogram structure to newth3.
4751
4753{
4755}
4756
4757
4758////////////////////////////////////////////////////////////////////////////////
4759/// Reset this histogram: contents, errors, etc.
4760
4762{
4765 // should also reset statistics once statistics are implemented for TH3
4766}
4767
4768
4769////////////////////////////////////////////////////////////////////////////////
4770/// Set total number of bins including under/overflow
4771/// Reallocate bin contents array
4772
4774{
4775 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
4776 fNcells = n;
4777 TArrayD::Set(n);
4778}
4779
4780
4781////////////////////////////////////////////////////////////////////////////////
4782/// Stream an object of class TH3D.
4783
4785{
4786 if (R__b.IsReading()) {
4787 UInt_t R__s, R__c;
4788 if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
4789 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
4790 if (R__v > 2) {
4791 R__b.ReadClassBuffer(TH3D::Class(), this, R__v, R__s, R__c);
4792 return;
4793 }
4794 //====process old versions before automatic schema evolution
4795 if (R__v < 2) {
4796 R__b.ReadVersion();
4799 R__b.ReadVersion(&R__s, &R__c);
4801 } else {
4804 R__b.CheckByteCount(R__s, R__c, TH3D::IsA());
4805 }
4806 //====end of old versions
4807
4808 } else {
4809 R__b.WriteClassBuffer(TH3D::Class(),this);
4810 }
4811}
4812
4813
4814////////////////////////////////////////////////////////////////////////////////
4815/// Operator =
4816
4818{
4819 // intentially call virtual Copy method to warn if TProfile3D is copied
4820 if (this != &h3d)
4821 h3d.Copy(*this);
4822 return *this;
4823}
4824
4825
4826////////////////////////////////////////////////////////////////////////////////
4827/// Operator *
4828
4830{
4831 TH3D hnew = h3d;
4832 hnew.Scale(c1);
4833 hnew.SetDirectory(nullptr);
4834 return hnew;
4835}
4836
4837
4838////////////////////////////////////////////////////////////////////////////////
4839/// Operator +
4840
4841TH3D operator+(TH3D const &h1, TH3D const &h2)
4842{
4843 TH3D hnew = h1;
4844 hnew.Add(&h2,1);
4845 hnew.SetDirectory(nullptr);
4846 return hnew;
4847}
4848
4849
4850////////////////////////////////////////////////////////////////////////////////
4851/// Operator -
4852
4853TH3D operator-(TH3D const &h1, TH3D const &h2)
4854{
4855 TH3D hnew = h1;
4856 hnew.Add(&h2,-1);
4857 hnew.SetDirectory(nullptr);
4858 return hnew;
4859}
4860
4861
4862////////////////////////////////////////////////////////////////////////////////
4863/// Operator *
4864
4865TH3D operator*(TH3D const &h1, TH3D const &h2)
4866{
4867 TH3D hnew = h1;
4868 hnew.Multiply(&h2);
4869 hnew.SetDirectory(nullptr);
4870 return hnew;
4871}
4872
4873
4874////////////////////////////////////////////////////////////////////////////////
4875/// Operator /
4876
4877TH3D operator/(TH3D const &h1, TH3D const &h2)
4878{
4879 TH3D hnew = h1;
4880 hnew.Divide(&h2);
4881 hnew.SetDirectory(nullptr);
4882 return hnew;
4883}
#define c(i)
Definition RSha256.hxx:101
#define s1(x)
Definition RSha256.hxx:91
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
short Style_t
Style number (short)
Definition RtypesCore.h:96
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Color_t
Color number (short)
Definition RtypesCore.h:99
short Version_t
Class version identifier (short)
Definition RtypesCore.h:79
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
short Short_t
Signed Short integer 2 bytes (short)
Definition RtypesCore.h:53
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
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 Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
char name[80]
Definition TGX11.cxx:110
TH3C operator-(TH3C const &h1, TH3C const &h2)
Operator -.
Definition TH3.cxx:3770
TH3C operator+(TH3C const &h1, TH3C const &h2)
Operator +.
Definition TH3.cxx:3758
TH3C operator/(TH3C const &h1, TH3C const &h2)
Operator /.
Definition TH3.cxx:3794
TH3C operator*(Float_t c1, TH3C const &h3c)
Operator *.
Definition TH3.cxx:3746
float xmin
int nentries
float ymin
float xmax
float ymax
#define gROOT
Definition TROOT.h:411
R__EXTERN TRandom * gRandom
Definition TRandom.h:62
#define gPad
Array of chars or bytes (8 bits per element).
Definition TArrayC.h:27
void Streamer(TBuffer &) override
Stream a TArrayC object.
Definition TArrayC.cxx:147
Char_t * fArray
Definition TArrayC.h:30
void Reset(Char_t val=0)
Definition TArrayC.h:47
void Set(Int_t n) override
Set size of this array to n chars.
Definition TArrayC.cxx:104
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 Set(Int_t n) override
Set size of this array to n doubles.
Definition TArrayD.cxx:105
void Reset()
Definition TArrayD.h:47
Array of floats (32 bits per element).
Definition TArrayF.h:27
void Reset()
Definition TArrayF.h:47
void Set(Int_t n) override
Set size of this array to n floats.
Definition TArrayF.cxx:104
void Streamer(TBuffer &) override
Stream a TArrayF object.
Definition TArrayF.cxx:147
Array of integers (32 bits per element).
Definition TArrayI.h:27
Int_t * fArray
Definition TArrayI.h:30
void Set(Int_t n) override
Set size of this array to n ints.
Definition TArrayI.cxx:104
void Reset()
Definition TArrayI.h:47
Array of long64s (64 bits per element).
Definition TArrayL64.h:27
Long64_t * fArray
Definition TArrayL64.h:30
void Set(Int_t n) override
Set size of this array to n long64s.
void Reset()
Definition TArrayL64.h:47
Array of shorts (16 bits per element).
Definition TArrayS.h:27
void Set(Int_t n) override
Set size of this array to n shorts.
Definition TArrayS.cxx:104
void Streamer(TBuffer &) override
Stream a TArrayS object.
Definition TArrayS.cxx:147
void Reset()
Definition TArrayS.h:47
Short_t * fArray
Definition TArrayS.h:30
Int_t fN
Definition TArray.h:38
virtual void Set(Int_t n)=0
virtual void Streamer(TBuffer &)
virtual Color_t GetTitleColor() const
Definition TAttAxis.h:47
virtual Color_t GetLabelColor() const
Definition TAttAxis.h:39
virtual Int_t GetNdivisions() const
Definition TAttAxis.h:37
virtual Color_t GetAxisColor() const
Definition TAttAxis.h:38
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition TAttAxis.cxx:279
virtual Style_t GetTitleFont() const
Definition TAttAxis.h:48
virtual Float_t GetLabelOffset() const
Definition TAttAxis.h:41
virtual void SetAxisColor(Color_t color=1, Float_t alpha=1.)
Set color of the line axis and tick marks.
Definition TAttAxis.cxx:141
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
Definition TAttAxis.cxx:184
virtual Style_t GetLabelFont() const
Definition TAttAxis.h:40
virtual void SetTitleFont(Style_t font=62)
Set the title font.
Definition TAttAxis.cxx:308
virtual void SetLabelOffset(Float_t offset=0.005)
Set distance between the axis and the labels.
Definition TAttAxis.cxx:172
virtual void SetLabelFont(Style_t font=62)
Set labels' font.
Definition TAttAxis.cxx:161
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title.
Definition TAttAxis.cxx:290
virtual void SetTitleColor(Color_t color=1)
Set color of axis title.
Definition TAttAxis.cxx:299
virtual Float_t GetTitleSize() const
Definition TAttAxis.h:45
virtual Float_t GetLabelSize() const
Definition TAttAxis.h:42
virtual Float_t GetTickLength() const
Definition TAttAxis.h:46
virtual Float_t GetTitleOffset() const
Definition TAttAxis.h:44
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length.
Definition TAttAxis.cxx:265
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition TAttAxis.cxx:214
virtual void SetLabelColor(Color_t color=1, Float_t alpha=1.)
Set color of labels.
Definition TAttAxis.cxx:151
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:31
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition TAttFill.h:38
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:35
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:42
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition TAttMarker.h:33
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition TAttMarker.h:39
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:32
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition TAttMarker.h:41
Class to manage histogram axis.
Definition TAxis.h:32
virtual void SetBinLabel(Int_t bin, const char *label)
Set label for bin.
Definition TAxis.cxx:875
Bool_t IsAlphanumeric() const
Definition TAxis.h:90
const char * GetTitle() const override
Returns title of object.
Definition TAxis.h:137
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 SetCanExtend(Bool_t canExtend)
Definition TAxis.h:92
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
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:521
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Definition TAxis.cxx:783
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x
Definition TAxis.cxx:421
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:472
virtual void ImportAttributes(const TAxis *axis)
Copy axis attributes to this.
Definition TAxis.cxx:684
Double_t GetXmin() const
Definition TAxis.h:141
Int_t GetNbins() const
Definition TAxis.h:127
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:545
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
Buffer base class used for serializing objects.
Definition TBuffer.h:43
1-Dim function class
Definition TF1.h:182
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function Note that this histogram is managed ...
Definition TF1.cxx:1611
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition TF1.cxx:1957
Double_t GetChisquare() const
Return the Chisquare after fitting. See ROOT::Fit::FitResult::Chi2()
Definition TF1.h:424
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition TF1.cxx:3559
virtual Int_t GetNpar() const
Definition TF1.h:461
virtual Int_t GetNumberFitPoints() const
Definition TF1.h:483
virtual Double_t * GetParameters() const
Definition TF1.h:500
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2306
virtual const char * GetParName(Int_t ipar) const
Definition TF1.h:509
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=nullptr)
Evaluate function with given coordinates and parameters.
Definition TF1.cxx:1475
virtual void SetParameters(const Double_t *params)
Definition TF1.h:633
virtual Double_t GetParameter(Int_t ipar) const
Definition TF1.h:492
A 3-Dim function with parameters.
Definition TF3.h:28
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:927
static TClass * Class()
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:10311
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
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition TH1.cxx:4425
TAxis * GetZaxis()
Definition TH1.h:574
@ kXaxis
Definition TH1.h:123
@ kAllAxes
Definition TH1.h:126
@ kZaxis
Definition TH1.h:125
@ kYaxis
Definition TH1.h:124
Int_t fNcells
Number of bins(1D), cells (2D) +U/Overflows.
Definition TH1.h:150
void Copy(TObject &hnew) const override
Copy this histogram structure to newth1.
Definition TH1.cxx:2642
Double_t fTsumw
Total Sum of weights.
Definition TH1.h:157
Double_t fTsumw2
Total Sum of squares of weights.
Definition TH1.h:158
static TClass * Class()
virtual Double_t DoIntegral(Int_t ix1, Int_t ix2, Int_t iy1, Int_t iy2, Int_t iz1, Int_t iz2, Double_t &err, Option_t *opt, Bool_t doerr=kFALSE) const
Internal function compute integral and optionally the error between the limits specified by the bin n...
Definition TH1.cxx:8005
Double_t fTsumwx2
Total Sum of weight*X*X.
Definition TH1.h:160
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition TH1.cxx:7630
virtual Int_t GetNbinsY() const
Definition TH1.h:543
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:9088
virtual Int_t GetNbinsZ() const
Definition TH1.h:544
virtual Int_t GetDimension() const
Definition TH1.h:528
void Streamer(TBuffer &) override
Stream a class object.
Definition TH1.cxx:6968
@ 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:6671
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition TH1.cxx:7138
TAxis * GetXaxis()
Definition TH1.h:572
virtual Int_t GetNcells() const
Definition TH1.h:545
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition TH1.cxx:7907
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition TH1.cxx:4488
virtual Int_t GetBin(Int_t binx, Int_t biny=0, Int_t binz=0) const
Return Global bin number corresponding to binx,y,z.
Definition TH1.cxx:4963
virtual Int_t GetNbinsX() const
Definition TH1.h:542
Int_t fBufferSize
fBuffer size
Definition TH1.h:168
Int_t fDimension
! Histogram dimension (1, 2 or 3 dim)
Definition TH1.h:171
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:9231
static Int_t fgBufferSize
! Default buffer size for automatic histograms
Definition TH1.h:176
TAxis * GetYaxis()
Definition TH1.h:573
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx:3037
virtual void SetBuffer(Int_t bufsize, Option_t *option="")
Set the maximum number of entries to be kept in the buffer.
Definition TH1.cxx:8486
UInt_t GetAxisLabelStatus() const
Internal function used in TH1::Fill to see which axis is full alphanumeric, i.e.
Definition TH1.cxx:6710
Double_t * fIntegral
! Integral of bins used by GetRandom
Definition TH1.h:172
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:9247
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:9177
virtual Double_t RetrieveBinContent(Int_t bin) const =0
Raw retrieval of bin content on internal data structure see convention for numbering bins in TH1::Get...
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6241
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculated from bin cont...
Definition TH1.cxx:7925
@ 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 Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5063
TAxis fXaxis
X axis descriptor.
Definition TH1.h:151
virtual void ExtendAxis(Double_t x, TAxis *axis)
Histogram is resized along axis such that x is in the axis range.
Definition TH1.cxx:6539
TArrayD fSumw2
Array of sum of squares of weights.
Definition TH1.h:165
virtual Int_t GetSumw2N() const
Definition TH1.h:563
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
Return Global bin number corresponding to x,y,z.
Definition TH1.cxx:3649
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:2723
TAxis fYaxis
Y axis descriptor.
Definition TH1.h:152
TVirtualHistPainter * fPainter
! Pointer to histogram painter
Definition TH1.h:173
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition TH1.cxx:8795
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:9048
virtual void SetEntries(Double_t n)
Definition TH1.h:640
static Bool_t fgDefaultSumw2
! Flag to call TH1::Sumw2 automatically at histogram creation time
Definition TH1.h:179
virtual void UpdateBinContent(Int_t bin, Double_t content)=0
Raw update of bin content on internal data structure see convention for numbering bins in TH1::GetBin...
Double_t fTsumwx
Total Sum of weight*X.
Definition TH1.h:159
virtual Double_t ComputeIntegral(Bool_t onlyPositive=false)
Compute integral (normalized cumulative sum of bins) w/o under/overflows The result is stored in fInt...
Definition TH1.cxx:2508
2-D histogram with a double per channel (see TH1 documentation)
Definition TH2.h:356
static TClass * Class()
3-D histogram with a byte per channel (see TH1 documentation)
Definition TH3.h:170
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH3.cxx:3662
TClass * IsA() const override
Definition TH3.h:204
~TH3C() override
Destructor.
Definition TH3.cxx:3555
void Reset(Option_t *option="") override
Reset this histogram: contents, errors, etc.
Definition TH3.cxx:3650
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH3.cxx:3618
TH3C & operator=(const TH3C &h1)
Operator =.
Definition TH3.cxx:3735
TH3C()
Constructor.
Definition TH3.cxx:3545
static TClass * Class()
void Streamer(TBuffer &) override
Stream an object of class TH3C.
Definition TH3.cxx:3702
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:3641
3-D histogram with a double per channel (see TH1 documentation)
Definition TH3.h:371
TClass * IsA() const override
Definition TH3.h:417
TH3D()
Constructor.
Definition TH3.cxx:4679
void Streamer(TBuffer &) override
Stream an object of class TH3D.
Definition TH3.cxx:4784
static TClass * Class()
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH3.cxx:4773
~TH3D() override
Destructor.
Definition TH3.cxx:4689
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:4752
TH3D & operator=(const TH3D &h1)
Operator =.
Definition TH3.cxx:4817
3-D histogram with a float per channel (see TH1 documentation)
Definition TH3.h:326
TH3F & operator=(const TH3F &h1)
Operator =.
Definition TH3.cxx:4601
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH3.cxx:4557
static TClass * Class()
TH3F()
Constructor.
Definition TH3.cxx:4464
~TH3F() override
Destructor.
Definition TH3.cxx:4474
void Streamer(TBuffer &) override
Stream an object of class TH3F.
Definition TH3.cxx:4568
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:4536
TClass * IsA() const override
Definition TH3.h:366
3-D histogram with an int per channel (see TH1 documentation)
Definition TH3.h:248
TH3I & operator=(const TH3I &h1)
Operator =.
Definition TH3.cxx:4180
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH3.cxx:4125
TH3I()
Constructor.
Definition TH3.cxx:4052
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:4148
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH3.cxx:4169
~TH3I() override
Destructor.
Definition TH3.cxx:4062
3-D histogram with a long64 per channel (see TH1 documentation)
Definition TH3.h:288
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:4354
TH3L & operator=(const TH3L &h1)
Operator =.
Definition TH3.cxx:4386
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH3.cxx:4331
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH3.cxx:4375
~TH3L() override
Destructor.
Definition TH3.cxx:4268
TH3L()
Constructor.
Definition TH3.cxx:4258
3-D histogram with a short per channel (see TH1 documentation)
Definition TH3.h:209
void Streamer(TBuffer &) override
Stream an object of class TH3S.
Definition TH3.cxx:3941
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH3.cxx:3930
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH3.cxx:3886
~TH3S() override
Destructor.
Definition TH3.cxx:3823
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:3909
TClass * IsA() const override
Definition TH3.h:243
static TClass * Class()
TH3S & operator=(const TH3S &h1)
Operator =.
Definition TH3.cxx:3974
TH3S()
Constructor.
Definition TH3.cxx:3813
The 3-D histogram classes derived from the 1-D histogram classes.
Definition TH3.h:40
virtual TH3 * Rebin3D(Int_t nxgroup=2, Int_t nygroup=2, Int_t nzgroup=2, const char *newname="")
Rebin this histogram grouping nxgroup/nygroup/nzgroup bins along the xaxis/yaxis/zaxis together.
Definition TH3.cxx:2973
Int_t BufferEmpty(Int_t action=0) override
Fill histogram with all entries in the buffer.
Definition TH3.cxx:230
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 Double_t GetCovariance(Int_t axis1=1, Int_t axis2=2) const
Return covariance between axis1 and axis2.
Definition TH3.cxx:1225
void GetStats(Double_t *stats) const override
Fill the array stats from the contents of this histogram The array stats must be correctly dimensione...
Definition TH3.cxx:1323
void Copy(TObject &hnew) const override
Copy.
Definition TH3.cxx:210
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:2119
Double_t fTsumwxz
Total Sum of weight*X*Z.
Definition TH3.h:48
Double_t KolmogorovTest(const TH1 *h2, Option_t *option="") const override
Statistical test of compatibility in shape between THIS histogram and h2, using Kolmogorov test.
Definition TH3.cxx:1548
virtual TH1D * ProjectionY(const char *name="_py", Int_t ixmin=0, Int_t ixmax=-1, Int_t izmin=0, Int_t izmax=-1, Option_t *option="") const
Project a 3-D histogram into a 1-D histogram along Y.
Definition TH3.cxx:1796
Double_t Interpolate(Double_t x, Double_t y) const override
Not yet implemented.
Definition TH3.cxx:1457
virtual void GetRandom3(Double_t &x, Double_t &y, Double_t &, TRandom *rng=nullptr)
Return 3 random numbers along axis x , y and z distributed according to the cell-contents of this 3-d...
Definition TH3.cxx:1275
void AddBinContent(Int_t binx, Int_t biny, Int_t binz)
Increment 3D bin content by 1.
Definition TH3.h:90
void Reset(Option_t *option="") override
Reset this histogram: contents, errors, etc.
Definition TH3.cxx:3465
~TH3() override
Destructor.
Definition TH3.cxx:202
Int_t Fill(Double_t) override
Invalid Fill method.
Definition TH3.cxx:334
virtual TH3 * RebinY(Int_t ngroup=2, const char *newname="")
Rebin only the Y axis see Rebin3D.
Definition TH3.cxx:2932
virtual Double_t IntegralAndError(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t &err, Option_t *option="") const
Return integral of bin contents in range [binx1,binx2],[biny1,biny2],[binz1,binz2] for a 3-D histogra...
Definition TH3.cxx:1437
virtual TH1D * ProjectionZ(const char *name="_pz", Int_t ixmin=0, Int_t ixmax=-1, Int_t iymin=0, Int_t iymax=-1, Option_t *option="") const
Project a 3-D histogram into a 1-D histogram along Z.
Definition TH3.cxx:1828
virtual TH1D * ProjectionX(const char *name="_px", Int_t iymin=0, Int_t iymax=-1, Int_t izmin=0, Int_t izmax=-1, Option_t *option="") const
Project a 3-D histogram into a 1-D histogram along X.
Definition TH3.cxx:1763
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:2822
static TClass * Class()
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
virtual TH1 * Project3D(Option_t *option="x") const
Project a 3-d histogram into 1 or 2-d histograms depending on the option parameter,...
Definition TH3.cxx:2425
virtual Double_t GetBinWithContent3(Double_t c, Int_t &binx, Int_t &biny, Int_t &binz, Int_t firstx=0, Int_t lastx=0, Int_t firsty=0, Int_t lasty=0, Int_t firstz=0, Int_t lastz=0, Double_t maxdiff=0) const
Compute first cell (binx,biny,binz) in the range [firstx,lastx](firsty,lasty][firstz,...
Definition TH3.cxx:1167
void DoFillProfileProjection(TProfile2D *p2, const TAxis &a1, const TAxis &a2, const TAxis &a3, Int_t bin1, Int_t bin2, Int_t bin3, Int_t inBin, Bool_t useWeights) const
internal function to fill the bins of the projected profile 2D histogram called from DoProjectProfile...
Definition TH3.cxx:2566
virtual TH3 * RebinZ(Int_t ngroup=2, const char *newname="")
Rebin only the Z axis see Rebin3D.
Definition TH3.cxx:2942
void Streamer(TBuffer &) override
Stream an object of class TH3.
Definition TH3.cxx:3497
Double_t Integral(Option_t *option="") const override
Return integral of bin contents.
Definition TH3.cxx:1406
virtual Int_t BufferFill(Double_t x, Double_t y, Double_t z, Double_t w)
Accumulate arguments in buffer.
Definition TH3.cxx:305
void FillRandom(TF1 *f1, Int_t ntimes=5000, TRandom *rng=nullptr) override
Fill histogram following distribution in function fname.
Definition TH3.cxx:852
TClass * IsA() const override
Definition TH3.h:165
virtual void SetShowProjection(const char *option="xy", Int_t nbins=1)
When the mouse is moved in a pad containing a 3-d view of this histogram a second canvas shows a proj...
Definition TH3.cxx:3691
TH3 * RebinX(Int_t ngroup=2, const char *newname="") override
Rebin only the X axis see Rebin3D.
Definition TH3.cxx:2922
virtual Double_t GetCorrelationFactor(Int_t axis1=1, Int_t axis2=2) const
Return correlation factor between axis1 and axis2.
Definition TH3.cxx:1207
virtual TH1D * DoProject1D(const char *name, const char *title, int imin1, int imax1, int imin2, int imax2, const TAxis *projAxis, const TAxis *axis1, const TAxis *axis2, Option_t *option) const
internal method performing the projection to 1D histogram called from TH3::Project3D
Definition TH3.cxx:1845
Double_t fTsumwz
Total Sum of weight*Z.
Definition TH3.h:46
Double_t GetBinContent(Int_t binx, Int_t biny, Int_t binz) const override
Definition TH3.h:114
void SetBinContent(Int_t bin, Double_t content) override
Set bin content.
Definition TH3.cxx:3484
Double_t fTsumwyz
Total Sum of weight*Y*Z.
Definition TH3.h:49
TH3()
Default constructor.
Definition TH3.cxx:76
Int_t GetBin(Int_t binx, Int_t biny, Int_t binz) const override
See comments in TH1::GetBin.
Definition TH3.cxx:1133
virtual void FitSlicesZ(TF1 *f1=nullptr, Int_t binminx=1, Int_t binmaxx=0, Int_t binminy=1, Int_t binmaxy=0, Int_t cut=0, Option_t *option="QNR")
Project slices along Z in case of a 3-D histogram, then fit each slice with function f1 and make a 2-...
Definition TH3.cxx:994
virtual TProfile2D * DoProjectProfile2D(const char *name, const char *title, const TAxis *projX, const TAxis *projY, bool originalRange, bool useUF, bool useOF) const
internal method to project to a 2D Profile called from TH3::Project3DProfile
Definition TH3.cxx:2592
void PutStats(Double_t *stats) override
Replace current statistics with the values in array stats.
Definition TH3.cxx:2905
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
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
Collectable string class.
Definition TObjString.h:28
Mother of all ROOT objects.
Definition TObject.h:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1045
Profile2D histograms are used to display the mean value of Z and its error for each cell in X,...
Definition TProfile2D.h:27
static TClass * Class()
This is the base class for the ROOT Random number generators.
Definition TRandom.h:27
Double_t Rndm() override
Machine independent random number generator.
Definition TRandom.cxx:558
Basic string class.
Definition TString.h:138
void ToLower()
Change string to lower-case.
Definition TString.cxx:1189
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition TString.cxx:545
const char * Data() const
Definition TString.h:384
void ToUpper()
Change string to upper case.
Definition TString.cxx:1202
TString & Remove(Ssiz_t pos)
Definition TString.h:693
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:640
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:659
virtual void SetShowProjection(const char *option, Int_t nbins)=0
small helper class to store/restore gPad context in TPad methods
Definition TVirtualPad.h:61
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
TF1 * f1
Definition legend1.C:11
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:251
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition TMath.cxx:637
Bool_t Permute(Int_t n, Int_t *a)
Simple recursive algorithm to find the permutations of n natural numbers, not necessarily all distinc...
Definition TMath.cxx:2560
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Definition TMath.h:913
Double_t Floor(Double_t x)
Rounds x downward, returning the largest integral value that is not greater than x.
Definition TMath.h:691
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:767
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Double_t Mean(Long64_t n, const T *a, const Double_t *w=nullptr)
Returns the weighted mean of an array a with length n.
Definition TMath.h:1176
Double_t KolmogorovProb(Double_t z)
Calculates the Kolmogorov distribution function,.
Definition TMath.cxx:679
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition TMathBase.h:348
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124