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