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