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