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#include <limits>
23#include <iomanip>
24
25#include "TROOT.h"
26#include "TBuffer.h"
27#include "TEnv.h"
28#include "TClass.h"
29#include "TMath.h"
30#include "THashList.h"
31#include "TH1.h"
32#include "TH2.h"
33#include "TH3.h"
34#include "TF2.h"
35#include "TF3.h"
36#include "TPluginManager.h"
37#include "TVirtualPad.h"
38#include "TRandom.h"
39#include "TVirtualFitter.h"
40#include "THLimitsFinder.h"
41#include "TProfile.h"
42#include "TStyle.h"
43#include "TVectorF.h"
44#include "TVectorD.h"
45#include "TBrowser.h"
46#include "TError.h"
47#include "TVirtualHistPainter.h"
48#include "TVirtualFFT.h"
49#include "TVirtualPaveStats.h"
50
51#include "HFitInterface.h"
52#include "Fit/DataRange.h"
53#include "Fit/BinData.h"
54#include "Math/GoFTest.h"
57
58#include "TH1Merger.h"
59
60/** \addtogroup Histograms
61@{
62\class TH1C
63\brief 1-D histogram with a byte per channel (see TH1 documentation)
64\class TH1S
65\brief 1-D histogram with a short per channel (see TH1 documentation)
66\class TH1I
67\brief 1-D histogram with an int per channel (see TH1 documentation)
68\class TH1L
69\brief 1-D histogram with a long64 per channel (see TH1 documentation)
70\class TH1F
71\brief 1-D histogram with a float per channel (see TH1 documentation)
72\class TH1D
73\brief 1-D histogram with a double per channel (see TH1 documentation)
74@}
75*/
76
77/** \class TH1
78 \ingroup Histograms
79TH1 is the base class of all histogram classes in %ROOT.
80
81It provides the common interface for operations such as binning, filling, drawing, which
82will be detailed below.
83
84-# [Creating histograms](\ref creating-histograms)
85 - [Labelling axes](\ref labelling-axis)
86-# [Binning](\ref binning)
87 - [Fix or variable bin size](\ref fix-var)
88 - [Convention for numbering bins](\ref convention)
89 - [Alphanumeric Bin Labels](\ref alpha)
90 - [Histograms with automatic bins](\ref auto-bin)
91 - [Rebinning](\ref rebinning)
92-# [Filling histograms](\ref filling-histograms)
93 - [Associated errors](\ref associated-errors)
94 - [Associated functions](\ref associated-functions)
95 - [Projections of histograms](\ref prof-hist)
96 - [Random Numbers and histograms](\ref random-numbers)
97 - [Making a copy of a histogram](\ref making-a-copy)
98 - [Normalizing histograms](\ref normalizing)
99-# [Drawing histograms](\ref drawing-histograms)
100 - [Setting Drawing histogram contour levels (2-D hists only)](\ref cont-level)
101 - [Setting histogram graphics attributes](\ref graph-att)
102 - [Customising how axes are drawn](\ref axis-drawing)
103-# [Fitting histograms](\ref fitting-histograms)
104-# [Saving/reading histograms to/from a ROOT file](\ref saving-histograms)
105-# [Operations on histograms](\ref operations-on-histograms)
106-# [Miscellaneous operations](\ref misc)
107
108ROOT supports the following histogram types:
109
110 - 1-D histograms:
111 - TH1C : histograms with one byte per channel. Maximum bin content = 127
112 - TH1S : histograms with one short per channel. Maximum bin content = 32767
113 - TH1I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
114 - TH1L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
115 - TH1F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax "***")
116 - TH1D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax "****")
117 - 2-D histograms:
118 - TH2C : histograms with one byte per channel. Maximum bin content = 127
119 - TH2S : histograms with one short per channel. Maximum bin content = 32767
120 - TH2I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
121 - TH2L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
122 - TH2F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax "***")
123 - TH2D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax "****")
124 - 3-D histograms:
125 - TH3C : histograms with one byte per channel. Maximum bin content = 127
126 - TH3S : histograms with one short per channel. Maximum bin content = 32767
127 - TH3I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
128 - TH3L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
129 - TH3F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax "***")
130 - TH3D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax "****")
131 - Profile histograms: See classes TProfile, TProfile2D and TProfile3D.
132 Profile histograms are used to display the mean value of Y and its standard deviation
133 for each bin in X. Profile histograms are in many cases an elegant
134 replacement of two-dimensional histograms : the inter-relation of two
135 measured quantities X and Y can always be visualized by a two-dimensional
136 histogram or scatter-plot; If Y is an unknown (but single-valued)
137 approximate function of X, this function is displayed by a profile
138 histogram with much better precision than by a scatter-plot.
139
140<sup>
141\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>
142\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>
143\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>
144\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)
145</sup>
146
147The inheritance hierarchy looks as follows:
148
149\image html classTH1__inherit__graph_org.svg width=100%
150
151\anchor creating-histograms
152## Creating histograms
153
154Histograms are created by invoking one of the constructors, e.g.
155~~~ {.cpp}
156 TH1F *h1 = new TH1F("h1", "h1 title", 100, 0, 4.4);
157 TH2F *h2 = new TH2F("h2", "h2 title", 40, 0, 4, 30, -3, 3);
158~~~
159Histograms may also be created by:
160
161 - calling the Clone() function, see below
162 - making a projection from a 2-D or 3-D histogram, see below
163 - reading a histogram from a file
164
165 When a histogram is created, a reference to it is automatically added
166 to the list of in-memory objects for the current file or directory.
167 Then the pointer to this histogram in the current directory can be found
168 by its name, doing:
169~~~ {.cpp}
170 TH1F *h1 = (TH1F*)gDirectory->FindObject(name);
171~~~
172
173 This default behaviour can be changed by:
174~~~ {.cpp}
175 h->SetDirectory(nullptr); // for the current histogram h
176 TH1::AddDirectory(kFALSE); // sets a global switch disabling the referencing
177~~~
178 When the histogram is deleted, the reference to it is removed from
179 the list of objects in memory.
180 When a file is closed, all histograms in memory associated with this file
181 are automatically deleted.
182
183\anchor labelling-axis
184### Labelling axes
185
186 Axis titles can be specified in the title argument of the constructor.
187 They must be separated by ";":
188~~~ {.cpp}
189 TH1F* h=new TH1F("h", "Histogram title;X Axis;Y Axis", 100, 0, 1);
190~~~
191 The histogram title and the axis titles can be any TLatex string, and
192 are persisted if a histogram is written to a file.
193
194 Any title can be omitted:
195~~~ {.cpp}
196 TH1F* h=new TH1F("h", "Histogram title;;Y Axis", 100, 0, 1);
197 TH1F* h=new TH1F("h", ";;Y Axis", 100, 0, 1);
198~~~
199 The method SetTitle() has the same syntax:
200~~~ {.cpp}
201 h->SetTitle("Histogram title;Another X title Axis");
202~~~
203Alternatively, the title of each axis can be set directly:
204~~~ {.cpp}
205 h->GetXaxis()->SetTitle("X axis title");
206 h->GetYaxis()->SetTitle("Y axis title");
207~~~
208For bin labels see \ref binning.
209
210\anchor binning
211## Binning
212
213\anchor fix-var
214### Fix or variable bin size
215
216 All histogram types support either fix or variable bin sizes.
217 2-D histograms may have fix size bins along X and variable size bins
218 along Y or vice-versa. The functions to fill, manipulate, draw or access
219 histograms are identical in both cases.
220
221 Each histogram always contains 3 axis objects of type TAxis: fXaxis, fYaxis and fZaxis.
222 To access the axis parameters, use:
223~~~ {.cpp}
224 TAxis *xaxis = h->GetXaxis(); etc.
225 Double_t binCenter = xaxis->GetBinCenter(bin), etc.
226~~~
227 See class TAxis for a description of all the access functions.
228 The axis range is always stored internally in double precision.
229
230\anchor convention
231### Convention for numbering bins
232
233 For all histogram types: nbins, xlow, xup
234~~~ {.cpp}
235 bin = 0; underflow bin
236 bin = 1; first bin with low-edge xlow INCLUDED
237 bin = nbins; last bin with upper-edge xup EXCLUDED
238 bin = nbins+1; overflow bin
239~~~
240 In case of 2-D or 3-D histograms, a "global bin" number is defined.
241 For example, assuming a 3-D histogram with (binx, biny, binz), the function
242~~~ {.cpp}
243 Int_t gbin = h->GetBin(binx, biny, binz);
244~~~
245 returns a global/linearized gbin number. This global gbin is useful
246 to access the bin content/error information independently of the dimension.
247 Note that to access the information other than bin content and errors
248 one should use the TAxis object directly with e.g.:
249~~~ {.cpp}
250 Double_t xcenter = h3->GetZaxis()->GetBinCenter(27);
251~~~
252 returns the center along z of bin number 27 (not the global bin)
253 in the 3-D histogram h3.
254
255\anchor alpha
256### Alphanumeric Bin Labels
257
258 By default, a histogram axis is drawn with its numeric bin labels.
259 One can specify alphanumeric labels instead with:
260
261 - call TAxis::SetBinLabel(bin, label);
262 This can always be done before or after filling.
263 When the histogram is drawn, bin labels will be automatically drawn.
264 See examples labels1.C and labels2.C
265 - call to a Fill function with one of the arguments being a string, e.g.
266~~~ {.cpp}
267 hist1->Fill(somename, weight);
268 hist2->Fill(x, somename, weight);
269 hist2->Fill(somename, y, weight);
270 hist2->Fill(somenamex, somenamey, weight);
271~~~
272 See examples hlabels1.C and hlabels2.C
273 - via TTree::Draw. see for example cernstaff.C
274~~~ {.cpp}
275 tree.Draw("Nation::Division");
276~~~
277 where "Nation" and "Division" are two branches of a Tree.
278
279When using the options 2 or 3 above, the labels are automatically
280 added to the list (THashList) of labels for a given axis.
281 By default, an axis is drawn with the order of bins corresponding
282 to the filling sequence. It is possible to reorder the axis
283
284 - alphabetically
285 - by increasing or decreasing values
286
287 The reordering can be triggered via the TAxis context menu by selecting
288 the menu item "LabelsOption" or by calling directly
289 TH1::LabelsOption(option, axis) where
290
291 - axis may be "X", "Y" or "Z"
292 - option may be:
293 - "a" sort by alphabetic order
294 - ">" sort by decreasing values
295 - "<" sort by increasing values
296 - "h" draw labels horizontal
297 - "v" draw labels vertical
298 - "u" draw labels up (end of label right adjusted)
299 - "d" draw labels down (start of label left adjusted)
300
301 When using the option 2 above, new labels are added by doubling the current
302 number of bins in case one label does not exist yet.
303 When the Filling is terminated, it is possible to trim the number
304 of bins to match the number of active labels by calling
305~~~ {.cpp}
306 TH1::LabelsDeflate(axis) with axis = "X", "Y" or "Z"
307~~~
308 This operation is automatic when using TTree::Draw.
309 Once bin labels have been created, they become persistent if the histogram
310 is written to a file or when generating the C++ code via SavePrimitive.
311
312\anchor auto-bin
313### Histograms with automatic bins
314
315 When a histogram is created with an axis lower limit greater or equal
316 to its upper limit, the SetBuffer is automatically called with an
317 argument fBufferSize equal to fgBufferSize (default value=1000).
318 fgBufferSize may be reset via the static function TH1::SetDefaultBufferSize.
319 The axis limits will be automatically computed when the buffer will
320 be full or when the function BufferEmpty is called.
321
322\anchor rebinning
323### Rebinning
324
325 At any time, a histogram can be rebinned via TH1::Rebin. This function
326 returns a new histogram with the rebinned contents.
327 If bin errors were stored, they are recomputed during the rebinning.
328
329
330\anchor filling-histograms
331## Filling histograms
333 A histogram is typically filled with statements like:
334~~~ {.cpp}
335 h1->Fill(x);
336 h1->Fill(x, w); //fill with weight
337 h2->Fill(x, y)
338 h2->Fill(x, y, w)
339 h3->Fill(x, y, z)
340 h3->Fill(x, y, z, w)
341~~~
342 or via one of the Fill functions accepting names described above.
343 The Fill functions compute the bin number corresponding to the given
344 x, y or z argument and increment this bin by the given weight.
345 The Fill functions return the bin number for 1-D histograms or global
346 bin number for 2-D and 3-D histograms.
347 If TH1::Sumw2 has been called before filling, the sum of squares of
348 weights is also stored.
349 One can also increment directly a bin number via TH1::AddBinContent
350 or replace the existing content via TH1::SetBinContent. Passing an
351 out-of-range bin to TH1::AddBinContent leads to undefined behavior.
352 To access the bin content of a given bin, do:
353~~~ {.cpp}
354 Double_t binContent = h->GetBinContent(bin);
355~~~
356
357 By default, the bin number is computed using the current axis ranges.
358 If the automatic binning option has been set via
359~~~ {.cpp}
360 h->SetCanExtend(TH1::kAllAxes);
361~~~
362 then, the Fill Function will automatically extend the axis range to
363 accomodate the new value specified in the Fill argument. The method
364 used is to double the bin size until the new value fits in the range,
365 merging bins two by two. This automatic binning options is extensively
366 used by the TTree::Draw function when histogramming Tree variables
367 with an unknown range.
368 This automatic binning option is supported for 1-D, 2-D and 3-D histograms.
369
370 During filling, some statistics parameters are incremented to compute
371 the mean value and Root Mean Square with the maximum precision.
372
373 In case of histograms of type TH1C, TH1S, TH2C, TH2S, TH3C, TH3S
374 a check is made that the bin contents do not exceed the maximum positive
375 capacity (127 or 32767). Histograms of all types may have positive
376 or/and negative bin contents.
377
378\anchor associated-errors
379### Associated errors
380 By default, for each bin, the sum of weights is computed at fill time.
381 One can also call TH1::Sumw2 to force the storage and computation
382 of the sum of the square of weights per bin.
383 If Sumw2 has been called, the error per bin is computed as the
384 sqrt(sum of squares of weights), otherwise the error is set equal
385 to the sqrt(bin content).
386 To return the error for a given bin number, do:
387~~~ {.cpp}
388 Double_t error = h->GetBinError(bin);
389~~~
390
391\anchor associated-functions
392### Associated functions
393 One or more object (typically a TF1*) can be added to the list
394 of functions (fFunctions) associated to each histogram.
395 When TH1::Fit is invoked, the fitted function is added to this list.
396 Given a histogram h, one can retrieve an associated function
397 with:
398~~~ {.cpp}
399 TF1 *myfunc = h->GetFunction("myfunc");
400~~~
401
402
403\anchor operations-on-histograms
404## Operations on histograms
405
406 Many types of operations are supported on histograms or between histograms
407
408 - Addition of a histogram to the current histogram.
409 - Additions of two histograms with coefficients and storage into the current
410 histogram.
411 - Multiplications and Divisions are supported in the same way as additions.
412 - The Add, Divide and Multiply functions also exist to add, divide or multiply
413 a histogram by a function.
414
415 If a histogram has associated error bars (TH1::Sumw2 has been called),
416 the resulting error bars are also computed assuming independent histograms.
417 In case of divisions, Binomial errors are also supported.
418 One can mark a histogram to be an "average" histogram by setting its bit kIsAverage via
419 myhist.SetBit(TH1::kIsAverage);
420 When adding (see TH1::Add) average histograms, the histograms are averaged and not summed.
421
422
423\anchor prof-hist
424### Projections of histograms
425
426 One can:
427
428 - make a 1-D projection of a 2-D histogram or Profile
429 see functions TH2::ProjectionX,Y, TH2::ProfileX,Y, TProfile::ProjectionX
430 - make a 1-D, 2-D or profile out of a 3-D histogram
431 see functions TH3::ProjectionZ, TH3::Project3D.
432
433 One can fit these projections via:
434~~~ {.cpp}
435 TH2::FitSlicesX,Y, TH3::FitSlicesZ.
436~~~
437
438\anchor random-numbers
439### Random Numbers and histograms
440
441 TH1::FillRandom can be used to randomly fill a histogram using
442 the contents of an existing TF1 function or another
443 TH1 histogram (for all dimensions).
444 For example, the following two statements create and fill a histogram
445 10000 times with a default gaussian distribution of mean 0 and sigma 1:
446~~~ {.cpp}
447 TH1F h1("h1", "histo from a gaussian", 100, -3, 3);
448 h1.FillRandom("gaus", 10000);
449~~~
450 TH1::GetRandom can be used to return a random number distributed
451 according to the contents of a histogram.
452
453\anchor making-a-copy
454### Making a copy of a histogram
455 Like for any other ROOT object derived from TObject, one can use
456 the Clone() function. This makes an identical copy of the original
457 histogram including all associated errors and functions, e.g.:
458~~~ {.cpp}
459 TH1F *hnew = (TH1F*)h->Clone("hnew");
460~~~
461
462\anchor normalizing
463### Normalizing histograms
464
465 One can scale a histogram such that the bins integral is equal to
466 the normalization parameter via TH1::Scale(Double_t norm), where norm
467 is the desired normalization divided by the integral of the histogram.
468
469
470\anchor drawing-histograms
471## Drawing histograms
472
473 Histograms are drawn via the THistPainter class. Each histogram has
474 a pointer to its own painter (to be usable in a multithreaded program).
475 Many drawing options are supported.
476 See THistPainter::Paint() for more details.
477
478 The same histogram can be drawn with different options in different pads.
479 When a histogram drawn in a pad is deleted, the histogram is
480 automatically removed from the pad or pads where it was drawn.
481 If a histogram is drawn in a pad, then filled again, the new status
482 of the histogram will be automatically shown in the pad next time
483 the pad is updated. One does not need to redraw the histogram.
484 To draw the current version of a histogram in a pad, one can use
485~~~ {.cpp}
486 h->DrawCopy();
487~~~
488 This makes a clone (see Clone below) of the histogram. Once the clone
489 is drawn, the original histogram may be modified or deleted without
490 affecting the aspect of the clone.
491
492 One can use TH1::SetMaximum() and TH1::SetMinimum() to force a particular
493 value for the maximum or the minimum scale on the plot. (For 1-D
494 histograms this means the y-axis, while for 2-D histograms these
495 functions affect the z-axis).
496
497 TH1::UseCurrentStyle() can be used to change all histogram graphics
498 attributes to correspond to the current selected style.
499 This function must be called for each histogram.
500 In case one reads and draws many histograms from a file, one can force
501 the histograms to inherit automatically the current graphics style
502 by calling before gROOT->ForceStyle().
503
504\anchor cont-level
505### Setting Drawing histogram contour levels (2-D hists only)
506
507 By default contours are automatically generated at equidistant
508 intervals. A default value of 20 levels is used. This can be modified
509 via TH1::SetContour() or TH1::SetContourLevel().
510 the contours level info is used by the drawing options "cont", "surf",
511 and "lego".
512
513\anchor graph-att
514### Setting histogram graphics attributes
515
516 The histogram classes inherit from the attribute classes:
517 TAttLine, TAttFill, and TAttMarker.
518 See the member functions of these classes for the list of options.
519
520\anchor axis-drawing
521### Customizing how axes are drawn
522
523 Use the functions of TAxis, such as
524~~~ {.cpp}
525 histogram.GetXaxis()->SetTicks("+");
526 histogram.GetYaxis()->SetRangeUser(1., 5.);
527~~~
528
529\anchor fitting-histograms
530## Fitting histograms
531
532 Histograms (1-D, 2-D, 3-D and Profiles) can be fitted with a user
533 specified function or a pre-defined function via TH1::Fit.
534 See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for the fitting documentation and the possible [fitting options](\ref HFitOpt)
535
536 The FitPanel can also be used for fitting an histogram. See the [FitPanel documentation](https://root.cern/manual/fitting/#using-the-fit-panel).
537
538\anchor saving-histograms
539## Saving/reading histograms to/from a ROOT file
540
541 The following statements create a ROOT file and store a histogram
542 on the file. Because TH1 derives from TNamed, the key identifier on
543 the file is the histogram name:
544~~~ {.cpp}
545 TFile f("histos.root", "new");
546 TH1F h1("hgaus", "histo from a gaussian", 100, -3, 3);
547 h1.FillRandom("gaus", 10000);
548 h1->Write();
549~~~
550 To read this histogram in another Root session, do:
551~~~ {.cpp}
552 TFile f("histos.root");
553 TH1F *h = (TH1F*)f.Get("hgaus");
554~~~
555 One can save all histograms in memory to the file by:
556~~~ {.cpp}
557 file->Write();
558~~~
559
560
561\anchor misc
562## Miscellaneous operations
563
564~~~ {.cpp}
565 TH1::KolmogorovTest(): statistical test of compatibility in shape
566 between two histograms
567 TH1::Smooth() smooths the bin contents of a 1-d histogram
568 TH1::Integral() returns the integral of bin contents in a given bin range
569 TH1::GetMean(int axis) returns the mean value along axis
570 TH1::GetStdDev(int axis) returns the sigma distribution along axis
571 TH1::GetEntries() returns the number of entries
572 TH1::Reset() resets the bin contents and errors of a histogram
573~~~
574 IMPORTANT NOTE: The returned values for GetMean and GetStdDev depend on how the
575 histogram statistics are calculated. By default, if no range has been set, the
576 returned values are the (unbinned) ones calculated at fill time. If a range has been
577 set, however, the values are calculated using the bins in range; THIS IS TRUE EVEN
578 IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset the range.
579 To ensure that the returned values are always those of the binned data stored in the
580 histogram, call TH1::ResetStats. See TH1::GetStats.
581*/
582
583TF1 *gF1=nullptr; //left for back compatibility (use TVirtualFitter::GetUserFunc instead)
584
589
590extern void H1InitGaus();
591extern void H1InitExpo();
592extern void H1InitPolynom();
593extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
594extern void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail);
595extern void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b);
596
597namespace {
598
599/// Enumeration specifying inconsistencies between two histograms,
600/// in increasing severity.
601enum EInconsistencyBits {
602 kFullyConsistent = 0,
603 kDifferentLabels = BIT(0),
604 kDifferentBinLimits = BIT(1),
605 kDifferentAxisLimits = BIT(2),
606 kDifferentNumberOfBins = BIT(3),
607 kDifferentDimensions = BIT(4)
608};
609
610} // namespace
611
613
614////////////////////////////////////////////////////////////////////////////////
615/// Histogram default constructor.
616
618{
619 fDirectory = nullptr;
620 fFunctions = new TList;
621 fNcells = 0;
622 fIntegral = nullptr;
623 fPainter = nullptr;
624 fEntries = 0;
625 fNormFactor = 0;
627 fMaximum = -1111;
628 fMinimum = -1111;
629 fBufferSize = 0;
630 fBuffer = nullptr;
633 fXaxis.SetName("xaxis");
634 fYaxis.SetName("yaxis");
635 fZaxis.SetName("zaxis");
636 fXaxis.SetParent(this);
637 fYaxis.SetParent(this);
638 fZaxis.SetParent(this);
640}
641
642////////////////////////////////////////////////////////////////////////////////
643/// Histogram default destructor.
644
646{
648 return;
649 }
650 delete[] fIntegral;
651 fIntegral = nullptr;
652 delete[] fBuffer;
653 fBuffer = nullptr;
654 if (fFunctions) {
656
658 TObject* obj = nullptr;
659 //special logic to support the case where the same object is
660 //added multiple times in fFunctions.
661 //This case happens when the same object is added with different
662 //drawing modes
663 //In the loop below we must be careful with objects (eg TCutG) that may
664 // have been added to the list of functions of several histograms
665 //and may have been already deleted.
666 while ((obj = fFunctions->First())) {
667 while(fFunctions->Remove(obj)) { }
669 break;
670 }
671 delete obj;
672 obj = nullptr;
673 }
674 delete fFunctions;
675 fFunctions = nullptr;
676 }
677 if (fDirectory) {
678 fDirectory->Remove(this);
679 fDirectory = nullptr;
680 }
681 delete fPainter;
682 fPainter = nullptr;
683}
684
685////////////////////////////////////////////////////////////////////////////////
686/// Constructor for fix bin size histograms.
687/// Creates the main histogram structure.
688///
689/// \param[in] name name of histogram (avoid blanks)
690/// \param[in] title histogram title.
691/// If title is of the form `stringt;stringx;stringy;stringz`,
692/// the histogram title is set to `stringt`,
693/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
694/// \param[in] nbins number of bins
695/// \param[in] xlow low edge of first bin
696/// \param[in] xup upper edge of last bin (not included in last bin)
697
698
699TH1::TH1(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
700 :TNamed(name,title)
701{
702 Build();
703 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
704 fXaxis.Set(nbins,xlow,xup);
705 fNcells = fXaxis.GetNbins()+2;
706}
707
708////////////////////////////////////////////////////////////////////////////////
709/// Constructor for variable bin size histograms using an input array of type float.
710/// Creates the main histogram structure.
711///
712/// \param[in] name name of histogram (avoid blanks)
713/// \param[in] title histogram title.
714/// If title is of the form `stringt;stringx;stringy;stringz`
715/// the histogram title is set to `stringt`,
716/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
717/// \param[in] nbins number of bins
718/// \param[in] xbins array of low-edges for each bin.
719/// This is an array of type float and size nbins+1
720
721TH1::TH1(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
722 :TNamed(name,title)
723{
724 Build();
725 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
726 if (xbins) fXaxis.Set(nbins,xbins);
727 else fXaxis.Set(nbins,0,1);
728 fNcells = fXaxis.GetNbins()+2;
729}
730
731////////////////////////////////////////////////////////////////////////////////
732/// Constructor for variable bin size histograms using an input array of type double.
733///
734/// \param[in] name name of histogram (avoid blanks)
735/// \param[in] title histogram title.
736/// If title is of the form `stringt;stringx;stringy;stringz`
737/// the histogram title is set to `stringt`,
738/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
739/// \param[in] nbins number of bins
740/// \param[in] xbins array of low-edges for each bin.
741/// This is an array of type double and size nbins+1
742
743TH1::TH1(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
744 :TNamed(name,title)
745{
746 Build();
747 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
748 if (xbins) fXaxis.Set(nbins,xbins);
749 else fXaxis.Set(nbins,0,1);
750 fNcells = fXaxis.GetNbins()+2;
751}
752
753////////////////////////////////////////////////////////////////////////////////
754/// Static function: cannot be inlined on Windows/NT.
755
757{
758 return fgAddDirectory;
759}
760
761////////////////////////////////////////////////////////////////////////////////
762/// Browse the Histogram object.
763
765{
766 Draw(b ? b->GetDrawOption() : "");
767 gPad->Update();
768}
769
770////////////////////////////////////////////////////////////////////////////////
771/// Creates histogram basic data structure.
772
774{
775 fDirectory = nullptr;
776 fPainter = nullptr;
777 fIntegral = nullptr;
778 fEntries = 0;
779 fNormFactor = 0;
781 fMaximum = -1111;
782 fMinimum = -1111;
783 fBufferSize = 0;
784 fBuffer = nullptr;
787 fXaxis.SetName("xaxis");
788 fYaxis.SetName("yaxis");
789 fZaxis.SetName("zaxis");
790 fYaxis.Set(1,0.,1.);
791 fZaxis.Set(1,0.,1.);
792 fXaxis.SetParent(this);
793 fYaxis.SetParent(this);
794 fZaxis.SetParent(this);
795
797
798 fFunctions = new TList;
799
801
804 if (fDirectory) {
806 fDirectory->Append(this,kTRUE);
807 }
808 }
809}
810
811////////////////////////////////////////////////////////////////////////////////
812/// Performs the operation: `this = this + c1*f1`
813/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
814///
815/// By default, the function is computed at the centre of the bin.
816/// if option "I" is specified (1-d histogram only), the integral of the
817/// function in each bin is used instead of the value of the function at
818/// the centre of the bin.
819///
820/// Only bins inside the function range are recomputed.
821///
822/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
823/// you should call Sumw2 before making this operation.
824/// This is particularly important if you fit the histogram after TH1::Add
825///
826/// The function return kFALSE if the Add operation failed
827
829{
830 if (!f1) {
831 Error("Add","Attempt to add a non-existing function");
832 return kFALSE;
833 }
834
835 TString opt = option;
836 opt.ToLower();
837 Bool_t integral = kFALSE;
838 if (opt.Contains("i") && fDimension == 1) integral = kTRUE;
839
840 Int_t ncellsx = GetNbinsX() + 2; // cells = normal bins + underflow bin + overflow bin
841 Int_t ncellsy = GetNbinsY() + 2;
842 Int_t ncellsz = GetNbinsZ() + 2;
843 if (fDimension < 2) ncellsy = 1;
844 if (fDimension < 3) ncellsz = 1;
845
846 // delete buffer if it is there since it will become invalid
847 if (fBuffer) BufferEmpty(1);
848
849 // - Add statistics
850 Double_t s1[10];
851 for (Int_t i = 0; i < 10; ++i) s1[i] = 0;
852 PutStats(s1);
853 SetMinimum();
854 SetMaximum();
855
856 // - Loop on bins (including underflows/overflows)
857 Int_t bin, binx, biny, binz;
858 Double_t cu=0;
859 Double_t xx[3];
860 Double_t *params = nullptr;
861 f1->InitArgs(xx,params);
862 for (binz = 0; binz < ncellsz; ++binz) {
863 xx[2] = fZaxis.GetBinCenter(binz);
864 for (biny = 0; biny < ncellsy; ++biny) {
865 xx[1] = fYaxis.GetBinCenter(biny);
866 for (binx = 0; binx < ncellsx; ++binx) {
867 xx[0] = fXaxis.GetBinCenter(binx);
868 if (!f1->IsInside(xx)) continue;
870 bin = binx + ncellsx * (biny + ncellsy * binz);
871 if (integral) {
872 cu = c1*f1->Integral(fXaxis.GetBinLowEdge(binx), fXaxis.GetBinUpEdge(binx), 0.) / fXaxis.GetBinWidth(binx);
873 } else {
874 cu = c1*f1->EvalPar(xx);
875 }
876 if (TF1::RejectedPoint()) continue;
877 AddBinContent(bin,cu);
878 }
879 }
880 }
881
882 return kTRUE;
883}
884
885int TH1::LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge) const
886{
887 const auto inconsistency = CheckConsistency(h1, h2);
888
889 if (inconsistency & kDifferentDimensions) {
890 if (useMerge)
891 Info(name, "Histograms have different dimensions - trying to use TH1::Merge");
892 else {
893 Error(name, "Histograms have different dimensions");
894 }
895 } else if (inconsistency & kDifferentNumberOfBins) {
896 if (useMerge)
897 Info(name, "Histograms have different number of bins - trying to use TH1::Merge");
898 else {
899 Error(name, "Histograms have different number of bins");
900 }
901 } else if (inconsistency & kDifferentAxisLimits) {
902 if (useMerge)
903 Info(name, "Histograms have different axis limits - trying to use TH1::Merge");
904 else
905 Warning(name, "Histograms have different axis limits");
906 } else if (inconsistency & kDifferentBinLimits) {
907 if (useMerge)
908 Info(name, "Histograms have different bin limits - trying to use TH1::Merge");
909 else
910 Warning(name, "Histograms have different bin limits");
911 } else if (inconsistency & kDifferentLabels) {
912 // in case of different labels -
913 if (useMerge)
914 Info(name, "Histograms have different labels - trying to use TH1::Merge");
915 else
916 Info(name, "Histograms have different labels");
917 }
918
919 return inconsistency;
920}
921
922////////////////////////////////////////////////////////////////////////////////
923/// Performs the operation: `this = this + c1*h1`
924/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
925///
926/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
927/// if not already set.
928///
929/// Note also that adding histogram with labels is not supported, histogram will be
930/// added merging them by bin number independently of the labels.
931/// For adding histogram with labels one should use TH1::Merge
932///
933/// SPECIAL CASE (Average/Efficiency histograms)
934/// For histograms representing averages or efficiencies, one should compute the average
935/// of the two histograms and not the sum. One can mark a histogram to be an average
936/// histogram by setting its bit kIsAverage with
937/// myhist.SetBit(TH1::kIsAverage);
938/// Note that the two histograms must have their kIsAverage bit set
939///
940/// IMPORTANT NOTE1: If you intend to use the errors of this histogram later
941/// you should call Sumw2 before making this operation.
942/// This is particularly important if you fit the histogram after TH1::Add
943///
944/// IMPORTANT NOTE2: if h1 has a normalisation factor, the normalisation factor
945/// is used , ie this = this + c1*factor*h1
946/// Use the other TH1::Add function if you do not want this feature
947///
948/// IMPORTANT NOTE3: You should be careful about the statistics of the
949/// returned histogram, whose statistics may be binned or unbinned,
950/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
951/// and whether TH1::ResetStats has been called on either this or h1.
952/// See TH1::GetStats.
953///
954/// The function return kFALSE if the Add operation failed
955
957{
958 if (!h1) {
959 Error("Add","Attempt to add a non-existing histogram");
960 return kFALSE;
961 }
962
963 // delete buffer if it is there since it will become invalid
964 if (fBuffer) BufferEmpty(1);
965
966 bool useMerge = false;
967 const bool considerMerge = (c1 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
968 const auto inconsistency = LoggedInconsistency("Add", this, h1, considerMerge);
969 // If there is a bad inconsistency and we can't even consider merging, just give up
970 if(inconsistency >= kDifferentNumberOfBins && !considerMerge) {
971 return false;
972 }
973 // If there is an inconsistency, we try to use merging
974 if(inconsistency > kFullyConsistent) {
975 useMerge = considerMerge;
976 }
977
978 if (useMerge) {
979 TList l;
980 l.Add(const_cast<TH1*>(h1));
981 auto iret = Merge(&l);
982 return (iret >= 0);
983 }
984
985 // Create Sumw2 if h1 has Sumw2 set
986 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
987
988 // - Add statistics
989 Double_t entries = TMath::Abs( GetEntries() + c1 * h1->GetEntries() );
990
991 // statistics can be preserved only in case of positive coefficients
992 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
993 Bool_t resetStats = (c1 < 0);
994 Double_t s1[kNstat] = {0};
995 Double_t s2[kNstat] = {0};
996 if (!resetStats) {
997 // need to initialize to zero s1 and s2 since
998 // GetStats fills only used elements depending on dimension and type
999 GetStats(s1);
1000 h1->GetStats(s2);
1001 }
1002
1003 SetMinimum();
1004 SetMaximum();
1005
1006 // - Loop on bins (including underflows/overflows)
1007 Double_t factor = 1;
1008 if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();
1009 Double_t c1sq = c1 * c1;
1010 Double_t factsq = factor * factor;
1011
1012 for (Int_t bin = 0; bin < fNcells; ++bin) {
1013 //special case where histograms have the kIsAverage bit set
1014 if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
1016 Double_t y2 = this->RetrieveBinContent(bin);
1017 Double_t e1sq = h1->GetBinErrorSqUnchecked(bin);
1018 Double_t e2sq = this->GetBinErrorSqUnchecked(bin);
1019 Double_t w1 = 1., w2 = 1.;
1020
1021 // consider all special cases when bin errors are zero
1022 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1023 if (e1sq) w1 = 1. / e1sq;
1024 else if (h1->fSumw2.fN) {
1025 w1 = 1.E200; // use an arbitrary huge value
1026 if (y1 == 0) {
1027 // use an estimated error from the global histogram scale
1028 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1029 w1 = 1./(sf*sf);
1030 }
1031 }
1032 if (e2sq) w2 = 1. / e2sq;
1033 else if (fSumw2.fN) {
1034 w2 = 1.E200; // use an arbitrary huge value
1035 if (y2 == 0) {
1036 // use an estimated error from the global histogram scale
1037 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1038 w2 = 1./(sf*sf);
1039 }
1040 }
1041
1042 double y = (w1*y1 + w2*y2)/(w1 + w2);
1043 UpdateBinContent(bin, y);
1044 if (fSumw2.fN) {
1045 double err2 = 1./(w1 + w2);
1046 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1047 fSumw2.fArray[bin] = err2;
1048 }
1049 } else { // normal case of addition between histograms
1050 AddBinContent(bin, c1 * factor * h1->RetrieveBinContent(bin));
1051 if (fSumw2.fN) fSumw2.fArray[bin] += c1sq * factsq * h1->GetBinErrorSqUnchecked(bin);
1052 }
1053 }
1054
1055 // update statistics (do here to avoid changes by SetBinContent)
1056 if (resetStats) {
1057 // statistics need to be reset in case coefficient are negative
1058 ResetStats();
1059 }
1060 else {
1061 for (Int_t i=0;i<kNstat;i++) {
1062 if (i == 1) s1[i] += c1*c1*s2[i];
1063 else s1[i] += c1*s2[i];
1064 }
1065 PutStats(s1);
1066 SetEntries(entries);
1067 }
1068 return kTRUE;
1069}
1070
1071////////////////////////////////////////////////////////////////////////////////
1072/// Replace contents of this histogram by the addition of h1 and h2.
1073///
1074/// `this = c1*h1 + c2*h2`
1075/// if errors are defined (see TH1::Sumw2), errors are also recalculated
1076///
1077/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
1078/// if not already set.
1079///
1080/// Note also that adding histogram with labels is not supported, histogram will be
1081/// added merging them by bin number independently of the labels.
1082/// For adding histogram ith labels one should use TH1::Merge
1083///
1084/// SPECIAL CASE (Average/Efficiency histograms)
1085/// For histograms representing averages or efficiencies, one should compute the average
1086/// of the two histograms and not the sum. One can mark a histogram to be an average
1087/// histogram by setting its bit kIsAverage with
1088/// myhist.SetBit(TH1::kIsAverage);
1089/// Note that the two histograms must have their kIsAverage bit set
1090///
1091/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
1092/// you should call Sumw2 before making this operation.
1093/// This is particularly important if you fit the histogram after TH1::Add
1094///
1095/// IMPORTANT NOTE2: You should be careful about the statistics of the
1096/// returned histogram, whose statistics may be binned or unbinned,
1097/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
1098/// and whether TH1::ResetStats has been called on either this or h1.
1099/// See TH1::GetStats.
1100///
1101/// ANOTHER SPECIAL CASE : h1 = h2 and c2 < 0
1102/// do a scaling this = c1 * h1 / (bin Volume)
1103///
1104/// The function returns kFALSE if the Add operation failed
1105
1107{
1108
1109 if (!h1 || !h2) {
1110 Error("Add","Attempt to add a non-existing histogram");
1111 return kFALSE;
1112 }
1113
1114 // delete buffer if it is there since it will become invalid
1115 if (fBuffer) BufferEmpty(1);
1116
1117 Bool_t normWidth = kFALSE;
1118 if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
1119
1120 if (h1 != h2) {
1121 bool useMerge = false;
1122 const bool considerMerge = (c1 == 1. && c2 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
1123
1124 // We can combine inconsistencies like this, since they are ordered and a
1125 // higher inconsistency is worse
1126 auto const inconsistency = std::max(LoggedInconsistency("Add", this, h1, considerMerge),
1127 LoggedInconsistency("Add", h1, h2, considerMerge));
1128
1129 // If there is a bad inconsistency and we can't even consider merging, just give up
1130 if(inconsistency >= kDifferentNumberOfBins && !considerMerge) {
1131 return false;
1132 }
1133 // If there is an inconsistency, we try to use merging
1134 if(inconsistency > kFullyConsistent) {
1135 useMerge = considerMerge;
1136 }
1137
1138 if (useMerge) {
1139 TList l;
1140 // why TList takes non-const pointers ????
1141 l.Add(const_cast<TH1*>(h1));
1142 l.Add(const_cast<TH1*>(h2));
1143 Reset("ICE");
1144 auto iret = Merge(&l);
1145 return (iret >= 0);
1146 }
1147 }
1148
1149 // Create Sumw2 if h1 or h2 have Sumw2 set
1150 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
1151
1152 // - Add statistics
1153 Double_t nEntries = TMath::Abs( c1*h1->GetEntries() + c2*h2->GetEntries() );
1154
1155 // TODO remove
1156 // statistics can be preserved only in case of positive coefficients
1157 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1158 // also in case of scaling with the width we cannot preserve the statistics
1159 Double_t s1[kNstat] = {0};
1160 Double_t s2[kNstat] = {0};
1161 Double_t s3[kNstat];
1162
1163
1164 Bool_t resetStats = (c1*c2 < 0) || normWidth;
1165 if (!resetStats) {
1166 // need to initialize to zero s1 and s2 since
1167 // GetStats fills only used elements depending on dimension and type
1168 h1->GetStats(s1);
1169 h2->GetStats(s2);
1170 for (Int_t i=0;i<kNstat;i++) {
1171 if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
1172 //else s3[i] = TMath::Abs(c1)*s1[i] + TMath::Abs(c2)*s2[i];
1173 else s3[i] = c1*s1[i] + c2*s2[i];
1174 }
1175 }
1176
1177 SetMinimum();
1178 SetMaximum();
1179
1180 if (normWidth) { // DEPRECATED CASE: belongs to fitting / drawing modules
1181
1182 Int_t nbinsx = GetNbinsX() + 2; // normal bins + underflow, overflow
1183 Int_t nbinsy = GetNbinsY() + 2;
1184 Int_t nbinsz = GetNbinsZ() + 2;
1185
1186 if (fDimension < 2) nbinsy = 1;
1187 if (fDimension < 3) nbinsz = 1;
1188
1189 Int_t bin, binx, biny, binz;
1190 for (binz = 0; binz < nbinsz; ++binz) {
1191 Double_t wz = h1->GetZaxis()->GetBinWidth(binz);
1192 for (biny = 0; biny < nbinsy; ++biny) {
1193 Double_t wy = h1->GetYaxis()->GetBinWidth(biny);
1194 for (binx = 0; binx < nbinsx; ++binx) {
1195 Double_t wx = h1->GetXaxis()->GetBinWidth(binx);
1196 bin = GetBin(binx, biny, binz);
1197 Double_t w = wx*wy*wz;
1198 UpdateBinContent(bin, c1 * h1->RetrieveBinContent(bin) / w);
1199 if (fSumw2.fN) {
1200 Double_t e1 = h1->GetBinError(bin)/w;
1201 fSumw2.fArray[bin] = c1*c1*e1*e1;
1202 }
1203 }
1204 }
1205 }
1206 } else if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
1207 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
1208 // special case where histograms have the kIsAverage bit set
1210 Double_t y2 = h2->RetrieveBinContent(i);
1212 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
1213 Double_t w1 = 1., w2 = 1.;
1214
1215 // consider all special cases when bin errors are zero
1216 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1217 if (e1sq) w1 = 1./ e1sq;
1218 else if (h1->fSumw2.fN) {
1219 w1 = 1.E200; // use an arbitrary huge value
1220 if (y1 == 0 ) { // use an estimated error from the global histogram scale
1221 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1222 w1 = 1./(sf*sf);
1223 }
1224 }
1225 if (e2sq) w2 = 1./ e2sq;
1226 else if (h2->fSumw2.fN) {
1227 w2 = 1.E200; // use an arbitrary huge value
1228 if (y2 == 0) { // use an estimated error from the global histogram scale
1229 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1230 w2 = 1./(sf*sf);
1231 }
1232 }
1233
1234 double y = (w1*y1 + w2*y2)/(w1 + w2);
1235 UpdateBinContent(i, y);
1236 if (fSumw2.fN) {
1237 double err2 = 1./(w1 + w2);
1238 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1239 fSumw2.fArray[i] = err2;
1240 }
1241 }
1242 } else { // case of simple histogram addition
1243 Double_t c1sq = c1 * c1;
1244 Double_t c2sq = c2 * c2;
1245 for (Int_t i = 0; i < fNcells; ++i) { // Loop on cells (bins including underflows/overflows)
1246 UpdateBinContent(i, c1 * h1->RetrieveBinContent(i) + c2 * h2->RetrieveBinContent(i));
1247 if (fSumw2.fN) {
1248 fSumw2.fArray[i] = c1sq * h1->GetBinErrorSqUnchecked(i) + c2sq * h2->GetBinErrorSqUnchecked(i);
1249 }
1250 }
1251 }
1252
1253 if (resetStats) {
1254 // statistics need to be reset in case coefficient are negative
1255 ResetStats();
1256 }
1257 else {
1258 // update statistics (do here to avoid changes by SetBinContent) FIXME remove???
1259 PutStats(s3);
1260 SetEntries(nEntries);
1261 }
1262
1263 return kTRUE;
1264}
1265
1266////////////////////////////////////////////////////////////////////////////////
1267/// Increment bin content by 1.
1268/// Passing an out-of-range bin leads to undefined behavior
1269
1271{
1272 AbstractMethod("AddBinContent");
1273}
1274
1275////////////////////////////////////////////////////////////////////////////////
1276/// Increment bin content by a weight w.
1277/// Passing an out-of-range bin leads to undefined behavior
1278
1280{
1281 AbstractMethod("AddBinContent");
1282}
1283
1284////////////////////////////////////////////////////////////////////////////////
1285/// Sets the flag controlling the automatic add of histograms in memory
1286///
1287/// By default (fAddDirectory = kTRUE), histograms are automatically added
1288/// to the list of objects in memory.
1289/// Note that one histogram can be removed from its support directory
1290/// by calling h->SetDirectory(nullptr) or h->SetDirectory(dir) to add it
1291/// to the list of objects in the directory dir.
1292///
1293/// NOTE that this is a static function. To call it, use;
1294/// TH1::AddDirectory
1295
1297{
1298 fgAddDirectory = add;
1299}
1300
1301////////////////////////////////////////////////////////////////////////////////
1302/// Auxiliary function to get the power of 2 next (larger) or previous (smaller)
1303/// a given x
1304///
1305/// next = kTRUE : next larger
1306/// next = kFALSE : previous smaller
1307///
1308/// Used by the autobin power of 2 algorithm
1309
1311{
1312 Int_t nn;
1313 Double_t f2 = std::frexp(x, &nn);
1314 return ((next && x > 0.) || (!next && x <= 0.)) ? std::ldexp(std::copysign(1., f2), nn)
1315 : std::ldexp(std::copysign(1., f2), --nn);
1316}
1317
1318////////////////////////////////////////////////////////////////////////////////
1319/// Auxiliary function to get the next power of 2 integer value larger then n
1320///
1321/// Used by the autobin power of 2 algorithm
1322
1324{
1325 Int_t nn;
1326 Double_t f2 = std::frexp(n, &nn);
1327 if (TMath::Abs(f2 - .5) > 0.001)
1328 return (Int_t)std::ldexp(1., nn);
1329 return n;
1330}
1331
1332////////////////////////////////////////////////////////////////////////////////
1333/// Buffer-based estimate of the histogram range using the power of 2 algorithm.
1334///
1335/// Used by the autobin power of 2 algorithm.
1336///
1337/// Works on arguments (min and max from fBuffer) and internal inputs: fXmin,
1338/// fXmax, NBinsX (from fXaxis), ...
1339/// Result save internally in fXaxis.
1340///
1341/// Overloaded by TH2 and TH3.
1342///
1343/// Return -1 if internal inputs are inconsistent, 0 otherwise.
1344
1346{
1347 // We need meaningful raw limits
1348 if (xmi >= xma)
1349 return -1;
1350
1352 Double_t xhmi = fXaxis.GetXmin();
1353 Double_t xhma = fXaxis.GetXmax();
1354
1355 // Now adjust
1356 if (TMath::Abs(xhma) > TMath::Abs(xhmi)) {
1357 // Start from the upper limit
1358 xhma = TH1::AutoP2GetPower2(xhma);
1359 xhmi = xhma - TH1::AutoP2GetPower2(xhma - xhmi);
1360 } else {
1361 // Start from the lower limit
1362 xhmi = TH1::AutoP2GetPower2(xhmi, kFALSE);
1363 xhma = xhmi + TH1::AutoP2GetPower2(xhma - xhmi);
1364 }
1365
1366 // Round the bins to the next power of 2; take into account the possible inflation
1367 // of the range
1368 Double_t rr = (xhma - xhmi) / (xma - xmi);
1369 Int_t nb = TH1::AutoP2GetBins((Int_t)(rr * GetNbinsX()));
1370
1371 // Adjust using the same bin width and offsets
1372 Double_t bw = (xhma - xhmi) / nb;
1373 // Bins to left free on each side
1374 Double_t autoside = gEnv->GetValue("Hist.Binning.Auto.Side", 0.05);
1375 Int_t nbside = (Int_t)(nb * autoside);
1376
1377 // Side up
1378 Int_t nbup = (xhma - xma) / bw;
1379 if (nbup % 2 != 0)
1380 nbup++; // Must be even
1381 if (nbup != nbside) {
1382 // Accounts also for both case: larger or smaller
1383 xhma -= bw * (nbup - nbside);
1384 nb -= (nbup - nbside);
1385 }
1386
1387 // Side low
1388 Int_t nblw = (xmi - xhmi) / bw;
1389 if (nblw % 2 != 0)
1390 nblw++; // Must be even
1391 if (nblw != nbside) {
1392 // Accounts also for both case: larger or smaller
1393 xhmi += bw * (nblw - nbside);
1394 nb -= (nblw - nbside);
1395 }
1396
1397 // Set everything and project
1398 SetBins(nb, xhmi, xhma);
1399
1400 // Done
1401 return 0;
1402}
1403
1404/// Fill histogram with all entries in the buffer.
1405///
1406/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
1407/// - action = 0 histogram is reset and filled from the buffer. When the histogram is filled from the
1408/// buffer the value fBuffer[0] is set to a negative number (= - number of entries)
1409/// When calling with action == 0 the histogram is NOT refilled when fBuffer[0] is < 0
1410/// While when calling with action = -1 the histogram is reset and ALWAYS refilled independently if
1411/// the histogram was filled before. This is needed when drawing the histogram
1412/// - action = 1 histogram is filled and buffer is deleted
1413/// The buffer is automatically deleted when filling the histogram and the entries is
1414/// larger than the buffer size
1415
1417{
1418 // do we need to compute the bin size?
1419 if (!fBuffer) return 0;
1420 Int_t nbentries = (Int_t)fBuffer[0];
1421
1422 // nbentries correspond to the number of entries of histogram
1423
1424 if (nbentries == 0) {
1425 // if action is 1 we delete the buffer
1426 // this will avoid infinite recursion
1427 if (action > 0) {
1428 delete [] fBuffer;
1429 fBuffer = nullptr;
1430 fBufferSize = 0;
1431 }
1432 return 0;
1433 }
1434 if (nbentries < 0 && action == 0) return 0; // case histogram has been already filled from the buffer
1435
1436 Double_t *buffer = fBuffer;
1437 if (nbentries < 0) {
1438 nbentries = -nbentries;
1439 // a reset might call BufferEmpty() giving an infinite recursion
1440 // Protect it by setting fBuffer = nullptr
1441 fBuffer = nullptr;
1442 //do not reset the list of functions
1443 Reset("ICES");
1444 fBuffer = buffer;
1445 }
1446 if (CanExtendAllAxes() || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
1447 //find min, max of entries in buffer
1450 for (Int_t i=0;i<nbentries;i++) {
1451 Double_t x = fBuffer[2*i+2];
1452 // skip infinity or NaN values
1453 if (!std::isfinite(x)) continue;
1454 if (x < xmin) xmin = x;
1455 if (x > xmax) xmax = x;
1456 }
1457 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
1458 Int_t rc = -1;
1460 if ((rc = AutoP2FindLimits(xmin, xmax)) < 0)
1461 Warning("BufferEmpty",
1462 "inconsistency found by power-of-2 autobin algorithm: fallback to standard method");
1463 }
1464 if (rc < 0)
1466 } else {
1467 fBuffer = nullptr;
1468 Int_t keep = fBufferSize; fBufferSize = 0;
1470 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax, &fXaxis);
1471 fBuffer = buffer;
1472 fBufferSize = keep;
1473 }
1474 }
1475
1476 // call DoFillN which will not put entries in the buffer as FillN does
1477 // set fBuffer to zero to avoid re-emptying the buffer from functions called
1478 // by DoFillN (e.g Sumw2)
1479 buffer = fBuffer; fBuffer = nullptr;
1480 DoFillN(nbentries,&buffer[2],&buffer[1],2);
1481 fBuffer = buffer;
1482
1483 // if action == 1 - delete the buffer
1484 if (action > 0) {
1485 delete [] fBuffer;
1486 fBuffer = nullptr;
1487 fBufferSize = 0;
1488 } else {
1489 // if number of entries is consistent with buffer - set it negative to avoid
1490 // refilling the histogram every time BufferEmpty(0) is called
1491 // In case it is not consistent, by setting fBuffer[0]=0 is like resetting the buffer
1492 // (it will not be used anymore the next time BufferEmpty is called)
1493 if (nbentries == (Int_t)fEntries)
1494 fBuffer[0] = -nbentries;
1495 else
1496 fBuffer[0] = 0;
1497 }
1498 return nbentries;
1499}
1500
1501////////////////////////////////////////////////////////////////////////////////
1502/// accumulate arguments in buffer. When buffer is full, empty the buffer
1503///
1504/// - `fBuffer[0]` = number of entries in buffer
1505/// - `fBuffer[1]` = w of first entry
1506/// - `fBuffer[2]` = x of first entry
1507
1509{
1510 if (!fBuffer) return -2;
1511 Int_t nbentries = (Int_t)fBuffer[0];
1512
1513
1514 if (nbentries < 0) {
1515 // reset nbentries to a positive value so next time BufferEmpty() is called
1516 // the histogram will be refilled
1517 nbentries = -nbentries;
1518 fBuffer[0] = nbentries;
1519 if (fEntries > 0) {
1520 // set fBuffer to zero to avoid calling BufferEmpty in Reset
1521 Double_t *buffer = fBuffer; fBuffer=nullptr;
1522 Reset("ICES"); // do not reset list of functions
1523 fBuffer = buffer;
1524 }
1525 }
1526 if (2*nbentries+2 >= fBufferSize) {
1527 BufferEmpty(1);
1528 if (!fBuffer)
1529 // to avoid infinite recursion Fill->BufferFill->Fill
1530 return Fill(x,w);
1531 // this cannot happen
1532 R__ASSERT(0);
1533 }
1534 fBuffer[2*nbentries+1] = w;
1535 fBuffer[2*nbentries+2] = x;
1536 fBuffer[0] += 1;
1537 return -2;
1538}
1539
1540////////////////////////////////////////////////////////////////////////////////
1541/// Check bin limits.
1542
1543bool TH1::CheckBinLimits(const TAxis* a1, const TAxis * a2)
1544{
1545 const TArrayD * h1Array = a1->GetXbins();
1546 const TArrayD * h2Array = a2->GetXbins();
1547 Int_t fN = h1Array->fN;
1548 if ( fN != 0 ) {
1549 if ( h2Array->fN != fN ) {
1550 return false;
1551 }
1552 else {
1553 for ( int i = 0; i < fN; ++i ) {
1554 // for i==fN (nbin+1) a->GetBinWidth() returns last bin width
1555 // we do not need to exclude that case
1556 double binWidth = a1->GetBinWidth(i);
1557 if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), binWidth*1E-10 ) ) {
1558 return false;
1559 }
1560 }
1561 }
1562 }
1563
1564 return true;
1565}
1566
1567////////////////////////////////////////////////////////////////////////////////
1568/// Check that axis have same labels.
1569
1570bool TH1::CheckBinLabels(const TAxis* a1, const TAxis * a2)
1571{
1572 THashList *l1 = a1->GetLabels();
1573 THashList *l2 = a2->GetLabels();
1574
1575 if (!l1 && !l2 )
1576 return true;
1577 if (!l1 || !l2 ) {
1578 return false;
1579 }
1580 // check now labels sizes are the same
1581 if (l1->GetSize() != l2->GetSize() ) {
1582 return false;
1583 }
1584 for (int i = 1; i <= a1->GetNbins(); ++i) {
1585 TString label1 = a1->GetBinLabel(i);
1586 TString label2 = a2->GetBinLabel(i);
1587 if (label1 != label2) {
1588 return false;
1589 }
1590 }
1591
1592 return true;
1593}
1594
1595////////////////////////////////////////////////////////////////////////////////
1596/// Check that the axis limits of the histograms are the same.
1597/// If a first and last bin is passed the axis is compared between the given range
1598
1599bool TH1::CheckAxisLimits(const TAxis *a1, const TAxis *a2 )
1600{
1601 double firstBin = a1->GetBinWidth(1);
1602 double lastBin = a1->GetBinWidth( a1->GetNbins() );
1603 if ( ! TMath::AreEqualAbs(a1->GetXmin(), a2->GetXmin(), firstBin* 1.E-10) ||
1604 ! TMath::AreEqualAbs(a1->GetXmax(), a2->GetXmax(), lastBin*1.E-10) ) {
1605 return false;
1606 }
1607 return true;
1608}
1609
1610////////////////////////////////////////////////////////////////////////////////
1611/// Check that the axis are the same
1612
1613bool TH1::CheckEqualAxes(const TAxis *a1, const TAxis *a2 )
1614{
1615 if (a1->GetNbins() != a2->GetNbins() ) {
1616 ::Info("CheckEqualAxes","Axes have different number of bins : nbin1 = %d nbin2 = %d",a1->GetNbins(),a2->GetNbins() );
1617 return false;
1618 }
1619 if(!CheckAxisLimits(a1,a2)) {
1620 ::Info("CheckEqualAxes","Axes have different limits");
1621 return false;
1622 }
1623 if(!CheckBinLimits(a1,a2)) {
1624 ::Info("CheckEqualAxes","Axes have different bin limits");
1625 return false;
1626 }
1627
1628 // check labels
1629 if(!CheckBinLabels(a1,a2)) {
1630 ::Info("CheckEqualAxes","Axes have different labels");
1631 return false;
1632 }
1633
1634 return true;
1635}
1636
1637////////////////////////////////////////////////////////////////////////////////
1638/// Check that two sub axis are the same.
1639/// The limits are defined by first bin and last bin
1640/// N.B. no check is done in this case for variable bins
1641
1642bool TH1::CheckConsistentSubAxes(const TAxis *a1, Int_t firstBin1, Int_t lastBin1, const TAxis * a2, Int_t firstBin2, Int_t lastBin2 )
1643{
1644 // By default is assumed that no bins are given for the second axis
1645 Int_t nbins1 = lastBin1-firstBin1 + 1;
1646 Double_t xmin1 = a1->GetBinLowEdge(firstBin1);
1647 Double_t xmax1 = a1->GetBinUpEdge(lastBin1);
1648
1649 Int_t nbins2 = a2->GetNbins();
1650 Double_t xmin2 = a2->GetXmin();
1651 Double_t xmax2 = a2->GetXmax();
1652
1653 if (firstBin2 < lastBin2) {
1654 // in this case assume no bins are given for the second axis
1655 nbins2 = lastBin1-firstBin1 + 1;
1656 xmin2 = a1->GetBinLowEdge(firstBin1);
1657 xmax2 = a1->GetBinUpEdge(lastBin1);
1658 }
1659
1660 if (nbins1 != nbins2 ) {
1661 ::Info("CheckConsistentSubAxes","Axes have different number of bins");
1662 return false;
1663 }
1664
1665 Double_t firstBin = a1->GetBinWidth(firstBin1);
1666 Double_t lastBin = a1->GetBinWidth(lastBin1);
1667 if ( ! TMath::AreEqualAbs(xmin1,xmin2,1.E-10 * firstBin) ||
1668 ! TMath::AreEqualAbs(xmax1,xmax2,1.E-10 * lastBin) ) {
1669 ::Info("CheckConsistentSubAxes","Axes have different limits");
1670 return false;
1671 }
1672
1673 return true;
1674}
1675
1676////////////////////////////////////////////////////////////////////////////////
1677/// Check histogram compatibility.
1678
1679int TH1::CheckConsistency(const TH1* h1, const TH1* h2)
1680{
1681 if (h1 == h2) return kFullyConsistent;
1682
1683 if (h1->GetDimension() != h2->GetDimension() ) {
1684 return kDifferentDimensions;
1685 }
1686 Int_t dim = h1->GetDimension();
1687
1688 // returns kTRUE if number of bins and bin limits are identical
1689 Int_t nbinsx = h1->GetNbinsX();
1690 Int_t nbinsy = h1->GetNbinsY();
1691 Int_t nbinsz = h1->GetNbinsZ();
1692
1693 // Check whether the histograms have the same number of bins.
1694 if (nbinsx != h2->GetNbinsX() ||
1695 (dim > 1 && nbinsy != h2->GetNbinsY()) ||
1696 (dim > 2 && nbinsz != h2->GetNbinsZ()) ) {
1697 return kDifferentNumberOfBins;
1698 }
1699
1700 bool ret = true;
1701
1702 // check axis limits
1703 ret &= CheckAxisLimits(h1->GetXaxis(), h2->GetXaxis());
1704 if (dim > 1) ret &= CheckAxisLimits(h1->GetYaxis(), h2->GetYaxis());
1705 if (dim > 2) ret &= CheckAxisLimits(h1->GetZaxis(), h2->GetZaxis());
1706 if (!ret) return kDifferentAxisLimits;
1707
1708 // check bin limits
1709 ret &= CheckBinLimits(h1->GetXaxis(), h2->GetXaxis());
1710 if (dim > 1) ret &= CheckBinLimits(h1->GetYaxis(), h2->GetYaxis());
1711 if (dim > 2) ret &= CheckBinLimits(h1->GetZaxis(), h2->GetZaxis());
1712 if (!ret) return kDifferentBinLimits;
1713
1714 // check labels if histograms are both not empty
1715 if ( !h1->IsEmpty() && !h2->IsEmpty() ) {
1716 ret &= CheckBinLabels(h1->GetXaxis(), h2->GetXaxis());
1717 if (dim > 1) ret &= CheckBinLabels(h1->GetYaxis(), h2->GetYaxis());
1718 if (dim > 2) ret &= CheckBinLabels(h1->GetZaxis(), h2->GetZaxis());
1719 if (!ret) return kDifferentLabels;
1720 }
1721
1722 return kFullyConsistent;
1723}
1724
1725////////////////////////////////////////////////////////////////////////////////
1726/// \f$ \chi^{2} \f$ test for comparing weighted and unweighted histograms.
1727///
1728/// Compares the histograms' adjusted (normalized) residuals.
1729/// Function: Returns p-value. Other return values are specified by the 3rd parameter
1730///
1731/// \param[in] h2 the second histogram
1732/// \param[in] option
1733/// - "UU" = experiment experiment comparison (unweighted-unweighted)
1734/// - "UW" = experiment MC comparison (unweighted-weighted). Note that
1735/// the first histogram should be unweighted
1736/// - "WW" = MC MC comparison (weighted-weighted)
1737/// - "NORM" = to be used when one or both of the histograms is scaled
1738/// but the histogram originally was unweighted
1739/// - by default underflows and overflows are not included:
1740/// * "OF" = overflows included
1741/// * "UF" = underflows included
1742/// - "P" = print chi2, ndf, p_value, igood
1743/// - "CHI2" = returns chi2 instead of p-value
1744/// - "CHI2/NDF" = returns \f$ \chi^{2} \f$/ndf
1745/// \param[in] res not empty - computes normalized residuals and returns them in this array
1746///
1747/// The current implementation is based on the papers \f$ \chi^{2} \f$ test for comparison
1748/// of weighted and unweighted histograms" in Proceedings of PHYSTAT05 and
1749/// "Comparison weighted and unweighted histograms", arXiv:physics/0605123
1750/// by N.Gagunashvili. This function has been implemented by Daniel Haertl in August 2006.
1751///
1752/// #### Introduction:
1753///
1754/// A frequently used technique in data analysis is the comparison of
1755/// histograms. First suggested by Pearson [1] the \f$ \chi^{2} \f$ test of
1756/// homogeneity is used widely for comparing usual (unweighted) histograms.
1757/// This paper describes the implementation modified \f$ \chi^{2} \f$ tests
1758/// for comparison of weighted and unweighted histograms and two weighted
1759/// histograms [2] as well as usual Pearson's \f$ \chi^{2} \f$ test for
1760/// comparison two usual (unweighted) histograms.
1761///
1762/// #### Overview:
1763///
1764/// Comparison of two histograms expect hypotheses that two histograms
1765/// represent identical distributions. To make a decision p-value should
1766/// be calculated. The hypotheses of identity is rejected if the p-value is
1767/// lower then some significance level. Traditionally significance levels
1768/// 0.1, 0.05 and 0.01 are used. The comparison procedure should include an
1769/// analysis of the residuals which is often helpful in identifying the
1770/// bins of histograms responsible for a significant overall \f$ \chi^{2} \f$ value.
1771/// Residuals are the difference between bin contents and expected bin
1772/// contents. Most convenient for analysis are the normalized residuals. If
1773/// hypotheses of identity are valid then normalized residuals are
1774/// approximately independent and identically distributed random variables
1775/// having N(0,1) distribution. Analysis of residuals expect test of above
1776/// mentioned properties of residuals. Notice that indirectly the analysis
1777/// of residuals increase the power of \f$ \chi^{2} \f$ test.
1778///
1779/// #### Methods of comparison:
1780///
1781/// \f$ \chi^{2} \f$ test for comparison two (unweighted) histograms:
1782/// Let us consider two histograms with the same binning and the number
1783/// of bins equal to r. Let us denote the number of events in the ith bin
1784/// in the first histogram as ni and as mi in the second one. The total
1785/// number of events in the first histogram is equal to:
1786/// \f[
1787/// N = \sum_{i=1}^{r} n_{i}
1788/// \f]
1789/// and
1790/// \f[
1791/// M = \sum_{i=1}^{r} m_{i}
1792/// \f]
1793/// in the second histogram. The hypothesis of identity (homogeneity) [3]
1794/// is that the two histograms represent random values with identical
1795/// distributions. It is equivalent that there exist r constants p1,...,pr,
1796/// such that
1797/// \f[
1798///\sum_{i=1}^{r} p_{i}=1
1799/// \f]
1800/// and the probability of belonging to the ith bin for some measured value
1801/// in both experiments is equal to pi. The number of events in the ith
1802/// bin is a random variable with a distribution approximated by a Poisson
1803/// probability distribution
1804/// \f[
1805///\frac{e^{-Np_{i}}(Np_{i})^{n_{i}}}{n_{i}!}
1806/// \f]
1807///for the first histogram and with distribution
1808/// \f[
1809///\frac{e^{-Mp_{i}}(Mp_{i})^{m_{i}}}{m_{i}!}
1810/// \f]
1811/// for the second histogram. If the hypothesis of homogeneity is valid,
1812/// then the maximum likelihood estimator of pi, i=1,...,r, is
1813/// \f[
1814///\hat{p}_{i}= \frac{n_{i}+m_{i}}{N+M}
1815/// \f]
1816/// and then
1817/// \f[
1818/// 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}}
1819/// \f]
1820/// has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [3].
1821/// The comparison procedure can include an analysis of the residuals which
1822/// is often helpful in identifying the bins of histograms responsible for
1823/// a significant overall \f$ \chi^{2} \f$ value. Most convenient for
1824/// analysis are the adjusted (normalized) residuals [4]
1825/// \f[
1826/// 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))}}
1827/// \f]
1828/// If hypotheses of homogeneity are valid then residuals ri are
1829/// approximately independent and identically distributed random variables
1830/// having N(0,1) distribution. The application of the \f$ \chi^{2} \f$ test has
1831/// restrictions related to the value of the expected frequencies Npi,
1832/// Mpi, i=1,...,r. A conservative rule formulated in [5] is that all the
1833/// expectations must be 1 or greater for both histograms. In practical
1834/// cases when expected frequencies are not known the estimated expected
1835/// frequencies \f$ M\hat{p}_{i}, N\hat{p}_{i}, i=1,...,r \f$ can be used.
1836///
1837/// #### Unweighted and weighted histograms comparison:
1838///
1839/// A simple modification of the ideas described above can be used for the
1840/// comparison of the usual (unweighted) and weighted histograms. Let us
1841/// denote the number of events in the ith bin in the unweighted
1842/// histogram as ni and the common weight of events in the ith bin of the
1843/// weighted histogram as wi. The total number of events in the
1844/// unweighted histogram is equal to
1845///\f[
1846/// N = \sum_{i=1}^{r} n_{i}
1847///\f]
1848/// and the total weight of events in the weighted histogram is equal to
1849///\f[
1850/// W = \sum_{i=1}^{r} w_{i}
1851///\f]
1852/// Let us formulate the hypothesis of identity of an unweighted histogram
1853/// to a weighted histogram so that there exist r constants p1,...,pr, such
1854/// that
1855///\f[
1856/// \sum_{i=1}^{r} p_{i} = 1
1857///\f]
1858/// for the unweighted histogram. The weight wi is a random variable with a
1859/// distribution approximated by the normal probability distribution
1860/// \f$ N(Wp_{i},\sigma_{i}^{2}) \f$ where \f$ \sigma_{i}^{2} \f$ is the variance of the weight wi.
1861/// If we replace the variance \f$ \sigma_{i}^{2} \f$
1862/// with estimate \f$ s_{i}^{2} \f$ (sum of squares of weights of
1863/// events in the ith bin) and the hypothesis of identity is valid, then the
1864/// maximum likelihood estimator of pi,i=1,...,r, is
1865///\f[
1866/// \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}}
1867///\f]
1868/// We may then use the test statistic
1869///\f[
1870/// 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}}
1871///\f]
1872/// and it has approximately a \f$ \sigma^{2}_{(r-1)} \f$ distribution [2]. This test, as well
1873/// as the original one [3], has a restriction on the expected frequencies. The
1874/// expected frequencies recommended for the weighted histogram is more than 25.
1875/// The value of the minimal expected frequency can be decreased down to 10 for
1876/// the case when the weights of the events are close to constant. In the case
1877/// of a weighted histogram if the number of events is unknown, then we can
1878/// apply this recommendation for the equivalent number of events as
1879///\f[
1880/// n_{i}^{equiv} = \frac{ w_{i}^{2} }{ s_{i}^{2} }
1881///\f]
1882/// The minimal expected frequency for an unweighted histogram must be 1. Notice
1883/// that any usual (unweighted) histogram can be considered as a weighted
1884/// histogram with events that have constant weights equal to 1.
1885/// The variance \f$ z_{i}^{2} \f$ of the difference between the weight wi
1886/// and the estimated expectation value of the weight is approximately equal to:
1887///\f[
1888/// 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}
1889///\f]
1890/// The residuals
1891///\f[
1892/// r_{i} = \frac{w_{i}-W\hat{p}_{i}}{z_{i}}
1893///\f]
1894/// have approximately a normal distribution with mean equal to 0 and standard
1895/// deviation equal to 1.
1896///
1897/// #### Two weighted histograms comparison:
1898///
1899/// Let us denote the common weight of events of the ith bin in the first
1900/// histogram as w1i and as w2i in the second one. The total weight of events
1901/// in the first histogram is equal to
1902///\f[
1903/// W_{1} = \sum_{i=1}^{r} w_{1i}
1904///\f]
1905/// and
1906///\f[
1907/// W_{2} = \sum_{i=1}^{r} w_{2i}
1908///\f]
1909/// in the second histogram. Let us formulate the hypothesis of identity of
1910/// weighted histograms so that there exist r constants p1,...,pr, such that
1911///\f[
1912/// \sum_{i=1}^{r} p_{i} = 1
1913///\f]
1914/// and also expectation value of weight w1i equal to W1pi and expectation value
1915/// of weight w2i equal to W2pi. Weights in both the histograms are random
1916/// variables with distributions which can be approximated by a normal
1917/// probability distribution \f$ N(W_{1}p_{i},\sigma_{1i}^{2}) \f$ for the first histogram
1918/// and by a distribution \f$ N(W_{2}p_{i},\sigma_{2i}^{2}) \f$ for the second.
1919/// Here \f$ \sigma_{1i}^{2} \f$ and \f$ \sigma_{2i}^{2} \f$ are the variances
1920/// of w1i and w2i with estimators \f$ s_{1i}^{2} \f$ and \f$ s_{2i}^{2} \f$ respectively.
1921/// If the hypothesis of identity is valid, then the maximum likelihood and
1922/// Least Square Method estimator of pi,i=1,...,r, is
1923///\f[
1924/// \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}}
1925///\f]
1926/// We may then use the test statistic
1927///\f[
1928/// 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}}
1929///\f]
1930/// and it has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [2].
1931/// The normalized or studentised residuals [6]
1932///\f[
1933/// 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})}}}
1934///\f]
1935/// have approximately a normal distribution with mean equal to 0 and standard
1936/// deviation 1. A recommended minimal expected frequency is equal to 10 for
1937/// the proposed test.
1938///
1939/// #### Numerical examples:
1940///
1941/// The method described herein is now illustrated with an example.
1942/// We take a distribution
1943///\f[
1944/// \phi(x) = \frac{2}{(x-10)^{2}+1} + \frac{1}{(x-14)^{2}+1} (1)
1945///\f]
1946/// defined on the interval [4,16]. Events distributed according to the formula
1947/// (1) are simulated to create the unweighted histogram. Uniformly distributed
1948/// events are simulated for the weighted histogram with weights calculated by
1949/// formula (1). Each histogram has the same number of bins: 20. Fig.1 shows
1950/// the result of comparison of the unweighted histogram with 200 events
1951/// (minimal expected frequency equal to one) and the weighted histogram with
1952/// 500 events (minimal expected frequency equal to 25)
1953/// Begin_Macro
1954/// ../../../tutorials/math/chi2test.C
1955/// End_Macro
1956/// Fig 1. An example of comparison of the unweighted histogram with 200 events
1957/// and the weighted histogram with 500 events:
1958/// 1. unweighted histogram;
1959/// 2. weighted histogram;
1960/// 3. normalized residuals plot;
1961/// 4. normal Q-Q plot of residuals.
1962///
1963/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1964/// 21.09 with p-value equal to 0.33, therefore the hypothesis of identity of
1965/// the two histograms can be accepted for 0.05 significant level. The behavior
1966/// of the normalized residuals plot (see Fig. 1c) and the normal Q-Q plot
1967/// (see Fig. 1d) of residuals are regular and we cannot identify the outliers
1968/// or bins with a big influence on \f$ \chi^{2} \f$.
1969///
1970/// The second example presents the same two histograms but 17 events was added
1971/// to content of bin number 15 in unweighted histogram. Fig.2 shows the result
1972/// of comparison of the unweighted histogram with 217 events (minimal expected
1973/// frequency equal to one) and the weighted histogram with 500 events (minimal
1974/// expected frequency equal to 25)
1975/// Begin_Macro
1976/// ../../../tutorials/math/chi2test.C(17)
1977/// End_Macro
1978/// Fig 2. An example of comparison of the unweighted histogram with 217 events
1979/// and the weighted histogram with 500 events:
1980/// 1. unweighted histogram;
1981/// 2. weighted histogram;
1982/// 3. normalized residuals plot;
1983/// 4. normal Q-Q plot of residuals.
1984///
1985/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1986/// 32.33 with p-value equal to 0.029, therefore the hypothesis of identity of
1987/// the two histograms is rejected for 0.05 significant level. The behavior of
1988/// the normalized residuals plot (see Fig. 2c) and the normal Q-Q plot (see
1989/// Fig. 2d) of residuals are not regular and we can identify the outlier or
1990/// bin with a big influence on \f$ \chi^{2} \f$.
1991///
1992/// #### References:
1993///
1994/// - [1] Pearson, K., 1904. On the Theory of Contingency and Its Relation to
1995/// Association and Normal Correlation. Drapers' Co. Memoirs, Biometric
1996/// Series No. 1, London.
1997/// - [2] Gagunashvili, N., 2006. \f$ \sigma^{2} \f$ test for comparison
1998/// of weighted and unweighted histograms. Statistical Problems in Particle
1999/// Physics, Astrophysics and Cosmology, Proceedings of PHYSTAT05,
2000/// Oxford, UK, 12-15 September 2005, Imperial College Press, London, 43-44.
2001/// Gagunashvili,N., Comparison of weighted and unweighted histograms,
2002/// arXiv:physics/0605123, 2006.
2003/// - [3] Cramer, H., 1946. Mathematical methods of statistics.
2004/// Princeton University Press, Princeton.
2005/// - [4] Haberman, S.J., 1973. The analysis of residuals in cross-classified tables.
2006/// Biometrics 29, 205-220.
2007/// - [5] Lewontin, R.C. and Felsenstein, J., 1965. The robustness of homogeneity
2008/// test in 2xN tables. Biometrics 21, 19-33.
2009/// - [6] Seber, G.A.F., Lee, A.J., 2003, Linear Regression Analysis.
2010/// John Wiley & Sons Inc., New York.
2011
2012Double_t TH1::Chi2Test(const TH1* h2, Option_t *option, Double_t *res) const
2013{
2014 Double_t chi2 = 0;
2015 Int_t ndf = 0, igood = 0;
2016
2017 TString opt = option;
2018 opt.ToUpper();
2019
2020 Double_t prob = Chi2TestX(h2,chi2,ndf,igood,option,res);
2021
2022 if(opt.Contains("P")) {
2023 printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
2024 }
2025 if(opt.Contains("CHI2/NDF")) {
2026 if (ndf == 0) return 0;
2027 return chi2/ndf;
2028 }
2029 if(opt.Contains("CHI2")) {
2030 return chi2;
2031 }
2032
2033 return prob;
2034}
2035
2036////////////////////////////////////////////////////////////////////////////////
2037/// The computation routine of the Chisquare test. For the method description,
2038/// see Chi2Test() function.
2039///
2040/// \return p-value
2041/// \param[in] h2 the second histogram
2042/// \param[in] option
2043/// - "UU" = experiment experiment comparison (unweighted-unweighted)
2044/// - "UW" = experiment MC comparison (unweighted-weighted). Note that the first
2045/// histogram should be unweighted
2046/// - "WW" = MC MC comparison (weighted-weighted)
2047/// - "NORM" = if one or both histograms is scaled
2048/// - "OF" = overflows included
2049/// - "UF" = underflows included
2050/// by default underflows and overflows are not included
2051/// \param[out] igood test output
2052/// - igood=0 - no problems
2053/// - For unweighted unweighted comparison
2054/// - igood=1'There is a bin in the 1st histogram with less than 1 event'
2055/// - igood=2'There is a bin in the 2nd histogram with less than 1 event'
2056/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2057/// - For unweighted weighted comparison
2058/// - igood=1'There is a bin in the 1st histogram with less then 1 event'
2059/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective number of events'
2060/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2061/// - For weighted weighted comparison
2062/// - igood=1'There is a bin in the 1st histogram with less then 10 effective
2063/// number of events'
2064/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective
2065/// number of events'
2066/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2067/// \param[out] chi2 chisquare of the test
2068/// \param[out] ndf number of degrees of freedom (important, when both histograms have the same empty bins)
2069/// \param[out] res normalized residuals for further analysis
2070
2071Double_t TH1::Chi2TestX(const TH1* h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option, Double_t *res) const
2072{
2073
2074 Int_t i_start, i_end;
2075 Int_t j_start, j_end;
2076 Int_t k_start, k_end;
2077
2078 Double_t sum1 = 0.0, sumw1 = 0.0;
2079 Double_t sum2 = 0.0, sumw2 = 0.0;
2080
2081 chi2 = 0.0;
2082 ndf = 0;
2083
2084 TString opt = option;
2085 opt.ToUpper();
2086
2087 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
2088
2089 const TAxis *xaxis1 = GetXaxis();
2090 const TAxis *xaxis2 = h2->GetXaxis();
2091 const TAxis *yaxis1 = GetYaxis();
2092 const TAxis *yaxis2 = h2->GetYaxis();
2093 const TAxis *zaxis1 = GetZaxis();
2094 const TAxis *zaxis2 = h2->GetZaxis();
2095
2096 Int_t nbinx1 = xaxis1->GetNbins();
2097 Int_t nbinx2 = xaxis2->GetNbins();
2098 Int_t nbiny1 = yaxis1->GetNbins();
2099 Int_t nbiny2 = yaxis2->GetNbins();
2100 Int_t nbinz1 = zaxis1->GetNbins();
2101 Int_t nbinz2 = zaxis2->GetNbins();
2102
2103 //check dimensions
2104 if (this->GetDimension() != h2->GetDimension() ){
2105 Error("Chi2TestX","Histograms have different dimensions.");
2106 return 0.0;
2107 }
2108
2109 //check number of channels
2110 if (nbinx1 != nbinx2) {
2111 Error("Chi2TestX","different number of x channels");
2112 }
2113 if (nbiny1 != nbiny2) {
2114 Error("Chi2TestX","different number of y channels");
2115 }
2116 if (nbinz1 != nbinz2) {
2117 Error("Chi2TestX","different number of z channels");
2118 }
2119
2120 //check for ranges
2121 i_start = j_start = k_start = 1;
2122 i_end = nbinx1;
2123 j_end = nbiny1;
2124 k_end = nbinz1;
2125
2126 if (xaxis1->TestBit(TAxis::kAxisRange)) {
2127 i_start = xaxis1->GetFirst();
2128 i_end = xaxis1->GetLast();
2129 }
2130 if (yaxis1->TestBit(TAxis::kAxisRange)) {
2131 j_start = yaxis1->GetFirst();
2132 j_end = yaxis1->GetLast();
2133 }
2134 if (zaxis1->TestBit(TAxis::kAxisRange)) {
2135 k_start = zaxis1->GetFirst();
2136 k_end = zaxis1->GetLast();
2137 }
2138
2139
2140 if (opt.Contains("OF")) {
2141 if (GetDimension() == 3) k_end = ++nbinz1;
2142 if (GetDimension() >= 2) j_end = ++nbiny1;
2143 if (GetDimension() >= 1) i_end = ++nbinx1;
2144 }
2145
2146 if (opt.Contains("UF")) {
2147 if (GetDimension() == 3) k_start = 0;
2148 if (GetDimension() >= 2) j_start = 0;
2149 if (GetDimension() >= 1) i_start = 0;
2150 }
2151
2152 ndf = (i_end - i_start + 1) * (j_end - j_start + 1) * (k_end - k_start + 1) - 1;
2153
2154 Bool_t comparisonUU = opt.Contains("UU");
2155 Bool_t comparisonUW = opt.Contains("UW");
2156 Bool_t comparisonWW = opt.Contains("WW");
2157 Bool_t scaledHistogram = opt.Contains("NORM");
2158
2159 if (scaledHistogram && !comparisonUU) {
2160 Info("Chi2TestX", "NORM option should be used together with UU option. It is ignored");
2161 }
2162
2163 // look at histo global bin content and effective entries
2164 Stat_t s[kNstat];
2165 GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2166 Double_t sumBinContent1 = s[0];
2167 Double_t effEntries1 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2168
2169 h2->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2170 Double_t sumBinContent2 = s[0];
2171 Double_t effEntries2 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2172
2173 if (!comparisonUU && !comparisonUW && !comparisonWW ) {
2174 // deduce automatically from type of histogram
2175 if (TMath::Abs(sumBinContent1 - effEntries1) < 1) {
2176 if ( TMath::Abs(sumBinContent2 - effEntries2) < 1) comparisonUU = true;
2177 else comparisonUW = true;
2178 }
2179 else comparisonWW = true;
2180 }
2181 // check unweighted histogram
2182 if (comparisonUW) {
2183 if (TMath::Abs(sumBinContent1 - effEntries1) >= 1) {
2184 Warning("Chi2TestX","First histogram is not unweighted and option UW has been requested");
2185 }
2186 }
2187 if ( (!scaledHistogram && comparisonUU) ) {
2188 if ( ( TMath::Abs(sumBinContent1 - effEntries1) >= 1) || (TMath::Abs(sumBinContent2 - effEntries2) >= 1) ) {
2189 Warning("Chi2TestX","Both histograms are not unweighted and option UU has been requested");
2190 }
2191 }
2192
2193
2194 //get number of events in histogram
2195 if (comparisonUU && scaledHistogram) {
2196 for (Int_t i = i_start; i <= i_end; ++i) {
2197 for (Int_t j = j_start; j <= j_end; ++j) {
2198 for (Int_t k = k_start; k <= k_end; ++k) {
2199
2200 Int_t bin = GetBin(i, j, k);
2201
2202 Double_t cnt1 = RetrieveBinContent(bin);
2203 Double_t cnt2 = h2->RetrieveBinContent(bin);
2204 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2205 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2206
2207 if (e1sq > 0.0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2208 else cnt1 = 0.0;
2209
2210 if (e2sq > 0.0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2211 else cnt2 = 0.0;
2212
2213 // sum contents
2214 sum1 += cnt1;
2215 sum2 += cnt2;
2216 sumw1 += e1sq;
2217 sumw2 += e2sq;
2218 }
2219 }
2220 }
2221 if (sumw1 <= 0.0 || sumw2 <= 0.0) {
2222 Error("Chi2TestX", "Cannot use option NORM when one histogram has all zero errors");
2223 return 0.0;
2224 }
2225
2226 } else {
2227 for (Int_t i = i_start; i <= i_end; ++i) {
2228 for (Int_t j = j_start; j <= j_end; ++j) {
2229 for (Int_t k = k_start; k <= k_end; ++k) {
2230
2231 Int_t bin = GetBin(i, j, k);
2232
2233 sum1 += RetrieveBinContent(bin);
2234 sum2 += h2->RetrieveBinContent(bin);
2235
2236 if ( comparisonWW ) sumw1 += GetBinErrorSqUnchecked(bin);
2237 if ( comparisonUW || comparisonWW ) sumw2 += h2->GetBinErrorSqUnchecked(bin);
2238 }
2239 }
2240 }
2241 }
2242 //checks that the histograms are not empty
2243 if (sum1 == 0.0 || sum2 == 0.0) {
2244 Error("Chi2TestX","one histogram is empty");
2245 return 0.0;
2246 }
2247
2248 if ( comparisonWW && ( sumw1 <= 0.0 && sumw2 <= 0.0 ) ){
2249 Error("Chi2TestX","Hist1 and Hist2 have both all zero errors\n");
2250 return 0.0;
2251 }
2252
2253 //THE TEST
2254 Int_t m = 0, n = 0;
2255
2256 //Experiment - experiment comparison
2257 if (comparisonUU) {
2258 Double_t sum = sum1 + sum2;
2259 for (Int_t i = i_start; i <= i_end; ++i) {
2260 for (Int_t j = j_start; j <= j_end; ++j) {
2261 for (Int_t k = k_start; k <= k_end; ++k) {
2262
2263 Int_t bin = GetBin(i, j, k);
2264
2265 Double_t cnt1 = RetrieveBinContent(bin);
2266 Double_t cnt2 = h2->RetrieveBinContent(bin);
2267
2268 if (scaledHistogram) {
2269 // scale bin value to effective bin entries
2270 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2271 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2272
2273 if (e1sq > 0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2274 else cnt1 = 0;
2275
2276 if (e2sq > 0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2277 else cnt2 = 0;
2278 }
2279
2280 if (Int_t(cnt1) == 0 && Int_t(cnt2) == 0) --ndf; // no data means one degree of freedom less
2281 else {
2282
2283 Double_t cntsum = cnt1 + cnt2;
2284 Double_t nexp1 = cntsum * sum1 / sum;
2285 //Double_t nexp2 = binsum*sum2/sum;
2286
2287 if (res) res[i - i_start] = (cnt1 - nexp1) / TMath::Sqrt(nexp1);
2288
2289 if (cnt1 < 1) ++m;
2290 if (cnt2 < 1) ++n;
2291
2292 //Habermann correction for residuals
2293 Double_t correc = (1. - sum1 / sum) * (1. - cntsum / sum);
2294 if (res) res[i - i_start] /= TMath::Sqrt(correc);
2295
2296 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2297 chi2 += delta * delta / cntsum;
2298 }
2299 }
2300 }
2301 }
2302 chi2 /= sum1 * sum2;
2303
2304 // flag error only when of the two histogram is zero
2305 if (m) {
2306 igood += 1;
2307 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2308 }
2309 if (n) {
2310 igood += 2;
2311 Info("Chi2TestX","There is a bin in h2 with less than 1 event.\n");
2312 }
2313
2314 Double_t prob = TMath::Prob(chi2,ndf);
2315 return prob;
2316
2317 }
2318
2319 // unweighted - weighted comparison
2320 // case of error = 0 and content not zero is treated without problems by excluding second chi2 sum
2321 // and can be considered as a data-theory comparison
2322 if ( comparisonUW ) {
2323 for (Int_t i = i_start; i <= i_end; ++i) {
2324 for (Int_t j = j_start; j <= j_end; ++j) {
2325 for (Int_t k = k_start; k <= k_end; ++k) {
2326
2327 Int_t bin = GetBin(i, j, k);
2328
2329 Double_t cnt1 = RetrieveBinContent(bin);
2330 Double_t cnt2 = h2->RetrieveBinContent(bin);
2331 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2332
2333 // case both histogram have zero bin contents
2334 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2335 --ndf; //no data means one degree of freedom less
2336 continue;
2337 }
2338
2339 // case weighted histogram has zero bin content and error
2340 if (cnt2 * cnt2 == 0 && e2sq == 0) {
2341 if (sumw2 > 0) {
2342 // use as approximated error as 1 scaled by a scaling ratio
2343 // estimated from the total sum weight and sum weight squared
2344 e2sq = sumw2 / sum2;
2345 }
2346 else {
2347 // return error because infinite discrepancy here:
2348 // bin1 != 0 and bin2 =0 in a histogram with all errors zero
2349 Error("Chi2TestX","Hist2 has in bin (%d,%d,%d) zero content and zero errors\n", i, j, k);
2350 chi2 = 0; return 0;
2351 }
2352 }
2353
2354 if (cnt1 < 1) m++;
2355 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2356
2357 Double_t var1 = sum2 * cnt2 - sum1 * e2sq;
2358 Double_t var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2359
2360 // if cnt1 is zero and cnt2 = 1 and sum1 = sum2 var1 = 0 && var2 == 0
2361 // approximate by incrementing cnt1
2362 // LM (this need to be fixed for numerical errors)
2363 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2364 sum1++;
2365 cnt1++;
2366 var1 = sum2 * cnt2 - sum1 * e2sq;
2367 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2368 }
2369 var2 = TMath::Sqrt(var2);
2370
2371 while (var1 + var2 == 0) {
2372 sum1++;
2373 cnt1++;
2374 var1 = sum2 * cnt2 - sum1 * e2sq;
2375 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2376 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2377 sum1++;
2378 cnt1++;
2379 var1 = sum2 * cnt2 - sum1 * e2sq;
2380 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2381 }
2382 var2 = TMath::Sqrt(var2);
2383 }
2384
2385 Double_t probb = (var1 + var2) / (2. * sum2 * sum2);
2386
2387 Double_t nexp1 = probb * sum1;
2388 Double_t nexp2 = probb * sum2;
2389
2390 Double_t delta1 = cnt1 - nexp1;
2391 Double_t delta2 = cnt2 - nexp2;
2392
2393 chi2 += delta1 * delta1 / nexp1;
2394
2395 if (e2sq > 0) {
2396 chi2 += delta2 * delta2 / e2sq;
2397 }
2398
2399 if (res) {
2400 if (e2sq > 0) {
2401 Double_t temp1 = sum2 * e2sq / var2;
2402 Double_t temp2 = 1.0 + (sum1 * e2sq - sum2 * cnt2) / var2;
2403 temp2 = temp1 * temp1 * sum1 * probb * (1.0 - probb) + temp2 * temp2 * e2sq / 4.0;
2404 // invert sign here
2405 res[i - i_start] = - delta2 / TMath::Sqrt(temp2);
2406 }
2407 else
2408 res[i - i_start] = delta1 / TMath::Sqrt(nexp1);
2409 }
2410 }
2411 }
2412 }
2413
2414 if (m) {
2415 igood += 1;
2416 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2417 }
2418 if (n) {
2419 igood += 2;
2420 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2421 }
2422
2423 Double_t prob = TMath::Prob(chi2, ndf);
2424
2425 return prob;
2426 }
2427
2428 // weighted - weighted comparison
2429 if (comparisonWW) {
2430 for (Int_t i = i_start; i <= i_end; ++i) {
2431 for (Int_t j = j_start; j <= j_end; ++j) {
2432 for (Int_t k = k_start; k <= k_end; ++k) {
2433
2434 Int_t bin = GetBin(i, j, k);
2435 Double_t cnt1 = RetrieveBinContent(bin);
2436 Double_t cnt2 = h2->RetrieveBinContent(bin);
2437 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2438 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2439
2440 // case both histogram have zero bin contents
2441 // (use square of content to avoid numerical errors)
2442 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2443 --ndf; //no data means one degree of freedom less
2444 continue;
2445 }
2446
2447 if (e1sq == 0 && e2sq == 0) {
2448 // cannot treat case of booth histogram have zero zero errors
2449 Error("Chi2TestX","h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
2450 chi2 = 0; return 0;
2451 }
2452
2453 Double_t sigma = sum1 * sum1 * e2sq + sum2 * sum2 * e1sq;
2454 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2455 chi2 += delta * delta / sigma;
2456
2457 if (res) {
2458 Double_t temp = cnt1 * sum1 * e2sq + cnt2 * sum2 * e1sq;
2459 Double_t probb = temp / sigma;
2460 Double_t z = 0;
2461 if (e1sq > e2sq) {
2462 Double_t d1 = cnt1 - sum1 * probb;
2463 Double_t s1 = e1sq * ( 1. - e2sq * sum1 * sum1 / sigma );
2464 z = d1 / TMath::Sqrt(s1);
2465 }
2466 else {
2467 Double_t d2 = cnt2 - sum2 * probb;
2468 Double_t s2 = e2sq * ( 1. - e1sq * sum2 * sum2 / sigma );
2469 z = -d2 / TMath::Sqrt(s2);
2470 }
2471 res[i - i_start] = z;
2472 }
2473
2474 if (e1sq > 0 && cnt1 * cnt1 / e1sq < 10) m++;
2475 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2476 }
2477 }
2478 }
2479 if (m) {
2480 igood += 1;
2481 Info("Chi2TestX","There is a bin in h1 with less than 10 effective events.\n");
2482 }
2483 if (n) {
2484 igood += 2;
2485 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2486 }
2487 Double_t prob = TMath::Prob(chi2, ndf);
2488 return prob;
2489 }
2490 return 0;
2491}
2492////////////////////////////////////////////////////////////////////////////////
2493/// Compute and return the chisquare of this histogram with respect to a function
2494/// The chisquare is computed by weighting each histogram point by the bin error
2495/// By default the full range of the histogram is used.
2496/// Use option "R" for restricting the chisquare calculation to the given range of the function
2497/// Use option "L" for using the chisquare based on the poisson likelihood (Baker-Cousins Chisquare)
2498/// Use option "P" for using the Pearson chisquare based on the expected bin errors
2499
2501{
2502 if (!func) {
2503 Error("Chisquare","Function pointer is Null - return -1");
2504 return -1;
2505 }
2506
2507 TString opt(option); opt.ToUpper();
2508 bool useRange = opt.Contains("R");
2509 ROOT::Fit::EChisquareType type = ROOT::Fit::EChisquareType::kNeyman; // default chi2 with observed error
2512
2513 return ROOT::Fit::Chisquare(*this, *func, useRange, type);
2514}
2515
2516////////////////////////////////////////////////////////////////////////////////
2517/// Remove all the content from the underflow and overflow bins, without changing the number of entries
2518/// After calling this method, every undeflow and overflow bins will have content 0.0
2519/// The Sumw2 is also cleared, since there is no more content in the bins
2520
2522{
2523 for (Int_t bin = 0; bin < fNcells; ++bin)
2524 if (IsBinUnderflow(bin) || IsBinOverflow(bin)) {
2525 UpdateBinContent(bin, 0.0);
2526 if (fSumw2.fN) fSumw2.fArray[bin] = 0.0;
2527 }
2528}
2529
2530////////////////////////////////////////////////////////////////////////////////
2531/// Compute integral (normalized cumulative sum of bins) w/o under/overflows
2532/// The result is stored in fIntegral and used by the GetRandom functions.
2533/// This function is automatically called by GetRandom when the fIntegral
2534/// array does not exist or when the number of entries in the histogram
2535/// has changed since the previous call to GetRandom.
2536/// The resulting integral is normalized to 1.
2537/// If the routine is called with the onlyPositive flag set an error will
2538/// be produced in case of negative bin content and a NaN value returned
2539/// \return 1 if success, 0 if integral is zero, NAN if onlyPositive-test fails
2540
2542{
2543 if (fBuffer) BufferEmpty();
2544
2545 // delete previously computed integral (if any)
2546 if (fIntegral) delete [] fIntegral;
2547
2548 // - Allocate space to store the integral and compute integral
2549 Int_t nbinsx = GetNbinsX();
2550 Int_t nbinsy = GetNbinsY();
2551 Int_t nbinsz = GetNbinsZ();
2552 Int_t nbins = nbinsx * nbinsy * nbinsz;
2553
2554 fIntegral = new Double_t[nbins + 2];
2555 Int_t ibin = 0; fIntegral[ibin] = 0;
2556
2557 for (Int_t binz=1; binz <= nbinsz; ++binz) {
2558 for (Int_t biny=1; biny <= nbinsy; ++biny) {
2559 for (Int_t binx=1; binx <= nbinsx; ++binx) {
2560 ++ibin;
2561 Double_t y = RetrieveBinContent(GetBin(binx, biny, binz));
2562 if (onlyPositive && y < 0) {
2563 Error("ComputeIntegral","Bin content is negative - return a NaN value");
2564 fIntegral[nbins] = TMath::QuietNaN();
2565 break;
2566 }
2567 fIntegral[ibin] = fIntegral[ibin - 1] + y;
2568 }
2569 }
2570 }
2571
2572 // - Normalize integral to 1
2573 if (fIntegral[nbins] == 0 ) {
2574 Error("ComputeIntegral", "Integral = 0, no hits in histogram bins (excluding over/underflow).");
2575 return 0;
2576 }
2577 for (Int_t bin=1; bin <= nbins; ++bin) fIntegral[bin] /= fIntegral[nbins];
2578 fIntegral[nbins+1] = fEntries;
2579 return fIntegral[nbins];
2580}
2581
2582////////////////////////////////////////////////////////////////////////////////
2583/// Return a pointer to the array of bins integral.
2584/// if the pointer fIntegral is null, TH1::ComputeIntegral is called
2585/// The array dimension is the number of bins in the histograms
2586/// including underflow and overflow (fNCells)
2587/// the last value integral[fNCells] is set to the number of entries of
2588/// the histogram
2589
2591{
2592 if (!fIntegral) ComputeIntegral();
2593 return fIntegral;
2594}
2595
2596////////////////////////////////////////////////////////////////////////////////
2597/// Return a pointer to a histogram containing the cumulative content.
2598/// The cumulative can be computed both in the forward (default) or backward
2599/// direction; the name of the new histogram is constructed from
2600/// the name of this histogram with the suffix "suffix" appended provided
2601/// by the user. If not provided a default suffix="_cumulative" is used.
2602///
2603/// The cumulative distribution is formed by filling each bin of the
2604/// resulting histogram with the sum of that bin and all previous
2605/// (forward == kTRUE) or following (forward = kFALSE) bins.
2606///
2607/// Note: while cumulative distributions make sense in one dimension, you
2608/// may not be getting what you expect in more than 1D because the concept
2609/// of a cumulative distribution is much trickier to define; make sure you
2610/// understand the order of summation before you use this method with
2611/// histograms of dimension >= 2.
2612///
2613/// Note 2: By default the cumulative is computed from bin 1 to Nbins
2614/// If an axis range is set, values between the minimum and maximum of the range
2615/// are set.
2616/// Setting an axis range can also be used for including underflow and overflow in
2617/// the cumulative (e.g. by setting h->GetXaxis()->SetRange(0, h->GetNbinsX()+1); )
2619
2620TH1 *TH1::GetCumulative(Bool_t forward, const char* suffix) const
2621{
2622 const Int_t firstX = fXaxis.GetFirst();
2623 const Int_t lastX = fXaxis.GetLast();
2624 const Int_t firstY = (fDimension > 1) ? fYaxis.GetFirst() : 1;
2625 const Int_t lastY = (fDimension > 1) ? fYaxis.GetLast() : 1;
2626 const Int_t firstZ = (fDimension > 1) ? fZaxis.GetFirst() : 1;
2627 const Int_t lastZ = (fDimension > 1) ? fZaxis.GetLast() : 1;
2628
2629 TH1* hintegrated = (TH1*) Clone(fName + suffix);
2630 hintegrated->Reset();
2631 Double_t sum = 0.;
2632 Double_t esum = 0;
2633 if (forward) { // Forward computation
2634 for (Int_t binz = firstZ; binz <= lastZ; ++binz) {
2635 for (Int_t biny = firstY; biny <= lastY; ++biny) {
2636 for (Int_t binx = firstX; binx <= lastX; ++binx) {
2637 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2638 sum += RetrieveBinContent(bin);
2639 hintegrated->AddBinContent(bin, sum);
2640 if (fSumw2.fN) {
2641 esum += GetBinErrorSqUnchecked(bin);
2642 hintegrated->fSumw2.fArray[bin] = esum;
2643 }
2644 }
2645 }
2646 }
2647 } else { // Backward computation
2648 for (Int_t binz = lastZ; binz >= firstZ; --binz) {
2649 for (Int_t biny = lastY; biny >= firstY; --biny) {
2650 for (Int_t binx = lastX; binx >= firstX; --binx) {
2651 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2652 sum += RetrieveBinContent(bin);
2653 hintegrated->AddBinContent(bin, sum);
2654 if (fSumw2.fN) {
2655 esum += GetBinErrorSqUnchecked(bin);
2656 hintegrated->fSumw2.fArray[bin] = esum;
2657 }
2658 }
2659 }
2660 }
2661 }
2662 return hintegrated;
2663}
2664
2665////////////////////////////////////////////////////////////////////////////////
2666/// Copy this histogram structure to newth1.
2667///
2668/// Note that this function does not copy the list of associated functions.
2669/// Use TObject::Clone to make a full copy of a histogram.
2670///
2671/// Note also that the histogram it will be created in gDirectory (if AddDirectoryStatus()=true)
2672/// or will not be added to any directory if AddDirectoryStatus()=false
2673/// independently of the current directory stored in the original histogram
2674
2675void TH1::Copy(TObject &obj) const
2676{
2677 if (((TH1&)obj).fDirectory) {
2678 // We are likely to change the hash value of this object
2679 // with TNamed::Copy, to keep things correct, we need to
2680 // clean up its existing entries.
2681 ((TH1&)obj).fDirectory->Remove(&obj);
2682 ((TH1&)obj).fDirectory = nullptr;
2683 }
2684 TNamed::Copy(obj);
2685 ((TH1&)obj).fDimension = fDimension;
2686 ((TH1&)obj).fNormFactor= fNormFactor;
2687 ((TH1&)obj).fNcells = fNcells;
2688 ((TH1&)obj).fBarOffset = fBarOffset;
2689 ((TH1&)obj).fBarWidth = fBarWidth;
2690 ((TH1&)obj).fOption = fOption;
2691 ((TH1&)obj).fBinStatErrOpt = fBinStatErrOpt;
2692 ((TH1&)obj).fBufferSize= fBufferSize;
2693 // copy the Buffer
2694 // delete first a previously existing buffer
2695 if (((TH1&)obj).fBuffer != nullptr) {
2696 delete [] ((TH1&)obj).fBuffer;
2697 ((TH1&)obj).fBuffer = nullptr;
2698 }
2699 if (fBuffer) {
2700 Double_t *buf = new Double_t[fBufferSize];
2701 for (Int_t i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
2702 // obj.fBuffer has been deleted before
2703 ((TH1&)obj).fBuffer = buf;
2704 }
2705
2706 // copy bin contents (this should be done by the derived classes, since TH1 does not store the bin content)
2707 // Do this in case derived from TArray
2708 TArray* a = dynamic_cast<TArray*>(&obj);
2709 if (a) {
2710 a->Set(fNcells);
2711 for (Int_t i = 0; i < fNcells; i++)
2713 }
2714
2715 ((TH1&)obj).fEntries = fEntries;
2716
2717 // which will call BufferEmpty(0) and set fBuffer[0] to a Maybe one should call
2718 // assignment operator on the TArrayD
2719
2720 ((TH1&)obj).fTsumw = fTsumw;
2721 ((TH1&)obj).fTsumw2 = fTsumw2;
2722 ((TH1&)obj).fTsumwx = fTsumwx;
2723 ((TH1&)obj).fTsumwx2 = fTsumwx2;
2724 ((TH1&)obj).fMaximum = fMaximum;
2725 ((TH1&)obj).fMinimum = fMinimum;
2726
2727 TAttLine::Copy(((TH1&)obj));
2728 TAttFill::Copy(((TH1&)obj));
2729 TAttMarker::Copy(((TH1&)obj));
2730 fXaxis.Copy(((TH1&)obj).fXaxis);
2731 fYaxis.Copy(((TH1&)obj).fYaxis);
2732 fZaxis.Copy(((TH1&)obj).fZaxis);
2733 ((TH1&)obj).fXaxis.SetParent(&obj);
2734 ((TH1&)obj).fYaxis.SetParent(&obj);
2735 ((TH1&)obj).fZaxis.SetParent(&obj);
2736 fContour.Copy(((TH1&)obj).fContour);
2737 fSumw2.Copy(((TH1&)obj).fSumw2);
2738 // fFunctions->Copy(((TH1&)obj).fFunctions);
2739 // when copying an histogram if the AddDirectoryStatus() is true it
2740 // will be added to gDirectory independently of the fDirectory stored.
2741 // and if the AddDirectoryStatus() is false it will not be added to
2742 // any directory (fDirectory = nullptr)
2743 if (fgAddDirectory && gDirectory) {
2744 gDirectory->Append(&obj);
2745 ((TH1&)obj).fFunctions->UseRWLock();
2746 ((TH1&)obj).fDirectory = gDirectory;
2747 } else
2748 ((TH1&)obj).fDirectory = nullptr;
2749
2750}
2751
2752////////////////////////////////////////////////////////////////////////////////
2753/// Make a complete copy of the underlying object. If 'newname' is set,
2754/// the copy's name will be set to that name.
2755
2756TObject* TH1::Clone(const char* newname) const
2757{
2758 TH1* obj = (TH1*)IsA()->GetNew()(nullptr);
2759 Copy(*obj);
2760
2761 // Now handle the parts that Copy doesn't do
2762 if(fFunctions) {
2763 // The Copy above might have published 'obj' to the ListOfCleanups.
2764 // Clone can call RecursiveRemove, for example via TCheckHashRecursiveRemoveConsistency
2765 // when dictionary information is initialized, so we need to
2766 // keep obj->fFunction valid during its execution and
2767 // protect the update with the write lock.
2768
2769 // Reset stats parent - else cloning the stats will clone this histogram, too.
2770 auto oldstats = dynamic_cast<TVirtualPaveStats*>(fFunctions->FindObject("stats"));
2771 TObject *oldparent = nullptr;
2772 if (oldstats) {
2773 oldparent = oldstats->GetParent();
2774 oldstats->SetParent(nullptr);
2775 }
2776
2777 auto newlist = (TList*)fFunctions->Clone();
2778
2779 if (oldstats)
2780 oldstats->SetParent(oldparent);
2781 auto newstats = dynamic_cast<TVirtualPaveStats*>(obj->fFunctions->FindObject("stats"));
2782 if (newstats)
2783 newstats->SetParent(obj);
2784
2785 auto oldlist = obj->fFunctions;
2786 {
2788 obj->fFunctions = newlist;
2789 }
2790 delete oldlist;
2791 }
2792 if(newname && strlen(newname) ) {
2793 obj->SetName(newname);
2794 }
2795 return obj;
2796}
2797
2798////////////////////////////////////////////////////////////////////////////////
2799/// Perform the automatic addition of the histogram to the given directory
2800///
2801/// Note this function is called in place when the semantic requires
2802/// this object to be added to a directory (I.e. when being read from
2803/// a TKey or being Cloned)
2804
2806{
2807 Bool_t addStatus = TH1::AddDirectoryStatus();
2808 if (addStatus) {
2809 SetDirectory(dir);
2810 if (dir) {
2812 }
2813 }
2814}
2815
2816////////////////////////////////////////////////////////////////////////////////
2817/// Compute distance from point px,py to a line.
2818///
2819/// Compute the closest distance of approach from point px,py to elements
2820/// of a histogram.
2821/// The distance is computed in pixels units.
2822///
2823/// #### Algorithm:
2824/// Currently, this simple model computes the distance from the mouse
2825/// to the histogram contour only.
2826
2828{
2829 if (!fPainter) return 9999;
2830 return fPainter->DistancetoPrimitive(px,py);
2831}
2832
2833////////////////////////////////////////////////////////////////////////////////
2834/// Performs the operation: `this = this/(c1*f1)`
2835/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2836///
2837/// Only bins inside the function range are recomputed.
2838/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2839/// you should call Sumw2 before making this operation.
2840/// This is particularly important if you fit the histogram after TH1::Divide
2841///
2842/// The function return kFALSE if the divide operation failed
2843
2845{
2846 if (!f1) {
2847 Error("Divide","Attempt to divide by a non-existing function");
2848 return kFALSE;
2849 }
2850
2851 // delete buffer if it is there since it will become invalid
2852 if (fBuffer) BufferEmpty(1);
2853
2854 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of
2855 Int_t ny = GetNbinsY() + 2;
2856 Int_t nz = GetNbinsZ() + 2;
2857 if (fDimension < 2) ny = 1;
2858 if (fDimension < 3) nz = 1;
2859
2860
2861 SetMinimum();
2862 SetMaximum();
2863
2864 // - Loop on bins (including underflows/overflows)
2865 Int_t bin, binx, biny, binz;
2866 Double_t cu, w;
2867 Double_t xx[3];
2868 Double_t *params = nullptr;
2869 f1->InitArgs(xx,params);
2870 for (binz = 0; binz < nz; ++binz) {
2871 xx[2] = fZaxis.GetBinCenter(binz);
2872 for (biny = 0; biny < ny; ++biny) {
2873 xx[1] = fYaxis.GetBinCenter(biny);
2874 for (binx = 0; binx < nx; ++binx) {
2875 xx[0] = fXaxis.GetBinCenter(binx);
2876 if (!f1->IsInside(xx)) continue;
2878 bin = binx + nx * (biny + ny * binz);
2879 cu = c1 * f1->EvalPar(xx);
2880 if (TF1::RejectedPoint()) continue;
2881 if (cu) w = RetrieveBinContent(bin) / cu;
2882 else w = 0;
2883 UpdateBinContent(bin, w);
2884 if (fSumw2.fN) {
2885 if (cu != 0) fSumw2.fArray[bin] = GetBinErrorSqUnchecked(bin) / (cu * cu);
2886 else fSumw2.fArray[bin] = 0;
2887 }
2888 }
2889 }
2890 }
2891 ResetStats();
2892 return kTRUE;
2893}
2894
2895////////////////////////////////////////////////////////////////////////////////
2896/// Divide this histogram by h1.
2897///
2898/// `this = this/h1`
2899/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2900/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
2901/// if not already set.
2902/// The resulting errors are calculated assuming uncorrelated histograms.
2903/// See the other TH1::Divide that gives the possibility to optionally
2904/// compute binomial errors.
2905///
2906/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2907/// you should call Sumw2 before making this operation.
2908/// This is particularly important if you fit the histogram after TH1::Scale
2909///
2910/// The function return kFALSE if the divide operation failed
2911
2912Bool_t TH1::Divide(const TH1 *h1)
2913{
2914 if (!h1) {
2915 Error("Divide", "Input histogram passed does not exist (NULL).");
2916 return kFALSE;
2917 }
2918
2919 // delete buffer if it is there since it will become invalid
2920 if (fBuffer) BufferEmpty(1);
2921
2922 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins) {
2923 return false;
2924 }
2925
2926 // Create Sumw2 if h1 has Sumw2 set
2927 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
2928
2929 // - Loop on bins (including underflows/overflows)
2930 for (Int_t i = 0; i < fNcells; ++i) {
2933 if (c1) UpdateBinContent(i, c0 / c1);
2934 else UpdateBinContent(i, 0);
2935
2936 if(fSumw2.fN) {
2937 if (c1 == 0) { fSumw2.fArray[i] = 0; continue; }
2938 Double_t c1sq = c1 * c1;
2939 fSumw2.fArray[i] = (GetBinErrorSqUnchecked(i) * c1sq + h1->GetBinErrorSqUnchecked(i) * c0 * c0) / (c1sq * c1sq);
2940 }
2941 }
2942 ResetStats();
2943 return kTRUE;
2944}
2945
2946////////////////////////////////////////////////////////////////////////////////
2947/// Replace contents of this histogram by the division of h1 by h2.
2948///
2949/// `this = c1*h1/(c2*h2)`
2950///
2951/// If errors are defined (see TH1::Sumw2), errors are also recalculated
2952/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
2953/// if not already set.
2954/// The resulting errors are calculated assuming uncorrelated histograms.
2955/// However, if option ="B" is specified, Binomial errors are computed.
2956/// In this case c1 and c2 do not make real sense and they are ignored.
2957///
2958/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2959/// you should call Sumw2 before making this operation.
2960/// This is particularly important if you fit the histogram after TH1::Divide
2961///
2962/// Please note also that in the binomial case errors are calculated using standard
2963/// binomial statistics, which means when b1 = b2, the error is zero.
2964/// If you prefer to have efficiency errors not going to zero when the efficiency is 1, you must
2965/// use the function TGraphAsymmErrors::BayesDivide, which will return an asymmetric and non-zero lower
2966/// error for the case b1=b2.
2967///
2968/// The function return kFALSE if the divide operation failed
2969
2971{
2972
2973 TString opt = option;
2974 opt.ToLower();
2975 Bool_t binomial = kFALSE;
2976 if (opt.Contains("b")) binomial = kTRUE;
2977 if (!h1 || !h2) {
2978 Error("Divide", "At least one of the input histograms passed does not exist (NULL).");
2979 return kFALSE;
2980 }
2981
2982 // delete buffer if it is there since it will become invalid
2983 if (fBuffer) BufferEmpty(1);
2984
2985 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins ||
2986 LoggedInconsistency("Divide", h1, h2) >= kDifferentNumberOfBins) {
2987 return false;
2988 }
2989
2990 if (!c2) {
2991 Error("Divide","Coefficient of dividing histogram cannot be zero");
2992 return kFALSE;
2993 }
2994
2995 // Create Sumw2 if h1 or h2 have Sumw2 set, or if binomial errors are explicitly requested
2996 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0 || binomial)) Sumw2();
2997
2998 SetMinimum();
2999 SetMaximum();
3000
3001 // - Loop on bins (including underflows/overflows)
3002 for (Int_t i = 0; i < fNcells; ++i) {
3004 Double_t b2 = h2->RetrieveBinContent(i);
3005 if (b2) UpdateBinContent(i, c1 * b1 / (c2 * b2));
3006 else UpdateBinContent(i, 0);
3007
3008 if (fSumw2.fN) {
3009 if (b2 == 0) { fSumw2.fArray[i] = 0; continue; }
3010 Double_t b1sq = b1 * b1; Double_t b2sq = b2 * b2;
3011 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
3013 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
3014 if (binomial) {
3015 if (b1 != b2) {
3016 // in the case of binomial statistics c1 and c2 must be 1 otherwise it does not make sense
3017 // c1 and c2 are ignored
3018 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));//this is the formula in Hbook/Hoper1
3019 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2); // old formula from G. Flucke
3020 // formula which works also for weighted histogram (see http://root-forum.cern.ch/viewtopic.php?t=3753 )
3021 fSumw2.fArray[i] = TMath::Abs( ( (1. - 2.* b1 / b2) * e1sq + b1sq * e2sq / b2sq ) / b2sq );
3022 } else {
3023 //in case b1=b2 error is zero
3024 //use TGraphAsymmErrors::BayesDivide for getting the asymmetric error not equal to zero
3025 fSumw2.fArray[i] = 0;
3026 }
3027 } else {
3028 fSumw2.fArray[i] = c1sq * c2sq * (e1sq * b2sq + e2sq * b1sq) / (c2sq * c2sq * b2sq * b2sq);
3029 }
3030 }
3031 }
3032 ResetStats();
3033 if (binomial)
3034 // in case of binomial division use denominator for number of entries
3035 SetEntries ( h2->GetEntries() );
3036
3037 return kTRUE;
3038}
3039
3040////////////////////////////////////////////////////////////////////////////////
3041/// Draw this histogram with options.
3042///
3043/// Histograms are drawn via the THistPainter class. Each histogram has
3044/// a pointer to its own painter (to be usable in a multithreaded program).
3045/// The same histogram can be drawn with different options in different pads.
3046/// When a histogram drawn in a pad is deleted, the histogram is
3047/// automatically removed from the pad or pads where it was drawn.
3048/// If a histogram is drawn in a pad, then filled again, the new status
3049/// of the histogram will be automatically shown in the pad next time
3050/// the pad is updated. One does not need to redraw the histogram.
3051/// To draw the current version of a histogram in a pad, one can use
3052/// `h->DrawCopy();`
3053/// This makes a clone of the histogram. Once the clone is drawn, the original
3054/// histogram may be modified or deleted without affecting the aspect of the
3055/// clone.
3056/// By default, TH1::Draw clears the current pad.
3057///
3058/// One can use TH1::SetMaximum and TH1::SetMinimum to force a particular
3059/// value for the maximum or the minimum scale on the plot.
3060///
3061/// TH1::UseCurrentStyle can be used to change all histogram graphics
3062/// attributes to correspond to the current selected style.
3063/// This function must be called for each histogram.
3064/// In case one reads and draws many histograms from a file, one can force
3065/// the histograms to inherit automatically the current graphics style
3066/// by calling before gROOT->ForceStyle();
3067///
3068/// See the THistPainter class for a description of all the drawing options.
3069
3071{
3072 TString opt1 = option; opt1.ToLower();
3073 TString opt2 = option;
3074 Int_t index = opt1.Index("same");
3075
3076 // Check if the string "same" is part of a TCutg name.
3077 if (index>=0) {
3078 Int_t indb = opt1.Index("[");
3079 if (indb>=0) {
3080 Int_t indk = opt1.Index("]");
3081 if (index>indb && index<indk) index = -1;
3082 }
3083 }
3084
3085 // If there is no pad or an empty pad the "same" option is ignored.
3086 if (gPad) {
3087 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
3088 if (index>=0) {
3089 if (gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
3090 gPad->GetY1() == 0 && gPad->GetY2() == 1 &&
3091 gPad->GetListOfPrimitives()->GetSize()==0) opt2.Remove(index,4);
3092 } else {
3093 //the following statement is necessary in case one attempts to draw
3094 //a temporary histogram already in the current pad
3095 if (TestBit(kCanDelete)) gPad->Remove(this);
3096 gPad->Clear();
3097 }
3098 gPad->IncrementPaletteColor(1, opt1);
3099 } else {
3100 if (index>=0) opt2.Remove(index,4);
3101 }
3102
3103 AppendPad(opt2.Data());
3104}
3105
3106////////////////////////////////////////////////////////////////////////////////
3107/// Copy this histogram and Draw in the current pad.
3108///
3109/// Once the histogram is drawn into the pad, any further modification
3110/// using graphics input will be made on the copy of the histogram,
3111/// and not to the original object.
3112/// By default a postfix "_copy" is added to the histogram name. Pass an empty postfix in case
3113/// you want to draw a histogram with the same name
3114///
3115/// See Draw for the list of options
3116
3117TH1 *TH1::DrawCopy(Option_t *option, const char * name_postfix) const
3118{
3119 TString opt = option;
3120 opt.ToLower();
3121 if (gPad && !opt.Contains("same")) gPad->Clear();
3122 TString newName;
3123 if (name_postfix) newName.Form("%s%s", GetName(), name_postfix);
3124 TH1 *newth1 = (TH1 *)Clone(newName.Data());
3125 newth1->SetDirectory(nullptr);
3126 newth1->SetBit(kCanDelete);
3127 if (gPad) gPad->IncrementPaletteColor(1, opt);
3128
3129 newth1->AppendPad(option);
3130 return newth1;
3131}
3132
3133////////////////////////////////////////////////////////////////////////////////
3134/// Draw a normalized copy of this histogram.
3135///
3136/// A clone of this histogram is normalized to norm and drawn with option.
3137/// A pointer to the normalized histogram is returned.
3138/// The contents of the histogram copy are scaled such that the new
3139/// sum of weights (excluding under and overflow) is equal to norm.
3140/// Note that the returned normalized histogram is not added to the list
3141/// of histograms in the current directory in memory.
3142/// It is the user's responsibility to delete this histogram.
3143/// The kCanDelete bit is set for the returned object. If a pad containing
3144/// this copy is cleared, the histogram will be automatically deleted.
3145///
3146/// See Draw for the list of options
3147
3149{
3151 if (sum == 0) {
3152 Error("DrawNormalized","Sum of weights is null. Cannot normalize histogram: %s",GetName());
3153 return nullptr;
3154 }
3155 Bool_t addStatus = TH1::AddDirectoryStatus();
3157 TH1 *h = (TH1*)Clone();
3159 // in case of drawing with error options - scale correctly the error
3160 TString opt(option); opt.ToUpper();
3161 if (fSumw2.fN == 0) {
3162 h->Sumw2();
3163 // do not use in this case the "Error option " for drawing which is enabled by default since the normalized histogram has now errors
3164 if (opt.IsNull() || opt == "SAME") opt += "HIST";
3165 }
3166 h->Scale(norm/sum);
3167 if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
3168 if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
3169 h->Draw(opt);
3170 TH1::AddDirectory(addStatus);
3171 return h;
3172}
3173
3174////////////////////////////////////////////////////////////////////////////////
3175/// Display a panel with all histogram drawing options.
3176///
3177/// See class TDrawPanelHist for example
3178
3179void TH1::DrawPanel()
3180{
3181 if (!fPainter) {Draw(); if (gPad) gPad->Update();}
3182 if (fPainter) fPainter->DrawPanel();
3183}
3184
3185////////////////////////////////////////////////////////////////////////////////
3186/// Evaluate function f1 at the center of bins of this histogram.
3187///
3188/// - If option "R" is specified, the function is evaluated only
3189/// for the bins included in the function range.
3190/// - If option "A" is specified, the value of the function is added to the
3191/// existing bin contents
3192/// - If option "S" is specified, the value of the function is used to
3193/// generate a value, distributed according to the Poisson
3194/// distribution, with f1 as the mean.
3195
3197{
3198 Double_t x[3];
3199 Int_t range, stat, add;
3200 if (!f1) return;
3201
3202 TString opt = option;
3203 opt.ToLower();
3204 if (opt.Contains("a")) add = 1;
3205 else add = 0;
3206 if (opt.Contains("s")) stat = 1;
3207 else stat = 0;
3208 if (opt.Contains("r")) range = 1;
3209 else range = 0;
3210
3211 // delete buffer if it is there since it will become invalid
3212 if (fBuffer) BufferEmpty(1);
3213
3214 Int_t nbinsx = fXaxis.GetNbins();
3215 Int_t nbinsy = fYaxis.GetNbins();
3216 Int_t nbinsz = fZaxis.GetNbins();
3217 if (!add) Reset();
3218
3219 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
3220 x[2] = fZaxis.GetBinCenter(binz);
3221 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
3222 x[1] = fYaxis.GetBinCenter(biny);
3223 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
3224 Int_t bin = GetBin(binx,biny,binz);
3225 x[0] = fXaxis.GetBinCenter(binx);
3226 if (range && !f1->IsInside(x)) continue;
3227 Double_t fu = f1->Eval(x[0], x[1], x[2]);
3228 if (stat) fu = gRandom->PoissonD(fu);
3229 AddBinContent(bin, fu);
3230 if (fSumw2.fN) fSumw2.fArray[bin] += TMath::Abs(fu);
3231 }
3232 }
3233 }
3234}
3235
3236////////////////////////////////////////////////////////////////////////////////
3237/// Execute action corresponding to one event.
3238///
3239/// This member function is called when a histogram is clicked with the locator
3240///
3241/// If Left button clicked on the bin top value, then the content of this bin
3242/// is modified according to the new position of the mouse when it is released.
3243
3244void TH1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3245{
3246 if (fPainter) fPainter->ExecuteEvent(event, px, py);
3247}
3248
3249////////////////////////////////////////////////////////////////////////////////
3250/// This function allows to do discrete Fourier transforms of TH1 and TH2.
3251/// Available transform types and flags are described below.
3252///
3253/// To extract more information about the transform, use the function
3254/// TVirtualFFT::GetCurrentTransform() to get a pointer to the current
3255/// transform object.
3256///
3257/// \param[out] h_output histogram for the output. If a null pointer is passed, a new histogram is created
3258/// and returned, otherwise, the provided histogram is used and should be big enough
3259/// \param[in] option option parameters consists of 3 parts:
3260/// - option on what to return
3261/// - "RE" - returns a histogram of the real part of the output
3262/// - "IM" - returns a histogram of the imaginary part of the output
3263/// - "MAG"- returns a histogram of the magnitude of the output
3264/// - "PH" - returns a histogram of the phase of the output
3265/// - option of transform type
3266/// - "R2C" - real to complex transforms - default
3267/// - "R2HC" - real to halfcomplex (special format of storing output data,
3268/// results the same as for R2C)
3269/// - "DHT" - discrete Hartley transform
3270/// real to real transforms (sine and cosine):
3271/// - "R2R_0", "R2R_1", "R2R_2", "R2R_3" - discrete cosine transforms of types I-IV
3272/// - "R2R_4", "R2R_5", "R2R_6", "R2R_7" - discrete sine transforms of types I-IV
3273/// To specify the type of each dimension of a 2-dimensional real to real
3274/// transform, use options of form "R2R_XX", for example, "R2R_02" for a transform,
3275/// which is of type "R2R_0" in 1st dimension and "R2R_2" in the 2nd.
3276/// - option of transform flag
3277/// - "ES" (from "estimate") - no time in preparing the transform, but probably sub-optimal
3278/// performance
3279/// - "M" (from "measure") - some time spend in finding the optimal way to do the transform
3280/// - "P" (from "patient") - more time spend in finding the optimal way to do the transform
3281/// - "EX" (from "exhaustive") - the most optimal way is found
3282/// This option should be chosen depending on how many transforms of the same size and
3283/// type are going to be done. Planning is only done once, for the first transform of this
3284/// size and type. Default is "ES".
3285///
3286/// Examples of valid options: "Mag R2C M" "Re R2R_11" "Im R2C ES" "PH R2HC EX"
3287
3288TH1* TH1::FFT(TH1* h_output, Option_t *option)
3289{
3290
3291 Int_t ndim[3];
3292 ndim[0] = this->GetNbinsX();
3293 ndim[1] = this->GetNbinsY();
3294 ndim[2] = this->GetNbinsZ();
3295
3296 TVirtualFFT *fft;
3297 TString opt = option;
3298 opt.ToUpper();
3299 if (!opt.Contains("2R")){
3300 if (!opt.Contains("2C") && !opt.Contains("2HC") && !opt.Contains("DHT")) {
3301 //no type specified, "R2C" by default
3302 opt.Append("R2C");
3303 }
3304 fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
3305 }
3306 else {
3307 //find the kind of transform
3308 Int_t ind = opt.Index("R2R", 3);
3309 Int_t *kind = new Int_t[2];
3310 char t;
3311 t = opt[ind+4];
3312 kind[0] = atoi(&t);
3313 if (h_output->GetDimension()>1) {
3314 t = opt[ind+5];
3315 kind[1] = atoi(&t);
3316 }
3317 fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
3318 delete [] kind;
3319 }
3320
3321 if (!fft) return nullptr;
3322 Int_t in=0;
3323 for (Int_t binx = 1; binx<=ndim[0]; binx++) {
3324 for (Int_t biny=1; biny<=ndim[1]; biny++) {
3325 for (Int_t binz=1; binz<=ndim[2]; binz++) {
3326 fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
3327 in++;
3328 }
3329 }
3330 }
3331 fft->Transform();
3332 h_output = TransformHisto(fft, h_output, option);
3333 return h_output;
3334}
3335
3336////////////////////////////////////////////////////////////////////////////////
3337/// Increment bin with abscissa X by 1.
3338///
3339/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3340/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3341///
3342/// If the storage of the sum of squares of weights has been triggered,
3343/// via the function Sumw2, then the sum of the squares of weights is incremented
3344/// by 1 in the bin corresponding to x.
3345///
3346/// The function returns the corresponding bin number which has its content incremented by 1
3347
3349{
3350 if (fBuffer) return BufferFill(x,1);
3351
3352 Int_t bin;
3353 fEntries++;
3354 bin =fXaxis.FindBin(x);
3355 if (bin <0) return -1;
3356 AddBinContent(bin);
3357 if (fSumw2.fN) ++fSumw2.fArray[bin];
3358 if (bin == 0 || bin > fXaxis.GetNbins()) {
3359 if (!GetStatOverflowsBehaviour()) return -1;
3360 }
3361 ++fTsumw;
3362 ++fTsumw2;
3363 fTsumwx += x;
3364 fTsumwx2 += x*x;
3365 return bin;
3366}
3367
3368////////////////////////////////////////////////////////////////////////////////
3369/// Increment bin with abscissa X with a weight w.
3370///
3371/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3372/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3373///
3374/// If the weight is not equal to 1, the storage of the sum of squares of
3375/// weights is automatically triggered and the sum of the squares of weights is incremented
3376/// by \f$ w^2 \f$ in the bin corresponding to x.
3377///
3378/// The function returns the corresponding bin number which has its content incremented by w
3379
3381{
3382
3383 if (fBuffer) return BufferFill(x,w);
3384
3385 Int_t bin;
3386 fEntries++;
3387 bin =fXaxis.FindBin(x);
3388 if (bin <0) return -1;
3389 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW) ) Sumw2(); // must be called before AddBinContent
3390 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3391 AddBinContent(bin, w);
3392 if (bin == 0 || bin > fXaxis.GetNbins()) {
3393 if (!GetStatOverflowsBehaviour()) return -1;
3394 }
3395 Double_t z= w;
3396 fTsumw += z;
3397 fTsumw2 += z*z;
3398 fTsumwx += z*x;
3399 fTsumwx2 += z*x*x;
3400 return bin;
3401}
3402
3403////////////////////////////////////////////////////////////////////////////////
3404/// Increment bin with namex with a weight w
3405///
3406/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3407/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3408///
3409/// If the weight is not equal to 1, the storage of the sum of squares of
3410/// weights is automatically triggered and the sum of the squares of weights is incremented
3411/// by \f$ w^2 \f$ in the bin corresponding to x.
3412///
3413/// The function returns the corresponding bin number which has its content
3414/// incremented by w.
3415
3416Int_t TH1::Fill(const char *namex, Double_t w)
3417{
3418 Int_t bin;
3419 fEntries++;
3420 bin =fXaxis.FindBin(namex);
3421 if (bin <0) return -1;
3422 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3423 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3424 AddBinContent(bin, w);
3425 if (bin == 0 || bin > fXaxis.GetNbins()) return -1;
3426 Double_t z= w;
3427 fTsumw += z;
3428 fTsumw2 += z*z;
3429 // this make sense if the histogram is not expanding (the x axis cannot be extended)
3430 if (!fXaxis.CanExtend() || !fXaxis.IsAlphanumeric()) {
3432 fTsumwx += z*x;
3433 fTsumwx2 += z*x*x;
3434 }
3435 return bin;
3436}
3437
3438////////////////////////////////////////////////////////////////////////////////
3439/// Fill this histogram with an array x and weights w.
3440///
3441/// \param[in] ntimes number of entries in arrays x and w (array size must be ntimes*stride)
3442/// \param[in] x array of values to be histogrammed
3443/// \param[in] w array of weighs
3444/// \param[in] stride step size through arrays x and w
3445///
3446/// If the weight is not equal to 1, the storage of the sum of squares of
3447/// weights is automatically triggered and the sum of the squares of weights is incremented
3448/// by \f$ w^2 \f$ in the bin corresponding to x.
3449/// if w is NULL each entry is assumed a weight=1
3450
3451void TH1::FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3452{
3453 //If a buffer is activated, fill buffer
3454 if (fBuffer) {
3455 ntimes *= stride;
3456 Int_t i = 0;
3457 for (i=0;i<ntimes;i+=stride) {
3458 if (!fBuffer) break; // buffer can be deleted in BufferFill when is empty
3459 if (w) BufferFill(x[i],w[i]);
3460 else BufferFill(x[i], 1.);
3461 }
3462 // fill the remaining entries if the buffer has been deleted
3463 if (i < ntimes && !fBuffer) {
3464 auto weights = w ? &w[i] : nullptr;
3465 DoFillN((ntimes-i)/stride,&x[i],weights,stride);
3466 }
3467 return;
3468 }
3469 // call internal method
3470 DoFillN(ntimes, x, w, stride);
3471}
3472
3473////////////////////////////////////////////////////////////////////////////////
3474/// Internal method to fill histogram content from a vector
3475/// called directly by TH1::BufferEmpty
3476
3477void TH1::DoFillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3478{
3479 Int_t bin,i;
3480
3481 fEntries += ntimes;
3482 Double_t ww = 1;
3483 Int_t nbins = fXaxis.GetNbins();
3484 ntimes *= stride;
3485 for (i=0;i<ntimes;i+=stride) {
3486 bin =fXaxis.FindBin(x[i]);
3487 if (bin <0) continue;
3488 if (w) ww = w[i];
3489 if (!fSumw2.fN && ww != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3490 if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
3491 AddBinContent(bin, ww);
3492 if (bin == 0 || bin > nbins) {
3493 if (!GetStatOverflowsBehaviour()) continue;
3494 }
3495 Double_t z= ww;
3496 fTsumw += z;
3497 fTsumw2 += z*z;
3498 fTsumwx += z*x[i];
3499 fTsumwx2 += z*x[i]*x[i];
3500 }
3501}
3502
3503////////////////////////////////////////////////////////////////////////////////
3504/// Fill histogram following distribution in function fname.
3505///
3506/// @param fname : Function name used for filling the histogram
3507/// @param ntimes : number of times the histogram is filled
3508/// @param rng : (optional) Random number generator used to sample
3509///
3510///
3511/// The distribution contained in the function fname (TF1) is integrated
3512/// over the channel contents for the bin range of this histogram.
3513/// It is normalized to 1.
3514///
3515/// Getting one random number implies:
3516/// - Generating a random number between 0 and 1 (say r1)
3517/// - Look in which bin in the normalized integral r1 corresponds to
3518/// - Fill histogram channel
3519/// ntimes random numbers are generated
3520///
3521/// One can also call TF1::GetRandom to get a random variate from a function.
3522
3523void TH1::FillRandom(const char *fname, Int_t ntimes, TRandom * rng)
3524{
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 FillRandom(f1, ntimes, rng);
3531
3532void TH1::FillRandom(TF1 *f1, Int_t ntimes, TRandom * rng)
3533{
3534 Int_t bin, binx, ibin, loop;
3535 Double_t r1, x;
3536
3537 // - Allocate temporary space to store the integral and compute integral
3538
3539 TAxis * xAxis = &fXaxis;
3540
3541 // in case axis of histogram is not defined use the function axis
3542 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
3544 f1->GetRange(xmin,xmax);
3545 Info("FillRandom","Using function axis and range [%g,%g]",xmin, xmax);
3546 xAxis = f1->GetHistogram()->GetXaxis();
3547 }
3548
3549 Int_t first = xAxis->GetFirst();
3550 Int_t last = xAxis->GetLast();
3551 Int_t nbinsx = last-first+1;
3552
3553 Double_t *integral = new Double_t[nbinsx+1];
3554 integral[0] = 0;
3555 for (binx=1;binx<=nbinsx;binx++) {
3556 Double_t fint = f1->Integral(xAxis->GetBinLowEdge(binx+first-1),xAxis->GetBinUpEdge(binx+first-1), 0.);
3557 integral[binx] = integral[binx-1] + fint;
3558 }
3559
3560 // - Normalize integral to 1
3561 if (integral[nbinsx] == 0 ) {
3562 delete [] integral;
3563 Error("FillRandom", "Integral = zero"); return;
3564 }
3565 for (bin=1;bin<=nbinsx;bin++) integral[bin] /= integral[nbinsx];
3566
3567 // --------------Start main loop ntimes
3568 for (loop=0;loop<ntimes;loop++) {
3569 r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
3570 ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
3571 //binx = 1 + ibin;
3572 //x = xAxis->GetBinCenter(binx); //this is not OK when SetBuffer is used
3573 x = xAxis->GetBinLowEdge(ibin+first)
3574 +xAxis->GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
3575 Fill(x);
3576 }
3577 delete [] integral;
3578}
3579
3580////////////////////////////////////////////////////////////////////////////////
3581/// Fill histogram following distribution in histogram h.
3582///
3583/// @param h : Histogram pointer used for sampling random number
3584/// @param ntimes : number of times the histogram is filled
3585/// @param rng : (optional) Random number generator used for sampling
3586///
3587/// The distribution contained in the histogram h (TH1) is integrated
3588/// over the channel contents for the bin range of this histogram.
3589/// It is normalized to 1.
3590///
3591/// Getting one random number implies:
3592/// - Generating a random number between 0 and 1 (say r1)
3593/// - Look in which bin in the normalized integral r1 corresponds to
3594/// - Fill histogram channel ntimes random numbers are generated
3595///
3596/// SPECIAL CASE when the target histogram has the same binning as the source.
3597/// in this case we simply use a poisson distribution where
3598/// the mean value per bin = bincontent/integral.
3599
3600void TH1::FillRandom(TH1 *h, Int_t ntimes, TRandom * rng)
3601{
3602 if (!h) { Error("FillRandom", "Null histogram"); return; }
3603 if (fDimension != h->GetDimension()) {
3604 Error("FillRandom", "Histograms with different dimensions"); return;
3605 }
3606 if (std::isnan(h->ComputeIntegral(true))) {
3607 Error("FillRandom", "Histograms contains negative bins, does not represent probabilities");
3608 return;
3609 }
3610
3611 //in case the target histogram has the same binning and ntimes much greater
3612 //than the number of bins we can use a fast method
3613 Int_t first = fXaxis.GetFirst();
3614 Int_t last = fXaxis.GetLast();
3615 Int_t nbins = last-first+1;
3616 if (ntimes > 10*nbins) {
3617 auto inconsistency = CheckConsistency(this,h);
3618 if (inconsistency != kFullyConsistent) return; // do nothing
3619 Double_t sumw = h->Integral(first,last);
3620 if (sumw == 0) return;
3621 Double_t sumgen = 0;
3622 for (Int_t bin=first;bin<=last;bin++) {
3623 Double_t mean = h->RetrieveBinContent(bin)*ntimes/sumw;
3624 Double_t cont = (rng) ? rng->Poisson(mean) : gRandom->Poisson(mean);
3625 sumgen += cont;
3626 AddBinContent(bin,cont);
3627 if (fSumw2.fN) fSumw2.fArray[bin] += cont;
3628 }
3629
3630 // fix for the fluctuations in the total number n
3631 // since we use Poisson instead of multinomial
3632 // add a correction to have ntimes as generated entries
3633 Int_t i;
3634 if (sumgen < ntimes) {
3635 // add missing entries
3636 for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
3637 {
3638 Double_t x = h->GetRandom();
3639 Fill(x);
3640 }
3641 }
3642 else if (sumgen > ntimes) {
3643 // remove extra entries
3644 i = Int_t(sumgen+0.5);
3645 while( i > ntimes) {
3646 Double_t x = h->GetRandom(rng);
3647 Int_t ibin = fXaxis.FindBin(x);
3649 // skip in case bin is empty
3650 if (y > 0) {
3651 SetBinContent(ibin, y-1.);
3652 i--;
3653 }
3654 }
3655 }
3656
3657 ResetStats();
3658 return;
3659 }
3660 // case of different axis and not too large ntimes
3661
3662 if (h->ComputeIntegral() ==0) return;
3663 Int_t loop;
3664 Double_t x;
3665 for (loop=0;loop<ntimes;loop++) {
3666 x = h->GetRandom();
3667 Fill(x);
3668 }
3669}
3670
3671////////////////////////////////////////////////////////////////////////////////
3672/// Return Global bin number corresponding to x,y,z
3673///
3674/// 2-D and 3-D histograms are represented with a one dimensional
3675/// structure. This has the advantage that all existing functions, such as
3676/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3677/// This function tries to extend the axis if the given point belongs to an
3678/// under-/overflow bin AND if CanExtendAllAxes() is true.
3679///
3680/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3681
3683{
3684 if (GetDimension() < 2) {
3685 return fXaxis.FindBin(x);
3686 }
3687 if (GetDimension() < 3) {
3688 Int_t nx = fXaxis.GetNbins()+2;
3689 Int_t binx = fXaxis.FindBin(x);
3690 Int_t biny = fYaxis.FindBin(y);
3691 return binx + nx*biny;
3692 }
3693 if (GetDimension() < 4) {
3694 Int_t nx = fXaxis.GetNbins()+2;
3695 Int_t ny = fYaxis.GetNbins()+2;
3696 Int_t binx = fXaxis.FindBin(x);
3697 Int_t biny = fYaxis.FindBin(y);
3698 Int_t binz = fZaxis.FindBin(z);
3699 return binx + nx*(biny +ny*binz);
3700 }
3701 return -1;
3702}
3703
3704////////////////////////////////////////////////////////////////////////////////
3705/// Return Global bin number corresponding to x,y,z.
3706///
3707/// 2-D and 3-D histograms are represented with a one dimensional
3708/// structure. This has the advantage that all existing functions, such as
3709/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3710/// This function DOES NOT try to extend the axis if the given point belongs
3711/// to an under-/overflow bin.
3712///
3713/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3714
3716{
3717 if (GetDimension() < 2) {
3718 return fXaxis.FindFixBin(x);
3719 }
3720 if (GetDimension() < 3) {
3721 Int_t nx = fXaxis.GetNbins()+2;
3722 Int_t binx = fXaxis.FindFixBin(x);
3723 Int_t biny = fYaxis.FindFixBin(y);
3724 return binx + nx*biny;
3725 }
3726 if (GetDimension() < 4) {
3727 Int_t nx = fXaxis.GetNbins()+2;
3728 Int_t ny = fYaxis.GetNbins()+2;
3729 Int_t binx = fXaxis.FindFixBin(x);
3730 Int_t biny = fYaxis.FindFixBin(y);
3731 Int_t binz = fZaxis.FindFixBin(z);
3732 return binx + nx*(biny +ny*binz);
3733 }
3734 return -1;
3735}
3736
3737////////////////////////////////////////////////////////////////////////////////
3738/// Find first bin with content > threshold for axis (1=x, 2=y, 3=z)
3739/// if no bins with content > threshold is found the function returns -1.
3740/// The search will occur between the specified first and last bin. Specifying
3741/// the value of the last bin to search to less than zero will search until the
3742/// last defined bin.
3743
3744Int_t TH1::FindFirstBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3745{
3746 if (fBuffer) ((TH1*)this)->BufferEmpty();
3747
3748 if (axis < 1 || (axis > 1 && GetDimension() == 1 ) ||
3749 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3 ) ) {
3750 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3751 axis = 1;
3752 }
3753 if (firstBin < 1) {
3754 firstBin = 1;
3755 }
3756 Int_t nbinsx = fXaxis.GetNbins();
3757 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3758 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3759
3760 if (axis == 1) {
3761 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3762 lastBin = fXaxis.GetNbins();
3763 }
3764 for (Int_t binx = firstBin; binx <= lastBin; binx++) {
3765 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3766 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3767 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binx;
3768 }
3769 }
3770 }
3771 }
3772 else if (axis == 2) {
3773 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3774 lastBin = fYaxis.GetNbins();
3775 }
3776 for (Int_t biny = firstBin; biny <= lastBin; biny++) {
3777 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3778 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3779 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return biny;
3780 }
3781 }
3782 }
3783 }
3784 else if (axis == 3) {
3785 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3786 lastBin = fZaxis.GetNbins();
3787 }
3788 for (Int_t binz = firstBin; binz <= lastBin; binz++) {
3789 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3790 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3791 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binz;
3792 }
3793 }
3794 }
3795 }
3796
3797 return -1;
3798}
3799
3800////////////////////////////////////////////////////////////////////////////////
3801/// Find last bin with content > threshold for axis (1=x, 2=y, 3=z)
3802/// if no bins with content > threshold is found the function returns -1.
3803/// The search will occur between the specified first and last bin. Specifying
3804/// the value of the last bin to search to less than zero will search until the
3805/// last defined bin.
3806
3807Int_t TH1::FindLastBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3808{
3809 if (fBuffer) ((TH1*)this)->BufferEmpty();
3810
3811
3812 if (axis < 1 || ( axis > 1 && GetDimension() == 1 ) ||
3813 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3) ) {
3814 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3815 axis = 1;
3816 }
3817 if (firstBin < 1) {
3818 firstBin = 1;
3819 }
3820 Int_t nbinsx = fXaxis.GetNbins();
3821 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3822 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3823
3824 if (axis == 1) {
3825 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3826 lastBin = fXaxis.GetNbins();
3827 }
3828 for (Int_t binx = lastBin; binx >= firstBin; binx--) {
3829 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3830 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3831 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binx;
3832 }
3833 }
3834 }
3835 }
3836 else if (axis == 2) {
3837 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3838 lastBin = fYaxis.GetNbins();
3839 }
3840 for (Int_t biny = lastBin; biny >= firstBin; biny--) {
3841 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3842 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3843 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return biny;
3844 }
3845 }
3846 }
3847 }
3848 else if (axis == 3) {
3849 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3850 lastBin = fZaxis.GetNbins();
3851 }
3852 for (Int_t binz = lastBin; binz >= firstBin; binz--) {
3853 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3854 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3855 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binz;
3856 }
3857 }
3858 }
3859 }
3860
3861 return -1;
3862}
3863
3864////////////////////////////////////////////////////////////////////////////////
3865/// Search object named name in the list of functions.
3866
3867TObject *TH1::FindObject(const char *name) const
3868{
3869 if (fFunctions) return fFunctions->FindObject(name);
3870 return nullptr;
3871}
3872
3873////////////////////////////////////////////////////////////////////////////////
3874/// Search object obj in the list of functions.
3875
3876TObject *TH1::FindObject(const TObject *obj) const
3877{
3878 if (fFunctions) return fFunctions->FindObject(obj);
3879 return nullptr;
3880}
3881
3882////////////////////////////////////////////////////////////////////////////////
3883/// Fit histogram with function fname.
3884///
3885///
3886/// fname is the name of a function available in the global ROOT list of functions
3887/// `gROOT->GetListOfFunctions`
3888/// The list include any TF1 object created by the user plus some pre-defined functions
3889/// which are automatically created by ROOT the first time a pre-defined function is requested from `gROOT`
3890/// (i.e. when calling `gROOT->GetFunction(const char *name)`).
3891/// These pre-defined functions are:
3892/// - `gaus, gausn` where gausn is the normalized Gaussian
3893/// - `landau, landaun`
3894/// - `expo`
3895/// - `pol1,...9, chebyshev1,...9`.
3896///
3897/// For printing the list of all available functions do:
3898///
3899/// TF1::InitStandardFunctions(); // not needed if `gROOT->GetFunction` is called before
3900/// gROOT->GetListOfFunctions()->ls()
3901///
3902/// `fname` can also be a formula that is accepted by the linear fitter containing the special operator `++`,
3903/// representing linear components separated by `++` sign, for example `x++sin(x)` for fitting `[0]*x+[1]*sin(x)`
3904///
3905/// This function finds a pointer to the TF1 object with name `fname` and calls TH1::Fit(TF1 *, Option_t *, Option_t *,
3906/// Double_t, Double_t). See there for the fitting options and the details about fitting histograms
3907
3908TFitResultPtr TH1::Fit(const char *fname ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
3909{
3910 char *linear;
3911 linear= (char*)strstr(fname, "++");
3912 Int_t ndim=GetDimension();
3913 if (linear){
3914 if (ndim<2){
3915 TF1 f1(fname, fname, xxmin, xxmax);
3916 return Fit(&f1,option,goption,xxmin,xxmax);
3917 }
3918 else if (ndim<3){
3919 TF2 f2(fname, fname);
3920 return Fit(&f2,option,goption,xxmin,xxmax);
3921 }
3922 else{
3923 TF3 f3(fname, fname);
3924 return Fit(&f3,option,goption,xxmin,xxmax);
3925 }
3926 }
3927 else{
3928 TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
3929 if (!f1) { Printf("Unknown function: %s",fname); return -1; }
3930 return Fit(f1,option,goption,xxmin,xxmax);
3931 }
3932}
3933
3934////////////////////////////////////////////////////////////////////////////////
3935/// Fit histogram with the function pointer f1.
3936///
3937/// \param[in] f1 pointer to the function object
3938/// \param[in] option string defining the fit options (see table below).
3939/// \param[in] goption specify a list of graphics options. See TH1::Draw for a complete list of these options.
3940/// \param[in] xxmin lower fitting range
3941/// \param[in] xxmax upper fitting range
3942/// \return A smart pointer to the TFitResult class
3943///
3944/// \anchor HFitOpt
3945/// ### Histogram Fitting Options
3946///
3947/// Here is the full list of fit options that can be given in the parameter `option`.
3948/// Several options can be used together by concatanating the strings without the need of any delimiters.
3949///
3950/// option | description
3951/// -------|------------
3952/// "L" | Uses a log likelihood method (default is chi-square method). To be used when the histogram represents counts.
3953/// "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.
3954/// "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.
3955/// "MULTI" | Uses Loglikelihood method based on multi-nomial distribution. In this case the function must be normalized and one fits only the function shape.
3956/// "W" | Fit using the chi-square method and ignoring the bin uncertainties and skip empty bins.
3957/// "WW" | Fit using the chi-square method and ignoring the bin uncertainties and include the empty bins.
3958/// "I" | Uses the integral of function in the bin instead of the default bin center value.
3959/// "F" | Uses the default minimizer (e.g. Minuit) when fitting a linear function (e.g. polN) instead of the linear fitter.
3960/// "U" | Uses a user specified objective function (e.g. user providedlikelihood function) defined using `TVirtualFitter::SetFCN`
3961/// "E" | Performs a better parameter errors estimation using the Minos technique for all fit parameters.
3962/// "M" | Uses the IMPROVE algorithm (available only in TMinuit). This algorithm attempts improve the found local minimum by searching for a better one.
3963/// "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`.
3964/// "Q" | Quiet mode (minimum printing)
3965/// "V" | Verbose mode (default is between Q and V)
3966/// "+" | 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.
3967/// "N" | Does not store the graphics function, does not draw the histogram with the function after fitting.
3968/// "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.
3969/// "R" | Fit using a fitting range specified in the function range with `TF1::SetRange`.
3970/// "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.
3971/// "C" | In case of linear fitting, do no calculate the chisquare (saves CPU time).
3972/// "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.
3973/// "WIDTH" | Scales the histogran bin content by the bin width (useful for variable bins histograms)
3974/// "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
3975/// "MULTITHREAD" | Forces usage of multi-thread execution whenever possible
3976///
3977/// The default fitting of an histogram (when no option is given) is perfomed as following:
3978/// - a chi-square fit (see below Chi-square Fits) computed using the bin histogram errors and excluding bins with zero errors (empty bins);
3979/// - the full range of the histogram is used;
3980/// - the default Minimizer with its default configuration is used (see below Minimizer Configuration) except for linear function;
3981/// - for linear functions (`polN`, `chenbyshev` or formula expressions combined using operator `++`) a linear minimization is used.
3982/// - only the status of the fit is returned;
3983/// - the fit is performed in Multithread whenever is enabled in ROOT;
3984/// - only the last fitted function is saved in the histogram;
3985/// - the histogram is drawn after fitting overalyed with the resulting fitting function
3986///
3987/// \anchor HFitMinimizer
3988/// ### Minimizer Configuration
3989///
3990/// The Fit is perfomed using the default Minimizer, defined in the `ROOT::Math::MinimizerOptions` class.
3991/// It is possible to change the default minimizer and its configuration parameters by calling these static functions before fitting (before calling `TH1::Fit`):
3992/// - `ROOT::Math::MinimizerOptions::SetDefaultMinimizer(minimizerName, minimizerAgorithm)` for changing the minmizer and/or the corresponding algorithm.
3993/// For example `ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");` will set the usage of the BFGS algorithm of the GSL multi-dimensional minimization
3994/// The current defaults are ("Minuit","Migrad").
3995/// See the documentation of the `ROOT::Math::MinimizerOptions` for the available minimizers in ROOT and their corresponding algorithms.
3996/// - `ROOT::Math::MinimizerOptions::SetDefaultTolerance` for setting a different tolerance value for the minimization.
3997/// - `ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls` for setting the maximum number of function calls.
3998/// - `ROOT::Math::MinimizerOptions::SetDefaultPrintLevel` for changing the minimizer print level from level=0 (minimal printing) to level=3 maximum printing
3999///
4000/// Other options are possible depending on the Minimizer used, see the corresponding documentation.
4001/// The default minimizer can be also set in the resource file in etc/system.rootrc. For example
4002///
4003/// ~~~ {.cpp}
4004/// Root.Fitter: Minuit2
4005/// ~~~
4006///
4007/// \anchor HFitChi2
4008/// ### Chi-square Fits
4009///
4010/// By default a chi-square (least-square) fit is performed on the histogram. The so-called modified least-square method
4011/// is used where the residual for each bin is computed using as error the observed value (the bin error) returned by `TH1::GetBinError`
4012///
4013/// \f[
4014/// Chi2 = \sum_{i}{ \left(\frac{y(i) - f(x(i) | p )}{e(i)} \right)^2 }
4015/// \f]
4016///
4017/// 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
4018/// an un-weighted histogram). Bins with zero errors are excluded from the fit. See also later the note on the treatment
4019/// of empty bins. When using option "I" the residual is computed not using the function value at the bin center, `f(x(i)|p)`,
4020/// but the integral of the function in the bin, Integral{ f(x|p)dx }, divided by the bin volume.
4021/// When using option `P` (Pearson chi2), the expected error computed as `e(i) = sqrt(f(x(i)|p))` is used.
4022/// In this case empty bins are considered in the fit.
4023/// Both chi-square methods should not be used when the bin content represent counts, especially in case of low bin statistics,
4024/// because they could return a biased result.
4025///
4026/// \anchor HFitNLL
4027/// ### Likelihood Fits
4028///
4029/// When using option "L" a likelihood fit is used instead of the default chi-square fit.
4030/// The likelihood is built assuming a Poisson probability density function for each bin.
4031/// The negative log-likelihood to be minimized is
4032///
4033/// \f[
4034/// NLL = - \sum_{i}{ \log {\mathrm P} ( y(i) | f(x(i) | p ) ) }
4035/// \f]
4036/// 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)`.
4037/// The exact likelihood used is the Poisson likelihood described in this paper:
4038/// S. Baker and R. D. Cousins, “Clarification of the use of chi-square and likelihood functions in fits to histograms,”
4039/// Nucl. Instrum. Meth. 221 (1984) 437.
4040///
4041/// \f[
4042/// NLL = \sum_{i}{( f(x(i) | p ) + y(i)\log(y(i)/ f(x(i) | p )) - y(i)) }
4043/// \f]
4044/// By using this formulation, `2*NLL` can be interpreted as the chi-square resulting from the fit.
4045///
4046/// This method should be always used when the bin content represents counts (i.e. errors are sqrt(N) ).
4047/// The likelihood method has the advantage of treating correctly bins with low statistics. In case of high
4048/// statistics/bin the distribution of the bin content becomes a normal distribution and the likelihood and the chi2 fit
4049/// give the same result.
4050///
4051/// The likelihood method, although a bit slower, it is therefore the recommended method,
4052/// when the histogram represent counts (Poisson statistics), where the chi-square methods may
4053/// give incorrect results, especially in case of low statistics.
4054/// In case of a weighted histogram, it is possible to perform also a likelihood fit by using the
4055/// option "WL". Note a weighted histogram is a histogram which has been filled with weights and it
4056/// has the information on the sum of the weight square for each bin ( TH1::Sumw2() has been called).
4057/// The bin error for a weighted histogram is the square root of the sum of the weight square.
4058///
4059/// \anchor HFitRes
4060/// ### Fit Result
4061///
4062/// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
4063/// By default the TFitResultPtr contains only the status of the fit which is return by an
4064/// automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
4065///
4066/// ~~~ {.cpp}
4067/// Int_t fitStatus = h->Fit(myFunc);
4068/// ~~~
4069///
4070/// If the option "S" is instead used, TFitResultPtr behaves as a smart
4071/// pointer to the TFitResult object. This is useful for retrieving the full result information from the fit, such as the covariance matrix,
4072/// as shown in this example code:
4073///
4074/// ~~~ {.cpp}
4075/// TFitResultPtr r = h->Fit(myFunc,"S");
4076/// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
4077/// Double_t chi2 = r->Chi2(); // to retrieve the fit chi2
4078/// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
4079/// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
4080/// r->Print("V"); // print full information of fit including covariance matrix
4081/// r->Write(); // store the result in a file
4082/// ~~~
4083///
4084/// The fit parameters, error and chi-square (but not covariance matrix) can be retrieved also
4085/// directly from the fitted function that is passed to this call.
4086/// Given a pointer to an associated fitted function `myfunc`, one can retrieve the function/fit
4087/// parameters with calls such as:
4088///
4089/// ~~~ {.cpp}
4090/// Double_t chi2 = myfunc->GetChisquare();
4091/// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
4092/// Double_t err0 = myfunc->GetParError(0); //error on first parameter
4093/// ~~~
4094///
4095/// ##### Associated functions
4096///
4097/// One or more object ( can be added to the list
4098/// of functions (fFunctions) associated to each histogram.
4099/// When TH1::Fit is invoked, the fitted function is added to the histogram list of functions (fFunctions).
4100/// If the histogram is made persistent, the list of associated functions is also persistent.
4101/// Given a histogram h, one can retrieve an associated function with:
4102///
4103/// ~~~ {.cpp}
4104/// TF1 *myfunc = h->GetFunction("myfunc");
4105/// ~~~
4106/// or by quering directly the list obtained by calling `TH1::GetListOfFunctions`.
4107///
4108/// \anchor HFitStatus
4109/// ### Fit status
4110///
4111/// The status of the fit is obtained converting the TFitResultPtr to an integer
4112/// independently if the fit option "S" is used or not:
4113///
4114/// ~~~ {.cpp}
4115/// TFitResultPtr r = h->Fit(myFunc,opt);
4116/// Int_t fitStatus = r;
4117/// ~~~
4118///
4119/// - `status = 0` : the fit has been performed successfully (i.e no error occurred).
4120/// - `status < 0` : there is an error not connected with the minimization procedure, for example when a wrong function is used.
4121/// - `status > 0` : return status from Minimizer, depends on used Minimizer. For example for TMinuit and Minuit2 we have:
4122/// - `status = migradStatus + 10*minosStatus + 100*hesseStatus + 1000*improveStatus`.
4123/// 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
4124/// only in Minos but not in Migrad a fitStatus of 40 will be returned.
4125/// Minuit2 returns 0 in case of success and different values in migrad,minos or
4126/// hesse depending on the error. See in this case the documentation of
4127/// Minuit2Minimizer::Minimize for the migrad return status, Minuit2Minimizer::GetMinosError for the
4128/// minos return status and Minuit2Minimizer::Hesse for the hesse return status.
4129/// If other minimizers are used see their specific documentation for the status code returned.
4130/// For example in the case of Fumili, see TFumili::Minimize.
4131///
4132/// \anchor HFitRange
4133/// ### Fitting in a range
4134///
4135/// In order to fit in a sub-range of the histogram you have two options:
4136/// - pass to this function the lower (`xxmin`) and upper (`xxmax`) values for the fitting range;
4137/// - define a specific range in the fitted function and use the fitting option "R".
4138/// For example, if your histogram has a defined range between -4 and 4 and you want to fit a gaussian
4139/// only in the interval 1 to 3, you can do:
4140///
4141/// ~~~ {.cpp}
4142/// TF1 *f1 = new TF1("f1", "gaus", 1, 3);
4143/// histo->Fit("f1", "R");
4144/// ~~~
4145///
4146/// The fitting range is also limited by the histogram range defined using TAxis::SetRange
4147/// or TAxis::SetRangeUser. Therefore the fitting range is the smallest range between the
4148/// histogram one and the one defined by one of the two previous options described above.
4149///
4150/// \anchor HFitInitial
4151/// ### Setting initial conditions
4152///
4153/// Parameters must be initialized before invoking the Fit function.
4154/// The setting of the parameter initial values is automatic for the
4155/// predefined functions such as poln, expo, gaus, landau. One can however disable
4156/// this automatic computation by using the option "B".
4157/// Note that if a predefined function is defined with an argument,
4158/// eg, gaus(0), expo(1), you must specify the initial values for
4159/// the parameters.
4160/// You can specify boundary limits for some or all parameters via
4161///
4162/// ~~~ {.cpp}
4163/// f1->SetParLimits(p_number, parmin, parmax);
4164/// ~~~
4165///
4166/// if `parmin >= parmax`, the parameter is fixed
4167/// Note that you are not forced to fix the limits for all parameters.
4168/// For example, if you fit a function with 6 parameters, you can do:
4169///
4170/// ~~~ {.cpp}
4171/// func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
4172/// func->SetParLimits(3, -10, -4);
4173/// func->FixParameter(4, 0);
4174/// func->SetParLimits(5, 1, 1);
4175/// ~~~
4176///
4177/// With this setup, parameters 0->2 can vary freely
4178/// Parameter 3 has boundaries [-10,-4] with initial value -8
4179/// Parameter 4 is fixed to 0
4180/// Parameter 5 is fixed to 100.
4181/// When the lower limit and upper limit are equal, the parameter is fixed.
4182/// However to fix a parameter to 0, one must call the FixParameter function.
4183///
4184/// \anchor HFitStatBox
4185/// ### Fit Statistics Box
4186///
4187/// The statistics box can display the result of the fit.
4188/// You can change the statistics box to display the fit parameters with
4189/// the TStyle::SetOptFit(mode) method. This mode has four digits.
4190/// mode = pcev (default = 0111)
4191///
4192/// v = 1; print name/values of parameters
4193/// e = 1; print errors (if e=1, v must be 1)
4194/// c = 1; print Chisquare/Number of degrees of freedom
4195/// p = 1; print Probability
4196///
4197/// For example: gStyle->SetOptFit(1011);
4198/// prints the fit probability, parameter names/values, and errors.
4199/// You can change the position of the statistics box with these lines
4200/// (where g is a pointer to the TGraph):
4201///
4202/// TPaveStats *st = (TPaveStats*)g->GetListOfFunctions()->FindObject("stats");
4203/// st->SetX1NDC(newx1); //new x start position
4204/// st->SetX2NDC(newx2); //new x end position
4205///
4206/// \anchor HFitExtra
4207/// ### Additional Notes on Fitting
4208///
4209/// #### Fitting a histogram of dimension N with a function of dimension N-1
4210///
4211/// It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
4212/// 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.
4213/// For correct error scaling, the obtained parameter error are corrected as in the case when the
4214/// option "W" is used.
4215///
4216/// #### User defined objective functions
4217///
4218/// By default when fitting a chi square function is used for fitting. When option "L" is used
4219/// a Poisson likelihood function is used. Using option "MULTI" a multinomial likelihood fit is used.
4220/// Thes functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
4221/// are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
4222/// the file math/mathcore/src/FitUtil.cxx.
4223/// It is possible to specify a user defined fitting function, using option "U" and
4224/// calling the following functions:
4225///
4226/// ~~~ {.cpp}
4227/// TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction);
4228/// ~~~
4229///
4230/// where MyFittingFunction is of type:
4231///
4232/// ~~~ {.cpp}
4233/// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
4234/// ~~~
4235///
4236/// #### Note on treatment of empty bins
4237///
4238/// Empty bins, which have the content equal to zero AND error equal to zero,
4239/// are excluded by default from the chi-square fit, but they are considered in the likelihood fit.
4240/// since they affect the likelihood if the function value in these bins is not negligible.
4241/// Note that if the histogram is having bins with zero content and non zero-errors they are considered as
4242/// any other bins in the fit. Instead bins with zero error and non-zero content are by default excluded in the chi-squared fit.
4243/// In general, one should not fit a histogram with non-empty bins and zero errors.
4244///
4245/// 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
4246/// fit). When using option "WW" the empty bins will be also considered in the chi-square fit with an error of 1.
4247/// Note that in this fitting case (option "W" or "WW") the resulting fitted parameter errors
4248/// are corrected by the obtained chi2 value using this scaling expression:
4249/// `errorp *= sqrt(chisquare/(ndf-1))` as it is done when fitting a TGraph with
4250/// no point errors.
4251///
4252/// #### Excluding points
4253///
4254/// You can use TF1::RejectPoint inside your fitting function to exclude some points
4255/// within a certain range from the fit. See the tutorial `fit/fitExclude.C`.
4256///
4257///
4258/// #### Warning when using the option "0"
4259///
4260/// When selecting the option "0", the fitted function is added to
4261/// the list of functions of the histogram, but it is not drawn when the histogram is drawn.
4262/// You can undo this behaviour resetting its corresponding bit in the TF1 object as following:
4263///
4264/// ~~~ {.cpp}
4265/// h.Fit("myFunction", "0"); // fit, store function but do not draw
4266/// h.Draw(); // function is not drawn
4267/// h.GetFunction("myFunction")->ResetBit(TF1::kNotDraw);
4268/// h.Draw(); // function is visible again
4269/// ~~~
4271
4273{
4274 // implementation of Fit method is in file hist/src/HFitImpl.cxx
4275 Foption_t fitOption;
4277
4278 // create range and minimizer options with default values
4279 ROOT::Fit::DataRange range(xxmin,xxmax);
4281
4282 // need to empty the buffer before
4283 // (t.b.d. do a ML unbinned fit with buffer data)
4284 if (fBuffer) BufferEmpty();
4285
4286 return ROOT::Fit::FitObject(this, f1 , fitOption , minOption, goption, range);
4287}
4288
4289////////////////////////////////////////////////////////////////////////////////
4290/// Display a panel with all histogram fit options.
4291///
4292/// See class TFitPanel for example
4293
4294void TH1::FitPanel()
4295{
4296 if (!gPad)
4297 gROOT->MakeDefCanvas();
4298
4299 if (!gPad) {
4300 Error("FitPanel", "Unable to create a default canvas");
4301 return;
4302 }
4303
4304
4305 // use plugin manager to create instance of TFitEditor
4306 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
4307 if (handler && handler->LoadPlugin() != -1) {
4308 if (handler->ExecPlugin(2, gPad, this) == 0)
4309 Error("FitPanel", "Unable to create the FitPanel");
4310 }
4311 else
4312 Error("FitPanel", "Unable to find the FitPanel plug-in");
4313}
4314
4315////////////////////////////////////////////////////////////////////////////////
4316/// Return a histogram containing the asymmetry of this histogram with h2,
4317/// where the asymmetry is defined as:
4318///
4319/// ~~~ {.cpp}
4320/// Asymmetry = (h1 - h2)/(h1 + h2) where h1 = this
4321/// ~~~
4322///
4323/// works for 1D, 2D, etc. histograms
4324/// c2 is an optional argument that gives a relative weight between the two
4325/// histograms, and dc2 is the error on this weight. This is useful, for example,
4326/// when forming an asymmetry between two histograms from 2 different data sets that
4327/// need to be normalized to each other in some way. The function calculates
4328/// the errors assuming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
4329///
4330/// example: assuming 'h1' and 'h2' are already filled
4331///
4332/// ~~~ {.cpp}
4333/// h3 = h1->GetAsymmetry(h2)
4334/// ~~~
4335///
4336/// then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
4337/// h1 and h2 are left intact.
4338///
4339/// Note that it is the user's responsibility to manage the created histogram.
4340/// The name of the returned histogram will be `Asymmetry_nameOfh1-nameOfh2`
4341///
4342/// code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
4343///
4344/// clone the histograms so top and bottom will have the
4345/// correct dimensions:
4346/// Sumw2 just makes sure the errors will be computed properly
4347/// when we form sums and ratios below.
4348
4350{
4351 TH1 *h1 = this;
4352 TString name = TString::Format("Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4353 TH1 *asym = (TH1*)Clone(name);
4354
4355 // set also the title
4356 TString title = TString::Format("(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4357 asym->SetTitle(title);
4358
4359 asym->Sumw2();
4360 Bool_t addStatus = TH1::AddDirectoryStatus();
4362 TH1 *top = (TH1*)asym->Clone();
4363 TH1 *bottom = (TH1*)asym->Clone();
4364 TH1::AddDirectory(addStatus);
4365
4366 // form the top and bottom of the asymmetry, and then divide:
4367 top->Add(h1,h2,1,-c2);
4368 bottom->Add(h1,h2,1,c2);
4369 asym->Divide(top,bottom);
4370
4371 Int_t xmax = asym->GetNbinsX();
4372 Int_t ymax = asym->GetNbinsY();
4373 Int_t zmax = asym->GetNbinsZ();
4374
4375 if (h1->fBuffer) h1->BufferEmpty(1);
4376 if (h2->fBuffer) h2->BufferEmpty(1);
4377 if (bottom->fBuffer) bottom->BufferEmpty(1);
4378
4379 // now loop over bins to calculate the correct errors
4380 // the reason this error calculation looks complex is because of c2
4381 for(Int_t i=1; i<= xmax; i++){
4382 for(Int_t j=1; j<= ymax; j++){
4383 for(Int_t k=1; k<= zmax; k++){
4384 Int_t bin = GetBin(i, j, k);
4385 // here some bin contents are written into variables to make the error
4386 // calculation a little more legible:
4388 Double_t b = h2->RetrieveBinContent(bin);
4389 Double_t bot = bottom->RetrieveBinContent(bin);
4390
4391 // make sure there are some events, if not, then the errors are set = 0
4392 // automatically.
4393 //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
4394 if(bot < 1e-6){}
4395 else{
4396 // computation of errors by Christos Leonidopoulos
4397 Double_t dasq = h1->GetBinErrorSqUnchecked(bin);
4398 Double_t dbsq = h2->GetBinErrorSqUnchecked(bin);
4399 Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4400 asym->SetBinError(i,j,k,error);
4401 }
4402 }
4403 }
4404 }
4405 delete top;
4406 delete bottom;
4407
4408 return asym;
4409}
4410
4411////////////////////////////////////////////////////////////////////////////////
4412/// Static function
4413/// return the default buffer size for automatic histograms
4414/// the parameter fgBufferSize may be changed via SetDefaultBufferSize
4415
4417{
4418 return fgBufferSize;
4419}
4420
4421////////////////////////////////////////////////////////////////////////////////
4422/// Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
4423/// see TH1::SetDefaultSumw2.
4424
4426{
4427 return fgDefaultSumw2;
4428}
4429
4430////////////////////////////////////////////////////////////////////////////////
4431/// Return the current number of entries.
4432
4434{
4435 if (fBuffer) {
4436 Int_t nentries = (Int_t) fBuffer[0];
4437 if (nentries > 0) return nentries;
4438 }
4439
4440 return fEntries;
4441}
4442
4443////////////////////////////////////////////////////////////////////////////////
4444/// Number of effective entries of the histogram.
4445///
4446/// \f[
4447/// neff = \frac{(\sum Weights )^2}{(\sum Weight^2 )}
4448/// \f]
4449///
4450/// In case of an unweighted histogram this number is equivalent to the
4451/// number of entries of the histogram.
4452/// For a weighted histogram, this number corresponds to the hypothetical number of unweighted entries
4453/// a histogram would need to have the same statistical power as this weighted histogram.
4454/// Note: The underflow/overflow are included if one has set the TH1::StatOverFlows flag
4455/// and if the statistics has been computed at filling time.
4456/// If a range is set in the histogram the number is computed from the given range.
4457
4459{
4460 Stat_t s[kNstat];
4461 this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
4462 return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4463}
4464
4465////////////////////////////////////////////////////////////////////////////////
4466/// Shortcut to set the three histogram colors with a single call.
4467///
4468/// By default: linecolor = markercolor = fillcolor = -1
4469/// If a color is < 0 this method does not change the corresponding color if positive or null it set the color.
4470///
4471/// For instance:
4472/// ~~~ {.cpp}
4473/// h->SetColors(kRed, kRed);
4474/// ~~~
4475/// will set the line color and the marker color to red.
4476
4477void TH1::SetColors(Color_t linecolor, Color_t markercolor, Color_t fillcolor)
4478{
4479 if (linecolor >= 0)
4480 SetLineColor(linecolor);
4481 if (markercolor >= 0)
4482 SetMarkerColor(markercolor);
4483 if (fillcolor >= 0)
4484 SetFillColor(fillcolor);
4485}
4486
4487
4488////////////////////////////////////////////////////////////////////////////////
4489/// Set highlight (enable/disable) mode for the histogram
4490/// by default highlight mode is disable
4491
4492void TH1::SetHighlight(Bool_t set)
4493{
4494 if (IsHighlight() == set)
4495 return;
4496 if (fDimension > 2) {
4497 Info("SetHighlight", "Supported only 1-D or 2-D histograms");
4498 return;
4499 }
4500
4501 SetBit(kIsHighlight, set);
4502
4503 if (fPainter)
4505}
4506
4507////////////////////////////////////////////////////////////////////////////////
4508/// Redefines TObject::GetObjectInfo.
4509/// Displays the histogram info (bin number, contents, integral up to bin
4510/// corresponding to cursor position px,py
4511
4512char *TH1::GetObjectInfo(Int_t px, Int_t py) const
4513{
4514 return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
4515}
4516
4517////////////////////////////////////////////////////////////////////////////////
4518/// Return pointer to painter.
4519/// If painter does not exist, it is created
4520
4522{
4523 if (!fPainter) {
4524 TString opt = option;
4525 opt.ToLower();
4526 if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
4527 //try to create TGLHistPainter
4528 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
4529
4530 if (handler && handler->LoadPlugin() != -1)
4531 fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
4532 }
4533 }
4534
4536
4537 return fPainter;
4538}
4539
4540////////////////////////////////////////////////////////////////////////////////
4541/// Compute Quantiles for this histogram
4542/// Quantile x_p := Q(p) is defined as the value x_p such that the cumulative
4543/// probability distribution Function F of variable X yields:
4544///
4545/// ~~~ {.cpp}
4546/// F(x_p) = Pr(X <= x_p) = p with 0 <= p <= 1.
4547/// x_p = Q(p) = F_inv(p)
4548/// ~~~
4549///
4550/// For instance the median x_0.5 of a distribution is defined as that value
4551/// of the random variable X for which the distribution function equals 0.5:
4552///
4553/// ~~~ {.cpp}
4554/// F(x_0.5) = Probability(X < x_0.5) = 0.5
4555/// x_0.5 = Q(0.5)
4556/// ~~~
4557///
4558/// \author Eddy Offermann
4559/// code from Eddy Offermann, Renaissance
4560///
4561/// \param[in] n maximum size of array xp and size of array p (if given)
4562/// \param[out] xp array to be filled with nq quantiles evaluated at (p). Memory has to be preallocated by caller.
4563/// If p is null (default value), then xp is actually set to the (first n) histogram bin edges
4564/// \param[in] p array of cumulative probabilities where quantiles should be evaluated.
4565/// - if p is null, the CDF of the histogram will be used instead as array, and will
4566/// have a size = number of bins + 1 in h. It will correspond to the
4567/// quantiles calculated at the lowest edge of the histogram (quantile=0) and
4568/// all the upper edges of the bins. (nbins might be > n).
4569/// - if p is not null, it is assumed to contain at least n values.
4570/// \return value nq (<=n) with the number of quantiles computed
4571///
4572/// Note that the Integral of the histogram is automatically recomputed
4573/// if the number of entries is different of the number of entries when
4574/// the integral was computed last time. In case you do not use the Fill
4575/// functions to fill your histogram, but SetBinContent, you must call
4576/// TH1::ComputeIntegral before calling this function.
4577///
4578/// Getting quantiles xp from two histograms and storing results in a TGraph,
4579/// a so-called QQ-plot
4580///
4581/// ~~~ {.cpp}
4582/// TGraph *gr = new TGraph(nprob);
4583/// h1->GetQuantiles(nprob,gr->GetX());
4584/// h2->GetQuantiles(nprob,gr->GetY());
4585/// gr->Draw("alp");
4586/// ~~~
4587///
4588/// Example:
4589///
4590/// ~~~ {.cpp}
4591/// void quantiles() {
4592/// // demo for quantiles
4593/// const Int_t nq = 20;
4594/// TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
4595/// h->FillRandom("gaus",5000);
4596/// h->GetXaxis()->SetTitle("x");
4597/// h->GetYaxis()->SetTitle("Counts");
4598///
4599/// Double_t p[nq]; // probabilities where to evaluate the quantiles in [0,1]
4600/// Double_t xp[nq]; // array of positions X to store the resulting quantiles
4601/// for (Int_t i=0;i<nq;i++) p[i] = Float_t(i+1)/nq;
4602/// h->GetQuantiles(nq,xp,p);
4603///
4604/// //show the original histogram in the top pad
4605/// TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
4606/// c1->Divide(1,2);
4607/// c1->cd(1);
4608/// h->Draw();
4609///
4610/// // show the quantiles in the bottom pad
4611/// c1->cd(2);
4612/// gPad->SetGrid();
4613/// TGraph *gr = new TGraph(nq,p,xp);
4614/// gr->SetMarkerStyle(21);
4615/// gr->GetXaxis()->SetTitle("p");
4616/// gr->GetYaxis()->SetTitle("x");
4617/// gr->Draw("alp");
4618/// }
4619/// ~~~
4620
4622{
4623 if (GetDimension() > 1) {
4624 Error("GetQuantiles","Only available for 1-d histograms");
4625 return 0;
4626 }
4627
4628 const Int_t nbins = GetXaxis()->GetNbins();
4629 if (!fIntegral) ComputeIntegral();
4630 if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4631
4632 Int_t i, ibin;
4633 Double_t *prob = (Double_t*)p;
4634 Int_t nq = n;
4635 if (p == nullptr) {
4636 nq = nbins+1;
4637 prob = new Double_t[nq];
4638 prob[0] = 0;
4639 for (i=1;i<nq;i++) {
4640 prob[i] = fIntegral[i]/fIntegral[nbins];
4641 }
4642 }
4643
4644 for (i = 0; i < nq; i++) {
4645 ibin = TMath::BinarySearch(nbins,fIntegral,prob[i]);
4646 if (fIntegral[ibin] == prob[i]) {
4647 if (prob[i] == 0.) {
4648 for (; ibin+1 <= nbins && fIntegral[ibin+1] == 0.; ++ibin) {
4649
4650 }
4651 xp[i] = fXaxis.GetBinUpEdge(ibin);
4652 }
4653 else if (prob[i] == 1.) {
4654 xp[i] = fXaxis.GetBinUpEdge(ibin);
4655 }
4656 else {
4657 // Find equal integral in later bins (ie their entries are zero)
4658 Double_t width = 0;
4659 for (Int_t j = ibin+1; j <= nbins; ++j) {
4660 if (prob[i] == fIntegral[j]) {
4661 width += fXaxis.GetBinWidth(j);
4662 }
4663 else
4664 break;
4665 }
4666 xp[i] = width == 0 ? fXaxis.GetBinCenter(ibin) : fXaxis.GetBinUpEdge(ibin) + width/2.;
4667 }
4668 }
4669 else {
4670 xp[i] = GetBinLowEdge(ibin+1);
4671 const Double_t dint = fIntegral[ibin+1]-fIntegral[ibin];
4672 if (dint > 0) xp[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4673 }
4674 }
4675
4676 if (!p) delete [] prob;
4677 return nq;
4678}
4679
4680////////////////////////////////////////////////////////////////////////////////
4681/// Decode string choptin and fill fitOption structure.
4682
4683Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
4684{
4686 return 1;
4687}
4688
4689////////////////////////////////////////////////////////////////////////////////
4690/// Compute Initial values of parameters for a gaussian.
4691
4692void H1InitGaus()
4693{
4694 Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4695 Int_t bin;
4696 const Double_t sqrtpi = 2.506628;
4697
4698 // - Compute mean value and StdDev of the histogram in the given range
4700 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4701 Int_t hxfirst = hFitter->GetXfirst();
4702 Int_t hxlast = hFitter->GetXlast();
4703 Double_t valmax = curHist->GetBinContent(hxfirst);
4704 Double_t binwidx = curHist->GetBinWidth(hxfirst);
4705 allcha = sumx = sumx2 = 0;
4706 for (bin=hxfirst;bin<=hxlast;bin++) {
4707 x = curHist->GetBinCenter(bin);
4708 val = TMath::Abs(curHist->GetBinContent(bin));
4709 if (val > valmax) valmax = val;
4710 sumx += val*x;
4711 sumx2 += val*x*x;
4712 allcha += val;
4713 }
4714 if (allcha == 0) return;
4715 mean = sumx/allcha;
4716 stddev = sumx2/allcha - mean*mean;
4717 if (stddev > 0) stddev = TMath::Sqrt(stddev);
4718 else stddev = 0;
4719 if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4720 //if the distribution is really gaussian, the best approximation
4721 //is binwidx*allcha/(sqrtpi*stddev)
4722 //However, in case of non-gaussian tails, this underestimates
4723 //the normalisation constant. In this case the maximum value
4724 //is a better approximation.
4725 //We take the average of both quantities
4726 Double_t constant = 0.5*(valmax+binwidx*allcha/(sqrtpi*stddev));
4727
4728 //In case the mean value is outside the histo limits and
4729 //the StdDev is bigger than the range, we take
4730 // mean = center of bins
4731 // stddev = half range
4732 Double_t xmin = curHist->GetXaxis()->GetXmin();
4733 Double_t xmax = curHist->GetXaxis()->GetXmax();
4734 if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4735 mean = 0.5*(xmax+xmin);
4736 stddev = 0.5*(xmax-xmin);
4737 }
4738 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4739 f1->SetParameter(0,constant);
4740 f1->SetParameter(1,mean);
4741 f1->SetParameter(2,stddev);
4742 f1->SetParLimits(2,0,10*stddev);
4743}
4744
4745////////////////////////////////////////////////////////////////////////////////
4746/// Compute Initial values of parameters for an exponential.
4747
4748void H1InitExpo()
4749{
4750 Double_t constant, slope;
4751 Int_t ifail;
4753 Int_t hxfirst = hFitter->GetXfirst();
4754 Int_t hxlast = hFitter->GetXlast();
4755 Int_t nchanx = hxlast - hxfirst + 1;
4756
4757 H1LeastSquareLinearFit(-nchanx, constant, slope, ifail);
4758
4759 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4760 f1->SetParameter(0,constant);
4761 f1->SetParameter(1,slope);
4762
4763}
4764
4765////////////////////////////////////////////////////////////////////////////////
4766/// Compute Initial values of parameters for a polynom.
4767
4768void H1InitPolynom()
4769{
4770 Double_t fitpar[25];
4771
4773 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4774 Int_t hxfirst = hFitter->GetXfirst();
4775 Int_t hxlast = hFitter->GetXlast();
4776 Int_t nchanx = hxlast - hxfirst + 1;
4777 Int_t npar = f1->GetNpar();
4778
4779 if (nchanx <=1 || npar == 1) {
4780 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4781 fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4782 } else {
4783 H1LeastSquareFit( nchanx, npar, fitpar);
4784 }
4785 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4786}
4787
4788////////////////////////////////////////////////////////////////////////////////
4789/// Least squares lpolynomial fitting without weights.
4790///
4791/// \param[in] n number of points to fit
4792/// \param[in] m number of parameters
4793/// \param[in] a array of parameters
4794///
4795/// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
4796/// (E.Keil. revised by B.Schorr, 23.10.1981.)
4797
4799{
4800 const Double_t zero = 0.;
4801 const Double_t one = 1.;
4802 const Int_t idim = 20;
4803
4804 Double_t b[400] /* was [20][20] */;
4805 Int_t i, k, l, ifail;
4806 Double_t power;
4807 Double_t da[20], xk, yk;
4808
4809 if (m <= 2) {
4810 H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4811 return;
4812 }
4813 if (m > idim || m > n) return;
4814 b[0] = Double_t(n);
4815 da[0] = zero;
4816 for (l = 2; l <= m; ++l) {
4817 b[l-1] = zero;
4818 b[m + l*20 - 21] = zero;
4819 da[l-1] = zero;
4820 }
4822 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4823 Int_t hxfirst = hFitter->GetXfirst();
4824 Int_t hxlast = hFitter->GetXlast();
4825 for (k = hxfirst; k <= hxlast; ++k) {
4826 xk = curHist->GetBinCenter(k);
4827 yk = curHist->GetBinContent(k);
4828 power = one;
4829 da[0] += yk;
4830 for (l = 2; l <= m; ++l) {
4831 power *= xk;
4832 b[l-1] += power;
4833 da[l-1] += power*yk;
4834 }
4835 for (l = 2; l <= m; ++l) {
4836 power *= xk;
4837 b[m + l*20 - 21] += power;
4838 }
4839 }
4840 for (i = 3; i <= m; ++i) {
4841 for (k = i; k <= m; ++k) {
4842 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4843 }
4844 }
4845 H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
4846
4847 for (i=0; i<m; ++i) a[i] = da[i];
4848
4849}
4850
4851////////////////////////////////////////////////////////////////////////////////
4852/// Least square linear fit without weights.
4853///
4854/// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
4855/// (added to LSQ by B. Schorr, 15.02.1982.)
4856
4857void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
4858{
4859 Double_t xbar, ybar, x2bar;
4860 Int_t i, n;
4861 Double_t xybar;
4862 Double_t fn, xk, yk;
4863 Double_t det;
4864
4865 n = TMath::Abs(ndata);
4866 ifail = -2;
4867 xbar = ybar = x2bar = xybar = 0;
4869 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4870 Int_t hxfirst = hFitter->GetXfirst();
4871 Int_t hxlast = hFitter->GetXlast();
4872 for (i = hxfirst; i <= hxlast; ++i) {
4873 xk = curHist->GetBinCenter(i);
4874 yk = curHist->GetBinContent(i);
4875 if (ndata < 0) {
4876 if (yk <= 0) yk = 1e-9;
4877 yk = TMath::Log(yk);
4878 }
4879 xbar += xk;
4880 ybar += yk;
4881 x2bar += xk*xk;
4882 xybar += xk*yk;
4883 }
4884 fn = Double_t(n);
4885 det = fn*x2bar - xbar*xbar;
4886 ifail = -1;
4887 if (det <= 0) {
4888 a0 = ybar/fn;
4889 a1 = 0;
4890 return;
4891 }
4892 ifail = 0;
4893 a0 = (x2bar*ybar - xbar*xybar) / det;
4894 a1 = (fn*xybar - xbar*ybar) / det;
4895
4896}
4897
4898////////////////////////////////////////////////////////////////////////////////
4899/// Extracted from CERN Program library routine DSEQN.
4900///
4901/// Translated to C++ by Rene Brun
4902
4903void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b)
4904{
4905 Int_t a_dim1, a_offset, b_dim1, b_offset;
4906 Int_t nmjp1, i, j, l;
4907 Int_t im1, jp1, nm1, nmi;
4908 Double_t s1, s21, s22;
4909 const Double_t one = 1.;
4910
4911 /* Parameter adjustments */
4912 b_dim1 = idim;
4913 b_offset = b_dim1 + 1;
4914 b -= b_offset;
4915 a_dim1 = idim;
4916 a_offset = a_dim1 + 1;
4917 a -= a_offset;
4918
4919 if (idim < n) return;
4920
4921 ifail = 0;
4922 for (j = 1; j <= n; ++j) {
4923 if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
4924 a[j + j*a_dim1] = one / a[j + j*a_dim1];
4925 if (j == n) continue;
4926 jp1 = j + 1;
4927 for (l = jp1; l <= n; ++l) {
4928 a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4929 s1 = -a[l + (j+1)*a_dim1];
4930 for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4931 a[l + (j+1)*a_dim1] = -s1;
4932 }
4933 }
4934 if (k <= 0) return;
4935
4936 for (l = 1; l <= k; ++l) {
4937 b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
4938 }
4939 if (n == 1) return;
4940 for (l = 1; l <= k; ++l) {
4941 for (i = 2; i <= n; ++i) {
4942 im1 = i - 1;
4943 s21 = -b[i + l*b_dim1];
4944 for (j = 1; j <= im1; ++j) {
4945 s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
4946 }
4947 b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
4948 }
4949 nm1 = n - 1;
4950 for (i = 1; i <= nm1; ++i) {
4951 nmi = n - i;
4952 s22 = -b[nmi + l*b_dim1];
4953 for (j = 1; j <= i; ++j) {
4954 nmjp1 = n - j + 1;
4955 s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
4956 }
4957 b[nmi + l*b_dim1] = -s22;
4958 }
4959 }
4960}
4961
4962////////////////////////////////////////////////////////////////////////////////
4963/// Return Global bin number corresponding to binx,y,z.
4964///
4965/// 2-D and 3-D histograms are represented with a one dimensional
4966/// structure.
4967/// This has the advantage that all existing functions, such as
4968/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
4969///
4970/// In case of a TH1x, returns binx directly.
4971/// see TH1::GetBinXYZ for the inverse transformation.
4972///
4973/// Convention for numbering bins
4974///
4975/// For all histogram types: nbins, xlow, xup
4976///
4977/// - bin = 0; underflow bin
4978/// - bin = 1; first bin with low-edge xlow INCLUDED
4979/// - bin = nbins; last bin with upper-edge xup EXCLUDED
4980/// - bin = nbins+1; overflow bin
4981///
4982/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4983/// For example, assuming a 3-D histogram with binx,biny,binz, the function
4984///
4985/// ~~~ {.cpp}
4986/// Int_t bin = h->GetBin(binx,biny,binz);
4987/// ~~~
4988///
4989/// returns a global/linearized bin number. This global bin is useful
4990/// to access the bin information independently of the dimension.
4991
4992Int_t TH1::GetBin(Int_t binx, Int_t, Int_t) const
4993{
4994 Int_t ofx = fXaxis.GetNbins() + 1; // overflow bin
4995 if (binx < 0) binx = 0;
4996 if (binx > ofx) binx = ofx;
4997
4998 return binx;
4999}
5000
5001////////////////////////////////////////////////////////////////////////////////
5002/// Return binx, biny, binz corresponding to the global bin number globalbin
5003/// see TH1::GetBin function above
5004
5005void TH1::GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz) const
5006{
5007 Int_t nx = fXaxis.GetNbins()+2;
5008 Int_t ny = fYaxis.GetNbins()+2;
5009
5010 if (GetDimension() == 1) {
5011 binx = binglobal%nx;
5012 biny = 0;
5013 binz = 0;
5014 return;
5015 }
5016 if (GetDimension() == 2) {
5017 binx = binglobal%nx;
5018 biny = ((binglobal-binx)/nx)%ny;
5019 binz = 0;
5020 return;
5021 }
5022 if (GetDimension() == 3) {
5023 binx = binglobal%nx;
5024 biny = ((binglobal-binx)/nx)%ny;
5025 binz = ((binglobal-binx)/nx -biny)/ny;
5026 }
5027}
5028
5029////////////////////////////////////////////////////////////////////////////////
5030/// Return a random number distributed according the histogram bin contents.
5031/// This function checks if the bins integral exists. If not, the integral
5032/// is evaluated, normalized to one.
5033///
5034/// @param rng (optional) Random number generator pointer used (default is gRandom)
5035///
5036/// The integral is automatically recomputed if the number of entries
5037/// is not the same then when the integral was computed.
5038/// NB Only valid for 1-d histograms. Use GetRandom2 or 3 otherwise.
5039/// If the histogram has a bin with negative content a NaN is returned
5040
5041Double_t TH1::GetRandom(TRandom * rng) const
5042{
5043 if (fDimension > 1) {
5044 Error("GetRandom","Function only valid for 1-d histograms");
5045 return 0;
5046 }
5047 Int_t nbinsx = GetNbinsX();
5048 Double_t integral = 0;
5049 // compute integral checking that all bins have positive content (see ROOT-5894)
5050 if (fIntegral) {
5051 if (fIntegral[nbinsx+1] != fEntries) integral = ((TH1*)this)->ComputeIntegral(true);
5052 else integral = fIntegral[nbinsx];
5053 } else {
5054 integral = ((TH1*)this)->ComputeIntegral(true);
5055 }
5056 if (integral == 0) return 0;
5057 // return a NaN in case some bins have negative content
5058 if (integral == TMath::QuietNaN() ) return TMath::QuietNaN();
5059
5060 Double_t r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
5061 Int_t ibin = TMath::BinarySearch(nbinsx,fIntegral,r1);
5062 Double_t x = GetBinLowEdge(ibin+1);
5063 if (r1 > fIntegral[ibin]) x +=
5064 GetBinWidth(ibin+1)*(r1-fIntegral[ibin])/(fIntegral[ibin+1] - fIntegral[ibin]);
5065 return x;
5066}
5067
5068////////////////////////////////////////////////////////////////////////////////
5069/// Return content of bin number bin.
5070///
5071/// Implemented in TH1C,S,F,D
5072///
5073/// Convention for numbering bins
5074///
5075/// For all histogram types: nbins, xlow, xup
5076///
5077/// - bin = 0; underflow bin
5078/// - bin = 1; first bin with low-edge xlow INCLUDED
5079/// - bin = nbins; last bin with upper-edge xup EXCLUDED
5080/// - bin = nbins+1; overflow bin
5081///
5082/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
5083/// For example, assuming a 3-D histogram with binx,biny,binz, the function
5084///
5085/// ~~~ {.cpp}
5086/// Int_t bin = h->GetBin(binx,biny,binz);
5087/// ~~~
5088///
5089/// returns a global/linearized bin number. This global bin is useful
5090/// to access the bin information independently of the dimension.
5091
5093{
5094 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
5095 if (bin < 0) bin = 0;
5096 if (bin >= fNcells) bin = fNcells-1;
5097
5098 return RetrieveBinContent(bin);
5099}
5100
5101////////////////////////////////////////////////////////////////////////////////
5102/// Compute first binx in the range [firstx,lastx] for which
5103/// diff = abs(bin_content-c) <= maxdiff
5104///
5105/// In case several bins in the specified range with diff=0 are found
5106/// the first bin found is returned in binx.
5107/// In case several bins in the specified range satisfy diff <=maxdiff
5108/// the bin with the smallest difference is returned in binx.
5109/// In all cases the function returns the smallest difference.
5110///
5111/// NOTE1: if firstx <= 0, firstx is set to bin 1
5112/// if (lastx < firstx then firstx is set to the number of bins
5113/// ie if firstx=0 and lastx=0 (default) the search is on all bins.
5114///
5115/// NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
5116
5117Double_t TH1::GetBinWithContent(Double_t c, Int_t &binx, Int_t firstx, Int_t lastx,Double_t maxdiff) const
5118{
5119 if (fDimension > 1) {
5120 binx = 0;
5121 Error("GetBinWithContent","function is only valid for 1-D histograms");
5122 return 0;
5123 }
5124
5125 if (fBuffer) ((TH1*)this)->BufferEmpty();
5126
5127 if (firstx <= 0) firstx = 1;
5128 if (lastx < firstx) lastx = fXaxis.GetNbins();
5129 Int_t binminx = 0;
5130 Double_t diff, curmax = 1.e240;
5131 for (Int_t i=firstx;i<=lastx;i++) {
5132 diff = TMath::Abs(RetrieveBinContent(i)-c);
5133 if (diff <= 0) {binx = i; return diff;}
5134 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
5135 }
5136 binx = binminx;
5137 return curmax;
5138}
5139
5140////////////////////////////////////////////////////////////////////////////////
5141/// Given a point x, approximates the value via linear interpolation
5142/// based on the two nearest bin centers
5143///
5144/// Andy Mastbaum 10/21/08
5145
5147{
5148 if (fBuffer) ((TH1*)this)->BufferEmpty();
5149
5150 Int_t xbin = fXaxis.FindFixBin(x);
5151 Double_t x0,x1,y0,y1;
5152
5153 if(x<=GetBinCenter(1)) {
5154 return RetrieveBinContent(1);
5155 } else if(x>=GetBinCenter(GetNbinsX())) {
5156 return RetrieveBinContent(GetNbinsX());
5157 } else {
5158 if(x<=GetBinCenter(xbin)) {
5159 y0 = RetrieveBinContent(xbin-1);
5160 x0 = GetBinCenter(xbin-1);
5161 y1 = RetrieveBinContent(xbin);
5162 x1 = GetBinCenter(xbin);
5163 } else {
5164 y0 = RetrieveBinContent(xbin);
5165 x0 = GetBinCenter(xbin);
5166 y1 = RetrieveBinContent(xbin+1);
5167 x1 = GetBinCenter(xbin+1);
5168 }
5169 return y0 + (x-x0)*((y1-y0)/(x1-x0));
5170 }
5171}
5172
5173////////////////////////////////////////////////////////////////////////////////
5174/// 2d Interpolation. Not yet implemented.
5175
5177{
5178 Error("Interpolate","This function must be called with 1 argument for a TH1");
5179 return 0;
5180}
5181
5182////////////////////////////////////////////////////////////////////////////////
5183/// 3d Interpolation. Not yet implemented.
5184
5186{
5187 Error("Interpolate","This function must be called with 1 argument for a TH1");
5188 return 0;
5189}
5190
5191///////////////////////////////////////////////////////////////////////////////
5192/// Check if a histogram is empty
5193/// (this is a protected method used mainly by TH1Merger )
5194
5195Bool_t TH1::IsEmpty() const
5196{
5197 // if fTsumw or fentries are not zero histogram is not empty
5198 // need to use GetEntries() instead of fEntries in case of bugger histograms
5199 // so we will flash the buffer
5200 if (fTsumw != 0) return kFALSE;
5201 if (GetEntries() != 0) return kFALSE;
5202 // case fTSumw == 0 amd entries are also zero
5203 // this should not really happening, but if one sets content by hand
5204 // it can happen. a call to ResetStats() should be done in such cases
5205 double sumw = 0;
5206 for (int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
5207 return (sumw != 0) ? kFALSE : kTRUE;
5208}
5209
5210////////////////////////////////////////////////////////////////////////////////
5211/// Return true if the bin is overflow.
5212
5213Bool_t TH1::IsBinOverflow(Int_t bin, Int_t iaxis) const
5214{
5215 Int_t binx, biny, binz;
5216 GetBinXYZ(bin, binx, biny, binz);
5217
5218 if (iaxis == 0) {
5219 if ( fDimension == 1 )
5220 return binx >= GetNbinsX() + 1;
5221 if ( fDimension == 2 )
5222 return (binx >= GetNbinsX() + 1) ||
5223 (biny >= GetNbinsY() + 1);
5224 if ( fDimension == 3 )
5225 return (binx >= GetNbinsX() + 1) ||
5226 (biny >= GetNbinsY() + 1) ||
5227 (binz >= GetNbinsZ() + 1);
5228 return kFALSE;
5229 }
5230 if (iaxis == 1)
5231 return binx >= GetNbinsX() + 1;
5232 if (iaxis == 2)
5233 return biny >= GetNbinsY() + 1;
5234 if (iaxis == 3)
5235 return binz >= GetNbinsZ() + 1;
5236
5237 Error("IsBinOverflow","Invalid axis value");
5238 return kFALSE;
5239}
5240
5241////////////////////////////////////////////////////////////////////////////////
5242/// Return true if the bin is underflow.
5243/// If iaxis = 0 make OR with all axes otherwise check only for the given axis
5244
5245Bool_t TH1::IsBinUnderflow(Int_t bin, Int_t iaxis) const
5246{
5247 Int_t binx, biny, binz;
5248 GetBinXYZ(bin, binx, biny, binz);
5249
5250 if (iaxis == 0) {
5251 if ( fDimension == 1 )
5252 return (binx <= 0);
5253 else if ( fDimension == 2 )
5254 return (binx <= 0 || biny <= 0);
5255 else if ( fDimension == 3 )
5256 return (binx <= 0 || biny <= 0 || binz <= 0);
5257 else
5258 return kFALSE;
5259 }
5260 if (iaxis == 1)
5261 return (binx <= 0);
5262 if (iaxis == 2)
5263 return (biny <= 0);
5264 if (iaxis == 3)
5265 return (binz <= 0);
5266
5267 Error("IsBinUnderflow","Invalid axis value");
5268 return kFALSE;
5269}
5270
5271////////////////////////////////////////////////////////////////////////////////
5272/// Reduce the number of bins for the axis passed in the option to the number of bins having a label.
5273/// The method will remove only the extra bins existing after the last "labeled" bin.
5274/// Note that if there are "un-labeled" bins present between "labeled" bins they will not be removed
5275
5277{
5278 Int_t iaxis = AxisChoice(ax);
5279 TAxis *axis = nullptr;
5280 if (iaxis == 1) axis = GetXaxis();
5281 if (iaxis == 2) axis = GetYaxis();
5282 if (iaxis == 3) axis = GetZaxis();
5283 if (!axis) {
5284 Error("LabelsDeflate","Invalid axis option %s",ax);
5285 return;
5286 }
5287 if (!axis->GetLabels()) return;
5288
5289 // find bin with last labels
5290 // bin number is object ID in list of labels
5291 // therefore max bin number is number of bins of the deflated histograms
5292 TIter next(axis->GetLabels());
5293 TObject *obj;
5294 Int_t nbins = 0;
5295 while ((obj = next())) {
5296 Int_t ibin = obj->GetUniqueID();
5297 if (ibin > nbins) nbins = ibin;
5298 }
5299 if (nbins < 1) nbins = 1;
5300
5301 // Do nothing in case it was the last bin
5302 if (nbins==axis->GetNbins()) return;
5303
5304 TH1 *hold = (TH1*)IsA()->New();
5305 R__ASSERT(hold);
5306 hold->SetDirectory(nullptr);
5307 Copy(*hold);
5308
5309 Bool_t timedisp = axis->GetTimeDisplay();
5310 Double_t xmin = axis->GetXmin();
5311 Double_t xmax = axis->GetBinUpEdge(nbins);
5312 if (xmax <= xmin) xmax = xmin +nbins;
5313 axis->SetRange(0,0);
5314 axis->Set(nbins,xmin,xmax);
5315 SetBinsLength(-1); // reset the number of cells
5316 Int_t errors = fSumw2.fN;
5317 if (errors) fSumw2.Set(fNcells);
5318 axis->SetTimeDisplay(timedisp);
5319 // reset histogram content
5320 Reset("ICE");
5321
5322 //now loop on all bins and refill
5323 // NOTE that if the bins without labels have content
5324 // it will be put in the underflow/overflow.
5325 // For this reason we use AddBinContent method
5326 Double_t oldEntries = fEntries;
5327 Int_t bin,binx,biny,binz;
5328 for (bin=0; bin < hold->fNcells; ++bin) {
5329 hold->GetBinXYZ(bin,binx,biny,binz);
5330 Int_t ibin = GetBin(binx,biny,binz);
5331 Double_t cu = hold->RetrieveBinContent(bin);
5332 AddBinContent(ibin,cu);
5333 if (errors) {
5334 fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5335 }
5336 }
5337 fEntries = oldEntries;
5338 delete hold;
5339}
5340
5341////////////////////////////////////////////////////////////////////////////////
5342/// Double the number of bins for axis.
5343/// Refill histogram.
5344/// This function is called by TAxis::FindBin(const char *label)
5345
5347{
5348 Int_t iaxis = AxisChoice(ax);
5349 TAxis *axis = nullptr;
5350 if (iaxis == 1) axis = GetXaxis();
5351 if (iaxis == 2) axis = GetYaxis();
5352 if (iaxis == 3) axis = GetZaxis();
5353 if (!axis) return;
5354
5355 TH1 *hold = (TH1*)IsA()->New();
5356 hold->SetDirectory(nullptr);
5357 Copy(*hold);
5358 hold->ResetBit(kMustCleanup);
5359
5360 Bool_t timedisp = axis->GetTimeDisplay();
5361 Int_t nbins = axis->GetNbins();
5362 Double_t xmin = axis->GetXmin();
5363 Double_t xmax = axis->GetXmax();
5364 xmax = xmin + 2*(xmax-xmin);
5365 axis->SetRange(0,0);
5366 // double the bins and recompute ncells
5367 axis->Set(2*nbins,xmin,xmax);
5368 SetBinsLength(-1);
5369 Int_t errors = fSumw2.fN;
5370 if (errors) fSumw2.Set(fNcells);
5371 axis->SetTimeDisplay(timedisp);
5372
5373 Reset("ICE"); // reset content and error
5374
5375 //now loop on all bins and refill
5376 Double_t oldEntries = fEntries;
5377 Int_t bin,ibin,binx,biny,binz;
5378 for (ibin =0; ibin < hold->fNcells; ibin++) {
5379 // get the binx,y,z values . The x-y-z (axis) bin values will stay the same between new-old after the expanding
5380 hold->GetBinXYZ(ibin,binx,biny,binz);
5381 bin = GetBin(binx,biny,binz);
5382
5383 // underflow and overflow will be cleaned up because their meaning has been altered
5384 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5385 continue;
5386 }
5387 else {
5388 AddBinContent(bin, hold->RetrieveBinContent(ibin));
5389 if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5390 }
5391 }
5392 fEntries = oldEntries;
5393 delete hold;
5394}
5395
5396////////////////////////////////////////////////////////////////////////////////
5397/// Sort bins with labels or set option(s) to draw axis with labels
5398/// \param[in] option
5399/// - "a" sort by alphabetic order
5400/// - ">" sort by decreasing values
5401/// - "<" sort by increasing values
5402/// - "h" draw labels horizontal
5403/// - "v" draw labels vertical
5404/// - "u" draw labels up (end of label right adjusted)
5405/// - "d" draw labels down (start of label left adjusted)
5406///
5407/// In case not all bins have labels sorting will work only in the case
5408/// the first `n` consecutive bins have all labels and sorting will be performed on
5409/// those label bins.
5410///
5411/// \param[in] ax axis
5412
5414{
5415 Int_t iaxis = AxisChoice(ax);
5416 TAxis *axis = nullptr;
5417 if (iaxis == 1)
5418 axis = GetXaxis();
5419 if (iaxis == 2)
5420 axis = GetYaxis();
5421 if (iaxis == 3)
5422 axis = GetZaxis();
5423 if (!axis)
5424 return;
5425 THashList *labels = axis->GetLabels();
5426 if (!labels) {
5427 Warning("LabelsOption", "Axis %s has no labels!",axis->GetName());
5428 return;
5429 }
5430 TString opt = option;
5431 opt.ToLower();
5432 Int_t iopt = -1;
5433 if (opt.Contains("h")) {
5438 iopt = 0;
5439 }
5440 if (opt.Contains("v")) {
5445 iopt = 1;
5446 }
5447 if (opt.Contains("u")) {
5448 axis->SetBit(TAxis::kLabelsUp);
5452 iopt = 2;
5453 }
5454 if (opt.Contains("d")) {
5459 iopt = 3;
5460 }
5461 Int_t sort = -1;
5462 if (opt.Contains("a"))
5463 sort = 0;
5464 if (opt.Contains(">"))
5465 sort = 1;
5466 if (opt.Contains("<"))
5467 sort = 2;
5468 if (sort < 0) {
5469 if (iopt < 0)
5470 Error("LabelsOption", "%s is an invalid label placement option!",opt.Data());
5471 return;
5472 }
5473
5474 // Code works only if first n bins have labels if we uncomment following line
5475 // but we don't want to support this special case
5476 // Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5477
5478 // support only cases where each bin has a labels (should be when axis is alphanumeric)
5479 Int_t n = labels->GetSize();
5480 if (n != axis->GetNbins()) {
5481 // check if labels are all consecutive and starts from the first bin
5482 // in that case the current code will work fine
5483 Int_t firstLabelBin = axis->GetNbins()+1;
5484 Int_t lastLabelBin = -1;
5485 for (Int_t i = 0; i < n; ++i) {
5486 Int_t bin = labels->At(i)->GetUniqueID();
5487 if (bin < firstLabelBin) firstLabelBin = bin;
5488 if (bin > lastLabelBin) lastLabelBin = bin;
5489 }
5490 if (firstLabelBin != 1 || lastLabelBin-firstLabelBin +1 != n) {
5491 Error("LabelsOption", "%s of Histogram %s contains bins without labels. Sorting will not work correctly - return",
5492 axis->GetName(), GetName());
5493 return;
5494 }
5495 // case where label bins are consecutive starting from first bin will work
5496 // calling before a TH1::LabelsDeflate() will avoid this error message
5497 Warning("LabelsOption", "axis %s of Histogram %s has extra following bins without labels. Sorting will work only for first label bins",
5498 axis->GetName(), GetName());
5499 }
5500 std::vector<Int_t> a(n);
5501 std::vector<Int_t> b(n);
5502
5503
5504 Int_t i, j, k;
5505 std::vector<Double_t> cont;
5506 std::vector<Double_t> errors2;
5507 THashList *labold = new THashList(labels->GetSize(), 1);
5508 TIter nextold(labels);
5509 TObject *obj = nullptr;
5510 labold->AddAll(labels);
5511 labels->Clear();
5512
5513 // delete buffer if it is there since bins will be reordered.
5514 if (fBuffer)
5515 BufferEmpty(1);
5516
5517 if (sort > 0) {
5518 //---sort by values of bins
5519 if (GetDimension() == 1) {
5520 cont.resize(n);
5521 if (fSumw2.fN)
5522 errors2.resize(n);
5523 for (i = 0; i < n; i++) {
5524 cont[i] = RetrieveBinContent(i + 1);
5525 if (!errors2.empty())
5526 errors2[i] = GetBinErrorSqUnchecked(i + 1);
5527 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5528 a[i] = i;
5529 }
5530 if (sort == 1)
5531 TMath::Sort(n, cont.data(), a.data(), kTRUE); // sort by decreasing values
5532 else
5533 TMath::Sort(n, cont.data(), a.data(), kFALSE); // sort by increasing values
5534 for (i = 0; i < n; i++) {
5535 // use UpdateBinCOntent to not screw up histogram entries
5536 UpdateBinContent(i + 1, cont[b[a[i]] - 1]); // b[a[i]] returns bin number. .we need to subtract 1
5537 if (gDebug)
5538 Info("LabelsOption","setting bin %d value %f from bin %d label %s at pos %d ",
5539 i+1,cont[b[a[i]] - 1],b[a[i]],labold->At(a[i])->GetName(),a[i]);
5540 if (!errors2.empty())
5541 fSumw2.fArray[i + 1] = errors2[b[a[i]] - 1];
5542 }
5543 for (i = 0; i < n; i++) {
5544 obj = labold->At(a[i]);
5545 labels->Add(obj);
5546 obj->SetUniqueID(i + 1);
5547 }
5548 } else if (GetDimension() == 2) {
5549 std::vector<Double_t> pcont(n + 2);
5550 Int_t nx = fXaxis.GetNbins() + 2;
5551 Int_t ny = fYaxis.GetNbins() + 2;
5552 cont.resize((nx + 2) * (ny + 2));
5553 if (fSumw2.fN)
5554 errors2.resize((nx + 2) * (ny + 2));
5555 for (i = 0; i < nx; i++) {
5556 for (j = 0; j < ny; j++) {
5557 Int_t bin = GetBin(i,j);
5558 cont[i + nx * j] = RetrieveBinContent(bin);
5559 if (!errors2.empty())
5560 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5561 if (axis == GetXaxis())
5562 k = i - 1;
5563 else
5564 k = j - 1;
5565 if (k >= 0 && k < n) { // we consider underflow/overflows in y for ordering the bins
5566 pcont[k] += cont[i + nx * j];
5567 a[k] = k;
5568 }
5569 }
5570 }
5571 if (sort == 1)
5572 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5573 else
5574 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5575 for (i = 0; i < n; i++) {
5576 // iterate on old label list to find corresponding bin match
5577 TIter next(labold);
5578 UInt_t bin = a[i] + 1;
5579 while ((obj = next())) {
5580 if (obj->GetUniqueID() == (UInt_t)bin)
5581 break;
5582 else
5583 obj = nullptr;
5584 }
5585 if (!obj) {
5586 // this should not really happen
5587 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5588 return;
5589 }
5590
5591 labels->Add(obj);
5592 if (gDebug)
5593 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from order " << a[i] << " bin "
5594 << b[a[i]] << "content " << pcont[a[i]] << std::endl;
5595 }
5596 // need to set here new ordered labels - otherwise loop before does not work since labold and labels list
5597 // contain same objects
5598 for (i = 0; i < n; i++) {
5599 labels->At(i)->SetUniqueID(i + 1);
5600 }
5601 // set now the bin contents
5602 if (axis == GetXaxis()) {
5603 for (i = 0; i < n; i++) {
5604 Int_t ix = a[i] + 1;
5605 for (j = 0; j < ny; j++) {
5606 Int_t bin = GetBin(i + 1, j);
5607 UpdateBinContent(bin, cont[ix + nx * j]);
5608 if (!errors2.empty())
5609 fSumw2.fArray[bin] = errors2[ix + nx * j];
5610 }
5611 }
5612 } else {
5613 // using y axis
5614 for (i = 0; i < nx; i++) {
5615 for (j = 0; j < n; j++) {
5616 Int_t iy = a[j] + 1;
5617 Int_t bin = GetBin(i, j + 1);
5618 UpdateBinContent(bin, cont[i + nx * iy]);
5619 if (!errors2.empty())
5620 fSumw2.fArray[bin] = errors2[i + nx * iy];
5621 }
5622 }
5623 }
5624 } else {
5625 // sorting histograms: 3D case
5626 std::vector<Double_t> pcont(n + 2);
5627 Int_t nx = fXaxis.GetNbins() + 2;
5628 Int_t ny = fYaxis.GetNbins() + 2;
5629 Int_t nz = fZaxis.GetNbins() + 2;
5630 Int_t l = 0;
5631 cont.resize((nx + 2) * (ny + 2) * (nz + 2));
5632 if (fSumw2.fN)
5633 errors2.resize((nx + 2) * (ny + 2) * (nz + 2));
5634 for (i = 0; i < nx; i++) {
5635 for (j = 0; j < ny; j++) {
5636 for (k = 0; k < nz; k++) {
5637 Int_t bin = GetBin(i,j,k);
5639 if (axis == GetXaxis())
5640 l = i - 1;
5641 else if (axis == GetYaxis())
5642 l = j - 1;
5643 else
5644 l = k - 1;
5645 if (l >= 0 && l < n) { // we consider underflow/overflows in y for ordering the bins
5646 pcont[l] += c;
5647 a[l] = l;
5648 }
5649 cont[i + nx * (j + ny * k)] = c;
5650 if (!errors2.empty())
5651 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5652 }
5653 }
5654 }
5655 if (sort == 1)
5656 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5657 else
5658 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5659 for (i = 0; i < n; i++) {
5660 // iterate on the old label list to find corresponding bin match
5661 TIter next(labold);
5662 UInt_t bin = a[i] + 1;
5663 obj = nullptr;
5664 while ((obj = next())) {
5665 if (obj->GetUniqueID() == (UInt_t)bin) {
5666 break;
5667 }
5668 else
5669 obj = nullptr;
5670 }
5671 if (!obj) {
5672 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5673 return;
5674 }
5675 labels->Add(obj);
5676 if (gDebug)
5677 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from bin " << a[i] << "content "
5678 << pcont[a[i]] << std::endl;
5679 }
5680
5681 // need to set here new ordered labels - otherwise loop before does not work since labold and llabels list
5682 // contain same objects
5683 for (i = 0; i < n; i++) {
5684 labels->At(i)->SetUniqueID(i + 1);
5685 }
5686 // set now the bin contents
5687 if (axis == GetXaxis()) {
5688 for (i = 0; i < n; i++) {
5689 Int_t ix = a[i] + 1;
5690 for (j = 0; j < ny; j++) {
5691 for (k = 0; k < nz; k++) {
5692 Int_t bin = GetBin(i + 1, j, k);
5693 UpdateBinContent(bin, cont[ix + nx * (j + ny * k)]);
5694 if (!errors2.empty())
5695 fSumw2.fArray[bin] = errors2[ix + nx * (j + ny * k)];
5696 }
5697 }
5698 }
5699 } else if (axis == GetYaxis()) {
5700 // using y axis
5701 for (i = 0; i < nx; i++) {
5702 for (j = 0; j < n; j++) {
5703 Int_t iy = a[j] + 1;
5704 for (k = 0; k < nz; k++) {
5705 Int_t bin = GetBin(i, j + 1, k);
5706 UpdateBinContent(bin, cont[i + nx * (iy + ny * k)]);
5707 if (!errors2.empty())
5708 fSumw2.fArray[bin] = errors2[i + nx * (iy + ny * k)];
5709 }
5710 }
5711 }
5712 } else {
5713 // using z axis
5714 for (i = 0; i < nx; i++) {
5715 for (j = 0; j < ny; j++) {
5716 for (k = 0; k < n; k++) {
5717 Int_t iz = a[k] + 1;
5718 Int_t bin = GetBin(i, j , k +1);
5719 UpdateBinContent(bin, cont[i + nx * (j + ny * iz)]);
5720 if (!errors2.empty())
5721 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * iz)];
5722 }
5723 }
5724 }
5725 }
5726 }
5727 } else {
5728 //---alphabetic sort
5729 // sort labels using vector of strings and TMath::Sort
5730 // I need to array because labels order in list is not necessary that of the bins
5731 std::vector<std::string> vecLabels(n);
5732 for (i = 0; i < n; i++) {
5733 vecLabels[i] = labold->At(i)->GetName();
5734 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5735 a[i] = i;
5736 }
5737 // sort in ascending order for strings
5738 TMath::Sort(n, vecLabels.data(), a.data(), kFALSE);
5739 // set the new labels
5740 for (i = 0; i < n; i++) {
5741 TObject *labelObj = labold->At(a[i]);
5742 labels->Add(labold->At(a[i]));
5743 // set the corresponding bin. NB bin starts from 1
5744 labelObj->SetUniqueID(i + 1);
5745 if (gDebug)
5746 std::cout << "bin " << i + 1 << " setting new labels for axis " << labold->At(a[i])->GetName() << " from "
5747 << b[a[i]] << std::endl;
5748 }
5749
5750 if (GetDimension() == 1) {
5751 cont.resize(n + 2);
5752 if (fSumw2.fN)
5753 errors2.resize(n + 2);
5754 for (i = 0; i < n; i++) {
5755 cont[i] = RetrieveBinContent(b[a[i]]);
5756 if (!errors2.empty())
5757 errors2[i] = GetBinErrorSqUnchecked(b[a[i]]);
5758 }
5759 for (i = 0; i < n; i++) {
5760 UpdateBinContent(i + 1, cont[i]);
5761 if (!errors2.empty())
5762 fSumw2.fArray[i+1] = errors2[i];
5763 }
5764 } else if (GetDimension() == 2) {
5765 Int_t nx = fXaxis.GetNbins() + 2;
5766 Int_t ny = fYaxis.GetNbins() + 2;
5767 cont.resize(nx * ny);
5768 if (fSumw2.fN)
5769 errors2.resize(nx * ny);
5770 // copy old bin contents and then set to new ordered bins
5771 // N.B. bin in histograms starts from 1, but in y we consider under/overflows
5772 for (i = 0; i < nx; i++) {
5773 for (j = 0; j < ny; j++) { // ny is nbins+2
5774 Int_t bin = GetBin(i, j);
5775 cont[i + nx * j] = RetrieveBinContent(bin);
5776 if (!errors2.empty())
5777 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5778 }
5779 }
5780 if (axis == GetXaxis()) {
5781 for (i = 0; i < n; i++) {
5782 for (j = 0; j < ny; j++) {
5783 Int_t bin = GetBin(i + 1 , j);
5784 UpdateBinContent(bin, cont[b[a[i]] + nx * j]);
5785 if (!errors2.empty())
5786 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * j];
5787 }
5788 }
5789 } else {
5790 for (i = 0; i < nx; i++) {
5791 for (j = 0; j < n; j++) {
5792 Int_t bin = GetBin(i, j + 1);
5793 UpdateBinContent(bin, cont[i + nx * b[a[j]]]);
5794 if (!errors2.empty())
5795 fSumw2.fArray[bin] = errors2[i + nx * b[a[j]]];
5796 }
5797 }
5798 }
5799 } else {
5800 // case of 3D (needs to be tested)
5801 Int_t nx = fXaxis.GetNbins() + 2;
5802 Int_t ny = fYaxis.GetNbins() + 2;
5803 Int_t nz = fZaxis.GetNbins() + 2;
5804 cont.resize(nx * ny * nz);
5805 if (fSumw2.fN)
5806 errors2.resize(nx * ny * nz);
5807 for (i = 0; i < nx; i++) {
5808 for (j = 0; j < ny; j++) {
5809 for (k = 0; k < nz; k++) {
5810 Int_t bin = GetBin(i, j, k);
5811 cont[i + nx * (j + ny * k)] = RetrieveBinContent(bin);
5812 if (!errors2.empty())
5813 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5814 }
5815 }
5816 }
5817 if (axis == GetXaxis()) {
5818 // labels on x axis
5819 for (i = 0; i < n; i++) { // for x we loop only on bins with the labels
5820 for (j = 0; j < ny; j++) {
5821 for (k = 0; k < nz; k++) {
5822 Int_t bin = GetBin(i + 1, j, k);
5823 UpdateBinContent(bin, cont[b[a[i]] + nx * (j + ny * k)]);
5824 if (!errors2.empty())
5825 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * (j + ny * k)];
5826 }
5827 }
5828 }
5829 } else if (axis == GetYaxis()) {
5830 // labels on y axis
5831 for (i = 0; i < nx; i++) {
5832 for (j = 0; j < n; j++) {
5833 for (k = 0; k < nz; k++) {
5834 Int_t bin = GetBin(i, j+1, k);
5835 UpdateBinContent(bin, cont[i + nx * (b[a[j]] + ny * k)]);
5836 if (!errors2.empty())
5837 fSumw2.fArray[bin] = errors2[i + nx * (b[a[j]] + ny * k)];
5838 }
5839 }
5840 }
5841 } else {
5842 // labels on z axis
5843 for (i = 0; i < nx; i++) {
5844 for (j = 0; j < ny; j++) {
5845 for (k = 0; k < n; k++) {
5846 Int_t bin = GetBin(i, j, k+1);
5847 UpdateBinContent(bin, cont[i + nx * (j + ny * b[a[k]])]);
5848 if (!errors2.empty())
5849 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * b[a[k]])];
5850 }
5851 }
5852 }
5853 }
5854 }
5855 }
5856 // need to set to zero the statistics if axis has been sorted
5857 // see for example TH3::PutStats for definition of s vector
5858 bool labelsAreSorted = kFALSE;
5859 for (i = 0; i < n; ++i) {
5860 if (a[i] != i) {
5861 labelsAreSorted = kTRUE;
5862 break;
5863 }
5864 }
5865 if (labelsAreSorted) {
5866 double s[TH1::kNstat];
5867 GetStats(s);
5868 if (iaxis == 1) {
5869 s[2] = 0; // fTsumwx
5870 s[3] = 0; // fTsumwx2
5871 s[6] = 0; // fTsumwxy
5872 s[9] = 0; // fTsumwxz
5873 } else if (iaxis == 2) {
5874 s[4] = 0; // fTsumwy
5875 s[5] = 0; // fTsumwy2
5876 s[6] = 0; // fTsumwxy
5877 s[10] = 0; // fTsumwyz
5878 } else if (iaxis == 3) {
5879 s[7] = 0; // fTsumwz
5880 s[8] = 0; // fTsumwz2
5881 s[9] = 0; // fTsumwxz
5882 s[10] = 0; // fTsumwyz
5883 }
5884 PutStats(s);
5885 }
5886 delete labold;
5887}
5888
5889////////////////////////////////////////////////////////////////////////////////
5890/// Test if two double are almost equal.
5891
5892static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5893{
5894 return TMath::Abs(a - b) < epsilon;
5895}
5896
5897////////////////////////////////////////////////////////////////////////////////
5898/// Test if a double is almost an integer.
5899
5900static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5901{
5902 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5903 AlmostEqual(a - TMath::Floor(a), 1, epsilon);
5904}
5905
5906////////////////////////////////////////////////////////////////////////////////
5907/// Test if the binning is equidistant.
5908
5909static inline bool IsEquidistantBinning(const TAxis& axis)
5910{
5911 // check if axis bin are equals
5912 if (!axis.GetXbins()->fN) return true; //
5913 // not able to check if there is only one axis entry
5914 bool isEquidistant = true;
5915 const Double_t firstBinWidth = axis.GetBinWidth(1);
5916 for (int i = 1; i < axis.GetNbins(); ++i) {
5917 const Double_t binWidth = axis.GetBinWidth(i);
5918 const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5919 isEquidistant &= match;
5920 if (!match)
5921 break;
5922 }
5923 return isEquidistant;
5924}
5925
5926////////////////////////////////////////////////////////////////////////////////
5927/// Same limits and bins.
5928
5929Bool_t TH1::SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2){
5930 return axis1.GetNbins() == axis2.GetNbins() &&
5931 TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
5932 TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
5933}
5934
5935////////////////////////////////////////////////////////////////////////////////
5936/// Finds new limits for the axis for the Merge function.
5937/// returns false if the limits are incompatible
5938
5939Bool_t TH1::RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
5940{
5941 if (SameLimitsAndNBins(destAxis, anAxis))
5942 return kTRUE;
5943
5944 if (!IsEquidistantBinning(destAxis) || !IsEquidistantBinning(anAxis))
5945 return kFALSE; // not equidistant user binning not supported
5946
5947 Double_t width1 = destAxis.GetBinWidth(0);
5948 Double_t width2 = anAxis.GetBinWidth(0);
5949 if (width1 == 0 || width2 == 0)
5950 return kFALSE; // no binning not supported
5951
5952 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
5953 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
5954 Double_t width = TMath::Max(width1, width2);
5955
5956 // check the bin size
5957 if (!AlmostInteger(width/width1) || !AlmostInteger(width/width2))
5958 return kFALSE;
5959
5960 // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
5961 // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
5962
5963
5964 // check the limits
5965 Double_t delta;
5966 delta = (destAxis.GetXmin() - xmin)/width1;
5967 if (!AlmostInteger(delta))
5968 xmin -= (TMath::Ceil(delta) - delta)*width1;
5969
5970 delta = (anAxis.GetXmin() - xmin)/width2;
5971 if (!AlmostInteger(delta))
5972 xmin -= (TMath::Ceil(delta) - delta)*width2;
5973
5974
5975 delta = (destAxis.GetXmin() - xmin)/width1;
5976 if (!AlmostInteger(delta))
5977 return kFALSE;
5978
5979
5980 delta = (xmax - destAxis.GetXmax())/width1;
5981 if (!AlmostInteger(delta))
5982 xmax += (TMath::Ceil(delta) - delta)*width1;
5983
5984
5985 delta = (xmax - anAxis.GetXmax())/width2;
5986 if (!AlmostInteger(delta))
5987 xmax += (TMath::Ceil(delta) - delta)*width2;
5988
5989
5990 delta = (xmax - destAxis.GetXmax())/width1;
5991 if (!AlmostInteger(delta))
5992 return kFALSE;
5993#ifdef DEBUG
5994 if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
5995 printf("TH1::RecomputeAxisLimits - Impossible\n");
5996 return kFALSE;
5997 }
5998#endif
5999
6000
6001 destAxis.Set(TMath::Nint((xmax - xmin)/width), xmin, xmax);
6002
6003 //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
6004
6005 return kTRUE;
6006}
6007
6008////////////////////////////////////////////////////////////////////////////////
6009/// Add all histograms in the collection to this histogram.
6010/// This function computes the min/max for the x axis,
6011/// compute a new number of bins, if necessary,
6012/// add bin contents, errors and statistics.
6013/// If all histograms have bin labels, bins with identical labels
6014/// will be merged, no matter what their order is.
6015/// If overflows are present and limits are different the function will fail.
6016/// The function returns the total number of entries in the result histogram
6017/// if the merge is successful, -1 otherwise.
6018///
6019/// Possible option:
6020/// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
6021/// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
6022/// (enabled by default) slows down the merging
6023///
6024/// IMPORTANT remark. The axis x may have different number
6025/// of bins and different limits, BUT the largest bin width must be
6026/// a multiple of the smallest bin width and the upper limit must also
6027/// be a multiple of the bin width.
6028/// Example:
6029///
6030/// ~~~ {.cpp}
6031/// void atest() {
6032/// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
6033/// TH1F *h2 = new TH1F("h2","h2",220,0,110);
6034/// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
6035/// TRandom r;
6036/// for (Int_t i=0;i<10000;i++) {
6037/// h1->Fill(r.Gaus(-55,10));
6038/// h2->Fill(r.Gaus(55,10));
6039/// h3->Fill(r.Gaus(0,10));
6040/// }
6041///
6042/// TList *list = new TList;
6043/// list->Add(h1);
6044/// list->Add(h2);
6045/// list->Add(h3);
6046/// TH1F *h = (TH1F*)h1->Clone("h");
6047/// h->Reset();
6048/// h->Merge(list);
6049/// h->Draw();
6050/// }
6051/// ~~~
6052
6054{
6055 if (!li) return 0;
6056 if (li->IsEmpty()) return (Long64_t) GetEntries();
6057
6058 // use TH1Merger class
6059 TH1Merger merger(*this,*li,opt);
6060 Bool_t ret = merger();
6061
6062 return (ret) ? GetEntries() : -1;
6063}
6064
6065
6066////////////////////////////////////////////////////////////////////////////////
6067/// Performs the operation:
6068///
6069/// `this = this*c1*f1`
6070///
6071/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
6072///
6073/// Only bins inside the function range are recomputed.
6074/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6075/// you should call Sumw2 before making this operation.
6076/// This is particularly important if you fit the histogram after TH1::Multiply
6077///
6078/// The function return kFALSE if the Multiply operation failed
6079
6081{
6082 if (!f1) {
6083 Error("Multiply","Attempt to multiply by a non-existing function");
6084 return kFALSE;
6085 }
6086
6087 // delete buffer if it is there since it will become invalid
6088 if (fBuffer) BufferEmpty(1);
6089
6090 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
6091 Int_t ny = GetNbinsY() + 2;
6092 Int_t nz = GetNbinsZ() + 2;
6093 if (fDimension < 2) ny = 1;
6094 if (fDimension < 3) nz = 1;
6095
6096 // reset min-maximum
6097 SetMinimum();
6098 SetMaximum();
6099
6100 // - Loop on bins (including underflows/overflows)
6101 Double_t xx[3];
6102 Double_t *params = nullptr;
6103 f1->InitArgs(xx,params);
6104
6105 for (Int_t binz = 0; binz < nz; ++binz) {
6106 xx[2] = fZaxis.GetBinCenter(binz);
6107 for (Int_t biny = 0; biny < ny; ++biny) {
6108 xx[1] = fYaxis.GetBinCenter(biny);
6109 for (Int_t binx = 0; binx < nx; ++binx) {
6110 xx[0] = fXaxis.GetBinCenter(binx);
6111 if (!f1->IsInside(xx)) continue;
6113 Int_t bin = binx + nx * (biny + ny *binz);
6114 Double_t cu = c1*f1->EvalPar(xx);
6115 if (TF1::RejectedPoint()) continue;
6116 UpdateBinContent(bin, RetrieveBinContent(bin) * cu);
6117 if (fSumw2.fN) {
6118 fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
6119 }
6120 }
6121 }
6122 }
6123 ResetStats();
6124 return kTRUE;
6125}
6126
6127////////////////////////////////////////////////////////////////////////////////
6128/// Multiply this histogram by h1.
6129///
6130/// `this = this*h1`
6131///
6132/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6133/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
6134/// if not already set.
6135///
6136/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6137/// you should call Sumw2 before making this operation.
6138/// This is particularly important if you fit the histogram after TH1::Multiply
6139///
6140/// The function return kFALSE if the Multiply operation failed
6141
6142Bool_t TH1::Multiply(const TH1 *h1)
6143{
6144 if (!h1) {
6145 Error("Multiply","Attempt to multiply by a non-existing histogram");
6146 return kFALSE;
6147 }
6148
6149 // delete buffer if it is there since it will become invalid
6150 if (fBuffer) BufferEmpty(1);
6151
6152 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins) {
6153 return false;
6154 }
6155
6156 // Create Sumw2 if h1 has Sumw2 set
6157 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
6158
6159 // - Reset min- maximum
6160 SetMinimum();
6161 SetMaximum();
6162
6163 // - Loop on bins (including underflows/overflows)
6164 for (Int_t i = 0; i < fNcells; ++i) {
6167 UpdateBinContent(i, c0 * c1);
6168 if (fSumw2.fN) {
6170 }
6171 }
6172 ResetStats();
6173 return kTRUE;
6174}
6175
6176////////////////////////////////////////////////////////////////////////////////
6177/// Replace contents of this histogram by multiplication of h1 by h2.
6178///
6179/// `this = (c1*h1)*(c2*h2)`
6180///
6181/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6182/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
6183/// if not already set.
6184///
6185/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6186/// you should call Sumw2 before making this operation.
6187/// This is particularly important if you fit the histogram after TH1::Multiply
6188///
6189/// The function return kFALSE if the Multiply operation failed
6190
6192{
6193 TString opt = option;
6194 opt.ToLower();
6195 // Bool_t binomial = kFALSE;
6196 // if (opt.Contains("b")) binomial = kTRUE;
6197 if (!h1 || !h2) {
6198 Error("Multiply","Attempt to multiply by a non-existing histogram");
6199 return kFALSE;
6200 }
6201
6202 // delete buffer if it is there since it will become invalid
6203 if (fBuffer) BufferEmpty(1);
6204
6205 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins ||
6206 LoggedInconsistency("Multiply", h1, h2) >= kDifferentNumberOfBins) {
6207 return false;
6208 }
6209
6210 // Create Sumw2 if h1 or h2 have Sumw2 set
6211 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
6212
6213 // - Reset min - maximum
6214 SetMinimum();
6215 SetMaximum();
6216
6217 // - Loop on bins (including underflows/overflows)
6218 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
6219 for (Int_t i = 0; i < fNcells; ++i) {
6221 Double_t b2 = h2->RetrieveBinContent(i);
6222 UpdateBinContent(i, c1 * b1 * c2 * b2);
6223 if (fSumw2.fN) {
6224 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
6225 }
6226 }
6227 ResetStats();
6228 return kTRUE;
6229}
6230
6231////////////////////////////////////////////////////////////////////////////////
6232/// Control routine to paint any kind of histograms.
6233///
6234/// This function is automatically called by TCanvas::Update.
6235/// (see TH1::Draw for the list of options)
6236
6238{
6240
6241 if (fPainter) {
6242 if (option && strlen(option) > 0)
6244 else
6246 }
6247}
6248
6249////////////////////////////////////////////////////////////////////////////////
6250/// Rebin this histogram
6251///
6252/// #### case 1 xbins=0
6253///
6254/// If newname is blank (default), the current histogram is modified and
6255/// a pointer to it is returned.
6256///
6257/// If newname is not blank, the current histogram is not modified, and a
6258/// new histogram is returned which is a Clone of the current histogram
6259/// with its name set to newname.
6260///
6261/// The parameter ngroup indicates how many bins of this have to be merged
6262/// into one bin of the result.
6263///
6264/// If the original histogram has errors stored (via Sumw2), the resulting
6265/// histograms has new errors correctly calculated.
6266///
6267/// examples: if h1 is an existing TH1F histogram with 100 bins
6268///
6269/// ~~~ {.cpp}
6270/// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
6271/// h1->Rebin(5); //merges five bins in one in h1
6272/// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
6273/// // merging 5 bins of h1 in one bin
6274/// ~~~
6275///
6276/// NOTE: If ngroup is not an exact divider of the number of bins,
6277/// the top limit of the rebinned histogram is reduced
6278/// to the upper edge of the last bin that can make a complete
6279/// group. The remaining bins are added to the overflow bin.
6280/// Statistics will be recomputed from the new bin contents.
6281///
6282/// #### case 2 xbins!=0
6283///
6284/// A new histogram is created (you should specify newname).
6285/// The parameter ngroup is the number of variable size bins in the created histogram.
6286/// The array xbins must contain ngroup+1 elements that represent the low-edges
6287/// of the bins.
6288/// If the original histogram has errors stored (via Sumw2), the resulting
6289/// histograms has new errors correctly calculated.
6290///
6291/// NOTE: The bin edges specified in xbins should correspond to bin edges
6292/// in the original histogram. If a bin edge in the new histogram is
6293/// in the middle of a bin in the original histogram, all entries in
6294/// the split bin in the original histogram will be transfered to the
6295/// lower of the two possible bins in the new histogram. This is
6296/// probably not what you want. A warning message is emitted in this
6297/// case
6298///
6299/// examples: if h1 is an existing TH1F histogram with 100 bins
6300///
6301/// ~~~ {.cpp}
6302/// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
6303/// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
6304/// ~~~
6305
6306TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
6307{
6308 Int_t nbins = fXaxis.GetNbins();
6311 if ((ngroup <= 0) || (ngroup > nbins)) {
6312 Error("Rebin", "Illegal value of ngroup=%d",ngroup);
6313 return nullptr;
6314 }
6315
6316 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
6317 Error("Rebin", "Operation valid on 1-D histograms only");
6318 return nullptr;
6319 }
6320 if (!newname && xbins) {
6321 Error("Rebin","if xbins is specified, newname must be given");
6322 return nullptr;
6323 }
6324
6325 Int_t newbins = nbins/ngroup;
6326 if (!xbins) {
6327 Int_t nbg = nbins/ngroup;
6328 if (nbg*ngroup != nbins) {
6329 Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
6330 }
6331 }
6332 else {
6333 // in the case that xbins is given (rebinning in variable bins), ngroup is
6334 // the new number of bins and number of grouped bins is not constant.
6335 // when looping for setting the contents for the new histogram we
6336 // need to loop on all bins of original histogram. Then set ngroup=nbins
6337 newbins = ngroup;
6338 ngroup = nbins;
6339 }
6340
6341 // Save old bin contents into a new array
6342 Double_t entries = fEntries;
6343 Double_t *oldBins = new Double_t[nbins+2];
6344 Int_t bin, i;
6345 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
6346 Double_t *oldErrors = nullptr;
6347 if (fSumw2.fN != 0) {
6348 oldErrors = new Double_t[nbins+2];
6349 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
6350 }
6351 // rebin will not include underflow/overflow if new axis range is larger than old axis range
6352 if (xbins) {
6353 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
6354 Warning("Rebin","underflow entries will not be used when rebinning");
6355 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
6356 Warning("Rebin","overflow entries will not be used when rebinning");
6357 }
6358
6359
6360 // create a clone of the old histogram if newname is specified
6361 TH1 *hnew = this;
6362 if ((newname && strlen(newname) > 0) || xbins) {
6363 hnew = (TH1*)Clone(newname);
6364 }
6365
6366 //reset can extend bit to avoid an axis extension in SetBinContent
6367 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
6368
6369 // save original statistics
6370 Double_t stat[kNstat];
6371 GetStats(stat);
6372 bool resetStat = false;
6373 // change axis specs and rebuild bin contents array::RebinAx
6374 if(!xbins && (newbins*ngroup != nbins)) {
6375 xmax = fXaxis.GetBinUpEdge(newbins*ngroup);
6376 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
6377 }
6378 // save the TAttAxis members (reset by SetBins)
6379 Int_t nDivisions = fXaxis.GetNdivisions();
6380 Color_t axisColor = fXaxis.GetAxisColor();
6381 Color_t labelColor = fXaxis.GetLabelColor();
6382 Style_t labelFont = fXaxis.GetLabelFont();
6383 Float_t labelOffset = fXaxis.GetLabelOffset();
6384 Float_t labelSize = fXaxis.GetLabelSize();
6385 Float_t tickLength = fXaxis.GetTickLength();
6386 Float_t titleOffset = fXaxis.GetTitleOffset();
6387 Float_t titleSize = fXaxis.GetTitleSize();
6388 Color_t titleColor = fXaxis.GetTitleColor();
6389 Style_t titleFont = fXaxis.GetTitleFont();
6390
6391 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
6392 Double_t *bins = new Double_t[newbins+1];
6393 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
6394 hnew->SetBins(newbins,bins); //this also changes errors array (if any)
6395 delete [] bins;
6396 } else if (xbins) {
6397 hnew->SetBins(newbins,xbins);
6398 } else {
6399 hnew->SetBins(newbins,xmin,xmax);
6400 }
6401
6402 // Restore axis attributes
6403 fXaxis.SetNdivisions(nDivisions);
6404 fXaxis.SetAxisColor(axisColor);
6405 fXaxis.SetLabelColor(labelColor);
6406 fXaxis.SetLabelFont(labelFont);
6407 fXaxis.SetLabelOffset(labelOffset);
6408 fXaxis.SetLabelSize(labelSize);
6409 fXaxis.SetTickLength(tickLength);
6410 fXaxis.SetTitleOffset(titleOffset);
6411 fXaxis.SetTitleSize(titleSize);
6412 fXaxis.SetTitleColor(titleColor);
6413 fXaxis.SetTitleFont(titleFont);
6414
6415 // copy merged bin contents (ignore under/overflows)
6416 // Start merging only once the new lowest edge is reached
6417 Int_t startbin = 1;
6418 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
6419 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
6420 startbin++;
6421 }
6422 Int_t oldbin = startbin;
6423 Double_t binContent, binError;
6424 for (bin = 1;bin<=newbins;bin++) {
6425 binContent = 0;
6426 binError = 0;
6427 Int_t imax = ngroup;
6428 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6429 // check bin edges for the cases when we provide an array of bins
6430 // be careful in case bins can have zero width
6431 if (xbins && !TMath::AreEqualAbs(fXaxis.GetBinLowEdge(oldbin),
6432 hnew->GetXaxis()->GetBinLowEdge(bin),
6433 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6434 {
6435 Warning("Rebin","Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6436 }
6437 for (i=0;i<ngroup;i++) {
6438 if( (oldbin+i > nbins) ||
6439 ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6440 imax = i;
6441 break;
6442 }
6443 binContent += oldBins[oldbin+i];
6444 if (oldErrors) binError += oldErrors[oldbin+i]*oldErrors[oldbin+i];
6445 }
6446 hnew->SetBinContent(bin,binContent);
6447 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6448 oldbin += imax;
6449 }
6450
6451 // sum underflow and overflow contents until startbin
6452 binContent = 0;
6453 binError = 0;
6454 for (i = 0; i < startbin; ++i) {
6455 binContent += oldBins[i];
6456 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6457 }
6458 hnew->SetBinContent(0,binContent);
6459 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6460 // sum overflow
6461 binContent = 0;
6462 binError = 0;
6463 for (i = oldbin; i <= nbins+1; ++i) {
6464 binContent += oldBins[i];
6465 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6466 }
6467 hnew->SetBinContent(newbins+1,binContent);
6468 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6469
6470 hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6471
6472 // restore statistics and entries modified by SetBinContent
6473 hnew->SetEntries(entries);
6474 if (!resetStat) hnew->PutStats(stat);
6475 delete [] oldBins;
6476 if (oldErrors) delete [] oldErrors;
6477 return hnew;
6478}
6479
6480////////////////////////////////////////////////////////////////////////////////
6481/// finds new limits for the axis so that *point* is within the range and
6482/// the limits are compatible with the previous ones (see TH1::Merge).
6483/// new limits are put into *newMin* and *newMax* variables.
6484/// axis - axis whose limits are to be recomputed
6485/// point - point that should fit within the new axis limits
6486/// newMin - new minimum will be stored here
6487/// newMax - new maximum will be stored here.
6488/// false if failed (e.g. if the initial axis limits are wrong
6489/// or the new range is more than \f$ 2^{64} \f$ times the old one).
6490
6491Bool_t TH1::FindNewAxisLimits(const TAxis* axis, const Double_t point, Double_t& newMin, Double_t &newMax)
6492{
6493 Double_t xmin = axis->GetXmin();
6494 Double_t xmax = axis->GetXmax();
6495 if (xmin >= xmax) return kFALSE;
6496 Double_t range = xmax-xmin;
6497
6498 //recompute new axis limits by doubling the current range
6499 Int_t ntimes = 0;
6500 while (point < xmin) {
6501 if (ntimes++ > 64)
6502 return kFALSE;
6503 xmin = xmin - range;
6504 range *= 2;
6505 }
6506 while (point >= xmax) {
6507 if (ntimes++ > 64)
6508 return kFALSE;
6509 xmax = xmax + range;
6510 range *= 2;
6511 }
6512 newMin = xmin;
6513 newMax = xmax;
6514 // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6515 // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6516
6517 return kTRUE;
6518}
6519
6520////////////////////////////////////////////////////////////////////////////////
6521/// Histogram is resized along axis such that x is in the axis range.
6522/// The new axis limits are recomputed by doubling iteratively
6523/// the current axis range until the specified value x is within the limits.
6524/// The algorithm makes a copy of the histogram, then loops on all bins
6525/// of the old histogram to fill the extended histogram.
6526/// Takes into account errors (Sumw2) if any.
6527/// The algorithm works for 1-d, 2-D and 3-D histograms.
6528/// The axis must be extendable before invoking this function.
6529/// Ex:
6530///
6531/// ~~~ {.cpp}
6532/// h->GetXaxis()->SetCanExtend(kTRUE);
6533/// ~~~
6534
6535void TH1::ExtendAxis(Double_t x, TAxis *axis)
6536{
6537 if (!axis->CanExtend()) return;
6538 if (TMath::IsNaN(x)) { // x may be a NaN
6540 return;
6541 }
6542
6543 if (axis->GetXmin() >= axis->GetXmax()) return;
6544 if (axis->GetNbins() <= 0) return;
6545
6547 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6548 return;
6549
6550 //save a copy of this histogram
6551 TH1 *hold = (TH1*)IsA()->New();
6552 hold->SetDirectory(nullptr);
6553 Copy(*hold);
6554 //set new axis limits
6555 axis->SetLimits(xmin,xmax);
6556
6557
6558 //now loop on all bins and refill
6559 Int_t errors = GetSumw2N();
6560
6561 Reset("ICE"); //reset only Integral, contents and Errors
6562
6563 int iaxis = 0;
6564 if (axis == &fXaxis) iaxis = 1;
6565 if (axis == &fYaxis) iaxis = 2;
6566 if (axis == &fZaxis) iaxis = 3;
6567 bool firstw = kTRUE;
6568 Int_t binx,biny, binz = 0;
6569 Int_t ix = 0,iy = 0,iz = 0;
6570 Double_t bx,by,bz;
6571 Int_t ncells = hold->GetNcells();
6572 for (Int_t bin = 0; bin < ncells; ++bin) {
6573 hold->GetBinXYZ(bin,binx,biny,binz);
6574 bx = hold->GetXaxis()->GetBinCenter(binx);
6575 ix = fXaxis.FindFixBin(bx);
6576 if (fDimension > 1) {
6577 by = hold->GetYaxis()->GetBinCenter(biny);
6578 iy = fYaxis.FindFixBin(by);
6579 if (fDimension > 2) {
6580 bz = hold->GetZaxis()->GetBinCenter(binz);
6581 iz = fZaxis.FindFixBin(bz);
6582 }
6583 }
6584 // exclude underflow/overflow
6585 double content = hold->RetrieveBinContent(bin);
6586 if (content == 0) continue;
6587 if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6588 if (firstw) {
6589 Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6590 " their content will be lost",GetName() );
6591 firstw= kFALSE;
6592 }
6593 continue;
6594 }
6595 Int_t ibin= GetBin(ix,iy,iz);
6596 AddBinContent(ibin, content);
6597 if (errors) {
6598 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6599 }
6600 }
6601 delete hold;
6602}
6603
6604////////////////////////////////////////////////////////////////////////////////
6605/// Recursively remove object from the list of functions
6606
6608{
6609 // Rely on TROOT::RecursiveRemove to take the readlock.
6610
6611 if (fFunctions) {
6613 }
6614}
6615
6616////////////////////////////////////////////////////////////////////////////////
6617/// Multiply this histogram by a constant c1.
6618///
6619/// `this = c1*this`
6620///
6621/// Note that both contents and errors (if any) are scaled.
6622/// This function uses the services of TH1::Add
6623///
6624/// IMPORTANT NOTE: Sumw2() is called automatically when scaling.
6625/// If you are not interested in the histogram statistics you can call
6626/// Sumw2(kFALSE) or use the option "nosw2"
6627///
6628/// One can scale a histogram such that the bins integral is equal to
6629/// the normalization parameter via TH1::Scale(Double_t norm), where norm
6630/// is the desired normalization divided by the integral of the histogram.
6631///
6632/// If option contains "width" the bin contents and errors are divided
6633/// by the bin width.
6634
6636{
6637
6638 TString opt = option; opt.ToLower();
6639 // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6640 if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6641 if (opt.Contains("width")) Add(this, this, c1, -1);
6642 else {
6643 if (fBuffer) BufferEmpty(1);
6644 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6645 if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6646 // update global histograms statistics
6647 Double_t s[kNstat] = {0};
6648 GetStats(s);
6649 for (Int_t i=0 ; i < kNstat; i++) {
6650 if (i == 1) s[i] = c1*c1*s[i];
6651 else s[i] = c1*s[i];
6652 }
6653 PutStats(s);
6654 SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6655 }
6656
6657 // if contours set, must also scale contours
6658 Int_t ncontours = GetContour();
6659 if (ncontours == 0) return;
6660 Double_t* levels = fContour.GetArray();
6661 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6662}
6663
6664////////////////////////////////////////////////////////////////////////////////
6665/// Returns true if all axes are extendable.
6666
6668{
6669 Bool_t canExtend = fXaxis.CanExtend();
6670 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6671 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6672
6673 return canExtend;
6674}
6675
6676////////////////////////////////////////////////////////////////////////////////
6677/// Make the histogram axes extendable / not extendable according to the bit mask
6678/// returns the previous bit mask specifying which axes are extendable
6679
6680UInt_t TH1::SetCanExtend(UInt_t extendBitMask)
6681{
6682 UInt_t oldExtendBitMask = kNoAxis;
6683
6684 if (fXaxis.CanExtend()) oldExtendBitMask |= kXaxis;
6685 if (extendBitMask & kXaxis) fXaxis.SetCanExtend(kTRUE);
6687
6688 if (GetDimension() > 1) {
6689 if (fYaxis.CanExtend()) oldExtendBitMask |= kYaxis;
6690 if (extendBitMask & kYaxis) fYaxis.SetCanExtend(kTRUE);
6692 }
6693
6694 if (GetDimension() > 2) {
6695 if (fZaxis.CanExtend()) oldExtendBitMask |= kZaxis;
6696 if (extendBitMask & kZaxis) fZaxis.SetCanExtend(kTRUE);
6698 }
6699
6700 return oldExtendBitMask;
6701}
6702
6703///////////////////////////////////////////////////////////////////////////////
6704/// Internal function used in TH1::Fill to see which axis is full alphanumeric,
6705/// i.e. can be extended and is alphanumeric
6707{
6708 UInt_t bitMask = kNoAxis;
6709 if (fXaxis.CanExtend() && fXaxis.IsAlphanumeric() ) bitMask |= kXaxis;
6711 bitMask |= kYaxis;
6713 bitMask |= kZaxis;
6714
6715 return bitMask;
6716}
6717
6718////////////////////////////////////////////////////////////////////////////////
6719/// Static function to set the default buffer size for automatic histograms.
6720/// When a histogram is created with one of its axis lower limit greater
6721/// or equal to its upper limit, the function SetBuffer is automatically
6722/// called with the default buffer size.
6723
6724void TH1::SetDefaultBufferSize(Int_t buffersize)
6725{
6726 fgBufferSize = buffersize > 0 ? buffersize : 0;
6727}
6728
6729////////////////////////////////////////////////////////////////////////////////
6730/// When this static function is called with `sumw2=kTRUE`, all new
6731/// histograms will automatically activate the storage
6732/// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6733
6734void TH1::SetDefaultSumw2(Bool_t sumw2)
6735{
6736 fgDefaultSumw2 = sumw2;
6737}
6738
6739////////////////////////////////////////////////////////////////////////////////
6740/// Change/set the title.
6741///
6742/// If title is in the form `stringt;stringx;stringy;stringz`
6743/// the histogram title is set to `stringt`, the x axis title to `stringx`,
6744/// the y axis title to `stringy`, and the z axis title to `stringz`.
6745///
6746/// To insert the character `;` in one of the titles, one should use `#;`
6747/// or `#semicolon`.
6748
6749void TH1::SetTitle(const char *title)
6750{
6751 fTitle = title;
6752 fTitle.ReplaceAll("#;",2,"#semicolon",10);
6753
6754 // Decode fTitle. It may contain X, Y and Z titles
6755 TString str1 = fTitle, str2;
6756 Int_t isc = str1.Index(";");
6757 Int_t lns = str1.Length();
6758
6759 if (isc >=0 ) {
6760 fTitle = str1(0,isc);
6761 str1 = str1(isc+1, lns);
6762 isc = str1.Index(";");
6763 if (isc >=0 ) {
6764 str2 = str1(0,isc);
6765 str2.ReplaceAll("#semicolon",10,";",1);
6766 fXaxis.SetTitle(str2.Data());
6767 lns = str1.Length();
6768 str1 = str1(isc+1, lns);
6769 isc = str1.Index(";");
6770 if (isc >=0 ) {
6771 str2 = str1(0,isc);
6772 str2.ReplaceAll("#semicolon",10,";",1);
6773 fYaxis.SetTitle(str2.Data());
6774 lns = str1.Length();
6775 str1 = str1(isc+1, lns);
6776 str1.ReplaceAll("#semicolon",10,";",1);
6777 fZaxis.SetTitle(str1.Data());
6778 } else {
6779 str1.ReplaceAll("#semicolon",10,";",1);
6780 fYaxis.SetTitle(str1.Data());
6781 }
6782 } else {
6783 str1.ReplaceAll("#semicolon",10,";",1);
6784 fXaxis.SetTitle(str1.Data());
6785 }
6786 }
6787
6788 fTitle.ReplaceAll("#semicolon",10,";",1);
6789
6790 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6791}
6792
6793////////////////////////////////////////////////////////////////////////////////
6794/// Smooth array xx, translation of Hbook routine `hsmoof.F`.
6795/// Based on algorithm 353QH twice presented by J. Friedman
6796/// in [Proc. of the 1974 CERN School of Computing, Norway, 11-24 August, 1974](https://cds.cern.ch/record/186223).
6797/// 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).
6798
6799void TH1::SmoothArray(Int_t nn, Double_t *xx, Int_t ntimes)
6800{
6801 if (nn < 3 ) {
6802 ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6803 return;
6804 }
6805
6806 Int_t ii;
6807 std::array<double, 3> hh{};
6808
6809 std::vector<double> yy(nn);
6810 std::vector<double> zz(nn);
6811 std::vector<double> rr(nn);
6812
6813 for (Int_t pass=0;pass<ntimes;pass++) {
6814 // first copy original data into temp array
6815 std::copy(xx, xx+nn, zz.begin() );
6816
6817 for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6818
6819 // do 353 i.e. running median 3, 5, and 3 in a single loop
6820 for (int kk = 0; kk < 3; kk++) {
6821 std::copy(zz.begin(), zz.end(), yy.begin());
6822 int medianType = (kk != 1) ? 3 : 5;
6823 int ifirst = (kk != 1 ) ? 1 : 2;
6824 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6825 //nn2 = nn - ik - 1;
6826 // do all elements beside the first and last point for median 3
6827 // and first two and last 2 for median 5
6828 for ( ii = ifirst; ii < ilast; ii++) {
6829 zz[ii] = TMath::Median(medianType, yy.data() + ii - ifirst);
6830 }
6831
6832 if (kk == 0) { // first median 3
6833 // first point
6834 hh[0] = zz[1];
6835 hh[1] = zz[0];
6836 hh[2] = 3*zz[1] - 2*zz[2];
6837 zz[0] = TMath::Median(3, hh.data());
6838 // last point
6839 hh[0] = zz[nn - 2];
6840 hh[1] = zz[nn - 1];
6841 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6842 zz[nn - 1] = TMath::Median(3, hh.data());
6843 }
6844
6845 if (kk == 1) { // median 5
6846 // second point with window length 3
6847 zz[1] = TMath::Median(3, yy.data());
6848 // second-to-last point with window length 3
6849 zz[nn - 2] = TMath::Median(3, yy.data() + nn - 3);
6850 }
6851
6852 // In the third iteration (kk == 2), the first and last point stay
6853 // the same (see paper linked in the documentation).
6854 }
6855
6856 std::copy ( zz.begin(), zz.end(), yy.begin() );
6857
6858 // quadratic interpolation for flat segments
6859 for (ii = 2; ii < (nn - 2); ii++) {
6860 if (zz[ii - 1] != zz[ii]) continue;
6861 if (zz[ii] != zz[ii + 1]) continue;
6862 const double tmp0 = zz[ii - 2] - zz[ii];
6863 const double tmp1 = zz[ii + 2] - zz[ii];
6864 if (tmp0 * tmp1 <= 0) continue;
6865 int jk = 1;
6866 if ( std::abs(tmp0) > std::abs(tmp0) ) jk = -1;
6867 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6868 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6869 }
6870
6871 // running means
6872 //std::copy(zz.begin(), zz.end(), yy.begin());
6873 for (ii = 1; ii < nn - 1; ii++) {
6874 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6875 }
6876 zz[0] = yy[0];
6877 zz[nn - 1] = yy[nn - 1];
6878
6879 if (noent == 0) {
6880
6881 // save computed values
6882 std::copy(zz.begin(), zz.end(), rr.begin());
6883
6884 // COMPUTE residuals
6885 for (ii = 0; ii < nn; ii++) {
6886 zz[ii] = xx[ii] - zz[ii];
6887 }
6888 }
6889
6890 } // end loop on noent
6891
6892
6893 double xmin = TMath::MinElement(nn,xx);
6894 for (ii = 0; ii < nn; ii++) {
6895 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6896 // make smoothing defined positive - not better using 0 ?
6897 else xx[ii] = std::max((rr[ii] + zz[ii]),0.0 );
6898 }
6899 }
6900}
6901
6902////////////////////////////////////////////////////////////////////////////////
6903/// Smooth bin contents of this histogram.
6904/// if option contains "R" smoothing is applied only to the bins
6905/// defined in the X axis range (default is to smooth all bins)
6906/// Bin contents are replaced by their smooth values.
6907/// Errors (if any) are not modified.
6908/// the smoothing procedure is repeated ntimes (default=1)
6909
6910void TH1::Smooth(Int_t ntimes, Option_t *option)
6911{
6912 if (fDimension != 1) {
6913 Error("Smooth","Smooth only supported for 1-d histograms");
6914 return;
6915 }
6916 Int_t nbins = fXaxis.GetNbins();
6917 if (nbins < 3) {
6918 Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
6919 return;
6920 }
6921
6922 // delete buffer if it is there since it will become invalid
6923 if (fBuffer) BufferEmpty(1);
6924
6925 Int_t firstbin = 1, lastbin = nbins;
6926 TString opt = option;
6927 opt.ToLower();
6928 if (opt.Contains("r")) {
6929 firstbin= fXaxis.GetFirst();
6930 lastbin = fXaxis.GetLast();
6931 }
6932 nbins = lastbin - firstbin + 1;
6933 Double_t *xx = new Double_t[nbins];
6934 Double_t nent = fEntries;
6935 Int_t i;
6936 for (i=0;i<nbins;i++) {
6937 xx[i] = RetrieveBinContent(i+firstbin);
6938 }
6939
6940 TH1::SmoothArray(nbins,xx,ntimes);
6941
6942 for (i=0;i<nbins;i++) {
6943 UpdateBinContent(i+firstbin,xx[i]);
6944 }
6945 fEntries = nent;
6946 delete [] xx;
6947
6948 if (gPad) gPad->Modified();
6949}
6950
6951////////////////////////////////////////////////////////////////////////////////
6952/// if flag=kTRUE, underflows and overflows are used by the Fill functions
6953/// in the computation of statistics (mean value, StdDev).
6954/// By default, underflows or overflows are not used.
6955
6956void TH1::StatOverflows(Bool_t flag)
6957{
6958 fgStatOverflows = flag;
6959}
6960
6961////////////////////////////////////////////////////////////////////////////////
6962/// Stream a class object.
6963
6964void TH1::Streamer(TBuffer &b)
6965{
6966 if (b.IsReading()) {
6967 UInt_t R__s, R__c;
6968 Version_t R__v = b.ReadVersion(&R__s, &R__c);
6969 if (fDirectory) fDirectory->Remove(this);
6970 fDirectory = nullptr;
6971 if (R__v > 2) {
6972 b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
6973
6975 fXaxis.SetParent(this);
6976 fYaxis.SetParent(this);
6977 fZaxis.SetParent(this);
6978 TIter next(fFunctions);
6979 TObject *obj;
6980 while ((obj=next())) {
6981 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
6982 }
6983 return;
6984 }
6985 //process old versions before automatic schema evolution
6990 b >> fNcells;
6991 fXaxis.Streamer(b);
6992 fYaxis.Streamer(b);
6993 fZaxis.Streamer(b);
6994 fXaxis.SetParent(this);
6995 fYaxis.SetParent(this);
6996 fZaxis.SetParent(this);
6997 b >> fBarOffset;
6998 b >> fBarWidth;
6999 b >> fEntries;
7000 b >> fTsumw;
7001 b >> fTsumw2;
7002 b >> fTsumwx;
7003 b >> fTsumwx2;
7004 if (R__v < 2) {
7005 Float_t maximum, minimum, norm;
7006 Float_t *contour=nullptr;
7007 b >> maximum; fMaximum = maximum;
7008 b >> minimum; fMinimum = minimum;
7009 b >> norm; fNormFactor = norm;
7010 Int_t n = b.ReadArray(contour);
7011 fContour.Set(n);
7012 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
7013 delete [] contour;
7014 } else {
7015 b >> fMaximum;
7016 b >> fMinimum;
7017 b >> fNormFactor;
7019 }
7020 fSumw2.Streamer(b);
7022 fFunctions->Delete();
7024 b.CheckByteCount(R__s, R__c, TH1::IsA());
7025
7026 } else {
7027 b.WriteClassBuffer(TH1::Class(),this);
7028 }
7029}
7030
7031////////////////////////////////////////////////////////////////////////////////
7032/// Print some global quantities for this histogram.
7033/// \param[in] option
7034/// - "base" is given, number of bins and ranges are also printed
7035/// - "range" is given, bin contents and errors are also printed
7036/// for all bins in the current range (default 1-->nbins)
7037/// - "all" is given, bin contents and errors are also printed
7038/// for all bins including under and overflows.
7039
7040void TH1::Print(Option_t *option) const
7041{
7042 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7043 printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
7044 TString opt = option;
7045 opt.ToLower();
7046 Int_t all;
7047 if (opt.Contains("all")) all = 0;
7048 else if (opt.Contains("range")) all = 1;
7049 else if (opt.Contains("base")) all = 2;
7050 else return;
7051
7052 Int_t bin, binx, biny, binz;
7053 Int_t firstx=0,lastx=0,firsty=0,lasty=0,firstz=0,lastz=0;
7054 if (all == 0) {
7055 lastx = fXaxis.GetNbins()+1;
7056 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
7057 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
7058 } else {
7059 firstx = fXaxis.GetFirst(); lastx = fXaxis.GetLast();
7060 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
7061 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
7062 }
7063
7064 if (all== 2) {
7065 printf(" Title = %s\n", GetTitle());
7066 printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
7067 if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
7068 if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
7069 printf("\n");
7070 return;
7071 }
7072
7073 Double_t w,e;
7074 Double_t x,y,z;
7075 if (fDimension == 1) {
7076 for (binx=firstx;binx<=lastx;binx++) {
7077 x = fXaxis.GetBinCenter(binx);
7078 w = RetrieveBinContent(binx);
7079 e = GetBinError(binx);
7080 if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
7081 else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
7082 }
7083 }
7084 if (fDimension == 2) {
7085 for (biny=firsty;biny<=lasty;biny++) {
7086 y = fYaxis.GetBinCenter(biny);
7087 for (binx=firstx;binx<=lastx;binx++) {
7088 bin = GetBin(binx,biny);
7089 x = fXaxis.GetBinCenter(binx);
7090 w = RetrieveBinContent(bin);
7091 e = GetBinError(bin);
7092 if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
7093 else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
7094 }
7095 }
7096 }
7097 if (fDimension == 3) {
7098 for (binz=firstz;binz<=lastz;binz++) {
7099 z = fZaxis.GetBinCenter(binz);
7100 for (biny=firsty;biny<=lasty;biny++) {
7101 y = fYaxis.GetBinCenter(biny);
7102 for (binx=firstx;binx<=lastx;binx++) {
7103 bin = GetBin(binx,biny,binz);
7104 x = fXaxis.GetBinCenter(binx);
7105 w = RetrieveBinContent(bin);
7106 e = GetBinError(bin);
7107 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);
7108 else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
7109 }
7110 }
7111 }
7112 }
7113}
7114
7115////////////////////////////////////////////////////////////////////////////////
7116/// Using the current bin info, recompute the arrays for contents and errors
7117
7118void TH1::Rebuild(Option_t *)
7119{
7120 SetBinsLength();
7121 if (fSumw2.fN) {
7123 }
7124}
7125
7126////////////////////////////////////////////////////////////////////////////////
7127/// Reset this histogram: contents, errors, etc.
7128/// \param[in] option
7129/// - if "ICE" is specified, resets only Integral, Contents and Errors.
7130/// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
7131/// This option is used
7132/// - if "M" is specified, resets also Minimum and Maximum
7133
7135{
7136 // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
7137 // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
7138
7139 TString opt = option;
7140 opt.ToUpper();
7141 fSumw2.Reset();
7142 if (fIntegral) {
7143 delete [] fIntegral;
7144 fIntegral = nullptr;
7145 }
7146
7147 if (opt.Contains("M")) {
7148 SetMinimum();
7149 SetMaximum();
7150 }
7151
7152 if (opt.Contains("ICE") && !opt.Contains("S")) return;
7153
7154 // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
7155 // But what is the sense of calling BufferEmpty() ? For making the axes ?
7156 // BufferEmpty will update contents that later will be
7157 // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
7158 // It may be needed for computing the axis limits....
7159 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
7160
7161 // need to reset also the statistics
7162 // (needs to be done after calling BufferEmpty() )
7163 fTsumw = 0;
7164 fTsumw2 = 0;
7165 fTsumwx = 0;
7166 fTsumwx2 = 0;
7167 fEntries = 0;
7168
7169 if (opt == "ICES") return;
7170
7171
7172 TObject *stats = fFunctions->FindObject("stats");
7173 fFunctions->Remove(stats);
7174 //special logic to support the case where the same object is
7175 //added multiple times in fFunctions.
7176 //This case happens when the same object is added with different
7177 //drawing modes
7178 TObject *obj;
7179 while ((obj = fFunctions->First())) {
7180 while(fFunctions->Remove(obj)) { }
7181 delete obj;
7182 }
7183 if(stats) fFunctions->Add(stats);
7184 fContour.Set(0);
7185}
7186
7187////////////////////////////////////////////////////////////////////////////////
7188/// Save the histogram as .csv, .tsv or .txt. In case of any other extension, fall
7189/// back to TObject::SaveAs, which saves as a .C macro (but with the file name
7190/// extension specified by the user)
7191///
7192/// The Under/Overflow bins are also exported (as first and last lines)
7193/// The fist 2 columns are the lower and upper edges of the bins
7194/// Column 3 contains the bin contents
7195/// The last column contains the error in y. If errors are not present, the column
7196/// is left empty
7197///
7198/// The result can be immediately imported into Excel, gnuplot, Python or whatever,
7199/// without the needing to install pyroot, etc.
7200///
7201/// \param filename the name of the file where to store the histogram
7202/// \param option some tuning options
7203///
7204/// The file extension defines the delimiter used:
7205/// - `.csv` : comma
7206/// - `.tsv` : tab
7207/// - `.txt` : space
7208///
7209/// If option = "title" a title line is generated. If the y-axis has a title,
7210/// this title is displayed as column 3 name, otherwise, it shows "BinContent"
7211
7212void TH1::SaveAs(const char *filename, Option_t *option) const
7213{
7214 char del = '\0';
7215 TString ext = "";
7216 TString fname = filename;
7217 TString opt = option;
7218
7219 if (filename) {
7220 if (fname.EndsWith(".csv")) {
7221 del = ',';
7222 ext = "csv";
7223 } else if (fname.EndsWith(".tsv")) {
7224 del = '\t';
7225 ext = "tsv";
7226 } else if (fname.EndsWith(".txt")) {
7227 del = ' ';
7228 ext = "txt";
7229 }
7230 }
7231 if (!del) {
7233 return;
7234 }
7235 std::ofstream out;
7236 out.open(filename, std::ios::out);
7237 if (!out.good()) {
7238 Error("SaveAs", "cannot open file: %s", filename);
7239 return;
7240 }
7241 if (opt.Contains("title")) {
7242 if (std::strcmp(GetYaxis()->GetTitle(), "") == 0) {
7243 out << "# " << "BinLowEdge" << del << "BinUpEdge" << del
7244 << "BinContent"
7245 << del << "ey" << std::endl;
7246 } else {
7247 out << "# " << "BinLowEdge" << del << "BinUpEdge" << del << GetYaxis()->GetTitle() << del << "ey" << std::endl;
7248 }
7249 }
7250 if (fSumw2.fN) {
7251 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7252 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7253 << GetBinError(i) << std::endl;
7254 }
7255 } else {
7256 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7257 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7258 << std::endl;
7259 }
7260 }
7261 out.close();
7262 Info("SaveAs", "%s file: %s has been generated", ext.Data(), filename);
7263}
7264
7265////////////////////////////////////////////////////////////////////////////////
7266/// Save primitive as a C++ statement(s) on output stream out
7267
7268void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
7269{
7270 // empty the buffer before if it exists
7271 if (fBuffer) BufferEmpty();
7272
7273 Bool_t nonEqiX = kFALSE;
7274 Bool_t nonEqiY = kFALSE;
7275 Bool_t nonEqiZ = kFALSE;
7276 Int_t i;
7277 static Int_t nxaxis = 0;
7278 static Int_t nyaxis = 0;
7279 static Int_t nzaxis = 0;
7280 TString sxaxis="xAxis",syaxis="yAxis",szaxis="zAxis";
7281
7282 const auto old_precision{out.precision()};
7283 constexpr auto max_precision{std::numeric_limits<double>::digits10 + 1};
7284 out << std::setprecision(max_precision);
7285 // Check if the histogram has equidistant X bins or not. If not, we
7286 // create an array holding the bins.
7287 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
7288 nonEqiX = kTRUE;
7289 nxaxis++;
7290 sxaxis += nxaxis;
7291 out << " Double_t "<<sxaxis<<"[" << GetXaxis()->GetXbins()->fN
7292 << "] = {";
7293 for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
7294 if (i != 0) out << ", ";
7295 out << GetXaxis()->GetXbins()->fArray[i];
7296 }
7297 out << "}; " << std::endl;
7298 }
7299 // If the histogram is 2 or 3 dimensional, check if the histogram
7300 // has equidistant Y bins or not. If not, we create an array
7301 // holding the bins.
7302 if (fDimension > 1 && GetYaxis()->GetXbins()->fN &&
7303 GetYaxis()->GetXbins()->fArray) {
7304 nonEqiY = kTRUE;
7305 nyaxis++;
7306 syaxis += nyaxis;
7307 out << " Double_t "<<syaxis<<"[" << GetYaxis()->GetXbins()->fN
7308 << "] = {";
7309 for (i = 0; i < GetYaxis()->GetXbins()->fN; i++) {
7310 if (i != 0) out << ", ";
7311 out << GetYaxis()->GetXbins()->fArray[i];
7312 }
7313 out << "}; " << std::endl;
7314 }
7315 // IF the histogram is 3 dimensional, check if the histogram
7316 // has equidistant Z bins or not. If not, we create an array
7317 // holding the bins.
7318 if (fDimension > 2 && GetZaxis()->GetXbins()->fN &&
7319 GetZaxis()->GetXbins()->fArray) {
7320 nonEqiZ = kTRUE;
7321 nzaxis++;
7322 szaxis += nzaxis;
7323 out << " Double_t "<<szaxis<<"[" << GetZaxis()->GetXbins()->fN
7324 << "] = {";
7325 for (i = 0; i < GetZaxis()->GetXbins()->fN; i++) {
7326 if (i != 0) out << ", ";
7327 out << GetZaxis()->GetXbins()->fArray[i];
7328 }
7329 out << "}; " << std::endl;
7330 }
7331
7332 char quote = '"';
7333 out <<" "<<std::endl;
7334 out <<" "<< ClassName() <<" *";
7335
7336 // Histogram pointer has by default the histogram name with an incremental suffix.
7337 // If the histogram belongs to a graph or a stack the suffix is not added because
7338 // the graph and stack objects are not aware of this new name. Same thing if
7339 // the histogram is drawn with the option COLZ because the TPaletteAxis drawn
7340 // when this option is selected, does not know this new name either.
7341 TString opt = option;
7342 opt.ToLower();
7343 static Int_t hcounter = 0;
7344 TString histName = GetName();
7345 if ( !histName.Contains("Graph")
7346 && !histName.Contains("_stack_")
7347 && !opt.Contains("colz")) {
7348 hcounter++;
7349 histName += "__";
7350 histName += hcounter;
7351 }
7352 histName = gInterpreter-> MapCppName(histName);
7353 const char *hname = histName.Data();
7354 if (!strlen(hname)) hname = "unnamed";
7355 TString savedName = GetName();
7356 this->SetName(hname);
7357 TString t(GetTitle());
7358 t.ReplaceAll("\\","\\\\");
7359 t.ReplaceAll("\"","\\\"");
7360 out << hname << " = new " << ClassName() << "(" << quote
7361 << hname << quote << "," << quote<< t.Data() << quote
7362 << "," << GetXaxis()->GetNbins();
7363 if (nonEqiX)
7364 out << ", "<<sxaxis;
7365 else
7366 out << "," << GetXaxis()->GetXmin()
7367 << "," << GetXaxis()->GetXmax();
7368 if (fDimension > 1) {
7369 out << "," << GetYaxis()->GetNbins();
7370 if (nonEqiY)
7371 out << ", "<<syaxis;
7372 else
7373 out << "," << GetYaxis()->GetXmin()
7374 << "," << GetYaxis()->GetXmax();
7375 }
7376 if (fDimension > 2) {
7377 out << "," << GetZaxis()->GetNbins();
7378 if (nonEqiZ)
7379 out << ", "<<szaxis;
7380 else
7381 out << "," << GetZaxis()->GetXmin()
7382 << "," << GetZaxis()->GetXmax();
7383 }
7384 out << ");" << std::endl;
7385
7386 // save bin contents
7387 Int_t bin;
7388 for (bin=0;bin<fNcells;bin++) {
7389 Double_t bc = RetrieveBinContent(bin);
7390 if (bc) {
7391 out<<" "<<hname<<"->SetBinContent("<<bin<<","<<bc<<");"<<std::endl;
7392 }
7393 }
7394
7395 // save bin errors
7396 if (fSumw2.fN) {
7397 for (bin=0;bin<fNcells;bin++) {
7398 Double_t be = GetBinError(bin);
7399 if (be) {
7400 out<<" "<<hname<<"->SetBinError("<<bin<<","<<be<<");"<<std::endl;
7401 }
7402 }
7403 }
7404
7405 TH1::SavePrimitiveHelp(out, hname, option);
7406 out << std::setprecision(old_precision);
7407 this->SetName(savedName.Data());
7408}
7409
7410////////////////////////////////////////////////////////////////////////////////
7411/// Helper function for the SavePrimitive functions from TH1
7412/// or classes derived from TH1, eg TProfile, TProfile2D.
7413
7414void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
7415{
7416 char quote = '"';
7417 if (TMath::Abs(GetBarOffset()) > 1e-5) {
7418 out<<" "<<hname<<"->SetBarOffset("<<GetBarOffset()<<");"<<std::endl;
7419 }
7420 if (TMath::Abs(GetBarWidth()-1) > 1e-5) {
7421 out<<" "<<hname<<"->SetBarWidth("<<GetBarWidth()<<");"<<std::endl;
7422 }
7423 if (fMinimum != -1111) {
7424 out<<" "<<hname<<"->SetMinimum("<<fMinimum<<");"<<std::endl;
7425 }
7426 if (fMaximum != -1111) {
7427 out<<" "<<hname<<"->SetMaximum("<<fMaximum<<");"<<std::endl;
7428 }
7429 if (fNormFactor != 0) {
7430 out<<" "<<hname<<"->SetNormFactor("<<fNormFactor<<");"<<std::endl;
7431 }
7432 if (fEntries != 0) {
7433 out<<" "<<hname<<"->SetEntries("<<fEntries<<");"<<std::endl;
7434 }
7435 if (!fDirectory) {
7436 out<<" "<<hname<<"->SetDirectory(nullptr);"<<std::endl;
7437 }
7438 if (TestBit(kNoStats)) {
7439 out<<" "<<hname<<"->SetStats(0);"<<std::endl;
7440 }
7441 if (fOption.Length() != 0) {
7442 out<<" "<<hname<<"->SetOption("<<quote<<fOption.Data()<<quote<<");"<<std::endl;
7443 }
7444
7445 // save contour levels
7446 Int_t ncontours = GetContour();
7447 if (ncontours > 0) {
7448 out<<" "<<hname<<"->SetContour("<<ncontours<<");"<<std::endl;
7449 Double_t zlevel;
7450 for (Int_t bin=0;bin<ncontours;bin++) {
7451 if (gPad->GetLogz()) {
7452 zlevel = TMath::Power(10,GetContourLevel(bin));
7453 } else {
7454 zlevel = GetContourLevel(bin);
7455 }
7456 out<<" "<<hname<<"->SetContourLevel("<<bin<<","<<zlevel<<");"<<std::endl;
7457 }
7458 }
7459
7460 // save list of functions
7461 auto lnk = fFunctions->FirstLink();
7462 static Int_t funcNumber = 0;
7463 while (lnk) {
7464 auto obj = lnk->GetObject();
7465 obj->SavePrimitive(out, TString::Format("nodraw #%d\n",++funcNumber).Data());
7466 if (obj->InheritsFrom(TF1::Class())) {
7467 TString fname;
7468 fname.Form("%s%d",obj->GetName(),funcNumber);
7469 out << " " << fname << "->SetParent(" << hname << ");\n";
7470 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7471 << fname <<");"<<std::endl;
7472 } else if (obj->InheritsFrom("TPaveStats")) {
7473 out<<" "<<hname<<"->GetListOfFunctions()->Add(ptstats);"<<std::endl;
7474 out<<" ptstats->SetParent("<<hname<<");"<<std::endl;
7475 } else if (obj->InheritsFrom("TPolyMarker")) {
7476 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7477 <<"pmarker ,"<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
7478 } else {
7479 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7480 <<obj->GetName()
7481 <<","<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
7482 }
7483 lnk = lnk->Next();
7484 }
7485
7486 // save attributes
7487 SaveFillAttributes(out,hname,0,1001);
7488 SaveLineAttributes(out,hname,1,1,1);
7489 SaveMarkerAttributes(out,hname,1,1,1);
7490 fXaxis.SaveAttributes(out,hname,"->GetXaxis()");
7491 fYaxis.SaveAttributes(out,hname,"->GetYaxis()");
7492 fZaxis.SaveAttributes(out,hname,"->GetZaxis()");
7493 TString opt = option;
7494 opt.ToLower();
7495 if (!opt.Contains("nodraw")) {
7496 out<<" "<<hname<<"->Draw("
7497 <<quote<<option<<quote<<");"<<std::endl;
7498 }
7499}
7500
7501////////////////////////////////////////////////////////////////////////////////
7502/// Copy current attributes from/to current style
7503
7505{
7506 if (!gStyle) return;
7507 if (gStyle->IsReading()) {
7508 fXaxis.ResetAttAxis("X");
7509 fYaxis.ResetAttAxis("Y");
7510 fZaxis.ResetAttAxis("Z");
7521 Int_t dostat = gStyle->GetOptStat();
7522 if (gStyle->GetOptFit() && !dostat) dostat = 1000000001;
7523 SetStats(dostat);
7524 } else {
7536 }
7537 TIter next(GetListOfFunctions());
7538 TObject *obj;
7539
7540 while ((obj = next())) {
7541 obj->UseCurrentStyle();
7542 }
7543}
7544
7545////////////////////////////////////////////////////////////////////////////////
7546/// For axis = 1,2 or 3 returns the mean value of the histogram along
7547/// X,Y or Z axis.
7548///
7549/// For axis = 11, 12, 13 returns the standard error of the mean value
7550/// of the histogram along X, Y or Z axis
7551///
7552/// Note that the mean value/StdDev is computed using the bins in the currently
7553/// defined range (see TAxis::SetRange). By default the range includes
7554/// all bins from 1 to nbins included, excluding underflows and overflows.
7555/// To force the underflows and overflows in the computation, one must
7556/// call the static function TH1::StatOverflows(kTRUE) before filling
7557/// the histogram.
7558///
7559/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7560/// are calculated. By default, if no range has been set, the returned mean is
7561/// the (unbinned) one calculated at fill time. If a range has been set, however,
7562/// the mean is calculated using the bins in range, as described above; THIS
7563/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7564/// the range. To ensure that the returned mean (and all other statistics) is
7565/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7566/// See TH1::GetStats.
7567///
7568/// Return mean value of this histogram along the X axis.
7569
7570Double_t TH1::GetMean(Int_t axis) const
7571{
7572 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7573 Double_t stats[kNstat];
7574 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7575 GetStats(stats);
7576 if (stats[0] == 0) return 0;
7577 if (axis<4){
7578 Int_t ax[3] = {2,4,7};
7579 return stats[ax[axis-1]]/stats[0];
7580 } else {
7581 // mean error = StdDev / sqrt( Neff )
7582 Double_t stddev = GetStdDev(axis-10);
7584 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7585 }
7586}
7587
7588////////////////////////////////////////////////////////////////////////////////
7589/// Return standard error of mean of this histogram along the X axis.
7590///
7591/// Note that the mean value/StdDev is computed using the bins in the currently
7592/// defined range (see TAxis::SetRange). By default the range includes
7593/// all bins from 1 to nbins included, excluding underflows and overflows.
7594/// To force the underflows and overflows in the computation, one must
7595/// call the static function TH1::StatOverflows(kTRUE) before filling
7596/// the histogram.
7597///
7598/// Also note, that although the definition of standard error doesn't include the
7599/// assumption of normality, many uses of this feature implicitly assume it.
7600///
7601/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7602/// are calculated. By default, if no range has been set, the returned value is
7603/// the (unbinned) one calculated at fill time. If a range has been set, however,
7604/// the value is calculated using the bins in range, as described above; THIS
7605/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7606/// the range. To ensure that the returned value (and all other statistics) is
7607/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7608/// See TH1::GetStats.
7609
7611{
7612 return GetMean(axis+10);
7613}
7614
7615////////////////////////////////////////////////////////////////////////////////
7616/// Returns the Standard Deviation (Sigma).
7617/// The Sigma estimate is computed as
7618/// \f[
7619/// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7620/// \f]
7621/// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7622/// X, Y or Z axis
7623/// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7624/// X, Y or Z axis for Normal distribution
7625///
7626/// Note that the mean value/sigma is computed using the bins in the currently
7627/// defined range (see TAxis::SetRange). By default the range includes
7628/// all bins from 1 to nbins included, excluding underflows and overflows.
7629/// To force the underflows and overflows in the computation, one must
7630/// call the static function TH1::StatOverflows(kTRUE) before filling
7631/// the histogram.
7632///
7633/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7634/// are calculated. By default, if no range has been set, the returned standard
7635/// deviation is the (unbinned) one calculated at fill time. If a range has been
7636/// set, however, the standard deviation is calculated using the bins in range,
7637/// as described above; THIS IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use
7638/// TAxis::SetRange(0, 0) to unset the range. To ensure that the returned standard
7639/// deviation (and all other statistics) is always that of the binned data stored
7640/// in the histogram, call TH1::ResetStats. See TH1::GetStats.
7641
7642Double_t TH1::GetStdDev(Int_t axis) const
7643{
7644 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7645
7646 Double_t x, stddev2, stats[kNstat];
7647 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7648 GetStats(stats);
7649 if (stats[0] == 0) return 0;
7650 Int_t ax[3] = {2,4,7};
7651 Int_t axm = ax[axis%10 - 1];
7652 x = stats[axm]/stats[0];
7653 // for negative stddev (e.g. when having negative weights) - return stdev=0
7654 stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7655 if (axis<10)
7656 return TMath::Sqrt(stddev2);
7657 else {
7658 // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7659 // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7661 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7662 }
7663}
7664
7665////////////////////////////////////////////////////////////////////////////////
7666/// Return error of standard deviation estimation for Normal distribution
7667///
7668/// Note that the mean value/StdDev is computed using the bins in the currently
7669/// defined range (see TAxis::SetRange). By default the range includes
7670/// all bins from 1 to nbins included, excluding underflows and overflows.
7671/// To force the underflows and overflows in the computation, one must
7672/// call the static function TH1::StatOverflows(kTRUE) before filling
7673/// the histogram.
7674///
7675/// Value returned is standard deviation of sample standard deviation.
7676/// Note that it is an approximated value which is valid only in the case that the
7677/// original data distribution is Normal. The correct one would require
7678/// the 4-th momentum value, which cannot be accurately estimated from a histogram since
7679/// the x-information for all entries is not kept.
7680///
7681/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7682/// are calculated. By default, if no range has been set, the returned value is
7683/// the (unbinned) one calculated at fill time. If a range has been set, however,
7684/// the value is calculated using the bins in range, as described above; THIS
7685/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7686/// the range. To ensure that the returned value (and all other statistics) is
7687/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7688/// See TH1::GetStats.
7689
7691{
7692 return GetStdDev(axis+10);
7693}
7694
7695////////////////////////////////////////////////////////////////////////////////
7696/// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7697/// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7698/// of the histogram along x, y or z axis
7699///
7700///Note, that since third and fourth moment are not calculated
7701///at the fill time, skewness and its standard error are computed bin by bin
7702///
7703/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7704/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7705
7707{
7708
7709 if (axis > 0 && axis <= 3){
7710
7711 Double_t mean = GetMean(axis);
7712 Double_t stddev = GetStdDev(axis);
7713 Double_t stddev3 = stddev*stddev*stddev;
7714
7715 Int_t firstBinX = fXaxis.GetFirst();
7716 Int_t lastBinX = fXaxis.GetLast();
7717 Int_t firstBinY = fYaxis.GetFirst();
7718 Int_t lastBinY = fYaxis.GetLast();
7719 Int_t firstBinZ = fZaxis.GetFirst();
7720 Int_t lastBinZ = fZaxis.GetLast();
7721 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7724 if (firstBinX == 1) firstBinX = 0;
7725 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7726 }
7728 if (firstBinY == 1) firstBinY = 0;
7729 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7730 }
7732 if (firstBinZ == 1) firstBinZ = 0;
7733 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7734 }
7735 }
7736
7737 Double_t x = 0;
7738 Double_t sum=0;
7739 Double_t np=0;
7740 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7741 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7742 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7743 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7744 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7745 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7746 Double_t w = GetBinContent(binx,biny,binz);
7747 np+=w;
7748 sum+=w*(x-mean)*(x-mean)*(x-mean);
7749 }
7750 }
7751 }
7752 sum/=np*stddev3;
7753 return sum;
7754 }
7755 else if (axis > 10 && axis <= 13) {
7756 //compute standard error of skewness
7757 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7759 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7760 }
7761 else {
7762 Error("GetSkewness", "illegal value of parameter");
7763 return 0;
7764 }
7765}
7766
7767////////////////////////////////////////////////////////////////////////////////
7768/// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7769/// Kurtosis(gaussian(0, 1)) = 0.
7770/// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7771/// of the histogram along x, y or z axis
7772////
7773/// Note, that since third and fourth moment are not calculated
7774/// at the fill time, kurtosis and its standard error are computed bin by bin
7775///
7776/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7777/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7778
7780{
7781 if (axis > 0 && axis <= 3){
7782
7783 Double_t mean = GetMean(axis);
7784 Double_t stddev = GetStdDev(axis);
7785 Double_t stddev4 = stddev*stddev*stddev*stddev;
7786
7787 Int_t firstBinX = fXaxis.GetFirst();
7788 Int_t lastBinX = fXaxis.GetLast();
7789 Int_t firstBinY = fYaxis.GetFirst();
7790 Int_t lastBinY = fYaxis.GetLast();
7791 Int_t firstBinZ = fZaxis.GetFirst();
7792 Int_t lastBinZ = fZaxis.GetLast();
7793 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7796 if (firstBinX == 1) firstBinX = 0;
7797 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7798 }
7800 if (firstBinY == 1) firstBinY = 0;
7801 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7802 }
7804 if (firstBinZ == 1) firstBinZ = 0;
7805 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7806 }
7807 }
7808
7809 Double_t x = 0;
7810 Double_t sum=0;
7811 Double_t np=0;
7812 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7813 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7814 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7815 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7816 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7817 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7818 Double_t w = GetBinContent(binx,biny,binz);
7819 np+=w;
7820 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7821 }
7822 }
7823 }
7824 sum/=(np*stddev4);
7825 return sum-3;
7826
7827 } else if (axis > 10 && axis <= 13) {
7828 //compute standard error of skewness
7829 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7831 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7832 }
7833 else {
7834 Error("GetKurtosis", "illegal value of parameter");
7835 return 0;
7836 }
7837}
7838
7839////////////////////////////////////////////////////////////////////////////////
7840/// fill the array stats from the contents of this histogram
7841/// The array stats must be correctly dimensioned in the calling program.
7842///
7843/// ~~~ {.cpp}
7844/// stats[0] = sumw
7845/// stats[1] = sumw2
7846/// stats[2] = sumwx
7847/// stats[3] = sumwx2
7848/// ~~~
7849///
7850/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7851/// is simply a copy of the statistics quantities computed at filling time.
7852/// If a sub-range is specified, the function recomputes these quantities
7853/// from the bin contents in the current axis range.
7854///
7855/// IMPORTANT NOTE: This means that the returned statistics are context-dependent.
7856/// If TAxis::kAxisRange, the returned statistics are dependent on the binning;
7857/// otherwise, they are a copy of the histogram statistics computed at fill time,
7858/// which are unbinned by default (calling TH1::ResetStats forces them to use
7859/// binned statistics). You can reset TAxis::kAxisRange using TAxis::SetRange(0, 0).
7860///
7861/// Note that the mean value/StdDev is computed using the bins in the currently
7862/// defined range (see TAxis::SetRange). By default the range includes
7863/// all bins from 1 to nbins included, excluding underflows and overflows.
7864/// To force the underflows and overflows in the computation, one must
7865/// call the static function TH1::StatOverflows(kTRUE) before filling
7866/// the histogram.
7867
7868void TH1::GetStats(Double_t *stats) const
7869{
7870 if (fBuffer) ((TH1*)this)->BufferEmpty();
7871
7872 // Loop on bins (possibly including underflows/overflows)
7873 Int_t bin, binx;
7874 Double_t w,err;
7875 Double_t x;
7876 // identify the case of labels with extension of axis range
7877 // in this case the statistics in x does not make any sense
7878 Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && fXaxis.CanExtend() );
7879 // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7880 if ( (fTsumw == 0 && fEntries > 0) || fXaxis.TestBit(TAxis::kAxisRange) ) {
7881 for (bin=0;bin<4;bin++) stats[bin] = 0;
7882
7883 Int_t firstBinX = fXaxis.GetFirst();
7884 Int_t lastBinX = fXaxis.GetLast();
7885 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7887 if (firstBinX == 1) firstBinX = 0;
7888 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7889 }
7890 for (binx = firstBinX; binx <= lastBinX; binx++) {
7891 x = fXaxis.GetBinCenter(binx);
7892 //w = TMath::Abs(RetrieveBinContent(binx));
7893 // not sure what to do here if w < 0
7894 w = RetrieveBinContent(binx);
7895 err = TMath::Abs(GetBinError(binx));
7896 stats[0] += w;
7897 stats[1] += err*err;
7898 // statistics in x makes sense only for not labels histograms
7899 if (!labelHist) {
7900 stats[2] += w*x;
7901 stats[3] += w*x*x;
7902 }
7903 }
7904 // if (stats[0] < 0) {
7905 // // in case total is negative do something ??
7906 // stats[0] = 0;
7907 // }
7908 } else {
7909 stats[0] = fTsumw;
7910 stats[1] = fTsumw2;
7911 stats[2] = fTsumwx;
7912 stats[3] = fTsumwx2;
7913 }
7914}
7915
7916////////////////////////////////////////////////////////////////////////////////
7917/// Replace current statistics with the values in array stats
7918
7919void TH1::PutStats(Double_t *stats)
7920{
7921 fTsumw = stats[0];
7922 fTsumw2 = stats[1];
7923 fTsumwx = stats[2];
7924 fTsumwx2 = stats[3];
7925}
7926
7927////////////////////////////////////////////////////////////////////////////////
7928/// Reset the statistics including the number of entries
7929/// and replace with values calculated from bin content
7930///
7931/// The number of entries is set to the total bin content or (in case of weighted histogram)
7932/// to number of effective entries
7933///
7934/// Note that, by default, before calling this function, statistics are those
7935/// computed at fill time, which are unbinned. See TH1::GetStats.
7936
7937void TH1::ResetStats()
7938{
7939 Double_t stats[kNstat] = {0};
7940 fTsumw = 0;
7941 fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
7942 GetStats(stats);
7943 PutStats(stats);
7945 // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
7946 if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
7947}
7948
7949////////////////////////////////////////////////////////////////////////////////
7950/// Return the sum of weights excluding under/overflows.
7951
7953{
7954 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7955
7956 Int_t bin,binx,biny,binz;
7957 Double_t sum =0;
7958 for(binz=1; binz<=fZaxis.GetNbins(); binz++) {
7959 for(biny=1; biny<=fYaxis.GetNbins(); biny++) {
7960 for(binx=1; binx<=fXaxis.GetNbins(); binx++) {
7961 bin = GetBin(binx,biny,binz);
7962 sum += RetrieveBinContent(bin);
7963 }
7964 }
7965 }
7966 return sum;
7967}
7968
7969////////////////////////////////////////////////////////////////////////////////
7970///Return integral of bin contents. Only bins in the bins range are considered.
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
7977{
7979}
7980
7981////////////////////////////////////////////////////////////////////////////////
7982/// Return integral of bin contents in range [binx1,binx2].
7983///
7984/// By default the integral is computed as the sum of bin contents in the range.
7985/// if option "width" is specified, the integral is the sum of
7986/// the bin contents multiplied by the bin width in x.
7987
7988Double_t TH1::Integral(Int_t binx1, Int_t binx2, Option_t *option) const
7989{
7990 double err = 0;
7991 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
7992}
7993
7994////////////////////////////////////////////////////////////////////////////////
7995/// Return integral of bin contents in range [binx1,binx2] and its error.
7996///
7997/// By default the integral is computed as the sum of bin contents in the range.
7998/// if option "width" is specified, the integral is the sum of
7999/// the bin contents multiplied by the bin width in x.
8000/// the error is computed using error propagation from the bin errors assuming that
8001/// all the bins are uncorrelated
8002
8003Double_t TH1::IntegralAndError(Int_t binx1, Int_t binx2, Double_t & error, Option_t *option) const
8004{
8005 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
8006}
8007
8008////////////////////////////////////////////////////////////////////////////////
8009/// Internal function compute integral and optionally the error between the limits
8010/// specified by the bin number values working for all histograms (1D, 2D and 3D)
8011
8012Double_t TH1::DoIntegral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error ,
8013 Option_t *option, Bool_t doError) const
8014{
8015 if (fBuffer) ((TH1*)this)->BufferEmpty();
8016
8017 Int_t nx = GetNbinsX() + 2;
8018 if (binx1 < 0) binx1 = 0;
8019 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
8020
8021 if (GetDimension() > 1) {
8022 Int_t ny = GetNbinsY() + 2;
8023 if (biny1 < 0) biny1 = 0;
8024 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
8025 } else {
8026 biny1 = 0; biny2 = 0;
8027 }
8028
8029 if (GetDimension() > 2) {
8030 Int_t nz = GetNbinsZ() + 2;
8031 if (binz1 < 0) binz1 = 0;
8032 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
8033 } else {
8034 binz1 = 0; binz2 = 0;
8035 }
8036
8037 // - Loop on bins in specified range
8038 TString opt = option;
8039 opt.ToLower();
8041 if (opt.Contains("width")) width = kTRUE;
8042
8043
8044 Double_t dx = 1., dy = .1, dz =.1;
8045 Double_t integral = 0;
8046 Double_t igerr2 = 0;
8047 for (Int_t binx = binx1; binx <= binx2; ++binx) {
8048 if (width) dx = fXaxis.GetBinWidth(binx);
8049 for (Int_t biny = biny1; biny <= biny2; ++biny) {
8050 if (width) dy = fYaxis.GetBinWidth(biny);
8051 for (Int_t binz = binz1; binz <= binz2; ++binz) {
8052 Int_t bin = GetBin(binx, biny, binz);
8053 Double_t dv = 0.0;
8054 if (width) {
8055 dz = fZaxis.GetBinWidth(binz);
8056 dv = dx * dy * dz;
8057 integral += RetrieveBinContent(bin) * dv;
8058 } else {
8059 integral += RetrieveBinContent(bin);
8060 }
8061 if (doError) {
8062 if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
8063 else igerr2 += GetBinErrorSqUnchecked(bin);
8064 }
8065 }
8066 }
8067 }
8068
8069 if (doError) error = TMath::Sqrt(igerr2);
8070 return integral;
8071}
8072
8073////////////////////////////////////////////////////////////////////////////////
8074/// Statistical test of compatibility in shape between
8075/// this histogram and h2, using the Anderson-Darling 2 sample test.
8076///
8077/// The AD 2 sample test formula are derived from the paper
8078/// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
8079///
8080/// The test is implemented in root in the ROOT::Math::GoFTest class
8081/// It is the same formula ( (6) in the paper), and also shown in
8082/// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
8083///
8084/// Binned data are considered as un-binned data
8085/// with identical observation happening in the bin center.
8086///
8087/// \param[in] h2 Pointer to 1D histogram
8088/// \param[in] option is a character string to specify options
8089/// - "D" Put out a line of "Debug" printout
8090/// - "T" Return the normalized A-D test statistic
8091///
8092/// - Note1: Underflow and overflow are not considered in the test
8093/// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
8094/// - Note3: The histograms are not required to have the same X axis
8095/// - Note4: The test works only for 1-dimensional histograms
8096
8098{
8099 Double_t advalue = 0;
8100 Double_t pvalue = AndersonDarlingTest(h2, advalue);
8101
8102 TString opt = option;
8103 opt.ToUpper();
8104 if (opt.Contains("D") ) {
8105 printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
8106 }
8107 if (opt.Contains("T") ) return advalue;
8108
8109 return pvalue;
8110}
8111
8112////////////////////////////////////////////////////////////////////////////////
8113/// Same function as above but returning also the test statistic value
8114
8115Double_t TH1::AndersonDarlingTest(const TH1 *h2, Double_t & advalue) const
8116{
8117 if (GetDimension() != 1 || h2->GetDimension() != 1) {
8118 Error("AndersonDarlingTest","Histograms must be 1-D");
8119 return -1;
8120 }
8121
8122 // empty the buffer. Probably we could add as an unbinned test
8123 if (fBuffer) ((TH1*)this)->BufferEmpty();
8124
8125 // use the BinData class
8126 ROOT::Fit::BinData data1;
8127 ROOT::Fit::BinData data2;
8128
8129 ROOT::Fit::FillData(data1, this, nullptr);
8130 ROOT::Fit::FillData(data2, h2, nullptr);
8131
8132 double pvalue;
8133 ROOT::Math::GoFTest::AndersonDarling2SamplesTest(data1,data2, pvalue,advalue);
8134
8135 return pvalue;
8136}
8137
8138////////////////////////////////////////////////////////////////////////////////
8139/// Statistical test of compatibility in shape between
8140/// this histogram and h2, using Kolmogorov test.
8141/// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
8142/// and not for binned data as in the case of the histogram (see NOTE 3 below).
8143/// So, before using this method blindly, read the NOTE 3.
8144///
8145/// Default: Ignore under- and overflow bins in comparison
8146///
8147/// \param[in] h2 histogram
8148/// \param[in] option is a character string to specify options
8149/// - "U" include Underflows in test (also for 2-dim)
8150/// - "O" include Overflows (also valid for 2-dim)
8151/// - "N" include comparison of normalizations
8152/// - "D" Put out a line of "Debug" printout
8153/// - "M" Return the Maximum Kolmogorov distance instead of prob
8154/// - "X" Run the pseudo experiments post-processor with the following procedure:
8155/// make pseudoexperiments based on random values from the parent distribution,
8156/// compare the KS distance of the pseudoexperiment to the parent
8157/// distribution, and count all the KS values above the value
8158/// obtained from the original data to Monte Carlo distribution.
8159/// The number of pseudo-experiments nEXPT is by default 1000, and
8160/// it can be changed by specifying the option as "X=number",
8161/// for example "X=10000" for 10000 toys.
8162/// The function returns the probability.
8163/// (thanks to Ben Kilminster to submit this procedure). Note that
8164/// this option "X" is much slower.
8165///
8166/// The returned function value is the probability of test
8167/// (much less than one means NOT compatible)
8168///
8169/// Code adapted by Rene Brun from original HBOOK routine HDIFF
8170///
8171/// NOTE1
8172/// A good description of the Kolmogorov test can be seen at:
8173/// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
8174///
8175/// NOTE2
8176/// see also alternative function TH1::Chi2Test
8177/// The Kolmogorov test is assumed to give better results than Chi2Test
8178/// in case of histograms with low statistics.
8179///
8180/// NOTE3 (Jan Conrad, Fred James)
8181/// "The returned value PROB is calculated such that it will be
8182/// uniformly distributed between zero and one for compatible histograms,
8183/// provided the data are not binned (or the number of bins is very large
8184/// compared with the number of events). Users who have access to unbinned
8185/// data and wish exact confidence levels should therefore not put their data
8186/// into histograms, but should call directly TMath::KolmogorovTest. On
8187/// the other hand, since TH1 is a convenient way of collecting data and
8188/// saving space, this function has been provided. However, the values of
8189/// PROB for binned data will be shifted slightly higher than expected,
8190/// depending on the effects of the binning. For example, when comparing two
8191/// uniform distributions of 500 events in 100 bins, the values of PROB,
8192/// instead of being exactly uniformly distributed between zero and one, have
8193/// a mean value of about 0.56. We can apply a useful
8194/// rule: As long as the bin width is small compared with any significant
8195/// physical effect (for example the experimental resolution) then the binning
8196/// cannot have an important effect. Therefore, we believe that for all
8197/// practical purposes, the probability value PROB is calculated correctly
8198/// provided the user is aware that:
8199///
8200/// 1. The value of PROB should not be expected to have exactly the correct
8201/// distribution for binned data.
8202/// 2. The user is responsible for seeing to it that the bin widths are
8203/// small compared with any physical phenomena of interest.
8204/// 3. The effect of binning (if any) is always to make the value of PROB
8205/// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
8206/// will assure that at most 5% of truly compatible histograms are rejected,
8207/// and usually somewhat less."
8208///
8209/// Note also that for GoF test of unbinned data ROOT provides also the class
8210/// ROOT::Math::GoFTest. The class has also method for doing one sample tests
8211/// (i.e. comparing the data with a given distribution).
8212
8214{
8215 TString opt = option;
8216 opt.ToUpper();
8217
8218 Double_t prob = 0;
8219 TH1 *h1 = (TH1*)this;
8220 if (h2 == nullptr) return 0;
8221 const TAxis *axis1 = h1->GetXaxis();
8222 const TAxis *axis2 = h2->GetXaxis();
8223 Int_t ncx1 = axis1->GetNbins();
8224 Int_t ncx2 = axis2->GetNbins();
8225
8226 // Check consistency of dimensions
8227 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
8228 Error("KolmogorovTest","Histograms must be 1-D\n");
8229 return 0;
8230 }
8231
8232 // Check consistency in number of channels
8233 if (ncx1 != ncx2) {
8234 Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
8235 return 0;
8236 }
8237
8238 // empty the buffer. Probably we could add as an unbinned test
8239 if (fBuffer) ((TH1*)this)->BufferEmpty();
8240
8241 // Check consistency in bin edges
8242 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
8243 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
8244 Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
8245 return 0;
8246 }
8247 }
8248
8249 Bool_t afunc1 = kFALSE;
8250 Bool_t afunc2 = kFALSE;
8251 Double_t sum1 = 0, sum2 = 0;
8252 Double_t ew1, ew2, w1 = 0, w2 = 0;
8253 Int_t bin;
8254 Int_t ifirst = 1;
8255 Int_t ilast = ncx1;
8256 // integral of all bins (use underflow/overflow if option)
8257 if (opt.Contains("U")) ifirst = 0;
8258 if (opt.Contains("O")) ilast = ncx1 +1;
8259 for (bin = ifirst; bin <= ilast; bin++) {
8260 sum1 += h1->RetrieveBinContent(bin);
8261 sum2 += h2->RetrieveBinContent(bin);
8262 ew1 = h1->GetBinError(bin);
8263 ew2 = h2->GetBinError(bin);
8264 w1 += ew1*ew1;
8265 w2 += ew2*ew2;
8266 }
8267 if (sum1 == 0) {
8268 Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
8269 return 0;
8270 }
8271 if (sum2 == 0) {
8272 Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
8273 return 0;
8274 }
8275
8276 // calculate the effective entries.
8277 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
8278 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
8279 Double_t esum1 = 0, esum2 = 0;
8280 if (w1 > 0)
8281 esum1 = sum1 * sum1 / w1;
8282 else
8283 afunc1 = kTRUE; // use later for calculating z
8284
8285 if (w2 > 0)
8286 esum2 = sum2 * sum2 / w2;
8287 else
8288 afunc2 = kTRUE; // use later for calculating z
8289
8290 if (afunc2 && afunc1) {
8291 Error("KolmogorovTest","Errors are zero for both histograms\n");
8292 return 0;
8293 }
8294
8295
8296 Double_t s1 = 1/sum1;
8297 Double_t s2 = 1/sum2;
8298
8299 // Find largest difference for Kolmogorov Test
8300 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
8301
8302 for (bin=ifirst;bin<=ilast;bin++) {
8303 rsum1 += s1*h1->RetrieveBinContent(bin);
8304 rsum2 += s2*h2->RetrieveBinContent(bin);
8305 dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
8306 }
8307
8308 // Get Kolmogorov probability
8309 Double_t z, prb1=0, prb2=0, prb3=0;
8310
8311 // case h1 is exact (has zero errors)
8312 if (afunc1)
8313 z = dfmax*TMath::Sqrt(esum2);
8314 // case h2 has zero errors
8315 else if (afunc2)
8316 z = dfmax*TMath::Sqrt(esum1);
8317 else
8318 // for comparison between two data sets
8319 z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
8320
8321 prob = TMath::KolmogorovProb(z);
8322
8323 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
8324 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
8325 // Combine probabilities for shape and normalization,
8326 prb1 = prob;
8327 Double_t d12 = esum1-esum2;
8328 Double_t chi2 = d12*d12/(esum1+esum2);
8329 prb2 = TMath::Prob(chi2,1);
8330 // see Eadie et al., section 11.6.2
8331 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
8332 else prob = 0;
8333 }
8334 // X option. Run Pseudo-experiments to determine NULL distribution of the
8335 // KS distance. We can find the probability from the number of pseudo-experiment that have a
8336 // KS distance larger than the one opbserved in the data.
8337 // We use the histogram with the largest statistics as a parent distribution for the NULL.
8338 // Note if one histogram has zero errors is considered as a function. In that case we use it
8339 // as parent distribution for the toys.
8340 //
8341 Int_t nEXPT = 1000;
8342 if (opt.Contains("X")) {
8343 // get number of pseudo-experiment of specified
8344 if (opt.Contains("X=")) {
8345 int numpos = opt.Index("X=") + 2; // 2 is length of X=
8346 int numlen = 0;
8347 int len = opt.Length();
8348 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) )
8349 numlen++;
8350 TString snum = opt(numpos,numlen);
8351 int num = atoi(snum.Data());
8352 if (num <= 0)
8353 Warning("KolmogorovTest","invalid number of toys given: %d - use 1000",num);
8354 else
8355 nEXPT = num;
8356 }
8357
8358 Double_t dSEXPT;
8359 TH1D hparent;
8360 // we cannot have afunc1 and func2 both True
8361 if (afunc1 || esum1 > esum2 ) h1->Copy(hparent);
8362 else h2->Copy(hparent);
8363
8364 // copy h1Expt from h1 and h2. It is just needed to get the correct binning
8365
8366
8367 if (hparent.GetMinimum() < 0.0) {
8368 // we need to create a new histogram
8369 // With negative bins we can't draw random samples in a meaningful way.
8370 Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
8371 "skewed. Reduce number of bins for histogram?");
8372 while (hparent.GetMinimum() < 0.0) {
8373 Int_t idx = hparent.GetMinimumBin();
8374 hparent.SetBinContent(idx, 0.0);
8375 }
8376 }
8377
8378 // make nEXPT experiments (this should be a parameter)
8379 prb3 = 0;
8380 TH1D h1Expt;
8381 h1->Copy(h1Expt);
8382 TH1D h2Expt;
8383 h1->Copy(h2Expt);
8384 // loop on pseudoexperients and generate the two histograms h1Expt and h2Expt according to the
8385 // parent distribution. In case the parent distribution is not an histogram but a function randomize only one
8386 // histogram
8387 for (Int_t i=0; i < nEXPT; i++) {
8388 if (!afunc1) {
8389 h1Expt.Reset();
8390 h1Expt.FillRandom(&hparent, (Int_t)esum1);
8391 }
8392 if (!afunc2) {
8393 h2Expt.Reset();
8394 h2Expt.FillRandom(&hparent, (Int_t)esum2);
8395 }
8396 // note we cannot have both afunc1 and afunc2 to be true
8397 if (afunc1)
8398 dSEXPT = hparent.KolmogorovTest(&h2Expt,"M");
8399 else if (afunc2)
8400 dSEXPT = hparent.KolmogorovTest(&h1Expt,"M");
8401 else
8402 dSEXPT = h1Expt.KolmogorovTest(&h2Expt,"M");
8403 // count number of cases toy KS distance (TS) is larger than oberved one
8404 if (dSEXPT>dfmax) prb3 += 1.0;
8405 }
8406 // compute p-value
8407 prb3 /= (Double_t)nEXPT;
8408 }
8409
8410
8411 // debug printout
8412 if (opt.Contains("D")) {
8413 printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
8414 printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
8415 printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
8416 if (opt.Contains("N"))
8417 printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
8418 if (opt.Contains("X"))
8419 printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
8420 }
8421 // This numerical error condition should never occur:
8422 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
8423 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
8424
8425 if(opt.Contains("M")) return dfmax;
8426 else if(opt.Contains("X")) return prb3;
8427 else return prob;
8428}
8429
8430////////////////////////////////////////////////////////////////////////////////
8431/// Replace bin contents by the contents of array content
8432
8433void TH1::SetContent(const Double_t *content)
8434{
8435 fEntries = fNcells;
8436 fTsumw = 0;
8437 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
8438}
8439
8440////////////////////////////////////////////////////////////////////////////////
8441/// Return contour values into array levels if pointer levels is non zero.
8442///
8443/// The function returns the number of contour levels.
8444/// see GetContourLevel to return one contour only
8445
8447{
8448 Int_t nlevels = fContour.fN;
8449 if (levels) {
8450 if (nlevels == 0) {
8451 nlevels = 20;
8452 SetContour(nlevels);
8453 } else {
8454 if (TestBit(kUserContour) == 0) SetContour(nlevels);
8455 }
8456 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
8457 }
8458 return nlevels;
8459}
8460
8461////////////////////////////////////////////////////////////////////////////////
8462/// Return value of contour number level.
8463/// Use GetContour to return the array of all contour levels
8464
8466{
8467 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
8468}
8469
8470////////////////////////////////////////////////////////////////////////////////
8471/// Return the value of contour number "level" in Pad coordinates.
8472/// ie: if the Pad is in log scale along Z it returns le log of the contour level
8473/// value. See GetContour to return the array of all contour levels
8474
8476{
8477 if (level <0 || level >= fContour.fN) return 0;
8478 Double_t zlevel = fContour.fArray[level];
8479
8480 // In case of user defined contours and Pad in log scale along Z,
8481 // fContour.fArray doesn't contain the log of the contour whereas it does
8482 // in case of equidistant contours.
8483 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
8484 if (zlevel <= 0) return 0;
8485 zlevel = TMath::Log10(zlevel);
8486 }
8487 return zlevel;
8488}
8489
8490////////////////////////////////////////////////////////////////////////////////
8491/// Set the maximum number of entries to be kept in the buffer.
8492
8493void TH1::SetBuffer(Int_t buffersize, Option_t * /*option*/)
8494{
8495 if (fBuffer) {
8496 BufferEmpty();
8497 delete [] fBuffer;
8498 fBuffer = nullptr;
8499 }
8500 if (buffersize <= 0) {
8501 fBufferSize = 0;
8502 return;
8503 }
8504 if (buffersize < 100) buffersize = 100;
8505 fBufferSize = 1 + buffersize*(fDimension+1);
8507 memset(fBuffer, 0, sizeof(Double_t)*fBufferSize);
8508}
8509
8510////////////////////////////////////////////////////////////////////////////////
8511/// Set the number and values of contour levels.
8512///
8513/// By default the number of contour levels is set to 20. The contours values
8514/// in the array "levels" should be specified in increasing order.
8515///
8516/// if argument levels = 0 or missing, equidistant contours are computed
8517
8518void TH1::SetContour(Int_t nlevels, const Double_t *levels)
8519{
8520 Int_t level;
8522 if (nlevels <=0 ) {
8523 fContour.Set(0);
8524 return;
8525 }
8526 fContour.Set(nlevels);
8527
8528 // - Contour levels are specified
8529 if (levels) {
8531 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
8532 } else {
8533 // - contour levels are computed automatically as equidistant contours
8534 Double_t zmin = GetMinimum();
8535 Double_t zmax = GetMaximum();
8536 if ((zmin == zmax) && (zmin != 0)) {
8537 zmax += 0.01*TMath::Abs(zmax);
8538 zmin -= 0.01*TMath::Abs(zmin);
8539 }
8540 Double_t dz = (zmax-zmin)/Double_t(nlevels);
8541 if (gPad && gPad->GetLogz()) {
8542 if (zmax <= 0) return;
8543 if (zmin <= 0) zmin = 0.001*zmax;
8544 zmin = TMath::Log10(zmin);
8545 zmax = TMath::Log10(zmax);
8546 dz = (zmax-zmin)/Double_t(nlevels);
8547 }
8548 for (level=0; level<nlevels; level++) {
8549 fContour.fArray[level] = zmin + dz*Double_t(level);
8550 }
8551 }
8552}
8553
8554////////////////////////////////////////////////////////////////////////////////
8555/// Set value for one contour level.
8556
8558{
8559 if (level < 0 || level >= fContour.fN) return;
8561 fContour.fArray[level] = value;
8562}
8563
8564////////////////////////////////////////////////////////////////////////////////
8565/// Return maximum value smaller than maxval of bins in the range,
8566/// unless the value has been overridden by TH1::SetMaximum,
8567/// in which case it returns that value. This happens, for example,
8568/// when the histogram is drawn and the y or z axis limits are changed
8569///
8570/// To get the maximum value of bins in the histogram regardless of
8571/// whether the value has been overridden (using TH1::SetMaximum), use
8572///
8573/// ~~~ {.cpp}
8574/// h->GetBinContent(h->GetMaximumBin())
8575/// ~~~
8576///
8577/// TH1::GetMaximumBin can be used to get the location of the maximum
8578/// value.
8579
8580Double_t TH1::GetMaximum(Double_t maxval) const
8581{
8582 if (fMaximum != -1111) return fMaximum;
8583
8584 // empty the buffer
8585 if (fBuffer) ((TH1*)this)->BufferEmpty();
8586
8587 Int_t bin, binx, biny, binz;
8588 Int_t xfirst = fXaxis.GetFirst();
8589 Int_t xlast = fXaxis.GetLast();
8590 Int_t yfirst = fYaxis.GetFirst();
8591 Int_t ylast = fYaxis.GetLast();
8592 Int_t zfirst = fZaxis.GetFirst();
8593 Int_t zlast = fZaxis.GetLast();
8594 Double_t maximum = -FLT_MAX, value;
8595 for (binz=zfirst;binz<=zlast;binz++) {
8596 for (biny=yfirst;biny<=ylast;biny++) {
8597 for (binx=xfirst;binx<=xlast;binx++) {
8598 bin = GetBin(binx,biny,binz);
8600 if (value > maximum && value < maxval) maximum = value;
8601 }
8602 }
8603 }
8604 return maximum;
8605}
8606
8607////////////////////////////////////////////////////////////////////////////////
8608/// Return location of bin with maximum value in the range.
8609///
8610/// TH1::GetMaximum can be used to get the maximum value.
8611
8613{
8614 Int_t locmax, locmay, locmaz;
8615 return GetMaximumBin(locmax, locmay, locmaz);
8616}
8617
8618////////////////////////////////////////////////////////////////////////////////
8619/// Return location of bin with maximum value in the range.
8620
8621Int_t TH1::GetMaximumBin(Int_t &locmax, Int_t &locmay, Int_t &locmaz) const
8622{
8623 // empty the buffer
8624 if (fBuffer) ((TH1*)this)->BufferEmpty();
8625
8626 Int_t bin, binx, biny, binz;
8627 Int_t locm;
8628 Int_t xfirst = fXaxis.GetFirst();
8629 Int_t xlast = fXaxis.GetLast();
8630 Int_t yfirst = fYaxis.GetFirst();
8631 Int_t ylast = fYaxis.GetLast();
8632 Int_t zfirst = fZaxis.GetFirst();
8633 Int_t zlast = fZaxis.GetLast();
8634 Double_t maximum = -FLT_MAX, value;
8635 locm = locmax = locmay = locmaz = 0;
8636 for (binz=zfirst;binz<=zlast;binz++) {
8637 for (biny=yfirst;biny<=ylast;biny++) {
8638 for (binx=xfirst;binx<=xlast;binx++) {
8639 bin = GetBin(binx,biny,binz);
8641 if (value > maximum) {
8642 maximum = value;
8643 locm = bin;
8644 locmax = binx;
8645 locmay = biny;
8646 locmaz = binz;
8647 }
8648 }
8649 }
8650 }
8651 return locm;
8652}
8653
8654////////////////////////////////////////////////////////////////////////////////
8655/// Return minimum value larger than minval of bins in the range,
8656/// unless the value has been overridden by TH1::SetMinimum,
8657/// in which case it returns that value. This happens, for example,
8658/// when the histogram is drawn and the y or z axis limits are changed
8659///
8660/// To get the minimum value of bins in the histogram regardless of
8661/// whether the value has been overridden (using TH1::SetMinimum), use
8662///
8663/// ~~~ {.cpp}
8664/// h->GetBinContent(h->GetMinimumBin())
8665/// ~~~
8666///
8667/// TH1::GetMinimumBin can be used to get the location of the
8668/// minimum value.
8669
8670Double_t TH1::GetMinimum(Double_t minval) const
8671{
8672 if (fMinimum != -1111) return fMinimum;
8673
8674 // empty the buffer
8675 if (fBuffer) ((TH1*)this)->BufferEmpty();
8676
8677 Int_t bin, binx, biny, binz;
8678 Int_t xfirst = fXaxis.GetFirst();
8679 Int_t xlast = fXaxis.GetLast();
8680 Int_t yfirst = fYaxis.GetFirst();
8681 Int_t ylast = fYaxis.GetLast();
8682 Int_t zfirst = fZaxis.GetFirst();
8683 Int_t zlast = fZaxis.GetLast();
8684 Double_t minimum=FLT_MAX, value;
8685 for (binz=zfirst;binz<=zlast;binz++) {
8686 for (biny=yfirst;biny<=ylast;biny++) {
8687 for (binx=xfirst;binx<=xlast;binx++) {
8688 bin = GetBin(binx,biny,binz);
8690 if (value < minimum && value > minval) minimum = value;
8691 }
8692 }
8693 }
8694 return minimum;
8695}
8696
8697////////////////////////////////////////////////////////////////////////////////
8698/// Return location of bin with minimum value in the range.
8699
8701{
8702 Int_t locmix, locmiy, locmiz;
8703 return GetMinimumBin(locmix, locmiy, locmiz);
8704}
8705
8706////////////////////////////////////////////////////////////////////////////////
8707/// Return location of bin with minimum value in the range.
8708
8709Int_t TH1::GetMinimumBin(Int_t &locmix, Int_t &locmiy, Int_t &locmiz) const
8710{
8711 // empty the buffer
8712 if (fBuffer) ((TH1*)this)->BufferEmpty();
8713
8714 Int_t bin, binx, biny, binz;
8715 Int_t locm;
8716 Int_t xfirst = fXaxis.GetFirst();
8717 Int_t xlast = fXaxis.GetLast();
8718 Int_t yfirst = fYaxis.GetFirst();
8719 Int_t ylast = fYaxis.GetLast();
8720 Int_t zfirst = fZaxis.GetFirst();
8721 Int_t zlast = fZaxis.GetLast();
8722 Double_t minimum = FLT_MAX, value;
8723 locm = locmix = locmiy = locmiz = 0;
8724 for (binz=zfirst;binz<=zlast;binz++) {
8725 for (biny=yfirst;biny<=ylast;biny++) {
8726 for (binx=xfirst;binx<=xlast;binx++) {
8727 bin = GetBin(binx,biny,binz);
8729 if (value < minimum) {
8730 minimum = value;
8731 locm = bin;
8732 locmix = binx;
8733 locmiy = biny;
8734 locmiz = binz;
8735 }
8736 }
8737 }
8738 }
8739 return locm;
8740}
8741
8742///////////////////////////////////////////////////////////////////////////////
8743/// Retrieve the minimum and maximum values in the histogram
8744///
8745/// This will not return a cached value and will always search the
8746/// histogram for the min and max values. The user can condition whether
8747/// or not to call this with the GetMinimumStored() and GetMaximumStored()
8748/// methods. If the cache is empty, then the value will be -1111. Users
8749/// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8750/// For example, the following recipe will make efficient use of this method
8751/// and the cached minimum and maximum values.
8752//
8753/// \code{.cpp}
8754/// Double_t currentMin = pHist->GetMinimumStored();
8755/// Double_t currentMax = pHist->GetMaximumStored();
8756/// if ((currentMin == -1111) || (currentMax == -1111)) {
8757/// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8758/// pHist->SetMinimum(currentMin);
8759/// pHist->SetMaximum(currentMax);
8760/// }
8761/// \endcode
8762///
8763/// \param min reference to variable that will hold found minimum value
8764/// \param max reference to variable that will hold found maximum value
8765
8766void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8767{
8768 // empty the buffer
8769 if (fBuffer) ((TH1*)this)->BufferEmpty();
8770
8771 Int_t bin, binx, biny, binz;
8772 Int_t xfirst = fXaxis.GetFirst();
8773 Int_t xlast = fXaxis.GetLast();
8774 Int_t yfirst = fYaxis.GetFirst();
8775 Int_t ylast = fYaxis.GetLast();
8776 Int_t zfirst = fZaxis.GetFirst();
8777 Int_t zlast = fZaxis.GetLast();
8778 min=TMath::Infinity();
8779 max=-TMath::Infinity();
8781 for (binz=zfirst;binz<=zlast;binz++) {
8782 for (biny=yfirst;biny<=ylast;biny++) {
8783 for (binx=xfirst;binx<=xlast;binx++) {
8784 bin = GetBin(binx,biny,binz);
8786 if (value < min) min = value;
8787 if (value > max) max = value;
8788 }
8789 }
8790 }
8791}
8792
8793////////////////////////////////////////////////////////////////////////////////
8794/// Redefine x axis parameters.
8795///
8796/// The X axis parameters are modified.
8797/// The bins content array is resized
8798/// if errors (Sumw2) the errors array is resized
8799/// The previous bin contents are lost
8800/// To change only the axis limits, see TAxis::SetRange
8801
8803{
8804 if (GetDimension() != 1) {
8805 Error("SetBins","Operation only valid for 1-d histograms");
8806 return;
8807 }
8808 fXaxis.SetRange(0,0);
8809 fXaxis.Set(nx,xmin,xmax);
8810 fYaxis.Set(1,0,1);
8811 fZaxis.Set(1,0,1);
8812 fNcells = nx+2;
8814 if (fSumw2.fN) {
8816 }
8817}
8818
8819////////////////////////////////////////////////////////////////////////////////
8820/// Redefine x axis parameters with variable bin sizes.
8821///
8822/// The X axis parameters are modified.
8823/// The bins content array is resized
8824/// if errors (Sumw2) the errors array is resized
8825/// The previous bin contents are lost
8826/// To change only the axis limits, see TAxis::SetRange
8827/// xBins is supposed to be of length nx+1
8828
8829void TH1::SetBins(Int_t nx, const Double_t *xBins)
8830{
8831 if (GetDimension() != 1) {
8832 Error("SetBins","Operation only valid for 1-d histograms");
8833 return;
8834 }
8835 fXaxis.SetRange(0,0);
8836 fXaxis.Set(nx,xBins);
8837 fYaxis.Set(1,0,1);
8838 fZaxis.Set(1,0,1);
8839 fNcells = nx+2;
8841 if (fSumw2.fN) {
8843 }
8844}
8845
8846////////////////////////////////////////////////////////////////////////////////
8847/// Redefine x and y axis parameters.
8848///
8849/// The X and Y axis parameters are modified.
8850/// The bins content array is resized
8851/// if errors (Sumw2) the errors array is resized
8852/// The previous bin contents are lost
8853/// To change only the axis limits, see TAxis::SetRange
8854
8856{
8857 if (GetDimension() != 2) {
8858 Error("SetBins","Operation only valid for 2-D histograms");
8859 return;
8860 }
8861 fXaxis.SetRange(0,0);
8862 fYaxis.SetRange(0,0);
8863 fXaxis.Set(nx,xmin,xmax);
8864 fYaxis.Set(ny,ymin,ymax);
8865 fZaxis.Set(1,0,1);
8866 fNcells = (nx+2)*(ny+2);
8868 if (fSumw2.fN) {
8870 }
8871}
8872
8873////////////////////////////////////////////////////////////////////////////////
8874/// Redefine x and y axis parameters with variable bin sizes.
8875///
8876/// The X and Y axis parameters are modified.
8877/// The bins content array is resized
8878/// if errors (Sumw2) the errors array is resized
8879/// The previous bin contents are lost
8880/// To change only the axis limits, see TAxis::SetRange
8881/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
8882
8883void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
8884{
8885 if (GetDimension() != 2) {
8886 Error("SetBins","Operation only valid for 2-D histograms");
8887 return;
8888 }
8889 fXaxis.SetRange(0,0);
8890 fYaxis.SetRange(0,0);
8891 fXaxis.Set(nx,xBins);
8892 fYaxis.Set(ny,yBins);
8893 fZaxis.Set(1,0,1);
8894 fNcells = (nx+2)*(ny+2);
8896 if (fSumw2.fN) {
8898 }
8899}
8900
8901////////////////////////////////////////////////////////////////////////////////
8902/// Redefine x, y and z axis parameters.
8903///
8904/// The X, Y and Z axis parameters are modified.
8905/// The bins content array is resized
8906/// if errors (Sumw2) the errors array is resized
8907/// The previous bin contents are lost
8908/// To change only the axis limits, see TAxis::SetRange
8909
8911{
8912 if (GetDimension() != 3) {
8913 Error("SetBins","Operation only valid for 3-D histograms");
8914 return;
8915 }
8916 fXaxis.SetRange(0,0);
8917 fYaxis.SetRange(0,0);
8918 fZaxis.SetRange(0,0);
8919 fXaxis.Set(nx,xmin,xmax);
8920 fYaxis.Set(ny,ymin,ymax);
8921 fZaxis.Set(nz,zmin,zmax);
8922 fNcells = (nx+2)*(ny+2)*(nz+2);
8924 if (fSumw2.fN) {
8926 }
8927}
8928
8929////////////////////////////////////////////////////////////////////////////////
8930/// Redefine x, y and z axis parameters with variable bin sizes.
8931///
8932/// The X, Y and Z axis parameters are modified.
8933/// The bins content array is resized
8934/// if errors (Sumw2) the errors array is resized
8935/// The previous bin contents are lost
8936/// To change only the axis limits, see TAxis::SetRange
8937/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
8938/// zBins is supposed to be of length nz+1
8939
8940void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
8941{
8942 if (GetDimension() != 3) {
8943 Error("SetBins","Operation only valid for 3-D histograms");
8944 return;
8945 }
8946 fXaxis.SetRange(0,0);
8947 fYaxis.SetRange(0,0);
8948 fZaxis.SetRange(0,0);
8949 fXaxis.Set(nx,xBins);
8950 fYaxis.Set(ny,yBins);
8951 fZaxis.Set(nz,zBins);
8952 fNcells = (nx+2)*(ny+2)*(nz+2);
8954 if (fSumw2.fN) {
8956 }
8957}
8958
8959////////////////////////////////////////////////////////////////////////////////
8960/// By default, when a histogram is created, it is added to the list
8961/// of histogram objects in the current directory in memory.
8962/// Remove reference to this histogram from current directory and add
8963/// reference to new directory dir. dir can be 0 in which case the
8964/// histogram does not belong to any directory.
8965///
8966/// Note that the directory is not a real property of the histogram and
8967/// it will not be copied when the histogram is copied or cloned.
8968/// If the user wants to have the copied (cloned) histogram in the same
8969/// directory, he needs to set again the directory using SetDirectory to the
8970/// copied histograms
8971
8973{
8974 if (fDirectory == dir) return;
8975 if (fDirectory) fDirectory->Remove(this);
8976 fDirectory = dir;
8977 if (fDirectory) {
8979 fDirectory->Append(this);
8980 }
8981}
8982
8983////////////////////////////////////////////////////////////////////////////////
8984/// Replace bin errors by values in array error.
8985
8986void TH1::SetError(const Double_t *error)
8987{
8988 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
8989}
8990
8991////////////////////////////////////////////////////////////////////////////////
8992/// Change the name of this histogram
8994
8995void TH1::SetName(const char *name)
8996{
8997 // Histograms are named objects in a THashList.
8998 // We must update the hashlist if we change the name
8999 // We protect this operation
9001 if (fDirectory) fDirectory->Remove(this);
9002 fName = name;
9003 if (fDirectory) fDirectory->Append(this);
9004}
9005
9006////////////////////////////////////////////////////////////////////////////////
9007/// Change the name and title of this histogram
9008
9009void TH1::SetNameTitle(const char *name, const char *title)
9010{
9011 // Histograms are named objects in a THashList.
9012 // We must update the hashlist if we change the name
9013 SetName(name);
9014 SetTitle(title);
9015}
9016
9017////////////////////////////////////////////////////////////////////////////////
9018/// Set statistics option on/off.
9019///
9020/// By default, the statistics box is drawn.
9021/// The paint options can be selected via gStyle->SetOptStat.
9022/// This function sets/resets the kNoStats bit in the histogram object.
9023/// It has priority over the Style option.
9024
9025void TH1::SetStats(Bool_t stats)
9026{
9028 if (!stats) {
9030 //remove the "stats" object from the list of functions
9031 if (fFunctions) {
9032 TObject *obj = fFunctions->FindObject("stats");
9033 if (obj) {
9034 fFunctions->Remove(obj);
9035 delete obj;
9036 }
9037 }
9038 }
9039}
9040
9041////////////////////////////////////////////////////////////////////////////////
9042/// Create structure to store sum of squares of weights.
9043///
9044/// if histogram is already filled, the sum of squares of weights
9045/// is filled with the existing bin contents
9046///
9047/// The error per bin will be computed as sqrt(sum of squares of weight)
9048/// for each bin.
9049///
9050/// This function is automatically called when the histogram is created
9051/// if the static function TH1::SetDefaultSumw2 has been called before.
9052/// If flag = false the structure containing the sum of the square of weights
9053/// is rest and it will be empty, but it is not deleted (i.e. GetSumw2()->fN = 0)
9054
9055void TH1::Sumw2(Bool_t flag)
9056{
9057 if (!flag) {
9058 // clear the array if existing - do nothing otherwise
9059 if (fSumw2.fN > 0 ) fSumw2.Set(0);
9060 return;
9061 }
9062
9063 if (fSumw2.fN == fNcells) {
9064 if (!fgDefaultSumw2 )
9065 Warning("Sumw2","Sum of squares of weights structure already created");
9066 return;
9067 }
9068
9070
9071 // empty the buffer
9072 if (fBuffer) BufferEmpty();
9073
9074 if (fEntries > 0)
9075 for (Int_t i = 0; i < fNcells; ++i)
9077}
9078
9079////////////////////////////////////////////////////////////////////////////////
9080/// Return pointer to function with name.
9081///
9082///
9083/// Functions such as TH1::Fit store the fitted function in the list of
9084/// functions of this histogram.
9085
9086TF1 *TH1::GetFunction(const char *name) const
9087{
9088 return (TF1*)fFunctions->FindObject(name);
9089}
9090
9091////////////////////////////////////////////////////////////////////////////////
9092/// Return value of error associated to bin number bin.
9093///
9094/// if the sum of squares of weights has been defined (via Sumw2),
9095/// this function returns the sqrt(sum of w2).
9096/// otherwise it returns the sqrt(contents) for this bin.
9097
9099{
9100 if (bin < 0) bin = 0;
9101 if (bin >= fNcells) bin = fNcells-1;
9102 if (fBuffer) ((TH1*)this)->BufferEmpty();
9103 if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
9104
9106}
9107
9108////////////////////////////////////////////////////////////////////////////////
9109/// Return lower error associated to bin number bin.
9110///
9111/// The error will depend on the statistic option used will return
9112/// the binContent - lower interval value
9113
9115{
9116 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9117 // in case of weighted histogram check if it is really weighted
9118 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9119
9120 if (bin < 0) bin = 0;
9121 if (bin >= fNcells) bin = fNcells-1;
9122 if (fBuffer) ((TH1*)this)->BufferEmpty();
9123
9124 Double_t alpha = 1.- 0.682689492;
9125 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9126
9128 Int_t n = int(c);
9129 if (n < 0) {
9130 Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
9131 ((TH1*)this)->fBinStatErrOpt = kNormal;
9132 return GetBinError(bin);
9133 }
9134
9135 if (n == 0) return 0;
9136 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
9137}
9138
9139////////////////////////////////////////////////////////////////////////////////
9140/// Return upper error associated to bin number bin.
9141///
9142/// The error will depend on the statistic option used will return
9143/// the binContent - upper interval value
9144
9146{
9147 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9148 // in case of weighted histogram check if it is really weighted
9149 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9150 if (bin < 0) bin = 0;
9151 if (bin >= fNcells) bin = fNcells-1;
9152 if (fBuffer) ((TH1*)this)->BufferEmpty();
9153
9154 Double_t alpha = 1.- 0.682689492;
9155 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9156
9158 Int_t n = int(c);
9159 if (n < 0) {
9160 Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
9161 ((TH1*)this)->fBinStatErrOpt = kNormal;
9162 return GetBinError(bin);
9163 }
9164
9165 // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
9166 // decide to return always (1-alpha)/2 upper interval
9167 //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
9168 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
9169}
9170
9171//L.M. These following getters are useless and should be probably deprecated
9172////////////////////////////////////////////////////////////////////////////////
9173/// Return bin center for 1D histogram.
9174/// Better to use h1.GetXaxis()->GetBinCenter(bin)
9175
9177{
9178 if (fDimension == 1) return fXaxis.GetBinCenter(bin);
9179 Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
9180 return TMath::QuietNaN();
9181}
9182
9183////////////////////////////////////////////////////////////////////////////////
9184/// Return bin lower edge for 1D histogram.
9185/// Better to use h1.GetXaxis()->GetBinLowEdge(bin)
9186
9188{
9189 if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
9190 Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
9191 return TMath::QuietNaN();
9192}
9193
9194////////////////////////////////////////////////////////////////////////////////
9195/// Return bin width for 1D histogram.
9196/// Better to use h1.GetXaxis()->GetBinWidth(bin)
9197
9199{
9200 if (fDimension == 1) return fXaxis.GetBinWidth(bin);
9201 Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
9202 return TMath::QuietNaN();
9203}
9204
9205////////////////////////////////////////////////////////////////////////////////
9206/// Fill array with center of bins for 1D histogram
9207/// Better to use h1.GetXaxis()->GetCenter(center)
9208
9209void TH1::GetCenter(Double_t *center) const
9210{
9211 if (fDimension == 1) {
9212 fXaxis.GetCenter(center);
9213 return;
9214 }
9215 Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
9216}
9217
9218////////////////////////////////////////////////////////////////////////////////
9219/// Fill array with low edge of bins for 1D histogram
9220/// Better to use h1.GetXaxis()->GetLowEdge(edge)
9221
9222void TH1::GetLowEdge(Double_t *edge) const
9223{
9224 if (fDimension == 1) {
9225 fXaxis.GetLowEdge(edge);
9226 return;
9227 }
9228 Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
9229}
9230
9231////////////////////////////////////////////////////////////////////////////////
9232/// Set the bin Error
9233/// Note that this resets the bin eror option to be of Normal Type and for the
9234/// non-empty bin the bin error is set by default to the square root of their content.
9235/// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
9236/// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
9237/// will not be recalculated after setting the content and a default error = 0 will be used for those bins.
9238///
9239/// See convention for numbering bins in TH1::GetBin
9240
9241void TH1::SetBinError(Int_t bin, Double_t error)
9242{
9243 if (bin < 0 || bin>= fNcells) return;
9244 if (!fSumw2.fN) Sumw2();
9245 fSumw2.fArray[bin] = error * error;
9246 // reset the bin error option
9248}
9249
9250////////////////////////////////////////////////////////////////////////////////
9251/// Set bin content
9252/// see convention for numbering bins in TH1::GetBin
9253/// In case the bin number is greater than the number of bins and
9254/// the timedisplay option is set or CanExtendAllAxes(),
9255/// the number of bins is automatically doubled to accommodate the new bin
9256
9257void TH1::SetBinContent(Int_t bin, Double_t content)
9258{
9259 fEntries++;
9260 fTsumw = 0;
9261 if (bin < 0) return;
9262 if (bin >= fNcells-1) {
9264 while (bin >= fNcells-1) LabelsInflate();
9265 } else {
9266 if (bin == fNcells-1) UpdateBinContent(bin, content);
9267 return;
9268 }
9269 }
9270 UpdateBinContent(bin, content);
9271}
9272
9273////////////////////////////////////////////////////////////////////////////////
9274/// See convention for numbering bins in TH1::GetBin
9275
9276void TH1::SetBinError(Int_t binx, Int_t biny, Double_t error)
9277{
9278 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9279 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9280 SetBinError(GetBin(binx, biny), error);
9281}
9282
9283////////////////////////////////////////////////////////////////////////////////
9284/// See convention for numbering bins in TH1::GetBin
9285
9286void TH1::SetBinError(Int_t binx, Int_t biny, Int_t binz, Double_t error)
9287{
9288 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9289 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9290 if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
9291 SetBinError(GetBin(binx, biny, binz), error);
9292}
9293
9294////////////////////////////////////////////////////////////////////////////////
9295/// This function calculates the background spectrum in this histogram.
9296/// The background is returned as a histogram.
9297///
9298/// \param[in] niter number of iterations (default value = 2)
9299/// Increasing niter make the result smoother and lower.
9300/// \param[in] option may contain one of the following options
9301/// - to set the direction parameter
9302/// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
9303/// - filterOrder-order of clipping filter (default "BackOrder2")
9304/// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
9305/// - "nosmoothing" - if selected, the background is not smoothed
9306/// By default the background is smoothed.
9307/// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
9308/// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
9309/// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
9310/// - "nocompton" - if selected the estimation of Compton edge
9311/// will be not be included (by default the compton estimation is set)
9312/// - "same" if this option is specified, the resulting background
9313/// histogram is superimposed on the picture in the current pad.
9314/// This option is given by default.
9315///
9316/// NOTE that the background is only evaluated in the current range of this histogram.
9317/// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
9318/// the returned histogram will be created with the same number of bins
9319/// as this input histogram, but only bins from binmin to binmax will be filled
9320/// with the estimated background.
9321
9323{
9324 return (TH1*)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticBackground((TH1*)0x%zx,%d,\"%s\")",
9325 (size_t)this, niter, option).Data());
9326}
9327
9328////////////////////////////////////////////////////////////////////////////////
9329/// Interface to TSpectrum::Search.
9330/// The function finds peaks in this histogram where the width is > sigma
9331/// and the peak maximum greater than threshold*maximum bin content of this.
9332/// For more details see TSpectrum::Search.
9333/// Note the difference in the default value for option compared to TSpectrum::Search
9334/// option="" by default (instead of "goff").
9335
9337{
9338 return (Int_t)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticSearch((TH1*)0x%zx,%g,\"%s\",%g)",
9339 (size_t)this, sigma, option, threshold).Data());
9340}
9341
9342////////////////////////////////////////////////////////////////////////////////
9343/// For a given transform (first parameter), fills the histogram (second parameter)
9344/// with the transform output data, specified in the third parameter
9345/// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
9346/// and the user is responsible for deleting it.
9347///
9348/// Available options:
9349/// - "RE" - real part of the output
9350/// - "IM" - imaginary part of the output
9351/// - "MAG" - magnitude of the output
9352/// - "PH" - phase of the output
9353
9355{
9356 if (!fft || !fft->GetN() ) {
9357 ::Error("TransformHisto","Invalid FFT transform class");
9358 return nullptr;
9359 }
9360
9361 if (fft->GetNdim()>2){
9362 ::Error("TransformHisto","Only 1d and 2D transform are supported");
9363 return nullptr;
9364 }
9365 Int_t binx,biny;
9366 TString opt = option;
9367 opt.ToUpper();
9368 Int_t *n = fft->GetN();
9369 TH1 *hout=nullptr;
9370 if (h_output) {
9371 hout = h_output;
9372 }
9373 else {
9374 TString name = TString::Format("out_%s", opt.Data());
9375 if (fft->GetNdim()==1)
9376 hout = new TH1D(name, name,n[0], 0, n[0]);
9377 else if (fft->GetNdim()==2)
9378 hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
9379 }
9380 R__ASSERT(hout != nullptr);
9381 TString type=fft->GetType();
9382 Int_t ind[2];
9383 if (opt.Contains("RE")){
9384 if (type.Contains("2C") || type.Contains("2HC")) {
9385 Double_t re, im;
9386 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9387 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9388 ind[0] = binx-1; ind[1] = biny-1;
9389 fft->GetPointComplex(ind, re, im);
9390 hout->SetBinContent(binx, biny, re);
9391 }
9392 }
9393 } else {
9394 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9395 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9396 ind[0] = binx-1; ind[1] = biny-1;
9397 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
9398 }
9399 }
9400 }
9401 }
9402 if (opt.Contains("IM")) {
9403 if (type.Contains("2C") || type.Contains("2HC")) {
9404 Double_t re, im;
9405 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9406 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9407 ind[0] = binx-1; ind[1] = biny-1;
9408 fft->GetPointComplex(ind, re, im);
9409 hout->SetBinContent(binx, biny, im);
9410 }
9411 }
9412 } else {
9413 ::Error("TransformHisto","No complex numbers in the output");
9414 return nullptr;
9415 }
9416 }
9417 if (opt.Contains("MA")) {
9418 if (type.Contains("2C") || type.Contains("2HC")) {
9419 Double_t re, im;
9420 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9421 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9422 ind[0] = binx-1; ind[1] = biny-1;
9423 fft->GetPointComplex(ind, re, im);
9424 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
9425 }
9426 }
9427 } else {
9428 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9429 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9430 ind[0] = binx-1; ind[1] = biny-1;
9431 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
9432 }
9433 }
9434 }
9435 }
9436 if (opt.Contains("PH")) {
9437 if (type.Contains("2C") || type.Contains("2HC")){
9438 Double_t re, im, ph;
9439 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
9440 for (biny=1; biny<=hout->GetNbinsY(); biny++){
9441 ind[0] = binx-1; ind[1] = biny-1;
9442 fft->GetPointComplex(ind, re, im);
9443 if (TMath::Abs(re) > 1e-13){
9444 ph = TMath::ATan(im/re);
9445 //find the correct quadrant
9446 if (re<0 && im<0)
9447 ph -= TMath::Pi();
9448 if (re<0 && im>=0)
9449 ph += TMath::Pi();
9450 } else {
9451 if (TMath::Abs(im) < 1e-13)
9452 ph = 0;
9453 else if (im>0)
9454 ph = TMath::Pi()*0.5;
9455 else
9456 ph = -TMath::Pi()*0.5;
9457 }
9458 hout->SetBinContent(binx, biny, ph);
9459 }
9460 }
9461 } else {
9462 printf("Pure real output, no phase");
9463 return nullptr;
9464 }
9465 }
9466
9467 return hout;
9468}
9469
9470////////////////////////////////////////////////////////////////////////////////
9471/// Raw retrieval of bin content on internal data structure
9472/// see convention for numbering bins in TH1::GetBin
9473
9475{
9476 AbstractMethod("RetrieveBinContent");
9477 return 0;
9478}
9479
9480////////////////////////////////////////////////////////////////////////////////
9481/// Raw update of bin content on internal data structure
9482/// see convention for numbering bins in TH1::GetBin
9483
9485{
9486 AbstractMethod("UpdateBinContent");
9487}
9488
9489////////////////////////////////////////////////////////////////////////////////
9490/// Print value overload
9491
9492std::string cling::printValue(TH1 *val) {
9493 std::ostringstream strm;
9494 strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
9495 return strm.str();
9496}
9497
9498//______________________________________________________________________________
9499// TH1C methods
9500// TH1C : histograms with one byte per channel. Maximum bin content = 127
9501//______________________________________________________________________________
9502
9503ClassImp(TH1C);
9504
9505////////////////////////////////////////////////////////////////////////////////
9506/// Constructor.
9507
9508TH1C::TH1C()
9509{
9510 fDimension = 1;
9511 SetBinsLength(3);
9512 if (fgDefaultSumw2) Sumw2();
9513}
9514
9515////////////////////////////////////////////////////////////////////////////////
9516/// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
9517/// (see TH1::TH1 for explanation of parameters)
9518
9519TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9520: TH1(name,title,nbins,xlow,xup)
9521{
9522 fDimension = 1;
9524
9525 if (xlow >= xup) SetBuffer(fgBufferSize);
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 Float_t *xbins)
9534: TH1(name,title,nbins,xbins)
9535{
9536 fDimension = 1;
9538 if (fgDefaultSumw2) Sumw2();
9539}
9540
9541////////////////////////////////////////////////////////////////////////////////
9542/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9543/// (see TH1::TH1 for explanation of parameters)
9544
9545TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9546: TH1(name,title,nbins,xbins)
9547{
9548 fDimension = 1;
9550 if (fgDefaultSumw2) Sumw2();
9551}
9552
9553////////////////////////////////////////////////////////////////////////////////
9554/// Destructor.
9555
9557{
9558}
9559
9560////////////////////////////////////////////////////////////////////////////////
9561/// Copy constructor.
9562/// The list of functions is not copied. (Use Clone() if needed)
9563
9564TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
9565{
9566 h1c.TH1C::Copy(*this);
9567}
9568
9569////////////////////////////////////////////////////////////////////////////////
9570/// Increment bin content by 1.
9571/// Passing an out-of-range bin leads to undefined behavior
9572
9573void TH1C::AddBinContent(Int_t bin)
9574{
9575 if (fArray[bin] < 127) fArray[bin]++;
9576}
9577
9578////////////////////////////////////////////////////////////////////////////////
9579/// Increment bin content by w.
9580/// \warning The value of w is cast to `Int_t` before being added.
9581/// Passing an out-of-range bin leads to undefined behavior
9582
9584{
9585 Int_t newval = fArray[bin] + Int_t(w);
9586 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
9587 if (newval < -127) fArray[bin] = -127;
9588 if (newval > 127) fArray[bin] = 127;
9589}
9590
9591////////////////////////////////////////////////////////////////////////////////
9592/// Copy this to newth1
9593
9594void TH1C::Copy(TObject &newth1) const
9595{
9596 TH1::Copy(newth1);
9597}
9598
9599////////////////////////////////////////////////////////////////////////////////
9600/// Reset.
9601
9603{
9606}
9607
9608////////////////////////////////////////////////////////////////////////////////
9609/// Set total number of bins including under/overflow
9610/// Reallocate bin contents array
9611
9613{
9614 if (n < 0) n = fXaxis.GetNbins() + 2;
9615 fNcells = n;
9616 TArrayC::Set(n);
9617}
9618
9619////////////////////////////////////////////////////////////////////////////////
9620/// Operator =
9621
9622TH1C& TH1C::operator=(const TH1C &h1)
9623{
9624 if (this != &h1)
9625 h1.TH1C::Copy(*this);
9626 return *this;
9627}
9628
9629////////////////////////////////////////////////////////////////////////////////
9630/// Operator *
9631
9633{
9634 TH1C hnew = h1;
9635 hnew.Scale(c1);
9636 hnew.SetDirectory(nullptr);
9637 return hnew;
9638}
9639
9640////////////////////////////////////////////////////////////////////////////////
9641/// Operator +
9642
9643TH1C operator+(const TH1C &h1, const TH1C &h2)
9644{
9645 TH1C hnew = h1;
9646 hnew.Add(&h2,1);
9647 hnew.SetDirectory(nullptr);
9648 return hnew;
9649}
9650
9651////////////////////////////////////////////////////////////////////////////////
9652/// Operator -
9653
9654TH1C operator-(const TH1C &h1, const TH1C &h2)
9655{
9656 TH1C hnew = h1;
9657 hnew.Add(&h2,-1);
9658 hnew.SetDirectory(nullptr);
9659 return hnew;
9660}
9661
9662////////////////////////////////////////////////////////////////////////////////
9663/// Operator *
9664
9665TH1C operator*(const TH1C &h1, const TH1C &h2)
9666{
9667 TH1C hnew = h1;
9668 hnew.Multiply(&h2);
9669 hnew.SetDirectory(nullptr);
9670 return hnew;
9671}
9672
9673////////////////////////////////////////////////////////////////////////////////
9674/// Operator /
9675
9676TH1C operator/(const TH1C &h1, const TH1C &h2)
9677{
9678 TH1C hnew = h1;
9679 hnew.Divide(&h2);
9680 hnew.SetDirectory(nullptr);
9681 return hnew;
9682}
9683
9684//______________________________________________________________________________
9685// TH1S methods
9686// TH1S : histograms with one short per channel. Maximum bin content = 32767
9687//______________________________________________________________________________
9688
9689ClassImp(TH1S);
9690
9691////////////////////////////////////////////////////////////////////////////////
9692/// Constructor.
9693
9694TH1S::TH1S()
9695{
9696 fDimension = 1;
9697 SetBinsLength(3);
9698 if (fgDefaultSumw2) Sumw2();
9699}
9700
9701////////////////////////////////////////////////////////////////////////////////
9702/// Create a 1-Dim histogram with fix bins of type short
9703/// (see TH1::TH1 for explanation of parameters)
9704
9705TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9706: TH1(name,title,nbins,xlow,xup)
9707{
9708 fDimension = 1;
9710
9711 if (xlow >= xup) SetBuffer(fgBufferSize);
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 Float_t *xbins)
9720: TH1(name,title,nbins,xbins)
9721{
9722 fDimension = 1;
9724 if (fgDefaultSumw2) Sumw2();
9725}
9726
9727////////////////////////////////////////////////////////////////////////////////
9728/// Create a 1-Dim histogram with variable bins of type short
9729/// (see TH1::TH1 for explanation of parameters)
9730
9731TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9732: TH1(name,title,nbins,xbins)
9733{
9734 fDimension = 1;
9736 if (fgDefaultSumw2) Sumw2();
9737}
9738
9739////////////////////////////////////////////////////////////////////////////////
9740/// Destructor.
9741
9743{
9744}
9745
9746////////////////////////////////////////////////////////////////////////////////
9747/// Copy constructor.
9748/// The list of functions is not copied. (Use Clone() if needed)
9749
9750TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9751{
9752 h1s.TH1S::Copy(*this);
9753}
9754
9755////////////////////////////////////////////////////////////////////////////////
9756/// Increment bin content by 1.
9757/// Passing an out-of-range bin leads to undefined behavior
9758
9759void TH1S::AddBinContent(Int_t bin)
9760{
9761 if (fArray[bin] < 32767) fArray[bin]++;
9762}
9763
9764////////////////////////////////////////////////////////////////////////////////
9765/// Increment bin content by w.
9766/// \warning The value of w is cast to `Int_t` before being added.
9767/// Passing an out-of-range bin leads to undefined behavior
9768
9770{
9771 Int_t newval = fArray[bin] + Int_t(w);
9772 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9773 if (newval < -32767) fArray[bin] = -32767;
9774 if (newval > 32767) fArray[bin] = 32767;
9775}
9776
9777////////////////////////////////////////////////////////////////////////////////
9778/// Copy this to newth1
9779
9780void TH1S::Copy(TObject &newth1) const
9781{
9782 TH1::Copy(newth1);
9783}
9784
9785////////////////////////////////////////////////////////////////////////////////
9786/// Reset.
9787
9789{
9792}
9793
9794////////////////////////////////////////////////////////////////////////////////
9795/// Set total number of bins including under/overflow
9796/// Reallocate bin contents array
9797
9799{
9800 if (n < 0) n = fXaxis.GetNbins() + 2;
9801 fNcells = n;
9802 TArrayS::Set(n);
9803}
9804
9805////////////////////////////////////////////////////////////////////////////////
9806/// Operator =
9807
9808TH1S& TH1S::operator=(const TH1S &h1)
9809{
9810 if (this != &h1)
9811 h1.TH1S::Copy(*this);
9812 return *this;
9813}
9814
9815////////////////////////////////////////////////////////////////////////////////
9816/// Operator *
9817
9819{
9820 TH1S hnew = h1;
9821 hnew.Scale(c1);
9822 hnew.SetDirectory(nullptr);
9823 return hnew;
9824}
9825
9826////////////////////////////////////////////////////////////////////////////////
9827/// Operator +
9828
9829TH1S operator+(const TH1S &h1, const TH1S &h2)
9830{
9831 TH1S hnew = h1;
9832 hnew.Add(&h2,1);
9833 hnew.SetDirectory(nullptr);
9834 return hnew;
9835}
9836
9837////////////////////////////////////////////////////////////////////////////////
9838/// Operator -
9839
9840TH1S operator-(const TH1S &h1, const TH1S &h2)
9841{
9842 TH1S hnew = h1;
9843 hnew.Add(&h2,-1);
9844 hnew.SetDirectory(nullptr);
9845 return hnew;
9846}
9847
9848////////////////////////////////////////////////////////////////////////////////
9849/// Operator *
9850
9851TH1S operator*(const TH1S &h1, const TH1S &h2)
9852{
9853 TH1S hnew = h1;
9854 hnew.Multiply(&h2);
9855 hnew.SetDirectory(nullptr);
9856 return hnew;
9857}
9858
9859////////////////////////////////////////////////////////////////////////////////
9860/// Operator /
9861
9862TH1S operator/(const TH1S &h1, const TH1S &h2)
9863{
9864 TH1S hnew = h1;
9865 hnew.Divide(&h2);
9866 hnew.SetDirectory(nullptr);
9867 return hnew;
9868}
9869
9870//______________________________________________________________________________
9871// TH1I methods
9872// TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9873// 2147483647 = INT_MAX
9874//______________________________________________________________________________
9875
9876ClassImp(TH1I);
9877
9878////////////////////////////////////////////////////////////////////////////////
9879/// Constructor.
9880
9881TH1I::TH1I()
9882{
9883 fDimension = 1;
9884 SetBinsLength(3);
9885 if (fgDefaultSumw2) Sumw2();
9886}
9887
9888////////////////////////////////////////////////////////////////////////////////
9889/// Create a 1-Dim histogram with fix bins of type integer
9890/// (see TH1::TH1 for explanation of parameters)
9891
9892TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9893: TH1(name,title,nbins,xlow,xup)
9894{
9895 fDimension = 1;
9897
9898 if (xlow >= xup) SetBuffer(fgBufferSize);
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 Float_t *xbins)
9907: TH1(name,title,nbins,xbins)
9908{
9909 fDimension = 1;
9911 if (fgDefaultSumw2) Sumw2();
9912}
9913
9914////////////////////////////////////////////////////////////////////////////////
9915/// Create a 1-Dim histogram with variable bins of type integer
9916/// (see TH1::TH1 for explanation of parameters)
9917
9918TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9919: TH1(name,title,nbins,xbins)
9920{
9921 fDimension = 1;
9923 if (fgDefaultSumw2) Sumw2();
9924}
9925
9926////////////////////////////////////////////////////////////////////////////////
9927/// Destructor.
9928
9930{
9931}
9932
9933////////////////////////////////////////////////////////////////////////////////
9934/// Copy constructor.
9935/// The list of functions is not copied. (Use Clone() if needed)
9936
9937TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
9938{
9939 h1i.TH1I::Copy(*this);
9940}
9941
9942////////////////////////////////////////////////////////////////////////////////
9943/// Increment bin content by 1.
9944/// Passing an out-of-range bin leads to undefined behavior
9945
9946void TH1I::AddBinContent(Int_t bin)
9947{
9948 if (fArray[bin] < INT_MAX) fArray[bin]++;
9949}
9950
9951////////////////////////////////////////////////////////////////////////////////
9952/// Increment bin content by w
9953/// \warning The value of w is cast to `Long64_t` before being added.
9954/// Passing an out-of-range bin leads to undefined behavior
9955
9957{
9958 Long64_t newval = fArray[bin] + Long64_t(w);
9959 if (newval > -INT_MAX && newval < INT_MAX) {fArray[bin] = Int_t(newval); return;}
9960 if (newval < -INT_MAX) fArray[bin] = -INT_MAX;
9961 if (newval > INT_MAX) fArray[bin] = INT_MAX;
9962}
9963
9964////////////////////////////////////////////////////////////////////////////////
9965/// Copy this to newth1
9966
9967void TH1I::Copy(TObject &newth1) const
9968{
9969 TH1::Copy(newth1);
9970}
9971
9972////////////////////////////////////////////////////////////////////////////////
9973/// Reset.
9974
9976{
9979}
9980
9981////////////////////////////////////////////////////////////////////////////////
9982/// Set total number of bins including under/overflow
9983/// Reallocate bin contents array
9984
9986{
9987 if (n < 0) n = fXaxis.GetNbins() + 2;
9988 fNcells = n;
9989 TArrayI::Set(n);
9990}
9991
9992////////////////////////////////////////////////////////////////////////////////
9993/// Operator =
9994
9995TH1I& TH1I::operator=(const TH1I &h1)
9996{
9997 if (this != &h1)
9998 h1.TH1I::Copy(*this);
9999 return *this;
10000}
10001
10002
10003////////////////////////////////////////////////////////////////////////////////
10004/// Operator *
10005
10007{
10008 TH1I hnew = h1;
10009 hnew.Scale(c1);
10010 hnew.SetDirectory(nullptr);
10011 return hnew;
10012}
10013
10014////////////////////////////////////////////////////////////////////////////////
10015/// Operator +
10016
10017TH1I operator+(const TH1I &h1, const TH1I &h2)
10018{
10019 TH1I hnew = h1;
10020 hnew.Add(&h2,1);
10021 hnew.SetDirectory(nullptr);
10022 return hnew;
10023}
10024
10025////////////////////////////////////////////////////////////////////////////////
10026/// Operator -
10027
10028TH1I operator-(const TH1I &h1, const TH1I &h2)
10029{
10030 TH1I hnew = h1;
10031 hnew.Add(&h2,-1);
10032 hnew.SetDirectory(nullptr);
10033 return hnew;
10034}
10035
10036////////////////////////////////////////////////////////////////////////////////
10037/// Operator *
10038
10039TH1I operator*(const TH1I &h1, const TH1I &h2)
10040{
10041 TH1I hnew = h1;
10042 hnew.Multiply(&h2);
10043 hnew.SetDirectory(nullptr);
10044 return hnew;
10045}
10046
10047////////////////////////////////////////////////////////////////////////////////
10048/// Operator /
10049
10050TH1I operator/(const TH1I &h1, const TH1I &h2)
10051{
10052 TH1I hnew = h1;
10053 hnew.Divide(&h2);
10054 hnew.SetDirectory(nullptr);
10055 return hnew;
10056}
10057
10058//______________________________________________________________________________
10059// TH1L methods
10060// TH1L : histograms with one long64 per channel. Maximum bin content = 9223372036854775807
10061// 9223372036854775807 = LLONG_MAX
10062//______________________________________________________________________________
10063
10064ClassImp(TH1L);
10065
10066////////////////////////////////////////////////////////////////////////////////
10067/// Constructor.
10068
10069TH1L::TH1L()
10070{
10071 fDimension = 1;
10072 SetBinsLength(3);
10073 if (fgDefaultSumw2) Sumw2();
10074}
10075
10076////////////////////////////////////////////////////////////////////////////////
10077/// Create a 1-Dim histogram with fix bins of type long64
10078/// (see TH1::TH1 for explanation of parameters)
10079
10080TH1L::TH1L(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10081: TH1(name,title,nbins,xlow,xup)
10082{
10083 fDimension = 1;
10085
10086 if (xlow >= xup) SetBuffer(fgBufferSize);
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 Float_t *xbins)
10095: TH1(name,title,nbins,xbins)
10096{
10097 fDimension = 1;
10099 if (fgDefaultSumw2) Sumw2();
10100}
10101
10102////////////////////////////////////////////////////////////////////////////////
10103/// Create a 1-Dim histogram with variable bins of type long64
10104/// (see TH1::TH1 for explanation of parameters)
10105
10106TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10107: TH1(name,title,nbins,xbins)
10108{
10109 fDimension = 1;
10111 if (fgDefaultSumw2) Sumw2();
10112}
10113
10114////////////////////////////////////////////////////////////////////////////////
10115/// Destructor.
10116
10118{
10119}
10120
10121////////////////////////////////////////////////////////////////////////////////
10122/// Copy constructor.
10123/// The list of functions is not copied. (Use Clone() if needed)
10124
10125TH1L::TH1L(const TH1L &h1l) : TH1(), TArrayL64()
10126{
10127 h1l.TH1L::Copy(*this);
10128}
10129
10130////////////////////////////////////////////////////////////////////////////////
10131/// Increment bin content by 1.
10132/// Passing an out-of-range bin leads to undefined behavior
10133
10134void TH1L::AddBinContent(Int_t bin)
10135{
10136 if (fArray[bin] < LLONG_MAX) fArray[bin]++;
10137}
10138
10139////////////////////////////////////////////////////////////////////////////////
10140/// Increment bin content by w.
10141/// \warning The value of w is cast to `Long64_t` before being added.
10142/// Passing an out-of-range bin leads to undefined behavior
10143
10145{
10146 Long64_t newval = fArray[bin] + Long64_t(w);
10147 if (newval > -LLONG_MAX && newval < LLONG_MAX) {fArray[bin] = newval; return;}
10148 if (newval < -LLONG_MAX) fArray[bin] = -LLONG_MAX;
10149 if (newval > LLONG_MAX) fArray[bin] = LLONG_MAX;
10150}
10151
10152////////////////////////////////////////////////////////////////////////////////
10153/// Copy this to newth1
10154
10155void TH1L::Copy(TObject &newth1) const
10156{
10157 TH1::Copy(newth1);
10158}
10159
10160////////////////////////////////////////////////////////////////////////////////
10161/// Reset.
10162
10164{
10167}
10168
10169////////////////////////////////////////////////////////////////////////////////
10170/// Set total number of bins including under/overflow
10171/// Reallocate bin contents array
10172
10174{
10175 if (n < 0) n = fXaxis.GetNbins() + 2;
10176 fNcells = n;
10178}
10179
10180////////////////////////////////////////////////////////////////////////////////
10181/// Operator =
10182
10183TH1L& TH1L::operator=(const TH1L &h1)
10184{
10185 if (this != &h1)
10186 h1.TH1L::Copy(*this);
10187 return *this;
10188}
10189
10190
10191////////////////////////////////////////////////////////////////////////////////
10192/// Operator *
10193
10195{
10196 TH1L hnew = h1;
10197 hnew.Scale(c1);
10198 hnew.SetDirectory(nullptr);
10199 return hnew;
10200}
10201
10202////////////////////////////////////////////////////////////////////////////////
10203/// Operator +
10204
10205TH1L operator+(const TH1L &h1, const TH1L &h2)
10206{
10207 TH1L hnew = h1;
10208 hnew.Add(&h2,1);
10209 hnew.SetDirectory(nullptr);
10210 return hnew;
10211}
10212
10213////////////////////////////////////////////////////////////////////////////////
10214/// Operator -
10215
10216TH1L operator-(const TH1L &h1, const TH1L &h2)
10217{
10218 TH1L hnew = h1;
10219 hnew.Add(&h2,-1);
10220 hnew.SetDirectory(nullptr);
10221 return hnew;
10222}
10223
10224////////////////////////////////////////////////////////////////////////////////
10225/// Operator *
10226
10227TH1L operator*(const TH1L &h1, const TH1L &h2)
10228{
10229 TH1L hnew = h1;
10230 hnew.Multiply(&h2);
10231 hnew.SetDirectory(nullptr);
10232 return hnew;
10233}
10234
10235////////////////////////////////////////////////////////////////////////////////
10236/// Operator /
10237
10238TH1L operator/(const TH1L &h1, const TH1L &h2)
10239{
10240 TH1L hnew = h1;
10241 hnew.Divide(&h2);
10242 hnew.SetDirectory(nullptr);
10243 return hnew;
10244}
10245
10246//______________________________________________________________________________
10247// TH1F methods
10248// TH1F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216
10249//______________________________________________________________________________
10250
10251ClassImp(TH1F);
10252
10253////////////////////////////////////////////////////////////////////////////////
10254/// Constructor.
10255
10256TH1F::TH1F()
10257{
10258 fDimension = 1;
10259 SetBinsLength(3);
10260 if (fgDefaultSumw2) Sumw2();
10261}
10262
10263////////////////////////////////////////////////////////////////////////////////
10264/// Create a 1-Dim histogram with fix bins of type float
10265/// (see TH1::TH1 for explanation of parameters)
10266
10267TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10268: TH1(name,title,nbins,xlow,xup)
10269{
10270 fDimension = 1;
10272
10273 if (xlow >= xup) SetBuffer(fgBufferSize);
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 Float_t *xbins)
10282: TH1(name,title,nbins,xbins)
10283{
10284 fDimension = 1;
10286 if (fgDefaultSumw2) Sumw2();
10287}
10288
10289////////////////////////////////////////////////////////////////////////////////
10290/// Create a 1-Dim histogram with variable bins of type float
10291/// (see TH1::TH1 for explanation of parameters)
10292
10293TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10294: TH1(name,title,nbins,xbins)
10295{
10296 fDimension = 1;
10298 if (fgDefaultSumw2) Sumw2();
10299}
10300
10301////////////////////////////////////////////////////////////////////////////////
10302/// Create a histogram from a TVectorF
10303/// by default the histogram name is "TVectorF" and title = ""
10304
10305TH1F::TH1F(const TVectorF &v)
10306: TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
10307{
10309 fDimension = 1;
10310 Int_t ivlow = v.GetLwb();
10311 for (Int_t i=0;i<fNcells-2;i++) {
10312 SetBinContent(i+1,v(i+ivlow));
10313 }
10315 if (fgDefaultSumw2) Sumw2();
10316}
10317
10318////////////////////////////////////////////////////////////////////////////////
10319/// Copy Constructor.
10320/// The list of functions is not copied. (Use Clone() if needed)
10321
10322TH1F::TH1F(const TH1F &h1f) : TH1(), TArrayF()
10323{
10324 h1f.TH1F::Copy(*this);
10325}
10326
10327////////////////////////////////////////////////////////////////////////////////
10328/// Destructor.
10329
10331{
10332}
10333
10334////////////////////////////////////////////////////////////////////////////////
10335/// Copy this to newth1.
10336
10337void TH1F::Copy(TObject &newth1) const
10338{
10339 TH1::Copy(newth1);
10340}
10341
10342////////////////////////////////////////////////////////////////////////////////
10343/// Reset.
10344
10346{
10349}
10350
10351////////////////////////////////////////////////////////////////////////////////
10352/// Set total number of bins including under/overflow
10353/// Reallocate bin contents array
10354
10356{
10357 if (n < 0) n = fXaxis.GetNbins() + 2;
10358 fNcells = n;
10359 TArrayF::Set(n);
10360}
10361
10362////////////////////////////////////////////////////////////////////////////////
10363/// Operator =
10364
10365TH1F& TH1F::operator=(const TH1F &h1f)
10366{
10367 if (this != &h1f)
10368 h1f.TH1F::Copy(*this);
10369 return *this;
10370}
10371
10372////////////////////////////////////////////////////////////////////////////////
10373/// Operator *
10374
10376{
10377 TH1F hnew = h1;
10378 hnew.Scale(c1);
10379 hnew.SetDirectory(nullptr);
10380 return hnew;
10381}
10382
10383////////////////////////////////////////////////////////////////////////////////
10384/// Operator +
10385
10386TH1F operator+(const TH1F &h1, const TH1F &h2)
10387{
10388 TH1F hnew = h1;
10389 hnew.Add(&h2,1);
10390 hnew.SetDirectory(nullptr);
10391 return hnew;
10392}
10393
10394////////////////////////////////////////////////////////////////////////////////
10395/// Operator -
10396
10397TH1F operator-(const TH1F &h1, const TH1F &h2)
10398{
10399 TH1F hnew = h1;
10400 hnew.Add(&h2,-1);
10401 hnew.SetDirectory(nullptr);
10402 return hnew;
10403}
10404
10405////////////////////////////////////////////////////////////////////////////////
10406/// Operator *
10407
10408TH1F operator*(const TH1F &h1, const TH1F &h2)
10409{
10410 TH1F hnew = h1;
10411 hnew.Multiply(&h2);
10412 hnew.SetDirectory(nullptr);
10413 return hnew;
10414}
10415
10416////////////////////////////////////////////////////////////////////////////////
10417/// Operator /
10418
10419TH1F operator/(const TH1F &h1, const TH1F &h2)
10420{
10421 TH1F hnew = h1;
10422 hnew.Divide(&h2);
10423 hnew.SetDirectory(nullptr);
10424 return hnew;
10425}
10426
10427//______________________________________________________________________________
10428// TH1D methods
10429// TH1D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992
10430//______________________________________________________________________________
10431
10432ClassImp(TH1D);
10433
10434////////////////////////////////////////////////////////////////////////////////
10435/// Constructor.
10436
10437TH1D::TH1D()
10438{
10439 fDimension = 1;
10440 SetBinsLength(3);
10441 if (fgDefaultSumw2) Sumw2();
10442}
10443
10444////////////////////////////////////////////////////////////////////////////////
10445/// Create a 1-Dim histogram with fix bins of type double
10446/// (see TH1::TH1 for explanation of parameters)
10447
10448TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10449: TH1(name,title,nbins,xlow,xup)
10450{
10451 fDimension = 1;
10453
10454 if (xlow >= xup) SetBuffer(fgBufferSize);
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 Float_t *xbins)
10463: TH1(name,title,nbins,xbins)
10464{
10465 fDimension = 1;
10467 if (fgDefaultSumw2) Sumw2();
10468}
10469
10470////////////////////////////////////////////////////////////////////////////////
10471/// Create a 1-Dim histogram with variable bins of type double
10472/// (see TH1::TH1 for explanation of parameters)
10473
10474TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10475: TH1(name,title,nbins,xbins)
10476{
10477 fDimension = 1;
10479 if (fgDefaultSumw2) Sumw2();
10480}
10481
10482////////////////////////////////////////////////////////////////////////////////
10483/// Create a histogram from a TVectorD
10484/// by default the histogram name is "TVectorD" and title = ""
10485
10486TH1D::TH1D(const TVectorD &v)
10487: TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
10488{
10490 fDimension = 1;
10491 Int_t ivlow = v.GetLwb();
10492 for (Int_t i=0;i<fNcells-2;i++) {
10493 SetBinContent(i+1,v(i+ivlow));
10494 }
10496 if (fgDefaultSumw2) Sumw2();
10497}
10498
10499////////////////////////////////////////////////////////////////////////////////
10500/// Destructor.
10501
10503{
10504}
10505
10506////////////////////////////////////////////////////////////////////////////////
10507/// Constructor.
10508
10509TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
10510{
10511 // intentially call virtual method to warn if TProfile is copying
10512 h1d.Copy(*this);
10513}
10514
10515////////////////////////////////////////////////////////////////////////////////
10516/// Copy this to newth1
10517
10518void TH1D::Copy(TObject &newth1) const
10519{
10520 TH1::Copy(newth1);
10521}
10522
10523////////////////////////////////////////////////////////////////////////////////
10524/// Reset.
10525
10527{
10530}
10531
10532////////////////////////////////////////////////////////////////////////////////
10533/// Set total number of bins including under/overflow
10534/// Reallocate bin contents array
10535
10537{
10538 if (n < 0) n = fXaxis.GetNbins() + 2;
10539 fNcells = n;
10540 TArrayD::Set(n);
10541}
10542
10543////////////////////////////////////////////////////////////////////////////////
10544/// Operator =
10545
10546TH1D& TH1D::operator=(const TH1D &h1d)
10547{
10548 // intentially call virtual method to warn if TProfile is copying
10549 if (this != &h1d)
10550 h1d.Copy(*this);
10551 return *this;
10552}
10553
10554////////////////////////////////////////////////////////////////////////////////
10555/// Operator *
10556
10558{
10559 TH1D hnew = h1;
10560 hnew.Scale(c1);
10561 hnew.SetDirectory(nullptr);
10562 return hnew;
10563}
10564
10565////////////////////////////////////////////////////////////////////////////////
10566/// Operator +
10567
10568TH1D operator+(const TH1D &h1, const TH1D &h2)
10569{
10570 TH1D hnew = h1;
10571 hnew.Add(&h2,1);
10572 hnew.SetDirectory(nullptr);
10573 return hnew;
10574}
10575
10576////////////////////////////////////////////////////////////////////////////////
10577/// Operator -
10578
10579TH1D operator-(const TH1D &h1, const TH1D &h2)
10580{
10581 TH1D hnew = h1;
10582 hnew.Add(&h2,-1);
10583 hnew.SetDirectory(nullptr);
10584 return hnew;
10585}
10586
10587////////////////////////////////////////////////////////////////////////////////
10588/// Operator *
10589
10590TH1D operator*(const TH1D &h1, const TH1D &h2)
10591{
10592 TH1D hnew = h1;
10593 hnew.Multiply(&h2);
10594 hnew.SetDirectory(nullptr);
10595 return hnew;
10596}
10597
10598////////////////////////////////////////////////////////////////////////////////
10599/// Operator /
10600
10601TH1D operator/(const TH1D &h1, const TH1D &h2)
10602{
10603 TH1D hnew = h1;
10604 hnew.Divide(&h2);
10605 hnew.SetDirectory(nullptr);
10606 return hnew;
10607}
10608
10609////////////////////////////////////////////////////////////////////////////////
10610///return pointer to histogram with name
10611///hid if id >=0
10612///h_id if id <0
10613
10614TH1 *R__H(Int_t hid)
10615{
10616 TString hname;
10617 if(hid >= 0) hname.Form("h%d",hid);
10618 else hname.Form("h_%d",hid);
10619 return (TH1*)gDirectory->Get(hname);
10620}
10621
10622////////////////////////////////////////////////////////////////////////////////
10623///return pointer to histogram with name hname
10624
10625TH1 *R__H(const char * hname)
10626{
10627 return (TH1*)gDirectory->Get(hname);
10628}
10629
10630
10631/// \fn void TH1::SetBarOffset(Float_t offset)
10632/// Set the bar offset as fraction of the bin width for drawing mode "B".
10633/// This shifts bars to the right on the x axis, and helps to draw bars next to each other.
10634/// \see THistPainter, SetBarWidth()
10635
10636/// \fn void TH1::SetBarWidth(Float_t width)
10637/// Set the width of bars as fraction of the bin width for drawing mode "B".
10638/// This allows for making bars narrower than the bin width. With SetBarOffset(), this helps to draw multiple bars next to each other.
10639/// \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:5907
void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
Least square linear fit without weights.
Definition TH1.cxx:4855
void H1InitGaus()
Compute Initial values of parameters for a gaussian.
Definition TH1.cxx:4690
void H1InitExpo()
Compute Initial values of parameters for an exponential.
Definition TH1.cxx:4746
TH1C operator+(const TH1C &h1, const TH1C &h2)
Operator +.
Definition TH1.cxx:9641
TH1C operator-(const TH1C &h1, const TH1C &h2)
Operator -.
Definition TH1.cxx:9652
TH1C operator/(const TH1C &h1, const TH1C &h2)
Operator /.
Definition TH1.cxx:9674
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:4901
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:5890
static Bool_t AlmostInteger(Double_t a, Double_t epsilon=0.00000001)
Test if a double is almost an integer.
Definition TH1.cxx:5898
TF1 * gF1
Definition TH1.cxx:583
TH1 * R__H(Int_t hid)
return pointer to histogram with name hid if id >=0 h_id if id <0
Definition TH1.cxx:10612
TH1C operator*(Double_t c1, const TH1C &h1)
Operator *.
Definition TH1.cxx:9630
void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
Least squares lpolynomial fitting without weights.
Definition TH1.cxx:4796
void H1InitPolynom()
Compute Initial values of parameters for a polynom.
Definition TH1.cxx:4766
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:554
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:795
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:711
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:1220
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:563
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis using bin numbers.
Definition TAxis.cxx:1057
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:542
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:5047
ROOT::NewFunc_t GetNew() const
Return the wrapper around new ThisClass().
Definition TClass.cxx:7516
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:459
~TH1C() override
Destructor.
Definition TH1.cxx:9554
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9610
TH1C & operator=(const TH1C &h1)
Operator =.
Definition TH1.cxx:9620
TH1C()
Constructor.
Definition TH1.cxx:9506
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9592
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9571
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:9600
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:671
~TH1D() override
Destructor.
Definition TH1.cxx:10500
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10534
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10516
TH1D()
Constructor.
Definition TH1.cxx:10435
TH1D & operator=(const TH1D &h1)
Operator =.
Definition TH1.cxx:10544
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:10524
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:623
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:657
TH1F & operator=(const TH1F &h1)
Operator =.
Definition TH1.cxx:10363
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10335
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10353
~TH1F() override
Destructor.
Definition TH1.cxx:10328
TH1F()
Constructor.
Definition TH1.cxx:10254
1-D histogram with an int per channel (see TH1 documentation)
Definition TH1.h:541
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9983
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9944
~TH1I() override
Destructor.
Definition TH1.cxx:9927
TH1I()
Constructor.
Definition TH1.cxx:9879
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9965
TH1I & operator=(const TH1I &h1)
Operator =.
Definition TH1.cxx:9993
1-D histogram with a long64 per channel (see TH1 documentation)
Definition TH1.h:582
TH1L & operator=(const TH1L &h1)
Operator =.
Definition TH1.cxx:10181
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:10132
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10171
~TH1L() override
Destructor.
Definition TH1.cxx:10115
TH1L()
Constructor.
Definition TH1.cxx:10067
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10153
1-D histogram with a short per channel (see TH1 documentation)
Definition TH1.h:500
TH1S & operator=(const TH1S &h1)
Operator =.
Definition TH1.cxx:9806
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9778
TH1S()
Constructor.
Definition TH1.cxx:9692
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9796
~TH1S() override
Destructor.
Definition TH1.cxx:9740
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9757
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:59
~TH1() override
Histogram default destructor.
Definition TH1.cxx:645
virtual void SetError(const Double_t *error)
Replace bin errors by values in array error.
Definition TH1.cxx:8984
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:8970
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition TH1.cxx:4292
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:1345
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition TH1.cxx:4456
char * GetObjectInfo(Int_t px, Int_t py) const override
Redefines TObject::GetObjectInfo.
Definition TH1.cxx:4510
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition TH1.cxx:6908
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:9174
virtual void Rebuild(Option_t *option="")
Using the current bin info, recompute the arrays for contents and errors.
Definition TH1.cxx:7116
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:365
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:3805
TAxis * GetZaxis()
Definition TH1.h:327
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a line.
Definition TH1.cxx:2825
virtual Bool_t Multiply(TF1 *f1, Double_t c1=1)
Performs the operation:
Definition TH1.cxx:6078
@ 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:7866
void Copy(TObject &hnew) const override
Copy this histogram structure to newth1.
Definition TH1.cxx:2673
void SetTitle(const char *title) override
Change/set the title.
Definition TH1.cxx:6747
Double_t fTsumw
Total Sum of weights.
Definition TH1.h:96
virtual Float_t GetBarWidth() const
Definition TH1.h:258
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:6954
virtual Float_t GetBarOffset() const
Definition TH1.h:257
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:1679
static TClass * Class()
static Int_t GetDefaultBufferSize()
Static function return the default buffer size for automatic histograms the parameter fgBufferSize ma...
Definition TH1.cxx:4414
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:8010
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:7640
TH1()
Histogram default constructor.
Definition TH1.cxx:617
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:9352
void UseCurrentStyle() override
Copy current attributes from/to current style.
Definition TH1.cxx:7502
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:5411
virtual Int_t GetNbinsY() const
Definition TH1.h:299
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:2069
static bool CheckBinLimits(const TAxis *a1, const TAxis *a2)
Check bin limits.
Definition TH1.cxx:1543
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition TH1.cxx:1270
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:9096
static Int_t FitOptionsMake(Option_t *option, Foption_t &Foption)
Decode string choptin and fill fitOption structure.
Definition TH1.cxx:4681
virtual Int_t GetNbinsZ() const
Definition TH1.h:300
virtual Double_t GetNormFactor() const
Definition TH1.h:302
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:7568
virtual Double_t GetSkewness(Int_t axis=1) const
Definition TH1.cxx:7704
virtual void ClearUnderflowAndOverflow()
Remove all the content from the underflow and overflow bins, without changing the number of entries A...
Definition TH1.cxx:2519
virtual void FillRandom(TF1 *f1, Int_t ntimes=5000, TRandom *rng=nullptr)
Definition TH1.cxx:3530
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition TH1.cxx:8473
virtual TH1 * DrawNormalized(Option_t *option="", Double_t norm=1) const
Draw a normalized copy of this histogram.
Definition TH1.cxx:3146
@ kNeutral
Adapt to the global flag.
Definition TH1.h:83
virtual Int_t GetDimension() const
Definition TH1.h:284
void Streamer(TBuffer &) override
Stream a class object.
Definition TH1.cxx:6962
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1296
@ 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:8555
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition TH1.cxx:6665
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:7132
void SetNameTitle(const char *name, const char *title) override
Change the name and title of this histogram.
Definition TH1.cxx:9007
TAxis * GetXaxis()
Definition TH1.h:325
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:5003
TH1 * GetCumulative(Bool_t forward=kTRUE, const char *suffix="_cumulative") const
Return a pointer to a histogram containing the cumulative content.
Definition TH1.cxx:2618
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:1310
virtual Int_t GetNcells() const
Definition TH1.h:301
virtual Int_t ShowPeaks(Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
Interface to TSpectrum::Search.
Definition TH1.cxx:9334
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition TH1.cxx:5937
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition TH1.cxx:7917
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition TH1.cxx:4519
TObject * FindObject(const char *name) const override
Search object named name in the list of functions.
Definition TH1.cxx:3865
void Print(Option_t *option="") const override
Print some global quantities for this histogram.
Definition TH1.cxx:7038
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
Definition TH1.cxx:4423
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:3742
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:3906
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:4990
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:8578
virtual Int_t GetNbinsX() const
Definition TH1.h:298
virtual void SetMaximum(Double_t maximum=-1111)
Definition TH1.h:405
virtual TH1 * FFT(TH1 *h_output, Option_t *option)
This function allows to do discrete Fourier transforms of TH1 and TH2.
Definition TH1.cxx:3286
virtual void LabelsInflate(Option_t *axis="X")
Double the number of bins for axis.
Definition TH1.cxx:5344
virtual TH1 * ShowBackground(Int_t niter=20, Option_t *option="same")
This function calculates the background spectrum in this histogram.
Definition TH1.cxx:9320
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
Definition TH1.cxx:5927
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:828
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:9472
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:8001
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:9239
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:381
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:3346
TAxis * GetYaxis()
Definition TH1.h:326
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:9112
void Browse(TBrowser *b) override
Browse the Histogram object.
Definition TH1.cxx:764
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition TH1.cxx:8431
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx:3068
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:7412
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:450
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:406
Bool_t IsBinUnderflow(Int_t bin, Int_t axis=0) const
Return true if the bin is underflow.
Definition TH1.cxx:5243
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TH1.cxx:7266
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check that axis have same labels.
Definition TH1.cxx:1570
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:5144
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:6732
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition TH1.cxx:5211
UInt_t GetAxisLabelStatus() const
Internal function used in TH1::Fill to see which axis is full alphanumeric, i.e.
Definition TH1.cxx:6704
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:7974
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:9255
virtual void DirectoryAutoAdd(TDirectory *)
Perform the automatic addition of the histogram to the given directory.
Definition TH1.cxx:2803
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:9220
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:9185
void Build()
Creates histogram basic data structure.
Definition TH1.cxx:773
virtual Double_t GetEntries() const
Return the current number of entries.
Definition TH1.cxx:4431
virtual TF1 * GetFunction(const char *name) const
Return pointer to function with name.
Definition TH1.cxx:9084
virtual TH1 * Rebin(Int_t ngroup=2, const char *newname="", const Double_t *xbins=nullptr)
Rebin this histogram.
Definition TH1.cxx:6304
virtual Int_t BufferFill(Double_t x, Double_t w)
accumulate arguments in buffer.
Definition TH1.cxx:1508
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:5115
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:6678
TList * GetListOfFunctions() const
Definition TH1.h:245
void SetName(const char *name) override
Change the name of this histogram.
Definition TH1.cxx:8993
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition TH1.cxx:3115
Bool_t IsEmpty() const
Check if a histogram is empty (this is a protected method used mainly by TH1Merger )
Definition TH1.cxx:5193
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition TH1.cxx:7608
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6235
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:8095
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculated from bin cont...
Definition TH1.cxx:7935
static void SetDefaultBufferSize(Int_t buffersize=1000)
Static function to set the default buffer size for automatic histograms.
Definition TH1.cxx:6722
virtual void SetBinErrorOption(EBinErrorOpt type)
Definition TH1.h:382
virtual void SetBuffer(Int_t buffersize, Option_t *option="")
Set the maximum number of entries to be kept in the buffer.
Definition TH1.cxx:8491
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Definition TH1.cxx:3177
virtual Double_t GetRandom(TRandom *rng=nullptr) const
Return a random number distributed according the histogram bin contents.
Definition TH1.cxx:5039
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:2498
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:2010
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:3475
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition TH1.cxx:8764
@ 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:8610
static Int_t AutoP2GetBins(Int_t n)
Auxiliary function to get the next power of 2 integer value larger then n.
Definition TH1.cxx:1323
Double_t fEntries
Number of entries.
Definition TH1.h:95
virtual Long64_t Merge(TCollection *list)
Definition TH1.h:346
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:4475
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TH1.cxx:3242
virtual Double_t * GetIntegral()
Return a pointer to the array of bins integral.
Definition TH1.cxx:2588
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:445
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:3449
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:9482
static bool CheckEqualAxes(const TAxis *a1, const TAxis *a2)
Check that the axis are the same.
Definition TH1.cxx:1613
@ 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:5090
virtual Int_t GetContour(Double_t *levels=nullptr)
Return contour values into array levels if pointer levels is non zero.
Definition TH1.cxx:8444
TAxis fXaxis
X axis descriptor.
Definition TH1.h:90
virtual Bool_t IsHighlight() const
Definition TH1.h:339
virtual void ExtendAxis(Double_t x, TAxis *axis)
Histogram is resized along axis such that x is in the axis range.
Definition TH1.cxx:6533
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:9196
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:4347
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition TH1.cxx:8463
virtual void SetContour(Int_t nlevels, const Double_t *levels=nullptr)
Set the number and values of contour levels.
Definition TH1.cxx:8516
virtual void SetHighlight(Bool_t set=kTRUE)
Set highlight (enable/disable) mode for the histogram by default highlight mode is disable.
Definition TH1.cxx:4490
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition TH1.cxx:9143
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition TH1.cxx:6633
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition TH1.cxx:8698
virtual Int_t GetSumw2N() const
Definition TH1.h:316
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:3680
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:7210
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:4619
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx:2754
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition TH1.cxx:7688
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:2842
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:8668
int LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge=false) const
Definition TH1.cxx:885
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:1642
void RecursiveRemove(TObject *obj) override
Recursively remove object from the list of functions.
Definition TH1.cxx:6605
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:8211
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition TH1.cxx:7950
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:6797
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:9207
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:8800
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:3713
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:9053
virtual void SetEntries(Double_t n)
Definition TH1.h:392
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:6489
static bool CheckAxisLimits(const TAxis *a1, const TAxis *a2)
Check that the axis limits of the histograms are the same.
Definition TH1.cxx:1599
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition TH1.cxx:756
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:5274
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:2539
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:3194
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:366
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition TH1.cxx:1416
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition TH1.cxx:9023
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition TH1.cxx:7777
2-D histogram with a double per channel (see TH1 documentation)
Definition TH2.h:358
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:896
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:697
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:1352
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Definition TMath.h:906
Double_t Floor(Double_t x)
Rounds x downward, returning the largest integral value that is not greater than x.
Definition TMath.h:684
Double_t ATan(Double_t)
Returns the principal value of the arc tangent of x, expressed in radians.
Definition TMath.h:644
Double_t Ceil(Double_t x)
Rounds x upward, returning the smallest integral value that is not less than x.
Definition TMath.h:672
T MinElement(Long64_t n, const T *a)
Returns minimum of array a of length n.
Definition TMath.h:964
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:760
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:666
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:725
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:766
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:921
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