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