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