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