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