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