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