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.
1747///
1748/// The projection is always of the type TH1D.
1749/// The projection is made from the cells along the X axis
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/// NOTE that if a TH1D named "name" exists in the current directory or pad
1761/// the histogram is reset and filled again with the projected contents of the TH3.
1762///
1763/// implemented using Project3D
1764
1767{
1768 // in case of default name append the parent name
1769 TString hname = name;
1770 if (hname == "_px") hname = TString::Format("%s%s", GetName(), name);
1771 TString title = TString::Format("%s ( Projection X )",GetTitle());
1772
1773 // when projecting in Z outer axis are Y and Z (order is important. It is defined in the DoProject1D function)
1774 return DoProject1D(hname, title, iymin, iymax, izmin, izmax, &fXaxis, &fYaxis, &fZaxis, option);
1775}
1776
1777
1778////////////////////////////////////////////////////////////////////////////////
1779/// Project a 3-D histogram into a 1-D histogram along Y.
1780///
1781/// The projection is always of the type TH1D.
1782/// The projection is made from the cells along the Y axis
1783/// ranging from ixmin to ixmax and izmin to izmax included.
1784/// By default, underflow and overflow are included in both the X and Z axis.
1785/// By setting ixmin=1 and ixmax=NbinsX the underflow and/or overflow in X will be excluded
1786/// By setting izmin=1 and izmax=NbinsZ the underflow and/or overflow in Z will be excluded
1787///
1788/// if option "e" is specified, the errors are computed.
1789/// if option "d" is specified, the projection is drawn in the current pad.
1790/// if option "o" original axis range of the target axes will be
1791/// kept, but only bins inside the selected range will be filled.
1792///
1793/// NOTE that if a TH1D named "name" exists in the current directory or pad,
1794/// the histogram is reset and filled again with the projected contents of the TH3.
1795///
1796/// implemented using Project3D
1797
1800{
1801 TString hname = name;
1802 if (hname == "_py") hname = TString::Format("%s%s", GetName(), name);
1803 TString title = TString::Format("%s ( Projection Y )",GetTitle());
1804
1805 // when projecting in Z outer axis are X and Y (order is important. It is defined in the DoProject1D function)
1806 return DoProject1D(hname, title, ixmin, ixmax, izmin, izmax, &fYaxis, &fXaxis, &fZaxis, option);
1807}
1808
1809////////////////////////////////////////////////////////////////////////////////
1810/// Project a 3-D histogram into a 1-D histogram along Z.
1811///
1812/// The projection is always of the type TH1D.
1813/// The projection is made from the cells along the Z axis
1814/// ranging from ixmin to ixmax and iymin to iymax included.
1815/// By default, bins 1 to nx and 1 to ny are included
1816/// By default, underflow and overflow are included in both the X and Y axis.
1817/// By Setting ixmin=1 and ixmax=NbinsX the underflow and/or overflow in X will be excluded
1818/// By setting iymin=1 and/or iymax=NbinsY the underflow and/or overflow in Y will be excluded
1819///
1820/// if option "e" is specified, the errors are computed.
1821/// if option "d" is specified, the projection is drawn in the current pad.
1822/// if option "o" original axis range of the target axes will be
1823/// kept, but only bins inside the selected range will be filled.
1824///
1825/// NOTE that if a TH1D named "name" exists in the current directory or pad,
1826/// the histogram is reset and filled again with the projected contents of the TH3.
1827///
1828/// implemented using Project3D
1829
1832{
1833
1834 TString hname = name;
1835 if (hname == "_pz") hname = TString::Format("%s%s", GetName(), name);
1836 TString title = TString::Format("%s ( Projection Z )",GetTitle());
1837
1838 // when projecting in Z outer axis are X and Y (order is important. It is defined in the DoProject1D function)
1839 return DoProject1D(hname, title, ixmin, ixmax, iymin, iymax, &fZaxis, &fXaxis, &fYaxis, option);
1840}
1841
1842
1843////////////////////////////////////////////////////////////////////////////////
1844/// internal method performing the projection to 1D histogram
1845/// called from TH3::Project3D
1846
1847TH1D *TH3::DoProject1D(const char* name, const char * title, int imin1, int imax1, int imin2, int imax2,
1848 const TAxis* projAxis, const TAxis * axis1, const TAxis * axis2, Option_t * option) const
1849{
1850
1851 TString opt = option;
1852 opt.ToLower();
1853
1854 // save previous axis range and bits
1855 // Int_t iminOld1 = axis1->GetFirst();
1856 // Int_t imaxOld1 = axis1->GetLast();
1857 // Int_t iminOld2 = axis2->GetFirst();
1858 // Int_t imaxOld2 = axis2->GetLast();
1859 // Bool_t hadRange1 = axis1->TestBit(TAxis::kAxisRange);
1860 // Bool_t hadRange2 = axis2->TestBit(TAxis::kAxisRange);
1861
1862 // need to cast-away constness to set range
1863 TAxis out1(*axis1);
1864 TAxis out2(*axis2);
1865 // const_cast<TAxis *>(axis1)->SetRange(imin1, imax1);
1866 // const_cast<TAxis*>(axis2)->SetRange(imin2,imax2);
1867 out1.SetRange(imin1, imax1);
1868 out2.SetRange(imin2, imax2);
1869
1871 if (opt.Contains("e") ) {
1873 opt.Remove(opt.First("e"),1);
1874 }
1876 if (opt.Contains('o') ) {
1878 opt.Remove(opt.First("o"),1);
1879 }
1880
1881 TH1D * h1 = DoProject1D(name, title, projAxis, &out1, &out2, computeErrors, originalRange,true,true);
1882
1883 // // restore original range
1884 // if (axis1->TestBit(TAxis::kAxisRange)) {
1885 // if (hadRange1) const_cast<TAxis*>(axis1)->SetRange(iminOld1,imaxOld1);
1886 // if (axis2->TestBit(TAxis::kAxisRange)) const_cast<TAxis*>(axis2)->SetRange(iminOld2,imaxOld2);
1887 // // we need also to restore the original bits
1888
1889 // draw in current pad
1890 if (h1 && opt.Contains("d")) {
1891 opt.Remove(opt.First("d"),1);
1892 TVirtualPad::TContext ctxt(gROOT->GetSelectedPad(), true, true);
1893 if (!gPad || !gPad->FindObject(h1)) {
1894 h1->Draw(opt);
1895 } else {
1896 h1->Paint(opt);
1897 }
1898 }
1899
1900 return h1;
1901}
1902
1903////////////////////////////////////////////////////////////////////////////////
1904/// internal methdod performing the projection to 1D histogram
1905/// called from other TH3::DoProject1D
1906
1907TH1D *TH3::DoProject1D(const char* name, const char * title, const TAxis* projX,
1908 const TAxis * out1, const TAxis * out2,
1909 bool computeErrors, bool originalRange,
1910 bool useUF, bool useOF) const
1911{
1912 // Create the projection histogram
1913 TH1D *h1 = nullptr;
1914
1915 // Get range to use as well as bin limits
1916 // Projected range must be inside and not outside original one (ROOT-8781)
1917 Int_t ixmin = std::max(projX->GetFirst(),1);
1918 Int_t ixmax = std::min(projX->GetLast(),projX->GetNbins());
1919 Int_t nx = ixmax-ixmin+1;
1920
1921 // Create the histogram, either reseting a preexisting one
1922 TObject *h1obj = gROOT->FindObject(name);
1923 if (h1obj && h1obj->InheritsFrom(TH1::Class())) {
1924 if (h1obj->IsA() != TH1D::Class() ) {
1925 Error("DoProject1D","Histogram with name %s must be a TH1D and is a %s",name,h1obj->ClassName());
1926 return nullptr;
1927 }
1928 h1 = (TH1D*)h1obj;
1929 // reset histogram and re-set the axis in any case
1930 h1->Reset();
1931 const TArrayD *bins = projX->GetXbins();
1932 if ( originalRange )
1933 {
1934 if (bins->fN == 0) {
1935 h1->SetBins(projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
1936 } else {
1937 h1->SetBins(projX->GetNbins(),bins->fArray);
1938 }
1939 } else {
1940 if (bins->fN == 0) {
1941 h1->SetBins(nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
1942 } else {
1943 h1->SetBins(nx,&bins->fArray[ixmin-1]);
1944 }
1945 }
1946 }
1947
1948 if (!h1) {
1949 const TArrayD *bins = projX->GetXbins();
1950 if ( originalRange )
1951 {
1952 if (bins->fN == 0) {
1953 h1 = new TH1D(name,title,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
1954 } else {
1955 h1 = new TH1D(name,title,projX->GetNbins(),bins->fArray);
1956 }
1957 } else {
1958 if (bins->fN == 0) {
1959 h1 = new TH1D(name,title,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
1960 } else {
1961 h1 = new TH1D(name,title,nx,&bins->fArray[ixmin-1]);
1962 }
1963 }
1964 }
1965
1966 // Copy the axis attributes and the axis labels if needed.
1968 THashList* labels = projX->GetLabels();
1969 if (labels) {
1970 TIter iL(labels);
1971 TObjString* lb;
1972 Int_t i = 1;
1973 while ((lb=(TObjString*)iL())) {
1974 h1->GetXaxis()->SetBinLabel(i,lb->String().Data());
1975 i++;
1976 }
1977 }
1978 h1->SetLineColor(this->GetLineColor());
1979 h1->SetFillColor(this->GetFillColor());
1980 h1->SetMarkerColor(this->GetMarkerColor());
1981 h1->SetMarkerStyle(this->GetMarkerStyle());
1982
1983 // Activate errors
1984 if ( computeErrors && (h1->GetSumw2N() != h1->GetNcells() ) ) h1->Sumw2();
1985
1986 // Set references to the axies in case out1 or out2 ar enot provided
1987 // and one can use the histogram axis given projX
1988 if (out1 == nullptr && out2 == nullptr) {
1989 if (projX == GetXaxis()) {
1990 out1 = GetYaxis();
1991 out2 = GetZaxis();
1992 } else if (projX == GetYaxis()) {
1993 out1 = GetXaxis();
1994 out2 = GetZaxis();
1995 } else {
1996 out1 = GetXaxis();
1997 out2 = GetYaxis();
1998 }
1999 }
2000 R__ASSERT(out1 != nullptr && out2 != nullptr);
2001
2002 Int_t *refX = nullptr, *refY = nullptr, *refZ = nullptr;
2004 if (projX == GetXaxis()) {
2005 refX = &ixbin;
2006 refY = &out1bin;
2007 refZ = &out2bin;
2008 }
2009 if (projX == GetYaxis()) {
2010 refX = &out1bin;
2011 refY = &ixbin;
2012 refZ = &out2bin;
2013 }
2014 if (projX == GetZaxis()) {
2015 refX = &out1bin;
2016 refY = &out2bin;
2017 refZ = &ixbin;
2018 }
2019 R__ASSERT (refX != nullptr && refY != nullptr && refZ != nullptr);
2020
2021 // Fill the projected histogram excluding underflow/overflows if considered in the option
2022 // if specified in the option (by default they considered)
2023 Double_t totcont = 0;
2024
2025 Int_t out1min = out1->GetFirst();
2026 Int_t out1max = out1->GetLast();
2027 // GetFirst(), GetLast() can return (0,0) when the range bit is set artificially (see TAxis::SetRange)
2028 //if (out1min == 0 && out1max == 0) { out1min = 1; out1max = out1->GetNbins(); }
2029 // correct for underflow/overflows
2030 if (useUF && !out1->TestBit(TAxis::kAxisRange) ) out1min -= 1;
2031 if (useOF && !out1->TestBit(TAxis::kAxisRange) ) out1max += 1;
2032 Int_t out2min = out2->GetFirst();
2033 Int_t out2max = out2->GetLast();
2034// if (out2min == 0 && out2max == 0) { out2min = 1; out2max = out2->GetNbins(); }
2035 if (useUF && !out2->TestBit(TAxis::kAxisRange) ) out2min -= 1;
2036 if (useOF && !out2->TestBit(TAxis::kAxisRange) ) out2max += 1;
2037
2038 // if the out axis has labels and is extendable, temporary make it non-extendable to avoid adding extra bins
2039 Bool_t extendable = projX->CanExtend();
2040 if ( labels && extendable ) h1->GetXaxis()->SetCanExtend(kFALSE);
2041 for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++) {
2042 if ( projX->TestBit(TAxis::kAxisRange) && ( ixbin < ixmin || ixbin > ixmax )) continue;
2043
2044 Double_t cont = 0;
2045 Double_t err2 = 0;
2046
2047 // loop on the bins to be integrated (outbin should be called inbin)
2048 for (out1bin = out1min; out1bin <= out1max; out1bin++) {
2049 for (out2bin = out2min; out2bin <= out2max; out2bin++) {
2050
2051 Int_t bin = GetBin(*refX, *refY, *refZ);
2052
2053 // sum the bin contents and errors if needed
2054 cont += RetrieveBinContent(bin);
2055 if (computeErrors) {
2056 Double_t exyz = GetBinError(bin);
2057 err2 += exyz*exyz;
2058 }
2059 }
2060 }
2061 Int_t ix = h1->FindBin( projX->GetBinCenter(ixbin) );
2062 h1->SetBinContent(ix ,cont);
2064 // sum all content
2065 totcont += cont;
2066
2067 }
2068 if ( labels ) h1->GetXaxis()->SetCanExtend(extendable);
2069
2070 // since we use a combination of fill and SetBinError we need to reset and recalculate the statistics
2071 // for weighted histograms otherwise sumw2 will be wrong.
2072 // We can keep the original statistics from the TH3 if the projected sumw is consistent with original one
2073 // i.e. when no events are thrown away
2074 bool resetStats = true;
2075 double eps = 1.E-12;
2076 if (IsA() == TH3F::Class() ) eps = 1.E-6;
2077 if (fTsumw != 0 && TMath::Abs( fTsumw - totcont) < TMath::Abs(fTsumw) * eps) resetStats = false;
2078
2079 bool resetEntries = resetStats;
2080 // entries are calculated using underflow/overflow. If excluded entries must be reset
2081 resetEntries |= !useUF || !useOF;
2082
2083
2084 if (!resetStats) {
2085 Double_t stats[kNstat];
2086 GetStats(stats);
2087 if ( projX == GetYaxis() ) {
2088 stats[2] = stats[4];
2089 stats[3] = stats[5];
2090 }
2091 else if ( projX == GetZaxis() ) {
2092 stats[2] = stats[7];
2093 stats[3] = stats[8];
2094 }
2095 h1->PutStats(stats);
2096 }
2097 else {
2098 // reset statistics
2099 h1->ResetStats();
2100 }
2101 if (resetEntries) {
2102 // in case of error calculation (i.e. when Sumw2() is set)
2103 // use the effective entries for the entries
2104 // since this is the only way to estimate them
2105 Double_t entries = TMath::Floor( totcont + 0.5); // to avoid numerical rounding
2106 if (computeErrors) entries = h1->GetEffectiveEntries();
2107 h1->SetEntries( entries );
2108 }
2109 else {
2111 }
2112
2113 return h1;
2114}
2115
2116
2117////////////////////////////////////////////////////////////////////////////////
2118/// internal method performing the projection to a 2D histogram
2119/// called from TH3::Project3D
2120
2121TH2D *TH3::DoProject2D(const char* name, const char * title, const TAxis* projX, const TAxis* projY,
2122 bool computeErrors, bool originalRange,
2123 bool useUF, bool useOF) const
2124{
2125 TH2D *h2 = nullptr;
2126
2127 // Get range to use as well as bin limits
2128 Int_t ixmin = std::max(projX->GetFirst(),1);
2129 Int_t ixmax = std::min(projX->GetLast(),projX->GetNbins());
2130 Int_t iymin = std::max(projY->GetFirst(),1);
2131 Int_t iymax = std::min(projY->GetLast(),projY->GetNbins());
2132
2133 Int_t nx = ixmax-ixmin+1;
2134 Int_t ny = iymax-iymin+1;
2135
2136 // Create the histogram, either reseting a preexisting one
2137 // or creating one from scratch.
2138 // Does an object with the same name exists?
2139 TObject *h2obj = gROOT->FindObject(name);
2140 if (h2obj && h2obj->InheritsFrom(TH1::Class())) {
2141 if ( h2obj->IsA() != TH2D::Class() ) {
2142 Error("DoProject2D","Histogram with name %s must be a TH2D and is a %s",name,h2obj->ClassName());
2143 return nullptr;
2144 }
2145 h2 = (TH2D*)h2obj;
2146 // reset histogram and its axes
2147 h2->Reset();
2148 const TArrayD *xbins = projX->GetXbins();
2149 const TArrayD *ybins = projY->GetXbins();
2150 if ( originalRange ) {
2151 h2->SetBins(projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
2152 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
2153 // set bins for mixed axis do not exists - need to set afterwards the variable bins
2154 if (ybins->fN != 0)
2155 h2->GetXaxis()->Set(projY->GetNbins(),&ybins->fArray[iymin-1]);
2156 if (xbins->fN != 0)
2157 h2->GetYaxis()->Set(projX->GetNbins(),&xbins->fArray[ixmin-1]);
2158 } else {
2159 h2->SetBins(ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
2160 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
2161 if (ybins->fN != 0)
2162 h2->GetXaxis()->Set(ny,&ybins->fArray[iymin-1]);
2163 if (xbins->fN != 0)
2164 h2->GetYaxis()->Set(nx,&xbins->fArray[ixmin-1]);
2165 }
2166 }
2167
2168
2169 if (!h2) {
2170 const TArrayD *xbins = projX->GetXbins();
2171 const TArrayD *ybins = projY->GetXbins();
2172 if ( originalRange )
2173 {
2174 if (xbins->fN == 0 && ybins->fN == 0) {
2175 h2 = new TH2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
2176 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
2177 } else if (ybins->fN == 0) {
2178 h2 = new TH2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
2179 ,projX->GetNbins(),&xbins->fArray[ixmin-1]);
2180 } else if (xbins->fN == 0) {
2181 h2 = new TH2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1]
2182 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
2183 } else {
2184 h2 = new TH2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1],projX->GetNbins(),&xbins->fArray[ixmin-1]);
2185 }
2186 } else {
2187 if (xbins->fN == 0 && ybins->fN == 0) {
2188 h2 = new TH2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
2189 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
2190 } else if (ybins->fN == 0) {
2191 h2 = new TH2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
2192 ,nx,&xbins->fArray[ixmin-1]);
2193 } else if (xbins->fN == 0) {
2194 h2 = new TH2D(name,title,ny,&ybins->fArray[iymin-1]
2195 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
2196 } else {
2197 h2 = new TH2D(name,title,ny,&ybins->fArray[iymin-1],nx,&xbins->fArray[ixmin-1]);
2198 }
2199 }
2200 }
2201
2202 // Copy the axis attributes and the axis labels if needed.
2203 THashList* labels1 = nullptr;
2204 THashList* labels2 = nullptr;
2205 // "xy"
2206 h2->GetXaxis()->ImportAttributes(projY);
2207 h2->GetYaxis()->ImportAttributes(projX);
2208 labels1 = projY->GetLabels();
2209 labels2 = projX->GetLabels();
2210 if (labels1) {
2211 TIter iL(labels1);
2212 TObjString* lb;
2213 Int_t i = 1;
2214 while ((lb=(TObjString*)iL())) {
2215 h2->GetXaxis()->SetBinLabel(i,lb->String().Data());
2216 i++;
2217 }
2218 }
2219 if (labels2) {
2220 TIter iL(labels2);
2221 TObjString* lb;
2222 Int_t i = 1;
2223 while ((lb=(TObjString*)iL())) {
2224 h2->GetYaxis()->SetBinLabel(i,lb->String().Data());
2225 i++;
2226 }
2227 }
2228 h2->SetLineColor(this->GetLineColor());
2229 h2->SetFillColor(this->GetFillColor());
2230 h2->SetMarkerColor(this->GetMarkerColor());
2231 h2->SetMarkerStyle(this->GetMarkerStyle());
2232
2233 // Activate errors
2234 if ( computeErrors && (h2->GetSumw2N() != h2->GetNcells()) ) h2->Sumw2();
2235
2236 // Set references to the axis, so that the bucle has no branches.
2237 const TAxis* out = nullptr;
2238 if ( projX != GetXaxis() && projY != GetXaxis() ) {
2239 out = GetXaxis();
2240 } else if ( projX != GetYaxis() && projY != GetYaxis() ) {
2241 out = GetYaxis();
2242 } else {
2243 out = GetZaxis();
2244 }
2245
2246 Int_t *refX = nullptr, *refY = nullptr, *refZ = nullptr;
2248 if ( projX == GetXaxis() && projY == GetYaxis() ) { refX = &ixbin; refY = &iybin; refZ = &outbin; }
2249 if ( projX == GetYaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &ixbin; refZ = &outbin; }
2250 if ( projX == GetXaxis() && projY == GetZaxis() ) { refX = &ixbin; refY = &outbin; refZ = &iybin; }
2251 if ( projX == GetZaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &outbin; refZ = &ixbin; }
2252 if ( projX == GetYaxis() && projY == GetZaxis() ) { refX = &outbin; refY = &ixbin; refZ = &iybin; }
2253 if ( projX == GetZaxis() && projY == GetYaxis() ) { refX = &outbin; refY = &iybin; refZ = &ixbin; }
2254 R__ASSERT (refX != nullptr && refY != nullptr && refZ != nullptr);
2255
2256 // Fill the projected histogram excluding underflow/overflows if considered in the option
2257 // if specified in the option (by default they considered)
2258 Double_t totcont = 0;
2259
2260 Int_t outmin = out->GetFirst();
2261 Int_t outmax = out->GetLast();
2262 // GetFirst(), GetLast() can return (0,0) when the range bit is set artificially (see TAxis::SetRange)
2263 if (outmin == 0 && outmax == 0) { outmin = 1; outmax = out->GetNbins(); }
2264 // correct for underflow/overflows
2265 if (useUF && !out->TestBit(TAxis::kAxisRange) ) outmin -= 1;
2266 if (useOF && !out->TestBit(TAxis::kAxisRange) ) outmax += 1;
2267
2268 for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++) {
2269 if ( projX->TestBit(TAxis::kAxisRange) && ( ixbin < ixmin || ixbin > ixmax )) continue;
2270 Int_t ix = h2->GetYaxis()->FindBin( projX->GetBinCenter(ixbin) );
2271
2272 for (iybin=0;iybin<=1+projY->GetNbins();iybin++) {
2273 if ( projY->TestBit(TAxis::kAxisRange) && ( iybin < iymin || iybin > iymax )) continue;
2274 Int_t iy = h2->GetXaxis()->FindBin( projY->GetBinCenter(iybin) );
2275
2276 Double_t cont = 0;
2277 Double_t err2 = 0;
2278
2279 // loop on the bins to be integrated (outbin should be called inbin)
2280 for (outbin = outmin; outbin <= outmax; outbin++) {
2281
2282 Int_t bin = GetBin(*refX,*refY,*refZ);
2283
2284 // sum the bin contents and errors if needed
2285 cont += RetrieveBinContent(bin);
2286 if (computeErrors) {
2287 Double_t exyz = GetBinError(bin);
2288 err2 += exyz*exyz;
2289 }
2290
2291 }
2292
2293 // remember axis are inverted
2294 h2->SetBinContent(iy , ix, cont);
2295 if (computeErrors) h2->SetBinError(iy, ix, TMath::Sqrt(err2) );
2296 // sum all content
2297 totcont += cont;
2298
2299 }
2300 }
2301
2302 // since we use fill we need to reset and recalculate the statistics (see comment in DoProject1D )
2303 // or keep original statistics if consistent sumw2
2304 bool resetStats = true;
2305 double eps = 1.E-12;
2306 if (IsA() == TH3F::Class() ) eps = 1.E-6;
2307 if (fTsumw != 0 && TMath::Abs( fTsumw - totcont) < TMath::Abs(fTsumw) * eps) resetStats = false;
2308
2309 bool resetEntries = resetStats;
2310 // entries are calculated using underflow/overflow. If excluded entries must be reset
2311 resetEntries |= !useUF || !useOF;
2312
2313 if (!resetStats) {
2314 Double_t stats[kNstat];
2315 Double_t oldst[kNstat]; // old statistics
2316 for (Int_t i = 0; i < kNstat; ++i) { oldst[i] = 0; }
2317 GetStats(oldst);
2318 std::copy(oldst,oldst+kNstat,stats);
2319 // not that projX refer to Y axis and projX refer to the X axis of projected histogram
2320 // nothing to do for projection in Y vs X
2321 if ( projY == GetXaxis() && projX == GetZaxis() ) { // case XZ
2322 stats[4] = oldst[7];
2323 stats[5] = oldst[8];
2324 stats[6] = oldst[9];
2325 }
2326 if ( projY == GetYaxis() ) {
2327 stats[2] = oldst[4];
2328 stats[3] = oldst[5];
2329 if ( projX == GetXaxis() ) { // case YX
2330 stats[4] = oldst[2];
2331 stats[5] = oldst[3];
2332 }
2333 if ( projX == GetZaxis() ) { // case YZ
2334 stats[4] = oldst[7];
2335 stats[5] = oldst[8];
2336 stats[6] = oldst[10];
2337 }
2338 }
2339 else if ( projY == GetZaxis() ) {
2340 stats[2] = oldst[7];
2341 stats[3] = oldst[8];
2342 if ( projX == GetXaxis() ) { // case ZX
2343 stats[4] = oldst[2];
2344 stats[5] = oldst[3];
2345 stats[6] = oldst[9];
2346 }
2347 if ( projX == GetYaxis() ) { // case ZY
2348 stats[4] = oldst[4];
2349 stats[5] = oldst[5];
2350 stats[6] = oldst[10];
2351 }
2352 }
2353 // set the new statistics
2354 h2->PutStats(stats);
2355 }
2356 else {
2357 // recalculate the statistics
2358 h2->ResetStats();
2359 }
2360
2361 if (resetEntries) {
2362 // use the effective entries for the entries
2363 // since this is the only way to estimate them
2364 Double_t entries = h2->GetEffectiveEntries();
2365 if (!computeErrors) entries = TMath::Floor( entries + 0.5); // to avoid numerical rounding
2366 h2->SetEntries( entries );
2367 }
2368 else {
2369 h2->SetEntries( fEntries );
2370 }
2371
2372
2373 return h2;
2374}
2375
2376
2377////////////////////////////////////////////////////////////////////////////////
2378/// Project a 3-d histogram into 1 or 2-d histograms depending on the
2379/// option parameter, which may contain a combination of the characters x,y,z,e
2380/// - option = "x" return the x projection into a TH1D histogram
2381/// - option = "y" return the y projection into a TH1D histogram
2382/// - option = "z" return the z projection into a TH1D histogram
2383/// - option = "xy" return the x versus y projection into a TH2D histogram
2384/// - option = "yx" return the y versus x projection into a TH2D histogram
2385/// - option = "xz" return the x versus z projection into a TH2D histogram
2386/// - option = "zx" return the z versus x projection into a TH2D histogram
2387/// - option = "yz" return the y versus z projection into a TH2D histogram
2388/// - option = "zy" return the z versus y projection into a TH2D histogram
2389///
2390/// NB: the notation "a vs b" means "a" vertical and "b" horizontal
2391///
2392/// option = "o" original axis range of the target axes will be
2393/// kept, but only bins inside the selected range will be filled.
2394///
2395/// If option contains the string "e", errors are computed
2396///
2397/// The projection is made for the selected bins only.
2398/// To select a bin range along an axis, use TAxis::SetRange, eg
2399/// h3.GetYaxis()->SetRange(23,56);
2400///
2401/// NOTE 1: The generated histogram is named th3name + option
2402/// eg if the TH3* h histogram is named "myhist", then
2403/// h->Project3D("xy"); produces a TH2D histogram named "myhist_xy"
2404/// if a histogram of the same type already exists, it is overwritten.
2405/// The following sequence
2406/// h->Project3D("xy");
2407/// h->Project3D("xy2");
2408/// will generate two TH2D histograms named "myhist_xy" and "myhist_xy2"
2409/// A different name can be generated by attaching a string to the option
2410/// For example h->Project3D("name_xy") will generate an histogram with the name: h3dname_name_xy.
2411///
2412/// NOTE 2: If an histogram of the same type and with the same name already exists in current Directory,
2413/// the histogram is reset and filled again with the projected contents of the TH3.
2414///
2415/// NOTE 3: The number of entries in the projected histogram is estimated from the number of
2416/// effective entries for all the cells included in the projection.
2417///
2418/// NOTE 4: underflow/overflow are included by default in the projection
2419/// To exclude underflow and/or overflow (for both axis in case of a projection to a 1D histogram) use option "NUF" and/or "NOF"
2420/// With SetRange() you can have all bins except underflow/overflow only if you set the axis bit range as
2421/// following after having called SetRange: axis->SetRange(1, axis->GetNbins());
2422///
2423/// NOTE 5: If TH1::AddDirectory is set to false, a new histogram is always created and the ownership of the
2424/// returned pointer is delegated to the user. Be sure in this case to call `delete` on it after it's no longer needed,
2425/// to avoid memory leaks.
2426
2428{
2429 TString opt = option;
2431 Int_t underscore = extra_name.Last('_');
2432 if (underscore > 0) {
2433 extra_name.Remove(underscore,extra_name.Length()-underscore);
2434 opt.Remove(0,underscore+1);
2435 }
2436 opt.ToLower();
2437
2438 Int_t pcase = 0;
2439 TString ptype;
2440 if (opt.Contains("x")) { pcase = 1; ptype = "x"; }
2441 if (opt.Contains("y")) { pcase = 2; ptype = "y"; }
2442 if (opt.Contains("z")) { pcase = 3; ptype = "z"; }
2443 if (opt.Contains("xy")) { pcase = 4; ptype = "xy"; }
2444 if (opt.Contains("yx")) { pcase = 5; ptype = "yx"; }
2445 if (opt.Contains("xz")) { pcase = 6; ptype = "xz"; }
2446 if (opt.Contains("zx")) { pcase = 7; ptype = "zx"; }
2447 if (opt.Contains("yz")) { pcase = 8; ptype = "yz"; }
2448 if (opt.Contains("zy")) { pcase = 9; ptype = "zy"; }
2449
2450 if (pcase == 0) {
2451 Error("Project3D","No projection axis specified - return a NULL pointer");
2452 return nullptr;
2453 }
2454 // do not remove ptype from opt to use later in the projected histo name
2455
2457 if (opt.Contains("e") ) {
2459 opt.Remove(opt.First("e"),1);
2460 }
2461
2462 Bool_t useUF = kTRUE;
2463 Bool_t useOF = kTRUE;
2464 if (opt.Contains("nuf") ) {
2465 useUF = kFALSE;
2466 opt.Remove(opt.Index("nuf"),3);
2467 }
2468 if (opt.Contains("nof") ) {
2469 useOF = kFALSE;
2470 opt.Remove(opt.Index("nof"),3);
2471 }
2472
2474 if (opt.Contains('o') ) {
2476 opt.Remove(opt.First("o"),1);
2477 }
2478
2479
2480 // Create the projection histogram
2481 TH1 *h = nullptr;
2482
2483 TString name = GetName();
2484 TString title = GetTitle();
2485 if (underscore > 0) {
2486 name += "_";
2487 name += extra_name;
2488 }
2489 name += "_"; name += opt;
2490 title += " "; title += ptype; title += " projection";
2491
2492 switch (pcase) {
2493 case 1:
2494 // "x"
2495 h = DoProject1D(name, title, this->GetXaxis(), nullptr, nullptr,
2496 computeErrors, originalRange, useUF, useOF);
2497 break;
2498
2499 case 2:
2500 // "y"
2501 h = DoProject1D(name, title, this->GetYaxis(), nullptr, nullptr,
2502 computeErrors, originalRange, useUF, useOF);
2503 break;
2504
2505 case 3:
2506 // "z"
2507 h = DoProject1D(name, title, this->GetZaxis(), nullptr, nullptr,
2508 computeErrors, originalRange, useUF, useOF);
2509 break;
2510
2511 case 4:
2512 // "xy"
2513 h = DoProject2D(name, title, this->GetXaxis(),this->GetYaxis(),
2514 computeErrors, originalRange, useUF, useOF);
2515 break;
2516
2517 case 5:
2518 // "yx"
2519 h = DoProject2D(name, title, this->GetYaxis(),this->GetXaxis(),
2520 computeErrors, originalRange, useUF, useOF);
2521 break;
2522
2523 case 6:
2524 // "xz"
2525 h = DoProject2D(name, title, this->GetXaxis(),this->GetZaxis(),
2526 computeErrors, originalRange, useUF, useOF);
2527 break;
2528
2529 case 7:
2530 // "zx"
2531 h = DoProject2D(name, title, this->GetZaxis(),this->GetXaxis(),
2532 computeErrors, originalRange, useUF, useOF);
2533 break;
2534
2535 case 8:
2536 // "yz"
2537 h = DoProject2D(name, title, this->GetYaxis(),this->GetZaxis(),
2538 computeErrors, originalRange, useUF, useOF);
2539 break;
2540
2541 case 9:
2542 // "zy"
2543 h = DoProject2D(name, title, this->GetZaxis(),this->GetYaxis(),
2544 computeErrors, originalRange, useUF, useOF);
2545 break;
2546
2547 }
2548
2549 // draw in current pad
2550 if (h && opt.Contains("d")) {
2551 opt.Remove(opt.First("d"),1);
2552 TVirtualPad::TContext ctxt(gROOT->GetSelectedPad(), true, true);
2553 if (!gPad || !gPad->FindObject(h)) {
2554 h->Draw(opt);
2555 } else {
2556 h->Paint(opt);
2557 }
2558 }
2559
2560 return h;
2561}
2562
2563
2564////////////////////////////////////////////////////////////////////////////////
2565/// internal function to fill the bins of the projected profile 2D histogram
2566/// called from DoProjectProfile2D
2567
2569 const TAxis & a1, const TAxis & a2, const TAxis & a3,
2571 Int_t inBin, Bool_t useWeights ) const {
2573 if (!cont) return;
2574 TArrayD & binSumw2 = *(p2->GetBinSumw2());
2575 if (useWeights && binSumw2.fN <= 0) useWeights = false;
2576 if (!useWeights) p2->SetBit(TH1::kIsNotW); // to use Fill for setting the bin contents of the Profile
2577 // the following fill update wrongly the fBinSumw2- need to save it before
2578 Double_t u = a1.GetBinCenter(bin1);
2579 Double_t v = a2.GetBinCenter(bin2);
2580 Double_t w = a3.GetBinCenter(bin3);
2581 Int_t outBin = p2->FindBin(u, v);
2582 if (outBin <0) return;
2583 Double_t tmp = 0;
2584 if ( useWeights ) tmp = binSumw2.fArray[outBin];
2585 p2->Fill( u , v, w, cont);
2586 if (useWeights ) binSumw2.fArray[outBin] = tmp + fSumw2.fArray[inBin];
2587}
2588
2589
2590////////////////////////////////////////////////////////////////////////////////
2591/// internal method to project to a 2D Profile
2592/// called from TH3::Project3DProfile
2593
2594TProfile2D *TH3::DoProjectProfile2D(const char* name, const char * title, const TAxis* projX, const TAxis* projY,
2595 bool originalRange, bool useUF, bool useOF) const
2596{
2597 // Get the ranges where we will work.
2598 Int_t ixmin = std::max(projX->GetFirst(),1);
2599 Int_t ixmax = std::min(projX->GetLast(),projX->GetNbins());
2600 Int_t iymin = std::max(projY->GetFirst(),1);
2601 Int_t iymax = std::min(projY->GetLast(),projY->GetNbins());
2602
2603 Int_t nx = ixmax-ixmin+1;
2604 Int_t ny = iymax-iymin+1;
2605
2606 // Create the projected profiles
2607 TProfile2D *p2 = nullptr;
2608
2609 // Create the histogram, either reseting a preexisting one
2610 // Does an object with the same name exists?
2611 TObject *p2obj = gROOT->FindObject(name);
2612 if (p2obj && p2obj->InheritsFrom(TH1::Class())) {
2613 if (p2obj->IsA() != TProfile2D::Class() ) {
2614 Error("DoProjectProfile2D","Histogram with name %s must be a TProfile2D and is a %s",name,p2obj->ClassName());
2615 return nullptr;
2616 }
2617 p2 = (TProfile2D*)p2obj;
2618 // reset existing profile and re-set bins
2619 p2->Reset();
2620 const TArrayD *xbins = projX->GetXbins();
2621 const TArrayD *ybins = projY->GetXbins();
2622 if ( originalRange ) {
2623 p2->SetBins(projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
2624 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
2625 // set bins for mixed axis do not exists - need to set afterwards the variable bins
2626 if (ybins->fN != 0)
2627 p2->GetXaxis()->Set(projY->GetNbins(),&ybins->fArray[iymin-1]);
2628 if (xbins->fN != 0)
2629 p2->GetYaxis()->Set(projX->GetNbins(),&xbins->fArray[ixmin-1]);
2630 } else {
2631 p2->SetBins(ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
2632 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
2633 if (ybins->fN != 0)
2634 p2->GetXaxis()->Set(ny,&ybins->fArray[iymin-1]);
2635 if (xbins->fN != 0)
2636 p2->GetYaxis()->Set(nx,&xbins->fArray[ixmin-1]);
2637 }
2638 }
2639
2640 if (!p2) {
2641 const TArrayD *xbins = projX->GetXbins();
2642 const TArrayD *ybins = projY->GetXbins();
2643 if ( originalRange ) {
2644 if (xbins->fN == 0 && ybins->fN == 0) {
2645 p2 = new TProfile2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
2646 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
2647 } else if (ybins->fN == 0) {
2648 p2 = new TProfile2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
2649 ,projX->GetNbins(),&xbins->fArray[ixmin-1]);
2650 } else if (xbins->fN == 0) {
2651 p2 = new TProfile2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1]
2652 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
2653 } else {
2654 p2 = new TProfile2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1],projX->GetNbins(),&xbins->fArray[ixmin-1]);
2655 }
2656 } else {
2657 if (xbins->fN == 0 && ybins->fN == 0) {
2658 p2 = new TProfile2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
2659 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
2660 } else if (ybins->fN == 0) {
2661 p2 = new TProfile2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
2662 ,nx,&xbins->fArray[ixmin-1]);
2663 } else if (xbins->fN == 0) {
2664 p2 = new TProfile2D(name,title,ny,&ybins->fArray[iymin-1]
2665 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
2666 } else {
2667 p2 = new TProfile2D(name,title,ny,&ybins->fArray[iymin-1],nx,&xbins->fArray[ixmin-1]);
2668 }
2669 }
2670 }
2671
2672 // Copy the axis attributes and the axis labels if needed
2673 p2->GetXaxis()->ImportAttributes(projY);
2674 p2->GetYaxis()->ImportAttributes(projX);
2675 THashList* labelsX = projY->GetLabels();
2676 if (labelsX) {
2677 TIter iL(labelsX);
2678 TObjString* lb;
2679 Int_t i = 1;
2680 while ((lb=(TObjString*)iL())) {
2681 p2->GetXaxis()->SetBinLabel(i,lb->String().Data());
2682 ++i;
2683 }
2684 }
2685 THashList* labelsY = projX->GetLabels();
2686 if (labelsY) {
2687 TIter iL(labelsY);
2688 TObjString* lb;
2689 Int_t i = 1;
2690 while ((lb=(TObjString*)iL())) {
2691 p2->GetYaxis()->SetBinLabel(i,lb->String().Data());
2692 ++i;
2693 }
2694 }
2695
2696 // Set references to the axis, so that the loop has no branches.
2697 const TAxis* outAxis = nullptr;
2698 if ( projX != GetXaxis() && projY != GetXaxis() ) {
2699 outAxis = GetXaxis();
2700 } else if ( projX != GetYaxis() && projY != GetYaxis() ) {
2701 outAxis = GetYaxis();
2702 } else {
2703 outAxis = GetZaxis();
2704 }
2705
2706 // Weights management
2707 bool useWeights = (GetSumw2N() > 0);
2708 // store sum of w2 in profile if histo is weighted
2709 if (useWeights && (p2->GetBinSumw2()->fN != p2->GetNcells() ) ) p2->Sumw2();
2710
2711 // Set references to the bins, so that the loop has no branches.
2712 Int_t *refX = nullptr, *refY = nullptr, *refZ = nullptr;
2714 if ( projX == GetXaxis() && projY == GetYaxis() ) { refX = &ixbin; refY = &iybin; refZ = &outbin; }
2715 if ( projX == GetYaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &ixbin; refZ = &outbin; }
2716 if ( projX == GetXaxis() && projY == GetZaxis() ) { refX = &ixbin; refY = &outbin; refZ = &iybin; }
2717 if ( projX == GetZaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &outbin; refZ = &ixbin; }
2718 if ( projX == GetYaxis() && projY == GetZaxis() ) { refX = &outbin; refY = &ixbin; refZ = &iybin; }
2719 if ( projX == GetZaxis() && projY == GetYaxis() ) { refX = &outbin; refY = &iybin; refZ = &ixbin; }
2720 R__ASSERT (refX != nullptr && refY != nullptr && refZ != nullptr);
2721
2722 Int_t outmin = outAxis->GetFirst();
2723 Int_t outmax = outAxis->GetLast();
2724 // GetFirst, GetLast can return underflow or overflow bins
2725 // correct for underflow/overflows
2726 if (useUF && !outAxis->TestBit(TAxis::kAxisRange) ) outmin -= 1;
2727 if (useOF && !outAxis->TestBit(TAxis::kAxisRange) ) outmax += 1;
2728
2729 TArrayD & binSumw2 = *(p2->GetBinSumw2());
2730 if (useWeights && binSumw2.fN <= 0) useWeights = false;
2731 if (!useWeights) p2->SetBit(TH1::kIsNotW);
2732
2733 // Call specific method for the projection
2734 for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++) {
2735 if ( (ixbin < ixmin || ixbin > ixmax) && projX->TestBit(TAxis::kAxisRange)) continue;
2736 for ( iybin=0;iybin<=1+projY->GetNbins();iybin++) {
2737 if ( (iybin < iymin || iybin > iymax) && projX->TestBit(TAxis::kAxisRange)) continue;
2738
2739 // profile output bin
2740 Int_t poutBin = p2->FindBin(projY->GetBinCenter(iybin), projX->GetBinCenter(ixbin));
2741 if (poutBin <0) continue;
2742 // loop on the bins to be integrated (outbin should be called inbin)
2743 for (outbin = outmin; outbin <= outmax; outbin++) {
2744
2745 Int_t bin = GetBin(*refX,*refY,*refZ);
2746
2747 //DoFillProfileProjection(p2, *projY, *projX, *outAxis, iybin, ixbin, outbin, bin, useWeights);
2748
2750 if (!cont) continue;
2751
2752 Double_t tmp = 0;
2753 // the following fill update wrongly the fBinSumw2- need to save it before
2754 if ( useWeights ) tmp = binSumw2.fArray[poutBin];
2755 p2->Fill( projY->GetBinCenter(iybin) , projX->GetBinCenter(ixbin), outAxis->GetBinCenter(outbin), cont);
2756 if (useWeights ) binSumw2.fArray[poutBin] = tmp + fSumw2.fArray[bin];
2757
2758 }
2759 }
2760 }
2761
2762 // recompute statistics for the projected profiles
2763 // forget about preserving old statistics
2764 bool resetStats = true;
2765 Double_t stats[kNstat];
2766 // reset statistics
2767 if (resetStats)
2768 for (Int_t i=0;i<kNstat;i++) stats[i] = 0;
2769
2770 p2->PutStats(stats);
2771 Double_t entries = fEntries;
2772 // recalculate the statistics
2773 if (resetStats) {
2774 entries = p2->GetEffectiveEntries();
2775 if (!useWeights) entries = TMath::Floor( entries + 0.5); // to avoid numerical rounding
2776 p2->SetEntries( entries );
2777 }
2778
2779 p2->SetEntries(entries);
2780
2781 return p2;
2782}
2783
2784
2785////////////////////////////////////////////////////////////////////////////////
2786/// Project a 3-d histogram into a 2-d profile histograms depending
2787/// on the option parameter
2788/// option may contain a combination of the characters x,y,z
2789/// option = "xy" return the x versus y projection into a TProfile2D histogram
2790/// option = "yx" return the y versus x projection into a TProfile2D histogram
2791/// option = "xz" return the x versus z projection into a TProfile2D histogram
2792/// option = "zx" return the z versus x projection into a TProfile2D histogram
2793/// option = "yz" return the y versus z projection into a TProfile2D histogram
2794/// option = "zy" return the z versus y projection into a TProfile2D histogram
2795/// NB: the notation "a vs b" means "a" vertical and "b" horizontal
2796///
2797/// option = "o" original axis range of the target axes will be
2798/// kept, but only bins inside the selected range will be filled.
2799///
2800/// The projection is made for the selected bins only.
2801/// To select a bin range along an axis, use TAxis::SetRange, eg
2802/// h3.GetYaxis()->SetRange(23,56);
2803///
2804/// NOTE 1: The generated histogram is named th3name + "_p" + option
2805/// eg if the TH3* h histogram is named "myhist", then
2806/// h->Project3D("xy"); produces a TProfile2D histogram named "myhist_pxy".
2807/// The following sequence
2808/// h->Project3DProfile("xy");
2809/// h->Project3DProfile("xy2");
2810/// will generate two TProfile2D histograms named "myhist_pxy" and "myhist_pxy2"
2811/// So, passing additional characters in the option string one can customize the name.
2812///
2813/// NOTE 2: If a profile of the same type already exists with compatible axes,
2814/// the profile is reset and filled again with the projected contents of the TH3.
2815/// In the case of axes incompatibility, an error is reported and a NULL pointer is returned.
2816///
2817/// NOTE 3: The number of entries in the projected profile is estimated from the number of
2818/// effective entries for all the cells included in the projection.
2819///
2820/// NOTE 4: underflow/overflow are by default excluded from the projection
2821/// (Note that this is a different default behavior compared to the projection to an histogram)
2822/// To include the underflow and/or overflow use option "UF" and/or "OF"
2823
2825{
2826 TString opt = option; opt.ToLower();
2827 Int_t pcase = 0;
2828 TString ptype;
2829 if (opt.Contains("xy")) { pcase = 4; ptype = "xy"; }
2830 if (opt.Contains("yx")) { pcase = 5; ptype = "yx"; }
2831 if (opt.Contains("xz")) { pcase = 6; ptype = "xz"; }
2832 if (opt.Contains("zx")) { pcase = 7; ptype = "zx"; }
2833 if (opt.Contains("yz")) { pcase = 8; ptype = "yz"; }
2834 if (opt.Contains("zy")) { pcase = 9; ptype = "zy"; }
2835
2836 if (pcase == 0) {
2837 Error("Project3D","No projection axis specified - return a NULL pointer");
2838 return nullptr;
2839 }
2840 // do not remove ptype from opt to use later in the projected histo name
2841
2843 if (opt.Contains("uf") ) {
2844 useUF = kTRUE;
2845 opt.Remove(opt.Index("uf"),2);
2846 }
2848 if (opt.Contains("of") ) {
2849 useOF = kTRUE;
2850 opt.Remove(opt.Index("of"),2);
2851 }
2852
2854 if (opt.Contains('o') ) {
2856 opt.Remove(opt.First("o"),1);
2857 }
2858
2859 // Create the projected profile
2860 TProfile2D *p2 = nullptr;
2861 TString name = GetName();
2862 TString title = GetTitle();
2863 name += "_p"; name += opt; // opt may include a user defined name
2864 title += " profile "; title += ptype; title += " projection";
2865
2866 // Call the method with the specific projected axes.
2867 switch (pcase) {
2868 case 4:
2869 // "xy"
2871 break;
2872
2873 case 5:
2874 // "yx"
2876 break;
2877
2878 case 6:
2879 // "xz"
2881 break;
2882
2883 case 7:
2884 // "zx"
2886 break;
2887
2888 case 8:
2889 // "yz"
2891 break;
2892
2893 case 9:
2894 // "zy"
2896 break;
2897
2898 }
2899
2900 return p2;
2901}
2902
2903
2904////////////////////////////////////////////////////////////////////////////////
2905/// Replace current statistics with the values in array stats
2906
2908{
2909 TH1::PutStats(stats);
2910 fTsumwy = stats[4];
2911 fTsumwy2 = stats[5];
2912 fTsumwxy = stats[6];
2913 fTsumwz = stats[7];
2914 fTsumwz2 = stats[8];
2915 fTsumwxz = stats[9];
2916 fTsumwyz = stats[10];
2917}
2918
2919
2920////////////////////////////////////////////////////////////////////////////////
2921/// Rebin only the X axis
2922/// see Rebin3D
2923
2925{
2926 return Rebin3D(ngroup, 1, 1, newname);
2927}
2928
2929
2930////////////////////////////////////////////////////////////////////////////////
2931/// Rebin only the Y axis
2932/// see Rebin3D
2933
2935{
2936 return Rebin3D(1, ngroup, 1, newname);
2937}
2938
2939
2940////////////////////////////////////////////////////////////////////////////////
2941/// Rebin only the Z axis
2942/// see Rebin3D
2943
2945{
2946 return Rebin3D(1, 1, ngroup, newname);
2947
2948}
2949
2950
2951////////////////////////////////////////////////////////////////////////////////
2952/// Rebin this histogram grouping nxgroup/nygroup/nzgroup bins along the xaxis/yaxis/zaxis together.
2953///
2954/// if newname is not blank a new temporary histogram hnew is created.
2955/// else the current histogram is modified (default)
2956/// The parameter nxgroup/nygroup indicate how many bins along the xaxis/yaxis of this
2957/// have to me merged into one bin of hnew
2958/// If the original histogram has errors stored (via Sumw2), the resulting
2959/// histograms has new errors correctly calculated.
2960///
2961/// examples: if hpxpy is an existing TH3 histogram with 40 x 40 x 40 bins
2962/// hpxpypz->Rebin3D(); // merges two bins along the xaxis and yaxis in one in hpxpypz
2963/// // Carefull: previous contents of hpxpy are lost
2964/// hpxpypz->RebinX(5); //merges five bins along the xaxis in one in hpxpypz
2965/// TH3 *hnew = hpxpypz->RebinY(5,"hnew"); // creates a new histogram hnew
2966/// // merging 5 bins of h1 along the yaxis in one bin
2967///
2968/// NOTE : If nxgroup/nygroup is not an exact divider of the number of bins,
2969/// along the xaxis/yaxis the top limit(s) of the rebinned histogram
2970/// is changed to the upper edge of the xbin=newxbins*nxgroup resp.
2971/// ybin=newybins*nygroup and the corresponding bins are added to
2972/// the overflow bin.
2973/// Statistics will be recomputed from the new bin contents.
2974
2976{
2977 Int_t i,j,k,xbin,ybin,zbin;
2985 Double_t zmin = fZaxis.GetXmin();
2986 Double_t zmax = fZaxis.GetXmax();
2987 if ((nxgroup <= 0) || (nxgroup > nxbins)) {
2988 Error("Rebin", "Illegal value of nxgroup=%d",nxgroup);
2989 return nullptr;
2990 }
2991 if ((nygroup <= 0) || (nygroup > nybins)) {
2992 Error("Rebin", "Illegal value of nygroup=%d",nygroup);
2993 return nullptr;
2994 }
2995 if ((nzgroup <= 0) || (nzgroup > nzbins)) {
2996 Error("Rebin", "Illegal value of nzgroup=%d",nzgroup);
2997 return nullptr;
2998 }
2999
3003
3004 // Save old bin contents into a new array
3005 Double_t entries = fEntries;
3007 for (Int_t ibin = 0; ibin < fNcells; ibin++) {
3009 }
3010 Double_t *oldSumw2 = nullptr;
3011 if (fSumw2.fN != 0) {
3012 oldSumw2 = new Double_t[fNcells];
3013 for (Int_t ibin = 0; ibin < fNcells; ibin++) {
3015 }
3016 }
3017
3018 // create a clone of the old histogram if newname is specified
3019 TH3 *hnew = this;
3020 if (newname && strlen(newname)) {
3021 hnew = (TH3*)Clone();
3022 hnew->SetName(newname);
3023 }
3024
3025 // save original statistics
3026 Double_t stat[kNstat];
3027 GetStats(stat);
3028 bool resetStat = false;
3029
3030
3031 // change axis specs and rebuild bin contents array
3032 if (newxbins*nxgroup != nxbins) {
3034 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
3035 }
3036 if (newybins*nygroup != nybins) {
3038 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
3039 }
3040 if (newzbins*nzgroup != nzbins) {
3042 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
3043 }
3044 // save the TAttAxis members (reset by SetBins) for x axis
3056 // save the TAttAxis members (reset by SetBins) for y axis
3068 // save the TAttAxis members (reset by SetBins) for z axis
3080
3081 // copy merged bin contents (ignore under/overflows)
3082 if (nxgroup != 1 || nygroup != 1 || nzgroup != 1) {
3083 if (fXaxis.GetXbins()->GetSize() > 0 || fYaxis.GetXbins()->GetSize() > 0 || fZaxis.GetXbins()->GetSize() > 0) {
3084 // variable bin sizes in x or y, don't treat both cases separately
3085 Double_t *xbins = new Double_t[newxbins+1];
3086 for (i = 0; i <= newxbins; ++i) xbins[i] = fXaxis.GetBinLowEdge(1+i*nxgroup);
3087 Double_t *ybins = new Double_t[newybins+1];
3088 for (i = 0; i <= newybins; ++i) ybins[i] = fYaxis.GetBinLowEdge(1+i*nygroup);
3089 Double_t *zbins = new Double_t[newzbins+1];
3090 for (i = 0; i <= newzbins; ++i) zbins[i] = fZaxis.GetBinLowEdge(1+i*nzgroup);
3091 hnew->SetBins(newxbins,xbins, newybins, ybins, newzbins, zbins);//changes also errors array (if any)
3092 delete [] xbins;
3093 delete [] ybins;
3094 delete [] zbins;
3095 } else {
3096 hnew->SetBins(newxbins, xmin, xmax, newybins, ymin, ymax, newzbins, zmin, zmax);//changes also errors array
3097 }
3098
3100 Int_t oldxbin = 1;
3101 Int_t oldybin = 1;
3102 Int_t oldzbin = 1;
3103 Int_t bin;
3104 for (xbin = 1; xbin <= newxbins; xbin++) {
3105 oldybin=1;
3106 oldzbin=1;
3107 for (ybin = 1; ybin <= newybins; ybin++) {
3108 oldzbin=1;
3109 for (zbin = 1; zbin <= newzbins; zbin++) {
3110 binContent = 0;
3111 binSumw2 = 0;
3112 for (i = 0; i < nxgroup; i++) {
3113 if (oldxbin+i > nxbins) break;
3114 for (j =0; j < nygroup; j++) {
3115 if (oldybin+j > nybins) break;
3116 for (k =0; k < nzgroup; k++) {
3117 if (oldzbin+k > nzbins) break;
3118 //get global bin (same conventions as in TH1::GetBin(xbin,ybin)
3119 bin = oldxbin + i + (oldybin + j)*(nxbins + 2) + (oldzbin + k)*(nxbins + 2)*(nybins + 2);
3120 binContent += oldBins[bin];
3121 if (oldSumw2) binSumw2 += oldSumw2[bin];
3122 }
3123 }
3124 }
3125 Int_t ibin = hnew->GetBin(xbin,ybin,zbin); // new bin number
3126 hnew->SetBinContent(ibin, binContent);
3127 if (oldSumw2) hnew->fSumw2.fArray[ibin] = binSumw2;
3128 oldzbin += nzgroup;
3129 }
3130 oldybin += nygroup;
3131 }
3132 oldxbin += nxgroup;
3133 }
3134
3135 // compute new underflow/overflows for the 8 vertices
3136 for (Int_t xover = 0; xover <= 1; xover++) {
3137 for (Int_t yover = 0; yover <= 1; yover++) {
3138 for (Int_t zover = 0; zover <= 1; zover++) {
3139 binContent = 0;
3140 binSumw2 = 0;
3141 // make loop in case of only underflow/overflow
3142 for (xbin = xover*oldxbin; xbin <= xover*(nxbins+1); xbin++) {
3143 for (ybin = yover*oldybin; ybin <= yover*(nybins+1); ybin++) {
3144 for (zbin = zover*oldzbin; zbin <= zover*(nzbins+1); zbin++) {
3145 bin = GetBin(xbin,ybin,zbin);
3146 binContent += oldBins[bin];
3147 if (oldSumw2) binSumw2 += oldSumw2[bin];
3148 }
3149 }
3150 }
3151 Int_t binNew = hnew->GetBin( xover *(newxbins+1),
3152 yover*(newybins+1), zover*(newzbins+1) );
3153 hnew->SetBinContent(binNew,binContent);
3154 if (oldSumw2) hnew->fSumw2.fArray[binNew] = binSumw2;
3155 }
3156 }
3157 }
3158
3163
3164 // recompute under/overflow contents in y for the new x and z bins
3165 oldxbin2 = 1;
3166 oldybin2 = 1;
3167 oldzbin2 = 1;
3168 for (xbin = 1; xbin<=newxbins; xbin++) {
3169 oldzbin2 = 1;
3170 for (zbin = 1; zbin<=newzbins; zbin++) {
3172 binError0 = binError2 = 0;
3173 for (i=0; i<nxgroup; i++) {
3174 if (oldxbin2+i > nxbins) break;
3175 for (k=0; k<nzgroup; k++) {
3176 if (oldzbin2+k > nzbins) break;
3177 //old underflow bin (in y)
3178 ufbin = oldxbin2 + i + (nxbins+2)*(nybins+2)*(oldzbin2+k);
3181 for (ybin = oldybin; ybin <= nybins + 1; ybin++) {
3182 //old overflow bin (in y)
3183 ofbin = ufbin + ybin*(nxbins+2);
3186 }
3187 }
3188 }
3189 hnew->SetBinContent(xbin,0,zbin,binContent0);
3190 hnew->SetBinContent(xbin,newybins+1,zbin,binContent2);
3191 if (oldSumw2) {
3192 hnew->SetBinError(xbin,0,zbin,TMath::Sqrt(binError0));
3193 hnew->SetBinError(xbin,newybins+1,zbin,TMath::Sqrt(binError2) );
3194 }
3195 oldzbin2 += nzgroup;
3196 }
3197 oldxbin2 += nxgroup;
3198 }
3199
3200 // recompute under/overflow contents in x for the new y and z bins
3201 oldxbin2 = 1;
3202 oldybin2 = 1;
3203 oldzbin2 = 1;
3204 for (ybin = 1; ybin<=newybins; ybin++) {
3205 oldzbin2 = 1;
3206 for (zbin = 1; zbin<=newzbins; zbin++) {
3208 binError0 = binError2 = 0;
3209 for (j=0; j<nygroup; j++) {
3210 if (oldybin2+j > nybins) break;
3211 for (k=0; k<nzgroup; k++) {
3212 if (oldzbin2+k > nzbins) break;
3213 //old underflow bin (in y)
3214 ufbin = (oldybin2 + j)*(nxbins+2) + (nxbins+2)*(nybins+2)*(oldzbin2+k);
3217 for (xbin = oldxbin; xbin <= nxbins + 1; xbin++) {
3218 //old overflow bin (in x)
3219 ofbin = ufbin + xbin;
3222 }
3223 }
3224 }
3225 hnew->SetBinContent(0,ybin,zbin,binContent0);
3226 hnew->SetBinContent(newxbins+1,ybin,zbin,binContent2);
3227 if (oldSumw2) {
3228 hnew->SetBinError(0,ybin,zbin,TMath::Sqrt(binError0));
3229 hnew->SetBinError(newxbins+1,ybin,zbin,TMath::Sqrt(binError2) );
3230 }
3231 oldzbin2 += nzgroup;
3232 }
3233 oldybin2 += nygroup;
3234 }
3235
3236 // recompute under/overflow contents in z for the new x and y bins
3237 oldxbin2 = 1;
3238 oldybin2 = 1;
3239 oldzbin2 = 1;
3240 for (xbin = 1; xbin<=newxbins; xbin++) {
3241 oldybin2 = 1;
3242 for (ybin = 1; ybin<=newybins; ybin++) {
3244 binError0 = binError2 = 0;
3245 for (i=0; i<nxgroup; i++) {
3246 if (oldxbin2+i > nxbins) break;
3247 for (j=0; j<nygroup; j++) {
3248 if (oldybin2+j > nybins) break;
3249 //old underflow bin (in z)
3250 ufbin = oldxbin2 + i + (nxbins+2)*(oldybin2+j);
3253 for (zbin = oldzbin; zbin <= nzbins + 1; zbin++) {
3254 //old overflow bin (in z)
3255 ofbin = ufbin + (nxbins+2)*(nybins+2)*zbin;
3258 }
3259 }
3260 }
3261 hnew->SetBinContent(xbin,ybin,0,binContent0);
3262 hnew->SetBinContent(xbin,ybin,newzbins+1,binContent2);
3263 if (oldSumw2) {
3264 hnew->SetBinError(xbin,ybin,0,TMath::Sqrt(binError0));
3265 hnew->SetBinError(xbin,ybin,newzbins+1,TMath::Sqrt(binError2) );
3266 }
3267 oldybin2 += nygroup;
3268 }
3269 oldxbin2 += nxgroup;
3270 }
3271
3272 // recompute under/overflow contents in y, z for the new x
3273 oldxbin2 = 1;
3274 oldybin2 = 1;
3275 oldzbin2 = 1;
3276 for (xbin = 1; xbin<=newxbins; xbin++) {
3277 binContent0 = 0;
3278 binContent2 = 0;
3279 binContent3 = 0;
3280 binContent4 = 0;
3281 binError0 = 0;
3282 binError2 = 0;
3283 binError3 = 0;
3284 binError4 = 0;
3285 for (i=0; i<nxgroup; i++) {
3286 if (oldxbin2+i > nxbins) break;
3287 ufbin = oldxbin2 + i; //
3290 for (ybin = oldybin; ybin <= nybins + 1; ybin++) {
3291 ofbin3 = ufbin+ybin*(nxbins+2);
3294 for (zbin = oldzbin; zbin <= nzbins + 1; zbin++) {
3295 //old overflow bin (in z)
3296 ofbin4 = oldxbin2 + i + ybin*(nxbins+2) + (nxbins+2)*(nybins+2)*zbin;
3299 }
3300 }
3301 for (zbin = oldzbin; zbin <= nzbins + 1; zbin++) {
3302 ofbin2 = ufbin+zbin*(nxbins+2)*(nybins+2);
3305 }
3306 }
3307 hnew->SetBinContent(xbin,0,0,binContent0);
3308 hnew->SetBinContent(xbin,0,newzbins+1,binContent2);
3309 hnew->SetBinContent(xbin,newybins+1,0,binContent3);
3310 hnew->SetBinContent(xbin,newybins+1,newzbins+1,binContent4);
3311 if (oldSumw2) {
3312 hnew->SetBinError(xbin,0,0,TMath::Sqrt(binError0));
3313 hnew->SetBinError(xbin,0,newzbins+1,TMath::Sqrt(binError2) );
3314 hnew->SetBinError(xbin,newybins+1,0,TMath::Sqrt(binError3) );
3315 hnew->SetBinError(xbin,newybins+1,newzbins+1,TMath::Sqrt(binError4) );
3316 }
3317 oldxbin2 += nxgroup;
3318 }
3319
3320 // recompute under/overflow contents in x, y for the new z
3321 oldxbin2 = 1;
3322 oldybin2 = 1;
3323 oldzbin2 = 1;
3324 for (zbin = 1; zbin<=newzbins; zbin++) {
3325 binContent0 = 0;
3326 binContent2 = 0;
3327 binContent3 = 0;
3328 binContent4 = 0;
3329 binError0 = 0;
3330 binError2 = 0;
3331 binError3 = 0;
3332 binError4 = 0;
3333 for (i=0; i<nzgroup; i++) {
3334 if (oldzbin2+i > nzbins) break;
3335 ufbin = (oldzbin2 + i)*(nxbins+2)*(nybins+2); //
3338 for (ybin = oldybin; ybin <= nybins + 1; ybin++) {
3339 ofbin3 = ufbin+ybin*(nxbins+2);
3342 for (xbin = oldxbin; xbin <= nxbins + 1; xbin++) {
3343 //old overflow bin (in z)
3344 ofbin4 = ufbin + xbin + ybin*(nxbins+2);
3347 }
3348 }
3349 for (xbin = oldxbin; xbin <= nxbins + 1; xbin++) {
3350 ofbin2 = xbin +(oldzbin2+i)*(nxbins+2)*(nybins+2);
3353 }
3354 }
3355 hnew->SetBinContent(0,0,zbin,binContent0);
3356 hnew->SetBinContent(0,newybins+1,zbin,binContent3);
3357 hnew->SetBinContent(newxbins+1,0,zbin,binContent2);
3358 hnew->SetBinContent(newxbins+1,newybins+1,zbin,binContent4);
3359 if (oldSumw2) {
3360 hnew->SetBinError(0,0,zbin,TMath::Sqrt(binError0));
3361 hnew->SetBinError(0,newybins+1,zbin,TMath::Sqrt(binError3) );
3362 hnew->SetBinError(newxbins+1,0,zbin,TMath::Sqrt(binError2) );
3363 hnew->SetBinError(newxbins+1,newybins+1,zbin,TMath::Sqrt(binError4) );
3364 }
3365 oldzbin2 += nzgroup;
3366 }
3367
3368 // recompute under/overflow contents in x, z for the new y
3369 oldxbin2 = 1;
3370 oldybin2 = 1;
3371 oldzbin2 = 1;
3372 for (ybin = 1; ybin<=newybins; ybin++) {
3373 binContent0 = 0;
3374 binContent2 = 0;
3375 binContent3 = 0;
3376 binContent4 = 0;
3377 binError0 = 0;
3378 binError2 = 0;
3379 binError3 = 0;
3380 binError4 = 0;
3381 for (i=0; i<nygroup; i++) {
3382 if (oldybin2+i > nybins) break;
3383 ufbin = (oldybin2 + i)*(nxbins+2); //
3386 for (xbin = oldxbin; xbin <= nxbins + 1; xbin++) {
3387 ofbin3 = ufbin+xbin;
3390 for (zbin = oldzbin; zbin <= nzbins + 1; zbin++) {
3391 //old overflow bin (in z)
3392 ofbin4 = xbin + (nxbins+2)*(nybins+2)*zbin+(oldybin2+i)*(nxbins+2);
3395 }
3396 }
3397 for (zbin = oldzbin; zbin <= nzbins + 1; zbin++) {
3398 ofbin2 = (oldybin2+i)*(nxbins+2)+zbin*(nxbins+2)*(nybins+2);
3401 }
3402 }
3403 hnew->SetBinContent(0,ybin,0,binContent0);
3404 hnew->SetBinContent(0,ybin,newzbins+1,binContent2);
3405 hnew->SetBinContent(newxbins+1,ybin,0,binContent3);
3406 hnew->SetBinContent(newxbins+1,ybin,newzbins+1,binContent4);
3407 if (oldSumw2) {
3408 hnew->SetBinError(0,ybin,0,TMath::Sqrt(binError0));
3409 hnew->SetBinError(0,ybin,newzbins+1,TMath::Sqrt(binError2) );
3410 hnew->SetBinError(newxbins+1,ybin,0,TMath::Sqrt(binError3) );
3411 hnew->SetBinError(newxbins+1,ybin,newzbins+1,TMath::Sqrt(binError4) );
3412 }
3413 oldybin2 += nygroup;
3414 }
3415 }
3416
3417 // Restore x axis attributes
3429 // Restore y axis attributes
3441 // Restore z axis attributes
3453
3454 //restore statistics and entries modified by SetBinContent
3455 hnew->SetEntries(entries);
3456 if (!resetStat) hnew->PutStats(stat);
3457
3458 delete [] oldBins;
3459 if (oldSumw2) delete [] oldSumw2;
3460 return hnew;
3461}
3462
3463
3464////////////////////////////////////////////////////////////////////////////////
3465/// Reset this histogram: contents, errors, etc.
3466
3468{
3470 TString opt = option;
3471 opt.ToUpper();
3472 if (opt.Contains("ICE") && !opt.Contains("S")) return;
3473 fTsumwy = 0;
3474 fTsumwy2 = 0;
3475 fTsumwxy = 0;
3476 fTsumwz = 0;
3477 fTsumwz2 = 0;
3478 fTsumwxz = 0;
3479 fTsumwyz = 0;
3480}
3481
3482
3483////////////////////////////////////////////////////////////////////////////////
3484/// Set bin content.
3485
3487{
3488 fEntries++;
3489 fTsumw = 0;
3490 if (bin < 0) return;
3491 if (bin >= fNcells) return;
3493}
3494
3495
3496////////////////////////////////////////////////////////////////////////////////
3497/// Stream an object of class TH3.
3498
3500{
3501 if (R__b.IsReading()) {
3502 UInt_t R__s, R__c;
3503 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3504 if (R__v > 2) {
3505 R__b.ReadClassBuffer(TH3::Class(), this, R__v, R__s, R__c);
3506 return;
3507 }
3508 //====process old versions before automatic schema evolution
3511 R__b.CheckByteCount(R__s, R__c, TH3::IsA());
3512 //====end of old versions
3513
3514 } else {
3515 R__b.WriteClassBuffer(TH3::Class(),this);
3516 }
3517}
3518
3519////////////////////////////////////////////////////////////////////////////////
3520/// static methdod performing the projection to 1D histogram
3521
3522TH1D *TH3::DoProject1D(const TH3 &h, const char *name, const char *title, const TAxis *projX, bool computeErrors,
3523 bool originalRange, bool useUF, bool useOF)
3524{
3525 return h.DoProject1D(name, title, projX, nullptr, nullptr, computeErrors, originalRange, useUF, useOF);
3526}
3527
3528////////////////////////////////////////////////////////////////////////////////
3529/// static methdod performing the projection to 2D histogram
3530
3531TH2D *TH3::DoProject2D(const TH3 &h, const char *name, const char *title, const TAxis *projX, const TAxis *projY,
3532 bool computeErrors, bool originalRange, bool useUF, bool useOF)
3533{
3534 return h.DoProject2D(name, title, projX, projY, computeErrors, originalRange, useUF, useOF);
3535}
3536
3537//______________________________________________________________________________
3538// TH3C methods
3539// TH3C a 3-D histogram with one byte per cell (char)
3540//______________________________________________________________________________
3541
3542
3543
3544////////////////////////////////////////////////////////////////////////////////
3545/// Constructor.
3546
3548{
3549 SetBinsLength(27);
3550 if (fgDefaultSumw2) Sumw2();
3551}
3552
3553
3554////////////////////////////////////////////////////////////////////////////////
3555/// Destructor.
3556
3558{
3559}
3560
3561
3562////////////////////////////////////////////////////////////////////////////////
3563/// Constructor for fix bin size 3-D histograms
3564/// (see TH3::TH3 for explanation of parameters)
3565
3566TH3C::TH3C(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
3567 ,Int_t nbinsy,Double_t ylow,Double_t yup
3569 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
3570{
3572 if (fgDefaultSumw2) Sumw2();
3573
3574 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
3575}
3576
3577
3578////////////////////////////////////////////////////////////////////////////////
3579/// Constructor for variable bin size 3-D histograms.
3580/// (see TH3::TH3 for explanation of parameters)
3581
3582TH3C::TH3C(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
3583 ,Int_t nbinsy,const Float_t *ybins
3584 ,Int_t nbinsz,const Float_t *zbins)
3585 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
3586{
3588 if (fgDefaultSumw2) Sumw2();
3589}
3590
3591
3592////////////////////////////////////////////////////////////////////////////////
3593/// Constructor for variable bin size 3-D histograms.
3594/// (see TH3::TH3 for explanation of parameters)
3595
3596TH3C::TH3C(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
3597 ,Int_t nbinsy,const Double_t *ybins
3598 ,Int_t nbinsz,const Double_t *zbins)
3599 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
3600{
3602 if (fgDefaultSumw2) Sumw2();
3603}
3604
3605
3606////////////////////////////////////////////////////////////////////////////////
3607/// Copy constructor.
3608/// The list of functions is not copied. (Use Clone() if needed)
3609
3611{
3612 h3c.TH3C::Copy(*this);
3613}
3614
3615
3616////////////////////////////////////////////////////////////////////////////////
3617/// Increment bin content by 1.
3618/// Passing an out-of-range bin leads to undefined behavior
3619
3621{
3622 if (fArray[bin] < 127) fArray[bin]++;
3623}
3624
3625
3626////////////////////////////////////////////////////////////////////////////////
3627/// Increment bin content by w.
3628/// \warning The value of w is cast to `Int_t` before being added.
3629/// Passing an out-of-range bin leads to undefined behavior
3630
3632{
3633 Int_t newval = fArray[bin] + Int_t(w);
3634 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
3635 if (newval < -127) fArray[bin] = -127;
3636 if (newval > 127) fArray[bin] = 127;
3637}
3638
3639
3640////////////////////////////////////////////////////////////////////////////////
3641/// Copy this 3-D histogram structure to newth3.
3642
3644{
3646}
3647
3648
3649////////////////////////////////////////////////////////////////////////////////
3650/// Reset this histogram: contents, errors, etc.
3651
3653{
3656 // should also reset statistics once statistics are implemented for TH3
3657}
3658
3659
3660////////////////////////////////////////////////////////////////////////////////
3661/// Set total number of bins including under/overflow
3662/// Reallocate bin contents array
3663
3665{
3666 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
3667 fNcells = n;
3668 TArrayC::Set(n);
3669}
3670
3671
3672////////////////////////////////////////////////////////////////////////////////
3673/// When the mouse is moved in a pad containing a 3-d view of this histogram
3674/// a second canvas shows a projection type given as option.
3675/// To stop the generation of the projections, delete the canvas
3676/// containing the projection.
3677/// option may contain a combination of the characters x,y,z,e
3678/// option = "x" return the x projection into a TH1D histogram
3679/// option = "y" return the y projection into a TH1D histogram
3680/// option = "z" return the z projection into a TH1D histogram
3681/// option = "xy" return the x versus y projection into a TH2D histogram
3682/// option = "yx" return the y versus x projection into a TH2D histogram
3683/// option = "xz" return the x versus z projection into a TH2D histogram
3684/// option = "zx" return the z versus x projection into a TH2D histogram
3685/// option = "yz" return the y versus z projection into a TH2D histogram
3686/// option = "zy" return the z versus y projection into a TH2D histogram
3687/// option can also include the drawing option for the projection, eg to draw
3688/// the xy projection using the draw option "box" do
3689/// myhist.SetShowProjection("xy box");
3690/// This function is typically called from the context menu.
3691/// NB: the notation "a vs b" means "a" vertical and "b" horizontal
3692
3693void TH3::SetShowProjection(const char *option,Int_t nbins)
3694{
3695 GetPainter();
3696
3698}
3699
3700
3701////////////////////////////////////////////////////////////////////////////////
3702/// Stream an object of class TH3C.
3703
3705{
3706 if (R__b.IsReading()) {
3707 UInt_t R__s, R__c;
3708 if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
3709 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3710 if (R__v > 2) {
3711 R__b.ReadClassBuffer(TH3C::Class(), this, R__v, R__s, R__c);
3712 return;
3713 }
3714 //====process old versions before automatic schema evolution
3715 if (R__v < 2) {
3716 R__b.ReadVersion();
3719 R__b.ReadVersion(&R__s, &R__c);
3721 } else {
3724 R__b.CheckByteCount(R__s, R__c, TH3C::IsA());
3725 }
3726 //====end of old versions
3727
3728 } else {
3729 R__b.WriteClassBuffer(TH3C::Class(),this);
3730 }
3731}
3732
3733
3734////////////////////////////////////////////////////////////////////////////////
3735/// Operator =
3736
3738{
3739 if (this != &h3c)
3740 h3c.TH3C::Copy(*this);
3741 return *this;
3742}
3743
3744
3745////////////////////////////////////////////////////////////////////////////////
3746/// Operator *
3747
3749{
3750 TH3C hnew = h3c;
3751 hnew.Scale(c1);
3752 hnew.SetDirectory(nullptr);
3753 return hnew;
3754}
3755
3756
3757////////////////////////////////////////////////////////////////////////////////
3758/// Operator +
3759
3760TH3C operator+(TH3C const &h1, TH3C const &h2)
3761{
3762 TH3C hnew = h1;
3763 hnew.Add(&h2,1);
3764 hnew.SetDirectory(nullptr);
3765 return hnew;
3766}
3767
3768
3769////////////////////////////////////////////////////////////////////////////////
3770/// Operator -
3771
3772TH3C operator-(TH3C const &h1, TH3C const &h2)
3773{
3774 TH3C hnew = h1;
3775 hnew.Add(&h2,-1);
3776 hnew.SetDirectory(nullptr);
3777 return hnew;
3778}
3779
3780
3781////////////////////////////////////////////////////////////////////////////////
3782/// Operator *
3783
3784TH3C operator*(TH3C const &h1, TH3C const &h2)
3785{
3786 TH3C hnew = h1;
3787 hnew.Multiply(&h2);
3788 hnew.SetDirectory(nullptr);
3789 return hnew;
3790}
3791
3792
3793////////////////////////////////////////////////////////////////////////////////
3794/// Operator /
3795
3796TH3C operator/(TH3C const &h1, TH3C const &h2)
3797{
3798 TH3C hnew = h1;
3799 hnew.Divide(&h2);
3800 hnew.SetDirectory(nullptr);
3801 return hnew;
3802}
3803
3804
3805//______________________________________________________________________________
3806// TH3S methods
3807// TH3S a 3-D histogram with two bytes per cell (short integer)
3808//______________________________________________________________________________
3809
3810
3811
3812////////////////////////////////////////////////////////////////////////////////
3813/// Constructor.
3814
3816{
3817 SetBinsLength(27);
3818 if (fgDefaultSumw2) Sumw2();
3819}
3820
3821
3822////////////////////////////////////////////////////////////////////////////////
3823/// Destructor.
3824
3826{
3827}
3828
3829
3830////////////////////////////////////////////////////////////////////////////////
3831/// Constructor for fix bin size 3-D histograms.
3832/// (see TH3::TH3 for explanation of parameters)
3833
3834TH3S::TH3S(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
3835 ,Int_t nbinsy,Double_t ylow,Double_t yup
3837 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
3838{
3840 if (fgDefaultSumw2) Sumw2();
3841
3842 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
3843}
3844
3845
3846////////////////////////////////////////////////////////////////////////////////
3847/// Constructor for variable bin size 3-D histograms.
3848/// (see TH3::TH3 for explanation of parameters)
3849
3850TH3S::TH3S(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
3851 ,Int_t nbinsy,const Float_t *ybins
3852 ,Int_t nbinsz,const Float_t *zbins)
3853 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
3854{
3856 if (fgDefaultSumw2) Sumw2();
3857}
3858
3859
3860////////////////////////////////////////////////////////////////////////////////
3861/// Constructor for variable bin size 3-D histograms.
3862/// (see TH3::TH3 for explanation of parameters)
3863
3864TH3S::TH3S(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
3865 ,Int_t nbinsy,const Double_t *ybins
3866 ,Int_t nbinsz,const Double_t *zbins)
3867 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
3868{
3870 if (fgDefaultSumw2) Sumw2();
3871}
3872
3873
3874////////////////////////////////////////////////////////////////////////////////
3875/// Copy Constructor.
3876/// The list of functions is not copied. (Use Clone() if needed)
3877
3879{
3880 h3s.TH3S::Copy(*this);
3881}
3882
3883
3884////////////////////////////////////////////////////////////////////////////////
3885/// Increment bin content by 1.
3886/// Passing an out-of-range bin leads to undefined behavior
3887
3889{
3890 if (fArray[bin] < 32767) fArray[bin]++;
3891}
3892
3893
3894////////////////////////////////////////////////////////////////////////////////
3895/// Increment bin content by w.
3896/// \warning The value of w is cast to `Int_t` before being added.
3897/// Passing an out-of-range bin leads to undefined behavior
3898
3900{
3901 Int_t newval = fArray[bin] + Int_t(w);
3902 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
3903 if (newval < -32767) fArray[bin] = -32767;
3904 if (newval > 32767) fArray[bin] = 32767;
3905}
3906
3907
3908////////////////////////////////////////////////////////////////////////////////
3909/// Copy this 3-D histogram structure to newth3.
3910
3912{
3914}
3915
3916
3917////////////////////////////////////////////////////////////////////////////////
3918/// Reset this histogram: contents, errors, etc.
3919
3921{
3924 // should also reset statistics once statistics are implemented for TH3
3925}
3926
3927
3928////////////////////////////////////////////////////////////////////////////////
3929/// Set total number of bins including under/overflow
3930/// Reallocate bin contents array
3931
3933{
3934 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
3935 fNcells = n;
3936 TArrayS::Set(n);
3937}
3938
3939
3940////////////////////////////////////////////////////////////////////////////////
3941/// Stream an object of class TH3S.
3942
3944{
3945 if (R__b.IsReading()) {
3946 UInt_t R__s, R__c;
3947 if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
3948 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3949 if (R__v > 2) {
3950 R__b.ReadClassBuffer(TH3S::Class(), this, R__v, R__s, R__c);
3951 return;
3952 }
3953 //====process old versions before automatic schema evolution
3954 if (R__v < 2) {
3955 R__b.ReadVersion();
3958 R__b.ReadVersion(&R__s, &R__c);
3960 } else {
3963 R__b.CheckByteCount(R__s, R__c, TH3S::IsA());
3964 }
3965 //====end of old versions
3966
3967 } else {
3968 R__b.WriteClassBuffer(TH3S::Class(),this);
3969 }
3970}
3971
3972
3973////////////////////////////////////////////////////////////////////////////////
3974/// Operator =
3975
3977{
3978 if (this != &h3s)
3979 h3s.TH3S::Copy(*this);
3980 return *this;
3981}
3982
3983
3984////////////////////////////////////////////////////////////////////////////////
3985/// Operator *
3986
3988{
3989 TH3S hnew = h3s;
3990 hnew.Scale(c1);
3991 hnew.SetDirectory(nullptr);
3992 return hnew;
3993}
3994
3995
3996////////////////////////////////////////////////////////////////////////////////
3997/// Operator +
3998
3999TH3S operator+(TH3S const &h1, TH3S const &h2)
4000{
4001 TH3S hnew = h1;
4002 hnew.Add(&h2,1);
4003 hnew.SetDirectory(nullptr);
4004 return hnew;
4005}
4006
4007
4008////////////////////////////////////////////////////////////////////////////////
4009/// Operator -
4010
4011TH3S operator-(TH3S const &h1, TH3S const &h2)
4012{
4013 TH3S hnew = h1;
4014 hnew.Add(&h2,-1);
4015 hnew.SetDirectory(nullptr);
4016 return hnew;
4017}
4018
4019
4020////////////////////////////////////////////////////////////////////////////////
4021/// Operator *
4022
4023TH3S operator*(TH3S const &h1, TH3S const &h2)
4024{
4025 TH3S hnew = h1;
4026 hnew.Multiply(&h2);
4027 hnew.SetDirectory(nullptr);
4028 return hnew;
4029}
4030
4031
4032////////////////////////////////////////////////////////////////////////////////
4033/// Operator /
4034
4035TH3S operator/(TH3S const &h1, TH3S const &h2)
4036{
4037 TH3S hnew = h1;
4038 hnew.Divide(&h2);
4039 hnew.SetDirectory(nullptr);
4040 return hnew;
4041}
4042
4043
4044//______________________________________________________________________________
4045// TH3I methods
4046// TH3I a 3-D histogram with four bytes per cell (32 bit integer)
4047//______________________________________________________________________________
4048
4049
4050
4051////////////////////////////////////////////////////////////////////////////////
4052/// Constructor.
4053
4055{
4056 SetBinsLength(27);
4057 if (fgDefaultSumw2) Sumw2();
4058}
4059
4060
4061////////////////////////////////////////////////////////////////////////////////
4062/// Destructor.
4063
4065{
4066}
4067
4068
4069////////////////////////////////////////////////////////////////////////////////
4070/// Constructor for fix bin size 3-D histograms
4071/// (see TH3::TH3 for explanation of parameters)
4072
4073TH3I::TH3I(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
4074 ,Int_t nbinsy,Double_t ylow,Double_t yup
4076 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
4077{
4079 if (fgDefaultSumw2) Sumw2();
4080
4081 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
4082}
4083
4084
4085////////////////////////////////////////////////////////////////////////////////
4086/// Constructor for variable bin size 3-D histograms
4087/// (see TH3::TH3 for explanation of parameters)
4088
4089TH3I::TH3I(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
4090 ,Int_t nbinsy,const Float_t *ybins
4091 ,Int_t nbinsz,const Float_t *zbins)
4092 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4093{
4095 if (fgDefaultSumw2) Sumw2();
4096}
4097
4098
4099////////////////////////////////////////////////////////////////////////////////
4100/// Constructor for variable bin size 3-D histograms
4101/// (see TH3::TH3 for explanation of parameters)
4102
4103TH3I::TH3I(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
4104 ,Int_t nbinsy,const Double_t *ybins
4105 ,Int_t nbinsz,const Double_t *zbins)
4106 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4107{
4109 if (fgDefaultSumw2) Sumw2();
4110}
4111
4112
4113////////////////////////////////////////////////////////////////////////////////
4114/// Copy constructor.
4115/// The list of functions is not copied. (Use Clone() if needed)
4116
4118{
4119 h3i.TH3I::Copy(*this);
4120}
4121
4122
4123////////////////////////////////////////////////////////////////////////////////
4124/// Increment bin content by 1.
4125/// Passing an out-of-range bin leads to undefined behavior
4126
4128{
4129 if (fArray[bin] < INT_MAX) fArray[bin]++;
4130}
4131
4132
4133////////////////////////////////////////////////////////////////////////////////
4134/// Increment bin content by w.
4135/// \warning The value of w is cast to `Long64_t` before being added.
4136/// Passing an out-of-range bin leads to undefined behavior
4137
4139{
4140 Long64_t newval = fArray[bin] + Long64_t(w);
4141 if (newval > -INT_MAX && newval < INT_MAX) {fArray[bin] = Int_t(newval); return;}
4142 if (newval < -INT_MAX) fArray[bin] = -INT_MAX;
4143 if (newval > INT_MAX) fArray[bin] = INT_MAX;
4144}
4145
4146
4147////////////////////////////////////////////////////////////////////////////////
4148/// Copy this 3-D histogram structure to newth3.
4149
4151{
4153}
4154
4155
4156////////////////////////////////////////////////////////////////////////////////
4157/// Reset this histogram: contents, errors, etc.
4158
4160{
4163 // should also reset statistics once statistics are implemented for TH3
4164}
4165
4166
4167////////////////////////////////////////////////////////////////////////////////
4168/// Set total number of bins including under/overflow
4169/// Reallocate bin contents array
4170
4172{
4173 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
4174 fNcells = n;
4175 TArrayI::Set(n);
4176}
4177
4178
4179////////////////////////////////////////////////////////////////////////////////
4180/// Operator =
4181
4183{
4184 if (this != &h3i)
4185 h3i.TH3I::Copy(*this);
4186 return *this;
4187}
4188
4189
4190////////////////////////////////////////////////////////////////////////////////
4191/// Operator *
4192
4194{
4195 TH3I hnew = h3i;
4196 hnew.Scale(c1);
4197 hnew.SetDirectory(nullptr);
4198 return hnew;
4199}
4200
4201
4202////////////////////////////////////////////////////////////////////////////////
4203/// Operator +
4204
4205TH3I operator+(TH3I const &h1, TH3I const &h2)
4206{
4207 TH3I hnew = h1;
4208 hnew.Add(&h2,1);
4209 hnew.SetDirectory(nullptr);
4210 return hnew;
4211}
4212
4213
4214////////////////////////////////////////////////////////////////////////////////
4215/// Operator _
4216
4217TH3I operator-(TH3I const &h1, TH3I const &h2)
4218{
4219 TH3I hnew = h1;
4220 hnew.Add(&h2,-1);
4221 hnew.SetDirectory(nullptr);
4222 return hnew;
4223}
4224
4225
4226////////////////////////////////////////////////////////////////////////////////
4227/// Operator *
4228
4229TH3I operator*(TH3I const &h1, TH3I const &h2)
4230{
4231 TH3I hnew = h1;
4232 hnew.Multiply(&h2);
4233 hnew.SetDirectory(nullptr);
4234 return hnew;
4235}
4236
4237
4238////////////////////////////////////////////////////////////////////////////////
4239/// Operator /
4240
4241TH3I operator/(TH3I const &h1, TH3I const &h2)
4242{
4243 TH3I hnew = h1;
4244 hnew.Divide(&h2);
4245 hnew.SetDirectory(nullptr);
4246 return hnew;
4247}
4248
4249
4250//______________________________________________________________________________
4251// TH3L methods
4252// TH3L a 3-D histogram with eight bytes per cell (64 bit integer)
4253//______________________________________________________________________________
4254
4255
4256
4257////////////////////////////////////////////////////////////////////////////////
4258/// Constructor.
4259
4261{
4262 SetBinsLength(27);
4263 if (fgDefaultSumw2) Sumw2();
4264}
4265
4266
4267////////////////////////////////////////////////////////////////////////////////
4268/// Destructor.
4269
4271{
4272}
4273
4274
4275////////////////////////////////////////////////////////////////////////////////
4276/// Constructor for fix bin size 3-D histograms
4277/// (see TH3::TH3 for explanation of parameters)
4278
4279TH3L::TH3L(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
4280 ,Int_t nbinsy,Double_t ylow,Double_t yup
4282 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
4283{
4285 if (fgDefaultSumw2) Sumw2();
4286
4287 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
4288}
4289
4290
4291////////////////////////////////////////////////////////////////////////////////
4292/// Constructor for variable bin size 3-D histograms
4293/// (see TH3::TH3 for explanation of parameters)
4294
4295TH3L::TH3L(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
4296 ,Int_t nbinsy,const Float_t *ybins
4297 ,Int_t nbinsz,const Float_t *zbins)
4298 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4299{
4301 if (fgDefaultSumw2) Sumw2();
4302}
4303
4304
4305////////////////////////////////////////////////////////////////////////////////
4306/// Constructor for variable bin size 3-D histograms
4307/// (see TH3::TH3 for explanation of parameters)
4308
4309TH3L::TH3L(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
4310 ,Int_t nbinsy,const Double_t *ybins
4311 ,Int_t nbinsz,const Double_t *zbins)
4312 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4313{
4315 if (fgDefaultSumw2) Sumw2();
4316}
4317
4318
4319////////////////////////////////////////////////////////////////////////////////
4320/// Copy constructor.
4321/// The list of functions is not copied. (Use Clone() if needed)
4322
4324{
4325 h3l.TH3L::Copy(*this);
4326}
4327
4328
4329////////////////////////////////////////////////////////////////////////////////
4330/// Increment bin content by 1.
4331/// Passing an out-of-range bin leads to undefined behavior
4332
4334{
4335 if (fArray[bin] < LLONG_MAX) fArray[bin]++;
4336}
4337
4338
4339////////////////////////////////////////////////////////////////////////////////
4340/// Increment bin content by w.
4341/// \warning The value of w is cast to `Long64_t` before being added.
4342/// Passing an out-of-range bin leads to undefined behavior
4343
4345{
4346 Long64_t newval = fArray[bin] + Long64_t(w);
4347 if (newval > -LLONG_MAX && newval < LLONG_MAX) {fArray[bin] = Int_t(newval); return;}
4348 if (newval < -LLONG_MAX) fArray[bin] = -LLONG_MAX;
4349 if (newval > LLONG_MAX) fArray[bin] = LLONG_MAX;
4350}
4351
4352
4353////////////////////////////////////////////////////////////////////////////////
4354/// Copy this 3-D histogram structure to newth3.
4355
4357{
4359}
4360
4361
4362////////////////////////////////////////////////////////////////////////////////
4363/// Reset this histogram: contents, errors, etc.
4364
4366{
4369 // should also reset statistics once statistics are implemented for TH3
4370}
4371
4372
4373////////////////////////////////////////////////////////////////////////////////
4374/// Set total number of bins including under/overflow
4375/// Reallocate bin contents array
4376
4378{
4379 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
4380 fNcells = n;
4382}
4383
4384
4385////////////////////////////////////////////////////////////////////////////////
4386/// Operator =
4387
4389{
4390 if (this != &h3l)
4391 h3l.TH3L::Copy(*this);
4392 return *this;
4393}
4394
4395
4396////////////////////////////////////////////////////////////////////////////////
4397/// Operator *
4398
4400{
4401 TH3L hnew = h3l;
4402 hnew.Scale(c1);
4403 hnew.SetDirectory(nullptr);
4404 return hnew;
4405}
4406
4407
4408////////////////////////////////////////////////////////////////////////////////
4409/// Operator +
4410
4411TH3L operator+(TH3L const &h1, TH3L const &h2)
4412{
4413 TH3L hnew = h1;
4414 hnew.Add(&h2,1);
4415 hnew.SetDirectory(nullptr);
4416 return hnew;
4417}
4418
4419
4420////////////////////////////////////////////////////////////////////////////////
4421/// Operator _
4422
4423TH3L operator-(TH3L const &h1, TH3L const &h2)
4424{
4425 TH3L hnew = h1;
4426 hnew.Add(&h2,-1);
4427 hnew.SetDirectory(nullptr);
4428 return hnew;
4429}
4430
4431
4432////////////////////////////////////////////////////////////////////////////////
4433/// Operator *
4434
4435TH3L operator*(TH3L const &h1, TH3L const &h2)
4436{
4437 TH3L hnew = h1;
4438 hnew.Multiply(&h2);
4439 hnew.SetDirectory(nullptr);
4440 return hnew;
4441}
4442
4443
4444////////////////////////////////////////////////////////////////////////////////
4445/// Operator /
4446
4447TH3L operator/(TH3L const &h1, TH3L const &h2)
4448{
4449 TH3L hnew = h1;
4450 hnew.Divide(&h2);
4451 hnew.SetDirectory(nullptr);
4452 return hnew;
4453}
4454
4455
4456//______________________________________________________________________________
4457// TH3F methods
4458// TH3F a 3-D histogram with four bytes per cell (float). Maximum precision 7 digits, maximum integer bin content = +/-16777216
4459//______________________________________________________________________________
4460
4461
4462
4463////////////////////////////////////////////////////////////////////////////////
4464/// Constructor.
4465
4467{
4468 SetBinsLength(27);
4469 if (fgDefaultSumw2) Sumw2();
4470}
4471
4472
4473////////////////////////////////////////////////////////////////////////////////
4474/// Destructor.
4475
4477{
4478}
4479
4480
4481////////////////////////////////////////////////////////////////////////////////
4482/// Constructor for fix bin size 3-D histograms
4483/// (see TH3::TH3 for explanation of parameters)
4484
4485TH3F::TH3F(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
4486 ,Int_t nbinsy,Double_t ylow,Double_t yup
4488 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
4489{
4491 if (fgDefaultSumw2) Sumw2();
4492
4493 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
4494}
4495
4496
4497////////////////////////////////////////////////////////////////////////////////
4498/// Constructor for variable bin size 3-D histograms
4499/// (see TH3::TH3 for explanation of parameters)
4500
4501TH3F::TH3F(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
4502 ,Int_t nbinsy,const Float_t *ybins
4503 ,Int_t nbinsz,const Float_t *zbins)
4504 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4505{
4507 if (fgDefaultSumw2) Sumw2();
4508}
4509
4510
4511////////////////////////////////////////////////////////////////////////////////
4512/// Constructor for variable bin size 3-D histograms
4513/// (see TH3::TH3 for explanation of parameters)
4514
4515TH3F::TH3F(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
4516 ,Int_t nbinsy,const Double_t *ybins
4517 ,Int_t nbinsz,const Double_t *zbins)
4518 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4519{
4521 if (fgDefaultSumw2) Sumw2();
4522}
4523
4524
4525////////////////////////////////////////////////////////////////////////////////
4526/// Copy constructor.
4527/// The list of functions is not copied. (Use Clone() if needed)
4528
4530{
4531 h3f.TH3F::Copy(*this);
4532}
4533
4534
4535////////////////////////////////////////////////////////////////////////////////
4536/// Copy this 3-D histogram structure to newth3.
4537
4539{
4541}
4542
4543
4544////////////////////////////////////////////////////////////////////////////////
4545/// Reset this histogram: contents, errors, etc.
4546
4548{
4551 // should also reset statistics once statistics are implemented for TH3
4552}
4553
4554
4555////////////////////////////////////////////////////////////////////////////////
4556/// Set total number of bins including under/overflow
4557/// Reallocate bin contents array
4558
4560{
4561 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
4562 fNcells = n;
4563 TArrayF::Set(n);
4564}
4565
4566
4567////////////////////////////////////////////////////////////////////////////////
4568/// Stream an object of class TH3F.
4569
4571{
4572 if (R__b.IsReading()) {
4573 UInt_t R__s, R__c;
4574 if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
4575 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
4576 if (R__v > 2) {
4577 R__b.ReadClassBuffer(TH3F::Class(), this, R__v, R__s, R__c);
4578 return;
4579 }
4580 //====process old versions before automatic schema evolution
4581 if (R__v < 2) {
4582 R__b.ReadVersion();
4585 R__b.ReadVersion(&R__s, &R__c);
4587 } else {
4590 R__b.CheckByteCount(R__s, R__c, TH3F::IsA());
4591 }
4592 //====end of old versions
4593
4594 } else {
4595 R__b.WriteClassBuffer(TH3F::Class(),this);
4596 }
4597}
4598
4599
4600////////////////////////////////////////////////////////////////////////////////
4601/// Operator =
4602
4604{
4605 if (this != &h3f)
4606 h3f.TH3F::Copy(*this);
4607 return *this;
4608}
4609
4610
4611////////////////////////////////////////////////////////////////////////////////
4612/// Operator *
4613
4615{
4616 TH3F hnew = h3f;
4617 hnew.Scale(c1);
4618 hnew.SetDirectory(nullptr);
4619 return hnew;
4620}
4621
4622
4623////////////////////////////////////////////////////////////////////////////////
4624/// Operator +
4625
4626TH3F operator+(TH3F const &h1, TH3F const &h2)
4627{
4628 TH3F hnew = h1;
4629 hnew.Add(&h2,1);
4630 hnew.SetDirectory(nullptr);
4631 return hnew;
4632}
4633
4634
4635////////////////////////////////////////////////////////////////////////////////
4636/// Operator -
4637
4638TH3F operator-(TH3F const &h1, TH3F const &h2)
4639{
4640 TH3F hnew = h1;
4641 hnew.Add(&h2,-1);
4642 hnew.SetDirectory(nullptr);
4643 return hnew;
4644}
4645
4646
4647////////////////////////////////////////////////////////////////////////////////
4648/// Operator *
4649
4650TH3F operator*(TH3F const &h1, TH3F const &h2)
4651{
4652 TH3F hnew = h1;
4653 hnew.Multiply(&h2);
4654 hnew.SetDirectory(nullptr);
4655 return hnew;
4656}
4657
4658
4659////////////////////////////////////////////////////////////////////////////////
4660/// Operator /
4661
4662TH3F operator/(TH3F const &h1, TH3F const &h2)
4663{
4664 TH3F hnew = h1;
4665 hnew.Divide(&h2);
4666 hnew.SetDirectory(nullptr);
4667 return hnew;
4668}
4669
4670
4671//______________________________________________________________________________
4672// TH3D methods
4673// TH3D a 3-D histogram with eight bytes per cell (double). Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992
4674//______________________________________________________________________________
4675
4676
4677
4678////////////////////////////////////////////////////////////////////////////////
4679/// Constructor.
4680
4682{
4683 SetBinsLength(27);
4684 if (fgDefaultSumw2) Sumw2();
4685}
4686
4687
4688////////////////////////////////////////////////////////////////////////////////
4689/// Destructor.
4690
4692{
4693}
4694
4695
4696////////////////////////////////////////////////////////////////////////////////
4697/// Constructor for fix bin size 3-D histograms
4698/// (see TH3::TH3 for explanation of parameters)
4699
4700TH3D::TH3D(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
4701 ,Int_t nbinsy,Double_t ylow,Double_t yup
4703 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
4704{
4706 if (fgDefaultSumw2) Sumw2();
4707
4708 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
4709}
4710
4711
4712////////////////////////////////////////////////////////////////////////////////
4713/// Constructor for variable bin size 3-D histograms
4714/// (see TH3::TH3 for explanation of parameters)
4715
4716TH3D::TH3D(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
4717 ,Int_t nbinsy,const Float_t *ybins
4718 ,Int_t nbinsz,const Float_t *zbins)
4719 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4720{
4722 if (fgDefaultSumw2) Sumw2();
4723}
4724
4725
4726////////////////////////////////////////////////////////////////////////////////
4727/// Constructor for variable bin size 3-D histograms
4728/// (see TH3::TH3 for explanation of parameters)
4729
4730TH3D::TH3D(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
4731 ,Int_t nbinsy,const Double_t *ybins
4732 ,Int_t nbinsz,const Double_t *zbins)
4733 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
4734{
4736 if (fgDefaultSumw2) Sumw2();
4737}
4738
4739
4740////////////////////////////////////////////////////////////////////////////////
4741/// Copy constructor.
4742/// The list of functions is not copied. (Use Clone() if needed)
4743
4745{
4746 // intentially call virtual Copy method to warn if TProfile3D is copied
4747 h3d.Copy(*this);
4748}
4749
4750
4751////////////////////////////////////////////////////////////////////////////////
4752/// Copy this 3-D histogram structure to newth3.
4753
4755{
4757}
4758
4759
4760////////////////////////////////////////////////////////////////////////////////
4761/// Reset this histogram: contents, errors, etc.
4762
4764{
4767 // should also reset statistics once statistics are implemented for TH3
4768}
4769
4770
4771////////////////////////////////////////////////////////////////////////////////
4772/// Set total number of bins including under/overflow
4773/// Reallocate bin contents array
4774
4776{
4777 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
4778 fNcells = n;
4779 TArrayD::Set(n);
4780}
4781
4782
4783////////////////////////////////////////////////////////////////////////////////
4784/// Stream an object of class TH3D.
4785
4787{
4788 if (R__b.IsReading()) {
4789 UInt_t R__s, R__c;
4790 if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
4791 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
4792 if (R__v > 2) {
4793 R__b.ReadClassBuffer(TH3D::Class(), this, R__v, R__s, R__c);
4794 return;
4795 }
4796 //====process old versions before automatic schema evolution
4797 if (R__v < 2) {
4798 R__b.ReadVersion();
4801 R__b.ReadVersion(&R__s, &R__c);
4803 } else {
4806 R__b.CheckByteCount(R__s, R__c, TH3D::IsA());
4807 }
4808 //====end of old versions
4809
4810 } else {
4811 R__b.WriteClassBuffer(TH3D::Class(),this);
4812 }
4813}
4814
4815
4816////////////////////////////////////////////////////////////////////////////////
4817/// Operator =
4818
4820{
4821 // intentially call virtual Copy method to warn if TProfile3D is copied
4822 if (this != &h3d)
4823 h3d.Copy(*this);
4824 return *this;
4825}
4826
4827
4828////////////////////////////////////////////////////////////////////////////////
4829/// Operator *
4830
4832{
4833 TH3D hnew = h3d;
4834 hnew.Scale(c1);
4835 hnew.SetDirectory(nullptr);
4836 return hnew;
4837}
4838
4839
4840////////////////////////////////////////////////////////////////////////////////
4841/// Operator +
4842
4843TH3D operator+(TH3D const &h1, TH3D const &h2)
4844{
4845 TH3D hnew = h1;
4846 hnew.Add(&h2,1);
4847 hnew.SetDirectory(nullptr);
4848 return hnew;
4849}
4850
4851
4852////////////////////////////////////////////////////////////////////////////////
4853/// Operator -
4854
4855TH3D operator-(TH3D const &h1, TH3D const &h2)
4856{
4857 TH3D hnew = h1;
4858 hnew.Add(&h2,-1);
4859 hnew.SetDirectory(nullptr);
4860 return hnew;
4861}
4862
4863
4864////////////////////////////////////////////////////////////////////////////////
4865/// Operator *
4866
4867TH3D operator*(TH3D const &h1, TH3D const &h2)
4868{
4869 TH3D hnew = h1;
4870 hnew.Multiply(&h2);
4871 hnew.SetDirectory(nullptr);
4872 return hnew;
4873}
4874
4875
4876////////////////////////////////////////////////////////////////////////////////
4877/// Operator /
4878
4879TH3D operator/(TH3D const &h1, TH3D const &h2)
4880{
4881 TH3D hnew = h1;
4882 hnew.Divide(&h2);
4883 hnew.SetDirectory(nullptr);
4884 return hnew;
4885}
#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:3772
TH3C operator+(TH3C const &h1, TH3C const &h2)
Operator +.
Definition TH3.cxx:3760
TH3C operator/(TH3C const &h1, TH3C const &h2)
Operator /.
Definition TH3.cxx:3796
TH3C operator*(Float_t c1, TH3C const &h3c)
Operator *.
Definition TH3.cxx:3748
float xmin
int nentries
float ymin
float xmax
float ymax
#define gROOT
Definition TROOT.h:411
R__EXTERN TRandom * gRandom
Definition TRandom.h:62
#define gPad
Array of chars or bytes (8 bits per element).
Definition TArrayC.h:27
void Streamer(TBuffer &) override
Stream a TArrayC object.
Definition TArrayC.cxx:147
Char_t * fArray
Definition TArrayC.h:30
void Reset(Char_t val=0)
Definition TArrayC.h:47
void Set(Int_t n) override
Set size of this array to n chars.
Definition TArrayC.cxx:104
Array of doubles (64 bits per element).
Definition TArrayD.h:27
Double_t * fArray
Definition TArrayD.h:30
void Streamer(TBuffer &) override
Stream a TArrayD object.
Definition TArrayD.cxx:148
void Set(Int_t n) override
Set size of this array to n doubles.
Definition TArrayD.cxx:105
void Reset()
Definition TArrayD.h:47
Array of floats (32 bits per element).
Definition TArrayF.h:27
void Reset()
Definition TArrayF.h:47
void Set(Int_t n) override
Set size of this array to n floats.
Definition TArrayF.cxx:104
void Streamer(TBuffer &) override
Stream a TArrayF object.
Definition TArrayF.cxx:147
Array of integers (32 bits per element).
Definition TArrayI.h:27
Int_t * fArray
Definition TArrayI.h:30
void Set(Int_t n) override
Set size of this array to n ints.
Definition TArrayI.cxx:104
void Reset()
Definition TArrayI.h:47
Array of long64s (64 bits per element).
Definition TArrayL64.h:27
Long64_t * fArray
Definition TArrayL64.h:30
void Set(Int_t n) override
Set size of this array to n long64s.
void Reset()
Definition TArrayL64.h:47
Array of shorts (16 bits per element).
Definition TArrayS.h:27
void Set(Int_t n) override
Set size of this array to n shorts.
Definition TArrayS.cxx:104
void Streamer(TBuffer &) override
Stream a TArrayS object.
Definition TArrayS.cxx:147
void Reset()
Definition TArrayS.h:47
Short_t * fArray
Definition TArrayS.h:30
Int_t fN
Definition TArray.h:38
virtual void Set(Int_t n)=0
virtual void Streamer(TBuffer &)
virtual Color_t GetTitleColor() const
Definition TAttAxis.h:47
virtual Color_t GetLabelColor() const
Definition TAttAxis.h:39
virtual Int_t GetNdivisions() const
Definition TAttAxis.h:37
virtual Color_t GetAxisColor() const
Definition TAttAxis.h:38
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition TAttAxis.cxx:279
virtual Style_t GetTitleFont() const
Definition TAttAxis.h:48
virtual Float_t GetLabelOffset() const
Definition TAttAxis.h:41
virtual void SetAxisColor(Color_t color=1, Float_t alpha=1.)
Set color of the line axis and tick marks.
Definition TAttAxis.cxx:141
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
Definition TAttAxis.cxx:184
virtual Style_t GetLabelFont() const
Definition TAttAxis.h:40
virtual void SetTitleFont(Style_t font=62)
Set the title font.
Definition TAttAxis.cxx:308
virtual void SetLabelOffset(Float_t offset=0.005)
Set distance between the axis and the labels.
Definition TAttAxis.cxx:172
virtual void SetLabelFont(Style_t font=62)
Set labels' font.
Definition TAttAxis.cxx:161
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title.
Definition TAttAxis.cxx:290
virtual void SetTitleColor(Color_t color=1)
Set color of axis title.
Definition TAttAxis.cxx:299
virtual Float_t GetTitleSize() const
Definition TAttAxis.h:45
virtual Float_t GetLabelSize() const
Definition TAttAxis.h:42
virtual Float_t GetTickLength() const
Definition TAttAxis.h:46
virtual Float_t GetTitleOffset() const
Definition TAttAxis.h:44
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length.
Definition TAttAxis.cxx:265
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition TAttAxis.cxx:214
virtual void SetLabelColor(Color_t color=1, Float_t alpha=1.)
Set color of labels.
Definition TAttAxis.cxx:151
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:31
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition TAttFill.h:38
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:35
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:42
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition TAttMarker.h:33
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition TAttMarker.h:39
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:32
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition TAttMarker.h:41
Class to manage histogram axis.
Definition TAxis.h:32
virtual void SetBinLabel(Int_t bin, const char *label)
Set label for bin.
Definition TAxis.cxx:875
Bool_t IsAlphanumeric() const
Definition TAxis.h:90
const char * GetTitle() const override
Returns title of object.
Definition TAxis.h:137
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:481
Bool_t CanExtend() const
Definition TAxis.h:88
const TArrayD * GetXbins() const
Definition TAxis.h:138
void SetCanExtend(Bool_t canExtend)
Definition TAxis.h:92
Double_t GetXmax() const
Definition TAxis.h:142
@ kAxisRange
Definition TAxis.h:66
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:292
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:521
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Definition TAxis.cxx:783
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x
Definition TAxis.cxx:421
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:472
virtual void ImportAttributes(const TAxis *axis)
Copy axis attributes to this.
Definition TAxis.cxx:684
Double_t GetXmin() const
Definition TAxis.h:141
Int_t GetNbins() const
Definition TAxis.h:127
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:545
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:531
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:461
Buffer base class used for serializing objects.
Definition TBuffer.h:43
1-Dim function class
Definition TF1.h:182
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function Note that this histogram is managed ...
Definition TF1.cxx:1611
virtual Double_t GetParError(Int_t ipar) const
Return value of parameter number ipar.
Definition TF1.cxx:1957
Double_t GetChisquare() const
Return the Chisquare after fitting. See ROOT::Fit::FitResult::Chi2()
Definition TF1.h:424
virtual void SetRange(Double_t xmin, Double_t xmax)
Initialize the upper and lower bounds to draw the function.
Definition TF1.cxx:3559
virtual Int_t GetNpar() const
Definition TF1.h:461
virtual Int_t GetNumberFitPoints() const
Definition TF1.h:483
virtual Double_t * GetParameters() const
Definition TF1.h:500
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2306
virtual const char * GetParName(Int_t ipar) const
Definition TF1.h:509
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=nullptr)
Evaluate function with given coordinates and parameters.
Definition TF1.cxx:1475
virtual void SetParameters(const Double_t *params)
Definition TF1.h:633
virtual Double_t GetParameter(Int_t ipar) const
Definition TF1.h:492
A 3-Dim function with parameters.
Definition TF3.h:28
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:927
static TClass * Class()
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:10324
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:574
@ kXaxis
Definition TH1.h:123
@ kAllAxes
Definition TH1.h:126
@ kZaxis
Definition TH1.h:125
@ kYaxis
Definition TH1.h:124
Int_t fNcells
Number of bins(1D), cells (2D) +U/Overflows.
Definition TH1.h:150
void Copy(TObject &hnew) const override
Copy this histogram structure to newth1.
Definition TH1.cxx: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:8018
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:7643
virtual Int_t GetNbinsY() const
Definition TH1.h:543
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:9101
virtual Int_t GetNbinsZ() const
Definition TH1.h:544
virtual Int_t GetDimension() const
Definition TH1.h:528
void Streamer(TBuffer &) override
Stream a class object.
Definition TH1.cxx:6981
@ kIsNotW
Histogram is forced to be not weighted even when the histogram is filled with weighted.
Definition TH1.h:411
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition TH1.cxx:6684
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition TH1.cxx:7151
TAxis * GetXaxis()
Definition TH1.h:572
virtual Int_t GetNcells() const
Definition TH1.h:545
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition TH1.cxx:7920
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:542
Int_t fBufferSize
fBuffer size
Definition TH1.h:168
Int_t fDimension
! Histogram dimension (1, 2 or 3 dim)
Definition TH1.h:171
virtual void SetBinError(Int_t bin, Double_t error)
Set the bin Error Note that this resets the bin eror option to be of Normal Type and for the non-empt...
Definition TH1.cxx:9244
static Int_t fgBufferSize
! Default buffer size for automatic histograms
Definition TH1.h:176
TAxis * GetYaxis()
Definition TH1.h:573
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx: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:8499
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:9260
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:9190
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:7938
@ kNstat
Size of statistics data (up to TProfile3D)
Definition TH1.h:423
Double_t fEntries
Number of entries.
Definition TH1.h:156
TAxis fZaxis
Z axis descriptor.
Definition TH1.h:153
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx: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:563
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
Return Global bin number corresponding to x,y,z.
Definition TH1.cxx:3660
Bool_t GetStatOverflowsBehaviour() const
Definition TH1.h:392
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx: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:8808
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:9061
virtual void SetEntries(Double_t n)
Definition TH1.h:640
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:170
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH3.cxx:3664
TClass * IsA() const override
Definition TH3.h:204
~TH3C() override
Destructor.
Definition TH3.cxx:3557
void Reset(Option_t *option="") override
Reset this histogram: contents, errors, etc.
Definition TH3.cxx:3652
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH3.cxx:3620
TH3C & operator=(const TH3C &h1)
Operator =.
Definition TH3.cxx:3737
TH3C()
Constructor.
Definition TH3.cxx:3547
static TClass * Class()
void Streamer(TBuffer &) override
Stream an object of class TH3C.
Definition TH3.cxx:3704
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:3643
3-D histogram with a double per channel (see TH1 documentation)
Definition TH3.h:418
TClass * IsA() const override
Definition TH3.h:464
TH3D()
Constructor.
Definition TH3.cxx:4681
void Streamer(TBuffer &) override
Stream an object of class TH3D.
Definition TH3.cxx:4786
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:4775
~TH3D() override
Destructor.
Definition TH3.cxx:4691
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:4754
TH3D & operator=(const TH3D &h1)
Operator =.
Definition TH3.cxx:4819
3-D histogram with a float per channel (see TH1 documentation)
Definition TH3.h:363
TH3F & operator=(const TH3F &h1)
Operator =.
Definition TH3.cxx:4603
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH3.cxx:4559
static TClass * Class()
TH3F()
Constructor.
Definition TH3.cxx:4466
~TH3F() override
Destructor.
Definition TH3.cxx:4476
void Streamer(TBuffer &) override
Stream an object of class TH3F.
Definition TH3.cxx:4570
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:4538
TClass * IsA() const override
Definition TH3.h:403
3-D histogram with an int per channel (see TH1 documentation)
Definition TH3.h:267
TH3I & operator=(const TH3I &h1)
Operator =.
Definition TH3.cxx:4182
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH3.cxx:4127
TH3I()
Constructor.
Definition TH3.cxx:4054
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:4150
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH3.cxx:4171
~TH3I() override
Destructor.
Definition TH3.cxx:4064
3-D histogram with a long64 per channel (see TH1 documentation)
Definition TH3.h:316
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:4356
TH3L & operator=(const TH3L &h1)
Operator =.
Definition TH3.cxx:4388
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH3.cxx:4333
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH3.cxx:4377
~TH3L() override
Destructor.
Definition TH3.cxx:4270
TH3L()
Constructor.
Definition TH3.cxx:4260
3-D histogram with a short per channel (see TH1 documentation)
Definition TH3.h:218
void Streamer(TBuffer &) override
Stream an object of class TH3S.
Definition TH3.cxx:3943
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH3.cxx:3932
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH3.cxx:3888
~TH3S() override
Destructor.
Definition TH3.cxx:3825
void Copy(TObject &hnew) const override
Copy this 3-D histogram structure to newth3.
Definition TH3.cxx:3911
TClass * IsA() const override
Definition TH3.h:252
static TClass * Class()
TH3S & operator=(const TH3S &h1)
Operator =.
Definition TH3.cxx:3976
TH3S()
Constructor.
Definition TH3.cxx:3815
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:2975
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
virtual TH2D * DoProject2D(const char *name, const char *title, const TAxis *projX, const TAxis *projY, bool computeErrors, bool originalRange, bool useUF, bool useOF) const
internal method performing the projection to a 2D histogram called from TH3::Project3D
Definition TH3.cxx:2121
Double_t fTsumwxz
Total Sum of weight*X*Z.
Definition TH3.h:48
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.
Definition TH3.cxx:1798
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:3467
~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:2934
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.
Definition TH3.cxx:1830
virtual TH1D * ProjectionX(const char *name="_px", Int_t iymin=0, Int_t iymax=-1, Int_t izmin=0, Int_t izmax=-1, Option_t *option="") const
Project a 3-D histogram into a 1-D histogram along X.
Definition TH3.cxx:1765
virtual TProfile2D * Project3DProfile(Option_t *option="xy") const
Project a 3-d histogram into a 2-d profile histograms depending on the option parameter option may co...
Definition TH3.cxx:2824
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:2427
virtual Double_t GetBinWithContent3(Double_t c, Int_t &binx, Int_t &biny, Int_t &binz, Int_t firstx=0, Int_t lastx=0, Int_t firsty=0, Int_t lasty=0, Int_t firstz=0, Int_t lastz=0, Double_t maxdiff=0) const
Compute first cell (binx,biny,binz) in the range [firstx,lastx](firsty,lasty][firstz,...
Definition TH3.cxx:1167
void DoFillProfileProjection(TProfile2D *p2, const TAxis &a1, const TAxis &a2, const TAxis &a3, Int_t bin1, Int_t bin2, Int_t bin3, Int_t inBin, Bool_t useWeights) const
internal function to fill the bins of the projected profile 2D histogram called from DoProjectProfile...
Definition TH3.cxx:2568
virtual TH3 * RebinZ(Int_t ngroup=2, const char *newname="")
Rebin only the Z axis see Rebin3D.
Definition TH3.cxx:2944
void Streamer(TBuffer &) override
Stream an object of class TH3.
Definition TH3.cxx:3499
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:165
virtual void SetShowProjection(const char *option="xy", Int_t nbins=1)
When the mouse is moved in a pad containing a 3-d view of this histogram a second canvas shows a proj...
Definition TH3.cxx:3693
TH3 * RebinX(Int_t ngroup=2, const char *newname="") override
Rebin only the X axis see Rebin3D.
Definition TH3.cxx:2924
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:1847
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:3486
Double_t fTsumwyz
Total Sum of weight*Y*Z.
Definition TH3.h:49
TH3()
Default constructor.
Definition TH3.cxx:76
Int_t GetBin(Int_t binx, Int_t biny, Int_t binz) const override
See comments in TH1::GetBin.
Definition TH3.cxx:1133
virtual void FitSlicesZ(TF1 *f1=nullptr, Int_t binminx=1, Int_t binmaxx=0, Int_t binminy=1, Int_t binmaxy=0, Int_t cut=0, Option_t *option="QNR")
Project slices along Z in case of a 3-D histogram, then fit each slice with function f1 and make a 2-...
Definition TH3.cxx:994
virtual TProfile2D * DoProjectProfile2D(const char *name, const char *title, const TAxis *projX, const TAxis *projY, bool originalRange, bool useUF, bool useOF) const
internal method to project to a 2D Profile called from TH3::Project3DProfile
Definition TH3.cxx:2594
void PutStats(Double_t *stats) override
Replace current statistics with the values in array stats.
Definition TH3.cxx:2907
static THLimitsFinder * GetLimitsFinder()
Return pointer to the current finder.
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
Collectable string class.
Definition TObjString.h:28
Mother of all ROOT objects.
Definition TObject.h:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1045
Profile2D histograms are used to display the mean value of Z and its error for each cell in X,...
Definition TProfile2D.h:27
static TClass * Class()
This is the base class for the ROOT Random number generators.
Definition TRandom.h:27
Double_t Rndm() override
Machine independent random number generator.
Definition TRandom.cxx:558
Basic string class.
Definition TString.h:138
void ToLower()
Change string to lower-case.
Definition TString.cxx:1189
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition TString.cxx:545
const char * Data() const
Definition TString.h:384
void ToUpper()
Change string to upper case.
Definition TString.cxx:1202
TString & Remove(Ssiz_t pos)
Definition TString.h:693
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:640
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:659
virtual void SetShowProjection(const char *option, Int_t nbins)=0
small helper class to store/restore gPad context in TPad methods
Definition TVirtualPad.h:61
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TH1F * h1
Definition legend1.C:5
TF1 * f1
Definition legend1.C:11
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:251
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition TMath.cxx:637
Bool_t Permute(Int_t n, Int_t *a)
Simple recursive algorithm to find the permutations of n natural numbers, not necessarily all distinc...
Definition TMath.cxx:2560
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Definition TMath.h:913
Double_t Floor(Double_t x)
Rounds x downward, returning the largest integral value that is not greater than x.
Definition TMath.h:691
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:767
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Double_t Mean(Long64_t n, const T *a, const Double_t *w=nullptr)
Returns the weighted mean of an array a with length n.
Definition TMath.h:1176
Double_t KolmogorovProb(Double_t z)
Calculates the Kolmogorov distribution function,.
Definition TMath.cxx:679
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition TMathBase.h:348
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124