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