Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TH1.cxx
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 // Author: Rene Brun 26/12/94
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 <stdlib.h>
13 #include <string.h>
14 #include <stdio.h>
15 #include <ctype.h>
16 #include <sstream>
17 #include <cmath>
18 
19 #include "Riostream.h"
20 #include "TROOT.h"
21 #include "TEnv.h"
22 #include "TClass.h"
23 #include "TMath.h"
24 #include "THashList.h"
25 #include "TH1.h"
26 #include "TH2.h"
27 #include "TH3.h"
28 #include "TF2.h"
29 #include "TF3.h"
30 #include "TPluginManager.h"
31 #include "TVirtualPad.h"
32 #include "TRandom.h"
33 #include "TVirtualFitter.h"
34 #include "THLimitsFinder.h"
35 #include "TProfile.h"
36 #include "TStyle.h"
37 #include "TVectorF.h"
38 #include "TVectorD.h"
39 #include "TBrowser.h"
40 #include "TObjString.h"
41 #include "TError.h"
42 #include "TVirtualHistPainter.h"
43 #include "TVirtualFFT.h"
44 #include "TSystem.h"
45 
46 #include "HFitInterface.h"
47 #include "Fit/DataRange.h"
48 #include "Fit/BinData.h"
49 #include "Math/GoFTest.h"
50 #include "Math/MinimizerOptions.h"
51 #include "Math/QuantFuncMathCore.h"
52 
53 #include "TH1Merger.h"
54 
55 /** \addtogroup Hist
56 @{
57 \class TH1C
58 \brief 1-D histogram with a byte per channel (see TH1 documentation)
59 \class TH1S
60 \brief 1-D histogram with a short per channel (see TH1 documentation)
61 \class TH1I
62 \brief 1-D histogram with an int per channel (see TH1 documentation)}
63 \class TH1F
64 \brief 1-D histogram with a float per channel (see TH1 documentation)}
65 \class TH1D
66 \brief 1-D histogram with a double per channel (see TH1 documentation)}
67 @}
68 */
69 
70 /** \class TH1
71 The TH1 histogram class.
72 
73 ### The Histogram classes
74 ROOT supports the following histogram types:
75 
76  - 1-D histograms:
77  - TH1C : histograms with one byte per channel. Maximum bin content = 127
78  - TH1S : histograms with one short per channel. Maximum bin content = 32767
79  - TH1I : histograms with one int per channel. Maximum bin content = 2147483647
80  - TH1F : histograms with one float per channel. Maximum precision 7 digits
81  - TH1D : histograms with one double per channel. Maximum precision 14 digits
82  - 2-D histograms:
83  - TH2C : histograms with one byte per channel. Maximum bin content = 127
84  - TH2S : histograms with one short per channel. Maximum bin content = 32767
85  - TH2I : histograms with one int per channel. Maximum bin content = 2147483647
86  - TH2F : histograms with one float per channel. Maximum precision 7 digits
87  - TH2D : histograms with one double per channel. Maximum precision 14 digits
88  - 3-D histograms:
89  - TH3C : histograms with one byte per channel. Maximum bin content = 127
90  - TH3S : histograms with one short per channel. Maximum bin content = 32767
91  - TH3I : histograms with one int per channel. Maximum bin content = 2147483647
92  - TH3F : histograms with one float per channel. Maximum precision 7 digits
93  - TH3D : histograms with one double per channel. Maximum precision 14 digits
94  - Profile histograms: See classes TProfile, TProfile2D and TProfile3D.
95  Profile histograms are used to display the mean value of Y and its standard deviation
96  for each bin in X. Profile histograms are in many cases an elegant
97  replacement of two-dimensional histograms : the inter-relation of two
98  measured quantities X and Y can always be visualized by a two-dimensional
99  histogram or scatter-plot; If Y is an unknown (but single-valued)
100  approximate function of X, this function is displayed by a profile
101  histogram with much better precision than by a scatter-plot.
102 
103 
104 All histogram classes are derived from the base class TH1
105 ~~~ {.cpp}
106  TH1
107  ^
108  |
109  |
110  |
111  +----------------+-------+------+------+-----+-----+
112  | | | | | | |
113  | | TH1C TH1S TH1I TH1F TH1D
114  | | |
115  | | |
116  | TH2 TProfile
117  | |
118  | |
119  | +-------+------+------+-----+-----+
120  | | | | | |
121  | TH2C TH2S TH2I TH2F TH2D
122  | |
123  TH3 |
124  | TProfile2D
125  |
126  +-------+------+------+------+------+
127  | | | | |
128  TH3C TH3S TH3I TH3F TH3D
129  |
130  |
131  TProfile3D
132 
133  The TH*C classes also inherit from the array class TArrayC.
134  The TH*S classes also inherit from the array class TArrayS.
135  The TH*I classes also inherit from the array class TArrayI.
136  The TH*F classes also inherit from the array class TArrayF.
137  The TH*D classes also inherit from the array class TArrayD.
138 ~~~
139 
140 #### Creating histograms
141 
142 Histograms are created by invoking one of the constructors, e.g.
143 ~~~ {.cpp}
144  TH1F *h1 = new TH1F("h1", "h1 title", 100, 0, 4.4);
145  TH2F *h2 = new TH2F("h2", "h2 title", 40, 0, 4, 30, -3, 3);
146 ~~~
147 Histograms may also be created by:
148 
149  - calling the Clone function, see below
150  - making a projection from a 2-D or 3-D histogram, see below
151  - reading an histogram from a file
152 
153  When an histogram is created, a reference to it is automatically added
154  to the list of in-memory objects for the current file or directory.
155  This default behaviour can be changed by:
156 ~~~ {.cpp}
157  h->SetDirectory(0); for the current histogram h
158  TH1::AddDirectory(kFALSE); sets a global switch disabling the reference
159 ~~~
160  When the histogram is deleted, the reference to it is removed from
161  the list of objects in memory.
162  When a file is closed, all histograms in memory associated with this file
163  are automatically deleted.
164 
165 #### Fix or variable bin size
166 
167  All histogram types support either fix or variable bin sizes.
168  2-D histograms may have fix size bins along X and variable size bins
169  along Y or vice-versa. The functions to fill, manipulate, draw or access
170  histograms are identical in both cases.
171 
172  Each histogram always contains 3 objects TAxis: fXaxis, fYaxis and fZaxis
173  o access the axis parameters, do:
174 ~~~ {.cpp}
175  TAxis *xaxis = h->GetXaxis(); etc.
176  Double_t binCenter = xaxis->GetBinCenter(bin), etc.
177 ~~~
178  See class TAxis for a description of all the access functions.
179  The axis range is always stored internally in double precision.
180 
181 #### Convention for numbering bins
182 
183  For all histogram types: nbins, xlow, xup
184 ~~~ {.cpp}
185  bin = 0; underflow bin
186  bin = 1; first bin with low-edge xlow INCLUDED
187  bin = nbins; last bin with upper-edge xup EXCLUDED
188  bin = nbins+1; overflow bin
189 ~~~
190  In case of 2-D or 3-D histograms, a "global bin" number is defined.
191  For example, assuming a 3-D histogram with (binx, biny, binz), the function
192 ~~~ {.cpp}
193  Int_t gbin = h->GetBin(binx, biny, binz);
194 ~~~
195  returns a global/linearized gbin number. This global gbin is useful
196  to access the bin content/error information independently of the dimension.
197  Note that to access the information other than bin content and errors
198  one should use the TAxis object directly with e.g.:
199 ~~~ {.cpp}
200  Double_t xcenter = h3->GetZaxis()->GetBinCenter(27);
201 ~~~
202  returns the center along z of bin number 27 (not the global bin)
203  in the 3-D histogram h3.
204 
205 #### Alphanumeric Bin Labels
206 
207  By default, an histogram axis is drawn with its numeric bin labels.
208  One can specify alphanumeric labels instead with:
209 
210  - call TAxis::SetBinLabel(bin, label);
211  This can always be done before or after filling.
212  When the histogram is drawn, bin labels will be automatically drawn.
213  See examples labels1.C and labels2.C
214  - call to a Fill function with one of the arguments being a string, e.g.
215 ~~~ {.cpp}
216  hist1->Fill(somename, weight);
217  hist2->Fill(x, somename, weight);
218  hist2->Fill(somename, y, weight);
219  hist2->Fill(somenamex, somenamey, weight);
220 ~~~
221  See examples hlabels1.C and hlabels2.C
222  - via TTree::Draw. see for example cernstaff.C
223 ~~~ {.cpp}
224  tree.Draw("Nation::Division");
225 ~~~
226  where "Nation" and "Division" are two branches of a Tree.
227 
228 When using the options 2 or 3 above, the labels are automatically
229  added to the list (THashList) of labels for a given axis.
230  By default, an axis is drawn with the order of bins corresponding
231  to the filling sequence. It is possible to reorder the axis
232 
233  - alphabetically
234  - by increasing or decreasing values
235 
236  The reordering can be triggered via the TAxis context menu by selecting
237  the menu item "LabelsOption" or by calling directly
238  TH1::LabelsOption(option, axis) where
239 
240  - axis may be "X", "Y" or "Z"
241  - option may be:
242  - "a" sort by alphabetic order
243  - ">" sort by decreasing values
244  - "<" sort by increasing values
245  - "h" draw labels horizontal
246  - "v" draw labels vertical
247  - "u" draw labels up (end of label right adjusted)
248  - "d" draw labels down (start of label left adjusted)
249 
250  When using the option 2 above, new labels are added by doubling the current
251  number of bins in case one label does not exist yet.
252  When the Filling is terminated, it is possible to trim the number
253  of bins to match the number of active labels by calling
254 ~~~ {.cpp}
255  TH1::LabelsDeflate(axis) with axis = "X", "Y" or "Z"
256 ~~~
257  This operation is automatic when using TTree::Draw.
258  Once bin labels have been created, they become persistent if the histogram
259  is written to a file or when generating the C++ code via SavePrimitive.
260 
261 #### Histograms with automatic bins
262 
263  When an histogram is created with an axis lower limit greater or equal
264  to its upper limit, the SetBuffer is automatically called with an
265  argument fBufferSize equal to fgBufferSize (default value=1000).
266  fgBufferSize may be reset via the static function TH1::SetDefaultBufferSize.
267  The axis limits will be automatically computed when the buffer will
268  be full or when the function BufferEmpty is called.
269 
270 #### Filling histograms
271 
272  An histogram is typically filled with statements like:
273 ~~~ {.cpp}
274  h1->Fill(x);
275  h1->Fill(x, w); //fill with weight
276  h2->Fill(x, y)
277  h2->Fill(x, y, w)
278  h3->Fill(x, y, z)
279  h3->Fill(x, y, z, w)
280 ~~~
281  or via one of the Fill functions accepting names described above.
282  The Fill functions compute the bin number corresponding to the given
283  x, y or z argument and increment this bin by the given weight.
284  The Fill functions return the bin number for 1-D histograms or global
285  bin number for 2-D and 3-D histograms.
286  If TH1::Sumw2 has been called before filling, the sum of squares of
287  weights is also stored.
288  One can also increment directly a bin number via TH1::AddBinContent
289  or replace the existing content via TH1::SetBinContent.
290  To access the bin content of a given bin, do:
291 ~~~ {.cpp}
292  Double_t binContent = h->GetBinContent(bin);
293 ~~~
294 
295  By default, the bin number is computed using the current axis ranges.
296  If the automatic binning option has been set via
297 ~~~ {.cpp}
298  h->SetCanExtend(TH1::kAllAxes);
299 ~~~
300  then, the Fill Function will automatically extend the axis range to
301  accomodate the new value specified in the Fill argument. The method
302  used is to double the bin size until the new value fits in the range,
303  merging bins two by two. This automatic binning options is extensively
304  used by the TTree::Draw function when histogramming Tree variables
305  with an unknown range.
306  This automatic binning option is supported for 1-D, 2-D and 3-D histograms.
307 
308  During filling, some statistics parameters are incremented to compute
309  the mean value and Root Mean Square with the maximum precision.
310 
311  In case of histograms of type TH1C, TH1S, TH2C, TH2S, TH3C, TH3S
312  a check is made that the bin contents do not exceed the maximum positive
313  capacity (127 or 32767). Histograms of all types may have positive
314  or/and negative bin contents.
315 
316 #### Rebinning
317  At any time, an histogram can be rebinned via TH1::Rebin. This function
318  returns a new histogram with the rebinned contents.
319  If bin errors were stored, they are recomputed during the rebinning.
320 
321 #### Associated errors
322  By default, for each bin, the sum of weights is computed at fill time.
323  One can also call TH1::Sumw2 to force the storage and computation
324  of the sum of the square of weights per bin.
325  If Sumw2 has been called, the error per bin is computed as the
326  sqrt(sum of squares of weights), otherwise the error is set equal
327  to the sqrt(bin content).
328  To return the error for a given bin number, do:
329 ~~~ {.cpp}
330  Double_t error = h->GetBinError(bin);
331 ~~~
332 
333 #### Associated functions
334  One or more object (typically a TF1*) can be added to the list
335  of functions (fFunctions) associated to each histogram.
336  When TH1::Fit is invoked, the fitted function is added to this list.
337  Given an histogram h, one can retrieve an associated function
338  with:
339 ~~~ {.cpp}
340  TF1 *myfunc = h->GetFunction("myfunc");
341 ~~~
342 
343 #### Operations on histograms
344 
345  Many types of operations are supported on histograms or between histograms
346 
347  - Addition of an histogram to the current histogram.
348  - Additions of two histograms with coefficients and storage into the current
349  histogram.
350  - Multiplications and Divisions are supported in the same way as additions.
351  - The Add, Divide and Multiply functions also exist to add, divide or multiply
352  an histogram by a function.
353 
354  If an histogram has associated error bars (TH1::Sumw2 has been called),
355  the resulting error bars are also computed assuming independent histograms.
356  In case of divisions, Binomial errors are also supported.
357  One can mark a histogram to be an "average" histogram by setting its bit kIsAverage via
358  myhist.SetBit(TH1::kIsAverage);
359  When adding (see TH1::Add) average histograms, the histograms are averaged and not summed.
360 
361 #### Fitting histograms
362 
363  Histograms (1-D, 2-D, 3-D and Profiles) can be fitted with a user
364  specified function via TH1::Fit. When an histogram is fitted, the
365  resulting function with its parameters is added to the list of functions
366  of this histogram. If the histogram is made persistent, the list of
367  associated functions is also persistent. Given a pointer (see above)
368  to an associated function myfunc, one can retrieve the function/fit
369  parameters with calls such as:
370 ~~~ {.cpp}
371  Double_t chi2 = myfunc->GetChisquare();
372  Double_t par0 = myfunc->GetParameter(0); value of 1st parameter
373  Double_t err0 = myfunc->GetParError(0); error on first parameter
374 ~~~
375 
376 #### Projections of histograms
377 
378  One can:
379 
380  - make a 1-D projection of a 2-D histogram or Profile
381  see functions TH2::ProjectionX,Y, TH2::ProfileX,Y, TProfile::ProjectionX
382  - make a 1-D, 2-D or profile out of a 3-D histogram
383  see functions TH3::ProjectionZ, TH3::Project3D.
384 
385  One can fit these projections via:
386 ~~~ {.cpp}
387  TH2::FitSlicesX,Y, TH3::FitSlicesZ.
388 ~~~
389 
390 #### Random Numbers and histograms
391 
392  TH1::FillRandom can be used to randomly fill an histogram using
393  the contents of an existing TF1 function or another
394  TH1 histogram (for all dimensions).
395  For example the following two statements create and fill an histogram
396  10000 times with a default gaussian distribution of mean 0 and sigma 1:
397 ~~~ {.cpp}
398  TH1F h1("h1", "histo from a gaussian", 100, -3, 3);
399  h1.FillRandom("gaus", 10000);
400 ~~~
401  TH1::GetRandom can be used to return a random number distributed
402  according the contents of an histogram.
403 
404 #### Making a copy of an histogram
405  Like for any other ROOT object derived from TObject, one can use
406  the Clone() function. This makes an identical copy of the original
407  histogram including all associated errors and functions, e.g.:
408 ~~~ {.cpp}
409  TH1F *hnew = (TH1F*)h->Clone("hnew");
410 ~~~
411 
412 #### Normalizing histograms
413 
414  One can scale an histogram such that the bins integral is equal to
415  the normalization parameter via TH1::Scale(Double_t norm), where norm
416  is the desired normalization divided by the integral of the histogram.
417 
418 #### Drawing histograms
419 
420  Histograms are drawn via the THistPainter class. Each histogram has
421  a pointer to its own painter (to be usable in a multithreaded program).
422  Many drawing options are supported.
423  See THistPainter::Paint() for more details.
424 
425  The same histogram can be drawn with different options in different pads.
426  When an histogram drawn in a pad is deleted, the histogram is
427  automatically removed from the pad or pads where it was drawn.
428  If an histogram is drawn in a pad, then filled again, the new status
429  of the histogram will be automatically shown in the pad next time
430  the pad is updated. One does not need to redraw the histogram.
431  To draw the current version of an histogram in a pad, one can use
432 ~~~ {.cpp}
433  h->DrawCopy();
434 ~~~
435  This makes a clone (see Clone below) of the histogram. Once the clone
436  is drawn, the original histogram may be modified or deleted without
437  affecting the aspect of the clone.
438 
439  One can use TH1::SetMaximum() and TH1::SetMinimum() to force a particular
440  value for the maximum or the minimum scale on the plot. (For 1-D
441  histograms this means the y-axis, while for 2-D histograms these
442  functions affect the z-axis).
443 
444  TH1::UseCurrentStyle() can be used to change all histogram graphics
445  attributes to correspond to the current selected style.
446  This function must be called for each histogram.
447  In case one reads and draws many histograms from a file, one can force
448  the histograms to inherit automatically the current graphics style
449  by calling before gROOT->ForceStyle().
450 
451 #### Setting Drawing histogram contour levels (2-D hists only)
452 
453  By default contours are automatically generated at equidistant
454  intervals. A default value of 20 levels is used. This can be modified
455  via TH1::SetContour() or TH1::SetContourLevel().
456  the contours level info is used by the drawing options "cont", "surf",
457  and "lego".
458 
459 #### Setting histogram graphics attributes
460 
461  The histogram classes inherit from the attribute classes:
462  TAttLine, TAttFill, and TAttMarker.
463  See the member functions of these classes for the list of options.
464 
465 #### Giving titles to the X, Y and Z axis
466 
467 ~~~ {.cpp}
468  h->GetXaxis()->SetTitle("X axis title");
469  h->GetYaxis()->SetTitle("Y axis title");
470 ~~~
471  The histogram title and the axis titles can be any TLatex string.
472  The titles are part of the persistent histogram.
473  It is also possible to specify the histogram title and the axis
474  titles at creation time. These titles can be given in the "title"
475  parameter. They must be separated by ";":
476 ~~~ {.cpp}
477  TH1F* h=new TH1F("h", "Histogram title;X Axis;Y Axis;Z Axis", 100, 0, 1);
478 ~~~
479  Any title can be omitted:
480 ~~~ {.cpp}
481  TH1F* h=new TH1F("h", "Histogram title;;Y Axis", 100, 0, 1);
482  TH1F* h=new TH1F("h", ";;Y Axis", 100, 0, 1);
483 ~~~
484  The method SetTitle has the same syntax:
485 ~~~ {.cpp}
486  h->SetTitle("Histogram title;Another X title Axis");
487 ~~~
488 
489 #### Saving/Reading histograms to/from a ROOT file
490 
491  The following statements create a ROOT file and store an histogram
492  on the file. Because TH1 derives from TNamed, the key identifier on
493  the file is the histogram name:
494 ~~~ {.cpp}
495  TFile f("histos.root", "new");
496  TH1F h1("hgaus", "histo from a gaussian", 100, -3, 3);
497  h1.FillRandom("gaus", 10000);
498  h1->Write();
499 ~~~
500  To read this histogram in another Root session, do:
501 ~~~ {.cpp}
502  TFile f("histos.root");
503  TH1F *h = (TH1F*)f.Get("hgaus");
504 ~~~
505  One can save all histograms in memory to the file by:
506 ~~~ {.cpp}
507  file->Write();
508 ~~~
509 
510 #### Miscellaneous operations
511 
512 ~~~ {.cpp}
513  TH1::KolmogorovTest(): statistical test of compatibility in shape
514  between two histograms
515  TH1::Smooth() smooths the bin contents of a 1-d histogram
516  TH1::Integral() returns the integral of bin contents in a given bin range
517  TH1::GetMean(int axis) returns the mean value along axis
518  TH1::GetStdDev(int axis) returns the sigma distribution along axis
519  TH1::GetEntries() returns the number of entries
520  TH1::Reset() resets the bin contents and errors of an histogram
521 ~~~
522 */
523 
524 TF1 *gF1=0; //left for back compatibility (use TVirtualFitter::GetUserFunc instead)
525 
526 Int_t TH1::fgBufferSize = 1000;
527 Bool_t TH1::fgAddDirectory = kTRUE;
528 Bool_t TH1::fgDefaultSumw2 = kFALSE;
529 Bool_t TH1::fgStatOverflows= kFALSE;
530 
531 extern void H1InitGaus();
532 extern void H1InitExpo();
533 extern void H1InitPolynom();
534 extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
535 extern void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail);
536 extern void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b);
537 
538 // Internal exceptions for the CheckConsistency method
539 class DifferentDimension: public std::exception {};
540 class DifferentNumberOfBins: public std::exception {};
541 class DifferentAxisLimits: public std::exception {};
542 class DifferentBinLimits: public std::exception {};
543 class DifferentLabels: public std::exception {};
544 
545 ClassImp(TH1);
546 
547 ////////////////////////////////////////////////////////////////////////////////
548 /// Histogram default constructor.
549 
550 TH1::TH1(): TNamed(), TAttLine(), TAttFill(), TAttMarker()
551 {
552  fDirectory = 0;
553  fFunctions = new TList;
554  fNcells = 0;
555  fIntegral = 0;
556  fPainter = 0;
557  fEntries = 0;
558  fNormFactor = 0;
559  fTsumw = fTsumw2=fTsumwx=fTsumwx2=0;
560  fMaximum = -1111;
561  fMinimum = -1111;
562  fBufferSize = 0;
563  fBuffer = 0;
564  fBinStatErrOpt = kNormal;
565  fStatOverflows = EStatOverflows::kNeutral;
566  fXaxis.SetName("xaxis");
567  fYaxis.SetName("yaxis");
568  fZaxis.SetName("zaxis");
569  fXaxis.SetParent(this);
570  fYaxis.SetParent(this);
571  fZaxis.SetParent(this);
572  UseCurrentStyle();
573 }
574 
575 ////////////////////////////////////////////////////////////////////////////////
576 /// Histogram default destructor.
577 
578 TH1::~TH1()
579 {
580  if (!TestBit(kNotDeleted)) {
581  return;
582  }
583  delete[] fIntegral;
584  fIntegral = 0;
585  delete[] fBuffer;
586  fBuffer = 0;
587  if (fFunctions) {
588  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
589 
590  fFunctions->SetBit(kInvalidObject);
591  TObject* obj = 0;
592  //special logic to support the case where the same object is
593  //added multiple times in fFunctions.
594  //This case happens when the same object is added with different
595  //drawing modes
596  //In the loop below we must be careful with objects (eg TCutG) that may
597  // have been added to the list of functions of several histograms
598  //and may have been already deleted.
599  while ((obj = fFunctions->First())) {
600  while(fFunctions->Remove(obj)) { }
601  if (!obj->TestBit(kNotDeleted)) {
602  break;
603  }
604  delete obj;
605  obj = 0;
606  }
607  delete fFunctions;
608  fFunctions = 0;
609  }
610  if (fDirectory) {
611  fDirectory->Remove(this);
612  fDirectory = 0;
613  }
614  delete fPainter;
615  fPainter = 0;
616 }
617 
618 ////////////////////////////////////////////////////////////////////////////////
619 /// Normal constructor for fix bin size histograms.
620 /// Creates the main histogram structure.
621 ///
622 /// \param[in] name name of histogram (avoid blanks)
623 /// \param[in] title histogram title.
624 /// If title is of the form stringt;stringx;stringy;stringz`
625 /// the histogram title is set to `stringt`,
626 /// the x axis title to `stringy`, the y axis title to `stringy`, etc.
627 /// \param[in] nbins number of bins
628 /// \param[in] xlow low edge of first bin
629 /// \param[in] xup upper edge of last bin (not included in last bin)
630 ///
631 /// When an histogram is created, it is automatically added to the list
632 /// of special objects in the current directory.
633 /// To find the pointer to this histogram in the current directory
634 /// by its name, do:
635 /// ~~~ {.cpp}
636 /// TH1F *h1 = (TH1F*)gDirectory->FindObject(name);
637 /// ~~~
638 
639 TH1::TH1(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
640  :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
641 {
642  Build();
643  if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
644  fXaxis.Set(nbins,xlow,xup);
645  fNcells = fXaxis.GetNbins()+2;
646 }
647 
648 ////////////////////////////////////////////////////////////////////////////////
649 /// Normal constructor for variable bin size histograms.
650 /// Creates the main histogram structure.
651 ///
652 /// \param[in] name name of histogram (avoid blanks)
653 /// \param[in] title histogram title.
654 /// If title is of the form `stringt;stringx;stringy;stringz`
655 /// the histogram title is set to `stringt`,
656 /// the x axis title to `stringy`, the y axis title to `stringy`, etc.
657 /// \param[in] nbins number of bins
658 /// \param[in] xbins array of low-edges for each bin.
659 /// This is an array of size nbins+1
660 
661 TH1::TH1(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
662  :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
663 {
664  Build();
665  if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
666  if (xbins) fXaxis.Set(nbins,xbins);
667  else fXaxis.Set(nbins,0,1);
668  fNcells = fXaxis.GetNbins()+2;
669 }
670 
671 ////////////////////////////////////////////////////////////////////////////////
672 /// Normal constructor for variable bin size histograms.
673 ///
674 /// \param[in] name name of histogram (avoid blanks)
675 /// \param[in] title histogram title.
676 /// If title is of the form `stringt;stringx;stringy;stringz`
677 /// the histogram title is set to `stringt`,
678 /// the x axis title to `stringy`, the y axis title to `stringy`, etc.
679 /// \param[in] nbins number of bins
680 /// \param[in] xbins array of low-edges for each bin.
681 /// This is an array of size nbins+1
682 
683 TH1::TH1(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
684  :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
685 {
686  Build();
687  if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
688  if (xbins) fXaxis.Set(nbins,xbins);
689  else fXaxis.Set(nbins,0,1);
690  fNcells = fXaxis.GetNbins()+2;
691 }
692 
693 ////////////////////////////////////////////////////////////////////////////////
694 /// Copy constructor.
695 /// The list of functions is not copied. (Use Clone if needed)
696 
697 TH1::TH1(const TH1 &h) : TNamed(), TAttLine(), TAttFill(), TAttMarker()
698 {
699  ((TH1&)h).Copy(*this);
700 }
701 
702 ////////////////////////////////////////////////////////////////////////////////
703 /// Static function: cannot be inlined on Windows/NT.
704 
705 Bool_t TH1::AddDirectoryStatus()
706 {
707  return fgAddDirectory;
708 }
709 
710 ////////////////////////////////////////////////////////////////////////////////
711 /// Browse the Histogram object.
712 
713 void TH1::Browse(TBrowser *b)
714 {
715  Draw(b ? b->GetDrawOption() : "");
716  gPad->Update();
717 }
718 
719 ////////////////////////////////////////////////////////////////////////////////
720 /// Creates histogram basic data structure.
721 
722 void TH1::Build()
723 {
724  fDirectory = 0;
725  fPainter = 0;
726  fIntegral = 0;
727  fEntries = 0;
728  fNormFactor = 0;
729  fTsumw = fTsumw2=fTsumwx=fTsumwx2=0;
730  fMaximum = -1111;
731  fMinimum = -1111;
732  fBufferSize = 0;
733  fBuffer = 0;
734  fBinStatErrOpt = kNormal;
735  fStatOverflows = EStatOverflows::kNeutral;
736  fXaxis.SetName("xaxis");
737  fYaxis.SetName("yaxis");
738  fZaxis.SetName("zaxis");
739  fYaxis.Set(1,0.,1.);
740  fZaxis.Set(1,0.,1.);
741  fXaxis.SetParent(this);
742  fYaxis.SetParent(this);
743  fZaxis.SetParent(this);
744 
745  SetTitle(fTitle.Data());
746 
747  fFunctions = new TList;
748 
749  UseCurrentStyle();
750 
751  if (TH1::AddDirectoryStatus()) {
752  fDirectory = gDirectory;
753  if (fDirectory) {
754  fFunctions->UseRWLock();
755  fDirectory->Append(this,kTRUE);
756  }
757  }
758 }
759 
760 ////////////////////////////////////////////////////////////////////////////////
761 /// Performs the operation: `this = this + c1*f1`
762 /// if errors are defined (see TH1::Sumw2), errors are also recalculated.
763 ///
764 /// By default, the function is computed at the centre of the bin.
765 /// if option "I" is specified (1-d histogram only), the integral of the
766 /// function in each bin is used instead of the value of the function at
767 /// the centre of the bin.
768 ///
769 /// Only bins inside the function range are recomputed.
770 ///
771 /// IMPORTANT NOTE: If you intend to use the errors of this histogram later
772 /// you should call Sumw2 before making this operation.
773 /// This is particularly important if you fit the histogram after TH1::Add
774 ///
775 /// The function return kFALSE if the Add operation failed
776 
777 Bool_t TH1::Add(TF1 *f1, Double_t c1, Option_t *option)
778 {
779  if (!f1) {
780  Error("Add","Attempt to add a non-existing function");
781  return kFALSE;
782  }
783 
784  TString opt = option;
785  opt.ToLower();
786  Bool_t integral = kFALSE;
787  if (opt.Contains("i") && fDimension == 1) integral = kTRUE;
788 
789  Int_t ncellsx = GetNbinsX() + 2; // cells = normal bins + underflow bin + overflow bin
790  Int_t ncellsy = GetNbinsY() + 2;
791  Int_t ncellsz = GetNbinsZ() + 2;
792  if (fDimension < 2) ncellsy = 1;
793  if (fDimension < 3) ncellsz = 1;
794 
795  // delete buffer if it is there since it will become invalid
796  if (fBuffer) BufferEmpty(1);
797 
798  // - Add statistics
799  Double_t s1[10];
800  for (Int_t i = 0; i < 10; ++i) s1[i] = 0;
801  PutStats(s1);
802  SetMinimum();
803  SetMaximum();
804 
805  // - Loop on bins (including underflows/overflows)
806  Int_t bin, binx, biny, binz;
807  Double_t cu=0;
808  Double_t xx[3];
809  Double_t *params = 0;
810  f1->InitArgs(xx,params);
811  for (binz = 0; binz < ncellsz; ++binz) {
812  xx[2] = fZaxis.GetBinCenter(binz);
813  for (biny = 0; biny < ncellsy; ++biny) {
814  xx[1] = fYaxis.GetBinCenter(biny);
815  for (binx = 0; binx < ncellsx; ++binx) {
816  xx[0] = fXaxis.GetBinCenter(binx);
817  if (!f1->IsInside(xx)) continue;
818  TF1::RejectPoint(kFALSE);
819  bin = binx + ncellsx * (biny + ncellsy * binz);
820  if (integral) {
821  cu = c1*f1->Integral(fXaxis.GetBinLowEdge(binx), fXaxis.GetBinUpEdge(binx), 0.) / fXaxis.GetBinWidth(binx);
822  } else {
823  cu = c1*f1->EvalPar(xx);
824  }
825  if (TF1::RejectedPoint()) continue;
826  AddBinContent(bin,cu);
827  }
828  }
829  }
830 
831  return kTRUE;
832 }
833 
834 ////////////////////////////////////////////////////////////////////////////////
835 /// Performs the operation: `this = this + c1*h1`
836 /// If errors are defined (see TH1::Sumw2), errors are also recalculated.
837 ///
838 /// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
839 /// if not already set.
840 ///
841 /// Note also that adding histogram with labels is not supported, histogram will be
842 /// added merging them by bin number independently of the labels.
843 /// For adding histogram with labels one should use TH1::Merge
844 ///
845 /// SPECIAL CASE (Average/Efficiency histograms)
846 /// For histograms representing averages or efficiencies, one should compute the average
847 /// of the two histograms and not the sum. One can mark a histogram to be an average
848 /// histogram by setting its bit kIsAverage with
849 /// myhist.SetBit(TH1::kIsAverage);
850 /// Note that the two histograms must have their kIsAverage bit set
851 ///
852 /// IMPORTANT NOTE1: If you intend to use the errors of this histogram later
853 /// you should call Sumw2 before making this operation.
854 /// This is particularly important if you fit the histogram after TH1::Add
855 ///
856 /// IMPORTANT NOTE2: if h1 has a normalisation factor, the normalisation factor
857 /// is used , ie this = this + c1*factor*h1
858 /// Use the other TH1::Add function if you do not want this feature
859 ///
860 /// The function return kFALSE if the Add operation failed
861 
862 Bool_t TH1::Add(const TH1 *h1, Double_t c1)
863 {
864  if (!h1) {
865  Error("Add","Attempt to add a non-existing histogram");
866  return kFALSE;
867  }
868 
869  // delete buffer if it is there since it will become invalid
870  if (fBuffer) BufferEmpty(1);
871 
872  bool useMerge = (c1 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
873  try {
874  CheckConsistency(this,h1);
875  useMerge = kFALSE;
876  } catch(DifferentNumberOfBins&) {
877  if (useMerge)
878  Info("Add","Attempt to add histograms with different number of bins - trying to use TH1::Merge");
879  else {
880  Error("Add","Attempt to add histograms with different number of bins : nbins h1 = %d , nbins h2 = %d",GetNbinsX(), h1->GetNbinsX());
881  return kFALSE;
882  }
883  } catch(DifferentAxisLimits&) {
884  if (useMerge)
885  Info("Add","Attempt to add histograms with different axis limits - trying to use TH1::Merge");
886  else
887  Warning("Add","Attempt to add histograms with different axis limits");
888  } catch(DifferentBinLimits&) {
889  if (useMerge)
890  Info("Add","Attempt to add histograms with different bin limits - trying to use TH1::Merge");
891  else
892  Warning("Add","Attempt to add histograms with different bin limits");
893  } catch(DifferentLabels&) {
894  // in case of different labels -
895  if (useMerge)
896  Info("Add","Attempt to add histograms with different labels - trying to use TH1::Merge");
897  else
898  Info("Warning","Attempt to add histograms with different labels");
899  }
900 
901  if (useMerge) {
902  TList l;
903  l.Add(const_cast<TH1*>(h1));
904  auto iret = Merge(&l);
905  return (iret >= 0);
906  }
907 
908  // Create Sumw2 if h1 has Sumw2 set
909  if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
910 
911  // - Add statistics
912  Double_t entries = TMath::Abs( GetEntries() + c1 * h1->GetEntries() );
913 
914  // statistics can be preserved only in case of positive coefficients
915  // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
916  Bool_t resetStats = (c1 < 0);
917  Double_t s1[kNstat] = {0};
918  Double_t s2[kNstat] = {0};
919  if (!resetStats) {
920  // need to initialize to zero s1 and s2 since
921  // GetStats fills only used elements depending on dimension and type
922  GetStats(s1);
923  h1->GetStats(s2);
924  }
925 
926  SetMinimum();
927  SetMaximum();
928 
929  // - Loop on bins (including underflows/overflows)
930  Double_t factor = 1;
931  if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();;
932  Double_t c1sq = c1 * c1;
933  Double_t factsq = factor * factor;
934 
935  for (Int_t bin = 0; bin < fNcells; ++bin) {
936  //special case where histograms have the kIsAverage bit set
937  if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
938  Double_t y1 = h1->RetrieveBinContent(bin);
939  Double_t y2 = this->RetrieveBinContent(bin);
940  Double_t e1sq = h1->GetBinErrorSqUnchecked(bin);
941  Double_t e2sq = this->GetBinErrorSqUnchecked(bin);
942  Double_t w1 = 1., w2 = 1.;
943 
944  // consider all special cases when bin errors are zero
945  // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
946  if (e1sq) w1 = 1. / e1sq;
947  else if (h1->fSumw2.fN) {
948  w1 = 1.E200; // use an arbitrary huge value
949  if (y1 == 0) {
950  // use an estimated error from the global histogram scale
951  double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
952  w1 = 1./(sf*sf);
953  }
954  }
955  if (e2sq) w2 = 1. / e2sq;
956  else if (fSumw2.fN) {
957  w2 = 1.E200; // use an arbitrary huge value
958  if (y2 == 0) {
959  // use an estimated error from the global histogram scale
960  double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
961  w2 = 1./(sf*sf);
962  }
963  }
964 
965  double y = (w1*y1 + w2*y2)/(w1 + w2);
966  UpdateBinContent(bin, y);
967  if (fSumw2.fN) {
968  double err2 = 1./(w1 + w2);
969  if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
970  fSumw2.fArray[bin] = err2;
971  }
972  } else { // normal case of addition between histograms
973  AddBinContent(bin, c1 * factor * h1->RetrieveBinContent(bin));
974  if (fSumw2.fN) fSumw2.fArray[bin] += c1sq * factsq * h1->GetBinErrorSqUnchecked(bin);
975  }
976  }
977 
978  // update statistics (do here to avoid changes by SetBinContent)
979  if (resetStats) {
980  // statistics need to be reset in case coefficient are negative
981  ResetStats();
982  }
983  else {
984  for (Int_t i=0;i<kNstat;i++) {
985  if (i == 1) s1[i] += c1*c1*s2[i];
986  else s1[i] += c1*s2[i];
987  }
988  PutStats(s1);
989  SetEntries(entries);
990  }
991  return kTRUE;
992 }
993 
994 ////////////////////////////////////////////////////////////////////////////////
995 /// Replace contents of this histogram by the addition of h1 and h2.
996 ///
997 /// `this = c1*h1 + c2*h2`
998 /// if errors are defined (see TH1::Sumw2), errors are also recalculated
999 ///
1000 /// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
1001 /// if not already set.
1002 ///
1003 /// Note also that adding histogram with labels is not supported, histogram will be
1004 /// added merging them by bin number independently of the labels.
1005 /// For adding histogram ith labels one should use TH1::Merge
1006 ///
1007 /// SPECIAL CASE (Average/Efficiency histograms)
1008 /// For histograms representing averages or efficiencies, one should compute the average
1009 /// of the two histograms and not the sum. One can mark a histogram to be an average
1010 /// histogram by setting its bit kIsAverage with
1011 /// myhist.SetBit(TH1::kIsAverage);
1012 /// Note that the two histograms must have their kIsAverage bit set
1013 ///
1014 /// IMPORTANT NOTE: If you intend to use the errors of this histogram later
1015 /// you should call Sumw2 before making this operation.
1016 /// This is particularly important if you fit the histogram after TH1::Add
1017 ///
1018 /// ANOTHER SPECIAL CASE : h1 = h2 and c2 < 0
1019 /// do a scaling this = c1 * h1 / (bin Volume)
1020 ///
1021 /// The function returns kFALSE if the Add operation failed
1022 
1023 Bool_t TH1::Add(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2)
1024 {
1025 
1026  if (!h1 || !h2) {
1027  Error("Add","Attempt to add a non-existing histogram");
1028  return kFALSE;
1029  }
1030 
1031  // delete buffer if it is there since it will become invalid
1032  if (fBuffer) BufferEmpty(1);
1033 
1034  Bool_t normWidth = kFALSE;
1035  if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
1036 
1037  if (h1 != h2) {
1038  bool useMerge = (c1 == 1. && c2 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
1039 
1040  try {
1041  CheckConsistency(h1,h2);
1042  CheckConsistency(this,h1);
1043  useMerge = kFALSE;
1044  } catch(DifferentNumberOfBins&) {
1045  if (useMerge)
1046  Info("Add","Attempt to add histograms with different number of bins - trying to use TH1::Merge");
1047  else {
1048  Error("Add","Attempt to add histograms with different number of bins : nbins h1 = %d , nbins h2 = %d",GetNbinsX(), h1->GetNbinsX());
1049  return kFALSE;
1050  }
1051  } catch(DifferentAxisLimits&) {
1052  if (useMerge)
1053  Info("Add","Attempt to add histograms with different axis limits - trying to use TH1::Merge");
1054  else
1055  Warning("Add","Attempt to add histograms with different axis limits");
1056  } catch(DifferentBinLimits&) {
1057  if (useMerge)
1058  Info("Add","Attempt to add histograms with different bin limits - trying to use TH1::Merge");
1059  else
1060  Warning("Add","Attempt to add histograms with different bin limits");
1061  } catch(DifferentLabels&) {
1062  // in case of different labels -
1063  if (useMerge)
1064  Info("Add","Attempt to add histograms with different labels - trying to use TH1::Merge");
1065  else
1066  Info("Warning","Attempt to add histograms with different labels");
1067  }
1068 
1069  if (useMerge) {
1070  TList l;
1071  // why TList takes non-const pointers ????
1072  l.Add(const_cast<TH1*>(h1));
1073  l.Add(const_cast<TH1*>(h2));
1074  Reset("ICE");
1075  auto iret = Merge(&l);
1076  return (iret >= 0);
1077  }
1078  }
1079 
1080  // Create Sumw2 if h1 or h2 have Sumw2 set
1081  if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
1082 
1083  // - Add statistics
1084  Double_t nEntries = TMath::Abs( c1*h1->GetEntries() + c2*h2->GetEntries() );
1085 
1086  // TODO remove
1087  // statistics can be preserved only in case of positive coefficients
1088  // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1089  // also in case of scaling with the width we cannot preserve the statistics
1090  Double_t s1[kNstat] = {0};
1091  Double_t s2[kNstat] = {0};
1092  Double_t s3[kNstat];
1093 
1094 
1095  Bool_t resetStats = (c1*c2 < 0) || normWidth;
1096  if (!resetStats) {
1097  // need to initialize to zero s1 and s2 since
1098  // GetStats fills only used elements depending on dimension and type
1099  h1->GetStats(s1);
1100  h2->GetStats(s2);
1101  for (Int_t i=0;i<kNstat;i++) {
1102  if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
1103  //else s3[i] = TMath::Abs(c1)*s1[i] + TMath::Abs(c2)*s2[i];
1104  else s3[i] = c1*s1[i] + c2*s2[i];
1105  }
1106  }
1107 
1108  SetMinimum();
1109  SetMaximum();
1110 
1111  if (normWidth) { // DEPRECATED CASE: belongs to fitting / drawing modules
1112 
1113  Int_t nbinsx = GetNbinsX() + 2; // normal bins + underflow, overflow
1114  Int_t nbinsy = GetNbinsY() + 2;
1115  Int_t nbinsz = GetNbinsZ() + 2;
1116 
1117  if (fDimension < 2) nbinsy = 1;
1118  if (fDimension < 3) nbinsz = 1;
1119 
1120  Int_t bin, binx, biny, binz;
1121  for (binz = 0; binz < nbinsz; ++binz) {
1122  Double_t wz = h1->GetZaxis()->GetBinWidth(binz);
1123  for (biny = 0; biny < nbinsy; ++biny) {
1124  Double_t wy = h1->GetYaxis()->GetBinWidth(biny);
1125  for (binx = 0; binx < nbinsx; ++binx) {
1126  Double_t wx = h1->GetXaxis()->GetBinWidth(binx);
1127  bin = GetBin(binx, biny, binz);
1128  Double_t w = wx*wy*wz;
1129  UpdateBinContent(bin, c1 * h1->RetrieveBinContent(bin) / w);
1130  if (fSumw2.fN) {
1131  Double_t e1 = h1->GetBinError(bin)/w;
1132  fSumw2.fArray[bin] = c1*c1*e1*e1;
1133  }
1134  }
1135  }
1136  }
1137  } else if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
1138  for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
1139  // special case where histograms have the kIsAverage bit set
1140  Double_t y1 = h1->RetrieveBinContent(i);
1141  Double_t y2 = h2->RetrieveBinContent(i);
1142  Double_t e1sq = h1->GetBinErrorSqUnchecked(i);
1143  Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
1144  Double_t w1 = 1., w2 = 1.;
1145 
1146  // consider all special cases when bin errors are zero
1147  // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1148  if (e1sq) w1 = 1./ e1sq;
1149  else if (h1->fSumw2.fN) {
1150  w1 = 1.E200; // use an arbitrary huge value
1151  if (y1 == 0 ) { // use an estimated error from the global histogram scale
1152  double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1153  w1 = 1./(sf*sf);
1154  }
1155  }
1156  if (e2sq) w2 = 1./ e2sq;
1157  else if (h2->fSumw2.fN) {
1158  w2 = 1.E200; // use an arbitrary huge value
1159  if (y2 == 0) { // use an estimated error from the global histogram scale
1160  double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1161  w2 = 1./(sf*sf);
1162  }
1163  }
1164 
1165  double y = (w1*y1 + w2*y2)/(w1 + w2);
1166  UpdateBinContent(i, y);
1167  if (fSumw2.fN) {
1168  double err2 = 1./(w1 + w2);
1169  if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1170  fSumw2.fArray[i] = err2;
1171  }
1172  }
1173  } else { // case of simple histogram addition
1174  Double_t c1sq = c1 * c1;
1175  Double_t c2sq = c2 * c2;
1176  for (Int_t i = 0; i < fNcells; ++i) { // Loop on cells (bins including underflows/overflows)
1177  UpdateBinContent(i, c1 * h1->RetrieveBinContent(i) + c2 * h2->RetrieveBinContent(i));
1178  if (fSumw2.fN) {
1179  fSumw2.fArray[i] = c1sq * h1->GetBinErrorSqUnchecked(i) + c2sq * h2->GetBinErrorSqUnchecked(i);
1180  }
1181  }
1182  }
1183 
1184  if (resetStats) {
1185  // statistics need to be reset in case coefficient are negative
1186  ResetStats();
1187  }
1188  else {
1189  // update statistics (do here to avoid changes by SetBinContent) FIXME remove???
1190  PutStats(s3);
1191  SetEntries(nEntries);
1192  }
1193 
1194  return kTRUE;
1195 }
1196 
1197 ////////////////////////////////////////////////////////////////////////////////
1198 /// Increment bin content by 1.
1199 
1200 void TH1::AddBinContent(Int_t)
1201 {
1202  AbstractMethod("AddBinContent");
1203 }
1204 
1205 ////////////////////////////////////////////////////////////////////////////////
1206 /// Increment bin content by a weight w.
1207 
1208 void TH1::AddBinContent(Int_t, Double_t)
1209 {
1210  AbstractMethod("AddBinContent");
1211 }
1212 
1213 ////////////////////////////////////////////////////////////////////////////////
1214 /// Sets the flag controlling the automatic add of histograms in memory
1215 ///
1216 /// By default (fAddDirectory = kTRUE), histograms are automatically added
1217 /// to the list of objects in memory.
1218 /// Note that one histogram can be removed from its support directory
1219 /// by calling h->SetDirectory(0) or h->SetDirectory(dir) to add it
1220 /// to the list of objects in the directory dir.
1221 ///
1222 /// NOTE that this is a static function. To call it, use;
1223 /// TH1::AddDirectory
1224 
1225 void TH1::AddDirectory(Bool_t add)
1226 {
1227  fgAddDirectory = add;
1228 }
1229 
1230 ////////////////////////////////////////////////////////////////////////////////
1231 /// Auxilliary function to get the power of 2 next (larger) or previous (smaller)
1232 /// a given x
1233 ///
1234 /// next = kTRUE : next larger
1235 /// next = kFALSE : previous smaller
1236 ///
1237 /// Used by the autobin power of 2 algorithm
1238 
1239 inline Double_t TH1::AutoP2GetPower2(Double_t x, Bool_t next)
1240 {
1241  Int_t nn;
1242  Double_t f2 = std::frexp(x, &nn);
1243  return ((next && x > 0.) || (!next && x <= 0.)) ? std::ldexp(std::copysign(1., f2), nn)
1244  : std::ldexp(std::copysign(1., f2), --nn);
1245 }
1246 
1247 ////////////////////////////////////////////////////////////////////////////////
1248 /// Auxilliary function to get the next power of 2 integer value larger then n
1249 ///
1250 /// Used by the autobin power of 2 algorithm
1251 
1252 inline Int_t TH1::AutoP2GetBins(Int_t n)
1253 {
1254  Int_t nn;
1255  Double_t f2 = std::frexp(n, &nn);
1256  if (TMath::Abs(f2 - .5) > 0.001)
1257  return (Int_t)std::ldexp(1., nn);
1258  return n;
1259 }
1260 
1261 ////////////////////////////////////////////////////////////////////////////////
1262 /// Buffer-based estimate of the histogram range using the power of 2 algorithm.
1263 ///
1264 /// Used by the autobin power of 2 algorithm.
1265 ///
1266 /// Works on arguments (min and max from fBuffer) and internal inputs: fXmin,
1267 /// fXmax, NBinsX (from fXaxis), ...
1268 /// Result save internally in fXaxis.
1269 ///
1270 /// Overloaded by TH2 and TH3.
1271 ///
1272 /// Return -1 if internal inputs are incosistent, 0 otherwise.
1273 ///
1274 
1275 Int_t TH1::AutoP2FindLimits(Double_t xmi, Double_t xma)
1276 {
1277  // We need meaningful raw limits
1278  if (xmi >= xma)
1279  return -1;
1280 
1281  THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this, xmi, xma);
1282  Double_t xhmi = fXaxis.GetXmin();
1283  Double_t xhma = fXaxis.GetXmax();
1284 
1285  // Now adjust
1286  if (TMath::Abs(xhma) > TMath::Abs(xhmi)) {
1287  // Start from the upper limit
1288  xhma = TH1::AutoP2GetPower2(xhma);
1289  xhmi = xhma - TH1::AutoP2GetPower2(xhma - xhmi);
1290  } else {
1291  // Start from the lower limit
1292  xhmi = TH1::AutoP2GetPower2(xhmi, kFALSE);
1293  xhma = xhmi + TH1::AutoP2GetPower2(xhma - xhmi);
1294  }
1295 
1296  // Round the bins to the next power of 2; take into account the possible inflation
1297  // of the range
1298  Double_t rr = (xhma - xhmi) / (xma - xmi);
1299  Int_t nb = TH1::AutoP2GetBins((Int_t)(rr * GetNbinsX()));
1300 
1301  // Adjust using the same bin width and offsets
1302  Double_t bw = (xhma - xhmi) / nb;
1303  // Bins to left free on each side
1304  Double_t autoside = gEnv->GetValue("Hist.Binning.Auto.Side", 0.05);
1305  Int_t nbside = (Int_t)(nb * autoside);
1306 
1307  // Side up
1308  Int_t nbup = (xhma - xma) / bw;
1309  if (nbup % 2 != 0)
1310  nbup++; // Must be even
1311  if (nbup != nbside) {
1312  // Accounts also for both case: larger or smaller
1313  xhma -= bw * (nbup - nbside);
1314  nb -= (nbup - nbside);
1315  }
1316 
1317  // Side low
1318  Int_t nblw = (xmi - xhmi) / bw;
1319  if (nblw % 2 != 0)
1320  nblw++; // Must be even
1321  if (nblw != nbside) {
1322  // Accounts also for both case: larger or smaller
1323  xhmi += bw * (nblw - nbside);
1324  nb -= (nblw - nbside);
1325  }
1326 
1327  // Set everything and project
1328  SetBins(nb, xhmi, xhma);
1329 
1330  // Done
1331  return 0;
1332 }
1333 
1334 /// Fill histogram with all entries in the buffer.
1335 ///
1336 /// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
1337 /// - action = 0 histogram is reset and filled from the buffer. When the histogram is filled from the
1338 /// buffer the value fBuffer[0] is set to a negative number (= - number of entries)
1339 /// When calling with action == 0 the histogram is NOT refilled when fBuffer[0] is < 0
1340 /// While when calling with action = -1 the histogram is reset and ALWAYS refilled independently if
1341 /// the histogram was filled before. This is needed when drawing the histogram
1342 /// - action = 1 histogram is filled and buffer is deleted
1343 /// The buffer is automatically deleted when filling the histogram and the entries is
1344 /// larger than the buffer size
1345 
1346 Int_t TH1::BufferEmpty(Int_t action)
1347 {
1348  // do we need to compute the bin size?
1349  if (!fBuffer) return 0;
1350  Int_t nbentries = (Int_t)fBuffer[0];
1351 
1352  // nbentries correspond to the number of entries of histogram
1353 
1354  if (nbentries == 0) {
1355  // if action is 1 we delete the buffer
1356  // this will avoid infinite recursion
1357  if (action > 0) {
1358  delete [] fBuffer;
1359  fBuffer = 0;
1360  fBufferSize = 0;
1361  }
1362  return 0;
1363  }
1364  if (nbentries < 0 && action == 0) return 0; // case histogram has been already filled from the buffer
1365 
1366  Double_t *buffer = fBuffer;
1367  if (nbentries < 0) {
1368  nbentries = -nbentries;
1369  // a reset might call BufferEmpty() giving an infinite recursion
1370  // Protect it by setting fBuffer = 0
1371  fBuffer=0;
1372  //do not reset the list of functions
1373  Reset("ICES");
1374  fBuffer = buffer;
1375  }
1376  if (CanExtendAllAxes() || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
1377  //find min, max of entries in buffer
1378  Double_t xmin = fBuffer[2];
1379  Double_t xmax = xmin;
1380  for (Int_t i=1;i<nbentries;i++) {
1381  Double_t x = fBuffer[2*i+2];
1382  if (x < xmin) xmin = x;
1383  if (x > xmax) xmax = x;
1384  }
1385  if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
1386  Int_t rc = -1;
1387  if (TestBit(TH1::kAutoBinPTwo)) {
1388  if ((rc = AutoP2FindLimits(xmin, xmax)) < 0)
1389  Warning("BufferEmpty",
1390  "incosistency found by power-of-2 autobin algorithm: fallback to standard method");
1391  }
1392  if (rc < 0)
1393  THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this, xmin, xmax);
1394  } else {
1395  fBuffer = 0;
1396  Int_t keep = fBufferSize; fBufferSize = 0;
1397  if (xmin < fXaxis.GetXmin()) ExtendAxis(xmin, &fXaxis);
1398  if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax, &fXaxis);
1399  fBuffer = buffer;
1400  fBufferSize = keep;
1401  }
1402  }
1403 
1404  // call DoFillN which will not put entries in the buffer as FillN does
1405  // set fBuffer to zero to avoid re-emptying the buffer from functions called
1406  // by DoFillN (e.g Sumw2)
1407  buffer = fBuffer; fBuffer = 0;
1408  DoFillN(nbentries,&buffer[2],&buffer[1],2);
1409  fBuffer = buffer;
1410 
1411  // if action == 1 - delete the buffer
1412  if (action > 0) {
1413  delete [] fBuffer;
1414  fBuffer = 0;
1415  fBufferSize = 0;
1416  } else {
1417  // if number of entries is consistent with buffer - set it negative to avoid
1418  // refilling the histogram every time BufferEmpty(0) is called
1419  // In case it is not consistent, by setting fBuffer[0]=0 is like resetting the buffer
1420  // (it will not be used anymore the next time BufferEmpty is called)
1421  if (nbentries == (Int_t)fEntries)
1422  fBuffer[0] = -nbentries;
1423  else
1424  fBuffer[0] = 0;
1425  }
1426  return nbentries;
1427 }
1428 
1429 ////////////////////////////////////////////////////////////////////////////////
1430 /// accumulate arguments in buffer. When buffer is full, empty the buffer
1431 ///
1432 /// - `fBuffer[0]` = number of entries in buffer
1433 /// - `fBuffer[1]` = w of first entry
1434 /// - `fBuffer[2]` = x of first entry
1435 
1436 Int_t TH1::BufferFill(Double_t x, Double_t w)
1437 {
1438  if (!fBuffer) return -2;
1439  Int_t nbentries = (Int_t)fBuffer[0];
1440 
1441 
1442  if (nbentries < 0) {
1443  // reset nbentries to a positive value so next time BufferEmpty() is called
1444  // the histogram will be refilled
1445  nbentries = -nbentries;
1446  fBuffer[0] = nbentries;
1447  if (fEntries > 0) {
1448  // set fBuffer to zero to avoid calling BufferEmpty in Reset
1449  Double_t *buffer = fBuffer; fBuffer=0;
1450  Reset("ICES"); // do not reset list of functions
1451  fBuffer = buffer;
1452  }
1453  }
1454  if (2*nbentries+2 >= fBufferSize) {
1455  BufferEmpty(1);
1456  if (!fBuffer)
1457  // to avoid infinite recursion Fill->BufferFill->Fill
1458  return Fill(x,w);
1459  // this cannot happen
1460  R__ASSERT(0);
1461  }
1462  fBuffer[2*nbentries+1] = w;
1463  fBuffer[2*nbentries+2] = x;
1464  fBuffer[0] += 1;
1465  return -2;
1466 }
1467 
1468 ////////////////////////////////////////////////////////////////////////////////
1469 /// Check bin limits.
1470 
1471 bool TH1::CheckBinLimits(const TAxis* a1, const TAxis * a2)
1472 {
1473  const TArrayD * h1Array = a1->GetXbins();
1474  const TArrayD * h2Array = a2->GetXbins();
1475  Int_t fN = h1Array->fN;
1476  if ( fN != 0 ) {
1477  if ( h2Array->fN != fN ) {
1478  throw DifferentBinLimits();
1479  return false;
1480  }
1481  else {
1482  for ( int i = 0; i < fN; ++i ) {
1483  // for i==fN (nbin+1) a->GetBinWidth() returns last bin width
1484  // we do not need to exclude that case
1485  double binWidth = a1->GetBinWidth(i);
1486  if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), binWidth*1E-10 ) ) {
1487  throw DifferentBinLimits();
1488  return false;
1489  }
1490  }
1491  }
1492  }
1493 
1494  return true;
1495 }
1496 
1497 ////////////////////////////////////////////////////////////////////////////////
1498 /// Check that axis have same labels.
1499 
1500 bool TH1::CheckBinLabels(const TAxis* a1, const TAxis * a2)
1501 {
1502  THashList *l1 = a1->GetLabels();
1503  THashList *l2 = a2->GetLabels();
1504 
1505  if (!l1 && !l2 )
1506  return true;
1507  if (!l1 || !l2 ) {
1508  throw DifferentLabels();
1509  return false;
1510  }
1511  // check now labels sizes are the same
1512  if (l1->GetSize() != l2->GetSize() ) {
1513  throw DifferentLabels();
1514  return false;
1515  }
1516  for (int i = 1; i <= a1->GetNbins(); ++i) {
1517  TString label1 = a1->GetBinLabel(i);
1518  TString label2 = a2->GetBinLabel(i);
1519  if (label1 != label2) {
1520  throw DifferentLabels();
1521  return false;
1522  }
1523  }
1524 
1525  return true;
1526 }
1527 
1528 ////////////////////////////////////////////////////////////////////////////////
1529 /// Check that the axis limits of the histograms are the same.
1530 /// If a first and last bin is passed the axis is compared between the given range
1531 
1532 bool TH1::CheckAxisLimits(const TAxis *a1, const TAxis *a2 )
1533 {
1534  double firstBin = a1->GetBinWidth(1);
1535  double lastBin = a1->GetBinWidth( a1->GetNbins() );
1536  if ( ! TMath::AreEqualAbs(a1->GetXmin(), a2->GetXmin(), firstBin* 1.E-10) ||
1537  ! TMath::AreEqualAbs(a1->GetXmax(), a2->GetXmax(), lastBin*1.E-10) ) {
1538  throw DifferentAxisLimits();
1539  return false;
1540  }
1541  return true;
1542 }
1543 
1544 ////////////////////////////////////////////////////////////////////////////////
1545 /// Check that the axis are the same
1546 
1547 bool TH1::CheckEqualAxes(const TAxis *a1, const TAxis *a2 )
1548 {
1549  if (a1->GetNbins() != a2->GetNbins() ) {
1550  //throw DifferentNumberOfBins();
1551  ::Info("CheckEqualAxes","Axes have different number of bins : nbin1 = %d nbin2 = %d",a1->GetNbins(),a2->GetNbins() );
1552  return false;
1553  }
1554  try {
1555  CheckAxisLimits(a1,a2);
1556  } catch (DifferentAxisLimits&) {
1557  ::Info("CheckEqualAxes","Axes have different limits");
1558  return false;
1559  }
1560  try {
1561  CheckBinLimits(a1,a2);
1562  } catch (DifferentBinLimits&) {
1563  ::Info("CheckEqualAxes","Axes have different bin limits");
1564  return false;
1565  }
1566 
1567  // check labels
1568  try {
1569  CheckBinLabels(a1,a2);
1570  } catch (DifferentLabels&) {
1571  ::Info("CheckEqualAxes","Axes have different labels");
1572  return false;
1573  }
1574 
1575  return true;
1576 }
1577 
1578 ////////////////////////////////////////////////////////////////////////////////
1579 /// Check that two sub axis are the same.
1580 /// The limits are defined by first bin and last bin
1581 /// N.B. no check is done in this case for variable bins
1582 
1583 bool TH1::CheckConsistentSubAxes(const TAxis *a1, Int_t firstBin1, Int_t lastBin1, const TAxis * a2, Int_t firstBin2, Int_t lastBin2 )
1584 {
1585  // By default is assumed that no bins are given for the second axis
1586  Int_t nbins1 = lastBin1-firstBin1 + 1;
1587  Double_t xmin1 = a1->GetBinLowEdge(firstBin1);
1588  Double_t xmax1 = a1->GetBinUpEdge(lastBin1);
1589 
1590  Int_t nbins2 = a2->GetNbins();
1591  Double_t xmin2 = a2->GetXmin();
1592  Double_t xmax2 = a2->GetXmax();
1593 
1594  if (firstBin2 < lastBin2) {
1595  // in this case assume no bins are given for the second axis
1596  nbins2 = lastBin1-firstBin1 + 1;
1597  xmin2 = a1->GetBinLowEdge(firstBin1);
1598  xmax2 = a1->GetBinUpEdge(lastBin1);
1599  }
1600 
1601  if (nbins1 != nbins2 ) {
1602  ::Info("CheckConsistentSubAxes","Axes have different number of bins");
1603  return false;
1604  }
1605 
1606  Double_t firstBin = a1->GetBinWidth(firstBin1);
1607  Double_t lastBin = a1->GetBinWidth(lastBin1);
1608  if ( ! TMath::AreEqualAbs(xmin1,xmin2,1.E-10 * firstBin) ||
1609  ! TMath::AreEqualAbs(xmax1,xmax2,1.E-10 * lastBin) ) {
1610  ::Info("CheckConsistentSubAxes","Axes have different limits");
1611  return false;
1612  }
1613 
1614  return true;
1615 }
1616 
1617 ////////////////////////////////////////////////////////////////////////////////
1618 /// Check histogram compatibility.
1619 
1620 bool TH1::CheckConsistency(const TH1* h1, const TH1* h2)
1621 {
1622  if (h1 == h2) return true;
1623 
1624  if (h1->GetDimension() != h2->GetDimension() ) {
1625  throw DifferentDimension();
1626  return false;
1627  }
1628  Int_t dim = h1->GetDimension();
1629 
1630  // returns kTRUE if number of bins and bin limits are identical
1631  Int_t nbinsx = h1->GetNbinsX();
1632  Int_t nbinsy = h1->GetNbinsY();
1633  Int_t nbinsz = h1->GetNbinsZ();
1634 
1635  // Check whether the histograms have the same number of bins.
1636  if (nbinsx != h2->GetNbinsX() ||
1637  (dim > 1 && nbinsy != h2->GetNbinsY()) ||
1638  (dim > 2 && nbinsz != h2->GetNbinsZ()) ) {
1639  throw DifferentNumberOfBins();
1640  return false;
1641  }
1642 
1643  bool ret = true;
1644 
1645  // check axis limits
1646  ret &= CheckAxisLimits(h1->GetXaxis(), h2->GetXaxis());
1647  if (dim > 1) ret &= CheckAxisLimits(h1->GetYaxis(), h2->GetYaxis());
1648  if (dim > 2) ret &= CheckAxisLimits(h1->GetZaxis(), h2->GetZaxis());
1649 
1650  // check bin limits
1651  ret &= CheckBinLimits(h1->GetXaxis(), h2->GetXaxis());
1652  if (dim > 1) ret &= CheckBinLimits(h1->GetYaxis(), h2->GetYaxis());
1653  if (dim > 2) ret &= CheckBinLimits(h1->GetZaxis(), h2->GetZaxis());
1654 
1655  // check labels if histograms are both not empty
1656  if ( !h1->IsEmpty() && !h2->IsEmpty() ) {
1657  ret &= CheckBinLabels(h1->GetXaxis(), h2->GetXaxis());
1658  if (dim > 1) ret &= CheckBinLabels(h1->GetYaxis(), h2->GetYaxis());
1659  if (dim > 2) ret &= CheckBinLabels(h1->GetZaxis(), h2->GetZaxis());
1660  }
1661 
1662  return ret;
1663 }
1664 
1665 ////////////////////////////////////////////////////////////////////////////////
1666 /// \f$ \chi^{2} \f$ test for comparing weighted and unweighted histograms
1667 ///
1668 /// Function: Returns p-value. Other return values are specified by the 3rd parameter
1669 ///
1670 /// \param[in] h2 the second histogram
1671 /// \param[in] option
1672 /// - "UU" = experiment experiment comparison (unweighted-unweighted)
1673 /// - "UW" = experiment MC comparison (unweighted-weighted). Note that
1674 /// the first histogram should be unweighted
1675 /// - "WW" = MC MC comparison (weighted-weighted)
1676 /// - "NORM" = to be used when one or both of the histograms is scaled
1677 /// but the histogram originally was unweighted
1678 /// - by default underflows and overflows are not included:
1679 /// * "OF" = overflows included
1680 /// * "UF" = underflows included
1681 /// - "P" = print chi2, ndf, p_value, igood
1682 /// - "CHI2" = returns chi2 instead of p-value
1683 /// - "CHI2/NDF" = returns \f$ \chi^{2} \f$/ndf
1684 /// \param[in] res not empty - computes normalized residuals and returns them in this array
1685 ///
1686 /// The current implementation is based on the papers \f$ \chi^{2} \f$ test for comparison
1687 /// of weighted and unweighted histograms" in Proceedings of PHYSTAT05 and
1688 /// "Comparison weighted and unweighted histograms", arXiv:physics/0605123
1689 /// by N.Gagunashvili. This function has been implemented by Daniel Haertl in August 2006.
1690 ///
1691 /// #### Introduction:
1692 ///
1693 /// A frequently used technique in data analysis is the comparison of
1694 /// histograms. First suggested by Pearson [1] the \f$ \chi^{2} \f$ test of
1695 /// homogeneity is used widely for comparing usual (unweighted) histograms.
1696 /// This paper describes the implementation modified \f$ \chi^{2} \f$ tests
1697 /// for comparison of weighted and unweighted histograms and two weighted
1698 /// histograms [2] as well as usual Pearson's \f$ \chi^{2} \f$ test for
1699 /// comparison two usual (unweighted) histograms.
1700 ///
1701 /// #### Overview:
1702 ///
1703 /// Comparison of two histograms expect hypotheses that two histograms
1704 /// represent identical distributions. To make a decision p-value should
1705 /// be calculated. The hypotheses of identity is rejected if the p-value is
1706 /// lower then some significance level. Traditionally significance levels
1707 /// 0.1, 0.05 and 0.01 are used. The comparison procedure should include an
1708 /// analysis of the residuals which is often helpful in identifying the
1709 /// bins of histograms responsible for a significant overall \f$ \chi^{2} \f$ value.
1710 /// Residuals are the difference between bin contents and expected bin
1711 /// contents. Most convenient for analysis are the normalized residuals. If
1712 /// hypotheses of identity are valid then normalized residuals are
1713 /// approximately independent and identically distributed random variables
1714 /// having N(0,1) distribution. Analysis of residuals expect test of above
1715 /// mentioned properties of residuals. Notice that indirectly the analysis
1716 /// of residuals increase the power of \f$ \chi^{2} \f$ test.
1717 ///
1718 /// #### Methods of comparison:
1719 ///
1720 /// \f$ \chi^{2} \f$ test for comparison two (unweighted) histograms:
1721 /// Let us consider two histograms with the same binning and the number
1722 /// of bins equal to r. Let us denote the number of events in the ith bin
1723 /// in the first histogram as ni and as mi in the second one. The total
1724 /// number of events in the first histogram is equal to:
1725 /// \f[
1726 /// N = \sum_{i=1}^{r} n_{i}
1727 /// \f]
1728 /// and
1729 /// \f[
1730 /// M = \sum_{i=1}^{r} m_{i}
1731 /// \f]
1732 /// in the second histogram. The hypothesis of identity (homogeneity) [3]
1733 /// is that the two histograms represent random values with identical
1734 /// distributions. It is equivalent that there exist r constants p1,...,pr,
1735 /// such that
1736 /// \f[
1737 ///\sum_{i=1}^{r} p_{i}=1
1738 /// \f]
1739 /// and the probability of belonging to the ith bin for some measured value
1740 /// in both experiments is equal to pi. The number of events in the ith
1741 /// bin is a random variable with a distribution approximated by a Poisson
1742 /// probability distribution
1743 /// \f[
1744 ///\frac{e^{-Np_{i}}(Np_{i})^{n_{i}}}{n_{i}!}
1745 /// \f]
1746 ///for the first histogram and with distribution
1747 /// \f[
1748 ///\frac{e^{-Mp_{i}}(Mp_{i})^{m_{i}}}{m_{i}!}
1749 /// \f]
1750 /// for the second histogram. If the hypothesis of homogeneity is valid,
1751 /// then the maximum likelihood estimator of pi, i=1,...,r, is
1752 /// \f[
1753 ///\hat{p}_{i}= \frac{n_{i}+m_{i}}{N+M}
1754 /// \f]
1755 /// and then
1756 /// \f[
1757 /// X^{2} = \sum_{i=1}^{r}\frac{(n_{i}-N\hat{p}_{i})^{2}}{N\hat{p}_{i}} + \sum_{i=1}^{r}\frac{(m_{i}-M\hat{p}_{i})^{2}}{M\hat{p}_{i}} =\frac{1}{MN} \sum_{i=1}^{r}\frac{(Mn_{i}-Nm_{i})^{2}}{n_{i}+m_{i}}
1758 /// \f]
1759 /// has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [3].
1760 /// The comparison procedure can include an analysis of the residuals which
1761 /// is often helpful in identifying the bins of histograms responsible for
1762 /// a significant overall \f$ \chi^{2} \f$ value. Most convenient for
1763 /// analysis are the adjusted (normalized) residuals [4]
1764 /// \f[
1765 /// r_{i} = \frac{n_{i}-N\hat{p}_{i}}{\sqrt{N\hat{p}_{i}}\sqrt{(1-N/(N+M))(1-(n_{i}+m_{i})/(N+M))}}
1766 /// \f]
1767 /// If hypotheses of homogeneity are valid then residuals ri are
1768 /// approximately independent and identically distributed random variables
1769 /// having N(0,1) distribution. The application of the \f$ \chi^{2} \f$ test has
1770 /// restrictions related to the value of the expected frequencies Npi,
1771 /// Mpi, i=1,...,r. A conservative rule formulated in [5] is that all the
1772 /// expectations must be 1 or greater for both histograms. In practical
1773 /// cases when expected frequencies are not known the estimated expected
1774 /// frequencies \f$ M\hat{p}_{i}, N\hat{p}_{i}, i=1,...,r \f$ can be used.
1775 ///
1776 /// #### Unweighted and weighted histograms comparison:
1777 ///
1778 /// A simple modification of the ideas described above can be used for the
1779 /// comparison of the usual (unweighted) and weighted histograms. Let us
1780 /// denote the number of events in the ith bin in the unweighted
1781 /// histogram as ni and the common weight of events in the ith bin of the
1782 /// weighted histogram as wi. The total number of events in the
1783 /// unweighted histogram is equal to
1784 ///\f[
1785 /// N = \sum_{i=1}^{r} n_{i}
1786 ///\f]
1787 /// and the total weight of events in the weighted histogram is equal to
1788 ///\f[
1789 /// W = \sum_{i=1}^{r} w_{i}
1790 ///\f]
1791 /// Let us formulate the hypothesis of identity of an unweighted histogram
1792 /// to a weighted histogram so that there exist r constants p1,...,pr, such
1793 /// that
1794 ///\f[
1795 /// \sum_{i=1}^{r} p_{i} = 1
1796 ///\f]
1797 /// for the unweighted histogram. The weight wi is a random variable with a
1798 /// distribution approximated by the normal probability distribution
1799 /// \f$ N(Wp_{i},\sigma_{i}^{2}) \f$ where \f$ \sigma_{i}^{2} \f$ is the variance of the weight wi.
1800 /// If we replace the variance \f$ \sigma_{i}^{2} \f$
1801 /// with estimate \f$ s_{i}^{2} \f$ (sum of squares of weights of
1802 /// events in the ith bin) and the hypothesis of identity is valid, then the
1803 /// maximum likelihood estimator of pi,i=1,...,r, is
1804 ///\f[
1805 /// \hat{p}_{i} = \frac{Ww_{i}-Ns_{i}^{2}+\sqrt{(Ww_{i}-Ns_{i}^{2})^{2}+4W^{2}s_{i}^{2}n_{i}}}{2W^{2}}
1806 ///\f]
1807 /// We may then use the test statistic
1808 ///\f[
1809 /// X^{2} = \sum_{i=1}^{r} \frac{(n_{i}-N\hat{p}_{i})^{2}}{N\hat{p}_{i}} + \sum_{i=1}^{r} \frac{(w_{i}-W\hat{p}_{i})^{2}}{s_{i}^{2}}
1810 ///\f]
1811 /// and it has approximately a \f$ \sigma^{2}_{(r-1)} \f$ distribution [2]. This test, as well
1812 /// as the original one [3], has a restriction on the expected frequencies. The
1813 /// expected frequencies recommended for the weighted histogram is more than 25.
1814 /// The value of the minimal expected frequency can be decreased down to 10 for
1815 /// the case when the weights of the events are close to constant. In the case
1816 /// of a weighted histogram if the number of events is unknown, then we can
1817 /// apply this recommendation for the equivalent number of events as
1818 ///\f[
1819 /// n_{i}^{equiv} = \frac{ w_{i}^{2} }{ s_{i}^{2} }
1820 ///\f]
1821 /// The minimal expected frequency for an unweighted histogram must be 1. Notice
1822 /// that any usual (unweighted) histogram can be considered as a weighted
1823 /// histogram with events that have constant weights equal to 1.
1824 /// The variance \f$ z_{i}^{2} \f$ of the difference between the weight wi
1825 /// and the estimated expectation value of the weight is approximately equal to:
1826 ///\f[
1827 /// z_{i}^{2} = Var(w_{i}-W\hat{p}_{i}) = N\hat{p}_{i}(1-N\hat{p}_{i})\left(\frac{Ws_{i}^{2}}{\sqrt{(Ns_{i}^{2}-w_{i}W)^{2}+4W^{2}s_{i}^{2}n_{i}}}\right)^{2}+\frac{s_{i}^{2}}{4}\left(1+\frac{Ns_{i}^{2}-w_{i}W}{\sqrt{(Ns_{i}^{2}-w_{i}W)^{2}+4W^{2}s_{i}^{2}n_{i}}}\right)^{2}
1828 ///\f]
1829 /// The residuals
1830 ///\f[
1831 /// r_{i} = \frac{w_{i}-W\hat{p}_{i}}{z_{i}}
1832 ///\f]
1833 /// have approximately a normal distribution with mean equal to 0 and standard
1834 /// deviation equal to 1.
1835 ///
1836 /// #### Two weighted histograms comparison:
1837 ///
1838 /// Let us denote the common weight of events of the ith bin in the first
1839 /// histogram as w1i and as w2i in the second one. The total weight of events
1840 /// in the first histogram is equal to
1841 ///\f[
1842 /// W_{1} = \sum_{i=1}^{r} w_{1i}
1843 ///\f]
1844 /// and
1845 ///\f[
1846 /// W_{2} = \sum_{i=1}^{r} w_{2i}
1847 ///\f]
1848 /// in the second histogram. Let us formulate the hypothesis of identity of
1849 /// weighted histograms so that there exist r constants p1,...,pr, such that
1850 ///\f[
1851 /// \sum_{i=1}^{r} p_{i} = 1
1852 ///\f]
1853 /// and also expectation value of weight w1i equal to W1pi and expectation value
1854 /// of weight w2i equal to W2pi. Weights in both the histograms are random
1855 /// variables with distributions which can be approximated by a normal
1856 /// probability distribution \f$ N(W_{1}p_{i},\sigma_{1i}^{2}) \f$ for the first histogram
1857 /// and by a distribution \f$ N(W_{2}p_{i},\sigma_{2i}^{2}) \f$ for the second.
1858 /// Here \f$ \sigma_{1i}^{2} \f$ and \f$ \sigma_{2i}^{2} \f$ are the variances
1859 /// of w1i and w2i with estimators \f$ s_{1i}^{2} \f$ and \f$ s_{2i}^{2} \f$ respectively.
1860 /// If the hypothesis of identity is valid, then the maximum likelihood and
1861 /// Least Square Method estimator of pi,i=1,...,r, is
1862 ///\f[
1863 /// \hat{p}_{i} = \frac{w_{1i}W_{1}/s_{1i}^{2}+w_{2i}W_{2} /s_{2i}^{2}}{W_{1}^{2}/s_{1i}^{2}+W_{2}^{2}/s_{2i}^{2}}
1864 ///\f]
1865 /// We may then use the test statistic
1866 ///\f[
1867 /// X^{2} = \sum_{i=1}^{r} \frac{(w_{1i}-W_{1}\hat{p}_{i})^{2}}{s_{1i}^{2}} + \sum_{i=1}^{r} \frac{(w_{2i}-W_{2}\hat{p}_{i})^{2}}{s_{2i}^{2}} = \sum_{i=1}^{r} \frac{(W_{1}w_{2i}-W_{2}w_{1i})^{2}}{W_{1}^{2}s_{2i}^{2}+W_{2}^{2}s_{1i}^{2}}
1868 ///\f]
1869 /// and it has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [2].
1870 /// The normalized or studentised residuals [6]
1871 ///\f[
1872 /// r_{i} = \frac{w_{1i}-W_{1}\hat{p}_{i}}{s_{1i}\sqrt{1 - \frac{1}{(1+W_{2}^{2}s_{1i}^{2}/W_{1}^{2}s_{2i}^{2})}}}
1873 ///\f]
1874 /// have approximately a normal distribution with mean equal to 0 and standard
1875 /// deviation 1. A recommended minimal expected frequency is equal to 10 for
1876 /// the proposed test.
1877 ///
1878 /// #### Numerical examples:
1879 ///
1880 /// The method described herein is now illustrated with an example.
1881 /// We take a distribution
1882 ///\f[
1883 /// \phi(x) = \frac{2}{(x-10)^{2}+1} + \frac{1}{(x-14)^{2}+1} (1)
1884 ///\f]
1885 /// defined on the interval [4,16]. Events distributed according to the formula
1886 /// (1) are simulated to create the unweighted histogram. Uniformly distributed
1887 /// events are simulated for the weighted histogram with weights calculated by
1888 /// formula (1). Each histogram has the same number of bins: 20. Fig.1 shows
1889 /// the result of comparison of the unweighted histogram with 200 events
1890 /// (minimal expected frequency equal to one) and the weighted histogram with
1891 /// 500 events (minimal expected frequency equal to 25)
1892 /// Begin_Macro
1893 /// ../../../tutorials/math/chi2test.C
1894 /// End_Macro
1895 /// Fig 1. An example of comparison of the unweighted histogram with 200 events
1896 /// and the weighted histogram with 500 events:
1897 /// 1. unweighted histogram;
1898 /// 2. weighted histogram;
1899 /// 3. normalized residuals plot;
1900 /// 4. normal Q-Q plot of residuals.
1901 ///
1902 /// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1903 /// 21.09 with p-value equal to 0.33, therefore the hypothesis of identity of
1904 /// the two histograms can be accepted for 0.05 significant level. The behavior
1905 /// of the normalized residuals plot (see Fig. 1c) and the normal Q-Q plot
1906 /// (see Fig. 1d) of residuals are regular and we cannot identify the outliers
1907 /// or bins with a big influence on \f$ \chi^{2} \f$.
1908 ///
1909 /// The second example presents the same two histograms but 17 events was added
1910 /// to content of bin number 15 in unweighted histogram. Fig.2 shows the result
1911 /// of comparison of the unweighted histogram with 217 events (minimal expected
1912 /// frequency equal to one) and the weighted histogram with 500 events (minimal
1913 /// expected frequency equal to 25)
1914 /// Begin_Macro
1915 /// ../../../tutorials/math/chi2test.C(17)
1916 /// End_Macro
1917 /// Fig 2. An example of comparison of the unweighted histogram with 217 events
1918 /// and the weighted histogram with 500 events:
1919 /// 1. unweighted histogram;
1920 /// 2. weighted histogram;
1921 /// 3. normalized residuals plot;
1922 /// 4. normal Q-Q plot of residuals.
1923 ///
1924 /// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1925 /// 32.33 with p-value equal to 0.029, therefore the hypothesis of identity of
1926 /// the two histograms is rejected for 0.05 significant level. The behavior of
1927 /// the normalized residuals plot (see Fig. 2c) and the normal Q-Q plot (see
1928 /// Fig. 2d) of residuals are not regular and we can identify the outlier or
1929 /// bin with a big influence on \f$ \chi^{2} \f$.
1930 ///
1931 /// #### References:
1932 ///
1933 /// - [1] Pearson, K., 1904. On the Theory of Contingency and Its Relation to
1934 /// Association and Normal Correlation. Drapers' Co. Memoirs, Biometric
1935 /// Series No. 1, London.
1936 /// - [2] Gagunashvili, N., 2006. \f$ \sigma^{2} \f$ test for comparison
1937 /// of weighted and unweighted histograms. Statistical Problems in Particle
1938 /// Physics, Astrophysics and Cosmology, Proceedings of PHYSTAT05,
1939 /// Oxford, UK, 12-15 September 2005, Imperial College Press, London, 43-44.
1940 /// Gagunashvili,N., Comparison of weighted and unweighted histograms,
1941 /// arXiv:physics/0605123, 2006.
1942 /// - [3] Cramer, H., 1946. Mathematical methods of statistics.
1943 /// Princeton University Press, Princeton.
1944 /// - [4] Haberman, S.J., 1973. The analysis of residuals in cross-classified tables.
1945 /// Biometrics 29, 205-220.
1946 /// - [5] Lewontin, R.C. and Felsenstein, J., 1965. The robustness of homogeneity
1947 /// test in 2xN tables. Biometrics 21, 19-33.
1948 /// - [6] Seber, G.A.F., Lee, A.J., 2003, Linear Regression Analysis.
1949 /// John Wiley & Sons Inc., New York.
1950 
1951 Double_t TH1::Chi2Test(const TH1* h2, Option_t *option, Double_t *res) const
1952 {
1953  Double_t chi2 = 0;
1954  Int_t ndf = 0, igood = 0;
1955 
1956  TString opt = option;
1957  opt.ToUpper();
1958 
1959  Double_t prob = Chi2TestX(h2,chi2,ndf,igood,option,res);
1960 
1961  if(opt.Contains("P")) {
1962  printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
1963  }
1964  if(opt.Contains("CHI2/NDF")) {
1965  if (ndf == 0) return 0;
1966  return chi2/ndf;
1967  }
1968  if(opt.Contains("CHI2")) {
1969  return chi2;
1970  }
1971 
1972  return prob;
1973 }
1974 
1975 ////////////////////////////////////////////////////////////////////////////////
1976 /// The computation routine of the Chisquare test. For the method description,
1977 /// see Chi2Test() function.
1978 ///
1979 /// \return p-value
1980 /// \param[in] h2 the second histogram
1981 /// \param[in] option
1982 /// - "UU" = experiment experiment comparison (unweighted-unweighted)
1983 /// - "UW" = experiment MC comparison (unweighted-weighted). Note that the first
1984 /// histogram should be unweighted
1985 /// - "WW" = MC MC comparison (weighted-weighted)
1986 /// - "NORM" = if one or both histograms is scaled
1987 /// - "OF" = overflows included
1988 /// - "UF" = underflows included
1989 /// by default underflows and overflows are not included
1990 /// \param[out] igood test output
1991 /// - igood=0 - no problems
1992 /// - For unweighted unweighted comparison
1993 /// - igood=1'There is a bin in the 1st histogram with less than 1 event'
1994 /// - igood=2'There is a bin in the 2nd histogram with less than 1 event'
1995 /// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
1996 /// - For unweighted weighted comparison
1997 /// - igood=1'There is a bin in the 1st histogram with less then 1 event'
1998 /// - igood=2'There is a bin in the 2nd histogram with less then 10 effective number of events'
1999 /// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2000 /// - For weighted weighted comparison
2001 /// - igood=1'There is a bin in the 1st histogram with less then 10 effective
2002 /// number of events'
2003 /// - igood=2'There is a bin in the 2nd histogram with less then 10 effective
2004 /// number of events'
2005 /// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2006 /// \param[out] chi2 chisquare of the test
2007 /// \param[out] ndf number of degrees of freedom (important, when both histograms have the same empty bins)
2008 /// \param[out] res normalized residuals for further analysis
2009 
2010 Double_t TH1::Chi2TestX(const TH1* h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option, Double_t *res) const
2011 {
2012 
2013  Int_t i_start, i_end;
2014  Int_t j_start, j_end;
2015  Int_t k_start, k_end;
2016 
2017  Double_t sum1 = 0.0, sumw1 = 0.0;
2018  Double_t sum2 = 0.0, sumw2 = 0.0;
2019 
2020  chi2 = 0.0;
2021  ndf = 0;
2022 
2023  TString opt = option;
2024  opt.ToUpper();
2025 
2026  if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
2027 
2028  const TAxis *xaxis1 = GetXaxis();
2029  const TAxis *xaxis2 = h2->GetXaxis();
2030  const TAxis *yaxis1 = GetYaxis();
2031  const TAxis *yaxis2 = h2->GetYaxis();
2032  const TAxis *zaxis1 = GetZaxis();
2033  const TAxis *zaxis2 = h2->GetZaxis();
2034 
2035  Int_t nbinx1 = xaxis1->GetNbins();
2036  Int_t nbinx2 = xaxis2->GetNbins();
2037  Int_t nbiny1 = yaxis1->GetNbins();
2038  Int_t nbiny2 = yaxis2->GetNbins();
2039  Int_t nbinz1 = zaxis1->GetNbins();
2040  Int_t nbinz2 = zaxis2->GetNbins();
2041 
2042  //check dimensions
2043  if (this->GetDimension() != h2->GetDimension() ){
2044  Error("Chi2TestX","Histograms have different dimensions.");
2045  return 0.0;
2046  }
2047 
2048  //check number of channels
2049  if (nbinx1 != nbinx2) {
2050  Error("Chi2TestX","different number of x channels");
2051  }
2052  if (nbiny1 != nbiny2) {
2053  Error("Chi2TestX","different number of y channels");
2054  }
2055  if (nbinz1 != nbinz2) {
2056  Error("Chi2TestX","different number of z channels");
2057  }
2058 
2059  //check for ranges
2060  i_start = j_start = k_start = 1;
2061  i_end = nbinx1;
2062  j_end = nbiny1;
2063  k_end = nbinz1;
2064 
2065  if (xaxis1->TestBit(TAxis::kAxisRange)) {
2066  i_start = xaxis1->GetFirst();
2067  i_end = xaxis1->GetLast();
2068  }
2069  if (yaxis1->TestBit(TAxis::kAxisRange)) {
2070  j_start = yaxis1->GetFirst();
2071  j_end = yaxis1->GetLast();
2072  }
2073  if (zaxis1->TestBit(TAxis::kAxisRange)) {
2074  k_start = zaxis1->GetFirst();
2075  k_end = zaxis1->GetLast();
2076  }
2077 
2078 
2079  if (opt.Contains("OF")) {
2080  if (GetDimension() == 3) k_end = ++nbinz1;
2081  if (GetDimension() >= 2) j_end = ++nbiny1;
2082  if (GetDimension() >= 1) i_end = ++nbinx1;
2083  }
2084 
2085  if (opt.Contains("UF")) {
2086  if (GetDimension() == 3) k_start = 0;
2087  if (GetDimension() >= 2) j_start = 0;
2088  if (GetDimension() >= 1) i_start = 0;
2089  }
2090 
2091  ndf = (i_end - i_start + 1) * (j_end - j_start + 1) * (k_end - k_start + 1) - 1;
2092 
2093  Bool_t comparisonUU = opt.Contains("UU");
2094  Bool_t comparisonUW = opt.Contains("UW");
2095  Bool_t comparisonWW = opt.Contains("WW");
2096  Bool_t scaledHistogram = opt.Contains("NORM");
2097 
2098  if (scaledHistogram && !comparisonUU) {
2099  Info("Chi2TestX", "NORM option should be used together with UU option. It is ignored");
2100  }
2101 
2102  // look at histo global bin content and effective entries
2103  Stat_t s[kNstat];
2104  GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2105  Double_t sumBinContent1 = s[0];
2106  Double_t effEntries1 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2107 
2108  h2->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2109  Double_t sumBinContent2 = s[0];
2110  Double_t effEntries2 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2111 
2112  if (!comparisonUU && !comparisonUW && !comparisonWW ) {
2113  // deduce automatically from type of histogram
2114  if (TMath::Abs(sumBinContent1 - effEntries1) < 1) {
2115  if ( TMath::Abs(sumBinContent2 - effEntries2) < 1) comparisonUU = true;
2116  else comparisonUW = true;
2117  }
2118  else comparisonWW = true;
2119  }
2120  // check unweighted histogram
2121  if (comparisonUW) {
2122  if (TMath::Abs(sumBinContent1 - effEntries1) >= 1) {
2123  Warning("Chi2TestX","First histogram is not unweighted and option UW has been requested");
2124  }
2125  }
2126  if ( (!scaledHistogram && comparisonUU) ) {
2127  if ( ( TMath::Abs(sumBinContent1 - effEntries1) >= 1) || (TMath::Abs(sumBinContent2 - effEntries2) >= 1) ) {
2128  Warning("Chi2TestX","Both histograms are not unweighted and option UU has been requested");
2129  }
2130  }
2131 
2132 
2133  //get number of events in histogram
2134  if (comparisonUU && scaledHistogram) {
2135  for (Int_t i = i_start; i <= i_end; ++i) {
2136  for (Int_t j = j_start; j <= j_end; ++j) {
2137  for (Int_t k = k_start; k <= k_end; ++k) {
2138 
2139  Int_t bin = GetBin(i, j, k);
2140 
2141  Double_t cnt1 = RetrieveBinContent(bin);
2142  Double_t cnt2 = h2->RetrieveBinContent(bin);
2143  Double_t e1sq = GetBinErrorSqUnchecked(bin);
2144  Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2145 
2146  if (e1sq > 0.0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2147  else cnt1 = 0.0;
2148 
2149  if (e2sq > 0.0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2150  else cnt2 = 0.0;
2151 
2152  // sum contents
2153  sum1 += cnt1;
2154  sum2 += cnt2;
2155  sumw1 += e1sq;
2156  sumw2 += e2sq;
2157  }
2158  }
2159  }
2160  if (sumw1 <= 0.0 || sumw2 <= 0.0) {
2161  Error("Chi2TestX", "Cannot use option NORM when one histogram has all zero errors");
2162  return 0.0;
2163  }
2164 
2165  } else {
2166  for (Int_t i = i_start; i <= i_end; ++i) {
2167  for (Int_t j = j_start; j <= j_end; ++j) {
2168  for (Int_t k = k_start; k <= k_end; ++k) {
2169 
2170  Int_t bin = GetBin(i, j, k);
2171 
2172  sum1 += RetrieveBinContent(bin);
2173  sum2 += h2->RetrieveBinContent(bin);
2174 
2175  if ( comparisonWW ) sumw1 += GetBinErrorSqUnchecked(bin);
2176  if ( comparisonUW || comparisonWW ) sumw2 += h2->GetBinErrorSqUnchecked(bin);
2177  }
2178  }
2179  }
2180  }
2181  //checks that the histograms are not empty
2182  if (sum1 == 0.0 || sum2 == 0.0) {
2183  Error("Chi2TestX","one histogram is empty");
2184  return 0.0;
2185  }
2186 
2187  if ( comparisonWW && ( sumw1 <= 0.0 && sumw2 <= 0.0 ) ){
2188  Error("Chi2TestX","Hist1 and Hist2 have both all zero errors\n");
2189  return 0.0;
2190  }
2191 
2192  //THE TEST
2193  Int_t m = 0, n = 0;
2194 
2195  //Experiment - experiment comparison
2196  if (comparisonUU) {
2197  Double_t sum = sum1 + sum2;
2198  for (Int_t i = i_start; i <= i_end; ++i) {
2199  for (Int_t j = j_start; j <= j_end; ++j) {
2200  for (Int_t k = k_start; k <= k_end; ++k) {
2201 
2202  Int_t bin = GetBin(i, j, k);
2203 
2204  Double_t cnt1 = RetrieveBinContent(bin);
2205  Double_t cnt2 = h2->RetrieveBinContent(bin);
2206 
2207  if (scaledHistogram) {
2208  // scale bin value to effective bin entries
2209  Double_t e1sq = GetBinErrorSqUnchecked(bin);
2210  Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2211 
2212  if (e1sq > 0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2213  else cnt1 = 0;
2214 
2215  if (e2sq > 0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2216  else cnt2 = 0;
2217  }
2218 
2219  if (Int_t(cnt1) == 0 && Int_t(cnt2) == 0) --ndf; // no data means one degree of freedom less
2220  else {
2221 
2222  Double_t cntsum = cnt1 + cnt2;
2223  Double_t nexp1 = cntsum * sum1 / sum;
2224  //Double_t nexp2 = binsum*sum2/sum;
2225 
2226  if (res) res[i - i_start] = (cnt1 - nexp1) / TMath::Sqrt(nexp1);
2227 
2228  if (cnt1 < 1) ++m;
2229  if (cnt2 < 1) ++n;
2230 
2231  //Habermann correction for residuals
2232  Double_t correc = (1. - sum1 / sum) * (1. - cntsum / sum);
2233  if (res) res[i - i_start] /= TMath::Sqrt(correc);
2234 
2235  Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2236  chi2 += delta * delta / cntsum;
2237  }
2238  }
2239  }
2240  }
2241  chi2 /= sum1 * sum2;
2242 
2243  // flag error only when of the two histogram is zero
2244  if (m) {
2245  igood += 1;
2246  Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2247  }
2248  if (n) {
2249  igood += 2;
2250  Info("Chi2TestX","There is a bin in h2 with less than 1 event.\n");
2251  }
2252 
2253  Double_t prob = TMath::Prob(chi2,ndf);
2254  return prob;
2255 
2256  }
2257 
2258  // unweighted - weighted comparison
2259  // case of error = 0 and content not zero is treated without problems by excluding second chi2 sum
2260  // and can be considered as a data-theory comparison
2261  if ( comparisonUW ) {
2262  for (Int_t i = i_start; i <= i_end; ++i) {
2263  for (Int_t j = j_start; j <= j_end; ++j) {
2264  for (Int_t k = k_start; k <= k_end; ++k) {
2265 
2266  Int_t bin = GetBin(i, j, k);
2267 
2268  Double_t cnt1 = RetrieveBinContent(bin);
2269  Double_t cnt2 = h2->RetrieveBinContent(bin);
2270  Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2271 
2272  // case both histogram have zero bin contents
2273  if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2274  --ndf; //no data means one degree of freedom less
2275  continue;
2276  }
2277 
2278  // case weighted histogram has zero bin content and error
2279  if (cnt2 * cnt2 == 0 && e2sq == 0) {
2280  if (sumw2 > 0) {
2281  // use as approximated error as 1 scaled by a scaling ratio
2282  // estimated from the total sum weight and sum weight squared
2283  e2sq = sumw2 / sum2;
2284  }
2285  else {
2286  // return error because infinite discrepancy here:
2287  // bin1 != 0 and bin2 =0 in a histogram with all errors zero
2288  Error("Chi2TestX","Hist2 has in bin (%d,%d,%d) zero content and zero errors\n", i, j, k);
2289  chi2 = 0; return 0;
2290  }
2291  }
2292 
2293  if (cnt1 < 1) m++;
2294  if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2295 
2296  Double_t var1 = sum2 * cnt2 - sum1 * e2sq;
2297  Double_t var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2298 
2299  // if cnt1 is zero and cnt2 = 1 and sum1 = sum2 var1 = 0 && var2 == 0
2300  // approximate by incrementing cnt1
2301  // LM (this need to be fixed for numerical errors)
2302  while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2303  sum1++;
2304  cnt1++;
2305  var1 = sum2 * cnt2 - sum1 * e2sq;
2306  var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2307  }
2308  var2 = TMath::Sqrt(var2);
2309 
2310  while (var1 + var2 == 0) {
2311  sum1++;
2312  cnt1++;
2313  var1 = sum2 * cnt2 - sum1 * e2sq;
2314  var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2315  while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2316  sum1++;
2317  cnt1++;
2318  var1 = sum2 * cnt2 - sum1 * e2sq;
2319  var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2320  }
2321  var2 = TMath::Sqrt(var2);
2322  }
2323 
2324  Double_t probb = (var1 + var2) / (2. * sum2 * sum2);
2325 
2326  Double_t nexp1 = probb * sum1;
2327  Double_t nexp2 = probb * sum2;
2328 
2329  Double_t delta1 = cnt1 - nexp1;
2330  Double_t delta2 = cnt2 - nexp2;
2331 
2332  chi2 += delta1 * delta1 / nexp1;
2333 
2334  if (e2sq > 0) {
2335  chi2 += delta2 * delta2 / e2sq;
2336  }
2337 
2338  if (res) {
2339  if (e2sq > 0) {
2340  Double_t temp1 = sum2 * e2sq / var2;
2341  Double_t temp2 = 1.0 + (sum1 * e2sq - sum2 * cnt2) / var2;
2342  temp2 = temp1 * temp1 * sum1 * probb * (1.0 - probb) + temp2 * temp2 * e2sq / 4.0;
2343  // invert sign here
2344  res[i - i_start] = - delta2 / TMath::Sqrt(temp2);
2345  }
2346  else
2347  res[i - i_start] = delta1 / TMath::Sqrt(nexp1);
2348  }
2349  }
2350  }
2351  }
2352 
2353  if (m) {
2354  igood += 1;
2355  Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2356  }
2357  if (n) {
2358  igood += 2;
2359  Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2360  }
2361 
2362  Double_t prob = TMath::Prob(chi2, ndf);
2363 
2364  return prob;
2365  }
2366 
2367  // weighted - weighted comparison
2368  if (comparisonWW) {
2369  for (Int_t i = i_start; i <= i_end; ++i) {
2370  for (Int_t j = j_start; j <= j_end; ++j) {
2371  for (Int_t k = k_start; k <= k_end; ++k) {
2372 
2373  Int_t bin = GetBin(i, j, k);
2374  Double_t cnt1 = RetrieveBinContent(bin);
2375  Double_t cnt2 = h2->RetrieveBinContent(bin);
2376  Double_t e1sq = GetBinErrorSqUnchecked(bin);
2377  Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2378 
2379  // case both histogram have zero bin contents
2380  // (use square of content to avoid numerical errors)
2381  if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2382  --ndf; //no data means one degree of freedom less
2383  continue;
2384  }
2385 
2386  if (e1sq == 0 && e2sq == 0) {
2387  // cannot treat case of booth histogram have zero zero errors
2388  Error("Chi2TestX","h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
2389  chi2 = 0; return 0;
2390  }
2391 
2392  Double_t sigma = sum1 * sum1 * e2sq + sum2 * sum2 * e1sq;
2393  Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2394  chi2 += delta * delta / sigma;
2395 
2396  if (res) {
2397  Double_t temp = cnt1 * sum1 * e2sq + cnt2 * sum2 * e1sq;
2398  Double_t probb = temp / sigma;
2399  Double_t z = 0;
2400  if (e1sq > e2sq) {
2401  Double_t d1 = cnt1 - sum1 * probb;
2402  Double_t s1 = e1sq * ( 1. - e2sq * sum1 * sum1 / sigma );
2403  z = d1 / TMath::Sqrt(s1);
2404  }
2405  else {
2406  Double_t d2 = cnt2 - sum2 * probb;
2407  Double_t s2 = e2sq * ( 1. - e1sq * sum2 * sum2 / sigma );
2408  z = -d2 / TMath::Sqrt(s2);
2409  }
2410  res[i - i_start] = z;
2411  }
2412 
2413  if (e1sq > 0 && cnt1 * cnt1 / e1sq < 10) m++;
2414  if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2415  }
2416  }
2417  }
2418  if (m) {
2419  igood += 1;
2420  Info("Chi2TestX","There is a bin in h1 with less than 10 effective events.\n");
2421  }
2422  if (n) {
2423  igood += 2;
2424  Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2425  }
2426  Double_t prob = TMath::Prob(chi2, ndf);
2427  return prob;
2428  }
2429  return 0;
2430 }
2431 ////////////////////////////////////////////////////////////////////////////////
2432 /// Compute and return the chisquare of this histogram with respect to a function
2433 /// The chisquare is computed by weighting each histogram point by the bin error
2434 /// By default the full range of the histogram is used.
2435 /// Use option "R" for restricting the chisquare calculation to the given range of the function
2436 /// Use option "L" for using the chisquare based on the poisson likelihood (Baker-Cousins Chisquare)
2437 
2438 Double_t TH1::Chisquare(TF1 * func, Option_t *option) const
2439 {
2440  if (!func) {
2441  Error("Chisquare","Function pointer is Null - return -1");
2442  return -1;
2443  }
2444 
2445  TString opt(option); opt.ToUpper();
2446  bool useRange = opt.Contains("R");
2447  bool usePL = opt.Contains("L");
2448 
2449  return ROOT::Fit::Chisquare(*this, *func, useRange, usePL);
2450 }
2451 
2452 ////////////////////////////////////////////////////////////////////////////////
2453 /// Remove all the content from the underflow and overflow bins, without changing the number of entries
2454 /// After calling this method, every undeflow and overflow bins will have content 0.0
2455 /// The Sumw2 is also cleared, since there is no more content in the bins
2456 
2457 void TH1::ClearUnderflowAndOverflow()
2458 {
2459  for (Int_t bin = 0; bin < fNcells; ++bin)
2460  if (IsBinUnderflow(bin) || IsBinOverflow(bin)) {
2461  UpdateBinContent(bin, 0.0);
2462  if (fSumw2.fN) fSumw2.fArray[bin] = 0.0;
2463  }
2464 }
2465 
2466 ////////////////////////////////////////////////////////////////////////////////
2467 /// Compute integral (cumulative sum of bins)
2468 /// The result stored in fIntegral is used by the GetRandom functions.
2469 /// This function is automatically called by GetRandom when the fIntegral
2470 /// array does not exist or when the number of entries in the histogram
2471 /// has changed since the previous call to GetRandom.
2472 /// The resulting integral is normalized to 1
2473 /// If the routine is called with the onlyPositive flag set an error will
2474 /// be produced in case of negative bin content and a NaN value returned
2475 
2476 Double_t TH1::ComputeIntegral(Bool_t onlyPositive)
2477 {
2478  if (fBuffer) BufferEmpty();
2479 
2480  // delete previously computed integral (if any)
2481  if (fIntegral) delete [] fIntegral;
2482 
2483  // - Allocate space to store the integral and compute integral
2484  Int_t nbinsx = GetNbinsX();
2485  Int_t nbinsy = GetNbinsY();
2486  Int_t nbinsz = GetNbinsZ();
2487  Int_t nbins = nbinsx * nbinsy * nbinsz;
2488 
2489  fIntegral = new Double_t[nbins + 2];
2490  Int_t ibin = 0; fIntegral[ibin] = 0;
2491 
2492  for (Int_t binz=1; binz <= nbinsz; ++binz) {
2493  for (Int_t biny=1; biny <= nbinsy; ++biny) {
2494  for (Int_t binx=1; binx <= nbinsx; ++binx) {
2495  ++ibin;
2496  Double_t y = RetrieveBinContent(GetBin(binx, biny, binz));
2497  if (onlyPositive && y < 0) {
2498  Error("ComputeIntegral","Bin content is negative - return a NaN value");
2499  fIntegral[nbins] = TMath::QuietNaN();
2500  break;
2501  }
2502  fIntegral[ibin] = fIntegral[ibin - 1] + y;
2503  }
2504  }
2505  }
2506 
2507  // - Normalize integral to 1
2508  if (fIntegral[nbins] == 0 ) {
2509  Error("ComputeIntegral", "Integral = zero"); return 0;
2510  }
2511  for (Int_t bin=1; bin <= nbins; ++bin) fIntegral[bin] /= fIntegral[nbins];
2512  fIntegral[nbins+1] = fEntries;
2513  return fIntegral[nbins];
2514 }
2515 
2516 ////////////////////////////////////////////////////////////////////////////////
2517 /// Return a pointer to the array of bins integral.
2518 /// if the pointer fIntegral is null, TH1::ComputeIntegral is called
2519 /// The array dimension is the number of bins in the histograms
2520 /// including underflow and overflow (fNCells)
2521 /// the last value integral[fNCells] is set to the number of entries of
2522 /// the histogram
2523 
2524 Double_t *TH1::GetIntegral()
2525 {
2526  if (!fIntegral) ComputeIntegral();
2527  return fIntegral;
2528 }
2529 
2530 ////////////////////////////////////////////////////////////////////////////////
2531 /// Return a pointer to an histogram containing the cumulative The
2532 /// cumulative can be computed both in the forward (default) or backward
2533 /// direction; the name of the new histogram is constructed from
2534 /// the name of this histogram with the suffix suffix appended.
2535 ///
2536 /// The cumulative distribution is formed by filling each bin of the
2537 /// resulting histogram with the sum of that bin and all previous
2538 /// (forward == kTRUE) or following (forward = kFALSE) bins.
2539 ///
2540 /// note: while cumulative distributions make sense in one dimension, you
2541 /// may not be getting what you expect in more than 1D because the concept
2542 /// of a cumulative distribution is much trickier to define; make sure you
2543 /// understand the order of summation before you use this method with
2544 /// histograms of dimension >= 2.
2545 
2546 TH1 *TH1::GetCumulative(Bool_t forward, const char* suffix) const
2547 {
2548  const Int_t nbinsx = GetNbinsX();
2549  const Int_t nbinsy = GetNbinsY();
2550  const Int_t nbinsz = GetNbinsZ();
2551  TH1* hintegrated = (TH1*) Clone(fName + suffix);
2552  hintegrated->Reset();
2553  if (forward) { // Forward computation
2554  Double_t sum = 0.;
2555  for (Int_t binz = 1; binz <= nbinsz; ++binz) {
2556  for (Int_t biny = 1; biny <= nbinsy; ++biny) {
2557  for (Int_t binx = 1; binx <= nbinsx; ++binx) {
2558  const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2559  sum += GetBinContent(bin);
2560  hintegrated->SetBinContent(bin, sum);
2561  }
2562  }
2563  }
2564  } else { // Backward computation
2565  Double_t sum = 0.;
2566  for (Int_t binz = nbinsz; binz >= 1; --binz) {
2567  for (Int_t biny = nbinsy; biny >= 1; --biny) {
2568  for (Int_t binx = nbinsx; binx >= 1; --binx) {
2569  const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2570  sum += GetBinContent(bin);
2571  hintegrated->SetBinContent(bin, sum);
2572  }
2573  }
2574  }
2575  }
2576  return hintegrated;
2577 }
2578 
2579 ////////////////////////////////////////////////////////////////////////////////
2580 /// Copy this histogram structure to newth1.
2581 ///
2582 /// Note that this function does not copy the list of associated functions.
2583 /// Use TObject::Clone to make a full copy of an histogram.
2584 ///
2585 /// Note also that the histogram it will be created in gDirectory (if AddDirectoryStatus()=true)
2586 /// or will not be added to any directory if AddDirectoryStatus()=false
2587 /// independently of the current directory stored in the original histogram
2588 
2589 void TH1::Copy(TObject &obj) const
2590 {
2591  if (((TH1&)obj).fDirectory) {
2592  // We are likely to change the hash value of this object
2593  // with TNamed::Copy, to keep things correct, we need to
2594  // clean up its existing entries.
2595  ((TH1&)obj).fDirectory->Remove(&obj);
2596  ((TH1&)obj).fDirectory = 0;
2597  }
2598  TNamed::Copy(obj);
2599  ((TH1&)obj).fDimension = fDimension;
2600  ((TH1&)obj).fNormFactor= fNormFactor;
2601  ((TH1&)obj).fNcells = fNcells;
2602  ((TH1&)obj).fBarOffset = fBarOffset;
2603  ((TH1&)obj).fBarWidth = fBarWidth;
2604  ((TH1&)obj).fOption = fOption;
2605  ((TH1&)obj).fBinStatErrOpt = fBinStatErrOpt;
2606  ((TH1&)obj).fBufferSize= fBufferSize;
2607  // copy the Buffer
2608  // delete first a previously existing buffer
2609  if (((TH1&)obj).fBuffer != 0) {
2610  delete [] ((TH1&)obj).fBuffer;
2611  ((TH1&)obj).fBuffer = 0;
2612  }
2613  if (fBuffer) {
2614  Double_t *buf = new Double_t[fBufferSize];
2615  for (Int_t i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
2616  // obj.fBuffer has been deleted before
2617  ((TH1&)obj).fBuffer = buf;
2618  }
2619 
2620 
2621  TArray* a = dynamic_cast<TArray*>(&obj);
2622  if (a) a->Set(fNcells);
2623  for (Int_t i = 0; i < fNcells; i++) ((TH1&)obj).UpdateBinContent(i, RetrieveBinContent(i));
2624 
2625  ((TH1&)obj).fEntries = fEntries;
2626 
2627  // which will call BufferEmpty(0) and set fBuffer[0] to a Maybe one should call
2628  // assignment operator on the TArrayD
2629 
2630  ((TH1&)obj).fTsumw = fTsumw;
2631  ((TH1&)obj).fTsumw2 = fTsumw2;
2632  ((TH1&)obj).fTsumwx = fTsumwx;
2633  ((TH1&)obj).fTsumwx2 = fTsumwx2;
2634  ((TH1&)obj).fMaximum = fMaximum;
2635  ((TH1&)obj).fMinimum = fMinimum;
2636 
2637  TAttLine::Copy(((TH1&)obj));
2638  TAttFill::Copy(((TH1&)obj));
2639  TAttMarker::Copy(((TH1&)obj));
2640  fXaxis.Copy(((TH1&)obj).fXaxis);
2641  fYaxis.Copy(((TH1&)obj).fYaxis);
2642  fZaxis.Copy(((TH1&)obj).fZaxis);
2643  ((TH1&)obj).fXaxis.SetParent(&obj);
2644  ((TH1&)obj).fYaxis.SetParent(&obj);
2645  ((TH1&)obj).fZaxis.SetParent(&obj);
2646  fContour.Copy(((TH1&)obj).fContour);
2647  fSumw2.Copy(((TH1&)obj).fSumw2);
2648  // fFunctions->Copy(((TH1&)obj).fFunctions);
2649  // when copying an histogram if the AddDirectoryStatus() is true it
2650  // will be added to gDirectory independently of the fDirectory stored.
2651  // and if the AddDirectoryStatus() is false it will not be added to
2652  // any directory (fDirectory = 0)
2653  if (fgAddDirectory && gDirectory) {
2654  gDirectory->Append(&obj);
2655  ((TH1&)obj).fFunctions->UseRWLock();
2656  ((TH1&)obj).fDirectory = gDirectory;
2657  } else
2658  ((TH1&)obj).fDirectory = 0;
2659 
2660 }
2661 
2662 ////////////////////////////////////////////////////////////////////////////////
2663 /// Make a complete copy of the underlying object. If 'newname' is set,
2664 /// the copy's name will be set to that name.
2665 
2666 TObject* TH1::Clone(const char* newname) const
2667 {
2668  TH1* obj = (TH1*)IsA()->GetNew()(0);
2669  Copy(*obj);
2670 
2671  // Now handle the parts that Copy doesn't do
2672  if(fFunctions) {
2673  // The Copy above might have published 'obj' to the ListOfCleanups.
2674  // Clone can call RecursiveRemove, for example via TCheckHashRecursiveRemoveConsistency
2675  // when dictionary information is initialized, so we need to
2676  // keep obj->fFunction valid during its execution and
2677  // protect the update with the write lock.
2678  auto newlist = (TList*)fFunctions->Clone();
2679  auto oldlist = obj->fFunctions;
2680  {
2681  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
2682  obj->fFunctions = newlist;
2683  }
2684  delete oldlist;
2685  }
2686  if(newname && strlen(newname) ) {
2687  obj->SetName(newname);
2688  }
2689  return obj;
2690 }
2691 
2692 ////////////////////////////////////////////////////////////////////////////////
2693 /// Perform the automatic addition of the histogram to the given directory
2694 ///
2695 /// Note this function is called in place when the semantic requires
2696 /// this object to be added to a directory (I.e. when being read from
2697 /// a TKey or being Cloned)
2698 
2699 void TH1::DirectoryAutoAdd(TDirectory *dir)
2700 {
2701  Bool_t addStatus = TH1::AddDirectoryStatus();
2702  if (addStatus) {
2703  SetDirectory(dir);
2704  if (dir) {
2705  ResetBit(kCanDelete);
2706  }
2707  }
2708 }
2709 
2710 ////////////////////////////////////////////////////////////////////////////////
2711 /// Compute distance from point px,py to a line.
2712 ///
2713 /// Compute the closest distance of approach from point px,py to elements
2714 /// of an histogram.
2715 /// The distance is computed in pixels units.
2716 ///
2717 /// #### Algorithm:
2718 /// Currently, this simple model computes the distance from the mouse
2719 /// to the histogram contour only.
2720 
2721 Int_t TH1::DistancetoPrimitive(Int_t px, Int_t py)
2722 {
2723  if (!fPainter) return 9999;
2724  return fPainter->DistancetoPrimitive(px,py);
2725 }
2726 
2727 ////////////////////////////////////////////////////////////////////////////////
2728 /// Performs the operation: `this = this/(c1*f1)`
2729 /// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2730 ///
2731 /// Only bins inside the function range are recomputed.
2732 /// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2733 /// you should call Sumw2 before making this operation.
2734 /// This is particularly important if you fit the histogram after TH1::Divide
2735 ///
2736 /// The function return kFALSE if the divide operation failed
2737 
2738 Bool_t TH1::Divide(TF1 *f1, Double_t c1)
2739 {
2740  if (!f1) {
2741  Error("Divide","Attempt to divide by a non-existing function");
2742  return kFALSE;
2743  }
2744 
2745  // delete buffer if it is there since it will become invalid
2746  if (fBuffer) BufferEmpty(1);
2747 
2748  Int_t nx = GetNbinsX() + 2; // normal bins + uf / of
2749  Int_t ny = GetNbinsY() + 2;
2750  Int_t nz = GetNbinsZ() + 2;
2751  if (fDimension < 2) ny = 1;
2752  if (fDimension < 3) nz = 1;
2753 
2754 
2755  SetMinimum();
2756  SetMaximum();
2757 
2758  // - Loop on bins (including underflows/overflows)
2759  Int_t bin, binx, biny, binz;
2760  Double_t cu, w;
2761  Double_t xx[3];
2762  Double_t *params = 0;
2763  f1->InitArgs(xx,params);
2764  for (binz = 0; binz < nz; ++binz) {
2765  xx[2] = fZaxis.GetBinCenter(binz);
2766  for (biny = 0; biny < ny; ++biny) {
2767  xx[1] = fYaxis.GetBinCenter(biny);
2768  for (binx = 0; binx < nx; ++binx) {
2769  xx[0] = fXaxis.GetBinCenter(binx);
2770  if (!f1->IsInside(xx)) continue;
2771  TF1::RejectPoint(kFALSE);
2772  bin = binx + nx * (biny + ny * binz);
2773  cu = c1 * f1->EvalPar(xx);
2774  if (TF1::RejectedPoint()) continue;
2775  if (cu) w = RetrieveBinContent(bin) / cu;
2776  else w = 0;
2777  UpdateBinContent(bin, w);
2778  if (fSumw2.fN) {
2779  if (cu != 0) fSumw2.fArray[bin] = GetBinErrorSqUnchecked(bin) / (cu * cu);
2780  else fSumw2.fArray[bin] = 0;
2781  }
2782  }
2783  }
2784  }
2785  ResetStats();
2786  return kTRUE;
2787 }
2788 
2789 ////////////////////////////////////////////////////////////////////////////////
2790 /// Divide this histogram by h1.
2791 ///
2792 /// `this = this/h1`
2793 /// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2794 /// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
2795 /// if not already set.
2796 /// The resulting errors are calculated assuming uncorrelated histograms.
2797 /// See the other TH1::Divide that gives the possibility to optionally
2798 /// compute binomial errors.
2799 ///
2800 /// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2801 /// you should call Sumw2 before making this operation.
2802 /// This is particularly important if you fit the histogram after TH1::Scale
2803 ///
2804 /// The function return kFALSE if the divide operation failed
2805 
2806 Bool_t TH1::Divide(const TH1 *h1)
2807 {
2808  if (!h1) {
2809  Error("Divide", "Input histogram passed does not exist (NULL).");
2810  return kFALSE;
2811  }
2812 
2813  // delete buffer if it is there since it will become invalid
2814  if (fBuffer) BufferEmpty(1);
2815 
2816  try {
2817  CheckConsistency(this,h1);
2818  } catch(DifferentNumberOfBins&) {
2819  Error("Divide","Cannot divide histograms with different number of bins");
2820  return kFALSE;
2821  } catch(DifferentAxisLimits&) {
2822  Warning("Divide","Dividing histograms with different axis limits");
2823  } catch(DifferentBinLimits&) {
2824  Warning("Divide","Dividing histograms with different bin limits");
2825  } catch(DifferentLabels&) {
2826  Warning("Divide","Dividing histograms with different labels");
2827  }
2828 
2829  // Create Sumw2 if h1 has Sumw2 set
2830  if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
2831 
2832  // - Loop on bins (including underflows/overflows)
2833  for (Int_t i = 0; i < fNcells; ++i) {
2834  Double_t c0 = RetrieveBinContent(i);
2835  Double_t c1 = h1->RetrieveBinContent(i);
2836  if (c1) UpdateBinContent(i, c0 / c1);
2837  else UpdateBinContent(i, 0);
2838 
2839  if(fSumw2.fN) {
2840  if (c1 == 0) { fSumw2.fArray[i] = 0; continue; }
2841  Double_t c1sq = c1 * c1;
2842  fSumw2.fArray[i] = (GetBinErrorSqUnchecked(i) * c1sq + h1->GetBinErrorSqUnchecked(i) * c0 * c0) / (c1sq * c1sq);
2843  }
2844  }
2845  ResetStats();
2846  return kTRUE;
2847 }
2848 
2849 ////////////////////////////////////////////////////////////////////////////////
2850 /// Replace contents of this histogram by the division of h1 by h2.
2851 ///
2852 /// `this = c1*h1/(c2*h2)`
2853 ///
2854 /// If errors are defined (see TH1::Sumw2), errors are also recalculated
2855 /// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
2856 /// if not already set.
2857 /// The resulting errors are calculated assuming uncorrelated histograms.
2858 /// However, if option ="B" is specified, Binomial errors are computed.
2859 /// In this case c1 and c2 do not make real sense and they are ignored.
2860 ///
2861 /// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2862 /// you should call Sumw2 before making this operation.
2863 /// This is particularly important if you fit the histogram after TH1::Divide
2864 ///
2865 /// Please note also that in the binomial case errors are calculated using standard
2866 /// binomial statistics, which means when b1 = b2, the error is zero.
2867 /// If you prefer to have efficiency errors not going to zero when the efficiency is 1, you must
2868 /// use the function TGraphAsymmErrors::BayesDivide, which will return an asymmetric and non-zero lower
2869 /// error for the case b1=b2.
2870 ///
2871 /// The function return kFALSE if the divide operation failed
2872 
2873 Bool_t TH1::Divide(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
2874 {
2875 
2876  TString opt = option;
2877  opt.ToLower();
2878  Bool_t binomial = kFALSE;
2879  if (opt.Contains("b")) binomial = kTRUE;
2880  if (!h1 || !h2) {
2881  Error("Divide", "At least one of the input histograms passed does not exist (NULL).");
2882  return kFALSE;
2883  }
2884 
2885  // delete buffer if it is there since it will become invalid
2886  if (fBuffer) BufferEmpty(1);
2887 
2888  try {
2889  CheckConsistency(h1,h2);
2890  CheckConsistency(this,h1);
2891  } catch(DifferentNumberOfBins&) {
2892  Error("Divide","Cannot divide histograms with different number of bins");
2893  return kFALSE;
2894  } catch(DifferentAxisLimits&) {
2895  Warning("Divide","Dividing histograms with different axis limits");
2896  } catch(DifferentBinLimits&) {
2897  Warning("Divide","Dividing histograms with different bin limits");
2898  } catch(DifferentLabels&) {
2899  Warning("Divide","Dividing histograms with different labels");
2900  }
2901 
2902 
2903  if (!c2) {
2904  Error("Divide","Coefficient of dividing histogram cannot be zero");
2905  return kFALSE;
2906  }
2907 
2908  // Create Sumw2 if h1 or h2 have Sumw2 set, or if binomial errors are explicitly requested
2909  if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0 || binomial)) Sumw2();
2910 
2911  SetMinimum();
2912  SetMaximum();
2913 
2914  // - Loop on bins (including underflows/overflows)
2915  for (Int_t i = 0; i < fNcells; ++i) {
2916  Double_t b1 = h1->RetrieveBinContent(i);
2917  Double_t b2 = h2->RetrieveBinContent(i);
2918  if (b2) UpdateBinContent(i, c1 * b1 / (c2 * b2));
2919  else UpdateBinContent(i, 0);
2920 
2921  if (fSumw2.fN) {
2922  if (b2 == 0) { fSumw2.fArray[i] = 0; continue; }
2923  Double_t b1sq = b1 * b1; Double_t b2sq = b2 * b2;
2924  Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
2925  Double_t e1sq = h1->GetBinErrorSqUnchecked(i);
2926  Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
2927  if (binomial) {
2928  if (b1 != b2) {
2929  // in the case of binomial statistics c1 and c2 must be 1 otherwise it does not make sense
2930  // c1 and c2 are ignored
2931  //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));//this is the formula in Hbook/Hoper1
2932  //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2); // old formula from G. Flucke
2933  // formula which works also for weighted histogram (see http://root-forum.cern.ch/viewtopic.php?t=3753 )
2934  fSumw2.fArray[i] = TMath::Abs( ( (1. - 2.* b1 / b2) * e1sq + b1sq * e2sq / b2sq ) / b2sq );
2935  } else {
2936  //in case b1=b2 error is zero
2937  //use TGraphAsymmErrors::BayesDivide for getting the asymmetric error not equal to zero
2938  fSumw2.fArray[i] = 0;
2939  }
2940  } else {
2941  fSumw2.fArray[i] = c1sq * c2sq * (e1sq * b2sq + e2sq * b1sq) / (c2sq * c2sq * b2sq * b2sq);
2942  }
2943  }
2944  }
2945  ResetStats();
2946  if (binomial)
2947  // in case of binomial division use denominator for number of entries
2948  SetEntries ( h2->GetEntries() );
2949 
2950  return kTRUE;
2951 }
2952 
2953 ////////////////////////////////////////////////////////////////////////////////
2954 /// Draw this histogram with options.
2955 ///
2956 /// Histograms are drawn via the THistPainter class. Each histogram has
2957 /// a pointer to its own painter (to be usable in a multithreaded program).
2958 /// The same histogram can be drawn with different options in different pads.
2959 /// When an histogram drawn in a pad is deleted, the histogram is
2960 /// automatically removed from the pad or pads where it was drawn.
2961 /// If an histogram is drawn in a pad, then filled again, the new status
2962 /// of the histogram will be automatically shown in the pad next time
2963 /// the pad is updated. One does not need to redraw the histogram.
2964 /// To draw the current version of an histogram in a pad, one can use
2965 /// `h->DrawCopy();`
2966 /// This makes a clone of the histogram. Once the clone is drawn, the original
2967 /// histogram may be modified or deleted without affecting the aspect of the
2968 /// clone.
2969 /// By default, TH1::Draw clears the current pad.
2970 ///
2971 /// One can use TH1::SetMaximum and TH1::SetMinimum to force a particular
2972 /// value for the maximum or the minimum scale on the plot.
2973 ///
2974 /// TH1::UseCurrentStyle can be used to change all histogram graphics
2975 /// attributes to correspond to the current selected style.
2976 /// This function must be called for each histogram.
2977 /// In case one reads and draws many histograms from a file, one can force
2978 /// the histograms to inherit automatically the current graphics style
2979 /// by calling before gROOT->ForceStyle();
2980 ///
2981 /// See the THistPainter class for a description of all the drawing options.
2982 
2983 void TH1::Draw(Option_t *option)
2984 {
2985  TString opt1 = option; opt1.ToLower();
2986  TString opt2 = option;
2987  Int_t index = opt1.Index("same");
2988 
2989  // Check if the string "same" is part of a TCutg name.
2990  if (index>=0) {
2991  Int_t indb = opt1.Index("[");
2992  if (indb>=0) {
2993  Int_t indk = opt1.Index("]");
2994  if (index>indb && index<indk) index = -1;
2995  }
2996  }
2997 
2998  // If there is no pad or an empty pad the "same" option is ignored.
2999  if (gPad) {
3000  if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
3001  if (index>=0) {
3002  if (gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
3003  gPad->GetY1() == 0 && gPad->GetY2() == 1 &&
3004  gPad->GetListOfPrimitives()->GetSize()==0) opt2.Remove(index,4);
3005  } else {
3006  //the following statement is necessary in case one attempts to draw
3007  //a temporary histogram already in the current pad
3008  if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(this);
3009  gPad->Clear();
3010  }
3011  gPad->IncrementPaletteColor(1, opt1);
3012  } else {
3013  if (index>=0) opt2.Remove(index,4);
3014  }
3015 
3016  AppendPad(opt2.Data());
3017 }
3018 
3019 ////////////////////////////////////////////////////////////////////////////////
3020 /// Copy this histogram and Draw in the current pad.
3021 ///
3022 /// Once the histogram is drawn into the pad, any further modification
3023 /// using graphics input will be made on the copy of the histogram,
3024 /// and not to the original object.
3025 /// By default a postfix "_copy" is added to the histogram name. Pass an empty postfix in case
3026 /// you want to draw an histogram with the same name
3027 ///
3028 /// See Draw for the list of options
3029 
3030 TH1 *TH1::DrawCopy(Option_t *option, const char * name_postfix) const
3031 {
3032  TString opt = option;
3033  opt.ToLower();
3034  if (gPad && !opt.Contains("same")) gPad->Clear();
3035  TString newName = (name_postfix) ? TString::Format("%s%s",GetName(),name_postfix) : "";
3036  TH1 *newth1 = (TH1 *)Clone(newName);
3037  newth1->SetDirectory(0);
3038  newth1->SetBit(kCanDelete);
3039  if (gPad) gPad->IncrementPaletteColor(1, opt);
3040 
3041  newth1->AppendPad(option);
3042  return newth1;
3043 }
3044 
3045 ////////////////////////////////////////////////////////////////////////////////
3046 /// Draw a normalized copy of this histogram.
3047 ///
3048 /// A clone of this histogram is normalized to norm and drawn with option.
3049 /// A pointer to the normalized histogram is returned.
3050 /// The contents of the histogram copy are scaled such that the new
3051 /// sum of weights (excluding under and overflow) is equal to norm.
3052 /// Note that the returned normalized histogram is not added to the list
3053 /// of histograms in the current directory in memory.
3054 /// It is the user's responsibility to delete this histogram.
3055 /// The kCanDelete bit is set for the returned object. If a pad containing
3056 /// this copy is cleared, the histogram will be automatically deleted.
3057 ///
3058 /// See Draw for the list of options
3059 
3060 TH1 *TH1::DrawNormalized(Option_t *option, Double_t norm) const
3061 {
3062  Double_t sum = GetSumOfWeights();
3063  if (sum == 0) {
3064  Error("DrawNormalized","Sum of weights is null. Cannot normalize histogram: %s",GetName());
3065  return 0;
3066  }
3067  Bool_t addStatus = TH1::AddDirectoryStatus();
3068  TH1::AddDirectory(kFALSE);
3069  TH1 *h = (TH1*)Clone();
3070  h->SetBit(kCanDelete);
3071  // in case of drawing with error options - scale correctly the error
3072  TString opt(option); opt.ToUpper();
3073  if (fSumw2.fN == 0) {
3074  h->Sumw2();
3075  // do not use in this case the "Error option " for drawing which is enabled by default since the normalized histogram has now errors
3076  if (opt.IsNull() || opt == "SAME") opt += "HIST";
3077  }
3078  h->Scale(norm/sum);
3079  if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
3080  if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
3081  h->Draw(opt);
3082  TH1::AddDirectory(addStatus);
3083  return h;
3084 }
3085 
3086 ////////////////////////////////////////////////////////////////////////////////
3087 /// Display a panel with all histogram drawing options.
3088 ///
3089 /// See class TDrawPanelHist for example
3090 
3091 void TH1::DrawPanel()
3092 {
3093  if (!fPainter) {Draw(); if (gPad) gPad->Update();}
3094  if (fPainter) fPainter->DrawPanel();
3095 }
3096 
3097 ////////////////////////////////////////////////////////////////////////////////
3098 /// Evaluate function f1 at the center of bins of this histogram.
3099 ///
3100 /// - If option "R" is specified, the function is evaluated only
3101 /// for the bins included in the function range.
3102 /// - If option "A" is specified, the value of the function is added to the
3103 /// existing bin contents
3104 /// - If option "S" is specified, the value of the function is used to
3105 /// generate a value, distributed according to the Poisson
3106 /// distribution, with f1 as the mean.
3107 
3108 void TH1::Eval(TF1 *f1, Option_t *option)
3109 {
3110  Double_t x[3];
3111  Int_t range, stat, add;
3112  if (!f1) return;
3113 
3114  TString opt = option;
3115  opt.ToLower();
3116  if (opt.Contains("a")) add = 1;
3117  else add = 0;
3118  if (opt.Contains("s")) stat = 1;
3119  else stat = 0;
3120  if (opt.Contains("r")) range = 1;
3121  else range = 0;
3122 
3123  // delete buffer if it is there since it will become invalid
3124  if (fBuffer) BufferEmpty(1);
3125 
3126  Int_t nbinsx = fXaxis.GetNbins();
3127  Int_t nbinsy = fYaxis.GetNbins();
3128  Int_t nbinsz = fZaxis.GetNbins();
3129  if (!add) Reset();
3130 
3131  for (Int_t binz = 1; binz <= nbinsz; ++binz) {
3132  x[2] = fZaxis.GetBinCenter(binz);
3133  for (Int_t biny = 1; biny <= nbinsy; ++biny) {
3134  x[1] = fYaxis.GetBinCenter(biny);
3135  for (Int_t binx = 1; binx <= nbinsx; ++binx) {
3136  Int_t bin = GetBin(binx,biny,binz);
3137  x[0] = fXaxis.GetBinCenter(binx);
3138  if (range && !f1->IsInside(x)) continue;
3139  Double_t fu = f1->Eval(x[0], x[1], x[2]);
3140  if (stat) fu = gRandom->PoissonD(fu);
3141  AddBinContent(bin, fu);
3142  if (fSumw2.fN) fSumw2.fArray[bin] += TMath::Abs(fu);
3143  }
3144  }
3145  }
3146 }
3147 
3148 ////////////////////////////////////////////////////////////////////////////////
3149 /// Execute action corresponding to one event.
3150 ///
3151 /// This member function is called when a histogram is clicked with the locator
3152 ///
3153 /// If Left button clicked on the bin top value, then the content of this bin
3154 /// is modified according to the new position of the mouse when it is released.
3155 
3156 void TH1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3157 {
3158  if (fPainter) fPainter->ExecuteEvent(event, px, py);
3159 }
3160 
3161 ////////////////////////////////////////////////////////////////////////////////
3162 /// This function allows to do discrete Fourier transforms of TH1 and TH2.
3163 /// Available transform types and flags are described below.
3164 ///
3165 /// To extract more information about the transform, use the function
3166 /// TVirtualFFT::GetCurrentTransform() to get a pointer to the current
3167 /// transform object.
3168 ///
3169 /// \param[out] h_output histogram for the output. If a null pointer is passed, a new histogram is created
3170 /// and returned, otherwise, the provided histogram is used and should be big enough
3171 /// \param[in] option option parameters consists of 3 parts:
3172 /// - option on what to return
3173 /// - "RE" - returns a histogram of the real part of the output
3174 /// - "IM" - returns a histogram of the imaginary part of the output
3175 /// - "MAG"- returns a histogram of the magnitude of the output
3176 /// - "PH" - returns a histogram of the phase of the output
3177 /// - option of transform type
3178 /// - "R2C" - real to complex transforms - default
3179 /// - "R2HC" - real to halfcomplex (special format of storing output data,
3180 /// results the same as for R2C)
3181 /// - "DHT" - discrete Hartley transform
3182 /// real to real transforms (sine and cosine):
3183 /// - "R2R_0", "R2R_1", "R2R_2", "R2R_3" - discrete cosine transforms of types I-IV
3184 /// - "R2R_4", "R2R_5", "R2R_6", "R2R_7" - discrete sine transforms of types I-IV
3185 /// To specify the type of each dimension of a 2-dimensional real to real
3186 /// transform, use options of form "R2R_XX", for example, "R2R_02" for a transform,
3187 /// which is of type "R2R_0" in 1st dimension and "R2R_2" in the 2nd.
3188 /// - option of transform flag
3189 /// - "ES" (from "estimate") - no time in preparing the transform, but probably sub-optimal
3190 /// performance
3191 /// - "M" (from "measure") - some time spend in finding the optimal way to do the transform
3192 /// - "P" (from "patient") - more time spend in finding the optimal way to do the transform
3193 /// - "EX" (from "exhaustive") - the most optimal way is found
3194 /// This option should be chosen depending on how many transforms of the same size and
3195 /// type are going to be done. Planning is only done once, for the first transform of this
3196 /// size and type. Default is "ES".
3197 ///
3198 /// Examples of valid options: "Mag R2C M" "Re R2R_11" "Im R2C ES" "PH R2HC EX"
3199 
3200 TH1* TH1::FFT(TH1* h_output, Option_t *option)
3201 {
3202 
3203  Int_t ndim[3];
3204  ndim[0] = this->GetNbinsX();
3205  ndim[1] = this->GetNbinsY();
3206  ndim[2] = this->GetNbinsZ();
3207 
3208  TVirtualFFT *fft;
3209  TString opt = option;
3210  opt.ToUpper();
3211  if (!opt.Contains("2R")){
3212  if (!opt.Contains("2C") && !opt.Contains("2HC") && !opt.Contains("DHT")) {
3213  //no type specified, "R2C" by default
3214  opt.Append("R2C");
3215  }
3216  fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
3217  }
3218  else {
3219  //find the kind of transform
3220  Int_t ind = opt.Index("R2R", 3);
3221  Int_t *kind = new Int_t[2];
3222  char t;
3223  t = opt[ind+4];
3224  kind[0] = atoi(&t);
3225  if (h_output->GetDimension()>1) {
3226  t = opt[ind+5];
3227  kind[1] = atoi(&t);
3228  }
3229  fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
3230  delete [] kind;
3231  }
3232 
3233  if (!fft) return 0;
3234  Int_t in=0;
3235  for (Int_t binx = 1; binx<=ndim[0]; binx++) {
3236  for (Int_t biny=1; biny<=ndim[1]; biny++) {
3237  for (Int_t binz=1; binz<=ndim[2]; binz++) {
3238  fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
3239  in++;
3240  }
3241  }
3242  }
3243  fft->Transform();
3244  h_output = TransformHisto(fft, h_output, option);
3245  return h_output;
3246 }
3247 
3248 ////////////////////////////////////////////////////////////////////////////////
3249 /// Increment bin with abscissa X by 1.
3250 ///
3251 /// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3252 /// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3253 ///
3254 /// If the storage of the sum of squares of weights has been triggered,
3255 /// via the function Sumw2, then the sum of the squares of weights is incremented
3256 /// by 1 in the bin corresponding to x.
3257 ///
3258 /// The function returns the corresponding bin number which has its content incremented by 1
3259 
3260 Int_t TH1::Fill(Double_t x)
3261 {
3262  if (fBuffer) return BufferFill(x,1);
3263 
3264  Int_t bin;
3265  fEntries++;
3266  bin =fXaxis.FindBin(x);
3267  if (bin <0) return -1;
3268  AddBinContent(bin);
3269  if (fSumw2.fN) ++fSumw2.fArray[bin];
3270  if (bin == 0 || bin > fXaxis.GetNbins()) {
3271  if (!GetStatOverflowsBehaviour()) return -1;
3272  }
3273  ++fTsumw;
3274  ++fTsumw2;
3275  fTsumwx += x;
3276  fTsumwx2 += x*x;
3277  return bin;
3278 }
3279 
3280 ////////////////////////////////////////////////////////////////////////////////
3281 /// Increment bin with abscissa X with a weight w.
3282 ///
3283 /// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3284 /// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3285 ///
3286 /// If the weight is not equal to 1, the storage of the sum of squares of
3287 /// weights is automatically triggered and the sum of the squares of weights is incremented
3288 /// by \f$ w^2 \f$ in the bin corresponding to x.
3289 ///
3290 /// The function returns the corresponding bin number which has its content incremented by w
3291 
3292 Int_t TH1::Fill(Double_t x, Double_t w)
3293 {
3294 
3295  if (fBuffer) return BufferFill(x,w);
3296 
3297  Int_t bin;
3298  fEntries++;
3299  bin =fXaxis.FindBin(x);
3300  if (bin <0) return -1;
3301  if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW) ) Sumw2(); // must be called before AddBinContent
3302  if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3303  AddBinContent(bin, w);
3304  if (bin == 0 || bin > fXaxis.GetNbins()) {
3305  if (!GetStatOverflowsBehaviour()) return -1;
3306  }
3307  Double_t z= w;
3308  fTsumw += z;
3309  fTsumw2 += z*z;
3310  fTsumwx += z*x;
3311  fTsumwx2 += z*x*x;
3312  return bin;
3313 }
3314 
3315 ////////////////////////////////////////////////////////////////////////////////
3316 /// Increment bin with namex with a weight w
3317 ///
3318 /// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3319 /// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3320 ///
3321 /// If the weight is not equal to 1, the storage of the sum of squares of
3322 /// weights is automatically triggered and the sum of the squares of weights is incremented
3323 /// by \f$ w^2 \f$ in the bin corresponding to x.
3324 ///
3325 /// The function returns the corresponding bin number which has its content
3326 /// incremented by w.
3327 
3328 Int_t TH1::Fill(const char *namex, Double_t w)
3329 {
3330  Int_t bin;
3331  fEntries++;
3332  bin =fXaxis.FindBin(namex);
3333  if (bin <0) return -1;
3334  if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3335  if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3336  AddBinContent(bin, w);
3337  if (bin == 0 || bin > fXaxis.GetNbins()) return -1;
3338  Double_t z= w;
3339  fTsumw += z;
3340  fTsumw2 += z*z;
3341  // this make sense if the histogram is not expanding (no axis can be extended)
3342  if (!CanExtendAllAxes()) {
3343  Double_t x = fXaxis.GetBinCenter(bin);
3344  fTsumwx += z*x;
3345  fTsumwx2 += z*x*x;
3346  }
3347  return bin;
3348 }
3349 
3350 ////////////////////////////////////////////////////////////////////////////////
3351 /// Fill this histogram with an array x and weights w.
3352 ///
3353 /// \param[in] ntimes number of entries in arrays x and w (array size must be ntimes*stride)
3354 /// \param[in] x array of values to be histogrammed
3355 /// \param[in] w array of weighs
3356 /// \param[in] stride step size through arrays x and w
3357 ///
3358 /// If the weight is not equal to 1, the storage of the sum of squares of
3359 /// weights is automatically triggered and the sum of the squares of weights is incremented
3360 /// by \f$ w^2 \f$ in the bin corresponding to x.
3361 /// if w is NULL each entry is assumed a weight=1
3362 
3363 void TH1::FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3364 {
3365  //If a buffer is activated, fill buffer
3366  if (fBuffer) {
3367  ntimes *= stride;
3368  Int_t i = 0;
3369  for (i=0;i<ntimes;i+=stride) {
3370  if (!fBuffer) break; // buffer can be deleted in BufferFill when is empty
3371  if (w) BufferFill(x[i],w[i]);
3372  else BufferFill(x[i], 1.);
3373  }
3374  // fill the remaining entries if the buffer has been deleted
3375  if (i < ntimes && fBuffer==0) {
3376  auto weights = w ? &w[i] : nullptr;
3377  DoFillN((ntimes-i)/stride,&x[i],weights,stride);
3378  }
3379  return;
3380  }
3381  // call internal method
3382  DoFillN(ntimes, x, w, stride);
3383 }
3384 
3385 ////////////////////////////////////////////////////////////////////////////////
3386 /// Internal method to fill histogram content from a vector
3387 /// called directly by TH1::BufferEmpty
3388 
3389 void TH1::DoFillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3390 {
3391  Int_t bin,i;
3392 
3393  fEntries += ntimes;
3394  Double_t ww = 1;
3395  Int_t nbins = fXaxis.GetNbins();
3396  ntimes *= stride;
3397  for (i=0;i<ntimes;i+=stride) {
3398  bin =fXaxis.FindBin(x[i]);
3399  if (bin <0) continue;
3400  if (w) ww = w[i];
3401  if (!fSumw2.fN && ww != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3402  if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
3403  AddBinContent(bin, ww);
3404  if (bin == 0 || bin > nbins) {
3405  if (!GetStatOverflowsBehaviour()) continue;
3406  }
3407  Double_t z= ww;
3408  fTsumw += z;
3409  fTsumw2 += z*z;
3410  fTsumwx += z*x[i];
3411  fTsumwx2 += z*x[i]*x[i];
3412  }
3413 }
3414 
3415 ////////////////////////////////////////////////////////////////////////////////
3416 /// Fill histogram following distribution in function fname.
3417 ///
3418 /// The distribution contained in the function fname (TF1) is integrated
3419 /// over the channel contents for the bin range of this histogram.
3420 /// It is normalized to 1.
3421 ///
3422 /// Getting one random number implies:
3423 /// - Generating a random number between 0 and 1 (say r1)
3424 /// - Look in which bin in the normalized integral r1 corresponds to
3425 /// - Fill histogram channel
3426 /// ntimes random numbers are generated
3427 ///
3428 /// One can also call TF1::GetRandom to get a random variate from a function.
3429 
3430 void TH1::FillRandom(const char *fname, Int_t ntimes)
3431 {
3432  Int_t bin, binx, ibin, loop;
3433  Double_t r1, x;
3434  // - Search for fname in the list of ROOT defined functions
3435  TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
3436  if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
3437 
3438  // - Allocate temporary space to store the integral and compute integral
3439 
3440  TAxis * xAxis = &fXaxis;
3441 
3442  // in case axis of histogram is not defined use the function axis
3443  if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
3444  Double_t xmin,xmax;
3445  f1->GetRange(xmin,xmax);
3446  Info("FillRandom","Using function axis and range [%g,%g]",xmin, xmax);
3447  xAxis = f1->GetHistogram()->GetXaxis();
3448  }
3449 
3450  Int_t first = xAxis->GetFirst();
3451  Int_t last = xAxis->GetLast();
3452  Int_t nbinsx = last-first+1;
3453 
3454  Double_t *integral = new Double_t[nbinsx+1];
3455  integral[0] = 0;
3456  for (binx=1;binx<=nbinsx;binx++) {
3457  Double_t fint = f1->Integral(xAxis->GetBinLowEdge(binx+first-1),xAxis->GetBinUpEdge(binx+first-1), 0.);
3458  integral[binx] = integral[binx-1] + fint;
3459  }
3460 
3461  // - Normalize integral to 1
3462  if (integral[nbinsx] == 0 ) {
3463  delete [] integral;
3464  Error("FillRandom", "Integral = zero"); return;
3465  }
3466  for (bin=1;bin<=nbinsx;bin++) integral[bin] /= integral[nbinsx];
3467 
3468  // --------------Start main loop ntimes
3469  for (loop=0;loop<ntimes;loop++) {
3470  r1 = gRandom->Rndm();
3471  ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
3472  //binx = 1 + ibin;
3473  //x = xAxis->GetBinCenter(binx); //this is not OK when SetBuffer is used
3474  x = xAxis->GetBinLowEdge(ibin+first)
3475  +xAxis->GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
3476  Fill(x);
3477  }
3478  delete [] integral;
3479 }
3480 
3481 ////////////////////////////////////////////////////////////////////////////////
3482 /// Fill histogram following distribution in histogram h.
3483 ///
3484 /// The distribution contained in the histogram h (TH1) is integrated
3485 /// over the channel contents for the bin range of this histogram.
3486 /// It is normalized to 1.
3487 ///
3488 /// Getting one random number implies:
3489 /// - Generating a random number between 0 and 1 (say r1)
3490 /// - Look in which bin in the normalized integral r1 corresponds to
3491 /// - Fill histogram channel ntimes random numbers are generated
3492 ///
3493 /// SPECIAL CASE when the target histogram has the same binning as the source.
3494 /// in this case we simply use a poisson distribution where
3495 /// the mean value per bin = bincontent/integral.
3496 
3497 void TH1::FillRandom(TH1 *h, Int_t ntimes)
3498 {
3499  if (!h) { Error("FillRandom", "Null histogram"); return; }
3500  if (fDimension != h->GetDimension()) {
3501  Error("FillRandom", "Histograms with different dimensions"); return;
3502  }
3503  if (std::isnan(h->ComputeIntegral(true))) {
3504  Error("FillRandom", "Histograms contains negative bins, does not represent probabilities");
3505  return;
3506  }
3507 
3508  //in case the target histogram has the same binning and ntimes much greater
3509  //than the number of bins we can use a fast method
3510  Int_t first = fXaxis.GetFirst();
3511  Int_t last = fXaxis.GetLast();
3512  Int_t nbins = last-first+1;
3513  if (ntimes > 10*nbins) {
3514  try {
3515  CheckConsistency(this,h);
3516  Double_t sumw = h->Integral(first,last);
3517  if (sumw == 0) return;
3518  Double_t sumgen = 0;
3519  for (Int_t bin=first;bin<=last;bin++) {
3520  Double_t mean = h->RetrieveBinContent(bin)*ntimes/sumw;
3521  Double_t cont = (Double_t)gRandom->Poisson(mean);
3522  sumgen += cont;
3523  AddBinContent(bin,cont);
3524  if (fSumw2.fN) fSumw2.fArray[bin] += cont;
3525  }
3526 
3527  // fix for the fluctuations in the total number n
3528  // since we use Poisson instead of multinomial
3529  // add a correction to have ntimes as generated entries
3530  Int_t i;
3531  if (sumgen < ntimes) {
3532  // add missing entries
3533  for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
3534  {
3535  Double_t x = h->GetRandom();
3536  Fill(x);
3537  }
3538  }
3539  else if (sumgen > ntimes) {
3540  // remove extra entries
3541  i = Int_t(sumgen+0.5);
3542  while( i > ntimes) {
3543  Double_t x = h->GetRandom();
3544  Int_t ibin = fXaxis.FindBin(x);
3545  Double_t y = RetrieveBinContent(ibin);
3546  // skip in case bin is empty
3547  if (y > 0) {
3548  SetBinContent(ibin, y-1.);
3549  i--;
3550  }
3551  }
3552  }
3553 
3554  ResetStats();
3555  return;
3556  }
3557  catch(std::exception&) {} // do nothing
3558  }
3559  // case of different axis and not too large ntimes
3560 
3561  if (h->ComputeIntegral() ==0) return;
3562  Int_t loop;
3563  Double_t x;
3564  for (loop=0;loop<ntimes;loop++) {
3565  x = h->GetRandom();
3566  Fill(x);
3567  }
3568 }
3569 
3570 ////////////////////////////////////////////////////////////////////////////////
3571 /// Return Global bin number corresponding to x,y,z
3572 ///
3573 /// 2-D and 3-D histograms are represented with a one dimensional
3574 /// structure. This has the advantage that all existing functions, such as
3575 /// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3576 /// This function tries to extend the axis if the given point belongs to an
3577 /// under-/overflow bin AND if CanExtendAllAxes() is true.
3578 ///
3579 /// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3580 
3581 Int_t TH1::FindBin(Double_t x, Double_t y, Double_t z)
3582 {
3583  if (GetDimension() < 2) {
3584  return fXaxis.FindBin(x);
3585  }
3586  if (GetDimension() < 3) {
3587  Int_t nx = fXaxis.GetNbins()+2;
3588  Int_t binx = fXaxis.FindBin(x);
3589  Int_t biny = fYaxis.FindBin(y);
3590  return binx + nx*biny;
3591  }
3592  if (GetDimension() < 4) {
3593  Int_t nx = fXaxis.GetNbins()+2;
3594  Int_t ny = fYaxis.GetNbins()+2;
3595  Int_t binx = fXaxis.FindBin(x);
3596  Int_t biny = fYaxis.FindBin(y);
3597  Int_t binz = fZaxis.FindBin(z);
3598  return binx + nx*(biny +ny*binz);
3599  }
3600  return -1;
3601 }
3602 
3603 ////////////////////////////////////////////////////////////////////////////////
3604 /// Return Global bin number corresponding to x,y,z.
3605 ///
3606 /// 2-D and 3-D histograms are represented with a one dimensional
3607 /// structure. This has the advantage that all existing functions, such as
3608 /// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3609 /// This function DOES NOT try to extend the axis if the given point belongs
3610 /// to an under-/overflow bin.
3611 ///
3612 /// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3613 
3614 Int_t TH1::FindFixBin(Double_t x, Double_t y, Double_t z) const
3615 {
3616  if (GetDimension() < 2) {
3617  return fXaxis.FindFixBin(x);
3618  }
3619  if (GetDimension() < 3) {
3620  Int_t nx = fXaxis.GetNbins()+2;
3621  Int_t binx = fXaxis.FindFixBin(x);
3622  Int_t biny = fYaxis.FindFixBin(y);
3623  return binx + nx*biny;
3624  }
3625  if (GetDimension() < 4) {
3626  Int_t nx = fXaxis.GetNbins()+2;
3627  Int_t ny = fYaxis.GetNbins()+2;
3628  Int_t binx = fXaxis.FindFixBin(x);
3629  Int_t biny = fYaxis.FindFixBin(y);
3630  Int_t binz = fZaxis.FindFixBin(z);
3631  return binx + nx*(biny +ny*binz);
3632  }
3633  return -1;
3634 }
3635 
3636 ////////////////////////////////////////////////////////////////////////////////
3637 /// Find first bin with content > threshold for axis (1=x, 2=y, 3=z)
3638 /// if no bins with content > threshold is found the function returns -1.
3639 /// The search will occur between the specified first and last bin. Specifying
3640 /// the value of the last bin to search to less than zero will search until the
3641 /// last defined bin.
3642 
3643 Int_t TH1::FindFirstBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3644 {
3645  if (fBuffer) ((TH1*)this)->BufferEmpty();
3646 
3647  if (axis < 1 || (axis > 1 && GetDimension() == 1 ) ||
3648  ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3 ) ) {
3649  Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3650  axis = 1;
3651  }
3652  if (firstBin < 1) {
3653  firstBin = 1;
3654  }
3655  Int_t nbinsx = fXaxis.GetNbins();
3656  Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3657  Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3658 
3659  if (axis == 1) {
3660  if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3661  lastBin = fXaxis.GetNbins();
3662  }
3663  for (Int_t binx = firstBin; binx <= lastBin; binx++) {
3664  for (Int_t biny = 1; biny <= nbinsy; biny++) {
3665  for (Int_t binz = 1; binz <= nbinsz; binz++) {
3666  if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binx;
3667  }
3668  }
3669  }
3670  }
3671  else if (axis == 2) {
3672  if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3673  lastBin = fYaxis.GetNbins();
3674  }
3675  for (Int_t biny = firstBin; biny <= lastBin; biny++) {
3676  for (Int_t binx = 1; binx <= nbinsx; binx++) {
3677  for (Int_t binz = 1; binz <= nbinsz; binz++) {
3678  if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return biny;
3679  }
3680  }
3681  }
3682  }
3683  else if (axis == 3) {
3684  if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3685  lastBin = fZaxis.GetNbins();
3686  }
3687  for (Int_t binz = firstBin; binz <= lastBin; binz++) {
3688  for (Int_t binx = 1; binx <= nbinsx; binx++) {
3689  for (Int_t biny = 1; biny <= nbinsy; biny++) {
3690  if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binz;
3691  }
3692  }
3693  }
3694  }
3695 
3696  return -1;
3697 }
3698 
3699 ////////////////////////////////////////////////////////////////////////////////
3700 /// Find last bin with content > threshold for axis (1=x, 2=y, 3=z)
3701 /// if no bins with content > threshold is found the function returns -1.
3702 /// The search will occur between the specified first and last bin. Specifying
3703 /// the value of the last bin to search to less than zero will search until the
3704 /// last defined bin.
3705 
3706 Int_t TH1::FindLastBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3707 {
3708  if (fBuffer) ((TH1*)this)->BufferEmpty();
3709 
3710 
3711  if (axis < 1 || ( axis > 1 && GetDimension() == 1 ) ||
3712  ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3) ) {
3713  Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3714  axis = 1;
3715  }
3716  if (firstBin < 1) {
3717  firstBin = 1;
3718  }
3719  Int_t nbinsx = fXaxis.GetNbins();
3720  Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3721  Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3722 
3723  if (axis == 1) {
3724  if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3725  lastBin = fXaxis.GetNbins();
3726  }
3727  for (Int_t binx = lastBin; binx >= firstBin; binx--) {
3728  for (Int_t biny = 1; biny <= nbinsy; biny++) {
3729  for (Int_t binz = 1; binz <= nbinsz; binz++) {
3730  if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binx;
3731  }
3732  }
3733  }
3734  }
3735  else if (axis == 2) {
3736  if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3737  lastBin = fYaxis.GetNbins();
3738  }
3739  for (Int_t biny = lastBin; biny >= firstBin; biny--) {
3740  for (Int_t binx = 1; binx <= nbinsx; binx++) {
3741  for (Int_t binz = 1; binz <= nbinsz; binz++) {
3742  if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return biny;
3743  }
3744  }
3745  }
3746  }
3747  else if (axis == 3) {
3748  if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3749  lastBin = fZaxis.GetNbins();
3750  }
3751  for (Int_t binz = lastBin; binz >= firstBin; binz--) {
3752  for (Int_t binx = 1; binx <= nbinsx; binx++) {
3753  for (Int_t biny = 1; biny <= nbinsy; biny++) {
3754  if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binz;
3755  }
3756  }
3757  }
3758  }
3759 
3760  return -1;
3761 }
3762 
3763 ////////////////////////////////////////////////////////////////////////////////
3764 /// Search object named name in the list of functions.
3765 
3766 TObject *TH1::FindObject(const char *name) const
3767 {
3768  if (fFunctions) return fFunctions->FindObject(name);
3769  return 0;
3770 }
3771 
3772 ////////////////////////////////////////////////////////////////////////////////
3773 /// Search object obj in the list of functions.
3774 
3775 TObject *TH1::FindObject(const TObject *obj) const
3776 {
3777  if (fFunctions) return fFunctions->FindObject(obj);
3778  return 0;
3779 }
3780 
3781 ////////////////////////////////////////////////////////////////////////////////
3782 /// Fit histogram with function fname.
3783 ///
3784 /// fname is the name of an already predefined function created by TF1 or TF2
3785 /// Predefined functions such as gaus, expo and poln are automatically
3786 /// created by ROOT.
3787 /// fname can also be a formula, accepted by the linear fitter (linear parts divided
3788 /// by "++" sign), for example "x++sin(x)" for fitting "[0]*x+[1]*sin(x)"
3789 ///
3790 /// This function finds a pointer to the TF1 object with name fname
3791 /// and calls TH1::Fit(TF1 *f1,...)
3792 
3793 TFitResultPtr TH1::Fit(const char *fname ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
3794 {
3795  char *linear;
3796  linear= (char*)strstr(fname, "++");
3797  Int_t ndim=GetDimension();
3798  if (linear){
3799  if (ndim<2){
3800  TF1 f1(fname, fname, xxmin, xxmax);
3801  return Fit(&f1,option,goption,xxmin,xxmax);
3802  }
3803  else if (ndim<3){
3804  TF2 f2(fname, fname);
3805  return Fit(&f2,option,goption,xxmin,xxmax);
3806  }
3807  else{
3808  TF3 f3(fname, fname);
3809  return Fit(&f3,option,goption,xxmin,xxmax);
3810  }
3811  }
3812  else{
3813  TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
3814  if (!f1) { Printf("Unknown function: %s",fname); return -1; }
3815  return Fit(f1,option,goption,xxmin,xxmax);
3816  }
3817 }
3818 
3819 ////////////////////////////////////////////////////////////////////////////////
3820 /// Fit histogram with function f1.
3821 ///
3822 /// \param[in] option fit options is given in parameter option.
3823 /// - "W" Set all weights to 1 for non empty bins; ignore error bars
3824 /// - "WW" Set all weights to 1 including empty bins; ignore error bars
3825 /// - "I" Use integral of function in bin, normalized by the bin volume,
3826 /// instead of value at bin center
3827 /// - "L" Use Loglikelihood method (default is chisquare method)
3828 /// - "WL" Use Loglikelihood method and bin contents are not integer,
3829 /// i.e. histogram is weighted (must have Sumw2() set)
3830 /// - "P" Use Pearson chi2 (using expected errors instead of observed errors)
3831 /// - "U" Use a User specified fitting algorithm (via SetFCN)
3832 /// - "Q" Quiet mode (minimum printing)
3833 /// - "V" Verbose mode (default is between Q and V)
3834 /// - "E" Perform better Errors estimation using Minos technique
3835 /// - "B" User defined parameter settings are used for predefined functions
3836 /// like "gaus", "expo", "poln", "landau".
3837 /// Use this option when you want to fix one or more parameters for these functions.
3838 /// - "M" More. Improve fit results.
3839 /// It uses the IMPROVE command of TMinuit (see TMinuit::mnimpr).
3840 /// This algorithm attempts to improve the found local minimum by searching for a
3841 /// better one.
3842 /// - "R" Use the Range specified in the function range
3843 /// - "N" Do not store the graphics function, do not draw
3844 /// - "0" Do not plot the result of the fit. By default the fitted function
3845 /// is drawn unless the option"N" above is specified.
3846 /// - "+" Add this new fitted function to the list of fitted functions
3847 /// (by default, any previous function is deleted)
3848 /// - "C" In case of linear fitting, don't calculate the chisquare
3849 /// (saves time)
3850 /// - "F" If fitting a polN, switch to minuit fitter
3851 /// - "S" The result of the fit is returned in the TFitResultPtr
3852 /// (see below Access to the Fit Result)
3853 /// \param[in] goption specify a list of graphics options. See TH1::Draw for a complete list of these options.
3854 /// \param[in] xxmin range
3855 /// \param[in] xxmax range
3856 ///
3857 /// In order to use the Range option, one must first create a function
3858 /// with the expression to be fitted. For example, if your histogram
3859 /// has a defined range between -4 and 4 and you want to fit a gaussian
3860 /// only in the interval 1 to 3, you can do:
3861 ///
3862 /// ~~~ {.cpp}
3863 /// TF1 *f1 = new TF1("f1", "gaus", 1, 3);
3864 /// histo->Fit("f1", "R");
3865 /// ~~~
3866 ///
3867 /// ## Setting initial conditions
3868 /// Parameters must be initialized before invoking the Fit function.
3869 /// The setting of the parameter initial values is automatic for the
3870 /// predefined functions : poln, expo, gaus, landau. One can however disable
3871 /// this automatic computation by specifying the option "B".
3872 /// Note that if a predefined function is defined with an argument,
3873 /// eg, gaus(0), expo(1), you must specify the initial values for
3874 /// the parameters.
3875 /// You can specify boundary limits for some or all parameters via
3876 ///
3877 /// ~~~ {.cpp}
3878 /// f1->SetParLimits(p_number, parmin, parmax);
3879 /// ~~~
3880 ///
3881 /// if parmin>=parmax, the parameter is fixed
3882 /// Note that you are not forced to fix the limits for all parameters.
3883 /// For example, if you fit a function with 6 parameters, you can do:
3884 ///
3885 /// ~~~ {.cpp}
3886 /// func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
3887 /// func->SetParLimits(3, -10, -4);
3888 /// func->FixParameter(4, 0);
3889 /// func->SetParLimits(5, 1, 1);
3890 /// ~~~
3891 ///
3892 /// With this setup, parameters 0->2 can vary freely
3893 /// Parameter 3 has boundaries [-10,-4] with initial value -8
3894 /// Parameter 4 is fixed to 0
3895 /// Parameter 5 is fixed to 100.
3896 /// When the lower limit and upper limit are equal, the parameter is fixed.
3897 /// However to fix a parameter to 0, one must call the FixParameter function.
3898 ///
3899 /// Note that option "I" gives better results but is slower.
3900 ///
3901 /// #### Changing the fitting objective function
3902 ///
3903 /// By default a chi square function is used for fitting. When option "L" (or "LL") is used
3904 /// a Poisson likelihood function (see note below) is used.
3905 /// The functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
3906 /// are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
3907 /// the file math/mathcore/src/FitUtil.cxx.
3908 /// To specify a User defined fitting function, specify option "U" and
3909 /// call the following functions:
3910 ///
3911 /// ~~~ {.cpp}
3912 /// TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction)
3913 /// ~~~
3914 ///
3915 /// where MyFittingFunction is of type:
3916 ///
3917 /// ~~~ {.cpp}
3918 /// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
3919 /// ~~~
3920 ///
3921 /// #### Chi2 Fits
3922 ///
3923 /// By default a chi2 (least-square) fit is performed on the histogram. The so-called modified least-square method
3924 /// is used where the residual for each bin is computed using as error the observed value (the bin error)
3925 ///
3926 /// \f[
3927 /// Chi2 = \sum{ \left(\frac{y(i) - f(x(i) | p )}{e(i)} \right)^2 }
3928 /// \f]
3929 ///
3930 /// where y(i) is the bin content for each bin i, x(i) is the bin center and e(i) is the bin error (sqrt(y(i) for
3931 /// an un-weighted histogram. Bins with zero errors are excluded from the fit. See also later the note on the treatment of empty bins.
3932 /// When using option "I" the residual is computed not using the function value at the bin center, f (x(i) | p), but the integral
3933 /// of the function in the bin, Integral{ f(x|p)dx } divided by the bin volume
3934 ///
3935 /// #### Likelihood Fits
3936 ///
3937 /// When using option "L" a likelihood fit is used instead of the default chi2 square fit.
3938 /// The likelihood is built assuming a Poisson probability density function for each bin.
3939 /// The negative log-likelihood to be minimized is
3940 ///
3941 /// \f[
3942 /// NLL = \sum{ log Poisson ( y(i) | f(x(i) | p ) ) }
3943 /// \f]
3944 ///
3945 /// The exact likelihood used is the Poisson likelihood described in this paper:
3946 /// S. Baker and R. D. Cousins, “Clarification of the use of chi-square and likelihood functions in fits to histograms,”
3947 /// Nucl. Instrum. Meth. 221 (1984) 437.
3948 ///
3949 /// This method can then be used only when the bin content represents counts (i.e. errors are sqrt(N) ).
3950 /// The likelihood method has the advantage of treating correctly bins with low statistics. In case of high
3951 /// statistics/bin the distribution of the bin content becomes a normal distribution and the likelihood and chi2 fit
3952 /// give the same result.
3953 ///
3954 /// The likelihood method, although a bit slower, it is therefore the recommended method in case of low
3955 /// bin statistics, where the chi2 method may give incorrect results, in particular when there are
3956 /// several empty bins (see also below).
3957 /// In case of a weighted histogram, it is possible to perform a likelihood fit by using the
3958 /// option "WL". Note a weighted histogram is an histogram which has been filled with weights and it
3959 /// contains the sum of the weight square ( TH1::Sumw2() has been called). The bin error for a weighted
3960 /// histogram is the square root of the sum of the weight square.
3961 ///
3962 /// #### Treatment of Empty Bins
3963 ///
3964 /// Empty bins, which have the content equal to zero AND error equal to zero,
3965 /// are excluded by default from the chisquare fit, but they are considered in the likelihood fit.
3966 /// since they affect the likelihood if the function value in these bins is not negligible.
3967 /// When using option "WW" these bins will be considered in the chi2 fit with an error of 1.
3968 /// Note that if the histogram is having bins with zero content and non zero-errors they are considered as
3969 /// any other bins in the fit. Instead bins with zero error and non-zero content are excluded in the chi2 fit.
3970 /// A likelihood fit should also not be performed on such an histogram, since we are assuming a wrong pdf for each bin.
3971 /// In general, one should not fit an histogram with non-empty bins and zero errors, apart if all the bins have zero errors.
3972 /// In this case one could use the option "w", which gives a weight=1 for each bin (unweighted least-square fit).
3973 ///
3974 /// #### Fitting a histogram of dimension N with a function of dimension N-1
3975 ///
3976 /// It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
3977 /// In this case the option "Integral" is not allowed and each cell has
3978 /// equal weight.
3979 ///
3980 /// #### Associated functions
3981 ///
3982 /// One or more object (typically a TF1*) can be added to the list
3983 /// of functions (fFunctions) associated to each histogram.
3984 /// When TH1::Fit is invoked, the fitted function is added to this list.
3985 /// Given an histogram h, one can retrieve an associated function
3986 /// with:
3987 ///
3988 /// ~~~ {.cpp}
3989 /// TF1 *myfunc = h->GetFunction("myfunc");
3990 /// ~~~
3991 ///
3992 /// #### Access to the fit result
3993 ///
3994 /// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
3995 /// By default the TFitResultPtr contains only the status of the fit which is return by an
3996 /// automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
3997 ///
3998 /// ~~~ {.cpp}
3999 /// Int_t fitStatus = h->Fit(myFunc)
4000 /// ~~~
4001 ///
4002 /// If the option "S" is instead used, TFitResultPtr contains the TFitResult and behaves as a smart
4003 /// pointer to it. For example one can do:
4004 ///
4005 /// ~~~ {.cpp}
4006 /// TFitResultPtr r = h->Fit(myFunc,"S");
4007 /// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
4008 /// Double_t chi2 = r->Chi2(); // to retrieve the fit chi2
4009 /// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
4010 /// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
4011 /// r->Print("V"); // print full information of fit including covariance matrix
4012 /// r->Write(); // store the result in a file
4013 /// ~~~
4014 ///
4015 /// The fit parameters, error and chi2 (but not covariance matrix) can be retrieved also
4016 /// from the fitted function.
4017 /// If the histogram is made persistent, the list of
4018 /// associated functions is also persistent. Given a pointer (see above)
4019 /// to an associated function myfunc, one can retrieve the function/fit
4020 /// parameters with calls such as:
4021 ///
4022 /// ~~~ {.cpp}
4023 /// Double_t chi2 = myfunc->GetChisquare();
4024 /// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
4025 /// Double_t err0 = myfunc->GetParError(0); //error on first parameter
4026 /// ~~~
4027 ///
4028 /// #### Access to the fit status
4029 ///
4030 /// The status of the fit can be obtained converting the TFitResultPtr to an integer
4031 /// independently if the fit option "S" is used or not:
4032 ///
4033 /// ~~~ {.cpp}
4034 /// TFitResultPtr r = h->Fit(myFunc,opt);
4035 /// Int_t fitStatus = r;
4036 /// ~~~
4037 ///
4038 /// The fitStatus is 0 if the fit is OK (i.e no error occurred).
4039 /// The value of the fit status code is negative in case of an error not connected with the
4040 /// minimization procedure, for example when a wrong function is used.
4041 /// Otherwise the return value is the one returned from the minimization procedure.
4042 /// When TMinuit (default case) or Minuit2 are used as minimizer the status returned is :
4043 /// `fitStatus = migradResult + 10*minosResult + 100*hesseResult + 1000*improveResult`.
4044 /// TMinuit will return 0 (for migrad, minos, hesse or improve) in case of success and 4 in
4045 /// case of error (see the documentation of TMinuit::mnexcm). So for example, for an error
4046 /// only in Minos but not in Migrad a fitStatus of 40 will be returned.
4047 /// Minuit2 will return also 0 in case of success and different values in migrad minos or
4048 /// hesse depending on the error. See in this case the documentation of
4049 /// Minuit2Minimizer::Minimize for the migradResult, Minuit2Minimizer::GetMinosError for the
4050 /// minosResult and Minuit2Minimizer::Hesse for the hesseResult.
4051 /// If other minimizers are used see their specific documentation for the status code returned.
4052 /// For example in the case of Fumili, for the status returned see TFumili::Minimize.
4053 ///
4054 /// #### Excluding points
4055 ///
4056 /// Use TF1::RejectPoint inside your fitting function to exclude points
4057 /// within a certain range from the fit. Example:
4058 ///
4059 /// ~~~ {.cpp}
4060 /// Double_t fline(Double_t *x, Double_t *par)
4061 /// {
4062 /// if (x[0] > 2.5 && x[0] < 3.5) {
4063 /// TF1::RejectPoint();
4064 /// return 0;
4065 /// }
4066 /// return par[0] + par[1]*x[0];
4067 /// }
4068 ///
4069 /// void exclude() {
4070 /// TF1 *f1 = new TF1("f1", "[0] +[1]*x +gaus(2)", 0, 5);
4071 /// f1->SetParameters(6, -1,5, 3, 0.2);
4072 /// TH1F *h = new TH1F("h", "background + signal", 100, 0, 5);
4073 /// h->FillRandom("f1", 2000);
4074 /// TF1 *fline = new TF1("fline", fline, 0, 5, 2);
4075 /// fline->SetParameters(2, -1);
4076 /// h->Fit("fline", "l");
4077 /// }
4078 /// ~~~
4079 ///
4080 /// #### Warning when using the option "0"
4081 ///
4082 /// When selecting the option "0", the fitted function is added to
4083 /// the list of functions of the histogram, but it is not drawn.
4084 /// You can undo what you disabled in the following way:
4085 ///
4086 /// ~~~ {.cpp}
4087 /// h.Fit("myFunction", "0"); // fit, store function but do not draw
4088 /// h.Draw(); function is not drawn
4089 /// const Int_t kNotDraw = 1<<9;
4090 /// h.GetFunction("myFunction")->ResetBit(kNotDraw);
4091 /// h.Draw(); // function is visible again
4092 /// ~~~
4093 ///
4094 /// #### Access to the Minimizer information during fitting
4095 ///
4096 /// This function calls, the ROOT::Fit::FitObject function implemented in HFitImpl.cxx
4097 /// which uses the ROOT::Fit::Fitter class. The Fitter class creates the objective function
4098 /// (e.g. chi2 or likelihood) and uses an implementation of the Minimizer interface for minimizing
4099 /// the function.
4100 /// The default minimizer is Minuit (class TMinuitMinimizer which calls TMinuit).
4101 /// The default can be set in the resource file in etc/system.rootrc. For example
4102 ///
4103 /// ~~~ {.cpp}
4104 /// Root.Fitter: Minuit2
4105 /// ~~~
4106 ///
4107 /// A different fitter can also be set via ROOT::Math::MinimizerOptions::SetDefaultMinimizer
4108 /// (or TVirtualFitter::SetDefaultFitter).
4109 /// For example ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");
4110 /// will set the usage of the BFGS algorithm of the GSL multi-dimensional minimization
4111 /// (implemented in libMathMore). ROOT::Math::MinimizerOptions can be used also to set other
4112 /// default options, like maximum number of function calls, minimization tolerance or print
4113 /// level. See the documentation of this class.
4114 ///
4115 /// For fitting linear functions (containing the "++" sign" and polN functions,
4116 /// the linear fitter is automatically initialized.
4117 
4118 TFitResultPtr TH1::Fit(TF1 *f1 ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
4119 {
4120  // implementation of Fit method is in file hist/src/HFitImpl.cxx
4121  Foption_t fitOption;
4122  ROOT::Fit::FitOptionsMake(ROOT::Fit::kHistogram,option,fitOption);
4123 
4124  // create range and minimizer options with default values
4125  ROOT::Fit::DataRange range(xxmin,xxmax);
4126  ROOT::Math::MinimizerOptions minOption;
4127 
4128  // need to empty the buffer before
4129  // (t.b.d. do a ML unbinned fit with buffer data)
4130  if (fBuffer) BufferEmpty();
4131 
4132  return ROOT::Fit::FitObject(this, f1 , fitOption , minOption, goption, range);
4133 }
4134 
4135 ////////////////////////////////////////////////////////////////////////////////
4136 /// Display a panel with all histogram fit options.
4137 ///
4138 /// See class TFitPanel for example
4139 
4140 void TH1::FitPanel()
4141 {
4142  if (!gPad)
4143  gROOT->MakeDefCanvas();
4144 
4145  if (!gPad) {
4146  Error("FitPanel", "Unable to create a default canvas");
4147  return;
4148  }
4149 
4150 
4151  // use plugin manager to create instance of TFitEditor
4152  TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
4153  if (handler && handler->LoadPlugin() != -1) {
4154  if (handler->ExecPlugin(2, gPad, this) == 0)
4155  Error("FitPanel", "Unable to create the FitPanel");
4156  }
4157  else
4158  Error("FitPanel", "Unable to find the FitPanel plug-in");
4159 }
4160 
4161 ////////////////////////////////////////////////////////////////////////////////
4162 /// Return an histogram containing the asymmetry of this histogram with h2,
4163 /// where the asymmetry is defined as:
4164 ///
4165 /// ~~~ {.cpp}
4166 /// Asymmetry = (h1 - h2)/(h1 + h2) where h1 = this
4167 /// ~~~
4168 ///
4169 /// works for 1D, 2D, etc. histograms
4170 /// c2 is an optional argument that gives a relative weight between the two
4171 /// histograms, and dc2 is the error on this weight. This is useful, for example,
4172 /// when forming an asymmetry between two histograms from 2 different data sets that
4173 /// need to be normalized to each other in some way. The function calculates
4174 /// the errors assuming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
4175 ///
4176 /// example: assuming 'h1' and 'h2' are already filled
4177 ///
4178 /// ~~~ {.cpp}
4179 /// h3 = h1->GetAsymmetry(h2)
4180 /// ~~~
4181 ///
4182 /// then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
4183 /// h1 and h2 are left intact.
4184 ///
4185 /// Note that it is the user's responsibility to manage the created histogram.
4186 /// The name of the returned histogram will be `Asymmetry_nameOfh1-nameOfh2`
4187 ///
4188 /// code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
4189 ///
4190 /// clone the histograms so top and bottom will have the
4191 /// correct dimensions:
4192 /// Sumw2 just makes sure the errors will be computed properly
4193 /// when we form sums and ratios below.
4194 
4195 TH1 *TH1::GetAsymmetry(TH1* h2, Double_t c2, Double_t dc2)
4196 {
4197  TH1 *h1 = this;
4198  TString name = TString::Format("Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4199  TH1 *asym = (TH1*)Clone(name);
4200 
4201  // set also the title
4202  TString title = TString::Format("(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4203  asym->SetTitle(title);
4204 
4205  asym->Sumw2();
4206  Bool_t addStatus = TH1::AddDirectoryStatus();
4207  TH1::AddDirectory(kFALSE);
4208  TH1 *top = (TH1*)asym->Clone();
4209  TH1 *bottom = (TH1*)asym->Clone();
4210  TH1::AddDirectory(addStatus);
4211 
4212  // form the top and bottom of the asymmetry, and then divide:
4213  top->Add(h1,h2,1,-c2);
4214  bottom->Add(h1,h2,1,c2);
4215  asym->Divide(top,bottom);
4216 
4217  Int_t xmax = asym->GetNbinsX();
4218  Int_t ymax = asym->GetNbinsY();
4219  Int_t zmax = asym->GetNbinsZ();
4220 
4221  if (h1->fBuffer) h1->BufferEmpty(1);
4222  if (h2->fBuffer) h2->BufferEmpty(1);
4223  if (bottom->fBuffer) bottom->BufferEmpty(1);
4224 
4225  // now loop over bins to calculate the correct errors
4226  // the reason this error calculation looks complex is because of c2
4227  for(Int_t i=1; i<= xmax; i++){
4228  for(Int_t j=1; j<= ymax; j++){
4229  for(Int_t k=1; k<= zmax; k++){
4230  Int_t bin = GetBin(i, j, k);
4231  // here some bin contents are written into variables to make the error
4232  // calculation a little more legible:
4233  Double_t a = h1->RetrieveBinContent(bin);
4234  Double_t b = h2->RetrieveBinContent(bin);
4235  Double_t bot = bottom->RetrieveBinContent(bin);
4236 
4237  // make sure there are some events, if not, then the errors are set = 0
4238  // automatically.
4239  //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
4240  if(bot < 1e-6){}
4241  else{
4242  // computation of errors by Christos Leonidopoulos
4243  Double_t dasq = h1->GetBinErrorSqUnchecked(bin);
4244  Double_t dbsq = h2->GetBinErrorSqUnchecked(bin);
4245  Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4246  asym->SetBinError(i,j,k,error);
4247  }
4248  }
4249  }
4250  }
4251  delete top;
4252  delete bottom;
4253 
4254  return asym;
4255 }
4256 
4257 ////////////////////////////////////////////////////////////////////////////////
4258 /// Static function
4259 /// return the default buffer size for automatic histograms
4260 /// the parameter fgBufferSize may be changed via SetDefaultBufferSize
4261 
4262 Int_t TH1::GetDefaultBufferSize()
4263 {
4264  return fgBufferSize;
4265 }
4266 
4267 ////////////////////////////////////////////////////////////////////////////////
4268 /// Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
4269 /// see TH1::SetDefaultSumw2.
4270 
4271 Bool_t TH1::GetDefaultSumw2()
4272 {
4273  return fgDefaultSumw2;
4274 }
4275 
4276 ////////////////////////////////////////////////////////////////////////////////
4277 /// Return the current number of entries.
4278 
4279 Double_t TH1::GetEntries() const
4280 {
4281  if (fBuffer) {
4282  Int_t nentries = (Int_t) fBuffer[0];
4283  if (nentries > 0) return nentries;
4284  }
4285 
4286  return fEntries;
4287 }
4288 
4289 ////////////////////////////////////////////////////////////////////////////////
4290 /// Number of effective entries of the histogram.
4291 ///
4292 /// \f[
4293 /// neff = \frac{(\sum Weights )^2}{(\sum Weight^2 )}
4294 /// \f]
4295 ///
4296 /// In case of an unweighted histogram this number is equivalent to the
4297 /// number of entries of the histogram.
4298 /// For a weighted histogram, this number corresponds to the hypothetical number of unweighted entries
4299 /// a histogram would need to have the same statistical power as this weighted histogram.
4300 /// Note: The underflow/overflow are included if one has set the TH1::StatOverFlows flag
4301 /// and if the statistics has been computed at filling time.
4302 /// If a range is set in the histogram the number is computed from the given range.
4303 
4304 Double_t TH1::GetEffectiveEntries() const
4305 {
4306  Stat_t s[kNstat];
4307  this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
4308  return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4309 }
4310 
4311 ////////////////////////////////////////////////////////////////////////////////
4312 /// Set highlight (enable/disable) mode for the histogram
4313 /// by default highlight mode is disable
4314 
4315 void TH1::SetHighlight(Bool_t set)
4316 {
4317  if (IsHighlight() == set) return;
4318  if (fDimension > 2) {
4319  Info("SetHighlight", "Supported only 1-D or 2-D histograms");
4320  return;
4321  }
4322 
4323  if (!fPainter) {
4324  Info("SetHighlight", "Need to draw histogram first");
4325  return;
4326  }
4327  SetBit(kIsHighlight, set);
4328  fPainter->SetHighlight();
4329 }
4330 
4331 ////////////////////////////////////////////////////////////////////////////////
4332 /// Redefines TObject::GetObjectInfo.
4333 /// Displays the histogram info (bin number, contents, integral up to bin
4334 /// corresponding to cursor position px,py
4335 
4336 char *TH1::GetObjectInfo(Int_t px, Int_t py) const
4337 {
4338  return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
4339 }
4340 
4341 ////////////////////////////////////////////////////////////////////////////////
4342 /// Return pointer to painter.
4343 /// If painter does not exist, it is created
4344 
4345 TVirtualHistPainter *TH1::GetPainter(Option_t *option)
4346 {
4347  if (!fPainter) {
4348  TString opt = option;
4349  opt.ToLower();
4350  if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
4351  //try to create TGLHistPainter
4352  TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
4353 
4354  if (handler && handler->LoadPlugin() != -1)
4355  fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
4356  }
4357  }
4358 
4359  if (!fPainter) fPainter = TVirtualHistPainter::HistPainter(this);
4360 
4361  return fPainter;
4362 }
4363 
4364 ////////////////////////////////////////////////////////////////////////////////
4365 /// Compute Quantiles for this histogram
4366 /// Quantile x_q of a probability distribution Function F is defined as
4367 ///
4368 /// ~~~ {.cpp}
4369 /// F(x_q) = q with 0 <= q <= 1.
4370 /// ~~~
4371 ///
4372 /// For instance the median x_0.5 of a distribution is defined as that value
4373 /// of the random variable for which the distribution function equals 0.5:
4374 ///
4375 /// ~~~ {.cpp}
4376 /// F(x_0.5) = Probability(x < x_0.5) = 0.5
4377 /// ~~~
4378 ///
4379 /// code from Eddy Offermann, Renaissance
4380 ///
4381 /// \param[in] nprobSum maximum size of array q and size of array probSum (if given)
4382 /// \param[in] probSum array of positions where quantiles will be computed.
4383 /// - if probSum is null, probSum will be computed internally and will
4384 /// have a size = number of bins + 1 in h. it will correspond to the
4385 /// quantiles calculated at the lowest edge of the histogram (quantile=0) and
4386 /// all the upper edges of the bins.
4387 /// - if probSum is not null, it is assumed to contain at least nprobSum values.
4388 /// \param[out] q array q filled with nq quantiles
4389 /// \return value nq (<=nprobSum) with the number of quantiles computed
4390 ///
4391 /// Note that the Integral of the histogram is automatically recomputed
4392 /// if the number of entries is different of the number of entries when
4393 /// the integral was computed last time. In case you do not use the Fill
4394 /// functions to fill your histogram, but SetBinContent, you must call
4395 /// TH1::ComputeIntegral before calling this function.
4396 ///
4397 /// Getting quantiles q from two histograms and storing results in a TGraph,
4398 /// a so-called QQ-plot
4399 ///
4400 /// ~~~ {.cpp}
4401 /// TGraph *gr = new TGraph(nprob);
4402 /// h1->GetQuantiles(nprob,gr->GetX());
4403 /// h2->GetQuantiles(nprob,gr->GetY());
4404 /// gr->Draw("alp");
4405 /// ~~~
4406 ///
4407 /// Example:
4408 ///
4409 /// ~~~ {.cpp}
4410 /// void quantiles() {
4411 /// // demo for quantiles
4412 /// const Int_t nq = 20;
4413 /// TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
4414 /// h->FillRandom("gaus",5000);
4415 ///
4416 /// Double_t xq[nq]; // position where to compute the quantiles in [0,1]
4417 /// Double_t yq[nq]; // array to contain the quantiles
4418 /// for (Int_t i=0;i<nq;i++) xq[i] = Float_t(i+1)/nq;
4419 /// h->GetQuantiles(nq,yq,xq);
4420 ///
4421 /// //show the original histogram in the top pad
4422 /// TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
4423 /// c1->Divide(1,2);
4424 /// c1->cd(1);
4425 /// h->Draw();
4426 ///
4427 /// // show the quantiles in the bottom pad
4428 /// c1->cd(2);
4429 /// gPad->SetGrid();
4430 /// TGraph *gr = new TGraph(nq,xq,yq);
4431 /// gr->SetMarkerStyle(21);
4432 /// gr->Draw("alp");
4433 /// }
4434 /// ~~~
4435 
4436 Int_t TH1::GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
4437 {
4438  if (GetDimension() > 1) {
4439  Error("GetQuantiles","Only available for 1-d histograms");
4440  return 0;
4441  }
4442 
4443  const Int_t nbins = GetXaxis()->GetNbins();
4444  if (!fIntegral) ComputeIntegral();
4445  if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4446 
4447  Int_t i, ibin;
4448  Double_t *prob = (Double_t*)probSum;
4449  Int_t nq = nprobSum;
4450  if (probSum == 0) {
4451  nq = nbins+1;
4452  prob = new Double_t[nq];
4453  prob[0] = 0;
4454  for (i=1;i<nq;i++) {
4455  prob[i] = fIntegral[i]/fIntegral[nbins];
4456  }
4457  }
4458 
4459  for (i = 0; i < nq; i++) {
4460  ibin = TMath::BinarySearch(nbins,fIntegral,prob[i]);
4461  while (ibin < nbins-1 && fIntegral[ibin+1] == prob[i]) {
4462  if (fIntegral[ibin+2] == prob[i]) ibin++;
4463  else break;
4464  }
4465  q[i] = GetBinLowEdge(ibin+1);
4466  const Double_t dint = fIntegral[ibin+1]-fIntegral[ibin];
4467  if (dint > 0) q[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4468  }
4469 
4470  if (!probSum) delete [] prob;
4471  return nq;
4472 }
4473 
4474 ////////////////////////////////////////////////////////////////////////////////
4475 /// Decode string choptin and fill fitOption structure.
4476 
4477 Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
4478 {
4479  ROOT::Fit::FitOptionsMake(ROOT::Fit::kHistogram, choptin,fitOption);
4480  return 1;
4481 }
4482 
4483 ////////////////////////////////////////////////////////////////////////////////
4484 /// Compute Initial values of parameters for a gaussian.
4485 
4486 void H1InitGaus()
4487 {
4488  Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4489  Int_t bin;
4490  const Double_t sqrtpi = 2.506628;
4491 
4492  // - Compute mean value and StdDev of the histogram in the given range
4493  TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
4494  TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4495  Int_t hxfirst = hFitter->GetXfirst();
4496  Int_t hxlast = hFitter->GetXlast();
4497  Double_t valmax = curHist->GetBinContent(hxfirst);
4498  Double_t binwidx = curHist->GetBinWidth(hxfirst);
4499  allcha = sumx = sumx2 = 0;
4500  for (bin=hxfirst;bin<=hxlast;bin++) {
4501  x = curHist->GetBinCenter(bin);
4502  val = TMath::Abs(curHist->GetBinContent(bin));
4503  if (val > valmax) valmax = val;
4504  sumx += val*x;
4505  sumx2 += val*x*x;
4506  allcha += val;
4507  }
4508  if (allcha == 0) return;
4509  mean = sumx/allcha;
4510  stddev = sumx2/allcha - mean*mean;
4511  if (stddev > 0) stddev = TMath::Sqrt(stddev);
4512  else stddev = 0;
4513  if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4514  //if the distribution is really gaussian, the best approximation
4515  //is binwidx*allcha/(sqrtpi*stddev)
4516  //However, in case of non-gaussian tails, this underestimates
4517  //the normalisation constant. In this case the maximum value
4518  //is a better approximation.
4519  //We take the average of both quantities
4520  Double_t constant = 0.5*(valmax+binwidx*allcha/(sqrtpi*stddev));
4521 
4522  //In case the mean value is outside the histo limits and
4523  //the StdDev is bigger than the range, we take
4524  // mean = center of bins
4525  // stddev = half range
4526  Double_t xmin = curHist->GetXaxis()->GetXmin();
4527  Double_t xmax = curHist->GetXaxis()->GetXmax();
4528  if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4529  mean = 0.5*(xmax+xmin);
4530  stddev = 0.5*(xmax-xmin);
4531  }
4532  TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4533  f1->SetParameter(0,constant);
4534  f1->SetParameter(1,mean);
4535  f1->SetParameter(2,stddev);
4536  f1->SetParLimits(2,0,10*stddev);
4537 }
4538 
4539 ////////////////////////////////////////////////////////////////////////////////
4540 /// Compute Initial values of parameters for an exponential.
4541 
4542 void H1InitExpo()
4543 {
4544  Double_t constant, slope;
4545  Int_t ifail;
4546  TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
4547  Int_t hxfirst = hFitter->GetXfirst();
4548  Int_t hxlast = hFitter->GetXlast();
4549  Int_t nchanx = hxlast - hxfirst + 1;
4550 
4551  H1LeastSquareLinearFit(-nchanx, constant, slope, ifail);
4552 
4553  TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4554  f1->SetParameter(0,constant);
4555  f1->SetParameter(1,slope);
4556 
4557 }
4558 
4559 ////////////////////////////////////////////////////////////////////////////////
4560 /// Compute Initial values of parameters for a polynom.
4561 
4562 void H1InitPolynom()
4563 {
4564  Double_t fitpar[25];
4565 
4566  TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
4567  TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4568  Int_t hxfirst = hFitter->GetXfirst();
4569  Int_t hxlast = hFitter->GetXlast();
4570  Int_t nchanx = hxlast - hxfirst + 1;
4571  Int_t npar = f1->GetNpar();
4572 
4573  if (nchanx <=1 || npar == 1) {
4574  TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4575  fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4576  } else {
4577  H1LeastSquareFit( nchanx, npar, fitpar);
4578  }
4579  for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4580 }
4581 
4582 ////////////////////////////////////////////////////////////////////////////////
4583 /// Least squares lpolynomial fitting without weights.
4584 ///
4585 /// \param[in] n number of points to fit
4586 /// \param[in] m number of parameters
4587 /// \param[in] a array of parameters
4588 ///
4589 /// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
4590 /// (E.Keil. revised by B.Schorr, 23.10.1981.)
4591 
4592 void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
4593 {
4594  const Double_t zero = 0.;
4595  const Double_t one = 1.;
4596  const Int_t idim = 20;
4597 
4598  Double_t b[400] /* was [20][20] */;
4599  Int_t i, k, l, ifail;
4600  Double_t power;
4601  Double_t da[20], xk, yk;
4602 
4603  if (m <= 2) {
4604  H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4605  return;
4606  }
4607  if (m > idim || m > n) return;
4608  b[0] = Double_t(n);
4609  da[0] = zero;
4610  for (l = 2; l <= m; ++l) {
4611  b[l-1] = zero;
4612  b[m + l*20 - 21] = zero;
4613  da[l-1] = zero;
4614  }
4615  TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
4616  TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4617  Int_t hxfirst = hFitter->GetXfirst();
4618  Int_t hxlast = hFitter->GetXlast();
4619  for (k = hxfirst; k <= hxlast; ++k) {
4620  xk = curHist->GetBinCenter(k);
4621  yk = curHist->GetBinContent(k);
4622  power = one;
4623  da[0] += yk;
4624  for (l = 2; l <= m; ++l) {
4625  power *= xk;
4626  b[l-1] += power;
4627  da[l-1] += power*yk;
4628  }
4629  for (l = 2; l <= m; ++l) {
4630  power *= xk;
4631  b[m + l*20 - 21] += power;
4632  }
4633  }
4634  for (i = 3; i <= m; ++i) {
4635  for (k = i; k <= m; ++k) {
4636  b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4637  }
4638  }
4639  H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
4640 
4641  for (i=0; i<m; ++i) a[i] = da[i];
4642 
4643 }
4644 
4645 ////////////////////////////////////////////////////////////////////////////////
4646 /// Least square linear fit without weights.
4647 ///
4648 /// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
4649 /// (added to LSQ by B. Schorr, 15.02.1982.)
4650 
4651 void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
4652 {
4653  Double_t xbar, ybar, x2bar;
4654  Int_t i, n;
4655  Double_t xybar;
4656  Double_t fn, xk, yk;
4657  Double_t det;
4658 
4659  n = TMath::Abs(ndata);
4660  ifail = -2;
4661  xbar = ybar = x2bar = xybar = 0;
4662  TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
4663  TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4664  Int_t hxfirst = hFitter->GetXfirst();
4665  Int_t hxlast = hFitter->GetXlast();
4666  for (i = hxfirst; i <= hxlast; ++i) {
4667  xk = curHist->GetBinCenter(i);
4668  yk = curHist->GetBinContent(i);
4669  if (ndata < 0) {
4670  if (yk <= 0) yk = 1e-9;
4671  yk = TMath::Log(yk);
4672  }
4673  xbar += xk;
4674  ybar += yk;
4675  x2bar += xk*xk;
4676  xybar += xk*yk;
4677  }
4678  fn = Double_t(n);
4679  det = fn*x2bar - xbar*xbar;
4680  ifail = -1;
4681  if (det <= 0) {
4682  a0 = ybar/fn;
4683  a1 = 0;
4684  return;
4685  }
4686  ifail = 0;
4687  a0 = (x2bar*ybar - xbar*xybar) / det;
4688  a1 = (fn*xybar - xbar*ybar) / det;
4689 
4690 }
4691 
4692 ////////////////////////////////////////////////////////////////////////////////
4693 /// Extracted from CERN Program library routine DSEQN.
4694 ///
4695 /// Translated to C++ by Rene Brun
4696 
4697 void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b)
4698 {
4699  Int_t a_dim1, a_offset, b_dim1, b_offset;
4700  Int_t nmjp1, i, j, l;
4701  Int_t im1, jp1, nm1, nmi;
4702  Double_t s1, s21, s22;
4703  const Double_t one = 1.;
4704 
4705  /* Parameter adjustments */
4706  b_dim1 = idim;
4707  b_offset = b_dim1 + 1;
4708  b -= b_offset;
4709  a_dim1 = idim;
4710  a_offset = a_dim1 + 1;
4711  a -= a_offset;
4712 
4713  if (idim < n) return;
4714 
4715  ifail = 0;
4716  for (j = 1; j <= n; ++j) {
4717  if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
4718  a[j + j*a_dim1] = one / a[j + j*a_dim1];
4719  if (j == n) continue;
4720  jp1 = j + 1;
4721  for (l = jp1; l <= n; ++l) {
4722  a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4723  s1 = -a[l + (j+1)*a_dim1];
4724  for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4725  a[l + (j+1)*a_dim1] = -s1;
4726  }
4727  }
4728  if (k <= 0) return;
4729 
4730  for (l = 1; l <= k; ++l) {
4731  b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
4732  }
4733  if (n == 1) return;
4734  for (l = 1; l <= k; ++l) {
4735  for (i = 2; i <= n; ++i) {
4736  im1 = i - 1;
4737  s21 = -b[i + l*b_dim1];
4738  for (j = 1; j <= im1; ++j) {
4739  s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
4740  }
4741  b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
4742  }
4743  nm1 = n - 1;
4744  for (i = 1; i <= nm1; ++i) {
4745  nmi = n - i;
4746  s22 = -b[nmi + l*b_dim1];
4747  for (j = 1; j <= i; ++j) {
4748  nmjp1 = n - j + 1;
4749  s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
4750  }
4751  b[nmi + l*b_dim1] = -s22;
4752  }
4753  }
4754 }
4755 
4756 ////////////////////////////////////////////////////////////////////////////////
4757 /// Return Global bin number corresponding to binx,y,z.
4758 ///
4759 /// 2-D and 3-D histograms are represented with a one dimensional
4760 /// structure.
4761 /// This has the advantage that all existing functions, such as
4762 /// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
4763 ///
4764 /// In case of a TH1x, returns binx directly.
4765 /// see TH1::GetBinXYZ for the inverse transformation.
4766 ///
4767 /// Convention for numbering bins
4768 ///
4769 /// For all histogram types: nbins, xlow, xup
4770 ///
4771 /// - bin = 0; underflow bin
4772 /// - bin = 1; first bin with low-edge xlow INCLUDED
4773 /// - bin = nbins; last bin with upper-edge xup EXCLUDED
4774 /// - bin = nbins+1; overflow bin
4775 ///
4776 /// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4777 /// For example, assuming a 3-D histogram with binx,biny,binz, the function
4778 ///
4779 /// ~~~ {.cpp}
4780 /// Int_t bin = h->GetBin(binx,biny,binz);
4781 /// ~~~
4782 ///
4783 /// returns a global/linearized bin number. This global bin is useful
4784 /// to access the bin information independently of the dimension.
4785 
4786 Int_t TH1::GetBin(Int_t binx, Int_t, Int_t) const
4787 {
4788  Int_t ofx = fXaxis.GetNbins() + 1; // overflow bin
4789  if (binx < 0) binx = 0;
4790  if (binx > ofx) binx = ofx;
4791 
4792  return binx;
4793 }
4794 
4795 ////////////////////////////////////////////////////////////////////////////////
4796 /// Return binx, biny, binz corresponding to the global bin number globalbin
4797 /// see TH1::GetBin function above
4798 
4799 void TH1::GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz) const
4800 {
4801  Int_t nx = fXaxis.GetNbins()+2;
4802  Int_t ny = fYaxis.GetNbins()+2;
4803 
4804  if (GetDimension() == 1) {
4805  binx = binglobal%nx;
4806  biny = 0;
4807  binz = 0;
4808  return;
4809  }
4810  if (GetDimension() == 2) {
4811  binx = binglobal%nx;
4812  biny = ((binglobal-binx)/nx)%ny;
4813  binz = 0;
4814  return;
4815  }
4816  if (GetDimension() == 3) {
4817  binx = binglobal%nx;
4818  biny = ((binglobal-binx)/nx)%ny;
4819  binz = ((binglobal-binx)/nx -biny)/ny;
4820  }
4821 }
4822 
4823 ////////////////////////////////////////////////////////////////////////////////
4824 /// Return a random number distributed according the histogram bin contents.
4825 /// This function checks if the bins integral exists. If not, the integral
4826 /// is evaluated, normalized to one.
4827 ///
4828 /// The integral is automatically recomputed if the number of entries
4829 /// is not the same then when the integral was computed.
4830 /// NB Only valid for 1-d histograms. Use GetRandom2 or 3 otherwise.
4831 /// If the histogram has a bin with negative content a NaN is returned
4832 
4833 Double_t TH1::GetRandom() const
4834 {
4835  if (fDimension > 1) {
4836  Error("GetRandom","Function only valid for 1-d histograms");
4837  return 0;
4838  }
4839  Int_t nbinsx = GetNbinsX();
4840  Double_t integral = 0;
4841  // compute integral checking that all bins have positive content (see ROOT-5894)
4842  if (fIntegral) {
4843  if (fIntegral[nbinsx+1] != fEntries) integral = ((TH1*)this)->ComputeIntegral(true);
4844  else integral = fIntegral[nbinsx];
4845  } else {
4846  integral = ((TH1*)this)->ComputeIntegral(true);
4847  }
4848  if (integral == 0) return 0;
4849  // return a NaN in case some bins have negative content
4850  if (integral == TMath::QuietNaN() ) return TMath::QuietNaN();
4851 
4852  Double_t r1 = gRandom->Rndm();
4853  Int_t ibin = TMath::BinarySearch(nbinsx,fIntegral,r1);
4854  Double_t x = GetBinLowEdge(ibin+1);
4855  if (r1 > fIntegral[ibin]) x +=
4856  GetBinWidth(ibin+1)*(r1-fIntegral[ibin])/(fIntegral[ibin+1] - fIntegral[ibin]);
4857  return x;
4858 }
4859 
4860 ////////////////////////////////////////////////////////////////////////////////
4861 /// Return content of bin number bin.
4862 ///
4863 /// Implemented in TH1C,S,F,D
4864 ///
4865 /// Convention for numbering bins
4866 ///
4867 /// For all histogram types: nbins, xlow, xup
4868 ///
4869 /// - bin = 0; underflow bin
4870 /// - bin = 1; first bin with low-edge xlow INCLUDED
4871 /// - bin = nbins; last bin with upper-edge xup EXCLUDED
4872 /// - bin = nbins+1; overflow bin
4873 ///
4874 /// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4875 /// For example, assuming a 3-D histogram with binx,biny,binz, the function
4876 ///
4877 /// ~~~ {.cpp}
4878 /// Int_t bin = h->GetBin(binx,biny,binz);
4879 /// ~~~
4880 ///
4881 /// returns a global/linearized bin number. This global bin is useful
4882 /// to access the bin information independently of the dimension.
4883 
4884 Double_t TH1::GetBinContent(Int_t bin) const
4885 {
4886  if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
4887  if (bin < 0) bin = 0;
4888  if (bin >= fNcells) bin = fNcells-1;
4889 
4890  return RetrieveBinContent(bin);
4891 }
4892 
4893 ////////////////////////////////////////////////////////////////////////////////
4894 /// Compute first binx in the range [firstx,lastx] for which
4895 /// diff = abs(bin_content-c) <= maxdiff
4896 ///
4897 /// In case several bins in the specified range with diff=0 are found
4898 /// the first bin found is returned in binx.
4899 /// In case several bins in the specified range satisfy diff <=maxdiff
4900 /// the bin with the smallest difference is returned in binx.
4901 /// In all cases the function returns the smallest difference.
4902 ///
4903 /// NOTE1: if firstx <= 0, firstx is set to bin 1
4904 /// if (lastx < firstx then firstx is set to the number of bins
4905 /// ie if firstx=0 and lastx=0 (default) the search is on all bins.
4906 ///
4907 /// NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
4908 
4909 Double_t TH1::GetBinWithContent(Double_t c, Int_t &binx, Int_t firstx, Int_t lastx,Double_t maxdiff) const
4910 {
4911  if (fDimension > 1) {
4912  binx = 0;
4913  Error("GetBinWithContent","function is only valid for 1-D histograms");
4914  return 0;
4915  }
4916 
4917  if (fBuffer) ((TH1*)this)->BufferEmpty();
4918 
4919  if (firstx <= 0) firstx = 1;
4920  if (lastx < firstx) lastx = fXaxis.GetNbins();
4921  Int_t binminx = 0;
4922  Double_t diff, curmax = 1.e240;
4923  for (Int_t i=firstx;i<=lastx;i++) {
4924  diff = TMath::Abs(RetrieveBinContent(i)-c);
4925  if (diff <= 0) {binx = i; return diff;}
4926  if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
4927  }
4928  binx = binminx;
4929  return curmax;
4930 }
4931 
4932 ////////////////////////////////////////////////////////////////////////////////
4933 /// Given a point x, approximates the value via linear interpolation
4934 /// based on the two nearest bin centers
4935 ///
4936 /// Andy Mastbaum 10/21/08
4937 
4938 Double_t TH1::Interpolate(Double_t x) const
4939 {
4940  if (fBuffer) ((TH1*)this)->BufferEmpty();
4941 
4942  Int_t xbin = fXaxis.FindFixBin(x);
4943  Double_t x0,x1,y0,y1;
4944 
4945  if(x<=GetBinCenter(1)) {
4946  return RetrieveBinContent(1);
4947  } else if(x>=GetBinCenter(GetNbinsX())) {
4948  return RetrieveBinContent(GetNbinsX());
4949  } else {
4950  if(x<=GetBinCenter(xbin)) {
4951  y0 = RetrieveBinContent(xbin-1);
4952  x0 = GetBinCenter(xbin-1);
4953  y1 = RetrieveBinContent(xbin);
4954  x1 = GetBinCenter(xbin);
4955  } else {
4956  y0 = RetrieveBinContent(xbin);
4957  x0 = GetBinCenter(xbin);
4958  y1 = RetrieveBinContent(xbin+1);
4959  x1 = GetBinCenter(xbin+1);
4960  }
4961  return y0 + (x-x0)*((y1-y0)/(x1-x0));
4962  }
4963 }
4964 
4965 ////////////////////////////////////////////////////////////////////////////////
4966 /// 2d Interpolation. Not yet implemented.
4967 
4968 Double_t TH1::Interpolate(Double_t, Double_t) const
4969 {
4970  Error("Interpolate","This function must be called with 1 argument for a TH1");
4971  return 0;
4972 }
4973 
4974 ////////////////////////////////////////////////////////////////////////////////
4975 /// 3d Interpolation. Not yet implemented.
4976 
4977 Double_t TH1::Interpolate(Double_t, Double_t, Double_t) const
4978 {
4979  Error("Interpolate","This function must be called with 1 argument for a TH1");
4980  return 0;
4981 }
4982 
4983 ///////////////////////////////////////////////////////////////////////////////
4984 /// Check if an histogram is empty
4985 /// (this a protected method used mainly by TH1Merger )
4986 
4987 Bool_t TH1::IsEmpty() const
4988 {
4989  // if fTsumw or fentries are not zero histogram is not empty
4990  // need to use GetEntries() instead of fEntries in case of bugger histograms
4991  // so we will flash the buffer
4992  if (fTsumw != 0) return kFALSE;
4993  if (GetEntries() != 0) return kFALSE;
4994  // case fTSumw == 0 amd entries are also zero
4995  // this should not really happening, but if one sets content by hand
4996  // it can happen. a call to ResetStats() should be done in such cases
4997  double sumw = 0;
4998  for (int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
4999  return (sumw != 0) ? kFALSE : kTRUE;
5000 }
5001 
5002 ////////////////////////////////////////////////////////////////////////////////
5003 /// Return true if the bin is overflow.
5004 
5005 Bool_t TH1::IsBinOverflow(Int_t bin, Int_t iaxis) const
5006 {
5007  Int_t binx, biny, binz;
5008  GetBinXYZ(bin, binx, biny, binz);
5009 
5010  if (iaxis == 0) {
5011  if ( fDimension == 1 )
5012  return binx >= GetNbinsX() + 1;
5013  if ( fDimension == 2 )
5014  return (binx >= GetNbinsX() + 1) ||
5015  (biny >= GetNbinsY() + 1);
5016  if ( fDimension == 3 )
5017  return (binx >= GetNbinsX() + 1) ||
5018  (biny >= GetNbinsY() + 1) ||
5019  (binz >= GetNbinsZ() + 1);
5020  return kFALSE;
5021  }
5022  if (iaxis == 1)
5023  return binx >= GetNbinsX() + 1;
5024  if (iaxis == 2)
5025  return biny >= GetNbinsY() + 1;
5026  if (iaxis == 3)
5027  return binz >= GetNbinsZ() + 1;
5028 
5029  Error("IsBinOverflow","Invalid axis value");
5030  return kFALSE;
5031 }
5032 
5033 ////////////////////////////////////////////////////////////////////////////////
5034 /// Return true if the bin is underflow.
5035 /// If iaxis = 0 make OR with all axes otherwise check only for the given axis
5036 
5037 Bool_t TH1::IsBinUnderflow(Int_t bin, Int_t iaxis) const
5038 {
5039  Int_t binx, biny, binz;
5040  GetBinXYZ(bin, binx, biny, binz);
5041 
5042  if (iaxis == 0) {
5043  if ( fDimension == 1 )
5044  return (binx <= 0);
5045  else if ( fDimension == 2 )
5046  return (binx <= 0 || biny <= 0);
5047  else if ( fDimension == 3 )
5048  return (binx <= 0 || biny <= 0 || binz <= 0);
5049  else
5050  return kFALSE;
5051  }
5052  if (iaxis == 1)
5053  return (binx <= 0);
5054  if (iaxis == 2)
5055  return (biny <= 0);
5056  if (iaxis == 3)
5057  return (binz <= 0);
5058 
5059  Error("IsBinUnderflow","Invalid axis value");
5060  return kFALSE;
5061 }
5062 
5063 ////////////////////////////////////////////////////////////////////////////////
5064 /// Reduce the number of bins for the axis passed in the option to the number of bins having a label.
5065 /// The method will remove only the extra bins existing after the last "labeled" bin.
5066 /// Note that if there are "un-labeled" bins present between "labeled" bins they will not be removed
5067 
5068 void TH1::LabelsDeflate(Option_t *ax)
5069 {
5070  Int_t iaxis = AxisChoice(ax);
5071  TAxis *axis = 0;
5072  if (iaxis == 1) axis = GetXaxis();
5073  if (iaxis == 2) axis = GetYaxis();
5074  if (iaxis == 3) axis = GetZaxis();
5075  if (!axis) {
5076  Error("LabelsDeflate","Invalid axis option %s",ax);
5077  return;
5078  }
5079  if (!axis->GetLabels()) return;
5080 
5081  // find bin with last labels
5082  // bin number is object ID in list of labels
5083  // therefore max bin number is number of bins of the deflated histograms
5084  TIter next(axis->GetLabels());
5085  TObject *obj;
5086  Int_t nbins = 0;
5087  while ((obj = next())) {
5088  Int_t ibin = obj->GetUniqueID();
5089  if (ibin > nbins) nbins = ibin;
5090  }
5091  if (nbins < 1) nbins = 1;
5092 
5093  // Do nothing in case it was the last bin
5094  if (nbins==axis->GetNbins()) return;
5095 
5096  TH1 *hold = (TH1*)IsA()->New();
5097  R__ASSERT(hold);
5098  hold->SetDirectory(0);
5099  Copy(*hold);
5100 
5101  Bool_t timedisp = axis->GetTimeDisplay();
5102  Double_t xmin = axis->GetXmin();
5103  Double_t xmax = axis->GetBinUpEdge(nbins);
5104  if (xmax <= xmin) xmax = xmin +nbins;
5105  axis->SetRange(0,0);
5106  axis->Set(nbins,xmin,xmax);
5107  SetBinsLength(-1); // reset the number of cells
5108  Int_t errors = fSumw2.fN;
5109  if (errors) fSumw2.Set(fNcells);
5110  axis->SetTimeDisplay(timedisp);
5111  // reset histogram content
5112  Reset("ICE");
5113 
5114  //now loop on all bins and refill
5115  // NOTE that if the bins without labels have content
5116  // it will be put in the underflow/overflow.
5117  // For this reason we use AddBinContent method
5118  Double_t oldEntries = fEntries;
5119  Int_t bin,binx,biny,binz;
5120  for (bin=0; bin < hold->fNcells; ++bin) {
5121  hold->GetBinXYZ(bin,binx,biny,binz);
5122  Int_t ibin = GetBin(binx,biny,binz);
5123  Double_t cu = hold->RetrieveBinContent(bin);
5124  AddBinContent(ibin,cu);
5125  if (errors) {
5126  fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5127  }
5128  }
5129  fEntries = oldEntries;
5130  delete hold;
5131 }
5132 
5133 ////////////////////////////////////////////////////////////////////////////////
5134 /// Double the number of bins for axis.
5135 /// Refill histogram
5136 /// This function is called by TAxis::FindBin(const char *label)
5137 
5138 void TH1::LabelsInflate(Option_t *ax)
5139 {
5140  Int_t iaxis = AxisChoice(ax);
5141  TAxis *axis = 0;
5142  if (iaxis == 1) axis = GetXaxis();
5143  if (iaxis == 2) axis = GetYaxis();
5144  if (iaxis == 3) axis = GetZaxis();
5145  if (!axis) return;
5146 
5147  TH1 *hold = (TH1*)IsA()->New();;
5148  hold->SetDirectory(0);
5149  Copy(*hold);
5150 
5151  Bool_t timedisp = axis->GetTimeDisplay();
5152  Int_t nbins = axis->GetNbins();
5153  Double_t xmin = axis->GetXmin();
5154  Double_t xmax = axis->GetXmax();
5155  xmax = xmin + 2*(xmax-xmin);
5156  axis->SetRange(0,0);
5157  // double the bins and recompute ncells
5158  axis->Set(2*nbins,xmin,xmax);
5159  SetBinsLength(-1);
5160  Int_t errors = fSumw2.fN;
5161  if (errors) fSumw2.Set(fNcells);
5162  axis->SetTimeDisplay(timedisp);
5163 
5164  Reset("ICE"); // reset content and error
5165 
5166  //now loop on all bins and refill
5167  Double_t oldEntries = fEntries;
5168  Int_t bin,ibin,binx,biny,binz;
5169  for (ibin =0; ibin < hold->fNcells; ibin++) {
5170  // get the binx,y,z values . The x-y-z (axis) bin values will stay the same between new-old after the expanding
5171  hold->GetBinXYZ(ibin,binx,biny,binz);
5172  bin = GetBin(binx,biny,binz);
5173 
5174  // underflow and overflow will be cleaned up because their meaning has been altered
5175  if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5176  continue;
5177  }
5178  else {
5179  AddBinContent(bin, hold->RetrieveBinContent(ibin));
5180  if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5181  }
5182  }
5183  fEntries = oldEntries;
5184  delete hold;
5185 }
5186 
5187 ////////////////////////////////////////////////////////////////////////////////
5188 /// Set option(s) to draw axis with labels
5189 /// \param[in] option
5190 /// - "a" sort by alphabetic order
5191 /// - ">" sort by decreasing values
5192 /// - "<" sort by increasing values
5193 /// - "h" draw labels horizontal
5194 /// - "v" draw labels vertical
5195 /// - "u" draw labels up (end of label right adjusted)
5196 /// - "d" draw labels down (start of label left adjusted)
5197 /// \param[in] ax axis
5198 
5199 void TH1::LabelsOption(Option_t *option, Option_t *ax)
5200 {
5201  Int_t iaxis = AxisChoice(ax);
5202  TAxis *axis = 0;
5203  if (iaxis == 1) axis = GetXaxis();
5204  if (iaxis == 2) axis = GetYaxis();
5205  if (iaxis == 3) axis = GetZaxis();
5206  if (!axis) return;
5207  THashList *labels = axis->GetLabels();
5208  if (!labels) {
5209  Warning("LabelsOption","Cannot sort. No labels");
5210  return;
5211  }
5212  TString opt = option;
5213  opt.ToLower();
5214  if (opt.Contains("h")) {
5215  axis->SetBit(TAxis::kLabelsHori);
5216  axis->ResetBit(TAxis::kLabelsVert);
5217  axis->ResetBit(TAxis::kLabelsDown);
5218  axis->ResetBit(TAxis::kLabelsUp);
5219  }
5220  if (opt.Contains("v")) {
5221  axis->SetBit(TAxis::kLabelsVert);
5222  axis->ResetBit(TAxis::kLabelsHori);
5223  axis->ResetBit(TAxis::kLabelsDown);
5224  axis->ResetBit(TAxis::kLabelsUp);
5225  }
5226  if (opt.Contains("u")) {
5227  axis->SetBit(TAxis::kLabelsUp);
5228  axis->ResetBit(TAxis::kLabelsVert);
5229  axis->ResetBit(TAxis::kLabelsDown);
5230  axis->ResetBit(TAxis::kLabelsHori);
5231  }
5232  if (opt.Contains("d")) {
5233  axis->SetBit(TAxis::kLabelsDown);
5234  axis->ResetBit(TAxis::kLabelsVert);
5235  axis->ResetBit(TAxis::kLabelsHori);
5236  axis->ResetBit(TAxis::kLabelsUp);
5237  }
5238  Int_t sort = -1;
5239  if (opt.Contains("a")) sort = 0;
5240  if (opt.Contains(">")) sort = 1;
5241  if (opt.Contains("<")) sort = 2;
5242  if (sort < 0) return;
5243  if (sort > 0 && GetDimension() > 2) {
5244  Error("LabelsOption","Sorting by value not implemented for 3-D histograms");
5245  return;
5246  }
5247 
5248  Double_t entries = fEntries;
5249  Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5250  std::vector<Int_t> a(n+2);
5251 
5252  Int_t i,j,k;
5253  std::vector<Double_t> cont;
5254  std::vector<Double_t> errors;
5255  THashList *labold = new THashList(labels->GetSize(),1);
5256  TIter nextold(labels);
5257  TObject *obj;
5258  while ((obj=nextold())) {
5259  labold->Add(obj);
5260  }
5261  labels->Clear();
5262  if (sort > 0) {
5263  //---sort by values of bins
5264  if (GetDimension() == 1) {
5265  cont.resize(n);
5266  if (fSumw2.fN) errors.resize(n);
5267  for (i=1;i<=n;i++) {
5268  cont[i-1] = GetBinContent(i);
5269  if (!errors.empty()) errors[i-1] = GetBinError(i);
5270  }
5271  if (sort ==1) TMath::Sort(n,cont.data(),a.data(),kTRUE); //sort by decreasing values
5272  else TMath::Sort(n,cont.data(),a.data(),kFALSE); //sort by increasing values
5273  for (i=1;i<=n;i++) {
5274  SetBinContent(i,cont[a[i-1]]);
5275  if (!errors.empty()) SetBinError(i,errors[a[i-1]]);
5276  }
5277  for (i=1;i<=n;i++) {
5278  obj = labold->At(a[i-1]);
5279  labels->Add(obj);
5280  obj->SetUniqueID(i);
5281  }
5282  } else if (GetDimension()== 2) {
5283  std::vector<Double_t> pcont(n+2);
5284  Int_t nx = fXaxis.GetNbins();
5285  Int_t ny = fYaxis.GetNbins();
5286  cont.resize( (nx+2)*(ny+2));
5287  if (fSumw2.fN) errors.resize( (nx+2)*(ny+2));
5288  for (i=1;i<=nx;i++) {
5289  for (j=1;j<=ny;j++) {
5290  cont[i+nx*j] = GetBinContent(i,j);
5291  if (!errors.empty()) errors[i+nx*j] = GetBinError(i,j);
5292  if (axis == GetXaxis()) k = i;
5293  else k = j;
5294  pcont[k-1] += cont[i+nx*j];
5295  }
5296  }
5297  if (sort ==1) TMath::Sort(n,pcont.data(),a.data(),kTRUE); //sort by decreasing values
5298  else TMath::Sort(n,pcont.data(),a.data(),kFALSE); //sort by increasing values
5299  for (i=0;i<n;i++) {
5300  obj = labold->At(a[i]);
5301  labels->Add(obj);
5302  obj->SetUniqueID(i+1);
5303  }
5304  if (axis == GetXaxis()) {
5305  for (i=1;i<=n;i++) {
5306  for (j=1;j<=ny;j++) {
5307  SetBinContent(i,j,cont[a[i-1]+1+nx*j]);
5308  if (!errors.empty()) SetBinError(i,j,errors[a[i-1]+1+nx*j]);
5309  }
5310  }
5311  }
5312  else {
5313  // using y axis
5314  for (i=1;i<=nx;i++) {
5315  for (j=1;j<=n;j++) {
5316  SetBinContent(i,j,cont[i+nx*(a[j-1]+1)]);
5317  if (!errors.empty()) SetBinError(i,j,errors[i+nx*(a[j-1]+1)]);
5318  }
5319  }
5320  }
5321  } else {
5322  //to be implemented for 3d
5323  }
5324  } else {
5325  //---alphabetic sort
5326  const UInt_t kUsed = 1<<18;
5327  TObject *objk=0;
5328  a[0] = 0;
5329  a[n+1] = n+1;
5330  for (i=1;i<=n;i++) {
5331  const char *label = "zzzzzzzzzzzz";
5332  for (j=1;j<=n;j++) {
5333  obj = labold->At(j-1);
5334  if (!obj) continue;
5335  if (obj->TestBit(kUsed)) continue;
5336  //use strcasecmp for case non-sensitive sort (may be an option)
5337  if (strcmp(label,obj->GetName()) < 0) continue;
5338  objk = obj;
5339  a[i] = j;
5340  label = obj->GetName();
5341  }
5342  if (objk) {
5343  objk->SetUniqueID(i);
5344  labels->Add(objk);
5345  objk->SetBit(kUsed);
5346  }
5347  }
5348  for (i=1;i<=n;i++) {
5349  obj = labels->At(i-1);
5350  if (!obj) continue;
5351  obj->ResetBit(kUsed);
5352  }
5353 
5354  if (GetDimension() == 1) {
5355  cont.resize(n+2);
5356  if (fSumw2.fN) errors.resize(n+2);
5357  for (i=1;i<=n;i++) {
5358  cont[i] = GetBinContent(a[i]);
5359  if (!errors.empty()) errors[i] = GetBinError(a[i]);
5360  }
5361  for (i=1;i<=n;i++) {
5362  SetBinContent(i,cont[i]);
5363  if (!errors.empty()) SetBinError(i,errors[i]);
5364  }
5365  } else if (GetDimension()== 2) {
5366  Int_t nx = fXaxis.GetNbins()+2;
5367  Int_t ny = fYaxis.GetNbins()+2;
5368  cont.resize(nx*ny);
5369  if (fSumw2.fN) errors.resize(nx*ny);
5370  for (i=0;i<nx;i++) {
5371  for (j=0;j<ny;j++) {
5372  cont[i+nx*j] = GetBinContent(i,j);
5373  if (!errors.empty()) errors[i+nx*j] = GetBinError(i,j);
5374  }
5375  }
5376  if (axis == GetXaxis()) {
5377  for (i=1;i<=n;i++) {
5378  for (j=0;j<ny;j++) {
5379  SetBinContent(i,j,cont[a[i]+nx*j]);
5380  if (!errors.empty()) SetBinError(i,j,errors[a[i]+nx*j]);
5381  }
5382  }
5383  } else {
5384  for (i=0;i<nx;i++) {
5385  for (j=1;j<=n;j++) {
5386  SetBinContent(i,j,cont[i+nx*a[j]]);
5387  if (!errors.empty()) SetBinError(i,j,errors[i+nx*a[j]]);
5388  }
5389  }
5390  }
5391  } else {
5392  Int_t nx = fXaxis.GetNbins()+2;
5393  Int_t ny = fYaxis.GetNbins()+2;
5394  Int_t nz = fZaxis.GetNbins()+2;
5395  cont.resize(nx*ny*nz);
5396  if (fSumw2.fN) errors.resize(nx*ny*nz);
5397  for (i=0;i<nx;i++) {
5398  for (j=0;j<ny;j++) {
5399  for (k=0;k<nz;k++) {
5400  cont[i+nx*(j+ny*k)] = GetBinContent(i,j,k);
5401  if (!errors.empty()) errors[i+nx*(j+ny*k)] = GetBinError(i,j,k);
5402  }
5403  }
5404  }
5405  if (axis == GetXaxis()) {
5406  // labels on x axis
5407  for (i=1;i<=n;i++) {
5408  for (j=0;j<ny;j++) {
5409  for (k=0;k<nz;k++) {
5410  SetBinContent(i,j,k,cont[a[i]+nx*(j+ny*k)]);
5411  if (!errors.empty()) SetBinError(i,j,k,errors[a[i]+nx*(j+ny*k)]);
5412  }
5413  }
5414  }
5415  }
5416  else if (axis == GetYaxis()) {
5417  // labels on y axis
5418  for (i=0;i<nx;i++) {
5419  for (j=1;j<=n;j++) {
5420  for (k=0;k<nz;k++) {
5421  SetBinContent(i,j,k,cont[i+nx*(a[j]+ny*k)]);
5422  if (!errors.empty()) SetBinError(i,j,k,errors[i+nx*(a[j]+ny*k)]);
5423  }
5424  }
5425  }
5426  }
5427  else {
5428  // labels on z axis
5429  for (i=0;i<nx;i++) {
5430  for (j=0;j<ny;j++) {
5431  for (k=1;k<=n;k++) {
5432  SetBinContent(i,j,k,cont[i+nx*(j+ny*a[k])]);
5433  if (!errors.empty()) SetBinError(i,j,k,errors[i+nx*(j+ny*a[k])]);
5434  }
5435  }
5436  }
5437  }
5438  }
5439  }
5440  fEntries = entries;
5441  delete labold;
5442 }
5443 
5444 ////////////////////////////////////////////////////////////////////////////////
5445 /// Test if two double are almost equal.
5446 
5447 static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5448 {
5449  return TMath::Abs(a - b) < epsilon;
5450 }
5451 
5452 ////////////////////////////////////////////////////////////////////////////////
5453 /// Test if a double is almost an integer.
5454 
5455 static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5456 {
5457  return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5458  AlmostEqual(a - TMath::Floor(a), 1, epsilon);
5459 }
5460 
5461 ////////////////////////////////////////////////////////////////////////////////
5462 /// Test if the binning is equidistant.
5463 
5464 static inline bool IsEquidistantBinning(const TAxis& axis)
5465 {
5466  // check if axis bin are equals
5467  if (!axis.GetXbins()->fN) return true; //
5468  // not able to check if there is only one axis entry
5469  bool isEquidistant = true;
5470  const Double_t firstBinWidth = axis.GetBinWidth(1);
5471  for (int i = 1; i < axis.GetNbins(); ++i) {
5472  const Double_t binWidth = axis.GetBinWidth(i);
5473  const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5474  isEquidistant &= match;
5475  if (!match)
5476  break;
5477  }
5478  return isEquidistant;
5479 }
5480 
5481 ////////////////////////////////////////////////////////////////////////////////
5482 /// Same limits and bins.
5483 
5484 Bool_t TH1::SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2){
5485  return axis1.GetNbins() == axis2.GetNbins() &&
5486  TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
5487  TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
5488 }
5489 
5490 ////////////////////////////////////////////////////////////////////////////////
5491 /// Finds new limits for the axis for the Merge function.
5492 /// returns false if the limits are incompatible
5493 
5494 Bool_t TH1::RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
5495 {
5496  if (SameLimitsAndNBins(destAxis, anAxis))
5497  return kTRUE;
5498 
5499  if (!IsEquidistantBinning(destAxis) || !IsEquidistantBinning(anAxis))
5500  return kFALSE; // not equidistant user binning not supported
5501 
5502  Double_t width1 = destAxis.GetBinWidth(0);
5503  Double_t width2 = anAxis.GetBinWidth(0);
5504  if (width1 == 0 || width2 == 0)
5505  return kFALSE; // no binning not supported
5506 
5507  Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
5508  Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
5509  Double_t width = TMath::Max(width1, width2);
5510 
5511  // check the bin size
5512  if (!AlmostInteger(width/width1) || !AlmostInteger(width/width2))
5513  return kFALSE;
5514 
5515  // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
5516  // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
5517 
5518 
5519  // check the limits
5520  Double_t delta;
5521  delta = (destAxis.GetXmin() - xmin)/width1;
5522  if (!AlmostInteger(delta))
5523  xmin -= (TMath::Ceil(delta) - delta)*width1;
5524 
5525  delta = (anAxis.GetXmin() - xmin)/width2;
5526  if (!AlmostInteger(delta))
5527  xmin -= (TMath::Ceil(delta) - delta)*width2;
5528 
5529 
5530  delta = (destAxis.GetXmin() - xmin)/width1;
5531  if (!AlmostInteger(delta))
5532  return kFALSE;
5533 
5534 
5535  delta = (xmax - destAxis.GetXmax())/width1;
5536  if (!AlmostInteger(delta))
5537  xmax += (TMath::Ceil(delta) - delta)*width1;
5538 
5539 
5540  delta = (xmax - anAxis.GetXmax())/width2;
5541  if (!AlmostInteger(delta))
5542  xmax += (TMath::Ceil(delta) - delta)*width2;
5543 
5544 
5545  delta = (xmax - destAxis.GetXmax())/width1;
5546  if (!AlmostInteger(delta))
5547  return kFALSE;
5548 #ifdef DEBUG
5549  if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
5550  printf("TH1::RecomputeAxisLimits - Impossible\n");
5551  return kFALSE;
5552  }
5553 #endif
5554 
5555 
5556  destAxis.Set(TMath::Nint((xmax - xmin)/width), xmin, xmax);
5557 
5558  //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
5559 
5560  return kTRUE;
5561 }
5562 
5563 ////////////////////////////////////////////////////////////////////////////////
5564 /// Add all histograms in the collection to this histogram.
5565 /// This function computes the min/max for the x axis,
5566 /// compute a new number of bins, if necessary,
5567 /// add bin contents, errors and statistics.
5568 /// If all histograms have bin labels, bins with identical labels
5569 /// will be merged, no matter what their order is.
5570 /// If overflows are present and limits are different the function will fail.
5571 /// The function returns the total number of entries in the result histogram
5572 /// if the merge is successful, -1 otherwise.
5573 ///
5574 /// Possible option:
5575 /// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
5576 /// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
5577 /// (enabled by default) slows down the merging
5578 ///
5579 /// IMPORTANT remark. The axis x may have different number
5580 /// of bins and different limits, BUT the largest bin width must be
5581 /// a multiple of the smallest bin width and the upper limit must also
5582 /// be a multiple of the bin width.
5583 /// Example:
5584 ///
5585 /// ~~~ {.cpp}
5586 /// void atest() {
5587 /// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
5588 /// TH1F *h2 = new TH1F("h2","h2",220,0,110);
5589 /// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
5590 /// TRandom r;
5591 /// for (Int_t i=0;i<10000;i++) {
5592 /// h1->Fill(r.Gaus(-55,10));
5593 /// h2->Fill(r.Gaus(55,10));
5594 /// h3->Fill(r.Gaus(0,10));
5595 /// }
5596 ///
5597 /// TList *list = new TList;
5598 /// list->Add(h1);
5599 /// list->Add(h2);
5600 /// list->Add(h3);
5601 /// TH1F *h = (TH1F*)h1->Clone("h");
5602 /// h->Reset();
5603 /// h->Merge(list);
5604 /// h->Draw();
5605 /// }
5606 /// ~~~
5607 
5608 Long64_t TH1::Merge(TCollection *li,Option_t * opt)
5609 {
5610  if (!li) return 0;
5611  if (li->IsEmpty()) return (Long64_t) GetEntries();
5612 
5613  // use TH1Merger class
5614  TH1Merger merger(*this,*li,opt);
5615  Bool_t ret = merger();
5616 
5617  return (ret) ? GetEntries() : -1;
5618 }
5619 
5620 
5621 ////////////////////////////////////////////////////////////////////////////////
5622 /// Performs the operation:
5623 ///
5624 /// `this = this*c1*f1`
5625 ///
5626 /// If errors are defined (see TH1::Sumw2), errors are also recalculated.
5627 ///
5628 /// Only bins inside the function range are recomputed.
5629 /// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5630 /// you should call Sumw2 before making this operation.
5631 /// This is particularly important if you fit the histogram after TH1::Multiply
5632 ///
5633 /// The function return kFALSE if the Multiply operation failed
5634 
5635 Bool_t TH1::Multiply(TF1 *f1, Double_t c1)
5636 {
5637  if (!f1) {
5638  Error("Multiply","Attempt to multiply by a non-existing function");
5639  return kFALSE;
5640  }
5641 
5642  // delete buffer if it is there since it will become invalid
5643  if (fBuffer) BufferEmpty(1);
5644 
5645  Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
5646  Int_t ny = GetNbinsY() + 2;
5647  Int_t nz = GetNbinsZ() + 2;
5648  if (fDimension < 2) ny = 1;
5649  if (fDimension < 3) nz = 1;
5650 
5651  // reset min-maximum
5652  SetMinimum();
5653  SetMaximum();
5654 
5655  // - Loop on bins (including underflows/overflows)
5656  Double_t xx[3];
5657  Double_t *params = 0;
5658  f1->InitArgs(xx,params);
5659 
5660  for (Int_t binz = 0; binz < nz; ++binz) {
5661  xx[2] = fZaxis.GetBinCenter(binz);
5662  for (Int_t biny = 0; biny < ny; ++biny) {
5663  xx[1] = fYaxis.GetBinCenter(biny);
5664  for (Int_t binx = 0; binx < nx; ++binx) {
5665  xx[0] = fXaxis.GetBinCenter(binx);
5666  if (!f1->IsInside(xx)) continue;
5667  TF1::RejectPoint(kFALSE);
5668  Int_t bin = binx + nx * (biny + ny *binz);
5669  Double_t cu = c1*f1->EvalPar(xx);
5670  if (TF1::RejectedPoint()) continue;
5671  UpdateBinContent(bin, RetrieveBinContent(bin) * cu);
5672  if (fSumw2.fN) {
5673  fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
5674  }
5675  }
5676  }
5677  }
5678  ResetStats();
5679  return kTRUE;
5680 }
5681 
5682 ////////////////////////////////////////////////////////////////////////////////
5683 /// Multiply this histogram by h1.
5684 ///
5685 /// `this = this*h1`
5686 ///
5687 /// If errors of this are available (TH1::Sumw2), errors are recalculated.
5688 /// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
5689 /// if not already set.
5690 ///
5691 /// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5692 /// you should call Sumw2 before making this operation.
5693 /// This is particularly important if you fit the histogram after TH1::Multiply
5694 ///
5695 /// The function return kFALSE if the Multiply operation failed
5696 
5697 Bool_t TH1::Multiply(const TH1 *h1)
5698 {
5699  if (!h1) {
5700  Error("Multiply","Attempt to multiply by a non-existing histogram");
5701  return kFALSE;
5702  }
5703 
5704  // delete buffer if it is there since it will become invalid
5705  if (fBuffer) BufferEmpty(1);
5706 
5707  try {
5708  CheckConsistency(this,h1);
5709  } catch(DifferentNumberOfBins&) {
5710  Error("Multiply","Attempt to multiply histograms with different number of bins");
5711  return kFALSE;
5712  } catch(DifferentAxisLimits&) {
5713  Warning("Multiply","Attempt to multiply histograms with different axis limits");
5714  } catch(DifferentBinLimits&) {
5715  Warning("Multiply","Attempt to multiply histograms with different bin limits");
5716  } catch(DifferentLabels&) {
5717  Warning("Multiply","Attempt to multiply histograms with different labels");
5718  }
5719 
5720  // Create Sumw2 if h1 has Sumw2 set
5721  if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
5722 
5723  // - Reset min- maximum
5724  SetMinimum();
5725  SetMaximum();
5726 
5727  // - Loop on bins (including underflows/overflows)
5728  for (Int_t i = 0; i < fNcells; ++i) {
5729  Double_t c0 = RetrieveBinContent(i);
5730  Double_t c1 = h1->RetrieveBinContent(i);
5731  UpdateBinContent(i, c0 * c1);
5732  if (fSumw2.fN) {
5733  fSumw2.fArray[i] = GetBinErrorSqUnchecked(i) * c1 * c1 + h1->GetBinErrorSqUnchecked(i) * c0 * c0;
5734  }
5735  }
5736  ResetStats();
5737  return kTRUE;
5738 }
5739 
5740 ////////////////////////////////////////////////////////////////////////////////
5741 /// Replace contents of this histogram by multiplication of h1 by h2.
5742 ///
5743 /// `this = (c1*h1)*(c2*h2)`
5744 ///
5745 /// If errors of this are available (TH1::Sumw2), errors are recalculated.
5746 /// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
5747 /// if not already set.
5748 ///
5749 /// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5750 /// you should call Sumw2 before making this operation.
5751 /// This is particularly important if you fit the histogram after TH1::Multiply
5752 ///
5753 /// The function return kFALSE if the Multiply operation failed
5754 
5755 Bool_t TH1::Multiply(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
5756 {
5757  TString opt = option;
5758  opt.ToLower();
5759  // Bool_t binomial = kFALSE;
5760  // if (opt.Contains("b")) binomial = kTRUE;
5761  if (!h1 || !h2) {
5762  Error("Multiply","Attempt to multiply by a non-existing histogram");
5763  return kFALSE;
5764  }
5765 
5766  // delete buffer if it is there since it will become invalid
5767  if (fBuffer) BufferEmpty(1);
5768 
5769  try {
5770  CheckConsistency(h1,h2);
5771  CheckConsistency(this,h1);
5772  } catch(DifferentNumberOfBins&) {
5773  Error("Multiply","Attempt to multiply histograms with different number of bins");
5774  return kFALSE;
5775  } catch(DifferentAxisLimits&) {
5776  Warning("Multiply","Attempt to multiply histograms with different axis limits");
5777  } catch(DifferentBinLimits&) {
5778  Warning("Multiply","Attempt to multiply histograms with different bin limits");
5779  } catch(DifferentLabels&) {
5780  Warning("Multiply","Attempt to multiply histograms with different labels");
5781  }
5782 
5783  // Create Sumw2 if h1 or h2 have Sumw2 set
5784  if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
5785 
5786  // - Reset min - maximum
5787  SetMinimum();
5788  SetMaximum();
5789 
5790  // - Loop on bins (including underflows/overflows)
5791  Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
5792  for (Int_t i = 0; i < fNcells; ++i) {
5793  Double_t b1 = h1->RetrieveBinContent(i);
5794  Double_t b2 = h2->RetrieveBinContent(i);
5795  UpdateBinContent(i, c1 * b1 * c2 * b2);
5796  if (fSumw2.fN) {
5797  fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
5798  }
5799  }
5800  ResetStats();
5801  return kTRUE;
5802 }
5803 
5804 ////////////////////////////////////////////////////////////////////////////////
5805 /// Control routine to paint any kind of histograms.
5806 ///
5807 /// This function is automatically called by TCanvas::Update.
5808 /// (see TH1::Draw for the list of options)
5809 
5810 void TH1::Paint(Option_t *option)
5811 {
5812  GetPainter(option);
5813 
5814  if (fPainter) {
5815  if (strlen(option) > 0) fPainter->Paint(option);
5816  else fPainter->Paint(fOption.Data());
5817  }
5818 }
5819 
5820 ////////////////////////////////////////////////////////////////////////////////
5821 /// Rebin this histogram
5822 ///
5823 /// #### case 1 xbins=0
5824 ///
5825 /// If newname is blank (default), the current histogram is modified and
5826 /// a pointer to it is returned.
5827 ///
5828 /// If newname is not blank, the current histogram is not modified, and a
5829 /// new histogram is returned which is a Clone of the current histogram
5830 /// with its name set to newname.
5831 ///
5832 /// The parameter ngroup indicates how many bins of this have to be merged
5833 /// into one bin of the result.
5834 ///
5835 /// If the original histogram has errors stored (via Sumw2), the resulting
5836 /// histograms has new errors correctly calculated.
5837 ///
5838 /// examples: if h1 is an existing TH1F histogram with 100 bins
5839 ///
5840 /// ~~~ {.cpp}
5841 /// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
5842 /// h1->Rebin(5); //merges five bins in one in h1
5843 /// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
5844 /// // merging 5 bins of h1 in one bin
5845 /// ~~~
5846 ///
5847 /// NOTE: If ngroup is not an exact divider of the number of bins,
5848 /// the top limit of the rebinned histogram is reduced
5849 /// to the upper edge of the last bin that can make a complete
5850 /// group. The remaining bins are added to the overflow bin.
5851 /// Statistics will be recomputed from the new bin contents.
5852 ///
5853 /// #### case 2 xbins!=0
5854 ///
5855 /// A new histogram is created (you should specify newname).
5856 /// The parameter ngroup is the number of variable size bins in the created histogram.
5857 /// The array xbins must contain ngroup+1 elements that represent the low-edges
5858 /// of the bins.
5859 /// If the original histogram has errors stored (via Sumw2), the resulting
5860 /// histograms has new errors correctly calculated.
5861 ///
5862 /// NOTE: The bin edges specified in xbins should correspond to bin edges
5863 /// in the original histogram. If a bin edge in the new histogram is
5864 /// in the middle of a bin in the original histogram, all entries in
5865 /// the split bin in the original histogram will be transfered to the
5866 /// lower of the two possible bins in the new histogram. This is
5867 /// probably not what you want. A warning message is emitted in this
5868 /// case
5869 ///
5870 /// examples: if h1 is an existing TH1F histogram with 100 bins
5871 ///
5872 /// ~~~ {.cpp}
5873 /// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
5874 /// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
5875 /// ~~~
5876 
5877 TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
5878 {
5879  Int_t nbins = fXaxis.GetNbins();
5880  Double_t xmin = fXaxis.GetXmin();
5881  Double_t xmax = fXaxis.GetXmax();
5882  if ((ngroup <= 0) || (ngroup > nbins)) {
5883  Error("Rebin", "Illegal value of ngroup=%d",ngroup);
5884  return 0;
5885  }
5886 
5887  if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
5888  Error("Rebin", "Operation valid on 1-D histograms only");
5889  return 0;
5890  }
5891  if (!newname && xbins) {
5892  Error("Rebin","if xbins is specified, newname must be given");
5893  return 0;
5894  }
5895 
5896  Int_t newbins = nbins/ngroup;
5897  if (!xbins) {
5898  Int_t nbg = nbins/ngroup;
5899  if (nbg*ngroup != nbins) {
5900  Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
5901  }
5902  }
5903  else {
5904  // in the case that xbins is given (rebinning in variable bins), ngroup is
5905  // the new number of bins and number of grouped bins is not constant.
5906  // when looping for setting the contents for the new histogram we
5907  // need to loop on all bins of original histogram. Then set ngroup=nbins
5908  newbins = ngroup;
5909  ngroup = nbins;
5910  }
5911 
5912  // Save old bin contents into a new array
5913  Double_t entries = fEntries;
5914  Double_t *oldBins = new Double_t[nbins+2];
5915  Int_t bin, i;
5916  for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
5917  Double_t *oldErrors = 0;
5918  if (fSumw2.fN != 0) {
5919  oldErrors = new Double_t[nbins+2];
5920  for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
5921  }
5922  // rebin will not include underflow/overflow if new axis range is larger than old axis range
5923  if (xbins) {
5924  if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
5925  Warning("Rebin","underflow entries will not be used when rebinning");
5926  if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
5927  Warning("Rebin","overflow entries will not be used when rebinning");
5928  }
5929 
5930 
5931  // create a clone of the old histogram if newname is specified
5932  TH1 *hnew = this;
5933  if ((newname && strlen(newname) > 0) || xbins) {
5934  hnew = (TH1*)Clone(newname);
5935  }
5936 
5937  //reset can extend bit to avoid an axis extension in SetBinContent
5938  UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
5939 
5940  // save original statistics
5941  Double_t stat[kNstat];
5942  GetStats(stat);
5943  bool resetStat = false;
5944  // change axis specs and rebuild bin contents array::RebinAx
5945  if(!xbins && (newbins*ngroup != nbins)) {
5946  xmax = fXaxis.GetBinUpEdge(newbins*ngroup);
5947  resetStat = true; //stats must be reset because top bins will be moved to overflow bin
5948  }
5949  // save the TAttAxis members (reset by SetBins)
5950  Int_t nDivisions = fXaxis.GetNdivisions();
5951  Color_t axisColor = fXaxis.GetAxisColor();
5952  Color_t labelColor = fXaxis.GetLabelColor();
5953  Style_t labelFont = fXaxis.GetLabelFont();
5954  Float_t labelOffset = fXaxis.GetLabelOffset();
5955  Float_t labelSize = fXaxis.GetLabelSize();
5956  Float_t tickLength = fXaxis.GetTickLength();
5957  Float_t titleOffset = fXaxis.GetTitleOffset();
5958  Float_t titleSize = fXaxis.GetTitleSize();
5959  Color_t titleColor = fXaxis.GetTitleColor();
5960  Style_t titleFont = fXaxis.GetTitleFont();
5961 
5962  if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
5963  Double_t *bins = new Double_t[newbins+1];
5964  for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
5965  hnew->SetBins(newbins,bins); //this also changes errors array (if any)
5966  delete [] bins;
5967  } else if (xbins) {
5968  hnew->SetBins(newbins,xbins);
5969  } else {
5970  hnew->SetBins(newbins,xmin,xmax);
5971  }
5972 
5973  // Restore axis attributes
5974  fXaxis.SetNdivisions(nDivisions);
5975  fXaxis.SetAxisColor(axisColor);
5976  fXaxis.SetLabelColor(labelColor);
5977  fXaxis.SetLabelFont(labelFont);
5978  fXaxis.SetLabelOffset(labelOffset);
5979  fXaxis.SetLabelSize(labelSize);
5980  fXaxis.SetTickLength(tickLength);
5981  fXaxis.SetTitleOffset(titleOffset);
5982  fXaxis.SetTitleSize(titleSize);
5983  fXaxis.SetTitleColor(titleColor);
5984  fXaxis.SetTitleFont(titleFont);
5985 
5986  // copy merged bin contents (ignore under/overflows)
5987  // Start merging only once the new lowest edge is reached
5988  Int_t startbin = 1;
5989  const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
5990  while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
5991  startbin++;
5992  }
5993  Int_t oldbin = startbin;
5994  Double_t binContent, binError;
5995  for (bin = 1;bin<=newbins;bin++) {
5996  binContent = 0;
5997  binError = 0;
5998  Int_t imax = ngroup;
5999  Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6000  // check bin edges for the cases when we provide an array of bins
6001  // be careful in case bins can have zero width
6002  if (xbins && !TMath::AreEqualAbs(fXaxis.GetBinLowEdge(oldbin),
6003  hnew->GetXaxis()->GetBinLowEdge(bin),
6004  TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6005  {
6006  Warning("Rebin","Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6007  }
6008  for (i=0;i<ngroup;i++) {
6009  if( (oldbin+i > nbins) ||
6010  ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6011  imax = i;
6012  break;
6013  }
6014  binContent += oldBins[oldbin+i];
6015  if (oldErrors) binError += oldErrors[oldbin+i]*oldErrors[oldbin+i];
6016  }
6017  hnew->SetBinContent(bin,binContent);
6018  if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6019  oldbin += imax;
6020  }
6021 
6022  // sum underflow and overflow contents until startbin
6023  binContent = 0;
6024  binError = 0;
6025  for (i = 0; i < startbin; ++i) {
6026  binContent += oldBins[i];
6027  if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6028  }
6029  hnew->SetBinContent(0,binContent);
6030  if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6031  // sum overflow
6032  binContent = 0;
6033  binError = 0;
6034  for (i = oldbin; i <= nbins+1; ++i) {
6035  binContent += oldBins[i];
6036  if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6037  }
6038  hnew->SetBinContent(newbins+1,binContent);
6039  if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6040 
6041  hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6042 
6043  // restore statistics and entries modified by SetBinContent
6044  hnew->SetEntries(entries);
6045  if (!resetStat) hnew->PutStats(stat);
6046  delete [] oldBins;
6047  if (oldErrors) delete [] oldErrors;
6048  return hnew;
6049 }
6050 
6051 ////////////////////////////////////////////////////////////////////////////////
6052 /// finds new limits for the axis so that *point* is within the range and
6053 /// the limits are compatible with the previous ones (see TH1::Merge).
6054 /// new limits are put into *newMin* and *newMax* variables.
6055 /// axis - axis whose limits are to be recomputed
6056 /// point - point that should fit within the new axis limits
6057 /// newMin - new minimum will be stored here
6058 /// newMax - new maximum will be stored here.
6059 /// false if failed (e.g. if the initial axis limits are wrong
6060 /// or the new range is more than \f$ 2^{64} \f$ times the old one).
6061 
6062 Bool_t TH1::FindNewAxisLimits(const TAxis* axis, const Double_t point, Double_t& newMin, Double_t &newMax)
6063 {
6064  Double_t xmin = axis->GetXmin();
6065  Double_t xmax = axis->GetXmax();
6066  if (xmin >= xmax) return kFALSE;
6067  Double_t range = xmax-xmin;
6068  Double_t binsize = range / axis->GetNbins();
6069 
6070  //recompute new axis limits by doubling the current range
6071  Int_t ntimes = 0;
6072  while (point < xmin) {
6073  if (ntimes++ > 64)
6074  return kFALSE;
6075  xmin = xmin - range;
6076  range *= 2;
6077  binsize *= 2;
6078  // // make sure that the merging will be correct
6079  // if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
6080  // xmin += 0.5 * binsize;
6081  // xmax += 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
6082  // }
6083  }
6084  while (point >= xmax) {
6085  if (ntimes++ > 64)
6086  return kFALSE;
6087  xmax = xmax + range;
6088  range *= 2;
6089  binsize *= 2;
6090  // // make sure that the merging will be correct
6091  // if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
6092  // xmin -= 0.5 * binsize;
6093  // xmax -= 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
6094  // }
6095  }
6096  newMin = xmin;
6097  newMax = xmax;
6098  // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6099  // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6100 
6101  return kTRUE;
6102 }
6103 
6104 ////////////////////////////////////////////////////////////////////////////////
6105 /// Histogram is resized along axis such that x is in the axis range.
6106 /// The new axis limits are recomputed by doubling iteratively
6107 /// the current axis range until the specified value x is within the limits.
6108 /// The algorithm makes a copy of the histogram, then loops on all bins
6109 /// of the old histogram to fill the extended histogram.
6110 /// Takes into account errors (Sumw2) if any.
6111 /// The algorithm works for 1-d, 2-D and 3-D histograms.
6112 /// The axis must be extendable before invoking this function.
6113 /// Ex:
6114 ///
6115 /// ~~~ {.cpp}
6116 /// h->GetXaxis()->SetCanExtend(kTRUE);
6117 /// ~~~
6118 
6119 void TH1::ExtendAxis(Double_t x, TAxis *axis)
6120 {
6121  if (!axis->CanExtend()) return;
6122  if (TMath::IsNaN(x)) { // x may be a NaN
6123  SetCanExtend(kNoAxis);
6124  return;
6125  }
6126 
6127  if (axis->GetXmin() >= axis->GetXmax()) return;
6128  if (axis->GetNbins() <= 0) return;
6129 
6130  Double_t xmin, xmax;
6131  if (!FindNewAxisLimits(axis, x, xmin, xmax))
6132  return;
6133 
6134  //save a copy of this histogram
6135  TH1 *hold = (TH1*)IsA()->New();
6136  hold->SetDirectory(0);
6137  Copy(*hold);
6138  //set new axis limits
6139  axis->SetLimits(xmin,xmax);
6140 
6141 
6142  //now loop on all bins and refill
6143  Int_t errors = GetSumw2N();
6144 
6145  Reset("ICE"); //reset only Integral, contents and Errors
6146 
6147  int iaxis = 0;
6148  if (axis == &fXaxis) iaxis = 1;
6149  if (axis == &fYaxis) iaxis = 2;
6150  if (axis == &fZaxis) iaxis = 3;
6151  bool firstw = kTRUE;
6152  Int_t binx,biny, binz = 0;
6153  Int_t ix = 0,iy = 0,iz = 0;
6154  Double_t bx,by,bz;
6155  Int_t ncells = hold->GetNcells();
6156  for (Int_t bin = 0; bin < ncells; ++bin) {
6157  hold->GetBinXYZ(bin,binx,biny,binz);
6158  bx = hold->GetXaxis()->GetBinCenter(binx);
6159  ix = fXaxis.FindFixBin(bx);
6160  if (fDimension > 1) {
6161  by = hold->GetYaxis()->GetBinCenter(biny);
6162  iy = fYaxis.FindFixBin(by);
6163  if (fDimension > 2) {
6164  bz = hold->GetZaxis()->GetBinCenter(binz);
6165  iz = fZaxis.FindFixBin(bz);
6166  }
6167  }
6168  // exclude underflow/overflow
6169  double content = hold->RetrieveBinContent(bin);
6170  if (content == 0) continue;
6171  if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6172  if (firstw) {
6173  Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6174  " their content will be lost",GetName() );
6175  firstw= kFALSE;
6176  }
6177  continue;
6178  }
6179  Int_t ibin= GetBin(ix,iy,iz);
6180  AddBinContent(ibin, content);
6181  if (errors) {
6182  fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6183  }
6184  }
6185  delete hold;
6186 }
6187 
6188 ////////////////////////////////////////////////////////////////////////////////
6189 /// Recursively remove object from the list of functions
6190 
6191 void TH1::RecursiveRemove(TObject *obj)
6192 {
6193  // Rely on TROOT::RecursiveRemove to take the readlock.
6194 
6195  if (fFunctions) {
6196  if (!fFunctions->TestBit(kInvalidObject)) fFunctions->RecursiveRemove(obj);
6197  }
6198 }
6199 
6200 ////////////////////////////////////////////////////////////////////////////////
6201 /// Multiply this histogram by a constant c1.
6202 ///
6203 /// `this = c1*this`
6204 ///
6205 /// Note that both contents and errors(if any) are scaled.
6206 /// This function uses the services of TH1::Add
6207 ///
6208 /// IMPORTANT NOTE: Sumw2() is called automatically when scaling
6209 /// If you are not interested in the histogram statistics you can call
6210 /// Sumw2(off) or use the option "nosw2"
6211 ///
6212 /// One can scale an histogram such that the bins integral is equal to
6213 /// the normalization parameter via TH1::Scale(Double_t norm), where norm
6214 /// is the desired normalization divided by the integral of the histogram.
6215 ///
6216 /// If option contains "width" the bin contents and errors are divided
6217 /// by the bin width.
6218 
6219 void TH1::Scale(Double_t c1, Option_t *option)
6220 {
6221 
6222  TString opt = option; opt.ToLower();
6223  // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6224  if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6225  if (opt.Contains("width")) Add(this, this, c1, -1);
6226  else {
6227  if (fBuffer) BufferEmpty(1);
6228  for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6229  if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6230  // update global histograms statistics
6231  Double_t s[kNstat] = {0};
6232  GetStats(s);
6233  for (Int_t i=0 ; i < kNstat; i++) {
6234  if (i == 1) s[i] = c1*c1*s[i];
6235  else s[i] = c1*s[i];
6236  }
6237  PutStats(s);
6238  SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6239  }
6240 
6241  // if contours set, must also scale contours
6242  Int_t ncontours = GetContour();
6243  if (ncontours == 0) return;
6244  Double_t* levels = fContour.GetArray();
6245  for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6246 }
6247 
6248 ////////////////////////////////////////////////////////////////////////////////
6249 /// Returns true if all axes are extendable.
6250 
6251 Bool_t TH1::CanExtendAllAxes() const
6252 {
6253  Bool_t canExtend = fXaxis.CanExtend();
6254  if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6255  if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6256 
6257  return canExtend;
6258 }
6259 
6260 ////////////////////////////////////////////////////////////////////////////////
6261 /// Make the histogram axes extendable / not extendable according to the bit mask
6262 /// returns the previous bit mask specifying which axes are extendable
6263 
6264 UInt_t TH1::SetCanExtend(UInt_t extendBitMask)
6265 {
6266  UInt_t oldExtendBitMask = kNoAxis;
6267 
6268  if (fXaxis.CanExtend()) oldExtendBitMask |= kXaxis;
6269  if (extendBitMask & kXaxis) fXaxis.SetCanExtend(kTRUE);
6270  else fXaxis.SetCanExtend(kFALSE);
6271 
6272  if (GetDimension() > 1) {
6273  if (fYaxis.CanExtend()) oldExtendBitMask |= kYaxis;
6274  if (extendBitMask & kYaxis) fYaxis.SetCanExtend(kTRUE);
6275  else fYaxis.SetCanExtend(kFALSE);
6276  }
6277 
6278  if (GetDimension() > 2) {
6279  if (fZaxis.CanExtend()) oldExtendBitMask |= kZaxis;
6280  if (extendBitMask & kZaxis) fZaxis.SetCanExtend(kTRUE);
6281  else fZaxis.SetCanExtend(kFALSE);
6282  }
6283 
6284  return oldExtendBitMask;
6285 }
6286 
6287 ////////////////////////////////////////////////////////////////////////////////
6288 /// Static function to set the default buffer size for automatic histograms.
6289 /// When an histogram is created with one of its axis lower limit greater
6290 /// or equal to its upper limit, the function SetBuffer is automatically
6291 /// called with the default buffer size.
6292 
6293 void TH1::SetDefaultBufferSize(Int_t buffersize)
6294 {
6295  fgBufferSize = buffersize > 0 ? buffersize : 0;
6296 }
6297 
6298 ////////////////////////////////////////////////////////////////////////////////
6299 /// When this static function is called with `sumw2=kTRUE`, all new
6300 /// histograms will automatically activate the storage
6301 /// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6302 
6303 void TH1::SetDefaultSumw2(Bool_t sumw2)
6304 {
6305  fgDefaultSumw2 = sumw2;
6306 }
6307 
6308 ////////////////////////////////////////////////////////////////////////////////
6309 /// Change (i.e. set) the title
6310 ///
6311 /// if title is in the form `stringt;stringx;stringy;stringz`
6312 /// the histogram title is set to `stringt`, the x axis title to `stringx`,
6313 /// the y axis title to `stringy`, and the z axis title to `stringz`.
6314 ///
6315 /// To insert the character `;` in one of the titles, one should use `#;`
6316 /// or `#semicolon`.
6317 
6318 void TH1::SetTitle(const char *title)
6319 {
6320  fTitle = title;
6321  fTitle.ReplaceAll("#;",2,"#semicolon",10);
6322 
6323  // Decode fTitle. It may contain X, Y and Z titles
6324  TString str1 = fTitle, str2;
6325  Int_t isc = str1.Index(";");
6326  Int_t lns = str1.Length();
6327 
6328  if (isc >=0 ) {
6329  fTitle = str1(0,isc);
6330  str1 = str1(isc+1, lns);
6331  isc = str1.Index(";");
6332  if (isc >=0 ) {
6333  str2 = str1(0,isc);
6334  str2.ReplaceAll("#semicolon",10,";",1);
6335  fXaxis.SetTitle(str2.Data());
6336  lns = str1.Length();
6337  str1 = str1(isc+1, lns);
6338  isc = str1.Index(";");
6339  if (isc >=0 ) {
6340  str2 = str1(0,isc);
6341  str2.ReplaceAll("#semicolon",10,";",1);
6342  fYaxis.SetTitle(str2.Data());
6343  lns = str1.Length();
6344  str1 = str1(isc+1, lns);
6345  str1.ReplaceAll("#semicolon",10,";",1);
6346  fZaxis.SetTitle(str1.Data());
6347  } else {
6348  str1.ReplaceAll("#semicolon",10,";",1);
6349  fYaxis.SetTitle(str1.Data());
6350  }
6351  } else {
6352  str1.ReplaceAll("#semicolon",10,";",1);
6353  fXaxis.SetTitle(str1.Data());
6354  }
6355  }
6356 
6357  fTitle.ReplaceAll("#semicolon",10,";",1);
6358 
6359  if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6360 }
6361 
6362 ////////////////////////////////////////////////////////////////////////////////
6363 /// Smooth array xx, translation of Hbook routine hsmoof.F
6364 /// based on algorithm 353QH twice presented by J. Friedman
6365 /// in Proc.of the 1974 CERN School of Computing, Norway, 11-24 August, 1974.
6366 
6367 void TH1::SmoothArray(Int_t nn, Double_t *xx, Int_t ntimes)
6368 {
6369  if (nn < 3 ) {
6370  ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6371  return;
6372  }
6373 
6374  Int_t ii;
6375  Double_t hh[6] = {0,0,0,0,0,0};
6376 
6377  std::vector<double> yy(nn);
6378  std::vector<double> zz(nn);
6379  std::vector<double> rr(nn);
6380 
6381  for (Int_t pass=0;pass<ntimes;pass++) {
6382  // first copy original data into temp array
6383  std::copy(xx, xx+nn, zz.begin() );
6384 
6385  for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6386 
6387  // do 353 i.e. running median 3, 5, and 3 in a single loop
6388  for (int kk = 0; kk < 3; kk++) {
6389  std::copy(zz.begin(), zz.end(), yy.begin());
6390  int medianType = (kk != 1) ? 3 : 5;
6391  int ifirst = (kk != 1 ) ? 1 : 2;
6392  int ilast = (kk != 1 ) ? nn-1 : nn -2;
6393  //nn2 = nn - ik - 1;
6394  // do all elements beside the first and last point for median 3
6395  // and first two and last 2 for median 5
6396  for ( ii = ifirst; ii < ilast; ii++) {
6397  assert(ii - ifirst >= 0);
6398  for (int jj = 0; jj < medianType; jj++) {
6399  hh[jj] = yy[ii - ifirst + jj ];
6400  }
6401  zz[ii] = TMath::Median(medianType, hh);
6402  }
6403 
6404  if (kk == 0) { // first median 3
6405  // first point
6406  hh[0] = zz[1];
6407  hh[1] = zz[0];
6408  hh[2] = 3*zz[1] - 2*zz[2];
6409  zz[0] = TMath::Median(3, hh);
6410  // last point
6411  hh[0] = zz[nn - 2];
6412  hh[1] = zz[nn - 1];
6413  hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6414  zz[nn - 1] = TMath::Median(3, hh);
6415  }
6416 
6417  if (kk == 1) { // median 5
6418  for (ii = 0; ii < 3; ii++) {
6419  hh[ii] = yy[ii];
6420  }
6421  zz[1] = TMath::Median(3, hh);
6422  // last two points
6423  for (ii = 0; ii < 3; ii++) {
6424  hh[ii] = yy[nn - 3 + ii];
6425  }
6426  zz[nn - 2] = TMath::Median(3, hh);
6427  }
6428 
6429  }
6430 
6431  std::copy ( zz.begin(), zz.end(), yy.begin() );
6432 
6433  // quadratic interpolation for flat segments
6434  for (ii = 2; ii < (nn - 2); ii++) {
6435  if (zz[ii - 1] != zz[ii]) continue;
6436  if (zz[ii] != zz[ii + 1]) continue;
6437  hh[0] = zz[ii - 2] - zz[ii];
6438  hh[1] = zz[ii + 2] - zz[ii];
6439  if (hh[0] * hh[1] <= 0) continue;
6440  int jk = 1;
6441  if ( TMath::Abs(hh[1]) > TMath::Abs(hh[0]) ) jk = -1;
6442  yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6443  yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6444  }
6445 
6446  // running means
6447  //std::copy(zz.begin(), zz.end(), yy.begin());
6448  for (ii = 1; ii < nn - 1; ii++) {
6449  zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6450  }
6451  zz[0] = yy[0];
6452  zz[nn - 1] = yy[nn - 1];
6453 
6454  if (noent == 0) {
6455 
6456  // save computed values
6457  std::copy(zz.begin(), zz.end(), rr.begin());
6458 
6459  // COMPUTE residuals
6460  for (ii = 0; ii < nn; ii++) {
6461  zz[ii] = xx[ii] - zz[ii];
6462  }
6463  }
6464 
6465  } // end loop on noent
6466 
6467 
6468  double xmin = TMath::MinElement(nn,xx);
6469  for (ii = 0; ii < nn; ii++) {
6470  if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6471  // make smoothing defined positive - not better using 0 ?
6472  else xx[ii] = TMath::Max((rr[ii] + zz[ii]),0.0 );
6473  }
6474  }
6475 }
6476 
6477 ////////////////////////////////////////////////////////////////////////////////
6478 /// Smooth bin contents of this histogram.
6479 /// if option contains "R" smoothing is applied only to the bins
6480 /// defined in the X axis range (default is to smooth all bins)
6481 /// Bin contents are replaced by their smooth values.
6482 /// Errors (if any) are not modified.
6483 /// the smoothing procedure is repeated ntimes (default=1)
6484 
6485 void TH1::Smooth(Int_t ntimes, Option_t *option)
6486 {
6487  if (fDimension != 1) {
6488  Error("Smooth","Smooth only supported for 1-d histograms");
6489  return;
6490  }
6491  Int_t nbins = fXaxis.GetNbins();
6492  if (nbins < 3) {
6493  Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
6494  return;
6495  }
6496 
6497  // delete buffer if it is there since it will become invalid
6498  if (fBuffer) BufferEmpty(1);
6499 
6500  Int_t firstbin = 1, lastbin = nbins;
6501  TString opt = option;
6502  opt.ToLower();
6503  if (opt.Contains("r")) {
6504  firstbin= fXaxis.GetFirst();
6505  lastbin = fXaxis.GetLast();
6506  }
6507  nbins = lastbin - firstbin + 1;
6508  Double_t *xx = new Double_t[nbins];
6509  Double_t nent = fEntries;
6510  Int_t i;
6511  for (i=0;i<nbins;i++) {
6512  xx[i] = RetrieveBinContent(i+firstbin);
6513  }
6514 
6515  TH1::SmoothArray(nbins,xx,ntimes);
6516 
6517  for (i=0;i<nbins;i++) {
6518  UpdateBinContent(i+firstbin,xx[i]);
6519  }
6520  fEntries = nent;
6521  delete [] xx;
6522 
6523  if (gPad) gPad->Modified();
6524 }
6525 
6526 ////////////////////////////////////////////////////////////////////////////////
6527 /// if flag=kTRUE, underflows and overflows are used by the Fill functions
6528 /// in the computation of statistics (mean value, StdDev).
6529 /// By default, underflows or overflows are not used.
6530 
6531 void TH1::StatOverflows(Bool_t flag)
6532 {
6533  fgStatOverflows = flag;
6534 }
6535 
6536 ////////////////////////////////////////////////////////////////////////////////
6537 /// Stream a class object.
6538 
6539 void TH1::Streamer(TBuffer &b)
6540 {
6541  if (b.IsReading()) {
6542  UInt_t R__s, R__c;
6543  Version_t R__v = b.ReadVersion(&R__s, &R__c);
6544  if (fDirectory) fDirectory->Remove(this);
6545  fDirectory = 0;
6546  if (R__v > 2) {
6547  b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
6548 
6549  ResetBit(kMustCleanup);
6550  fXaxis.SetParent(this);
6551  fYaxis.SetParent(this);
6552  fZaxis.SetParent(this);
6553  TIter next(fFunctions);
6554  TObject *obj;
6555  while ((obj=next())) {
6556  if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
6557  }
6558  return;
6559  }
6560  //process old versions before automatic schema evolution
6561  TNamed::Streamer(b);
6562  TAttLine::Streamer(b);
6563  TAttFill::Streamer(b);
6564  TAttMarker::Streamer(b);
6565  b >> fNcells;
6566  fXaxis.Streamer(b);
6567  fYaxis.Streamer(b);
6568  fZaxis.Streamer(b);
6569  fXaxis.SetParent(this);
6570  fYaxis.SetParent(this);
6571  fZaxis.SetParent(this);
6572  b >> fBarOffset;
6573  b >> fBarWidth;
6574  b >> fEntries;
6575  b >> fTsumw;
6576  b >> fTsumw2;
6577  b >> fTsumwx;
6578  b >> fTsumwx2;
6579  if (R__v < 2) {
6580  Float_t maximum, minimum, norm;
6581  Float_t *contour=0;
6582  b >> maximum; fMaximum = maximum;
6583  b >> minimum; fMinimum = minimum;
6584  b >> norm; fNormFactor = norm;
6585  Int_t n = b.ReadArray(contour);
6586  fContour.Set(n);
6587  for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
6588  delete [] contour;
6589  } else {
6590  b >> fMaximum;
6591  b >> fMinimum;
6592  b >> fNormFactor;
6593  fContour.Streamer(b);
6594  }
6595  fSumw2.Streamer(b);
6596  fOption.Streamer(b);
6597  fFunctions->Delete();
6598  fFunctions->Streamer(b);
6599  b.CheckByteCount(R__s, R__c, TH1::IsA());
6600 
6601  } else {
6602  b.WriteClassBuffer(TH1::Class(),this);
6603  }
6604 }
6605 
6606 ////////////////////////////////////////////////////////////////////////////////
6607 /// Print some global quantities for this histogram.
6608 /// \param[in] option
6609 /// - "base" is given, number of bins and ranges are also printed
6610 /// - "range" is given, bin contents and errors are also printed
6611 /// for all bins in the current range (default 1-->nbins)
6612 /// - "all" is given, bin contents and errors are also printed
6613 /// for all bins including under and overflows.
6614 
6615 void TH1::Print(Option_t *option) const
6616 {
6617  if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
6618  printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
6619  TString opt = option;
6620  opt.ToLower();
6621  Int_t all;
6622  if (opt.Contains("all")) all = 0;
6623  else if (opt.Contains("range")) all = 1;
6624  else if (opt.Contains("base")) all = 2;
6625  else return;
6626 
6627  Int_t bin, binx, biny, binz;
6628  Int_t firstx=0,lastx=0,firsty=0,lasty=0,firstz=0,lastz=0;
6629  if (all == 0) {
6630  lastx = fXaxis.GetNbins()+1;
6631  if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
6632  if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
6633  } else {
6634  firstx = fXaxis.GetFirst(); lastx = fXaxis.GetLast();
6635  if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
6636  if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
6637  }
6638 
6639  if (all== 2) {
6640  printf(" Title = %s\n", GetTitle());
6641  printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
6642  if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
6643  if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
6644  printf("\n");
6645  return;
6646  }
6647 
6648  Double_t w,e;
6649  Double_t x,y,z;
6650  if (fDimension == 1) {
6651  for (binx=firstx;binx<=lastx;binx++) {
6652  x = fXaxis.GetBinCenter(binx);
6653  w = RetrieveBinContent(binx);
6654  e = GetBinError(binx);
6655  if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
6656  else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
6657  }
6658  }
6659  if (fDimension == 2) {
6660  for (biny=firsty;biny<=lasty;biny++) {
6661  y = fYaxis.GetBinCenter(biny);
6662  for (binx=firstx;binx<=lastx;binx++) {
6663  bin = GetBin(binx,biny);
6664  x = fXaxis.GetBinCenter(binx);
6665  w = RetrieveBinContent(bin);
6666  e = GetBinError(bin);
6667  if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
6668  else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
6669  }
6670  }
6671  }
6672  if (fDimension == 3) {
6673  for (binz=firstz;binz<=lastz;binz++) {
6674  z = fZaxis.GetBinCenter(binz);
6675  for (biny=firsty;biny<=lasty;biny++) {
6676  y = fYaxis.GetBinCenter(biny);
6677  for (binx=firstx;binx<=lastx;binx++) {
6678  bin = GetBin(binx,biny,binz);
6679  x = fXaxis.GetBinCenter(binx);
6680  w = RetrieveBinContent(bin);
6681  e = GetBinError(bin);
6682  if(fSumw2.fN) printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g, error=%g\n",binx,biny,binz,w,x,y,z,e);
6683  else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
6684  }
6685  }
6686  }
6687  }
6688 }
6689 
6690 ////////////////////////////////////////////////////////////////////////////////
6691 /// Using the current bin info, recompute the arrays for contents and errors
6692 
6693 void TH1::Rebuild(Option_t *)
6694 {
6695  SetBinsLength();
6696  if (fSumw2.fN) {
6697  fSumw2.Set(fNcells);
6698  }
6699 }
6700 
6701 ////////////////////////////////////////////////////////////////////////////////
6702 /// Reset this histogram: contents, errors, etc.
6703 /// \param[in] option
6704 /// - if "ICE" is specified, resets only Integral, Contents and Errors.
6705 /// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
6706 /// This option is used
6707 /// - if "M" is specified, resets also Minimum and Maximum
6708 
6709 void TH1::Reset(Option_t *option)
6710 {
6711  // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
6712  // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
6713 
6714  TString opt = option;
6715  opt.ToUpper();
6716  fSumw2.Reset();
6717  if (fIntegral) {delete [] fIntegral; fIntegral = 0;}
6718 
6719  if (opt.Contains("M")) {
6720  SetMinimum();
6721  SetMaximum();
6722  }
6723 
6724  if (opt.Contains("ICE") && !opt.Contains("S")) return;
6725 
6726  // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
6727  // But what is the sense of calling BufferEmpty() ? For making the axes ?
6728  // BufferEmpty will update contents that later will be
6729  // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
6730  // It may be needed for computing the axis limits....
6731  if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
6732 
6733  // need to reset also the statistics
6734  // (needs to be done after calling BufferEmpty() )
6735  fTsumw = 0;
6736  fTsumw2 = 0;
6737  fTsumwx = 0;
6738  fTsumwx2 = 0;
6739  fEntries = 0;
6740 
6741  if (opt == "ICES") return;
6742 
6743 
6744  TObject *stats = fFunctions->FindObject("stats");
6745  fFunctions->Remove(stats);
6746  //special logic to support the case where the same object is
6747  //added multiple times in fFunctions.
6748  //This case happens when the same object is added with different
6749  //drawing modes
6750  TObject *obj;
6751  while ((obj = fFunctions->First())) {
6752  while(fFunctions->Remove(obj)) { }
6753  delete obj;
6754  }
6755  if(stats) fFunctions->Add(stats);
6756  fContour.Set(0);
6757 }
6758 
6759 ////////////////////////////////////////////////////////////////////////////////
6760 /// Save primitive as a C++ statement(s) on output stream out
6761 
6762 void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
6763 {
6764  // empty the buffer before if it exists
6765  if (fBuffer) BufferEmpty();
6766 
6767  Bool_t nonEqiX = kFALSE;
6768  Bool_t nonEqiY = kFALSE;
6769  Bool_t nonEqiZ = kFALSE;
6770  Int_t i;
6771  static Int_t nxaxis = 0;
6772  static Int_t nyaxis = 0;
6773  static Int_t nzaxis = 0;
6774  TString sxaxis="xAxis",syaxis="yAxis",szaxis="zAxis";
6775 
6776  // Check if the histogram has equidistant X bins or not. If not, we
6777  // create an array holding the bins.
6778  if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
6779  nonEqiX = kTRUE;
6780  nxaxis++;
6781  sxaxis += nxaxis;
6782  out << " Double_t "<<sxaxis<<"[" << GetXaxis()->GetXbins()->fN
6783  << "] = {";
6784  for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
6785  if (i != 0) out << ", ";
6786  out << GetXaxis()->GetXbins()->fArray[i];
6787  }
6788  out << "}; " << std::endl;
6789  }
6790  // If the histogram is 2 or 3 dimensional, check if the histogram
6791  // has equidistant Y bins or not. If not, we create an array
6792  // holding the bins.
6793  if (fDimension > 1 && GetYaxis()->GetXbins()->fN &&
6794  GetYaxis()->GetXbins()->fArray) {
6795  nonEqiY = kTRUE;
6796  nyaxis++;
6797  syaxis += nyaxis;
6798  out << " Double_t "<<syaxis<<"[" << GetYaxis()->GetXbins()->fN
6799  << "] = {";
6800  for (i = 0; i < GetYaxis()->GetXbins()->fN; i++) {
6801  if (i != 0) out << ", ";
6802  out << GetYaxis()->GetXbins()->fArray[i];
6803  }
6804  out << "}; " << std::endl;
6805  }
6806  // IF the histogram is 3 dimensional, check if the histogram
6807  // has equidistant Z bins or not. If not, we create an array
6808  // holding the bins.
6809  if (fDimension > 2 && GetZaxis()->GetXbins()->fN &&
6810  GetZaxis()->GetXbins()->fArray) {
6811  nonEqiZ = kTRUE;
6812  nzaxis++;
6813  szaxis += nzaxis;
6814  out << " Double_t "<<szaxis<<"[" << GetZaxis()->GetXbins()->fN
6815  << "] = {";
6816  for (i = 0; i < GetZaxis()->GetXbins()->fN; i++) {
6817  if (i != 0) out << ", ";
6818  out << GetZaxis()->GetXbins()->fArray[i];
6819  }
6820  out << "}; " << std::endl;
6821  }
6822 
6823  char quote = '"';
6824  out <<" "<<std::endl;
6825  out <<" "<< ClassName() <<" *";
6826 
6827  // Histogram pointer has by default the histogram name with an incremental suffix.
6828  // If the histogram belongs to a graph or a stack the suffix is not added because
6829  // the graph and stack objects are not aware of this new name. Same thing if
6830  // the histogram is drawn with the option COLZ because the TPaletteAxis drawn
6831  // when this option is selected, does not know this new name either.
6832  TString opt = option;
6833  opt.ToLower();
6834  static Int_t hcounter = 0;
6835  TString histName = GetName();
6836  if ( !histName.Contains("Graph")
6837  && !histName.Contains("_stack_")
6838  && !opt.Contains("colz")) {
6839  hcounter++;
6840  histName += "__";
6841  histName += hcounter;
6842  }
6843  histName = gInterpreter-> MapCppName(histName);
6844  const char *hname = histName.Data();
6845  if (!strlen(hname)) hname = "unnamed";
6846  TString savedName = GetName();
6847  this->SetName(hname);
6848  TString t(GetTitle());
6849  t.ReplaceAll("\\","\\\\");
6850  t.ReplaceAll("\"","\\\"");
6851  out << hname << " = new " << ClassName() << "(" << quote
6852  << hname << quote << "," << quote<< t.Data() << quote
6853  << "," << GetXaxis()->GetNbins();
6854  if (nonEqiX)
6855  out << ", "<<sxaxis;
6856  else
6857  out << "," << GetXaxis()->GetXmin()
6858  << "," << GetXaxis()->GetXmax();
6859  if (fDimension > 1) {
6860  out << "," << GetYaxis()->GetNbins();
6861  if (nonEqiY)
6862  out << ", "<<syaxis;
6863  else
6864  out << "," << GetYaxis()->GetXmin()
6865  << "," << GetYaxis()->GetXmax();
6866  }
6867  if (fDimension > 2) {
6868  out << "," << GetZaxis()->GetNbins();
6869  if (nonEqiZ)
6870  out << ", "<<szaxis;
6871  else
6872  out << "," << GetZaxis()->GetXmin()
6873  << "," << GetZaxis()->GetXmax();
6874  }
6875  out << ");" << std::endl;
6876 
6877  // save bin contents
6878  Int_t bin;
6879  for (bin=0;bin<fNcells;bin++) {
6880  Double_t bc = RetrieveBinContent(bin);
6881  if (bc) {
6882  out<<" "<<hname<<"->SetBinContent("<<bin<<","<<bc<<");"<<std::endl;
6883  }
6884  }
6885 
6886  // save bin errors
6887  if (fSumw2.fN) {
6888  for (bin=0;bin<fNcells;bin++) {
6889  Double_t be = GetBinError(bin);
6890  if (be) {
6891  out<<" "<<hname<<"->SetBinError("<<bin<<","<<be<<");"<<std::endl;
6892  }
6893  }
6894  }
6895 
6896  TH1::SavePrimitiveHelp(out, hname, option);
6897  this->SetName(savedName.Data());
6898 }
6899 
6900 ////////////////////////////////////////////////////////////////////////////////
6901 /// Helper function for the SavePrimitive functions from TH1
6902 /// or classes derived from TH1, eg TProfile, TProfile2D.
6903 
6904 void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
6905 {
6906  char quote = '"';
6907  if (TMath::Abs(GetBarOffset()) > 1e-5) {
6908  out<<" "<<hname<<"->SetBarOffset("<<GetBarOffset()<<");"<<std::endl;
6909  }
6910  if (TMath::Abs(GetBarWidth()-1) > 1e-5) {
6911  out<<" "<<hname<<"->SetBarWidth("<<GetBarWidth()<<");"<<std::endl;
6912  }
6913  if (fMinimum != -1111) {
6914  out<<" "<<hname<<"->SetMinimum("<<fMinimum<<");"<<std::endl;
6915  }
6916  if (fMaximum != -1111) {
6917  out<<" "<<hname<<"->SetMaximum("<<fMaximum<<");"<<std::endl;
6918  }
6919  if (fNormFactor != 0) {
6920  out<<" "<<hname<<"->SetNormFactor("<<fNormFactor<<");"<<std::endl;
6921  }
6922  if (fEntries != 0) {
6923  out<<" "<<hname<<"->SetEntries("<<fEntries<<");"<<std::endl;
6924  }
6925  if (fDirectory == 0) {
6926  out<<" "<<hname<<"->SetDirectory(0);"<<std::endl;
6927  }
6928  if (TestBit(kNoStats)) {
6929  out<<" "<<hname<<"->SetStats(0);"<<std::endl;
6930  }
6931  if (fOption.Length() != 0) {
6932  out<<" "<<hname<<"->SetOption("<<quote<<fOption.Data()<<quote<<");"<<std::endl;
6933  }
6934 
6935  // save contour levels
6936  Int_t ncontours = GetContour();
6937  if (ncontours > 0) {
6938  out<<" "<<hname<<"->SetContour("<<ncontours<<");"<<std::endl;
6939  Double_t zlevel;
6940  for (Int_t bin=0;bin<ncontours;bin++) {
6941  if (gPad->GetLogz()) {
6942  zlevel = TMath::Power(10,GetContourLevel(bin));
6943  } else {
6944  zlevel = GetContourLevel(bin);
6945  }
6946  out<<" "<<hname<<"->SetContourLevel("<<bin<<","<<zlevel<<");"<<std::endl;
6947  }
6948  }
6949 
6950  // save list of functions
6951  TObjOptLink *lnk = (TObjOptLink*)fFunctions->FirstLink();
6952  TObject *obj;
6953  static Int_t funcNumber = 0;
6954  while (lnk) {
6955  obj = lnk->GetObject();
6956  obj->SavePrimitive(out,Form("nodraw #%d\n",++funcNumber));
6957  if (obj->InheritsFrom(TF1::Class())) {
6958  TString fname;
6959  fname.Form("%s%d",obj->GetName(),funcNumber);
6960  out << " " << fname << "->SetParent(" << hname << ");\n";
6961  out<<" "<<hname<<"->GetListOfFunctions()->Add("
6962  << fname <<");"<<std::endl;
6963  } else if (obj->InheritsFrom("TPaveStats")) {
6964  out<<" "<<hname<<"->GetListOfFunctions()->Add(ptstats);"<<std::endl;
6965  out<<" ptstats->SetParent("<<hname<<");"<<std::endl;
6966  } else if (obj->InheritsFrom("TPolyMarker")) {
6967  out<<" "<<hname<<"->GetListOfFunctions()->Add("
6968  <<"pmarker ,"<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
6969  } else {
6970  out<<" "<<hname<<"->GetListOfFunctions()->Add("
6971  <<obj->GetName()
6972  <<","<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
6973  }
6974  lnk = (TObjOptLink*)lnk->Next();
6975  }
6976 
6977  // save attributes
6978  SaveFillAttributes(out,hname,0,1001);
6979  SaveLineAttributes(out,hname,1,1,1);
6980  SaveMarkerAttributes(out,hname,1,1,1);
6981  fXaxis.SaveAttributes(out,hname,"->GetXaxis()");
6982  fYaxis.SaveAttributes(out,hname,"->GetYaxis()");
6983  fZaxis.SaveAttributes(out,hname,"->GetZaxis()");
6984  TString opt = option;
6985  opt.ToLower();
6986  if (!opt.Contains("nodraw")) {
6987  out<<" "<<hname<<"->Draw("
6988  <<quote<<option<<quote<<");"<<std::endl;
6989  }
6990 }
6991 
6992 ////////////////////////////////////////////////////////////////////////////////
6993 /// Copy current attributes from/to current style
6994 
6995 void TH1::UseCurrentStyle()
6996 {
6997  if (!gStyle) return;
6998  if (gStyle->IsReading()) {
6999  fXaxis.ResetAttAxis("X");
7000  fYaxis.ResetAttAxis("Y");
7001  fZaxis.ResetAttAxis("Z");
7002  SetBarOffset(gStyle->GetBarOffset());
7003  SetBarWidth(gStyle->GetBarWidth());
7004  SetFillColor(gStyle->GetHistFillColor());
7005  SetFillStyle(gStyle->GetHistFillStyle());
7006  SetLineColor(gStyle->GetHistLineColor());
7007  SetLineStyle(gStyle->GetHistLineStyle());
7008  SetLineWidth(gStyle->GetHistLineWidth());
7009  SetMarkerColor(gStyle->GetMarkerColor());
7010  SetMarkerStyle(gStyle->GetMarkerStyle());
7011  SetMarkerSize(gStyle->GetMarkerSize());
7012  Int_t dostat = gStyle->GetOptStat();
7013  if (gStyle->GetOptFit() && !dostat) dostat = 1000000001;
7014  SetStats(dostat);
7015  } else {
7016  gStyle->SetBarOffset(fBarOffset);
7017  gStyle->SetBarWidth(fBarWidth);
7018  gStyle->SetHistFillColor(GetFillColor());
7019  gStyle->SetHistFillStyle(GetFillStyle());
7020  gStyle->SetHistLineColor(GetLineColor());
7021  gStyle->SetHistLineStyle(GetLineStyle());
7022  gStyle->SetHistLineWidth(GetLineWidth());
7023  gStyle->SetMarkerColor(GetMarkerColor());
7024  gStyle->SetMarkerStyle(GetMarkerStyle());
7025  gStyle->SetMarkerSize(GetMarkerSize());
7026  gStyle->SetOptStat(TestBit(kNoStats));
7027  }
7028  TIter next(GetListOfFunctions());
7029  TObject *obj;
7030 
7031  while ((obj = next())) {
7032  obj->UseCurrentStyle();
7033  }
7034 }
7035 
7036 ////////////////////////////////////////////////////////////////////////////////
7037 /// For axis = 1,2 or 3 returns the mean value of the histogram along
7038 /// X,Y or Z axis.
7039 ///
7040 /// For axis = 11, 12, 13 returns the standard error of the mean value
7041 /// of the histogram along X, Y or Z axis
7042 ///
7043 /// Note that the mean value/StdDev is computed using the bins in the currently
7044 /// defined range (see TAxis::SetRange). By default the range includes
7045 /// all bins from 1 to nbins included, excluding underflows and overflows.
7046 /// To force the underflows and overflows in the computation, one must
7047 /// call the static function TH1::StatOverflows(kTRUE) before filling
7048 /// the histogram.
7049 ///
7050 /// Return mean value of this histogram along the X axis.
7051 ///
7052 /// Note that the mean value/StdDev is computed using the bins in the currently
7053 /// defined range (see TAxis::SetRange). By default the range includes
7054 /// all bins from 1 to nbins included, excluding underflows and overflows.
7055 /// To force the underflows and overflows in the computation, one must
7056 /// call the static function TH1::StatOverflows(kTRUE) before filling
7057 /// the histogram.
7058 
7059 Double_t TH1::GetMean(Int_t axis) const
7060 {
7061  if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7062  Double_t stats[kNstat];
7063  for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7064  GetStats(stats);
7065  if (stats[0] == 0) return 0;
7066  if (axis<4){
7067  Int_t ax[3] = {2,4,7};
7068  return stats[ax[axis-1]]/stats[0];
7069  } else {
7070  // mean error = StdDev / sqrt( Neff )
7071  Double_t stddev = GetStdDev(axis-10);
7072  Double_t neff = GetEffectiveEntries();
7073  return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7074  }
7075 }
7076 
7077 ////////////////////////////////////////////////////////////////////////////////
7078 /// Return standard error of mean of this histogram along the X axis.
7079 ///
7080 /// Note that the mean value/StdDev is computed using the bins in the currently
7081 /// defined range (see TAxis::SetRange). By default the range includes
7082 /// all bins from 1 to nbins included, excluding underflows and overflows.
7083 /// To force the underflows and overflows in the computation, one must
7084 /// call the static function TH1::StatOverflows(kTRUE) before filling
7085 /// the histogram.
7086 ///
7087 /// Also note, that although the definition of standard error doesn't include the
7088 /// assumption of normality, many uses of this feature implicitly assume it.
7089 
7090 Double_t TH1::GetMeanError(Int_t axis) const
7091 {
7092  return GetMean(axis+10);
7093 }
7094 
7095 ////////////////////////////////////////////////////////////////////////////////
7096 /// Returns the Standard Deviation (Sigma).
7097 /// The Sigma estimate is computed as
7098 /// \f[
7099 /// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7100 /// \f]
7101 /// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7102 /// X, Y or Z axis
7103 /// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7104 /// X, Y or Z axis for Normal distribution
7105 ///
7106 /// Note that the mean value/sigma is computed using the bins in the currently
7107 /// defined range (see TAxis::SetRange). By default the range includes
7108 /// all bins from 1 to nbins included, excluding underflows and overflows.
7109 /// To force the underflows and overflows in the computation, one must
7110 /// call the static function TH1::StatOverflows(kTRUE) before filling
7111 /// the histogram.
7112 
7113 Double_t TH1::GetStdDev(Int_t axis) const
7114 {
7115  if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7116 
7117  Double_t x, stddev2, stats[kNstat];
7118  for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7119  GetStats(stats);
7120  if (stats[0] == 0) return 0;
7121  Int_t ax[3] = {2,4,7};
7122  Int_t axm = ax[axis%10 - 1];
7123  x = stats[axm]/stats[0];
7124  // for negative stddev (e.g. when having negative weights) - return stdev=0
7125  stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7126  if (axis<10)
7127  return TMath::Sqrt(stddev2);
7128  else {
7129  // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7130  // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7131  Double_t neff = GetEffectiveEntries();
7132  return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7133  }
7134 }
7135 
7136 ////////////////////////////////////////////////////////////////////////////////
7137 /// Return error of standard deviation estimation for Normal distribution
7138 ///
7139 /// Note that the mean value/StdDev is computed using the bins in the currently
7140 /// defined range (see TAxis::SetRange). By default the range includes
7141 /// all bins from 1 to nbins included, excluding underflows and overflows.
7142 /// To force the underflows and overflows in the computation, one must
7143 /// call the static function TH1::StatOverflows(kTRUE) before filling
7144 /// the histogram.
7145 ///
7146 /// Value returned is standard deviation of sample standard deviation.
7147 /// Note that it is an approximated value which is valid only in the case that the
7148 /// original data distribution is Normal. The correct one would require
7149 /// the 4-th momentum value, which cannot be accurately estimated from an histogram since
7150 /// the x-information for all entries is not kept.
7151 
7152 Double_t TH1::GetStdDevError(Int_t axis) const
7153 {
7154  return GetStdDev(axis+10);
7155 }
7156 
7157 ////////////////////////////////////////////////////////////////////////////////
7158 /// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7159 /// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7160 /// of the histogram along x, y or z axis
7161 ///
7162 ///Note, that since third and fourth moment are not calculated
7163 ///at the fill time, skewness and its standard error are computed bin by bin
7164 
7165 Double_t TH1::GetSkewness(Int_t axis) const
7166 {
7167 
7168  if (axis > 0 && axis <= 3){
7169 
7170  Double_t mean = GetMean(axis);
7171  Double_t stddev = GetStdDev(axis);
7172  Double_t stddev3 = stddev*stddev*stddev;
7173 
7174  Int_t firstBinX = fXaxis.GetFirst();
7175  Int_t lastBinX = fXaxis.GetLast();
7176  Int_t firstBinY = fYaxis.GetFirst();
7177  Int_t lastBinY = fYaxis.GetLast();
7178  Int_t firstBinZ = fZaxis.GetFirst();
7179  Int_t lastBinZ = fZaxis.GetLast();
7180  // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7181  if (GetStatOverflowsBehaviour()) {
7182  if ( !fXaxis.TestBit(TAxis::kAxisRange) ) {
7183  if (firstBinX == 1) firstBinX = 0;
7184  if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7185  }
7186  if ( !fYaxis.TestBit(TAxis::kAxisRange) ) {
7187  if (firstBinY == 1) firstBinY = 0;
7188  if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7189  }
7190  if ( !fZaxis.TestBit(TAxis::kAxisRange) ) {
7191  if (firstBinZ == 1) firstBinZ = 0;
7192  if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7193  }
7194  }
7195 
7196  Double_t x = 0;
7197  Double_t sum=0;
7198  Double_t np=0;
7199  for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7200  for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7201  for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7202  if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7203  else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7204  else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7205  Double_t w = GetBinContent(binx,biny,binz);
7206  np+=w;
7207  sum+=w*(x-mean)*(x-mean)*(x-mean);
7208  }
7209  }
7210  }
7211  sum/=np*stddev3;
7212  return sum;
7213  }
7214  else if (axis > 10 && axis <= 13) {
7215  //compute standard error of skewness
7216  // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7217  Double_t neff = GetEffectiveEntries();
7218  return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7219  }
7220  else {
7221  Error("GetSkewness", "illegal value of parameter");
7222  return 0;
7223  }
7224 }
7225 
7226 ////////////////////////////////////////////////////////////////////////////////
7227 /// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7228 /// Kurtosis(gaussian(0, 1)) = 0.
7229 /// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7230 /// of the histogram along x, y or z axis
7231 ////
7232 /// Note, that since third and fourth moment are not calculated
7233 /// at the fill time, kurtosis and its standard error are computed bin by bin
7234 
7235 Double_t TH1::GetKurtosis(Int_t axis) const
7236 {
7237  if (axis > 0 && axis <= 3){
7238 
7239  Double_t mean = GetMean(axis);
7240  Double_t stddev = GetStdDev(axis);
7241  Double_t stddev4 = stddev*stddev*stddev*stddev;
7242 
7243  Int_t firstBinX = fXaxis.GetFirst();
7244  Int_t lastBinX = fXaxis.GetLast();
7245  Int_t firstBinY = fYaxis.GetFirst();
7246  Int_t lastBinY = fYaxis.GetLast();
7247  Int_t firstBinZ = fZaxis.GetFirst();
7248  Int_t lastBinZ = fZaxis.GetLast();
7249  // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7250  if (GetStatOverflowsBehaviour()) {
7251  if ( !fXaxis.TestBit(TAxis::kAxisRange) ) {
7252  if (firstBinX == 1) firstBinX = 0;
7253  if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7254  }
7255  if ( !fYaxis.TestBit(TAxis::kAxisRange) ) {
7256  if (firstBinY == 1) firstBinY = 0;
7257  if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7258  }
7259  if ( !fZaxis.TestBit(TAxis::kAxisRange) ) {
7260  if (firstBinZ == 1) firstBinZ = 0;
7261  if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7262  }
7263  }
7264 
7265  Double_t x = 0;
7266  Double_t sum=0;
7267  Double_t np=0;
7268  for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7269  for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7270  for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7271  if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7272  else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7273  else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7274  Double_t w = GetBinContent(binx,biny,binz);
7275  np+=w;
7276  sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7277  }
7278  }
7279  }
7280  sum/=(np*stddev4);
7281  return sum-3;
7282 
7283  } else if (axis > 10 && axis <= 13) {
7284  //compute standard error of skewness
7285  // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7286  Double_t neff = GetEffectiveEntries();
7287  return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7288  }
7289  else {
7290  Error("GetKurtosis", "illegal value of parameter");
7291  return 0;
7292  }
7293 }
7294 
7295 ////////////////////////////////////////////////////////////////////////////////
7296 /// fill the array stats from the contents of this histogram
7297 /// The array stats must be correctly dimensioned in the calling program.
7298 ///
7299 /// ~~~ {.cpp}
7300 /// stats[0] = sumw
7301 /// stats[1] = sumw2
7302 /// stats[2] = sumwx
7303 /// stats[3] = sumwx2
7304 /// ~~~
7305 ///
7306 /// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7307 /// is simply a copy of the statistics quantities computed at filling time.
7308 /// If a sub-range is specified, the function recomputes these quantities
7309 /// from the bin contents in the current axis range.
7310 ///
7311 /// Note that the mean value/StdDev is computed using the bins in the currently
7312 /// defined range (see TAxis::SetRange). By default the range includes
7313 /// all bins from 1 to nbins included, excluding underflows and overflows.
7314 /// To force the underflows and overflows in the computation, one must
7315 /// call the static function TH1::StatOverflows(kTRUE) before filling
7316 /// the histogram.
7317 
7318 void TH1::GetStats(Double_t *stats) const
7319 {
7320  if (fBuffer) ((TH1*)this)->BufferEmpty();
7321 
7322  // Loop on bins (possibly including underflows/overflows)
7323  Int_t bin, binx;
7324  Double_t w,err;
7325  Double_t x;
7326  // identify the case of labels with extension of axis range
7327  // in this case the statistics in x does not make any sense
7328  Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && CanExtendAllAxes() );
7329  // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7330  if ((fTsumw == 0 && fEntries > 0) || ( fXaxis.TestBit(TAxis::kAxisRange) && !labelHist) ) {
7331  for (bin=0;bin<4;bin++) stats[bin] = 0;
7332 
7333  Int_t firstBinX = fXaxis.GetFirst();
7334  Int_t lastBinX = fXaxis.GetLast();
7335  // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7336  if (GetStatOverflowsBehaviour() && !fXaxis.TestBit(TAxis::kAxisRange)) {
7337  if (firstBinX == 1) firstBinX = 0;
7338  if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7339  }
7340  for (binx = firstBinX; binx <= lastBinX; binx++) {
7341  x = fXaxis.GetBinCenter(binx);
7342  //w = TMath::Abs(RetrieveBinContent(binx));
7343  // not sure what to do here if w < 0
7344  w = RetrieveBinContent(binx);
7345  err = TMath::Abs(GetBinError(binx));
7346  stats[0] += w;
7347  stats[1] += err*err;
7348  // statistics in x makes sense only for not labels histograms
7349  if (!labelHist) {
7350  stats[2] += w*x;
7351  stats[3] += w*x*x;
7352  }
7353  }
7354  // if (stats[0] < 0) {
7355  // // in case total is negative do something ??
7356  // stats[0] = 0;
7357  // }
7358  } else {
7359  stats[0] = fTsumw;
7360  stats[1] = fTsumw2;
7361  stats[2] = fTsumwx;
7362  stats[3] = fTsumwx2;
7363  }
7364 }
7365 
7366 ////////////////////////////////////////////////////////////////////////////////
7367 /// Replace current statistics with the values in array stats
7368 
7369 void TH1::PutStats(Double_t *stats)
7370 {
7371  fTsumw = stats[0];
7372  fTsumw2 = stats[1];
7373  fTsumwx = stats[2];
7374  fTsumwx2 = stats[3];
7375 }
7376 
7377 ////////////////////////////////////////////////////////////////////////////////
7378 /// Reset the statistics including the number of entries
7379 /// and replace with values calculates from bin content
7380 ///
7381 /// The number of entries is set to the total bin content or (in case of weighted histogram)
7382 /// to number of effective entries
7383 
7384 void TH1::ResetStats()
7385 {
7386  Double_t stats[kNstat] = {0};
7387  fTsumw = 0;
7388  fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
7389  GetStats(stats);
7390  PutStats(stats);
7391  fEntries = TMath::Abs(fTsumw);
7392  // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
7393  if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
7394 }
7395 
7396 ////////////////////////////////////////////////////////////////////////////////
7397 /// Return the sum of weights excluding under/overflows.
7398 
7399 Double_t TH1::GetSumOfWeights() const
7400 {
7401  if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7402 
7403  Int_t bin,binx,biny,binz;
7404  Double_t sum =0;
7405  for(binz=1; binz<=fZaxis.GetNbins(); binz++) {
7406  for(biny=1; biny<=fYaxis.GetNbins(); biny++) {
7407  for(binx=1; binx<=fXaxis.GetNbins(); binx++) {
7408  bin = GetBin(binx,biny,binz);
7409  sum += RetrieveBinContent(bin);
7410  }
7411  }
7412  }
7413  return sum;
7414 }
7415 
7416 ////////////////////////////////////////////////////////////////////////////////
7417 ///Return integral of bin contents. Only bins in the bins range are considered.
7418 ///
7419 /// By default the integral is computed as the sum of bin contents in the range.
7420 /// if option "width" is specified, the integral is the sum of
7421 /// the bin contents multiplied by the bin width in x.
7422 
7423 Double_t TH1::Integral(Option_t *option) const
7424 {
7425  return Integral(fXaxis.GetFirst(),fXaxis.GetLast(),option);
7426 }
7427 
7428 ////////////////////////////////////////////////////////////////////////////////
7429 /// Return integral of bin contents in range [binx1,binx2].
7430 ///
7431 /// By default the integral is computed as the sum of bin contents in the range.
7432 /// if option "width" is specified, the integral is the sum of
7433 /// the bin contents multiplied by the bin width in x.
7434 
7435 Double_t TH1::Integral(Int_t binx1, Int_t binx2, Option_t *option) const
7436 {
7437  double err = 0;
7438  return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
7439 }
7440 
7441 ////////////////////////////////////////////////////////////////////////////////
7442 /// Return integral of bin contents in range [binx1,binx2] and its error.
7443 ///
7444 /// By default the integral is computed as the sum of bin contents in the range.
7445 /// if option "width" is specified, the integral is the sum of
7446 /// the bin contents multiplied by the bin width in x.
7447 /// the error is computed using error propagation from the bin errors assuming that
7448 /// all the bins are uncorrelated
7449 
7450 Double_t TH1::IntegralAndError(Int_t binx1, Int_t binx2, Double_t & error, Option_t *option) const
7451 {
7452  return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
7453 }
7454 
7455 ////////////////////////////////////////////////////////////////////////////////
7456 /// Internal function compute integral and optionally the error between the limits
7457 /// specified by the bin number values working for all histograms (1D, 2D and 3D)
7458 
7459 Double_t TH1::DoIntegral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error ,
7460  Option_t *option, Bool_t doError) const
7461 {
7462  if (fBuffer) ((TH1*)this)->BufferEmpty();
7463 
7464  Int_t nx = GetNbinsX() + 2;
7465  if (binx1 < 0) binx1 = 0;
7466  if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
7467 
7468  if (GetDimension() > 1) {
7469  Int_t ny = GetNbinsY() + 2;
7470  if (biny1 < 0) biny1 = 0;
7471  if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
7472  } else {
7473  biny1 = 0; biny2 = 0;
7474  }
7475 
7476  if (GetDimension() > 2) {
7477  Int_t nz = GetNbinsZ() + 2;
7478  if (binz1 < 0) binz1 = 0;
7479  if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
7480  } else {
7481  binz1 = 0; binz2 = 0;
7482  }
7483 
7484  // - Loop on bins in specified range
7485  TString opt = option;
7486  opt.ToLower();
7487  Bool_t width = kFALSE;
7488  if (opt.Contains("width")) width = kTRUE;
7489 
7490 
7491  Double_t dx = 1., dy = .1, dz =.1;
7492  Double_t integral = 0;
7493  Double_t igerr2 = 0;
7494  for (Int_t binx = binx1; binx <= binx2; ++binx) {
7495  if (width) dx = fXaxis.GetBinWidth(binx);
7496  for (Int_t biny = biny1; biny <= biny2; ++biny) {
7497  if (width) dy = fYaxis.GetBinWidth(biny);
7498  for (Int_t binz = binz1; binz <= binz2; ++binz) {
7499  Int_t bin = GetBin(binx, biny, binz);
7500  Double_t dv = 0.0;
7501  if (width) {
7502  dz = fZaxis.GetBinWidth(binz);
7503  dv = dx * dy * dz;
7504  integral += RetrieveBinContent(bin) * dv;
7505  } else {
7506  integral += RetrieveBinContent(bin);
7507  }
7508  if (doError) {
7509  if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
7510  else igerr2 += GetBinErrorSqUnchecked(bin);
7511  }
7512  }
7513  }
7514  }
7515 
7516  if (doError) error = TMath::Sqrt(igerr2);
7517  return integral;
7518 }
7519 
7520 ////////////////////////////////////////////////////////////////////////////////
7521 /// Statistical test of compatibility in shape between
7522 /// this histogram and h2, using the Anderson-Darling 2 sample test.
7523 ///
7524 /// The AD 2 sample test formula are derived from the paper
7525 /// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
7526 ///
7527 /// The test is implemented in root in the ROOT::Math::GoFTest class
7528 /// It is the same formula ( (6) in the paper), and also shown in
7529 /// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
7530 ///
7531 /// Binned data are considered as un-binned data
7532 /// with identical observation happening in the bin center.
7533 ///
7534 /// \param[in] option is a character string to specify options
7535 /// - "D" Put out a line of "Debug" printout
7536 /// - "T" Return the normalized A-D test statistic
7537 ///
7538 /// - Note1: Underflow and overflow are not considered in the test
7539 /// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
7540 /// - Note3: The histograms are not required to have the same X axis
7541 /// - Note4: The test works only for 1-dimensional histograms
7542 
7543 Double_t TH1::AndersonDarlingTest(const TH1 *h2, Option_t *option) const
7544 {
7545  Double_t advalue = 0;
7546  Double_t pvalue = AndersonDarlingTest(h2, advalue);
7547 
7548  TString opt = option;
7549  opt.ToUpper();
7550  if (opt.Contains("D") ) {
7551  printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
7552  }
7553  if (opt.Contains("T") ) return advalue;
7554 
7555  return pvalue;
7556 }
7557 
7558 ////////////////////////////////////////////////////////////////////////////////
7559 /// Same function as above but returning also the test statistic value
7560 
7561 Double_t TH1::AndersonDarlingTest(const TH1 *h2, Double_t & advalue) const
7562 {
7563  if (GetDimension() != 1 || h2->GetDimension() != 1) {
7564  Error("AndersonDarlingTest","Histograms must be 1-D");
7565  return -1;
7566  }
7567 
7568  // empty the buffer. Probably we could add as an unbinned test
7569  if (fBuffer) ((TH1*)this)->BufferEmpty();
7570 
7571  // use the BinData class
7572  ROOT::Fit::BinData data1;
7573  ROOT::Fit::BinData data2;
7574 
7575  ROOT::Fit::FillData(data1, this, 0);
7576  ROOT::Fit::FillData(data2, h2, 0);
7577 
7578  double pvalue;
7579  ROOT::Math::GoFTest::AndersonDarling2SamplesTest(data1,data2, pvalue,advalue);
7580 
7581  return pvalue;
7582 }
7583 
7584 ////////////////////////////////////////////////////////////////////////////////
7585 /// Statistical test of compatibility in shape between
7586 /// this histogram and h2, using Kolmogorov test.
7587 /// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
7588 /// and not for binned data as in the case of the histogram (see NOTE 3 below).
7589 /// So, before using this method blindly, read the NOTE 3.
7590 ///
7591 /// Default: Ignore under- and overflow bins in comparison
7592 ///
7593 /// \param[in] h2 histogram
7594 /// \param[in] option is a character string to specify options
7595 /// - "U" include Underflows in test (also for 2-dim)
7596 /// - "O" include Overflows (also valid for 2-dim)
7597 /// - "N" include comparison of normalizations
7598 /// - "D" Put out a line of "Debug" printout
7599 /// - "M" Return the Maximum Kolmogorov distance instead of prob
7600 /// - "X" Run the pseudo experiments post-processor with the following procedure:
7601 /// make pseudoexperiments based on random values from the parent distribution,
7602 /// compare the KS distance of the pseudoexperiment to the parent
7603 /// distribution, and count all the KS values above the value
7604 /// obtained from the original data to Monte Carlo distribution.
7605 /// The number of pseudo-experiments nEXPT is currently fixed at 1000.
7606 /// The function returns the probability.
7607 /// (thanks to Ben Kilminster to submit this procedure). Note that
7608 /// this option "X" is much slower.
7609 ///
7610 /// The returned function value is the probability of test
7611 /// (much less than one means NOT compatible)
7612 ///
7613 /// Code adapted by Rene Brun from original HBOOK routine HDIFF
7614 ///
7615 /// NOTE1
7616 /// A good description of the Kolmogorov test can be seen at:
7617 /// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
7618 ///
7619 /// NOTE2
7620 /// see also alternative function TH1::Chi2Test
7621 /// The Kolmogorov test is assumed to give better results than Chi2Test
7622 /// in case of histograms with low statistics.
7623 ///
7624 /// NOTE3 (Jan Conrad, Fred James)
7625 /// "The returned value PROB is calculated such that it will be
7626 /// uniformly distributed between zero and one for compatible histograms,
7627 /// provided the data are not binned (or the number of bins is very large
7628 /// compared with the number of events). Users who have access to unbinned
7629 /// data and wish exact confidence levels should therefore not put their data
7630 /// into histograms, but should call directly TMath::KolmogorovTest. On
7631 /// the other hand, since TH1 is a convenient way of collecting data and
7632 /// saving space, this function has been provided. However, the values of
7633 /// PROB for binned data will be shifted slightly higher than expected,
7634 /// depending on the effects of the binning. For example, when comparing two
7635 /// uniform distributions of 500 events in 100 bins, the values of PROB,
7636 /// instead of being exactly uniformly distributed between zero and one, have
7637 /// a mean value of about 0.56. We can apply a useful
7638 /// rule: As long as the bin width is small compared with any significant
7639 /// physical effect (for example the experimental resolution) then the binning
7640 /// cannot have an important effect. Therefore, we believe that for all
7641 /// practical purposes, the probability value PROB is calculated correctly
7642 /// provided the user is aware that:
7643 ///
7644 /// 1. The value of PROB should not be expected to have exactly the correct
7645 /// distribution for binned data.
7646 /// 2. The user is responsible for seeing to it that the bin widths are
7647 /// small compared with any physical phenomena of interest.
7648 /// 3. The effect of binning (if any) is always to make the value of PROB
7649 /// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
7650 /// will assure that at most 5% of truly compatible histograms are rejected,
7651 /// and usually somewhat less."
7652 ///
7653 /// Note also that for GoF test of unbinned data ROOT provides also the class
7654 /// ROOT::Math::GoFTest. The class has also method for doing one sample tests
7655 /// (i.e. comparing the data with a given distribution).
7656 
7657 Double_t TH1::KolmogorovTest(const TH1 *h2, Option_t *option) const
7658 {
7659  TString opt = option;
7660  opt.ToUpper();
7661 
7662  Double_t prob = 0;
7663  TH1 *h1 = (TH1*)this;
7664  if (h2 == 0) return 0;
7665  const TAxis *axis1 = h1->GetXaxis();
7666  const TAxis *axis2 = h2->GetXaxis();
7667  Int_t ncx1 = axis1->GetNbins();
7668  Int_t ncx2 = axis2->GetNbins();
7669 
7670  // Check consistency of dimensions
7671  if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
7672  Error("KolmogorovTest","Histograms must be 1-D\n");
7673  return 0;
7674  }
7675 
7676  // Check consistency in number of channels
7677  if (ncx1 != ncx2) {
7678  Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
7679  return 0;
7680  }
7681 
7682  // empty the buffer. Probably we could add as an unbinned test
7683  if (fBuffer) ((TH1*)this)->BufferEmpty();
7684 
7685  // Check consistency in bin edges
7686  for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
7687  if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
7688  Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
7689  return 0;
7690  }
7691  }
7692 
7693  Bool_t afunc1 = kFALSE;
7694  Bool_t afunc2 = kFALSE;
7695  Double_t sum1 = 0, sum2 = 0;
7696  Double_t ew1, ew2, w1 = 0, w2 = 0;
7697  Int_t bin;
7698  Int_t ifirst = 1;
7699  Int_t ilast = ncx1;
7700  // integral of all bins (use underflow/overflow if option)
7701  if (opt.Contains("U")) ifirst = 0;
7702  if (opt.Contains("O")) ilast = ncx1 +1;
7703  for (bin = ifirst; bin <= ilast; bin++) {
7704  sum1 += h1->RetrieveBinContent(bin);
7705  sum2 += h2->RetrieveBinContent(bin);
7706  ew1 = h1->GetBinError(bin);
7707  ew2 = h2->GetBinError(bin);
7708  w1 += ew1*ew1;
7709  w2 += ew2*ew2;
7710  }
7711  if (sum1 == 0) {
7712  Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
7713  return 0;
7714  }
7715  if (sum2 == 0) {
7716  Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
7717  return 0;
7718  }
7719 
7720  // calculate the effective entries.
7721  // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
7722  // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
7723  Double_t esum1 = 0, esum2 = 0;
7724  if (w1 > 0)
7725  esum1 = sum1 * sum1 / w1;
7726  else
7727  afunc1 = kTRUE; // use later for calculating z
7728 
7729  if (w2 > 0)
7730  esum2 = sum2 * sum2 / w2;
7731  else
7732  afunc2 = kTRUE; // use later for calculating z
7733 
7734  if (afunc2 && afunc1) {
7735  Error("KolmogorovTest","Errors are zero for both histograms\n");
7736  return 0;
7737  }
7738 
7739 
7740  Double_t s1 = 1/sum1;
7741  Double_t s2 = 1/sum2;
7742 
7743  // Find largest difference for Kolmogorov Test
7744  Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
7745 
7746  for (bin=ifirst;bin<=ilast;bin++) {
7747  rsum1 += s1*h1->RetrieveBinContent(bin);
7748  rsum2 += s2*h2->RetrieveBinContent(bin);
7749  dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
7750  }
7751 
7752  // Get Kolmogorov probability
7753  Double_t z, prb1=0, prb2=0, prb3=0;
7754 
7755  // case h1 is exact (has zero errors)
7756  if (afunc1)
7757  z = dfmax*TMath::Sqrt(esum2);
7758  // case h2 has zero errors
7759  else if (afunc2)
7760  z = dfmax*TMath::Sqrt(esum1);
7761  else
7762  // for comparison between two data sets
7763  z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
7764 
7765  prob = TMath::KolmogorovProb(z);
7766 
7767  // option N to combine normalization makes sense if both afunc1 and afunc2 are false
7768  if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
7769  // Combine probabilities for shape and normalization,
7770  prb1 = prob;
7771  Double_t d12 = esum1-esum2;
7772  Double_t chi2 = d12*d12/(esum1+esum2);
7773  prb2 = TMath::Prob(chi2,1);
7774  // see Eadie et al., section 11.6.2
7775  if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
7776  else prob = 0;
7777  }
7778  // X option. Pseudo-experiments post-processor to determine KS probability
7779  const Int_t nEXPT = 1000;
7780  if (opt.Contains("X") && !(afunc1 || afunc2 ) ) {
7781  Double_t dSEXPT;
7782  TH1 *h1_cpy = (TH1 *)(gDirectory ? gDirectory->CloneObject(this, kFALSE) : gROOT->CloneObject(this, kFALSE));
7783  TH1 *h1Expt = (TH1*)(gDirectory ? gDirectory->CloneObject(this,kFALSE) : gROOT->CloneObject(this,kFALSE));
7784  TH1 *h2Expt = (TH1*)(gDirectory ? gDirectory->CloneObject(this,kFALSE) : gROOT->CloneObject(this,kFALSE));
7785 
7786  if (GetMinimum() < 0.0) {
7787  // we need to create a new histogram
7788  // With negative bins we can't draw random samples in a meaningful way.
7789  Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
7790  "skewed. Reduce number of bins for histogram?");
7791  while (h1_cpy->GetMinimum() < 0.0) {
7792  Int_t idx = h1_cpy->GetMinimumBin();
7793  h1_cpy->SetBinContent(idx, 0.0);
7794  }
7795  }
7796 
7797  // make nEXPT experiments (this should be a parameter)
7798  prb3 = 0;
7799  for (Int_t i=0; i < nEXPT; i++) {
7800  h1Expt->Reset();
7801  h2Expt->Reset();
7802  h1Expt->FillRandom(h1_cpy, (Int_t)esum1);
7803  h2Expt->FillRandom(h1_cpy, (Int_t)esum2);
7804  dSEXPT = h1Expt->KolmogorovTest(h2Expt,"M");
7805  if (dSEXPT>dfmax) prb3 += 1.0;
7806  }
7807  prb3 /= (Double_t)nEXPT;
7808  delete h1_cpy;
7809  delete h1Expt;
7810  delete h2Expt;
7811  }
7812 
7813  // debug printout
7814  if (opt.Contains("D")) {
7815  printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
7816  printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
7817  printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
7818  if (opt.Contains("N"))
7819  printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
7820  if (opt.Contains("X"))
7821  printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
7822  }
7823  // This numerical error condition should never occur:
7824  if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
7825  if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
7826 
7827  if(opt.Contains("M")) return dfmax;
7828  else if(opt.Contains("X")) return prb3;
7829  else return prob;
7830 }
7831 
7832 ////////////////////////////////////////////////////////////////////////////////
7833 /// Replace bin contents by the contents of array content
7834 
7835 void TH1::SetContent(const Double_t *content)
7836 {
7837  fEntries = fNcells;
7838  fTsumw = 0;
7839  for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
7840 }
7841 
7842 ////////////////////////////////////////////////////////////////////////////////
7843 /// Return contour values into array levels if pointer levels is non zero.
7844 ///
7845 /// The function returns the number of contour levels.
7846 /// see GetContourLevel to return one contour only
7847 
7848 Int_t TH1::GetContour(Double_t *levels)
7849 {
7850  Int_t nlevels = fContour.fN;
7851  if (levels) {
7852  if (nlevels == 0) {
7853  nlevels = 20;
7854  SetContour(nlevels);
7855  } else {
7856  if (TestBit(kUserContour) == 0) SetContour(nlevels);
7857  }
7858  for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
7859  }
7860  return nlevels;
7861 }
7862 
7863 ////////////////////////////////////////////////////////////////////////////////
7864 /// Return value of contour number level.
7865 /// Use GetContour to return the array of all contour levels
7866 
7867 Double_t TH1::GetContourLevel(Int_t level) const
7868 {
7869  return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
7870 }
7871 
7872 ////////////////////////////////////////////////////////////////////////////////
7873 /// Return the value of contour number "level" in Pad coordinates.
7874 /// ie: if the Pad is in log scale along Z it returns le log of the contour level
7875 /// value. See GetContour to return the array of all contour levels
7876 
7877 Double_t TH1::GetContourLevelPad(Int_t level) const
7878 {
7879  if (level <0 || level >= fContour.fN) return 0;
7880  Double_t zlevel = fContour.fArray[level];
7881 
7882  // In case of user defined contours and Pad in log scale along Z,
7883  // fContour.fArray doesn't contain the log of the contour whereas it does
7884  // in case of equidistant contours.
7885  if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
7886  if (zlevel <= 0) return 0;
7887  zlevel = TMath::Log10(zlevel);
7888  }
7889  return zlevel;
7890 }
7891 
7892 ////////////////////////////////////////////////////////////////////////////////
7893 /// Set the maximum number of entries to be kept in the buffer.
7894 
7895 void TH1::SetBuffer(Int_t buffersize, Option_t * /*option*/)
7896 {
7897  if (fBuffer) {
7898  BufferEmpty();
7899  delete [] fBuffer;
7900  fBuffer = 0;
7901  }
7902  if (buffersize <= 0) {
7903  fBufferSize = 0;
7904  return;
7905  }
7906  if (buffersize < 100) buffersize = 100;
7907  fBufferSize = 1 + buffersize*(fDimension+1);
7908  fBuffer = new Double_t[fBufferSize];
7909  memset(fBuffer,0,sizeof(Double_t)*fBufferSize);
7910 }
7911 
7912 ////////////////////////////////////////////////////////////////////////////////
7913 /// Set the number and values of contour levels.
7914 ///
7915 /// By default the number of contour levels is set to 20. The contours values
7916 /// in the array "levels" should be specified in increasing order.
7917 ///
7918 /// if argument levels = 0 or missing, equidistant contours are computed
7919 
7920 void TH1::SetContour(Int_t nlevels, const Double_t *levels)
7921 {
7922  Int_t level;
7923  ResetBit(kUserContour);
7924  if (nlevels <=0 ) {
7925  fContour.Set(0);
7926  return;
7927  }
7928  fContour.Set(nlevels);
7929 
7930  // - Contour levels are specified
7931  if (levels) {
7932  SetBit(kUserContour);
7933  for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
7934  } else {
7935  // - contour levels are computed automatically as equidistant contours
7936  Double_t zmin = GetMinimum();
7937  Double_t zmax = GetMaximum();
7938  if ((zmin == zmax) && (zmin != 0)) {
7939  zmax += 0.01*TMath::Abs(zmax);
7940  zmin -= 0.01*TMath::Abs(zmin);
7941  }
7942  Double_t dz = (zmax-zmin)/Double_t(nlevels);
7943  if (gPad && gPad->GetLogz()) {
7944  if (zmax <= 0) return;
7945  if (zmin <= 0) zmin = 0.001*zmax;
7946  zmin = TMath::Log10(zmin);
7947  zmax = TMath::Log10(zmax);
7948  dz = (zmax-zmin)/Double_t(nlevels);
7949  }
7950  for (level=0; level<nlevels; level++) {
7951  fContour.fArray[level] = zmin + dz*Double_t(level);
7952  }
7953  }
7954 }
7955 
7956 ////////////////////////////////////////////////////////////////////////////////
7957 /// Set value for one contour level.
7958 
7959 void TH1::SetContourLevel(Int_t level, Double_t value)
7960 {
7961  if (level < 0 || level >= fContour.fN) return;
7962  SetBit(kUserContour);
7963  fContour.fArray[level] = value;
7964 }
7965 
7966 ////////////////////////////////////////////////////////////////////////////////
7967 /// Return maximum value smaller than maxval of bins in the range,
7968 /// unless the value has been overridden by TH1::SetMaximum,
7969 /// in which case it returns that value. (This happens, for example,
7970 /// when the histogram is drawn and the y or z axis limits are changed
7971 ///
7972 /// To get the maximum value of bins in the histogram regardless of
7973 /// whether the value has been overridden, use
7974 ///
7975 /// ~~~ {.cpp}
7976 /// h->GetBinContent(h->GetMaximumBin())
7977 /// ~~~
7978 
7979 Double_t TH1::GetMaximum(Double_t maxval) const
7980 {
7981  if (fMaximum != -1111) return fMaximum;
7982 
7983  // empty the buffer
7984  if (fBuffer) ((TH1*)this)->BufferEmpty();
7985 
7986  Int_t bin, binx, biny, binz;
7987  Int_t xfirst = fXaxis.GetFirst();
7988  Int_t xlast = fXaxis.GetLast();
7989  Int_t yfirst = fYaxis.GetFirst();
7990  Int_t ylast = fYaxis.GetLast();
7991  Int_t zfirst = fZaxis.GetFirst();
7992  Int_t zlast = fZaxis.GetLast();
7993  Double_t maximum = -FLT_MAX, value;
7994  for (binz=zfirst;binz<=zlast;binz++) {
7995  for (biny=yfirst;biny<=ylast;biny++) {
7996  for (binx=xfirst;binx<=xlast;binx++) {
7997  bin = GetBin(binx,biny,binz);
7998  value = RetrieveBinContent(bin);
7999  if (value > maximum && value < maxval) maximum = value;
8000  }
8001  }
8002  }
8003  return maximum;
8004 }
8005 
8006 ////////////////////////////////////////////////////////////////////////////////
8007 /// Return location of bin with maximum value in the range.
8008 
8009 Int_t TH1::GetMaximumBin() const
8010 {
8011  Int_t locmax, locmay, locmaz;
8012  return GetMaximumBin(locmax, locmay, locmaz);
8013 }
8014 
8015 ////////////////////////////////////////////////////////////////////////////////
8016 /// Return location of bin with maximum value in the range.
8017 
8018 Int_t TH1::GetMaximumBin(Int_t &locmax, Int_t &locmay, Int_t &locmaz) const
8019 {
8020  // empty the buffer
8021  if (fBuffer) ((TH1*)this)->BufferEmpty();
8022 
8023  Int_t bin, binx, biny, binz;
8024  Int_t locm;
8025  Int_t xfirst = fXaxis.GetFirst();
8026  Int_t xlast = fXaxis.GetLast();
8027  Int_t yfirst = fYaxis.GetFirst();
8028  Int_t ylast = fYaxis.GetLast();
8029  Int_t zfirst = fZaxis.GetFirst();
8030  Int_t zlast = fZaxis.GetLast();
8031  Double_t maximum = -FLT_MAX, value;
8032  locm = locmax = locmay = locmaz = 0;
8033  for (binz=zfirst;binz<=zlast;binz++) {
8034  for (biny=yfirst;biny<=ylast;biny++) {
8035  for (binx=xfirst;binx<=xlast;binx++) {
8036  bin = GetBin(binx,biny,binz);
8037  value = RetrieveBinContent(bin);
8038  if (value > maximum) {
8039  maximum = value;
8040  locm = bin;
8041  locmax = binx;
8042  locmay = biny;
8043  locmaz = binz;
8044  }
8045  }
8046  }
8047  }
8048  return locm;
8049 }
8050 
8051 ////////////////////////////////////////////////////////////////////////////////
8052 /// Return minimum value larger than minval of bins in the range,
8053 /// unless the value has been overridden by TH1::SetMinimum,
8054 /// in which case it returns that value. (This happens, for example,
8055 /// when the histogram is drawn and the y or z axis limits are changed
8056 ///
8057 /// To get the minimum value of bins in the histogram regardless of
8058 /// whether the value has been overridden, use
8059 ///
8060 /// ~~~ {.cpp}
8061 /// h->GetBinContent(h->GetMinimumBin())
8062 /// ~~~
8063 
8064 Double_t TH1::GetMinimum(Double_t minval) const
8065 {
8066  if (fMinimum != -1111) return fMinimum;
8067 
8068  // empty the buffer
8069  if (fBuffer) ((TH1*)this)->BufferEmpty();
8070 
8071  Int_t bin, binx, biny, binz;
8072  Int_t xfirst = fXaxis.GetFirst();
8073  Int_t xlast = fXaxis.GetLast();
8074  Int_t yfirst = fYaxis.GetFirst();
8075  Int_t ylast = fYaxis.GetLast();
8076  Int_t zfirst = fZaxis.GetFirst();
8077  Int_t zlast = fZaxis.GetLast();
8078  Double_t minimum=FLT_MAX, value;
8079  for (binz=zfirst;binz<=zlast;binz++) {
8080  for (biny=yfirst;biny<=ylast;biny++) {
8081  for (binx=xfirst;binx<=xlast;binx++) {
8082  bin = GetBin(binx,biny,binz);
8083  value = RetrieveBinContent(bin);
8084  if (value < minimum && value > minval) minimum = value;
8085  }
8086  }
8087  }
8088  return minimum;
8089 }
8090 
8091 ////////////////////////////////////////////////////////////////////////////////
8092 /// Return location of bin with minimum value in the range.
8093 
8094 Int_t TH1::GetMinimumBin() const
8095 {
8096  Int_t locmix, locmiy, locmiz;
8097  return GetMinimumBin(locmix, locmiy, locmiz);
8098 }
8099 
8100 ////////////////////////////////////////////////////////////////////////////////
8101 /// Return location of bin with minimum value in the range.
8102 
8103 Int_t TH1::GetMinimumBin(Int_t &locmix, Int_t &locmiy, Int_t &locmiz) const
8104 {
8105  // empty the buffer
8106  if (fBuffer) ((TH1*)this)->BufferEmpty();
8107 
8108  Int_t bin, binx, biny, binz;
8109  Int_t locm;
8110  Int_t xfirst = fXaxis.GetFirst();
8111  Int_t xlast = fXaxis.GetLast();
8112  Int_t yfirst = fYaxis.GetFirst();
8113  Int_t ylast = fYaxis.GetLast();
8114  Int_t zfirst = fZaxis.GetFirst();
8115  Int_t zlast = fZaxis.GetLast();
8116  Double_t minimum = FLT_MAX, value;
8117  locm = locmix = locmiy = locmiz = 0;
8118  for (binz=zfirst;binz<=zlast;binz++) {
8119  for (biny=yfirst;biny<=ylast;biny++) {
8120  for (binx=xfirst;binx<=xlast;binx++) {
8121  bin = GetBin(binx,biny,binz);
8122  value = RetrieveBinContent(bin);
8123  if (value < minimum) {
8124  minimum = value;
8125  locm = bin;
8126  locmix = binx;
8127  locmiy = biny;
8128  locmiz = binz;
8129  }
8130  }
8131  }
8132  }
8133  return locm;
8134 }
8135 
8136 ///////////////////////////////////////////////////////////////////////////////
8137 /// Retrieve the minimum and maximum values in the histogram
8138 ///
8139 /// This will not return a cached value and will always search the
8140 /// histogram for the min and max values. The user can condition whether
8141 /// or not to call this with the GetMinimumStored() and GetMaximumStored()
8142 /// methods. If the cache is empty, then the value will be -1111. Users
8143 /// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8144 /// For example, the following recipe will make efficient use of this method
8145 /// and the cached minimum and maximum values.
8146 //
8147 /// \code{.cpp}
8148 /// Double_t currentMin = pHist->GetMinimumStored();
8149 /// Double_t currentMax = pHist->GetMaximumStored();
8150 /// if ((currentMin == -1111) || (currentMax == -1111)) {
8151 /// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8152 /// pHist->SetMinimum(currentMin);
8153 /// pHist->SetMaximum(currentMax);
8154 /// }
8155 /// \endcode
8156 ///
8157 /// \param min reference to variable that will hold found minimum value
8158 /// \param max reference to variable that will hold found maximum value
8159 
8160 void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8161 {
8162  // empty the buffer
8163  if (fBuffer) ((TH1*)this)->BufferEmpty();
8164 
8165  Int_t bin, binx, biny, binz;
8166  Int_t xfirst = fXaxis.GetFirst();
8167  Int_t xlast = fXaxis.GetLast();
8168  Int_t yfirst = fYaxis.GetFirst();
8169  Int_t ylast = fYaxis.GetLast();
8170  Int_t zfirst = fZaxis.GetFirst();
8171  Int_t zlast = fZaxis.GetLast();
8172  min=TMath::Infinity();
8173  max=-TMath::Infinity();
8174  Double_t value;
8175  for (binz=zfirst;binz<=zlast;binz++) {
8176  for (biny=yfirst;biny<=ylast;biny++) {
8177  for (binx=xfirst;binx<=xlast;binx++) {
8178  bin = GetBin(binx,biny,binz);
8179  value = RetrieveBinContent(bin);
8180  if (value < min) min = value;
8181  if (value > max) max = value;
8182  }
8183  }
8184  }
8185 }
8186 
8187 ////////////////////////////////////////////////////////////////////////////////
8188 /// Redefine x axis parameters.
8189 ///
8190 /// The X axis parameters are modified.
8191 /// The bins content array is resized
8192 /// if errors (Sumw2) the errors array is resized
8193 /// The previous bin contents are lost
8194 /// To change only the axis limits, see TAxis::SetRange
8195 
8196 void TH1::SetBins(Int_t nx, Double_t xmin, Double_t xmax)
8197 {
8198  if (GetDimension() != 1) {
8199  Error("SetBins","Operation only valid for 1-d histograms");
8200  return;
8201  }
8202  fXaxis.SetRange(0,0);
8203  fXaxis.Set(nx,xmin,xmax);
8204  fYaxis.Set(1,0,1);
8205  fZaxis.Set(1,0,1);
8206  fNcells = nx+2;
8207  SetBinsLength(fNcells);
8208  if (fSumw2.fN) {
8209  fSumw2.Set(fNcells);
8210  }
8211 }
8212 
8213 ////////////////////////////////////////////////////////////////////////////////
8214 /// Redefine x axis parameters with variable bin sizes.
8215 ///
8216 /// The X axis parameters are modified.
8217 /// The bins content array is resized
8218 /// if errors (Sumw2) the errors array is resized
8219 /// The previous bin contents are lost
8220 /// To change only the axis limits, see TAxis::SetRange
8221 /// xBins is supposed to be of length nx+1
8222 
8223 void TH1::SetBins(Int_t nx, const Double_t *xBins)
8224 {
8225  if (GetDimension() != 1) {
8226  Error("SetBins","Operation only valid for 1-d histograms");
8227  return;
8228  }
8229  fXaxis.SetRange(0,0);
8230  fXaxis.Set(nx,xBins);
8231  fYaxis.Set(1,0,1);
8232  fZaxis.Set(1,0,1);
8233  fNcells = nx+2;
8234  SetBinsLength(fNcells);
8235  if (fSumw2.fN) {
8236  fSumw2.Set(fNcells);
8237  }
8238 }
8239 
8240 ////////////////////////////////////////////////////////////////////////////////
8241 /// Redefine x and y axis parameters.
8242 ///
8243 /// The X and Y axis parameters are modified.
8244 /// The bins content array is resized
8245 /// if errors (Sumw2) the errors array is resized
8246 /// The previous bin contents are lost
8247 /// To change only the axis limits, see TAxis::SetRange
8248 
8249 void TH1::SetBins(Int_t nx, Double_t xmin, Double_t xmax, Int_t ny, Double_t ymin, Double_t ymax)
8250 {
8251  if (GetDimension() != 2) {
8252  Error("SetBins","Operation only valid for 2-D histograms");
8253  return;
8254  }
8255  fXaxis.SetRange(0,0);
8256  fYaxis.SetRange(0,0);
8257  fXaxis.Set(nx,xmin,xmax);
8258  fYaxis.Set(ny,ymin,ymax);
8259  fZaxis.Set(1,0,1);
8260  fNcells = (nx+2)*(ny+2);
8261  SetBinsLength(fNcells);
8262  if (fSumw2.fN) {
8263  fSumw2.Set(fNcells);
8264  }
8265 }
8266 
8267 ////////////////////////////////////////////////////////////////////////////////
8268 /// Redefine x and y axis parameters with variable bin sizes.
8269 ///
8270 /// The X and Y axis parameters are modified.
8271 /// The bins content array is resized
8272 /// if errors (Sumw2) the errors array is resized
8273 /// The previous bin contents are lost
8274 /// To change only the axis limits, see TAxis::SetRange
8275 /// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
8276 
8277 void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
8278 {
8279  if (GetDimension() != 2) {
8280  Error("SetBins","Operation only valid for 2-D histograms");
8281  return;
8282  }
8283  fXaxis.SetRange(0,0);
8284  fYaxis.SetRange(0,0);
8285  fXaxis.Set(nx,xBins);
8286  fYaxis.Set(ny,yBins);
8287  fZaxis.Set(1,0,1);
8288  fNcells = (nx+2)*(ny+2);
8289  SetBinsLength(fNcells);
8290  if (fSumw2.fN) {
8291  fSumw2.Set(fNcells);
8292  }
8293 }
8294 
8295 ////////////////////////////////////////////////////////////////////////////////
8296 /// Redefine x, y and z axis parameters.
8297 ///
8298 /// The X, Y and Z axis parameters are modified.
8299 /// The bins content array is resized
8300 /// if errors (Sumw2) the errors array is resized
8301 /// The previous bin contents are lost
8302 /// To change only the axis limits, see TAxis::SetRange
8303 
8304 void TH1::SetBins(Int_t nx, Double_t xmin, Double_t xmax, Int_t ny, Double_t ymin, Double_t ymax, Int_t nz, Double_t zmin, Double_t zmax)
8305 {
8306  if (GetDimension() != 3) {
8307  Error("SetBins","Operation only valid for 3-D histograms");
8308  return;
8309  }
8310  fXaxis.SetRange(0,0);
8311  fYaxis.SetRange(0,0);
8312  fZaxis.SetRange(0,0);
8313  fXaxis.Set(nx,xmin,xmax);
8314  fYaxis.Set(ny,ymin,ymax);
8315  fZaxis.Set(nz,zmin,zmax);
8316  fNcells = (nx+2)*(ny+2)*(nz+2);
8317  SetBinsLength(fNcells);
8318  if (fSumw2.fN) {
8319  fSumw2.Set(fNcells);
8320  }
8321 }
8322 
8323 ////////////////////////////////////////////////////////////////////////////////
8324 /// Redefine x, y and z axis parameters with variable bin sizes.
8325 ///
8326 /// The X, Y and Z axis parameters are modified.
8327 /// The bins content array is resized
8328 /// if errors (Sumw2) the errors array is resized
8329 /// The previous bin contents are lost
8330 /// To change only the axis limits, see TAxis::SetRange
8331 /// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
8332 /// zBins is supposed to be of length nz+1
8333 
8334 void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
8335 {
8336  if (GetDimension() != 3) {
8337  Error("SetBins","Operation only valid for 3-D histograms");
8338  return;
8339  }
8340  fXaxis.SetRange(0,0);
8341  fYaxis.SetRange(0,0);
8342  fZaxis.SetRange(0,0);
8343  fXaxis.Set(nx,xBins);
8344  fYaxis.Set(ny,yBins);
8345  fZaxis.Set(nz,zBins);
8346  fNcells = (nx+2)*(ny+2)*(nz+2);
8347  SetBinsLength(fNcells);
8348  if (fSumw2.fN) {
8349  fSumw2.Set(fNcells);
8350  }
8351 }
8352 
8353 ////////////////////////////////////////////////////////////////////////////////
8354 /// By default when an histogram is created, it is added to the list
8355 /// of histogram objects in the current directory in memory.
8356 /// Remove reference to this histogram from current directory and add
8357 /// reference to new directory dir. dir can be 0 in which case the
8358 /// histogram does not belong to any directory.
8359 ///
8360 /// Note that the directory is not a real property of the histogram and
8361 /// it will not be copied when the histogram is copied or cloned.
8362 /// If the user wants to have the copied (cloned) histogram in the same
8363 /// directory, he needs to set again the directory using SetDirectory to the
8364 /// copied histograms
8365 
8366 void TH1::SetDirectory(TDirectory *dir)
8367 {
8368  if (fDirectory == dir) return;
8369  if (fDirectory) fDirectory->Remove(this);
8370  fDirectory = dir;
8371  if (fDirectory) {
8372  fFunctions->UseRWLock();
8373  fDirectory->Append(this);
8374  }
8375 }
8376 
8377 ////////////////////////////////////////////////////////////////////////////////
8378 /// Replace bin errors by values in array error.
8379 
8380 void TH1::SetError(const Double_t *error)
8381 {
8382  for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
8383 }
8384 
8385 ////////////////////////////////////////////////////////////////////////////////
8386 /// Change the name of this histogram
8387 ///
8388 
8389 void TH1::SetName(const char *name)
8390 {
8391  // Histograms are named objects in a THashList.
8392  // We must update the hashlist if we change the name
8393  // We protect this operation
8394  R__LOCKGUARD(gROOTMutex);
8395  if (fDirectory) fDirectory->Remove(this);
8396  fName = name;
8397  if (fDirectory) fDirectory->Append(this);
8398 }
8399 
8400 ////////////////////////////////////////////////////////////////////////////////
8401 /// Change the name and title of this histogram
8402 
8403 void TH1::SetNameTitle(const char *name, const char *title)
8404 {
8405  // Histograms are named objects in a THashList.
8406  // We must update the hashlist if we change the name
8407  SetName(name);
8408  SetTitle(title);
8409 }
8410 
8411 ////////////////////////////////////////////////////////////////////////////////
8412 /// Set statistics option on/off
8413 ///
8414 /// By default, the statistics box is drawn.
8415 /// The paint options can be selected via gStyle->SetOptStats.
8416 /// This function sets/resets the kNoStats bin in the histogram object.
8417 /// It has priority over the Style option.
8418 
8419 void TH1::SetStats(Bool_t stats)
8420 {
8421  ResetBit(kNoStats);
8422  if (!stats) {
8423  SetBit(kNoStats);
8424  //remove the "stats" object from the list of functions
8425  if (fFunctions) {
8426  TObject *obj = fFunctions->FindObject("stats");
8427  if (obj) {
8428  fFunctions->Remove(obj);
8429  delete obj;
8430  }
8431  }
8432  }
8433 }
8434 
8435 ////////////////////////////////////////////////////////////////////////////////
8436 /// Create structure to store sum of squares of weights.
8437 ///
8438 /// if histogram is already filled, the sum of squares of weights
8439 /// is filled with the existing bin contents
8440 ///
8441 /// The error per bin will be computed as sqrt(sum of squares of weight)
8442 /// for each bin.
8443 ///
8444 /// This function is automatically called when the histogram is created
8445 /// if the static function TH1::SetDefaultSumw2 has been called before.
8446 /// If flag = false the structure containing the sum of the square of weights
8447 /// is rest and it will be empty, but it is not deleted (i.e. GetSumw2()->fN = 0)
8448 
8449 void TH1::Sumw2(Bool_t flag)
8450 {
8451  if (!flag) {
8452  // clear the array if existing - do nothing otherwise
8453  if (fSumw2.fN > 0 ) fSumw2.Set(0);
8454  return;
8455  }
8456 
8457  if (fSumw2.fN == fNcells) {
8458  if (!fgDefaultSumw2 )
8459  Warning("Sumw2","Sum of squares of weights structure already created");
8460  return;
8461  }
8462 
8463  fSumw2.Set(fNcells);
8464 
8465  // empty the buffer
8466  if (fBuffer) BufferEmpty();
8467 
8468  if (fEntries > 0)
8469  for (Int_t i = 0; i < fNcells; ++i)
8470  fSumw2.fArray[i] = TMath::Abs(RetrieveBinContent(i));
8471 }
8472 
8473 ////////////////////////////////////////////////////////////////////////////////
8474 /// Return pointer to function with name.
8475 ///
8476 ///
8477 /// Functions such as TH1::Fit store the fitted function in the list of
8478 /// functions of this histogram.
8479 
8480 TF1 *TH1::GetFunction(const char *name) const
8481 {
8482  return (TF1*)fFunctions->FindObject(name);
8483 }
8484 
8485 ////////////////////////////////////////////////////////////////////////////////
8486 /// Return value of error associated to bin number bin.
8487 ///
8488 /// if the sum of squares of weights has been defined (via Sumw2),
8489 /// this function returns the sqrt(sum of w2).
8490 /// otherwise it returns the sqrt(contents) for this bin.
8491 
8492 Double_t TH1::GetBinError(Int_t bin) const
8493 {
8494  if (bin < 0) bin = 0;
8495  if (bin >= fNcells) bin = fNcells-1;
8496  if (fBuffer) ((TH1*)this)->BufferEmpty();
8497  if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
8498 
8499  return TMath::Sqrt(TMath::Abs(RetrieveBinContent(bin)));
8500 }
8501 
8502 ////////////////////////////////////////////////////////////////////////////////
8503 /// Return lower error associated to bin number bin.
8504 ///
8505 /// The error will depend on the statistic option used will return
8506 /// the binContent - lower interval value
8507 
8508 Double_t TH1::GetBinErrorLow(Int_t bin) const
8509 {
8510  if (fBinStatErrOpt == kNormal) return GetBinError(bin);
8511  // in case of weighted histogram check if it is really weighted
8512  if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
8513 
8514  if (bin < 0) bin = 0;
8515  if (bin >= fNcells) bin = fNcells-1;
8516  if (fBuffer) ((TH1*)this)->BufferEmpty();
8517 
8518  Double_t alpha = 1.- 0.682689492;
8519  if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
8520 
8521  Double_t c = RetrieveBinContent(bin);
8522  Int_t n = int(c);
8523  if (n < 0) {
8524  Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
8525  ((TH1*)this)->fBinStatErrOpt = kNormal;
8526  return GetBinError(bin);
8527  }
8528 
8529  if (n == 0) return 0;
8530  return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
8531 }
8532 
8533 ////////////////////////////////////////////////////////////////////////////////
8534 /// Return upper error associated to bin number bin.
8535 ///
8536 /// The error will depend on the statistic option used will return
8537 /// the binContent - upper interval value
8538 
8539 Double_t TH1::GetBinErrorUp(Int_t bin) const
8540 {
8541  if (fBinStatErrOpt == kNormal) return GetBinError(bin);
8542  // in case of weighted histogram check if it is really weighted
8543  if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
8544  if (bin < 0) bin = 0;
8545  if (bin >= fNcells) bin = fNcells-1;
8546  if (fBuffer) ((TH1*)this)->BufferEmpty();
8547 
8548  Double_t alpha = 1.- 0.682689492;
8549  if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
8550 
8551  Double_t c = RetrieveBinContent(bin);
8552  Int_t n = int(c);
8553  if (n < 0) {
8554  Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
8555  ((TH1*)this)->fBinStatErrOpt = kNormal;
8556  return GetBinError(bin);
8557  }
8558 
8559  // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
8560  // decide to return always (1-alpha)/2 upper interval
8561  //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
8562  return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
8563 }
8564 
8565 //L.M. These following getters are useless and should be probably deprecated
8566 ////////////////////////////////////////////////////////////////////////////////
8567 /// Return bin center for 1D histogram.
8568 /// Better to use h1.GetXaxis().GetBinCenter(bin)
8569 
8570 Double_t TH1::GetBinCenter(Int_t bin) const
8571 {
8572  if (fDimension == 1) return fXaxis.GetBinCenter(bin);
8573  Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
8574  return TMath::QuietNaN();
8575 }
8576 
8577 ////////////////////////////////////////////////////////////////////////////////
8578 /// Return bin lower edge for 1D histogram.
8579 /// Better to use h1.GetXaxis().GetBinLowEdge(bin)
8580 
8581 Double_t TH1::GetBinLowEdge(Int_t bin) const
8582 {
8583  if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
8584  Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
8585  return TMath::QuietNaN();
8586 }
8587 
8588 ////////////////////////////////////////////////////////////////////////////////
8589 /// Return bin width for 1D histogram.
8590 /// Better to use h1.GetXaxis().GetBinWidth(bin)
8591 
8592 Double_t TH1::GetBinWidth(Int_t bin) const
8593 {
8594  if (fDimension == 1) return fXaxis.GetBinWidth(bin);
8595  Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
8596  return TMath::QuietNaN();
8597 }
8598 
8599 ////////////////////////////////////////////////////////////////////////////////
8600 /// Fill array with center of bins for 1D histogram
8601 /// Better to use h1.GetXaxis().GetCenter(center)
8602 
8603 void TH1::GetCenter(Double_t *center) const
8604 {
8605  if (fDimension == 1) {
8606  fXaxis.GetCenter(center);
8607  return;
8608  }
8609  Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
8610 }
8611 
8612 ////////////////////////////////////////////////////////////////////////////////
8613 /// Fill array with low edge of bins for 1D histogram
8614 /// Better to use h1.GetXaxis().GetLowEdge(edge)
8615 
8616 void TH1::GetLowEdge(Double_t *edge) const
8617 {
8618  if (fDimension == 1) {
8619  fXaxis.GetLowEdge(edge);
8620  return;
8621  }
8622  Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
8623 }
8624 
8625 ////////////////////////////////////////////////////////////////////////////////
8626 /// Set the bin Error
8627 /// Note that this resets the bin eror option to be of Normal Type and for the
8628 /// non-empty bin the bin error is set by default to the square root of their content.
8629 /// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
8630 /// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
8631 /// will not recalcualated after setting the content and a default error = 0 will be used for those bins.
8632 ///
8633 /// See convention for numbering bins in TH1::GetBin
8634 
8635 void TH1::SetBinError(Int_t bin, Double_t error)
8636 {
8637  if (bin < 0 || bin>= fNcells) return;
8638  if (!fSumw2.fN) Sumw2();
8639  fSumw2.fArray[bin] = error * error;
8640  // reset the bin error option
8641  SetBinErrorOption(kNormal);
8642 }
8643 
8644 ////////////////////////////////////////////////////////////////////////////////
8645 /// Set bin content
8646 /// see convention for numbering bins in TH1::GetBin
8647 /// In case the bin number is greater than the number of bins and
8648 /// the timedisplay option is set or CanExtendAllAxes(),
8649 /// the number of bins is automatically doubled to accommodate the new bin
8650 
8651 void TH1::SetBinContent(Int_t bin, Double_t content)
8652 {
8653  fEntries++;
8654  fTsumw = 0;
8655  if (bin < 0) return;
8656  if (bin >= fNcells-1) {
8657  if (fXaxis.GetTimeDisplay() || CanExtendAllAxes() ) {
8658  while (bin >= fNcells-1) LabelsInflate();
8659  } else {
8660  if (bin == fNcells-1) UpdateBinContent(bin, content);
8661  return;
8662  }
8663  }
8664  UpdateBinContent(bin, content);
8665 }
8666 
8667 ////////////////////////////////////////////////////////////////////////////////
8668 /// See convention for numbering bins in TH1::GetBin
8669 
8670 void TH1::SetBinError(Int_t binx, Int_t biny, Double_t error)
8671 {
8672  if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
8673  if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
8674  SetBinError(GetBin(binx, biny), error);
8675 }
8676 
8677 ////////////////////////////////////////////////////////////////////////////////
8678 /// See convention for numbering bins in TH1::GetBin
8679 
8680 void TH1::SetBinError(Int_t binx, Int_t biny, Int_t binz, Double_t error)
8681 {
8682  if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
8683  if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
8684  if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
8685  SetBinError(GetBin(binx, biny, binz), error);
8686 }
8687 
8688 ////////////////////////////////////////////////////////////////////////////////
8689 /// This function calculates the background spectrum in this histogram.
8690 /// The background is returned as a histogram.
8691 ///
8692 /// \param[in] niter number of iterations (default value = 2)
8693 /// Increasing niter make the result smoother and lower.
8694 /// \param[in] option may contain one of the following options
8695 /// - to set the direction parameter
8696 /// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
8697 /// - filterOrder-order of clipping filter (default "BackOrder2")
8698 /// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
8699 /// - "nosmoothing" - if selected, the background is not smoothed
8700 /// By default the background is smoothed.
8701 /// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
8702 /// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
8703 /// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
8704 /// - "nocompton" - if selected the estimation of Compton edge
8705 /// will be not be included (by default the compton estimation is set)
8706 /// - "same" if this option is specified, the resulting background
8707 /// histogram is superimposed on the picture in the current pad.
8708 /// This option is given by default.
8709 ///
8710 /// NOTE that the background is only evaluated in the current range of this histogram.
8711 /// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
8712 /// the returned histogram will be created with the same number of bins
8713 /// as this input histogram, but only bins from binmin to binmax will be filled
8714 /// with the estimated background.
8715 
8716 TH1 *TH1::ShowBackground(Int_t niter, Option_t *option)
8717 {
8718 
8719  return (TH1*)gROOT->ProcessLineFast(Form("TSpectrum::StaticBackground((TH1*)0x%lx,%d,\"%s\")",
8720  (ULong_t)this, niter, option));
8721 }
8722 
8723 ////////////////////////////////////////////////////////////////////////////////
8724 /// Interface to TSpectrum::Search.
8725 /// The function finds peaks in this histogram where the width is > sigma
8726 /// and the peak maximum greater than threshold*maximum bin content of this.
8727 /// For more details see TSpectrum::Search.
8728 /// Note the difference in the default value for option compared to TSpectrum::Search
8729 /// option="" by default (instead of "goff").
8730 
8731 Int_t TH1::ShowPeaks(Double_t sigma, Option_t *option, Double_t threshold)
8732 {
8733  return (Int_t)gROOT->ProcessLineFast(Form("TSpectrum::StaticSearch((TH1*)0x%lx,%g,\"%s\",%g)",
8734  (ULong_t)this, sigma, option, threshold));
8735 }
8736 
8737 ////////////////////////////////////////////////////////////////////////////////
8738 /// For a given transform (first parameter), fills the histogram (second parameter)
8739 /// with the transform output data, specified in the third parameter
8740 /// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
8741 /// and the user is responsible for deleting it.
8742 ///
8743 /// Available options:
8744 /// - "RE" - real part of the output
8745 /// - "IM" - imaginary part of the output
8746 /// - "MAG" - magnitude of the output
8747 /// - "PH" - phase of the output
8748 
8749 TH1* TH1::TransformHisto(TVirtualFFT *fft, TH1* h_output, Option_t *option)
8750 {
8751  if (!fft || !fft->GetN() ) {
8752  ::Error("TransformHisto","Invalid FFT transform class");
8753  return 0;
8754  }
8755 
8756  if (fft->GetNdim()>2){
8757  ::Error("TransformHisto","Only 1d and 2D transform are supported");
8758  return 0;
8759  }
8760  Int_t binx,biny;
8761  TString opt = option;
8762  opt.ToUpper();
8763  Int_t *n = fft->GetN();
8764  TH1 *hout=0;
8765  if (h_output) {
8766  hout = h_output;
8767  }
8768  else {
8769  TString name = TString::Format("out_%s", opt.Data());
8770  if (fft->GetNdim()==1)
8771  hout = new TH1D(name, name,n[0], 0, n[0]);
8772  else if (fft->GetNdim()==2)
8773  hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
8774  }
8775  R__ASSERT(hout != 0);
8776  TString type=fft->GetType();
8777  Int_t ind[2];
8778  if (opt.Contains("RE")){
8779  if (type.Contains("2C") || type.Contains("2HC")) {
8780  Double_t re, im;
8781  for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8782  for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8783  ind[0] = binx-1; ind[1] = biny-1;
8784  fft->GetPointComplex(ind, re, im);
8785  hout->SetBinContent(binx, biny, re);
8786  }
8787  }
8788  } else {
8789  for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8790  for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8791  ind[0] = binx-1; ind[1] = biny-1;
8792  hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
8793  }
8794  }
8795  }
8796  }
8797  if (opt.Contains("IM")) {
8798  if (type.Contains("2C") || type.Contains("2HC")) {
8799  Double_t re, im;
8800  for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8801  for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8802  ind[0] = binx-1; ind[1] = biny-1;
8803  fft->GetPointComplex(ind, re, im);
8804  hout->SetBinContent(binx, biny, im);
8805  }
8806  }
8807  } else {
8808  ::Error("TransformHisto","No complex numbers in the output");
8809  return 0;
8810  }
8811  }
8812  if (opt.Contains("MA")) {
8813  if (type.Contains("2C") || type.Contains("2HC")) {
8814  Double_t re, im;
8815  for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8816  for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8817  ind[0] = binx-1; ind[1] = biny-1;
8818  fft->GetPointComplex(ind, re, im);
8819  hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
8820  }
8821  }
8822  } else {
8823  for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8824  for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8825  ind[0] = binx-1; ind[1] = biny-1;
8826  hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
8827  }
8828  }
8829  }
8830  }
8831  if (opt.Contains("PH")) {
8832  if (type.Contains("2C") || type.Contains("2HC")){
8833  Double_t re, im, ph;
8834  for (binx = 1; binx<=hout->GetNbinsX(); binx++){
8835  for (biny=1; biny<=hout->GetNbinsY(); biny++){
8836  ind[0] = binx-1; ind[1] = biny-1;
8837  fft->GetPointComplex(ind, re, im);
8838  if (TMath::Abs(re) > 1e-13){
8839  ph = TMath::ATan(im/re);
8840  //find the correct quadrant
8841  if (re<0 && im<0)
8842  ph -= TMath::Pi();
8843  if (re<0 && im>=0)
8844  ph += TMath::Pi();
8845  } else {
8846  if (TMath::Abs(im) < 1e-13)
8847  ph = 0;
8848  else if (im>0)
8849  ph = TMath::Pi()*0.5;
8850  else
8851  ph = -TMath::Pi()*0.5;
8852  }
8853  hout->SetBinContent(binx, biny, ph);
8854  }
8855  }
8856  } else {
8857  printf("Pure real output, no phase");
8858  return 0;
8859  }
8860  }
8861 
8862  return hout;
8863 }
8864 
8865 ////////////////////////////////////////////////////////////////////////////////
8866 /// Raw retrieval of bin content on internal data structure
8867 /// see convention for numbering bins in TH1::GetBin
8868 
8869 Double_t TH1::RetrieveBinContent(Int_t) const
8870 {
8871  AbstractMethod("RetrieveBinContent");
8872  return 0;
8873 }
8874 
8875 ////////////////////////////////////////////////////////////////////////////////
8876 /// Raw update of bin content on internal data structure
8877 /// see convention for numbering bins in TH1::GetBin
8878 
8879 void TH1::UpdateBinContent(Int_t, Double_t)
8880 {
8881  AbstractMethod("UpdateBinContent");
8882 }
8883 
8884 ////////////////////////////////////////////////////////////////////////////////
8885 /// Print value overload
8886 
8887 std::string cling::printValue(TH1 *val) {
8888  std::ostringstream strm;
8889  strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
8890  return strm.str();
8891 }
8892 
8893 //______________________________________________________________________________
8894 // TH1C methods
8895 // TH1C : histograms with one byte per channel. Maximum bin content = 127
8896 //______________________________________________________________________________
8897 
8898 ClassImp(TH1C);
8899 
8900 ////////////////////////////////////////////////////////////////////////////////
8901 /// Constructor.
8902 
8903 TH1C::TH1C(): TH1(), TArrayC()
8904 {
8905  fDimension = 1;
8906  SetBinsLength(3);
8907  if (fgDefaultSumw2) Sumw2();
8908 }
8909 
8910 ////////////////////////////////////////////////////////////////////////////////
8911 /// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
8912 /// (see TH1::TH1 for explanation of parameters)
8913 
8914 TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
8915 : TH1(name,title,nbins,xlow,xup)
8916 {
8917  fDimension = 1;
8918  TArrayC::Set(fNcells);
8919 
8920  if (xlow >= xup) SetBuffer(fgBufferSize);
8921  if (fgDefaultSumw2) Sumw2();
8922 }
8923 
8924 ////////////////////////////////////////////////////////////////////////////////
8925 /// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
8926 /// (see TH1::TH1 for explanation of parameters)
8927 
8928 TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
8929 : TH1(name,title,nbins,xbins)
8930 {
8931  fDimension = 1;
8932  TArrayC::Set(fNcells);
8933  if (fgDefaultSumw2) Sumw2();
8934 }
8935 
8936 ////////////////////////////////////////////////////////////////////////////////
8937 /// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
8938 /// (see TH1::TH1 for explanation of parameters)
8939 
8940 TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
8941 : TH1(name,title,nbins,xbins)
8942 {
8943  fDimension = 1;
8944  TArrayC::Set(fNcells);
8945  if (fgDefaultSumw2) Sumw2();
8946 }
8947 
8948 ////////////////////////////////////////////////////////////////////////////////
8949 /// Destructor.
8950 
8951 TH1C::~TH1C()
8952 {
8953 }
8954 
8955 ////////////////////////////////////////////////////////////////////////////////
8956 /// Copy constructor.
8957 
8958 TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
8959 {
8960  ((TH1C&)h1c).Copy(*this);
8961 }
8962 
8963 ////////////////////////////////////////////////////////////////////////////////
8964 /// Increment bin content by 1.
8965 
8966 void TH1C::AddBinContent(Int_t bin)
8967 {
8968  if (fArray[bin] < 127) fArray[bin]++;
8969 }
8970 
8971 ////////////////////////////////////////////////////////////////////////////////
8972 /// Increment bin content by w.
8973 
8974 void TH1C::AddBinContent(Int_t bin, Double_t w)
8975 {
8976  Int_t newval = fArray[bin] + Int_t(w);
8977  if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
8978  if (newval < -127) fArray[bin] = -127;
8979  if (newval > 127) fArray[bin] = 127;
8980 }
8981 
8982 ////////////////////////////////////////////////////////////////////////////////
8983 /// Copy this to newth1
8984 
8985 void TH1C::Copy(TObject &newth1) const
8986 {
8987  TH1::Copy(newth1);
8988 }
8989 
8990 ////////////////////////////////////////////////////////////////////////////////
8991 /// Reset.
8992 
8993 void TH1C::Reset(Option_t *option)
8994 {
8995  TH1::Reset(option);
8996  TArrayC::Reset();
8997 }
8998 
8999 ////////////////////////////////////////////////////////////////////////////////
9000 /// Set total number of bins including under/overflow
9001 /// Reallocate bin contents array
9002 
9003 void TH1C::SetBinsLength(Int_t n)
9004 {
9005  if (n < 0) n = fXaxis.GetNbins() + 2;
9006  fNcells = n;
9007  TArrayC::Set(n);
9008 }
9009 
9010 ////////////////////////////////////////////////////////////////////////////////
9011 /// Operator =
9012 
9013 TH1C& TH1C::operator=(const TH1C &h1)
9014 {
9015  if (this != &h1) ((TH1C&)h1).Copy(*this);
9016  return *this;
9017 }
9018 
9019 ////////////////////////////////////////////////////////////////////////////////
9020 /// Operator *
9021 
9022 TH1C operator*(Double_t c1, const TH1C &h1)
9023 {
9024  TH1C hnew = h1;
9025  hnew.Scale(c1);
9026  hnew.SetDirectory(0);
9027  return hnew;
9028 }
9029 
9030 ////////////////////////////////////////////////////////////////////////////////
9031 /// Operator +
9032 
9033 TH1C operator+(const TH1C &h1, const TH1C &h2)
9034 {
9035  TH1C hnew = h1;
9036  hnew.Add(&h2,1);
9037  hnew.SetDirectory(0);
9038  return hnew;
9039 }
9040 
9041 ////////////////////////////////////////////////////////////////////////////////
9042 /// Operator -
9043 
9044 TH1C operator-(const TH1C &h1, const TH1C &h2)
9045 {
9046  TH1C hnew = h1;
9047  hnew.Add(&h2,-1);
9048  hnew.SetDirectory(0);
9049  return hnew;
9050 }
9051 
9052 ////////////////////////////////////////////////////////////////////////////////
9053 /// Operator *
9054 
9055 TH1C operator*(const TH1C &h1, const TH1C &h2)
9056 {
9057  TH1C hnew = h1;
9058  hnew.Multiply(&h2);
9059  hnew.SetDirectory(0);
9060  return hnew;
9061 }
9062 
9063 ////////////////////////////////////////////////////////////////////////////////
9064 /// Operator /
9065 
9066 TH1C operator/(const TH1C &h1, const TH1C &h2)
9067 {
9068  TH1C hnew = h1;
9069  hnew.Divide(&h2);
9070  hnew.SetDirectory(0);
9071  return hnew;
9072 }
9073 
9074 //______________________________________________________________________________
9075 // TH1S methods
9076 // TH1S : histograms with one short per channel. Maximum bin content = 32767
9077 //______________________________________________________________________________
9078 
9079 ClassImp(TH1S);
9080 
9081 ////////////////////////////////////////////////////////////////////////////////
9082 /// Constructor.
9083 
9084 TH1S::TH1S(): TH1(), TArrayS()
9085 {
9086  fDimension = 1;
9087  SetBinsLength(3);
9088  if (fgDefaultSumw2) Sumw2();
9089 }
9090 
9091 ////////////////////////////////////////////////////////////////////////////////
9092 /// Create a 1-Dim histogram with fix bins of type short
9093 /// (see TH1::TH1 for explanation of parameters)
9094 
9095 TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9096 : TH1(name,title,nbins,xlow,xup)
9097 {
9098  fDimension = 1;
9099  TArrayS::Set(fNcells);
9100 
9101  if (xlow >= xup) SetBuffer(fgBufferSize);
9102  if (fgDefaultSumw2) Sumw2();
9103 }
9104 
9105 ////////////////////////////////////////////////////////////////////////////////
9106 /// Create a 1-Dim histogram with variable bins of type short
9107 /// (see TH1::TH1 for explanation of parameters)
9108 
9109 TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9110 : TH1(name,title,nbins,xbins)
9111 {
9112  fDimension = 1;
9113  TArrayS::Set(fNcells);
9114  if (fgDefaultSumw2) Sumw2();
9115 }
9116 
9117 ////////////////////////////////////////////////////////////////////////////////
9118 /// Create a 1-Dim histogram with variable bins of type short
9119 /// (see TH1::TH1 for explanation of parameters)
9120 
9121 TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9122 : TH1(name,title,nbins,xbins)
9123 {
9124  fDimension = 1;
9125  TArrayS::Set(fNcells);
9126  if (fgDefaultSumw2) Sumw2();
9127 }
9128 
9129 ////////////////////////////////////////////////////////////////////////////////
9130 /// Destructor.
9131 
9132 TH1S::~TH1S()
9133 {
9134 }
9135 
9136 ////////////////////////////////////////////////////////////////////////////////
9137 /// Copy constructor.
9138 
9139 TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9140 {
9141  ((TH1S&)h1s).Copy(*this);
9142 }
9143 
9144 ////////////////////////////////////////////////////////////////////////////////
9145 /// Increment bin content by 1.
9146 
9147 void TH1S::AddBinContent(Int_t bin)
9148 {
9149  if (fArray[bin] < 32767) fArray[bin]++;
9150 }
9151 
9152 ////////////////////////////////////////////////////////////////////////////////
9153 /// Increment bin content by w
9154 
9155 void TH1S::AddBinContent(Int_t bin, Double_t w)
9156 {
9157  Int_t newval = fArray[bin] + Int_t(w);
9158  if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9159  if (newval < -32767) fArray[bin] = -32767;
9160  if (newval > 32767) fArray[bin] = 32767;
9161 }
9162 
9163 ////////////////////////////////////////////////////////////////////////////////
9164 /// Copy this to newth1
9165 
9166 void TH1S::Copy(TObject &newth1) const
9167 {
9168  TH1::Copy(newth1);
9169 }
9170 
9171 ////////////////////////////////////////////////////////////////////////////////
9172 /// Reset.
9173 
9174 void TH1S::Reset(Option_t *option)
9175 {
9176  TH1::Reset(option);
9177  TArrayS::Reset();
9178 }
9179 
9180 ////////////////////////////////////////////////////////////////////////////////
9181 /// Set total number of bins including under/overflow
9182 /// Reallocate bin contents array
9183 
9184 void TH1S::SetBinsLength(Int_t n)
9185 {
9186  if (n < 0) n = fXaxis.GetNbins() + 2;
9187  fNcells = n;
9188  TArrayS::Set(n);
9189 }
9190 
9191 ////////////////////////////////////////////////////////////////////////////////
9192 /// Operator =
9193 
9194 TH1S& TH1S::operator=(const TH1S &h1)
9195 {
9196  if (this != &h1) ((TH1S&)h1).Copy(*this);
9197  return *this;
9198 }
9199 
9200 ////////////////////////////////////////////////////////////////////////////////
9201 /// Operator *
9202 
9203 TH1S operator*(Double_t c1, const TH1S &h1)
9204 {
9205  TH1S hnew = h1;
9206  hnew.Scale(c1);
9207  hnew.SetDirectory(0);
9208  return hnew;
9209 }
9210 
9211 ////////////////////////////////////////////////////////////////////////////////
9212 /// Operator +
9213 
9214 TH1S operator+(const TH1S &h1, const TH1S &h2)
9215 {
9216  TH1S hnew = h1;
9217  hnew.Add(&h2,1);
9218  hnew.SetDirectory(0);
9219  return hnew;
9220 }
9221 
9222 ////////////////////////////////////////////////////////////////////////////////
9223 /// Operator -
9224 
9225 TH1S operator-(const TH1S &h1, const TH1S &h2)
9226 {
9227  TH1S hnew = h1;
9228  hnew.Add(&h2,-1);
9229  hnew.SetDirectory(0);
9230  return hnew;
9231 }
9232 
9233 ////////////////////////////////////////////////////////////////////////////////
9234 /// Operator *
9235 
9236 TH1S operator*(const TH1S &h1, const TH1S &h2)
9237 {
9238  TH1S hnew = h1;
9239  hnew.Multiply(&h2);
9240  hnew.SetDirectory(0);
9241  return hnew;
9242 }
9243 
9244 ////////////////////////////////////////////////////////////////////////////////
9245 /// Operator /
9246 
9247 TH1S operator/(const TH1S &h1, const TH1S &h2)
9248 {
9249  TH1S hnew = h1;
9250  hnew.Divide(&h2);
9251  hnew.SetDirectory(0);
9252  return hnew;
9253 }
9254 
9255 //______________________________________________________________________________
9256 // TH1I methods
9257 // TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9258 //______________________________________________________________________________
9259 
9260 ClassImp(TH1I);
9261 
9262 ////////////////////////////////////////////////////////////////////////////////
9263 /// Constructor.
9264 
9265 TH1I::TH1I(): TH1(), TArrayI()
9266 {
9267  fDimension = 1;
9268  SetBinsLength(3);
9269  if (fgDefaultSumw2) Sumw2();
9270 }
9271 
9272 ////////////////////////////////////////////////////////////////////////////////
9273 /// Create a 1-Dim histogram with fix bins of type integer
9274 /// (see TH1::TH1 for explanation of parameters)
9275 
9276 TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9277 : TH1(name,title,nbins,xlow,xup)
9278 {
9279  fDimension = 1;
9280  TArrayI::Set(fNcells);
9281 
9282  if (xlow >= xup) SetBuffer(fgBufferSize);
9283  if (fgDefaultSumw2) Sumw2();
9284 }
9285 
9286 ////////////////////////////////////////////////////////////////////////////////
9287 /// Create a 1-Dim histogram with variable bins of type integer
9288 /// (see TH1::TH1 for explanation of parameters)
9289 
9290 TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9291 : TH1(name,title,nbins,xbins)
9292 {
9293  fDimension = 1;
9294  TArrayI::Set(fNcells);
9295  if (fgDefaultSumw2) Sumw2();
9296 }
9297 
9298 ////////////////////////////////////////////////////////////////////////////////
9299 /// Create a 1-Dim histogram with variable bins of type integer
9300 /// (see TH1::TH1 for explanation of parameters)
9301 
9302 TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9303 : TH1(name,title,nbins,xbins)
9304 {
9305  fDimension = 1;
9306  TArrayI::Set(fNcells);
9307  if (fgDefaultSumw2) Sumw2();
9308 }
9309 
9310 ////////////////////////////////////////////////////////////////////////////////
9311 /// Destructor.
9312 
9313 TH1I::~TH1I()
9314 {
9315 }
9316 
9317 ////////////////////////////////////////////////////////////////////////////////
9318 /// Copy constructor.
9319 
9320 TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
9321 {
9322  ((TH1I&)h1i).Copy(*this);
9323 }
9324 
9325 ////////////////////////////////////////////////////////////////////////////////
9326 /// Increment bin content by 1.
9327 
9328 void TH1I::AddBinContent(Int_t bin)
9329 {
9330  if (fArray[bin] < 2147483647) fArray[bin]++;
9331 }
9332 
9333 ////////////////////////////////////////////////////////////////////////////////
9334 /// Increment bin content by w
9335 
9336 void TH1I::AddBinContent(Int_t bin, Double_t w)
9337 {
9338  Long64_t newval = fArray[bin] + Long64_t(w);
9339  if (newval > -2147483647 && newval < 2147483647) {fArray[bin] = Int_t(newval); return;}
9340  if (newval < -2147483647) fArray[bin] = -2147483647;
9341  if (newval > 2147483647) fArray[bin] = 2147483647;
9342 }
9343 
9344 ////////////////////////////////////////////////////////////////////////////////
9345 /// Copy this to newth1
9346 
9347 void TH1I::Copy(TObject &newth1) const
9348 {
9349  TH1::Copy(newth1);
9350 }
9351 
9352 ////////////////////////////////////////////////////////////////////////////////
9353 /// Reset.
9354 
9355 void TH1I::Reset(Option_t *option)
9356 {
9357  TH1::Reset(option);
9358  TArrayI::Reset();
9359 }
9360 
9361 ////////////////////////////////////////////////////////////////////////////////
9362 /// Set total number of bins including under/overflow
9363 /// Reallocate bin contents array
9364 
9365 void TH1I::SetBinsLength(Int_t n)
9366 {
9367  if (n < 0) n = fXaxis.GetNbins() + 2;
9368  fNcells = n;
9369  TArrayI::Set(n);
9370 }
9371 
9372 ////////////////////////////////////////////////////////////////////////////////
9373 /// Operator =
9374 
9375 TH1I& TH1I::operator=(const TH1I &h1)
9376 {
9377  if (this != &h1) ((TH1I&)h1).Copy(*this);
9378  return *this;
9379 }
9380 
9381 
9382 ////////////////////////////////////////////////////////////////////////////////
9383 /// Operator *
9384 
9385 TH1I operator*(Double_t c1, const TH1I &h1)
9386 {
9387  TH1I hnew = h1;
9388  hnew.Scale(c1);
9389  hnew.SetDirectory(0);
9390  return hnew;
9391 }
9392 
9393 ////////////////////////////////////////////////////////////////////////////////
9394 /// Operator +
9395 
9396 TH1I operator+(const TH1I &h1, const TH1I &h2)
9397 {
9398  TH1I hnew = h1;
9399  hnew.Add(&h2,1);
9400  hnew.SetDirectory(0);
9401  return hnew;
9402 }
9403 
9404 ////////////////////////////////////////////////////////////////////////////////
9405 /// Operator -
9406 
9407 TH1I operator-(const TH1I &h1, const TH1I &h2)
9408 {
9409  TH1I hnew = h1;
9410  hnew.Add(&h2,-1);
9411  hnew.SetDirectory(0);
9412  return hnew;
9413 }
9414 
9415 ////////////////////////////////////////////////////////////////////////////////
9416 /// Operator *
9417 
9418 TH1I operator*(const TH1I &h1, const TH1I &h2)
9419 {
9420  TH1I hnew = h1;
9421  hnew.Multiply(&h2);
9422  hnew.SetDirectory(0);
9423  return hnew;
9424 }
9425 
9426 ////////////////////////////////////////////////////////////////////////////////
9427 /// Operator /
9428 
9429 TH1I operator/(const TH1I &h1, const TH1I &h2)
9430 {
9431  TH1I hnew = h1;
9432  hnew.Divide(&h2);
9433  hnew.SetDirectory(0);
9434  return hnew;
9435 }
9436 
9437 //______________________________________________________________________________
9438 // TH1F methods
9439 // TH1F : histograms with one float per channel. Maximum precision 7 digits
9440 //______________________________________________________________________________
9441 
9442 ClassImp(TH1F);
9443 
9444 ////////////////////////////////////////////////////////////////////////////////
9445 /// Constructor.
9446 
9447 TH1F::TH1F(): TH1(), TArrayF()
9448 {
9449  fDimension = 1;
9450  SetBinsLength(3);
9451  if (fgDefaultSumw2) Sumw2();
9452 }
9453 
9454 ////////////////////////////////////////////////////////////////////////////////
9455 /// Create a 1-Dim histogram with fix bins of type float
9456 /// (see TH1::TH1 for explanation of parameters)
9457 
9458 TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9459 : TH1(name,title,nbins,xlow,xup)
9460 {
9461  fDimension = 1;
9462  TArrayF::Set(fNcells);
9463 
9464  if (xlow >= xup) SetBuffer(fgBufferSize);
9465  if (fgDefaultSumw2) Sumw2();
9466 }
9467 
9468 ////////////////////////////////////////////////////////////////////////////////
9469 /// Create a 1-Dim histogram with variable bins of type float
9470 /// (see TH1::TH1 for explanation of parameters)
9471 
9472 TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9473 : TH1(name,title,nbins,xbins)
9474 {
9475  fDimension = 1;
9476  TArrayF::Set(fNcells);
9477  if (fgDefaultSumw2) Sumw2();
9478 }
9479 
9480 ////////////////////////////////////////////////////////////////////////////////
9481 /// Create a 1-Dim histogram with variable bins of type float
9482 /// (see TH1::TH1 for explanation of parameters)
9483 
9484 TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9485 : TH1(name,title,nbins,xbins)
9486 {
9487  fDimension = 1;
9488  TArrayF::Set(fNcells);
9489  if (fgDefaultSumw2) Sumw2();
9490 }
9491 
9492 ////////////////////////////////////////////////////////////////////////////////
9493 /// Create a histogram from a TVectorF
9494 /// by default the histogram name is "TVectorF" and title = ""
9495 
9496 TH1F::TH1F(const TVectorF &v)
9497 : TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
9498 {
9499  TArrayF::Set(fNcells);
9500  fDimension = 1;
9501  Int_t ivlow = v.GetLwb();
9502  for (Int_t i=0;i<fNcells-2;i++) {
9503  SetBinContent(i+1,v(i+ivlow));
9504  }
9505  TArrayF::Set(fNcells);
9506  if (fgDefaultSumw2) Sumw2();
9507 }
9508 
9509 ////////////////////////////////////////////////////////////////////////////////
9510 /// Copy Constructor.
9511 
9512 TH1F::TH1F(const TH1F &h) : TH1(), TArrayF()
9513 {
9514  ((TH1F&)h).Copy(*this);
9515 }
9516 
9517 ////////////////////////////////////////////////////////////////////////////////
9518 /// Destructor.
9519 
9520 TH1F::~TH1F()
9521 {
9522 }
9523 
9524 ////////////////////////////////////////////////////////////////////////////////
9525 /// Copy this to newth1.
9526 
9527 void TH1F::Copy(TObject &newth1) const
9528 {
9529  TH1::Copy(newth1);
9530 }
9531 
9532 ////////////////////////////////////////////////////////////////////////////////
9533 /// Reset.
9534 
9535 void TH1F::Reset(Option_t *option)
9536 {
9537  TH1::Reset(option);
9538  TArrayF::Reset();
9539 }
9540 
9541 ////////////////////////////////////////////////////////////////////////////////
9542 /// Set total number of bins including under/overflow
9543 /// Reallocate bin contents array
9544 
9545 void TH1F::SetBinsLength(Int_t n)
9546 {
9547  if (n < 0) n = fXaxis.GetNbins() + 2;
9548  fNcells = n;
9549  TArrayF::Set(n);
9550 }
9551 
9552 ////////////////////////////////////////////////////////////////////////////////
9553 /// Operator =
9554 
9555 TH1F& TH1F::operator=(const TH1F &h1)
9556 {
9557  if (this != &h1) ((TH1F&)h1).Copy(*this);
9558  return *this;
9559 }
9560 
9561 ////////////////////////////////////////////////////////////////////////////////
9562 /// Operator *
9563 
9564 TH1F operator*(Double_t c1, const TH1F &h1)
9565 {
9566  TH1F hnew = h1;
9567  hnew.Scale(c1);
9568  hnew.SetDirectory(0);
9569  return hnew;
9570 }
9571 
9572 ////////////////////////////////////////////////////////////////////////////////
9573 /// Operator +
9574 
9575 TH1F operator+(const TH1F &h1, const TH1F &h2)
9576 {
9577  TH1F hnew = h1;
9578  hnew.Add(&h2,1);
9579  hnew.SetDirectory(0);
9580  return hnew;
9581 }
9582 
9583 ////////////////////////////////////////////////////////////////////////////////
9584 /// Operator -
9585 
9586 TH1F operator-(const TH1F &h1, const TH1F &h2)
9587 {
9588  TH1F hnew = h1;
9589  hnew.Add(&h2,-1);
9590  hnew.SetDirectory(0);
9591  return hnew;
9592 }
9593 
9594 ////////////////////////////////////////////////////////////////////////////////
9595 /// Operator *
9596 
9597 TH1F operator*(const TH1F &h1, const TH1F &h2)
9598 {
9599  TH1F hnew = h1;
9600  hnew.Multiply(&h2);
9601  hnew.SetDirectory(0);
9602  return hnew;
9603 }
9604 
9605 ////////////////////////////////////////////////////////////////////////////////
9606 /// Operator /
9607 
9608 TH1F operator/(const TH1F &h1, const TH1F &h2)
9609 {
9610  TH1F hnew = h1;
9611  hnew.Divide(&h2);
9612  hnew.SetDirectory(0);
9613  return hnew;
9614 }
9615 
9616 //______________________________________________________________________________
9617 // TH1D methods
9618 // TH1D : histograms with one double per channel. Maximum precision 14 digits
9619 //______________________________________________________________________________
9620 
9621 ClassImp(TH1D);
9622 
9623 ////////////////////////////////////////////////////////////////////////////////
9624 /// Constructor.
9625 
9626 TH1D::TH1D(): TH1(), TArrayD()
9627 {
9628  fDimension = 1;
9629  SetBinsLength(3);
9630  if (fgDefaultSumw2) Sumw2();
9631 }
9632 
9633 ////////////////////////////////////////////////////////////////////////////////
9634 /// Create a 1-Dim histogram with fix bins of type double
9635 /// (see TH1::TH1 for explanation of parameters)
9636 
9637 TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9638 : TH1(name,title,nbins,xlow,xup)
9639 {
9640  fDimension = 1;
9641  TArrayD::Set(fNcells);
9642 
9643  if (xlow >= xup) SetBuffer(fgBufferSize);
9644  if (fgDefaultSumw2) Sumw2();
9645 }
9646 
9647 ////////////////////////////////////////////////////////////////////////////////
9648 /// Create a 1-Dim histogram with variable bins of type double
9649 /// (see TH1::TH1 for explanation of parameters)
9650 
9651 TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9652 : TH1(name,title,nbins,xbins)
9653 {
9654  fDimension = 1;
9655  TArrayD::Set(fNcells);
9656  if (fgDefaultSumw2) Sumw2();
9657 }
9658 
9659 ////////////////////////////////////////////////////////////////////////////////
9660 /// Create a 1-Dim histogram with variable bins of type double
9661 /// (see TH1::TH1 for explanation of parameters)
9662 
9663 TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9664 : TH1(name,title,nbins,xbins)
9665 {
9666  fDimension = 1;
9667  TArrayD::Set(fNcells);
9668  if (fgDefaultSumw2) Sumw2();
9669 }
9670 
9671 ////////////////////////////////////////////////////////////////////////////////
9672 /// Create a histogram from a TVectorD
9673 /// by default the histogram name is "TVectorD" and title = ""
9674 
9675 TH1D::TH1D(const TVectorD &v)
9676 : TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
9677 {
9678  TArrayD::Set(fNcells);
9679  fDimension = 1;
9680  Int_t ivlow = v.GetLwb();
9681  for (Int_t i=0;i<fNcells-2;i++) {
9682  SetBinContent(i+1,v(i+ivlow));
9683  }
9684  TArrayD::Set(fNcells);
9685  if (fgDefaultSumw2) Sumw2();
9686 }
9687 
9688 ////////////////////////////////////////////////////////////////////////////////
9689 /// Destructor.
9690 
9691 TH1D::~TH1D()
9692 {
9693 }
9694 
9695 ////////////////////////////////////////////////////////////////////////////////
9696 /// Constructor.
9697 
9698 TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
9699 {
9700  ((TH1D&)h1d).Copy(*this);
9701 }
9702 
9703 ////////////////////////////////////////////////////////////////////////////////
9704 /// Copy this to newth1
9705 
9706 void TH1D::Copy(TObject &newth1) const
9707 {
9708  TH1::Copy(newth1);
9709 }
9710 
9711 ////////////////////////////////////////////////////////////////////////////////
9712 /// Reset.
9713 
9714 void TH1D::Reset(Option_t *option)
9715 {
9716  TH1::Reset(option);
9717  TArrayD::Reset();
9718 }
9719 
9720 ////////////////////////////////////////////////////////////////////////////////
9721 /// Set total number of bins including under/overflow
9722 /// Reallocate bin contents array
9723 
9724 void TH1D::SetBinsLength(Int_t n)
9725 {
9726  if (n < 0) n = fXaxis.GetNbins() + 2;
9727  fNcells = n;
9728  TArrayD::Set(n);
9729 }
9730 
9731 ////////////////////////////////////////////////////////////////////////////////
9732 /// Operator =
9733 
9734 TH1D& TH1D::operator=(const TH1D &h1)
9735 {
9736  if (this != &h1) ((TH1D&)h1).Copy(*this);
9737  return *this;
9738 }
9739 
9740 ////////////////////////////////////////////////////////////////////////////////
9741 /// Operator *
9742 
9743 TH1D operator*(Double_t c1, const TH1D &h1)
9744 {
9745  TH1D hnew = h1;
9746  hnew.Scale(c1);
9747  hnew.SetDirectory(0);
9748  return hnew;
9749 }
9750 
9751 ////////////////////////////////////////////////////////////////////////////////
9752 /// Operator +
9753 
9754 TH1D operator+(const TH1D &h1, const TH1D &h2)
9755 {
9756  TH1D hnew = h1;
9757  hnew.Add(&h2,1);
9758  hnew.SetDirectory(0);
9759  return hnew;
9760 }
9761 
9762 ////////////////////////////////////////////////////////////////////////////////
9763 /// Operator -
9764 
9765 TH1D operator-(const TH1D &h1, const TH1D &h2)
9766 {
9767  TH1D hnew = h1;
9768  hnew.Add(&h2,-1);
9769  hnew.SetDirectory(0);
9770  return hnew;
9771 }
9772 
9773 ////////////////////////////////////////////////////////////////////////////////
9774 /// Operator *
9775 
9776 TH1D operator*(const TH1D &h1, const TH1D &h2)
9777 {
9778  TH1D hnew = h1;
9779  hnew.Multiply(&h2);
9780  hnew.SetDirectory(0);
9781  return hnew;
9782 }
9783 
9784 ////////////////////////////////////////////////////////////////////////////////
9785 /// Operator /
9786 
9787 TH1D operator/(const TH1D &h1, const TH1D &h2)
9788 {
9789  TH1D hnew = h1;
9790  hnew.Divide(&h2);
9791  hnew.SetDirectory(0);
9792  return hnew;
9793 }
9794 
9795 ////////////////////////////////////////////////////////////////////////////////
9796 ///return pointer to histogram with name
9797 ///hid if id >=0
9798 ///h_id if id <0
9799 
9800 TH1 *R__H(Int_t hid)
9801 {
9802  TString hname;
9803  if(hid >= 0) hname.Form("h%d",hid);
9804  else hname.Form("h_%d",hid);
9805  return (TH1*)gDirectory->Get(hname);
9806 }
9807 
9808 ////////////////////////////////////////////////////////////////////////////////
9809 ///return pointer to histogram with name hname
9810 
9811 TH1 *R__H(const char * hname)
9812 {
9813  return (TH1*)gDirectory->Get(hname);
9814 }