Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 <array>
13#include <cctype>
14#include <climits>
15#include <cmath>
16#include <cstdio>
17#include <cstdlib>
18#include <cstring>
19#include <iostream>
20#include <sstream>
21#include <fstream>
22
23#include "TROOT.h"
24#include "TBuffer.h"
25#include "TEnv.h"
26#include "TClass.h"
27#include "TMath.h"
28#include "THashList.h"
29#include "TH1.h"
30#include "TH2.h"
31#include "TH3.h"
32#include "TF2.h"
33#include "TF3.h"
34#include "TPluginManager.h"
35#include "TVirtualPad.h"
36#include "TRandom.h"
37#include "TVirtualFitter.h"
38#include "THLimitsFinder.h"
39#include "TProfile.h"
40#include "TStyle.h"
41#include "TVectorF.h"
42#include "TVectorD.h"
43#include "TBrowser.h"
44#include "TError.h"
45#include "TVirtualHistPainter.h"
46#include "TVirtualFFT.h"
47#include "TVirtualPaveStats.h"
48
49#include "HFitInterface.h"
50#include "Fit/DataRange.h"
51#include "Fit/BinData.h"
52#include "Math/GoFTest.h"
55
56#include "TH1Merger.h"
57
58/** \addtogroup Histograms
59@{
60\class TH1C
61\brief 1-D histogram with a byte per channel (see TH1 documentation)
62\class TH1S
63\brief 1-D histogram with a short per channel (see TH1 documentation)
64\class TH1I
65\brief 1-D histogram with an int per channel (see TH1 documentation)
66\class TH1L
67\brief 1-D histogram with a long64 per channel (see TH1 documentation)
68\class TH1F
69\brief 1-D histogram with a float per channel (see TH1 documentation)
70\class TH1D
71\brief 1-D histogram with a double per channel (see TH1 documentation)
72@}
73*/
74
75/** \class TH1
76 \ingroup Histograms
77TH1 is the base class of all histogram classes in %ROOT.
78
79It provides the common interface for operations such as binning, filling, drawing, which
80will be detailed below.
81
82-# [Creating histograms](\ref creating-histograms)
83 - [Labelling axes](\ref labelling-axis)
84-# [Binning](\ref binning)
85 - [Fix or variable bin size](\ref fix-var)
86 - [Convention for numbering bins](\ref convention)
87 - [Alphanumeric Bin Labels](\ref alpha)
88 - [Histograms with automatic bins](\ref auto-bin)
89 - [Rebinning](\ref rebinning)
90-# [Filling histograms](\ref filling-histograms)
91 - [Associated errors](\ref associated-errors)
92 - [Associated functions](\ref associated-functions)
93 - [Projections of histograms](\ref prof-hist)
94 - [Random Numbers and histograms](\ref random-numbers)
95 - [Making a copy of a histogram](\ref making-a-copy)
96 - [Normalizing histograms](\ref normalizing)
97-# [Drawing histograms](\ref drawing-histograms)
98 - [Setting Drawing histogram contour levels (2-D hists only)](\ref cont-level)
99 - [Setting histogram graphics attributes](\ref graph-att)
100 - [Customising how axes are drawn](\ref axis-drawing)
101-# [Fitting histograms](\ref fitting-histograms)
102-# [Saving/reading histograms to/from a ROOT file](\ref saving-histograms)
103-# [Operations on histograms](\ref operations-on-histograms)
104-# [Miscellaneous operations](\ref misc)
105
106ROOT supports the following histogram types:
107
108 - 1-D histograms:
109 - TH1C : histograms with one byte per channel. Maximum bin content = 127
110 - TH1S : histograms with one short per channel. Maximum bin content = 32767
111 - TH1I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
112 - TH1L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
113 - TH1F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax "***")
114 - TH1D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax "****")
115 - 2-D histograms:
116 - TH2C : histograms with one byte per channel. Maximum bin content = 127
117 - TH2S : histograms with one short per channel. Maximum bin content = 32767
118 - TH2I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
119 - TH2L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
120 - TH2F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax "***")
121 - TH2D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax "****")
122 - 3-D histograms:
123 - TH3C : histograms with one byte per channel. Maximum bin content = 127
124 - TH3S : histograms with one short per channel. Maximum bin content = 32767
125 - TH3I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
126 - TH3L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
127 - TH3F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax "***")
128 - TH3D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax "****")
129 - Profile histograms: See classes TProfile, TProfile2D and TProfile3D.
130 Profile histograms are used to display the mean value of Y and its standard deviation
131 for each bin in X. Profile histograms are in many cases an elegant
132 replacement of two-dimensional histograms : the inter-relation of two
133 measured quantities X and Y can always be visualized by a two-dimensional
134 histogram or scatter-plot; If Y is an unknown (but single-valued)
135 approximate function of X, this function is displayed by a profile
136 histogram with much better precision than by a scatter-plot.
137
138<sup>
139\anchor intmax (*) INT_MAX = 2147483647 is the [maximum value for a variable of type int.](https://docs.microsoft.com/en-us/cpp/c-language/cpp-integer-limits)<br>
140\anchor llongmax (**) LLONG_MAX = 9223372036854775807 is the [maximum value for a variable of type long64.](https://docs.microsoft.com/en-us/cpp/c-language/cpp-integer-limits)<br>
141\anchor floatmax (***) 2^24 = 16777216 is the [maximum integer that can be properly represented by a float32 with 23-bit mantissa.](https://stackoverflow.com/a/3793950/7471760)<br>
142\anchor doublemax (****) 2^53 = 9007199254740992 is the [maximum integer that can be properly represented by a double64 with 52-bit mantissa.](https://stackoverflow.com/a/3793950/7471760)
143</sup>
144
145The inheritance hierarchy looks as follows:
146
147\image html classTH1__inherit__graph_org.svg width=100%
148
149\anchor creating-histograms
150## Creating histograms
151
152Histograms are created by invoking one of the constructors, e.g.
153~~~ {.cpp}
154 TH1F *h1 = new TH1F("h1", "h1 title", 100, 0, 4.4);
155 TH2F *h2 = new TH2F("h2", "h2 title", 40, 0, 4, 30, -3, 3);
156~~~
157Histograms may also be created by:
158
159 - calling the Clone() function, see below
160 - making a projection from a 2-D or 3-D histogram, see below
161 - reading a histogram from a file
162
163 When a histogram is created, a reference to it is automatically added
164 to the list of in-memory objects for the current file or directory.
165 Then the pointer to this histogram in the current directory can be found
166 by its name, doing:
167~~~ {.cpp}
168 TH1F *h1 = (TH1F*)gDirectory->FindObject(name);
169~~~
170
171 This default behaviour can be changed by:
172~~~ {.cpp}
173 h->SetDirectory(nullptr); // for the current histogram h
174 TH1::AddDirectory(kFALSE); // sets a global switch disabling the referencing
175~~~
176 When the histogram is deleted, the reference to it is removed from
177 the list of objects in memory.
178 When a file is closed, all histograms in memory associated with this file
179 are automatically deleted.
180
181\anchor labelling-axis
182### Labelling axes
183
184 Axis titles can be specified in the title argument of the constructor.
185 They must be separated by ";":
186~~~ {.cpp}
187 TH1F* h=new TH1F("h", "Histogram title;X Axis;Y Axis", 100, 0, 1);
188~~~
189 The histogram title and the axis titles can be any TLatex string, and
190 are persisted if a histogram is written to a file.
191
192 Any title can be omitted:
193~~~ {.cpp}
194 TH1F* h=new TH1F("h", "Histogram title;;Y Axis", 100, 0, 1);
195 TH1F* h=new TH1F("h", ";;Y Axis", 100, 0, 1);
196~~~
197 The method SetTitle() has the same syntax:
198~~~ {.cpp}
199 h->SetTitle("Histogram title;Another X title Axis");
200~~~
201Alternatively, the title of each axis can be set directly:
202~~~ {.cpp}
203 h->GetXaxis()->SetTitle("X axis title");
204 h->GetYaxis()->SetTitle("Y axis title");
205~~~
206For bin labels see \ref binning.
207
208\anchor binning
209## Binning
210
211\anchor fix-var
212### Fix or variable bin size
213
214 All histogram types support either fix or variable bin sizes.
215 2-D histograms may have fix size bins along X and variable size bins
216 along Y or vice-versa. The functions to fill, manipulate, draw or access
217 histograms are identical in both cases.
218
219 Each histogram always contains 3 axis objects of type TAxis: fXaxis, fYaxis and fZaxis.
220 To access the axis parameters, use:
221~~~ {.cpp}
222 TAxis *xaxis = h->GetXaxis(); etc.
223 Double_t binCenter = xaxis->GetBinCenter(bin), etc.
224~~~
225 See class TAxis for a description of all the access functions.
226 The axis range is always stored internally in double precision.
227
228\anchor convention
229### Convention for numbering bins
230
231 For all histogram types: nbins, xlow, xup
232~~~ {.cpp}
233 bin = 0; underflow bin
234 bin = 1; first bin with low-edge xlow INCLUDED
235 bin = nbins; last bin with upper-edge xup EXCLUDED
236 bin = nbins+1; overflow bin
237~~~
238 In case of 2-D or 3-D histograms, a "global bin" number is defined.
239 For example, assuming a 3-D histogram with (binx, biny, binz), the function
240~~~ {.cpp}
241 Int_t gbin = h->GetBin(binx, biny, binz);
242~~~
243 returns a global/linearized gbin number. This global gbin is useful
244 to access the bin content/error information independently of the dimension.
245 Note that to access the information other than bin content and errors
246 one should use the TAxis object directly with e.g.:
247~~~ {.cpp}
248 Double_t xcenter = h3->GetZaxis()->GetBinCenter(27);
249~~~
250 returns the center along z of bin number 27 (not the global bin)
251 in the 3-D histogram h3.
252
253\anchor alpha
254### Alphanumeric Bin Labels
255
256 By default, a histogram axis is drawn with its numeric bin labels.
257 One can specify alphanumeric labels instead with:
258
259 - call TAxis::SetBinLabel(bin, label);
260 This can always be done before or after filling.
261 When the histogram is drawn, bin labels will be automatically drawn.
262 See examples labels1.C and labels2.C
263 - call to a Fill function with one of the arguments being a string, e.g.
264~~~ {.cpp}
265 hist1->Fill(somename, weight);
266 hist2->Fill(x, somename, weight);
267 hist2->Fill(somename, y, weight);
268 hist2->Fill(somenamex, somenamey, weight);
269~~~
270 See examples hlabels1.C and hlabels2.C
271 - via TTree::Draw. see for example cernstaff.C
272~~~ {.cpp}
273 tree.Draw("Nation::Division");
274~~~
275 where "Nation" and "Division" are two branches of a Tree.
276
277When using the options 2 or 3 above, the labels are automatically
278 added to the list (THashList) of labels for a given axis.
279 By default, an axis is drawn with the order of bins corresponding
280 to the filling sequence. It is possible to reorder the axis
281
282 - alphabetically
283 - by increasing or decreasing values
284
285 The reordering can be triggered via the TAxis context menu by selecting
286 the menu item "LabelsOption" or by calling directly
287 TH1::LabelsOption(option, axis) where
288
289 - axis may be "X", "Y" or "Z"
290 - option may be:
291 - "a" sort by alphabetic order
292 - ">" sort by decreasing values
293 - "<" sort by increasing values
294 - "h" draw labels horizontal
295 - "v" draw labels vertical
296 - "u" draw labels up (end of label right adjusted)
297 - "d" draw labels down (start of label left adjusted)
298
299 When using the option 2 above, new labels are added by doubling the current
300 number of bins in case one label does not exist yet.
301 When the Filling is terminated, it is possible to trim the number
302 of bins to match the number of active labels by calling
303~~~ {.cpp}
304 TH1::LabelsDeflate(axis) with axis = "X", "Y" or "Z"
305~~~
306 This operation is automatic when using TTree::Draw.
307 Once bin labels have been created, they become persistent if the histogram
308 is written to a file or when generating the C++ code via SavePrimitive.
309
310\anchor auto-bin
311### Histograms with automatic bins
312
313 When a histogram is created with an axis lower limit greater or equal
314 to its upper limit, the SetBuffer is automatically called with an
315 argument fBufferSize equal to fgBufferSize (default value=1000).
316 fgBufferSize may be reset via the static function TH1::SetDefaultBufferSize.
317 The axis limits will be automatically computed when the buffer will
318 be full or when the function BufferEmpty is called.
319
320\anchor rebinning
321### Rebinning
322
323 At any time, a histogram can be rebinned via TH1::Rebin. This function
324 returns a new histogram with the rebinned contents.
325 If bin errors were stored, they are recomputed during the rebinning.
326
327
328\anchor filling-histograms
329## Filling histograms
331 A histogram is typically filled with statements like:
332~~~ {.cpp}
333 h1->Fill(x);
334 h1->Fill(x, w); //fill with weight
335 h2->Fill(x, y)
336 h2->Fill(x, y, w)
337 h3->Fill(x, y, z)
338 h3->Fill(x, y, z, w)
339~~~
340 or via one of the Fill functions accepting names described above.
341 The Fill functions compute the bin number corresponding to the given
342 x, y or z argument and increment this bin by the given weight.
343 The Fill functions return the bin number for 1-D histograms or global
344 bin number for 2-D and 3-D histograms.
345 If TH1::Sumw2 has been called before filling, the sum of squares of
346 weights is also stored.
347 One can also increment directly a bin number via TH1::AddBinContent
348 or replace the existing content via TH1::SetBinContent. Passing an
349 out-of-range bin to TH1::AddBinContent leads to undefined behavior.
350 To access the bin content of a given bin, do:
351~~~ {.cpp}
352 Double_t binContent = h->GetBinContent(bin);
353~~~
354
355 By default, the bin number is computed using the current axis ranges.
356 If the automatic binning option has been set via
357~~~ {.cpp}
358 h->SetCanExtend(TH1::kAllAxes);
359~~~
360 then, the Fill Function will automatically extend the axis range to
361 accomodate the new value specified in the Fill argument. The method
362 used is to double the bin size until the new value fits in the range,
363 merging bins two by two. This automatic binning options is extensively
364 used by the TTree::Draw function when histogramming Tree variables
365 with an unknown range.
366 This automatic binning option is supported for 1-D, 2-D and 3-D histograms.
367
368 During filling, some statistics parameters are incremented to compute
369 the mean value and Root Mean Square with the maximum precision.
370
371 In case of histograms of type TH1C, TH1S, TH2C, TH2S, TH3C, TH3S
372 a check is made that the bin contents do not exceed the maximum positive
373 capacity (127 or 32767). Histograms of all types may have positive
374 or/and negative bin contents.
375
376\anchor associated-errors
377### Associated errors
378 By default, for each bin, the sum of weights is computed at fill time.
379 One can also call TH1::Sumw2 to force the storage and computation
380 of the sum of the square of weights per bin.
381 If Sumw2 has been called, the error per bin is computed as the
382 sqrt(sum of squares of weights), otherwise the error is set equal
383 to the sqrt(bin content).
384 To return the error for a given bin number, do:
385~~~ {.cpp}
386 Double_t error = h->GetBinError(bin);
387~~~
388
389\anchor associated-functions
390### Associated functions
391 One or more object (typically a TF1*) can be added to the list
392 of functions (fFunctions) associated to each histogram.
393 When TH1::Fit is invoked, the fitted function is added to this list.
394 Given a histogram h, one can retrieve an associated function
395 with:
396~~~ {.cpp}
397 TF1 *myfunc = h->GetFunction("myfunc");
398~~~
399
400
401\anchor operations-on-histograms
402## Operations on histograms
403
404 Many types of operations are supported on histograms or between histograms
405
406 - Addition of a histogram to the current histogram.
407 - Additions of two histograms with coefficients and storage into the current
408 histogram.
409 - Multiplications and Divisions are supported in the same way as additions.
410 - The Add, Divide and Multiply functions also exist to add, divide or multiply
411 a histogram by a function.
412
413 If a histogram has associated error bars (TH1::Sumw2 has been called),
414 the resulting error bars are also computed assuming independent histograms.
415 In case of divisions, Binomial errors are also supported.
416 One can mark a histogram to be an "average" histogram by setting its bit kIsAverage via
417 myhist.SetBit(TH1::kIsAverage);
418 When adding (see TH1::Add) average histograms, the histograms are averaged and not summed.
419
420
421\anchor prof-hist
422### Projections of histograms
423
424 One can:
425
426 - make a 1-D projection of a 2-D histogram or Profile
427 see functions TH2::ProjectionX,Y, TH2::ProfileX,Y, TProfile::ProjectionX
428 - make a 1-D, 2-D or profile out of a 3-D histogram
429 see functions TH3::ProjectionZ, TH3::Project3D.
430
431 One can fit these projections via:
432~~~ {.cpp}
433 TH2::FitSlicesX,Y, TH3::FitSlicesZ.
434~~~
435
436\anchor random-numbers
437### Random Numbers and histograms
438
439 TH1::FillRandom can be used to randomly fill a histogram using
440 the contents of an existing TF1 function or another
441 TH1 histogram (for all dimensions).
442 For example, the following two statements create and fill a histogram
443 10000 times with a default gaussian distribution of mean 0 and sigma 1:
444~~~ {.cpp}
445 TH1F h1("h1", "histo from a gaussian", 100, -3, 3);
446 h1.FillRandom("gaus", 10000);
447~~~
448 TH1::GetRandom can be used to return a random number distributed
449 according to the contents of a histogram.
450
451\anchor making-a-copy
452### Making a copy of a histogram
453 Like for any other ROOT object derived from TObject, one can use
454 the Clone() function. This makes an identical copy of the original
455 histogram including all associated errors and functions, e.g.:
456~~~ {.cpp}
457 TH1F *hnew = (TH1F*)h->Clone("hnew");
458~~~
459
460\anchor normalizing
461### Normalizing histograms
462
463 One can scale a histogram such that the bins integral is equal to
464 the normalization parameter via TH1::Scale(Double_t norm), where norm
465 is the desired normalization divided by the integral of the histogram.
466
467
468\anchor drawing-histograms
469## Drawing histograms
470
471 Histograms are drawn via the THistPainter class. Each histogram has
472 a pointer to its own painter (to be usable in a multithreaded program).
473 Many drawing options are supported.
474 See THistPainter::Paint() for more details.
475
476 The same histogram can be drawn with different options in different pads.
477 When a histogram drawn in a pad is deleted, the histogram is
478 automatically removed from the pad or pads where it was drawn.
479 If a histogram is drawn in a pad, then filled again, the new status
480 of the histogram will be automatically shown in the pad next time
481 the pad is updated. One does not need to redraw the histogram.
482 To draw the current version of a histogram in a pad, one can use
483~~~ {.cpp}
484 h->DrawCopy();
485~~~
486 This makes a clone (see Clone below) of the histogram. Once the clone
487 is drawn, the original histogram may be modified or deleted without
488 affecting the aspect of the clone.
489
490 One can use TH1::SetMaximum() and TH1::SetMinimum() to force a particular
491 value for the maximum or the minimum scale on the plot. (For 1-D
492 histograms this means the y-axis, while for 2-D histograms these
493 functions affect the z-axis).
494
495 TH1::UseCurrentStyle() can be used to change all histogram graphics
496 attributes to correspond to the current selected style.
497 This function must be called for each histogram.
498 In case one reads and draws many histograms from a file, one can force
499 the histograms to inherit automatically the current graphics style
500 by calling before gROOT->ForceStyle().
501
502\anchor cont-level
503### Setting Drawing histogram contour levels (2-D hists only)
504
505 By default contours are automatically generated at equidistant
506 intervals. A default value of 20 levels is used. This can be modified
507 via TH1::SetContour() or TH1::SetContourLevel().
508 the contours level info is used by the drawing options "cont", "surf",
509 and "lego".
510
511\anchor graph-att
512### Setting histogram graphics attributes
513
514 The histogram classes inherit from the attribute classes:
515 TAttLine, TAttFill, and TAttMarker.
516 See the member functions of these classes for the list of options.
517
518\anchor axis-drawing
519### Customizing how axes are drawn
520
521 Use the functions of TAxis, such as
522~~~ {.cpp}
523 histogram.GetXaxis()->SetTicks("+");
524 histogram.GetYaxis()->SetRangeUser(1., 5.);
525~~~
526
527\anchor fitting-histograms
528## Fitting histograms
529
530 Histograms (1-D, 2-D, 3-D and Profiles) can be fitted with a user
531 specified function or a pre-defined function via TH1::Fit.
532 See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for the fitting documentation and the possible [fitting options](\ref HFitOpt)
533
534 The FitPanel can also be used for fitting an histogram. See the [FitPanel documentation](https://root.cern/manual/fitting/#using-the-fit-panel).
535
536\anchor saving-histograms
537## Saving/reading histograms to/from a ROOT file
538
539 The following statements create a ROOT file and store a histogram
540 on the file. Because TH1 derives from TNamed, the key identifier on
541 the file is the histogram name:
542~~~ {.cpp}
543 TFile f("histos.root", "new");
544 TH1F h1("hgaus", "histo from a gaussian", 100, -3, 3);
545 h1.FillRandom("gaus", 10000);
546 h1->Write();
547~~~
548 To read this histogram in another Root session, do:
549~~~ {.cpp}
550 TFile f("histos.root");
551 TH1F *h = (TH1F*)f.Get("hgaus");
552~~~
553 One can save all histograms in memory to the file by:
554~~~ {.cpp}
555 file->Write();
556~~~
557
558
559\anchor misc
560## Miscellaneous operations
561
562~~~ {.cpp}
563 TH1::KolmogorovTest(): statistical test of compatibility in shape
564 between two histograms
565 TH1::Smooth() smooths the bin contents of a 1-d histogram
566 TH1::Integral() returns the integral of bin contents in a given bin range
567 TH1::GetMean(int axis) returns the mean value along axis
568 TH1::GetStdDev(int axis) returns the sigma distribution along axis
569 TH1::GetEntries() returns the number of entries
570 TH1::Reset() resets the bin contents and errors of a histogram
571~~~
572 IMPORTANT NOTE: The returned values for GetMean and GetStdDev depend on how the
573 histogram statistics are calculated. By default, if no range has been set, the
574 returned values are the (unbinned) ones calculated at fill time. If a range has been
575 set, however, the values are calculated using the bins in range; THIS IS TRUE EVEN
576 IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset the range.
577 To ensure that the returned values are always those of the binned data stored in the
578 histogram, call TH1::ResetStats. See TH1::GetStats.
579*/
580
581TF1 *gF1=nullptr; //left for back compatibility (use TVirtualFitter::GetUserFunc instead)
582
587
588extern void H1InitGaus();
589extern void H1InitExpo();
590extern void H1InitPolynom();
591extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
592extern void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail);
593extern void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b);
594
595namespace {
596
597/// Enumeration specifying inconsistencies between two histograms,
598/// in increasing severity.
599enum EInconsistencyBits {
600 kFullyConsistent = 0,
601 kDifferentLabels = BIT(0),
602 kDifferentBinLimits = BIT(1),
603 kDifferentAxisLimits = BIT(2),
604 kDifferentNumberOfBins = BIT(3),
605 kDifferentDimensions = BIT(4)
606};
607
608} // namespace
609
611
612////////////////////////////////////////////////////////////////////////////////
613/// Histogram default constructor.
614
616{
617 fDirectory = nullptr;
618 fFunctions = new TList;
619 fNcells = 0;
620 fIntegral = nullptr;
621 fPainter = nullptr;
622 fEntries = 0;
623 fNormFactor = 0;
625 fMaximum = -1111;
626 fMinimum = -1111;
627 fBufferSize = 0;
628 fBuffer = nullptr;
631 fXaxis.SetName("xaxis");
632 fYaxis.SetName("yaxis");
633 fZaxis.SetName("zaxis");
634 fXaxis.SetParent(this);
635 fYaxis.SetParent(this);
636 fZaxis.SetParent(this);
638}
639
640////////////////////////////////////////////////////////////////////////////////
641/// Histogram default destructor.
642
644{
646 return;
647 }
648 delete[] fIntegral;
649 fIntegral = nullptr;
650 delete[] fBuffer;
651 fBuffer = nullptr;
652 if (fFunctions) {
654
656 TObject* obj = nullptr;
657 //special logic to support the case where the same object is
658 //added multiple times in fFunctions.
659 //This case happens when the same object is added with different
660 //drawing modes
661 //In the loop below we must be careful with objects (eg TCutG) that may
662 // have been added to the list of functions of several histograms
663 //and may have been already deleted.
664 while ((obj = fFunctions->First())) {
665 while(fFunctions->Remove(obj)) { }
667 break;
668 }
669 delete obj;
670 obj = nullptr;
671 }
672 delete fFunctions;
673 fFunctions = nullptr;
674 }
675 if (fDirectory) {
676 fDirectory->Remove(this);
677 fDirectory = nullptr;
678 }
679 delete fPainter;
680 fPainter = nullptr;
681}
682
683////////////////////////////////////////////////////////////////////////////////
684/// Constructor for fix bin size histograms.
685/// Creates the main histogram structure.
686///
687/// \param[in] name name of histogram (avoid blanks)
688/// \param[in] title histogram title.
689/// If title is of the form `stringt;stringx;stringy;stringz`,
690/// the histogram title is set to `stringt`,
691/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
692/// \param[in] nbins number of bins
693/// \param[in] xlow low edge of first bin
694/// \param[in] xup upper edge of last bin (not included in last bin)
695
696
697TH1::TH1(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
698 :TNamed(name,title)
699{
700 Build();
701 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
702 fXaxis.Set(nbins,xlow,xup);
703 fNcells = fXaxis.GetNbins()+2;
704}
705
706////////////////////////////////////////////////////////////////////////////////
707/// Constructor for variable bin size histograms using an input array of type float.
708/// Creates the main histogram structure.
709///
710/// \param[in] name name of histogram (avoid blanks)
711/// \param[in] title histogram title.
712/// If title is of the form `stringt;stringx;stringy;stringz`
713/// the histogram title is set to `stringt`,
714/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
715/// \param[in] nbins number of bins
716/// \param[in] xbins array of low-edges for each bin.
717/// This is an array of type float and size nbins+1
718
719TH1::TH1(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
720 :TNamed(name,title)
721{
722 Build();
723 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
724 if (xbins) fXaxis.Set(nbins,xbins);
725 else fXaxis.Set(nbins,0,1);
726 fNcells = fXaxis.GetNbins()+2;
727}
728
729////////////////////////////////////////////////////////////////////////////////
730/// Constructor for variable bin size histograms using an input array of type double.
731///
732/// \param[in] name name of histogram (avoid blanks)
733/// \param[in] title histogram title.
734/// If title is of the form `stringt;stringx;stringy;stringz`
735/// the histogram title is set to `stringt`,
736/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
737/// \param[in] nbins number of bins
738/// \param[in] xbins array of low-edges for each bin.
739/// This is an array of type double and size nbins+1
740
741TH1::TH1(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
742 :TNamed(name,title)
743{
744 Build();
745 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
746 if (xbins) fXaxis.Set(nbins,xbins);
747 else fXaxis.Set(nbins,0,1);
748 fNcells = fXaxis.GetNbins()+2;
749}
750
751////////////////////////////////////////////////////////////////////////////////
752/// Static function: cannot be inlined on Windows/NT.
753
755{
756 return fgAddDirectory;
757}
758
759////////////////////////////////////////////////////////////////////////////////
760/// Browse the Histogram object.
761
763{
764 Draw(b ? b->GetDrawOption() : "");
765 gPad->Update();
766}
767
768////////////////////////////////////////////////////////////////////////////////
769/// Creates histogram basic data structure.
770
772{
773 fDirectory = nullptr;
774 fPainter = nullptr;
775 fIntegral = nullptr;
776 fEntries = 0;
777 fNormFactor = 0;
779 fMaximum = -1111;
780 fMinimum = -1111;
781 fBufferSize = 0;
782 fBuffer = nullptr;
785 fXaxis.SetName("xaxis");
786 fYaxis.SetName("yaxis");
787 fZaxis.SetName("zaxis");
788 fYaxis.Set(1,0.,1.);
789 fZaxis.Set(1,0.,1.);
790 fXaxis.SetParent(this);
791 fYaxis.SetParent(this);
792 fZaxis.SetParent(this);
793
795
796 fFunctions = new TList;
797
799
802 if (fDirectory) {
804 fDirectory->Append(this,kTRUE);
805 }
806 }
807}
808
809////////////////////////////////////////////////////////////////////////////////
810/// Performs the operation: `this = this + c1*f1`
811/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
812///
813/// By default, the function is computed at the centre of the bin.
814/// if option "I" is specified (1-d histogram only), the integral of the
815/// function in each bin is used instead of the value of the function at
816/// the centre of the bin.
817///
818/// Only bins inside the function range are recomputed.
819///
820/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
821/// you should call Sumw2 before making this operation.
822/// This is particularly important if you fit the histogram after TH1::Add
823///
824/// The function return kFALSE if the Add operation failed
825
827{
828 if (!f1) {
829 Error("Add","Attempt to add a non-existing function");
830 return kFALSE;
831 }
832
833 TString opt = option;
834 opt.ToLower();
835 Bool_t integral = kFALSE;
836 if (opt.Contains("i") && fDimension == 1) integral = kTRUE;
837
838 Int_t ncellsx = GetNbinsX() + 2; // cells = normal bins + underflow bin + overflow bin
839 Int_t ncellsy = GetNbinsY() + 2;
840 Int_t ncellsz = GetNbinsZ() + 2;
841 if (fDimension < 2) ncellsy = 1;
842 if (fDimension < 3) ncellsz = 1;
843
844 // delete buffer if it is there since it will become invalid
845 if (fBuffer) BufferEmpty(1);
846
847 // - Add statistics
848 Double_t s1[10];
849 for (Int_t i = 0; i < 10; ++i) s1[i] = 0;
850 PutStats(s1);
851 SetMinimum();
852 SetMaximum();
853
854 // - Loop on bins (including underflows/overflows)
855 Int_t bin, binx, biny, binz;
856 Double_t cu=0;
857 Double_t xx[3];
858 Double_t *params = nullptr;
859 f1->InitArgs(xx,params);
860 for (binz = 0; binz < ncellsz; ++binz) {
861 xx[2] = fZaxis.GetBinCenter(binz);
862 for (biny = 0; biny < ncellsy; ++biny) {
863 xx[1] = fYaxis.GetBinCenter(biny);
864 for (binx = 0; binx < ncellsx; ++binx) {
865 xx[0] = fXaxis.GetBinCenter(binx);
866 if (!f1->IsInside(xx)) continue;
868 bin = binx + ncellsx * (biny + ncellsy * binz);
869 if (integral) {
870 cu = c1*f1->Integral(fXaxis.GetBinLowEdge(binx), fXaxis.GetBinUpEdge(binx), 0.) / fXaxis.GetBinWidth(binx);
871 } else {
872 cu = c1*f1->EvalPar(xx);
873 }
874 if (TF1::RejectedPoint()) continue;
875 AddBinContent(bin,cu);
876 }
877 }
878 }
879
880 return kTRUE;
881}
882
883int TH1::LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge) const
884{
885 const auto inconsistency = CheckConsistency(h1, h2);
886
887 if (inconsistency & kDifferentDimensions) {
888 if (useMerge)
889 Info(name, "Histograms have different dimensions - trying to use TH1::Merge");
890 else {
891 Error(name, "Histograms have different dimensions");
892 }
893 } else if (inconsistency & kDifferentNumberOfBins) {
894 if (useMerge)
895 Info(name, "Histograms have different number of bins - trying to use TH1::Merge");
896 else {
897 Error(name, "Histograms have different number of bins");
898 }
899 } else if (inconsistency & kDifferentAxisLimits) {
900 if (useMerge)
901 Info(name, "Histograms have different axis limits - trying to use TH1::Merge");
902 else
903 Warning(name, "Histograms have different axis limits");
904 } else if (inconsistency & kDifferentBinLimits) {
905 if (useMerge)
906 Info(name, "Histograms have different bin limits - trying to use TH1::Merge");
907 else
908 Warning(name, "Histograms have different bin limits");
909 } else if (inconsistency & kDifferentLabels) {
910 // in case of different labels -
911 if (useMerge)
912 Info(name, "Histograms have different labels - trying to use TH1::Merge");
913 else
914 Info(name, "Histograms have different labels");
915 }
916
917 return inconsistency;
918}
919
920////////////////////////////////////////////////////////////////////////////////
921/// Performs the operation: `this = this + c1*h1`
922/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
923///
924/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
925/// if not already set.
926///
927/// Note also that adding histogram with labels is not supported, histogram will be
928/// added merging them by bin number independently of the labels.
929/// For adding histogram with labels one should use TH1::Merge
930///
931/// SPECIAL CASE (Average/Efficiency histograms)
932/// For histograms representing averages or efficiencies, one should compute the average
933/// of the two histograms and not the sum. One can mark a histogram to be an average
934/// histogram by setting its bit kIsAverage with
935/// myhist.SetBit(TH1::kIsAverage);
936/// Note that the two histograms must have their kIsAverage bit set
937///
938/// IMPORTANT NOTE1: If you intend to use the errors of this histogram later
939/// you should call Sumw2 before making this operation.
940/// This is particularly important if you fit the histogram after TH1::Add
941///
942/// IMPORTANT NOTE2: if h1 has a normalisation factor, the normalisation factor
943/// is used , ie this = this + c1*factor*h1
944/// Use the other TH1::Add function if you do not want this feature
945///
946/// IMPORTANT NOTE3: You should be careful about the statistics of the
947/// returned histogram, whose statistics may be binned or unbinned,
948/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
949/// and whether TH1::ResetStats has been called on either this or h1.
950/// See TH1::GetStats.
951///
952/// The function return kFALSE if the Add operation failed
953
955{
956 if (!h1) {
957 Error("Add","Attempt to add a non-existing histogram");
958 return kFALSE;
959 }
960
961 // delete buffer if it is there since it will become invalid
962 if (fBuffer) BufferEmpty(1);
963
964 bool useMerge = false;
965 const bool considerMerge = (c1 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
966 const auto inconsistency = LoggedInconsistency("Add", this, h1, considerMerge);
967 // If there is a bad inconsistency and we can't even consider merging, just give up
968 if(inconsistency >= kDifferentNumberOfBins && !considerMerge) {
969 return false;
970 }
971 // If there is an inconsistency, we try to use merging
972 if(inconsistency > kFullyConsistent) {
973 useMerge = considerMerge;
974 }
975
976 if (useMerge) {
977 TList l;
978 l.Add(const_cast<TH1*>(h1));
979 auto iret = Merge(&l);
980 return (iret >= 0);
981 }
982
983 // Create Sumw2 if h1 has Sumw2 set
984 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
985
986 // - Add statistics
987 Double_t entries = TMath::Abs( GetEntries() + c1 * h1->GetEntries() );
988
989 // statistics can be preserved only in case of positive coefficients
990 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
991 Bool_t resetStats = (c1 < 0);
992 Double_t s1[kNstat] = {0};
993 Double_t s2[kNstat] = {0};
994 if (!resetStats) {
995 // need to initialize to zero s1 and s2 since
996 // GetStats fills only used elements depending on dimension and type
997 GetStats(s1);
998 h1->GetStats(s2);
999 }
1000
1001 SetMinimum();
1002 SetMaximum();
1003
1004 // - Loop on bins (including underflows/overflows)
1005 Double_t factor = 1;
1006 if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();
1007 Double_t c1sq = c1 * c1;
1008 Double_t factsq = factor * factor;
1009
1010 for (Int_t bin = 0; bin < fNcells; ++bin) {
1011 //special case where histograms have the kIsAverage bit set
1012 if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
1014 Double_t y2 = this->RetrieveBinContent(bin);
1015 Double_t e1sq = h1->GetBinErrorSqUnchecked(bin);
1016 Double_t e2sq = this->GetBinErrorSqUnchecked(bin);
1017 Double_t w1 = 1., w2 = 1.;
1018
1019 // consider all special cases when bin errors are zero
1020 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1021 if (e1sq) w1 = 1. / e1sq;
1022 else if (h1->fSumw2.fN) {
1023 w1 = 1.E200; // use an arbitrary huge value
1024 if (y1 == 0) {
1025 // use an estimated error from the global histogram scale
1026 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1027 w1 = 1./(sf*sf);
1028 }
1029 }
1030 if (e2sq) w2 = 1. / e2sq;
1031 else if (fSumw2.fN) {
1032 w2 = 1.E200; // use an arbitrary huge value
1033 if (y2 == 0) {
1034 // use an estimated error from the global histogram scale
1035 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1036 w2 = 1./(sf*sf);
1037 }
1038 }
1039
1040 double y = (w1*y1 + w2*y2)/(w1 + w2);
1041 UpdateBinContent(bin, y);
1042 if (fSumw2.fN) {
1043 double err2 = 1./(w1 + w2);
1044 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1045 fSumw2.fArray[bin] = err2;
1046 }
1047 } else { // normal case of addition between histograms
1048 AddBinContent(bin, c1 * factor * h1->RetrieveBinContent(bin));
1049 if (fSumw2.fN) fSumw2.fArray[bin] += c1sq * factsq * h1->GetBinErrorSqUnchecked(bin);
1050 }
1051 }
1052
1053 // update statistics (do here to avoid changes by SetBinContent)
1054 if (resetStats) {
1055 // statistics need to be reset in case coefficient are negative
1056 ResetStats();
1057 }
1058 else {
1059 for (Int_t i=0;i<kNstat;i++) {
1060 if (i == 1) s1[i] += c1*c1*s2[i];
1061 else s1[i] += c1*s2[i];
1062 }
1063 PutStats(s1);
1064 SetEntries(entries);
1065 }
1066 return kTRUE;
1067}
1068
1069////////////////////////////////////////////////////////////////////////////////
1070/// Replace contents of this histogram by the addition of h1 and h2.
1071///
1072/// `this = c1*h1 + c2*h2`
1073/// if errors are defined (see TH1::Sumw2), errors are also recalculated
1074///
1075/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
1076/// if not already set.
1077///
1078/// Note also that adding histogram with labels is not supported, histogram will be
1079/// added merging them by bin number independently of the labels.
1080/// For adding histogram ith labels one should use TH1::Merge
1081///
1082/// SPECIAL CASE (Average/Efficiency histograms)
1083/// For histograms representing averages or efficiencies, one should compute the average
1084/// of the two histograms and not the sum. One can mark a histogram to be an average
1085/// histogram by setting its bit kIsAverage with
1086/// myhist.SetBit(TH1::kIsAverage);
1087/// Note that the two histograms must have their kIsAverage bit set
1088///
1089/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
1090/// you should call Sumw2 before making this operation.
1091/// This is particularly important if you fit the histogram after TH1::Add
1092///
1093/// IMPORTANT NOTE2: You should be careful about the statistics of the
1094/// returned histogram, whose statistics may be binned or unbinned,
1095/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
1096/// and whether TH1::ResetStats has been called on either this or h1.
1097/// See TH1::GetStats.
1098///
1099/// ANOTHER SPECIAL CASE : h1 = h2 and c2 < 0
1100/// do a scaling this = c1 * h1 / (bin Volume)
1101///
1102/// The function returns kFALSE if the Add operation failed
1103
1105{
1106
1107 if (!h1 || !h2) {
1108 Error("Add","Attempt to add a non-existing histogram");
1109 return kFALSE;
1110 }
1111
1112 // delete buffer if it is there since it will become invalid
1113 if (fBuffer) BufferEmpty(1);
1114
1115 Bool_t normWidth = kFALSE;
1116 if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
1117
1118 if (h1 != h2) {
1119 bool useMerge = false;
1120 const bool considerMerge = (c1 == 1. && c2 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
1121
1122 // We can combine inconsistencies like this, since they are ordered and a
1123 // higher inconsistency is worse
1124 auto const inconsistency = std::max(LoggedInconsistency("Add", this, h1, considerMerge),
1125 LoggedInconsistency("Add", h1, h2, considerMerge));
1126
1127 // If there is a bad inconsistency and we can't even consider merging, just give up
1128 if(inconsistency >= kDifferentNumberOfBins && !considerMerge) {
1129 return false;
1130 }
1131 // If there is an inconsistency, we try to use merging
1132 if(inconsistency > kFullyConsistent) {
1133 useMerge = considerMerge;
1134 }
1135
1136 if (useMerge) {
1137 TList l;
1138 // why TList takes non-const pointers ????
1139 l.Add(const_cast<TH1*>(h1));
1140 l.Add(const_cast<TH1*>(h2));
1141 Reset("ICE");
1142 auto iret = Merge(&l);
1143 return (iret >= 0);
1144 }
1145 }
1146
1147 // Create Sumw2 if h1 or h2 have Sumw2 set
1148 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
1149
1150 // - Add statistics
1151 Double_t nEntries = TMath::Abs( c1*h1->GetEntries() + c2*h2->GetEntries() );
1152
1153 // TODO remove
1154 // statistics can be preserved only in case of positive coefficients
1155 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1156 // also in case of scaling with the width we cannot preserve the statistics
1157 Double_t s1[kNstat] = {0};
1158 Double_t s2[kNstat] = {0};
1159 Double_t s3[kNstat];
1160
1161
1162 Bool_t resetStats = (c1*c2 < 0) || normWidth;
1163 if (!resetStats) {
1164 // need to initialize to zero s1 and s2 since
1165 // GetStats fills only used elements depending on dimension and type
1166 h1->GetStats(s1);
1167 h2->GetStats(s2);
1168 for (Int_t i=0;i<kNstat;i++) {
1169 if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
1170 //else s3[i] = TMath::Abs(c1)*s1[i] + TMath::Abs(c2)*s2[i];
1171 else s3[i] = c1*s1[i] + c2*s2[i];
1172 }
1173 }
1174
1175 SetMinimum();
1176 SetMaximum();
1177
1178 if (normWidth) { // DEPRECATED CASE: belongs to fitting / drawing modules
1179
1180 Int_t nbinsx = GetNbinsX() + 2; // normal bins + underflow, overflow
1181 Int_t nbinsy = GetNbinsY() + 2;
1182 Int_t nbinsz = GetNbinsZ() + 2;
1183
1184 if (fDimension < 2) nbinsy = 1;
1185 if (fDimension < 3) nbinsz = 1;
1186
1187 Int_t bin, binx, biny, binz;
1188 for (binz = 0; binz < nbinsz; ++binz) {
1189 Double_t wz = h1->GetZaxis()->GetBinWidth(binz);
1190 for (biny = 0; biny < nbinsy; ++biny) {
1191 Double_t wy = h1->GetYaxis()->GetBinWidth(biny);
1192 for (binx = 0; binx < nbinsx; ++binx) {
1193 Double_t wx = h1->GetXaxis()->GetBinWidth(binx);
1194 bin = GetBin(binx, biny, binz);
1195 Double_t w = wx*wy*wz;
1196 UpdateBinContent(bin, c1 * h1->RetrieveBinContent(bin) / w);
1197 if (fSumw2.fN) {
1198 Double_t e1 = h1->GetBinError(bin)/w;
1199 fSumw2.fArray[bin] = c1*c1*e1*e1;
1200 }
1201 }
1202 }
1203 }
1204 } else if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
1205 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
1206 // special case where histograms have the kIsAverage bit set
1208 Double_t y2 = h2->RetrieveBinContent(i);
1210 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
1211 Double_t w1 = 1., w2 = 1.;
1212
1213 // consider all special cases when bin errors are zero
1214 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1215 if (e1sq) w1 = 1./ e1sq;
1216 else if (h1->fSumw2.fN) {
1217 w1 = 1.E200; // use an arbitrary huge value
1218 if (y1 == 0 ) { // use an estimated error from the global histogram scale
1219 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1220 w1 = 1./(sf*sf);
1221 }
1222 }
1223 if (e2sq) w2 = 1./ e2sq;
1224 else if (h2->fSumw2.fN) {
1225 w2 = 1.E200; // use an arbitrary huge value
1226 if (y2 == 0) { // use an estimated error from the global histogram scale
1227 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1228 w2 = 1./(sf*sf);
1229 }
1230 }
1231
1232 double y = (w1*y1 + w2*y2)/(w1 + w2);
1233 UpdateBinContent(i, y);
1234 if (fSumw2.fN) {
1235 double err2 = 1./(w1 + w2);
1236 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1237 fSumw2.fArray[i] = err2;
1238 }
1239 }
1240 } else { // case of simple histogram addition
1241 Double_t c1sq = c1 * c1;
1242 Double_t c2sq = c2 * c2;
1243 for (Int_t i = 0; i < fNcells; ++i) { // Loop on cells (bins including underflows/overflows)
1244 UpdateBinContent(i, c1 * h1->RetrieveBinContent(i) + c2 * h2->RetrieveBinContent(i));
1245 if (fSumw2.fN) {
1246 fSumw2.fArray[i] = c1sq * h1->GetBinErrorSqUnchecked(i) + c2sq * h2->GetBinErrorSqUnchecked(i);
1247 }
1248 }
1249 }
1250
1251 if (resetStats) {
1252 // statistics need to be reset in case coefficient are negative
1253 ResetStats();
1254 }
1255 else {
1256 // update statistics (do here to avoid changes by SetBinContent) FIXME remove???
1257 PutStats(s3);
1258 SetEntries(nEntries);
1259 }
1260
1261 return kTRUE;
1262}
1263
1264////////////////////////////////////////////////////////////////////////////////
1265/// Increment bin content by 1.
1266/// Passing an out-of-range bin leads to undefined behavior
1267
1269{
1270 AbstractMethod("AddBinContent");
1271}
1272
1273////////////////////////////////////////////////////////////////////////////////
1274/// Increment bin content by a weight w.
1275/// Passing an out-of-range bin leads to undefined behavior
1276
1278{
1279 AbstractMethod("AddBinContent");
1280}
1281
1282////////////////////////////////////////////////////////////////////////////////
1283/// Sets the flag controlling the automatic add of histograms in memory
1284///
1285/// By default (fAddDirectory = kTRUE), histograms are automatically added
1286/// to the list of objects in memory.
1287/// Note that one histogram can be removed from its support directory
1288/// by calling h->SetDirectory(nullptr) or h->SetDirectory(dir) to add it
1289/// to the list of objects in the directory dir.
1290///
1291/// NOTE that this is a static function. To call it, use;
1292/// TH1::AddDirectory
1293
1295{
1296 fgAddDirectory = add;
1297}
1298
1299////////////////////////////////////////////////////////////////////////////////
1300/// Auxiliary function to get the power of 2 next (larger) or previous (smaller)
1301/// a given x
1302///
1303/// next = kTRUE : next larger
1304/// next = kFALSE : previous smaller
1305///
1306/// Used by the autobin power of 2 algorithm
1307
1309{
1310 Int_t nn;
1311 Double_t f2 = std::frexp(x, &nn);
1312 return ((next && x > 0.) || (!next && x <= 0.)) ? std::ldexp(std::copysign(1., f2), nn)
1313 : std::ldexp(std::copysign(1., f2), --nn);
1314}
1315
1316////////////////////////////////////////////////////////////////////////////////
1317/// Auxiliary function to get the next power of 2 integer value larger then n
1318///
1319/// Used by the autobin power of 2 algorithm
1320
1322{
1323 Int_t nn;
1324 Double_t f2 = std::frexp(n, &nn);
1325 if (TMath::Abs(f2 - .5) > 0.001)
1326 return (Int_t)std::ldexp(1., nn);
1327 return n;
1328}
1329
1330////////////////////////////////////////////////////////////////////////////////
1331/// Buffer-based estimate of the histogram range using the power of 2 algorithm.
1332///
1333/// Used by the autobin power of 2 algorithm.
1334///
1335/// Works on arguments (min and max from fBuffer) and internal inputs: fXmin,
1336/// fXmax, NBinsX (from fXaxis), ...
1337/// Result save internally in fXaxis.
1338///
1339/// Overloaded by TH2 and TH3.
1340///
1341/// Return -1 if internal inputs are inconsistent, 0 otherwise.
1342
1344{
1345 // We need meaningful raw limits
1346 if (xmi >= xma)
1347 return -1;
1348
1350 Double_t xhmi = fXaxis.GetXmin();
1351 Double_t xhma = fXaxis.GetXmax();
1352
1353 // Now adjust
1354 if (TMath::Abs(xhma) > TMath::Abs(xhmi)) {
1355 // Start from the upper limit
1356 xhma = TH1::AutoP2GetPower2(xhma);
1357 xhmi = xhma - TH1::AutoP2GetPower2(xhma - xhmi);
1358 } else {
1359 // Start from the lower limit
1360 xhmi = TH1::AutoP2GetPower2(xhmi, kFALSE);
1361 xhma = xhmi + TH1::AutoP2GetPower2(xhma - xhmi);
1362 }
1363
1364 // Round the bins to the next power of 2; take into account the possible inflation
1365 // of the range
1366 Double_t rr = (xhma - xhmi) / (xma - xmi);
1367 Int_t nb = TH1::AutoP2GetBins((Int_t)(rr * GetNbinsX()));
1368
1369 // Adjust using the same bin width and offsets
1370 Double_t bw = (xhma - xhmi) / nb;
1371 // Bins to left free on each side
1372 Double_t autoside = gEnv->GetValue("Hist.Binning.Auto.Side", 0.05);
1373 Int_t nbside = (Int_t)(nb * autoside);
1374
1375 // Side up
1376 Int_t nbup = (xhma - xma) / bw;
1377 if (nbup % 2 != 0)
1378 nbup++; // Must be even
1379 if (nbup != nbside) {
1380 // Accounts also for both case: larger or smaller
1381 xhma -= bw * (nbup - nbside);
1382 nb -= (nbup - nbside);
1383 }
1384
1385 // Side low
1386 Int_t nblw = (xmi - xhmi) / bw;
1387 if (nblw % 2 != 0)
1388 nblw++; // Must be even
1389 if (nblw != nbside) {
1390 // Accounts also for both case: larger or smaller
1391 xhmi += bw * (nblw - nbside);
1392 nb -= (nblw - nbside);
1393 }
1394
1395 // Set everything and project
1396 SetBins(nb, xhmi, xhma);
1397
1398 // Done
1399 return 0;
1400}
1401
1402/// Fill histogram with all entries in the buffer.
1403///
1404/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
1405/// - action = 0 histogram is reset and filled from the buffer. When the histogram is filled from the
1406/// buffer the value fBuffer[0] is set to a negative number (= - number of entries)
1407/// When calling with action == 0 the histogram is NOT refilled when fBuffer[0] is < 0
1408/// While when calling with action = -1 the histogram is reset and ALWAYS refilled independently if
1409/// the histogram was filled before. This is needed when drawing the histogram
1410/// - action = 1 histogram is filled and buffer is deleted
1411/// The buffer is automatically deleted when filling the histogram and the entries is
1412/// larger than the buffer size
1413
1415{
1416 // do we need to compute the bin size?
1417 if (!fBuffer) return 0;
1418 Int_t nbentries = (Int_t)fBuffer[0];
1419
1420 // nbentries correspond to the number of entries of histogram
1421
1422 if (nbentries == 0) {
1423 // if action is 1 we delete the buffer
1424 // this will avoid infinite recursion
1425 if (action > 0) {
1426 delete [] fBuffer;
1427 fBuffer = nullptr;
1428 fBufferSize = 0;
1429 }
1430 return 0;
1431 }
1432 if (nbentries < 0 && action == 0) return 0; // case histogram has been already filled from the buffer
1433
1434 Double_t *buffer = fBuffer;
1435 if (nbentries < 0) {
1436 nbentries = -nbentries;
1437 // a reset might call BufferEmpty() giving an infinite recursion
1438 // Protect it by setting fBuffer = nullptr
1439 fBuffer = nullptr;
1440 //do not reset the list of functions
1441 Reset("ICES");
1442 fBuffer = buffer;
1443 }
1444 if (CanExtendAllAxes() || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
1445 //find min, max of entries in buffer
1448 for (Int_t i=0;i<nbentries;i++) {
1449 Double_t x = fBuffer[2*i+2];
1450 // skip infinity or NaN values
1451 if (!std::isfinite(x)) continue;
1452 if (x < xmin) xmin = x;
1453 if (x > xmax) xmax = x;
1454 }
1455 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
1456 Int_t rc = -1;
1458 if ((rc = AutoP2FindLimits(xmin, xmax)) < 0)
1459 Warning("BufferEmpty",
1460 "inconsistency found by power-of-2 autobin algorithm: fallback to standard method");
1461 }
1462 if (rc < 0)
1464 } else {
1465 fBuffer = nullptr;
1466 Int_t keep = fBufferSize; fBufferSize = 0;
1468 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax, &fXaxis);
1469 fBuffer = buffer;
1470 fBufferSize = keep;
1471 }
1472 }
1473
1474 // call DoFillN which will not put entries in the buffer as FillN does
1475 // set fBuffer to zero to avoid re-emptying the buffer from functions called
1476 // by DoFillN (e.g Sumw2)
1477 buffer = fBuffer; fBuffer = nullptr;
1478 DoFillN(nbentries,&buffer[2],&buffer[1],2);
1479 fBuffer = buffer;
1480
1481 // if action == 1 - delete the buffer
1482 if (action > 0) {
1483 delete [] fBuffer;
1484 fBuffer = nullptr;
1485 fBufferSize = 0;
1486 } else {
1487 // if number of entries is consistent with buffer - set it negative to avoid
1488 // refilling the histogram every time BufferEmpty(0) is called
1489 // In case it is not consistent, by setting fBuffer[0]=0 is like resetting the buffer
1490 // (it will not be used anymore the next time BufferEmpty is called)
1491 if (nbentries == (Int_t)fEntries)
1492 fBuffer[0] = -nbentries;
1493 else
1494 fBuffer[0] = 0;
1495 }
1496 return nbentries;
1497}
1498
1499////////////////////////////////////////////////////////////////////////////////
1500/// accumulate arguments in buffer. When buffer is full, empty the buffer
1501///
1502/// - `fBuffer[0]` = number of entries in buffer
1503/// - `fBuffer[1]` = w of first entry
1504/// - `fBuffer[2]` = x of first entry
1505
1507{
1508 if (!fBuffer) return -2;
1509 Int_t nbentries = (Int_t)fBuffer[0];
1510
1511
1512 if (nbentries < 0) {
1513 // reset nbentries to a positive value so next time BufferEmpty() is called
1514 // the histogram will be refilled
1515 nbentries = -nbentries;
1516 fBuffer[0] = nbentries;
1517 if (fEntries > 0) {
1518 // set fBuffer to zero to avoid calling BufferEmpty in Reset
1519 Double_t *buffer = fBuffer; fBuffer=nullptr;
1520 Reset("ICES"); // do not reset list of functions
1521 fBuffer = buffer;
1522 }
1523 }
1524 if (2*nbentries+2 >= fBufferSize) {
1525 BufferEmpty(1);
1526 if (!fBuffer)
1527 // to avoid infinite recursion Fill->BufferFill->Fill
1528 return Fill(x,w);
1529 // this cannot happen
1530 R__ASSERT(0);
1531 }
1532 fBuffer[2*nbentries+1] = w;
1533 fBuffer[2*nbentries+2] = x;
1534 fBuffer[0] += 1;
1535 return -2;
1536}
1537
1538////////////////////////////////////////////////////////////////////////////////
1539/// Check bin limits.
1540
1541bool TH1::CheckBinLimits(const TAxis* a1, const TAxis * a2)
1542{
1543 const TArrayD * h1Array = a1->GetXbins();
1544 const TArrayD * h2Array = a2->GetXbins();
1545 Int_t fN = h1Array->fN;
1546 if ( fN != 0 ) {
1547 if ( h2Array->fN != fN ) {
1548 return false;
1549 }
1550 else {
1551 for ( int i = 0; i < fN; ++i ) {
1552 // for i==fN (nbin+1) a->GetBinWidth() returns last bin width
1553 // we do not need to exclude that case
1554 double binWidth = a1->GetBinWidth(i);
1555 if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), binWidth*1E-10 ) ) {
1556 return false;
1557 }
1558 }
1559 }
1560 }
1561
1562 return true;
1563}
1564
1565////////////////////////////////////////////////////////////////////////////////
1566/// Check that axis have same labels.
1567
1568bool TH1::CheckBinLabels(const TAxis* a1, const TAxis * a2)
1569{
1570 THashList *l1 = a1->GetLabels();
1571 THashList *l2 = a2->GetLabels();
1572
1573 if (!l1 && !l2 )
1574 return true;
1575 if (!l1 || !l2 ) {
1576 return false;
1577 }
1578 // check now labels sizes are the same
1579 if (l1->GetSize() != l2->GetSize() ) {
1580 return false;
1581 }
1582 for (int i = 1; i <= a1->GetNbins(); ++i) {
1583 TString label1 = a1->GetBinLabel(i);
1584 TString label2 = a2->GetBinLabel(i);
1585 if (label1 != label2) {
1586 return false;
1587 }
1588 }
1589
1590 return true;
1591}
1592
1593////////////////////////////////////////////////////////////////////////////////
1594/// Check that the axis limits of the histograms are the same.
1595/// If a first and last bin is passed the axis is compared between the given range
1596
1597bool TH1::CheckAxisLimits(const TAxis *a1, const TAxis *a2 )
1598{
1599 double firstBin = a1->GetBinWidth(1);
1600 double lastBin = a1->GetBinWidth( a1->GetNbins() );
1601 if ( ! TMath::AreEqualAbs(a1->GetXmin(), a2->GetXmin(), firstBin* 1.E-10) ||
1602 ! TMath::AreEqualAbs(a1->GetXmax(), a2->GetXmax(), lastBin*1.E-10) ) {
1603 return false;
1604 }
1605 return true;
1606}
1607
1608////////////////////////////////////////////////////////////////////////////////
1609/// Check that the axis are the same
1610
1611bool TH1::CheckEqualAxes(const TAxis *a1, const TAxis *a2 )
1612{
1613 if (a1->GetNbins() != a2->GetNbins() ) {
1614 ::Info("CheckEqualAxes","Axes have different number of bins : nbin1 = %d nbin2 = %d",a1->GetNbins(),a2->GetNbins() );
1615 return false;
1616 }
1617 if(!CheckAxisLimits(a1,a2)) {
1618 ::Info("CheckEqualAxes","Axes have different limits");
1619 return false;
1620 }
1621 if(!CheckBinLimits(a1,a2)) {
1622 ::Info("CheckEqualAxes","Axes have different bin limits");
1623 return false;
1624 }
1625
1626 // check labels
1627 if(!CheckBinLabels(a1,a2)) {
1628 ::Info("CheckEqualAxes","Axes have different labels");
1629 return false;
1630 }
1631
1632 return true;
1633}
1634
1635////////////////////////////////////////////////////////////////////////////////
1636/// Check that two sub axis are the same.
1637/// The limits are defined by first bin and last bin
1638/// N.B. no check is done in this case for variable bins
1639
1640bool TH1::CheckConsistentSubAxes(const TAxis *a1, Int_t firstBin1, Int_t lastBin1, const TAxis * a2, Int_t firstBin2, Int_t lastBin2 )
1641{
1642 // By default is assumed that no bins are given for the second axis
1643 Int_t nbins1 = lastBin1-firstBin1 + 1;
1644 Double_t xmin1 = a1->GetBinLowEdge(firstBin1);
1645 Double_t xmax1 = a1->GetBinUpEdge(lastBin1);
1646
1647 Int_t nbins2 = a2->GetNbins();
1648 Double_t xmin2 = a2->GetXmin();
1649 Double_t xmax2 = a2->GetXmax();
1650
1651 if (firstBin2 < lastBin2) {
1652 // in this case assume no bins are given for the second axis
1653 nbins2 = lastBin1-firstBin1 + 1;
1654 xmin2 = a1->GetBinLowEdge(firstBin1);
1655 xmax2 = a1->GetBinUpEdge(lastBin1);
1656 }
1657
1658 if (nbins1 != nbins2 ) {
1659 ::Info("CheckConsistentSubAxes","Axes have different number of bins");
1660 return false;
1661 }
1662
1663 Double_t firstBin = a1->GetBinWidth(firstBin1);
1664 Double_t lastBin = a1->GetBinWidth(lastBin1);
1665 if ( ! TMath::AreEqualAbs(xmin1,xmin2,1.E-10 * firstBin) ||
1666 ! TMath::AreEqualAbs(xmax1,xmax2,1.E-10 * lastBin) ) {
1667 ::Info("CheckConsistentSubAxes","Axes have different limits");
1668 return false;
1669 }
1670
1671 return true;
1672}
1673
1674////////////////////////////////////////////////////////////////////////////////
1675/// Check histogram compatibility.
1676
1677int TH1::CheckConsistency(const TH1* h1, const TH1* h2)
1678{
1679 if (h1 == h2) return kFullyConsistent;
1680
1681 if (h1->GetDimension() != h2->GetDimension() ) {
1682 return kDifferentDimensions;
1683 }
1684 Int_t dim = h1->GetDimension();
1685
1686 // returns kTRUE if number of bins and bin limits are identical
1687 Int_t nbinsx = h1->GetNbinsX();
1688 Int_t nbinsy = h1->GetNbinsY();
1689 Int_t nbinsz = h1->GetNbinsZ();
1690
1691 // Check whether the histograms have the same number of bins.
1692 if (nbinsx != h2->GetNbinsX() ||
1693 (dim > 1 && nbinsy != h2->GetNbinsY()) ||
1694 (dim > 2 && nbinsz != h2->GetNbinsZ()) ) {
1695 return kDifferentNumberOfBins;
1696 }
1697
1698 bool ret = true;
1699
1700 // check axis limits
1701 ret &= CheckAxisLimits(h1->GetXaxis(), h2->GetXaxis());
1702 if (dim > 1) ret &= CheckAxisLimits(h1->GetYaxis(), h2->GetYaxis());
1703 if (dim > 2) ret &= CheckAxisLimits(h1->GetZaxis(), h2->GetZaxis());
1704 if (!ret) return kDifferentAxisLimits;
1705
1706 // check bin limits
1707 ret &= CheckBinLimits(h1->GetXaxis(), h2->GetXaxis());
1708 if (dim > 1) ret &= CheckBinLimits(h1->GetYaxis(), h2->GetYaxis());
1709 if (dim > 2) ret &= CheckBinLimits(h1->GetZaxis(), h2->GetZaxis());
1710 if (!ret) return kDifferentBinLimits;
1711
1712 // check labels if histograms are both not empty
1713 if ( !h1->IsEmpty() && !h2->IsEmpty() ) {
1714 ret &= CheckBinLabels(h1->GetXaxis(), h2->GetXaxis());
1715 if (dim > 1) ret &= CheckBinLabels(h1->GetYaxis(), h2->GetYaxis());
1716 if (dim > 2) ret &= CheckBinLabels(h1->GetZaxis(), h2->GetZaxis());
1717 if (!ret) return kDifferentLabels;
1718 }
1719
1720 return kFullyConsistent;
1721}
1722
1723////////////////////////////////////////////////////////////////////////////////
1724/// \f$ \chi^{2} \f$ test for comparing weighted and unweighted histograms.
1725///
1726/// Compares the histograms' adjusted (normalized) residuals.
1727/// Function: Returns p-value. Other return values are specified by the 3rd parameter
1728///
1729/// \param[in] h2 the second histogram
1730/// \param[in] option
1731/// - "UU" = experiment experiment comparison (unweighted-unweighted)
1732/// - "UW" = experiment MC comparison (unweighted-weighted). Note that
1733/// the first histogram should be unweighted
1734/// - "WW" = MC MC comparison (weighted-weighted)
1735/// - "NORM" = to be used when one or both of the histograms is scaled
1736/// but the histogram originally was unweighted
1737/// - by default underflows and overflows are not included:
1738/// * "OF" = overflows included
1739/// * "UF" = underflows included
1740/// - "P" = print chi2, ndf, p_value, igood
1741/// - "CHI2" = returns chi2 instead of p-value
1742/// - "CHI2/NDF" = returns \f$ \chi^{2} \f$/ndf
1743/// \param[in] res not empty - computes normalized residuals and returns them in this array
1744///
1745/// The current implementation is based on the papers \f$ \chi^{2} \f$ test for comparison
1746/// of weighted and unweighted histograms" in Proceedings of PHYSTAT05 and
1747/// "Comparison weighted and unweighted histograms", arXiv:physics/0605123
1748/// by N.Gagunashvili. This function has been implemented by Daniel Haertl in August 2006.
1749///
1750/// #### Introduction:
1751///
1752/// A frequently used technique in data analysis is the comparison of
1753/// histograms. First suggested by Pearson [1] the \f$ \chi^{2} \f$ test of
1754/// homogeneity is used widely for comparing usual (unweighted) histograms.
1755/// This paper describes the implementation modified \f$ \chi^{2} \f$ tests
1756/// for comparison of weighted and unweighted histograms and two weighted
1757/// histograms [2] as well as usual Pearson's \f$ \chi^{2} \f$ test for
1758/// comparison two usual (unweighted) histograms.
1759///
1760/// #### Overview:
1761///
1762/// Comparison of two histograms expect hypotheses that two histograms
1763/// represent identical distributions. To make a decision p-value should
1764/// be calculated. The hypotheses of identity is rejected if the p-value is
1765/// lower then some significance level. Traditionally significance levels
1766/// 0.1, 0.05 and 0.01 are used. The comparison procedure should include an
1767/// analysis of the residuals which is often helpful in identifying the
1768/// bins of histograms responsible for a significant overall \f$ \chi^{2} \f$ value.
1769/// Residuals are the difference between bin contents and expected bin
1770/// contents. Most convenient for analysis are the normalized residuals. If
1771/// hypotheses of identity are valid then normalized residuals are
1772/// approximately independent and identically distributed random variables
1773/// having N(0,1) distribution. Analysis of residuals expect test of above
1774/// mentioned properties of residuals. Notice that indirectly the analysis
1775/// of residuals increase the power of \f$ \chi^{2} \f$ test.
1776///
1777/// #### Methods of comparison:
1778///
1779/// \f$ \chi^{2} \f$ test for comparison two (unweighted) histograms:
1780/// Let us consider two histograms with the same binning and the number
1781/// of bins equal to r. Let us denote the number of events in the ith bin
1782/// in the first histogram as ni and as mi in the second one. The total
1783/// number of events in the first histogram is equal to:
1784/// \f[
1785/// N = \sum_{i=1}^{r} n_{i}
1786/// \f]
1787/// and
1788/// \f[
1789/// M = \sum_{i=1}^{r} m_{i}
1790/// \f]
1791/// in the second histogram. The hypothesis of identity (homogeneity) [3]
1792/// is that the two histograms represent random values with identical
1793/// distributions. It is equivalent that there exist r constants p1,...,pr,
1794/// such that
1795/// \f[
1796///\sum_{i=1}^{r} p_{i}=1
1797/// \f]
1798/// and the probability of belonging to the ith bin for some measured value
1799/// in both experiments is equal to pi. The number of events in the ith
1800/// bin is a random variable with a distribution approximated by a Poisson
1801/// probability distribution
1802/// \f[
1803///\frac{e^{-Np_{i}}(Np_{i})^{n_{i}}}{n_{i}!}
1804/// \f]
1805///for the first histogram and with distribution
1806/// \f[
1807///\frac{e^{-Mp_{i}}(Mp_{i})^{m_{i}}}{m_{i}!}
1808/// \f]
1809/// for the second histogram. If the hypothesis of homogeneity is valid,
1810/// then the maximum likelihood estimator of pi, i=1,...,r, is
1811/// \f[
1812///\hat{p}_{i}= \frac{n_{i}+m_{i}}{N+M}
1813/// \f]
1814/// and then
1815/// \f[
1816/// 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}}
1817/// \f]
1818/// has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [3].
1819/// The comparison procedure can include an analysis of the residuals which
1820/// is often helpful in identifying the bins of histograms responsible for
1821/// a significant overall \f$ \chi^{2} \f$ value. Most convenient for
1822/// analysis are the adjusted (normalized) residuals [4]
1823/// \f[
1824/// 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))}}
1825/// \f]
1826/// If hypotheses of homogeneity are valid then residuals ri are
1827/// approximately independent and identically distributed random variables
1828/// having N(0,1) distribution. The application of the \f$ \chi^{2} \f$ test has
1829/// restrictions related to the value of the expected frequencies Npi,
1830/// Mpi, i=1,...,r. A conservative rule formulated in [5] is that all the
1831/// expectations must be 1 or greater for both histograms. In practical
1832/// cases when expected frequencies are not known the estimated expected
1833/// frequencies \f$ M\hat{p}_{i}, N\hat{p}_{i}, i=1,...,r \f$ can be used.
1834///
1835/// #### Unweighted and weighted histograms comparison:
1836///
1837/// A simple modification of the ideas described above can be used for the
1838/// comparison of the usual (unweighted) and weighted histograms. Let us
1839/// denote the number of events in the ith bin in the unweighted
1840/// histogram as ni and the common weight of events in the ith bin of the
1841/// weighted histogram as wi. The total number of events in the
1842/// unweighted histogram is equal to
1843///\f[
1844/// N = \sum_{i=1}^{r} n_{i}
1845///\f]
1846/// and the total weight of events in the weighted histogram is equal to
1847///\f[
1848/// W = \sum_{i=1}^{r} w_{i}
1849///\f]
1850/// Let us formulate the hypothesis of identity of an unweighted histogram
1851/// to a weighted histogram so that there exist r constants p1,...,pr, such
1852/// that
1853///\f[
1854/// \sum_{i=1}^{r} p_{i} = 1
1855///\f]
1856/// for the unweighted histogram. The weight wi is a random variable with a
1857/// distribution approximated by the normal probability distribution
1858/// \f$ N(Wp_{i},\sigma_{i}^{2}) \f$ where \f$ \sigma_{i}^{2} \f$ is the variance of the weight wi.
1859/// If we replace the variance \f$ \sigma_{i}^{2} \f$
1860/// with estimate \f$ s_{i}^{2} \f$ (sum of squares of weights of
1861/// events in the ith bin) and the hypothesis of identity is valid, then the
1862/// maximum likelihood estimator of pi,i=1,...,r, is
1863///\f[
1864/// \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}}
1865///\f]
1866/// We may then use the test statistic
1867///\f[
1868/// 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}}
1869///\f]
1870/// and it has approximately a \f$ \sigma^{2}_{(r-1)} \f$ distribution [2]. This test, as well
1871/// as the original one [3], has a restriction on the expected frequencies. The
1872/// expected frequencies recommended for the weighted histogram is more than 25.
1873/// The value of the minimal expected frequency can be decreased down to 10 for
1874/// the case when the weights of the events are close to constant. In the case
1875/// of a weighted histogram if the number of events is unknown, then we can
1876/// apply this recommendation for the equivalent number of events as
1877///\f[
1878/// n_{i}^{equiv} = \frac{ w_{i}^{2} }{ s_{i}^{2} }
1879///\f]
1880/// The minimal expected frequency for an unweighted histogram must be 1. Notice
1881/// that any usual (unweighted) histogram can be considered as a weighted
1882/// histogram with events that have constant weights equal to 1.
1883/// The variance \f$ z_{i}^{2} \f$ of the difference between the weight wi
1884/// and the estimated expectation value of the weight is approximately equal to:
1885///\f[
1886/// 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}
1887///\f]
1888/// The residuals
1889///\f[
1890/// r_{i} = \frac{w_{i}-W\hat{p}_{i}}{z_{i}}
1891///\f]
1892/// have approximately a normal distribution with mean equal to 0 and standard
1893/// deviation equal to 1.
1894///
1895/// #### Two weighted histograms comparison:
1896///
1897/// Let us denote the common weight of events of the ith bin in the first
1898/// histogram as w1i and as w2i in the second one. The total weight of events
1899/// in the first histogram is equal to
1900///\f[
1901/// W_{1} = \sum_{i=1}^{r} w_{1i}
1902///\f]
1903/// and
1904///\f[
1905/// W_{2} = \sum_{i=1}^{r} w_{2i}
1906///\f]
1907/// in the second histogram. Let us formulate the hypothesis of identity of
1908/// weighted histograms so that there exist r constants p1,...,pr, such that
1909///\f[
1910/// \sum_{i=1}^{r} p_{i} = 1
1911///\f]
1912/// and also expectation value of weight w1i equal to W1pi and expectation value
1913/// of weight w2i equal to W2pi. Weights in both the histograms are random
1914/// variables with distributions which can be approximated by a normal
1915/// probability distribution \f$ N(W_{1}p_{i},\sigma_{1i}^{2}) \f$ for the first histogram
1916/// and by a distribution \f$ N(W_{2}p_{i},\sigma_{2i}^{2}) \f$ for the second.
1917/// Here \f$ \sigma_{1i}^{2} \f$ and \f$ \sigma_{2i}^{2} \f$ are the variances
1918/// of w1i and w2i with estimators \f$ s_{1i}^{2} \f$ and \f$ s_{2i}^{2} \f$ respectively.
1919/// If the hypothesis of identity is valid, then the maximum likelihood and
1920/// Least Square Method estimator of pi,i=1,...,r, is
1921///\f[
1922/// \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}}
1923///\f]
1924/// We may then use the test statistic
1925///\f[
1926/// 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}}
1927///\f]
1928/// and it has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [2].
1929/// The normalized or studentised residuals [6]
1930///\f[
1931/// 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})}}}
1932///\f]
1933/// have approximately a normal distribution with mean equal to 0 and standard
1934/// deviation 1. A recommended minimal expected frequency is equal to 10 for
1935/// the proposed test.
1936///
1937/// #### Numerical examples:
1938///
1939/// The method described herein is now illustrated with an example.
1940/// We take a distribution
1941///\f[
1942/// \phi(x) = \frac{2}{(x-10)^{2}+1} + \frac{1}{(x-14)^{2}+1} (1)
1943///\f]
1944/// defined on the interval [4,16]. Events distributed according to the formula
1945/// (1) are simulated to create the unweighted histogram. Uniformly distributed
1946/// events are simulated for the weighted histogram with weights calculated by
1947/// formula (1). Each histogram has the same number of bins: 20. Fig.1 shows
1948/// the result of comparison of the unweighted histogram with 200 events
1949/// (minimal expected frequency equal to one) and the weighted histogram with
1950/// 500 events (minimal expected frequency equal to 25)
1951/// Begin_Macro
1952/// ../../../tutorials/math/chi2test.C
1953/// End_Macro
1954/// Fig 1. An example of comparison of the unweighted histogram with 200 events
1955/// and the weighted histogram with 500 events:
1956/// 1. unweighted histogram;
1957/// 2. weighted histogram;
1958/// 3. normalized residuals plot;
1959/// 4. normal Q-Q plot of residuals.
1960///
1961/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1962/// 21.09 with p-value equal to 0.33, therefore the hypothesis of identity of
1963/// the two histograms can be accepted for 0.05 significant level. The behavior
1964/// of the normalized residuals plot (see Fig. 1c) and the normal Q-Q plot
1965/// (see Fig. 1d) of residuals are regular and we cannot identify the outliers
1966/// or bins with a big influence on \f$ \chi^{2} \f$.
1967///
1968/// The second example presents the same two histograms but 17 events was added
1969/// to content of bin number 15 in unweighted histogram. Fig.2 shows the result
1970/// of comparison of the unweighted histogram with 217 events (minimal expected
1971/// frequency equal to one) and the weighted histogram with 500 events (minimal
1972/// expected frequency equal to 25)
1973/// Begin_Macro
1974/// ../../../tutorials/math/chi2test.C(17)
1975/// End_Macro
1976/// Fig 2. An example of comparison of the unweighted histogram with 217 events
1977/// and the weighted histogram with 500 events:
1978/// 1. unweighted histogram;
1979/// 2. weighted histogram;
1980/// 3. normalized residuals plot;
1981/// 4. normal Q-Q plot of residuals.
1982///
1983/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1984/// 32.33 with p-value equal to 0.029, therefore the hypothesis of identity of
1985/// the two histograms is rejected for 0.05 significant level. The behavior of
1986/// the normalized residuals plot (see Fig. 2c) and the normal Q-Q plot (see
1987/// Fig. 2d) of residuals are not regular and we can identify the outlier or
1988/// bin with a big influence on \f$ \chi^{2} \f$.
1989///
1990/// #### References:
1991///
1992/// - [1] Pearson, K., 1904. On the Theory of Contingency and Its Relation to
1993/// Association and Normal Correlation. Drapers' Co. Memoirs, Biometric
1994/// Series No. 1, London.
1995/// - [2] Gagunashvili, N., 2006. \f$ \sigma^{2} \f$ test for comparison
1996/// of weighted and unweighted histograms. Statistical Problems in Particle
1997/// Physics, Astrophysics and Cosmology, Proceedings of PHYSTAT05,
1998/// Oxford, UK, 12-15 September 2005, Imperial College Press, London, 43-44.
1999/// Gagunashvili,N., Comparison of weighted and unweighted histograms,
2000/// arXiv:physics/0605123, 2006.
2001/// - [3] Cramer, H., 1946. Mathematical methods of statistics.
2002/// Princeton University Press, Princeton.
2003/// - [4] Haberman, S.J., 1973. The analysis of residuals in cross-classified tables.
2004/// Biometrics 29, 205-220.
2005/// - [5] Lewontin, R.C. and Felsenstein, J., 1965. The robustness of homogeneity
2006/// test in 2xN tables. Biometrics 21, 19-33.
2007/// - [6] Seber, G.A.F., Lee, A.J., 2003, Linear Regression Analysis.
2008/// John Wiley & Sons Inc., New York.
2009
2010Double_t TH1::Chi2Test(const TH1* h2, Option_t *option, Double_t *res) const
2011{
2012 Double_t chi2 = 0;
2013 Int_t ndf = 0, igood = 0;
2014
2015 TString opt = option;
2016 opt.ToUpper();
2017
2018 Double_t prob = Chi2TestX(h2,chi2,ndf,igood,option,res);
2019
2020 if(opt.Contains("P")) {
2021 printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
2022 }
2023 if(opt.Contains("CHI2/NDF")) {
2024 if (ndf == 0) return 0;
2025 return chi2/ndf;
2026 }
2027 if(opt.Contains("CHI2")) {
2028 return chi2;
2029 }
2030
2031 return prob;
2032}
2033
2034////////////////////////////////////////////////////////////////////////////////
2035/// The computation routine of the Chisquare test. For the method description,
2036/// see Chi2Test() function.
2037///
2038/// \return p-value
2039/// \param[in] h2 the second histogram
2040/// \param[in] option
2041/// - "UU" = experiment experiment comparison (unweighted-unweighted)
2042/// - "UW" = experiment MC comparison (unweighted-weighted). Note that the first
2043/// histogram should be unweighted
2044/// - "WW" = MC MC comparison (weighted-weighted)
2045/// - "NORM" = if one or both histograms is scaled
2046/// - "OF" = overflows included
2047/// - "UF" = underflows included
2048/// by default underflows and overflows are not included
2049/// \param[out] igood test output
2050/// - igood=0 - no problems
2051/// - For unweighted unweighted comparison
2052/// - igood=1'There is a bin in the 1st histogram with less than 1 event'
2053/// - igood=2'There is a bin in the 2nd histogram with less than 1 event'
2054/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2055/// - For unweighted weighted comparison
2056/// - igood=1'There is a bin in the 1st histogram with less then 1 event'
2057/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective number of events'
2058/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2059/// - For weighted weighted comparison
2060/// - igood=1'There is a bin in the 1st histogram with less then 10 effective
2061/// number of events'
2062/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective
2063/// number of events'
2064/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2065/// \param[out] chi2 chisquare of the test
2066/// \param[out] ndf number of degrees of freedom (important, when both histograms have the same empty bins)
2067/// \param[out] res normalized residuals for further analysis
2068
2069Double_t TH1::Chi2TestX(const TH1* h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option, Double_t *res) const
2070{
2071
2072 Int_t i_start, i_end;
2073 Int_t j_start, j_end;
2074 Int_t k_start, k_end;
2075
2076 Double_t sum1 = 0.0, sumw1 = 0.0;
2077 Double_t sum2 = 0.0, sumw2 = 0.0;
2078
2079 chi2 = 0.0;
2080 ndf = 0;
2081
2082 TString opt = option;
2083 opt.ToUpper();
2084
2085 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
2086
2087 const TAxis *xaxis1 = GetXaxis();
2088 const TAxis *xaxis2 = h2->GetXaxis();
2089 const TAxis *yaxis1 = GetYaxis();
2090 const TAxis *yaxis2 = h2->GetYaxis();
2091 const TAxis *zaxis1 = GetZaxis();
2092 const TAxis *zaxis2 = h2->GetZaxis();
2093
2094 Int_t nbinx1 = xaxis1->GetNbins();
2095 Int_t nbinx2 = xaxis2->GetNbins();
2096 Int_t nbiny1 = yaxis1->GetNbins();
2097 Int_t nbiny2 = yaxis2->GetNbins();
2098 Int_t nbinz1 = zaxis1->GetNbins();
2099 Int_t nbinz2 = zaxis2->GetNbins();
2100
2101 //check dimensions
2102 if (this->GetDimension() != h2->GetDimension() ){
2103 Error("Chi2TestX","Histograms have different dimensions.");
2104 return 0.0;
2105 }
2106
2107 //check number of channels
2108 if (nbinx1 != nbinx2) {
2109 Error("Chi2TestX","different number of x channels");
2110 }
2111 if (nbiny1 != nbiny2) {
2112 Error("Chi2TestX","different number of y channels");
2113 }
2114 if (nbinz1 != nbinz2) {
2115 Error("Chi2TestX","different number of z channels");
2116 }
2117
2118 //check for ranges
2119 i_start = j_start = k_start = 1;
2120 i_end = nbinx1;
2121 j_end = nbiny1;
2122 k_end = nbinz1;
2123
2124 if (xaxis1->TestBit(TAxis::kAxisRange)) {
2125 i_start = xaxis1->GetFirst();
2126 i_end = xaxis1->GetLast();
2127 }
2128 if (yaxis1->TestBit(TAxis::kAxisRange)) {
2129 j_start = yaxis1->GetFirst();
2130 j_end = yaxis1->GetLast();
2131 }
2132 if (zaxis1->TestBit(TAxis::kAxisRange)) {
2133 k_start = zaxis1->GetFirst();
2134 k_end = zaxis1->GetLast();
2135 }
2136
2137
2138 if (opt.Contains("OF")) {
2139 if (GetDimension() == 3) k_end = ++nbinz1;
2140 if (GetDimension() >= 2) j_end = ++nbiny1;
2141 if (GetDimension() >= 1) i_end = ++nbinx1;
2142 }
2143
2144 if (opt.Contains("UF")) {
2145 if (GetDimension() == 3) k_start = 0;
2146 if (GetDimension() >= 2) j_start = 0;
2147 if (GetDimension() >= 1) i_start = 0;
2148 }
2149
2150 ndf = (i_end - i_start + 1) * (j_end - j_start + 1) * (k_end - k_start + 1) - 1;
2151
2152 Bool_t comparisonUU = opt.Contains("UU");
2153 Bool_t comparisonUW = opt.Contains("UW");
2154 Bool_t comparisonWW = opt.Contains("WW");
2155 Bool_t scaledHistogram = opt.Contains("NORM");
2156
2157 if (scaledHistogram && !comparisonUU) {
2158 Info("Chi2TestX", "NORM option should be used together with UU option. It is ignored");
2159 }
2160
2161 // look at histo global bin content and effective entries
2162 Stat_t s[kNstat];
2163 GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2164 Double_t sumBinContent1 = s[0];
2165 Double_t effEntries1 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2166
2167 h2->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2168 Double_t sumBinContent2 = s[0];
2169 Double_t effEntries2 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2170
2171 if (!comparisonUU && !comparisonUW && !comparisonWW ) {
2172 // deduce automatically from type of histogram
2173 if (TMath::Abs(sumBinContent1 - effEntries1) < 1) {
2174 if ( TMath::Abs(sumBinContent2 - effEntries2) < 1) comparisonUU = true;
2175 else comparisonUW = true;
2176 }
2177 else comparisonWW = true;
2178 }
2179 // check unweighted histogram
2180 if (comparisonUW) {
2181 if (TMath::Abs(sumBinContent1 - effEntries1) >= 1) {
2182 Warning("Chi2TestX","First histogram is not unweighted and option UW has been requested");
2183 }
2184 }
2185 if ( (!scaledHistogram && comparisonUU) ) {
2186 if ( ( TMath::Abs(sumBinContent1 - effEntries1) >= 1) || (TMath::Abs(sumBinContent2 - effEntries2) >= 1) ) {
2187 Warning("Chi2TestX","Both histograms are not unweighted and option UU has been requested");
2188 }
2189 }
2190
2191
2192 //get number of events in histogram
2193 if (comparisonUU && scaledHistogram) {
2194 for (Int_t i = i_start; i <= i_end; ++i) {
2195 for (Int_t j = j_start; j <= j_end; ++j) {
2196 for (Int_t k = k_start; k <= k_end; ++k) {
2197
2198 Int_t bin = GetBin(i, j, k);
2199
2200 Double_t cnt1 = RetrieveBinContent(bin);
2201 Double_t cnt2 = h2->RetrieveBinContent(bin);
2202 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2203 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2204
2205 if (e1sq > 0.0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2206 else cnt1 = 0.0;
2207
2208 if (e2sq > 0.0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2209 else cnt2 = 0.0;
2210
2211 // sum contents
2212 sum1 += cnt1;
2213 sum2 += cnt2;
2214 sumw1 += e1sq;
2215 sumw2 += e2sq;
2216 }
2217 }
2218 }
2219 if (sumw1 <= 0.0 || sumw2 <= 0.0) {
2220 Error("Chi2TestX", "Cannot use option NORM when one histogram has all zero errors");
2221 return 0.0;
2222 }
2223
2224 } else {
2225 for (Int_t i = i_start; i <= i_end; ++i) {
2226 for (Int_t j = j_start; j <= j_end; ++j) {
2227 for (Int_t k = k_start; k <= k_end; ++k) {
2228
2229 Int_t bin = GetBin(i, j, k);
2230
2231 sum1 += RetrieveBinContent(bin);
2232 sum2 += h2->RetrieveBinContent(bin);
2233
2234 if ( comparisonWW ) sumw1 += GetBinErrorSqUnchecked(bin);
2235 if ( comparisonUW || comparisonWW ) sumw2 += h2->GetBinErrorSqUnchecked(bin);
2236 }
2237 }
2238 }
2239 }
2240 //checks that the histograms are not empty
2241 if (sum1 == 0.0 || sum2 == 0.0) {
2242 Error("Chi2TestX","one histogram is empty");
2243 return 0.0;
2244 }
2245
2246 if ( comparisonWW && ( sumw1 <= 0.0 && sumw2 <= 0.0 ) ){
2247 Error("Chi2TestX","Hist1 and Hist2 have both all zero errors\n");
2248 return 0.0;
2249 }
2250
2251 //THE TEST
2252 Int_t m = 0, n = 0;
2253
2254 //Experiment - experiment comparison
2255 if (comparisonUU) {
2256 Double_t sum = sum1 + sum2;
2257 for (Int_t i = i_start; i <= i_end; ++i) {
2258 for (Int_t j = j_start; j <= j_end; ++j) {
2259 for (Int_t k = k_start; k <= k_end; ++k) {
2260
2261 Int_t bin = GetBin(i, j, k);
2262
2263 Double_t cnt1 = RetrieveBinContent(bin);
2264 Double_t cnt2 = h2->RetrieveBinContent(bin);
2265
2266 if (scaledHistogram) {
2267 // scale bin value to effective bin entries
2268 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2269 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2270
2271 if (e1sq > 0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2272 else cnt1 = 0;
2273
2274 if (e2sq > 0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2275 else cnt2 = 0;
2276 }
2277
2278 if (Int_t(cnt1) == 0 && Int_t(cnt2) == 0) --ndf; // no data means one degree of freedom less
2279 else {
2280
2281 Double_t cntsum = cnt1 + cnt2;
2282 Double_t nexp1 = cntsum * sum1 / sum;
2283 //Double_t nexp2 = binsum*sum2/sum;
2284
2285 if (res) res[i - i_start] = (cnt1 - nexp1) / TMath::Sqrt(nexp1);
2286
2287 if (cnt1 < 1) ++m;
2288 if (cnt2 < 1) ++n;
2289
2290 //Habermann correction for residuals
2291 Double_t correc = (1. - sum1 / sum) * (1. - cntsum / sum);
2292 if (res) res[i - i_start] /= TMath::Sqrt(correc);
2293
2294 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2295 chi2 += delta * delta / cntsum;
2296 }
2297 }
2298 }
2299 }
2300 chi2 /= sum1 * sum2;
2301
2302 // flag error only when of the two histogram is zero
2303 if (m) {
2304 igood += 1;
2305 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2306 }
2307 if (n) {
2308 igood += 2;
2309 Info("Chi2TestX","There is a bin in h2 with less than 1 event.\n");
2310 }
2311
2312 Double_t prob = TMath::Prob(chi2,ndf);
2313 return prob;
2314
2315 }
2316
2317 // unweighted - weighted comparison
2318 // case of error = 0 and content not zero is treated without problems by excluding second chi2 sum
2319 // and can be considered as a data-theory comparison
2320 if ( comparisonUW ) {
2321 for (Int_t i = i_start; i <= i_end; ++i) {
2322 for (Int_t j = j_start; j <= j_end; ++j) {
2323 for (Int_t k = k_start; k <= k_end; ++k) {
2324
2325 Int_t bin = GetBin(i, j, k);
2326
2327 Double_t cnt1 = RetrieveBinContent(bin);
2328 Double_t cnt2 = h2->RetrieveBinContent(bin);
2329 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2330
2331 // case both histogram have zero bin contents
2332 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2333 --ndf; //no data means one degree of freedom less
2334 continue;
2335 }
2336
2337 // case weighted histogram has zero bin content and error
2338 if (cnt2 * cnt2 == 0 && e2sq == 0) {
2339 if (sumw2 > 0) {
2340 // use as approximated error as 1 scaled by a scaling ratio
2341 // estimated from the total sum weight and sum weight squared
2342 e2sq = sumw2 / sum2;
2343 }
2344 else {
2345 // return error because infinite discrepancy here:
2346 // bin1 != 0 and bin2 =0 in a histogram with all errors zero
2347 Error("Chi2TestX","Hist2 has in bin (%d,%d,%d) zero content and zero errors\n", i, j, k);
2348 chi2 = 0; return 0;
2349 }
2350 }
2351
2352 if (cnt1 < 1) m++;
2353 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2354
2355 Double_t var1 = sum2 * cnt2 - sum1 * e2sq;
2356 Double_t var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2357
2358 // if cnt1 is zero and cnt2 = 1 and sum1 = sum2 var1 = 0 && var2 == 0
2359 // approximate by incrementing cnt1
2360 // LM (this need to be fixed for numerical errors)
2361 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2362 sum1++;
2363 cnt1++;
2364 var1 = sum2 * cnt2 - sum1 * e2sq;
2365 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2366 }
2367 var2 = TMath::Sqrt(var2);
2368
2369 while (var1 + var2 == 0) {
2370 sum1++;
2371 cnt1++;
2372 var1 = sum2 * cnt2 - sum1 * e2sq;
2373 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2374 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2375 sum1++;
2376 cnt1++;
2377 var1 = sum2 * cnt2 - sum1 * e2sq;
2378 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2379 }
2380 var2 = TMath::Sqrt(var2);
2381 }
2382
2383 Double_t probb = (var1 + var2) / (2. * sum2 * sum2);
2384
2385 Double_t nexp1 = probb * sum1;
2386 Double_t nexp2 = probb * sum2;
2387
2388 Double_t delta1 = cnt1 - nexp1;
2389 Double_t delta2 = cnt2 - nexp2;
2390
2391 chi2 += delta1 * delta1 / nexp1;
2392
2393 if (e2sq > 0) {
2394 chi2 += delta2 * delta2 / e2sq;
2395 }
2396
2397 if (res) {
2398 if (e2sq > 0) {
2399 Double_t temp1 = sum2 * e2sq / var2;
2400 Double_t temp2 = 1.0 + (sum1 * e2sq - sum2 * cnt2) / var2;
2401 temp2 = temp1 * temp1 * sum1 * probb * (1.0 - probb) + temp2 * temp2 * e2sq / 4.0;
2402 // invert sign here
2403 res[i - i_start] = - delta2 / TMath::Sqrt(temp2);
2404 }
2405 else
2406 res[i - i_start] = delta1 / TMath::Sqrt(nexp1);
2407 }
2408 }
2409 }
2410 }
2411
2412 if (m) {
2413 igood += 1;
2414 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2415 }
2416 if (n) {
2417 igood += 2;
2418 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2419 }
2420
2421 Double_t prob = TMath::Prob(chi2, ndf);
2422
2423 return prob;
2424 }
2425
2426 // weighted - weighted comparison
2427 if (comparisonWW) {
2428 for (Int_t i = i_start; i <= i_end; ++i) {
2429 for (Int_t j = j_start; j <= j_end; ++j) {
2430 for (Int_t k = k_start; k <= k_end; ++k) {
2431
2432 Int_t bin = GetBin(i, j, k);
2433 Double_t cnt1 = RetrieveBinContent(bin);
2434 Double_t cnt2 = h2->RetrieveBinContent(bin);
2435 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2436 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2437
2438 // case both histogram have zero bin contents
2439 // (use square of content to avoid numerical errors)
2440 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2441 --ndf; //no data means one degree of freedom less
2442 continue;
2443 }
2444
2445 if (e1sq == 0 && e2sq == 0) {
2446 // cannot treat case of booth histogram have zero zero errors
2447 Error("Chi2TestX","h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
2448 chi2 = 0; return 0;
2449 }
2450
2451 Double_t sigma = sum1 * sum1 * e2sq + sum2 * sum2 * e1sq;
2452 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2453 chi2 += delta * delta / sigma;
2454
2455 if (res) {
2456 Double_t temp = cnt1 * sum1 * e2sq + cnt2 * sum2 * e1sq;
2457 Double_t probb = temp / sigma;
2458 Double_t z = 0;
2459 if (e1sq > e2sq) {
2460 Double_t d1 = cnt1 - sum1 * probb;
2461 Double_t s1 = e1sq * ( 1. - e2sq * sum1 * sum1 / sigma );
2462 z = d1 / TMath::Sqrt(s1);
2463 }
2464 else {
2465 Double_t d2 = cnt2 - sum2 * probb;
2466 Double_t s2 = e2sq * ( 1. - e1sq * sum2 * sum2 / sigma );
2467 z = -d2 / TMath::Sqrt(s2);
2468 }
2469 res[i - i_start] = z;
2470 }
2471
2472 if (e1sq > 0 && cnt1 * cnt1 / e1sq < 10) m++;
2473 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2474 }
2475 }
2476 }
2477 if (m) {
2478 igood += 1;
2479 Info("Chi2TestX","There is a bin in h1 with less than 10 effective events.\n");
2480 }
2481 if (n) {
2482 igood += 2;
2483 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2484 }
2485 Double_t prob = TMath::Prob(chi2, ndf);
2486 return prob;
2487 }
2488 return 0;
2489}
2490////////////////////////////////////////////////////////////////////////////////
2491/// Compute and return the chisquare of this histogram with respect to a function
2492/// The chisquare is computed by weighting each histogram point by the bin error
2493/// By default the full range of the histogram is used.
2494/// Use option "R" for restricting the chisquare calculation to the given range of the function
2495/// Use option "L" for using the chisquare based on the poisson likelihood (Baker-Cousins Chisquare)
2496/// Use option "P" for using the Pearson chisquare based on the expected bin errors
2497
2499{
2500 if (!func) {
2501 Error("Chisquare","Function pointer is Null - return -1");
2502 return -1;
2503 }
2504
2505 TString opt(option); opt.ToUpper();
2506 bool useRange = opt.Contains("R");
2507 ROOT::Fit::EChisquareType type = ROOT::Fit::EChisquareType::kNeyman; // default chi2 with observed error
2510
2511 return ROOT::Fit::Chisquare(*this, *func, useRange, type);
2512}
2513
2514////////////////////////////////////////////////////////////////////////////////
2515/// Remove all the content from the underflow and overflow bins, without changing the number of entries
2516/// After calling this method, every undeflow and overflow bins will have content 0.0
2517/// The Sumw2 is also cleared, since there is no more content in the bins
2518
2520{
2521 for (Int_t bin = 0; bin < fNcells; ++bin)
2522 if (IsBinUnderflow(bin) || IsBinOverflow(bin)) {
2523 UpdateBinContent(bin, 0.0);
2524 if (fSumw2.fN) fSumw2.fArray[bin] = 0.0;
2525 }
2526}
2527
2528////////////////////////////////////////////////////////////////////////////////
2529/// Compute integral (normalized cumulative sum of bins) w/o under/overflows
2530/// The result is stored in fIntegral and used by the GetRandom functions.
2531/// This function is automatically called by GetRandom when the fIntegral
2532/// array does not exist or when the number of entries in the histogram
2533/// has changed since the previous call to GetRandom.
2534/// The resulting integral is normalized to 1.
2535/// If the routine is called with the onlyPositive flag set an error will
2536/// be produced in case of negative bin content and a NaN value returned
2537/// \return 1 if success, 0 if integral is zero, NAN if onlyPositive-test fails
2538
2540{
2541 if (fBuffer) BufferEmpty();
2542
2543 // delete previously computed integral (if any)
2544 if (fIntegral) delete [] fIntegral;
2545
2546 // - Allocate space to store the integral and compute integral
2547 Int_t nbinsx = GetNbinsX();
2548 Int_t nbinsy = GetNbinsY();
2549 Int_t nbinsz = GetNbinsZ();
2550 Int_t nbins = nbinsx * nbinsy * nbinsz;
2551
2552 fIntegral = new Double_t[nbins + 2];
2553 Int_t ibin = 0; fIntegral[ibin] = 0;
2554
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 ++ibin;
2559 Double_t y = RetrieveBinContent(GetBin(binx, biny, binz));
2560 if (onlyPositive && y < 0) {
2561 Error("ComputeIntegral","Bin content is negative - return a NaN value");
2562 fIntegral[nbins] = TMath::QuietNaN();
2563 break;
2564 }
2565 fIntegral[ibin] = fIntegral[ibin - 1] + y;
2566 }
2567 }
2568 }
2569
2570 // - Normalize integral to 1
2571 if (fIntegral[nbins] == 0 ) {
2572 Error("ComputeIntegral", "Integral = 0, no hits in histogram bins (excluding over/underflow).");
2573 return 0;
2574 }
2575 for (Int_t bin=1; bin <= nbins; ++bin) fIntegral[bin] /= fIntegral[nbins];
2576 fIntegral[nbins+1] = fEntries;
2577 return fIntegral[nbins];
2578}
2579
2580////////////////////////////////////////////////////////////////////////////////
2581/// Return a pointer to the array of bins integral.
2582/// if the pointer fIntegral is null, TH1::ComputeIntegral is called
2583/// The array dimension is the number of bins in the histograms
2584/// including underflow and overflow (fNCells)
2585/// the last value integral[fNCells] is set to the number of entries of
2586/// the histogram
2587
2589{
2590 if (!fIntegral) ComputeIntegral();
2591 return fIntegral;
2592}
2593
2594////////////////////////////////////////////////////////////////////////////////
2595/// Return a pointer to a histogram containing the cumulative content.
2596/// The cumulative can be computed both in the forward (default) or backward
2597/// direction; the name of the new histogram is constructed from
2598/// the name of this histogram with the suffix "suffix" appended provided
2599/// by the user. If not provided a default suffix="_cumulative" is used.
2600///
2601/// The cumulative distribution is formed by filling each bin of the
2602/// resulting histogram with the sum of that bin and all previous
2603/// (forward == kTRUE) or following (forward = kFALSE) bins.
2604///
2605/// Note: while cumulative distributions make sense in one dimension, you
2606/// may not be getting what you expect in more than 1D because the concept
2607/// of a cumulative distribution is much trickier to define; make sure you
2608/// understand the order of summation before you use this method with
2609/// histograms of dimension >= 2.
2610///
2611/// Note 2: By default the cumulative is computed from bin 1 to Nbins
2612/// If an axis range is set, values between the minimum and maximum of the range
2613/// are set.
2614/// Setting an axis range can also be used for including underflow and overflow in
2615/// the cumulative (e.g. by setting h->GetXaxis()->SetRange(0, h->GetNbinsX()+1); )
2617
2618TH1 *TH1::GetCumulative(Bool_t forward, const char* suffix) const
2619{
2620 const Int_t firstX = fXaxis.GetFirst();
2621 const Int_t lastX = fXaxis.GetLast();
2622 const Int_t firstY = (fDimension > 1) ? fYaxis.GetFirst() : 1;
2623 const Int_t lastY = (fDimension > 1) ? fYaxis.GetLast() : 1;
2624 const Int_t firstZ = (fDimension > 1) ? fZaxis.GetFirst() : 1;
2625 const Int_t lastZ = (fDimension > 1) ? fZaxis.GetLast() : 1;
2626
2627 TH1* hintegrated = (TH1*) Clone(fName + suffix);
2628 hintegrated->Reset();
2629 Double_t sum = 0.;
2630 Double_t esum = 0;
2631 if (forward) { // Forward computation
2632 for (Int_t binz = firstZ; binz <= lastZ; ++binz) {
2633 for (Int_t biny = firstY; biny <= lastY; ++biny) {
2634 for (Int_t binx = firstX; binx <= lastX; ++binx) {
2635 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2636 sum += RetrieveBinContent(bin);
2637 hintegrated->AddBinContent(bin, sum);
2638 if (fSumw2.fN) {
2639 esum += GetBinErrorSqUnchecked(bin);
2640 hintegrated->fSumw2.fArray[bin] = esum;
2641 }
2642 }
2643 }
2644 }
2645 } else { // Backward computation
2646 for (Int_t binz = lastZ; binz >= firstZ; --binz) {
2647 for (Int_t biny = lastY; biny >= firstY; --biny) {
2648 for (Int_t binx = lastX; binx >= firstX; --binx) {
2649 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2650 sum += RetrieveBinContent(bin);
2651 hintegrated->AddBinContent(bin, sum);
2652 if (fSumw2.fN) {
2653 esum += GetBinErrorSqUnchecked(bin);
2654 hintegrated->fSumw2.fArray[bin] = esum;
2655 }
2656 }
2657 }
2658 }
2659 }
2660 return hintegrated;
2661}
2662
2663////////////////////////////////////////////////////////////////////////////////
2664/// Copy this histogram structure to newth1.
2665///
2666/// Note that this function does not copy the list of associated functions.
2667/// Use TObject::Clone to make a full copy of a histogram.
2668///
2669/// Note also that the histogram it will be created in gDirectory (if AddDirectoryStatus()=true)
2670/// or will not be added to any directory if AddDirectoryStatus()=false
2671/// independently of the current directory stored in the original histogram
2672
2673void TH1::Copy(TObject &obj) const
2674{
2675 if (((TH1&)obj).fDirectory) {
2676 // We are likely to change the hash value of this object
2677 // with TNamed::Copy, to keep things correct, we need to
2678 // clean up its existing entries.
2679 ((TH1&)obj).fDirectory->Remove(&obj);
2680 ((TH1&)obj).fDirectory = nullptr;
2681 }
2682 TNamed::Copy(obj);
2683 ((TH1&)obj).fDimension = fDimension;
2684 ((TH1&)obj).fNormFactor= fNormFactor;
2685 ((TH1&)obj).fNcells = fNcells;
2686 ((TH1&)obj).fBarOffset = fBarOffset;
2687 ((TH1&)obj).fBarWidth = fBarWidth;
2688 ((TH1&)obj).fOption = fOption;
2689 ((TH1&)obj).fBinStatErrOpt = fBinStatErrOpt;
2690 ((TH1&)obj).fBufferSize= fBufferSize;
2691 // copy the Buffer
2692 // delete first a previously existing buffer
2693 if (((TH1&)obj).fBuffer != nullptr) {
2694 delete [] ((TH1&)obj).fBuffer;
2695 ((TH1&)obj).fBuffer = nullptr;
2696 }
2697 if (fBuffer) {
2698 Double_t *buf = new Double_t[fBufferSize];
2699 for (Int_t i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
2700 // obj.fBuffer has been deleted before
2701 ((TH1&)obj).fBuffer = buf;
2702 }
2703
2704 // copy bin contents (this should be done by the derived classes, since TH1 does not store the bin content)
2705 // Do this in case derived from TArray
2706 TArray* a = dynamic_cast<TArray*>(&obj);
2707 if (a) {
2708 a->Set(fNcells);
2709 for (Int_t i = 0; i < fNcells; i++)
2711 }
2712
2713 ((TH1&)obj).fEntries = fEntries;
2714
2715 // which will call BufferEmpty(0) and set fBuffer[0] to a Maybe one should call
2716 // assignment operator on the TArrayD
2717
2718 ((TH1&)obj).fTsumw = fTsumw;
2719 ((TH1&)obj).fTsumw2 = fTsumw2;
2720 ((TH1&)obj).fTsumwx = fTsumwx;
2721 ((TH1&)obj).fTsumwx2 = fTsumwx2;
2722 ((TH1&)obj).fMaximum = fMaximum;
2723 ((TH1&)obj).fMinimum = fMinimum;
2724
2725 TAttLine::Copy(((TH1&)obj));
2726 TAttFill::Copy(((TH1&)obj));
2727 TAttMarker::Copy(((TH1&)obj));
2728 fXaxis.Copy(((TH1&)obj).fXaxis);
2729 fYaxis.Copy(((TH1&)obj).fYaxis);
2730 fZaxis.Copy(((TH1&)obj).fZaxis);
2731 ((TH1&)obj).fXaxis.SetParent(&obj);
2732 ((TH1&)obj).fYaxis.SetParent(&obj);
2733 ((TH1&)obj).fZaxis.SetParent(&obj);
2734 fContour.Copy(((TH1&)obj).fContour);
2735 fSumw2.Copy(((TH1&)obj).fSumw2);
2736 // fFunctions->Copy(((TH1&)obj).fFunctions);
2737 // when copying an histogram if the AddDirectoryStatus() is true it
2738 // will be added to gDirectory independently of the fDirectory stored.
2739 // and if the AddDirectoryStatus() is false it will not be added to
2740 // any directory (fDirectory = nullptr)
2741 if (fgAddDirectory && gDirectory) {
2742 gDirectory->Append(&obj);
2743 ((TH1&)obj).fFunctions->UseRWLock();
2744 ((TH1&)obj).fDirectory = gDirectory;
2745 } else
2746 ((TH1&)obj).fDirectory = nullptr;
2747
2748}
2749
2750////////////////////////////////////////////////////////////////////////////////
2751/// Make a complete copy of the underlying object. If 'newname' is set,
2752/// the copy's name will be set to that name.
2753
2754TObject* TH1::Clone(const char* newname) const
2755{
2756 TH1* obj = (TH1*)IsA()->GetNew()(nullptr);
2757 Copy(*obj);
2758
2759 // Now handle the parts that Copy doesn't do
2760 if(fFunctions) {
2761 // The Copy above might have published 'obj' to the ListOfCleanups.
2762 // Clone can call RecursiveRemove, for example via TCheckHashRecursiveRemoveConsistency
2763 // when dictionary information is initialized, so we need to
2764 // keep obj->fFunction valid during its execution and
2765 // protect the update with the write lock.
2766
2767 // Reset stats parent - else cloning the stats will clone this histogram, too.
2768 auto oldstats = dynamic_cast<TVirtualPaveStats*>(fFunctions->FindObject("stats"));
2769 TObject *oldparent = nullptr;
2770 if (oldstats) {
2771 oldparent = oldstats->GetParent();
2772 oldstats->SetParent(nullptr);
2773 }
2774
2775 auto newlist = (TList*)fFunctions->Clone();
2776
2777 if (oldstats)
2778 oldstats->SetParent(oldparent);
2779 auto newstats = dynamic_cast<TVirtualPaveStats*>(obj->fFunctions->FindObject("stats"));
2780 if (newstats)
2781 newstats->SetParent(obj);
2782
2783 auto oldlist = obj->fFunctions;
2784 {
2786 obj->fFunctions = newlist;
2787 }
2788 delete oldlist;
2789 }
2790 if(newname && strlen(newname) ) {
2791 obj->SetName(newname);
2792 }
2793 return obj;
2794}
2795
2796////////////////////////////////////////////////////////////////////////////////
2797/// Perform the automatic addition of the histogram to the given directory
2798///
2799/// Note this function is called in place when the semantic requires
2800/// this object to be added to a directory (I.e. when being read from
2801/// a TKey or being Cloned)
2802
2804{
2805 Bool_t addStatus = TH1::AddDirectoryStatus();
2806 if (addStatus) {
2807 SetDirectory(dir);
2808 if (dir) {
2810 }
2811 }
2812}
2813
2814////////////////////////////////////////////////////////////////////////////////
2815/// Compute distance from point px,py to a line.
2816///
2817/// Compute the closest distance of approach from point px,py to elements
2818/// of a histogram.
2819/// The distance is computed in pixels units.
2820///
2821/// #### Algorithm:
2822/// Currently, this simple model computes the distance from the mouse
2823/// to the histogram contour only.
2824
2826{
2827 if (!fPainter) return 9999;
2828 return fPainter->DistancetoPrimitive(px,py);
2829}
2830
2831////////////////////////////////////////////////////////////////////////////////
2832/// Performs the operation: `this = this/(c1*f1)`
2833/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2834///
2835/// Only bins inside the function range are recomputed.
2836/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2837/// you should call Sumw2 before making this operation.
2838/// This is particularly important if you fit the histogram after TH1::Divide
2839///
2840/// The function return kFALSE if the divide operation failed
2841
2843{
2844 if (!f1) {
2845 Error("Divide","Attempt to divide by a non-existing function");
2846 return kFALSE;
2847 }
2848
2849 // delete buffer if it is there since it will become invalid
2850 if (fBuffer) BufferEmpty(1);
2851
2852 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of
2853 Int_t ny = GetNbinsY() + 2;
2854 Int_t nz = GetNbinsZ() + 2;
2855 if (fDimension < 2) ny = 1;
2856 if (fDimension < 3) nz = 1;
2857
2858
2859 SetMinimum();
2860 SetMaximum();
2861
2862 // - Loop on bins (including underflows/overflows)
2863 Int_t bin, binx, biny, binz;
2864 Double_t cu, w;
2865 Double_t xx[3];
2866 Double_t *params = nullptr;
2867 f1->InitArgs(xx,params);
2868 for (binz = 0; binz < nz; ++binz) {
2869 xx[2] = fZaxis.GetBinCenter(binz);
2870 for (biny = 0; biny < ny; ++biny) {
2871 xx[1] = fYaxis.GetBinCenter(biny);
2872 for (binx = 0; binx < nx; ++binx) {
2873 xx[0] = fXaxis.GetBinCenter(binx);
2874 if (!f1->IsInside(xx)) continue;
2876 bin = binx + nx * (biny + ny * binz);
2877 cu = c1 * f1->EvalPar(xx);
2878 if (TF1::RejectedPoint()) continue;
2879 if (cu) w = RetrieveBinContent(bin) / cu;
2880 else w = 0;
2881 UpdateBinContent(bin, w);
2882 if (fSumw2.fN) {
2883 if (cu != 0) fSumw2.fArray[bin] = GetBinErrorSqUnchecked(bin) / (cu * cu);
2884 else fSumw2.fArray[bin] = 0;
2885 }
2886 }
2887 }
2888 }
2889 ResetStats();
2890 return kTRUE;
2891}
2892
2893////////////////////////////////////////////////////////////////////////////////
2894/// Divide this histogram by h1.
2895///
2896/// `this = this/h1`
2897/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2898/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
2899/// if not already set.
2900/// The resulting errors are calculated assuming uncorrelated histograms.
2901/// See the other TH1::Divide that gives the possibility to optionally
2902/// compute binomial errors.
2903///
2904/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2905/// you should call Sumw2 before making this operation.
2906/// This is particularly important if you fit the histogram after TH1::Scale
2907///
2908/// The function return kFALSE if the divide operation failed
2909
2910Bool_t TH1::Divide(const TH1 *h1)
2911{
2912 if (!h1) {
2913 Error("Divide", "Input histogram passed does not exist (NULL).");
2914 return kFALSE;
2915 }
2916
2917 // delete buffer if it is there since it will become invalid
2918 if (fBuffer) BufferEmpty(1);
2919
2920 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins) {
2921 return false;
2922 }
2923
2924 // Create Sumw2 if h1 has Sumw2 set
2925 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
2926
2927 // - Loop on bins (including underflows/overflows)
2928 for (Int_t i = 0; i < fNcells; ++i) {
2931 if (c1) UpdateBinContent(i, c0 / c1);
2932 else UpdateBinContent(i, 0);
2933
2934 if(fSumw2.fN) {
2935 if (c1 == 0) { fSumw2.fArray[i] = 0; continue; }
2936 Double_t c1sq = c1 * c1;
2937 fSumw2.fArray[i] = (GetBinErrorSqUnchecked(i) * c1sq + h1->GetBinErrorSqUnchecked(i) * c0 * c0) / (c1sq * c1sq);
2938 }
2939 }
2940 ResetStats();
2941 return kTRUE;
2942}
2943
2944////////////////////////////////////////////////////////////////////////////////
2945/// Replace contents of this histogram by the division of h1 by h2.
2946///
2947/// `this = c1*h1/(c2*h2)`
2948///
2949/// If errors are defined (see TH1::Sumw2), errors are also recalculated
2950/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
2951/// if not already set.
2952/// The resulting errors are calculated assuming uncorrelated histograms.
2953/// However, if option ="B" is specified, Binomial errors are computed.
2954/// In this case c1 and c2 do not make real sense and they are ignored.
2955///
2956/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2957/// you should call Sumw2 before making this operation.
2958/// This is particularly important if you fit the histogram after TH1::Divide
2959///
2960/// Please note also that in the binomial case errors are calculated using standard
2961/// binomial statistics, which means when b1 = b2, the error is zero.
2962/// If you prefer to have efficiency errors not going to zero when the efficiency is 1, you must
2963/// use the function TGraphAsymmErrors::BayesDivide, which will return an asymmetric and non-zero lower
2964/// error for the case b1=b2.
2965///
2966/// The function return kFALSE if the divide operation failed
2967
2969{
2970
2971 TString opt = option;
2972 opt.ToLower();
2973 Bool_t binomial = kFALSE;
2974 if (opt.Contains("b")) binomial = kTRUE;
2975 if (!h1 || !h2) {
2976 Error("Divide", "At least one of the input histograms passed does not exist (NULL).");
2977 return kFALSE;
2978 }
2979
2980 // delete buffer if it is there since it will become invalid
2981 if (fBuffer) BufferEmpty(1);
2982
2983 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins ||
2984 LoggedInconsistency("Divide", h1, h2) >= kDifferentNumberOfBins) {
2985 return false;
2986 }
2987
2988 if (!c2) {
2989 Error("Divide","Coefficient of dividing histogram cannot be zero");
2990 return kFALSE;
2991 }
2992
2993 // Create Sumw2 if h1 or h2 have Sumw2 set, or if binomial errors are explicitly requested
2994 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0 || binomial)) Sumw2();
2995
2996 SetMinimum();
2997 SetMaximum();
2998
2999 // - Loop on bins (including underflows/overflows)
3000 for (Int_t i = 0; i < fNcells; ++i) {
3002 Double_t b2 = h2->RetrieveBinContent(i);
3003 if (b2) UpdateBinContent(i, c1 * b1 / (c2 * b2));
3004 else UpdateBinContent(i, 0);
3005
3006 if (fSumw2.fN) {
3007 if (b2 == 0) { fSumw2.fArray[i] = 0; continue; }
3008 Double_t b1sq = b1 * b1; Double_t b2sq = b2 * b2;
3009 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
3011 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
3012 if (binomial) {
3013 if (b1 != b2) {
3014 // in the case of binomial statistics c1 and c2 must be 1 otherwise it does not make sense
3015 // c1 and c2 are ignored
3016 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));//this is the formula in Hbook/Hoper1
3017 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2); // old formula from G. Flucke
3018 // formula which works also for weighted histogram (see http://root-forum.cern.ch/viewtopic.php?t=3753 )
3019 fSumw2.fArray[i] = TMath::Abs( ( (1. - 2.* b1 / b2) * e1sq + b1sq * e2sq / b2sq ) / b2sq );
3020 } else {
3021 //in case b1=b2 error is zero
3022 //use TGraphAsymmErrors::BayesDivide for getting the asymmetric error not equal to zero
3023 fSumw2.fArray[i] = 0;
3024 }
3025 } else {
3026 fSumw2.fArray[i] = c1sq * c2sq * (e1sq * b2sq + e2sq * b1sq) / (c2sq * c2sq * b2sq * b2sq);
3027 }
3028 }
3029 }
3030 ResetStats();
3031 if (binomial)
3032 // in case of binomial division use denominator for number of entries
3033 SetEntries ( h2->GetEntries() );
3034
3035 return kTRUE;
3036}
3037
3038////////////////////////////////////////////////////////////////////////////////
3039/// Draw this histogram with options.
3040///
3041/// Histograms are drawn via the THistPainter class. Each histogram has
3042/// a pointer to its own painter (to be usable in a multithreaded program).
3043/// The same histogram can be drawn with different options in different pads.
3044/// When a histogram drawn in a pad is deleted, the histogram is
3045/// automatically removed from the pad or pads where it was drawn.
3046/// If a histogram is drawn in a pad, then filled again, the new status
3047/// of the histogram will be automatically shown in the pad next time
3048/// the pad is updated. One does not need to redraw the histogram.
3049/// To draw the current version of a histogram in a pad, one can use
3050/// `h->DrawCopy();`
3051/// This makes a clone of the histogram. Once the clone is drawn, the original
3052/// histogram may be modified or deleted without affecting the aspect of the
3053/// clone.
3054/// By default, TH1::Draw clears the current pad.
3055///
3056/// One can use TH1::SetMaximum and TH1::SetMinimum to force a particular
3057/// value for the maximum or the minimum scale on the plot.
3058///
3059/// TH1::UseCurrentStyle can be used to change all histogram graphics
3060/// attributes to correspond to the current selected style.
3061/// This function must be called for each histogram.
3062/// In case one reads and draws many histograms from a file, one can force
3063/// the histograms to inherit automatically the current graphics style
3064/// by calling before gROOT->ForceStyle();
3065///
3066/// See the THistPainter class for a description of all the drawing options.
3067
3069{
3070 TString opt1 = option; opt1.ToLower();
3071 TString opt2 = option;
3072 Int_t index = opt1.Index("same");
3073
3074 // Check if the string "same" is part of a TCutg name.
3075 if (index>=0) {
3076 Int_t indb = opt1.Index("[");
3077 if (indb>=0) {
3078 Int_t indk = opt1.Index("]");
3079 if (index>indb && index<indk) index = -1;
3080 }
3081 }
3082
3083 // If there is no pad or an empty pad the "same" option is ignored.
3084 if (gPad) {
3085 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
3086 if (index>=0) {
3087 if (gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
3088 gPad->GetY1() == 0 && gPad->GetY2() == 1 &&
3089 gPad->GetListOfPrimitives()->GetSize()==0) opt2.Remove(index,4);
3090 } else {
3091 //the following statement is necessary in case one attempts to draw
3092 //a temporary histogram already in the current pad
3093 if (TestBit(kCanDelete)) gPad->Remove(this);
3094 gPad->Clear();
3095 }
3096 gPad->IncrementPaletteColor(1, opt1);
3097 } else {
3098 if (index>=0) opt2.Remove(index,4);
3099 }
3100
3101 AppendPad(opt2.Data());
3102}
3103
3104////////////////////////////////////////////////////////////////////////////////
3105/// Copy this histogram and Draw in the current pad.
3106///
3107/// Once the histogram is drawn into the pad, any further modification
3108/// using graphics input will be made on the copy of the histogram,
3109/// and not to the original object.
3110/// By default a postfix "_copy" is added to the histogram name. Pass an empty postfix in case
3111/// you want to draw a histogram with the same name
3112///
3113/// See Draw for the list of options
3114
3115TH1 *TH1::DrawCopy(Option_t *option, const char * name_postfix) const
3116{
3117 TString opt = option;
3118 opt.ToLower();
3119 if (gPad && !opt.Contains("same")) gPad->Clear();
3120 TString newName;
3121 if (name_postfix) newName.Form("%s%s", GetName(), name_postfix);
3122 TH1 *newth1 = (TH1 *)Clone(newName.Data());
3123 newth1->SetDirectory(nullptr);
3124 newth1->SetBit(kCanDelete);
3125 if (gPad) gPad->IncrementPaletteColor(1, opt);
3126
3127 newth1->AppendPad(option);
3128 return newth1;
3129}
3130
3131////////////////////////////////////////////////////////////////////////////////
3132/// Draw a normalized copy of this histogram.
3133///
3134/// A clone of this histogram is normalized to norm and drawn with option.
3135/// A pointer to the normalized histogram is returned.
3136/// The contents of the histogram copy are scaled such that the new
3137/// sum of weights (excluding under and overflow) is equal to norm.
3138/// Note that the returned normalized histogram is not added to the list
3139/// of histograms in the current directory in memory.
3140/// It is the user's responsibility to delete this histogram.
3141/// The kCanDelete bit is set for the returned object. If a pad containing
3142/// this copy is cleared, the histogram will be automatically deleted.
3143///
3144/// See Draw for the list of options
3145
3147{
3149 if (sum == 0) {
3150 Error("DrawNormalized","Sum of weights is null. Cannot normalize histogram: %s",GetName());
3151 return nullptr;
3152 }
3153 Bool_t addStatus = TH1::AddDirectoryStatus();
3155 TH1 *h = (TH1*)Clone();
3157 // in case of drawing with error options - scale correctly the error
3158 TString opt(option); opt.ToUpper();
3159 if (fSumw2.fN == 0) {
3160 h->Sumw2();
3161 // do not use in this case the "Error option " for drawing which is enabled by default since the normalized histogram has now errors
3162 if (opt.IsNull() || opt == "SAME") opt += "HIST";
3163 }
3164 h->Scale(norm/sum);
3165 if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
3166 if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
3167 h->Draw(opt);
3168 TH1::AddDirectory(addStatus);
3169 return h;
3170}
3171
3172////////////////////////////////////////////////////////////////////////////////
3173/// Display a panel with all histogram drawing options.
3174///
3175/// See class TDrawPanelHist for example
3176
3177void TH1::DrawPanel()
3178{
3179 if (!fPainter) {Draw(); if (gPad) gPad->Update();}
3180 if (fPainter) fPainter->DrawPanel();
3181}
3182
3183////////////////////////////////////////////////////////////////////////////////
3184/// Evaluate function f1 at the center of bins of this histogram.
3185///
3186/// - If option "R" is specified, the function is evaluated only
3187/// for the bins included in the function range.
3188/// - If option "A" is specified, the value of the function is added to the
3189/// existing bin contents
3190/// - If option "S" is specified, the value of the function is used to
3191/// generate a value, distributed according to the Poisson
3192/// distribution, with f1 as the mean.
3193
3195{
3196 Double_t x[3];
3197 Int_t range, stat, add;
3198 if (!f1) return;
3199
3200 TString opt = option;
3201 opt.ToLower();
3202 if (opt.Contains("a")) add = 1;
3203 else add = 0;
3204 if (opt.Contains("s")) stat = 1;
3205 else stat = 0;
3206 if (opt.Contains("r")) range = 1;
3207 else range = 0;
3208
3209 // delete buffer if it is there since it will become invalid
3210 if (fBuffer) BufferEmpty(1);
3211
3212 Int_t nbinsx = fXaxis.GetNbins();
3213 Int_t nbinsy = fYaxis.GetNbins();
3214 Int_t nbinsz = fZaxis.GetNbins();
3215 if (!add) Reset();
3216
3217 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
3218 x[2] = fZaxis.GetBinCenter(binz);
3219 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
3220 x[1] = fYaxis.GetBinCenter(biny);
3221 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
3222 Int_t bin = GetBin(binx,biny,binz);
3223 x[0] = fXaxis.GetBinCenter(binx);
3224 if (range && !f1->IsInside(x)) continue;
3225 Double_t fu = f1->Eval(x[0], x[1], x[2]);
3226 if (stat) fu = gRandom->PoissonD(fu);
3227 AddBinContent(bin, fu);
3228 if (fSumw2.fN) fSumw2.fArray[bin] += TMath::Abs(fu);
3229 }
3230 }
3231 }
3232}
3233
3234////////////////////////////////////////////////////////////////////////////////
3235/// Execute action corresponding to one event.
3236///
3237/// This member function is called when a histogram is clicked with the locator
3238///
3239/// If Left button clicked on the bin top value, then the content of this bin
3240/// is modified according to the new position of the mouse when it is released.
3241
3242void TH1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3243{
3244 if (fPainter) fPainter->ExecuteEvent(event, px, py);
3245}
3246
3247////////////////////////////////////////////////////////////////////////////////
3248/// This function allows to do discrete Fourier transforms of TH1 and TH2.
3249/// Available transform types and flags are described below.
3250///
3251/// To extract more information about the transform, use the function
3252/// TVirtualFFT::GetCurrentTransform() to get a pointer to the current
3253/// transform object.
3254///
3255/// \param[out] h_output histogram for the output. If a null pointer is passed, a new histogram is created
3256/// and returned, otherwise, the provided histogram is used and should be big enough
3257/// \param[in] option option parameters consists of 3 parts:
3258/// - option on what to return
3259/// - "RE" - returns a histogram of the real part of the output
3260/// - "IM" - returns a histogram of the imaginary part of the output
3261/// - "MAG"- returns a histogram of the magnitude of the output
3262/// - "PH" - returns a histogram of the phase of the output
3263/// - option of transform type
3264/// - "R2C" - real to complex transforms - default
3265/// - "R2HC" - real to halfcomplex (special format of storing output data,
3266/// results the same as for R2C)
3267/// - "DHT" - discrete Hartley transform
3268/// real to real transforms (sine and cosine):
3269/// - "R2R_0", "R2R_1", "R2R_2", "R2R_3" - discrete cosine transforms of types I-IV
3270/// - "R2R_4", "R2R_5", "R2R_6", "R2R_7" - discrete sine transforms of types I-IV
3271/// To specify the type of each dimension of a 2-dimensional real to real
3272/// transform, use options of form "R2R_XX", for example, "R2R_02" for a transform,
3273/// which is of type "R2R_0" in 1st dimension and "R2R_2" in the 2nd.
3274/// - option of transform flag
3275/// - "ES" (from "estimate") - no time in preparing the transform, but probably sub-optimal
3276/// performance
3277/// - "M" (from "measure") - some time spend in finding the optimal way to do the transform
3278/// - "P" (from "patient") - more time spend in finding the optimal way to do the transform
3279/// - "EX" (from "exhaustive") - the most optimal way is found
3280/// This option should be chosen depending on how many transforms of the same size and
3281/// type are going to be done. Planning is only done once, for the first transform of this
3282/// size and type. Default is "ES".
3283///
3284/// Examples of valid options: "Mag R2C M" "Re R2R_11" "Im R2C ES" "PH R2HC EX"
3285
3286TH1* TH1::FFT(TH1* h_output, Option_t *option)
3287{
3288
3289 Int_t ndim[3];
3290 ndim[0] = this->GetNbinsX();
3291 ndim[1] = this->GetNbinsY();
3292 ndim[2] = this->GetNbinsZ();
3293
3294 TVirtualFFT *fft;
3295 TString opt = option;
3296 opt.ToUpper();
3297 if (!opt.Contains("2R")){
3298 if (!opt.Contains("2C") && !opt.Contains("2HC") && !opt.Contains("DHT")) {
3299 //no type specified, "R2C" by default
3300 opt.Append("R2C");
3301 }
3302 fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
3303 }
3304 else {
3305 //find the kind of transform
3306 Int_t ind = opt.Index("R2R", 3);
3307 Int_t *kind = new Int_t[2];
3308 char t;
3309 t = opt[ind+4];
3310 kind[0] = atoi(&t);
3311 if (h_output->GetDimension()>1) {
3312 t = opt[ind+5];
3313 kind[1] = atoi(&t);
3314 }
3315 fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
3316 delete [] kind;
3317 }
3318
3319 if (!fft) return nullptr;
3320 Int_t in=0;
3321 for (Int_t binx = 1; binx<=ndim[0]; binx++) {
3322 for (Int_t biny=1; biny<=ndim[1]; biny++) {
3323 for (Int_t binz=1; binz<=ndim[2]; binz++) {
3324 fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
3325 in++;
3326 }
3327 }
3328 }
3329 fft->Transform();
3330 h_output = TransformHisto(fft, h_output, option);
3331 return h_output;
3332}
3333
3334////////////////////////////////////////////////////////////////////////////////
3335/// Increment bin with abscissa X by 1.
3336///
3337/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3338/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3339///
3340/// If the storage of the sum of squares of weights has been triggered,
3341/// via the function Sumw2, then the sum of the squares of weights is incremented
3342/// by 1 in the bin corresponding to x.
3343///
3344/// The function returns the corresponding bin number which has its content incremented by 1
3345
3347{
3348 if (fBuffer) return BufferFill(x,1);
3349
3350 Int_t bin;
3351 fEntries++;
3352 bin =fXaxis.FindBin(x);
3353 if (bin <0) return -1;
3354 AddBinContent(bin);
3355 if (fSumw2.fN) ++fSumw2.fArray[bin];
3356 if (bin == 0 || bin > fXaxis.GetNbins()) {
3357 if (!GetStatOverflowsBehaviour()) return -1;
3358 }
3359 ++fTsumw;
3360 ++fTsumw2;
3361 fTsumwx += x;
3362 fTsumwx2 += x*x;
3363 return bin;
3364}
3365
3366////////////////////////////////////////////////////////////////////////////////
3367/// Increment bin with abscissa X with a weight w.
3368///
3369/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3370/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3371///
3372/// If the weight is not equal to 1, the storage of the sum of squares of
3373/// weights is automatically triggered and the sum of the squares of weights is incremented
3374/// by \f$ w^2 \f$ in the bin corresponding to x.
3375///
3376/// The function returns the corresponding bin number which has its content incremented by w
3377
3379{
3380
3381 if (fBuffer) return BufferFill(x,w);
3382
3383 Int_t bin;
3384 fEntries++;
3385 bin =fXaxis.FindBin(x);
3386 if (bin <0) return -1;
3387 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW) ) Sumw2(); // must be called before AddBinContent
3388 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3389 AddBinContent(bin, w);
3390 if (bin == 0 || bin > fXaxis.GetNbins()) {
3391 if (!GetStatOverflowsBehaviour()) return -1;
3392 }
3393 Double_t z= w;
3394 fTsumw += z;
3395 fTsumw2 += z*z;
3396 fTsumwx += z*x;
3397 fTsumwx2 += z*x*x;
3398 return bin;
3399}
3400
3401////////////////////////////////////////////////////////////////////////////////
3402/// Increment bin with namex with a weight w
3403///
3404/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3405/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3406///
3407/// If the weight is not equal to 1, the storage of the sum of squares of
3408/// weights is automatically triggered and the sum of the squares of weights is incremented
3409/// by \f$ w^2 \f$ in the bin corresponding to x.
3410///
3411/// The function returns the corresponding bin number which has its content
3412/// incremented by w.
3413
3414Int_t TH1::Fill(const char *namex, Double_t w)
3415{
3416 Int_t bin;
3417 fEntries++;
3418 bin =fXaxis.FindBin(namex);
3419 if (bin <0) return -1;
3420 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3421 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3422 AddBinContent(bin, w);
3423 if (bin == 0 || bin > fXaxis.GetNbins()) return -1;
3424 Double_t z= w;
3425 fTsumw += z;
3426 fTsumw2 += z*z;
3427 // this make sense if the histogram is not expanding (the x axis cannot be extended)
3428 if (!fXaxis.CanExtend() || !fXaxis.IsAlphanumeric()) {
3430 fTsumwx += z*x;
3431 fTsumwx2 += z*x*x;
3432 }
3433 return bin;
3434}
3435
3436////////////////////////////////////////////////////////////////////////////////
3437/// Fill this histogram with an array x and weights w.
3438///
3439/// \param[in] ntimes number of entries in arrays x and w (array size must be ntimes*stride)
3440/// \param[in] x array of values to be histogrammed
3441/// \param[in] w array of weighs
3442/// \param[in] stride step size through arrays x and w
3443///
3444/// If the weight is not equal to 1, the storage of the sum of squares of
3445/// weights is automatically triggered and the sum of the squares of weights is incremented
3446/// by \f$ w^2 \f$ in the bin corresponding to x.
3447/// if w is NULL each entry is assumed a weight=1
3448
3449void TH1::FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3450{
3451 //If a buffer is activated, fill buffer
3452 if (fBuffer) {
3453 ntimes *= stride;
3454 Int_t i = 0;
3455 for (i=0;i<ntimes;i+=stride) {
3456 if (!fBuffer) break; // buffer can be deleted in BufferFill when is empty
3457 if (w) BufferFill(x[i],w[i]);
3458 else BufferFill(x[i], 1.);
3459 }
3460 // fill the remaining entries if the buffer has been deleted
3461 if (i < ntimes && !fBuffer) {
3462 auto weights = w ? &w[i] : nullptr;
3463 DoFillN((ntimes-i)/stride,&x[i],weights,stride);
3464 }
3465 return;
3466 }
3467 // call internal method
3468 DoFillN(ntimes, x, w, stride);
3469}
3470
3471////////////////////////////////////////////////////////////////////////////////
3472/// Internal method to fill histogram content from a vector
3473/// called directly by TH1::BufferEmpty
3474
3475void TH1::DoFillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3476{
3477 Int_t bin,i;
3478
3479 fEntries += ntimes;
3480 Double_t ww = 1;
3481 Int_t nbins = fXaxis.GetNbins();
3482 ntimes *= stride;
3483 for (i=0;i<ntimes;i+=stride) {
3484 bin =fXaxis.FindBin(x[i]);
3485 if (bin <0) continue;
3486 if (w) ww = w[i];
3487 if (!fSumw2.fN && ww != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3488 if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
3489 AddBinContent(bin, ww);
3490 if (bin == 0 || bin > nbins) {
3491 if (!GetStatOverflowsBehaviour()) continue;
3492 }
3493 Double_t z= ww;
3494 fTsumw += z;
3495 fTsumw2 += z*z;
3496 fTsumwx += z*x[i];
3497 fTsumwx2 += z*x[i]*x[i];
3498 }
3499}
3500
3501////////////////////////////////////////////////////////////////////////////////
3502/// Fill histogram following distribution in function fname.
3503///
3504/// @param fname : Function name used for filling the histogram
3505/// @param ntimes : number of times the histogram is filled
3506/// @param rng : (optional) Random number generator used to sample
3507///
3508///
3509/// The distribution contained in the function fname (TF1) is integrated
3510/// over the channel contents for the bin range of this histogram.
3511/// It is normalized to 1.
3512///
3513/// Getting one random number implies:
3514/// - Generating a random number between 0 and 1 (say r1)
3515/// - Look in which bin in the normalized integral r1 corresponds to
3516/// - Fill histogram channel
3517/// ntimes random numbers are generated
3518///
3519/// One can also call TF1::GetRandom to get a random variate from a function.
3520
3521void TH1::FillRandom(const char *fname, Int_t ntimes, TRandom * rng)
3522{
3523 Int_t bin, binx, ibin, loop;
3524 Double_t r1, x;
3525 // - Search for fname in the list of ROOT defined functions
3526 TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
3527 if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
3528
3529 // - Allocate temporary space to store the integral and compute integral
3530
3531 TAxis * xAxis = &fXaxis;
3532
3533 // in case axis of histogram is not defined use the function axis
3534 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
3536 f1->GetRange(xmin,xmax);
3537 Info("FillRandom","Using function axis and range [%g,%g]",xmin, xmax);
3538 xAxis = f1->GetHistogram()->GetXaxis();
3539 }
3540
3541 Int_t first = xAxis->GetFirst();
3542 Int_t last = xAxis->GetLast();
3543 Int_t nbinsx = last-first+1;
3544
3545 Double_t *integral = new Double_t[nbinsx+1];
3546 integral[0] = 0;
3547 for (binx=1;binx<=nbinsx;binx++) {
3548 Double_t fint = f1->Integral(xAxis->GetBinLowEdge(binx+first-1),xAxis->GetBinUpEdge(binx+first-1), 0.);
3549 integral[binx] = integral[binx-1] + fint;
3550 }
3551
3552 // - Normalize integral to 1
3553 if (integral[nbinsx] == 0 ) {
3554 delete [] integral;
3555 Error("FillRandom", "Integral = zero"); return;
3556 }
3557 for (bin=1;bin<=nbinsx;bin++) integral[bin] /= integral[nbinsx];
3558
3559 // --------------Start main loop ntimes
3560 for (loop=0;loop<ntimes;loop++) {
3561 r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
3562 ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
3563 //binx = 1 + ibin;
3564 //x = xAxis->GetBinCenter(binx); //this is not OK when SetBuffer is used
3565 x = xAxis->GetBinLowEdge(ibin+first)
3566 +xAxis->GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
3567 Fill(x);
3568 }
3569 delete [] integral;
3570}
3571
3572////////////////////////////////////////////////////////////////////////////////
3573/// Fill histogram following distribution in histogram h.
3574///
3575/// @param h : Histogram pointer used for sampling random number
3576/// @param ntimes : number of times the histogram is filled
3577/// @param rng : (optional) Random number generator used for sampling
3578///
3579/// The distribution contained in the histogram h (TH1) is integrated
3580/// over the channel contents for the bin range of this histogram.
3581/// It is normalized to 1.
3582///
3583/// Getting one random number implies:
3584/// - Generating a random number between 0 and 1 (say r1)
3585/// - Look in which bin in the normalized integral r1 corresponds to
3586/// - Fill histogram channel ntimes random numbers are generated
3587///
3588/// SPECIAL CASE when the target histogram has the same binning as the source.
3589/// in this case we simply use a poisson distribution where
3590/// the mean value per bin = bincontent/integral.
3591
3592void TH1::FillRandom(TH1 *h, Int_t ntimes, TRandom * rng)
3593{
3594 if (!h) { Error("FillRandom", "Null histogram"); return; }
3595 if (fDimension != h->GetDimension()) {
3596 Error("FillRandom", "Histograms with different dimensions"); return;
3597 }
3598 if (std::isnan(h->ComputeIntegral(true))) {
3599 Error("FillRandom", "Histograms contains negative bins, does not represent probabilities");
3600 return;
3601 }
3602
3603 //in case the target histogram has the same binning and ntimes much greater
3604 //than the number of bins we can use a fast method
3605 Int_t first = fXaxis.GetFirst();
3606 Int_t last = fXaxis.GetLast();
3607 Int_t nbins = last-first+1;
3608 if (ntimes > 10*nbins) {
3609 auto inconsistency = CheckConsistency(this,h);
3610 if (inconsistency != kFullyConsistent) return; // do nothing
3611 Double_t sumw = h->Integral(first,last);
3612 if (sumw == 0) return;
3613 Double_t sumgen = 0;
3614 for (Int_t bin=first;bin<=last;bin++) {
3615 Double_t mean = h->RetrieveBinContent(bin)*ntimes/sumw;
3616 Double_t cont = (rng) ? rng->Poisson(mean) : gRandom->Poisson(mean);
3617 sumgen += cont;
3618 AddBinContent(bin,cont);
3619 if (fSumw2.fN) fSumw2.fArray[bin] += cont;
3620 }
3621
3622 // fix for the fluctuations in the total number n
3623 // since we use Poisson instead of multinomial
3624 // add a correction to have ntimes as generated entries
3625 Int_t i;
3626 if (sumgen < ntimes) {
3627 // add missing entries
3628 for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
3629 {
3630 Double_t x = h->GetRandom();
3631 Fill(x);
3632 }
3633 }
3634 else if (sumgen > ntimes) {
3635 // remove extra entries
3636 i = Int_t(sumgen+0.5);
3637 while( i > ntimes) {
3638 Double_t x = h->GetRandom(rng);
3639 Int_t ibin = fXaxis.FindBin(x);
3641 // skip in case bin is empty
3642 if (y > 0) {
3643 SetBinContent(ibin, y-1.);
3644 i--;
3645 }
3646 }
3647 }
3648
3649 ResetStats();
3650 return;
3651 }
3652 // case of different axis and not too large ntimes
3653
3654 if (h->ComputeIntegral() ==0) return;
3655 Int_t loop;
3656 Double_t x;
3657 for (loop=0;loop<ntimes;loop++) {
3658 x = h->GetRandom();
3659 Fill(x);
3660 }
3661}
3662
3663////////////////////////////////////////////////////////////////////////////////
3664/// Return Global bin number corresponding to x,y,z
3665///
3666/// 2-D and 3-D histograms are represented with a one dimensional
3667/// structure. This has the advantage that all existing functions, such as
3668/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3669/// This function tries to extend the axis if the given point belongs to an
3670/// under-/overflow bin AND if CanExtendAllAxes() is true.
3671///
3672/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3673
3675{
3676 if (GetDimension() < 2) {
3677 return fXaxis.FindBin(x);
3678 }
3679 if (GetDimension() < 3) {
3680 Int_t nx = fXaxis.GetNbins()+2;
3681 Int_t binx = fXaxis.FindBin(x);
3682 Int_t biny = fYaxis.FindBin(y);
3683 return binx + nx*biny;
3684 }
3685 if (GetDimension() < 4) {
3686 Int_t nx = fXaxis.GetNbins()+2;
3687 Int_t ny = fYaxis.GetNbins()+2;
3688 Int_t binx = fXaxis.FindBin(x);
3689 Int_t biny = fYaxis.FindBin(y);
3690 Int_t binz = fZaxis.FindBin(z);
3691 return binx + nx*(biny +ny*binz);
3692 }
3693 return -1;
3694}
3695
3696////////////////////////////////////////////////////////////////////////////////
3697/// Return Global bin number corresponding to x,y,z.
3698///
3699/// 2-D and 3-D histograms are represented with a one dimensional
3700/// structure. This has the advantage that all existing functions, such as
3701/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3702/// This function DOES NOT try to extend the axis if the given point belongs
3703/// to an under-/overflow bin.
3704///
3705/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3706
3708{
3709 if (GetDimension() < 2) {
3710 return fXaxis.FindFixBin(x);
3711 }
3712 if (GetDimension() < 3) {
3713 Int_t nx = fXaxis.GetNbins()+2;
3714 Int_t binx = fXaxis.FindFixBin(x);
3715 Int_t biny = fYaxis.FindFixBin(y);
3716 return binx + nx*biny;
3717 }
3718 if (GetDimension() < 4) {
3719 Int_t nx = fXaxis.GetNbins()+2;
3720 Int_t ny = fYaxis.GetNbins()+2;
3721 Int_t binx = fXaxis.FindFixBin(x);
3722 Int_t biny = fYaxis.FindFixBin(y);
3723 Int_t binz = fZaxis.FindFixBin(z);
3724 return binx + nx*(biny +ny*binz);
3725 }
3726 return -1;
3727}
3728
3729////////////////////////////////////////////////////////////////////////////////
3730/// Find first bin with content > threshold for axis (1=x, 2=y, 3=z)
3731/// if no bins with content > threshold is found the function returns -1.
3732/// The search will occur between the specified first and last bin. Specifying
3733/// the value of the last bin to search to less than zero will search until the
3734/// last defined bin.
3735
3736Int_t TH1::FindFirstBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3737{
3738 if (fBuffer) ((TH1*)this)->BufferEmpty();
3739
3740 if (axis < 1 || (axis > 1 && GetDimension() == 1 ) ||
3741 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3 ) ) {
3742 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3743 axis = 1;
3744 }
3745 if (firstBin < 1) {
3746 firstBin = 1;
3747 }
3748 Int_t nbinsx = fXaxis.GetNbins();
3749 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3750 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3751
3752 if (axis == 1) {
3753 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3754 lastBin = fXaxis.GetNbins();
3755 }
3756 for (Int_t binx = firstBin; binx <= lastBin; binx++) {
3757 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3758 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3759 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binx;
3760 }
3761 }
3762 }
3763 }
3764 else if (axis == 2) {
3765 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3766 lastBin = fYaxis.GetNbins();
3767 }
3768 for (Int_t biny = firstBin; biny <= lastBin; biny++) {
3769 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3770 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3771 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return biny;
3772 }
3773 }
3774 }
3775 }
3776 else if (axis == 3) {
3777 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3778 lastBin = fZaxis.GetNbins();
3779 }
3780 for (Int_t binz = firstBin; binz <= lastBin; binz++) {
3781 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3782 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3783 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binz;
3784 }
3785 }
3786 }
3787 }
3788
3789 return -1;
3790}
3791
3792////////////////////////////////////////////////////////////////////////////////
3793/// Find last bin with content > threshold for axis (1=x, 2=y, 3=z)
3794/// if no bins with content > threshold is found the function returns -1.
3795/// The search will occur between the specified first and last bin. Specifying
3796/// the value of the last bin to search to less than zero will search until the
3797/// last defined bin.
3798
3799Int_t TH1::FindLastBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3800{
3801 if (fBuffer) ((TH1*)this)->BufferEmpty();
3802
3803
3804 if (axis < 1 || ( axis > 1 && GetDimension() == 1 ) ||
3805 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3) ) {
3806 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3807 axis = 1;
3808 }
3809 if (firstBin < 1) {
3810 firstBin = 1;
3811 }
3812 Int_t nbinsx = fXaxis.GetNbins();
3813 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3814 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3815
3816 if (axis == 1) {
3817 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3818 lastBin = fXaxis.GetNbins();
3819 }
3820 for (Int_t binx = lastBin; binx >= firstBin; binx--) {
3821 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3822 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3823 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binx;
3824 }
3825 }
3826 }
3827 }
3828 else if (axis == 2) {
3829 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3830 lastBin = fYaxis.GetNbins();
3831 }
3832 for (Int_t biny = lastBin; biny >= firstBin; biny--) {
3833 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3834 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3835 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return biny;
3836 }
3837 }
3838 }
3839 }
3840 else if (axis == 3) {
3841 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3842 lastBin = fZaxis.GetNbins();
3843 }
3844 for (Int_t binz = lastBin; binz >= firstBin; binz--) {
3845 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3846 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3847 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binz;
3848 }
3849 }
3850 }
3851 }
3852
3853 return -1;
3854}
3855
3856////////////////////////////////////////////////////////////////////////////////
3857/// Search object named name in the list of functions.
3858
3859TObject *TH1::FindObject(const char *name) const
3860{
3861 if (fFunctions) return fFunctions->FindObject(name);
3862 return nullptr;
3863}
3864
3865////////////////////////////////////////////////////////////////////////////////
3866/// Search object obj in the list of functions.
3867
3868TObject *TH1::FindObject(const TObject *obj) const
3869{
3870 if (fFunctions) return fFunctions->FindObject(obj);
3871 return nullptr;
3872}
3873
3874////////////////////////////////////////////////////////////////////////////////
3875/// Fit histogram with function fname.
3876///
3877///
3878/// fname is the name of a function available in the global ROOT list of functions
3879/// `gROOT->GetListOfFunctions`
3880/// The list include any TF1 object created by the user plus some pre-defined functions
3881/// which are automatically created by ROOT the first time a pre-defined function is requested from `gROOT`
3882/// (i.e. when calling `gROOT->GetFunction(const char *name)`).
3883/// These pre-defined functions are:
3884/// - `gaus, gausn` where gausn is the normalized Gaussian
3885/// - `landau, landaun`
3886/// - `expo`
3887/// - `pol1,...9, chebyshev1,...9`.
3888///
3889/// For printing the list of all available functions do:
3890///
3891/// TF1::InitStandardFunctions(); // not needed if `gROOT->GetFunction` is called before
3892/// gROOT->GetListOfFunctions()->ls()
3893///
3894/// `fname` can also be a formula that is accepted by the linear fitter containing the special operator `++`,
3895/// representing linear components separated by `++` sign, for example `x++sin(x)` for fitting `[0]*x+[1]*sin(x)`
3896///
3897/// This function finds a pointer to the TF1 object with name `fname` and calls TH1::Fit(TF1 *, Option_t *, Option_t *,
3898/// Double_t, Double_t). See there for the fitting options and the details about fitting histograms
3899
3900TFitResultPtr TH1::Fit(const char *fname ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
3901{
3902 char *linear;
3903 linear= (char*)strstr(fname, "++");
3904 Int_t ndim=GetDimension();
3905 if (linear){
3906 if (ndim<2){
3907 TF1 f1(fname, fname, xxmin, xxmax);
3908 return Fit(&f1,option,goption,xxmin,xxmax);
3909 }
3910 else if (ndim<3){
3911 TF2 f2(fname, fname);
3912 return Fit(&f2,option,goption,xxmin,xxmax);
3913 }
3914 else{
3915 TF3 f3(fname, fname);
3916 return Fit(&f3,option,goption,xxmin,xxmax);
3917 }
3918 }
3919 else{
3920 TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
3921 if (!f1) { Printf("Unknown function: %s",fname); return -1; }
3922 return Fit(f1,option,goption,xxmin,xxmax);
3923 }
3924}
3925
3926////////////////////////////////////////////////////////////////////////////////
3927/// Fit histogram with the function pointer f1.
3928///
3929/// \param[in] f1 pointer to the function object
3930/// \param[in] option string defining the fit options (see table below).
3931/// \param[in] goption specify a list of graphics options. See TH1::Draw for a complete list of these options.
3932/// \param[in] xxmin lower fitting range
3933/// \param[in] xxmax upper fitting range
3934/// \return A smart pointer to the TFitResult class
3935///
3936/// \anchor HFitOpt
3937/// ### Histogram Fitting Options
3938///
3939/// Here is the full list of fit options that can be given in the parameter `option`.
3940/// Several options can be used together by concatanating the strings without the need of any delimiters.
3941///
3942/// option | description
3943/// -------|------------
3944/// "L" | Uses a log likelihood method (default is chi-square method). To be used when the histogram represents counts.
3945/// "WL" | Weighted log likelihood method. To be used when the histogram has been filled with weights different than 1. This is needed for getting correct parameter uncertainties for weighted fits.
3946/// "P" | Uses Pearson chi-square method. Uses expected errors instead of the observed one (default case). The expected error is instead estimated from the square-root of the bin function value.
3947/// "MULTI" | Uses Loglikelihood method based on multi-nomial distribution. In this case the function must be normalized and one fits only the function shape.
3948/// "W" | Fit using the chi-square method and ignoring the bin uncertainties and skip empty bins.
3949/// "WW" | Fit using the chi-square method and ignoring the bin uncertainties and include the empty bins.
3950/// "I" | Uses the integral of function in the bin instead of the default bin center value.
3951/// "F" | Uses the default minimizer (e.g. Minuit) when fitting a linear function (e.g. polN) instead of the linear fitter.
3952/// "U" | Uses a user specified objective function (e.g. user providedlikelihood function) defined using `TVirtualFitter::SetFCN`
3953/// "E" | Performs a better parameter errors estimation using the Minos technique for all fit parameters.
3954/// "M" | Uses the IMPROVE algorithm (available only in TMinuit). This algorithm attempts improve the found local minimum by searching for a better one.
3955/// "S" | The full result of the fit is returned in the `TFitResultPtr`. This is needed to get the covariance matrix of the fit. See `TFitResult` and the base class `ROOT::Math::FitResult`.
3956/// "Q" | Quiet mode (minimum printing)
3957/// "V" | Verbose mode (default is between Q and V)
3958/// "+" | Adds this new fitted function to the list of fitted functions. By default, the previous function is deleted and only the last one is kept.
3959/// "N" | Does not store the graphics function, does not draw the histogram with the function after fitting.
3960/// "0" | Does not draw the histogram and the fitted function after fitting, but in contrast to option "N", it stores the fitted function in the histogram list of functions.
3961/// "R" | Fit using a fitting range specified in the function range with `TF1::SetRange`.
3962/// "B" | Use this option when you want to fix or set limits on one or more parameters and the fitting function is a predefined one (e.g gaus, expo,..), otherwise in case of pre-defined functions, some default initial values and limits will be used.
3963/// "C" | In case of linear fitting, do no calculate the chisquare (saves CPU time).
3964/// "G" | Uses the gradient implemented in `TF1::GradientPar` for the minimization. This allows to use Automatic Differentiation when it is supported by the provided TF1 function.
3965/// "WIDTH" | Scales the histogran bin content by the bin width (useful for variable bins histograms)
3966/// "SERIAL" | Runs in serial mode. By defult if ROOT is built with MT support and MT is enables, the fit is perfomed in multi-thread - "E" Perform better Errors estimation using Minos technique
3967/// "MULTITHREAD" | Forces usage of multi-thread execution whenever possible
3968///
3969/// The default fitting of an histogram (when no option is given) is perfomed as following:
3970/// - a chi-square fit (see below Chi-square Fits) computed using the bin histogram errors and excluding bins with zero errors (empty bins);
3971/// - the full range of the histogram is used;
3972/// - the default Minimizer with its default configuration is used (see below Minimizer Configuration) except for linear function;
3973/// - for linear functions (`polN`, `chenbyshev` or formula expressions combined using operator `++`) a linear minimization is used.
3974/// - only the status of the fit is returned;
3975/// - the fit is performed in Multithread whenever is enabled in ROOT;
3976/// - only the last fitted function is saved in the histogram;
3977/// - the histogram is drawn after fitting overalyed with the resulting fitting function
3978///
3979/// \anchor HFitMinimizer
3980/// ### Minimizer Configuration
3981///
3982/// The Fit is perfomed using the default Minimizer, defined in the `ROOT::Math::MinimizerOptions` class.
3983/// It is possible to change the default minimizer and its configuration parameters by calling these static functions before fitting (before calling `TH1::Fit`):
3984/// - `ROOT::Math::MinimizerOptions::SetDefaultMinimizer(minimizerName, minimizerAgorithm)` for changing the minmizer and/or the corresponding algorithm.
3985/// For example `ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");` will set the usage of the BFGS algorithm of the GSL multi-dimensional minimization
3986/// The current defaults are ("Minuit","Migrad").
3987/// See the documentation of the `ROOT::Math::MinimizerOptions` for the available minimizers in ROOT and their corresponding algorithms.
3988/// - `ROOT::Math::MinimizerOptions::SetDefaultTolerance` for setting a different tolerance value for the minimization.
3989/// - `ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls` for setting the maximum number of function calls.
3990/// - `ROOT::Math::MinimizerOptions::SetDefaultPrintLevel` for changing the minimizer print level from level=0 (minimal printing) to level=3 maximum printing
3991///
3992/// Other options are possible depending on the Minimizer used, see the corresponding documentation.
3993/// The default minimizer can be also set in the resource file in etc/system.rootrc. For example
3994///
3995/// ~~~ {.cpp}
3996/// Root.Fitter: Minuit2
3997/// ~~~
3998///
3999/// \anchor HFitChi2
4000/// ### Chi-square Fits
4001///
4002/// By default a chi-square (least-square) fit is performed on the histogram. The so-called modified least-square method
4003/// is used where the residual for each bin is computed using as error the observed value (the bin error) returned by `TH1::GetBinError`
4004///
4005/// \f[
4006/// Chi2 = \sum_{i}{ \left(\frac{y(i) - f(x(i) | p )}{e(i)} \right)^2 }
4007/// \f]
4008///
4009/// 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
4010/// an un-weighted histogram). Bins with zero errors are excluded from the fit. See also later the note on the treatment
4011/// of empty bins. When using option "I" the residual is computed not using the function value at the bin center, `f(x(i)|p)`,
4012/// but the integral of the function in the bin, Integral{ f(x|p)dx }, divided by the bin volume.
4013/// When using option `P` (Pearson chi2), the expected error computed as `e(i) = sqrt(f(x(i)|p))` is used.
4014/// In this case empty bins are considered in the fit.
4015/// Both chi-square methods should not be used when the bin content represent counts, especially in case of low bin statistics,
4016/// because they could return a biased result.
4017///
4018/// \anchor HFitNLL
4019/// ### Likelihood Fits
4020///
4021/// When using option "L" a likelihood fit is used instead of the default chi-square fit.
4022/// The likelihood is built assuming a Poisson probability density function for each bin.
4023/// The negative log-likelihood to be minimized is
4024///
4025/// \f[
4026/// NLL = - \sum_{i}{ \log {\mathrm P} ( y(i) | f(x(i) | p ) ) }
4027/// \f]
4028/// where `P(y|f)` is the Poisson distribution of observing a count `y(i)` in the bin when the expected count is `f(x(i)|p)`.
4029/// The exact likelihood used is the Poisson likelihood described in this paper:
4030/// S. Baker and R. D. Cousins, “Clarification of the use of chi-square and likelihood functions in fits to histograms,”
4031/// Nucl. Instrum. Meth. 221 (1984) 437.
4032///
4033/// \f[
4034/// NLL = \sum_{i}{( f(x(i) | p ) + y(i)\log(y(i)/ f(x(i) | p )) - y(i)) }
4035/// \f]
4036/// By using this formulation, `2*NLL` can be interpreted as the chi-square resulting from the fit.
4037///
4038/// This method should be always used when the bin content represents counts (i.e. errors are sqrt(N) ).
4039/// The likelihood method has the advantage of treating correctly bins with low statistics. In case of high
4040/// statistics/bin the distribution of the bin content becomes a normal distribution and the likelihood and the chi2 fit
4041/// give the same result.
4042///
4043/// The likelihood method, although a bit slower, it is therefore the recommended method,
4044/// when the histogram represent counts (Poisson statistics), where the chi-square methods may
4045/// give incorrect results, especially in case of low statistics.
4046/// In case of a weighted histogram, it is possible to perform also a likelihood fit by using the
4047/// option "WL". Note a weighted histogram is a histogram which has been filled with weights and it
4048/// has the information on the sum of the weight square for each bin ( TH1::Sumw2() has been called).
4049/// The bin error for a weighted histogram is the square root of the sum of the weight square.
4050///
4051/// \anchor HFitRes
4052/// ### Fit Result
4053///
4054/// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
4055/// By default the TFitResultPtr contains only the status of the fit which is return by an
4056/// automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
4057///
4058/// ~~~ {.cpp}
4059/// Int_t fitStatus = h->Fit(myFunc);
4060/// ~~~
4061///
4062/// If the option "S" is instead used, TFitResultPtr behaves as a smart
4063/// pointer to the TFitResult object. This is useful for retrieving the full result information from the fit, such as the covariance matrix,
4064/// as shown in this example code:
4065///
4066/// ~~~ {.cpp}
4067/// TFitResultPtr r = h->Fit(myFunc,"S");
4068/// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
4069/// Double_t chi2 = r->Chi2(); // to retrieve the fit chi2
4070/// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
4071/// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
4072/// r->Print("V"); // print full information of fit including covariance matrix
4073/// r->Write(); // store the result in a file
4074/// ~~~
4075///
4076/// The fit parameters, error and chi-square (but not covariance matrix) can be retrieved also
4077/// directly from the fitted function that is passed to this call.
4078/// Given a pointer to an associated fitted function `myfunc`, one can retrieve the function/fit
4079/// parameters with calls such as:
4080///
4081/// ~~~ {.cpp}
4082/// Double_t chi2 = myfunc->GetChisquare();
4083/// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
4084/// Double_t err0 = myfunc->GetParError(0); //error on first parameter
4085/// ~~~
4086///
4087/// ##### Associated functions
4088///
4089/// One or more object ( can be added to the list
4090/// of functions (fFunctions) associated to each histogram.
4091/// When TH1::Fit is invoked, the fitted function is added to the histogram list of functions (fFunctions).
4092/// If the histogram is made persistent, the list of associated functions is also persistent.
4093/// Given a histogram h, one can retrieve an associated function with:
4094///
4095/// ~~~ {.cpp}
4096/// TF1 *myfunc = h->GetFunction("myfunc");
4097/// ~~~
4098/// or by quering directly the list obtained by calling `TH1::GetListOfFunctions`.
4099///
4100/// \anchor HFitStatus
4101/// ### Fit status
4102///
4103/// The status of the fit is obtained converting the TFitResultPtr to an integer
4104/// independently if the fit option "S" is used or not:
4105///
4106/// ~~~ {.cpp}
4107/// TFitResultPtr r = h->Fit(myFunc,opt);
4108/// Int_t fitStatus = r;
4109/// ~~~
4110///
4111/// - `status = 0` : the fit has been performed successfully (i.e no error occurred).
4112/// - `status < 0` : there is an error not connected with the minimization procedure, for example when a wrong function is used.
4113/// - `status > 0` : return status from Minimizer, depends on used Minimizer. For example for TMinuit and Minuit2 we have:
4114/// - `status = migradStatus + 10*minosStatus + 100*hesseStatus + 1000*improveStatus`.
4115/// TMinuit returns 0 (for migrad, minos, hesse or improve) in case of success and 4 in case of error (see the documentation of TMinuit::mnexcm). For example, for an error
4116/// only in Minos but not in Migrad a fitStatus of 40 will be returned.
4117/// Minuit2 returns 0 in case of success and different values in migrad,minos or
4118/// hesse depending on the error. See in this case the documentation of
4119/// Minuit2Minimizer::Minimize for the migrad return status, Minuit2Minimizer::GetMinosError for the
4120/// minos return status and Minuit2Minimizer::Hesse for the hesse return status.
4121/// If other minimizers are used see their specific documentation for the status code returned.
4122/// For example in the case of Fumili, see TFumili::Minimize.
4123///
4124/// \anchor HFitRange
4125/// ### Fitting in a range
4126///
4127/// In order to fit in a sub-range of the histogram you have two options:
4128/// - pass to this function the lower (`xxmin`) and upper (`xxmax`) values for the fitting range;
4129/// - define a specific range in the fitted function and use the fitting option "R".
4130/// For example, if your histogram has a defined range between -4 and 4 and you want to fit a gaussian
4131/// only in the interval 1 to 3, you can do:
4132///
4133/// ~~~ {.cpp}
4134/// TF1 *f1 = new TF1("f1", "gaus", 1, 3);
4135/// histo->Fit("f1", "R");
4136/// ~~~
4137///
4138/// The fitting range is also limited by the histogram range defined using TAxis::SetRange
4139/// or TAxis::SetRangeUser. Therefore the fitting range is the smallest range between the
4140/// histogram one and the one defined by one of the two previous options described above.
4141///
4142/// \anchor HFitInitial
4143/// ### Setting initial conditions
4144///
4145/// Parameters must be initialized before invoking the Fit function.
4146/// The setting of the parameter initial values is automatic for the
4147/// predefined functions such as poln, expo, gaus, landau. One can however disable
4148/// this automatic computation by using the option "B".
4149/// Note that if a predefined function is defined with an argument,
4150/// eg, gaus(0), expo(1), you must specify the initial values for
4151/// the parameters.
4152/// You can specify boundary limits for some or all parameters via
4153///
4154/// ~~~ {.cpp}
4155/// f1->SetParLimits(p_number, parmin, parmax);
4156/// ~~~
4157///
4158/// if `parmin >= parmax`, the parameter is fixed
4159/// Note that you are not forced to fix the limits for all parameters.
4160/// For example, if you fit a function with 6 parameters, you can do:
4161///
4162/// ~~~ {.cpp}
4163/// func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
4164/// func->SetParLimits(3, -10, -4);
4165/// func->FixParameter(4, 0);
4166/// func->SetParLimits(5, 1, 1);
4167/// ~~~
4168///
4169/// With this setup, parameters 0->2 can vary freely
4170/// Parameter 3 has boundaries [-10,-4] with initial value -8
4171/// Parameter 4 is fixed to 0
4172/// Parameter 5 is fixed to 100.
4173/// When the lower limit and upper limit are equal, the parameter is fixed.
4174/// However to fix a parameter to 0, one must call the FixParameter function.
4175///
4176/// \anchor HFitStatBox
4177/// ### Fit Statistics Box
4178///
4179/// The statistics box can display the result of the fit.
4180/// You can change the statistics box to display the fit parameters with
4181/// the TStyle::SetOptFit(mode) method. This mode has four digits.
4182/// mode = pcev (default = 0111)
4183///
4184/// v = 1; print name/values of parameters
4185/// e = 1; print errors (if e=1, v must be 1)
4186/// c = 1; print Chisquare/Number of degrees of freedom
4187/// p = 1; print Probability
4188///
4189/// For example: gStyle->SetOptFit(1011);
4190/// prints the fit probability, parameter names/values, and errors.
4191/// You can change the position of the statistics box with these lines
4192/// (where g is a pointer to the TGraph):
4193///
4194/// TPaveStats *st = (TPaveStats*)g->GetListOfFunctions()->FindObject("stats");
4195/// st->SetX1NDC(newx1); //new x start position
4196/// st->SetX2NDC(newx2); //new x end position
4197///
4198/// \anchor HFitExtra
4199/// ### Additional Notes on Fitting
4200///
4201/// #### Fitting a histogram of dimension N with a function of dimension N-1
4202///
4203/// It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
4204/// In this case the chi-square is computed from the squared error distance between the function values and the bin centers weighted by the bin content.
4205/// For correct error scaling, the obtained parameter error are corrected as in the case when the
4206/// option "W" is used.
4207///
4208/// #### User defined objective functions
4209///
4210/// By default when fitting a chi square function is used for fitting. When option "L" is used
4211/// a Poisson likelihood function is used. Using option "MULTI" a multinomial likelihood fit is used.
4212/// Thes functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
4213/// are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
4214/// the file math/mathcore/src/FitUtil.cxx.
4215/// It is possible to specify a user defined fitting function, using option "U" and
4216/// calling the following functions:
4217///
4218/// ~~~ {.cpp}
4219/// TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction);
4220/// ~~~
4221///
4222/// where MyFittingFunction is of type:
4223///
4224/// ~~~ {.cpp}
4225/// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
4226/// ~~~
4227///
4228/// #### Note on treatment of empty bins
4229///
4230/// Empty bins, which have the content equal to zero AND error equal to zero,
4231/// are excluded by default from the chi-square fit, but they are considered in the likelihood fit.
4232/// since they affect the likelihood if the function value in these bins is not negligible.
4233/// Note that if the histogram is having bins with zero content and non zero-errors they are considered as
4234/// any other bins in the fit. Instead bins with zero error and non-zero content are by default excluded in the chi-squared fit.
4235/// In general, one should not fit a histogram with non-empty bins and zero errors.
4236///
4237/// If the bin errors are not known, one should use the fit option "W", which gives a weight=1 for each bin (it is an unweighted least-square
4238/// fit). When using option "WW" the empty bins will be also considered in the chi-square fit with an error of 1.
4239/// Note that in this fitting case (option "W" or "WW") the resulting fitted parameter errors
4240/// are corrected by the obtained chi2 value using this scaling expression:
4241/// `errorp *= sqrt(chisquare/(ndf-1))` as it is done when fitting a TGraph with
4242/// no point errors.
4243///
4244/// #### Excluding points
4245///
4246/// You can use TF1::RejectPoint inside your fitting function to exclude some points
4247/// within a certain range from the fit. See the tutorial `fit/fitExclude.C`.
4248///
4249///
4250/// #### Warning when using the option "0"
4251///
4252/// When selecting the option "0", the fitted function is added to
4253/// the list of functions of the histogram, but it is not drawn when the histogram is drawn.
4254/// You can undo this behaviour resetting its corresponding bit in the TF1 object as following:
4255///
4256/// ~~~ {.cpp}
4257/// h.Fit("myFunction", "0"); // fit, store function but do not draw
4258/// h.Draw(); // function is not drawn
4259/// h.GetFunction("myFunction")->ResetBit(TF1::kNotDraw);
4260/// h.Draw(); // function is visible again
4261/// ~~~
4263
4265{
4266 // implementation of Fit method is in file hist/src/HFitImpl.cxx
4267 Foption_t fitOption;
4269
4270 // create range and minimizer options with default values
4271 ROOT::Fit::DataRange range(xxmin,xxmax);
4273
4274 // need to empty the buffer before
4275 // (t.b.d. do a ML unbinned fit with buffer data)
4276 if (fBuffer) BufferEmpty();
4277
4278 return ROOT::Fit::FitObject(this, f1 , fitOption , minOption, goption, range);
4279}
4280
4281////////////////////////////////////////////////////////////////////////////////
4282/// Display a panel with all histogram fit options.
4283///
4284/// See class TFitPanel for example
4285
4286void TH1::FitPanel()
4287{
4288 if (!gPad)
4289 gROOT->MakeDefCanvas();
4290
4291 if (!gPad) {
4292 Error("FitPanel", "Unable to create a default canvas");
4293 return;
4294 }
4295
4296
4297 // use plugin manager to create instance of TFitEditor
4298 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
4299 if (handler && handler->LoadPlugin() != -1) {
4300 if (handler->ExecPlugin(2, gPad, this) == 0)
4301 Error("FitPanel", "Unable to create the FitPanel");
4302 }
4303 else
4304 Error("FitPanel", "Unable to find the FitPanel plug-in");
4305}
4306
4307////////////////////////////////////////////////////////////////////////////////
4308/// Return a histogram containing the asymmetry of this histogram with h2,
4309/// where the asymmetry is defined as:
4310///
4311/// ~~~ {.cpp}
4312/// Asymmetry = (h1 - h2)/(h1 + h2) where h1 = this
4313/// ~~~
4314///
4315/// works for 1D, 2D, etc. histograms
4316/// c2 is an optional argument that gives a relative weight between the two
4317/// histograms, and dc2 is the error on this weight. This is useful, for example,
4318/// when forming an asymmetry between two histograms from 2 different data sets that
4319/// need to be normalized to each other in some way. The function calculates
4320/// the errors assuming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
4321///
4322/// example: assuming 'h1' and 'h2' are already filled
4323///
4324/// ~~~ {.cpp}
4325/// h3 = h1->GetAsymmetry(h2)
4326/// ~~~
4327///
4328/// then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
4329/// h1 and h2 are left intact.
4330///
4331/// Note that it is the user's responsibility to manage the created histogram.
4332/// The name of the returned histogram will be `Asymmetry_nameOfh1-nameOfh2`
4333///
4334/// code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
4335///
4336/// clone the histograms so top and bottom will have the
4337/// correct dimensions:
4338/// Sumw2 just makes sure the errors will be computed properly
4339/// when we form sums and ratios below.
4340
4342{
4343 TH1 *h1 = this;
4344 TString name = TString::Format("Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4345 TH1 *asym = (TH1*)Clone(name);
4346
4347 // set also the title
4348 TString title = TString::Format("(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4349 asym->SetTitle(title);
4350
4351 asym->Sumw2();
4352 Bool_t addStatus = TH1::AddDirectoryStatus();
4354 TH1 *top = (TH1*)asym->Clone();
4355 TH1 *bottom = (TH1*)asym->Clone();
4356 TH1::AddDirectory(addStatus);
4357
4358 // form the top and bottom of the asymmetry, and then divide:
4359 top->Add(h1,h2,1,-c2);
4360 bottom->Add(h1,h2,1,c2);
4361 asym->Divide(top,bottom);
4362
4363 Int_t xmax = asym->GetNbinsX();
4364 Int_t ymax = asym->GetNbinsY();
4365 Int_t zmax = asym->GetNbinsZ();
4366
4367 if (h1->fBuffer) h1->BufferEmpty(1);
4368 if (h2->fBuffer) h2->BufferEmpty(1);
4369 if (bottom->fBuffer) bottom->BufferEmpty(1);
4370
4371 // now loop over bins to calculate the correct errors
4372 // the reason this error calculation looks complex is because of c2
4373 for(Int_t i=1; i<= xmax; i++){
4374 for(Int_t j=1; j<= ymax; j++){
4375 for(Int_t k=1; k<= zmax; k++){
4376 Int_t bin = GetBin(i, j, k);
4377 // here some bin contents are written into variables to make the error
4378 // calculation a little more legible:
4380 Double_t b = h2->RetrieveBinContent(bin);
4381 Double_t bot = bottom->RetrieveBinContent(bin);
4382
4383 // make sure there are some events, if not, then the errors are set = 0
4384 // automatically.
4385 //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
4386 if(bot < 1e-6){}
4387 else{
4388 // computation of errors by Christos Leonidopoulos
4389 Double_t dasq = h1->GetBinErrorSqUnchecked(bin);
4390 Double_t dbsq = h2->GetBinErrorSqUnchecked(bin);
4391 Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4392 asym->SetBinError(i,j,k,error);
4393 }
4394 }
4395 }
4396 }
4397 delete top;
4398 delete bottom;
4399
4400 return asym;
4401}
4402
4403////////////////////////////////////////////////////////////////////////////////
4404/// Static function
4405/// return the default buffer size for automatic histograms
4406/// the parameter fgBufferSize may be changed via SetDefaultBufferSize
4407
4409{
4410 return fgBufferSize;
4411}
4412
4413////////////////////////////////////////////////////////////////////////////////
4414/// Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
4415/// see TH1::SetDefaultSumw2.
4416
4418{
4419 return fgDefaultSumw2;
4420}
4421
4422////////////////////////////////////////////////////////////////////////////////
4423/// Return the current number of entries.
4424
4426{
4427 if (fBuffer) {
4428 Int_t nentries = (Int_t) fBuffer[0];
4429 if (nentries > 0) return nentries;
4430 }
4431
4432 return fEntries;
4433}
4434
4435////////////////////////////////////////////////////////////////////////////////
4436/// Number of effective entries of the histogram.
4437///
4438/// \f[
4439/// neff = \frac{(\sum Weights )^2}{(\sum Weight^2 )}
4440/// \f]
4441///
4442/// In case of an unweighted histogram this number is equivalent to the
4443/// number of entries of the histogram.
4444/// For a weighted histogram, this number corresponds to the hypothetical number of unweighted entries
4445/// a histogram would need to have the same statistical power as this weighted histogram.
4446/// Note: The underflow/overflow are included if one has set the TH1::StatOverFlows flag
4447/// and if the statistics has been computed at filling time.
4448/// If a range is set in the histogram the number is computed from the given range.
4449
4451{
4452 Stat_t s[kNstat];
4453 this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
4454 return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4455}
4456
4457////////////////////////////////////////////////////////////////////////////////
4458/// Shortcut to set the three histogram colors with a single call.
4459///
4460/// By default: linecolor = markercolor = fillcolor = -1
4461/// If a color is < 0 this method does not change the corresponding color if positive or null it set the color.
4462///
4463/// For instance:
4464/// ~~~ {.cpp}
4465/// h->SetColors(kRed, kRed);
4466/// ~~~
4467/// will set the line color and the marker color to red.
4468
4469void TH1::SetColors(Color_t linecolor, Color_t markercolor, Color_t fillcolor)
4470{
4471 if (linecolor >= 0)
4472 SetLineColor(linecolor);
4473 if (markercolor >= 0)
4474 SetMarkerColor(markercolor);
4475 if (fillcolor >= 0)
4476 SetFillColor(fillcolor);
4477}
4478
4479
4480////////////////////////////////////////////////////////////////////////////////
4481/// Set highlight (enable/disable) mode for the histogram
4482/// by default highlight mode is disable
4483
4484void TH1::SetHighlight(Bool_t set)
4485{
4486 if (IsHighlight() == set)
4487 return;
4488 if (fDimension > 2) {
4489 Info("SetHighlight", "Supported only 1-D or 2-D histograms");
4490 return;
4491 }
4492
4493 SetBit(kIsHighlight, set);
4494
4495 if (fPainter)
4497}
4498
4499////////////////////////////////////////////////////////////////////////////////
4500/// Redefines TObject::GetObjectInfo.
4501/// Displays the histogram info (bin number, contents, integral up to bin
4502/// corresponding to cursor position px,py
4503
4504char *TH1::GetObjectInfo(Int_t px, Int_t py) const
4505{
4506 return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
4507}
4508
4509////////////////////////////////////////////////////////////////////////////////
4510/// Return pointer to painter.
4511/// If painter does not exist, it is created
4512
4514{
4515 if (!fPainter) {
4516 TString opt = option;
4517 opt.ToLower();
4518 if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
4519 //try to create TGLHistPainter
4520 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
4521
4522 if (handler && handler->LoadPlugin() != -1)
4523 fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
4524 }
4525 }
4526
4528
4529 return fPainter;
4530}
4531
4532////////////////////////////////////////////////////////////////////////////////
4533/// Compute Quantiles for this histogram
4534/// Quantile x_p := Q(p) is defined as the value x_p such that the cumulative
4535/// probability distribution Function F of variable X yields:
4536///
4537/// ~~~ {.cpp}
4538/// F(x_p) = Pr(X <= x_p) = p with 0 <= p <= 1.
4539/// x_p = Q(p) = F_inv(p)
4540/// ~~~
4541///
4542/// For instance the median x_0.5 of a distribution is defined as that value
4543/// of the random variable X for which the distribution function equals 0.5:
4544///
4545/// ~~~ {.cpp}
4546/// F(x_0.5) = Probability(X < x_0.5) = 0.5
4547/// x_0.5 = Q(0.5)
4548/// ~~~
4549///
4550/// \author Eddy Offermann
4551/// code from Eddy Offermann, Renaissance
4552///
4553/// \param[in] n maximum size of array xp and size of array p (if given)
4554/// \param[out] xp array to be filled with nq quantiles evaluated at (p). Memory has to be preallocated by caller.
4555/// If p is null (default value), then xp is actually set to the (first n) histogram bin edges
4556/// \param[in] p array of cumulative probabilities where quantiles should be evaluated.
4557/// - if p is null, the CDF of the histogram will be used instead as array, and will
4558/// have a size = number of bins + 1 in h. It will correspond to the
4559/// quantiles calculated at the lowest edge of the histogram (quantile=0) and
4560/// all the upper edges of the bins. (nbins might be > n).
4561/// - if p is not null, it is assumed to contain at least n values.
4562/// \return value nq (<=n) with the number of quantiles computed
4563///
4564/// Note that the Integral of the histogram is automatically recomputed
4565/// if the number of entries is different of the number of entries when
4566/// the integral was computed last time. In case you do not use the Fill
4567/// functions to fill your histogram, but SetBinContent, you must call
4568/// TH1::ComputeIntegral before calling this function.
4569///
4570/// Getting quantiles xp from two histograms and storing results in a TGraph,
4571/// a so-called QQ-plot
4572///
4573/// ~~~ {.cpp}
4574/// TGraph *gr = new TGraph(nprob);
4575/// h1->GetQuantiles(nprob,gr->GetX());
4576/// h2->GetQuantiles(nprob,gr->GetY());
4577/// gr->Draw("alp");
4578/// ~~~
4579///
4580/// Example:
4581///
4582/// ~~~ {.cpp}
4583/// void quantiles() {
4584/// // demo for quantiles
4585/// const Int_t nq = 20;
4586/// TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
4587/// h->FillRandom("gaus",5000);
4588/// h->GetXaxis()->SetTitle("x");
4589/// h->GetYaxis()->SetTitle("Counts");
4590///
4591/// Double_t p[nq]; // probabilities where to evaluate the quantiles in [0,1]
4592/// Double_t xp[nq]; // array of positions X to store the resulting quantiles
4593/// for (Int_t i=0;i<nq;i++) p[i] = Float_t(i+1)/nq;
4594/// h->GetQuantiles(nq,xp,p);
4595///
4596/// //show the original histogram in the top pad
4597/// TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
4598/// c1->Divide(1,2);
4599/// c1->cd(1);
4600/// h->Draw();
4601///
4602/// // show the quantiles in the bottom pad
4603/// c1->cd(2);
4604/// gPad->SetGrid();
4605/// TGraph *gr = new TGraph(nq,p,xp);
4606/// gr->SetMarkerStyle(21);
4607/// gr->GetXaxis()->SetTitle("p");
4608/// gr->GetYaxis()->SetTitle("x");
4609/// gr->Draw("alp");
4610/// }
4611/// ~~~
4612
4614{
4615 if (GetDimension() > 1) {
4616 Error("GetQuantiles","Only available for 1-d histograms");
4617 return 0;
4618 }
4619
4620 const Int_t nbins = GetXaxis()->GetNbins();
4621 if (!fIntegral) ComputeIntegral();
4622 if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4623
4624 Int_t i, ibin;
4625 Double_t *prob = (Double_t*)p;
4626 Int_t nq = n;
4627 if (p == nullptr) {
4628 nq = nbins+1;
4629 prob = new Double_t[nq];
4630 prob[0] = 0;
4631 for (i=1;i<nq;i++) {
4632 prob[i] = fIntegral[i]/fIntegral[nbins];
4633 }
4634 }
4635
4636 for (i = 0; i < nq; i++) {
4637 ibin = TMath::BinarySearch(nbins,fIntegral,prob[i]);
4638 if (fIntegral[ibin] == prob[i]) {
4639 if (prob[i] == 0.) {
4640 for (; ibin+1 <= nbins && fIntegral[ibin+1] == 0.; ++ibin) {
4641
4642 }
4643 xp[i] = fXaxis.GetBinUpEdge(ibin);
4644 }
4645 else if (prob[i] == 1.) {
4646 xp[i] = fXaxis.GetBinUpEdge(ibin);
4647 }
4648 else {
4649 // Find equal integral in later bins (ie their entries are zero)
4650 Double_t width = 0;
4651 for (Int_t j = ibin+1; j <= nbins; ++j) {
4652 if (prob[i] == fIntegral[j]) {
4653 width += fXaxis.GetBinWidth(j);
4654 }
4655 else
4656 break;
4657 }
4658 xp[i] = width == 0 ? fXaxis.GetBinCenter(ibin) : fXaxis.GetBinUpEdge(ibin) + width/2.;
4659 }
4660 }
4661 else {
4662 xp[i] = GetBinLowEdge(ibin+1);
4663 const Double_t dint = fIntegral[ibin+1]-fIntegral[ibin];
4664 if (dint > 0) xp[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4665 }
4666 }
4667
4668 if (!p) delete [] prob;
4669 return nq;
4670}
4671
4672////////////////////////////////////////////////////////////////////////////////
4673/// Decode string choptin and fill fitOption structure.
4674
4675Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
4676{
4678 return 1;
4679}
4680
4681////////////////////////////////////////////////////////////////////////////////
4682/// Compute Initial values of parameters for a gaussian.
4683
4684void H1InitGaus()
4685{
4686 Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4687 Int_t bin;
4688 const Double_t sqrtpi = 2.506628;
4689
4690 // - Compute mean value and StdDev of the histogram in the given range
4692 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4693 Int_t hxfirst = hFitter->GetXfirst();
4694 Int_t hxlast = hFitter->GetXlast();
4695 Double_t valmax = curHist->GetBinContent(hxfirst);
4696 Double_t binwidx = curHist->GetBinWidth(hxfirst);
4697 allcha = sumx = sumx2 = 0;
4698 for (bin=hxfirst;bin<=hxlast;bin++) {
4699 x = curHist->GetBinCenter(bin);
4700 val = TMath::Abs(curHist->GetBinContent(bin));
4701 if (val > valmax) valmax = val;
4702 sumx += val*x;
4703 sumx2 += val*x*x;
4704 allcha += val;
4705 }
4706 if (allcha == 0) return;
4707 mean = sumx/allcha;
4708 stddev = sumx2/allcha - mean*mean;
4709 if (stddev > 0) stddev = TMath::Sqrt(stddev);
4710 else stddev = 0;
4711 if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4712 //if the distribution is really gaussian, the best approximation
4713 //is binwidx*allcha/(sqrtpi*stddev)
4714 //However, in case of non-gaussian tails, this underestimates
4715 //the normalisation constant. In this case the maximum value
4716 //is a better approximation.
4717 //We take the average of both quantities
4718 Double_t constant = 0.5*(valmax+binwidx*allcha/(sqrtpi*stddev));
4719
4720 //In case the mean value is outside the histo limits and
4721 //the StdDev is bigger than the range, we take
4722 // mean = center of bins
4723 // stddev = half range
4724 Double_t xmin = curHist->GetXaxis()->GetXmin();
4725 Double_t xmax = curHist->GetXaxis()->GetXmax();
4726 if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4727 mean = 0.5*(xmax+xmin);
4728 stddev = 0.5*(xmax-xmin);
4729 }
4730 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4731 f1->SetParameter(0,constant);
4732 f1->SetParameter(1,mean);
4733 f1->SetParameter(2,stddev);
4734 f1->SetParLimits(2,0,10*stddev);
4735}
4736
4737////////////////////////////////////////////////////////////////////////////////
4738/// Compute Initial values of parameters for an exponential.
4739
4740void H1InitExpo()
4741{
4742 Double_t constant, slope;
4743 Int_t ifail;
4745 Int_t hxfirst = hFitter->GetXfirst();
4746 Int_t hxlast = hFitter->GetXlast();
4747 Int_t nchanx = hxlast - hxfirst + 1;
4748
4749 H1LeastSquareLinearFit(-nchanx, constant, slope, ifail);
4750
4751 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4752 f1->SetParameter(0,constant);
4753 f1->SetParameter(1,slope);
4754
4755}
4756
4757////////////////////////////////////////////////////////////////////////////////
4758/// Compute Initial values of parameters for a polynom.
4759
4760void H1InitPolynom()
4761{
4762 Double_t fitpar[25];
4763
4765 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4766 Int_t hxfirst = hFitter->GetXfirst();
4767 Int_t hxlast = hFitter->GetXlast();
4768 Int_t nchanx = hxlast - hxfirst + 1;
4769 Int_t npar = f1->GetNpar();
4770
4771 if (nchanx <=1 || npar == 1) {
4772 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4773 fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4774 } else {
4775 H1LeastSquareFit( nchanx, npar, fitpar);
4776 }
4777 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4778}
4779
4780////////////////////////////////////////////////////////////////////////////////
4781/// Least squares lpolynomial fitting without weights.
4782///
4783/// \param[in] n number of points to fit
4784/// \param[in] m number of parameters
4785/// \param[in] a array of parameters
4786///
4787/// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
4788/// (E.Keil. revised by B.Schorr, 23.10.1981.)
4789
4791{
4792 const Double_t zero = 0.;
4793 const Double_t one = 1.;
4794 const Int_t idim = 20;
4795
4796 Double_t b[400] /* was [20][20] */;
4797 Int_t i, k, l, ifail;
4798 Double_t power;
4799 Double_t da[20], xk, yk;
4800
4801 if (m <= 2) {
4802 H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4803 return;
4804 }
4805 if (m > idim || m > n) return;
4806 b[0] = Double_t(n);
4807 da[0] = zero;
4808 for (l = 2; l <= m; ++l) {
4809 b[l-1] = zero;
4810 b[m + l*20 - 21] = zero;
4811 da[l-1] = zero;
4812 }
4814 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4815 Int_t hxfirst = hFitter->GetXfirst();
4816 Int_t hxlast = hFitter->GetXlast();
4817 for (k = hxfirst; k <= hxlast; ++k) {
4818 xk = curHist->GetBinCenter(k);
4819 yk = curHist->GetBinContent(k);
4820 power = one;
4821 da[0] += yk;
4822 for (l = 2; l <= m; ++l) {
4823 power *= xk;
4824 b[l-1] += power;
4825 da[l-1] += power*yk;
4826 }
4827 for (l = 2; l <= m; ++l) {
4828 power *= xk;
4829 b[m + l*20 - 21] += power;
4830 }
4831 }
4832 for (i = 3; i <= m; ++i) {
4833 for (k = i; k <= m; ++k) {
4834 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4835 }
4836 }
4837 H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
4838
4839 for (i=0; i<m; ++i) a[i] = da[i];
4840
4841}
4842
4843////////////////////////////////////////////////////////////////////////////////
4844/// Least square linear fit without weights.
4845///
4846/// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
4847/// (added to LSQ by B. Schorr, 15.02.1982.)
4848
4849void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
4850{
4851 Double_t xbar, ybar, x2bar;
4852 Int_t i, n;
4853 Double_t xybar;
4854 Double_t fn, xk, yk;
4855 Double_t det;
4856
4857 n = TMath::Abs(ndata);
4858 ifail = -2;
4859 xbar = ybar = x2bar = xybar = 0;
4861 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4862 Int_t hxfirst = hFitter->GetXfirst();
4863 Int_t hxlast = hFitter->GetXlast();
4864 for (i = hxfirst; i <= hxlast; ++i) {
4865 xk = curHist->GetBinCenter(i);
4866 yk = curHist->GetBinContent(i);
4867 if (ndata < 0) {
4868 if (yk <= 0) yk = 1e-9;
4869 yk = TMath::Log(yk);
4870 }
4871 xbar += xk;
4872 ybar += yk;
4873 x2bar += xk*xk;
4874 xybar += xk*yk;
4875 }
4876 fn = Double_t(n);
4877 det = fn*x2bar - xbar*xbar;
4878 ifail = -1;
4879 if (det <= 0) {
4880 a0 = ybar/fn;
4881 a1 = 0;
4882 return;
4883 }
4884 ifail = 0;
4885 a0 = (x2bar*ybar - xbar*xybar) / det;
4886 a1 = (fn*xybar - xbar*ybar) / det;
4887
4888}
4889
4890////////////////////////////////////////////////////////////////////////////////
4891/// Extracted from CERN Program library routine DSEQN.
4892///
4893/// Translated to C++ by Rene Brun
4894
4895void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b)
4896{
4897 Int_t a_dim1, a_offset, b_dim1, b_offset;
4898 Int_t nmjp1, i, j, l;
4899 Int_t im1, jp1, nm1, nmi;
4900 Double_t s1, s21, s22;
4901 const Double_t one = 1.;
4902
4903 /* Parameter adjustments */
4904 b_dim1 = idim;
4905 b_offset = b_dim1 + 1;
4906 b -= b_offset;
4907 a_dim1 = idim;
4908 a_offset = a_dim1 + 1;
4909 a -= a_offset;
4910
4911 if (idim < n) return;
4912
4913 ifail = 0;
4914 for (j = 1; j <= n; ++j) {
4915 if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
4916 a[j + j*a_dim1] = one / a[j + j*a_dim1];
4917 if (j == n) continue;
4918 jp1 = j + 1;
4919 for (l = jp1; l <= n; ++l) {
4920 a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4921 s1 = -a[l + (j+1)*a_dim1];
4922 for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4923 a[l + (j+1)*a_dim1] = -s1;
4924 }
4925 }
4926 if (k <= 0) return;
4927
4928 for (l = 1; l <= k; ++l) {
4929 b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
4930 }
4931 if (n == 1) return;
4932 for (l = 1; l <= k; ++l) {
4933 for (i = 2; i <= n; ++i) {
4934 im1 = i - 1;
4935 s21 = -b[i + l*b_dim1];
4936 for (j = 1; j <= im1; ++j) {
4937 s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
4938 }
4939 b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
4940 }
4941 nm1 = n - 1;
4942 for (i = 1; i <= nm1; ++i) {
4943 nmi = n - i;
4944 s22 = -b[nmi + l*b_dim1];
4945 for (j = 1; j <= i; ++j) {
4946 nmjp1 = n - j + 1;
4947 s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
4948 }
4949 b[nmi + l*b_dim1] = -s22;
4950 }
4951 }
4952}
4953
4954////////////////////////////////////////////////////////////////////////////////
4955/// Return Global bin number corresponding to binx,y,z.
4956///
4957/// 2-D and 3-D histograms are represented with a one dimensional
4958/// structure.
4959/// This has the advantage that all existing functions, such as
4960/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
4961///
4962/// In case of a TH1x, returns binx directly.
4963/// see TH1::GetBinXYZ for the inverse transformation.
4964///
4965/// Convention for numbering bins
4966///
4967/// For all histogram types: nbins, xlow, xup
4968///
4969/// - bin = 0; underflow bin
4970/// - bin = 1; first bin with low-edge xlow INCLUDED
4971/// - bin = nbins; last bin with upper-edge xup EXCLUDED
4972/// - bin = nbins+1; overflow bin
4973///
4974/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4975/// For example, assuming a 3-D histogram with binx,biny,binz, the function
4976///
4977/// ~~~ {.cpp}
4978/// Int_t bin = h->GetBin(binx,biny,binz);
4979/// ~~~
4980///
4981/// returns a global/linearized bin number. This global bin is useful
4982/// to access the bin information independently of the dimension.
4983
4984Int_t TH1::GetBin(Int_t binx, Int_t, Int_t) const
4985{
4986 Int_t ofx = fXaxis.GetNbins() + 1; // overflow bin
4987 if (binx < 0) binx = 0;
4988 if (binx > ofx) binx = ofx;
4989
4990 return binx;
4991}
4992
4993////////////////////////////////////////////////////////////////////////////////
4994/// Return binx, biny, binz corresponding to the global bin number globalbin
4995/// see TH1::GetBin function above
4996
4997void TH1::GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz) const
4998{
4999 Int_t nx = fXaxis.GetNbins()+2;
5000 Int_t ny = fYaxis.GetNbins()+2;
5001
5002 if (GetDimension() == 1) {
5003 binx = binglobal%nx;
5004 biny = 0;
5005 binz = 0;
5006 return;
5007 }
5008 if (GetDimension() == 2) {
5009 binx = binglobal%nx;
5010 biny = ((binglobal-binx)/nx)%ny;
5011 binz = 0;
5012 return;
5013 }
5014 if (GetDimension() == 3) {
5015 binx = binglobal%nx;
5016 biny = ((binglobal-binx)/nx)%ny;
5017 binz = ((binglobal-binx)/nx -biny)/ny;
5018 }
5019}
5020
5021////////////////////////////////////////////////////////////////////////////////
5022/// Return a random number distributed according the histogram bin contents.
5023/// This function checks if the bins integral exists. If not, the integral
5024/// is evaluated, normalized to one.
5025///
5026/// @param rng (optional) Random number generator pointer used (default is gRandom)
5027///
5028/// The integral is automatically recomputed if the number of entries
5029/// is not the same then when the integral was computed.
5030/// NB Only valid for 1-d histograms. Use GetRandom2 or 3 otherwise.
5031/// If the histogram has a bin with negative content a NaN is returned
5032
5033Double_t TH1::GetRandom(TRandom * rng) const
5034{
5035 if (fDimension > 1) {
5036 Error("GetRandom","Function only valid for 1-d histograms");
5037 return 0;
5038 }
5039 Int_t nbinsx = GetNbinsX();
5040 Double_t integral = 0;
5041 // compute integral checking that all bins have positive content (see ROOT-5894)
5042 if (fIntegral) {
5043 if (fIntegral[nbinsx+1] != fEntries) integral = ((TH1*)this)->ComputeIntegral(true);
5044 else integral = fIntegral[nbinsx];
5045 } else {
5046 integral = ((TH1*)this)->ComputeIntegral(true);
5047 }
5048 if (integral == 0) return 0;
5049 // return a NaN in case some bins have negative content
5050 if (integral == TMath::QuietNaN() ) return TMath::QuietNaN();
5051
5052 Double_t r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
5053 Int_t ibin = TMath::BinarySearch(nbinsx,fIntegral,r1);
5054 Double_t x = GetBinLowEdge(ibin+1);
5055 if (r1 > fIntegral[ibin]) x +=
5056 GetBinWidth(ibin+1)*(r1-fIntegral[ibin])/(fIntegral[ibin+1] - fIntegral[ibin]);
5057 return x;
5058}
5059
5060////////////////////////////////////////////////////////////////////////////////
5061/// Return content of bin number bin.
5062///
5063/// Implemented in TH1C,S,F,D
5064///
5065/// Convention for numbering bins
5066///
5067/// For all histogram types: nbins, xlow, xup
5068///
5069/// - bin = 0; underflow bin
5070/// - bin = 1; first bin with low-edge xlow INCLUDED
5071/// - bin = nbins; last bin with upper-edge xup EXCLUDED
5072/// - bin = nbins+1; overflow bin
5073///
5074/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
5075/// For example, assuming a 3-D histogram with binx,biny,binz, the function
5076///
5077/// ~~~ {.cpp}
5078/// Int_t bin = h->GetBin(binx,biny,binz);
5079/// ~~~
5080///
5081/// returns a global/linearized bin number. This global bin is useful
5082/// to access the bin information independently of the dimension.
5083
5085{
5086 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
5087 if (bin < 0) bin = 0;
5088 if (bin >= fNcells) bin = fNcells-1;
5089
5090 return RetrieveBinContent(bin);
5091}
5092
5093////////////////////////////////////////////////////////////////////////////////
5094/// Compute first binx in the range [firstx,lastx] for which
5095/// diff = abs(bin_content-c) <= maxdiff
5096///
5097/// In case several bins in the specified range with diff=0 are found
5098/// the first bin found is returned in binx.
5099/// In case several bins in the specified range satisfy diff <=maxdiff
5100/// the bin with the smallest difference is returned in binx.
5101/// In all cases the function returns the smallest difference.
5102///
5103/// NOTE1: if firstx <= 0, firstx is set to bin 1
5104/// if (lastx < firstx then firstx is set to the number of bins
5105/// ie if firstx=0 and lastx=0 (default) the search is on all bins.
5106///
5107/// NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
5108
5109Double_t TH1::GetBinWithContent(Double_t c, Int_t &binx, Int_t firstx, Int_t lastx,Double_t maxdiff) const
5110{
5111 if (fDimension > 1) {
5112 binx = 0;
5113 Error("GetBinWithContent","function is only valid for 1-D histograms");
5114 return 0;
5115 }
5116
5117 if (fBuffer) ((TH1*)this)->BufferEmpty();
5118
5119 if (firstx <= 0) firstx = 1;
5120 if (lastx < firstx) lastx = fXaxis.GetNbins();
5121 Int_t binminx = 0;
5122 Double_t diff, curmax = 1.e240;
5123 for (Int_t i=firstx;i<=lastx;i++) {
5124 diff = TMath::Abs(RetrieveBinContent(i)-c);
5125 if (diff <= 0) {binx = i; return diff;}
5126 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
5127 }
5128 binx = binminx;
5129 return curmax;
5130}
5131
5132////////////////////////////////////////////////////////////////////////////////
5133/// Given a point x, approximates the value via linear interpolation
5134/// based on the two nearest bin centers
5135///
5136/// Andy Mastbaum 10/21/08
5137
5139{
5140 if (fBuffer) ((TH1*)this)->BufferEmpty();
5141
5142 Int_t xbin = fXaxis.FindFixBin(x);
5143 Double_t x0,x1,y0,y1;
5144
5145 if(x<=GetBinCenter(1)) {
5146 return RetrieveBinContent(1);
5147 } else if(x>=GetBinCenter(GetNbinsX())) {
5148 return RetrieveBinContent(GetNbinsX());
5149 } else {
5150 if(x<=GetBinCenter(xbin)) {
5151 y0 = RetrieveBinContent(xbin-1);
5152 x0 = GetBinCenter(xbin-1);
5153 y1 = RetrieveBinContent(xbin);
5154 x1 = GetBinCenter(xbin);
5155 } else {
5156 y0 = RetrieveBinContent(xbin);
5157 x0 = GetBinCenter(xbin);
5158 y1 = RetrieveBinContent(xbin+1);
5159 x1 = GetBinCenter(xbin+1);
5160 }
5161 return y0 + (x-x0)*((y1-y0)/(x1-x0));
5162 }
5163}
5164
5165////////////////////////////////////////////////////////////////////////////////
5166/// 2d Interpolation. Not yet implemented.
5167
5169{
5170 Error("Interpolate","This function must be called with 1 argument for a TH1");
5171 return 0;
5172}
5173
5174////////////////////////////////////////////////////////////////////////////////
5175/// 3d Interpolation. Not yet implemented.
5176
5178{
5179 Error("Interpolate","This function must be called with 1 argument for a TH1");
5180 return 0;
5181}
5182
5183///////////////////////////////////////////////////////////////////////////////
5184/// Check if a histogram is empty
5185/// (this is a protected method used mainly by TH1Merger )
5186
5187Bool_t TH1::IsEmpty() const
5188{
5189 // if fTsumw or fentries are not zero histogram is not empty
5190 // need to use GetEntries() instead of fEntries in case of bugger histograms
5191 // so we will flash the buffer
5192 if (fTsumw != 0) return kFALSE;
5193 if (GetEntries() != 0) return kFALSE;
5194 // case fTSumw == 0 amd entries are also zero
5195 // this should not really happening, but if one sets content by hand
5196 // it can happen. a call to ResetStats() should be done in such cases
5197 double sumw = 0;
5198 for (int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
5199 return (sumw != 0) ? kFALSE : kTRUE;
5200}
5201
5202////////////////////////////////////////////////////////////////////////////////
5203/// Return true if the bin is overflow.
5204
5205Bool_t TH1::IsBinOverflow(Int_t bin, Int_t iaxis) const
5206{
5207 Int_t binx, biny, binz;
5208 GetBinXYZ(bin, binx, biny, binz);
5209
5210 if (iaxis == 0) {
5211 if ( fDimension == 1 )
5212 return binx >= GetNbinsX() + 1;
5213 if ( fDimension == 2 )
5214 return (binx >= GetNbinsX() + 1) ||
5215 (biny >= GetNbinsY() + 1);
5216 if ( fDimension == 3 )
5217 return (binx >= GetNbinsX() + 1) ||
5218 (biny >= GetNbinsY() + 1) ||
5219 (binz >= GetNbinsZ() + 1);
5220 return kFALSE;
5221 }
5222 if (iaxis == 1)
5223 return binx >= GetNbinsX() + 1;
5224 if (iaxis == 2)
5225 return biny >= GetNbinsY() + 1;
5226 if (iaxis == 3)
5227 return binz >= GetNbinsZ() + 1;
5228
5229 Error("IsBinOverflow","Invalid axis value");
5230 return kFALSE;
5231}
5232
5233////////////////////////////////////////////////////////////////////////////////
5234/// Return true if the bin is underflow.
5235/// If iaxis = 0 make OR with all axes otherwise check only for the given axis
5236
5237Bool_t TH1::IsBinUnderflow(Int_t bin, Int_t iaxis) const
5238{
5239 Int_t binx, biny, binz;
5240 GetBinXYZ(bin, binx, biny, binz);
5241
5242 if (iaxis == 0) {
5243 if ( fDimension == 1 )
5244 return (binx <= 0);
5245 else if ( fDimension == 2 )
5246 return (binx <= 0 || biny <= 0);
5247 else if ( fDimension == 3 )
5248 return (binx <= 0 || biny <= 0 || binz <= 0);
5249 else
5250 return kFALSE;
5251 }
5252 if (iaxis == 1)
5253 return (binx <= 0);
5254 if (iaxis == 2)
5255 return (biny <= 0);
5256 if (iaxis == 3)
5257 return (binz <= 0);
5258
5259 Error("IsBinUnderflow","Invalid axis value");
5260 return kFALSE;
5261}
5262
5263////////////////////////////////////////////////////////////////////////////////
5264/// Reduce the number of bins for the axis passed in the option to the number of bins having a label.
5265/// The method will remove only the extra bins existing after the last "labeled" bin.
5266/// Note that if there are "un-labeled" bins present between "labeled" bins they will not be removed
5267
5269{
5270 Int_t iaxis = AxisChoice(ax);
5271 TAxis *axis = nullptr;
5272 if (iaxis == 1) axis = GetXaxis();
5273 if (iaxis == 2) axis = GetYaxis();
5274 if (iaxis == 3) axis = GetZaxis();
5275 if (!axis) {
5276 Error("LabelsDeflate","Invalid axis option %s",ax);
5277 return;
5278 }
5279 if (!axis->GetLabels()) return;
5280
5281 // find bin with last labels
5282 // bin number is object ID in list of labels
5283 // therefore max bin number is number of bins of the deflated histograms
5284 TIter next(axis->GetLabels());
5285 TObject *obj;
5286 Int_t nbins = 0;
5287 while ((obj = next())) {
5288 Int_t ibin = obj->GetUniqueID();
5289 if (ibin > nbins) nbins = ibin;
5290 }
5291 if (nbins < 1) nbins = 1;
5292
5293 // Do nothing in case it was the last bin
5294 if (nbins==axis->GetNbins()) return;
5295
5296 TH1 *hold = (TH1*)IsA()->New();
5297 R__ASSERT(hold);
5298 hold->SetDirectory(nullptr);
5299 Copy(*hold);
5300
5301 Bool_t timedisp = axis->GetTimeDisplay();
5302 Double_t xmin = axis->GetXmin();
5303 Double_t xmax = axis->GetBinUpEdge(nbins);
5304 if (xmax <= xmin) xmax = xmin +nbins;
5305 axis->SetRange(0,0);
5306 axis->Set(nbins,xmin,xmax);
5307 SetBinsLength(-1); // reset the number of cells
5308 Int_t errors = fSumw2.fN;
5309 if (errors) fSumw2.Set(fNcells);
5310 axis->SetTimeDisplay(timedisp);
5311 // reset histogram content
5312 Reset("ICE");
5313
5314 //now loop on all bins and refill
5315 // NOTE that if the bins without labels have content
5316 // it will be put in the underflow/overflow.
5317 // For this reason we use AddBinContent method
5318 Double_t oldEntries = fEntries;
5319 Int_t bin,binx,biny,binz;
5320 for (bin=0; bin < hold->fNcells; ++bin) {
5321 hold->GetBinXYZ(bin,binx,biny,binz);
5322 Int_t ibin = GetBin(binx,biny,binz);
5323 Double_t cu = hold->RetrieveBinContent(bin);
5324 AddBinContent(ibin,cu);
5325 if (errors) {
5326 fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5327 }
5328 }
5329 fEntries = oldEntries;
5330 delete hold;
5331}
5332
5333////////////////////////////////////////////////////////////////////////////////
5334/// Double the number of bins for axis.
5335/// Refill histogram.
5336/// This function is called by TAxis::FindBin(const char *label)
5337
5339{
5340 Int_t iaxis = AxisChoice(ax);
5341 TAxis *axis = nullptr;
5342 if (iaxis == 1) axis = GetXaxis();
5343 if (iaxis == 2) axis = GetYaxis();
5344 if (iaxis == 3) axis = GetZaxis();
5345 if (!axis) return;
5346
5347 TH1 *hold = (TH1*)IsA()->New();
5348 hold->SetDirectory(nullptr);
5349 Copy(*hold);
5350 hold->ResetBit(kMustCleanup);
5351
5352 Bool_t timedisp = axis->GetTimeDisplay();
5353 Int_t nbins = axis->GetNbins();
5354 Double_t xmin = axis->GetXmin();
5355 Double_t xmax = axis->GetXmax();
5356 xmax = xmin + 2*(xmax-xmin);
5357 axis->SetRange(0,0);
5358 // double the bins and recompute ncells
5359 axis->Set(2*nbins,xmin,xmax);
5360 SetBinsLength(-1);
5361 Int_t errors = fSumw2.fN;
5362 if (errors) fSumw2.Set(fNcells);
5363 axis->SetTimeDisplay(timedisp);
5364
5365 Reset("ICE"); // reset content and error
5366
5367 //now loop on all bins and refill
5368 Double_t oldEntries = fEntries;
5369 Int_t bin,ibin,binx,biny,binz;
5370 for (ibin =0; ibin < hold->fNcells; ibin++) {
5371 // get the binx,y,z values . The x-y-z (axis) bin values will stay the same between new-old after the expanding
5372 hold->GetBinXYZ(ibin,binx,biny,binz);
5373 bin = GetBin(binx,biny,binz);
5374
5375 // underflow and overflow will be cleaned up because their meaning has been altered
5376 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5377 continue;
5378 }
5379 else {
5380 AddBinContent(bin, hold->RetrieveBinContent(ibin));
5381 if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5382 }
5383 }
5384 fEntries = oldEntries;
5385 delete hold;
5386}
5387
5388////////////////////////////////////////////////////////////////////////////////
5389/// Sort bins with labels or set option(s) to draw axis with labels
5390/// \param[in] option
5391/// - "a" sort by alphabetic order
5392/// - ">" sort by decreasing values
5393/// - "<" sort by increasing values
5394/// - "h" draw labels horizontal
5395/// - "v" draw labels vertical
5396/// - "u" draw labels up (end of label right adjusted)
5397/// - "d" draw labels down (start of label left adjusted)
5398///
5399/// In case not all bins have labels sorting will work only in the case
5400/// the first `n` consecutive bins have all labels and sorting will be performed on
5401/// those label bins.
5402///
5403/// \param[in] ax axis
5404
5406{
5407 Int_t iaxis = AxisChoice(ax);
5408 TAxis *axis = nullptr;
5409 if (iaxis == 1)
5410 axis = GetXaxis();
5411 if (iaxis == 2)
5412 axis = GetYaxis();
5413 if (iaxis == 3)
5414 axis = GetZaxis();
5415 if (!axis)
5416 return;
5417 THashList *labels = axis->GetLabels();
5418 if (!labels) {
5419 Warning("LabelsOption", "Axis %s has no labels!",axis->GetName());
5420 return;
5421 }
5422 TString opt = option;
5423 opt.ToLower();
5424 Int_t iopt = -1;
5425 if (opt.Contains("h")) {
5430 iopt = 0;
5431 }
5432 if (opt.Contains("v")) {
5437 iopt = 1;
5438 }
5439 if (opt.Contains("u")) {
5440 axis->SetBit(TAxis::kLabelsUp);
5444 iopt = 2;
5445 }
5446 if (opt.Contains("d")) {
5451 iopt = 3;
5452 }
5453 Int_t sort = -1;
5454 if (opt.Contains("a"))
5455 sort = 0;
5456 if (opt.Contains(">"))
5457 sort = 1;
5458 if (opt.Contains("<"))
5459 sort = 2;
5460 if (sort < 0) {
5461 if (iopt < 0)
5462 Error("LabelsOption", "%s is an invalid label placement option!",opt.Data());
5463 return;
5464 }
5465
5466 // Code works only if first n bins have labels if we uncomment following line
5467 // but we don't want to support this special case
5468 // Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5469
5470 // support only cases where each bin has a labels (should be when axis is alphanumeric)
5471 Int_t n = labels->GetSize();
5472 if (n != axis->GetNbins()) {
5473 // check if labels are all consecutive and starts from the first bin
5474 // in that case the current code will work fine
5475 Int_t firstLabelBin = axis->GetNbins()+1;
5476 Int_t lastLabelBin = -1;
5477 for (Int_t i = 0; i < n; ++i) {
5478 Int_t bin = labels->At(i)->GetUniqueID();
5479 if (bin < firstLabelBin) firstLabelBin = bin;
5480 if (bin > lastLabelBin) lastLabelBin = bin;
5481 }
5482 if (firstLabelBin != 1 || lastLabelBin-firstLabelBin +1 != n) {
5483 Error("LabelsOption", "%s of Histogram %s contains bins without labels. Sorting will not work correctly - return",
5484 axis->GetName(), GetName());
5485 return;
5486 }
5487 // case where label bins are consecutive starting from first bin will work
5488 // calling before a TH1::LabelsDeflate() will avoid this error message
5489 Warning("LabelsOption", "axis %s of Histogram %s has extra following bins without labels. Sorting will work only for first label bins",
5490 axis->GetName(), GetName());
5491 }
5492 std::vector<Int_t> a(n);
5493 std::vector<Int_t> b(n);
5494
5495
5496 Int_t i, j, k;
5497 std::vector<Double_t> cont;
5498 std::vector<Double_t> errors2;
5499 THashList *labold = new THashList(labels->GetSize(), 1);
5500 TIter nextold(labels);
5501 TObject *obj = nullptr;
5502 labold->AddAll(labels);
5503 labels->Clear();
5504
5505 // delete buffer if it is there since bins will be reordered.
5506 if (fBuffer)
5507 BufferEmpty(1);
5508
5509 if (sort > 0) {
5510 //---sort by values of bins
5511 if (GetDimension() == 1) {
5512 cont.resize(n);
5513 if (fSumw2.fN)
5514 errors2.resize(n);
5515 for (i = 0; i < n; i++) {
5516 cont[i] = RetrieveBinContent(i + 1);
5517 if (!errors2.empty())
5518 errors2[i] = GetBinErrorSqUnchecked(i + 1);
5519 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5520 a[i] = i;
5521 }
5522 if (sort == 1)
5523 TMath::Sort(n, cont.data(), a.data(), kTRUE); // sort by decreasing values
5524 else
5525 TMath::Sort(n, cont.data(), a.data(), kFALSE); // sort by increasing values
5526 for (i = 0; i < n; i++) {
5527 // use UpdateBinCOntent to not screw up histogram entries
5528 UpdateBinContent(i + 1, cont[b[a[i]] - 1]); // b[a[i]] returns bin number. .we need to subtract 1
5529 if (gDebug)
5530 Info("LabelsOption","setting bin %d value %f from bin %d label %s at pos %d ",
5531 i+1,cont[b[a[i]] - 1],b[a[i]],labold->At(a[i])->GetName(),a[i]);
5532 if (!errors2.empty())
5533 fSumw2.fArray[i + 1] = errors2[b[a[i]] - 1];
5534 }
5535 for (i = 0; i < n; i++) {
5536 obj = labold->At(a[i]);
5537 labels->Add(obj);
5538 obj->SetUniqueID(i + 1);
5539 }
5540 } else if (GetDimension() == 2) {
5541 std::vector<Double_t> pcont(n + 2);
5542 Int_t nx = fXaxis.GetNbins() + 2;
5543 Int_t ny = fYaxis.GetNbins() + 2;
5544 cont.resize((nx + 2) * (ny + 2));
5545 if (fSumw2.fN)
5546 errors2.resize((nx + 2) * (ny + 2));
5547 for (i = 0; i < nx; i++) {
5548 for (j = 0; j < ny; j++) {
5549 Int_t bin = GetBin(i,j);
5550 cont[i + nx * j] = RetrieveBinContent(bin);
5551 if (!errors2.empty())
5552 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5553 if (axis == GetXaxis())
5554 k = i - 1;
5555 else
5556 k = j - 1;
5557 if (k >= 0 && k < n) { // we consider underflow/overflows in y for ordering the bins
5558 pcont[k] += cont[i + nx * j];
5559 a[k] = k;
5560 }
5561 }
5562 }
5563 if (sort == 1)
5564 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5565 else
5566 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5567 for (i = 0; i < n; i++) {
5568 // iterate on old label list to find corresponding bin match
5569 TIter next(labold);
5570 UInt_t bin = a[i] + 1;
5571 while ((obj = next())) {
5572 if (obj->GetUniqueID() == (UInt_t)bin)
5573 break;
5574 else
5575 obj = nullptr;
5576 }
5577 if (!obj) {
5578 // this should not really happen
5579 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5580 return;
5581 }
5582
5583 labels->Add(obj);
5584 if (gDebug)
5585 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from order " << a[i] << " bin "
5586 << b[a[i]] << "content " << pcont[a[i]] << std::endl;
5587 }
5588 // need to set here new ordered labels - otherwise loop before does not work since labold and labels list
5589 // contain same objects
5590 for (i = 0; i < n; i++) {
5591 labels->At(i)->SetUniqueID(i + 1);
5592 }
5593 // set now the bin contents
5594 if (axis == GetXaxis()) {
5595 for (i = 0; i < n; i++) {
5596 Int_t ix = a[i] + 1;
5597 for (j = 0; j < ny; j++) {
5598 Int_t bin = GetBin(i + 1, j);
5599 UpdateBinContent(bin, cont[ix + nx * j]);
5600 if (!errors2.empty())
5601 fSumw2.fArray[bin] = errors2[ix + nx * j];
5602 }
5603 }
5604 } else {
5605 // using y axis
5606 for (i = 0; i < nx; i++) {
5607 for (j = 0; j < n; j++) {
5608 Int_t iy = a[j] + 1;
5609 Int_t bin = GetBin(i, j + 1);
5610 UpdateBinContent(bin, cont[i + nx * iy]);
5611 if (!errors2.empty())
5612 fSumw2.fArray[bin] = errors2[i + nx * iy];
5613 }
5614 }
5615 }
5616 } else {
5617 // sorting histograms: 3D case
5618 std::vector<Double_t> pcont(n + 2);
5619 Int_t nx = fXaxis.GetNbins() + 2;
5620 Int_t ny = fYaxis.GetNbins() + 2;
5621 Int_t nz = fZaxis.GetNbins() + 2;
5622 Int_t l = 0;
5623 cont.resize((nx + 2) * (ny + 2) * (nz + 2));
5624 if (fSumw2.fN)
5625 errors2.resize((nx + 2) * (ny + 2) * (nz + 2));
5626 for (i = 0; i < nx; i++) {
5627 for (j = 0; j < ny; j++) {
5628 for (k = 0; k < nz; k++) {
5629 Int_t bin = GetBin(i,j,k);
5631 if (axis == GetXaxis())
5632 l = i - 1;
5633 else if (axis == GetYaxis())
5634 l = j - 1;
5635 else
5636 l = k - 1;
5637 if (l >= 0 && l < n) { // we consider underflow/overflows in y for ordering the bins
5638 pcont[l] += c;
5639 a[l] = l;
5640 }
5641 cont[i + nx * (j + ny * k)] = c;
5642 if (!errors2.empty())
5643 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5644 }
5645 }
5646 }
5647 if (sort == 1)
5648 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5649 else
5650 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5651 for (i = 0; i < n; i++) {
5652 // iterate on the old label list to find corresponding bin match
5653 TIter next(labold);
5654 UInt_t bin = a[i] + 1;
5655 obj = nullptr;
5656 while ((obj = next())) {
5657 if (obj->GetUniqueID() == (UInt_t)bin) {
5658 break;
5659 }
5660 else
5661 obj = nullptr;
5662 }
5663 if (!obj) {
5664 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5665 return;
5666 }
5667 labels->Add(obj);
5668 if (gDebug)
5669 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from bin " << a[i] << "content "
5670 << pcont[a[i]] << std::endl;
5671 }
5672
5673 // need to set here new ordered labels - otherwise loop before does not work since labold and llabels list
5674 // contain same objects
5675 for (i = 0; i < n; i++) {
5676 labels->At(i)->SetUniqueID(i + 1);
5677 }
5678 // set now the bin contents
5679 if (axis == GetXaxis()) {
5680 for (i = 0; i < n; i++) {
5681 Int_t ix = a[i] + 1;
5682 for (j = 0; j < ny; j++) {
5683 for (k = 0; k < nz; k++) {
5684 Int_t bin = GetBin(i + 1, j, k);
5685 UpdateBinContent(bin, cont[ix + nx * (j + ny * k)]);
5686 if (!errors2.empty())
5687 fSumw2.fArray[bin] = errors2[ix + nx * (j + ny * k)];
5688 }
5689 }
5690 }
5691 } else if (axis == GetYaxis()) {
5692 // using y axis
5693 for (i = 0; i < nx; i++) {
5694 for (j = 0; j < n; j++) {
5695 Int_t iy = a[j] + 1;
5696 for (k = 0; k < nz; k++) {
5697 Int_t bin = GetBin(i, j + 1, k);
5698 UpdateBinContent(bin, cont[i + nx * (iy + ny * k)]);
5699 if (!errors2.empty())
5700 fSumw2.fArray[bin] = errors2[i + nx * (iy + ny * k)];
5701 }
5702 }
5703 }
5704 } else {
5705 // using z axis
5706 for (i = 0; i < nx; i++) {
5707 for (j = 0; j < ny; j++) {
5708 for (k = 0; k < n; k++) {
5709 Int_t iz = a[k] + 1;
5710 Int_t bin = GetBin(i, j , k +1);
5711 UpdateBinContent(bin, cont[i + nx * (j + ny * iz)]);
5712 if (!errors2.empty())
5713 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * iz)];
5714 }
5715 }
5716 }
5717 }
5718 }
5719 } else {
5720 //---alphabetic sort
5721 // sort labels using vector of strings and TMath::Sort
5722 // I need to array because labels order in list is not necessary that of the bins
5723 std::vector<std::string> vecLabels(n);
5724 for (i = 0; i < n; i++) {
5725 vecLabels[i] = labold->At(i)->GetName();
5726 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5727 a[i] = i;
5728 }
5729 // sort in ascending order for strings
5730 TMath::Sort(n, vecLabels.data(), a.data(), kFALSE);
5731 // set the new labels
5732 for (i = 0; i < n; i++) {
5733 TObject *labelObj = labold->At(a[i]);
5734 labels->Add(labold->At(a[i]));
5735 // set the corresponding bin. NB bin starts from 1
5736 labelObj->SetUniqueID(i + 1);
5737 if (gDebug)
5738 std::cout << "bin " << i + 1 << " setting new labels for axis " << labold->At(a[i])->GetName() << " from "
5739 << b[a[i]] << std::endl;
5740 }
5741
5742 if (GetDimension() == 1) {
5743 cont.resize(n + 2);
5744 if (fSumw2.fN)
5745 errors2.resize(n + 2);
5746 for (i = 0; i < n; i++) {
5747 cont[i] = RetrieveBinContent(b[a[i]]);
5748 if (!errors2.empty())
5749 errors2[i] = GetBinErrorSqUnchecked(b[a[i]]);
5750 }
5751 for (i = 0; i < n; i++) {
5752 UpdateBinContent(i + 1, cont[i]);
5753 if (!errors2.empty())
5754 fSumw2.fArray[i+1] = errors2[i];
5755 }
5756 } else if (GetDimension() == 2) {
5757 Int_t nx = fXaxis.GetNbins() + 2;
5758 Int_t ny = fYaxis.GetNbins() + 2;
5759 cont.resize(nx * ny);
5760 if (fSumw2.fN)
5761 errors2.resize(nx * ny);
5762 // copy old bin contents and then set to new ordered bins
5763 // N.B. bin in histograms starts from 1, but in y we consider under/overflows
5764 for (i = 0; i < nx; i++) {
5765 for (j = 0; j < ny; j++) { // ny is nbins+2
5766 Int_t bin = GetBin(i, j);
5767 cont[i + nx * j] = RetrieveBinContent(bin);
5768 if (!errors2.empty())
5769 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5770 }
5771 }
5772 if (axis == GetXaxis()) {
5773 for (i = 0; i < n; i++) {
5774 for (j = 0; j < ny; j++) {
5775 Int_t bin = GetBin(i + 1 , j);
5776 UpdateBinContent(bin, cont[b[a[i]] + nx * j]);
5777 if (!errors2.empty())
5778 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * j];
5779 }
5780 }
5781 } else {
5782 for (i = 0; i < nx; i++) {
5783 for (j = 0; j < n; j++) {
5784 Int_t bin = GetBin(i, j + 1);
5785 UpdateBinContent(bin, cont[i + nx * b[a[j]]]);
5786 if (!errors2.empty())
5787 fSumw2.fArray[bin] = errors2[i + nx * b[a[j]]];
5788 }
5789 }
5790 }
5791 } else {
5792 // case of 3D (needs to be tested)
5793 Int_t nx = fXaxis.GetNbins() + 2;
5794 Int_t ny = fYaxis.GetNbins() + 2;
5795 Int_t nz = fZaxis.GetNbins() + 2;
5796 cont.resize(nx * ny * nz);
5797 if (fSumw2.fN)
5798 errors2.resize(nx * ny * nz);
5799 for (i = 0; i < nx; i++) {
5800 for (j = 0; j < ny; j++) {
5801 for (k = 0; k < nz; k++) {
5802 Int_t bin = GetBin(i, j, k);
5803 cont[i + nx * (j + ny * k)] = RetrieveBinContent(bin);
5804 if (!errors2.empty())
5805 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5806 }
5807 }
5808 }
5809 if (axis == GetXaxis()) {
5810 // labels on x axis
5811 for (i = 0; i < n; i++) { // for x we loop only on bins with the labels
5812 for (j = 0; j < ny; j++) {
5813 for (k = 0; k < nz; k++) {
5814 Int_t bin = GetBin(i + 1, j, k);
5815 UpdateBinContent(bin, cont[b[a[i]] + nx * (j + ny * k)]);
5816 if (!errors2.empty())
5817 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * (j + ny * k)];
5818 }
5819 }
5820 }
5821 } else if (axis == GetYaxis()) {
5822 // labels on y axis
5823 for (i = 0; i < nx; i++) {
5824 for (j = 0; j < n; j++) {
5825 for (k = 0; k < nz; k++) {
5826 Int_t bin = GetBin(i, j+1, k);
5827 UpdateBinContent(bin, cont[i + nx * (b[a[j]] + ny * k)]);
5828 if (!errors2.empty())
5829 fSumw2.fArray[bin] = errors2[i + nx * (b[a[j]] + ny * k)];
5830 }
5831 }
5832 }
5833 } else {
5834 // labels on z axis
5835 for (i = 0; i < nx; i++) {
5836 for (j = 0; j < ny; j++) {
5837 for (k = 0; k < n; k++) {
5838 Int_t bin = GetBin(i, j, k+1);
5839 UpdateBinContent(bin, cont[i + nx * (j + ny * b[a[k]])]);
5840 if (!errors2.empty())
5841 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * b[a[k]])];
5842 }
5843 }
5844 }
5845 }
5846 }
5847 }
5848 // need to set to zero the statistics if axis has been sorted
5849 // see for example TH3::PutStats for definition of s vector
5850 bool labelsAreSorted = kFALSE;
5851 for (i = 0; i < n; ++i) {
5852 if (a[i] != i) {
5853 labelsAreSorted = kTRUE;
5854 break;
5855 }
5856 }
5857 if (labelsAreSorted) {
5858 double s[TH1::kNstat];
5859 GetStats(s);
5860 if (iaxis == 1) {
5861 s[2] = 0; // fTsumwx
5862 s[3] = 0; // fTsumwx2
5863 s[6] = 0; // fTsumwxy
5864 s[9] = 0; // fTsumwxz
5865 } else if (iaxis == 2) {
5866 s[4] = 0; // fTsumwy
5867 s[5] = 0; // fTsumwy2
5868 s[6] = 0; // fTsumwxy
5869 s[10] = 0; // fTsumwyz
5870 } else if (iaxis == 3) {
5871 s[7] = 0; // fTsumwz
5872 s[8] = 0; // fTsumwz2
5873 s[9] = 0; // fTsumwxz
5874 s[10] = 0; // fTsumwyz
5875 }
5876 PutStats(s);
5877 }
5878 delete labold;
5879}
5880
5881////////////////////////////////////////////////////////////////////////////////
5882/// Test if two double are almost equal.
5883
5884static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5885{
5886 return TMath::Abs(a - b) < epsilon;
5887}
5888
5889////////////////////////////////////////////////////////////////////////////////
5890/// Test if a double is almost an integer.
5891
5892static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5893{
5894 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5895 AlmostEqual(a - TMath::Floor(a), 1, epsilon);
5896}
5897
5898////////////////////////////////////////////////////////////////////////////////
5899/// Test if the binning is equidistant.
5900
5901static inline bool IsEquidistantBinning(const TAxis& axis)
5902{
5903 // check if axis bin are equals
5904 if (!axis.GetXbins()->fN) return true; //
5905 // not able to check if there is only one axis entry
5906 bool isEquidistant = true;
5907 const Double_t firstBinWidth = axis.GetBinWidth(1);
5908 for (int i = 1; i < axis.GetNbins(); ++i) {
5909 const Double_t binWidth = axis.GetBinWidth(i);
5910 const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5911 isEquidistant &= match;
5912 if (!match)
5913 break;
5914 }
5915 return isEquidistant;
5916}
5917
5918////////////////////////////////////////////////////////////////////////////////
5919/// Same limits and bins.
5920
5921Bool_t TH1::SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2){
5922 return axis1.GetNbins() == axis2.GetNbins() &&
5923 TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
5924 TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
5925}
5926
5927////////////////////////////////////////////////////////////////////////////////
5928/// Finds new limits for the axis for the Merge function.
5929/// returns false if the limits are incompatible
5930
5931Bool_t TH1::RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
5932{
5933 if (SameLimitsAndNBins(destAxis, anAxis))
5934 return kTRUE;
5935
5936 if (!IsEquidistantBinning(destAxis) || !IsEquidistantBinning(anAxis))
5937 return kFALSE; // not equidistant user binning not supported
5938
5939 Double_t width1 = destAxis.GetBinWidth(0);
5940 Double_t width2 = anAxis.GetBinWidth(0);
5941 if (width1 == 0 || width2 == 0)
5942 return kFALSE; // no binning not supported
5943
5944 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
5945 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
5946 Double_t width = TMath::Max(width1, width2);
5947
5948 // check the bin size
5949 if (!AlmostInteger(width/width1) || !AlmostInteger(width/width2))
5950 return kFALSE;
5951
5952 // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
5953 // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
5954
5955
5956 // check the limits
5957 Double_t delta;
5958 delta = (destAxis.GetXmin() - xmin)/width1;
5959 if (!AlmostInteger(delta))
5960 xmin -= (TMath::Ceil(delta) - delta)*width1;
5961
5962 delta = (anAxis.GetXmin() - xmin)/width2;
5963 if (!AlmostInteger(delta))
5964 xmin -= (TMath::Ceil(delta) - delta)*width2;
5965
5966
5967 delta = (destAxis.GetXmin() - xmin)/width1;
5968 if (!AlmostInteger(delta))
5969 return kFALSE;
5970
5971
5972 delta = (xmax - destAxis.GetXmax())/width1;
5973 if (!AlmostInteger(delta))
5974 xmax += (TMath::Ceil(delta) - delta)*width1;
5975
5976
5977 delta = (xmax - anAxis.GetXmax())/width2;
5978 if (!AlmostInteger(delta))
5979 xmax += (TMath::Ceil(delta) - delta)*width2;
5980
5981
5982 delta = (xmax - destAxis.GetXmax())/width1;
5983 if (!AlmostInteger(delta))
5984 return kFALSE;
5985#ifdef DEBUG
5986 if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
5987 printf("TH1::RecomputeAxisLimits - Impossible\n");
5988 return kFALSE;
5989 }
5990#endif
5991
5992
5993 destAxis.Set(TMath::Nint((xmax - xmin)/width), xmin, xmax);
5994
5995 //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
5996
5997 return kTRUE;
5998}
5999
6000////////////////////////////////////////////////////////////////////////////////
6001/// Add all histograms in the collection to this histogram.
6002/// This function computes the min/max for the x axis,
6003/// compute a new number of bins, if necessary,
6004/// add bin contents, errors and statistics.
6005/// If all histograms have bin labels, bins with identical labels
6006/// will be merged, no matter what their order is.
6007/// If overflows are present and limits are different the function will fail.
6008/// The function returns the total number of entries in the result histogram
6009/// if the merge is successful, -1 otherwise.
6010///
6011/// Possible option:
6012/// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
6013/// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
6014/// (enabled by default) slows down the merging
6015///
6016/// IMPORTANT remark. The axis x may have different number
6017/// of bins and different limits, BUT the largest bin width must be
6018/// a multiple of the smallest bin width and the upper limit must also
6019/// be a multiple of the bin width.
6020/// Example:
6021///
6022/// ~~~ {.cpp}
6023/// void atest() {
6024/// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
6025/// TH1F *h2 = new TH1F("h2","h2",220,0,110);
6026/// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
6027/// TRandom r;
6028/// for (Int_t i=0;i<10000;i++) {
6029/// h1->Fill(r.Gaus(-55,10));
6030/// h2->Fill(r.Gaus(55,10));
6031/// h3->Fill(r.Gaus(0,10));
6032/// }
6033///
6034/// TList *list = new TList;
6035/// list->Add(h1);
6036/// list->Add(h2);
6037/// list->Add(h3);
6038/// TH1F *h = (TH1F*)h1->Clone("h");
6039/// h->Reset();
6040/// h->Merge(list);
6041/// h->Draw();
6042/// }
6043/// ~~~
6044
6046{
6047 if (!li) return 0;
6048 if (li->IsEmpty()) return (Long64_t) GetEntries();
6049
6050 // use TH1Merger class
6051 TH1Merger merger(*this,*li,opt);
6052 Bool_t ret = merger();
6053
6054 return (ret) ? GetEntries() : -1;
6055}
6056
6057
6058////////////////////////////////////////////////////////////////////////////////
6059/// Performs the operation:
6060///
6061/// `this = this*c1*f1`
6062///
6063/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
6064///
6065/// Only bins inside the function range are recomputed.
6066/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6067/// you should call Sumw2 before making this operation.
6068/// This is particularly important if you fit the histogram after TH1::Multiply
6069///
6070/// The function return kFALSE if the Multiply operation failed
6071
6073{
6074 if (!f1) {
6075 Error("Multiply","Attempt to multiply by a non-existing function");
6076 return kFALSE;
6077 }
6078
6079 // delete buffer if it is there since it will become invalid
6080 if (fBuffer) BufferEmpty(1);
6081
6082 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
6083 Int_t ny = GetNbinsY() + 2;
6084 Int_t nz = GetNbinsZ() + 2;
6085 if (fDimension < 2) ny = 1;
6086 if (fDimension < 3) nz = 1;
6087
6088 // reset min-maximum
6089 SetMinimum();
6090 SetMaximum();
6091
6092 // - Loop on bins (including underflows/overflows)
6093 Double_t xx[3];
6094 Double_t *params = nullptr;
6095 f1->InitArgs(xx,params);
6096
6097 for (Int_t binz = 0; binz < nz; ++binz) {
6098 xx[2] = fZaxis.GetBinCenter(binz);
6099 for (Int_t biny = 0; biny < ny; ++biny) {
6100 xx[1] = fYaxis.GetBinCenter(biny);
6101 for (Int_t binx = 0; binx < nx; ++binx) {
6102 xx[0] = fXaxis.GetBinCenter(binx);
6103 if (!f1->IsInside(xx)) continue;
6105 Int_t bin = binx + nx * (biny + ny *binz);
6106 Double_t cu = c1*f1->EvalPar(xx);
6107 if (TF1::RejectedPoint()) continue;
6108 UpdateBinContent(bin, RetrieveBinContent(bin) * cu);
6109 if (fSumw2.fN) {
6110 fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
6111 }
6112 }
6113 }
6114 }
6115 ResetStats();
6116 return kTRUE;
6117}
6118
6119////////////////////////////////////////////////////////////////////////////////
6120/// Multiply this histogram by h1.
6121///
6122/// `this = this*h1`
6123///
6124/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6125/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
6126/// if not already set.
6127///
6128/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6129/// you should call Sumw2 before making this operation.
6130/// This is particularly important if you fit the histogram after TH1::Multiply
6131///
6132/// The function return kFALSE if the Multiply operation failed
6133
6134Bool_t TH1::Multiply(const TH1 *h1)
6135{
6136 if (!h1) {
6137 Error("Multiply","Attempt to multiply by a non-existing histogram");
6138 return kFALSE;
6139 }
6140
6141 // delete buffer if it is there since it will become invalid
6142 if (fBuffer) BufferEmpty(1);
6143
6144 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins) {
6145 return false;
6146 }
6147
6148 // Create Sumw2 if h1 has Sumw2 set
6149 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
6150
6151 // - Reset min- maximum
6152 SetMinimum();
6153 SetMaximum();
6154
6155 // - Loop on bins (including underflows/overflows)
6156 for (Int_t i = 0; i < fNcells; ++i) {
6159 UpdateBinContent(i, c0 * c1);
6160 if (fSumw2.fN) {
6162 }
6163 }
6164 ResetStats();
6165 return kTRUE;
6166}
6167
6168////////////////////////////////////////////////////////////////////////////////
6169/// Replace contents of this histogram by multiplication of h1 by h2.
6170///
6171/// `this = (c1*h1)*(c2*h2)`
6172///
6173/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6174/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
6175/// if not already set.
6176///
6177/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6178/// you should call Sumw2 before making this operation.
6179/// This is particularly important if you fit the histogram after TH1::Multiply
6180///
6181/// The function return kFALSE if the Multiply operation failed
6182
6184{
6185 TString opt = option;
6186 opt.ToLower();
6187 // Bool_t binomial = kFALSE;
6188 // if (opt.Contains("b")) binomial = kTRUE;
6189 if (!h1 || !h2) {
6190 Error("Multiply","Attempt to multiply by a non-existing histogram");
6191 return kFALSE;
6192 }
6193
6194 // delete buffer if it is there since it will become invalid
6195 if (fBuffer) BufferEmpty(1);
6196
6197 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins ||
6198 LoggedInconsistency("Multiply", h1, h2) >= kDifferentNumberOfBins) {
6199 return false;
6200 }
6201
6202 // Create Sumw2 if h1 or h2 have Sumw2 set
6203 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
6204
6205 // - Reset min - maximum
6206 SetMinimum();
6207 SetMaximum();
6208
6209 // - Loop on bins (including underflows/overflows)
6210 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
6211 for (Int_t i = 0; i < fNcells; ++i) {
6213 Double_t b2 = h2->RetrieveBinContent(i);
6214 UpdateBinContent(i, c1 * b1 * c2 * b2);
6215 if (fSumw2.fN) {
6216 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
6217 }
6218 }
6219 ResetStats();
6220 return kTRUE;
6221}
6222
6223////////////////////////////////////////////////////////////////////////////////
6224/// Control routine to paint any kind of histograms.
6225///
6226/// This function is automatically called by TCanvas::Update.
6227/// (see TH1::Draw for the list of options)
6228
6230{
6232
6233 if (fPainter) {
6234 if (option && strlen(option) > 0)
6236 else
6238 }
6239}
6240
6241////////////////////////////////////////////////////////////////////////////////
6242/// Rebin this histogram
6243///
6244/// #### case 1 xbins=0
6245///
6246/// If newname is blank (default), the current histogram is modified and
6247/// a pointer to it is returned.
6248///
6249/// If newname is not blank, the current histogram is not modified, and a
6250/// new histogram is returned which is a Clone of the current histogram
6251/// with its name set to newname.
6252///
6253/// The parameter ngroup indicates how many bins of this have to be merged
6254/// into one bin of the result.
6255///
6256/// If the original histogram has errors stored (via Sumw2), the resulting
6257/// histograms has new errors correctly calculated.
6258///
6259/// examples: if h1 is an existing TH1F histogram with 100 bins
6260///
6261/// ~~~ {.cpp}
6262/// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
6263/// h1->Rebin(5); //merges five bins in one in h1
6264/// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
6265/// // merging 5 bins of h1 in one bin
6266/// ~~~
6267///
6268/// NOTE: If ngroup is not an exact divider of the number of bins,
6269/// the top limit of the rebinned histogram is reduced
6270/// to the upper edge of the last bin that can make a complete
6271/// group. The remaining bins are added to the overflow bin.
6272/// Statistics will be recomputed from the new bin contents.
6273///
6274/// #### case 2 xbins!=0
6275///
6276/// A new histogram is created (you should specify newname).
6277/// The parameter ngroup is the number of variable size bins in the created histogram.
6278/// The array xbins must contain ngroup+1 elements that represent the low-edges
6279/// of the bins.
6280/// If the original histogram has errors stored (via Sumw2), the resulting
6281/// histograms has new errors correctly calculated.
6282///
6283/// NOTE: The bin edges specified in xbins should correspond to bin edges
6284/// in the original histogram. If a bin edge in the new histogram is
6285/// in the middle of a bin in the original histogram, all entries in
6286/// the split bin in the original histogram will be transfered to the
6287/// lower of the two possible bins in the new histogram. This is
6288/// probably not what you want. A warning message is emitted in this
6289/// case
6290///
6291/// examples: if h1 is an existing TH1F histogram with 100 bins
6292///
6293/// ~~~ {.cpp}
6294/// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
6295/// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
6296/// ~~~
6297
6298TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
6299{
6300 Int_t nbins = fXaxis.GetNbins();
6303 if ((ngroup <= 0) || (ngroup > nbins)) {
6304 Error("Rebin", "Illegal value of ngroup=%d",ngroup);
6305 return nullptr;
6306 }
6307
6308 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
6309 Error("Rebin", "Operation valid on 1-D histograms only");
6310 return nullptr;
6311 }
6312 if (!newname && xbins) {
6313 Error("Rebin","if xbins is specified, newname must be given");
6314 return nullptr;
6315 }
6316
6317 Int_t newbins = nbins/ngroup;
6318 if (!xbins) {
6319 Int_t nbg = nbins/ngroup;
6320 if (nbg*ngroup != nbins) {
6321 Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
6322 }
6323 }
6324 else {
6325 // in the case that xbins is given (rebinning in variable bins), ngroup is
6326 // the new number of bins and number of grouped bins is not constant.
6327 // when looping for setting the contents for the new histogram we
6328 // need to loop on all bins of original histogram. Then set ngroup=nbins
6329 newbins = ngroup;
6330 ngroup = nbins;
6331 }
6332
6333 // Save old bin contents into a new array
6334 Double_t entries = fEntries;
6335 Double_t *oldBins = new Double_t[nbins+2];
6336 Int_t bin, i;
6337 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
6338 Double_t *oldErrors = nullptr;
6339 if (fSumw2.fN != 0) {
6340 oldErrors = new Double_t[nbins+2];
6341 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
6342 }
6343 // rebin will not include underflow/overflow if new axis range is larger than old axis range
6344 if (xbins) {
6345 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
6346 Warning("Rebin","underflow entries will not be used when rebinning");
6347 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
6348 Warning("Rebin","overflow entries will not be used when rebinning");
6349 }
6350
6351
6352 // create a clone of the old histogram if newname is specified
6353 TH1 *hnew = this;
6354 if ((newname && strlen(newname) > 0) || xbins) {
6355 hnew = (TH1*)Clone(newname);
6356 }
6357
6358 //reset can extend bit to avoid an axis extension in SetBinContent
6359 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
6360
6361 // save original statistics
6362 Double_t stat[kNstat];
6363 GetStats(stat);
6364 bool resetStat = false;
6365 // change axis specs and rebuild bin contents array::RebinAx
6366 if(!xbins && (newbins*ngroup != nbins)) {
6367 xmax = fXaxis.GetBinUpEdge(newbins*ngroup);
6368 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
6369 }
6370 // save the TAttAxis members (reset by SetBins)
6371 Int_t nDivisions = fXaxis.GetNdivisions();
6372 Color_t axisColor = fXaxis.GetAxisColor();
6373 Color_t labelColor = fXaxis.GetLabelColor();
6374 Style_t labelFont = fXaxis.GetLabelFont();
6375 Float_t labelOffset = fXaxis.GetLabelOffset();
6376 Float_t labelSize = fXaxis.GetLabelSize();
6377 Float_t tickLength = fXaxis.GetTickLength();
6378 Float_t titleOffset = fXaxis.GetTitleOffset();
6379 Float_t titleSize = fXaxis.GetTitleSize();
6380 Color_t titleColor = fXaxis.GetTitleColor();
6381 Style_t titleFont = fXaxis.GetTitleFont();
6382
6383 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
6384 Double_t *bins = new Double_t[newbins+1];
6385 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
6386 hnew->SetBins(newbins,bins); //this also changes errors array (if any)
6387 delete [] bins;
6388 } else if (xbins) {
6389 hnew->SetBins(newbins,xbins);
6390 } else {
6391 hnew->SetBins(newbins,xmin,xmax);
6392 }
6393
6394 // Restore axis attributes
6395 fXaxis.SetNdivisions(nDivisions);
6396 fXaxis.SetAxisColor(axisColor);
6397 fXaxis.SetLabelColor(labelColor);
6398 fXaxis.SetLabelFont(labelFont);
6399 fXaxis.SetLabelOffset(labelOffset);
6400 fXaxis.SetLabelSize(labelSize);
6401 fXaxis.SetTickLength(tickLength);
6402 fXaxis.SetTitleOffset(titleOffset);
6403 fXaxis.SetTitleSize(titleSize);
6404 fXaxis.SetTitleColor(titleColor);
6405 fXaxis.SetTitleFont(titleFont);
6406
6407 // copy merged bin contents (ignore under/overflows)
6408 // Start merging only once the new lowest edge is reached
6409 Int_t startbin = 1;
6410 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
6411 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
6412 startbin++;
6413 }
6414 Int_t oldbin = startbin;
6415 Double_t binContent, binError;
6416 for (bin = 1;bin<=newbins;bin++) {
6417 binContent = 0;
6418 binError = 0;
6419 Int_t imax = ngroup;
6420 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6421 // check bin edges for the cases when we provide an array of bins
6422 // be careful in case bins can have zero width
6423 if (xbins && !TMath::AreEqualAbs(fXaxis.GetBinLowEdge(oldbin),
6424 hnew->GetXaxis()->GetBinLowEdge(bin),
6425 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6426 {
6427 Warning("Rebin","Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6428 }
6429 for (i=0;i<ngroup;i++) {
6430 if( (oldbin+i > nbins) ||
6431 ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6432 imax = i;
6433 break;
6434 }
6435 binContent += oldBins[oldbin+i];
6436 if (oldErrors) binError += oldErrors[oldbin+i]*oldErrors[oldbin+i];
6437 }
6438 hnew->SetBinContent(bin,binContent);
6439 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6440 oldbin += imax;
6441 }
6442
6443 // sum underflow and overflow contents until startbin
6444 binContent = 0;
6445 binError = 0;
6446 for (i = 0; i < startbin; ++i) {
6447 binContent += oldBins[i];
6448 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6449 }
6450 hnew->SetBinContent(0,binContent);
6451 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6452 // sum overflow
6453 binContent = 0;
6454 binError = 0;
6455 for (i = oldbin; i <= nbins+1; ++i) {
6456 binContent += oldBins[i];
6457 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6458 }
6459 hnew->SetBinContent(newbins+1,binContent);
6460 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6461
6462 hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6463
6464 // restore statistics and entries modified by SetBinContent
6465 hnew->SetEntries(entries);
6466 if (!resetStat) hnew->PutStats(stat);
6467 delete [] oldBins;
6468 if (oldErrors) delete [] oldErrors;
6469 return hnew;
6470}
6471
6472////////////////////////////////////////////////////////////////////////////////
6473/// finds new limits for the axis so that *point* is within the range and
6474/// the limits are compatible with the previous ones (see TH1::Merge).
6475/// new limits are put into *newMin* and *newMax* variables.
6476/// axis - axis whose limits are to be recomputed
6477/// point - point that should fit within the new axis limits
6478/// newMin - new minimum will be stored here
6479/// newMax - new maximum will be stored here.
6480/// false if failed (e.g. if the initial axis limits are wrong
6481/// or the new range is more than \f$ 2^{64} \f$ times the old one).
6482
6483Bool_t TH1::FindNewAxisLimits(const TAxis* axis, const Double_t point, Double_t& newMin, Double_t &newMax)
6484{
6485 Double_t xmin = axis->GetXmin();
6486 Double_t xmax = axis->GetXmax();
6487 if (xmin >= xmax) return kFALSE;
6488 Double_t range = xmax-xmin;
6489
6490 //recompute new axis limits by doubling the current range
6491 Int_t ntimes = 0;
6492 while (point < xmin) {
6493 if (ntimes++ > 64)
6494 return kFALSE;
6495 xmin = xmin - range;
6496 range *= 2;
6497 }
6498 while (point >= xmax) {
6499 if (ntimes++ > 64)
6500 return kFALSE;
6501 xmax = xmax + range;
6502 range *= 2;
6503 }
6504 newMin = xmin;
6505 newMax = xmax;
6506 // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6507 // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6508
6509 return kTRUE;
6510}
6511
6512////////////////////////////////////////////////////////////////////////////////
6513/// Histogram is resized along axis such that x is in the axis range.
6514/// The new axis limits are recomputed by doubling iteratively
6515/// the current axis range until the specified value x is within the limits.
6516/// The algorithm makes a copy of the histogram, then loops on all bins
6517/// of the old histogram to fill the extended histogram.
6518/// Takes into account errors (Sumw2) if any.
6519/// The algorithm works for 1-d, 2-D and 3-D histograms.
6520/// The axis must be extendable before invoking this function.
6521/// Ex:
6522///
6523/// ~~~ {.cpp}
6524/// h->GetXaxis()->SetCanExtend(kTRUE);
6525/// ~~~
6526
6527void TH1::ExtendAxis(Double_t x, TAxis *axis)
6528{
6529 if (!axis->CanExtend()) return;
6530 if (TMath::IsNaN(x)) { // x may be a NaN
6532 return;
6533 }
6534
6535 if (axis->GetXmin() >= axis->GetXmax()) return;
6536 if (axis->GetNbins() <= 0) return;
6537
6539 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6540 return;
6541
6542 //save a copy of this histogram
6543 TH1 *hold = (TH1*)IsA()->New();
6544 hold->SetDirectory(nullptr);
6545 Copy(*hold);
6546 //set new axis limits
6547 axis->SetLimits(xmin,xmax);
6548
6549
6550 //now loop on all bins and refill
6551 Int_t errors = GetSumw2N();
6552
6553 Reset("ICE"); //reset only Integral, contents and Errors
6554
6555 int iaxis = 0;
6556 if (axis == &fXaxis) iaxis = 1;
6557 if (axis == &fYaxis) iaxis = 2;
6558 if (axis == &fZaxis) iaxis = 3;
6559 bool firstw = kTRUE;
6560 Int_t binx,biny, binz = 0;
6561 Int_t ix = 0,iy = 0,iz = 0;
6562 Double_t bx,by,bz;
6563 Int_t ncells = hold->GetNcells();
6564 for (Int_t bin = 0; bin < ncells; ++bin) {
6565 hold->GetBinXYZ(bin,binx,biny,binz);
6566 bx = hold->GetXaxis()->GetBinCenter(binx);
6567 ix = fXaxis.FindFixBin(bx);
6568 if (fDimension > 1) {
6569 by = hold->GetYaxis()->GetBinCenter(biny);
6570 iy = fYaxis.FindFixBin(by);
6571 if (fDimension > 2) {
6572 bz = hold->GetZaxis()->GetBinCenter(binz);
6573 iz = fZaxis.FindFixBin(bz);
6574 }
6575 }
6576 // exclude underflow/overflow
6577 double content = hold->RetrieveBinContent(bin);
6578 if (content == 0) continue;
6579 if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6580 if (firstw) {
6581 Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6582 " their content will be lost",GetName() );
6583 firstw= kFALSE;
6584 }
6585 continue;
6586 }
6587 Int_t ibin= GetBin(ix,iy,iz);
6588 AddBinContent(ibin, content);
6589 if (errors) {
6590 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6591 }
6592 }
6593 delete hold;
6594}
6595
6596////////////////////////////////////////////////////////////////////////////////
6597/// Recursively remove object from the list of functions
6598
6600{
6601 // Rely on TROOT::RecursiveRemove to take the readlock.
6602
6603 if (fFunctions) {
6605 }
6606}
6607
6608////////////////////////////////////////////////////////////////////////////////
6609/// Multiply this histogram by a constant c1.
6610///
6611/// `this = c1*this`
6612///
6613/// Note that both contents and errors (if any) are scaled.
6614/// This function uses the services of TH1::Add
6615///
6616/// IMPORTANT NOTE: Sumw2() is called automatically when scaling.
6617/// If you are not interested in the histogram statistics you can call
6618/// Sumw2(kFALSE) or use the option "nosw2"
6619///
6620/// One can scale a histogram such that the bins integral is equal to
6621/// the normalization parameter via TH1::Scale(Double_t norm), where norm
6622/// is the desired normalization divided by the integral of the histogram.
6623///
6624/// If option contains "width" the bin contents and errors are divided
6625/// by the bin width.
6626
6628{
6629
6630 TString opt = option; opt.ToLower();
6631 // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6632 if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6633 if (opt.Contains("width")) Add(this, this, c1, -1);
6634 else {
6635 if (fBuffer) BufferEmpty(1);
6636 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6637 if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6638 // update global histograms statistics
6639 Double_t s[kNstat] = {0};
6640 GetStats(s);
6641 for (Int_t i=0 ; i < kNstat; i++) {
6642 if (i == 1) s[i] = c1*c1*s[i];
6643 else s[i] = c1*s[i];
6644 }
6645 PutStats(s);
6646 SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6647 }
6648
6649 // if contours set, must also scale contours
6650 Int_t ncontours = GetContour();
6651 if (ncontours == 0) return;
6652 Double_t* levels = fContour.GetArray();
6653 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6654}
6655
6656////////////////////////////////////////////////////////////////////////////////
6657/// Returns true if all axes are extendable.
6658
6660{
6661 Bool_t canExtend = fXaxis.CanExtend();
6662 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6663 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6664
6665 return canExtend;
6666}
6667
6668////////////////////////////////////////////////////////////////////////////////
6669/// Make the histogram axes extendable / not extendable according to the bit mask
6670/// returns the previous bit mask specifying which axes are extendable
6671
6672UInt_t TH1::SetCanExtend(UInt_t extendBitMask)
6673{
6674 UInt_t oldExtendBitMask = kNoAxis;
6675
6676 if (fXaxis.CanExtend()) oldExtendBitMask |= kXaxis;
6677 if (extendBitMask & kXaxis) fXaxis.SetCanExtend(kTRUE);
6679
6680 if (GetDimension() > 1) {
6681 if (fYaxis.CanExtend()) oldExtendBitMask |= kYaxis;
6682 if (extendBitMask & kYaxis) fYaxis.SetCanExtend(kTRUE);
6684 }
6685
6686 if (GetDimension() > 2) {
6687 if (fZaxis.CanExtend()) oldExtendBitMask |= kZaxis;
6688 if (extendBitMask & kZaxis) fZaxis.SetCanExtend(kTRUE);
6690 }
6691
6692 return oldExtendBitMask;
6693}
6694
6695///////////////////////////////////////////////////////////////////////////////
6696/// Internal function used in TH1::Fill to see which axis is full alphanumeric,
6697/// i.e. can be extended and is alphanumeric
6699{
6700 UInt_t bitMask = kNoAxis;
6701 if (fXaxis.CanExtend() && fXaxis.IsAlphanumeric() ) bitMask |= kXaxis;
6703 bitMask |= kYaxis;
6705 bitMask |= kZaxis;
6706
6707 return bitMask;
6708}
6709
6710////////////////////////////////////////////////////////////////////////////////
6711/// Static function to set the default buffer size for automatic histograms.
6712/// When a histogram is created with one of its axis lower limit greater
6713/// or equal to its upper limit, the function SetBuffer is automatically
6714/// called with the default buffer size.
6715
6716void TH1::SetDefaultBufferSize(Int_t buffersize)
6717{
6718 fgBufferSize = buffersize > 0 ? buffersize : 0;
6719}
6720
6721////////////////////////////////////////////////////////////////////////////////
6722/// When this static function is called with `sumw2=kTRUE`, all new
6723/// histograms will automatically activate the storage
6724/// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6725
6726void TH1::SetDefaultSumw2(Bool_t sumw2)
6727{
6728 fgDefaultSumw2 = sumw2;
6729}
6730
6731////////////////////////////////////////////////////////////////////////////////
6732/// Change/set the title.
6733///
6734/// If title is in the form `stringt;stringx;stringy;stringz`
6735/// the histogram title is set to `stringt`, the x axis title to `stringx`,
6736/// the y axis title to `stringy`, and the z axis title to `stringz`.
6737///
6738/// To insert the character `;` in one of the titles, one should use `#;`
6739/// or `#semicolon`.
6740
6741void TH1::SetTitle(const char *title)
6742{
6743 fTitle = title;
6744 fTitle.ReplaceAll("#;",2,"#semicolon",10);
6745
6746 // Decode fTitle. It may contain X, Y and Z titles
6747 TString str1 = fTitle, str2;
6748 Int_t isc = str1.Index(";");
6749 Int_t lns = str1.Length();
6750
6751 if (isc >=0 ) {
6752 fTitle = str1(0,isc);
6753 str1 = str1(isc+1, lns);
6754 isc = str1.Index(";");
6755 if (isc >=0 ) {
6756 str2 = str1(0,isc);
6757 str2.ReplaceAll("#semicolon",10,";",1);
6758 fXaxis.SetTitle(str2.Data());
6759 lns = str1.Length();
6760 str1 = str1(isc+1, lns);
6761 isc = str1.Index(";");
6762 if (isc >=0 ) {
6763 str2 = str1(0,isc);
6764 str2.ReplaceAll("#semicolon",10,";",1);
6765 fYaxis.SetTitle(str2.Data());
6766 lns = str1.Length();
6767 str1 = str1(isc+1, lns);
6768 str1.ReplaceAll("#semicolon",10,";",1);
6769 fZaxis.SetTitle(str1.Data());
6770 } else {
6771 str1.ReplaceAll("#semicolon",10,";",1);
6772 fYaxis.SetTitle(str1.Data());
6773 }
6774 } else {
6775 str1.ReplaceAll("#semicolon",10,";",1);
6776 fXaxis.SetTitle(str1.Data());
6777 }
6778 }
6779
6780 fTitle.ReplaceAll("#semicolon",10,";",1);
6781
6782 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6783}
6784
6785////////////////////////////////////////////////////////////////////////////////
6786/// Smooth array xx, translation of Hbook routine `hsmoof.F`.
6787/// Based on algorithm 353QH twice presented by J. Friedman
6788/// in [Proc. of the 1974 CERN School of Computing, Norway, 11-24 August, 1974](https://cds.cern.ch/record/186223).
6789/// See also Section 4.2 in [J. Friedman, Data Analysis Techniques for High Energy Physics](https://www.slac.stanford.edu/pubs/slacreports/reports16/slac-r-176.pdf).
6790
6791void TH1::SmoothArray(Int_t nn, Double_t *xx, Int_t ntimes)
6792{
6793 if (nn < 3 ) {
6794 ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6795 return;
6796 }
6797
6798 Int_t ii;
6799 std::array<double, 3> hh{};
6800
6801 std::vector<double> yy(nn);
6802 std::vector<double> zz(nn);
6803 std::vector<double> rr(nn);
6804
6805 for (Int_t pass=0;pass<ntimes;pass++) {
6806 // first copy original data into temp array
6807 std::copy(xx, xx+nn, zz.begin() );
6808
6809 for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6810
6811 // do 353 i.e. running median 3, 5, and 3 in a single loop
6812 for (int kk = 0; kk < 3; kk++) {
6813 std::copy(zz.begin(), zz.end(), yy.begin());
6814 int medianType = (kk != 1) ? 3 : 5;
6815 int ifirst = (kk != 1 ) ? 1 : 2;
6816 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6817 //nn2 = nn - ik - 1;
6818 // do all elements beside the first and last point for median 3
6819 // and first two and last 2 for median 5
6820 for ( ii = ifirst; ii < ilast; ii++) {
6821 zz[ii] = TMath::Median(medianType, yy.data() + ii - ifirst);
6822 }
6823
6824 if (kk == 0) { // first median 3
6825 // first point
6826 hh[0] = zz[1];
6827 hh[1] = zz[0];
6828 hh[2] = 3*zz[1] - 2*zz[2];
6829 zz[0] = TMath::Median(3, hh.data());
6830 // last point
6831 hh[0] = zz[nn - 2];
6832 hh[1] = zz[nn - 1];
6833 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6834 zz[nn - 1] = TMath::Median(3, hh.data());
6835 }
6836
6837 if (kk == 1) { // median 5
6838 // second point with window length 3
6839 zz[1] = TMath::Median(3, yy.data());
6840 // second-to-last point with window length 3
6841 zz[nn - 2] = TMath::Median(3, yy.data() + nn - 3);
6842 }
6843
6844 // In the third iteration (kk == 2), the first and last point stay
6845 // the same (see paper linked in the documentation).
6846 }
6847
6848 std::copy ( zz.begin(), zz.end(), yy.begin() );
6849
6850 // quadratic interpolation for flat segments
6851 for (ii = 2; ii < (nn - 2); ii++) {
6852 if (zz[ii - 1] != zz[ii]) continue;
6853 if (zz[ii] != zz[ii + 1]) continue;
6854 const double tmp0 = zz[ii - 2] - zz[ii];
6855 const double tmp1 = zz[ii + 2] - zz[ii];
6856 if (tmp0 * tmp1 <= 0) continue;
6857 int jk = 1;
6858 if ( std::abs(tmp0) > std::abs(tmp0) ) jk = -1;
6859 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6860 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6861 }
6862
6863 // running means
6864 //std::copy(zz.begin(), zz.end(), yy.begin());
6865 for (ii = 1; ii < nn - 1; ii++) {
6866 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6867 }
6868 zz[0] = yy[0];
6869 zz[nn - 1] = yy[nn - 1];
6870
6871 if (noent == 0) {
6872
6873 // save computed values
6874 std::copy(zz.begin(), zz.end(), rr.begin());
6875
6876 // COMPUTE residuals
6877 for (ii = 0; ii < nn; ii++) {
6878 zz[ii] = xx[ii] - zz[ii];
6879 }
6880 }
6881
6882 } // end loop on noent
6883
6884
6885 double xmin = TMath::MinElement(nn,xx);
6886 for (ii = 0; ii < nn; ii++) {
6887 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6888 // make smoothing defined positive - not better using 0 ?
6889 else xx[ii] = std::max((rr[ii] + zz[ii]),0.0 );
6890 }
6891 }
6892}
6893
6894////////////////////////////////////////////////////////////////////////////////
6895/// Smooth bin contents of this histogram.
6896/// if option contains "R" smoothing is applied only to the bins
6897/// defined in the X axis range (default is to smooth all bins)
6898/// Bin contents are replaced by their smooth values.
6899/// Errors (if any) are not modified.
6900/// the smoothing procedure is repeated ntimes (default=1)
6901
6902void TH1::Smooth(Int_t ntimes, Option_t *option)
6903{
6904 if (fDimension != 1) {
6905 Error("Smooth","Smooth only supported for 1-d histograms");
6906 return;
6907 }
6908 Int_t nbins = fXaxis.GetNbins();
6909 if (nbins < 3) {
6910 Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
6911 return;
6912 }
6913
6914 // delete buffer if it is there since it will become invalid
6915 if (fBuffer) BufferEmpty(1);
6916
6917 Int_t firstbin = 1, lastbin = nbins;
6918 TString opt = option;
6919 opt.ToLower();
6920 if (opt.Contains("r")) {
6921 firstbin= fXaxis.GetFirst();
6922 lastbin = fXaxis.GetLast();
6923 }
6924 nbins = lastbin - firstbin + 1;
6925 Double_t *xx = new Double_t[nbins];
6926 Double_t nent = fEntries;
6927 Int_t i;
6928 for (i=0;i<nbins;i++) {
6929 xx[i] = RetrieveBinContent(i+firstbin);
6930 }
6931
6932 TH1::SmoothArray(nbins,xx,ntimes);
6933
6934 for (i=0;i<nbins;i++) {
6935 UpdateBinContent(i+firstbin,xx[i]);
6936 }
6937 fEntries = nent;
6938 delete [] xx;
6939
6940 if (gPad) gPad->Modified();
6941}
6942
6943////////////////////////////////////////////////////////////////////////////////
6944/// if flag=kTRUE, underflows and overflows are used by the Fill functions
6945/// in the computation of statistics (mean value, StdDev).
6946/// By default, underflows or overflows are not used.
6947
6948void TH1::StatOverflows(Bool_t flag)
6949{
6950 fgStatOverflows = flag;
6951}
6952
6953////////////////////////////////////////////////////////////////////////////////
6954/// Stream a class object.
6955
6956void TH1::Streamer(TBuffer &b)
6957{
6958 if (b.IsReading()) {
6959 UInt_t R__s, R__c;
6960 Version_t R__v = b.ReadVersion(&R__s, &R__c);
6961 if (fDirectory) fDirectory->Remove(this);
6962 fDirectory = nullptr;
6963 if (R__v > 2) {
6964 b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
6965
6967 fXaxis.SetParent(this);
6968 fYaxis.SetParent(this);
6969 fZaxis.SetParent(this);
6970 TIter next(fFunctions);
6971 TObject *obj;
6972 while ((obj=next())) {
6973 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
6974 }
6975 return;
6976 }
6977 //process old versions before automatic schema evolution
6982 b >> fNcells;
6983 fXaxis.Streamer(b);
6984 fYaxis.Streamer(b);
6985 fZaxis.Streamer(b);
6986 fXaxis.SetParent(this);
6987 fYaxis.SetParent(this);
6988 fZaxis.SetParent(this);
6989 b >> fBarOffset;
6990 b >> fBarWidth;
6991 b >> fEntries;
6992 b >> fTsumw;
6993 b >> fTsumw2;
6994 b >> fTsumwx;
6995 b >> fTsumwx2;
6996 if (R__v < 2) {
6997 Float_t maximum, minimum, norm;
6998 Float_t *contour=nullptr;
6999 b >> maximum; fMaximum = maximum;
7000 b >> minimum; fMinimum = minimum;
7001 b >> norm; fNormFactor = norm;
7002 Int_t n = b.ReadArray(contour);
7003 fContour.Set(n);
7004 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
7005 delete [] contour;
7006 } else {
7007 b >> fMaximum;
7008 b >> fMinimum;
7009 b >> fNormFactor;
7011 }
7012 fSumw2.Streamer(b);
7014 fFunctions->Delete();
7016 b.CheckByteCount(R__s, R__c, TH1::IsA());
7017
7018 } else {
7019 b.WriteClassBuffer(TH1::Class(),this);
7020 }
7021}
7022
7023////////////////////////////////////////////////////////////////////////////////
7024/// Print some global quantities for this histogram.
7025/// \param[in] option
7026/// - "base" is given, number of bins and ranges are also printed
7027/// - "range" is given, bin contents and errors are also printed
7028/// for all bins in the current range (default 1-->nbins)
7029/// - "all" is given, bin contents and errors are also printed
7030/// for all bins including under and overflows.
7031
7032void TH1::Print(Option_t *option) const
7033{
7034 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7035 printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
7036 TString opt = option;
7037 opt.ToLower();
7038 Int_t all;
7039 if (opt.Contains("all")) all = 0;
7040 else if (opt.Contains("range")) all = 1;
7041 else if (opt.Contains("base")) all = 2;
7042 else return;
7043
7044 Int_t bin, binx, biny, binz;
7045 Int_t firstx=0,lastx=0,firsty=0,lasty=0,firstz=0,lastz=0;
7046 if (all == 0) {
7047 lastx = fXaxis.GetNbins()+1;
7048 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
7049 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
7050 } else {
7051 firstx = fXaxis.GetFirst(); lastx = fXaxis.GetLast();
7052 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
7053 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
7054 }
7055
7056 if (all== 2) {
7057 printf(" Title = %s\n", GetTitle());
7058 printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
7059 if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
7060 if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
7061 printf("\n");
7062 return;
7063 }
7064
7065 Double_t w,e;
7066 Double_t x,y,z;
7067 if (fDimension == 1) {
7068 for (binx=firstx;binx<=lastx;binx++) {
7069 x = fXaxis.GetBinCenter(binx);
7070 w = RetrieveBinContent(binx);
7071 e = GetBinError(binx);
7072 if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
7073 else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
7074 }
7075 }
7076 if (fDimension == 2) {
7077 for (biny=firsty;biny<=lasty;biny++) {
7078 y = fYaxis.GetBinCenter(biny);
7079 for (binx=firstx;binx<=lastx;binx++) {
7080 bin = GetBin(binx,biny);
7081 x = fXaxis.GetBinCenter(binx);
7082 w = RetrieveBinContent(bin);
7083 e = GetBinError(bin);
7084 if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
7085 else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
7086 }
7087 }
7088 }
7089 if (fDimension == 3) {
7090 for (binz=firstz;binz<=lastz;binz++) {
7091 z = fZaxis.GetBinCenter(binz);
7092 for (biny=firsty;biny<=lasty;biny++) {
7093 y = fYaxis.GetBinCenter(biny);
7094 for (binx=firstx;binx<=lastx;binx++) {
7095 bin = GetBin(binx,biny,binz);
7096 x = fXaxis.GetBinCenter(binx);
7097 w = RetrieveBinContent(bin);
7098 e = GetBinError(bin);
7099 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);
7100 else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
7101 }
7102 }
7103 }
7104 }
7105}
7106
7107////////////////////////////////////////////////////////////////////////////////
7108/// Using the current bin info, recompute the arrays for contents and errors
7109
7110void TH1::Rebuild(Option_t *)
7111{
7112 SetBinsLength();
7113 if (fSumw2.fN) {
7115 }
7116}
7117
7118////////////////////////////////////////////////////////////////////////////////
7119/// Reset this histogram: contents, errors, etc.
7120/// \param[in] option
7121/// - if "ICE" is specified, resets only Integral, Contents and Errors.
7122/// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
7123/// This option is used
7124/// - if "M" is specified, resets also Minimum and Maximum
7125
7127{
7128 // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
7129 // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
7130
7131 TString opt = option;
7132 opt.ToUpper();
7133 fSumw2.Reset();
7134 if (fIntegral) {
7135 delete [] fIntegral;
7136 fIntegral = nullptr;
7137 }
7138
7139 if (opt.Contains("M")) {
7140 SetMinimum();
7141 SetMaximum();
7142 }
7143
7144 if (opt.Contains("ICE") && !opt.Contains("S")) return;
7145
7146 // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
7147 // But what is the sense of calling BufferEmpty() ? For making the axes ?
7148 // BufferEmpty will update contents that later will be
7149 // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
7150 // It may be needed for computing the axis limits....
7151 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
7152
7153 // need to reset also the statistics
7154 // (needs to be done after calling BufferEmpty() )
7155 fTsumw = 0;
7156 fTsumw2 = 0;
7157 fTsumwx = 0;
7158 fTsumwx2 = 0;
7159 fEntries = 0;
7160
7161 if (opt == "ICES") return;
7162
7163
7164 TObject *stats = fFunctions->FindObject("stats");
7165 fFunctions->Remove(stats);
7166 //special logic to support the case where the same object is
7167 //added multiple times in fFunctions.
7168 //This case happens when the same object is added with different
7169 //drawing modes
7170 TObject *obj;
7171 while ((obj = fFunctions->First())) {
7172 while(fFunctions->Remove(obj)) { }
7173 delete obj;
7174 }
7175 if(stats) fFunctions->Add(stats);
7176 fContour.Set(0);
7177}
7178
7179////////////////////////////////////////////////////////////////////////////////
7180/// Save the histogram as .csv, .tsv or .txt. In case of any other extension, fall
7181/// back to TObject::SaveAs, which saves as a .C macro (but with the file name
7182/// extension specified by the user)
7183///
7184/// The Under/Overflow bins are also exported (as first and last lines)
7185/// The fist 2 columns are the lower and upper edges of the bins
7186/// Column 3 contains the bin contents
7187/// The last column contains the error in y. If errors are not present, the column
7188/// is left empty
7189///
7190/// The result can be immediately imported into Excel, gnuplot, Python or whatever,
7191/// without the needing to install pyroot, etc.
7192///
7193/// \param filename the name of the file where to store the histogram
7194/// \param option some tuning options
7195///
7196/// The file extension defines the delimiter used:
7197/// - `.csv` : comma
7198/// - `.tsv` : tab
7199/// - `.txt` : space
7200///
7201/// If option = "title" a title line is generated. If the y-axis has a title,
7202/// this title is displayed as column 3 name, otherwise, it shows "BinContent"
7203
7204void TH1::SaveAs(const char *filename, Option_t *option) const
7205{
7206 char del = '\0';
7207 TString ext = "";
7208 TString fname = filename;
7209 TString opt = option;
7210
7211 if (filename) {
7212 if (fname.EndsWith(".csv")) {
7213 del = ',';
7214 ext = "csv";
7215 } else if (fname.EndsWith(".tsv")) {
7216 del = '\t';
7217 ext = "tsv";
7218 } else if (fname.EndsWith(".txt")) {
7219 del = ' ';
7220 ext = "txt";
7221 }
7222 }
7223 if (!del) {
7225 return;
7226 }
7227 std::ofstream out;
7228 out.open(filename, std::ios::out);
7229 if (!out.good()) {
7230 Error("SaveAs", "cannot open file: %s", filename);
7231 return;
7232 }
7233 if (opt.Contains("title")) {
7234 if (std::strcmp(GetYaxis()->GetTitle(), "") == 0) {
7235 out << "# " << "BinLowEdge" << del << "BinUpEdge" << del
7236 << "BinContent"
7237 << del << "ey" << std::endl;
7238 } else {
7239 out << "# " << "BinLowEdge" << del << "BinUpEdge" << del << GetYaxis()->GetTitle() << del << "ey" << std::endl;
7240 }
7241 }
7242 if (fSumw2.fN) {
7243 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7244 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7245 << GetBinError(i) << std::endl;
7246 }
7247 } else {
7248 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7249 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7250 << std::endl;
7251 }
7252 }
7253 out.close();
7254 Info("SaveAs", "%s file: %s has been generated", ext.Data(), filename);
7255}
7256
7257////////////////////////////////////////////////////////////////////////////////
7258/// Save primitive as a C++ statement(s) on output stream out
7259
7260void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
7261{
7262 // empty the buffer before if it exists
7263 if (fBuffer) BufferEmpty();
7264
7265 Bool_t nonEqiX = kFALSE;
7266 Bool_t nonEqiY = kFALSE;
7267 Bool_t nonEqiZ = kFALSE;
7268 Int_t i;
7269 static Int_t nxaxis = 0;
7270 static Int_t nyaxis = 0;
7271 static Int_t nzaxis = 0;
7272 TString sxaxis="xAxis",syaxis="yAxis",szaxis="zAxis";
7273
7274 // Check if the histogram has equidistant X bins or not. If not, we
7275 // create an array holding the bins.
7276 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
7277 nonEqiX = kTRUE;
7278 nxaxis++;
7279 sxaxis += nxaxis;
7280 out << " Double_t "<<sxaxis<<"[" << GetXaxis()->GetXbins()->fN
7281 << "] = {";
7282 for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
7283 if (i != 0) out << ", ";
7284 out << GetXaxis()->GetXbins()->fArray[i];
7285 }
7286 out << "}; " << std::endl;
7287 }
7288 // If the histogram is 2 or 3 dimensional, check if the histogram
7289 // has equidistant Y bins or not. If not, we create an array
7290 // holding the bins.
7291 if (fDimension > 1 && GetYaxis()->GetXbins()->fN &&
7292 GetYaxis()->GetXbins()->fArray) {
7293 nonEqiY = kTRUE;
7294 nyaxis++;
7295 syaxis += nyaxis;
7296 out << " Double_t "<<syaxis<<"[" << GetYaxis()->GetXbins()->fN
7297 << "] = {";
7298 for (i = 0; i < GetYaxis()->GetXbins()->fN; i++) {
7299 if (i != 0) out << ", ";
7300 out << GetYaxis()->GetXbins()->fArray[i];
7301 }
7302 out << "}; " << std::endl;
7303 }
7304 // IF the histogram is 3 dimensional, check if the histogram
7305 // has equidistant Z bins or not. If not, we create an array
7306 // holding the bins.
7307 if (fDimension > 2 && GetZaxis()->GetXbins()->fN &&
7308 GetZaxis()->GetXbins()->fArray) {
7309 nonEqiZ = kTRUE;
7310 nzaxis++;
7311 szaxis += nzaxis;
7312 out << " Double_t "<<szaxis<<"[" << GetZaxis()->GetXbins()->fN
7313 << "] = {";
7314 for (i = 0; i < GetZaxis()->GetXbins()->fN; i++) {
7315 if (i != 0) out << ", ";
7316 out << GetZaxis()->GetXbins()->fArray[i];
7317 }
7318 out << "}; " << std::endl;
7319 }
7320
7321 char quote = '"';
7322 out <<" "<<std::endl;
7323 out <<" "<< ClassName() <<" *";
7324
7325 // Histogram pointer has by default the histogram name with an incremental suffix.
7326 // If the histogram belongs to a graph or a stack the suffix is not added because
7327 // the graph and stack objects are not aware of this new name. Same thing if
7328 // the histogram is drawn with the option COLZ because the TPaletteAxis drawn
7329 // when this option is selected, does not know this new name either.
7330 TString opt = option;
7331 opt.ToLower();
7332 static Int_t hcounter = 0;
7333 TString histName = GetName();
7334 if ( !histName.Contains("Graph")
7335 && !histName.Contains("_stack_")
7336 && !opt.Contains("colz")) {
7337 hcounter++;
7338 histName += "__";
7339 histName += hcounter;
7340 }
7341 histName = gInterpreter-> MapCppName(histName);
7342 const char *hname = histName.Data();
7343 if (!strlen(hname)) hname = "unnamed";
7344 TString savedName = GetName();
7345 this->SetName(hname);
7346 TString t(GetTitle());
7347 t.ReplaceAll("\\","\\\\");
7348 t.ReplaceAll("\"","\\\"");
7349 out << hname << " = new " << ClassName() << "(" << quote
7350 << hname << quote << "," << quote<< t.Data() << quote
7351 << "," << GetXaxis()->GetNbins();
7352 if (nonEqiX)
7353 out << ", "<<sxaxis;
7354 else
7355 out << "," << GetXaxis()->GetXmin()
7356 << "," << GetXaxis()->GetXmax();
7357 if (fDimension > 1) {
7358 out << "," << GetYaxis()->GetNbins();
7359 if (nonEqiY)
7360 out << ", "<<syaxis;
7361 else
7362 out << "," << GetYaxis()->GetXmin()
7363 << "," << GetYaxis()->GetXmax();
7364 }
7365 if (fDimension > 2) {
7366 out << "," << GetZaxis()->GetNbins();
7367 if (nonEqiZ)
7368 out << ", "<<szaxis;
7369 else
7370 out << "," << GetZaxis()->GetXmin()
7371 << "," << GetZaxis()->GetXmax();
7372 }
7373 out << ");" << std::endl;
7374
7375 // save bin contents
7376 Int_t bin;
7377 for (bin=0;bin<fNcells;bin++) {
7378 Double_t bc = RetrieveBinContent(bin);
7379 if (bc) {
7380 out<<" "<<hname<<"->SetBinContent("<<bin<<","<<bc<<");"<<std::endl;
7381 }
7382 }
7383
7384 // save bin errors
7385 if (fSumw2.fN) {
7386 for (bin=0;bin<fNcells;bin++) {
7387 Double_t be = GetBinError(bin);
7388 if (be) {
7389 out<<" "<<hname<<"->SetBinError("<<bin<<","<<be<<");"<<std::endl;
7390 }
7391 }
7392 }
7393
7394 TH1::SavePrimitiveHelp(out, hname, option);
7395 this->SetName(savedName.Data());
7396}
7397
7398////////////////////////////////////////////////////////////////////////////////
7399/// Helper function for the SavePrimitive functions from TH1
7400/// or classes derived from TH1, eg TProfile, TProfile2D.
7401
7402void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
7403{
7404 char quote = '"';
7405 if (TMath::Abs(GetBarOffset()) > 1e-5) {
7406 out<<" "<<hname<<"->SetBarOffset("<<GetBarOffset()<<");"<<std::endl;
7407 }
7408 if (TMath::Abs(GetBarWidth()-1) > 1e-5) {
7409 out<<" "<<hname<<"->SetBarWidth("<<GetBarWidth()<<");"<<std::endl;
7410 }
7411 if (fMinimum != -1111) {
7412 out<<" "<<hname<<"->SetMinimum("<<fMinimum<<");"<<std::endl;
7413 }
7414 if (fMaximum != -1111) {
7415 out<<" "<<hname<<"->SetMaximum("<<fMaximum<<");"<<std::endl;
7416 }
7417 if (fNormFactor != 0) {
7418 out<<" "<<hname<<"->SetNormFactor("<<fNormFactor<<");"<<std::endl;
7419 }
7420 if (fEntries != 0) {
7421 out<<" "<<hname<<"->SetEntries("<<fEntries<<");"<<std::endl;
7422 }
7423 if (!fDirectory) {
7424 out<<" "<<hname<<"->SetDirectory(nullptr);"<<std::endl;
7425 }
7426 if (TestBit(kNoStats)) {
7427 out<<" "<<hname<<"->SetStats(0);"<<std::endl;
7428 }
7429 if (fOption.Length() != 0) {
7430 out<<" "<<hname<<"->SetOption("<<quote<<fOption.Data()<<quote<<");"<<std::endl;
7431 }
7432
7433 // save contour levels
7434 Int_t ncontours = GetContour();
7435 if (ncontours > 0) {
7436 out<<" "<<hname<<"->SetContour("<<ncontours<<");"<<std::endl;
7437 Double_t zlevel;
7438 for (Int_t bin=0;bin<ncontours;bin++) {
7439 if (gPad->GetLogz()) {
7440 zlevel = TMath::Power(10,GetContourLevel(bin));
7441 } else {
7442 zlevel = GetContourLevel(bin);
7443 }
7444 out<<" "<<hname<<"->SetContourLevel("<<bin<<","<<zlevel<<");"<<std::endl;
7445 }
7446 }
7447
7448 // save list of functions
7449 auto lnk = fFunctions->FirstLink();
7450 static Int_t funcNumber = 0;
7451 while (lnk) {
7452 auto obj = lnk->GetObject();
7453 obj->SavePrimitive(out, TString::Format("nodraw #%d\n",++funcNumber).Data());
7454 if (obj->InheritsFrom(TF1::Class())) {
7455 TString fname;
7456 fname.Form("%s%d",obj->GetName(),funcNumber);
7457 out << " " << fname << "->SetParent(" << hname << ");\n";
7458 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7459 << fname <<");"<<std::endl;
7460 } else if (obj->InheritsFrom("TPaveStats")) {
7461 out<<" "<<hname<<"->GetListOfFunctions()->Add(ptstats);"<<std::endl;
7462 out<<" ptstats->SetParent("<<hname<<");"<<std::endl;
7463 } else if (obj->InheritsFrom("TPolyMarker")) {
7464 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7465 <<"pmarker ,"<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
7466 } else {
7467 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7468 <<obj->GetName()
7469 <<","<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
7470 }
7471 lnk = lnk->Next();
7472 }
7473
7474 // save attributes
7475 SaveFillAttributes(out,hname,0,1001);
7476 SaveLineAttributes(out,hname,1,1,1);
7477 SaveMarkerAttributes(out,hname,1,1,1);
7478 fXaxis.SaveAttributes(out,hname,"->GetXaxis()");
7479 fYaxis.SaveAttributes(out,hname,"->GetYaxis()");
7480 fZaxis.SaveAttributes(out,hname,"->GetZaxis()");
7481 TString opt = option;
7482 opt.ToLower();
7483 if (!opt.Contains("nodraw")) {
7484 out<<" "<<hname<<"->Draw("
7485 <<quote<<option<<quote<<");"<<std::endl;
7486 }
7487}
7488
7489////////////////////////////////////////////////////////////////////////////////
7490/// Copy current attributes from/to current style
7491
7493{
7494 if (!gStyle) return;
7495 if (gStyle->IsReading()) {
7496 fXaxis.ResetAttAxis("X");
7497 fYaxis.ResetAttAxis("Y");
7498 fZaxis.ResetAttAxis("Z");
7509 Int_t dostat = gStyle->GetOptStat();
7510 if (gStyle->GetOptFit() && !dostat) dostat = 1000000001;
7511 SetStats(dostat);
7512 } else {
7524 }
7525 TIter next(GetListOfFunctions());
7526 TObject *obj;
7527
7528 while ((obj = next())) {
7529 obj->UseCurrentStyle();
7530 }
7531}
7532
7533////////////////////////////////////////////////////////////////////////////////
7534/// For axis = 1,2 or 3 returns the mean value of the histogram along
7535/// X,Y or Z axis.
7536///
7537/// For axis = 11, 12, 13 returns the standard error of the mean value
7538/// of the histogram along X, Y or Z axis
7539///
7540/// Note that the mean value/StdDev is computed using the bins in the currently
7541/// defined range (see TAxis::SetRange). By default the range includes
7542/// all bins from 1 to nbins included, excluding underflows and overflows.
7543/// To force the underflows and overflows in the computation, one must
7544/// call the static function TH1::StatOverflows(kTRUE) before filling
7545/// the histogram.
7546///
7547/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7548/// are calculated. By default, if no range has been set, the returned mean is
7549/// the (unbinned) one calculated at fill time. If a range has been set, however,
7550/// the mean is calculated using the bins in range, as described above; THIS
7551/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7552/// the range. To ensure that the returned mean (and all other statistics) is
7553/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7554/// See TH1::GetStats.
7555///
7556/// Return mean value of this histogram along the X axis.
7557
7558Double_t TH1::GetMean(Int_t axis) const
7559{
7560 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7561 Double_t stats[kNstat];
7562 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7563 GetStats(stats);
7564 if (stats[0] == 0) return 0;
7565 if (axis<4){
7566 Int_t ax[3] = {2,4,7};
7567 return stats[ax[axis-1]]/stats[0];
7568 } else {
7569 // mean error = StdDev / sqrt( Neff )
7570 Double_t stddev = GetStdDev(axis-10);
7572 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7573 }
7574}
7575
7576////////////////////////////////////////////////////////////////////////////////
7577/// Return standard error of mean of this histogram along the X axis.
7578///
7579/// Note that the mean value/StdDev is computed using the bins in the currently
7580/// defined range (see TAxis::SetRange). By default the range includes
7581/// all bins from 1 to nbins included, excluding underflows and overflows.
7582/// To force the underflows and overflows in the computation, one must
7583/// call the static function TH1::StatOverflows(kTRUE) before filling
7584/// the histogram.
7585///
7586/// Also note, that although the definition of standard error doesn't include the
7587/// assumption of normality, many uses of this feature implicitly assume it.
7588///
7589/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7590/// are calculated. By default, if no range has been set, the returned value is
7591/// the (unbinned) one calculated at fill time. If a range has been set, however,
7592/// the value is calculated using the bins in range, as described above; THIS
7593/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7594/// the range. To ensure that the returned value (and all other statistics) is
7595/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7596/// See TH1::GetStats.
7597
7599{
7600 return GetMean(axis+10);
7601}
7602
7603////////////////////////////////////////////////////////////////////////////////
7604/// Returns the Standard Deviation (Sigma).
7605/// The Sigma estimate is computed as
7606/// \f[
7607/// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7608/// \f]
7609/// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7610/// X, Y or Z axis
7611/// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7612/// X, Y or Z axis for Normal distribution
7613///
7614/// Note that the mean value/sigma is computed using the bins in the currently
7615/// defined range (see TAxis::SetRange). By default the range includes
7616/// all bins from 1 to nbins included, excluding underflows and overflows.
7617/// To force the underflows and overflows in the computation, one must
7618/// call the static function TH1::StatOverflows(kTRUE) before filling
7619/// the histogram.
7620///
7621/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7622/// are calculated. By default, if no range has been set, the returned standard
7623/// deviation is the (unbinned) one calculated at fill time. If a range has been
7624/// set, however, the standard deviation is calculated using the bins in range,
7625/// as described above; THIS IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use
7626/// TAxis::SetRange(0, 0) to unset the range. To ensure that the returned standard
7627/// deviation (and all other statistics) is always that of the binned data stored
7628/// in the histogram, call TH1::ResetStats. See TH1::GetStats.
7629
7630Double_t TH1::GetStdDev(Int_t axis) const
7631{
7632 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7633
7634 Double_t x, stddev2, stats[kNstat];
7635 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7636 GetStats(stats);
7637 if (stats[0] == 0) return 0;
7638 Int_t ax[3] = {2,4,7};
7639 Int_t axm = ax[axis%10 - 1];
7640 x = stats[axm]/stats[0];
7641 // for negative stddev (e.g. when having negative weights) - return stdev=0
7642 stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7643 if (axis<10)
7644 return TMath::Sqrt(stddev2);
7645 else {
7646 // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7647 // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7649 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7650 }
7651}
7652
7653////////////////////////////////////////////////////////////////////////////////
7654/// Return error of standard deviation estimation for Normal distribution
7655///
7656/// Note that the mean value/StdDev is computed using the bins in the currently
7657/// defined range (see TAxis::SetRange). By default the range includes
7658/// all bins from 1 to nbins included, excluding underflows and overflows.
7659/// To force the underflows and overflows in the computation, one must
7660/// call the static function TH1::StatOverflows(kTRUE) before filling
7661/// the histogram.
7662///
7663/// Value returned is standard deviation of sample standard deviation.
7664/// Note that it is an approximated value which is valid only in the case that the
7665/// original data distribution is Normal. The correct one would require
7666/// the 4-th momentum value, which cannot be accurately estimated from a histogram since
7667/// the x-information for all entries is not kept.
7668///
7669/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7670/// are calculated. By default, if no range has been set, the returned value is
7671/// the (unbinned) one calculated at fill time. If a range has been set, however,
7672/// the value is calculated using the bins in range, as described above; THIS
7673/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7674/// the range. To ensure that the returned value (and all other statistics) is
7675/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7676/// See TH1::GetStats.
7677
7679{
7680 return GetStdDev(axis+10);
7681}
7682
7683////////////////////////////////////////////////////////////////////////////////
7684/// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7685/// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7686/// of the histogram along x, y or z axis
7687///
7688///Note, that since third and fourth moment are not calculated
7689///at the fill time, skewness and its standard error are computed bin by bin
7690///
7691/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7692/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7693
7695{
7696
7697 if (axis > 0 && axis <= 3){
7698
7699 Double_t mean = GetMean(axis);
7700 Double_t stddev = GetStdDev(axis);
7701 Double_t stddev3 = stddev*stddev*stddev;
7702
7703 Int_t firstBinX = fXaxis.GetFirst();
7704 Int_t lastBinX = fXaxis.GetLast();
7705 Int_t firstBinY = fYaxis.GetFirst();
7706 Int_t lastBinY = fYaxis.GetLast();
7707 Int_t firstBinZ = fZaxis.GetFirst();
7708 Int_t lastBinZ = fZaxis.GetLast();
7709 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7712 if (firstBinX == 1) firstBinX = 0;
7713 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7714 }
7716 if (firstBinY == 1) firstBinY = 0;
7717 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7718 }
7720 if (firstBinZ == 1) firstBinZ = 0;
7721 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7722 }
7723 }
7724
7725 Double_t x = 0;
7726 Double_t sum=0;
7727 Double_t np=0;
7728 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7729 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7730 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7731 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7732 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7733 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7734 Double_t w = GetBinContent(binx,biny,binz);
7735 np+=w;
7736 sum+=w*(x-mean)*(x-mean)*(x-mean);
7737 }
7738 }
7739 }
7740 sum/=np*stddev3;
7741 return sum;
7742 }
7743 else if (axis > 10 && axis <= 13) {
7744 //compute standard error of skewness
7745 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7747 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7748 }
7749 else {
7750 Error("GetSkewness", "illegal value of parameter");
7751 return 0;
7752 }
7753}
7754
7755////////////////////////////////////////////////////////////////////////////////
7756/// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7757/// Kurtosis(gaussian(0, 1)) = 0.
7758/// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7759/// of the histogram along x, y or z axis
7760////
7761/// Note, that since third and fourth moment are not calculated
7762/// at the fill time, kurtosis and its standard error are computed bin by bin
7763///
7764/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7765/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7766
7768{
7769 if (axis > 0 && axis <= 3){
7770
7771 Double_t mean = GetMean(axis);
7772 Double_t stddev = GetStdDev(axis);
7773 Double_t stddev4 = stddev*stddev*stddev*stddev;
7774
7775 Int_t firstBinX = fXaxis.GetFirst();
7776 Int_t lastBinX = fXaxis.GetLast();
7777 Int_t firstBinY = fYaxis.GetFirst();
7778 Int_t lastBinY = fYaxis.GetLast();
7779 Int_t firstBinZ = fZaxis.GetFirst();
7780 Int_t lastBinZ = fZaxis.GetLast();
7781 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7784 if (firstBinX == 1) firstBinX = 0;
7785 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7786 }
7788 if (firstBinY == 1) firstBinY = 0;
7789 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7790 }
7792 if (firstBinZ == 1) firstBinZ = 0;
7793 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7794 }
7795 }
7796
7797 Double_t x = 0;
7798 Double_t sum=0;
7799 Double_t np=0;
7800 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7801 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7802 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7803 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7804 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7805 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7806 Double_t w = GetBinContent(binx,biny,binz);
7807 np+=w;
7808 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7809 }
7810 }
7811 }
7812 sum/=(np*stddev4);
7813 return sum-3;
7814
7815 } else if (axis > 10 && axis <= 13) {
7816 //compute standard error of skewness
7817 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7819 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7820 }
7821 else {
7822 Error("GetKurtosis", "illegal value of parameter");
7823 return 0;
7824 }
7825}
7826
7827////////////////////////////////////////////////////////////////////////////////
7828/// fill the array stats from the contents of this histogram
7829/// The array stats must be correctly dimensioned in the calling program.
7830///
7831/// ~~~ {.cpp}
7832/// stats[0] = sumw
7833/// stats[1] = sumw2
7834/// stats[2] = sumwx
7835/// stats[3] = sumwx2
7836/// ~~~
7837///
7838/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7839/// is simply a copy of the statistics quantities computed at filling time.
7840/// If a sub-range is specified, the function recomputes these quantities
7841/// from the bin contents in the current axis range.
7842///
7843/// IMPORTANT NOTE: This means that the returned statistics are context-dependent.
7844/// If TAxis::kAxisRange, the returned statistics are dependent on the binning;
7845/// otherwise, they are a copy of the histogram statistics computed at fill time,
7846/// which are unbinned by default (calling TH1::ResetStats forces them to use
7847/// binned statistics). You can reset TAxis::kAxisRange using TAxis::SetRange(0, 0).
7848///
7849/// Note that the mean value/StdDev is computed using the bins in the currently
7850/// defined range (see TAxis::SetRange). By default the range includes
7851/// all bins from 1 to nbins included, excluding underflows and overflows.
7852/// To force the underflows and overflows in the computation, one must
7853/// call the static function TH1::StatOverflows(kTRUE) before filling
7854/// the histogram.
7855
7856void TH1::GetStats(Double_t *stats) const
7857{
7858 if (fBuffer) ((TH1*)this)->BufferEmpty();
7859
7860 // Loop on bins (possibly including underflows/overflows)
7861 Int_t bin, binx;
7862 Double_t w,err;
7863 Double_t x;
7864 // identify the case of labels with extension of axis range
7865 // in this case the statistics in x does not make any sense
7866 Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && fXaxis.CanExtend() );
7867 // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7868 if ( (fTsumw == 0 && fEntries > 0) || fXaxis.TestBit(TAxis::kAxisRange) ) {
7869 for (bin=0;bin<4;bin++) stats[bin] = 0;
7870
7871 Int_t firstBinX = fXaxis.GetFirst();
7872 Int_t lastBinX = fXaxis.GetLast();
7873 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7875 if (firstBinX == 1) firstBinX = 0;
7876 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7877 }
7878 for (binx = firstBinX; binx <= lastBinX; binx++) {
7879 x = fXaxis.GetBinCenter(binx);
7880 //w = TMath::Abs(RetrieveBinContent(binx));
7881 // not sure what to do here if w < 0
7882 w = RetrieveBinContent(binx);
7883 err = TMath::Abs(GetBinError(binx));
7884 stats[0] += w;
7885 stats[1] += err*err;
7886 // statistics in x makes sense only for not labels histograms
7887 if (!labelHist) {
7888 stats[2] += w*x;
7889 stats[3] += w*x*x;
7890 }
7891 }
7892 // if (stats[0] < 0) {
7893 // // in case total is negative do something ??
7894 // stats[0] = 0;
7895 // }
7896 } else {
7897 stats[0] = fTsumw;
7898 stats[1] = fTsumw2;
7899 stats[2] = fTsumwx;
7900 stats[3] = fTsumwx2;
7901 }
7902}
7903
7904////////////////////////////////////////////////////////////////////////////////
7905/// Replace current statistics with the values in array stats
7906
7907void TH1::PutStats(Double_t *stats)
7908{
7909 fTsumw = stats[0];
7910 fTsumw2 = stats[1];
7911 fTsumwx = stats[2];
7912 fTsumwx2 = stats[3];
7913}
7914
7915////////////////////////////////////////////////////////////////////////////////
7916/// Reset the statistics including the number of entries
7917/// and replace with values calculated from bin content
7918///
7919/// The number of entries is set to the total bin content or (in case of weighted histogram)
7920/// to number of effective entries
7921///
7922/// Note that, by default, before calling this function, statistics are those
7923/// computed at fill time, which are unbinned. See TH1::GetStats.
7924
7925void TH1::ResetStats()
7926{
7927 Double_t stats[kNstat] = {0};
7928 fTsumw = 0;
7929 fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
7930 GetStats(stats);
7931 PutStats(stats);
7933 // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
7934 if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
7935}
7936
7937////////////////////////////////////////////////////////////////////////////////
7938/// Return the sum of weights excluding under/overflows.
7939
7941{
7942 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7943
7944 Int_t bin,binx,biny,binz;
7945 Double_t sum =0;
7946 for(binz=1; binz<=fZaxis.GetNbins(); binz++) {
7947 for(biny=1; biny<=fYaxis.GetNbins(); biny++) {
7948 for(binx=1; binx<=fXaxis.GetNbins(); binx++) {
7949 bin = GetBin(binx,biny,binz);
7950 sum += RetrieveBinContent(bin);
7951 }
7952 }
7953 }
7954 return sum;
7955}
7956
7957////////////////////////////////////////////////////////////////////////////////
7958///Return integral of bin contents. Only bins in the bins range are considered.
7959///
7960/// By default the integral is computed as the sum of bin contents in the range.
7961/// if option "width" is specified, the integral is the sum of
7962/// the bin contents multiplied by the bin width in x.
7963
7965{
7967}
7968
7969////////////////////////////////////////////////////////////////////////////////
7970/// Return integral of bin contents in range [binx1,binx2].
7971///
7972/// By default the integral is computed as the sum of bin contents in the range.
7973/// if option "width" is specified, the integral is the sum of
7974/// the bin contents multiplied by the bin width in x.
7975
7976Double_t TH1::Integral(Int_t binx1, Int_t binx2, Option_t *option) const
7977{
7978 double err = 0;
7979 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
7980}
7981
7982////////////////////////////////////////////////////////////////////////////////
7983/// Return integral of bin contents in range [binx1,binx2] and its error.
7984///
7985/// By default the integral is computed as the sum of bin contents in the range.
7986/// if option "width" is specified, the integral is the sum of
7987/// the bin contents multiplied by the bin width in x.
7988/// the error is computed using error propagation from the bin errors assuming that
7989/// all the bins are uncorrelated
7990
7991Double_t TH1::IntegralAndError(Int_t binx1, Int_t binx2, Double_t & error, Option_t *option) const
7992{
7993 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
7994}
7995
7996////////////////////////////////////////////////////////////////////////////////
7997/// Internal function compute integral and optionally the error between the limits
7998/// specified by the bin number values working for all histograms (1D, 2D and 3D)
7999
8000Double_t TH1::DoIntegral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error ,
8001 Option_t *option, Bool_t doError) const
8002{
8003 if (fBuffer) ((TH1*)this)->BufferEmpty();
8004
8005 Int_t nx = GetNbinsX() + 2;
8006 if (binx1 < 0) binx1 = 0;
8007 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
8008
8009 if (GetDimension() > 1) {
8010 Int_t ny = GetNbinsY() + 2;
8011 if (biny1 < 0) biny1 = 0;
8012 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
8013 } else {
8014 biny1 = 0; biny2 = 0;
8015 }
8016
8017 if (GetDimension() > 2) {
8018 Int_t nz = GetNbinsZ() + 2;
8019 if (binz1 < 0) binz1 = 0;
8020 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
8021 } else {
8022 binz1 = 0; binz2 = 0;
8023 }
8024
8025 // - Loop on bins in specified range
8026 TString opt = option;
8027 opt.ToLower();
8029 if (opt.Contains("width")) width = kTRUE;
8030
8031
8032 Double_t dx = 1., dy = .1, dz =.1;
8033 Double_t integral = 0;
8034 Double_t igerr2 = 0;
8035 for (Int_t binx = binx1; binx <= binx2; ++binx) {
8036 if (width) dx = fXaxis.GetBinWidth(binx);
8037 for (Int_t biny = biny1; biny <= biny2; ++biny) {
8038 if (width) dy = fYaxis.GetBinWidth(biny);
8039 for (Int_t binz = binz1; binz <= binz2; ++binz) {
8040 Int_t bin = GetBin(binx, biny, binz);
8041 Double_t dv = 0.0;
8042 if (width) {
8043 dz = fZaxis.GetBinWidth(binz);
8044 dv = dx * dy * dz;
8045 integral += RetrieveBinContent(bin) * dv;
8046 } else {
8047 integral += RetrieveBinContent(bin);
8048 }
8049 if (doError) {
8050 if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
8051 else igerr2 += GetBinErrorSqUnchecked(bin);
8052 }
8053 }
8054 }
8055 }
8056
8057 if (doError) error = TMath::Sqrt(igerr2);
8058 return integral;
8059}
8060
8061////////////////////////////////////////////////////////////////////////////////
8062/// Statistical test of compatibility in shape between
8063/// this histogram and h2, using the Anderson-Darling 2 sample test.
8064///
8065/// The AD 2 sample test formula are derived from the paper
8066/// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
8067///
8068/// The test is implemented in root in the ROOT::Math::GoFTest class
8069/// It is the same formula ( (6) in the paper), and also shown in
8070/// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
8071///
8072/// Binned data are considered as un-binned data
8073/// with identical observation happening in the bin center.
8074///
8075/// \param[in] h2 Pointer to 1D histogram
8076/// \param[in] option is a character string to specify options
8077/// - "D" Put out a line of "Debug" printout
8078/// - "T" Return the normalized A-D test statistic
8079///
8080/// - Note1: Underflow and overflow are not considered in the test
8081/// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
8082/// - Note3: The histograms are not required to have the same X axis
8083/// - Note4: The test works only for 1-dimensional histograms
8084
8086{
8087 Double_t advalue = 0;
8088 Double_t pvalue = AndersonDarlingTest(h2, advalue);
8089
8090 TString opt = option;
8091 opt.ToUpper();
8092 if (opt.Contains("D") ) {
8093 printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
8094 }
8095 if (opt.Contains("T") ) return advalue;
8096
8097 return pvalue;
8098}
8099
8100////////////////////////////////////////////////////////////////////////////////
8101/// Same function as above but returning also the test statistic value
8102
8103Double_t TH1::AndersonDarlingTest(const TH1 *h2, Double_t & advalue) const
8104{
8105 if (GetDimension() != 1 || h2->GetDimension() != 1) {
8106 Error("AndersonDarlingTest","Histograms must be 1-D");
8107 return -1;
8108 }
8109
8110 // empty the buffer. Probably we could add as an unbinned test
8111 if (fBuffer) ((TH1*)this)->BufferEmpty();
8112
8113 // use the BinData class
8114 ROOT::Fit::BinData data1;
8115 ROOT::Fit::BinData data2;
8116
8117 ROOT::Fit::FillData(data1, this, nullptr);
8118 ROOT::Fit::FillData(data2, h2, nullptr);
8119
8120 double pvalue;
8121 ROOT::Math::GoFTest::AndersonDarling2SamplesTest(data1,data2, pvalue,advalue);
8122
8123 return pvalue;
8124}
8125
8126////////////////////////////////////////////////////////////////////////////////
8127/// Statistical test of compatibility in shape between
8128/// this histogram and h2, using Kolmogorov test.
8129/// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
8130/// and not for binned data as in the case of the histogram (see NOTE 3 below).
8131/// So, before using this method blindly, read the NOTE 3.
8132///
8133/// Default: Ignore under- and overflow bins in comparison
8134///
8135/// \param[in] h2 histogram
8136/// \param[in] option is a character string to specify options
8137/// - "U" include Underflows in test (also for 2-dim)
8138/// - "O" include Overflows (also valid for 2-dim)
8139/// - "N" include comparison of normalizations
8140/// - "D" Put out a line of "Debug" printout
8141/// - "M" Return the Maximum Kolmogorov distance instead of prob
8142/// - "X" Run the pseudo experiments post-processor with the following procedure:
8143/// make pseudoexperiments based on random values from the parent distribution,
8144/// compare the KS distance of the pseudoexperiment to the parent
8145/// distribution, and count all the KS values above the value
8146/// obtained from the original data to Monte Carlo distribution.
8147/// The number of pseudo-experiments nEXPT is by default 1000, and
8148/// it can be changed by specifying the option as "X=number",
8149/// for example "X=10000" for 10000 toys.
8150/// The function returns the probability.
8151/// (thanks to Ben Kilminster to submit this procedure). Note that
8152/// this option "X" is much slower.
8153///
8154/// The returned function value is the probability of test
8155/// (much less than one means NOT compatible)
8156///
8157/// Code adapted by Rene Brun from original HBOOK routine HDIFF
8158///
8159/// NOTE1
8160/// A good description of the Kolmogorov test can be seen at:
8161/// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
8162///
8163/// NOTE2
8164/// see also alternative function TH1::Chi2Test
8165/// The Kolmogorov test is assumed to give better results than Chi2Test
8166/// in case of histograms with low statistics.
8167///
8168/// NOTE3 (Jan Conrad, Fred James)
8169/// "The returned value PROB is calculated such that it will be
8170/// uniformly distributed between zero and one for compatible histograms,
8171/// provided the data are not binned (or the number of bins is very large
8172/// compared with the number of events). Users who have access to unbinned
8173/// data and wish exact confidence levels should therefore not put their data
8174/// into histograms, but should call directly TMath::KolmogorovTest. On
8175/// the other hand, since TH1 is a convenient way of collecting data and
8176/// saving space, this function has been provided. However, the values of
8177/// PROB for binned data will be shifted slightly higher than expected,
8178/// depending on the effects of the binning. For example, when comparing two
8179/// uniform distributions of 500 events in 100 bins, the values of PROB,
8180/// instead of being exactly uniformly distributed between zero and one, have
8181/// a mean value of about 0.56. We can apply a useful
8182/// rule: As long as the bin width is small compared with any significant
8183/// physical effect (for example the experimental resolution) then the binning
8184/// cannot have an important effect. Therefore, we believe that for all
8185/// practical purposes, the probability value PROB is calculated correctly
8186/// provided the user is aware that:
8187///
8188/// 1. The value of PROB should not be expected to have exactly the correct
8189/// distribution for binned data.
8190/// 2. The user is responsible for seeing to it that the bin widths are
8191/// small compared with any physical phenomena of interest.
8192/// 3. The effect of binning (if any) is always to make the value of PROB
8193/// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
8194/// will assure that at most 5% of truly compatible histograms are rejected,
8195/// and usually somewhat less."
8196///
8197/// Note also that for GoF test of unbinned data ROOT provides also the class
8198/// ROOT::Math::GoFTest. The class has also method for doing one sample tests
8199/// (i.e. comparing the data with a given distribution).
8200
8202{
8203 TString opt = option;
8204 opt.ToUpper();
8205
8206 Double_t prob = 0;
8207 TH1 *h1 = (TH1*)this;
8208 if (h2 == nullptr) return 0;
8209 const TAxis *axis1 = h1->GetXaxis();
8210 const TAxis *axis2 = h2->GetXaxis();
8211 Int_t ncx1 = axis1->GetNbins();
8212 Int_t ncx2 = axis2->GetNbins();
8213
8214 // Check consistency of dimensions
8215 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
8216 Error("KolmogorovTest","Histograms must be 1-D\n");
8217 return 0;
8218 }
8219
8220 // Check consistency in number of channels
8221 if (ncx1 != ncx2) {
8222 Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
8223 return 0;
8224 }
8225
8226 // empty the buffer. Probably we could add as an unbinned test
8227 if (fBuffer) ((TH1*)this)->BufferEmpty();
8228
8229 // Check consistency in bin edges
8230 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
8231 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
8232 Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
8233 return 0;
8234 }
8235 }
8236
8237 Bool_t afunc1 = kFALSE;
8238 Bool_t afunc2 = kFALSE;
8239 Double_t sum1 = 0, sum2 = 0;
8240 Double_t ew1, ew2, w1 = 0, w2 = 0;
8241 Int_t bin;
8242 Int_t ifirst = 1;
8243 Int_t ilast = ncx1;
8244 // integral of all bins (use underflow/overflow if option)
8245 if (opt.Contains("U")) ifirst = 0;
8246 if (opt.Contains("O")) ilast = ncx1 +1;
8247 for (bin = ifirst; bin <= ilast; bin++) {
8248 sum1 += h1->RetrieveBinContent(bin);
8249 sum2 += h2->RetrieveBinContent(bin);
8250 ew1 = h1->GetBinError(bin);
8251 ew2 = h2->GetBinError(bin);
8252 w1 += ew1*ew1;
8253 w2 += ew2*ew2;
8254 }
8255 if (sum1 == 0) {
8256 Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
8257 return 0;
8258 }
8259 if (sum2 == 0) {
8260 Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
8261 return 0;
8262 }
8263
8264 // calculate the effective entries.
8265 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
8266 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
8267 Double_t esum1 = 0, esum2 = 0;
8268 if (w1 > 0)
8269 esum1 = sum1 * sum1 / w1;
8270 else
8271 afunc1 = kTRUE; // use later for calculating z
8272
8273 if (w2 > 0)
8274 esum2 = sum2 * sum2 / w2;
8275 else
8276 afunc2 = kTRUE; // use later for calculating z
8277
8278 if (afunc2 && afunc1) {
8279 Error("KolmogorovTest","Errors are zero for both histograms\n");
8280 return 0;
8281 }
8282
8283
8284 Double_t s1 = 1/sum1;
8285 Double_t s2 = 1/sum2;
8286
8287 // Find largest difference for Kolmogorov Test
8288 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
8289
8290 for (bin=ifirst;bin<=ilast;bin++) {
8291 rsum1 += s1*h1->RetrieveBinContent(bin);
8292 rsum2 += s2*h2->RetrieveBinContent(bin);
8293 dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
8294 }
8295
8296 // Get Kolmogorov probability
8297 Double_t z, prb1=0, prb2=0, prb3=0;
8298
8299 // case h1 is exact (has zero errors)
8300 if (afunc1)
8301 z = dfmax*TMath::Sqrt(esum2);
8302 // case h2 has zero errors
8303 else if (afunc2)
8304 z = dfmax*TMath::Sqrt(esum1);
8305 else
8306 // for comparison between two data sets
8307 z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
8308
8309 prob = TMath::KolmogorovProb(z);
8310
8311 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
8312 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
8313 // Combine probabilities for shape and normalization,
8314 prb1 = prob;
8315 Double_t d12 = esum1-esum2;
8316 Double_t chi2 = d12*d12/(esum1+esum2);
8317 prb2 = TMath::Prob(chi2,1);
8318 // see Eadie et al., section 11.6.2
8319 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
8320 else prob = 0;
8321 }
8322 // X option. Run Pseudo-experiments to determine NULL distribution of the
8323 // KS distance. We can find the probability from the number of pseudo-experiment that have a
8324 // KS distance larger than the one opbserved in the data.
8325 // We use the histogram with the largest statistics as a parent distribution for the NULL.
8326 // Note if one histogram has zero errors is considered as a function. In that case we use it
8327 // as parent distribution for the toys.
8328 //
8329 Int_t nEXPT = 1000;
8330 if (opt.Contains("X")) {
8331 // get number of pseudo-experiment of specified
8332 if (opt.Contains("X=")) {
8333 int numpos = opt.Index("X=") + 2; // 2 is length of X=
8334 int numlen = 0;
8335 int len = opt.Length();
8336 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) )
8337 numlen++;
8338 TString snum = opt(numpos,numlen);
8339 int num = atoi(snum.Data());
8340 if (num <= 0)
8341 Warning("KolmogorovTest","invalid number of toys given: %d - use 1000",num);
8342 else
8343 nEXPT = num;
8344 }
8345
8346 Double_t dSEXPT;
8347 TH1D hparent;
8348 // we cannot have afunc1 and func2 both True
8349 if (afunc1 || esum1 > esum2 ) h1->Copy(hparent);
8350 else h2->Copy(hparent);
8351
8352 // copy h1Expt from h1 and h2. It is just needed to get the correct binning
8353
8354
8355 if (hparent.GetMinimum() < 0.0) {
8356 // we need to create a new histogram
8357 // With negative bins we can't draw random samples in a meaningful way.
8358 Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
8359 "skewed. Reduce number of bins for histogram?");
8360 while (hparent.GetMinimum() < 0.0) {
8361 Int_t idx = hparent.GetMinimumBin();
8362 hparent.SetBinContent(idx, 0.0);
8363 }
8364 }
8365
8366 // make nEXPT experiments (this should be a parameter)
8367 prb3 = 0;
8368 TH1D h1Expt;
8369 h1->Copy(h1Expt);
8370 TH1D h2Expt;
8371 h1->Copy(h2Expt);
8372 // loop on pseudoexperients and generate the two histograms h1Expt and h2Expt according to the
8373 // parent distribution. In case the parent distribution is not an histogram but a function randomize only one
8374 // histogram
8375 for (Int_t i=0; i < nEXPT; i++) {
8376 if (!afunc1) {
8377 h1Expt.Reset();
8378 h1Expt.FillRandom(&hparent, (Int_t)esum1);
8379 }
8380 if (!afunc2) {
8381 h2Expt.Reset();
8382 h2Expt.FillRandom(&hparent, (Int_t)esum2);
8383 }
8384 // note we cannot have both afunc1 and afunc2 to be true
8385 if (afunc1)
8386 dSEXPT = hparent.KolmogorovTest(&h2Expt,"M");
8387 else if (afunc2)
8388 dSEXPT = hparent.KolmogorovTest(&h1Expt,"M");
8389 else
8390 dSEXPT = h1Expt.KolmogorovTest(&h2Expt,"M");
8391 // count number of cases toy KS distance (TS) is larger than oberved one
8392 if (dSEXPT>dfmax) prb3 += 1.0;
8393 }
8394 // compute p-value
8395 prb3 /= (Double_t)nEXPT;
8396 }
8397
8398
8399 // debug printout
8400 if (opt.Contains("D")) {
8401 printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
8402 printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
8403 printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
8404 if (opt.Contains("N"))
8405 printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
8406 if (opt.Contains("X"))
8407 printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
8408 }
8409 // This numerical error condition should never occur:
8410 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
8411 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
8412
8413 if(opt.Contains("M")) return dfmax;
8414 else if(opt.Contains("X")) return prb3;
8415 else return prob;
8416}
8417
8418////////////////////////////////////////////////////////////////////////////////
8419/// Replace bin contents by the contents of array content
8420
8421void TH1::SetContent(const Double_t *content)
8422{
8423 fEntries = fNcells;
8424 fTsumw = 0;
8425 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
8426}
8427
8428////////////////////////////////////////////////////////////////////////////////
8429/// Return contour values into array levels if pointer levels is non zero.
8430///
8431/// The function returns the number of contour levels.
8432/// see GetContourLevel to return one contour only
8433
8435{
8436 Int_t nlevels = fContour.fN;
8437 if (levels) {
8438 if (nlevels == 0) {
8439 nlevels = 20;
8440 SetContour(nlevels);
8441 } else {
8442 if (TestBit(kUserContour) == 0) SetContour(nlevels);
8443 }
8444 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
8445 }
8446 return nlevels;
8447}
8448
8449////////////////////////////////////////////////////////////////////////////////
8450/// Return value of contour number level.
8451/// Use GetContour to return the array of all contour levels
8452
8454{
8455 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
8456}
8457
8458////////////////////////////////////////////////////////////////////////////////
8459/// Return the value of contour number "level" in Pad coordinates.
8460/// ie: if the Pad is in log scale along Z it returns le log of the contour level
8461/// value. See GetContour to return the array of all contour levels
8462
8464{
8465 if (level <0 || level >= fContour.fN) return 0;
8466 Double_t zlevel = fContour.fArray[level];
8467
8468 // In case of user defined contours and Pad in log scale along Z,
8469 // fContour.fArray doesn't contain the log of the contour whereas it does
8470 // in case of equidistant contours.
8471 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
8472 if (zlevel <= 0) return 0;
8473 zlevel = TMath::Log10(zlevel);
8474 }
8475 return zlevel;
8476}
8477
8478////////////////////////////////////////////////////////////////////////////////
8479/// Set the maximum number of entries to be kept in the buffer.
8480
8481void TH1::SetBuffer(Int_t buffersize, Option_t * /*option*/)
8482{
8483 if (fBuffer) {
8484 BufferEmpty();
8485 delete [] fBuffer;
8486 fBuffer = nullptr;
8487 }
8488 if (buffersize <= 0) {
8489 fBufferSize = 0;
8490 return;
8491 }
8492 if (buffersize < 100) buffersize = 100;
8493 fBufferSize = 1 + buffersize*(fDimension+1);
8495 memset(fBuffer, 0, sizeof(Double_t)*fBufferSize);
8496}
8497
8498////////////////////////////////////////////////////////////////////////////////
8499/// Set the number and values of contour levels.
8500///
8501/// By default the number of contour levels is set to 20. The contours values
8502/// in the array "levels" should be specified in increasing order.
8503///
8504/// if argument levels = 0 or missing, equidistant contours are computed
8505
8506void TH1::SetContour(Int_t nlevels, const Double_t *levels)
8507{
8508 Int_t level;
8510 if (nlevels <=0 ) {
8511 fContour.Set(0);
8512 return;
8513 }
8514 fContour.Set(nlevels);
8515
8516 // - Contour levels are specified
8517 if (levels) {
8519 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
8520 } else {
8521 // - contour levels are computed automatically as equidistant contours
8522 Double_t zmin = GetMinimum();
8523 Double_t zmax = GetMaximum();
8524 if ((zmin == zmax) && (zmin != 0)) {
8525 zmax += 0.01*TMath::Abs(zmax);
8526 zmin -= 0.01*TMath::Abs(zmin);
8527 }
8528 Double_t dz = (zmax-zmin)/Double_t(nlevels);
8529 if (gPad && gPad->GetLogz()) {
8530 if (zmax <= 0) return;
8531 if (zmin <= 0) zmin = 0.001*zmax;
8532 zmin = TMath::Log10(zmin);
8533 zmax = TMath::Log10(zmax);
8534 dz = (zmax-zmin)/Double_t(nlevels);
8535 }
8536 for (level=0; level<nlevels; level++) {
8537 fContour.fArray[level] = zmin + dz*Double_t(level);
8538 }
8539 }
8540}
8541
8542////////////////////////////////////////////////////////////////////////////////
8543/// Set value for one contour level.
8544
8546{
8547 if (level < 0 || level >= fContour.fN) return;
8549 fContour.fArray[level] = value;
8550}
8551
8552////////////////////////////////////////////////////////////////////////////////
8553/// Return maximum value smaller than maxval of bins in the range,
8554/// unless the value has been overridden by TH1::SetMaximum,
8555/// in which case it returns that value. This happens, for example,
8556/// when the histogram is drawn and the y or z axis limits are changed
8557///
8558/// To get the maximum value of bins in the histogram regardless of
8559/// whether the value has been overridden (using TH1::SetMaximum), use
8560///
8561/// ~~~ {.cpp}
8562/// h->GetBinContent(h->GetMaximumBin())
8563/// ~~~
8564///
8565/// TH1::GetMaximumBin can be used to get the location of the maximum
8566/// value.
8567
8568Double_t TH1::GetMaximum(Double_t maxval) const
8569{
8570 if (fMaximum != -1111) return fMaximum;
8571
8572 // empty the buffer
8573 if (fBuffer) ((TH1*)this)->BufferEmpty();
8574
8575 Int_t bin, binx, biny, binz;
8576 Int_t xfirst = fXaxis.GetFirst();
8577 Int_t xlast = fXaxis.GetLast();
8578 Int_t yfirst = fYaxis.GetFirst();
8579 Int_t ylast = fYaxis.GetLast();
8580 Int_t zfirst = fZaxis.GetFirst();
8581 Int_t zlast = fZaxis.GetLast();
8582 Double_t maximum = -FLT_MAX, value;
8583 for (binz=zfirst;binz<=zlast;binz++) {
8584 for (biny=yfirst;biny<=ylast;biny++) {
8585 for (binx=xfirst;binx<=xlast;binx++) {
8586 bin = GetBin(binx,biny,binz);
8588 if (value > maximum && value < maxval) maximum = value;
8589 }
8590 }
8591 }
8592 return maximum;
8593}
8594
8595////////////////////////////////////////////////////////////////////////////////
8596/// Return location of bin with maximum value in the range.
8597///
8598/// TH1::GetMaximum can be used to get the maximum value.
8599
8601{
8602 Int_t locmax, locmay, locmaz;
8603 return GetMaximumBin(locmax, locmay, locmaz);
8604}
8605
8606////////////////////////////////////////////////////////////////////////////////
8607/// Return location of bin with maximum value in the range.
8608
8609Int_t TH1::GetMaximumBin(Int_t &locmax, Int_t &locmay, Int_t &locmaz) const
8610{
8611 // empty the buffer
8612 if (fBuffer) ((TH1*)this)->BufferEmpty();
8613
8614 Int_t bin, binx, biny, binz;
8615 Int_t locm;
8616 Int_t xfirst = fXaxis.GetFirst();
8617 Int_t xlast = fXaxis.GetLast();
8618 Int_t yfirst = fYaxis.GetFirst();
8619 Int_t ylast = fYaxis.GetLast();
8620 Int_t zfirst = fZaxis.GetFirst();
8621 Int_t zlast = fZaxis.GetLast();
8622 Double_t maximum = -FLT_MAX, value;
8623 locm = locmax = locmay = locmaz = 0;
8624 for (binz=zfirst;binz<=zlast;binz++) {
8625 for (biny=yfirst;biny<=ylast;biny++) {
8626 for (binx=xfirst;binx<=xlast;binx++) {
8627 bin = GetBin(binx,biny,binz);
8629 if (value > maximum) {
8630 maximum = value;
8631 locm = bin;
8632 locmax = binx;
8633 locmay = biny;
8634 locmaz = binz;
8635 }
8636 }
8637 }
8638 }
8639 return locm;
8640}
8641
8642////////////////////////////////////////////////////////////////////////////////
8643/// Return minimum value larger than minval of bins in the range,
8644/// unless the value has been overridden by TH1::SetMinimum,
8645/// in which case it returns that value. This happens, for example,
8646/// when the histogram is drawn and the y or z axis limits are changed
8647///
8648/// To get the minimum value of bins in the histogram regardless of
8649/// whether the value has been overridden (using TH1::SetMinimum), use
8650///
8651/// ~~~ {.cpp}
8652/// h->GetBinContent(h->GetMinimumBin())
8653/// ~~~
8654///
8655/// TH1::GetMinimumBin can be used to get the location of the
8656/// minimum value.
8657
8658Double_t TH1::GetMinimum(Double_t minval) const
8659{
8660 if (fMinimum != -1111) return fMinimum;
8661
8662 // empty the buffer
8663 if (fBuffer) ((TH1*)this)->BufferEmpty();
8664
8665 Int_t bin, binx, biny, binz;
8666 Int_t xfirst = fXaxis.GetFirst();
8667 Int_t xlast = fXaxis.GetLast();
8668 Int_t yfirst = fYaxis.GetFirst();
8669 Int_t ylast = fYaxis.GetLast();
8670 Int_t zfirst = fZaxis.GetFirst();
8671 Int_t zlast = fZaxis.GetLast();
8672 Double_t minimum=FLT_MAX, value;
8673 for (binz=zfirst;binz<=zlast;binz++) {
8674 for (biny=yfirst;biny<=ylast;biny++) {
8675 for (binx=xfirst;binx<=xlast;binx++) {
8676 bin = GetBin(binx,biny,binz);
8678 if (value < minimum && value > minval) minimum = value;
8679 }
8680 }
8681 }
8682 return minimum;
8683}
8684
8685////////////////////////////////////////////////////////////////////////////////
8686/// Return location of bin with minimum value in the range.
8687
8689{
8690 Int_t locmix, locmiy, locmiz;
8691 return GetMinimumBin(locmix, locmiy, locmiz);
8692}
8693
8694////////////////////////////////////////////////////////////////////////////////
8695/// Return location of bin with minimum value in the range.
8696
8697Int_t TH1::GetMinimumBin(Int_t &locmix, Int_t &locmiy, Int_t &locmiz) const
8698{
8699 // empty the buffer
8700 if (fBuffer) ((TH1*)this)->BufferEmpty();
8701
8702 Int_t bin, binx, biny, binz;
8703 Int_t locm;
8704 Int_t xfirst = fXaxis.GetFirst();
8705 Int_t xlast = fXaxis.GetLast();
8706 Int_t yfirst = fYaxis.GetFirst();
8707 Int_t ylast = fYaxis.GetLast();
8708 Int_t zfirst = fZaxis.GetFirst();
8709 Int_t zlast = fZaxis.GetLast();
8710 Double_t minimum = FLT_MAX, value;
8711 locm = locmix = locmiy = locmiz = 0;
8712 for (binz=zfirst;binz<=zlast;binz++) {
8713 for (biny=yfirst;biny<=ylast;biny++) {
8714 for (binx=xfirst;binx<=xlast;binx++) {
8715 bin = GetBin(binx,biny,binz);
8717 if (value < minimum) {
8718 minimum = value;
8719 locm = bin;
8720 locmix = binx;
8721 locmiy = biny;
8722 locmiz = binz;
8723 }
8724 }
8725 }
8726 }
8727 return locm;
8728}
8729
8730///////////////////////////////////////////////////////////////////////////////
8731/// Retrieve the minimum and maximum values in the histogram
8732///
8733/// This will not return a cached value and will always search the
8734/// histogram for the min and max values. The user can condition whether
8735/// or not to call this with the GetMinimumStored() and GetMaximumStored()
8736/// methods. If the cache is empty, then the value will be -1111. Users
8737/// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8738/// For example, the following recipe will make efficient use of this method
8739/// and the cached minimum and maximum values.
8740//
8741/// \code{.cpp}
8742/// Double_t currentMin = pHist->GetMinimumStored();
8743/// Double_t currentMax = pHist->GetMaximumStored();
8744/// if ((currentMin == -1111) || (currentMax == -1111)) {
8745/// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8746/// pHist->SetMinimum(currentMin);
8747/// pHist->SetMaximum(currentMax);
8748/// }
8749/// \endcode
8750///
8751/// \param min reference to variable that will hold found minimum value
8752/// \param max reference to variable that will hold found maximum value
8753
8754void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8755{
8756 // empty the buffer
8757 if (fBuffer) ((TH1*)this)->BufferEmpty();
8758
8759 Int_t bin, binx, biny, binz;
8760 Int_t xfirst = fXaxis.GetFirst();
8761 Int_t xlast = fXaxis.GetLast();
8762 Int_t yfirst = fYaxis.GetFirst();
8763 Int_t ylast = fYaxis.GetLast();
8764 Int_t zfirst = fZaxis.GetFirst();
8765 Int_t zlast = fZaxis.GetLast();
8766 min=TMath::Infinity();
8767 max=-TMath::Infinity();
8769 for (binz=zfirst;binz<=zlast;binz++) {
8770 for (biny=yfirst;biny<=ylast;biny++) {
8771 for (binx=xfirst;binx<=xlast;binx++) {
8772 bin = GetBin(binx,biny,binz);
8774 if (value < min) min = value;
8775 if (value > max) max = value;
8776 }
8777 }
8778 }
8779}
8780
8781////////////////////////////////////////////////////////////////////////////////
8782/// Redefine x axis parameters.
8783///
8784/// The X axis parameters are modified.
8785/// The bins content array is resized
8786/// if errors (Sumw2) the errors array is resized
8787/// The previous bin contents are lost
8788/// To change only the axis limits, see TAxis::SetRange
8789
8791{
8792 if (GetDimension() != 1) {
8793 Error("SetBins","Operation only valid for 1-d histograms");
8794 return;
8795 }
8796 fXaxis.SetRange(0,0);
8797 fXaxis.Set(nx,xmin,xmax);
8798 fYaxis.Set(1,0,1);
8799 fZaxis.Set(1,0,1);
8800 fNcells = nx+2;
8802 if (fSumw2.fN) {
8804 }
8805}
8806
8807////////////////////////////////////////////////////////////////////////////////
8808/// Redefine x axis parameters with variable bin sizes.
8809///
8810/// The X axis parameters are modified.
8811/// The bins content array is resized
8812/// if errors (Sumw2) the errors array is resized
8813/// The previous bin contents are lost
8814/// To change only the axis limits, see TAxis::SetRange
8815/// xBins is supposed to be of length nx+1
8816
8817void TH1::SetBins(Int_t nx, const Double_t *xBins)
8818{
8819 if (GetDimension() != 1) {
8820 Error("SetBins","Operation only valid for 1-d histograms");
8821 return;
8822 }
8823 fXaxis.SetRange(0,0);
8824 fXaxis.Set(nx,xBins);
8825 fYaxis.Set(1,0,1);
8826 fZaxis.Set(1,0,1);
8827 fNcells = nx+2;
8829 if (fSumw2.fN) {
8831 }
8832}
8833
8834////////////////////////////////////////////////////////////////////////////////
8835/// Redefine x and y axis parameters.
8836///
8837/// The X and Y axis parameters are modified.
8838/// The bins content array is resized
8839/// if errors (Sumw2) the errors array is resized
8840/// The previous bin contents are lost
8841/// To change only the axis limits, see TAxis::SetRange
8842
8844{
8845 if (GetDimension() != 2) {
8846 Error("SetBins","Operation only valid for 2-D histograms");
8847 return;
8848 }
8849 fXaxis.SetRange(0,0);
8850 fYaxis.SetRange(0,0);
8851 fXaxis.Set(nx,xmin,xmax);
8852 fYaxis.Set(ny,ymin,ymax);
8853 fZaxis.Set(1,0,1);
8854 fNcells = (nx+2)*(ny+2);
8856 if (fSumw2.fN) {
8858 }
8859}
8860
8861////////////////////////////////////////////////////////////////////////////////
8862/// Redefine x and y axis parameters with variable bin sizes.
8863///
8864/// The X and Y axis parameters are modified.
8865/// The bins content array is resized
8866/// if errors (Sumw2) the errors array is resized
8867/// The previous bin contents are lost
8868/// To change only the axis limits, see TAxis::SetRange
8869/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
8870
8871void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
8872{
8873 if (GetDimension() != 2) {
8874 Error("SetBins","Operation only valid for 2-D histograms");
8875 return;
8876 }
8877 fXaxis.SetRange(0,0);
8878 fYaxis.SetRange(0,0);
8879 fXaxis.Set(nx,xBins);
8880 fYaxis.Set(ny,yBins);
8881 fZaxis.Set(1,0,1);
8882 fNcells = (nx+2)*(ny+2);
8884 if (fSumw2.fN) {
8886 }
8887}
8888
8889////////////////////////////////////////////////////////////////////////////////
8890/// Redefine x, y and z axis parameters.
8891///
8892/// The X, Y and Z axis parameters are modified.
8893/// The bins content array is resized
8894/// if errors (Sumw2) the errors array is resized
8895/// The previous bin contents are lost
8896/// To change only the axis limits, see TAxis::SetRange
8897
8899{
8900 if (GetDimension() != 3) {
8901 Error("SetBins","Operation only valid for 3-D histograms");
8902 return;
8903 }
8904 fXaxis.SetRange(0,0);
8905 fYaxis.SetRange(0,0);
8906 fZaxis.SetRange(0,0);
8907 fXaxis.Set(nx,xmin,xmax);
8908 fYaxis.Set(ny,ymin,ymax);
8909 fZaxis.Set(nz,zmin,zmax);
8910 fNcells = (nx+2)*(ny+2)*(nz+2);
8912 if (fSumw2.fN) {
8914 }
8915}
8916
8917////////////////////////////////////////////////////////////////////////////////
8918/// Redefine x, y and z axis parameters with variable bin sizes.
8919///
8920/// The X, Y and Z axis parameters are modified.
8921/// The bins content array is resized
8922/// if errors (Sumw2) the errors array is resized
8923/// The previous bin contents are lost
8924/// To change only the axis limits, see TAxis::SetRange
8925/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
8926/// zBins is supposed to be of length nz+1
8927
8928void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
8929{
8930 if (GetDimension() != 3) {
8931 Error("SetBins","Operation only valid for 3-D histograms");
8932 return;
8933 }
8934 fXaxis.SetRange(0,0);
8935 fYaxis.SetRange(0,0);
8936 fZaxis.SetRange(0,0);
8937 fXaxis.Set(nx,xBins);
8938 fYaxis.Set(ny,yBins);
8939 fZaxis.Set(nz,zBins);
8940 fNcells = (nx+2)*(ny+2)*(nz+2);
8942 if (fSumw2.fN) {
8944 }
8945}
8946
8947////////////////////////////////////////////////////////////////////////////////
8948/// By default, when a histogram is created, it is added to the list
8949/// of histogram objects in the current directory in memory.
8950/// Remove reference to this histogram from current directory and add
8951/// reference to new directory dir. dir can be 0 in which case the
8952/// histogram does not belong to any directory.
8953///
8954/// Note that the directory is not a real property of the histogram and
8955/// it will not be copied when the histogram is copied or cloned.
8956/// If the user wants to have the copied (cloned) histogram in the same
8957/// directory, he needs to set again the directory using SetDirectory to the
8958/// copied histograms
8959
8961{
8962 if (fDirectory == dir) return;
8963 if (fDirectory) fDirectory->Remove(this);
8964 fDirectory = dir;
8965 if (fDirectory) {
8967 fDirectory->Append(this);
8968 }
8969}
8970
8971////////////////////////////////////////////////////////////////////////////////
8972/// Replace bin errors by values in array error.
8973
8974void TH1::SetError(const Double_t *error)
8975{
8976 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
8977}
8978
8979////////////////////////////////////////////////////////////////////////////////
8980/// Change the name of this histogram
8982
8983void TH1::SetName(const char *name)
8984{
8985 // Histograms are named objects in a THashList.
8986 // We must update the hashlist if we change the name
8987 // We protect this operation
8989 if (fDirectory) fDirectory->Remove(this);
8990 fName = name;
8991 if (fDirectory) fDirectory->Append(this);
8992}
8993
8994////////////////////////////////////////////////////////////////////////////////
8995/// Change the name and title of this histogram
8996
8997void TH1::SetNameTitle(const char *name, const char *title)
8998{
8999 // Histograms are named objects in a THashList.
9000 // We must update the hashlist if we change the name
9001 SetName(name);
9002 SetTitle(title);
9003}
9004
9005////////////////////////////////////////////////////////////////////////////////
9006/// Set statistics option on/off.
9007///
9008/// By default, the statistics box is drawn.
9009/// The paint options can be selected via gStyle->SetOptStat.
9010/// This function sets/resets the kNoStats bit in the histogram object.
9011/// It has priority over the Style option.
9012
9013void TH1::SetStats(Bool_t stats)
9014{
9016 if (!stats) {
9018 //remove the "stats" object from the list of functions
9019 if (fFunctions) {
9020 TObject *obj = fFunctions->FindObject("stats");
9021 if (obj) {
9022 fFunctions->Remove(obj);
9023 delete obj;
9024 }
9025 }
9026 }
9027}
9028
9029////////////////////////////////////////////////////////////////////////////////
9030/// Create structure to store sum of squares of weights.
9031///
9032/// if histogram is already filled, the sum of squares of weights
9033/// is filled with the existing bin contents
9034///
9035/// The error per bin will be computed as sqrt(sum of squares of weight)
9036/// for each bin.
9037///
9038/// This function is automatically called when the histogram is created
9039/// if the static function TH1::SetDefaultSumw2 has been called before.
9040/// If flag = false the structure containing the sum of the square of weights
9041/// is rest and it will be empty, but it is not deleted (i.e. GetSumw2()->fN = 0)
9042
9043void TH1::Sumw2(Bool_t flag)
9044{
9045 if (!flag) {
9046 // clear the array if existing - do nothing otherwise
9047 if (fSumw2.fN > 0 ) fSumw2.Set(0);
9048 return;
9049 }
9050
9051 if (fSumw2.fN == fNcells) {
9052 if (!fgDefaultSumw2 )
9053 Warning("Sumw2","Sum of squares of weights structure already created");
9054 return;
9055 }
9056
9058
9059 // empty the buffer
9060 if (fBuffer) BufferEmpty();
9061
9062 if (fEntries > 0)
9063 for (Int_t i = 0; i < fNcells; ++i)
9065}
9066
9067////////////////////////////////////////////////////////////////////////////////
9068/// Return pointer to function with name.
9069///
9070///
9071/// Functions such as TH1::Fit store the fitted function in the list of
9072/// functions of this histogram.
9073
9074TF1 *TH1::GetFunction(const char *name) const
9075{
9076 return (TF1*)fFunctions->FindObject(name);
9077}
9078
9079////////////////////////////////////////////////////////////////////////////////
9080/// Return value of error associated to bin number bin.
9081///
9082/// if the sum of squares of weights has been defined (via Sumw2),
9083/// this function returns the sqrt(sum of w2).
9084/// otherwise it returns the sqrt(contents) for this bin.
9085
9087{
9088 if (bin < 0) bin = 0;
9089 if (bin >= fNcells) bin = fNcells-1;
9090 if (fBuffer) ((TH1*)this)->BufferEmpty();
9091 if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
9092
9094}
9095
9096////////////////////////////////////////////////////////////////////////////////
9097/// Return lower error associated to bin number bin.
9098///
9099/// The error will depend on the statistic option used will return
9100/// the binContent - lower interval value
9101
9103{
9104 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9105 // in case of weighted histogram check if it is really weighted
9106 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9107
9108 if (bin < 0) bin = 0;
9109 if (bin >= fNcells) bin = fNcells-1;
9110 if (fBuffer) ((TH1*)this)->BufferEmpty();
9111
9112 Double_t alpha = 1.- 0.682689492;
9113 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9114
9116 Int_t n = int(c);
9117 if (n < 0) {
9118 Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
9119 ((TH1*)this)->fBinStatErrOpt = kNormal;
9120 return GetBinError(bin);
9121 }
9122
9123 if (n == 0) return 0;
9124 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
9125}
9126
9127////////////////////////////////////////////////////////////////////////////////
9128/// Return upper error associated to bin number bin.
9129///
9130/// The error will depend on the statistic option used will return
9131/// the binContent - upper interval value
9132
9134{
9135 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9136 // in case of weighted histogram check if it is really weighted
9137 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9138 if (bin < 0) bin = 0;
9139 if (bin >= fNcells) bin = fNcells-1;
9140 if (fBuffer) ((TH1*)this)->BufferEmpty();
9141
9142 Double_t alpha = 1.- 0.682689492;
9143 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9144
9146 Int_t n = int(c);
9147 if (n < 0) {
9148 Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
9149 ((TH1*)this)->fBinStatErrOpt = kNormal;
9150 return GetBinError(bin);
9151 }
9152
9153 // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
9154 // decide to return always (1-alpha)/2 upper interval
9155 //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
9156 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
9157}
9158
9159//L.M. These following getters are useless and should be probably deprecated
9160////////////////////////////////////////////////////////////////////////////////
9161/// Return bin center for 1D histogram.
9162/// Better to use h1.GetXaxis()->GetBinCenter(bin)
9163
9165{
9166 if (fDimension == 1) return fXaxis.GetBinCenter(bin);
9167 Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
9168 return TMath::QuietNaN();
9169}
9170
9171////////////////////////////////////////////////////////////////////////////////
9172/// Return bin lower edge for 1D histogram.
9173/// Better to use h1.GetXaxis()->GetBinLowEdge(bin)
9174
9176{
9177 if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
9178 Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
9179 return TMath::QuietNaN();
9180}
9181
9182////////////////////////////////////////////////////////////////////////////////
9183/// Return bin width for 1D histogram.
9184/// Better to use h1.GetXaxis()->GetBinWidth(bin)
9185
9187{
9188 if (fDimension == 1) return fXaxis.GetBinWidth(bin);
9189 Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
9190 return TMath::QuietNaN();
9191}
9192
9193////////////////////////////////////////////////////////////////////////////////
9194/// Fill array with center of bins for 1D histogram
9195/// Better to use h1.GetXaxis()->GetCenter(center)
9196
9197void TH1::GetCenter(Double_t *center) const
9198{
9199 if (fDimension == 1) {
9200 fXaxis.GetCenter(center);
9201 return;
9202 }
9203 Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
9204}
9205
9206////////////////////////////////////////////////////////////////////////////////
9207/// Fill array with low edge of bins for 1D histogram
9208/// Better to use h1.GetXaxis()->GetLowEdge(edge)
9209
9210void TH1::GetLowEdge(Double_t *edge) const
9211{
9212 if (fDimension == 1) {
9213 fXaxis.GetLowEdge(edge);
9214 return;
9215 }
9216 Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
9217}
9218
9219////////////////////////////////////////////////////////////////////////////////
9220/// Set the bin Error
9221/// Note that this resets the bin eror option to be of Normal Type and for the
9222/// non-empty bin the bin error is set by default to the square root of their content.
9223/// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
9224/// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
9225/// will not be recalculated after setting the content and a default error = 0 will be used for those bins.
9226///
9227/// See convention for numbering bins in TH1::GetBin
9228
9229void TH1::SetBinError(Int_t bin, Double_t error)
9230{
9231 if (bin < 0 || bin>= fNcells) return;
9232 if (!fSumw2.fN) Sumw2();
9233 fSumw2.fArray[bin] = error * error;
9234 // reset the bin error option
9236}
9237
9238////////////////////////////////////////////////////////////////////////////////
9239/// Set bin content
9240/// see convention for numbering bins in TH1::GetBin
9241/// In case the bin number is greater than the number of bins and
9242/// the timedisplay option is set or CanExtendAllAxes(),
9243/// the number of bins is automatically doubled to accommodate the new bin
9244
9245void TH1::SetBinContent(Int_t bin, Double_t content)
9246{
9247 fEntries++;
9248 fTsumw = 0;
9249 if (bin < 0) return;
9250 if (bin >= fNcells-1) {
9252 while (bin >= fNcells-1) LabelsInflate();
9253 } else {
9254 if (bin == fNcells-1) UpdateBinContent(bin, content);
9255 return;
9256 }
9257 }
9258 UpdateBinContent(bin, content);
9259}
9260
9261////////////////////////////////////////////////////////////////////////////////
9262/// See convention for numbering bins in TH1::GetBin
9263
9264void TH1::SetBinError(Int_t binx, Int_t biny, Double_t error)
9265{
9266 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9267 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9268 SetBinError(GetBin(binx, biny), error);
9269}
9270
9271////////////////////////////////////////////////////////////////////////////////
9272/// See convention for numbering bins in TH1::GetBin
9273
9274void TH1::SetBinError(Int_t binx, Int_t biny, Int_t binz, Double_t error)
9275{
9276 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9277 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9278 if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
9279 SetBinError(GetBin(binx, biny, binz), error);
9280}
9281
9282////////////////////////////////////////////////////////////////////////////////
9283/// This function calculates the background spectrum in this histogram.
9284/// The background is returned as a histogram.
9285///
9286/// \param[in] niter number of iterations (default value = 2)
9287/// Increasing niter make the result smoother and lower.
9288/// \param[in] option may contain one of the following options
9289/// - to set the direction parameter
9290/// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
9291/// - filterOrder-order of clipping filter (default "BackOrder2")
9292/// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
9293/// - "nosmoothing" - if selected, the background is not smoothed
9294/// By default the background is smoothed.
9295/// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
9296/// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
9297/// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
9298/// - "nocompton" - if selected the estimation of Compton edge
9299/// will be not be included (by default the compton estimation is set)
9300/// - "same" if this option is specified, the resulting background
9301/// histogram is superimposed on the picture in the current pad.
9302/// This option is given by default.
9303///
9304/// NOTE that the background is only evaluated in the current range of this histogram.
9305/// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
9306/// the returned histogram will be created with the same number of bins
9307/// as this input histogram, but only bins from binmin to binmax will be filled
9308/// with the estimated background.
9309
9311{
9312 return (TH1*)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticBackground((TH1*)0x%zx,%d,\"%s\")",
9313 (size_t)this, niter, option).Data());
9314}
9315
9316////////////////////////////////////////////////////////////////////////////////
9317/// Interface to TSpectrum::Search.
9318/// The function finds peaks in this histogram where the width is > sigma
9319/// and the peak maximum greater than threshold*maximum bin content of this.
9320/// For more details see TSpectrum::Search.
9321/// Note the difference in the default value for option compared to TSpectrum::Search
9322/// option="" by default (instead of "goff").
9323
9325{
9326 return (Int_t)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticSearch((TH1*)0x%zx,%g,\"%s\",%g)",
9327 (size_t)this, sigma, option, threshold).Data());
9328}
9329
9330////////////////////////////////////////////////////////////////////////////////
9331/// For a given transform (first parameter), fills the histogram (second parameter)
9332/// with the transform output data, specified in the third parameter
9333/// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
9334/// and the user is responsible for deleting it.
9335///
9336/// Available options:
9337/// - "RE" - real part of the output
9338/// - "IM" - imaginary part of the output
9339/// - "MAG" - magnitude of the output
9340/// - "PH" - phase of the output
9341
9343{
9344 if (!fft || !fft->GetN() ) {
9345 ::Error("TransformHisto","Invalid FFT transform class");
9346 return nullptr;
9347 }
9348
9349 if (fft->GetNdim()>2){
9350 ::Error("TransformHisto","Only 1d and 2D transform are supported");
9351 return nullptr;
9352 }
9353 Int_t binx,biny;
9354 TString opt = option;
9355 opt.ToUpper();
9356 Int_t *n = fft->GetN();
9357 TH1 *hout=nullptr;
9358 if (h_output) {
9359 hout = h_output;
9360 }
9361 else {
9362 TString name = TString::Format("out_%s", opt.Data());
9363 if (fft->GetNdim()==1)
9364 hout = new TH1D(name, name,n[0], 0, n[0]);
9365 else if (fft->GetNdim()==2)
9366 hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
9367 }
9368 R__ASSERT(hout != nullptr);
9369 TString type=fft->GetType();
9370 Int_t ind[2];
9371 if (opt.Contains("RE")){
9372 if (type.Contains("2C") || type.Contains("2HC")) {
9373 Double_t re, im;
9374 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9375 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9376 ind[0] = binx-1; ind[1] = biny-1;
9377 fft->GetPointComplex(ind, re, im);
9378 hout->SetBinContent(binx, biny, re);
9379 }
9380 }
9381 } else {
9382 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9383 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9384 ind[0] = binx-1; ind[1] = biny-1;
9385 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
9386 }
9387 }
9388 }
9389 }
9390 if (opt.Contains("IM")) {
9391 if (type.Contains("2C") || type.Contains("2HC")) {
9392 Double_t re, im;
9393 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9394 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9395 ind[0] = binx-1; ind[1] = biny-1;
9396 fft->GetPointComplex(ind, re, im);
9397 hout->SetBinContent(binx, biny, im);
9398 }
9399 }
9400 } else {
9401 ::Error("TransformHisto","No complex numbers in the output");
9402 return nullptr;
9403 }
9404 }
9405 if (opt.Contains("MA")) {
9406 if (type.Contains("2C") || type.Contains("2HC")) {
9407 Double_t re, im;
9408 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9409 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9410 ind[0] = binx-1; ind[1] = biny-1;
9411 fft->GetPointComplex(ind, re, im);
9412 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
9413 }
9414 }
9415 } else {
9416 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9417 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9418 ind[0] = binx-1; ind[1] = biny-1;
9419 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
9420 }
9421 }
9422 }
9423 }
9424 if (opt.Contains("PH")) {
9425 if (type.Contains("2C") || type.Contains("2HC")){
9426 Double_t re, im, ph;
9427 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
9428 for (biny=1; biny<=hout->GetNbinsY(); biny++){
9429 ind[0] = binx-1; ind[1] = biny-1;
9430 fft->GetPointComplex(ind, re, im);
9431 if (TMath::Abs(re) > 1e-13){
9432 ph = TMath::ATan(im/re);
9433 //find the correct quadrant
9434 if (re<0 && im<0)
9435 ph -= TMath::Pi();
9436 if (re<0 && im>=0)
9437 ph += TMath::Pi();
9438 } else {
9439 if (TMath::Abs(im) < 1e-13)
9440 ph = 0;
9441 else if (im>0)
9442 ph = TMath::Pi()*0.5;
9443 else
9444 ph = -TMath::Pi()*0.5;
9445 }
9446 hout->SetBinContent(binx, biny, ph);
9447 }
9448 }
9449 } else {
9450 printf("Pure real output, no phase");
9451 return nullptr;
9452 }
9453 }
9454
9455 return hout;
9456}
9457
9458////////////////////////////////////////////////////////////////////////////////
9459/// Raw retrieval of bin content on internal data structure
9460/// see convention for numbering bins in TH1::GetBin
9461
9463{
9464 AbstractMethod("RetrieveBinContent");
9465 return 0;
9466}
9467
9468////////////////////////////////////////////////////////////////////////////////
9469/// Raw update of bin content on internal data structure
9470/// see convention for numbering bins in TH1::GetBin
9471
9473{
9474 AbstractMethod("UpdateBinContent");
9475}
9476
9477////////////////////////////////////////////////////////////////////////////////
9478/// Print value overload
9479
9480std::string cling::printValue(TH1 *val) {
9481 std::ostringstream strm;
9482 strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
9483 return strm.str();
9484}
9485
9486//______________________________________________________________________________
9487// TH1C methods
9488// TH1C : histograms with one byte per channel. Maximum bin content = 127
9489//______________________________________________________________________________
9490
9491ClassImp(TH1C);
9492
9493////////////////////////////////////////////////////////////////////////////////
9494/// Constructor.
9495
9496TH1C::TH1C()
9497{
9498 fDimension = 1;
9499 SetBinsLength(3);
9500 if (fgDefaultSumw2) Sumw2();
9501}
9502
9503////////////////////////////////////////////////////////////////////////////////
9504/// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
9505/// (see TH1::TH1 for explanation of parameters)
9506
9507TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9508: TH1(name,title,nbins,xlow,xup)
9509{
9510 fDimension = 1;
9512
9513 if (xlow >= xup) SetBuffer(fgBufferSize);
9514 if (fgDefaultSumw2) Sumw2();
9515}
9516
9517////////////////////////////////////////////////////////////////////////////////
9518/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9519/// (see TH1::TH1 for explanation of parameters)
9520
9521TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9522: TH1(name,title,nbins,xbins)
9523{
9524 fDimension = 1;
9526 if (fgDefaultSumw2) Sumw2();
9527}
9528
9529////////////////////////////////////////////////////////////////////////////////
9530/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9531/// (see TH1::TH1 for explanation of parameters)
9532
9533TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9534: TH1(name,title,nbins,xbins)
9535{
9536 fDimension = 1;
9538 if (fgDefaultSumw2) Sumw2();
9539}
9540
9541////////////////////////////////////////////////////////////////////////////////
9542/// Destructor.
9543
9545{
9546}
9547
9548////////////////////////////////////////////////////////////////////////////////
9549/// Copy constructor.
9550/// The list of functions is not copied. (Use Clone() if needed)
9551
9552TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
9553{
9554 h1c.TH1C::Copy(*this);
9555}
9556
9557////////////////////////////////////////////////////////////////////////////////
9558/// Increment bin content by 1.
9559/// Passing an out-of-range bin leads to undefined behavior
9560
9561void TH1C::AddBinContent(Int_t bin)
9562{
9563 if (fArray[bin] < 127) fArray[bin]++;
9564}
9565
9566////////////////////////////////////////////////////////////////////////////////
9567/// Increment bin content by w.
9568/// \warning The value of w is cast to `Int_t` before being added.
9569/// Passing an out-of-range bin leads to undefined behavior
9570
9572{
9573 Int_t newval = fArray[bin] + Int_t(w);
9574 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
9575 if (newval < -127) fArray[bin] = -127;
9576 if (newval > 127) fArray[bin] = 127;
9577}
9578
9579////////////////////////////////////////////////////////////////////////////////
9580/// Copy this to newth1
9581
9582void TH1C::Copy(TObject &newth1) const
9583{
9584 TH1::Copy(newth1);
9585}
9586
9587////////////////////////////////////////////////////////////////////////////////
9588/// Reset.
9589
9591{
9594}
9595
9596////////////////////////////////////////////////////////////////////////////////
9597/// Set total number of bins including under/overflow
9598/// Reallocate bin contents array
9599
9601{
9602 if (n < 0) n = fXaxis.GetNbins() + 2;
9603 fNcells = n;
9604 TArrayC::Set(n);
9605}
9606
9607////////////////////////////////////////////////////////////////////////////////
9608/// Operator =
9609
9610TH1C& TH1C::operator=(const TH1C &h1)
9611{
9612 if (this != &h1)
9613 h1.TH1C::Copy(*this);
9614 return *this;
9615}
9616
9617////////////////////////////////////////////////////////////////////////////////
9618/// Operator *
9619
9621{
9622 TH1C hnew = h1;
9623 hnew.Scale(c1);
9624 hnew.SetDirectory(nullptr);
9625 return hnew;
9626}
9627
9628////////////////////////////////////////////////////////////////////////////////
9629/// Operator +
9630
9631TH1C operator+(const TH1C &h1, const TH1C &h2)
9632{
9633 TH1C hnew = h1;
9634 hnew.Add(&h2,1);
9635 hnew.SetDirectory(nullptr);
9636 return hnew;
9637}
9638
9639////////////////////////////////////////////////////////////////////////////////
9640/// Operator -
9641
9642TH1C operator-(const TH1C &h1, const TH1C &h2)
9643{
9644 TH1C hnew = h1;
9645 hnew.Add(&h2,-1);
9646 hnew.SetDirectory(nullptr);
9647 return hnew;
9648}
9649
9650////////////////////////////////////////////////////////////////////////////////
9651/// Operator *
9652
9653TH1C operator*(const TH1C &h1, const TH1C &h2)
9654{
9655 TH1C hnew = h1;
9656 hnew.Multiply(&h2);
9657 hnew.SetDirectory(nullptr);
9658 return hnew;
9659}
9660
9661////////////////////////////////////////////////////////////////////////////////
9662/// Operator /
9663
9664TH1C operator/(const TH1C &h1, const TH1C &h2)
9665{
9666 TH1C hnew = h1;
9667 hnew.Divide(&h2);
9668 hnew.SetDirectory(nullptr);
9669 return hnew;
9670}
9671
9672//______________________________________________________________________________
9673// TH1S methods
9674// TH1S : histograms with one short per channel. Maximum bin content = 32767
9675//______________________________________________________________________________
9676
9677ClassImp(TH1S);
9678
9679////////////////////////////////////////////////////////////////////////////////
9680/// Constructor.
9681
9682TH1S::TH1S()
9683{
9684 fDimension = 1;
9685 SetBinsLength(3);
9686 if (fgDefaultSumw2) Sumw2();
9687}
9688
9689////////////////////////////////////////////////////////////////////////////////
9690/// Create a 1-Dim histogram with fix bins of type short
9691/// (see TH1::TH1 for explanation of parameters)
9692
9693TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9694: TH1(name,title,nbins,xlow,xup)
9695{
9696 fDimension = 1;
9698
9699 if (xlow >= xup) SetBuffer(fgBufferSize);
9700 if (fgDefaultSumw2) Sumw2();
9701}
9702
9703////////////////////////////////////////////////////////////////////////////////
9704/// Create a 1-Dim histogram with variable bins of type short
9705/// (see TH1::TH1 for explanation of parameters)
9706
9707TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9708: TH1(name,title,nbins,xbins)
9709{
9710 fDimension = 1;
9712 if (fgDefaultSumw2) Sumw2();
9713}
9714
9715////////////////////////////////////////////////////////////////////////////////
9716/// Create a 1-Dim histogram with variable bins of type short
9717/// (see TH1::TH1 for explanation of parameters)
9718
9719TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9720: TH1(name,title,nbins,xbins)
9721{
9722 fDimension = 1;
9724 if (fgDefaultSumw2) Sumw2();
9725}
9726
9727////////////////////////////////////////////////////////////////////////////////
9728/// Destructor.
9729
9731{
9732}
9733
9734////////////////////////////////////////////////////////////////////////////////
9735/// Copy constructor.
9736/// The list of functions is not copied. (Use Clone() if needed)
9737
9738TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9739{
9740 h1s.TH1S::Copy(*this);
9741}
9742
9743////////////////////////////////////////////////////////////////////////////////
9744/// Increment bin content by 1.
9745/// Passing an out-of-range bin leads to undefined behavior
9746
9747void TH1S::AddBinContent(Int_t bin)
9748{
9749 if (fArray[bin] < 32767) fArray[bin]++;
9750}
9751
9752////////////////////////////////////////////////////////////////////////////////
9753/// Increment bin content by w.
9754/// \warning The value of w is cast to `Int_t` before being added.
9755/// Passing an out-of-range bin leads to undefined behavior
9756
9758{
9759 Int_t newval = fArray[bin] + Int_t(w);
9760 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9761 if (newval < -32767) fArray[bin] = -32767;
9762 if (newval > 32767) fArray[bin] = 32767;
9763}
9764
9765////////////////////////////////////////////////////////////////////////////////
9766/// Copy this to newth1
9767
9768void TH1S::Copy(TObject &newth1) const
9769{
9770 TH1::Copy(newth1);
9771}
9772
9773////////////////////////////////////////////////////////////////////////////////
9774/// Reset.
9775
9777{
9780}
9781
9782////////////////////////////////////////////////////////////////////////////////
9783/// Set total number of bins including under/overflow
9784/// Reallocate bin contents array
9785
9787{
9788 if (n < 0) n = fXaxis.GetNbins() + 2;
9789 fNcells = n;
9790 TArrayS::Set(n);
9791}
9792
9793////////////////////////////////////////////////////////////////////////////////
9794/// Operator =
9795
9796TH1S& TH1S::operator=(const TH1S &h1)
9797{
9798 if (this != &h1)
9799 h1.TH1S::Copy(*this);
9800 return *this;
9801}
9802
9803////////////////////////////////////////////////////////////////////////////////
9804/// Operator *
9805
9807{
9808 TH1S hnew = h1;
9809 hnew.Scale(c1);
9810 hnew.SetDirectory(nullptr);
9811 return hnew;
9812}
9813
9814////////////////////////////////////////////////////////////////////////////////
9815/// Operator +
9816
9817TH1S operator+(const TH1S &h1, const TH1S &h2)
9818{
9819 TH1S hnew = h1;
9820 hnew.Add(&h2,1);
9821 hnew.SetDirectory(nullptr);
9822 return hnew;
9823}
9824
9825////////////////////////////////////////////////////////////////////////////////
9826/// Operator -
9827
9828TH1S operator-(const TH1S &h1, const TH1S &h2)
9829{
9830 TH1S hnew = h1;
9831 hnew.Add(&h2,-1);
9832 hnew.SetDirectory(nullptr);
9833 return hnew;
9834}
9835
9836////////////////////////////////////////////////////////////////////////////////
9837/// Operator *
9838
9839TH1S operator*(const TH1S &h1, const TH1S &h2)
9840{
9841 TH1S hnew = h1;
9842 hnew.Multiply(&h2);
9843 hnew.SetDirectory(nullptr);
9844 return hnew;
9845}
9846
9847////////////////////////////////////////////////////////////////////////////////
9848/// Operator /
9849
9850TH1S operator/(const TH1S &h1, const TH1S &h2)
9851{
9852 TH1S hnew = h1;
9853 hnew.Divide(&h2);
9854 hnew.SetDirectory(nullptr);
9855 return hnew;
9856}
9857
9858//______________________________________________________________________________
9859// TH1I methods
9860// TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9861// 2147483647 = INT_MAX
9862//______________________________________________________________________________
9863
9864ClassImp(TH1I);
9865
9866////////////////////////////////////////////////////////////////////////////////
9867/// Constructor.
9868
9869TH1I::TH1I()
9870{
9871 fDimension = 1;
9872 SetBinsLength(3);
9873 if (fgDefaultSumw2) Sumw2();
9874}
9875
9876////////////////////////////////////////////////////////////////////////////////
9877/// Create a 1-Dim histogram with fix bins of type integer
9878/// (see TH1::TH1 for explanation of parameters)
9879
9880TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9881: TH1(name,title,nbins,xlow,xup)
9882{
9883 fDimension = 1;
9885
9886 if (xlow >= xup) SetBuffer(fgBufferSize);
9887 if (fgDefaultSumw2) Sumw2();
9888}
9889
9890////////////////////////////////////////////////////////////////////////////////
9891/// Create a 1-Dim histogram with variable bins of type integer
9892/// (see TH1::TH1 for explanation of parameters)
9893
9894TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9895: TH1(name,title,nbins,xbins)
9896{
9897 fDimension = 1;
9899 if (fgDefaultSumw2) Sumw2();
9900}
9901
9902////////////////////////////////////////////////////////////////////////////////
9903/// Create a 1-Dim histogram with variable bins of type integer
9904/// (see TH1::TH1 for explanation of parameters)
9905
9906TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9907: TH1(name,title,nbins,xbins)
9908{
9909 fDimension = 1;
9911 if (fgDefaultSumw2) Sumw2();
9912}
9913
9914////////////////////////////////////////////////////////////////////////////////
9915/// Destructor.
9916
9918{
9919}
9920
9921////////////////////////////////////////////////////////////////////////////////
9922/// Copy constructor.
9923/// The list of functions is not copied. (Use Clone() if needed)
9924
9925TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
9926{
9927 h1i.TH1I::Copy(*this);
9928}
9929
9930////////////////////////////////////////////////////////////////////////////////
9931/// Increment bin content by 1.
9932/// Passing an out-of-range bin leads to undefined behavior
9933
9934void TH1I::AddBinContent(Int_t bin)
9935{
9936 if (fArray[bin] < INT_MAX) fArray[bin]++;
9937}
9938
9939////////////////////////////////////////////////////////////////////////////////
9940/// Increment bin content by w
9941/// \warning The value of w is cast to `Long64_t` before being added.
9942/// Passing an out-of-range bin leads to undefined behavior
9943
9945{
9946 Long64_t newval = fArray[bin] + Long64_t(w);
9947 if (newval > -INT_MAX && newval < INT_MAX) {fArray[bin] = Int_t(newval); return;}
9948 if (newval < -INT_MAX) fArray[bin] = -INT_MAX;
9949 if (newval > INT_MAX) fArray[bin] = INT_MAX;
9950}
9951
9952////////////////////////////////////////////////////////////////////////////////
9953/// Copy this to newth1
9954
9955void TH1I::Copy(TObject &newth1) const
9956{
9957 TH1::Copy(newth1);
9958}
9959
9960////////////////////////////////////////////////////////////////////////////////
9961/// Reset.
9962
9964{
9967}
9968
9969////////////////////////////////////////////////////////////////////////////////
9970/// Set total number of bins including under/overflow
9971/// Reallocate bin contents array
9972
9974{
9975 if (n < 0) n = fXaxis.GetNbins() + 2;
9976 fNcells = n;
9977 TArrayI::Set(n);
9978}
9979
9980////////////////////////////////////////////////////////////////////////////////
9981/// Operator =
9982
9983TH1I& TH1I::operator=(const TH1I &h1)
9984{
9985 if (this != &h1)
9986 h1.TH1I::Copy(*this);
9987 return *this;
9988}
9989
9990
9991////////////////////////////////////////////////////////////////////////////////
9992/// Operator *
9993
9995{
9996 TH1I hnew = h1;
9997 hnew.Scale(c1);
9998 hnew.SetDirectory(nullptr);
9999 return hnew;
10000}
10001
10002////////////////////////////////////////////////////////////////////////////////
10003/// Operator +
10004
10005TH1I operator+(const TH1I &h1, const TH1I &h2)
10006{
10007 TH1I hnew = h1;
10008 hnew.Add(&h2,1);
10009 hnew.SetDirectory(nullptr);
10010 return hnew;
10011}
10012
10013////////////////////////////////////////////////////////////////////////////////
10014/// Operator -
10015
10016TH1I operator-(const TH1I &h1, const TH1I &h2)
10017{
10018 TH1I hnew = h1;
10019 hnew.Add(&h2,-1);
10020 hnew.SetDirectory(nullptr);
10021 return hnew;
10022}
10023
10024////////////////////////////////////////////////////////////////////////////////
10025/// Operator *
10026
10027TH1I operator*(const TH1I &h1, const TH1I &h2)
10028{
10029 TH1I hnew = h1;
10030 hnew.Multiply(&h2);
10031 hnew.SetDirectory(nullptr);
10032 return hnew;
10033}
10034
10035////////////////////////////////////////////////////////////////////////////////
10036/// Operator /
10037
10038TH1I operator/(const TH1I &h1, const TH1I &h2)
10039{
10040 TH1I hnew = h1;
10041 hnew.Divide(&h2);
10042 hnew.SetDirectory(nullptr);
10043 return hnew;
10044}
10045
10046//______________________________________________________________________________
10047// TH1L methods
10048// TH1L : histograms with one long64 per channel. Maximum bin content = 9223372036854775807
10049// 9223372036854775807 = LLONG_MAX
10050//______________________________________________________________________________
10051
10052ClassImp(TH1L);
10053
10054////////////////////////////////////////////////////////////////////////////////
10055/// Constructor.
10056
10057TH1L::TH1L()
10058{
10059 fDimension = 1;
10060 SetBinsLength(3);
10061 if (fgDefaultSumw2) Sumw2();
10062}
10063
10064////////////////////////////////////////////////////////////////////////////////
10065/// Create a 1-Dim histogram with fix bins of type long64
10066/// (see TH1::TH1 for explanation of parameters)
10067
10068TH1L::TH1L(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10069: TH1(name,title,nbins,xlow,xup)
10070{
10071 fDimension = 1;
10073
10074 if (xlow >= xup) SetBuffer(fgBufferSize);
10075 if (fgDefaultSumw2) Sumw2();
10076}
10077
10078////////////////////////////////////////////////////////////////////////////////
10079/// Create a 1-Dim histogram with variable bins of type long64
10080/// (see TH1::TH1 for explanation of parameters)
10081
10082TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10083: TH1(name,title,nbins,xbins)
10084{
10085 fDimension = 1;
10087 if (fgDefaultSumw2) Sumw2();
10088}
10089
10090////////////////////////////////////////////////////////////////////////////////
10091/// Create a 1-Dim histogram with variable bins of type long64
10092/// (see TH1::TH1 for explanation of parameters)
10093
10094TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10095: TH1(name,title,nbins,xbins)
10096{
10097 fDimension = 1;
10099 if (fgDefaultSumw2) Sumw2();
10100}
10101
10102////////////////////////////////////////////////////////////////////////////////
10103/// Destructor.
10104
10106{
10107}
10108
10109////////////////////////////////////////////////////////////////////////////////
10110/// Copy constructor.
10111/// The list of functions is not copied. (Use Clone() if needed)
10112
10113TH1L::TH1L(const TH1L &h1l) : TH1(), TArrayL64()
10114{
10115 h1l.TH1L::Copy(*this);
10116}
10117
10118////////////////////////////////////////////////////////////////////////////////
10119/// Increment bin content by 1.
10120/// Passing an out-of-range bin leads to undefined behavior
10121
10122void TH1L::AddBinContent(Int_t bin)
10123{
10124 if (fArray[bin] < LLONG_MAX) fArray[bin]++;
10125}
10126
10127////////////////////////////////////////////////////////////////////////////////
10128/// Increment bin content by w.
10129/// \warning The value of w is cast to `Long64_t` before being added.
10130/// Passing an out-of-range bin leads to undefined behavior
10131
10133{
10134 Long64_t newval = fArray[bin] + Long64_t(w);
10135 if (newval > -LLONG_MAX && newval < LLONG_MAX) {fArray[bin] = newval; return;}
10136 if (newval < -LLONG_MAX) fArray[bin] = -LLONG_MAX;
10137 if (newval > LLONG_MAX) fArray[bin] = LLONG_MAX;
10138}
10139
10140////////////////////////////////////////////////////////////////////////////////
10141/// Copy this to newth1
10142
10143void TH1L::Copy(TObject &newth1) const
10144{
10145 TH1::Copy(newth1);
10146}
10147
10148////////////////////////////////////////////////////////////////////////////////
10149/// Reset.
10150
10152{
10155}
10156
10157////////////////////////////////////////////////////////////////////////////////
10158/// Set total number of bins including under/overflow
10159/// Reallocate bin contents array
10160
10162{
10163 if (n < 0) n = fXaxis.GetNbins() + 2;
10164 fNcells = n;
10166}
10167
10168////////////////////////////////////////////////////////////////////////////////
10169/// Operator =
10170
10171TH1L& TH1L::operator=(const TH1L &h1)
10172{
10173 if (this != &h1)
10174 h1.TH1L::Copy(*this);
10175 return *this;
10176}
10177
10178
10179////////////////////////////////////////////////////////////////////////////////
10180/// Operator *
10181
10183{
10184 TH1L hnew = h1;
10185 hnew.Scale(c1);
10186 hnew.SetDirectory(nullptr);
10187 return hnew;
10188}
10189
10190////////////////////////////////////////////////////////////////////////////////
10191/// Operator +
10192
10193TH1L operator+(const TH1L &h1, const TH1L &h2)
10194{
10195 TH1L hnew = h1;
10196 hnew.Add(&h2,1);
10197 hnew.SetDirectory(nullptr);
10198 return hnew;
10199}
10200
10201////////////////////////////////////////////////////////////////////////////////
10202/// Operator -
10203
10204TH1L operator-(const TH1L &h1, const TH1L &h2)
10205{
10206 TH1L hnew = h1;
10207 hnew.Add(&h2,-1);
10208 hnew.SetDirectory(nullptr);
10209 return hnew;
10210}
10211
10212////////////////////////////////////////////////////////////////////////////////
10213/// Operator *
10214
10215TH1L operator*(const TH1L &h1, const TH1L &h2)
10216{
10217 TH1L hnew = h1;
10218 hnew.Multiply(&h2);
10219 hnew.SetDirectory(nullptr);
10220 return hnew;
10221}
10222
10223////////////////////////////////////////////////////////////////////////////////
10224/// Operator /
10225
10226TH1L operator/(const TH1L &h1, const TH1L &h2)
10227{
10228 TH1L hnew = h1;
10229 hnew.Divide(&h2);
10230 hnew.SetDirectory(nullptr);
10231 return hnew;
10232}
10233
10234//______________________________________________________________________________
10235// TH1F methods
10236// TH1F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216
10237//______________________________________________________________________________
10238
10239ClassImp(TH1F);
10240
10241////////////////////////////////////////////////////////////////////////////////
10242/// Constructor.
10243
10244TH1F::TH1F()
10245{
10246 fDimension = 1;
10247 SetBinsLength(3);
10248 if (fgDefaultSumw2) Sumw2();
10249}
10250
10251////////////////////////////////////////////////////////////////////////////////
10252/// Create a 1-Dim histogram with fix bins of type float
10253/// (see TH1::TH1 for explanation of parameters)
10254
10255TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10256: TH1(name,title,nbins,xlow,xup)
10257{
10258 fDimension = 1;
10260
10261 if (xlow >= xup) SetBuffer(fgBufferSize);
10262 if (fgDefaultSumw2) Sumw2();
10263}
10264
10265////////////////////////////////////////////////////////////////////////////////
10266/// Create a 1-Dim histogram with variable bins of type float
10267/// (see TH1::TH1 for explanation of parameters)
10268
10269TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10270: TH1(name,title,nbins,xbins)
10271{
10272 fDimension = 1;
10274 if (fgDefaultSumw2) Sumw2();
10275}
10276
10277////////////////////////////////////////////////////////////////////////////////
10278/// Create a 1-Dim histogram with variable bins of type float
10279/// (see TH1::TH1 for explanation of parameters)
10280
10281TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10282: TH1(name,title,nbins,xbins)
10283{
10284 fDimension = 1;
10286 if (fgDefaultSumw2) Sumw2();
10287}
10288
10289////////////////////////////////////////////////////////////////////////////////
10290/// Create a histogram from a TVectorF
10291/// by default the histogram name is "TVectorF" and title = ""
10292
10293TH1F::TH1F(const TVectorF &v)
10294: TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
10295{
10297 fDimension = 1;
10298 Int_t ivlow = v.GetLwb();
10299 for (Int_t i=0;i<fNcells-2;i++) {
10300 SetBinContent(i+1,v(i+ivlow));
10301 }
10303 if (fgDefaultSumw2) Sumw2();
10304}
10305
10306////////////////////////////////////////////////////////////////////////////////
10307/// Copy Constructor.
10308/// The list of functions is not copied. (Use Clone() if needed)
10309
10310TH1F::TH1F(const TH1F &h1f) : TH1(), TArrayF()
10311{
10312 h1f.TH1F::Copy(*this);
10313}
10314
10315////////////////////////////////////////////////////////////////////////////////
10316/// Destructor.
10317
10319{
10320}
10321
10322////////////////////////////////////////////////////////////////////////////////
10323/// Copy this to newth1.
10324
10325void TH1F::Copy(TObject &newth1) const
10326{
10327 TH1::Copy(newth1);
10328}
10329
10330////////////////////////////////////////////////////////////////////////////////
10331/// Reset.
10332
10334{
10337}
10338
10339////////////////////////////////////////////////////////////////////////////////
10340/// Set total number of bins including under/overflow
10341/// Reallocate bin contents array
10342
10344{
10345 if (n < 0) n = fXaxis.GetNbins() + 2;
10346 fNcells = n;
10347 TArrayF::Set(n);
10348}
10349
10350////////////////////////////////////////////////////////////////////////////////
10351/// Operator =
10352
10353TH1F& TH1F::operator=(const TH1F &h1f)
10354{
10355 if (this != &h1f)
10356 h1f.TH1F::Copy(*this);
10357 return *this;
10358}
10359
10360////////////////////////////////////////////////////////////////////////////////
10361/// Operator *
10362
10364{
10365 TH1F hnew = h1;
10366 hnew.Scale(c1);
10367 hnew.SetDirectory(nullptr);
10368 return hnew;
10369}
10370
10371////////////////////////////////////////////////////////////////////////////////
10372/// Operator +
10373
10374TH1F operator+(const TH1F &h1, const TH1F &h2)
10375{
10376 TH1F hnew = h1;
10377 hnew.Add(&h2,1);
10378 hnew.SetDirectory(nullptr);
10379 return hnew;
10380}
10381
10382////////////////////////////////////////////////////////////////////////////////
10383/// Operator -
10384
10385TH1F operator-(const TH1F &h1, const TH1F &h2)
10386{
10387 TH1F hnew = h1;
10388 hnew.Add(&h2,-1);
10389 hnew.SetDirectory(nullptr);
10390 return hnew;
10391}
10392
10393////////////////////////////////////////////////////////////////////////////////
10394/// Operator *
10395
10396TH1F operator*(const TH1F &h1, const TH1F &h2)
10397{
10398 TH1F hnew = h1;
10399 hnew.Multiply(&h2);
10400 hnew.SetDirectory(nullptr);
10401 return hnew;
10402}
10403
10404////////////////////////////////////////////////////////////////////////////////
10405/// Operator /
10406
10407TH1F operator/(const TH1F &h1, const TH1F &h2)
10408{
10409 TH1F hnew = h1;
10410 hnew.Divide(&h2);
10411 hnew.SetDirectory(nullptr);
10412 return hnew;
10413}
10414
10415//______________________________________________________________________________
10416// TH1D methods
10417// TH1D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992
10418//______________________________________________________________________________
10419
10420ClassImp(TH1D);
10421
10422////////////////////////////////////////////////////////////////////////////////
10423/// Constructor.
10424
10425TH1D::TH1D()
10426{
10427 fDimension = 1;
10428 SetBinsLength(3);
10429 if (fgDefaultSumw2) Sumw2();
10430}
10431
10432////////////////////////////////////////////////////////////////////////////////
10433/// Create a 1-Dim histogram with fix bins of type double
10434/// (see TH1::TH1 for explanation of parameters)
10435
10436TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10437: TH1(name,title,nbins,xlow,xup)
10438{
10439 fDimension = 1;
10441
10442 if (xlow >= xup) SetBuffer(fgBufferSize);
10443 if (fgDefaultSumw2) Sumw2();
10444}
10445
10446////////////////////////////////////////////////////////////////////////////////
10447/// Create a 1-Dim histogram with variable bins of type double
10448/// (see TH1::TH1 for explanation of parameters)
10449
10450TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10451: TH1(name,title,nbins,xbins)
10452{
10453 fDimension = 1;
10455 if (fgDefaultSumw2) Sumw2();
10456}
10457
10458////////////////////////////////////////////////////////////////////////////////
10459/// Create a 1-Dim histogram with variable bins of type double
10460/// (see TH1::TH1 for explanation of parameters)
10461
10462TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10463: TH1(name,title,nbins,xbins)
10464{
10465 fDimension = 1;
10467 if (fgDefaultSumw2) Sumw2();
10468}
10469
10470////////////////////////////////////////////////////////////////////////////////
10471/// Create a histogram from a TVectorD
10472/// by default the histogram name is "TVectorD" and title = ""
10473
10474TH1D::TH1D(const TVectorD &v)
10475: TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
10476{
10478 fDimension = 1;
10479 Int_t ivlow = v.GetLwb();
10480 for (Int_t i=0;i<fNcells-2;i++) {
10481 SetBinContent(i+1,v(i+ivlow));
10482 }
10484 if (fgDefaultSumw2) Sumw2();
10485}
10486
10487////////////////////////////////////////////////////////////////////////////////
10488/// Destructor.
10489
10491{
10492}
10493
10494////////////////////////////////////////////////////////////////////////////////
10495/// Constructor.
10496
10497TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
10498{
10499 // intentially call virtual method to warn if TProfile is copying
10500 h1d.Copy(*this);
10501}
10502
10503////////////////////////////////////////////////////////////////////////////////
10504/// Copy this to newth1
10505
10506void TH1D::Copy(TObject &newth1) const
10507{
10508 TH1::Copy(newth1);
10509}
10510
10511////////////////////////////////////////////////////////////////////////////////
10512/// Reset.
10513
10515{
10518}
10519
10520////////////////////////////////////////////////////////////////////////////////
10521/// Set total number of bins including under/overflow
10522/// Reallocate bin contents array
10523
10525{
10526 if (n < 0) n = fXaxis.GetNbins() + 2;
10527 fNcells = n;
10528 TArrayD::Set(n);
10529}
10530
10531////////////////////////////////////////////////////////////////////////////////
10532/// Operator =
10533
10534TH1D& TH1D::operator=(const TH1D &h1d)
10535{
10536 // intentially call virtual method to warn if TProfile is copying
10537 if (this != &h1d)
10538 h1d.Copy(*this);
10539 return *this;
10540}
10541
10542////////////////////////////////////////////////////////////////////////////////
10543/// Operator *
10544
10546{
10547 TH1D hnew = h1;
10548 hnew.Scale(c1);
10549 hnew.SetDirectory(nullptr);
10550 return hnew;
10551}
10552
10553////////////////////////////////////////////////////////////////////////////////
10554/// Operator +
10555
10556TH1D operator+(const TH1D &h1, const TH1D &h2)
10557{
10558 TH1D hnew = h1;
10559 hnew.Add(&h2,1);
10560 hnew.SetDirectory(nullptr);
10561 return hnew;
10562}
10563
10564////////////////////////////////////////////////////////////////////////////////
10565/// Operator -
10566
10567TH1D operator-(const TH1D &h1, const TH1D &h2)
10568{
10569 TH1D hnew = h1;
10570 hnew.Add(&h2,-1);
10571 hnew.SetDirectory(nullptr);
10572 return hnew;
10573}
10574
10575////////////////////////////////////////////////////////////////////////////////
10576/// Operator *
10577
10578TH1D operator*(const TH1D &h1, const TH1D &h2)
10579{
10580 TH1D hnew = h1;
10581 hnew.Multiply(&h2);
10582 hnew.SetDirectory(nullptr);
10583 return hnew;
10584}
10585
10586////////////////////////////////////////////////////////////////////////////////
10587/// Operator /
10588
10589TH1D operator/(const TH1D &h1, const TH1D &h2)
10590{
10591 TH1D hnew = h1;
10592 hnew.Divide(&h2);
10593 hnew.SetDirectory(nullptr);
10594 return hnew;
10595}
10596
10597////////////////////////////////////////////////////////////////////////////////
10598///return pointer to histogram with name
10599///hid if id >=0
10600///h_id if id <0
10601
10602TH1 *R__H(Int_t hid)
10603{
10604 TString hname;
10605 if(hid >= 0) hname.Form("h%d",hid);
10606 else hname.Form("h_%d",hid);
10607 return (TH1*)gDirectory->Get(hname);
10608}
10609
10610////////////////////////////////////////////////////////////////////////////////
10611///return pointer to histogram with name hname
10612
10613TH1 *R__H(const char * hname)
10614{
10615 return (TH1*)gDirectory->Get(hname);
10616}
10617
10618
10619/// \fn void TH1::SetBarOffset(Float_t offset)
10620/// Set the bar offset as fraction of the bin width for drawing mode "B".
10621/// This shifts bars to the right on the x axis, and helps to draw bars next to each other.
10622/// \see THistPainter, SetBarWidth()
10623
10624/// \fn void TH1::SetBarWidth(Float_t width)
10625/// Set the width of bars as fraction of the bin width for drawing mode "B".
10626/// This allows for making bars narrower than the bin width. With SetBarOffset(), this helps to draw multiple bars next to each other.
10627/// \see THistPainter, SetBarOffset()
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define s1(x)
Definition RSha256.hxx:91
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
short Style_t
Definition RtypesCore.h:82
bool Bool_t
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
short Color_t
Definition RtypesCore.h:85
short Version_t
Definition RtypesCore.h:65
char Char_t
Definition RtypesCore.h:37
float Float_t
Definition RtypesCore.h:57
short Short_t
Definition RtypesCore.h:39
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:69
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
const char Option_t
Definition RtypesCore.h:66
#define BIT(n)
Definition Rtypes.h:90
#define ClassImp(name)
Definition Rtypes.h:382
#define gDirectory
Definition TDirectory.h:384
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t SetLineWidth
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t SetFillStyle
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t del
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t SetLineColor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t SetFillColor
Option_t Option_t SetMarkerStyle
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char y1
char name[80]
Definition TGX11.cxx:110
static bool IsEquidistantBinning(const TAxis &axis)
Test if the binning is equidistant.
Definition TH1.cxx:5899
void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
Least square linear fit without weights.
Definition TH1.cxx:4847
void H1InitGaus()
Compute Initial values of parameters for a gaussian.
Definition TH1.cxx:4682
void H1InitExpo()
Compute Initial values of parameters for an exponential.
Definition TH1.cxx:4738
TH1C operator+(const TH1C &h1, const TH1C &h2)
Operator +.
Definition TH1.cxx:9629
TH1C operator-(const TH1C &h1, const TH1C &h2)
Operator -.
Definition TH1.cxx:9640
TH1C operator/(const TH1C &h1, const TH1C &h2)
Operator /.
Definition TH1.cxx:9662
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:4893
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:5882
static Bool_t AlmostInteger(Double_t a, Double_t epsilon=0.00000001)
Test if a double is almost an integer.
Definition TH1.cxx:5890
TF1 * gF1
Definition TH1.cxx:581
TH1 * R__H(Int_t hid)
return pointer to histogram with name hid if id >=0 h_id if id <0
Definition TH1.cxx:10600
TH1C operator*(Double_t c1, const TH1C &h1)
Operator *.
Definition TH1.cxx:9618
void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
Least squares lpolynomial fitting without weights.
Definition TH1.cxx:4788
void H1InitPolynom()
Compute Initial values of parameters for a polynom.
Definition TH1.cxx:4758
float xmin
int nentries
float ymin
float xmax
float ymax
#define gInterpreter
Int_t gDebug
Definition TROOT.cxx:597
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:406
R__EXTERN TRandom * gRandom
Definition TRandom.h:62
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2503
R__EXTERN TStyle * gStyle
Definition TStyle.h:436
#define R__LOCKGUARD(mutex)
#define gPad
#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:52
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition DataRange.h:35
void AndersonDarling2SamplesTest(Double_t &pvalue, Double_t &testStat) const
Performs the Anderson-Darling 2-Sample Test.
Definition GoFTest.cxx:646
Array of chars or bytes (8 bits per element).
Definition TArrayC.h:27
Char_t * fArray
Definition TArrayC.h:30
void Reset(Char_t val=0)
Definition TArrayC.h:47
void Set(Int_t n) override
Set size of this array to n chars.
Definition TArrayC.cxx:105
Array of doubles (64 bits per element).
Definition TArrayD.h:27
Double_t GetAt(Int_t i) const override
Definition TArrayD.h:45
Double_t * fArray
Definition TArrayD.h:30
void Streamer(TBuffer &) override
Stream a TArrayD object.
Definition TArrayD.cxx:149
void Copy(TArrayD &array) const
Definition TArrayD.h:42
void Set(Int_t n) override
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 Reset()
Definition TArrayF.h:47
void Set(Int_t n) override
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) override
Set size of this array to n ints.
Definition TArrayI.cxx:105
void Reset()
Definition TArrayI.h:47
Array of long64s (64 bits per element).
Definition TArrayL64.h:27
Long64_t * fArray
Definition TArrayL64.h:30
void Set(Int_t n) override
Set size of this array to n long64s.
void Reset()
Definition TArrayL64.h:47
Array of shorts (16 bits per element).
Definition TArrayS.h:27
void Set(Int_t n) override
Set size of this array to n shorts.
Definition TArrayS.cxx:105
void Reset()
Definition TArrayS.h:47
Short_t * fArray
Definition TArrayS.h:30
Abstract array base class.
Definition TArray.h:31
Int_t fN
Definition TArray.h:38
virtual void Set(Int_t n)=0
Int_t GetSize() const
Definition TArray.h:47
virtual Color_t GetTitleColor() const
Definition TAttAxis.h:46
virtual Color_t GetLabelColor() const
Definition TAttAxis.h:38
virtual Int_t GetNdivisions() const
Definition TAttAxis.h:36
virtual Color_t GetAxisColor() const
Definition TAttAxis.h:37
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition TAttAxis.cxx:298
virtual Style_t GetTitleFont() const
Definition TAttAxis.h:47
virtual Float_t GetLabelOffset() const
Definition TAttAxis.h:40
virtual void SetAxisColor(Color_t color=1, Float_t alpha=1.)
Set color of the line axis and tick marks.
Definition TAttAxis.cxx:160
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
Definition TAttAxis.cxx:203
virtual Style_t GetLabelFont() const
Definition TAttAxis.h:39
virtual void SetTitleFont(Style_t font=62)
Set the title font.
Definition TAttAxis.cxx:327
virtual void SetLabelOffset(Float_t offset=0.005)
Set distance between the axis and the labels.
Definition TAttAxis.cxx:191
virtual void SetLabelFont(Style_t font=62)
Set labels' font.
Definition TAttAxis.cxx:180
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title.
Definition TAttAxis.cxx:309
virtual void SetTitleColor(Color_t color=1)
Set color of axis title.
Definition TAttAxis.cxx:318
virtual Float_t GetTitleSize() const
Definition TAttAxis.h:44
virtual Float_t GetLabelSize() const
Definition TAttAxis.h:41
virtual Float_t GetTickLength() const
Definition TAttAxis.h:45
virtual void ResetAttAxis(Option_t *option="")
Reset axis attributes.
Definition TAttAxis.cxx:79
virtual Float_t GetTitleOffset() const
Definition TAttAxis.h:43
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length.
Definition TAttAxis.cxx:284
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition TAttAxis.cxx:233
virtual void SetLabelColor(Color_t color=1, Float_t alpha=1.)
Set color of labels.
Definition TAttAxis.cxx:170
virtual void Streamer(TBuffer &)
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:207
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:31
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:239
virtual void Streamer(TBuffer &)
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 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:177
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:275
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.
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.
virtual void Streamer(TBuffer &)
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition TAttMarker.h:45
Class to manage histogram axis.
Definition TAxis.h:31
virtual void GetCenter(Double_t *center) const
Return an array with the center of all bins.
Definition TAxis.cxx:553
virtual Bool_t GetTimeDisplay() const
Definition TAxis.h:131
Bool_t IsAlphanumeric() const
Definition TAxis.h:88
const char * GetTitle() const override
Returns title of object.
Definition TAxis.h:135
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:478
Bool_t CanExtend() const
Definition TAxis.h:86
virtual void SetParent(TObject *obj)
Definition TAxis.h:167
const TArrayD * GetXbins() const
Definition TAxis.h:136
void SetCanExtend(Bool_t canExtend)
Definition TAxis.h:90
void Copy(TObject &axis) const override
Copy axis structure to another axis.
Definition TAxis.cxx:216
Double_t GetXmax() const
Definition TAxis.h:140
@ kLabelsUp
Definition TAxis.h:74
@ kLabelsDown
Definition TAxis.h:73
@ kLabelsHori
Definition TAxis.h:71
@ kAxisRange
Definition TAxis.h:65
@ kLabelsVert
Definition TAxis.h:72
const char * GetBinLabel(Int_t bin) const
Return label for bin.
Definition TAxis.cxx:440
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:293
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:518
virtual void SetTimeDisplay(Int_t value)
Definition TAxis.h:171
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Definition TAxis.cxx:794
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:419
void SaveAttributes(std::ostream &out, const char *name, const char *subname) override
Save axis attributes as C++ statement(s) on output stream out.
Definition TAxis.cxx:710
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:469
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition TAxis.h:164
Double_t GetXmin() const
Definition TAxis.h:139
void Streamer(TBuffer &) override
Stream an object of class TAxis.
Definition TAxis.cxx:1216
Int_t GetNbins() const
Definition TAxis.h:125
virtual void GetLowEdge(Double_t *edge) const
Return an array with the low edge of all bins.
Definition TAxis.cxx:562
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis using bin numbers.
Definition TAxis.cxx:1052
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:540
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:528
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:458
THashList * GetLabels() const
Definition TAxis.h:121
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
Buffer base class used for serializing objects.
Definition TBuffer.h:43
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:5045
ROOT::NewFunc_t GetNew() const
Return the wrapper around new ThisClass().
Definition TClass.cxx:7514
Collection abstract base class.
Definition TCollection.h:65
virtual bool UseRWLock(Bool_t enable=true)
Set this collection to use a RW lock upon access, making it thread safe.
virtual void AddAll(const TCollection *col)
Add all objects from collection col to this collection.
virtual Bool_t IsEmpty() const
TObject * Clone(const char *newname="") const override
Make a clone of an collection using the Streamer facility.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Describe directory structure in memory.
Definition TDirectory.h:45
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
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:233
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:3683
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function Note that this histogram is managed ...
Definition TF1.cxx:1584
static TClass * Class()
virtual Int_t GetNpar() const
Definition TF1.h:509
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
IntegralOneDim or analytical integral.
Definition TF1.cxx:2531
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition TF1.cxx:2482
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2281
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=nullptr)
Evaluate function with given coordinates and parameters.
Definition TF1.cxx:1468
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set lower and upper limits for parameter ipar.
Definition TF1.cxx:3507
static Bool_t RejectedPoint()
See TF1::RejectPoint above.
Definition TF1.cxx:3692
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:1439
virtual void SetParameter(Int_t param, Double_t value)
Definition TF1.h:667
virtual Bool_t IsInside(const Double_t *x) const
return kTRUE if the point is inside the function range
Definition TF1.h:626
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...
1-D histogram with a byte per channel (see TH1 documentation)
Definition TH1.h:458
~TH1C() override
Destructor.
Definition TH1.cxx:9542
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9598
TH1C & operator=(const TH1C &h1)
Operator =.
Definition TH1.cxx:9608
TH1C()
Constructor.
Definition TH1.cxx:9494
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9580
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9559
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:9588
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:670
~TH1D() override
Destructor.
Definition TH1.cxx:10488
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10522
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10504
TH1D()
Constructor.
Definition TH1.cxx:10423
TH1D & operator=(const TH1D &h1)
Operator =.
Definition TH1.cxx:10532
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:10512
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:622
Double_t RetrieveBinContent(Int_t bin) const override
Raw retrieval of bin content on internal data structure see convention for numbering bins in TH1::Get...
Definition TH1.h:656
TH1F & operator=(const TH1F &h1)
Operator =.
Definition TH1.cxx:10351
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10323
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10341
~TH1F() override
Destructor.
Definition TH1.cxx:10316
TH1F()
Constructor.
Definition TH1.cxx:10242
1-D histogram with an int per channel (see TH1 documentation)
Definition TH1.h:540
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9971
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9932
~TH1I() override
Destructor.
Definition TH1.cxx:9915
TH1I()
Constructor.
Definition TH1.cxx:9867
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9953
TH1I & operator=(const TH1I &h1)
Operator =.
Definition TH1.cxx:9981
1-D histogram with a long64 per channel (see TH1 documentation)
Definition TH1.h:581
TH1L & operator=(const TH1L &h1)
Operator =.
Definition TH1.cxx:10169
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:10120
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10159
~TH1L() override
Destructor.
Definition TH1.cxx:10103
TH1L()
Constructor.
Definition TH1.cxx:10055
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10141
1-D histogram with a short per channel (see TH1 documentation)
Definition TH1.h:499
TH1S & operator=(const TH1S &h1)
Operator =.
Definition TH1.cxx:9794
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9766
TH1S()
Constructor.
Definition TH1.cxx:9680
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9784
~TH1S() override
Destructor.
Definition TH1.cxx:9728
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9745
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:59
~TH1() override
Histogram default destructor.
Definition TH1.cxx:643
virtual void SetError(const Double_t *error)
Replace bin errors by values in array error.
Definition TH1.cxx:8972
virtual void SetDirectory(TDirectory *dir)
By default, when a histogram is created, it is added to the list of histogram objects in the current ...
Definition TH1.cxx:8958
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition TH1.cxx:4284
Double_t * fBuffer
[fBufferSize] entry buffer
Definition TH1.h:108
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:1343
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition TH1.cxx:4448
char * GetObjectInfo(Int_t px, Int_t py) const override
Redefines TObject::GetObjectInfo.
Definition TH1.cxx:4502
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition TH1.cxx:6900
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:9162
virtual void Rebuild(Option_t *option="")
Using the current bin info, recompute the arrays for contents and errors.
Definition TH1.cxx:7108
virtual void SetBarOffset(Float_t offset=0.25)
Set the bar offset as fraction of the bin width for drawing mode "B".
Definition TH1.h:364
static Bool_t fgStatOverflows
! Flag to use under/overflows in statistics
Definition TH1.h:117
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:3797
TAxis * GetZaxis()
Definition TH1.h:326
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a line.
Definition TH1.cxx:2823
virtual Bool_t Multiply(TF1 *f1, Double_t c1=1)
Performs the operation:
Definition TH1.cxx:6070
@ kXaxis
Definition TH1.h:73
@ kNoAxis
NOTE: Must always be 0 !!!
Definition TH1.h:72
@ kZaxis
Definition TH1.h:75
@ kYaxis
Definition TH1.h:74
Int_t fNcells
Number of bins(1D), cells (2D) +U/Overflows.
Definition TH1.h:89
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:7854
void Copy(TObject &hnew) const override
Copy this histogram structure to newth1.
Definition TH1.cxx:2671
void SetTitle(const char *title) override
Change/set the title.
Definition TH1.cxx:6739
Double_t fTsumw
Total Sum of weights.
Definition TH1.h:96
virtual Float_t GetBarWidth() const
Definition TH1.h:257
Double_t fTsumw2
Total Sum of squares of weights.
Definition TH1.h:97
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:6946
virtual Float_t GetBarOffset() const
Definition TH1.h:256
TList * fFunctions
->Pointer to list of functions (fits and user)
Definition TH1.h:106
static Bool_t fgAddDirectory
! Flag to add histograms to the directory
Definition TH1.h:116
static int CheckConsistency(const TH1 *h1, const TH1 *h2)
Check histogram compatibility.
Definition TH1.cxx:1677
static TClass * Class()
static Int_t GetDefaultBufferSize()
Static function return the default buffer size for automatic histograms the parameter fgBufferSize ma...
Definition TH1.cxx:4406
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:7998
Double_t fTsumwx2
Total Sum of weight*X*X.
Definition TH1.h:99
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition TH1.cxx:7628
TH1()
Histogram default constructor.
Definition TH1.cxx:615
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:9340
void UseCurrentStyle() override
Copy current attributes from/to current style.
Definition TH1.cxx:7490
virtual void LabelsOption(Option_t *option="h", Option_t *axis="X")
Sort bins with labels or set option(s) to draw axis with labels.
Definition TH1.cxx:5403
virtual Int_t GetNbinsY() const
Definition TH1.h:298
Short_t fBarOffset
(1000*offset) for bar charts or legos
Definition TH1.h:93
virtual Double_t Chi2TestX(const TH1 *h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option="UU", Double_t *res=nullptr) const
The computation routine of the Chisquare test.
Definition TH1.cxx:2067
static bool CheckBinLimits(const TAxis *a1, const TAxis *a2)
Check bin limits.
Definition TH1.cxx:1541
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition TH1.cxx:1268
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:9084
static Int_t FitOptionsMake(Option_t *option, Foption_t &Foption)
Decode string choptin and fill fitOption structure.
Definition TH1.cxx:4673
virtual Int_t GetNbinsZ() const
Definition TH1.h:299
virtual Double_t GetNormFactor() const
Definition TH1.h:301
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:7556
virtual Double_t GetSkewness(Int_t axis=1) const
Definition TH1.cxx:7692
virtual void ClearUnderflowAndOverflow()
Remove all the content from the underflow and overflow bins, without changing the number of entries A...
Definition TH1.cxx:2517
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition TH1.cxx:8461
virtual TH1 * DrawNormalized(Option_t *option="", Double_t norm=1) const
Draw a normalized copy of this histogram.
Definition TH1.cxx:3144
@ kNeutral
Adapt to the global flag.
Definition TH1.h:83
virtual Int_t GetDimension() const
Definition TH1.h:283
void Streamer(TBuffer &) override
Stream a class object.
Definition TH1.cxx:6954
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1294
@ kIsAverage
Bin contents are average (used by Add)
Definition TH1.h:171
@ kUserContour
User specified contour levels.
Definition TH1.h:166
@ kNoStats
Don't draw stats box.
Definition TH1.h:165
@ kAutoBinPTwo
different than 1.
Definition TH1.h:174
@ kIsNotW
Histogram is forced to be not weighted even when the histogram is filled with weighted.
Definition TH1.h:172
@ kIsHighlight
bit set if histo is highlight
Definition TH1.h:175
virtual void SetContourLevel(Int_t level, Double_t value)
Set value for one contour level.
Definition TH1.cxx:8543
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition TH1.cxx:6657
TDirectory * fDirectory
! Pointer to directory holding this histogram
Definition TH1.h:109
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition TH1.cxx:7124
void SetNameTitle(const char *name, const char *title) override
Change the name and title of this histogram.
Definition TH1.cxx:8995
TAxis * GetXaxis()
Definition TH1.h:324
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:4995
TH1 * GetCumulative(Bool_t forward=kTRUE, const char *suffix="_cumulative") const
Return a pointer to a histogram containing the cumulative content.
Definition TH1.cxx:2616
static Double_t AutoP2GetPower2(Double_t x, Bool_t next=kTRUE)
Auxiliary function to get the power of 2 next (larger) or previous (smaller) a given x.
Definition TH1.cxx:1308
virtual Int_t GetNcells() const
Definition TH1.h:300
virtual Int_t ShowPeaks(Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
Interface to TSpectrum::Search.
Definition TH1.cxx:9322
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition TH1.cxx:5929
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition TH1.cxx:7905
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition TH1.cxx:4511
TObject * FindObject(const char *name) const override
Search object named name in the list of functions.
Definition TH1.cxx:3857
virtual void FillRandom(const char *fname, Int_t ntimes=5000, TRandom *rng=nullptr)
Fill histogram following distribution in function fname.
Definition TH1.cxx:3519
void Print(Option_t *option="") const override
Print some global quantities for this histogram.
Definition TH1.cxx:7030
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
Definition TH1.cxx:4415
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:3734
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:3898
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:4982
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:8566
virtual Int_t GetNbinsX() const
Definition TH1.h:297
virtual void SetMaximum(Double_t maximum=-1111)
Definition TH1.h:404
virtual TH1 * FFT(TH1 *h_output, Option_t *option)
This function allows to do discrete Fourier transforms of TH1 and TH2.
Definition TH1.cxx:3284
virtual void LabelsInflate(Option_t *axis="X")
Double the number of bins for axis.
Definition TH1.cxx:5336
virtual TH1 * ShowBackground(Int_t niter=20, Option_t *option="same")
This function calculates the background spectrum in this histogram.
Definition TH1.cxx:9308
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
Definition TH1.cxx:5919
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:826
Double_t fMaximum
Maximum value for plotting.
Definition TH1.h:100
Int_t fBufferSize
fBuffer size
Definition TH1.h:107
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:9460
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:7989
Int_t fDimension
! Histogram dimension (1, 2 or 3 dim)
Definition TH1.h:110
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:9227
EBinErrorOpt fBinStatErrOpt
Option for bin statistical errors.
Definition TH1.h:113
static Int_t fgBufferSize
! Default buffer size for automatic histograms
Definition TH1.h:115
virtual void SetBinsLength(Int_t=-1)
Definition TH1.h:380
Double_t fNormFactor
Normalization factor.
Definition TH1.h:102
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3344
TAxis * GetYaxis()
Definition TH1.h:325
TArrayD fContour
Array to display contour levels.
Definition TH1.h:103
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition TH1.cxx:9100
void Browse(TBrowser *b) override
Browse the Histogram object.
Definition TH1.cxx:762
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition TH1.cxx:8419
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx:3066
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:7400
Short_t fBarWidth
(1000*width) for bar charts or legos
Definition TH1.h:94
virtual Double_t GetBinErrorSqUnchecked(Int_t bin) const
Definition TH1.h:449
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:405
Bool_t IsBinUnderflow(Int_t bin, Int_t axis=0) const
Return true if the bin is underflow.
Definition TH1.cxx:5235
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TH1.cxx:7258
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check that axis have same labels.
Definition TH1.cxx:1568
virtual Double_t Interpolate(Double_t x) const
Given a point x, approximates the value via linear interpolation based on the two nearest bin centers...
Definition TH1.cxx:5136
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:6724
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition TH1.cxx:5203
UInt_t GetAxisLabelStatus() const
Internal function used in TH1::Fill to see which axis is full alphanumeric, i.e.
Definition TH1.cxx:6696
Double_t * fIntegral
! Integral of bins used by GetRandom
Definition TH1.h:111
Double_t fMinimum
Minimum value for plotting.
Definition TH1.h:101
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition TH1.cxx:7962
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:9243
virtual void DirectoryAutoAdd(TDirectory *)
Perform the automatic addition of the histogram to the given directory.
Definition TH1.cxx:2801
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:9208
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:9173
void Build()
Creates histogram basic data structure.
Definition TH1.cxx:771
virtual Double_t GetEntries() const
Return the current number of entries.
Definition TH1.cxx:4423
virtual TF1 * GetFunction(const char *name) const
Return pointer to function with name.
Definition TH1.cxx:9072
virtual TH1 * Rebin(Int_t ngroup=2, const char *newname="", const Double_t *xbins=nullptr)
Rebin this histogram.
Definition TH1.cxx:6296
virtual Int_t BufferFill(Double_t x, Double_t w)
accumulate arguments in buffer.
Definition TH1.cxx:1506
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:5107
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:6670
TList * GetListOfFunctions() const
Definition TH1.h:244
void SetName(const char *name) override
Change the name of this histogram.
Definition TH1.cxx:8981
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition TH1.cxx:3113
Bool_t IsEmpty() const
Check if a histogram is empty (this is a protected method used mainly by TH1Merger )
Definition TH1.cxx:5185
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition TH1.cxx:7596
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6227
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:8083
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculated from bin cont...
Definition TH1.cxx:7923
static void SetDefaultBufferSize(Int_t buffersize=1000)
Static function to set the default buffer size for automatic histograms.
Definition TH1.cxx:6714
virtual void SetBinErrorOption(EBinErrorOpt type)
Definition TH1.h:381
virtual void SetBuffer(Int_t buffersize, Option_t *option="")
Set the maximum number of entries to be kept in the buffer.
Definition TH1.cxx:8479
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Definition TH1.cxx:3175
virtual Double_t GetRandom(TRandom *rng=nullptr) const
Return a random number distributed according the histogram bin contents.
Definition TH1.cxx:5031
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:2496
virtual Double_t Chi2Test(const TH1 *h2, Option_t *option="UU", Double_t *res=nullptr) const
test for comparing weighted and unweighted histograms.
Definition TH1.cxx:2008
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:3473
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition TH1.cxx:8752
@ kNstat
Size of statistics data (up to TProfile3D)
Definition TH1.h:184
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition TH1.cxx:8598
static Int_t AutoP2GetBins(Int_t n)
Auxiliary function to get the next power of 2 integer value larger then n.
Definition TH1.cxx:1321
Double_t fEntries
Number of entries.
Definition TH1.h:95
virtual Long64_t Merge(TCollection *list)
Definition TH1.h:345
virtual void SetColors(Color_t linecolor=-1, Color_t markercolor=-1, Color_t fillcolor=-1)
Shortcut to set the three histogram colors with a single call.
Definition TH1.cxx:4467
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TH1.cxx:3240
virtual Double_t * GetIntegral()
Return a pointer to the array of bins integral.
Definition TH1.cxx:2586
TAxis fZaxis
Z axis descriptor.
Definition TH1.h:92
EStatOverflows fStatOverflows
Per object flag to use under/overflows in statistics.
Definition TH1.h:114
TClass * IsA() const override
Definition TH1.h:444
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:3447
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:9470
static bool CheckEqualAxes(const TAxis *a1, const TAxis *a2)
Check that the axis are the same.
Definition TH1.cxx:1611
@ kPoisson2
Errors from Poisson interval at 95% CL (~ 2 sigma)
Definition TH1.h:67
@ kNormal
Errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition TH1.h:65
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5082
virtual Int_t GetContour(Double_t *levels=nullptr)
Return contour values into array levels if pointer levels is non zero.
Definition TH1.cxx:8432
TAxis fXaxis
X axis descriptor.
Definition TH1.h:90
virtual Bool_t IsHighlight() const
Definition TH1.h:338
virtual void ExtendAxis(Double_t x, TAxis *axis)
Histogram is resized along axis such that x is in the axis range.
Definition TH1.cxx:6525
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:9184
TArrayD fSumw2
Array of sum of squares of weights.
Definition TH1.h:104
TH1 * GetAsymmetry(TH1 *h2, Double_t c2=1, Double_t dc2=0)
Return a histogram containing the asymmetry of this histogram with h2, where the asymmetry is defined...
Definition TH1.cxx:4339
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition TH1.cxx:8451
virtual void SetContour(Int_t nlevels, const Double_t *levels=nullptr)
Set the number and values of contour levels.
Definition TH1.cxx:8504
virtual void SetHighlight(Bool_t set=kTRUE)
Set highlight (enable/disable) mode for the histogram by default highlight mode is disable.
Definition TH1.cxx:4482
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition TH1.cxx:9131
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition TH1.cxx:6625
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition TH1.cxx:8686
virtual Int_t GetSumw2N() const
Definition TH1.h:315
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:3672
Bool_t GetStatOverflowsBehaviour() const
Definition TH1.h:152
void SaveAs(const char *filename="hist", Option_t *option="") const override
Save the histogram as .csv, .tsv or .txt.
Definition TH1.cxx:7202
virtual Int_t GetQuantiles(Int_t n, Double_t *xp, const Double_t *p=nullptr)
Compute Quantiles for this histogram Quantile x_p := Q(p) is defined as the value x_p such that the c...
Definition TH1.cxx:4611
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx:2752
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition TH1.cxx:7676
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:2840
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:8656
int LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge=false) const
Definition TH1.cxx:883
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:1640
void RecursiveRemove(TObject *obj) override
Recursively remove object from the list of functions.
Definition TH1.cxx:6597
TAxis fYaxis
Y axis descriptor.
Definition TH1.h:91
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:8199
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition TH1.cxx:7938
static void SmoothArray(Int_t NN, Double_t *XX, Int_t ntimes=1)
Smooth array xx, translation of Hbook routine hsmoof.F.
Definition TH1.cxx:6789
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:9195
TVirtualHistPainter * fPainter
! Pointer to histogram painter
Definition TH1.h:112
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition TH1.cxx:8788
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:3705
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:9041
virtual void SetEntries(Double_t n)
Definition TH1.h:391
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:6481
static bool CheckAxisLimits(const TAxis *a1, const TAxis *a2)
Check that the axis limits of the histograms are the same.
Definition TH1.cxx:1597
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition TH1.cxx:754
static Bool_t fgDefaultSumw2
! Flag to call TH1::Sumw2 automatically at histogram creation time
Definition TH1.h:118
Double_t fTsumwx
Total Sum of weight*X.
Definition TH1.h:98
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:5266
virtual Double_t ComputeIntegral(Bool_t onlyPositive=false)
Compute integral (normalized cumulative sum of bins) w/o under/overflows The result is stored in fInt...
Definition TH1.cxx:2537
TString fOption
Histogram options.
Definition TH1.h:105
virtual void Eval(TF1 *f1, Option_t *option="")
Evaluate function f1 at the center of bins of this histogram.
Definition TH1.cxx:3192
virtual void SetBarWidth(Float_t width=0.5)
Set the width of bars as fraction of the bin width for drawing mode "B".
Definition TH1.h:365
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition TH1.cxx:1414
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition TH1.cxx:9011
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition TH1.cxx:7765
2-D histogram with a double per channel (see TH1 documentation)
Definition TH2.h:357
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="") override
Remove all objects from the list.
A doubly linked list.
Definition TList.h:38
void Streamer(TBuffer &) override
Stream all objects in the collection to or from the I/O buffer.
Definition TList.cxx:1189
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:576
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition TList.cxx:762
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:820
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:657
virtual TObjLink * FirstLink() const
Definition TList.h:102
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:468
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:355
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
void Copy(TObject &named) const override
Copy this to obj.
Definition TNamed.cxx:94
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
void Streamer(TBuffer &) override
Stream an object of class TObject.
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
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
Mother of all ROOT objects.
Definition TObject.h:41
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:1047
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:456
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:199
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:474
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:225
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition TObject.cxx:819
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:991
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:202
virtual void SaveAs(const char *filename="", Option_t *option="") const
Save this object in the file specified by filename.
Definition TObject.cxx:704
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:798
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:542
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1005
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:809
void ResetBit(UInt_t f)
Definition TObject.h:198
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:64
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:979
Longptr_t ExecPlugin(int nargs)
Int_t LoadPlugin()
Load the plugin library for this handler.
static TClass * Class()
This is the base class for the ROOT Random number generators.
Definition TRandom.h:27
Double_t Rndm() override
Machine independent random number generator.
Definition TRandom.cxx:559
virtual Double_t PoissonD(Double_t mean)
Generates a random number according to a Poisson law.
Definition TRandom.cxx:461
virtual ULong64_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition TRandom.cxx:404
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
void ToLower()
Change string to lower-case.
Definition TString.cxx:1182
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2244
void Clear()
Clear string without changing its capacity.
Definition TString.cxx:1235
const char * Data() const
Definition TString.h:376
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
void ToUpper()
Change string to upper case.
Definition TString.cxx:1195
Bool_t IsNull() const
Definition TString.h:414
TString & Remove(Ssiz_t pos)
Definition TString.h:685
virtual void Streamer(TBuffer &)
Stream a string object.
Definition TString.cxx:1412
TString & Append(const char *cs)
Definition TString.h:572
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:2378
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2356
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
Int_t GetOptStat() const
Definition TStyle.h:245
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:1640
void SetHistFillColor(Color_t color=1)
Definition TStyle.h:379
Color_t GetHistLineColor() const
Definition TStyle.h:233
Bool_t IsReading() const
Definition TStyle.h:296
Float_t GetBarOffset() const
Definition TStyle.h:182
void SetHistLineStyle(Style_t styl=0)
Definition TStyle.h:382
Style_t GetHistFillStyle() const
Definition TStyle.h:234
Color_t GetHistFillColor() const
Definition TStyle.h:232
Float_t GetBarWidth() const
Definition TStyle.h:183
Bool_t GetCanvasPreferGL() const
Definition TStyle.h:187
void SetHistLineColor(Color_t color=1)
Definition TStyle.h:380
void SetBarOffset(Float_t baroff=0.5)
Definition TStyle.h:335
Style_t GetHistLineStyle() const
Definition TStyle.h:235
void SetBarWidth(Float_t barwidth=0.5)
Definition TStyle.h:336
void SetHistFillStyle(Style_t styl=0)
Definition TStyle.h:381
Width_t GetHistLineWidth() const
Definition TStyle.h:236
Int_t GetOptFit() const
Definition TStyle.h:244
void SetHistLineWidth(Width_t width=1)
Definition TStyle.h:383
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
Int_t DistancetoPrimitive(Int_t px, Int_t py) override=0
Computes distance from point (px,py) to the object.
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override=0
Execute action corresponding to an event at (px,py).
virtual void SetHighlight()=0
static TVirtualHistPainter * HistPainter(TH1 *obj)
Static function returning a pointer to the current histogram painter.
void Paint(Option_t *option="") override=0
This method must be overridden if a class wants to paint itself.
virtual void SetParent(TObject *)=0
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
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
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
R__ALWAYS_INLINE bool HasBeenDeleted(const TObject *obj)
Check if the TObject's memory has been deleted.
Definition TObject.h:402
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:972
double Chisquare(const TH1 &h1, TF1 &f1, bool useRange, EChisquareType type)
compute the chi2 value for an histogram given a function (see TH1::Chisquare for the documentation)
void FitOptionsMake(EFitObjectType type, const char *option, Foption_t &fitOption)
Decode list of options into fitOption.
Definition HFitImpl.cxx:685
void FillData(BinData &dv, const TH1 *hist, TF1 *func=nullptr)
fill the data vector from a TH1.
R__EXTERN TVirtualRWMutex * gCoreMutex
Bool_t IsNaN(Double_t x)
Definition TMath.h:892
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:693
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:250
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:637
Double_t Median(Long64_t n, const T *a, const Double_t *w=nullptr, Long64_t *work=nullptr)
Same as RMS.
Definition TMath.h:1272
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Definition TMath.h:902
Double_t Floor(Double_t x)
Rounds x downward, returning the largest integral value that is not greater than x.
Definition TMath.h:680
Double_t ATan(Double_t)
Returns the principal value of the arc tangent of x, expressed in radians.
Definition TMath.h:640
Double_t Ceil(Double_t x)
Rounds x upward, returning the smallest integral value that is not less than x.
Definition TMath.h:668
T MinElement(Long64_t n, const T *a)
Returns minimum of array a of length n.
Definition TMath.h:960
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:756
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:662
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:721
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
constexpr Double_t Pi()
Definition TMath.h:37
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Comparing floating points.
Definition TMath.h:426
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Comparing floating points.
Definition TMath.h:418
Double_t KolmogorovProb(Double_t z)
Calculates the Kolmogorov distribution function,.
Definition TMath.cxx:679
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Sort the n elements of the array a of generic templated type Element.
Definition TMathBase.h:431
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition TMathBase.h:347
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:762
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
Definition TMath.h:917
th1 Draw()
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345