Logo ROOT   6.18/05
Reference Guide
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"
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
71The TH1 histogram class.
72
73### The Histogram classes
74ROOT 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
104All 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
142Histograms 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~~~
147Histograms 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
228When 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
524TF1 *gF1=0; //left for back compatibility (use TVirtualFitter::GetUserFunc instead)
525
530
531extern void H1InitGaus();
532extern void H1InitExpo();
533extern void H1InitPolynom();
534extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
535extern void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail);
536extern 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
539class DifferentDimension: public std::exception {};
540class DifferentNumberOfBins: public std::exception {};
541class DifferentAxisLimits: public std::exception {};
542class DifferentBinLimits: public std::exception {};
543class DifferentLabels: public std::exception {};
544
546
547////////////////////////////////////////////////////////////////////////////////
548/// Histogram default constructor.
549
551{
552 fDirectory = 0;
553 fFunctions = new TList;
554 fNcells = 0;
555 fIntegral = 0;
556 fPainter = 0;
557 fEntries = 0;
558 fNormFactor = 0;
560 fMaximum = -1111;
561 fMinimum = -1111;
562 fBufferSize = 0;
563 fBuffer = 0;
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);
573}
574
575////////////////////////////////////////////////////////////////////////////////
576/// Histogram default destructor.
577
579{
580 if (!TestBit(kNotDeleted)) {
581 return;
582 }
583 delete[] fIntegral;
584 fIntegral = 0;
585 delete[] fBuffer;
586 fBuffer = 0;
587 if (fFunctions) {
589
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
639TH1::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
661TH1::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
683TH1::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
698{
699 ((TH1&)h).Copy(*this);
700}
701
702////////////////////////////////////////////////////////////////////////////////
703/// Static function: cannot be inlined on Windows/NT.
704
706{
707 return fgAddDirectory;
708}
709
710////////////////////////////////////////////////////////////////////////////////
711/// Browse the Histogram object.
712
714{
715 Draw(b ? b->GetDrawOption() : "");
716 gPad->Update();
717}
718
719////////////////////////////////////////////////////////////////////////////////
720/// Creates histogram basic data structure.
721
723{
724 fDirectory = 0;
725 fPainter = 0;
726 fIntegral = 0;
727 fEntries = 0;
728 fNormFactor = 0;
730 fMaximum = -1111;
731 fMinimum = -1111;
732 fBufferSize = 0;
733 fBuffer = 0;
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
746
747 fFunctions = new TList;
748
750
753 if (fDirectory) {
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
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;
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
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);
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
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
1141 Double_t y2 = h2->RetrieveBinContent(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)
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
1201{
1202 AbstractMethod("AddBinContent");
1203}
1204
1205////////////////////////////////////////////////////////////////////////////////
1206/// Increment bin content by a weight w.
1207
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
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
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
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
1276{
1277 // We need meaningful raw limits
1278 if (xmi >= xma)
1279 return -1;
1280
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
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;
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)
1394 } else {
1395 fBuffer = 0;
1396 Int_t keep = fBufferSize; fBufferSize = 0;
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
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
1471bool 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
1500bool 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
1532bool 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
1547bool 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
1583bool 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
1620bool 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
1951Double_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
2010Double_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
2438Double_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
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
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
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
2546TH1 *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
2589void 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
2666TObject* 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 {
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
2700{
2701 Bool_t addStatus = TH1::AddDirectoryStatus();
2702 if (addStatus) {
2703 SetDirectory(dir);
2704 if (dir) {
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
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
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;
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
2806Bool_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) {
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
2873Bool_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) {
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;
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
2983void 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
3030TH1 *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
3060TH1 *TH1::DrawNormalized(Option_t *option, Double_t norm) const
3061{
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();
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
3091void 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
3108void 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
3156void 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
3200TH1* 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
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
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
3328Int_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()) {
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
3363void 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
3389void 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
3430void 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()) {
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
3497void 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
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);
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
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
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
3643Int_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
3706Int_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
3766TObject *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
3775TObject *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
3793TFitResultPtr 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(y(i) - \frac{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
4118TFitResultPtr 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;
4123
4124 // create range and minimizer options with default values
4125 ROOT::Fit::DataRange range(xxmin,xxmax);
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
4140void 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
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();
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:
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
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
4272{
4273 return fgDefaultSumw2;
4274}
4275
4276////////////////////////////////////////////////////////////////////////////////
4277/// Return the current number of entries.
4278
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
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
4315void 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);
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
4336char *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
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
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
4436Int_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
4477Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
4478{
4480 return 1;
4481}
4482
4483////////////////////////////////////////////////////////////////////////////////
4484/// Compute Initial values of parameters for a gaussian.
4485
4486void 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
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
4542void H1InitExpo()
4543{
4544 Double_t constant, slope;
4545 Int_t ifail;
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
4562void H1InitPolynom()
4563{
4564 Double_t fitpar[25];
4565
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
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 }
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
4651void 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;
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
4697void 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
4786Int_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
4799void 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
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
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
4909Double_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
4939{
4940 if (fBuffer) ((TH1*)this)->BufferEmpty();
4941
4942 Int_t xbin = FindBin(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/// Interpolate. Not yet implemented.
4967
4969{
4970 Error("Interpolate","This function must be called with 1 argument for a TH1");
4971 return 0;
4972}
4973
4974////////////////////////////////////////////////////////////////////////////////
4975/// Interpolate. Not yet implemented.
4976
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
4987Bool_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
5005Bool_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
5037Bool_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
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
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
5199void 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")) {
5219 }
5220 if (opt.Contains("v")) {
5225 }
5226 if (opt.Contains("u")) {
5227 axis->SetBit(TAxis::kLabelsUp);
5231 }
5232 if (opt.Contains("d")) {
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
5447static 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
5455static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5456{
5457 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5459}
5460
5461////////////////////////////////////////////////////////////////////////////////
5462/// Test if the binning is equidistant.
5463
5464static 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
5484Bool_t TH1::SameLimitsAndNBins(const TAxis& axis1, const TAxis& axis2)
5485{
5486 return axis1.GetNbins() == axis2.GetNbins()
5487 && axis1.GetXmin() == axis2.GetXmin()
5488 && axis1.GetXmax() == axis2.GetXmax();
5489}
5490
5491////////////////////////////////////////////////////////////////////////////////
5492/// Finds new limits for the axis for the Merge function.
5493/// returns false if the limits are incompatible
5494
5495Bool_t TH1::RecomputeAxisLimits(TAxis& destAxis, const TAxis& anAxis)
5496{
5497 if (SameLimitsAndNBins(destAxis, anAxis))
5498 return kTRUE;
5499
5500 if (!IsEquidistantBinning(destAxis) || !IsEquidistantBinning(anAxis))
5501 return kFALSE; // not equidistant user binning not supported
5502
5503 Double_t width1 = destAxis.GetBinWidth(0);
5504 Double_t width2 = anAxis.GetBinWidth(0);
5505 if (width1 == 0 || width2 == 0)
5506 return kFALSE; // no binning not supported
5507
5508 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
5509 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
5510 Double_t width = TMath::Max(width1, width2);
5511
5512 // check the bin size
5513 if (!AlmostInteger(width/width1) || !AlmostInteger(width/width2))
5514 return kFALSE;
5515
5516 // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
5517 // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
5518
5519
5520 // check the limits
5521 Double_t delta;
5522 delta = (destAxis.GetXmin() - xmin)/width1;
5523 if (!AlmostInteger(delta))
5524 xmin -= (TMath::Ceil(delta) - delta)*width1;
5525
5526 delta = (anAxis.GetXmin() - xmin)/width2;
5527 if (!AlmostInteger(delta))
5528 xmin -= (TMath::Ceil(delta) - delta)*width2;
5529
5530
5531 delta = (destAxis.GetXmin() - xmin)/width1;
5532 if (!AlmostInteger(delta))
5533 return kFALSE;
5534
5535
5536 delta = (xmax - destAxis.GetXmax())/width1;
5537 if (!AlmostInteger(delta))
5538 xmax += (TMath::Ceil(delta) - delta)*width1;
5539
5540
5541 delta = (xmax - anAxis.GetXmax())/width2;
5542 if (!AlmostInteger(delta))
5543 xmax += (TMath::Ceil(delta) - delta)*width2;
5544
5545
5546 delta = (xmax - destAxis.GetXmax())/width1;
5547 if (!AlmostInteger(delta))
5548 return kFALSE;
5549#ifdef DEBUG
5550 if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
5551 printf("TH1::RecomputeAxisLimits - Impossible\n");
5552 return kFALSE;
5553 }
5554#endif
5555
5556
5557 destAxis.Set(TMath::Nint((xmax - xmin)/width), xmin, xmax);
5558
5559 //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
5560
5561 return kTRUE;
5562}
5563
5564////////////////////////////////////////////////////////////////////////////////
5565/// Add all histograms in the collection to this histogram.
5566/// This function computes the min/max for the x axis,
5567/// compute a new number of bins, if necessary,
5568/// add bin contents, errors and statistics.
5569/// If all histograms have bin labels, bins with identical labels
5570/// will be merged, no matter what their order is.
5571/// If overflows are present and limits are different the function will fail.
5572/// The function returns the total number of entries in the result histogram
5573/// if the merge is successful, -1 otherwise.
5574///
5575/// Possible option:
5576/// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
5577/// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
5578/// (enabled by default) slows down the merging
5579///
5580/// IMPORTANT remark. The axis x may have different number
5581/// of bins and different limits, BUT the largest bin width must be
5582/// a multiple of the smallest bin width and the upper limit must also
5583/// be a multiple of the bin width.
5584/// Example:
5585///
5586/// ~~~ {.cpp}
5587/// void atest() {
5588/// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
5589/// TH1F *h2 = new TH1F("h2","h2",220,0,110);
5590/// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
5591/// TRandom r;
5592/// for (Int_t i=0;i<10000;i++) {
5593/// h1->Fill(r.Gaus(-55,10));
5594/// h2->Fill(r.Gaus(55,10));
5595/// h3->Fill(r.Gaus(0,10));
5596/// }
5597///
5598/// TList *list = new TList;
5599/// list->Add(h1);
5600/// list->Add(h2);
5601/// list->Add(h3);
5602/// TH1F *h = (TH1F*)h1->Clone("h");
5603/// h->Reset();
5604/// h->Merge(list);
5605/// h->Draw();
5606/// }
5607/// ~~~
5608
5610{
5611 if (!li) return 0;
5612 if (li->IsEmpty()) return (Long64_t) GetEntries();
5613
5614 // use TH1Merger class
5615 TH1Merger merger(*this,*li,opt);
5616 Bool_t ret = merger();
5617
5618 return (ret) ? GetEntries() : -1;
5619}
5620
5621
5622////////////////////////////////////////////////////////////////////////////////
5623/// Performs the operation:
5624///
5625/// `this = this*c1*f1`
5626///
5627/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
5628///
5629/// Only bins inside the function range are recomputed.
5630/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5631/// you should call Sumw2 before making this operation.
5632/// This is particularly important if you fit the histogram after TH1::Multiply
5633///
5634/// The function return kFALSE if the Multiply operation failed
5635
5637{
5638 if (!f1) {
5639 Error("Multiply","Attempt to multiply by a non-existing function");
5640 return kFALSE;
5641 }
5642
5643 // delete buffer if it is there since it will become invalid
5644 if (fBuffer) BufferEmpty(1);
5645
5646 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
5647 Int_t ny = GetNbinsY() + 2;
5648 Int_t nz = GetNbinsZ() + 2;
5649 if (fDimension < 2) ny = 1;
5650 if (fDimension < 3) nz = 1;
5651
5652 // reset min-maximum
5653 SetMinimum();
5654 SetMaximum();
5655
5656 // - Loop on bins (including underflows/overflows)
5657 Double_t xx[3];
5658 Double_t *params = 0;
5659 f1->InitArgs(xx,params);
5660
5661 for (Int_t binz = 0; binz < nz; ++binz) {
5662 xx[2] = fZaxis.GetBinCenter(binz);
5663 for (Int_t biny = 0; biny < ny; ++biny) {
5664 xx[1] = fYaxis.GetBinCenter(biny);
5665 for (Int_t binx = 0; binx < nx; ++binx) {
5666 xx[0] = fXaxis.GetBinCenter(binx);
5667 if (!f1->IsInside(xx)) continue;
5669 Int_t bin = binx + nx * (biny + ny *binz);
5670 Double_t cu = c1*f1->EvalPar(xx);
5671 if (TF1::RejectedPoint()) continue;
5672 UpdateBinContent(bin, RetrieveBinContent(bin) * cu);
5673 if (fSumw2.fN) {
5674 fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
5675 }
5676 }
5677 }
5678 }
5679 ResetStats();
5680 return kTRUE;
5681}
5682
5683////////////////////////////////////////////////////////////////////////////////
5684/// Multiply this histogram by h1.
5685///
5686/// `this = this*h1`
5687///
5688/// If errors of this are available (TH1::Sumw2), errors are recalculated.
5689/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
5690/// if not already set.
5691///
5692/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5693/// you should call Sumw2 before making this operation.
5694/// This is particularly important if you fit the histogram after TH1::Multiply
5695///
5696/// The function return kFALSE if the Multiply operation failed
5697
5698Bool_t TH1::Multiply(const TH1 *h1)
5699{
5700 if (!h1) {
5701 Error("Multiply","Attempt to multiply by a non-existing histogram");
5702 return kFALSE;
5703 }
5704
5705 // delete buffer if it is there since it will become invalid
5706 if (fBuffer) BufferEmpty(1);
5707
5708 try {
5709 CheckConsistency(this,h1);
5710 } catch(DifferentNumberOfBins&) {
5711 Error("Multiply","Attempt to multiply histograms with different number of bins");
5712 return kFALSE;
5713 } catch(DifferentAxisLimits&) {
5714 Warning("Multiply","Attempt to multiply histograms with different axis limits");
5715 } catch(DifferentBinLimits&) {
5716 Warning("Multiply","Attempt to multiply histograms with different bin limits");
5717 } catch(DifferentLabels&) {
5718 Warning("Multiply","Attempt to multiply histograms with different labels");
5719 }
5720
5721 // Create Sumw2 if h1 has Sumw2 set
5722 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
5723
5724 // - Reset min- maximum
5725 SetMinimum();
5726 SetMaximum();
5727
5728 // - Loop on bins (including underflows/overflows)
5729 for (Int_t i = 0; i < fNcells; ++i) {
5732 UpdateBinContent(i, c0 * c1);
5733 if (fSumw2.fN) {
5735 }
5736 }
5737 ResetStats();
5738 return kTRUE;
5739}
5740
5741////////////////////////////////////////////////////////////////////////////////
5742/// Replace contents of this histogram by multiplication of h1 by h2.
5743///
5744/// `this = (c1*h1)*(c2*h2)`
5745///
5746/// If errors of this are available (TH1::Sumw2), errors are recalculated.
5747/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
5748/// if not already set.
5749///
5750/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5751/// you should call Sumw2 before making this operation.
5752/// This is particularly important if you fit the histogram after TH1::Multiply
5753///
5754/// The function return kFALSE if the Multiply operation failed
5755
5756Bool_t TH1::Multiply(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
5757{
5758 TString opt = option;
5759 opt.ToLower();
5760 // Bool_t binomial = kFALSE;
5761 // if (opt.Contains("b")) binomial = kTRUE;
5762 if (!h1 || !h2) {
5763 Error("Multiply","Attempt to multiply by a non-existing histogram");
5764 return kFALSE;
5765 }
5766
5767 // delete buffer if it is there since it will become invalid
5768 if (fBuffer) BufferEmpty(1);
5769
5770 try {
5771 CheckConsistency(h1,h2);
5772 CheckConsistency(this,h1);
5773 } catch(DifferentNumberOfBins&) {
5774 Error("Multiply","Attempt to multiply histograms with different number of bins");
5775 return kFALSE;
5776 } catch(DifferentAxisLimits&) {
5777 Warning("Multiply","Attempt to multiply histograms with different axis limits");
5778 } catch(DifferentBinLimits&) {
5779 Warning("Multiply","Attempt to multiply histograms with different bin limits");
5780 } catch(DifferentLabels&) {
5781 Warning("Multiply","Attempt to multiply histograms with different labels");
5782 }
5783
5784 // Create Sumw2 if h1 or h2 have Sumw2 set
5785 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
5786
5787 // - Reset min - maximum
5788 SetMinimum();
5789 SetMaximum();
5790
5791 // - Loop on bins (including underflows/overflows)
5792 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
5793 for (Int_t i = 0; i < fNcells; ++i) {
5795 Double_t b2 = h2->RetrieveBinContent(i);
5796 UpdateBinContent(i, c1 * b1 * c2 * b2);
5797 if (fSumw2.fN) {
5798 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
5799 }
5800 }
5801 ResetStats();
5802 return kTRUE;
5803}
5804
5805////////////////////////////////////////////////////////////////////////////////
5806/// Control routine to paint any kind of histograms.
5807///
5808/// This function is automatically called by TCanvas::Update.
5809/// (see TH1::Draw for the list of options)
5810
5811void TH1::Paint(Option_t *option)
5812{
5813 GetPainter(option);
5814
5815 if (fPainter) {
5816 if (strlen(option) > 0) fPainter->Paint(option);
5817 else fPainter->Paint(fOption.Data());
5818 }
5819}
5820
5821////////////////////////////////////////////////////////////////////////////////
5822/// Rebin this histogram
5823///
5824/// #### case 1 xbins=0
5825///
5826/// If newname is blank (default), the current histogram is modified and
5827/// a pointer to it is returned.
5828///
5829/// If newname is not blank, the current histogram is not modified, and a
5830/// new histogram is returned which is a Clone of the current histogram
5831/// with its name set to newname.
5832///
5833/// The parameter ngroup indicates how many bins of this have to be merged
5834/// into one bin of the result.
5835///
5836/// If the original histogram has errors stored (via Sumw2), the resulting
5837/// histograms has new errors correctly calculated.
5838///
5839/// examples: if h1 is an existing TH1F histogram with 100 bins
5840///
5841/// ~~~ {.cpp}
5842/// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
5843/// h1->Rebin(5); //merges five bins in one in h1
5844/// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
5845/// // merging 5 bins of h1 in one bin
5846/// ~~~
5847///
5848/// NOTE: If ngroup is not an exact divider of the number of bins,
5849/// the top limit of the rebinned histogram is reduced
5850/// to the upper edge of the last bin that can make a complete
5851/// group. The remaining bins are added to the overflow bin.
5852/// Statistics will be recomputed from the new bin contents.
5853///
5854/// #### case 2 xbins!=0
5855///
5856/// A new histogram is created (you should specify newname).
5857/// The parameter ngroup is the number of variable size bins in the created histogram.
5858/// The array xbins must contain ngroup+1 elements that represent the low-edges
5859/// of the bins.
5860/// If the original histogram has errors stored (via Sumw2), the resulting
5861/// histograms has new errors correctly calculated.
5862///
5863/// NOTE: The bin edges specified in xbins should correspond to bin edges
5864/// in the original histogram. If a bin edge in the new histogram is
5865/// in the middle of a bin in the original histogram, all entries in
5866/// the split bin in the original histogram will be transfered to the
5867/// lower of the two possible bins in the new histogram. This is
5868/// probably not what you want. A warning message is emitted in this
5869/// case
5870///
5871/// examples: if h1 is an existing TH1F histogram with 100 bins
5872///
5873/// ~~~ {.cpp}
5874/// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
5875/// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
5876/// ~~~
5877
5878TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
5879{
5880 Int_t nbins = fXaxis.GetNbins();
5883 if ((ngroup <= 0) || (ngroup > nbins)) {
5884 Error("Rebin", "Illegal value of ngroup=%d",ngroup);
5885 return 0;
5886 }
5887
5888 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
5889 Error("Rebin", "Operation valid on 1-D histograms only");
5890 return 0;
5891 }
5892 if (!newname && xbins) {
5893 Error("Rebin","if xbins is specified, newname must be given");
5894 return 0;
5895 }
5896
5897 Int_t newbins = nbins/ngroup;
5898 if (!xbins) {
5899 Int_t nbg = nbins/ngroup;
5900 if (nbg*ngroup != nbins) {
5901 Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
5902 }
5903 }
5904 else {
5905 // in the case that xbins is given (rebinning in variable bins), ngroup is
5906 // the new number of bins and number of grouped bins is not constant.
5907 // when looping for setting the contents for the new histogram we
5908 // need to loop on all bins of original histogram. Then set ngroup=nbins
5909 newbins = ngroup;
5910 ngroup = nbins;
5911 }
5912
5913 // Save old bin contents into a new array
5914 Double_t entries = fEntries;
5915 Double_t *oldBins = new Double_t[nbins+2];
5916 Int_t bin, i;
5917 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
5918 Double_t *oldErrors = 0;
5919 if (fSumw2.fN != 0) {
5920 oldErrors = new Double_t[nbins+2];
5921 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
5922 }
5923 // rebin will not include underflow/overflow if new axis range is larger than old axis range
5924 if (xbins) {
5925 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
5926 Warning("Rebin","underflow entries will not be used when rebinning");
5927 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
5928 Warning("Rebin","overflow entries will not be used when rebinning");
5929 }
5930
5931
5932 // create a clone of the old histogram if newname is specified
5933 TH1 *hnew = this;
5934 if ((newname && strlen(newname) > 0) || xbins) {
5935 hnew = (TH1*)Clone(newname);
5936 }
5937
5938 //reset can extend bit to avoid an axis extension in SetBinContent
5939 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
5940
5941 // save original statistics
5942 Double_t stat[kNstat];
5943 GetStats(stat);
5944 bool resetStat = false;
5945 // change axis specs and rebuild bin contents array::RebinAx
5946 if(!xbins && (newbins*ngroup != nbins)) {
5947 xmax = fXaxis.GetBinUpEdge(newbins*ngroup);
5948 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
5949 }
5950 // save the TAttAxis members (reset by SetBins)
5951 Int_t nDivisions = fXaxis.GetNdivisions();
5952 Color_t axisColor = fXaxis.GetAxisColor();
5953 Color_t labelColor = fXaxis.GetLabelColor();
5954 Style_t labelFont = fXaxis.GetLabelFont();
5955 Float_t labelOffset = fXaxis.GetLabelOffset();
5956 Float_t labelSize = fXaxis.GetLabelSize();
5957 Float_t tickLength = fXaxis.GetTickLength();
5958 Float_t titleOffset = fXaxis.GetTitleOffset();
5959 Float_t titleSize = fXaxis.GetTitleSize();
5960 Color_t titleColor = fXaxis.GetTitleColor();
5961 Style_t titleFont = fXaxis.GetTitleFont();
5962
5963 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
5964 Double_t *bins = new Double_t[newbins+1];
5965 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
5966 hnew->SetBins(newbins,bins); //this also changes errors array (if any)
5967 delete [] bins;
5968 } else if (xbins) {
5969 hnew->SetBins(newbins,xbins);
5970 } else {
5971 hnew->SetBins(newbins,xmin,xmax);
5972 }
5973
5974 // Restore axis attributes
5975 fXaxis.SetNdivisions(nDivisions);
5976 fXaxis.SetAxisColor(axisColor);
5977 fXaxis.SetLabelColor(labelColor);
5978 fXaxis.SetLabelFont(labelFont);
5979 fXaxis.SetLabelOffset(labelOffset);
5980 fXaxis.SetLabelSize(labelSize);
5981 fXaxis.SetTickLength(tickLength);
5982 fXaxis.SetTitleOffset(titleOffset);
5983 fXaxis.SetTitleSize(titleSize);
5984 fXaxis.SetTitleColor(titleColor);
5985 fXaxis.SetTitleFont(titleFont);
5986
5987 // copy merged bin contents (ignore under/overflows)
5988 // Start merging only once the new lowest edge is reached
5989 Int_t startbin = 1;
5990 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
5991 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
5992 startbin++;
5993 }
5994 Int_t oldbin = startbin;
5995 Double_t binContent, binError;
5996 for (bin = 1;bin<=newbins;bin++) {
5997 binContent = 0;
5998 binError = 0;
5999 Int_t imax = ngroup;
6000 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6001 // check bin edges for the cases when we provide an array of bins
6002 // be careful in case bins can have zero width
6003 if (xbins && !TMath::AreEqualAbs(fXaxis.GetBinLowEdge(oldbin),
6004 hnew->GetXaxis()->GetBinLowEdge(bin),
6005 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6006 {
6007 Warning("Rebin","Bin edge %d of rebinned histogram does not much any bin edges of the old histogram. Result can be inconsistent",bin);
6008 }
6009 for (i=0;i<ngroup;i++) {
6010 if( (oldbin+i > nbins) ||
6011 ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6012 imax = i;
6013 break;
6014 }
6015 binContent += oldBins[oldbin+i];
6016 if (oldErrors) binError += oldErrors[oldbin+i]*oldErrors[oldbin+i];
6017 }
6018 hnew->SetBinContent(bin,binContent);
6019 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6020 oldbin += imax;
6021 }
6022
6023 // sum underflow and overflow contents until startbin
6024 binContent = 0;
6025 binError = 0;
6026 for (i = 0; i < startbin; ++i) {
6027 binContent += oldBins[i];
6028 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6029 }
6030 hnew->SetBinContent(0,binContent);
6031 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6032 // sum overflow
6033 binContent = 0;
6034 binError = 0;
6035 for (i = oldbin; i <= nbins+1; ++i) {
6036 binContent += oldBins[i];
6037 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6038 }
6039 hnew->SetBinContent(newbins+1,binContent);
6040 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6041
6042 hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6043
6044 // restore statistics and entries modified by SetBinContent
6045 hnew->SetEntries(entries);
6046 if (!resetStat) hnew->PutStats(stat);
6047 delete [] oldBins;
6048 if (oldErrors) delete [] oldErrors;
6049 return hnew;
6050}
6051
6052////////////////////////////////////////////////////////////////////////////////
6053/// finds new limits for the axis so that *point* is within the range and
6054/// the limits are compatible with the previous ones (see TH1::Merge).
6055/// new limits are put into *newMin* and *newMax* variables.
6056/// axis - axis whose limits are to be recomputed
6057/// point - point that should fit within the new axis limits
6058/// newMin - new minimum will be stored here
6059/// newMax - new maximum will be stored here.
6060/// false if failed (e.g. if the initial axis limits are wrong
6061/// or the new range is more than \f$ 2^{64} \f$ times the old one).
6062
6063Bool_t TH1::FindNewAxisLimits(const TAxis* axis, const Double_t point, Double_t& newMin, Double_t &newMax)
6064{
6065 Double_t xmin = axis->GetXmin();
6066 Double_t xmax = axis->GetXmax();
6067 if (xmin >= xmax) return kFALSE;
6068 Double_t range = xmax-xmin;
6069 Double_t binsize = range / axis->GetNbins();
6070
6071 //recompute new axis limits by doubling the current range
6072 Int_t ntimes = 0;
6073 while (point < xmin) {
6074 if (ntimes++ > 64)
6075 return kFALSE;
6076 xmin = xmin - range;
6077 range *= 2;
6078 binsize *= 2;
6079 // // make sure that the merging will be correct
6080 // if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
6081 // xmin += 0.5 * binsize;
6082 // xmax += 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
6083 // }
6084 }
6085 while (point >= xmax) {
6086 if (ntimes++ > 64)
6087 return kFALSE;
6088 xmax = xmax + range;
6089 range *= 2;
6090 binsize *= 2;
6091 // // make sure that the merging will be correct
6092 // if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
6093 // xmin -= 0.5 * binsize;
6094 // xmax -= 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
6095 // }
6096 }
6097 newMin = xmin;
6098 newMax = xmax;
6099 // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6100 // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6101
6102 return kTRUE;
6103}
6104
6105////////////////////////////////////////////////////////////////////////////////
6106/// Histogram is resized along axis such that x is in the axis range.
6107/// The new axis limits are recomputed by doubling iteratively
6108/// the current axis range until the specified value x is within the limits.
6109/// The algorithm makes a copy of the histogram, then loops on all bins
6110/// of the old histogram to fill the extended histogram.
6111/// Takes into account errors (Sumw2) if any.
6112/// The algorithm works for 1-d, 2-D and 3-D histograms.
6113/// The axis must be extendable before invoking this function.
6114/// Ex:
6115///
6116/// ~~~ {.cpp}
6117/// h->GetXaxis()->SetCanExtend(kTRUE);
6118/// ~~~
6119
6120void TH1::ExtendAxis(Double_t x, TAxis *axis)
6121{
6122 if (!axis->CanExtend()) return;
6123 if (TMath::IsNaN(x)) { // x may be a NaN
6125 return;
6126 }
6127
6128 if (axis->GetXmin() >= axis->GetXmax()) return;
6129 if (axis->GetNbins() <= 0) return;
6130
6132 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6133 return;
6134
6135 //save a copy of this histogram
6136 TH1 *hold = (TH1*)IsA()->New();
6137 hold->SetDirectory(0);
6138 Copy(*hold);
6139 //set new axis limits
6140 axis->SetLimits(xmin,xmax);
6141
6142
6143 //now loop on all bins and refill
6144 Int_t errors = GetSumw2N();
6145
6146 Reset("ICE"); //reset only Integral, contents and Errors
6147
6148 int iaxis = 0;
6149 if (axis == &fXaxis) iaxis = 1;
6150 if (axis == &fYaxis) iaxis = 2;
6151 if (axis == &fZaxis) iaxis = 3;
6152 bool firstw = kTRUE;
6153 Int_t binx,biny, binz = 0;
6154 Int_t ix = 0,iy = 0,iz = 0;
6155 Double_t bx,by,bz;
6156 Int_t ncells = hold->GetNcells();
6157 for (Int_t bin = 0; bin < ncells; ++bin) {
6158 hold->GetBinXYZ(bin,binx,biny,binz);
6159 bx = hold->GetXaxis()->GetBinCenter(binx);
6160 ix = fXaxis.FindFixBin(bx);
6161 if (fDimension > 1) {
6162 by = hold->GetYaxis()->GetBinCenter(biny);
6163 iy = fYaxis.FindFixBin(by);
6164 if (fDimension > 2) {
6165 bz = hold->GetZaxis()->GetBinCenter(binz);
6166 iz = fZaxis.FindFixBin(bz);
6167 }
6168 }
6169 // exclude underflow/overflow
6170 double content = hold->RetrieveBinContent(bin);
6171 if (content == 0) continue;
6172 if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6173 if (firstw) {
6174 Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6175 " their content will be lost",GetName() );
6176 firstw= kFALSE;
6177 }
6178 continue;
6179 }
6180 Int_t ibin= GetBin(ix,iy,iz);
6181 AddBinContent(ibin, content);
6182 if (errors) {
6183 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6184 }
6185 }
6186 delete hold;
6187}
6188
6189////////////////////////////////////////////////////////////////////////////////
6190/// Recursively remove object from the list of functions
6191
6193{
6194 // Rely on TROOT::RecursiveRemove to take the readlock.
6195
6196 if (fFunctions) {
6198 }
6199}
6200
6201////////////////////////////////////////////////////////////////////////////////
6202/// Multiply this histogram by a constant c1.
6203///
6204/// `this = c1*this`
6205///
6206/// Note that both contents and errors(if any) are scaled.
6207/// This function uses the services of TH1::Add
6208///
6209/// IMPORTANT NOTE: Sumw2() is called automatically when scaling
6210/// If you are not interested in the histogram statistics you can call
6211/// Sumw2(off) or use the option "nosw2"
6212///
6213/// One can scale an histogram such that the bins integral is equal to
6214/// the normalization parameter via TH1::Scale(Double_t norm), where norm
6215/// is the desired normalization divided by the integral of the histogram.
6216///
6217/// If option contains "width" the bin contents and errors are divided
6218/// by the bin width.
6219
6220void TH1::Scale(Double_t c1, Option_t *option)
6221{
6222
6223 TString opt = option; opt.ToLower();
6224 // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6225 if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6226 if (opt.Contains("width")) Add(this, this, c1, -1);
6227 else {
6228 if (fBuffer) BufferEmpty(1);
6229 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6230 if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6231 SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6232 }
6233
6234 // if contours set, must also scale contours
6235 Int_t ncontours = GetContour();
6236 if (ncontours == 0) return;
6237 Double_t* levels = fContour.GetArray();
6238 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6239}
6240
6241////////////////////////////////////////////////////////////////////////////////
6242/// Returns true if all axes are extendable.
6243
6245{
6246 Bool_t canExtend = fXaxis.CanExtend();
6247 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6248 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6249
6250 return canExtend;
6251}
6252
6253////////////////////////////////////////////////////////////////////////////////
6254/// Make the histogram axes extendable / not extendable according to the bit mask
6255/// returns the previous bit mask specifying which axes are extendable
6256
6257UInt_t TH1::SetCanExtend(UInt_t extendBitMask)
6258{
6259 UInt_t oldExtendBitMask = kNoAxis;
6260
6261 if (fXaxis.CanExtend()) oldExtendBitMask |= kXaxis;
6262 if (extendBitMask & kXaxis) fXaxis.SetCanExtend(kTRUE);
6264
6265 if (GetDimension() > 1) {
6266 if (fYaxis.CanExtend()) oldExtendBitMask |= kYaxis;
6267 if (extendBitMask & kYaxis) fYaxis.SetCanExtend(kTRUE);
6269 }
6270
6271 if (GetDimension() > 2) {
6272 if (fZaxis.CanExtend()) oldExtendBitMask |= kZaxis;
6273 if (extendBitMask & kZaxis) fZaxis.SetCanExtend(kTRUE);
6275 }
6276
6277 return oldExtendBitMask;
6278}
6279
6280////////////////////////////////////////////////////////////////////////////////
6281/// Static function to set the default buffer size for automatic histograms.
6282/// When an histogram is created with one of its axis lower limit greater
6283/// or equal to its upper limit, the function SetBuffer is automatically
6284/// called with the default buffer size.
6285
6286void TH1::SetDefaultBufferSize(Int_t buffersize)
6287{
6288 fgBufferSize = buffersize > 0 ? buffersize : 0;
6289}
6290
6291////////////////////////////////////////////////////////////////////////////////
6292/// When this static function is called with `sumw2=kTRUE`, all new
6293/// histograms will automatically activate the storage
6294/// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6295
6296void TH1::SetDefaultSumw2(Bool_t sumw2)
6297{
6298 fgDefaultSumw2 = sumw2;
6299}
6300
6301////////////////////////////////////////////////////////////////////////////////
6302/// Change (i.e. set) the title
6303///
6304/// if title is in the form `stringt;stringx;stringy;stringz`
6305/// the histogram title is set to `stringt`, the x axis title to `stringx`,
6306/// the y axis title to `stringy`, and the z axis title to `stringz`.
6307///
6308/// To insert the character `;` in one of the titles, one should use `#;`
6309/// or `#semicolon`.
6310
6311void TH1::SetTitle(const char *title)
6312{
6313 fTitle = title;
6314 fTitle.ReplaceAll("#;",2,"#semicolon",10);
6315
6316 // Decode fTitle. It may contain X, Y and Z titles
6317 TString str1 = fTitle, str2;
6318 Int_t isc = str1.Index(";");
6319 Int_t lns = str1.Length();
6320
6321 if (isc >=0 ) {
6322 fTitle = str1(0,isc);
6323 str1 = str1(isc+1, lns);
6324 isc = str1.Index(";");
6325 if (isc >=0 ) {
6326 str2 = str1(0,isc);
6327 str2.ReplaceAll("#semicolon",10,";",1);
6328 fXaxis.SetTitle(str2.Data());
6329 lns = str1.Length();
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 fYaxis.SetTitle(str2.Data());
6336 lns = str1.Length();
6337 str1 = str1(isc+1, lns);
6338 str1.ReplaceAll("#semicolon",10,";",1);
6339 fZaxis.SetTitle(str1.Data());
6340 } else {
6341 str1.ReplaceAll("#semicolon",10,";",1);
6342 fYaxis.SetTitle(str1.Data());
6343 }
6344 } else {
6345 str1.ReplaceAll("#semicolon",10,";",1);
6346 fXaxis.SetTitle(str1.Data());
6347 }
6348 }
6349
6350 fTitle.ReplaceAll("#semicolon",10,";",1);
6351
6352 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6353}
6354
6355////////////////////////////////////////////////////////////////////////////////
6356/// Smooth array xx, translation of Hbook routine hsmoof.F
6357/// based on algorithm 353QH twice presented by J. Friedman
6358/// in Proc.of the 1974 CERN School of Computing, Norway, 11-24 August, 1974.
6359
6360void TH1::SmoothArray(Int_t nn, Double_t *xx, Int_t ntimes)
6361{
6362 if (nn < 3 ) {
6363 ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6364 return;
6365 }
6366
6367 Int_t ii;
6368 Double_t hh[6] = {0,0,0,0,0,0};
6369
6370 std::vector<double> yy(nn);
6371 std::vector<double> zz(nn);
6372 std::vector<double> rr(nn);
6373
6374 for (Int_t pass=0;pass<ntimes;pass++) {
6375 // first copy original data into temp array
6376 std::copy(xx, xx+nn, zz.begin() );
6377
6378 for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6379
6380 // do 353 i.e. running median 3, 5, and 3 in a single loop
6381 for (int kk = 0; kk < 3; kk++) {
6382 std::copy(zz.begin(), zz.end(), yy.begin());
6383 int medianType = (kk != 1) ? 3 : 5;
6384 int ifirst = (kk != 1 ) ? 1 : 2;
6385 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6386 //nn2 = nn - ik - 1;
6387 // do all elements beside the first and last point for median 3
6388 // and first two and last 2 for median 5
6389 for ( ii = ifirst; ii < ilast; ii++) {
6390 assert(ii - ifirst >= 0);
6391 for (int jj = 0; jj < medianType; jj++) {
6392 hh[jj] = yy[ii - ifirst + jj ];
6393 }
6394 zz[ii] = TMath::Median(medianType, hh);
6395 }
6396
6397 if (kk == 0) { // first median 3
6398 // first point
6399 hh[0] = zz[1];
6400 hh[1] = zz[0];
6401 hh[2] = 3*zz[1] - 2*zz[2];
6402 zz[0] = TMath::Median(3, hh);
6403 // last point
6404 hh[0] = zz[nn - 2];
6405 hh[1] = zz[nn - 1];
6406 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6407 zz[nn - 1] = TMath::Median(3, hh);
6408 }
6409
6410 if (kk == 1) { // median 5
6411 for (ii = 0; ii < 3; ii++) {
6412 hh[ii] = yy[ii];
6413 }
6414 zz[1] = TMath::Median(3, hh);
6415 // last two points
6416 for (ii = 0; ii < 3; ii++) {
6417 hh[ii] = yy[nn - 3 + ii];
6418 }
6419 zz[nn - 2] = TMath::Median(3, hh);
6420 }
6421
6422 }
6423
6424 std::copy ( zz.begin(), zz.end(), yy.begin() );
6425
6426 // quadratic interpolation for flat segments
6427 for (ii = 2; ii < (nn - 2); ii++) {
6428 if (zz[ii - 1] != zz[ii]) continue;
6429 if (zz[ii] != zz[ii + 1]) continue;
6430 hh[0] = zz[ii - 2] - zz[ii];
6431 hh[1] = zz[ii + 2] - zz[ii];
6432 if (hh[0] * hh[1] <= 0) continue;
6433 int jk = 1;
6434 if ( TMath::Abs(hh[1]) > TMath::Abs(hh[0]) ) jk = -1;
6435 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6436 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6437 }
6438
6439 // running means
6440 //std::copy(zz.begin(), zz.end(), yy.begin());
6441 for (ii = 1; ii < nn - 1; ii++) {
6442 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6443 }
6444 zz[0] = yy[0];
6445 zz[nn - 1] = yy[nn - 1];
6446
6447 if (noent == 0) {
6448
6449 // save computed values
6450 std::copy(zz.begin(), zz.end(), rr.begin());
6451
6452 // COMPUTE residuals
6453 for (ii = 0; ii < nn; ii++) {
6454 zz[ii] = xx[ii] - zz[ii];
6455 }
6456 }
6457
6458 } // end loop on noent
6459
6460
6461 double xmin = TMath::MinElement(nn,xx);
6462 for (ii = 0; ii < nn; ii++) {
6463 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6464 // make smoothing defined positive - not better using 0 ?
6465 else xx[ii] = TMath::Max((rr[ii] + zz[ii]),0.0 );
6466 }
6467 }
6468}
6469
6470////////////////////////////////////////////////////////////////////////////////
6471/// Smooth bin contents of this histogram.
6472/// if option contains "R" smoothing is applied only to the bins
6473/// defined in the X axis range (default is to smooth all bins)
6474/// Bin contents are replaced by their smooth values.
6475/// Errors (if any) are not modified.
6476/// the smoothing procedure is repeated ntimes (default=1)
6477
6478void TH1::Smooth(Int_t ntimes, Option_t *option)
6479{
6480 if (fDimension != 1) {
6481 Error("Smooth","Smooth only supported for 1-d histograms");
6482 return;
6483 }
6484 Int_t nbins = fXaxis.GetNbins();
6485 if (nbins < 3) {
6486 Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
6487 return;
6488 }
6489
6490 // delete buffer if it is there since it will become invalid
6491 if (fBuffer) BufferEmpty(1);
6492
6493 Int_t firstbin = 1, lastbin = nbins;
6494 TString opt = option;
6495 opt.ToLower();
6496 if (opt.Contains("r")) {
6497 firstbin= fXaxis.GetFirst();
6498 lastbin = fXaxis.GetLast();
6499 }
6500 nbins = lastbin - firstbin + 1;
6501 Double_t *xx = new Double_t[nbins];
6502 Double_t nent = fEntries;
6503 Int_t i;
6504 for (i=0;i<nbins;i++) {
6505 xx[i] = RetrieveBinContent(i+firstbin);
6506 }
6507
6508 TH1::SmoothArray(nbins,xx,ntimes);
6509
6510 for (i=0;i<nbins;i++) {
6511 UpdateBinContent(i+firstbin,xx[i]);
6512 }
6513 fEntries = nent;
6514 delete [] xx;
6515
6516 if (gPad) gPad->Modified();
6517}
6518
6519////////////////////////////////////////////////////////////////////////////////
6520/// if flag=kTRUE, underflows and overflows are used by the Fill functions
6521/// in the computation of statistics (mean value, StdDev).
6522/// By default, underflows or overflows are not used.
6523
6524void TH1::StatOverflows(Bool_t flag)
6525{
6526 fgStatOverflows = flag;
6527}
6528
6529////////////////////////////////////////////////////////////////////////////////
6530/// Stream a class object.
6531
6532void TH1::Streamer(TBuffer &b)
6533{
6534 if (b.IsReading()) {
6535 UInt_t R__s, R__c;
6536 Version_t R__v = b.ReadVersion(&R__s, &R__c);
6537 if (fDirectory) fDirectory->Remove(this);
6538 fDirectory = 0;
6539 if (R__v > 2) {
6540 b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
6541
6543 fXaxis.SetParent(this);
6544 fYaxis.SetParent(this);
6545 fZaxis.SetParent(this);
6546 TIter next(fFunctions);
6547 TObject *obj;
6548 while ((obj=next())) {
6549 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
6550 }
6551 return;
6552 }
6553 //process old versions before automatic schema evolution
6554 TNamed::Streamer(b);
6555 TAttLine::Streamer(b);
6556 TAttFill::Streamer(b);
6557 TAttMarker::Streamer(b);
6558 b >> fNcells;
6559 fXaxis.Streamer(b);
6560 fYaxis.Streamer(b);
6561 fZaxis.Streamer(b);
6562 fXaxis.SetParent(this);
6563 fYaxis.SetParent(this);
6564 fZaxis.SetParent(this);
6565 b >> fBarOffset;
6566 b >> fBarWidth;
6567 b >> fEntries;
6568 b >> fTsumw;
6569 b >> fTsumw2;
6570 b >> fTsumwx;
6571 b >> fTsumwx2;
6572 if (R__v < 2) {
6573 Float_t maximum, minimum, norm;
6574 Float_t *contour=0;
6575 b >> maximum; fMaximum = maximum;
6576 b >> minimum; fMinimum = minimum;
6577 b >> norm; fNormFactor = norm;
6578 Int_t n = b.ReadArray(contour);
6579 fContour.Set(n);
6580 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
6581 delete [] contour;
6582 } else {
6583 b >> fMaximum;
6584 b >> fMinimum;
6585 b >> fNormFactor;
6586 fContour.Streamer(b);
6587 }
6588 fSumw2.Streamer(b);
6589 fOption.Streamer(b);
6590 fFunctions->Delete();
6591 fFunctions->Streamer(b);
6592 b.CheckByteCount(R__s, R__c, TH1::IsA());
6593
6594 } else {
6595 b.WriteClassBuffer(TH1::Class(),this);
6596 }
6597}
6598
6599////////////////////////////////////////////////////////////////////////////////
6600/// Print some global quantities for this histogram.
6601/// \param[in] option
6602/// - "base" is given, number of bins and ranges are also printed
6603/// - "range" is given, bin contents and errors are also printed
6604/// for all bins in the current range (default 1-->nbins)
6605/// - "all" is given, bin contents and errors are also printed
6606/// for all bins including under and overflows.
6607
6608void TH1::Print(Option_t *option) const
6609{
6610 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
6611 printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
6612 TString opt = option;
6613 opt.ToLower();
6614 Int_t all;
6615 if (opt.Contains("all")) all = 0;
6616 else if (opt.Contains("range")) all = 1;
6617 else if (opt.Contains("base")) all = 2;
6618 else return;
6619
6620 Int_t bin, binx, biny, binz;
6621 Int_t firstx=0,lastx=0,firsty=0,lasty=0,firstz=0,lastz=0;
6622 if (all == 0) {
6623 lastx = fXaxis.GetNbins()+1;
6624 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
6625 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
6626 } else {
6627 firstx = fXaxis.GetFirst(); lastx = fXaxis.GetLast();
6628 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
6629 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
6630 }
6631
6632 if (all== 2) {
6633 printf(" Title = %s\n", GetTitle());
6634 printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
6635 if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
6636 if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
6637 printf("\n");
6638 return;
6639 }
6640
6641 Double_t w,e;
6642 Double_t x,y,z;
6643 if (fDimension == 1) {
6644 for (binx=firstx;binx<=lastx;binx++) {
6645 x = fXaxis.GetBinCenter(binx);
6646 w = RetrieveBinContent(binx);
6647 e = GetBinError(binx);
6648 if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
6649 else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
6650 }
6651 }
6652 if (fDimension == 2) {
6653 for (biny=firsty;biny<=lasty;biny++) {
6654 y = fYaxis.GetBinCenter(biny);
6655 for (binx=firstx;binx<=lastx;binx++) {
6656 bin = GetBin(binx,biny);
6657 x = fXaxis.GetBinCenter(binx);
6658 w = RetrieveBinContent(bin);
6659 e = GetBinError(bin);
6660 if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
6661 else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
6662 }
6663 }
6664 }
6665 if (fDimension == 3) {
6666 for (binz=firstz;binz<=lastz;binz++) {
6667 z = fZaxis.GetBinCenter(binz);
6668 for (biny=firsty;biny<=lasty;biny++) {
6669 y = fYaxis.GetBinCenter(biny);
6670 for (binx=firstx;binx<=lastx;binx++) {
6671 bin = GetBin(binx,biny,binz);
6672 x = fXaxis.GetBinCenter(binx);
6673 w = RetrieveBinContent(bin);
6674 e = GetBinError(bin);
6675 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);
6676 else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
6677 }
6678 }
6679 }
6680 }
6681}
6682
6683////////////////////////////////////////////////////////////////////////////////
6684/// Using the current bin info, recompute the arrays for contents and errors
6685
6686void TH1::Rebuild(Option_t *)
6687{
6688 SetBinsLength();
6689 if (fSumw2.fN) {
6691 }
6692}
6693
6694////////////////////////////////////////////////////////////////////////////////
6695/// Reset this histogram: contents, errors, etc.
6696/// \param[in] option
6697/// - if "ICE" is specified, resets only Integral, Contents and Errors.
6698/// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
6699/// This option is used
6700/// - if "M" is specified, resets also Minimum and Maximum
6701
6702void TH1::Reset(Option_t *option)
6703{
6704 // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
6705 // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
6706
6707 TString opt = option;
6708 opt.ToUpper();
6709 fSumw2.Reset();
6710 if (fIntegral) {delete [] fIntegral; fIntegral = 0;}
6711
6712 if (opt.Contains("M")) {
6713 SetMinimum();
6714 SetMaximum();
6715 }
6716
6717 if (opt.Contains("ICE") && !opt.Contains("S")) return;
6718
6719 // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
6720 // But what is the sense of calling BufferEmpty() ? For making the axes ?
6721 // BufferEmpty will update contents that later will be
6722 // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
6723 // It may be needed for computing the axis limits....
6724 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
6725
6726 // need to reset also the statistics
6727 // (needs to be done after calling BufferEmpty() )
6728 fTsumw = 0;
6729 fTsumw2 = 0;
6730 fTsumwx = 0;
6731 fTsumwx2 = 0;
6732 fEntries = 0;
6733
6734 if (opt == "ICES") return;
6735
6736
6737 TObject *stats = fFunctions->FindObject("stats");
6738 fFunctions->Remove(stats);
6739 //special logic to support the case where the same object is
6740 //added multiple times in fFunctions.
6741 //This case happens when the same object is added with different
6742 //drawing modes
6743 TObject *obj;
6744 while ((obj = fFunctions->First())) {
6745 while(fFunctions->Remove(obj)) { }
6746 delete obj;
6747 }
6748 if(stats) fFunctions->Add(stats);
6749 fContour.Set(0);
6750}
6751
6752////////////////////////////////////////////////////////////////////////////////
6753/// Save primitive as a C++ statement(s) on output stream out
6754
6755void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
6756{
6757 // empty the buffer before if it exists
6758 if (fBuffer) BufferEmpty();
6759
6760 Bool_t nonEqiX = kFALSE;
6761 Bool_t nonEqiY = kFALSE;
6762 Bool_t nonEqiZ = kFALSE;
6763 Int_t i;
6764 static Int_t nxaxis = 0;
6765 static Int_t nyaxis = 0;
6766 static Int_t nzaxis = 0;
6767 TString sxaxis="xAxis",syaxis="yAxis",szaxis="zAxis";
6768
6769 // Check if the histogram has equidistant X bins or not. If not, we
6770 // create an array holding the bins.
6771 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
6772 nonEqiX = kTRUE;
6773 nxaxis++;
6774 sxaxis += nxaxis;
6775 out << " Double_t "<<sxaxis<<"[" << GetXaxis()->GetXbins()->fN
6776 << "] = {";
6777 for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
6778 if (i != 0) out << ", ";
6779 out << GetXaxis()->GetXbins()->fArray[i];
6780 }
6781 out << "}; " << std::endl;
6782 }
6783 // If the histogram is 2 or 3 dimensional, check if the histogram
6784 // has equidistant Y bins or not. If not, we create an array
6785 // holding the bins.
6786 if (fDimension > 1 && GetYaxis()->GetXbins()->fN &&
6787 GetYaxis()->GetXbins()->fArray) {
6788 nonEqiY = kTRUE;
6789 nyaxis++;
6790 syaxis += nyaxis;
6791 out << " Double_t "<<syaxis<<"[" << GetYaxis()->GetXbins()->fN
6792 << "] = {";
6793 for (i = 0; i < GetYaxis()->GetXbins()->fN; i++) {
6794 if (i != 0) out << ", ";
6795 out << GetYaxis()->GetXbins()->fArray[i];
6796 }
6797 out << "}; " << std::endl;
6798 }
6799 // IF the histogram is 3 dimensional, check if the histogram
6800 // has equidistant Z bins or not. If not, we create an array
6801 // holding the bins.
6802 if (fDimension > 2 && GetZaxis()->GetXbins()->fN &&
6803 GetZaxis()->GetXbins()->fArray) {
6804 nonEqiZ = kTRUE;
6805 nzaxis++;
6806 szaxis += nzaxis;
6807 out << " Double_t "<<szaxis<<"[" << GetZaxis()->GetXbins()->fN
6808 << "] = {";
6809 for (i = 0; i < GetZaxis()->GetXbins()->fN; i++) {
6810 if (i != 0) out << ", ";
6811 out << GetZaxis()->GetXbins()->fArray[i];
6812 }
6813 out << "}; " << std::endl;
6814 }
6815
6816 char quote = '"';
6817 out <<" "<<std::endl;
6818 out <<" "<< ClassName() <<" *";
6819
6820 // Histogram pointer has by default the histogram name with an incremental suffix.
6821 // If the histogram belongs to a graph or a stack the suffix is not added because
6822 // the graph and stack objects are not aware of this new name. Same thing if
6823 // the histogram is drawn with the option COLZ because the TPaletteAxis drawn
6824 // when this option is selected, does not know this new name either.
6825 TString opt = option;
6826 opt.ToLower();
6827 static Int_t hcounter = 0;
6828 TString histName = GetName();
6829 if ( !histName.Contains("Graph")
6830 && !histName.Contains("_stack_")
6831 && !opt.Contains("colz")) {
6832 hcounter++;
6833 histName += "__";
6834 histName += hcounter;
6835 }
6836 histName = gInterpreter-> MapCppName(histName);
6837 const char *hname = histName.Data();
6838 if (!strlen(hname)) hname = "unnamed";
6839 TString savedName = GetName();
6840 this->SetName(hname);
6841 TString t(GetTitle());
6842 t.ReplaceAll("\\","\\\\");
6843 t.ReplaceAll("\"","\\\"");
6844 out << hname << " = new " << ClassName() << "(" << quote
6845 << hname << quote << "," << quote<< t.Data() << quote
6846 << "," << GetXaxis()->GetNbins();
6847 if (nonEqiX)
6848 out << ", "<<sxaxis;
6849 else
6850 out << "," << GetXaxis()->GetXmin()
6851 << "," << GetXaxis()->GetXmax();
6852 if (fDimension > 1) {
6853 out << "," << GetYaxis()->GetNbins();
6854 if (nonEqiY)
6855 out << ", "<<syaxis;
6856 else
6857 out << "," << GetYaxis()->GetXmin()
6858 << "," << GetYaxis()->GetXmax();
6859 }
6860 if (fDimension > 2) {
6861 out << "," << GetZaxis()->GetNbins();
6862 if (nonEqiZ)
6863 out << ", "<<szaxis;
6864 else
6865 out << "," << GetZaxis()->GetXmin()
6866 << "," << GetZaxis()->GetXmax();
6867 }
6868 out << ");" << std::endl;
6869
6870 // save bin contents
6871 Int_t bin;
6872 for (bin=0;bin<fNcells;bin++) {
6873 Double_t bc = RetrieveBinContent(bin);
6874 if (bc) {
6875 out<<" "<<hname<<"->SetBinContent("<<bin<<","<<bc<<");"<<std::endl;
6876 }
6877 }
6878
6879 // save bin errors
6880 if (fSumw2.fN) {
6881 for (bin=0;bin<fNcells;bin++) {
6882 Double_t be = GetBinError(bin);
6883 if (be) {
6884 out<<" "<<hname<<"->SetBinError("<<bin<<","<<be<<");"<<std::endl;
6885 }
6886 }
6887 }
6888
6889 TH1::SavePrimitiveHelp(out, hname, option);
6890 this->SetName(savedName.Data());
6891}
6892
6893////////////////////////////////////////////////////////////////////////////////
6894/// Helper function for the SavePrimitive functions from TH1
6895/// or classes derived from TH1, eg TProfile, TProfile2D.
6896
6897void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
6898{
6899 char quote = '"';
6900 if (TMath::Abs(GetBarOffset()) > 1e-5) {
6901 out<<" "<<hname<<"->SetBarOffset("<<GetBarOffset()<<");"<<std::endl;
6902 }
6903 if (TMath::Abs(GetBarWidth()-1) > 1e-5) {
6904 out<<" "<<hname<<"->SetBarWidth("<<GetBarWidth()<<");"<<std::endl;
6905 }
6906 if (fMinimum != -1111) {
6907 out<<" "<<hname<<"->SetMinimum("<<fMinimum<<");"<<std::endl;
6908 }
6909 if (fMaximum != -1111) {
6910 out<<" "<<hname<<"->SetMaximum("<<fMaximum<<");"<<std::endl;
6911 }
6912 if (fNormFactor != 0) {
6913 out<<" "<<hname<<"->SetNormFactor("<<fNormFactor<<");"<<std::endl;
6914 }
6915 if (fEntries != 0) {
6916 out<<" "<<hname<<"->SetEntries("<<fEntries<<");"<<std::endl;
6917 }
6918 if (fDirectory == 0) {
6919 out<<" "<<hname<<"->SetDirectory(0);"<<std::endl;
6920 }
6921 if (TestBit(kNoStats)) {
6922 out<<" "<<hname<<"->SetStats(0);"<<std::endl;
6923 }
6924 if (fOption.Length() != 0) {
6925 out<<" "<<hname<<"->SetOption("<<quote<<fOption.Data()<<quote<<");"<<std::endl;
6926 }
6927
6928 // save contour levels
6929 Int_t ncontours = GetContour();
6930 if (ncontours > 0) {
6931 out<<" "<<hname<<"->SetContour("<<ncontours<<");"<<std::endl;
6932 Double_t zlevel;
6933 for (Int_t bin=0;bin<ncontours;bin++) {
6934 if (gPad->GetLogz()) {
6935 zlevel = TMath::Power(10,GetContourLevel(bin));
6936 } else {
6937 zlevel = GetContourLevel(bin);
6938 }
6939 out<<" "<<hname<<"->SetContourLevel("<<bin<<","<<zlevel<<");"<<std::endl;
6940 }
6941 }
6942
6943 // save list of functions
6945 TObject *obj;
6946 static Int_t funcNumber = 0;
6947 while (lnk) {
6948 obj = lnk->GetObject();
6949 obj->SavePrimitive(out,Form("nodraw #%d\n",++funcNumber));
6950 if (obj->InheritsFrom(TF1::Class())) {
6951 TString fname;
6952 fname.Form("%s%d",obj->GetName(),funcNumber);
6953 out << " " << fname << "->SetParent(" << hname << ");\n";
6954 out<<" "<<hname<<"->GetListOfFunctions()->Add("
6955 << fname <<");"<<std::endl;
6956 } else if (obj->InheritsFrom("TPaveStats")) {
6957 out<<" "<<hname<<"->GetListOfFunctions()->Add(ptstats);"<<std::endl;
6958 out<<" ptstats->SetParent("<<hname<<");"<<std::endl;
6959 } else if (obj->InheritsFrom("TPolyMarker")) {
6960 out<<" "<<hname<<"->GetListOfFunctions()->Add("
6961 <<"pmarker ,"<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
6962 } else {
6963 out<<" "<<hname<<"->GetListOfFunctions()->Add("
6964 <<obj->GetName()
6965 <<","<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
6966 }
6967 lnk = (TObjOptLink*)lnk->Next();
6968 }
6969
6970 // save attributes
6971 SaveFillAttributes(out,hname,0,1001);
6972 SaveLineAttributes(out,hname,1,1,1);
6973 SaveMarkerAttributes(out,hname,1,1,1);
6974 fXaxis.SaveAttributes(out,hname,"->GetXaxis()");
6975 fYaxis.SaveAttributes(out,hname,"->GetYaxis()");
6976 fZaxis.SaveAttributes(out,hname,"->GetZaxis()");
6977 TString opt = option;
6978 opt.ToLower();
6979 if (!opt.Contains("nodraw")) {
6980 out<<" "<<hname<<"->Draw("
6981 <<quote<<option<<quote<<");"<<std::endl;
6982 }
6983}
6984
6985////////////////////////////////////////////////////////////////////////////////
6986/// Copy current attributes from/to current style
6987
6989{
6990 if (!gStyle) return;
6991 if (gStyle->IsReading()) {
6992 fXaxis.ResetAttAxis("X");
6993 fYaxis.ResetAttAxis("Y");
6994 fZaxis.ResetAttAxis("Z");
7005 Int_t dostat = gStyle->GetOptStat();
7006 if (gStyle->GetOptFit() && !dostat) dostat = 1000000001;
7007 SetStats(dostat);
7008 } else {
7020 }
7021 TIter next(GetListOfFunctions());
7022 TObject *obj;
7023
7024 while ((obj = next())) {
7025 obj->UseCurrentStyle();
7026 }
7027}
7028
7029////////////////////////////////////////////////////////////////////////////////
7030/// For axis = 1,2 or 3 returns the mean value of the histogram along
7031/// X,Y or Z axis.
7032///
7033/// For axis = 11, 12, 13 returns the standard error of the mean value
7034/// of the histogram along X, Y or Z axis
7035///
7036/// Note that the mean value/StdDev is computed using the bins in the currently
7037/// defined range (see TAxis::SetRange). By default the range includes
7038/// all bins from 1 to nbins included, excluding underflows and overflows.
7039/// To force the underflows and overflows in the computation, one must
7040/// call the static function TH1::StatOverflows(kTRUE) before filling
7041/// the histogram.
7042///
7043/// Return mean value of this histogram along the X axis.
7044///
7045/// Note that the mean value/StdDev is computed using the bins in the currently
7046/// defined range (see TAxis::SetRange). By default the range includes
7047/// all bins from 1 to nbins included, excluding underflows and overflows.
7048/// To force the underflows and overflows in the computation, one must
7049/// call the static function TH1::StatOverflows(kTRUE) before filling
7050/// the histogram.
7051
7052Double_t TH1::GetMean(Int_t axis) const
7053{
7054 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7055 Double_t stats[kNstat];
7056 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7057 GetStats(stats);
7058 if (stats[0] == 0) return 0;
7059 if (axis<4){
7060 Int_t ax[3] = {2,4,7};
7061 return stats[ax[axis-1]]/stats[0];
7062 } else {
7063 // mean error = StdDev / sqrt( Neff )
7064 Double_t stddev = GetStdDev(axis-10);
7066 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7067 }
7068}
7069
7070////////////////////////////////////////////////////////////////////////////////
7071/// Return standard error of mean of this histogram along the X axis.
7072///
7073/// Note that the mean value/StdDev is computed using the bins in the currently
7074/// defined range (see TAxis::SetRange). By default the range includes
7075/// all bins from 1 to nbins included, excluding underflows and overflows.
7076/// To force the underflows and overflows in the computation, one must
7077/// call the static function TH1::StatOverflows(kTRUE) before filling
7078/// the histogram.
7079///
7080/// Also note, that although the definition of standard error doesn't include the
7081/// assumption of normality, many uses of this feature implicitly assume it.
7082
7084{
7085 return GetMean(axis+10);
7086}
7087
7088////////////////////////////////////////////////////////////////////////////////
7089/// Returns the Standard Deviation (Sigma).
7090/// The Sigma estimate is computed as
7091/// \f[
7092/// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7093/// \f]
7094/// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7095/// X, Y or Z axis
7096/// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7097/// X, Y or Z axis for Normal distribution
7098///
7099/// Note that the mean value/sigma is computed using the bins in the currently
7100/// defined range (see TAxis::SetRange). By default the range includes
7101/// all bins from 1 to nbins included, excluding underflows and overflows.
7102/// To force the underflows and overflows in the computation, one must
7103/// call the static function TH1::StatOverflows(kTRUE) before filling
7104/// the histogram.
7105
7106Double_t TH1::GetStdDev(Int_t axis) const
7107{
7108 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7109
7110 Double_t x, stddev2, stats[kNstat];
7111 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7112 GetStats(stats);
7113 if (stats[0] == 0) return 0;
7114 Int_t ax[3] = {2,4,7};
7115 Int_t axm = ax[axis%10 - 1];
7116 x = stats[axm]/stats[0];
7117 stddev2 = TMath::Abs(stats[axm+1]/stats[0] -x*x);
7118 if (axis<10)
7119 return TMath::Sqrt(stddev2);
7120 else {
7121 // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7122 // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7124 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7125 }
7126}
7127
7128////////////////////////////////////////////////////////////////////////////////
7129/// Return error of standard deviation estimation for Normal distribution
7130///
7131/// Note that the mean value/StdDev is computed using the bins in the currently
7132/// defined range (see TAxis::SetRange). By default the range includes
7133/// all bins from 1 to nbins included, excluding underflows and overflows.
7134/// To force the underflows and overflows in the computation, one must
7135/// call the static function TH1::StatOverflows(kTRUE) before filling
7136/// the histogram.
7137///
7138/// Value returned is standard deviation of sample standard deviation.
7139/// Note that it is an approximated value which is valid only in the case that the
7140/// original data distribution is Normal. The correct one would require
7141/// the 4-th momentum value, which cannot be accurately estimated from an histogram since
7142/// the x-information for all entries is not kept.
7143
7145{
7146 return GetStdDev(axis+10);
7147}
7148
7149////////////////////////////////////////////////////////////////////////////////
7150/// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7151/// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7152/// of the histogram along x, y or z axis
7153///
7154///Note, that since third and fourth moment are not calculated
7155///at the fill time, skewness and its standard error are computed bin by bin
7156
7158{
7159
7160 if (axis > 0 && axis <= 3){
7161
7162 Double_t mean = GetMean(axis);
7163 Double_t stddev = GetStdDev(axis);
7164 Double_t stddev3 = stddev*stddev*stddev;
7165
7166 Int_t firstBinX = fXaxis.GetFirst();
7167 Int_t lastBinX = fXaxis.GetLast();
7168 Int_t firstBinY = fYaxis.GetFirst();
7169 Int_t lastBinY = fYaxis.GetLast();
7170 Int_t firstBinZ = fZaxis.GetFirst();
7171 Int_t lastBinZ = fZaxis.GetLast();
7172 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7175 if (firstBinX == 1) firstBinX = 0;
7176 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7177 }
7179 if (firstBinY == 1) firstBinY = 0;
7180 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7181 }
7183 if (firstBinZ == 1) firstBinZ = 0;
7184 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7185 }
7186 }
7187
7188 Double_t x = 0;
7189 Double_t sum=0;
7190 Double_t np=0;
7191 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7192 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7193 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7194 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7195 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7196 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7197 Double_t w = GetBinContent(binx,biny,binz);
7198 np+=w;
7199 sum+=w*(x-mean)*(x-mean)*(x-mean);
7200 }
7201 }
7202 }
7203 sum/=np*stddev3;
7204 return sum;
7205 }
7206 else if (axis > 10 && axis <= 13) {
7207 //compute standard error of skewness
7208 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7210 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7211 }
7212 else {
7213 Error("GetSkewness", "illegal value of parameter");
7214 return 0;
7215 }
7216}
7217
7218////////////////////////////////////////////////////////////////////////////////
7219/// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7220/// Kurtosis(gaussian(0, 1)) = 0.
7221/// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7222/// of the histogram along x, y or z axis
7223////
7224/// Note, that since third and fourth moment are not calculated
7225/// at the fill time, kurtosis and its standard error are computed bin by bin
7226
7228{
7229 if (axis > 0 && axis <= 3){
7230
7231 Double_t mean = GetMean(axis);
7232 Double_t stddev = GetStdDev(axis);
7233 Double_t stddev4 = stddev*stddev*stddev*stddev;
7234
7235 Int_t firstBinX = fXaxis.GetFirst();
7236 Int_t lastBinX = fXaxis.GetLast();
7237 Int_t firstBinY = fYaxis.GetFirst();
7238 Int_t lastBinY = fYaxis.GetLast();
7239 Int_t firstBinZ = fZaxis.GetFirst();
7240 Int_t lastBinZ = fZaxis.GetLast();
7241 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7244 if (firstBinX == 1) firstBinX = 0;
7245 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7246 }
7248 if (firstBinY == 1) firstBinY = 0;
7249 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7250 }
7252 if (firstBinZ == 1) firstBinZ = 0;
7253 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7254 }
7255 }
7256
7257 Double_t x = 0;
7258 Double_t sum=0;
7259 Double_t np=0;
7260 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7261 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7262 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7263 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7264 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7265 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7266 Double_t w = GetBinContent(binx,biny,binz);
7267 np+=w;
7268 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7269 }
7270 }
7271 }
7272 sum/=(np*stddev4);
7273 return sum-3;
7274
7275 } else if (axis > 10 && axis <= 13) {
7276 //compute standard error of skewness
7277 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7279 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7280 }
7281 else {
7282 Error("GetKurtosis", "illegal value of parameter");
7283 return 0;
7284 }
7285}
7286
7287////////////////////////////////////////////////////////////////////////////////
7288/// fill the array stats from the contents of this histogram
7289/// The array stats must be correctly dimensioned in the calling program.
7290///
7291/// ~~~ {.cpp}
7292/// stats[0] = sumw
7293/// stats[1] = sumw2
7294/// stats[2] = sumwx
7295/// stats[3] = sumwx2
7296/// ~~~
7297///
7298/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7299/// is simply a copy of the statistics quantities computed at filling time.
7300/// If a sub-range is specified, the function recomputes these quantities
7301/// from the bin contents in the current axis range.
7302///
7303/// Note that the mean value/StdDev is computed using the bins in the currently
7304/// defined range (see TAxis::SetRange). By default the range includes
7305/// all bins from 1 to nbins included, excluding underflows and overflows.
7306/// To force the underflows and overflows in the computation, one must
7307/// call the static function TH1::StatOverflows(kTRUE) before filling
7308/// the histogram.
7309
7310void TH1::GetStats(Double_t *stats) const
7311{
7312 if (fBuffer) ((TH1*)this)->BufferEmpty();
7313
7314 // Loop on bins (possibly including underflows/overflows)
7315 Int_t bin, binx;
7316 Double_t w,err;
7317 Double_t x;
7318 // identify the case of labels with extension of axis range
7319 // in this case the statistics in x does not make any sense
7320 Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && CanExtendAllAxes() );
7321 // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7322 if ((fTsumw == 0 && fEntries > 0) || ( fXaxis.TestBit(TAxis::kAxisRange) && !labelHist) ) {
7323 for (bin=0;bin<4;bin++) stats[bin] = 0;
7324
7325 Int_t firstBinX = fXaxis.GetFirst();
7326 Int_t lastBinX = fXaxis.GetLast();
7327 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7329 if (firstBinX == 1) firstBinX = 0;
7330 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7331 }
7332 for (binx = firstBinX; binx <= lastBinX; binx++) {
7333 x = fXaxis.GetBinCenter(binx);
7334 //w = TMath::Abs(RetrieveBinContent(binx));
7335 // not sure what to do here if w < 0
7336 w = RetrieveBinContent(binx);
7337 err = TMath::Abs(GetBinError(binx));
7338 stats[0] += w;
7339 stats[1] += err*err;
7340 // statistics in x makes sense only for not labels histograms
7341 if (!labelHist) {
7342 stats[2] += w*x;
7343 stats[3] += w*x*x;
7344 }
7345 }
7346 // if (stats[0] < 0) {
7347 // // in case total is negative do something ??
7348 // stats[0] = 0;
7349 // }
7350 } else {
7351 stats[0] = fTsumw;
7352 stats[1] = fTsumw2;
7353 stats[2] = fTsumwx;
7354 stats[3] = fTsumwx2;
7355 }
7356}
7357
7358////////////////////////////////////////////////////////////////////////////////
7359/// Replace current statistics with the values in array stats
7360
7361void TH1::PutStats(Double_t *stats)
7362{
7363 fTsumw = stats[0];
7364 fTsumw2 = stats[1];
7365 fTsumwx = stats[2];
7366 fTsumwx2 = stats[3];
7367}
7368
7369////////////////////////////////////////////////////////////////////////////////
7370/// Reset the statistics including the number of entries
7371/// and replace with values calculates from bin content
7372///
7373/// The number of entries is set to the total bin content or (in case of weighted histogram)
7374/// to number of effective entries
7375
7376void TH1::ResetStats()
7377{
7378 Double_t stats[kNstat] = {0};
7379 fTsumw = 0;
7380 fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
7381 GetStats(stats);
7382 PutStats(stats);
7384 // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
7385 if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
7386}
7387
7388////////////////////////////////////////////////////////////////////////////////
7389/// Return the sum of weights excluding under/overflows.
7390
7392{
7393 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7394
7395 Int_t bin,binx,biny,binz;
7396 Double_t sum =0;
7397 for(binz=1; binz<=fZaxis.GetNbins(); binz++) {
7398 for(biny=1; biny<=fYaxis.GetNbins(); biny++) {
7399 for(binx=1; binx<=fXaxis.GetNbins(); binx++) {
7400 bin = GetBin(binx,biny,binz);
7401 sum += RetrieveBinContent(bin);
7402 }
7403 }
7404 }
7405 return sum;
7406}
7407
7408////////////////////////////////////////////////////////////////////////////////
7409///Return integral of bin contents. Only bins in the bins range are considered.
7410///
7411/// By default the integral is computed as the sum of bin contents in the range.
7412/// if option "width" is specified, the integral is the sum of
7413/// the bin contents multiplied by the bin width in x.
7414
7415Double_t TH1::Integral(Option_t *option) const
7416{
7417 return Integral(fXaxis.GetFirst(),fXaxis.GetLast(),option);
7418}
7419
7420////////////////////////////////////////////////////////////////////////////////
7421/// Return integral of bin contents in range [binx1,binx2].
7422///
7423/// By default the integral is computed as the sum of bin contents in the range.
7424/// if option "width" is specified, the integral is the sum of
7425/// the bin contents multiplied by the bin width in x.
7426
7427Double_t TH1::Integral(Int_t binx1, Int_t binx2, Option_t *option) const
7428{
7429 double err = 0;
7430 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
7431}
7432
7433////////////////////////////////////////////////////////////////////////////////
7434/// Return integral of bin contents in range [binx1,binx2] and its error.
7435///
7436/// By default the integral is computed as the sum of bin contents in the range.
7437/// if option "width" is specified, the integral is the sum of
7438/// the bin contents multiplied by the bin width in x.
7439/// the error is computed using error propagation from the bin errors assuming that
7440/// all the bins are uncorrelated
7441
7442Double_t TH1::IntegralAndError(Int_t binx1, Int_t binx2, Double_t & error, Option_t *option) const
7443{
7444 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
7445}
7446
7447////////////////////////////////////////////////////////////////////////////////
7448/// Internal function compute integral and optionally the error between the limits
7449/// specified by the bin number values working for all histograms (1D, 2D and 3D)
7450
7451Double_t TH1::DoIntegral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error ,
7452 Option_t *option, Bool_t doError) const
7453{
7454 if (fBuffer) ((TH1*)this)->BufferEmpty();
7455
7456 Int_t nx = GetNbinsX() + 2;
7457 if (binx1 < 0) binx1 = 0;
7458 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
7459
7460 if (GetDimension() > 1) {
7461 Int_t ny = GetNbinsY() + 2;
7462 if (biny1 < 0) biny1 = 0;
7463 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
7464 } else {
7465 biny1 = 0; biny2 = 0;
7466 }
7467
7468 if (GetDimension() > 2) {
7469 Int_t nz = GetNbinsZ() + 2;
7470 if (binz1 < 0) binz1 = 0;
7471 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
7472 } else {
7473 binz1 = 0; binz2 = 0;
7474 }
7475
7476 // - Loop on bins in specified range
7477 TString opt = option;
7478 opt.ToLower();
7480 if (opt.Contains("width")) width = kTRUE;
7481
7482
7483 Double_t dx = 1., dy = .1, dz =.1;
7484 Double_t integral = 0;
7485 Double_t igerr2 = 0;
7486 for (Int_t binx = binx1; binx <= binx2; ++binx) {
7487 if (width) dx = fXaxis.GetBinWidth(binx);
7488 for (Int_t biny = biny1; biny <= biny2; ++biny) {
7489 if (width) dy = fYaxis.GetBinWidth(biny);
7490 for (Int_t binz = binz1; binz <= binz2; ++binz) {
7491 Int_t bin = GetBin(binx, biny, binz);
7492 Double_t dv = 0.0;
7493 if (width) {
7494 dz = fZaxis.GetBinWidth(binz);
7495 dv = dx * dy * dz;
7496 integral += RetrieveBinContent(bin) * dv;
7497 } else {
7498 integral += RetrieveBinContent(bin);
7499 }
7500 if (doError) {
7501 if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
7502 else igerr2 += GetBinErrorSqUnchecked(bin);
7503 }
7504 }
7505 }
7506 }
7507
7508 if (doError) error = TMath::Sqrt(igerr2);
7509 return integral;
7510}
7511
7512////////////////////////////////////////////////////////////////////////////////
7513/// Statistical test of compatibility in shape between
7514/// this histogram and h2, using the Anderson-Darling 2 sample test.
7515///
7516/// The AD 2 sample test formula are derived from the paper
7517/// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
7518///
7519/// The test is implemented in root in the ROOT::Math::GoFTest class
7520/// It is the same formula ( (6) in the paper), and also shown in
7521/// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
7522///
7523/// Binned data are considered as un-binned data
7524/// with identical observation happening in the bin center.
7525///
7526/// \param[in] option is a character string to specify options
7527/// - "D" Put out a line of "Debug" printout
7528/// - "T" Return the normalized A-D test statistic
7529///
7530/// - Note1: Underflow and overflow are not considered in the test
7531/// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
7532/// - Note3: The histograms are not required to have the same X axis
7533/// - Note4: The test works only for 1-dimensional histograms
7534
7535Double_t TH1::AndersonDarlingTest(const TH1 *h2, Option_t *option) const
7536{
7537 Double_t advalue = 0;
7538 Double_t pvalue = AndersonDarlingTest(h2, advalue);
7539
7540 TString opt = option;
7541 opt.ToUpper();
7542 if (opt.Contains("D") ) {
7543 printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
7544 }
7545 if (opt.Contains("T") ) return advalue;
7546
7547 return pvalue;
7548}
7549
7550////////////////////////////////////////////////////////////////////////////////
7551/// Same function as above but returning also the test statistic value
7552
7553Double_t TH1::AndersonDarlingTest(const TH1 *h2, Double_t & advalue) const
7554{
7555 if (GetDimension() != 1 || h2->GetDimension() != 1) {
7556 Error("AndersonDarlingTest","Histograms must be 1-D");
7557 return -1;
7558 }
7559
7560 // empty the buffer. Probably we could add as an unbinned test
7561 if (fBuffer) ((TH1*)this)->BufferEmpty();
7562
7563 // use the BinData class
7564 ROOT::Fit::BinData data1;
7565 ROOT::Fit::BinData data2;
7566
7567 ROOT::Fit::FillData(data1, this, 0);
7568 ROOT::Fit::FillData(data2, h2, 0);
7569
7570 double pvalue;
7571 ROOT::Math::GoFTest::AndersonDarling2SamplesTest(data1,data2, pvalue,advalue);
7572
7573 return pvalue;
7574}
7575
7576////////////////////////////////////////////////////////////////////////////////
7577/// Statistical test of compatibility in shape between
7578/// this histogram and h2, using Kolmogorov test.
7579/// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
7580/// and not for binned data as in the case of the histogram (see NOTE 3 below).
7581/// So, before using this method blindly, read the NOTE 3.
7582///
7583/// Default: Ignore under- and overflow bins in comparison
7584///
7585/// \param[in] h2 histogram
7586/// \param[in] option is a character string to specify options
7587/// - "U" include Underflows in test (also for 2-dim)
7588/// - "O" include Overflows (also valid for 2-dim)
7589/// - "N" include comparison of normalizations
7590/// - "D" Put out a line of "Debug" printout
7591/// - "M" Return the Maximum Kolmogorov distance instead of prob
7592/// - "X" Run the pseudo experiments post-processor with the following procedure:
7593/// make pseudoexperiments based on random values from the parent distribution,
7594/// compare the KS distance of the pseudoexperiment to the parent
7595/// distribution, and count all the KS values above the value
7596/// obtained from the original data to Monte Carlo distribution.
7597/// The number of pseudo-experiments nEXPT is currently fixed at 1000.
7598/// The function returns the probability.
7599/// (thanks to Ben Kilminster to submit this procedure). Note that
7600/// this option "X" is much slower.
7601///
7602/// The returned function value is the probability of test
7603/// (much less than one means NOT compatible)
7604///
7605/// Code adapted by Rene Brun from original HBOOK routine HDIFF
7606///
7607/// NOTE1
7608/// A good description of the Kolmogorov test can be seen at:
7609/// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
7610///
7611/// NOTE2
7612/// see also alternative function TH1::Chi2Test
7613/// The Kolmogorov test is assumed to give better results than Chi2Test
7614/// in case of histograms with low statistics.
7615///
7616/// NOTE3 (Jan Conrad, Fred James)
7617/// "The returned value PROB is calculated such that it will be
7618/// uniformly distributed between zero and one for compatible histograms,
7619/// provided the data are not binned (or the number of bins is very large
7620/// compared with the number of events). Users who have access to unbinned
7621/// data and wish exact confidence levels should therefore not put their data
7622/// into histograms, but should call directly TMath::KolmogorovTest. On
7623/// the other hand, since TH1 is a convenient way of collecting data and
7624/// saving space, this function has been provided. However, the values of
7625/// PROB for binned data will be shifted slightly higher than expected,
7626/// depending on the effects of the binning. For example, when comparing two
7627/// uniform distributions of 500 events in 100 bins, the values of PROB,
7628/// instead of being exactly uniformly distributed between zero and one, have
7629/// a mean value of about 0.56. We can apply a useful
7630/// rule: As long as the bin width is small compared with any significant
7631/// physical effect (for example the experimental resolution) then the binning
7632/// cannot have an important effect. Therefore, we believe that for all
7633/// practical purposes, the probability value PROB is calculated correctly
7634/// provided the user is aware that:
7635///
7636/// 1. The value of PROB should not be expected to have exactly the correct
7637/// distribution for binned data.
7638/// 2. The user is responsible for seeing to it that the bin widths are
7639/// small compared with any physical phenomena of interest.
7640/// 3. The effect of binning (if any) is always to make the value of PROB
7641/// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
7642/// will assure that at most 5% of truly compatible histograms are rejected,
7643/// and usually somewhat less."
7644///
7645/// Note also that for GoF test of unbinned data ROOT provides also the class
7646/// ROOT::Math::GoFTest. The class has also method for doing one sample tests
7647/// (i.e. comparing the data with a given distribution).
7648
7649Double_t TH1::KolmogorovTest(const TH1 *h2, Option_t *option) const
7650{
7651 TString opt = option;
7652 opt.ToUpper();
7653
7654 Double_t prob = 0;
7655 TH1 *h1 = (TH1*)this;
7656 if (h2 == 0) return 0;
7657 const TAxis *axis1 = h1->GetXaxis();
7658 const TAxis *axis2 = h2->GetXaxis();
7659 Int_t ncx1 = axis1->GetNbins();
7660 Int_t ncx2 = axis2->GetNbins();
7661
7662 // Check consistency of dimensions
7663 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
7664 Error("KolmogorovTest","Histograms must be 1-D\n");
7665 return 0;
7666 }
7667
7668 // Check consistency in number of channels
7669 if (ncx1 != ncx2) {
7670 Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
7671 return 0;
7672 }
7673
7674 // empty the buffer. Probably we could add as an unbinned test
7675 if (fBuffer) ((TH1*)this)->BufferEmpty();
7676
7677 // Check consistency in bin edges
7678 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
7679 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
7680 Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
7681 return 0;
7682 }
7683 }
7684
7685 Bool_t afunc1 = kFALSE;
7686 Bool_t afunc2 = kFALSE;
7687 Double_t sum1 = 0, sum2 = 0;
7688 Double_t ew1, ew2, w1 = 0, w2 = 0;
7689 Int_t bin;
7690 Int_t ifirst = 1;
7691 Int_t ilast = ncx1;
7692 // integral of all bins (use underflow/overflow if option)
7693 if (opt.Contains("U")) ifirst = 0;
7694 if (opt.Contains("O")) ilast = ncx1 +1;
7695 for (bin = ifirst; bin <= ilast; bin++) {
7696 sum1 += h1->RetrieveBinContent(bin);
7697 sum2 += h2->RetrieveBinContent(bin);
7698 ew1 = h1->GetBinError(bin);
7699 ew2 = h2->GetBinError(bin);
7700 w1 += ew1*ew1;
7701 w2 += ew2*ew2;
7702 }
7703 if (sum1 == 0) {
7704 Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
7705 return 0;
7706 }
7707 if (sum2 == 0) {
7708 Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
7709 return 0;
7710 }
7711
7712 // calculate the effective entries.
7713 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
7714 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
7715 Double_t esum1 = 0, esum2 = 0;
7716 if (w1 > 0)
7717 esum1 = sum1 * sum1 / w1;
7718 else
7719 afunc1 = kTRUE; // use later for calculating z
7720
7721 if (w2 > 0)
7722 esum2 = sum2 * sum2 / w2;
7723 else
7724 afunc2 = kTRUE; // use later for calculating z
7725
7726 if (afunc2 && afunc1) {
7727 Error("KolmogorovTest","Errors are zero for both histograms\n");
7728 return 0;
7729 }
7730
7731
7732 Double_t s1 = 1/sum1;
7733 Double_t s2 = 1/sum2;
7734
7735 // Find largest difference for Kolmogorov Test
7736 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
7737
7738 for (bin=ifirst;bin<=ilast;bin++) {
7739 rsum1 += s1*h1->RetrieveBinContent(bin);
7740 rsum2 += s2*h2->RetrieveBinContent(bin);
7741 dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
7742 }
7743
7744 // Get Kolmogorov probability
7745 Double_t z, prb1=0, prb2=0, prb3=0;
7746
7747 // case h1 is exact (has zero errors)
7748 if (afunc1)
7749 z = dfmax*TMath::Sqrt(esum2);
7750 // case h2 has zero errors
7751 else if (afunc2)
7752 z = dfmax*TMath::Sqrt(esum1);
7753 else
7754 // for comparison between two data sets
7755 z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
7756
7757 prob = TMath::KolmogorovProb(z);
7758
7759 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
7760 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
7761 // Combine probabilities for shape and normalization,
7762 prb1 = prob;
7763 Double_t d12 = esum1-esum2;
7764 Double_t chi2 = d12*d12/(esum1+esum2);
7765 prb2 = TMath::Prob(chi2,1);
7766 // see Eadie et al., section 11.6.2
7767 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
7768 else prob = 0;
7769 }
7770 // X option. Pseudo-experiments post-processor to determine KS probability
7771 const Int_t nEXPT = 1000;
7772 if (opt.Contains("X") && !(afunc1 || afunc2 ) ) {
7773 Double_t dSEXPT;
7774 TH1 *h1_cpy = (TH1 *)(gDirectory ? gDirectory->CloneObject(this, kFALSE) : gROOT->CloneObject(this, kFALSE));
7775 TH1 *hExpt = (TH1*)(gDirectory ? gDirectory->CloneObject(this,kFALSE) : gROOT->CloneObject(this,kFALSE));
7776
7777 if (h1_cpy->GetMinimum() < 0.0) {
7778 // With negative bins we can't draw random samples in a meaningful way.
7779 Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
7780 "skewed. Reduce number of bins for histogram?");
7781 while (h1_cpy->GetMinimum() < 0.0) {
7782 Int_t idx = h1_cpy->GetMinimumBin();
7783 h1_cpy->SetBinContent(idx, 0.0);
7784 }
7785 }
7786
7787 // make nEXPT experiments (this should be a parameter)
7788 prb3 = 0;
7789 for (Int_t i=0; i < nEXPT; i++) {
7790 hExpt->Reset();
7791 hExpt->FillRandom(h1_cpy, (Int_t)esum2);
7792 dSEXPT = KolmogorovTest(hExpt,"M");
7793 if (dSEXPT>dfmax) prb3 += 1.0;
7794 }
7795 prb3 /= (Double_t)nEXPT;
7796 delete h1_cpy;
7797 delete hExpt;
7798 }
7799
7800 // debug printout
7801 if (opt.Contains("D")) {
7802 printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
7803 printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
7804 printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
7805 if (opt.Contains("N"))
7806 printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
7807 if (opt.Contains("X"))
7808 printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
7809 }
7810 // This numerical error condition should never occur:
7811 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
7812 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
7813
7814 if(opt.Contains("M")) return dfmax;
7815 else if(opt.Contains("X")) return prb3;
7816 else return prob;
7817}
7818
7819////////////////////////////////////////////////////////////////////////////////
7820/// Replace bin contents by the contents of array content
7821
7822void TH1::SetContent(const Double_t *content)
7823{
7824 fEntries = fNcells;
7825 fTsumw = 0;
7826 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
7827}
7828
7829////////////////////////////////////////////////////////////////////////////////
7830/// Return contour values into array levels if pointer levels is non zero.
7831///
7832/// The function returns the number of contour levels.
7833/// see GetContourLevel to return one contour only
7834
7836{
7837 Int_t nlevels = fContour.fN;
7838 if (levels) {
7839 if (nlevels == 0) {
7840 nlevels = 20;
7841 SetContour(nlevels);
7842 } else {
7843 if (TestBit(kUserContour) == 0) SetContour(nlevels);
7844 }
7845 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
7846 }
7847 return nlevels;
7848}
7849
7850////////////////////////////////////////////////////////////////////////////////
7851/// Return value of contour number level.
7852/// Use GetContour to return the array of all contour levels
7853
7855{
7856 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
7857}
7858
7859////////////////////////////////////////////////////////////////////////////////
7860/// Return the value of contour number "level" in Pad coordinates.
7861/// ie: if the Pad is in log scale along Z it returns le log of the contour level
7862/// value. See GetContour to return the array of all contour levels
7863
7865{
7866 if (level <0 || level >= fContour.fN) return 0;
7867 Double_t zlevel = fContour.fArray[level];
7868
7869 // In case of user defined contours and Pad in log scale along Z,
7870 // fContour.fArray doesn't contain the log of the contour whereas it does
7871 // in case of equidistant contours.
7872 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
7873 if (zlevel <= 0) return 0;
7874 zlevel = TMath::Log10(zlevel);
7875 }
7876 return zlevel;
7877}
7878
7879////////////////////////////////////////////////////////////////////////////////
7880/// Set the maximum number of entries to be kept in the buffer.
7881
7882void TH1::SetBuffer(Int_t buffersize, Option_t * /*option*/)
7883{
7884 if (fBuffer) {
7885 BufferEmpty();
7886 delete [] fBuffer;
7887 fBuffer = 0;
7888 }
7889 if (buffersize <= 0) {
7890 fBufferSize = 0;
7891 return;
7892 }
7893 if (buffersize < 100) buffersize = 100;
7894 fBufferSize = 1 + buffersize*(fDimension+1);
7896 memset(fBuffer,0,sizeof(Double_t)*fBufferSize);
7897}
7898
7899////////////////////////////////////////////////////////////////////////////////
7900/// Set the number and values of contour levels.
7901///
7902/// By default the number of contour levels is set to 20. The contours values
7903/// in the array "levels" should be specified in increasing order.
7904///
7905/// if argument levels = 0 or missing, equidistant contours are computed
7906
7907void TH1::SetContour(Int_t nlevels, const Double_t *levels)
7908{
7909 Int_t level;
7911 if (nlevels <=0 ) {
7912 fContour.Set(0);
7913 return;
7914 }
7915 fContour.Set(nlevels);
7916
7917 // - Contour levels are specified
7918 if (levels) {
7920 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
7921 } else {
7922 // - contour levels are computed automatically as equidistant contours
7923 Double_t zmin = GetMinimum();
7924 Double_t zmax = GetMaximum();
7925 if ((zmin == zmax) && (zmin != 0)) {
7926 zmax += 0.01*TMath::Abs(zmax);
7927 zmin -= 0.01*TMath::Abs(zmin);
7928 }
7929 Double_t dz = (zmax-zmin)/Double_t(nlevels);
7930 if (gPad && gPad->GetLogz()) {
7931 if (zmax <= 0) return;
7932 if (zmin <= 0) zmin = 0.001*zmax;
7933 zmin = TMath::Log10(zmin);
7934 zmax = TMath::Log10(zmax);
7935 dz = (zmax-zmin)/Double_t(nlevels);
7936 }
7937 for (level=0; level<nlevels; level++) {
7938 fContour.fArray[level] = zmin + dz*Double_t(level);
7939 }
7940 }
7941}
7942
7943////////////////////////////////////////////////////////////////////////////////
7944/// Set value for one contour level.
7945
7946void TH1::SetContourLevel(Int_t level, Double_t value)
7947{
7948 if (level < 0 || level >= fContour.fN) return;
7950 fContour.fArray[level] = value;
7951}
7952
7953////////////////////////////////////////////////////////////////////////////////
7954/// Return maximum value smaller than maxval of bins in the range,
7955/// unless the value has been overridden by TH1::SetMaximum,
7956/// in which case it returns that value. (This happens, for example,
7957/// when the histogram is drawn and the y or z axis limits are changed
7958///
7959/// To get the maximum value of bins in the histogram regardless of
7960/// whether the value has been overridden, use
7961///
7962/// ~~~ {.cpp}
7963/// h->GetBinContent(h->GetMaximumBin())
7964/// ~~~
7965
7966Double_t TH1::GetMaximum(Double_t maxval) const
7967{
7968 if (fMaximum != -1111) return fMaximum;
7969
7970 // empty the buffer
7971 if (fBuffer) ((TH1*)this)->BufferEmpty();
7972
7973 Int_t bin, binx, biny, binz;
7974 Int_t xfirst = fXaxis.GetFirst();
7975 Int_t xlast = fXaxis.GetLast();
7976 Int_t yfirst = fYaxis.GetFirst();
7977 Int_t ylast = fYaxis.GetLast();
7978 Int_t zfirst = fZaxis.GetFirst();
7979 Int_t zlast = fZaxis.GetLast();
7980 Double_t maximum = -FLT_MAX, value;
7981 for (binz=zfirst;binz<=zlast;binz++) {
7982 for (biny=yfirst;biny<=ylast;biny++) {
7983 for (binx=xfirst;binx<=xlast;binx++) {
7984 bin = GetBin(binx,biny,binz);
7985 value = RetrieveBinContent(bin);
7986 if (value > maximum && value < maxval) maximum = value;
7987 }
7988 }
7989 }
7990 return maximum;
7991}
7992
7993////////////////////////////////////////////////////////////////////////////////
7994/// Return location of bin with maximum value in the range.
7995
7997{
7998 Int_t locmax, locmay, locmaz;
7999 return GetMaximumBin(locmax, locmay, locmaz);
8000}
8001
8002////////////////////////////////////////////////////////////////////////////////
8003/// Return location of bin with maximum value in the range.
8004
8005Int_t TH1::GetMaximumBin(Int_t &locmax, Int_t &locmay, Int_t &locmaz) const
8006{
8007 // empty the buffer
8008 if (fBuffer) ((TH1*)this)->BufferEmpty();
8009
8010 Int_t bin, binx, biny, binz;
8011 Int_t locm;
8012 Int_t xfirst = fXaxis.GetFirst();
8013 Int_t xlast = fXaxis.GetLast();
8014 Int_t yfirst = fYaxis.GetFirst();
8015 Int_t ylast = fYaxis.GetLast();
8016 Int_t zfirst = fZaxis.GetFirst();
8017 Int_t zlast = fZaxis.GetLast();
8018 Double_t maximum = -FLT_MAX, value;
8019 locm = locmax = locmay = locmaz = 0;
8020 for (binz=zfirst;binz<=zlast;binz++) {
8021 for (biny=yfirst;biny<=ylast;biny++) {
8022 for (binx=xfirst;binx<=xlast;binx++) {
8023 bin = GetBin(binx,biny,binz);
8024 value = RetrieveBinContent(bin);
8025 if (value > maximum) {
8026 maximum = value;
8027 locm = bin;
8028 locmax = binx;
8029 locmay = biny;
8030 locmaz = binz;
8031 }
8032 }
8033 }
8034 }
8035 return locm;
8036}
8037
8038////////////////////////////////////////////////////////////////////////////////
8039/// Return minimum value larger than minval of bins in the range,
8040/// unless the value has been overridden by TH1::SetMinimum,
8041/// in which case it returns that value. (This happens, for example,
8042/// when the histogram is drawn and the y or z axis limits are changed
8043///
8044/// To get the minimum value of bins in the histogram regardless of
8045/// whether the value has been overridden, use
8046///
8047/// ~~~ {.cpp}
8048/// h->GetBinContent(h->GetMinimumBin())
8049/// ~~~
8050
8051Double_t TH1::GetMinimum(Double_t minval) const
8052{
8053 if (fMinimum != -1111) return fMinimum;
8054
8055 // empty the buffer
8056 if (fBuffer) ((TH1*)this)->BufferEmpty();
8057
8058 Int_t bin, binx, biny, binz;
8059 Int_t xfirst = fXaxis.GetFirst();
8060 Int_t xlast = fXaxis.GetLast();
8061 Int_t yfirst = fYaxis.GetFirst();
8062 Int_t ylast = fYaxis.GetLast();
8063 Int_t zfirst = fZaxis.GetFirst();
8064 Int_t zlast = fZaxis.GetLast();
8065 Double_t minimum=FLT_MAX, value;
8066 for (binz=zfirst;binz<=zlast;binz++) {
8067 for (biny=yfirst;biny<=ylast;biny++) {
8068 for (binx=xfirst;binx<=xlast;binx++) {
8069 bin = GetBin(binx,biny,binz);
8070 value = RetrieveBinContent(bin);
8071 if (value < minimum && value > minval) minimum = value;
8072 }
8073 }
8074 }
8075 return minimum;
8076}
8077
8078////////////////////////////////////////////////////////////////////////////////
8079/// Return location of bin with minimum value in the range.
8080
8082{
8083 Int_t locmix, locmiy, locmiz;
8084 return GetMinimumBin(locmix, locmiy, locmiz);
8085}
8086
8087////////////////////////////////////////////////////////////////////////////////
8088/// Return location of bin with minimum value in the range.
8089
8090Int_t TH1::GetMinimumBin(Int_t &locmix, Int_t &locmiy, Int_t &locmiz) const
8091{
8092 // empty the buffer
8093 if (fBuffer) ((TH1*)this)->BufferEmpty();
8094
8095 Int_t bin, binx, biny, binz;
8096 Int_t locm;
8097 Int_t xfirst = fXaxis.GetFirst();
8098 Int_t xlast = fXaxis.GetLast();
8099 Int_t yfirst = fYaxis.GetFirst();
8100 Int_t ylast = fYaxis.GetLast();
8101 Int_t zfirst = fZaxis.GetFirst();
8102 Int_t zlast = fZaxis.GetLast();
8103 Double_t minimum = FLT_MAX, value;
8104 locm = locmix = locmiy = locmiz = 0;
8105 for (binz=zfirst;binz<=zlast;binz++) {
8106 for (biny=yfirst;biny<=ylast;biny++) {
8107 for (binx=xfirst;binx<=xlast;binx++) {
8108 bin = GetBin(binx,biny,binz);
8109 value = RetrieveBinContent(bin);
8110 if (value < minimum) {
8111 minimum = value;
8112 locm = bin;
8113 locmix = binx;
8114 locmiy = biny;
8115 locmiz = binz;
8116 }
8117 }
8118 }
8119 }
8120 return locm;
8121}
8122
8123///////////////////////////////////////////////////////////////////////////////
8124/// Retrieve the minimum and maximum values in the histogram
8125///
8126/// This will not return a cached value and will always search the
8127/// histogram for the min and max values. The user can condition whether
8128/// or not to call this with the GetMinimumStored() and GetMaximumStored()
8129/// methods. If the cache is empty, then the value will be -1111. Users
8130/// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8131/// For example, the following recipe will make efficient use of this method
8132/// and the cached minimum and maximum values.
8133//
8134/// \code{.cpp}
8135/// Double_t currentMin = pHist->GetMinimumStored();
8136/// Double_t currentMax = pHist->GetMaximumStored();
8137/// if ((currentMin == -1111) || (currentMax == -1111)) {
8138/// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8139/// pHist->SetMinimum(currentMin);
8140/// pHist->SetMaximum(currentMax);
8141/// }
8142/// \endcode
8143///
8144/// \param min reference to variable that will hold found minimum value
8145/// \param max reference to variable that will hold found maximum value
8146
8147void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8148{
8149 // empty the buffer
8150 if (fBuffer) ((TH1*)this)->BufferEmpty();
8151
8152 Int_t bin, binx, biny, binz;
8153 Int_t xfirst = fXaxis.GetFirst();
8154 Int_t xlast = fXaxis.GetLast();
8155 Int_t yfirst = fYaxis.GetFirst();
8156 Int_t ylast = fYaxis.GetLast();
8157 Int_t zfirst = fZaxis.GetFirst();
8158 Int_t zlast = fZaxis.GetLast();
8159 min=TMath::Infinity();
8160 max=-TMath::Infinity();
8161 Double_t value;
8162 for (binz=zfirst;binz<=zlast;binz++) {
8163 for (biny=yfirst;biny<=ylast;biny++) {
8164 for (binx=xfirst;binx<=xlast;binx++) {
8165 bin = GetBin(binx,biny,binz);
8166 value = RetrieveBinContent(bin);
8167 if (value < min) min = value;
8168 if (value > max) max = value;
8169 }
8170 }
8171 }
8172}
8173
8174////////////////////////////////////////////////////////////////////////////////
8175/// Redefine x axis parameters.
8176///
8177/// The X axis parameters are modified.
8178/// The bins content array is resized
8179/// if errors (Sumw2) the errors array is resized
8180/// The previous bin contents are lost
8181/// To change only the axis limits, see TAxis::SetRange
8182
8184{
8185 if (GetDimension() != 1) {
8186 Error("SetBins","Operation only valid for 1-d histograms");
8187 return;
8188 }
8189 fXaxis.SetRange(0,0);
8190 fXaxis.Set(nx,xmin,xmax);
8191 fYaxis.Set(1,0,1);
8192 fZaxis.Set(1,0,1);
8193 fNcells = nx+2;
8195 if (fSumw2.fN) {
8197 }
8198}
8199
8200////////////////////////////////////////////////////////////////////////////////
8201/// Redefine x axis parameters with variable bin sizes.
8202///
8203/// The X axis parameters are modified.
8204/// The bins content array is resized
8205/// if errors (Sumw2) the errors array is resized
8206/// The previous bin contents are lost
8207/// To change only the axis limits, see TAxis::SetRange
8208/// xBins is supposed to be of length nx+1
8209
8210void TH1::SetBins(Int_t nx, const Double_t *xBins)
8211{
8212 if (GetDimension() != 1) {
8213 Error("SetBins","Operation only valid for 1-d histograms");
8214 return;
8215 }
8216 fXaxis.SetRange(0,0);
8217 fXaxis.Set(nx,xBins);
8218 fYaxis.Set(1,0,1);
8219 fZaxis.Set(1,0,1);
8220 fNcells = nx+2;
8222 if (fSumw2.fN) {
8224 }
8225}
8226
8227////////////////////////////////////////////////////////////////////////////////
8228/// Redefine x and y axis parameters.
8229///
8230/// The X and Y axis parameters are modified.
8231/// The bins content array is resized
8232/// if errors (Sumw2) the errors array is resized
8233/// The previous bin contents are lost
8234/// To change only the axis limits, see TAxis::SetRange
8235
8237{
8238 if (GetDimension() != 2) {
8239 Error("SetBins","Operation only valid for 2-D histograms");
8240 return;
8241 }
8242 fXaxis.SetRange(0,0);
8243 fYaxis.SetRange(0,0);
8244 fXaxis.Set(nx,xmin,xmax);
8245 fYaxis.Set(ny,ymin,ymax);
8246 fZaxis.Set(1,0,1);
8247 fNcells = (nx+2)*(ny+2);
8249 if (fSumw2.fN) {
8251 }
8252}
8253
8254////////////////////////////////////////////////////////////////////////////////
8255/// Redefine x and y axis parameters with variable bin sizes.
8256///
8257/// The X and Y axis parameters are modified.
8258/// The bins content array is resized
8259/// if errors (Sumw2) the errors array is resized
8260/// The previous bin contents are lost
8261/// To change only the axis limits, see TAxis::SetRange
8262/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
8263
8264void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
8265{
8266 if (GetDimension() != 2) {
8267 Error("SetBins","Operation only valid for 2-D histograms");
8268 return;
8269 }
8270 fXaxis.SetRange(0,0);
8271 fYaxis.SetRange(0,0);
8272 fXaxis.Set(nx,xBins);
8273 fYaxis.Set(ny,yBins);
8274 fZaxis.Set(1,0,1);
8275 fNcells = (nx+2)*(ny+2);
8277 if (fSumw2.fN) {
8279 }
8280}
8281
8282////////////////////////////////////////////////////////////////////////////////
8283/// Redefine x, y and z axis parameters.
8284///
8285/// The X, Y and Z axis parameters are modified.
8286/// The bins content array is resized
8287/// if errors (Sumw2) the errors array is resized
8288/// The previous bin contents are lost
8289/// To change only the axis limits, see TAxis::SetRange
8290
8292{
8293 if (GetDimension() != 3) {
8294 Error("SetBins","Operation only valid for 3-D histograms");
8295 return;
8296 }
8297 fXaxis.SetRange(0,0);
8298 fYaxis.SetRange(0,0);
8299 fZaxis.SetRange(0,0);
8300 fXaxis.Set(nx,xmin,xmax);
8301 fYaxis.Set(ny,ymin,ymax);
8302 fZaxis.Set(nz,zmin,zmax);
8303 fNcells = (nx+2)*(ny+2)*(nz+2);
8305 if (fSumw2.fN) {
8307 }
8308}
8309
8310////////////////////////////////////////////////////////////////////////////////
8311/// Redefine x, y and z axis parameters with variable bin sizes.
8312///
8313/// The X, Y and Z axis parameters are modified.
8314/// The bins content array is resized
8315/// if errors (Sumw2) the errors array is resized
8316/// The previous bin contents are lost
8317/// To change only the axis limits, see TAxis::SetRange
8318/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
8319/// zBins is supposed to be of length nz+1
8320
8321void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
8322{
8323 if (GetDimension() != 3) {
8324 Error("SetBins","Operation only valid for 3-D histograms");
8325 return;
8326 }
8327 fXaxis.SetRange(0,0);
8328 fYaxis.SetRange(0,0);
8329 fZaxis.SetRange(0,0);
8330 fXaxis.Set(nx,xBins);
8331 fYaxis.Set(ny,yBins);
8332 fZaxis.Set(nz,zBins);
8333 fNcells = (nx+2)*(ny+2)*(nz+2);
8335 if (fSumw2.fN) {
8337 }
8338}
8339
8340////////////////////////////////////////////////////////////////////////////////
8341/// By default when an histogram is created, it is added to the list
8342/// of histogram objects in the current directory in memory.
8343/// Remove reference to this histogram from current directory and add
8344/// reference to new directory dir. dir can be 0 in which case the
8345/// histogram does not belong to any directory.
8346///
8347/// Note that the directory is not a real property of the histogram and
8348/// it will not be copied when the histogram is copied or cloned.
8349/// If the user wants to have the copied (cloned) histogram in the same
8350/// directory, he needs to set again the directory using SetDirectory to the
8351/// copied histograms
8352
8354{
8355 if (fDirectory == dir) return;
8356 if (fDirectory) fDirectory->Remove(this);
8357 fDirectory = dir;
8358 if (fDirectory) {
8360 fDirectory->Append(this);
8361 }
8362}
8363
8364////////////////////////////////////////////////////////////////////////////////
8365/// Replace bin errors by values in array error.
8366
8367void TH1::SetError(const Double_t *error)
8368{
8369 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
8370}
8371
8372////////////////////////////////////////////////////////////////////////////////
8373/// Change the name of this histogram
8375
8376void TH1::SetName(const char *name)
8377{
8378 // Histograms are named objects in a THashList.
8379 // We must update the hashlist if we change the name
8380 // We protect this operation
8382 if (fDirectory) fDirectory->Remove(this);
8383 fName = name;
8384 if (fDirectory) fDirectory->Append(this);
8385}
8386
8387////////////////////////////////////////////////////////////////////////////////
8388/// Change the name and title of this histogram
8389
8390void TH1::SetNameTitle(const char *name, const char *title)
8391{
8392 // Histograms are named objects in a THashList.
8393 // We must update the hashlist if we change the name
8394 SetName(name);
8395 SetTitle(title);
8396}
8397
8398////////////////////////////////////////////////////////////////////////////////
8399/// Set statistics option on/off
8400///
8401/// By default, the statistics box is drawn.
8402/// The paint options can be selected via gStyle->SetOptStats.
8403/// This function sets/resets the kNoStats bin in the histogram object.
8404/// It has priority over the Style option.
8405
8406void TH1::SetStats(Bool_t stats)
8407{
8409 if (!stats) {
8411 //remove the "stats" object from the list of functions
8412 if (fFunctions) {
8413 TObject *obj = fFunctions->FindObject("stats");
8414 if (obj) {
8415 fFunctions->Remove(obj);
8416 delete obj;
8417 }
8418 }
8419 }
8420}
8421
8422////////////////////////////////////////////////////////////////////////////////
8423/// Create structure to store sum of squares of weights.
8424///
8425/// if histogram is already filled, the sum of squares of weights
8426/// is filled with the existing bin contents
8427///
8428/// The error per bin will be computed as sqrt(sum of squares of weight)
8429/// for each bin.
8430///
8431/// This function is automatically called when the histogram is created
8432/// if the static function TH1::SetDefaultSumw2 has been called before.
8433/// If flag = false the structure is deleted
8434
8435void TH1::Sumw2(Bool_t flag)
8436{
8437 if (!flag) {
8438 // clear the array if existing - do nothing otherwise
8439 if (fSumw2.fN > 0 ) fSumw2.Set(0);
8440 return;
8441 }
8442
8443 if (fSumw2.fN == fNcells) {
8444 if (!fgDefaultSumw2 )
8445 Warning("Sumw2","Sum of squares of weights structure already created");
8446 return;
8447 }
8448
8450
8451 // empty the buffer
8452 if (fBuffer) BufferEmpty();
8453
8454 if (fEntries > 0)
8455 for (Int_t i = 0; i < fNcells; ++i)
8457}
8458
8459////////////////////////////////////////////////////////////////////////////////
8460/// Return pointer to function with name.
8461///
8462///
8463/// Functions such as TH1::Fit store the fitted function in the list of
8464/// functions of this histogram.
8465
8466TF1 *TH1::GetFunction(const char *name) const
8467{
8468 return (TF1*)fFunctions->FindObject(name);
8469}
8470
8471////////////////////////////////////////////////////////////////////////////////
8472/// Return value of error associated to bin number bin.
8473///
8474/// if the sum of squares of weights has been defined (via Sumw2),
8475/// this function returns the sqrt(sum of w2).
8476/// otherwise it returns the sqrt(contents) for this bin.
8477
8479{
8480 if (bin < 0) bin = 0;
8481 if (bin >= fNcells) bin = fNcells-1;
8482 if (fBuffer) ((TH1*)this)->BufferEmpty();
8483 if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
8484
8486}
8487
8488////////////////////////////////////////////////////////////////////////////////
8489/// Return lower error associated to bin number bin.
8490///
8491/// The error will depend on the statistic option used will return
8492/// the binContent - lower interval value
8493
8495{
8496 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
8497 // in case of weighted histogram check if it is really weighted
8498 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
8499
8500 if (bin < 0) bin = 0;
8501 if (bin >= fNcells) bin = fNcells-1;
8502 if (fBuffer) ((TH1*)this)->BufferEmpty();
8503
8504 Double_t alpha = 1.- 0.682689492;
8505 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
8506
8508 Int_t n = int(c);
8509 if (n < 0) {
8510 Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
8511 ((TH1*)this)->fBinStatErrOpt = kNormal;
8512 return GetBinError(bin);
8513 }
8514
8515 if (n == 0) return 0;
8516 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
8517}
8518
8519////////////////////////////////////////////////////////////////////////////////
8520/// Return upper error associated to bin number bin.
8521///
8522/// The error will depend on the statistic option used will return
8523/// the binContent - upper interval value
8524
8526{
8527 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
8528 // in case of weighted histogram check if it is really weighted
8529 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
8530 if (bin < 0) bin = 0;
8531 if (bin >= fNcells) bin = fNcells-1;
8532 if (fBuffer) ((TH1*)this)->BufferEmpty();
8533
8534 Double_t alpha = 1.- 0.682689492;
8535 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
8536
8538 Int_t n = int(c);
8539 if (n < 0) {
8540 Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
8541 ((TH1*)this)->fBinStatErrOpt = kNormal;
8542 return GetBinError(bin);
8543 }
8544
8545 // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
8546 // decide to return always (1-alpha)/2 upper interval
8547 //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
8548 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
8549}
8550
8551//L.M. These following getters are useless and should be probably deprecated
8552////////////////////////////////////////////////////////////////////////////////
8553/// Return bin center for 1D histogram.
8554/// Better to use h1.GetXaxis().GetBinCenter(bin)
8555
8557{
8558 if (fDimension == 1) return fXaxis.GetBinCenter(bin);
8559 Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
8560 return TMath::QuietNaN();
8561}
8562
8563////////////////////////////////////////////////////////////////////////////////
8564/// Return bin lower edge for 1D histogram.
8565/// Better to use h1.GetXaxis().GetBinLowEdge(bin)
8566
8568{
8569 if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
8570 Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
8571 return TMath::QuietNaN();
8572}
8573
8574////////////////////////////////////////////////////////////////////////////////
8575/// Return bin width for 1D histogram.
8576/// Better to use h1.GetXaxis().GetBinWidth(bin)
8577
8579{
8580 if (fDimension == 1) return fXaxis.GetBinWidth(bin);
8581 Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
8582 return TMath::QuietNaN();
8583}
8584
8585////////////////////////////////////////////////////////////////////////////////
8586/// Fill array with center of bins for 1D histogram
8587/// Better to use h1.GetXaxis().GetCenter(center)
8588
8589void TH1::GetCenter(Double_t *center) const
8590{
8591 if (fDimension == 1) {
8592 fXaxis.GetCenter(center);
8593 return;
8594 }
8595 Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
8596}
8597
8598////////////////////////////////////////////////////////////////////////////////
8599/// Fill array with low edge of bins for 1D histogram
8600/// Better to use h1.GetXaxis().GetLowEdge(edge)
8601
8602void TH1::GetLowEdge(Double_t *edge) const
8603{
8604 if (fDimension == 1) {
8605 fXaxis.GetLowEdge(edge);
8606 return;
8607 }
8608 Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
8609}
8610
8611////////////////////////////////////////////////////////////////////////////////
8612/// Set the bin Error
8613/// Note that this resets the bin eror option to be of Normal Type and for the
8614/// non-empty bin the bin error is set by default to the square root of their content.
8615/// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
8616/// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
8617/// will not recalcualated after setting the content and a default error = 0 will be used for those bins.
8618///
8619/// See convention for numbering bins in TH1::GetBin
8620
8621void TH1::SetBinError(Int_t bin, Double_t error)
8622{
8623 if (bin < 0 || bin>= fNcells) return;
8624 if (!fSumw2.fN) Sumw2();
8625 fSumw2.fArray[bin] = error * error;
8626 // reset the bin error option
8628}
8629
8630////////////////////////////////////////////////////////////////////////////////
8631/// Set bin content
8632/// see convention for numbering bins in TH1::GetBin
8633/// In case the bin number is greater than the number of bins and
8634/// the timedisplay option is set or CanExtendAllAxes(),
8635/// the number of bins is automatically doubled to accommodate the new bin
8636
8637void TH1::SetBinContent(Int_t bin, Double_t content)
8638{
8639 fEntries++;
8640 fTsumw = 0;
8641 if (bin < 0) return;
8642 if (bin >= fNcells-1) {
8644 while (bin >= fNcells-1) LabelsInflate();
8645 } else {
8646 if (bin == fNcells-1) UpdateBinContent(bin, content);
8647 return;
8648 }
8649 }
8650 UpdateBinContent(bin, content);
8651}
8652
8653////////////////////////////////////////////////////////////////////////////////
8654/// See convention for numbering bins in TH1::GetBin
8655
8656void TH1::SetBinError(Int_t binx, Int_t biny, Double_t error)
8657{
8658 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
8659 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
8660 SetBinError(GetBin(binx, biny), error);
8661}
8662
8663////////////////////////////////////////////////////////////////////////////////
8664/// See convention for numbering bins in TH1::GetBin
8665
8666void TH1::SetBinError(Int_t binx, Int_t biny, Int_t binz, Double_t error)
8667{
8668 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
8669 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
8670 if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
8671 SetBinError(GetBin(binx, biny, binz), error);
8672}
8673
8674////////////////////////////////////////////////////////////////////////////////
8675/// This function calculates the background spectrum in this histogram.
8676/// The background is returned as a histogram.
8677///
8678/// \param[in] niter number of iterations (default value = 2)
8679/// Increasing niter make the result smoother and lower.
8680/// \param[in] option may contain one of the following options
8681/// - to set the direction parameter
8682/// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
8683/// - filterOrder-order of clipping filter (default "BackOrder2")
8684/// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
8685/// - "nosmoothing" - if selected, the background is not smoothed
8686/// By default the background is smoothed.
8687/// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
8688/// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
8689/// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
8690/// - "nocompton" - if selected the estimation of Compton edge
8691/// will be not be included (by default the compton estimation is set)
8692/// - "same" if this option is specified, the resulting background
8693/// histogram is superimposed on the picture in the current pad.
8694/// This option is given by default.
8695///
8696/// NOTE that the background is only evaluated in the current range of this histogram.
8697/// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
8698/// the returned histogram will be created with the same number of bins
8699/// as this input histogram, but only bins from binmin to binmax will be filled
8700/// with the estimated background.
8701
8702TH1 *TH1::ShowBackground(Int_t niter, Option_t *option)
8703{
8704
8705 return (TH1*)gROOT->ProcessLineFast(Form("TSpectrum::StaticBackground((TH1*)0x%lx,%d,\"%s\")",
8706 (ULong_t)this, niter, option));
8707}
8708
8709////////////////////////////////////////////////////////////////////////////////
8710/// Interface to TSpectrum::Search.
8711/// The function finds peaks in this histogram where the width is > sigma
8712/// and the peak maximum greater than threshold*maximum bin content of this.
8713/// For more details see TSpectrum::Search.
8714/// Note the difference in the default value for option compared to TSpectrum::Search
8715/// option="" by default (instead of "goff").
8716
8718{
8719 return (Int_t)gROOT->ProcessLineFast(Form("TSpectrum::StaticSearch((TH1*)0x%lx,%g,\"%s\",%g)",
8720 (ULong_t)this, sigma, option, threshold));
8721}
8722
8723////////////////////////////////////////////////////////////////////////////////
8724/// For a given transform (first parameter), fills the histogram (second parameter)
8725/// with the transform output data, specified in the third parameter
8726/// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
8727/// and the user is responsible for deleting it.
8728///
8729/// Available options:
8730/// - "RE" - real part of the output
8731/// - "IM" - imaginary part of the output
8732/// - "MAG" - magnitude of the output
8733/// - "PH" - phase of the output
8734
8735TH1* TH1::TransformHisto(TVirtualFFT *fft, TH1* h_output, Option_t *option)
8736{
8737 if (!fft || !fft->GetN() ) {
8738 ::Error("TransformHisto","Invalid FFT transform class");
8739 return 0;
8740 }
8741
8742 if (fft->GetNdim()>2){
8743 ::Error("TransformHisto","Only 1d and 2D transform are supported");
8744 return 0;
8745 }
8746 Int_t binx,biny;
8747 TString opt = option;
8748 opt.ToUpper();
8749 Int_t *n = fft->GetN();
8750 TH1 *hout=0;
8751 if (h_output) {
8752 hout = h_output;
8753 }
8754 else {
8755 TString name = TString::Format("out_%s", opt.Data());
8756 if (fft->GetNdim()==1)
8757 hout = new TH1D(name, name,n[0], 0, n[0]);
8758 else if (fft->GetNdim()==2)
8759 hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
8760 }
8761 R__ASSERT(hout != 0);
8762 TString type=fft->GetType();
8763 Int_t ind[2];
8764 if (opt.Contains("RE")){
8765 if (type.Contains("2C") || type.Contains("2HC")) {
8766 Double_t re, im;
8767 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8768 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8769 ind[0] = binx-1; ind[1] = biny-1;
8770 fft->GetPointComplex(ind, re, im);
8771 hout->SetBinContent(binx, biny, re);
8772 }
8773 }
8774 } else {
8775 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8776 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8777 ind[0] = binx-1; ind[1] = biny-1;
8778 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
8779 }
8780 }
8781 }
8782 }
8783 if (opt.Contains("IM")) {
8784 if (type.Contains("2C") || type.Contains("2HC")) {
8785 Double_t re, im;
8786 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8787 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8788 ind[0] = binx-1; ind[1] = biny-1;
8789 fft->GetPointComplex(ind, re, im);
8790 hout->SetBinContent(binx, biny, im);
8791 }
8792 }
8793 } else {
8794 ::Error("TransformHisto","No complex numbers in the output");
8795 return 0;
8796 }
8797 }
8798 if (opt.Contains("MA")) {
8799 if (type.Contains("2C") || type.Contains("2HC")) {
8800 Double_t re, im;
8801 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8802 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8803 ind[0] = binx-1; ind[1] = biny-1;
8804 fft->GetPointComplex(ind, re, im);
8805 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
8806 }
8807 }
8808 } else {
8809 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8810 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8811 ind[0] = binx-1; ind[1] = biny-1;
8812 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
8813 }
8814 }
8815 }
8816 }
8817 if (opt.Contains("PH")) {
8818 if (type.Contains("2C") || type.Contains("2HC")){
8819 Double_t re, im, ph;
8820 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
8821 for (biny=1; biny<=hout->GetNbinsY(); biny++){
8822 ind[0] = binx-1; ind[1] = biny-1;
8823 fft->GetPointComplex(ind, re, im);
8824 if (TMath::Abs(re) > 1e-13){
8825 ph = TMath::ATan(im/re);
8826 //find the correct quadrant
8827 if (re<0 && im<0)
8828 ph -= TMath::Pi();
8829 if (re<0 && im>=0)
8830 ph += TMath::Pi();
8831 } else {
8832 if (TMath::Abs(im) < 1e-13)
8833 ph = 0;
8834 else if (im>0)
8835 ph = TMath::Pi()*0.5;
8836 else
8837 ph = -TMath::Pi()*0.5;
8838 }
8839 hout->SetBinContent(binx, biny, ph);
8840 }
8841 }
8842 } else {
8843 printf("Pure real output, no phase");
8844 return 0;
8845 }
8846 }
8847
8848 return hout;
8849}
8850
8851////////////////////////////////////////////////////////////////////////////////
8852/// Raw retrieval of bin content on internal data structure
8853/// see convention for numbering bins in TH1::GetBin
8854
8856{
8857 AbstractMethod("RetrieveBinContent");
8858 return 0;
8859}
8860
8861////////////////////////////////////////////////////////////////////////////////
8862/// Raw update of bin content on internal data structure
8863/// see convention for numbering bins in TH1::GetBin
8864
8866{
8867 AbstractMethod("UpdateBinContent");
8868}
8869
8870////////////////////////////////////////////////////////////////////////////////
8871/// Print value overload
8872
8873std::string cling::printValue(TH1 *val) {
8874 std::ostringstream strm;
8875 strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
8876 return strm.str();
8877}
8878
8879//______________________________________________________________________________
8880// TH1C methods
8881// TH1C : histograms with one byte per channel. Maximum bin content = 127
8882//______________________________________________________________________________
8883
8884ClassImp(TH1C);
8885
8886////////////////////////////////////////////////////////////////////////////////
8887/// Constructor.
8888
8889TH1C::TH1C(): TH1(), TArrayC()
8890{
8891 fDimension = 1;
8892 SetBinsLength(3);
8893 if (fgDefaultSumw2) Sumw2();
8894}
8895
8896////////////////////////////////////////////////////////////////////////////////
8897/// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
8898/// (see TH1::TH1 for explanation of parameters)
8899
8900TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
8901: TH1(name,title,nbins,xlow,xup)
8902{
8903 fDimension = 1;
8905
8906 if (xlow >= xup) SetBuffer(fgBufferSize);
8907 if (fgDefaultSumw2) Sumw2();
8908}
8909
8910////////////////////////////////////////////////////////////////////////////////
8911/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
8912/// (see TH1::TH1 for explanation of parameters)
8913
8914TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
8915: TH1(name,title,nbins,xbins)
8916{
8917 fDimension = 1;
8919 if (fgDefaultSumw2) Sumw2();
8920}
8921
8922////////////////////////////////////////////////////////////////////////////////
8923/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
8924/// (see TH1::TH1 for explanation of parameters)
8925
8926TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
8927: TH1(name,title,nbins,xbins)
8928{
8929 fDimension = 1;
8931 if (fgDefaultSumw2) Sumw2();
8932}
8933
8934////////////////////////////////////////////////////////////////////////////////
8935/// Destructor.
8936
8938{
8939}
8940
8941////////////////////////////////////////////////////////////////////////////////
8942/// Copy constructor.
8943
8944TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
8945{
8946 ((TH1C&)h1c).Copy(*this);
8947}
8948
8949////////////////////////////////////////////////////////////////////////////////
8950/// Increment bin content by 1.
8951
8952void TH1C::AddBinContent(Int_t bin)
8953{
8954 if (fArray[bin] < 127) fArray[bin]++;
8955}
8956
8957////////////////////////////////////////////////////////////////////////////////
8958/// Increment bin content by w.
8959
8961{
8962 Int_t newval = fArray[bin] + Int_t(w);
8963 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
8964 if (newval < -127) fArray[bin] = -127;
8965 if (newval > 127) fArray[bin] = 127;
8966}
8967
8968////////////////////////////////////////////////////////////////////////////////
8969/// Copy this to newth1
8970
8971void TH1C::Copy(TObject &newth1) const
8972{
8973 TH1::Copy(newth1);
8974}
8975
8976////////////////////////////////////////////////////////////////////////////////
8977/// Reset.
8978
8979void TH1C::Reset(Option_t *option)
8980{
8981 TH1::Reset(option);
8983}
8984
8985////////////////////////////////////////////////////////////////////////////////
8986/// Set total number of bins including under/overflow
8987/// Reallocate bin contents array
8988
8990{
8991 if (n < 0) n = fXaxis.GetNbins() + 2;
8992 fNcells = n;
8993 TArrayC::Set(n);
8994}
8995
8996////////////////////////////////////////////////////////////////////////////////
8997/// Operator =
8998
8999TH1C& TH1C::operator=(const TH1C &h1)
9000{
9001 if (this != &h1) ((TH1C&)h1).Copy(*this);
9002 return *this;
9003}
9004
9005////////////////////////////////////////////////////////////////////////////////
9006/// Operator *
9007
9009{
9010 TH1C hnew = h1;
9011 hnew.Scale(c1);
9012 hnew.SetDirectory(0);
9013 return hnew;
9014}
9015
9016////////////////////////////////////////////////////////////////////////////////
9017/// Operator +
9018
9019TH1C operator+(const TH1C &h1, const TH1C &h2)
9020{
9021 TH1C hnew = h1;
9022 hnew.Add(&h2,1);
9023 hnew.SetDirectory(0);
9024 return hnew;
9025}
9026
9027////////////////////////////////////////////////////////////////////////////////
9028/// Operator -
9029
9030TH1C operator-(const TH1C &h1, const TH1C &h2)
9031{
9032 TH1C hnew = h1;
9033 hnew.Add(&h2,-1);
9034 hnew.SetDirectory(0);
9035 return hnew;
9036}
9037
9038////////////////////////////////////////////////////////////////////////////////
9039/// Operator *
9040
9041TH1C operator*(const TH1C &h1, const TH1C &h2)
9042{
9043 TH1C hnew = h1;
9044 hnew.Multiply(&h2);
9045 hnew.SetDirectory(0);
9046 return hnew;
9047}
9048
9049////////////////////////////////////////////////////////////////////////////////
9050/// Operator /
9051
9052TH1C operator/(const TH1C &h1, const TH1C &h2)
9053{
9054 TH1C hnew = h1;
9055 hnew.Divide(&h2);
9056 hnew.SetDirectory(0);
9057 return hnew;
9058}
9059
9060//______________________________________________________________________________
9061// TH1S methods
9062// TH1S : histograms with one short per channel. Maximum bin content = 32767
9063//______________________________________________________________________________
9064
9065ClassImp(TH1S);
9066
9067////////////////////////////////////////////////////////////////////////////////
9068/// Constructor.
9069
9070TH1S::TH1S(): TH1(), TArrayS()
9071{
9072 fDimension = 1;
9073 SetBinsLength(3);
9074 if (fgDefaultSumw2) Sumw2();
9075}
9076
9077////////////////////////////////////////////////////////////////////////////////
9078/// Create a 1-Dim histogram with fix bins of type short
9079/// (see TH1::TH1 for explanation of parameters)
9080
9081TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9082: TH1(name,title,nbins,xlow,xup)
9083{
9084 fDimension = 1;
9086
9087 if (xlow >= xup) SetBuffer(fgBufferSize);
9088 if (fgDefaultSumw2) Sumw2();
9089}
9090
9091////////////////////////////////////////////////////////////////////////////////
9092/// Create a 1-Dim histogram with variable bins of type short
9093/// (see TH1::TH1 for explanation of parameters)
9094
9095TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9096: TH1(name,title,nbins,xbins)
9097{
9098 fDimension = 1;
9100 if (fgDefaultSumw2) Sumw2();
9101}
9102
9103////////////////////////////////////////////////////////////////////////////////
9104/// Create a 1-Dim histogram with variable bins of type short
9105/// (see TH1::TH1 for explanation of parameters)
9106
9107TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9108: TH1(name,title,nbins,xbins)
9109{
9110 fDimension = 1;
9112 if (fgDefaultSumw2) Sumw2();
9113}
9114
9115////////////////////////////////////////////////////////////////////////////////
9116/// Destructor.
9117
9119{
9120}
9121
9122////////////////////////////////////////////////////////////////////////////////
9123/// Copy constructor.
9124
9125TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9126{
9127 ((TH1S&)h1s).Copy(*this);
9128}
9129
9130////////////////////////////////////////////////////////////////////////////////
9131/// Increment bin content by 1.
9132
9133void TH1S::AddBinContent(Int_t bin)
9134{
9135 if (fArray[bin] < 32767) fArray[bin]++;
9136}
9137
9138////////////////////////////////////////////////////////////////////////////////
9139/// Increment bin content by w
9140
9142{
9143 Int_t newval = fArray[bin] + Int_t(w);
9144 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9145 if (newval < -32767) fArray[bin] = -32767;
9146 if (newval > 32767) fArray[bin] = 32767;
9147}
9148
9149////////////////////////////////////////////////////////////////////////////////
9150/// Copy this to newth1
9151
9152void TH1S::Copy(TObject &newth1) const
9153{
9154 TH1::Copy(newth1);
9155}
9156
9157////////////////////////////////////////////////////////////////////////////////
9158/// Reset.
9159
9160void TH1S::Reset(Option_t *option)
9161{
9162 TH1::Reset(option);
9164}
9165
9166////////////////////////////////////////////////////////////////////////////////
9167/// Set total number of bins including under/overflow
9168/// Reallocate bin contents array
9169
9171{
9172 if (n < 0) n = fXaxis.GetNbins() + 2;
9173 fNcells = n;
9174 TArrayS::Set(n);
9175}
9176
9177////////////////////////////////////////////////////////////////////////////////
9178/// Operator =
9179
9180TH1S& TH1S::operator=(const TH1S &h1)
9181{
9182 if (this != &h1) ((TH1S&)h1).Copy(*this);
9183 return *this;
9184}
9185
9186////////////////////////////////////////////////////////////////////////////////
9187/// Operator *
9188
9190{
9191 TH1S hnew = h1;
9192 hnew.Scale(c1);
9193 hnew.SetDirectory(0);
9194 return hnew;
9195}
9196
9197////////////////////////////////////////////////////////////////////////////////
9198/// Operator +
9199
9200TH1S operator+(const TH1S &h1, const TH1S &h2)
9201{
9202 TH1S hnew = h1;
9203 hnew.Add(&h2,1);
9204 hnew.SetDirectory(0);
9205 return hnew;
9206}
9207
9208////////////////////////////////////////////////////////////////////////////////
9209/// Operator -
9210
9211TH1S operator-(const TH1S &h1, const TH1S &h2)
9212{
9213 TH1S hnew = h1;
9214 hnew.Add(&h2,-1);
9215 hnew.SetDirectory(0);
9216 return hnew;
9217}
9218
9219////////////////////////////////////////////////////////////////////////////////
9220/// Operator *
9221
9222TH1S operator*(const TH1S &h1, const TH1S &h2)
9223{
9224 TH1S hnew = h1;
9225 hnew.Multiply(&h2);
9226 hnew.SetDirectory(0);
9227 return hnew;
9228}
9229
9230////////////////////////////////////////////////////////////////////////////////
9231/// Operator /
9232
9233TH1S operator/(const TH1S &h1, const TH1S &h2)
9234{
9235 TH1S hnew = h1;
9236 hnew.Divide(&h2);
9237 hnew.SetDirectory(0);
9238 return hnew;
9239}
9240
9241//______________________________________________________________________________
9242// TH1I methods
9243// TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9244//______________________________________________________________________________
9245
9246ClassImp(TH1I);
9247
9248////////////////////////////////////////////////////////////////////////////////
9249/// Constructor.
9250
9251TH1I::TH1I(): TH1(), TArrayI()
9252{
9253 fDimension = 1;
9254 SetBinsLength(3);
9255 if (fgDefaultSumw2) Sumw2();
9256}
9257
9258////////////////////////////////////////////////////////////////////////////////
9259/// Create a 1-Dim histogram with fix bins of type integer
9260/// (see TH1::TH1 for explanation of parameters)
9261
9262TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9263: TH1(name,title,nbins,xlow,xup)
9264{
9265 fDimension = 1;
9267
9268 if (xlow >= xup) SetBuffer(fgBufferSize);
9269 if (fgDefaultSumw2) Sumw2();
9270}
9271
9272////////////////////////////////////////////////////////////////////////////////
9273/// Create a 1-Dim histogram with variable bins of type integer
9274/// (see TH1::TH1 for explanation of parameters)
9275
9276TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9277: TH1(name,title,nbins,xbins)
9278{
9279 fDimension = 1;
9281 if (fgDefaultSumw2) Sumw2();
9282}
9283
9284////////////////////////////////////////////////////////////////////////////////
9285/// Create a 1-Dim histogram with variable bins of type integer
9286/// (see TH1::TH1 for explanation of parameters)
9287
9288TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9289: TH1(name,title,nbins,xbins)
9290{
9291 fDimension = 1;
9293 if (fgDefaultSumw2) Sumw2();
9294}
9295
9296////////////////////////////////////////////////////////////////////////////////
9297/// Destructor.
9298
9300{
9301}
9302
9303////////////////////////////////////////////////////////////////////////////////
9304/// Copy constructor.
9305
9306TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
9307{
9308 ((TH1I&)h1i).Copy(*this);
9309}
9310
9311////////////////////////////////////////////////////////////////////////////////
9312/// Increment bin content by 1.
9313
9314void TH1I::AddBinContent(Int_t bin)
9315{
9316 if (fArray[bin] < 2147483647) fArray[bin]++;
9317}
9318
9319////////////////////////////////////////////////////////////////////////////////
9320/// Increment bin content by w
9321
9323{
9324 Long64_t newval = fArray[bin] + Long64_t(w);
9325 if (newval > -2147483647 && newval < 2147483647) {fArray[bin] = Int_t(newval); return;}
9326 if (newval < -2147483647) fArray[bin] = -2147483647;
9327 if (newval > 2147483647) fArray[bin] = 2147483647;
9328}
9329
9330////////////////////////////////////////////////////////////////////////////////
9331/// Copy this to newth1
9332
9333void TH1I::Copy(TObject &newth1) const
9334{
9335 TH1::Copy(newth1);
9336}
9337
9338////////////////////////////////////////////////////////////////////////////////
9339/// Reset.
9340
9341void TH1I::Reset(Option_t *option)
9342{
9343 TH1::Reset(option);
9345}
9346
9347////////////////////////////////////////////////////////////////////////////////
9348/// Set total number of bins including under/overflow
9349/// Reallocate bin contents array
9350
9352{
9353 if (n < 0) n = fXaxis.GetNbins() + 2;
9354 fNcells = n;
9355 TArrayI::Set(n);
9356}
9357
9358////////////////////////////////////////////////////////////////////////////////
9359/// Operator =
9360
9361TH1I& TH1I::operator=(const TH1I &h1)
9362{
9363 if (this != &h1) ((TH1I&)h1).Copy(*this);
9364 return *this;
9365}
9366
9367
9368////////////////////////////////////////////////////////////////////////////////
9369/// Operator *
9370
9372{
9373 TH1I hnew = h1;
9374 hnew.Scale(c1);
9375 hnew.SetDirectory(0);
9376 return hnew;
9377}
9378
9379////////////////////////////////////////////////////////////////////////////////
9380/// Operator +
9381
9382TH1I operator+(const TH1I &h1, const TH1I &h2)
9383{
9384 TH1I hnew = h1;
9385 hnew.Add(&h2,1);
9386 hnew.SetDirectory(0);
9387 return hnew;
9388}
9389
9390////////////////////////////////////////////////////////////////////////////////
9391/// Operator -
9392
9393TH1I operator-(const TH1I &h1, const TH1I &h2)
9394{
9395 TH1I hnew = h1;
9396 hnew.Add(&h2,-1);
9397 hnew.SetDirectory(0);
9398 return hnew;
9399}
9400
9401////////////////////////////////////////////////////////////////////////////////
9402/// Operator *
9403
9404TH1I operator*(const TH1I &h1, const TH1I &h2)
9405{
9406 TH1I hnew = h1;
9407 hnew.Multiply(&h2);
9408 hnew.SetDirectory(0);
9409 return hnew;
9410}
9411
9412////////////////////////////////////////////////////////////////////////////////
9413/// Operator /
9414
9415TH1I operator/(const TH1I &h1, const TH1I &h2)
9416{
9417 TH1I hnew = h1;
9418 hnew.Divide(&h2);
9419 hnew.SetDirectory(0);
9420 return hnew;
9421}
9422
9423//______________________________________________________________________________
9424// TH1F methods
9425// TH1F : histograms with one float per channel. Maximum precision 7 digits
9426//______________________________________________________________________________
9427
9428ClassImp(TH1F);
9429
9430////////////////////////////////////////////////////////////////////////////////
9431/// Constructor.
9432
9433TH1F::TH1F(): TH1(), TArrayF()
9434{
9435 fDimension = 1;
9436 SetBinsLength(3);
9437 if (fgDefaultSumw2) Sumw2();
9438}
9439
9440////////////////////////////////////////////////////////////////////////////////
9441/// Create a 1-Dim histogram with fix bins of type float
9442/// (see TH1::TH1 for explanation of parameters)
9443
9444TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9445: TH1(name,title,nbins,xlow,xup)
9446{
9447 fDimension = 1;
9449
9450 if (xlow >= xup) SetBuffer(fgBufferSize);
9451 if (fgDefaultSumw2) Sumw2();
9452}
9453
9454////////////////////////////////////////////////////////////////////////////////
9455/// Create a 1-Dim histogram with variable bins of type float
9456/// (see TH1::TH1 for explanation of parameters)
9457
9458TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9459: TH1(name,title,nbins,xbins)
9460{
9461 fDimension = 1;
9463 if (fgDefaultSumw2) Sumw2();
9464}
9465
9466////////////////////////////////////////////////////////////////////////////////
9467/// Create a 1-Dim histogram with variable bins of type float
9468/// (see TH1::TH1 for explanation of parameters)
9469
9470TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9471: TH1(name,title,nbins,xbins)
9472{
9473 fDimension = 1;
9475 if (fgDefaultSumw2) Sumw2();
9476}
9477
9478////////////////////////////////////////////////////////////////////////////////
9479/// Create a histogram from a TVectorF
9480/// by default the histogram name is "TVectorF" and title = ""
9481
9482TH1F::TH1F(const TVectorF &v)
9483: TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
9484{
9486 fDimension = 1;
9487 Int_t ivlow = v.GetLwb();
9488 for (Int_t i=0;i<fNcells-2;i++) {
9489 SetBinContent(i+1,v(i+ivlow));
9490 }
9492 if (fgDefaultSumw2) Sumw2();
9493}
9494
9495////////////////////////////////////////////////////////////////////////////////
9496/// Copy Constructor.
9497
9498TH1F::TH1F(const TH1F &h) : TH1(), TArrayF()
9499{
9500 ((TH1F&)h).Copy(*this);
9501}
9502
9503////////////////////////////////////////////////////////////////////////////////
9504/// Destructor.
9505
9507{
9508}
9509
9510////////////////////////////////////////////////////////////////////////////////
9511/// Copy this to newth1.
9512
9513void TH1F::Copy(TObject &newth1) const
9514{
9515 TH1::Copy(newth1);
9516}
9517
9518////////////////////////////////////////////////////////////////////////////////
9519/// Reset.
9520
9521void TH1F::Reset(Option_t *option)
9522{
9523 TH1::Reset(option);
9525}
9526
9527////////////////////////////////////////////////////////////////////////////////
9528/// Set total number of bins including under/overflow
9529/// Reallocate bin contents array
9530
9532{
9533 if (n < 0) n = fXaxis.GetNbins() + 2;
9534 fNcells = n;
9535 TArrayF::Set(n);
9536}
9537
9538////////////////////////////////////////////////////////////////////////////////
9539/// Operator =
9540
9541TH1F& TH1F::operator=(const TH1F &h1)
9542{
9543 if (this != &h1) ((TH1F&)h1).Copy(*this);
9544 return *this;
9545}
9546
9547////////////////////////////////////////////////////////////////////////////////
9548/// Operator *
9549
9551{
9552 TH1F hnew = h1;
9553 hnew.Scale(c1);
9554 hnew.SetDirectory(0);
9555 return hnew;
9556}
9557
9558////////////////////////////////////////////////////////////////////////////////
9559/// Operator +
9560
9561TH1F operator+(const TH1F &h1, const TH1F &h2)
9562{
9563 TH1F hnew = h1;
9564 hnew.Add(&h2,1);
9565 hnew.SetDirectory(0);
9566 return hnew;
9567}
9568
9569////////////////////////////////////////////////////////////////////////////////
9570/// Operator -
9571
9572TH1F operator-(const TH1F &h1, const TH1F &h2)
9573{
9574 TH1F hnew = h1;
9575 hnew.Add(&h2,-1);
9576 hnew.SetDirectory(0);
9577 return hnew;
9578}
9579
9580////////////////////////////////////////////////////////////////////////////////
9581/// Operator *
9582
9583TH1F operator*(const TH1F &h1, const TH1F &h2)
9584{
9585 TH1F hnew = h1;
9586 hnew.Multiply(&h2);
9587 hnew.SetDirectory(0);
9588 return hnew;
9589}
9590
9591////////////////////////////////////////////////////////////////////////////////
9592/// Operator /
9593
9594TH1F operator/(const TH1F &h1, const TH1F &h2)
9595{
9596 TH1F hnew = h1;
9597 hnew.Divide(&h2);
9598 hnew.SetDirectory(0);
9599 return hnew;
9600}
9601
9602//______________________________________________________________________________
9603// TH1D methods
9604// TH1D : histograms with one double per channel. Maximum precision 14 digits
9605//______________________________________________________________________________
9606
9607ClassImp(TH1D);
9608
9609////////////////////////////////////////////////////////////////////////////////
9610/// Constructor.
9611
9612TH1D::TH1D(): TH1(), TArrayD()
9613{
9614 fDimension = 1;
9615 SetBinsLength(3);
9616 if (fgDefaultSumw2) Sumw2();
9617}
9618
9619////////////////////////////////////////////////////////////////////////////////
9620/// Create a 1-Dim histogram with fix bins of type double
9621/// (see TH1::TH1 for explanation of parameters)
9622
9623TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9624: TH1(name,title,nbins,xlow,xup)
9625{
9626 fDimension = 1;
9628
9629 if (xlow >= xup) SetBuffer(fgBufferSize);
9630 if (fgDefaultSumw2) Sumw2();
9631}
9632
9633////////////////////////////////////////////////////////////////////////////////
9634/// Create a 1-Dim histogram with variable bins of type double
9635/// (see TH1::TH1 for explanation of parameters)
9636
9637TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9638: TH1(name,title,nbins,xbins)
9639{
9640 fDimension = 1;
9642 if (fgDefaultSumw2) Sumw2();
9643}
9644
9645////////////////////////////////////////////////////////////////////////////////
9646/// Create a 1-Dim histogram with variable bins of type double
9647/// (see TH1::TH1 for explanation of parameters)
9648
9649TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9650: TH1(name,title,nbins,xbins)
9651{
9652 fDimension = 1;
9654 if (fgDefaultSumw2) Sumw2();
9655}
9656
9657////////////////////////////////////////////////////////////////////////////////
9658/// Create a histogram from a TVectorD
9659/// by default the histogram name is "TVectorD" and title = ""
9660
9661TH1D::TH1D(const TVectorD &v)
9662: TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
9663{
9665 fDimension = 1;
9666 Int_t ivlow = v.GetLwb();
9667 for (Int_t i=0;i<fNcells-2;i++) {
9668 SetBinContent(i+1,v(i+ivlow));
9669 }
9671 if (fgDefaultSumw2) Sumw2();
9672}
9673
9674////////////////////////////////////////////////////////////////////////////////
9675/// Destructor.
9676
9678{
9679}
9680
9681////////////////////////////////////////////////////////////////////////////////
9682/// Constructor.
9683
9684TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
9685{
9686 ((TH1D&)h1d).Copy(*this);
9687}
9688
9689////////////////////////////////////////////////////////////////////////////////
9690/// Copy this to newth1
9691
9692void TH1D::Copy(TObject &newth1) const
9693{
9694 TH1::Copy(newth1);
9695}
9696
9697////////////////////////////////////////////////////////////////////////////////
9698/// Reset.
9699
9700void TH1D::Reset(Option_t *option)
9701{
9702 TH1::Reset(option);
9704}
9705
9706////////////////////////////////////////////////////////////////////////////////
9707/// Set total number of bins including under/overflow
9708/// Reallocate bin contents array
9709
9711{
9712 if (n < 0) n = fXaxis.GetNbins() + 2;
9713 fNcells = n;
9714 TArrayD::Set(n);
9715}
9716
9717////////////////////////////////////////////////////////////////////////////////
9718/// Operator =
9719
9720TH1D& TH1D::operator=(const TH1D &h1)
9721{
9722 if (this != &h1) ((TH1D&)h1).Copy(*this);
9723 return *this;
9724}
9725
9726////////////////////////////////////////////////////////////////////////////////
9727/// Operator *
9728
9730{
9731 TH1D hnew = h1;
9732 hnew.Scale(c1);
9733 hnew.SetDirectory(0);
9734 return hnew;
9735}
9736
9737////////////////////////////////////////////////////////////////////////////////
9738/// Operator +
9739
9740TH1D operator+(const TH1D &h1, const TH1D &h2)
9741{
9742 TH1D hnew = h1;
9743 hnew.Add(&h2,1);
9744 hnew.SetDirectory(0);
9745 return hnew;
9746}
9747
9748////////////////////////////////////////////////////////////////////////////////
9749/// Operator -
9750
9751TH1D operator-(const TH1D &h1, const TH1D &h2)
9752{
9753 TH1D hnew = h1;
9754 hnew.Add(&h2,-1);
9755 hnew.SetDirectory(0);
9756 return hnew;
9757}
9758
9759////////////////////////////////////////////////////////////////////////////////
9760/// Operator *
9761
9762TH1D operator*(const TH1D &h1, const TH1D &h2)
9763{
9764 TH1D hnew = h1;
9765 hnew.Multiply(&h2);
9766 hnew.SetDirectory(0);
9767 return hnew;
9768}
9769
9770////////////////////////////////////////////////////////////////////////////////
9771/// Operator /
9772
9773TH1D operator/(const TH1D &h1, const TH1D &h2)
9774{
9775 TH1D hnew = h1;
9776 hnew.Divide(&h2);
9777 hnew.SetDirectory(0);
9778 return hnew;
9779}
9780
9781////////////////////////////////////////////////////////////////////////////////
9782///return pointer to histogram with name
9783///hid if id >=0
9784///h_id if id <0
9785
9786TH1 *R__H(Int_t hid)
9787{
9788 TString hname;
9789 if(hid >= 0) hname.Form("h%d",hid);
9790 else hname.Form("h_%d",hid);
9791 return (TH1*)gDirectory->Get(hname);
9792}
9793
9794////////////////////////////////////////////////////////////////////////////////
9795///return pointer to histogram with name hname
9796
9797TH1 *R__H(const char * hname)
9798{
9799 return (TH1*)gDirectory->Get(hname);
9800}
void Class()
Definition: Class.C:29
SVector< double, 2 > v
Definition: Dict.h:5
#define b(i)
Definition: RSha256.hxx:100
#define c(i)
Definition: RSha256.hxx:101
#define s1(x)
Definition: RSha256.hxx:91
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
static const double x1[5]
int Int_t
Definition: RtypesCore.h:41
short Version_t
Definition: RtypesCore.h:61
char Char_t
Definition: RtypesCore.h:29
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
bool Bool_t
Definition: RtypesCore.h:59
short Short_t
Definition: RtypesCore.h:35
double Double_t
Definition: RtypesCore.h:55
double Stat_t
Definition: RtypesCore.h:73
short Color_t
Definition: RtypesCore.h:79
long long Long64_t
Definition: RtypesCore.h:69
short Style_t
Definition: RtypesCore.h:76
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
#define ClassImp(name)
Definition: Rtypes.h:365
#define gDirectory
Definition: TDirectory.h:218
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
#define R__ASSERT(e)
Definition: TError.h:96
char name[80]
Definition: TGX11.cxx:109
int type
Definition: TGX11.cxx:120
static bool IsEquidistantBinning(const TAxis &axis)
Test if the binning is equidistant.
Definition: TH1.cxx:5462
void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
Least square linear fit without weights.
Definition: TH1.cxx:4649
void H1InitGaus()
Compute Initial values of parameters for a gaussian.
Definition: TH1.cxx:4484
void H1InitExpo()
Compute Initial values of parameters for an exponential.
Definition: TH1.cxx:4540
TH1C operator+(const TH1C &h1, const TH1C &h2)
Operator +.
Definition: TH1.cxx:9017
TH1C operator-(const TH1C &h1, const TH1C &h2)
Operator -.
Definition: TH1.cxx:9028
TH1C operator/(const TH1C &h1, const TH1C &h2)
Operator /.
Definition: TH1.cxx:9050
void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b)
Extracted from CERN Program library routine DSEQN.
Definition: TH1.cxx:4695
static Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon=0.00000001)
Test if two double are almost equal.
Definition: TH1.cxx:5445
static Bool_t AlmostInteger(Double_t a, Double_t epsilon=0.00000001)
Test if a double is almost an integer.
Definition: TH1.cxx:5453
TF1 * gF1
Definition: TH1.cxx:524
TH1 * R__H(Int_t hid)
return pointer to histogram with name hid if id >=0 h_id if id <0
Definition: TH1.cxx:9784
TH1C operator*(Double_t c1, const TH1C &h1)
Operator *.
Definition: TH1.cxx:9006
void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
Least squares lpolynomial fitting without weights.
Definition: TH1.cxx:4590
void H1InitPolynom()
Compute Initial values of parameters for a polynom.
Definition: TH1.cxx:4560
float xmin
Definition: THbookFile.cxx:93
int nentries
Definition: THbookFile.cxx:89
float * q
Definition: THbookFile.cxx:87
float ymin
Definition: THbookFile.cxx:93
float xmax
Definition: THbookFile.cxx:93
float ymax
Definition: THbookFile.cxx:93
#define gInterpreter
Definition: TInterpreter.h:553
int isnan(double)
double ldexp(double, int)
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:59
#define gROOT
Definition: TROOT.h:414
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
char * Form(const char *fmt,...)
void Printf(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:406
#define R__LOCKGUARD(mutex)
#define gPad
Definition: TVirtualPad.h:286
#define R__WRITE_LOCKGUARD(mutex)
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition: BinData.h:53
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition: DataRange.h:34
void AndersonDarling2SamplesTest(Double_t &pvalue, Double_t &testStat) const
Definition: GoFTest.cxx:646
Array of chars or bytes (8 bits per element).
Definition: TArrayC.h:27
void Set(Int_t n)
Set size of this array to n chars.
Definition: TArrayC.cxx:105
Char_t * fArray
Definition: TArrayC.h:30
void Copy(TArrayC &array) const
Definition: TArrayC.h:42
void Reset(Char_t val=0)
Definition: TArrayC.h:47
Array of doubles (64 bits per element).
Definition: TArrayD.h:27
Double_t GetAt(Int_t i) const
Definition: TArrayD.h:45
Double_t * fArray
Definition: TArrayD.h:30
void Copy(TArrayD &array) const
Definition: TArrayD.h:42
void Set(Int_t n)
Set size of this array to n doubles.
Definition: TArrayD.cxx:106
const Double_t * GetArray() const
Definition: TArrayD.h:43
void Reset()
Definition: TArrayD.h:47
Array of floats (32 bits per element).
Definition: TArrayF.h:27
void Copy(TArrayF &array) const
Definition: TArrayF.h:42
void Reset()
Definition: TArrayF.h:47
void Set(Int_t n)
Set size of this array to n floats.
Definition: TArrayF.cxx:105
Array of integers (32 bits per element).
Definition: TArrayI.h:27
Int_t * fArray
Definition: TArrayI.h:30
void Set(Int_t n)
Set size of this array to n ints.
Definition: TArrayI.cxx:105
void Reset()
Definition: TArrayI.h:47
void Copy(TArrayI &array) const
Definition: TArrayI.h:42
Array of shorts (16 bits per element).
Definition: TArrayS.h:27
void Set(Int_t n)
Set size of this array to n shorts.
Definition: TArrayS.cxx:105
void Reset()
Definition: TArrayS.h:47
void Copy(TArrayS &array) const
Definition: TArrayS.h:42
Short_t * fArray
Definition: TArrayS.h:30
Abstract array base class.
Definition: TArray.h:31
Int_t fN
Definition: TArray.h:38
Int_t GetSize() const
Definition: TArray.h:47
virtual Color_t GetTitleColor() const
Definition: TAttAxis.h:45
virtual Color_t GetLabelColor() const
Definition: TAttAxis.h:38
virtual Int_t GetNdivisions() const
Definition: TAttAxis.h:36
virtual Color_t GetAxisColor() const
Definition: TAttAxis.h:37
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title Offset is a correction factor with respect to the "s...
Definition: TAttAxis.cxx:294
virtual Style_t GetTitleFont() const
Definition: TAttAxis.h:46
virtual Float_t GetLabelOffset() const
Definition: TAttAxis.h:40
virtual void SetAxisColor(Color_t color=1, Float_t alpha=1.)
Set color of the line axis and tick marks.
Definition: TAttAxis.cxx:163
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels The size is expressed in per cent of the pad width.
Definition: TAttAxis.cxx:204
virtual Style_t GetLabelFont() const
Definition: TAttAxis.h:39
virtual void SetTitleFont(Style_t font=62)
Set the title font.
Definition: TAttAxis.cxx:322
virtual void SetLabelOffset(Float_t offset=0.005)
Set distance between the axis and the labels The distance is expressed in per cent of the pad width.
Definition: TAttAxis.cxx:193
virtual void SetLabelFont(Style_t font=62)
Set labels' font.
Definition: TAttAxis.cxx:183
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title The size is expressed in per cent of the pad width.
Definition: TAttAxis.cxx:304
virtual void SetTitleColor(Color_t color=1)
Set color of axis title.
Definition: TAttAxis.cxx:313
virtual Float_t GetTitleSize() const
Definition: TAttAxis.h:43
virtual Float_t GetLabelSize() const
Definition: TAttAxis.h:41
virtual Float_t GetTickLength() const
Definition: TAttAxis.h:44
virtual void ResetAttAxis(Option_t *option="")
Reset axis attributes.
Definition: TAttAxis.cxx:79
virtual Float_t GetTitleOffset() const
Definition: TAttAxis.h:42
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length The length is expressed in per cent of the pad width.
Definition: TAttAxis.cxx:280
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition: TAttAxis.cxx:229
virtual void SetLabelColor(Color_t color=1, Float_t alpha=1.)
Set color of labels.
Definition: TAttAxis.cxx:173
Fill Area Attributes class.
Definition: TAttFill.h:19
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition: TAttFill.cxx:202
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
Save fill attributes as C++ statement(s) on output stream out.
Definition: TAttFill.cxx:234
Line Attributes class.
Definition: TAttLine.h:18
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition: TAttLine.h:42
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition: TAttLine.cxx:164
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition: TAttLine.cxx:262
Marker Attributes class.
Definition: TAttMarker.h:19
virtual void SaveMarkerAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t sizdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition: TAttMarker.cxx:245
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition: TAttMarker.h:32
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition: TAttMarker.h:38
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition: TAttMarker.h:31
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition: TAttMarker.h:33
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:40
void Copy(TAttMarker &attmarker) const
Copy this marker attributes to a new TAttMarker.
Definition: TAttMarker.cxx:210
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition: TAttMarker.h:41
Class to manage histogram axis.
Definition: TAxis.h:30
virtual void GetCenter(Double_t *center) const
Return an array with the center of all bins.
Definition: TAxis.cxx:539
virtual Bool_t GetTimeDisplay() const
Definition: TAxis.h:126
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:464
Bool_t CanExtend() const
Definition: TAxis.h:82
virtual void SetParent(TObject *obj)
Definition: TAxis.h:157
const TArrayD * GetXbins() const
Definition: TAxis.h:130
void SetCanExtend(Bool_t canExtend)
Definition: TAxis.h:86
Double_t GetXmax() const
Definition: TAxis.h:134
virtual void SaveAttributes(std::ostream &out, const char *name, const char *subname)
Save axis attributes as C++ statement(s) on output stream out.
Definition: TAxis.cxx:647
@ kLabelsUp
Definition: TAxis.h:70
@ kLabelsDown
Definition: TAxis.h:69
@ kLabelsHori
Definition: TAxis.h:67
@ kAxisRange
Definition: TAxis.h:61
@ kLabelsVert
Definition: TAxis.h:68
const char * GetBinLabel(Int_t bin) const
Return label for bin.
Definition: TAxis.cxx:426
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:279
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:504
virtual void SetTimeDisplay(Int_t value)
Definition: TAxis.h:161
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Definition: TAxis.cxx:717
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:405
virtual void Copy(TObject &axis) const
Copy axis structure to another axis.
Definition: TAxis.cxx:208
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:455
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition: TAxis.h:154
Double_t GetXmin() const
Definition: TAxis.h:133
Int_t GetNbins() const
Definition: TAxis.h:121
virtual void GetLowEdge(Double_t *edge) const
Return an array with the low edge of all bins.
Definition: TAxis.cxx:548
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis from bin first to last.
Definition: TAxis.cxx:903
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:526
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:514
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:444
THashList * GetLabels() const
Definition: TAxis.h:117
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
Collection abstract base class.
Definition: TCollection.h:63
virtual bool UseRWLock()
Set this collection to use a RW lock upon access, making it thread safe.
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
virtual Bool_t IsEmpty() const
Definition: TCollection.h:186
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
Describe directory structure in memory.
Definition: TDirectory.h:34
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
Definition: TDirectory.cxx:190
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
1-Dim function class
Definition: TF1.h:211
static void RejectPoint(Bool_t reject=kTRUE)
Static function to set the global flag to reject points the fgRejectPoint global flag is tested by al...
Definition: TF1.cxx:3650
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function.
Definition: TF1.cxx:1564
virtual Int_t GetNpar() const
Definition: TF1.h:475
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
IntegralOneDim or analytical integral.
Definition: TF1.cxx:2502
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=0)
Evaluate function with given coordinates and parameters.
Definition: TF1.cxx:1458
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition: TF1.cxx:2454
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition: TF1.cxx:2263
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set limits for parameter ipar.
Definition: TF1.cxx:3497
static Bool_t RejectedPoint()
See TF1::RejectPoint above.
Definition: TF1.cxx:3659
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this function.
Definition: TF1.cxx:1429
virtual void SetParameter(Int_t param, Double_t value)
Definition: TF1.h:628
virtual Bool_t IsInside(const Double_t *x) const
return kTRUE if the point is inside the function range
Definition: TF1.h:592
A 2-Dim function with parameters.
Definition: TF2.h:29
A 3-Dim function with parameters.
Definition: TF3.h:28
Provides an indirection to the TFitResult class and with a semantics identical to a TFitResult pointe...
Definition: TFitResultPtr.h:31
1-D histogram with a byte per channel (see TH1 documentation)
Definition: TH1.h:448
TH1C & operator=(const TH1C &h1)
Operator =.
Definition: TH1.cxx:8997
TH1C()
Constructor.
Definition: TH1.cxx:8887
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:8969
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:8987
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH1.cxx:8950
virtual ~TH1C()
Destructor.
Definition: TH1.cxx:8935
virtual void Reset(Option_t *option="")
Reset.
Definition: TH1.cxx:8977
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:614
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:9690
virtual ~TH1D()
Destructor.
Definition: TH1.cxx:9675
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9708
TH1D()
Constructor.
Definition: TH1.cxx:9610
TH1D & operator=(const TH1D &h1)
Operator =.
Definition: TH1.cxx:9718
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:571
virtual Double_t RetrieveBinContent(Int_t bin) const
Raw retrieval of bin content on internal data structure see convention for numbering bins in TH1::Get...
Definition: TH1.h:600
virtual ~TH1F()
Destructor.
Definition: TH1.cxx:9504
TH1F & operator=(const TH1F &h1)
Operator =.
Definition: TH1.cxx:9539
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9529
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:9511
TH1F()
Constructor.
Definition: TH1.cxx:9431
1-D histogram with an int per channel (see TH1 documentation)}
Definition: TH1.h:530
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:9331
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH1.cxx:9312
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9349
virtual ~TH1I()
Destructor.
Definition: TH1.cxx:9297
TH1I()
Constructor.
Definition: TH1.cxx:9249
TH1I & operator=(const TH1I &h1)
Operator =.
Definition: TH1.cxx:9359
1-D histogram with a short per channel (see TH1 documentation)
Definition: TH1.h:489
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH1.cxx:9131
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9168
virtual ~TH1S()
Destructor.
Definition: TH1.cxx:9116
TH1S & operator=(const TH1S &h1)
Operator =.
Definition: TH1.cxx:9178
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:9150
TH1S()
Constructor.
Definition: TH1.cxx:9068
The TH1 histogram class.
Definition: TH1.h:56
virtual void SetError(const Double_t *error)
Replace bin errors by values in array error.
Definition: TH1.cxx:8365
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8351
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition: TH1.cxx:4138
Double_t * fBuffer
[fBufferSize] entry buffer
Definition: TH1.h:105
virtual Int_t AutoP2FindLimits(Double_t min, Double_t max)
Buffer-based estimate of the histogram range using the power of 2 algorithm.
Definition: TH1.cxx:1275
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition: TH1.cxx:4302
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TH1.cxx:6753
virtual void SetTitle(const char *title)
See GetStatOverflows for more information.
Definition: TH1.cxx:6309
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition: TH1.cxx:6476
virtual void Print(Option_t *option="") const
Print some global quantities for this histogram.
Definition: TH1.cxx:6606
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition: TH1.cxx:8554
virtual void Rebuild(Option_t *option="")
Using the current bin info, recompute the arrays for contents and errors.
Definition: TH1.cxx:6684
static Bool_t fgStatOverflows
!flag to use under/overflows in statistics
Definition: TH1.h:114
virtual Int_t FindLastBinAbove(Double_t threshold=0, Int_t axis=1, Int_t firstBin=1, Int_t lastBin=-1) const
Find last bin with content > threshold for axis (1=x, 2=y, 3=z) if no bins with content > threshold i...
Definition: TH1.cxx:3704
TAxis * GetZaxis()
Definition: TH1.h:318
virtual Bool_t Multiply(TF1 *f1, Double_t c1=1)
Performs the operation:
Definition: TH1.cxx:5634
virtual void Browse(TBrowser *b)
Browse the Histogram object.
Definition: TH1.cxx:713
Int_t fNcells
number of bins(1D), cells (2D) +U/Overflows
Definition: TH1.h:86
virtual void GetStats(Double_t *stats) const
fill the array stats from the contents of this histogram The array stats must be correctly dimensione...
Definition: TH1.cxx:7308
virtual void FillRandom(const char *fname, Int_t ntimes=5000)
Fill histogram following distribution in function fname.
Definition: TH1.cxx:3428
Double_t fTsumw
Total Sum of weights.
Definition: TH1.h:93
virtual Float_t GetBarWidth() const
Definition: TH1.h:252
Double_t fTsumw2
Total Sum of squares of weights.
Definition: TH1.h:94
static void StatOverflows(Bool_t flag=kTRUE)
if flag=kTRUE, underflows and overflows are used by the Fill functions in the computation of statisti...
Definition: TH1.cxx:6522
virtual Float_t GetBarOffset() const
Definition: TH1.h:251
virtual ~TH1()
Histogram default destructor.
Definition: TH1.cxx:578
TList * fFunctions
->Pointer to list of functions (fits and user)
Definition: TH1.h:103
static Bool_t fgAddDirectory
!flag to add histograms to the directory
Definition: TH1.h:113
virtual Int_t GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum=0)
Compute Quantiles for this histogram Quantile x_q of a probability distribution Function F is defined...
Definition: TH1.cxx:4434
static Int_t GetDefaultBufferSize()
Static function return the default buffer size for automatic histograms the parameter fgBufferSize ma...
Definition: TH1.cxx:4260
virtual Double_t DoIntegral(Int_t ix1, Int_t ix2, Int_t iy1, Int_t iy2, Int_t iz1, Int_t iz2, Double_t &err, Option_t *opt, Bool_t doerr=kFALSE) const
Internal function compute integral and optionally the error between the limits specified by the bin n...
Definition: TH1.cxx:7449
Double_t fTsumwx2
Total Sum of weight*X*X.
Definition: TH1.h:96
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition: TH1.cxx:7104
TH1()
Histogram default constructor.
Definition: TH1.cxx:550
static TH1 * TransformHisto(TVirtualFFT *fft, TH1 *h_output, Option_t *option)
For a given transform (first parameter), fills the histogram (second parameter) with the transform ou...
Definition: TH1.cxx:8733
virtual void LabelsOption(Option_t *option="h", Option_t *axis="X")
Set option(s) to draw axis with labels.
Definition: TH1.cxx:5197
virtual Int_t GetNbinsY() const
Definition: TH1.h:293
Short_t fBarOffset
(1000*offset) for bar charts or legos
Definition: TH1.h:90
static bool CheckBinLimits(const TAxis *a1, const TAxis *a2)
Check bin limits.
Definition: TH1.cxx:1471
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH1.cxx:1200
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8476
static Int_t FitOptionsMake(Option_t *option, Foption_t &Foption)
Decode string choptin and fill fitOption structure.
Definition: TH1.cxx:4475
virtual Int_t GetNbinsZ() const
Definition: TH1.h:294
virtual Double_t GetNormFactor() const
Definition: TH1.h:296
virtual Double_t GetMean(Int_t axis=1) const
For axis = 1,2 or 3 returns the mean value of the histogram along X,Y or Z axis.
Definition: TH1.cxx:7050
virtual Double_t GetSkewness(Int_t axis=1) const
Definition: TH1.cxx:7155
virtual void ClearUnderflowAndOverflow()
Remove all the content from the underflow and overflow bins, without changing the number of entries A...
Definition: TH1.cxx:2455
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition: TH1.cxx:7862
virtual TH1 * DrawNormalized(Option_t *option="", Double_t norm=1) const
Draw a normalized copy of this histogram.
Definition: TH1.cxx:3058
virtual Double_t Chi2TestX(const TH1 *h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option="UU", Double_t *res=0) const
The computation routine of the Chisquare test.
Definition: TH1.cxx:2008
virtual Int_t GetDimension() const
Definition: TH1.h:278
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition: TH1.cxx:1225
@ kIsAverage
Bin contents are average (used by Add)
Definition: TH1.h:166
@ kUserContour
user specified contour levels
Definition: TH1.h:161
@ kNoStats
don't draw stats box
Definition: TH1.h:160
@ kAutoBinPTwo
Use Power(2)-based algorithm for autobinning.
Definition: TH1.h:169
@ kIsNotW
Histogram is forced to be not weighted even when the histogram is filled with weighted different than...
Definition: TH1.h:167
@ kIsHighlight
bit set if histo is highlight
Definition: TH1.h:170
virtual Double_t GetRandom() const
Return a random number distributed according the histogram bin contents.
Definition: TH1.cxx:4831
virtual void SetContourLevel(Int_t level, Double_t value)
Set value for one contour level.
Definition: TH1.cxx:7944
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition: TH1.cxx:6242
TDirectory * fDirectory
!Pointer to directory holding this histogram
Definition: TH1.h:106
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition: TH1.cxx:6700
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:316
virtual void GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz) const
Return binx, biny, binz corresponding to the global bin number globalbin see TH1::GetBin function abo...
Definition: TH1.cxx:4797
TH1 * GetCumulative(Bool_t forward=kTRUE, const char *suffix="_cumulative") const
Return a pointer to an histogram containing the cumulative The cumulative can be computed both in the...
Definition: TH1.cxx:2544
void UseCurrentStyle()
Copy current attributes from/to current style.
Definition: TH1.cxx:6986
static Double_t AutoP2GetPower2(Double_t x, Bool_t next=kTRUE)
Auxilliary function to get the power of 2 next (larger) or previous (smaller) a given x.
Definition: TH1.cxx:1239
virtual Int_t GetNcells() const
Definition: TH1.h:295
virtual Int_t ShowPeaks(Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
Interface to TSpectrum::Search.
Definition: TH1.cxx:8715
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition: TH1.cxx:5493
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition: TH1.cxx:7359
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition: TH1.cxx:4343
TObject * Clone(const char *newname=0) const
Make a complete copy of the underlying object.
Definition: TH1.cxx:2664
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
Definition: TH1.cxx:4269
virtual Int_t FindFirstBinAbove(Double_t threshold=0, Int_t axis=1, Int_t firstBin=1, Int_t lastBin=-1) const
Find first bin with content > threshold for axis (1=x, 2=y, 3=z) if no bins with content > threshold ...
Definition: TH1.cxx:3641
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Double_t xmin=0, Double_t xmax=0)
Fit histogram with function fname.
Definition: TH1.cxx:3791
virtual Int_t GetBin(Int_t binx, Int_t biny=0, Int_t binz=0) const
Return Global bin number corresponding to binx,y,z.
Definition: TH1.cxx:4784
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
Return maximum value smaller than maxval of bins in the range, unless the value has been overridden b...
Definition: TH1.cxx:7964
virtual Int_t GetNbinsX() const
Definition: TH1.h:292
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:394
virtual TH1 * FFT(TH1 *h_output, Option_t *option)
This function allows to do discrete Fourier transforms of TH1 and TH2.
Definition: TH1.cxx:3198
virtual void LabelsInflate(Option_t *axis="X")
Double the number of bins for axis.
Definition: TH1.cxx:5136
virtual TH1 * ShowBackground(Int_t niter=20, Option_t *option="same")
This function calculates the background spectrum in this histogram.
Definition: TH1.cxx:8700
virtual Double_t Chi2Test(const TH1 *h2, Option_t *option="UU", Double_t *res=0) const
test for comparing weighted and unweighted histograms
Definition: TH1.cxx:1949
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
Definition: TH1.cxx:5482
virtual Bool_t Add(TF1 *h1, Double_t c1=1, Option_t *option="")
Performs the operation: this = this + c1*f1 if errors are defined (see TH1::Sumw2),...
Definition: TH1.cxx:777
Double_t fMaximum
Maximum value for plotting.
Definition: TH1.h:97
Int_t fBufferSize
fBuffer size
Definition: TH1.h:104
virtual void RecursiveRemove(TObject *obj)
Recursively remove object from the list of functions.
Definition: TH1.cxx:6190
virtual Double_t RetrieveBinContent(Int_t bin) const
Raw retrieval of bin content on internal data structure see convention for numbering bins in TH1::Get...
Definition: TH1.cxx:8853
virtual Double_t IntegralAndError(Int_t binx1, Int_t binx2, Double_t &err, Option_t *option="") const
Return integral of bin contents in range [binx1,binx2] and its error.
Definition: TH1.cxx:7440
Int_t fDimension
!Histogram dimension (1, 2 or 3 dim)
Definition: TH1.h:107
virtual void SetBinError(Int_t bin, Double_t error)
Set the bin Error Note that this resets the bin eror option to be of Normal Type and for the non-empt...
Definition: TH1.cxx:8619
EBinErrorOpt fBinStatErrOpt
option for bin statistical errors
Definition: TH1.h:110
static Int_t fgBufferSize
!default buffer size for automatic histograms
Definition: TH1.h:112
virtual void SetBinsLength(Int_t=-1)
Definition: TH1.h:371
Double_t fNormFactor
Normalization factor.
Definition: TH1.h:99
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3258
virtual TObject * FindObject(const char *name) const
Search object named name in the list of functions.
Definition: TH1.cxx:3764
TAxis * GetYaxis()
Definition: TH1.h:317
TArrayD fContour
Array to display contour levels.
Definition: TH1.h:100
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition: TH1.cxx:8492
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition: TH1.cxx:7820
virtual void SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option="")
Helper function for the SavePrimitive functions from TH1 or classes derived from TH1,...
Definition: TH1.cxx:6895
Short_t fBarWidth
(1000*width) for bar charts or legos
Definition: TH1.h:91
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition: TH1.cxx:7905
virtual Double_t GetBinErrorSqUnchecked(Int_t bin) const
Definition: TH1.h:439
Int_t AxisChoice(Option_t *axis) const
Choose an axis according to "axis".
Definition: Haxis.cxx:14
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:395
Bool_t IsBinUnderflow(Int_t bin, Int_t axis=0) const
Return true if the bin is underflow.
Definition: TH1.cxx:5035
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check that axis have same labels.
Definition: TH1.cxx:1500
static void SetDefaultSumw2(Bool_t sumw2=kTRUE)
When this static function is called with sumw2=kTRUE, all new histograms will automatically activate ...
Definition: TH1.cxx:6294
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition: TH1.cxx:5003
Double_t * fIntegral
!Integral of bins used by GetRandom
Definition: TH1.h:108
Double_t fMinimum
Minimum value for plotting.
Definition: TH1.h:98
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH1.cxx:7413
virtual void SetBarWidth(Float_t width=0.5)
Definition: TH1.h:356
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
Definition: TH1.cxx:8635
virtual void DirectoryAutoAdd(TDirectory *)
Perform the automatic addition of the histogram to the given directory.
Definition: TH1.cxx:2697
@ kNstat
Definition: TH1.h:179
virtual void GetLowEdge(Double_t *edge) const
Fill array with low edge of bins for 1D histogram Better to use h1.GetXaxis().GetLowEdge(edge)
Definition: TH1.cxx:8600
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8565
void Build()
Creates histogram basic data structure.
Definition: TH1.cxx:722
virtual Double_t GetEntries() const
Return the current number of entries.
Definition: TH1.cxx:4277
virtual TF1 * GetFunction(const char *name) const
Return pointer to function with name.
Definition: TH1.cxx:8464
virtual Int_t BufferFill(Double_t x, Double_t w)
accumulate arguments in buffer.
Definition: TH1.cxx:1436
virtual Double_t GetBinWithContent(Double_t c, Int_t &binx, Int_t firstx=0, Int_t lastx=0, Double_t maxdiff=0) const
Compute first binx in the range [firstx,lastx] for which diff = abs(bin_content-c) <= maxdiff.
Definition: TH1.cxx:4907
virtual UInt_t SetCanExtend(UInt_t extendBitMask)
Make the histogram axes extendable / not extendable according to the bit mask returns the previous bi...
Definition: TH1.cxx:6255
TList * GetListOfFunctions() const
Definition: TH1.h:239
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition: TH1.cxx:3028
virtual void Copy(TObject &hnew) const
Copy this histogram structure to newth1.
Definition: TH1.cxx:2587
Bool_t IsEmpty() const
Check if an histogram is empty (this a protected method used mainly by TH1Merger )
Definition: TH1.cxx:4985
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition: TH1.cxx:7081
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2981
virtual void SetBarOffset(Float_t offset=0.25)
Definition: TH1.h:355
virtual Double_t AndersonDarlingTest(const TH1 *h2, Option_t *option="") const
Statistical test of compatibility in shape between this histogram and h2, using the Anderson-Darling ...
Definition: TH1.cxx:7533
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculates from bin cont...
Definition: TH1.cxx:7374
static void SetDefaultBufferSize(Int_t buffersize=1000)
Static function to set the default buffer size for automatic histograms.
Definition: TH1.cxx:6284
virtual void SetBinErrorOption(EBinErrorOpt type)
Definition: TH1.h:372
virtual void SetBuffer(Int_t buffersize, Option_t *option="")
Set the maximum number of entries to be kept in the buffer.
Definition: TH1.cxx:7880
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Definition: TH1.cxx:3089
@ kXaxis
Definition: TH1.h:70
@ kNoAxis
NOTE: Must always be 0 !!!
Definition: TH1.h:69
@ kZaxis
Definition: TH1.h:72
@ kYaxis
Definition: TH1.h:71
virtual Double_t Chisquare(TF1 *f1, Option_t *option="") const
Compute and return the chisquare of this histogram with respect to a function The chisquare is comput...
Definition: TH1.cxx:2436
virtual void DoFillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride=1)
Internal method to fill histogram content from a vector called directly by TH1::BufferEmpty.
Definition: TH1.cxx:3387
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition: TH1.cxx:8145
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition: TH1.cxx:7994
static Int_t AutoP2GetBins(Int_t n)
Auxilliary function to get the next power of 2 integer value larger then n.
Definition: TH1.cxx:1252
Double_t fEntries
Number of entries.
Definition: TH1.h:92
virtual Long64_t Merge(TCollection *list)
Definition: TH1.h:337
virtual void SetName(const char *name)
Change the name of this histogram.
Definition: TH1.cxx:8374
virtual Double_t * GetIntegral()
Return a pointer to the array of bins integral.
Definition: TH1.cxx:2522
TAxis fZaxis
Z axis descriptor.
Definition: TH1.h:89
EStatOverflows fStatOverflows
per object flag to use under/overflows in statistics
Definition: TH1.h:111
virtual void FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride=1)
Fill this histogram with an array x and weights w.
Definition: TH1.cxx:3361
virtual void UpdateBinContent(Int_t bin, Double_t content)
Raw update of bin content on internal data structure see convention for numbering bins in TH1::GetBin...
Definition: TH1.cxx:8863
static bool CheckEqualAxes(const TAxis *a1, const TAxis *a2)
Check that the axis are the same.
Definition: TH1.cxx:1547
@ kPoisson2
errors from Poisson interval at 95% CL (~ 2 sigma)
Definition: TH1.h:64
@ kNormal
errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition: TH1.h:62
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4882
TAxis fXaxis
X axis descriptor.
Definition: TH1.h:87
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TH1.cxx:3154
virtual Bool_t IsHighlight() const
Definition: TH1.h:330
virtual Double_t Interpolate(Double_t x)
Given a point x, approximates the value via linear interpolation based on the two nearest bin centers...
Definition: TH1.cxx:4936
virtual void ExtendAxis(Double_t x, TAxis *axis)
Histogram is resized along axis such that x is in the axis range.
Definition: TH1.cxx:6118
virtual void SetNameTitle(const char *name, const char *title)
Change the name and title of this histogram.
Definition: TH1.cxx:8388
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8576
static bool CheckConsistency(const TH1 *h1, const TH1 *h2)
Check histogram compatibility.
Definition: TH1.cxx:1620
TArrayD fSumw2
Array of sum of squares of weights.
Definition: TH1.h:101
TH1 * GetAsymmetry(TH1 *h2, Double_t c2=1, Double_t dc2=0)
Return an histogram containing the asymmetry of this histogram with h2, where the asymmetry is define...
Definition: TH1.cxx:4193
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition: TH1.cxx:7852
virtual void SetHighlight(Bool_t set=kTRUE)
Set highlight (enable/disable) mode for the histogram by default highlight mode is disable.
Definition: TH1.cxx:4313
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition: TH1.cxx:8523
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition: TH1.cxx:6218
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms.
Definition: TH1.cxx:5809
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition: TH1.cxx:8079
virtual Int_t GetSumw2N() const
Definition: TH1.h:310
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
Return Global bin number corresponding to x,y,z.
Definition: TH1.cxx:3579
Bool_t GetStatOverflowsBehaviour() const
Definition: TH1.h:148
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition: TH1.cxx:7142
virtual Bool_t Divide(TF1 *f1, Double_t c1=1)
Performs the operation: this = this/(c1*f1) if errors are defined (see TH1::Sumw2),...
Definition: TH1.cxx:2736
virtual Double_t GetMinimum(Double_t minval=-FLT_MAX) const
Return minimum value larger than minval of bins in the range, unless the value has been overridden by...
Definition: TH1.cxx:8049
static bool CheckConsistentSubAxes(const TAxis *a1, Int_t firstBin1, Int_t lastBin1, const TAxis *a2, Int_t firstBin2=0, Int_t lastBin2=0)
Check that two sub axis are the same.
Definition: TH1.cxx:1583
TAxis fYaxis
Y axis descriptor.
Definition: TH1.h:88
virtual Double_t KolmogorovTest(const TH1 *h2, Option_t *option="") const
Statistical test of compatibility in shape between this histogram and h2, using Kolmogorov test.
Definition: TH1.cxx:7647
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7389
static void SmoothArray(Int_t NN, Double_t *XX, Int_t ntimes=1)
Smooth array xx, translation of Hbook routine hsmoof.F based on algorithm 353QH twice presented by J.
Definition: TH1.cxx:6358
virtual void GetCenter(Double_t *center) const
Fill array with center of bins for 1D histogram Better to use h1.GetXaxis().GetCenter(center)
Definition: TH1.cxx:8587
TVirtualHistPainter * fPainter
!pointer to histogram painter
Definition: TH1.h:109
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition: TH1.cxx:8181
virtual Int_t FindFixBin(Double_t x, Double_t y=0, Double_t z=0) const
Return Global bin number corresponding to x,y,z.
Definition: TH1.cxx:3612
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Redefines TObject::GetObjectInfo.
Definition: TH1.cxx:4334
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition: TH1.cxx:8433
virtual void SetEntries(Double_t n)
Definition: TH1.h:381
virtual Bool_t FindNewAxisLimits(const TAxis *axis, const Double_t point, Double_t &newMin, Double_t &newMax)
finds new limits for the axis so that point is within the range and the limits are compatible with th...
Definition: TH1.cxx:6061
static bool CheckAxisLimits(const TAxis *a1, const TAxis *a2)
Check that the axis limits of the histograms are the same.
Definition: TH1.cxx:1532
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition: TH1.cxx:705
static Bool_t fgDefaultSumw2
!flag to call TH1::Sumw2 automatically at histogram creation time
Definition: TH1.h:115
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a line.
Definition: TH1.cxx:2719
Double_t fTsumwx
Total Sum of weight*X.
Definition: TH1.h:95
virtual void LabelsDeflate(Option_t *axis="X")
Reduce the number of bins for the axis passed in the option to the number of bins having a label.
Definition: TH1.cxx:5066
virtual Double_t ComputeIntegral(Bool_t onlyPositive=false)
Compute integral (cumulative sum of bins) The result stored in fIntegral is used by the GetRandom fun...
Definition: TH1.cxx:2474
TString fOption
histogram options
Definition: TH1.h:102
virtual Int_t GetContour(Double_t *levels=0)
Return contour values into array levels if pointer levels is non zero.
Definition: TH1.cxx:7833
virtual void Eval(TF1 *f1, Option_t *option="")
Evaluate function f1 at the center of bins of this histogram.
Definition: TH1.cxx:3106
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition: TH1.cxx:1346
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition: TH1.cxx:8404
virtual TH1 * Rebin(Int_t ngroup=2, const char *newname="", const Double_t *xbins=0)
Rebin this histogram.
Definition: TH1.cxx:5876
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition: TH1.cxx:7225
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:289
static THLimitsFinder * GetLimitsFinder()
Return pointer to the current finder.
virtual Int_t FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax)
Compute the best axis limits for the X axis.
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
void Clear(Option_t *option="")
Remove all objects from the list.
Definition: THashList.cxx:189
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:819
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:575
virtual TObjLink * FirstLink() const
Definition: TList.h:108
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: TList.cxx:761
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:656
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual void Copy(TObject &named) const
Copy this to obj.
Definition: TNamed.cxx:94
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
TString fTitle
Definition: TNamed.h:33
TString fName
Definition: TNamed.h:32
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Mother of all ROOT objects.
Definition: TObject.h:37
void AbstractMethod(const char *method) const
Use this method to implement an "abstract" method that you don't want to leave purely abstract.
Definition: TObject.cxx:922
@ kNotDeleted
object has not been deleted
Definition: TObject.h:78
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition: TObject.cxx:375
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition: TObject.cxx:715
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:105
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TObject.cxx:664
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:705
void ResetBit(UInt_t f)
Definition: TObject.h:171
@ kCanDelete
if object in a list can be deleted
Definition: TObject.h:58
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition: TObject.h:68
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Long_t ExecPlugin(int nargs, const T &... params)
Int_t LoadPlugin()
Load the plugin library for this handler.
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition: TRandom.cxx:391
virtual Double_t PoissonD(Double_t mean)
Generates a random number according to a Poisson law.
Definition: TRandom.cxx:443
virtual Double_t Rndm()
Machine independent random number generator.
Definition: TRandom.cxx:541
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1138
Bool_t IsNull() const
Definition: TString.h:402
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
TString & Append(const char *cs)
Definition: TString.h:559
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
Int_t GetOptStat() const
Definition: TStyle.h:232
void SetOptStat(Int_t stat=1)
The type of information printed in the histogram statistics box can be selected via the parameter mod...
Definition: TStyle.cxx:1444
void SetHistFillColor(Color_t color=1)
Definition: TStyle.h:356
Color_t GetHistLineColor() const
Definition: TStyle.h:220
Bool_t IsReading() const
Definition: TStyle.h:277
Float_t GetBarOffset() const
Definition: TStyle.h:170
void SetHistLineStyle(Style_t styl=0)
Definition: TStyle.h:359
Style_t GetHistFillStyle() const
Definition: TStyle.h:221
Color_t GetHistFillColor() const
Definition: TStyle.h:219
Float_t GetBarWidth() const
Definition: TStyle.h:171
Bool_t GetCanvasPreferGL() const
Definition: TStyle.h:175
void SetHistLineColor(Color_t color=1)
Definition: TStyle.h:357
void SetBarOffset(Float_t baroff=0.5)
Definition: TStyle.h:313
Style_t GetHistLineStyle() const
Definition: TStyle.h:222
void SetBarWidth(Float_t barwidth=0.5)
Definition: TStyle.h:314
void SetHistFillStyle(Style_t styl=0)
Definition: TStyle.h:358
Width_t GetHistLineWidth() const
Definition: TStyle.h:223
Int_t GetOptFit() const
Definition: TStyle.h:231
void SetHistLineWidth(Width_t width=1)
Definition: TStyle.h:360
TVectorT.
Definition: TVectorT.h:27
TVirtualFFT is an interface class for Fast Fourier Transforms.
Definition: TVirtualFFT.h:88
static TVirtualFFT * FFT(Int_t ndim, Int_t *n, Option_t *option)
Returns a pointer to the FFT of requested size and type.
virtual Int_t GetNdim() const =0
static TVirtualFFT * SineCosine(Int_t ndim, Int_t *n, Int_t *r2rkind, Option_t *option)
Returns a pointer to a sine or cosine transform of requested size and kind.
virtual Option_t * GetType() const =0
virtual void Transform()=0
virtual void GetPointComplex(Int_t ipoint, Double_t &re, Double_t &im, Bool_t fromInput=kFALSE) const =0
virtual Int_t * GetN() const =0
virtual Double_t GetPointReal(Int_t ipoint, Bool_t fromInput=kFALSE) const =0
virtual void SetPoint(Int_t ipoint, Double_t re, Double_t im=0)=0
Abstract Base Class for Fitting.
virtual Int_t GetXlast() const
virtual TObject * GetObjectFit() const
virtual Int_t GetXfirst() const
static TVirtualFitter * GetFitter()
static: return the current Fitter
virtual TObject * GetUserFunc() const
Abstract interface to a histogram painter.
virtual void DrawPanel()=0
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)=0
Execute action corresponding to an event at (px,py).
virtual void Paint(Option_t *option="")=0
This method must be overridden if a class wants to paint itself.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)=0
Computes distance from point (px,py) to the object.
virtual void SetHighlight()=0
static TVirtualHistPainter * HistPainter(TH1 *obj)
Static function returning a pointer to the current histogram painter.
double gamma_quantile_c(double z, double alpha, double theta)
Inverse ( ) of the cumulative distribution function of the upper tail of the gamma distribution (gamm...
double gamma_quantile(double z, double alpha, double theta)
Inverse ( ) of the cumulative distribution function of the lower tail of the gamma distribution (gamm...
const Double_t sigma
return c1
Definition: legend1.C:41
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
TH1F * h1
Definition: legend1.C:5
TF1 * f1
Definition: legend1.C:11
return c2
Definition: legend2.C:14
TFitResultPtr FitObject(TH1 *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
fitting function for a TH1 (called from TH1::Fit)
Definition: HFitImpl.cxx:964
void FitOptionsMake(EFitObjectType type, const char *option, Foption_t &fitOption)
Decode list of options into fitOption.
Definition: HFitImpl.cxx:681
void FillData(BinData &dv, const TH1 *hist, TF1 *func=0)
fill the data vector from a TH1.
double Chisquare(const TH1 &h1, TF1 &f1, bool useRange, bool usePL=false)
compute the chi2 value for an histogram given a function (see TH1::Chisquare for the documentation)
Definition: HFitImpl.cxx:1018
R__EXTERN TVirtualRWMutex * gCoreMutex
static constexpr double s
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN
Definition: NeuralNet.icc:544
Bool_t IsNaN(Double_t x)
Definition: TMath.h:880
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:701
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:212
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition: TMath.cxx:621
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754
Definition: TMath.h:889
Double_t Floor(Double_t x)
Definition: TMath.h:691
Double_t ATan(Double_t)
Definition: TMath.h:663
Double_t Ceil(Double_t x)
Definition: TMath.h:683
T MinElement(Long64_t n, const T *a)
Return minimum of array a of length n.
Definition: TMath.h:940
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:97
Double_t Log(Double_t x)
Definition: TMath.h:748
Double_t Sqrt(Double_t x)
Definition: TMath.h:679
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:723
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
constexpr Double_t Pi()
Definition: TMath.h:38
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition: TMath.h:416
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Definition: TMath.h:412
Double_t KolmogorovProb(Double_t z)
Calculates the Kolmogorov distribution function,.
Definition: TMath.cxx:663
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Definition: TMathBase.h:362
Double_t Median(Long64_t n, const T *a, const Double_t *w=0, Long64_t *work=0)
Return the median of the array a where each entry i has weight w[i] .
Definition: TMath.h:1235
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMathBase.h:278
Double_t Log10(Double_t x)
Definition: TMath.h:752
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
Definition: TMath.h:902
Definition: first.py:1
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12
static long int sum(long int i)
Definition: Factory.cxx:2258
REAL epsilon
Definition: triangle.c:617