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