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