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 <memory>
21#include <sstream>
22#include <fstream>
23#include <limits>
24#include <iomanip>
25
26#include "TROOT.h"
27#include "TBuffer.h"
28#include "TEnv.h"
29#include "TClass.h"
30#include "TMath.h"
31#include "THashList.h"
32#include "TH1.h"
33#include "TH2.h"
34#include "TH3.h"
35#include "TF2.h"
36#include "TF3.h"
37#include "TPluginManager.h"
38#include "TVirtualPad.h"
39#include "TRandom.h"
40#include "TVirtualFitter.h"
41#include "THLimitsFinder.h"
42#include "TProfile.h"
43#include "TStyle.h"
44#include "TVectorF.h"
45#include "TVectorD.h"
46#include "TBrowser.h"
47#include "TError.h"
48#include "TVirtualHistPainter.h"
49#include "TVirtualFFT.h"
50#include "TVirtualPaveStats.h"
51
52#include "HFitInterface.h"
53#include "Fit/DataRange.h"
54#include "Fit/BinData.h"
55#include "Math/GoFTest.h"
58
59#include "TH1Merger.h"
60
61/** \addtogroup Histograms
62@{
63\class TH1C
64\brief 1-D histogram with a byte per channel (see TH1 documentation)
65\class TH1S
66\brief 1-D histogram with a short per channel (see TH1 documentation)
67\class TH1I
68\brief 1-D histogram with an int per channel (see TH1 documentation)
69\class TH1L
70\brief 1-D histogram with a long64 per channel (see TH1 documentation)
71\class TH1F
72\brief 1-D histogram with a float per channel (see TH1 documentation)
73\class TH1D
74\brief 1-D histogram with a double per channel (see TH1 documentation)
75@}
76*/
77
78// clang-format off
79
80/** \class TH1
81 \ingroup Histograms
82TH1 is the base class of all histogram classes in %ROOT.
83
84It provides the common interface for operations such as binning, filling, drawing, which
85will be detailed below.
86
87-# [Creating histograms](\ref creating-histograms)
88 - [Labelling axes](\ref labelling-axis)
89-# [Binning](\ref binning)
90 - [Fix or variable bin size](\ref fix-var)
91 - [Convention for numbering bins](\ref convention)
92 - [Alphanumeric Bin Labels](\ref alpha)
93 - [Histograms with automatic bins](\ref auto-bin)
94 - [Rebinning](\ref rebinning)
95-# [Filling histograms](\ref filling-histograms)
96 - [Associated errors](\ref associated-errors)
97 - [Associated functions](\ref associated-functions)
98 - [Projections of histograms](\ref prof-hist)
99 - [Random Numbers and histograms](\ref random-numbers)
100 - [Making a copy of a histogram](\ref making-a-copy)
101 - [Normalizing histograms](\ref normalizing)
102-# [Drawing histograms](\ref drawing-histograms)
103 - [Setting Drawing histogram contour levels (2-D hists only)](\ref cont-level)
104 - [Setting histogram graphics attributes](\ref graph-att)
105 - [Customising how axes are drawn](\ref axis-drawing)
106-# [Fitting histograms](\ref fitting-histograms)
107-# [Saving/reading histograms to/from a ROOT file](\ref saving-histograms)
108-# [Operations on histograms](\ref operations-on-histograms)
109-# [Miscellaneous operations](\ref misc)
110
111ROOT supports the following histogram types:
112
113 - 1-D histograms:
114 - TH1C : histograms with one byte per channel. Maximum bin content = 127
115 - TH1S : histograms with one short per channel. Maximum bin content = 32767
116 - TH1I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
117 - TH1L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
118 - TH1F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content =
119+/-16777216 (\ref floatmax "***")
120 - TH1D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content =
121+/-9007199254740992 (\ref doublemax "****")
122 - 2-D histograms:
123 - TH2C : histograms with one byte per channel. Maximum bin content = 127
124 - TH2S : histograms with one short per channel. Maximum bin content = 32767
125 - TH2I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
126 - TH2L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
127 - TH2F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content =
128+/-16777216 (\ref floatmax "***")
129 - TH2D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content =
130+/-9007199254740992 (\ref doublemax "****")
131 - 3-D histograms:
132 - TH3C : histograms with one byte per channel. Maximum bin content = 127
133 - TH3S : histograms with one short per channel. Maximum bin content = 32767
134 - TH3I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
135 - TH3L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
136 - TH3F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content =
137+/-16777216 (\ref floatmax "***")
138 - TH3D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content =
139+/-9007199254740992 (\ref doublemax "****")
140 - Profile histograms: See classes TProfile, TProfile2D and TProfile3D.
141 Profile histograms are used to display the mean value of Y and its standard deviation
142 for each bin in X. Profile histograms are in many cases an elegant
143 replacement of two-dimensional histograms : the inter-relation of two
144 measured quantities X and Y can always be visualized by a two-dimensional
145 histogram or scatter-plot; If Y is an unknown (but single-valued)
146 approximate function of X, this function is displayed by a profile
147 histogram with much better precision than by a scatter-plot.
148
149<sup>
150\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>
151\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>
152\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>
153\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)
154</sup>
155
156The inheritance hierarchy looks as follows:
157
158\image html classTH1__inherit__graph_org.svg width=100%
159
160\anchor creating-histograms
161## Creating histograms
162
163Histograms are created by invoking one of the constructors, e.g.
164~~~ {.cpp}
165 TH1F *h1 = new TH1F("h1", "h1 title", 100, 0, 4.4);
166 TH2F *h2 = new TH2F("h2", "h2 title", 40, 0, 4, 30, -3, 3);
167~~~
168Histograms may also be created by:
169
170 - calling the Clone() function, see below
171 - making a projection from a 2-D or 3-D histogram, see below
172 - reading a histogram from a file
173
174 When a histogram is created in ROOT 6, a reference to it is automatically added
175 to the list of in-memory objects for the current file or directory.
176 Then the pointer to this histogram in the current directory can be found
177 by its name, doing:
178~~~ {.cpp}
179 TH1F *h1 = (TH1F*)gDirectory->FindObject(name);
180~~~
181
182 This default behaviour can be changed by:
183~~~ {.cpp}
184 h->SetDirectory(nullptr); // for one histogram h
185 TH1::AddDirectory(kFALSE); // deprecated, see below
186~~~
187 When the histogram is deleted, the reference to it is removed from
188 the list of objects in memory.
189 When a file is closed, all histograms in memory associated with this file
190 are automatically deleted.
191
192In ROOT 7, this auto registration will be phased out. This mode can be tested in ROOT 6 using
193ROOT::Experimental::DisableObjectAutoRegistration(). To opt in to the ROOT-6-style registration
194in ROOT 7, use ROOT::Experimental::EnableObjectAutoRegistration().
195
196\anchor labelling-axis
197### Labelling axes
198
199 Axis titles can be specified in the title argument of the constructor.
200 They must be separated by ";":
201~~~ {.cpp}
202 TH1F* h=new TH1F("h", "Histogram title;X Axis;Y Axis", 100, 0, 1);
203~~~
204 The histogram title and the axis titles can be any TLatex string, and
205 are persisted if a histogram is written to a file.
206
207 Any title can be omitted:
208~~~ {.cpp}
209 TH1F* h=new TH1F("h", "Histogram title;;Y Axis", 100, 0, 1);
210 TH1F* h=new TH1F("h", ";;Y Axis", 100, 0, 1);
211~~~
212 The method SetTitle() has the same syntax:
213~~~ {.cpp}
214 h->SetTitle("Histogram title;Another X title Axis");
215~~~
216Alternatively, the title of each axis can be set directly:
217~~~ {.cpp}
218 h->GetXaxis()->SetTitle("X axis title");
219 h->GetYaxis()->SetTitle("Y axis title");
220~~~
221For bin labels see \ref binning.
222
223\anchor binning
224## Binning
225
226\anchor fix-var
227### Fix or variable bin size
228
229 All histogram types support either fix or variable bin sizes.
230 2-D histograms may have fix size bins along X and variable size bins
231 along Y or vice-versa. The functions to fill, manipulate, draw or access
232 histograms are identical in both cases.
233
234 Each histogram always contains 3 axis objects of type TAxis: fXaxis, fYaxis and fZaxis.
235 To access the axis parameters, use:
236~~~ {.cpp}
237 TAxis *xaxis = h->GetXaxis(); etc.
238 Double_t binCenter = xaxis->GetBinCenter(bin), etc.
239~~~
240 See class TAxis for a description of all the access functions.
241 The axis range is always stored internally in double precision.
242
243\anchor convention
244### Convention for numbering bins
245
246 For all histogram types: nbins, xlow, xup
247~~~ {.cpp}
248 bin = 0; underflow bin
249 bin = 1; first bin with low-edge xlow INCLUDED
250 bin = nbins; last bin with upper-edge xup EXCLUDED
251 bin = nbins+1; overflow bin
252~~~
253 In case of 2-D or 3-D histograms, a "global bin" number is defined.
254 For example, assuming a 3-D histogram with (binx, biny, binz), the function
255~~~ {.cpp}
256 Int_t gbin = h->GetBin(binx, biny, binz);
257~~~
258 returns a global/linearized gbin number. This global gbin is useful
259 to access the bin content/error information independently of the dimension.
260 Note that to access the information other than bin content and errors
261 one should use the TAxis object directly with e.g.:
262~~~ {.cpp}
263 Double_t xcenter = h3->GetZaxis()->GetBinCenter(27);
264~~~
265 returns the center along z of bin number 27 (not the global bin)
266 in the 3-D histogram h3.
267
268\anchor alpha
269### Alphanumeric Bin Labels
270
271 By default, a histogram axis is drawn with its numeric bin labels.
272 One can specify alphanumeric labels instead with:
273
274 - call TAxis::SetBinLabel(bin, label);
275 This can always be done before or after filling.
276 When the histogram is drawn, bin labels will be automatically drawn.
277 See examples labels1.C and labels2.C
278 - call to a Fill function with one of the arguments being a string, e.g.
279~~~ {.cpp}
280 hist1->Fill(somename, weight);
281 hist2->Fill(x, somename, weight);
282 hist2->Fill(somename, y, weight);
283 hist2->Fill(somenamex, somenamey, weight);
284~~~
285 See examples hlabels1.C and hlabels2.C
286 - via TTree::Draw. see for example cernstaff.C
287~~~ {.cpp}
288 tree.Draw("Nation::Division");
289~~~
290 where "Nation" and "Division" are two branches of a Tree.
291
292When using the options 2 or 3 above, the labels are automatically
293 added to the list (THashList) of labels for a given axis.
294 By default, an axis is drawn with the order of bins corresponding
295 to the filling sequence. It is possible to reorder the axis
296
297 - alphabetically
298 - by increasing or decreasing values
299
300 The reordering can be triggered via the TAxis context menu by selecting
301 the menu item "LabelsOption" or by calling directly
302 TH1::LabelsOption(option, axis) where
303
304 - axis may be "X", "Y" or "Z"
305 - option may be:
306 - "a" sort by alphabetic order
307 - ">" sort by decreasing values
308 - "<" sort by increasing values
309 - "h" draw labels horizontal
310 - "v" draw labels vertical
311 - "u" draw labels up (end of label right adjusted)
312 - "d" draw labels down (start of label left adjusted)
313
314 When using the option 2 above, new labels are added by doubling the current
315 number of bins in case one label does not exist yet.
316 When the Filling is terminated, it is possible to trim the number
317 of bins to match the number of active labels by calling
318~~~ {.cpp}
319 TH1::LabelsDeflate(axis) with axis = "X", "Y" or "Z"
320~~~
321 This operation is automatic when using TTree::Draw.
322 Once bin labels have been created, they become persistent if the histogram
323 is written to a file or when generating the C++ code via SavePrimitive.
324
325\anchor auto-bin
326### Histograms with automatic bins
327
328 When a histogram is created with an axis lower limit greater or equal
329 to its upper limit, the SetBuffer is automatically called with an
330 argument fBufferSize equal to fgBufferSize (default value=1000).
331 fgBufferSize may be reset via the static function TH1::SetDefaultBufferSize.
332 The axis limits will be automatically computed when the buffer will
333 be full or when the function BufferEmpty is called.
334
335\anchor rebinning
336### Rebinning
337
338 At any time, a histogram can be rebinned via TH1::Rebin. This function
339 returns a new histogram with the rebinned contents.
340 If bin errors were stored, they are recomputed during the rebinning.
341
342
343\anchor filling-histograms
344## Filling histograms
345
346 A histogram is typically filled with statements like:
347~~~ {.cpp}
348 h1->Fill(x);
349 h1->Fill(x, w); //fill with weight
350 h2->Fill(x, y)
351 h2->Fill(x, y, w)
352 h3->Fill(x, y, z)
353 h3->Fill(x, y, z, w)
354~~~
355 or via one of the Fill functions accepting names described above.
356 The Fill functions compute the bin number corresponding to the given
357 x, y or z argument and increment this bin by the given weight.
358 The Fill functions return the bin number for 1-D histograms or global
359 bin number for 2-D and 3-D histograms.
360 If TH1::Sumw2 has been called before filling, the sum of squares of
361 weights is also stored.
362 One can also increment directly a bin number via TH1::AddBinContent
363 or replace the existing content via TH1::SetBinContent. Passing an
364 out-of-range bin to TH1::AddBinContent leads to undefined behavior.
365 To access the bin content of a given bin, do:
366~~~ {.cpp}
367 Double_t binContent = h->GetBinContent(bin);
368~~~
369
370 By default, the bin number is computed using the current axis ranges.
371 If the automatic binning option has been set via
372~~~ {.cpp}
373 h->SetCanExtend(TH1::kAllAxes);
374~~~
375 then, the Fill Function will automatically extend the axis range to
376 accommodate the new value specified in the Fill argument. The method
377 used is to double the bin size until the new value fits in the range,
378 merging bins two by two. This automatic binning options is extensively
379 used by the TTree::Draw function when histogramming Tree variables
380 with an unknown range.
381 This automatic binning option is supported for 1-D, 2-D and 3-D histograms.
382
383 During filling, some statistics parameters are incremented to compute
384 the mean value and Root Mean Square with the maximum precision.
385
386 In case of histograms of type TH1C, TH1S, TH2C, TH2S, TH3C, TH3S
387 a check is made that the bin contents do not exceed the maximum positive
388 capacity (127 or 32767). Histograms of all types may have positive
389 or/and negative bin contents.
390
391\anchor associated-errors
392### Associated errors
393 By default, for each bin, the sum of weights is computed at fill time.
394 One can also call TH1::Sumw2 to force the storage and computation
395 of the sum of the square of weights per bin.
396 If Sumw2 has been called, the error per bin is computed as the
397 sqrt(sum of squares of weights), otherwise the error is set equal
398 to the sqrt(bin content).
399 To return the error for a given bin number, do:
400~~~ {.cpp}
401 Double_t error = h->GetBinError(bin);
402~~~
403
404\anchor associated-functions
405### Associated functions
406 One or more objects (typically a TF1*) can be added to the list
407 of functions (fFunctions) associated to each histogram.
408 When TH1::Fit is invoked, the fitted function is added to this list.
409 Given a histogram (or TGraph) `h`, one can retrieve an associated function
410 with:
411~~~ {.cpp}
412 TF1 *myfunc = h->GetFunction("myfunc");
413~~~
414
415
416\anchor operations-on-histograms
417## Operations on histograms
418
419 Many types of operations are supported on histograms or between histograms
420
421 - Addition of a histogram to the current histogram.
422 - Additions of two histograms with coefficients and storage into the current
423 histogram.
424 - Multiplications and Divisions are supported in the same way as additions.
425 - The Add, Divide and Multiply functions also exist to add, divide or multiply
426 a histogram by a function.
427
428 If a histogram has associated error bars (TH1::Sumw2 has been called),
429 the resulting error bars are also computed assuming independent histograms.
430 In case of divisions, Binomial errors are also supported.
431 One can mark a histogram to be an "average" histogram by setting its bit kIsAverage via
432 myhist.SetBit(TH1::kIsAverage);
433 When adding (see TH1::Add) average histograms, the histograms are averaged and not summed.
434
435
436\anchor prof-hist
437### Projections of histograms
438
439 One can:
440
441 - make a 1-D projection of a 2-D histogram or Profile
442 see functions TH2::ProjectionX,Y, TH2::ProfileX,Y, TProfile::ProjectionX
443 - make a 1-D, 2-D or profile out of a 3-D histogram
444 see functions TH3::ProjectionZ, TH3::Project3D.
445
446 One can fit these projections via:
447~~~ {.cpp}
448 TH2::FitSlicesX,Y, TH3::FitSlicesZ.
449~~~
450
451\anchor random-numbers
452### Random Numbers and histograms
453
454 TH1::FillRandom can be used to randomly fill a histogram using
455 the contents of an existing TF1 function or another
456 TH1 histogram (for all dimensions).
457 For example, the following two statements create and fill a histogram
458 10000 times with a default gaussian distribution of mean 0 and sigma 1:
459~~~ {.cpp}
460 TH1F h1("h1", "histo from a gaussian", 100, -3, 3);
461 h1.FillRandom("gaus", 10000);
462~~~
463 TH1::GetRandom can be used to return a random number distributed
464 according to the contents of a histogram.
465
466\anchor making-a-copy
467### Making a copy of a histogram
468 Like for any other ROOT object derived from TObject, one can use
469 the Clone() function. This makes an identical copy of the original
470 histogram including all associated errors and functions, e.g.:
471~~~ {.cpp}
472 TH1F *hnew = (TH1F*)h->Clone("hnew");
473~~~
474
475\anchor normalizing
476### Normalizing histograms
477
478 One can scale a histogram such that the bins integral is equal to
479 the normalization parameter via TH1::Scale(Double_t norm), where norm
480 is the desired normalization divided by the integral of the histogram.
481
482
483\anchor drawing-histograms
484## Drawing histograms
485
486 Histograms are drawn via the THistPainter class. Each histogram has
487 a pointer to its own painter (to be usable in a multithreaded program).
488 Many drawing options are supported.
489 See THistPainter::Paint() for more details.
490
491 The same histogram can be drawn with different options in different pads.
492 When a histogram drawn in a pad is deleted, the histogram is
493 automatically removed from all pads where it was drawn.
494 If a histogram is drawn in a pad, then modified, the new status
495 of the histogram will be automatically shown in the pad next time
496 the pad is updated. One does not need to redraw the histogram.
497 To draw the current version of a histogram in a pad, one can use
498~~~ {.cpp}
499 h->DrawCopy();
500~~~
501 DrawCopy() is also useful when a temporary histogram should be drawn, for
502 example in
503~~~ {.cpp}
504 void drawHisto() {
505 TH1D histo("histo", "An example histogram", 10, 0, 10);
506 // ...
507 histo.DrawCopy();
508 } // histo goes out of scope here, but the copy stays visible
509~~~
510
511 One can use TH1::SetMaximum() and TH1::SetMinimum() to force a particular
512 value for the maximum or the minimum scale on the plot. (For 1-D
513 histograms this means the y-axis, while for 2-D histograms these
514 functions affect the z-axis).
516 TH1::UseCurrentStyle() can be used to change all histogram graphics
517 attributes to correspond to the current selected style.
518 This function must be called for each histogram.
519 In case one reads and draws many histograms from a file, one can force
520 the histograms to inherit automatically the current graphics style
521 by calling before gROOT->ForceStyle().
522
523\anchor cont-level
524### Setting Drawing histogram contour levels (2-D hists only)
525
526 By default contours are automatically generated at equidistant
527 intervals. A default value of 20 levels is used. This can be modified
528 via TH1::SetContour() or TH1::SetContourLevel().
529 the contours level info is used by the drawing options "cont", "surf",
530 and "lego".
531
532\anchor graph-att
533### Setting histogram graphics attributes
534
535 The histogram classes inherit from the attribute classes:
536 TAttLine, TAttFill, and TAttMarker.
537 See the member functions of these classes for the list of options.
538
539\anchor axis-drawing
540### Customizing how axes are drawn
541
542 Use the functions of TAxis, such as
543~~~ {.cpp}
544 histogram.GetXaxis()->SetTicks("+");
545 histogram.GetYaxis()->SetRangeUser(1., 5.);
546~~~
547
548\anchor fitting-histograms
549## Fitting histograms
550
551 Histograms (1-D, 2-D, 3-D and Profiles) can be fitted with a user
552 specified function or a pre-defined function via TH1::Fit.
553 See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for the fitting documentation and the possible [fitting options](\ref HFitOpt)
554
555 The FitPanel can also be used for fitting an histogram. See the [FitPanel documentation](https://root.cern/manual/fitting/#using-the-fit-panel).
556
557\anchor saving-histograms
558## Saving/reading histograms to/from a ROOT file
559
560 The following statements create a ROOT file and store a histogram
561 on the file. Because TH1 derives from TNamed, the key identifier on
562 the file is the histogram name:
563~~~ {.cpp}
564 TFile f("histos.root", "new");
565 TH1F h1("hgaus", "histo from a gaussian", 100, -3, 3);
566 h1.FillRandom("gaus", 10000);
567 h1->Write();
568~~~
569 To read this histogram in another Root session, do:
570~~~ {.cpp}
571 TFile f("histos.root");
572 TH1F *h = (TH1F*)f.Get("hgaus");
573~~~
574 One can save all histograms in memory to the file by:
575~~~ {.cpp}
576 file->Write();
577~~~
580\anchor misc
581## Miscellaneous operations
582
583~~~ {.cpp}
584 TH1::KolmogorovTest(): statistical test of compatibility in shape
585 between two histograms
586 TH1::Smooth() smooths the bin contents of a 1-d histogram
587 TH1::Integral() returns the integral of bin contents in a given bin range
588 TH1::GetMean(int axis) returns the mean value along axis
589 TH1::GetStdDev(int axis) returns the sigma distribution along axis
590 TH1::GetEntries() returns the number of entries
591 TH1::Reset() resets the bin contents and errors of a histogram
592~~~
593 IMPORTANT NOTE: The returned values for GetMean and GetStdDev depend on how the
594 histogram statistics are calculated. By default, if no range has been set, the
595 returned values are the (unbinned) ones calculated at fill time. If a range has been
596 set, however, the values are calculated using the bins in range; THIS IS TRUE EVEN
597 IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset the range.
598 To ensure that the returned values are always those of the binned data stored in the
599 histogram, call TH1::ResetStats. See TH1::GetStats.
600*/
601
602// clang-format on
603
604TF1 *gF1=nullptr; //left for back compatibility (use TVirtualFitter::GetUserFunc instead)
605
610
611extern void H1InitGaus();
612extern void H1InitExpo();
613extern void H1InitPolynom();
614extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
617
618
619////////////////////////////////////////////////////////////////////////////////
620/// Histogram default constructor.
621
623{
624 fDirectory = nullptr;
625 fFunctions = new TList;
626 fNcells = 0;
627 fIntegral = nullptr;
628 fPainter = nullptr;
629 fEntries = 0;
630 fNormFactor = 0;
632 fMaximum = -1111;
633 fMinimum = -1111;
634 fBufferSize = 0;
635 fBuffer = nullptr;
638 fXaxis.SetName("xaxis");
639 fYaxis.SetName("yaxis");
640 fZaxis.SetName("zaxis");
641 fXaxis.SetParent(this);
642 fYaxis.SetParent(this);
643 fZaxis.SetParent(this);
645}
646
647////////////////////////////////////////////////////////////////////////////////
648/// Histogram default destructor.
649
651{
653 return;
654 }
655 delete[] fIntegral;
656 fIntegral = nullptr;
657 delete[] fBuffer;
658 fBuffer = nullptr;
659 if (fFunctions) {
661
663 TObject* obj = nullptr;
664 //special logic to support the case where the same object is
665 //added multiple times in fFunctions.
666 //This case happens when the same object is added with different
667 //drawing modes
668 //In the loop below we must be careful with objects (eg TCutG) that may
669 // have been added to the list of functions of several histograms
670 //and may have been already deleted.
671 while ((obj = fFunctions->First())) {
672 while(fFunctions->Remove(obj)) { }
674 break;
675 }
676 delete obj;
677 obj = nullptr;
678 }
679 delete fFunctions;
680 fFunctions = nullptr;
681 }
682 if (fDirectory) {
683 fDirectory->Remove(this);
684 fDirectory = nullptr;
685 }
686 delete fPainter;
687 fPainter = nullptr;
688}
689
690////////////////////////////////////////////////////////////////////////////////
691/// Constructor for fix bin size histograms.
692/// Creates the main histogram structure.
693///
694/// \param[in] name name of histogram (avoid blanks)
695/// \param[in] title histogram title.
696/// If title is of the form `stringt;stringx;stringy;stringz`,
697/// the histogram title is set to `stringt`,
698/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
699/// \param[in] nbins number of bins
700/// \param[in] xlow low edge of first bin
701/// \param[in] xup upper edge of last bin (not included in last bin)
702/// \note if xup <= xlow, automatic bins are calculated when buffer size is reached
703
704TH1::TH1(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
705 :TNamed(name,title)
706{
707 Build();
708 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
709 fXaxis.Set(nbins,xlow,xup);
710 fNcells = fXaxis.GetNbins()+2;
711}
712
713////////////////////////////////////////////////////////////////////////////////
714/// Constructor for variable bin size histograms using an input array of type float.
715/// Creates the main histogram structure.
716///
717/// \param[in] name name of histogram (avoid blanks)
718/// \param[in] title histogram title.
719/// If title is of the form `stringt;stringx;stringy;stringz`
720/// the histogram title is set to `stringt`,
721/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
722/// \param[in] nbins number of bins
723/// \param[in] xbins array of low-edges for each bin.
724/// This is an array of type float and size nbins+1
725
726TH1::TH1(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
727 :TNamed(name,title)
728{
729 Build();
730 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
731 if (xbins) fXaxis.Set(nbins,xbins);
732 else fXaxis.Set(nbins,0,1);
733 fNcells = fXaxis.GetNbins()+2;
734}
735
736////////////////////////////////////////////////////////////////////////////////
737/// Constructor for variable bin size histograms using an input array of type double.
738///
739/// \param[in] name name of histogram (avoid blanks)
740/// \param[in] title histogram title.
741/// If title is of the form `stringt;stringx;stringy;stringz`
742/// the histogram title is set to `stringt`,
743/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
744/// \param[in] nbins number of bins
745/// \param[in] xbins array of low-edges for each bin.
746/// This is an array of type double and size nbins+1
747
748TH1::TH1(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
749 :TNamed(name,title)
750{
751 Build();
752 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
753 if (xbins) fXaxis.Set(nbins,xbins);
754 else fXaxis.Set(nbins,0,1);
755 fNcells = fXaxis.GetNbins()+2;
756}
757
758////////////////////////////////////////////////////////////////////////////////
759/// Check whether TH1-derived classes should register themselves to the current gDirectory.
760/// \note Even if this returns true, the state of
761/// ROOT::Experimental::ObjectAutoRegistrationEnabled() might prevent the registration of
762/// histograms, since it has higher precedence.
763
768
769////////////////////////////////////////////////////////////////////////////////
770/// Browse the Histogram object.
771
773{
774 Draw(b ? b->GetDrawOption() : "");
775 gPad->Update();
776}
777
778////////////////////////////////////////////////////////////////////////////////
779/// Creates histogram basic data structure.
780
782{
783 fDirectory = nullptr;
784 fPainter = nullptr;
785 fIntegral = nullptr;
786 fEntries = 0;
787 fNormFactor = 0;
789 fMaximum = -1111;
790 fMinimum = -1111;
791 fBufferSize = 0;
792 fBuffer = nullptr;
795 fXaxis.SetName("xaxis");
796 fYaxis.SetName("yaxis");
797 fZaxis.SetName("zaxis");
798 fYaxis.Set(1,0.,1.);
799 fZaxis.Set(1,0.,1.);
800 fXaxis.SetParent(this);
801 fYaxis.SetParent(this);
802 fZaxis.SetParent(this);
803
805
806 fFunctions = new TList;
807
809
812 if (fDirectory) {
814 fDirectory->Append(this,kTRUE);
815 }
816 }
817}
818
819////////////////////////////////////////////////////////////////////////////////
820/// Performs the operation: `this = this + c1*f1`
821/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
822///
823/// By default, the function is computed at the centre of the bin.
824/// if option "I" is specified (1-d histogram only), the integral of the
825/// function in each bin is used instead of the value of the function at
826/// the centre of the bin.
827///
828/// Only bins inside the function range are recomputed.
829///
830/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
831/// you should call Sumw2 before making this operation.
832/// This is particularly important if you fit the histogram after TH1::Add
833///
834/// The function return kFALSE if the Add operation failed
835
837{
838 if (!f1) {
839 Error("Add","Attempt to add a non-existing function");
840 return kFALSE;
841 }
842
843 TString opt = option;
844 opt.ToLower();
845 Bool_t integral = kFALSE;
846 if (opt.Contains("i") && fDimension == 1) integral = kTRUE;
847
848 Int_t ncellsx = GetNbinsX() + 2; // cells = normal bins + underflow bin + overflow bin
849 Int_t ncellsy = GetNbinsY() + 2;
850 Int_t ncellsz = GetNbinsZ() + 2;
851 if (fDimension < 2) ncellsy = 1;
852 if (fDimension < 3) ncellsz = 1;
853
854 // delete buffer if it is there since it will become invalid
855 if (fBuffer) BufferEmpty(1);
856
857 // - Add statistics
858 Double_t s1[10];
859 for (Int_t i = 0; i < 10; ++i) s1[i] = 0;
860 PutStats(s1);
861 SetMinimum();
862 SetMaximum();
863
864 // - Loop on bins (including underflows/overflows)
865 Int_t bin, binx, biny, binz;
866 Double_t cu=0;
867 Double_t xx[3];
868 Double_t *params = nullptr;
869 f1->InitArgs(xx,params);
870 for (binz = 0; binz < ncellsz; ++binz) {
872 for (biny = 0; biny < ncellsy; ++biny) {
874 for (binx = 0; binx < ncellsx; ++binx) {
876 if (!f1->IsInside(xx)) continue;
878 bin = binx + ncellsx * (biny + ncellsy * binz);
879 if (integral) {
881 } else {
882 cu = c1*f1->EvalPar(xx);
883 }
884 if (TF1::RejectedPoint()) continue;
885 AddBinContent(bin,cu);
886 }
887 }
888 }
889
890 return kTRUE;
891}
892
893int TH1::LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge) const
894{
895 const auto inconsistency = CheckConsistency(h1, h2);
896
898 if (useMerge)
899 Info(name, "Histograms have different dimensions - trying to use TH1::Merge");
900 else {
901 Error(name, "Histograms have different dimensions");
902 }
904 if (useMerge)
905 Info(name, "Histograms have different number of bins - trying to use TH1::Merge");
906 else {
907 Error(name, "Histograms have different number of bins");
908 }
909 } else if (inconsistency & kDifferentAxisLimits) {
910 if (useMerge)
911 Info(name, "Histograms have different axis limits - trying to use TH1::Merge");
912 else
913 Warning(name, "Histograms have different axis limits");
914 } else if (inconsistency & kDifferentBinLimits) {
915 if (useMerge)
916 Info(name, "Histograms have different bin limits - trying to use TH1::Merge");
917 else
918 Warning(name, "Histograms have different bin limits");
919 } else if (inconsistency & kDifferentLabels) {
920 // in case of different labels -
921 if (useMerge)
922 Info(name, "Histograms have different labels - trying to use TH1::Merge");
923 else
924 Info(name, "Histograms have different labels");
925 }
926
927 return inconsistency;
928}
929
930////////////////////////////////////////////////////////////////////////////////
931/// Performs the operation: `this = this + c1*h1`
932/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
933///
934/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
935/// if not already set.
936///
937/// Note also that adding histogram with labels is not supported, histogram will be
938/// added merging them by bin number independently of the labels.
939/// For adding histogram with labels one should use TH1::Merge
940///
941/// SPECIAL CASE (Average/Efficiency histograms)
942/// For histograms representing averages or efficiencies, one should compute the average
943/// of the two histograms and not the sum. One can mark a histogram to be an average
944/// histogram by setting its bit kIsAverage with
945/// myhist.SetBit(TH1::kIsAverage);
946/// Note that the two histograms must have their kIsAverage bit set
947///
948/// IMPORTANT NOTE1: If you intend to use the errors of this histogram later
949/// you should call Sumw2 before making this operation.
950/// This is particularly important if you fit the histogram after TH1::Add
951///
952/// IMPORTANT NOTE2: if h1 has a normalisation factor, the normalisation factor
953/// is used , ie this = this + c1*factor*h1
954/// Use the other TH1::Add function if you do not want this feature
955///
956/// IMPORTANT NOTE3: You should be careful about the statistics of the
957/// returned histogram, whose statistics may be binned or unbinned,
958/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
959/// and whether TH1::ResetStats has been called on either this or h1.
960/// See TH1::GetStats.
961///
962/// The function return kFALSE if the Add operation failed
963
965{
966 if (!h1) {
967 Error("Add","Attempt to add a non-existing histogram");
968 return kFALSE;
969 }
970
971 // delete buffer if it is there since it will become invalid
972 if (fBuffer) BufferEmpty(1);
973
974 bool useMerge = false;
975 const bool considerMerge = (c1 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
976 const auto inconsistency = LoggedInconsistency("Add", this, h1, considerMerge);
977 // If there is a bad inconsistency and we can't even consider merging, just give up
979 return false;
980 }
981 // If there is an inconsistency, we try to use merging
984 }
985
986 if (useMerge) {
987 TList l;
988 l.Add(const_cast<TH1*>(h1));
989 auto iret = Merge(&l);
990 return (iret >= 0);
991 }
992
993 // Create Sumw2 if h1 has Sumw2 set
994 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
995 // In addition, create Sumw2 if is not a simple addition, otherwise errors will not be correctly computed
996 if (fSumw2.fN == 0 && c1 != 1.0) Sumw2();
997
998 // - Add statistics (for c1=1)
999 Double_t entries = GetEntries() + h1->GetEntries();
1000
1001 // statistics can be preserved only in case of positive coefficients
1002 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1003 Bool_t resetStats = (c1 < 0);
1004 Double_t s1[kNstat] = {0};
1005 Double_t s2[kNstat] = {0};
1006 if (!resetStats) {
1007 // need to initialize to zero s1 and s2 since
1008 // GetStats fills only used elements depending on dimension and type
1009 GetStats(s1);
1010 h1->GetStats(s2);
1011 }
1012
1013 SetMinimum();
1014 SetMaximum();
1015
1016 // - Loop on bins (including underflows/overflows)
1017 Double_t factor = 1;
1018 if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();
1019 Double_t c1sq = c1 * c1;
1020 Double_t factsq = factor * factor;
1021
1022 for (Int_t bin = 0; bin < fNcells; ++bin) {
1023 //special case where histograms have the kIsAverage bit set
1024 if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
1026 Double_t y2 = this->RetrieveBinContent(bin);
1029 Double_t w1 = 1., w2 = 1.;
1030
1031 // consider all special cases when bin errors are zero
1032 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1033 if (e1sq) w1 = 1. / e1sq;
1034 else if (h1->fSumw2.fN) {
1035 w1 = 1.E200; // use an arbitrary huge value
1036 if (y1 == 0) {
1037 // use an estimated error from the global histogram scale
1038 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1039 w1 = 1./(sf*sf);
1040 }
1041 }
1042 if (e2sq) w2 = 1. / e2sq;
1043 else if (fSumw2.fN) {
1044 w2 = 1.E200; // use an arbitrary huge value
1045 if (y2 == 0) {
1046 // use an estimated error from the global histogram scale
1047 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1048 w2 = 1./(sf*sf);
1049 }
1050 }
1051
1052 double y = (w1*y1 + w2*y2)/(w1 + w2);
1053 UpdateBinContent(bin, y);
1054 if (fSumw2.fN) {
1055 double err2 = 1./(w1 + w2);
1056 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1057 fSumw2.fArray[bin] = err2;
1058 }
1059 } else { // normal case of addition between histograms
1060 AddBinContent(bin, c1 * factor * h1->RetrieveBinContent(bin));
1061 if (fSumw2.fN) fSumw2.fArray[bin] += c1sq * factsq * h1->GetBinErrorSqUnchecked(bin);
1062 }
1063 }
1064
1065 // update statistics (do here to avoid changes by SetBinContent)
1066 if (resetStats) {
1067 // statistics need to be reset in case coefficient are negative
1068 ResetStats();
1069 }
1070 else {
1071 for (Int_t i=0;i<kNstat;i++) {
1072 if (i == 1) s1[i] += c1*c1*s2[i];
1073 else s1[i] += c1*s2[i];
1074 }
1075 PutStats(s1);
1076 if (c1 == 1.0)
1077 SetEntries(entries);
1078 else {
1079 // compute entries as effective entries in case of
1080 // weights different than 1
1081 double sumw2 = 0;
1082 double sumw = GetSumOfAllWeights(true, &sumw2);
1083 if (sumw2 > 0) SetEntries( sumw*sumw/sumw2);
1084 }
1085 }
1086 return kTRUE;
1087}
1088
1089////////////////////////////////////////////////////////////////////////////////
1090/// Replace contents of this histogram by the addition of h1 and h2.
1091///
1092/// `this = c1*h1 + c2*h2`
1093/// if errors are defined (see TH1::Sumw2), errors are also recalculated
1094///
1095/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
1096/// if not already set.
1097///
1098/// Note also that adding histogram with labels is not supported, histogram will be
1099/// added merging them by bin number independently of the labels.
1100/// For adding histogram ith labels one should use TH1::Merge
1101///
1102/// SPECIAL CASE (Average/Efficiency histograms)
1103/// For histograms representing averages or efficiencies, one should compute the average
1104/// of the two histograms and not the sum. One can mark a histogram to be an average
1105/// histogram by setting its bit kIsAverage with
1106/// myhist.SetBit(TH1::kIsAverage);
1107/// Note that the two histograms must have their kIsAverage bit set
1108///
1109/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
1110/// you should call Sumw2 before making this operation.
1111/// This is particularly important if you fit the histogram after TH1::Add
1112///
1113/// IMPORTANT NOTE2: You should be careful about the statistics of the
1114/// returned histogram, whose statistics may be binned or unbinned,
1115/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
1116/// and whether TH1::ResetStats has been called on either this or h1.
1117/// See TH1::GetStats.
1118///
1119/// ANOTHER SPECIAL CASE : h1 = h2 and c2 < 0
1120/// do a scaling this = c1 * h1 / (bin Volume)
1121///
1122/// The function returns kFALSE if the Add operation failed
1123
1125{
1126
1127 if (!h1 || !h2) {
1128 Error("Add","Attempt to add a non-existing histogram");
1129 return kFALSE;
1130 }
1131
1132 // delete buffer if it is there since it will become invalid
1133 if (fBuffer) BufferEmpty(1);
1134
1136 if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
1137
1138 if (h1 != h2) {
1139 bool useMerge = false;
1140 const bool considerMerge = (c1 == 1. && c2 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
1141
1142 // We can combine inconsistencies like this, since they are ordered and a
1143 // higher inconsistency is worse
1144 auto const inconsistency = std::max(LoggedInconsistency("Add", this, h1, considerMerge),
1145 LoggedInconsistency("Add", h1, h2, considerMerge));
1146
1147 // If there is a bad inconsistency and we can't even consider merging, just give up
1149 return false;
1150 }
1151 // If there is an inconsistency, we try to use merging
1154 }
1155
1156 if (useMerge) {
1157 TList l;
1158 // why TList takes non-const pointers ????
1159 l.Add(const_cast<TH1*>(h1));
1160 l.Add(const_cast<TH1*>(h2));
1161 Reset("ICE");
1162 auto iret = Merge(&l);
1163 return (iret >= 0);
1164 }
1165 }
1166
1167 // Create Sumw2 if h1 or h2 have Sumw2 set
1168 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
1169 // Create also Sumw2 if not a simple addition (c1 = 1, c2 = 1)
1170 if (fSumw2.fN == 0 && (c1 != 1.0 || c2 != 1.0)) Sumw2();
1171 // - Add statistics
1173
1174 // TODO remove
1175 // statistics can be preserved only in case of positive coefficients
1176 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1177 // also in case of scaling with the width we cannot preserve the statistics
1178 Double_t s1[kNstat] = {0};
1179 Double_t s2[kNstat] = {0};
1181
1182
1183 Bool_t resetStats = (c1*c2 < 0) || normWidth;
1184 if (!resetStats) {
1185 // need to initialize to zero s1 and s2 since
1186 // GetStats fills only used elements depending on dimension and type
1187 h1->GetStats(s1);
1188 h2->GetStats(s2);
1189 for (Int_t i=0;i<kNstat;i++) {
1190 if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
1191 //else s3[i] = TMath::Abs(c1)*s1[i] + TMath::Abs(c2)*s2[i];
1192 else s3[i] = c1*s1[i] + c2*s2[i];
1193 }
1194 }
1195
1196 SetMinimum();
1197 SetMaximum();
1198
1199 if (normWidth) { // DEPRECATED CASE: belongs to fitting / drawing modules
1200
1201 Int_t nbinsx = GetNbinsX() + 2; // normal bins + underflow, overflow
1202 Int_t nbinsy = GetNbinsY() + 2;
1203 Int_t nbinsz = GetNbinsZ() + 2;
1204
1205 if (fDimension < 2) nbinsy = 1;
1206 if (fDimension < 3) nbinsz = 1;
1207
1208 Int_t bin, binx, biny, binz;
1209 for (binz = 0; binz < nbinsz; ++binz) {
1211 for (biny = 0; biny < nbinsy; ++biny) {
1213 for (binx = 0; binx < nbinsx; ++binx) {
1215 bin = GetBin(binx, biny, binz);
1216 Double_t w = wx*wy*wz;
1217 UpdateBinContent(bin, c1 * h1->RetrieveBinContent(bin) / w);
1218 if (fSumw2.fN) {
1219 Double_t e1 = h1->GetBinError(bin)/w;
1220 fSumw2.fArray[bin] = c1*c1*e1*e1;
1221 }
1222 }
1223 }
1224 }
1225 } else if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
1226 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
1227 // special case where histograms have the kIsAverage bit set
1232 Double_t w1 = 1., w2 = 1.;
1233
1234 // consider all special cases when bin errors are zero
1235 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1236 if (e1sq) w1 = 1./ e1sq;
1237 else if (h1->fSumw2.fN) {
1238 w1 = 1.E200; // use an arbitrary huge value
1239 if (y1 == 0 ) { // use an estimated error from the global histogram scale
1240 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1241 w1 = 1./(sf*sf);
1242 }
1243 }
1244 if (e2sq) w2 = 1./ e2sq;
1245 else if (h2->fSumw2.fN) {
1246 w2 = 1.E200; // use an arbitrary huge value
1247 if (y2 == 0) { // use an estimated error from the global histogram scale
1248 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1249 w2 = 1./(sf*sf);
1250 }
1251 }
1252
1253 double y = (w1*y1 + w2*y2)/(w1 + w2);
1254 UpdateBinContent(i, y);
1255 if (fSumw2.fN) {
1256 double err2 = 1./(w1 + w2);
1257 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1258 fSumw2.fArray[i] = err2;
1259 }
1260 }
1261 } else { // case of simple histogram addition
1262 Double_t c1sq = c1 * c1;
1263 Double_t c2sq = c2 * c2;
1264 for (Int_t i = 0; i < fNcells; ++i) { // Loop on cells (bins including underflows/overflows)
1266 if (fSumw2.fN) {
1268 }
1269 }
1270 }
1271
1272 if (resetStats) {
1273 // statistics need to be reset in case coefficient are negative
1274 ResetStats();
1275 }
1276 else {
1277 // update statistics
1278 PutStats(s3);
1279 // previous entries are correct only if c1=1 and c2=1
1280 if (c1 == 1.0 && c2 == 1.0)
1282 else {
1283 // compute entries as effective entries in case of
1284 // weights different than 1
1285 double sumw2 = 0;
1286 double sumw = GetSumOfAllWeights(true, &sumw2);
1287 if (sumw2 > 0) SetEntries( sumw*sumw/sumw2);
1288 }
1289 }
1290
1291 return kTRUE;
1292}
1293
1294////////////////////////////////////////////////////////////////////////////////
1295/// Sets the flag controlling the automatic add of histograms in memory.
1296///
1297/// By default (fAddDirectory = kTRUE), histograms are automatically added
1298/// to the current directory (gDirectory).
1299/// Note that one histogram can be removed from its support directory
1300/// by calling h->SetDirectory(nullptr) or h->SetDirectory(dir) to add it
1301/// to the list of objects in the directory dir.
1302///
1303/// This is a static function. To call it, use `TH1::AddDirectory`
1304///
1305/// \deprecated Use ROOT::Experimental::ObjectAutoRegistrationEnabled(). It can be
1306/// set using an entry in rootrc or an environment variable, is initialised in a
1307/// thread-safe manner and covers more cases.
1308
1310{
1311 fgAddDirectory = add;
1312}
1313
1314////////////////////////////////////////////////////////////////////////////////
1315/// Auxiliary function to get the power of 2 next (larger) or previous (smaller)
1316/// a given x
1317///
1318/// next = kTRUE : next larger
1319/// next = kFALSE : previous smaller
1320///
1321/// Used by the autobin power of 2 algorithm
1322
1324{
1325 Int_t nn;
1326 Double_t f2 = std::frexp(x, &nn);
1327 return ((next && x > 0.) || (!next && x <= 0.)) ? std::ldexp(std::copysign(1., f2), nn)
1328 : std::ldexp(std::copysign(1., f2), --nn);
1329}
1330
1331////////////////////////////////////////////////////////////////////////////////
1332/// Auxiliary function to get the next power of 2 integer value larger then n
1333///
1334/// Used by the autobin power of 2 algorithm
1335
1337{
1338 Int_t nn;
1339 Double_t f2 = std::frexp(n, &nn);
1340 if (TMath::Abs(f2 - .5) > 0.001)
1341 return (Int_t)std::ldexp(1., nn);
1342 return n;
1343}
1344
1345////////////////////////////////////////////////////////////////////////////////
1346/// Buffer-based estimate of the histogram range using the power of 2 algorithm.
1347///
1348/// Used by the autobin power of 2 algorithm.
1349///
1350/// Works on arguments (min and max from fBuffer) and internal inputs: fXmin,
1351/// fXmax, NBinsX (from fXaxis), ...
1352/// Result save internally in fXaxis.
1353///
1354/// Overloaded by TH2 and TH3.
1355///
1356/// Return -1 if internal inputs are inconsistent, 0 otherwise.
1357
1359{
1360 // We need meaningful raw limits
1361 if (xmi >= xma)
1362 return -1;
1363
1364 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this, xmi, xma);
1367
1368 // Now adjust
1369 if (TMath::Abs(xhma) > TMath::Abs(xhmi)) {
1370 // Start from the upper limit
1373 } else {
1374 // Start from the lower limit
1377 }
1378
1379 // Round the bins to the next power of 2; take into account the possible inflation
1380 // of the range
1381 Double_t rr = (xhma - xhmi) / (xma - xmi);
1383
1384 // Adjust using the same bin width and offsets
1385 Double_t bw = (xhma - xhmi) / nb;
1386 // Bins to left free on each side
1387 Double_t autoside = gEnv->GetValue("Hist.Binning.Auto.Side", 0.05);
1388 Int_t nbside = (Int_t)(nb * autoside);
1389
1390 // Side up
1391 Int_t nbup = (xhma - xma) / bw;
1392 if (nbup % 2 != 0)
1393 nbup++; // Must be even
1394 if (nbup != nbside) {
1395 // Accounts also for both case: larger or smaller
1396 xhma -= bw * (nbup - nbside);
1397 nb -= (nbup - nbside);
1398 }
1399
1400 // Side low
1401 Int_t nblw = (xmi - xhmi) / bw;
1402 if (nblw % 2 != 0)
1403 nblw++; // Must be even
1404 if (nblw != nbside) {
1405 // Accounts also for both case: larger or smaller
1406 xhmi += bw * (nblw - nbside);
1407 nb -= (nblw - nbside);
1408 }
1409
1410 // Set everything and project
1411 SetBins(nb, xhmi, xhma);
1412
1413 // Done
1414 return 0;
1415}
1416
1417/// Fill histogram with all entries in the buffer.
1418///
1419/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
1420/// - action = 0 histogram is reset and filled from the buffer. When the histogram is filled from the
1421/// buffer the value fBuffer[0] is set to a negative number (= - number of entries)
1422/// When calling with action == 0 the histogram is NOT refilled when fBuffer[0] is < 0
1423/// While when calling with action = -1 the histogram is reset and ALWAYS refilled independently if
1424/// the histogram was filled before. This is needed when drawing the histogram
1425/// - action = 1 histogram is filled and buffer is deleted
1426/// The buffer is automatically deleted when filling the histogram and the entries is
1427/// larger than the buffer size
1428
1430{
1431 // do we need to compute the bin size?
1432 if (!fBuffer) return 0;
1434
1435 // nbentries correspond to the number of entries of histogram
1436
1437 if (nbentries == 0) {
1438 // if action is 1 we delete the buffer
1439 // this will avoid infinite recursion
1440 if (action > 0) {
1441 delete [] fBuffer;
1442 fBuffer = nullptr;
1443 fBufferSize = 0;
1444 }
1445 return 0;
1446 }
1447 if (nbentries < 0 && action == 0) return 0; // case histogram has been already filled from the buffer
1448
1449 Double_t *buffer = fBuffer;
1450 if (nbentries < 0) {
1452 // a reset might call BufferEmpty() giving an infinite recursion
1453 // Protect it by setting fBuffer = nullptr
1454 fBuffer = nullptr;
1455 //do not reset the list of functions
1456 Reset("ICES");
1457 fBuffer = buffer;
1458 }
1459 if (CanExtendAllAxes() || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
1460 //find min, max of entries in buffer
1463 for (Int_t i=0;i<nbentries;i++) {
1464 Double_t x = fBuffer[2*i+2];
1465 // skip infinity or NaN values
1466 if (!std::isfinite(x)) continue;
1467 if (x < xmin) xmin = x;
1468 if (x > xmax) xmax = x;
1469 }
1470 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
1471 Int_t rc = -1;
1473 if ((rc = AutoP2FindLimits(xmin, xmax)) < 0)
1474 Warning("BufferEmpty",
1475 "inconsistency found by power-of-2 autobin algorithm: fallback to standard method");
1476 }
1477 if (rc < 0)
1478 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this, xmin, xmax);
1479 } else {
1480 fBuffer = nullptr;
1483 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax, &fXaxis);
1484 fBuffer = buffer;
1485 fBufferSize = keep;
1486 }
1487 }
1488
1489 // call DoFillN which will not put entries in the buffer as FillN does
1490 // set fBuffer to zero to avoid re-emptying the buffer from functions called
1491 // by DoFillN (e.g Sumw2)
1492 buffer = fBuffer; fBuffer = nullptr;
1493 DoFillN(nbentries,&buffer[2],&buffer[1],2);
1494 fBuffer = buffer;
1495
1496 // if action == 1 - delete the buffer
1497 if (action > 0) {
1498 delete [] fBuffer;
1499 fBuffer = nullptr;
1500 fBufferSize = 0;
1501 } else {
1502 // if number of entries is consistent with buffer - set it negative to avoid
1503 // refilling the histogram every time BufferEmpty(0) is called
1504 // In case it is not consistent, by setting fBuffer[0]=0 is like resetting the buffer
1505 // (it will not be used anymore the next time BufferEmpty is called)
1506 if (nbentries == (Int_t)fEntries)
1507 fBuffer[0] = -nbentries;
1508 else
1509 fBuffer[0] = 0;
1510 }
1511 return nbentries;
1512}
1513
1514////////////////////////////////////////////////////////////////////////////////
1515/// accumulate arguments in buffer. When buffer is full, empty the buffer
1516///
1517/// - `fBuffer[0]` = number of entries in buffer
1518/// - `fBuffer[1]` = w of first entry
1519/// - `fBuffer[2]` = x of first entry
1520
1522{
1523 if (!fBuffer) return -2;
1525
1526
1527 if (nbentries < 0) {
1528 // reset nbentries to a positive value so next time BufferEmpty() is called
1529 // the histogram will be refilled
1531 fBuffer[0] = nbentries;
1532 if (fEntries > 0) {
1533 // set fBuffer to zero to avoid calling BufferEmpty in Reset
1534 Double_t *buffer = fBuffer; fBuffer=nullptr;
1535 Reset("ICES"); // do not reset list of functions
1536 fBuffer = buffer;
1537 }
1538 }
1539 if (2*nbentries+2 >= fBufferSize) {
1540 BufferEmpty(1);
1541 if (!fBuffer)
1542 // to avoid infinite recursion Fill->BufferFill->Fill
1543 return Fill(x,w);
1544 // this cannot happen
1545 R__ASSERT(0);
1546 }
1547 fBuffer[2*nbentries+1] = w;
1548 fBuffer[2*nbentries+2] = x;
1549 fBuffer[0] += 1;
1550 return -2;
1551}
1552
1553////////////////////////////////////////////////////////////////////////////////
1554/// Check bin limits.
1555
1556bool TH1::CheckBinLimits(const TAxis* a1, const TAxis * a2)
1557{
1558 const TArrayD * h1Array = a1->GetXbins();
1559 const TArrayD * h2Array = a2->GetXbins();
1560 Int_t fN = h1Array->fN;
1561 if ( fN != 0 ) {
1562 if ( h2Array->fN != fN ) {
1563 return false;
1564 }
1565 else {
1566 for ( int i = 0; i < fN; ++i ) {
1567 // for i==fN (nbin+1) a->GetBinWidth() returns last bin width
1568 // we do not need to exclude that case
1569 double binWidth = a1->GetBinWidth(i);
1570 if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), binWidth*1E-10 ) ) {
1571 return false;
1572 }
1573 }
1574 }
1575 }
1576
1577 return true;
1578}
1579
1580////////////////////////////////////////////////////////////////////////////////
1581/// Check that axis have same labels.
1582
1583bool TH1::CheckBinLabels(const TAxis* a1, const TAxis * a2)
1584{
1585 THashList *l1 = a1->GetLabels();
1586 THashList *l2 = a2->GetLabels();
1587
1588 if (!l1 && !l2 )
1589 return true;
1590 if (!l1 || !l2 ) {
1591 return false;
1592 }
1593 // check now labels sizes are the same
1594 if (l1->GetSize() != l2->GetSize() ) {
1595 return false;
1596 }
1597 for (int i = 1; i <= a1->GetNbins(); ++i) {
1598 TString label1 = a1->GetBinLabel(i);
1599 TString label2 = a2->GetBinLabel(i);
1600 if (label1 != label2) {
1601 return false;
1602 }
1603 }
1604
1605 return true;
1606}
1607
1608////////////////////////////////////////////////////////////////////////////////
1609/// Check that the axis limits of the histograms are the same.
1610/// If a first and last bin is passed the axis is compared between the given range
1611
1612bool TH1::CheckAxisLimits(const TAxis *a1, const TAxis *a2 )
1613{
1614 double firstBin = a1->GetBinWidth(1);
1615 double lastBin = a1->GetBinWidth( a1->GetNbins() );
1616 if ( ! TMath::AreEqualAbs(a1->GetXmin(), a2->GetXmin(), firstBin* 1.E-10) ||
1617 ! TMath::AreEqualAbs(a1->GetXmax(), a2->GetXmax(), lastBin*1.E-10) ) {
1618 return false;
1619 }
1620 return true;
1621}
1622
1623////////////////////////////////////////////////////////////////////////////////
1624/// Check that the axis are the same
1625
1626bool TH1::CheckEqualAxes(const TAxis *a1, const TAxis *a2 )
1627{
1628 if (a1->GetNbins() != a2->GetNbins() ) {
1629 ::Info("CheckEqualAxes","Axes have different number of bins : nbin1 = %d nbin2 = %d",a1->GetNbins(),a2->GetNbins() );
1630 return false;
1631 }
1632 if(!CheckAxisLimits(a1,a2)) {
1633 ::Info("CheckEqualAxes","Axes have different limits");
1634 return false;
1635 }
1636 if(!CheckBinLimits(a1,a2)) {
1637 ::Info("CheckEqualAxes","Axes have different bin limits");
1638 return false;
1639 }
1640
1641 // check labels
1642 if(!CheckBinLabels(a1,a2)) {
1643 ::Info("CheckEqualAxes","Axes have different labels");
1644 return false;
1645 }
1646
1647 return true;
1648}
1649
1650////////////////////////////////////////////////////////////////////////////////
1651/// Check that two sub axis are the same.
1652/// The limits are defined by first bin and last bin
1653/// N.B. no check is done in this case for variable bins
1654
1656{
1657 // By default is assumed that no bins are given for the second axis
1659 Double_t xmin1 = a1->GetBinLowEdge(firstBin1);
1660 Double_t xmax1 = a1->GetBinUpEdge(lastBin1);
1661
1662 Int_t nbins2 = a2->GetNbins();
1663 Double_t xmin2 = a2->GetXmin();
1664 Double_t xmax2 = a2->GetXmax();
1665
1666 if (firstBin2 < lastBin2) {
1667 // in this case assume no bins are given for the second axis
1669 xmin2 = a1->GetBinLowEdge(firstBin1);
1670 xmax2 = a1->GetBinUpEdge(lastBin1);
1671 }
1672
1673 if (nbins1 != nbins2 ) {
1674 ::Info("CheckConsistentSubAxes","Axes have different number of bins");
1675 return false;
1676 }
1677
1678 Double_t firstBin = a1->GetBinWidth(firstBin1);
1679 Double_t lastBin = a1->GetBinWidth(lastBin1);
1680 if ( ! TMath::AreEqualAbs(xmin1,xmin2,1.E-10 * firstBin) ||
1681 ! TMath::AreEqualAbs(xmax1,xmax2,1.E-10 * lastBin) ) {
1682 ::Info("CheckConsistentSubAxes","Axes have different limits");
1683 return false;
1684 }
1685
1686 return true;
1687}
1688
1689////////////////////////////////////////////////////////////////////////////////
1690/// Check histogram compatibility.
1691/// The returned integer is part of EInconsistencyBits
1692/// The value 0 means that the histograms are compatible
1693
1695{
1696 if (h1 == h2) return kFullyConsistent;
1697
1698 if (h1->GetDimension() != h2->GetDimension() ) {
1699 return kDifferentDimensions;
1700 }
1701 Int_t dim = h1->GetDimension();
1702
1703 // returns kTRUE if number of bins and bin limits are identical
1704 Int_t nbinsx = h1->GetNbinsX();
1705 Int_t nbinsy = h1->GetNbinsY();
1706 Int_t nbinsz = h1->GetNbinsZ();
1707
1708 // Check whether the histograms have the same number of bins.
1709 if (nbinsx != h2->GetNbinsX() ||
1710 (dim > 1 && nbinsy != h2->GetNbinsY()) ||
1711 (dim > 2 && nbinsz != h2->GetNbinsZ()) ) {
1713 }
1714
1715 bool ret = true;
1716
1717 // check axis limits
1718 ret &= CheckAxisLimits(h1->GetXaxis(), h2->GetXaxis());
1719 if (dim > 1) ret &= CheckAxisLimits(h1->GetYaxis(), h2->GetYaxis());
1720 if (dim > 2) ret &= CheckAxisLimits(h1->GetZaxis(), h2->GetZaxis());
1721 if (!ret) return kDifferentAxisLimits;
1722
1723 // check bin limits
1724 ret &= CheckBinLimits(h1->GetXaxis(), h2->GetXaxis());
1725 if (dim > 1) ret &= CheckBinLimits(h1->GetYaxis(), h2->GetYaxis());
1726 if (dim > 2) ret &= CheckBinLimits(h1->GetZaxis(), h2->GetZaxis());
1727 if (!ret) return kDifferentBinLimits;
1728
1729 // check labels if histograms are both not empty
1730 if ( !h1->IsEmpty() && !h2->IsEmpty() ) {
1731 ret &= CheckBinLabels(h1->GetXaxis(), h2->GetXaxis());
1732 if (dim > 1) ret &= CheckBinLabels(h1->GetYaxis(), h2->GetYaxis());
1733 if (dim > 2) ret &= CheckBinLabels(h1->GetZaxis(), h2->GetZaxis());
1734 if (!ret) return kDifferentLabels;
1735 }
1736
1737 return kFullyConsistent;
1738}
1739
1740////////////////////////////////////////////////////////////////////////////////
1741/// \f$ \chi^{2} \f$ test for comparing weighted and unweighted histograms.
1742///
1743/// Compares the histograms' adjusted (normalized) residuals.
1744/// Function: Returns p-value. Other return values are specified by the 3rd parameter
1745///
1746/// \param[in] h2 the second histogram
1747/// \param[in] option
1748/// - "UU" = experiment experiment comparison (unweighted-unweighted)
1749/// - "UW" = experiment MC comparison (unweighted-weighted). Note that
1750/// the first histogram should be unweighted
1751/// - "WW" = MC MC comparison (weighted-weighted)
1752/// - "NORM" = to be used when one or both of the histograms is scaled
1753/// but the histogram originally was unweighted
1754/// - by default underflows and overflows are not included:
1755/// * "OF" = overflows included
1756/// * "UF" = underflows included
1757/// - "P" = print chi2, ndf, p_value, igood
1758/// - "CHI2" = returns chi2 instead of p-value
1759/// - "CHI2/NDF" = returns \f$ \chi^{2} \f$/ndf
1760/// \param[in] res not empty - computes normalized residuals and returns them in this array
1761///
1762/// The current implementation is based on the papers \f$ \chi^{2} \f$ test for comparison
1763/// of weighted and unweighted histograms" in Proceedings of PHYSTAT05 and
1764/// "Comparison weighted and unweighted histograms", arXiv:physics/0605123
1765/// by N.Gagunashvili. This function has been implemented by Daniel Haertl in August 2006.
1766///
1767/// #### Introduction:
1768///
1769/// A frequently used technique in data analysis is the comparison of
1770/// histograms. First suggested by Pearson [1] the \f$ \chi^{2} \f$ test of
1771/// homogeneity is used widely for comparing usual (unweighted) histograms.
1772/// This paper describes the implementation modified \f$ \chi^{2} \f$ tests
1773/// for comparison of weighted and unweighted histograms and two weighted
1774/// histograms [2] as well as usual Pearson's \f$ \chi^{2} \f$ test for
1775/// comparison two usual (unweighted) histograms.
1776///
1777/// #### Overview:
1778///
1779/// Comparison of two histograms expect hypotheses that two histograms
1780/// represent identical distributions. To make a decision p-value should
1781/// be calculated. The hypotheses of identity is rejected if the p-value is
1782/// lower then some significance level. Traditionally significance levels
1783/// 0.1, 0.05 and 0.01 are used. The comparison procedure should include an
1784/// analysis of the residuals which is often helpful in identifying the
1785/// bins of histograms responsible for a significant overall \f$ \chi^{2} \f$ value.
1786/// Residuals are the difference between bin contents and expected bin
1787/// contents. Most convenient for analysis are the normalized residuals. If
1788/// hypotheses of identity are valid then normalized residuals are
1789/// approximately independent and identically distributed random variables
1790/// having N(0,1) distribution. Analysis of residuals expect test of above
1791/// mentioned properties of residuals. Notice that indirectly the analysis
1792/// of residuals increase the power of \f$ \chi^{2} \f$ test.
1793///
1794/// #### Methods of comparison:
1795///
1796/// \f$ \chi^{2} \f$ test for comparison two (unweighted) histograms:
1797/// Let us consider two histograms with the same binning and the number
1798/// of bins equal to r. Let us denote the number of events in the ith bin
1799/// in the first histogram as ni and as mi in the second one. The total
1800/// number of events in the first histogram is equal to:
1801/// \f[
1802/// N = \sum_{i=1}^{r} n_{i}
1803/// \f]
1804/// and
1805/// \f[
1806/// M = \sum_{i=1}^{r} m_{i}
1807/// \f]
1808/// in the second histogram. The hypothesis of identity (homogeneity) [3]
1809/// is that the two histograms represent random values with identical
1810/// distributions. It is equivalent that there exist r constants p1,...,pr,
1811/// such that
1812/// \f[
1813///\sum_{i=1}^{r} p_{i}=1
1814/// \f]
1815/// and the probability of belonging to the ith bin for some measured value
1816/// in both experiments is equal to pi. The number of events in the ith
1817/// bin is a random variable with a distribution approximated by a Poisson
1818/// probability distribution
1819/// \f[
1820///\frac{e^{-Np_{i}}(Np_{i})^{n_{i}}}{n_{i}!}
1821/// \f]
1822///for the first histogram and with distribution
1823/// \f[
1824///\frac{e^{-Mp_{i}}(Mp_{i})^{m_{i}}}{m_{i}!}
1825/// \f]
1826/// for the second histogram. If the hypothesis of homogeneity is valid,
1827/// then the maximum likelihood estimator of pi, i=1,...,r, is
1828/// \f[
1829///\hat{p}_{i}= \frac{n_{i}+m_{i}}{N+M}
1830/// \f]
1831/// and then
1832/// \f[
1833/// 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}}
1834/// \f]
1835/// has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [3].
1836/// The comparison procedure can include an analysis of the residuals which
1837/// is often helpful in identifying the bins of histograms responsible for
1838/// a significant overall \f$ \chi^{2} \f$ value. Most convenient for
1839/// analysis are the adjusted (normalized) residuals [4]
1840/// \f[
1841/// 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))}}
1842/// \f]
1843/// If hypotheses of homogeneity are valid then residuals ri are
1844/// approximately independent and identically distributed random variables
1845/// having N(0,1) distribution. The application of the \f$ \chi^{2} \f$ test has
1846/// restrictions related to the value of the expected frequencies Npi,
1847/// Mpi, i=1,...,r. A conservative rule formulated in [5] is that all the
1848/// expectations must be 1 or greater for both histograms. In practical
1849/// cases when expected frequencies are not known the estimated expected
1850/// frequencies \f$ M\hat{p}_{i}, N\hat{p}_{i}, i=1,...,r \f$ can be used.
1851///
1852/// #### Unweighted and weighted histograms comparison:
1853///
1854/// A simple modification of the ideas described above can be used for the
1855/// comparison of the usual (unweighted) and weighted histograms. Let us
1856/// denote the number of events in the ith bin in the unweighted
1857/// histogram as ni and the common weight of events in the ith bin of the
1858/// weighted histogram as wi. The total number of events in the
1859/// unweighted histogram is equal to
1860///\f[
1861/// N = \sum_{i=1}^{r} n_{i}
1862///\f]
1863/// and the total weight of events in the weighted histogram is equal to
1864///\f[
1865/// W = \sum_{i=1}^{r} w_{i}
1866///\f]
1867/// Let us formulate the hypothesis of identity of an unweighted histogram
1868/// to a weighted histogram so that there exist r constants p1,...,pr, such
1869/// that
1870///\f[
1871/// \sum_{i=1}^{r} p_{i} = 1
1872///\f]
1873/// for the unweighted histogram. The weight wi is a random variable with a
1874/// distribution approximated by the normal probability distribution
1875/// \f$ N(Wp_{i},\sigma_{i}^{2}) \f$ where \f$ \sigma_{i}^{2} \f$ is the variance of the weight wi.
1876/// If we replace the variance \f$ \sigma_{i}^{2} \f$
1877/// with estimate \f$ s_{i}^{2} \f$ (sum of squares of weights of
1878/// events in the ith bin) and the hypothesis of identity is valid, then the
1879/// maximum likelihood estimator of pi,i=1,...,r, is
1880///\f[
1881/// \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}}
1882///\f]
1883/// We may then use the test statistic
1884///\f[
1885/// 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}}
1886///\f]
1887/// and it has approximately a \f$ \sigma^{2}_{(r-1)} \f$ distribution [2]. This test, as well
1888/// as the original one [3], has a restriction on the expected frequencies. The
1889/// expected frequencies recommended for the weighted histogram is more than 25.
1890/// The value of the minimal expected frequency can be decreased down to 10 for
1891/// the case when the weights of the events are close to constant. In the case
1892/// of a weighted histogram if the number of events is unknown, then we can
1893/// apply this recommendation for the equivalent number of events as
1894///\f[
1895/// n_{i}^{equiv} = \frac{ w_{i}^{2} }{ s_{i}^{2} }
1896///\f]
1897/// The minimal expected frequency for an unweighted histogram must be 1. Notice
1898/// that any usual (unweighted) histogram can be considered as a weighted
1899/// histogram with events that have constant weights equal to 1.
1900/// The variance \f$ z_{i}^{2} \f$ of the difference between the weight wi
1901/// and the estimated expectation value of the weight is approximately equal to:
1902///\f[
1903/// 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}
1904///\f]
1905/// The residuals
1906///\f[
1907/// r_{i} = \frac{w_{i}-W\hat{p}_{i}}{z_{i}}
1908///\f]
1909/// have approximately a normal distribution with mean equal to 0 and standard
1910/// deviation equal to 1.
1911///
1912/// #### Two weighted histograms comparison:
1913///
1914/// Let us denote the common weight of events of the ith bin in the first
1915/// histogram as w1i and as w2i in the second one. The total weight of events
1916/// in the first histogram is equal to
1917///\f[
1918/// W_{1} = \sum_{i=1}^{r} w_{1i}
1919///\f]
1920/// and
1921///\f[
1922/// W_{2} = \sum_{i=1}^{r} w_{2i}
1923///\f]
1924/// in the second histogram. Let us formulate the hypothesis of identity of
1925/// weighted histograms so that there exist r constants p1,...,pr, such that
1926///\f[
1927/// \sum_{i=1}^{r} p_{i} = 1
1928///\f]
1929/// and also expectation value of weight w1i equal to W1pi and expectation value
1930/// of weight w2i equal to W2pi. Weights in both the histograms are random
1931/// variables with distributions which can be approximated by a normal
1932/// probability distribution \f$ N(W_{1}p_{i},\sigma_{1i}^{2}) \f$ for the first histogram
1933/// and by a distribution \f$ N(W_{2}p_{i},\sigma_{2i}^{2}) \f$ for the second.
1934/// Here \f$ \sigma_{1i}^{2} \f$ and \f$ \sigma_{2i}^{2} \f$ are the variances
1935/// of w1i and w2i with estimators \f$ s_{1i}^{2} \f$ and \f$ s_{2i}^{2} \f$ respectively.
1936/// If the hypothesis of identity is valid, then the maximum likelihood and
1937/// Least Square Method estimator of pi,i=1,...,r, is
1938///\f[
1939/// \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}}
1940///\f]
1941/// We may then use the test statistic
1942///\f[
1943/// 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}}
1944///\f]
1945/// and it has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [2].
1946/// The normalized or studentised residuals [6]
1947///\f[
1948/// 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})}}}
1949///\f]
1950/// have approximately a normal distribution with mean equal to 0 and standard
1951/// deviation 1. A recommended minimal expected frequency is equal to 10 for
1952/// the proposed test.
1953///
1954/// #### Numerical examples:
1955///
1956/// The method described herein is now illustrated with an example.
1957/// We take a distribution
1958///\f[
1959/// \phi(x) = \frac{2}{(x-10)^{2}+1} + \frac{1}{(x-14)^{2}+1} (1)
1960///\f]
1961/// defined on the interval [4,16]. Events distributed according to the formula
1962/// (1) are simulated to create the unweighted histogram. Uniformly distributed
1963/// events are simulated for the weighted histogram with weights calculated by
1964/// formula (1). Each histogram has the same number of bins: 20. Fig.1 shows
1965/// the result of comparison of the unweighted histogram with 200 events
1966/// (minimal expected frequency equal to one) and the weighted histogram with
1967/// 500 events (minimal expected frequency equal to 25)
1968/// Begin_Macro
1969/// ../../../tutorials/math/chi2test.C
1970/// End_Macro
1971/// Fig 1. An example of comparison of the unweighted histogram with 200 events
1972/// and the weighted histogram with 500 events:
1973/// 1. unweighted histogram;
1974/// 2. weighted histogram;
1975/// 3. normalized residuals plot;
1976/// 4. normal Q-Q plot of residuals.
1977///
1978/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1979/// 21.09 with p-value equal to 0.33, therefore the hypothesis of identity of
1980/// the two histograms can be accepted for 0.05 significant level. The behavior
1981/// of the normalized residuals plot (see Fig. 1c) and the normal Q-Q plot
1982/// (see Fig. 1d) of residuals are regular and we cannot identify the outliers
1983/// or bins with a big influence on \f$ \chi^{2} \f$.
1984///
1985/// The second example presents the same two histograms but 17 events was added
1986/// to content of bin number 15 in unweighted histogram. Fig.2 shows the result
1987/// of comparison of the unweighted histogram with 217 events (minimal expected
1988/// frequency equal to one) and the weighted histogram with 500 events (minimal
1989/// expected frequency equal to 25)
1990/// Begin_Macro
1991/// ../../../tutorials/math/chi2test.C(17)
1992/// End_Macro
1993/// Fig 2. An example of comparison of the unweighted histogram with 217 events
1994/// and the weighted histogram with 500 events:
1995/// 1. unweighted histogram;
1996/// 2. weighted histogram;
1997/// 3. normalized residuals plot;
1998/// 4. normal Q-Q plot of residuals.
1999///
2000/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
2001/// 32.33 with p-value equal to 0.029, therefore the hypothesis of identity of
2002/// the two histograms is rejected for 0.05 significant level. The behavior of
2003/// the normalized residuals plot (see Fig. 2c) and the normal Q-Q plot (see
2004/// Fig. 2d) of residuals are not regular and we can identify the outlier or
2005/// bin with a big influence on \f$ \chi^{2} \f$.
2006///
2007/// #### References:
2008///
2009/// - [1] Pearson, K., 1904. On the Theory of Contingency and Its Relation to
2010/// Association and Normal Correlation. Drapers' Co. Memoirs, Biometric
2011/// Series No. 1, London.
2012/// - [2] Gagunashvili, N., 2006. \f$ \sigma^{2} \f$ test for comparison
2013/// of weighted and unweighted histograms. Statistical Problems in Particle
2014/// Physics, Astrophysics and Cosmology, Proceedings of PHYSTAT05,
2015/// Oxford, UK, 12-15 September 2005, Imperial College Press, London, 43-44.
2016/// Gagunashvili,N., Comparison of weighted and unweighted histograms,
2017/// arXiv:physics/0605123, 2006.
2018/// - [3] Cramer, H., 1946. Mathematical methods of statistics.
2019/// Princeton University Press, Princeton.
2020/// - [4] Haberman, S.J., 1973. The analysis of residuals in cross-classified tables.
2021/// Biometrics 29, 205-220.
2022/// - [5] Lewontin, R.C. and Felsenstein, J., 1965. The robustness of homogeneity
2023/// test in 2xN tables. Biometrics 21, 19-33.
2024/// - [6] Seber, G.A.F., Lee, A.J., 2003, Linear Regression Analysis.
2025/// John Wiley & Sons Inc., New York.
2026
2027Double_t TH1::Chi2Test(const TH1* h2, Option_t *option, Double_t *res) const
2028{
2029 Double_t chi2 = 0;
2030 Int_t ndf = 0, igood = 0;
2031
2032 TString opt = option;
2033 opt.ToUpper();
2034
2035 Double_t prob = Chi2TestX(h2,chi2,ndf,igood,option,res);
2036
2037 if(opt.Contains("P")) {
2038 printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
2039 }
2040 if(opt.Contains("CHI2/NDF")) {
2041 if (ndf == 0) return 0;
2042 return chi2/ndf;
2043 }
2044 if(opt.Contains("CHI2")) {
2045 return chi2;
2046 }
2047
2048 return prob;
2049}
2050
2051////////////////////////////////////////////////////////////////////////////////
2052/// The computation routine of the Chisquare test. For the method description,
2053/// see Chi2Test() function.
2054///
2055/// \return p-value
2056/// \param[in] h2 the second histogram
2057/// \param[in] option
2058/// - "UU" = experiment experiment comparison (unweighted-unweighted)
2059/// - "UW" = experiment MC comparison (unweighted-weighted). Note that the first
2060/// histogram should be unweighted
2061/// - "WW" = MC MC comparison (weighted-weighted)
2062/// - "NORM" = if one or both histograms is scaled
2063/// - "OF" = overflows included
2064/// - "UF" = underflows included
2065/// by default underflows and overflows are not included
2066/// \param[out] igood test output
2067/// - igood=0 - no problems
2068/// - For unweighted unweighted comparison
2069/// - igood=1'There is a bin in the 1st histogram with less than 1 event'
2070/// - igood=2'There is a bin in the 2nd histogram with less than 1 event'
2071/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2072/// - For unweighted weighted comparison
2073/// - igood=1'There is a bin in the 1st histogram with less then 1 event'
2074/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective number of events'
2075/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2076/// - For weighted weighted comparison
2077/// - igood=1'There is a bin in the 1st histogram with less then 10 effective
2078/// number of events'
2079/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective
2080/// number of events'
2081/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2082/// \param[out] chi2 chisquare of the test
2083/// \param[out] ndf number of degrees of freedom (important, when both histograms have the same empty bins)
2084/// \param[out] res normalized residuals for further analysis
2085
2086Double_t TH1::Chi2TestX(const TH1* h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option, Double_t *res) const
2087{
2088
2092
2093 Double_t sum1 = 0.0, sumw1 = 0.0;
2094 Double_t sum2 = 0.0, sumw2 = 0.0;
2095
2096 chi2 = 0.0;
2097 ndf = 0;
2098
2099 TString opt = option;
2100 opt.ToUpper();
2101
2102 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
2103
2104 const TAxis *xaxis1 = GetXaxis();
2105 const TAxis *xaxis2 = h2->GetXaxis();
2106 const TAxis *yaxis1 = GetYaxis();
2107 const TAxis *yaxis2 = h2->GetYaxis();
2108 const TAxis *zaxis1 = GetZaxis();
2109 const TAxis *zaxis2 = h2->GetZaxis();
2110
2111 Int_t nbinx1 = xaxis1->GetNbins();
2112 Int_t nbinx2 = xaxis2->GetNbins();
2113 Int_t nbiny1 = yaxis1->GetNbins();
2114 Int_t nbiny2 = yaxis2->GetNbins();
2115 Int_t nbinz1 = zaxis1->GetNbins();
2116 Int_t nbinz2 = zaxis2->GetNbins();
2117
2118 //check dimensions
2119 if (this->GetDimension() != h2->GetDimension() ){
2120 Error("Chi2TestX","Histograms have different dimensions.");
2121 return 0.0;
2122 }
2123
2124 //check number of channels
2125 if (nbinx1 != nbinx2) {
2126 Error("Chi2TestX","different number of x channels");
2127 }
2128 if (nbiny1 != nbiny2) {
2129 Error("Chi2TestX","different number of y channels");
2130 }
2131 if (nbinz1 != nbinz2) {
2132 Error("Chi2TestX","different number of z channels");
2133 }
2134
2135 //check for ranges
2136 i_start = j_start = k_start = 1;
2137 i_end = nbinx1;
2138 j_end = nbiny1;
2139 k_end = nbinz1;
2140
2141 if (xaxis1->TestBit(TAxis::kAxisRange)) {
2142 i_start = xaxis1->GetFirst();
2143 i_end = xaxis1->GetLast();
2144 }
2145 if (yaxis1->TestBit(TAxis::kAxisRange)) {
2146 j_start = yaxis1->GetFirst();
2147 j_end = yaxis1->GetLast();
2148 }
2149 if (zaxis1->TestBit(TAxis::kAxisRange)) {
2150 k_start = zaxis1->GetFirst();
2151 k_end = zaxis1->GetLast();
2152 }
2153
2154
2155 if (opt.Contains("OF")) {
2156 if (GetDimension() == 3) k_end = ++nbinz1;
2157 if (GetDimension() >= 2) j_end = ++nbiny1;
2158 if (GetDimension() >= 1) i_end = ++nbinx1;
2159 }
2160
2161 if (opt.Contains("UF")) {
2162 if (GetDimension() == 3) k_start = 0;
2163 if (GetDimension() >= 2) j_start = 0;
2164 if (GetDimension() >= 1) i_start = 0;
2165 }
2166
2167 ndf = (i_end - i_start + 1) * (j_end - j_start + 1) * (k_end - k_start + 1) - 1;
2168
2169 Bool_t comparisonUU = opt.Contains("UU");
2170 Bool_t comparisonUW = opt.Contains("UW");
2171 Bool_t comparisonWW = opt.Contains("WW");
2172 Bool_t scaledHistogram = opt.Contains("NORM");
2173
2174 if (scaledHistogram && !comparisonUU) {
2175 Info("Chi2TestX", "NORM option should be used together with UU option. It is ignored");
2176 }
2177
2178 // look at histo global bin content and effective entries
2179 Stat_t s[kNstat];
2180 GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2181 Double_t sumBinContent1 = s[0];
2182 Double_t effEntries1 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2183
2184 h2->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2185 Double_t sumBinContent2 = s[0];
2186 Double_t effEntries2 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2187
2188 if (!comparisonUU && !comparisonUW && !comparisonWW ) {
2189 // deduce automatically from type of histogram
2192 else comparisonUW = true;
2193 }
2194 else comparisonWW = true;
2195 }
2196 // check unweighted histogram
2197 if (comparisonUW) {
2199 Warning("Chi2TestX","First histogram is not unweighted and option UW has been requested");
2200 }
2201 }
2202 if ( (!scaledHistogram && comparisonUU) ) {
2204 Warning("Chi2TestX","Both histograms are not unweighted and option UU has been requested");
2205 }
2206 }
2207
2208
2209 //get number of events in histogram
2211 for (Int_t i = i_start; i <= i_end; ++i) {
2212 for (Int_t j = j_start; j <= j_end; ++j) {
2213 for (Int_t k = k_start; k <= k_end; ++k) {
2214
2215 Int_t bin = GetBin(i, j, k);
2216
2218 Double_t cnt2 = h2->RetrieveBinContent(bin);
2221
2222 if (e1sq > 0.0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2223 else cnt1 = 0.0;
2224
2225 if (e2sq > 0.0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2226 else cnt2 = 0.0;
2227
2228 // sum contents
2229 sum1 += cnt1;
2230 sum2 += cnt2;
2231 sumw1 += e1sq;
2232 sumw2 += e2sq;
2233 }
2234 }
2235 }
2236 if (sumw1 <= 0.0 || sumw2 <= 0.0) {
2237 Error("Chi2TestX", "Cannot use option NORM when one histogram has all zero errors");
2238 return 0.0;
2239 }
2240
2241 } else {
2242 for (Int_t i = i_start; i <= i_end; ++i) {
2243 for (Int_t j = j_start; j <= j_end; ++j) {
2244 for (Int_t k = k_start; k <= k_end; ++k) {
2245
2246 Int_t bin = GetBin(i, j, k);
2247
2248 sum1 += RetrieveBinContent(bin);
2249 sum2 += h2->RetrieveBinContent(bin);
2250
2253 }
2254 }
2255 }
2256 }
2257 //checks that the histograms are not empty
2258 if (sum1 == 0.0 || sum2 == 0.0) {
2259 Error("Chi2TestX","one histogram is empty");
2260 return 0.0;
2261 }
2262
2263 if ( comparisonWW && ( sumw1 <= 0.0 && sumw2 <= 0.0 ) ){
2264 Error("Chi2TestX","Hist1 and Hist2 have both all zero errors\n");
2265 return 0.0;
2266 }
2267
2268 //THE TEST
2269 Int_t m = 0, n = 0;
2270 //Experiment - experiment comparison
2271 if (comparisonUU) {
2272 Int_t resIndex = 0;
2273 Double_t sum = sum1 + sum2;
2274 for (Int_t i = i_start; i <= i_end; ++i) {
2275 for (Int_t j = j_start; j <= j_end; ++j) {
2276 for (Int_t k = k_start; k <= k_end; ++k) {
2277
2278 Int_t bin = GetBin(i, j, k);
2279
2281 Double_t cnt2 = h2->RetrieveBinContent(bin);
2282
2283 if (scaledHistogram) {
2284 // scale bin value to effective bin entries
2287
2288 if (e1sq > 0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2289 else cnt1 = 0;
2290
2291 if (e2sq > 0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2292 else cnt2 = 0;
2293 }
2294
2295 if (Int_t(cnt1) == 0 && Int_t(cnt2) == 0) --ndf; // no data means one degree of freedom less
2296 else {
2297
2300 //Double_t nexp2 = binsum*sum2/sum;
2301
2302 if (res) res[resIndex] = (cnt1 - nexp1) / TMath::Sqrt(nexp1);
2303
2304 if (cnt1 < 1) ++m;
2305 if (cnt2 < 1) ++n;
2306
2307 //Habermann correction for residuals
2308 Double_t correc = (1. - sum1 / sum) * (1. - cntsum / sum);
2309 if (res) res[resIndex] /= TMath::Sqrt(correc);
2310 if (res) resIndex++;
2311 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2312 chi2 += delta * delta / cntsum;
2313 }
2314 }
2315 }
2316 }
2317 chi2 /= sum1 * sum2;
2318
2319 // flag error only when of the two histogram is zero
2320 if (m) {
2321 igood += 1;
2322 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2323 }
2324 if (n) {
2325 igood += 2;
2326 Info("Chi2TestX","There is a bin in h2 with less than 1 event.\n");
2327 }
2328
2330 return prob;
2331
2332 }
2333
2334 // unweighted - weighted comparison
2335 // case of error = 0 and content not zero is treated without problems by excluding second chi2 sum
2336 // and can be considered as a data-theory comparison
2337 if ( comparisonUW ) {
2338 Int_t resIndex = 0;
2339 for (Int_t i = i_start; i <= i_end; ++i) {
2340 for (Int_t j = j_start; j <= j_end; ++j) {
2341 for (Int_t k = k_start; k <= k_end; ++k) {
2342
2343 Int_t bin = GetBin(i, j, k);
2344
2346 Double_t cnt2 = h2->RetrieveBinContent(bin);
2348
2349 // case both histogram have zero bin contents
2350 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2351 --ndf; //no data means one degree of freedom less
2352 continue;
2353 }
2354
2355 // case weighted histogram has zero bin content and error
2356 if (cnt2 * cnt2 == 0 && e2sq == 0) {
2357 if (sumw2 > 0) {
2358 // use as approximated error as 1 scaled by a scaling ratio
2359 // estimated from the total sum weight and sum weight squared
2360 e2sq = sumw2 / sum2;
2361 }
2362 else {
2363 // return error because infinite discrepancy here:
2364 // bin1 != 0 and bin2 =0 in a histogram with all errors zero
2365 Error("Chi2TestX","Hist2 has in bin (%d,%d,%d) zero content and zero errors\n", i, j, k);
2366 chi2 = 0; return 0;
2367 }
2368 }
2369
2370 if (cnt1 < 1) m++;
2371 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2372
2373 Double_t var1 = sum2 * cnt2 - sum1 * e2sq;
2374 Double_t var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2375
2376 // if cnt1 is zero and cnt2 = 1 and sum1 = sum2 var1 = 0 && var2 == 0
2377 // approximate by incrementing cnt1
2378 // LM (this need to be fixed for numerical errors)
2379 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2380 sum1++;
2381 cnt1++;
2382 var1 = sum2 * cnt2 - sum1 * e2sq;
2383 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2384 }
2386
2387 while (var1 + var2 == 0) {
2388 sum1++;
2389 cnt1++;
2390 var1 = sum2 * cnt2 - sum1 * e2sq;
2391 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2392 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2393 sum1++;
2394 cnt1++;
2395 var1 = sum2 * cnt2 - sum1 * e2sq;
2396 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2397 }
2399 }
2400
2401 Double_t probb = (var1 + var2) / (2. * sum2 * sum2);
2402
2405
2408
2409 chi2 += delta1 * delta1 / nexp1;
2410
2411 if (e2sq > 0) {
2412 chi2 += delta2 * delta2 / e2sq;
2413 }
2414
2415 if (res) {
2416 if (e2sq > 0) {
2417 Double_t temp1 = sum2 * e2sq / var2;
2418 Double_t temp2 = 1.0 + (sum1 * e2sq - sum2 * cnt2) / var2;
2419 temp2 = temp1 * temp1 * sum1 * probb * (1.0 - probb) + temp2 * temp2 * e2sq / 4.0;
2420 // invert sign here
2421 res[resIndex] = - delta2 / TMath::Sqrt(temp2);
2422 }
2423 else
2424 res[resIndex] = delta1 / TMath::Sqrt(nexp1);
2425 resIndex++;
2426 }
2427 }
2428 }
2429 }
2430
2431 if (m) {
2432 igood += 1;
2433 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2434 }
2435 if (n) {
2436 igood += 2;
2437 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2438 }
2439
2440 Double_t prob = TMath::Prob(chi2, ndf);
2441
2442 return prob;
2443 }
2444
2445 // weighted - weighted comparison
2446 if (comparisonWW) {
2447 Int_t resIndex = 0;
2448 for (Int_t i = i_start; i <= i_end; ++i) {
2449 for (Int_t j = j_start; j <= j_end; ++j) {
2450 for (Int_t k = k_start; k <= k_end; ++k) {
2451
2452 Int_t bin = GetBin(i, j, k);
2454 Double_t cnt2 = h2->RetrieveBinContent(bin);
2457
2458 // case both histogram have zero bin contents
2459 // (use square of content to avoid numerical errors)
2460 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2461 --ndf; //no data means one degree of freedom less
2462 continue;
2463 }
2464
2465 if (e1sq == 0 && e2sq == 0) {
2466 // cannot treat case of booth histogram have zero zero errors
2467 Error("Chi2TestX","h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
2468 chi2 = 0; return 0;
2469 }
2470
2471 Double_t sigma = sum1 * sum1 * e2sq + sum2 * sum2 * e1sq;
2472 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2473 chi2 += delta * delta / sigma;
2474
2475 if (res) {
2476 Double_t temp = cnt1 * sum1 * e2sq + cnt2 * sum2 * e1sq;
2477 Double_t probb = temp / sigma;
2478 Double_t z = 0;
2479 if (e1sq > e2sq) {
2480 Double_t d1 = cnt1 - sum1 * probb;
2481 Double_t s1 = e1sq * ( 1. - e2sq * sum1 * sum1 / sigma );
2482 z = d1 / TMath::Sqrt(s1);
2483 }
2484 else {
2485 Double_t d2 = cnt2 - sum2 * probb;
2486 Double_t s2 = e2sq * ( 1. - e1sq * sum2 * sum2 / sigma );
2487 z = -d2 / TMath::Sqrt(s2);
2488 }
2489 res[resIndex] = z;
2490 resIndex++;
2491 }
2492
2493 if (e1sq > 0 && cnt1 * cnt1 / e1sq < 10) m++;
2494 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2495 }
2496 }
2497 }
2498 if (m) {
2499 igood += 1;
2500 Info("Chi2TestX","There is a bin in h1 with less than 10 effective events.\n");
2501 }
2502 if (n) {
2503 igood += 2;
2504 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2505 }
2506 Double_t prob = TMath::Prob(chi2, ndf);
2507 return prob;
2508 }
2509 return 0;
2510}
2511////////////////////////////////////////////////////////////////////////////////
2512/// Compute and return the chisquare of this histogram with respect to a function
2513/// The chisquare is computed by weighting each histogram point by the bin error
2514/// By default the full range of the histogram is used, unless TAxis::SetRange or TAxis::SetRangeUser was called before.
2515/// Use option "R" for restricting the chisquare calculation to the given range of the function
2516/// Use option "L" for using the chisquare based on the poisson likelihood (Baker-Cousins Chisquare)
2517/// Use option "P" for using the Pearson chisquare based on the expected bin errors
2518
2520{
2521 if (!func) {
2522 Error("Chisquare","Function pointer is Null - return -1");
2523 return -1;
2524 }
2525
2526 TString opt(option); opt.ToUpper();
2527 bool useRange = opt.Contains("R");
2528 ROOT::Fit::EChisquareType type = ROOT::Fit::EChisquareType::kNeyman; // default chi2 with observed error
2531
2532 return ROOT::Fit::Chisquare(*this, *func, useRange, type);
2533}
2534
2535////////////////////////////////////////////////////////////////////////////////
2536/// Remove all the content from the underflow and overflow bins, without changing the number of entries
2537/// After calling this method, every undeflow and overflow bins will have content 0.0
2538/// The Sumw2 is also cleared, since there is no more content in the bins
2539
2541{
2542 for (Int_t bin = 0; bin < fNcells; ++bin)
2543 if (IsBinUnderflow(bin) || IsBinOverflow(bin)) {
2544 UpdateBinContent(bin, 0.0);
2545 if (fSumw2.fN) fSumw2.fArray[bin] = 0.0;
2546 }
2547}
2548
2549////////////////////////////////////////////////////////////////////////////////
2550/// Compute integral (normalized cumulative sum of bins) w/o under/overflows
2551/// The result is stored in fIntegral and used by the GetRandom functions.
2552/// This function is automatically called by GetRandom when the fIntegral
2553/// array does not exist or when the number of entries in the histogram
2554/// has changed since the previous call to GetRandom.
2555/// The resulting integral is normalized to 1.
2556/// If the routine is called with the onlyPositive flag set an error will
2557/// be produced in case of negative bin content and a NaN value returned
2558/// \param onlyPositive If set to true, an error will be produced and NaN will be returned
2559/// when a bin with negative number of entries is encountered.
2560/// \param option
2561/// - `""` (default) Compute the cumulative density function assuming current bin contents represent counts.
2562/// - `"width"` Computes the cumulative density function assuming current bin contents represent densities.
2563/// \return 1 if success, 0 if integral is zero, NAN if onlyPositive-test fails
2564
2566{
2567 if (fBuffer) BufferEmpty();
2569 // delete previously computed integral (if any)
2570 if (fIntegral) delete [] fIntegral;
2571
2572 // - Allocate space to store the integral and compute integral
2576 Int_t nbins = nbinsx * nbinsy * nbinsz;
2577
2578 fIntegral = new Double_t[nbins + 2];
2579 Int_t ibin = 0; fIntegral[ibin] = 0;
2580
2581 for (Int_t binz=1; binz <= nbinsz; ++binz) {
2583 for (Int_t biny=1; biny <= nbinsy; ++biny) {
2585 for (Int_t binx=1; binx <= nbinsx; ++binx) {
2587 ++ibin;
2589 if (useArea)
2590 y *= xWidth * yWidth * zWidth;
2591
2592 if (onlyPositive && y < 0) {
2593 Error("ComputeIntegral","Bin content is negative - return a NaN value");
2594 fIntegral[nbins] = TMath::QuietNaN();
2595 break;
2596 }
2597 fIntegral[ibin] = fIntegral[ibin - 1] + y;
2598 }
2599 }
2600 }
2601
2602 // - Normalize integral to 1
2603 if (fIntegral[nbins] == 0 ) {
2604 Error("ComputeIntegral", "Integral = 0, no hits in histogram bins (excluding over/underflow).");
2605 return 0;
2606 }
2607 for (Int_t bin=1; bin <= nbins; ++bin) fIntegral[bin] /= fIntegral[nbins];
2608 fIntegral[nbins+1] = fEntries;
2609 return fIntegral[nbins];
2610}
2611
2612////////////////////////////////////////////////////////////////////////////////
2613/// Return a pointer to the array of bins integral.
2614/// if the pointer fIntegral is null, TH1::ComputeIntegral is called
2615/// The array dimension is the number of bins in the histograms
2616/// including underflow and overflow (fNCells)
2617/// the last value integral[fNCells] is set to the number of entries of
2618/// the histogram
2619
2621{
2622 if (!fIntegral) ComputeIntegral();
2623 return fIntegral;
2624}
2625
2626////////////////////////////////////////////////////////////////////////////////
2627/// Return a pointer to a histogram containing the cumulative content.
2628/// The cumulative can be computed both in the forward (default) or backward
2629/// direction; the name of the new histogram is constructed from
2630/// the name of this histogram with the suffix "suffix" appended provided
2631/// by the user. If not provided a default suffix="_cumulative" is used.
2632///
2633/// The cumulative distribution is formed by filling each bin of the
2634/// resulting histogram with the sum of that bin and all previous
2635/// (forward == kTRUE) or following (forward = kFALSE) bins.
2636///
2637/// Note: while cumulative distributions make sense in one dimension, you
2638/// may not be getting what you expect in more than 1D because the concept
2639/// of a cumulative distribution is much trickier to define; make sure you
2640/// understand the order of summation before you use this method with
2641/// histograms of dimension >= 2.
2642///
2643/// Note 2: By default the cumulative is computed from bin 1 to Nbins
2644/// If an axis range is set, values between the minimum and maximum of the range
2645/// are set.
2646/// Setting an axis range can also be used for including underflow and overflow in
2647/// the cumulative (e.g. by setting h->GetXaxis()->SetRange(0, h->GetNbinsX()+1); )
2649
2650TH1 *TH1::GetCumulative(Bool_t forward, const char* suffix) const
2651{
2652 const Int_t firstX = fXaxis.GetFirst();
2653 const Int_t lastX = fXaxis.GetLast();
2654 const Int_t firstY = (fDimension > 1) ? fYaxis.GetFirst() : 1;
2655 const Int_t lastY = (fDimension > 1) ? fYaxis.GetLast() : 1;
2656 const Int_t firstZ = (fDimension > 1) ? fZaxis.GetFirst() : 1;
2657 const Int_t lastZ = (fDimension > 1) ? fZaxis.GetLast() : 1;
2658
2660 hintegrated->Reset();
2661 Double_t sum = 0.;
2662 Double_t esum = 0;
2663 if (forward) { // Forward computation
2664 for (Int_t binz = firstZ; binz <= lastZ; ++binz) {
2665 for (Int_t biny = firstY; biny <= lastY; ++biny) {
2666 for (Int_t binx = firstX; binx <= lastX; ++binx) {
2667 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2668 sum += RetrieveBinContent(bin);
2669 hintegrated->AddBinContent(bin, sum);
2670 if (fSumw2.fN) {
2672 hintegrated->fSumw2.fArray[bin] = esum;
2673 }
2674 }
2675 }
2676 }
2677 } else { // Backward computation
2678 for (Int_t binz = lastZ; binz >= firstZ; --binz) {
2679 for (Int_t biny = lastY; biny >= firstY; --biny) {
2680 for (Int_t binx = lastX; binx >= firstX; --binx) {
2681 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2682 sum += RetrieveBinContent(bin);
2683 hintegrated->AddBinContent(bin, sum);
2684 if (fSumw2.fN) {
2686 hintegrated->fSumw2.fArray[bin] = esum;
2687 }
2688 }
2689 }
2690 }
2691 }
2692 return hintegrated;
2693}
2694
2695////////////////////////////////////////////////////////////////////////////////
2696/// Copy this histogram structure to newth1.
2697///
2698/// Note that this function does not copy the list of associated functions.
2699/// Use TObject::Clone to make a full copy of a histogram.
2700///
2701/// Note also that the histogram it will be created in gDirectory (if AddDirectoryStatus()=true)
2702/// or will not be added to any directory if AddDirectoryStatus()=false
2703/// independently of the current directory stored in the original histogram
2704
2705void TH1::Copy(TObject &obj) const
2706{
2707 if (((TH1&)obj).fDirectory) {
2708 // We are likely to change the hash value of this object
2709 // with TNamed::Copy, to keep things correct, we need to
2710 // clean up its existing entries.
2711 ((TH1&)obj).fDirectory->Remove(&obj);
2712 ((TH1&)obj).fDirectory = nullptr;
2713 }
2714 TNamed::Copy(obj);
2715 ((TH1&)obj).fDimension = fDimension;
2716 ((TH1&)obj).fNormFactor= fNormFactor;
2717 ((TH1&)obj).fNcells = fNcells;
2718 ((TH1&)obj).fBarOffset = fBarOffset;
2719 ((TH1&)obj).fBarWidth = fBarWidth;
2720 ((TH1&)obj).fOption = fOption;
2721 ((TH1&)obj).fBinStatErrOpt = fBinStatErrOpt;
2722 ((TH1&)obj).fBufferSize= fBufferSize;
2723 // copy the Buffer
2724 // delete first a previously existing buffer
2725 if (((TH1&)obj).fBuffer != nullptr) {
2726 delete [] ((TH1&)obj).fBuffer;
2727 ((TH1&)obj).fBuffer = nullptr;
2728 }
2729 if (fBuffer) {
2730 Double_t *buf = new Double_t[fBufferSize];
2731 for (Int_t i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
2732 // obj.fBuffer has been deleted before
2733 ((TH1&)obj).fBuffer = buf;
2734 }
2735
2736 // copy bin contents (this should be done by the derived classes, since TH1 does not store the bin content)
2737 // Do this in case derived from TArray
2738 TArray* a = dynamic_cast<TArray*>(&obj);
2739 if (a) {
2740 a->Set(fNcells);
2741 for (Int_t i = 0; i < fNcells; i++)
2743 }
2744
2745 ((TH1&)obj).fEntries = fEntries;
2746
2747 // which will call BufferEmpty(0) and set fBuffer[0] to a Maybe one should call
2748 // assignment operator on the TArrayD
2749
2750 ((TH1&)obj).fTsumw = fTsumw;
2751 ((TH1&)obj).fTsumw2 = fTsumw2;
2752 ((TH1&)obj).fTsumwx = fTsumwx;
2753 ((TH1&)obj).fTsumwx2 = fTsumwx2;
2754 ((TH1&)obj).fMaximum = fMaximum;
2755 ((TH1&)obj).fMinimum = fMinimum;
2756
2757 TAttLine::Copy(((TH1&)obj));
2758 TAttFill::Copy(((TH1&)obj));
2759 TAttMarker::Copy(((TH1&)obj));
2760 fXaxis.Copy(((TH1&)obj).fXaxis);
2761 fYaxis.Copy(((TH1&)obj).fYaxis);
2762 fZaxis.Copy(((TH1&)obj).fZaxis);
2763 ((TH1&)obj).fXaxis.SetParent(&obj);
2764 ((TH1&)obj).fYaxis.SetParent(&obj);
2765 ((TH1&)obj).fZaxis.SetParent(&obj);
2766 fContour.Copy(((TH1&)obj).fContour);
2767 fSumw2.Copy(((TH1&)obj).fSumw2);
2768 // fFunctions->Copy(((TH1&)obj).fFunctions);
2769 // when copying an histogram if the AddDirectoryStatus() is true it
2770 // will be added to gDirectory independently of the fDirectory stored.
2771 // and if the AddDirectoryStatus() is false it will not be added to
2772 // any directory (fDirectory = nullptr)
2774 gDirectory->Append(&obj);
2775 ((TH1&)obj).fFunctions->UseRWLock();
2776 ((TH1&)obj).fDirectory = gDirectory;
2777 } else
2778 ((TH1&)obj).fDirectory = nullptr;
2779
2780}
2781
2782////////////////////////////////////////////////////////////////////////////////
2783/// Make a complete copy of the underlying object. If 'newname' is set,
2784/// the copy's name will be set to that name.
2785
2786TObject* TH1::Clone(const char* newname) const
2787{
2788 TH1* obj = (TH1*)IsA()->GetNew()(nullptr);
2789 Copy(*obj);
2790
2791 // Now handle the parts that Copy doesn't do
2792 if(fFunctions) {
2793 // The Copy above might have published 'obj' to the ListOfCleanups.
2794 // Clone can call RecursiveRemove, for example via TCheckHashRecursiveRemoveConsistency
2795 // when dictionary information is initialized, so we need to
2796 // keep obj->fFunction valid during its execution and
2797 // protect the update with the write lock.
2798
2799 // Reset stats parent - else cloning the stats will clone this histogram, too.
2800 auto oldstats = dynamic_cast<TVirtualPaveStats*>(fFunctions->FindObject("stats"));
2801 TObject *oldparent = nullptr;
2802 if (oldstats) {
2803 oldparent = oldstats->GetParent();
2804 oldstats->SetParent(nullptr);
2805 }
2806
2807 auto newlist = (TList*)fFunctions->Clone();
2808
2809 if (oldstats)
2810 oldstats->SetParent(oldparent);
2811 auto newstats = dynamic_cast<TVirtualPaveStats*>(obj->fFunctions->FindObject("stats"));
2812 if (newstats)
2813 newstats->SetParent(obj);
2814
2815 auto oldlist = obj->fFunctions;
2816 {
2818 obj->fFunctions = newlist;
2819 }
2820 delete oldlist;
2821 }
2822 if(newname && strlen(newname) ) {
2823 obj->SetName(newname);
2824 }
2825 return obj;
2826}
2827
2828////////////////////////////////////////////////////////////////////////////////
2829/// Callback to perform the automatic addition of the histogram to the given directory.
2830///
2831/// This callback is used to register a histogram to the current directory when a TKey
2832/// is read or an object is being cloned using TDirectory::CloneObject().
2833
2835{
2837 if (addStatus) {
2838 SetDirectory(dir);
2839 if (dir) {
2841 }
2842 }
2843}
2844
2845////////////////////////////////////////////////////////////////////////////////
2846/// Compute distance from point px,py to a line.
2847///
2848/// Compute the closest distance of approach from point px,py to elements
2849/// of a histogram.
2850/// The distance is computed in pixels units.
2851///
2852/// #### Algorithm:
2853/// Currently, this simple model computes the distance from the mouse
2854/// to the histogram contour only.
2855
2857{
2858 if (!fPainter) return 9999;
2859 return fPainter->DistancetoPrimitive(px,py);
2860}
2861
2862////////////////////////////////////////////////////////////////////////////////
2863/// Performs the operation: `this = this/(c1*f1)`
2864/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2865///
2866/// Only bins inside the function range are recomputed.
2867/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2868/// you should call Sumw2 before making this operation.
2869/// This is particularly important if you fit the histogram after TH1::Divide
2870///
2871/// The function return kFALSE if the divide operation failed
2872
2874{
2875 if (!f1) {
2876 Error("Divide","Attempt to divide by a non-existing function");
2877 return kFALSE;
2878 }
2879
2880 // delete buffer if it is there since it will become invalid
2881 if (fBuffer) BufferEmpty(1);
2882
2883 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of
2884 Int_t ny = GetNbinsY() + 2;
2885 Int_t nz = GetNbinsZ() + 2;
2886 if (fDimension < 2) ny = 1;
2887 if (fDimension < 3) nz = 1;
2888
2889
2890 SetMinimum();
2891 SetMaximum();
2892
2893 // - Loop on bins (including underflows/overflows)
2894 Int_t bin, binx, biny, binz;
2895 Double_t cu, w;
2896 Double_t xx[3];
2897 Double_t *params = nullptr;
2898 f1->InitArgs(xx,params);
2899 for (binz = 0; binz < nz; ++binz) {
2900 xx[2] = fZaxis.GetBinCenter(binz);
2901 for (biny = 0; biny < ny; ++biny) {
2902 xx[1] = fYaxis.GetBinCenter(biny);
2903 for (binx = 0; binx < nx; ++binx) {
2904 xx[0] = fXaxis.GetBinCenter(binx);
2905 if (!f1->IsInside(xx)) continue;
2907 bin = binx + nx * (biny + ny * binz);
2908 cu = c1 * f1->EvalPar(xx);
2909 if (TF1::RejectedPoint()) continue;
2910 if (cu) w = RetrieveBinContent(bin) / cu;
2911 else w = 0;
2912 UpdateBinContent(bin, w);
2913 if (fSumw2.fN) {
2914 if (cu != 0) fSumw2.fArray[bin] = GetBinErrorSqUnchecked(bin) / (cu * cu);
2915 else fSumw2.fArray[bin] = 0;
2916 }
2917 }
2918 }
2919 }
2920 ResetStats();
2921 return kTRUE;
2922}
2923
2924////////////////////////////////////////////////////////////////////////////////
2925/// Divide this histogram by h1.
2926///
2927/// `this = this/h1`
2928/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2929/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
2930/// if not already set.
2931/// The resulting errors are calculated assuming uncorrelated histograms.
2932/// See the other TH1::Divide that gives the possibility to optionally
2933/// compute binomial errors.
2934///
2935/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2936/// you should call Sumw2 before making this operation.
2937/// This is particularly important if you fit the histogram after TH1::Scale
2938///
2939/// The function return kFALSE if the divide operation failed
2940
2941Bool_t TH1::Divide(const TH1 *h1)
2942{
2943 if (!h1) {
2944 Error("Divide", "Input histogram passed does not exist (NULL).");
2945 return kFALSE;
2946 }
2947
2948 // delete buffer if it is there since it will become invalid
2949 if (fBuffer) BufferEmpty(1);
2950
2951 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins) {
2952 return false;
2953 }
2954
2955 // Create Sumw2 if h1 has Sumw2 set
2956 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
2957
2958 // - Loop on bins (including underflows/overflows)
2959 for (Int_t i = 0; i < fNcells; ++i) {
2962 if (c1) UpdateBinContent(i, c0 / c1);
2963 else UpdateBinContent(i, 0);
2964
2965 if(fSumw2.fN) {
2966 if (c1 == 0) { fSumw2.fArray[i] = 0; continue; }
2967 Double_t c1sq = c1 * c1;
2969 }
2970 }
2971 ResetStats();
2972 return kTRUE;
2973}
2974
2975////////////////////////////////////////////////////////////////////////////////
2976/// Replace contents of this histogram by the division of h1 by h2.
2977///
2978/// `this = c1*h1/(c2*h2)`
2979///
2980/// If errors are defined (see TH1::Sumw2), errors are also recalculated
2981/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
2982/// if not already set.
2983/// The resulting errors are calculated assuming uncorrelated histograms.
2984/// However, if option ="B" is specified, Binomial errors are computed.
2985/// In this case c1 and c2 do not make real sense and they are ignored.
2986///
2987/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2988/// you should call Sumw2 before making this operation.
2989/// This is particularly important if you fit the histogram after TH1::Divide
2990///
2991/// Please note also that in the binomial case errors are calculated using standard
2992/// binomial statistics, which means when b1 = b2, the error is zero.
2993/// If you prefer to have efficiency errors not going to zero when the efficiency is 1, you must
2994/// use the function TGraphAsymmErrors::BayesDivide, which will return an asymmetric and non-zero lower
2995/// error for the case b1=b2.
2996///
2997/// The function return kFALSE if the divide operation failed
2998
3000{
3001
3002 TString opt = option;
3003 opt.ToLower();
3004 Bool_t binomial = kFALSE;
3005 if (opt.Contains("b")) binomial = kTRUE;
3006 if (!h1 || !h2) {
3007 Error("Divide", "At least one of the input histograms passed does not exist (NULL).");
3008 return kFALSE;
3009 }
3010
3011 // delete buffer if it is there since it will become invalid
3012 if (fBuffer) BufferEmpty(1);
3013
3014 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins ||
3015 LoggedInconsistency("Divide", h1, h2) >= kDifferentNumberOfBins) {
3016 return false;
3017 }
3018
3019 if (!c2) {
3020 Error("Divide","Coefficient of dividing histogram cannot be zero");
3021 return kFALSE;
3022 }
3023
3024 // Create Sumw2 if h1 or h2 have Sumw2 set, or if binomial errors are explicitly requested
3025 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0 || binomial)) Sumw2();
3026
3027 SetMinimum();
3028 SetMaximum();
3029
3030 // - Loop on bins (including underflows/overflows)
3031 for (Int_t i = 0; i < fNcells; ++i) {
3033 Double_t b2 = h2->RetrieveBinContent(i);
3034 if (b2) UpdateBinContent(i, c1 * b1 / (c2 * b2));
3035 else UpdateBinContent(i, 0);
3036
3037 if (fSumw2.fN) {
3038 if (b2 == 0) { fSumw2.fArray[i] = 0; continue; }
3039 Double_t b1sq = b1 * b1; Double_t b2sq = b2 * b2;
3040 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
3043 if (binomial) {
3044 if (b1 != b2) {
3045 // in the case of binomial statistics c1 and c2 must be 1 otherwise it does not make sense
3046 // c1 and c2 are ignored
3047 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));//this is the formula in Hbook/Hoper1
3048 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2); // old formula from G. Flucke
3049 // formula which works also for weighted histogram (see http://root-forum.cern.ch/viewtopic.php?t=3753 )
3050 fSumw2.fArray[i] = TMath::Abs( ( (1. - 2.* b1 / b2) * e1sq + b1sq * e2sq / b2sq ) / b2sq );
3051 } else {
3052 //in case b1=b2 error is zero
3053 //use TGraphAsymmErrors::BayesDivide for getting the asymmetric error not equal to zero
3054 fSumw2.fArray[i] = 0;
3055 }
3056 } else {
3057 fSumw2.fArray[i] = c1sq * c2sq * (e1sq * b2sq + e2sq * b1sq) / (c2sq * c2sq * b2sq * b2sq);
3058 }
3059 }
3060 }
3061 ResetStats();
3062 if (binomial)
3063 // in case of binomial division use denominator for number of entries
3064 SetEntries ( h2->GetEntries() );
3065
3066 return kTRUE;
3067}
3068
3069////////////////////////////////////////////////////////////////////////////////
3070/// Draw this histogram with options.
3071///
3072/// Histograms are drawn via the THistPainter class. Each histogram has
3073/// a pointer to its own painter (to be usable in a multithreaded program).
3074/// The same histogram can be drawn with different options in different pads.
3075/// If a histogram is updated after it has been drawn, the updated data will
3076/// be shown the next time the pad is updated. One does not need to
3077/// redraw the histogram.
3078///
3079/// When a histogram is deleted, the histogram is **automatically removed from
3080/// all pads where it was drawn**. If a histogram should be modified or deleted
3081/// without affecting what is drawn, it should be drawn using DrawCopy().
3082///
3083/// By default, TH1::Draw clears the current pad. Passing the option "SAME", the
3084/// histogram will be drawn on top of what's in the pad.
3085/// One can use TH1::SetMaximum and TH1::SetMinimum to force a particular
3086/// value for the maximum or the minimum scale on the plot.
3087///
3088/// TH1::UseCurrentStyle can be used to change all histogram graphics
3089/// attributes to correspond to the current selected style.
3090/// This function must be called for each histogram.
3091/// In case one reads and draws many histograms from a file, one can force
3092/// the histograms to inherit automatically the current graphics style
3093/// by calling before gROOT->ForceStyle();
3094///
3095/// See the THistPainter class for a description of all the drawing options.
3096
3098{
3099 TString opt1 = option; opt1.ToLower();
3101 Int_t index = opt1.Index("same");
3102
3103 // Check if the string "same" is part of a TCutg name.
3104 if (index>=0) {
3105 Int_t indb = opt1.Index("[");
3106 if (indb>=0) {
3107 Int_t indk = opt1.Index("]");
3108 if (index>indb && index<indk) index = -1;
3109 }
3110 }
3111
3112 // If there is no pad or an empty pad the "same" option is ignored.
3113 if (gPad) {
3114 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
3115 if (index>=0) {
3116 if (gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
3117 gPad->GetY1() == 0 && gPad->GetY2() == 1 &&
3118 gPad->GetListOfPrimitives()->GetSize()==0) opt2.Remove(index,4);
3119 } else {
3120 //the following statement is necessary in case one attempts to draw
3121 //a temporary histogram already in the current pad
3122 if (TestBit(kCanDelete)) gPad->Remove(this);
3123 gPad->Clear();
3124 }
3125 gPad->IncrementPaletteColor(1, opt1);
3126 } else {
3127 if (index>=0) opt2.Remove(index,4);
3128 }
3129
3130 AppendPad(opt2.Data());
3131}
3132
3133////////////////////////////////////////////////////////////////////////////////
3134/// Copy this histogram and Draw in the current pad.
3135///
3136/// Once the histogram is drawn into the pad, the original and its drawn copy can be modified or deleted without
3137/// affecting each other. The copied histogram will be owned by the pad, and is deleted when the pad is cleared.
3138///
3139/// DrawCopy() is useful if the original histogram is a temporary, e.g. from code such as
3140/// ~~~ {.cpp}
3141/// void someFunction(...) {
3142/// TH1D histogram(...);
3143/// histogram.DrawCopy();
3144///
3145/// // or equivalently
3146/// std::unique_ptr<TH1F> histogram(...);
3147/// histogram->DrawCopy();
3148/// }
3149/// ~~~
3150/// If Draw() has been used, the histograms would disappear from the canvas at the end of this function.
3151///
3152/// By default a postfix "_copy" is added to the histogram name. Pass an empty postfix in case
3153/// you want to draw a histogram with the same name.
3154///
3155/// See Draw() for the list of options.
3156///
3157/// In contrast to TObject::DrawClone(), DrawCopy
3158/// - Ignores `gROOT->SetSelectedPad()`.
3159/// - Does not register the histogram to any directory.
3160/// - And can cycle through a colour palette when multiple objects are drawn with auto colouring.
3161
3162TH1 *TH1::DrawCopy(Option_t *option, const char * name_postfix) const
3163{
3164 TString opt = option;
3165 opt.ToLower();
3166 if (gPad && !opt.Contains("same")) gPad->Clear();
3168 if (name_postfix) newName.Form("%s%s", GetName(), name_postfix);
3169 TH1 *newth1 = (TH1 *)Clone(newName.Data());
3170 newth1->SetDirectory(nullptr);
3171 newth1->SetBit(kCanDelete);
3172 if (gPad) gPad->IncrementPaletteColor(1, opt);
3173
3174 newth1->AppendPad(option);
3175 return newth1;
3176}
3177
3178////////////////////////////////////////////////////////////////////////////////
3179/// Draw a normalized copy of this histogram.
3180///
3181/// A clone of this histogram is normalized to norm and drawn with option.
3182/// A pointer to the normalized histogram is returned.
3183/// The contents of the histogram copy are scaled such that the new
3184/// sum of weights (excluding under and overflow) is equal to norm.
3185/// Note that the returned normalized histogram is not added to the list
3186/// of histograms in the current directory in memory.
3187/// It is the user's responsibility to delete this histogram.
3188/// The kCanDelete bit is set for the returned object. If a pad containing
3189/// this copy is cleared, the histogram will be automatically deleted.
3190///
3191/// See Draw for the list of options
3192
3194{
3196 if (sum == 0) {
3197 Error("DrawNormalized","Sum of weights is null. Cannot normalize histogram: %s",GetName());
3198 return nullptr;
3199 }
3200
3201 TDirectory::TContext ctx{nullptr};
3202 TH1 *h = (TH1*)Clone();
3204 // in case of drawing with error options - scale correctly the error
3205 TString opt(option); opt.ToUpper();
3206 if (fSumw2.fN == 0) {
3207 h->Sumw2();
3208 // do not use in this case the "Error option " for drawing which is enabled by default since the normalized histogram has now errors
3209 if (opt.IsNull() || opt == "SAME") opt += "HIST";
3210 }
3211 h->Scale(norm/sum);
3212 if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
3213 if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
3214 h->Draw(opt);
3215
3216 return h;
3217}
3218
3219////////////////////////////////////////////////////////////////////////////////
3220/// Display a panel with all histogram drawing options.
3221///
3222/// See class TDrawPanelHist for example
3223
3224void TH1::DrawPanel()
3225{
3226 if (!fPainter) {Draw(); if (gPad) gPad->Update();}
3227 if (fPainter) fPainter->DrawPanel();
3228}
3229
3230////////////////////////////////////////////////////////////////////////////////
3231/// Evaluate function f1 at the center of bins of this histogram.
3232///
3233/// - If option "R" is specified, the function is evaluated only
3234/// for the bins included in the function range.
3235/// - If option "A" is specified, the value of the function is added to the
3236/// existing bin contents
3237/// - If option "S" is specified, the value of the function is used to
3238/// generate a value, distributed according to the Poisson
3239/// distribution, with f1 as the mean.
3240
3242{
3243 Double_t x[3];
3244 Int_t range, stat, add;
3245 if (!f1) return;
3246
3247 TString opt = option;
3248 opt.ToLower();
3249 if (opt.Contains("a")) add = 1;
3250 else add = 0;
3251 if (opt.Contains("s")) stat = 1;
3252 else stat = 0;
3253 if (opt.Contains("r")) range = 1;
3254 else range = 0;
3255
3256 // delete buffer if it is there since it will become invalid
3257 if (fBuffer) BufferEmpty(1);
3258
3262 if (!add) Reset();
3263
3264 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
3265 x[2] = fZaxis.GetBinCenter(binz);
3266 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
3267 x[1] = fYaxis.GetBinCenter(biny);
3268 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
3269 Int_t bin = GetBin(binx,biny,binz);
3270 x[0] = fXaxis.GetBinCenter(binx);
3271 if (range && !f1->IsInside(x)) continue;
3272 Double_t fu = f1->Eval(x[0], x[1], x[2]);
3273 if (stat) fu = gRandom->PoissonD(fu);
3274 AddBinContent(bin, fu);
3275 if (fSumw2.fN) fSumw2.fArray[bin] += TMath::Abs(fu);
3276 }
3277 }
3278 }
3279}
3280
3281////////////////////////////////////////////////////////////////////////////////
3282/// Execute action corresponding to one event.
3283///
3284/// This member function is called when a histogram is clicked with the locator
3285///
3286/// If Left button clicked on the bin top value, then the content of this bin
3287/// is modified according to the new position of the mouse when it is released.
3288
3289void TH1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3290{
3291 if (fPainter) fPainter->ExecuteEvent(event, px, py);
3292}
3293
3294////////////////////////////////////////////////////////////////////////////////
3295/// This function allows to do discrete Fourier transforms of TH1 and TH2.
3296/// Available transform types and flags are described below.
3297///
3298/// To extract more information about the transform, use the function
3299/// TVirtualFFT::GetCurrentTransform() to get a pointer to the current
3300/// transform object.
3301///
3302/// \param[out] h_output histogram for the output. If a null pointer is passed, a new histogram is created
3303/// and returned, otherwise, the provided histogram is used and should be big enough
3304/// \param[in] option option parameters consists of 3 parts:
3305/// - option on what to return
3306/// - "RE" - returns a histogram of the real part of the output
3307/// - "IM" - returns a histogram of the imaginary part of the output
3308/// - "MAG"- returns a histogram of the magnitude of the output
3309/// - "PH" - returns a histogram of the phase of the output
3310/// - option of transform type
3311/// - "R2C" - real to complex transforms - default
3312/// - "R2HC" - real to halfcomplex (special format of storing output data,
3313/// results the same as for R2C)
3314/// - "DHT" - discrete Hartley transform
3315/// real to real transforms (sine and cosine):
3316/// - "R2R_0", "R2R_1", "R2R_2", "R2R_3" - discrete cosine transforms of types I-IV
3317/// - "R2R_4", "R2R_5", "R2R_6", "R2R_7" - discrete sine transforms of types I-IV
3318/// To specify the type of each dimension of a 2-dimensional real to real
3319/// transform, use options of form "R2R_XX", for example, "R2R_02" for a transform,
3320/// which is of type "R2R_0" in 1st dimension and "R2R_2" in the 2nd.
3321/// - option of transform flag
3322/// - "ES" (from "estimate") - no time in preparing the transform, but probably sub-optimal
3323/// performance
3324/// - "M" (from "measure") - some time spend in finding the optimal way to do the transform
3325/// - "P" (from "patient") - more time spend in finding the optimal way to do the transform
3326/// - "EX" (from "exhaustive") - the most optimal way is found
3327/// This option should be chosen depending on how many transforms of the same size and
3328/// type are going to be done. Planning is only done once, for the first transform of this
3329/// size and type. Default is "ES".
3330///
3331/// Examples of valid options: "Mag R2C M" "Re R2R_11" "Im R2C ES" "PH R2HC EX"
3332
3334{
3335
3336 Int_t ndim[3];
3337 ndim[0] = this->GetNbinsX();
3338 ndim[1] = this->GetNbinsY();
3339 ndim[2] = this->GetNbinsZ();
3340
3342 TString opt = option;
3343 opt.ToUpper();
3344 if (!opt.Contains("2R")){
3345 if (!opt.Contains("2C") && !opt.Contains("2HC") && !opt.Contains("DHT")) {
3346 //no type specified, "R2C" by default
3347 opt.Append("R2C");
3348 }
3349 fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
3350 }
3351 else {
3352 //find the kind of transform
3353 Int_t ind = opt.Index("R2R", 3);
3354 Int_t *kind = new Int_t[2];
3355 char t;
3356 t = opt[ind+4];
3357 kind[0] = atoi(&t);
3358 if (h_output->GetDimension()>1) {
3359 t = opt[ind+5];
3360 kind[1] = atoi(&t);
3361 }
3362 fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
3363 delete [] kind;
3364 }
3365
3366 if (!fft) return nullptr;
3367 Int_t in=0;
3368 for (Int_t binx = 1; binx<=ndim[0]; binx++) {
3369 for (Int_t biny=1; biny<=ndim[1]; biny++) {
3370 for (Int_t binz=1; binz<=ndim[2]; binz++) {
3371 fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
3372 in++;
3373 }
3374 }
3375 }
3376 fft->Transform();
3378 return h_output;
3379}
3380
3381////////////////////////////////////////////////////////////////////////////////
3382/// Increment bin with abscissa X by 1.
3383///
3384/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3385/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3386///
3387/// If the storage of the sum of squares of weights has been triggered,
3388/// via the function Sumw2, then the sum of the squares of weights is incremented
3389/// by 1 in the bin corresponding to x.
3390///
3391/// The function returns the corresponding bin number which has its content incremented by 1
3392
3394{
3395 if (fBuffer) return BufferFill(x,1);
3396
3397 Int_t bin;
3398 fEntries++;
3399 bin =fXaxis.FindBin(x);
3400 if (bin <0) return -1;
3401 AddBinContent(bin);
3402 if (fSumw2.fN) ++fSumw2.fArray[bin];
3403 if (bin == 0 || bin > fXaxis.GetNbins()) {
3404 if (!GetStatOverflowsBehaviour()) return -1;
3405 }
3406 ++fTsumw;
3407 ++fTsumw2;
3408 fTsumwx += x;
3409 fTsumwx2 += x*x;
3410 return bin;
3411}
3412
3413////////////////////////////////////////////////////////////////////////////////
3414/// Increment bin with abscissa X with a weight w.
3415///
3416/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3417/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3418///
3419/// If the weight is not equal to 1, the storage of the sum of squares of
3420/// weights is automatically triggered and the sum of the squares of weights is incremented
3421/// by \f$ w^2 \f$ in the bin corresponding to x.
3422///
3423/// The function returns the corresponding bin number which has its content incremented by w
3424
3426{
3427
3428 if (fBuffer) return BufferFill(x,w);
3429
3430 Int_t bin;
3431 fEntries++;
3432 bin =fXaxis.FindBin(x);
3433 if (bin <0) return -1;
3434 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW) ) Sumw2(); // must be called before AddBinContent
3435 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3436 AddBinContent(bin, w);
3437 if (bin == 0 || bin > fXaxis.GetNbins()) {
3438 if (!GetStatOverflowsBehaviour()) return -1;
3439 }
3440 Double_t z= w;
3441 fTsumw += z;
3442 fTsumw2 += z*z;
3443 fTsumwx += z*x;
3444 fTsumwx2 += z*x*x;
3445 return bin;
3446}
3447
3448////////////////////////////////////////////////////////////////////////////////
3449/// Increment bin with namex with a weight w
3450///
3451/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3452/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3453///
3454/// If the weight is not equal to 1, the storage of the sum of squares of
3455/// weights is automatically triggered and the sum of the squares of weights is incremented
3456/// by \f$ w^2 \f$ in the bin corresponding to x.
3457///
3458/// The function returns the corresponding bin number which has its content
3459/// incremented by w.
3460
3461Int_t TH1::Fill(const char *namex, Double_t w)
3462{
3463 Int_t bin;
3464 fEntries++;
3465 bin =fXaxis.FindBin(namex);
3466 if (bin <0) return -1;
3467 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3468 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3469 AddBinContent(bin, w);
3470 if (bin == 0 || bin > fXaxis.GetNbins()) return -1;
3471 Double_t z= w;
3472 fTsumw += z;
3473 fTsumw2 += z*z;
3474 // this make sense if the histogram is not expanding (the x axis cannot be extended)
3475 if (!fXaxis.CanExtend() || !fXaxis.IsAlphanumeric()) {
3477 fTsumwx += z*x;
3478 fTsumwx2 += z*x*x;
3479 }
3480 return bin;
3481}
3482
3483////////////////////////////////////////////////////////////////////////////////
3484/// Fill this histogram with an array x and weights w.
3485///
3486/// \param[in] ntimes number of entries in arrays x and w (array size must be ntimes*stride)
3487/// \param[in] x array of values to be histogrammed
3488/// \param[in] w array of weighs
3489/// \param[in] stride step size through arrays x and w
3490///
3491/// If the weight is not equal to 1, the storage of the sum of squares of
3492/// weights is automatically triggered and the sum of the squares of weights is incremented
3493/// by \f$ w^2 \f$ in the bin corresponding to x.
3494/// if w is NULL each entry is assumed a weight=1
3495
3496void TH1::FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3497{
3498 //If a buffer is activated, fill buffer
3499 if (fBuffer) {
3500 ntimes *= stride;
3501 Int_t i = 0;
3502 for (i=0;i<ntimes;i+=stride) {
3503 if (!fBuffer) break; // buffer can be deleted in BufferFill when is empty
3504 if (w) BufferFill(x[i],w[i]);
3505 else BufferFill(x[i], 1.);
3506 }
3507 // fill the remaining entries if the buffer has been deleted
3508 if (i < ntimes && !fBuffer) {
3509 auto weights = w ? &w[i] : nullptr;
3510 DoFillN((ntimes-i)/stride,&x[i],weights,stride);
3511 }
3512 return;
3513 }
3514 // call internal method
3515 DoFillN(ntimes, x, w, stride);
3516}
3517
3518////////////////////////////////////////////////////////////////////////////////
3519/// Internal method to fill histogram content from a vector
3520/// called directly by TH1::BufferEmpty
3521
3522void TH1::DoFillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3523{
3524 Int_t bin,i;
3525
3526 fEntries += ntimes;
3527 Double_t ww = 1;
3528 Int_t nbins = fXaxis.GetNbins();
3529 ntimes *= stride;
3530 for (i=0;i<ntimes;i+=stride) {
3531 bin =fXaxis.FindBin(x[i]);
3532 if (bin <0) continue;
3533 if (w) ww = w[i];
3534 if (!fSumw2.fN && ww != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3535 if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
3536 AddBinContent(bin, ww);
3537 if (bin == 0 || bin > nbins) {
3538 if (!GetStatOverflowsBehaviour()) continue;
3539 }
3540 Double_t z= ww;
3541 fTsumw += z;
3542 fTsumw2 += z*z;
3543 fTsumwx += z*x[i];
3544 fTsumwx2 += z*x[i]*x[i];
3545 }
3546}
3547
3548////////////////////////////////////////////////////////////////////////////////
3549/// Fill histogram following distribution in function fname.
3550///
3551/// @param fname : Function name used for filling the histogram
3552/// @param ntimes : number of times the histogram is filled
3553/// @param rng : (optional) Random number generator used to sample
3554///
3555///
3556/// The distribution contained in the function fname (TF1) is integrated
3557/// over the channel contents for the bin range of this histogram.
3558/// It is normalized to 1.
3559///
3560/// Getting one random number implies:
3561/// - Generating a random number between 0 and 1 (say r1)
3562/// - Look in which bin in the normalized integral r1 corresponds to
3563/// - Fill histogram channel
3564/// ntimes random numbers are generated
3565///
3566/// One can also call TF1::GetRandom to get a random variate from a function.
3567
3568void TH1::FillRandom(const char *fname, Int_t ntimes, TRandom * rng)
3569{
3570 // - Search for fname in the list of ROOT defined functions
3571 TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
3572 if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
3573
3576
3578{
3579 Int_t bin, binx, ibin, loop;
3580 Double_t r1, x;
3581
3582 // - Allocate temporary space to store the integral and compute integral
3583
3584 TAxis * xAxis = &fXaxis;
3585
3586 // in case axis of histogram is not defined use the function axis
3587 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
3589 f1->GetRange(xmin,xmax);
3590 Info("FillRandom","Using function axis and range [%g,%g]",xmin, xmax);
3591 xAxis = f1->GetHistogram()->GetXaxis();
3592 }
3593
3594 Int_t first = xAxis->GetFirst();
3595 Int_t last = xAxis->GetLast();
3596 Int_t nbinsx = last-first+1;
3597
3598 Double_t *integral = new Double_t[nbinsx+1];
3599 integral[0] = 0;
3600 for (binx=1;binx<=nbinsx;binx++) {
3601 Double_t fint = f1->Integral(xAxis->GetBinLowEdge(binx+first-1),xAxis->GetBinUpEdge(binx+first-1), 0.);
3602 integral[binx] = integral[binx-1] + fint;
3603 }
3604
3605 // - Normalize integral to 1
3606 if (integral[nbinsx] == 0 ) {
3607 delete [] integral;
3608 Error("FillRandom", "Integral = zero"); return;
3609 }
3610 for (bin=1;bin<=nbinsx;bin++) integral[bin] /= integral[nbinsx];
3611
3612 // --------------Start main loop ntimes
3613 for (loop=0;loop<ntimes;loop++) {
3614 r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
3615 ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
3616 //binx = 1 + ibin;
3617 //x = xAxis->GetBinCenter(binx); //this is not OK when SetBuffer is used
3618 x = xAxis->GetBinLowEdge(ibin+first)
3619 +xAxis->GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
3620 Fill(x);
3621 }
3622 delete [] integral;
3623}
3624
3625////////////////////////////////////////////////////////////////////////////////
3626/// Fill histogram following distribution in histogram h.
3627///
3628/// @param h : Histogram pointer used for sampling random number
3629/// @param ntimes : number of times the histogram is filled
3630/// @param rng : (optional) Random number generator used for sampling
3631///
3632/// The distribution contained in the histogram h (TH1) is integrated
3633/// over the channel contents for the bin range of this histogram.
3634/// It is normalized to 1.
3635///
3636/// Getting one random number implies:
3637/// - Generating a random number between 0 and 1 (say r1)
3638/// - Look in which bin in the normalized integral r1 corresponds to
3639/// - Fill histogram channel ntimes random numbers are generated
3640///
3641/// SPECIAL CASE when the target histogram has the same binning as the source.
3642/// in this case we simply use a poisson distribution where
3643/// the mean value per bin = bincontent/integral.
3644
3646{
3647 if (!h) { Error("FillRandom", "Null histogram"); return; }
3648 if (fDimension != h->GetDimension()) {
3649 Error("FillRandom", "Histograms with different dimensions"); return;
3650 }
3651 if (std::isnan(h->ComputeIntegral(true))) {
3652 Error("FillRandom", "Histograms contains negative bins, does not represent probabilities");
3653 return;
3654 }
3655
3656 //in case the target histogram has the same binning and ntimes much greater
3657 //than the number of bins we can use a fast method
3658 Int_t first = fXaxis.GetFirst();
3659 Int_t last = fXaxis.GetLast();
3660 Int_t nbins = last-first+1;
3661 if (ntimes > 10*nbins) {
3662 auto inconsistency = CheckConsistency(this,h);
3663 if (inconsistency != kFullyConsistent) return; // do nothing
3664 Double_t sumw = h->Integral(first,last);
3665 if (sumw == 0) return;
3666 Double_t sumgen = 0;
3667 for (Int_t bin=first;bin<=last;bin++) {
3668 Double_t mean = h->RetrieveBinContent(bin)*ntimes/sumw;
3669 Double_t cont = (rng) ? rng->Poisson(mean) : gRandom->Poisson(mean);
3670 sumgen += cont;
3671 AddBinContent(bin,cont);
3672 if (fSumw2.fN) fSumw2.fArray[bin] += cont;
3673 }
3674
3675 // fix for the fluctuations in the total number n
3676 // since we use Poisson instead of multinomial
3677 // add a correction to have ntimes as generated entries
3678 Int_t i;
3679 if (sumgen < ntimes) {
3680 // add missing entries
3681 for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
3682 {
3683 Double_t x = h->GetRandom();
3684 Fill(x);
3685 }
3686 }
3687 else if (sumgen > ntimes) {
3688 // remove extra entries
3689 i = Int_t(sumgen+0.5);
3690 while( i > ntimes) {
3691 Double_t x = h->GetRandom(rng);
3694 // skip in case bin is empty
3695 if (y > 0) {
3696 SetBinContent(ibin, y-1.);
3697 i--;
3698 }
3699 }
3700 }
3701
3702 ResetStats();
3703 return;
3704 }
3705 // case of different axis and not too large ntimes
3706
3707 if (h->ComputeIntegral() ==0) return;
3708 Int_t loop;
3709 Double_t x;
3710 for (loop=0;loop<ntimes;loop++) {
3711 x = h->GetRandom();
3712 Fill(x);
3713 }
3714}
3715
3716////////////////////////////////////////////////////////////////////////////////
3717/// Return Global bin number corresponding to x,y,z
3718///
3719/// 2-D and 3-D histograms are represented with a one dimensional
3720/// structure. This has the advantage that all existing functions, such as
3721/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3722/// This function tries to extend the axis if the given point belongs to an
3723/// under-/overflow bin AND if CanExtendAllAxes() is true.
3724///
3725/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3726
3728{
3729 if (GetDimension() < 2) {
3730 return fXaxis.FindBin(x);
3731 }
3732 if (GetDimension() < 3) {
3733 Int_t nx = fXaxis.GetNbins()+2;
3736 return binx + nx*biny;
3737 }
3738 if (GetDimension() < 4) {
3739 Int_t nx = fXaxis.GetNbins()+2;
3740 Int_t ny = fYaxis.GetNbins()+2;
3743 Int_t binz = fZaxis.FindBin(z);
3744 return binx + nx*(biny +ny*binz);
3745 }
3746 return -1;
3747}
3748
3749////////////////////////////////////////////////////////////////////////////////
3750/// Return Global bin number corresponding to x,y,z.
3751///
3752/// 2-D and 3-D histograms are represented with a one dimensional
3753/// structure. This has the advantage that all existing functions, such as
3754/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3755/// This function DOES NOT try to extend the axis if the given point belongs
3756/// to an under-/overflow bin.
3757///
3758/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3759
3761{
3762 if (GetDimension() < 2) {
3763 return fXaxis.FindFixBin(x);
3764 }
3765 if (GetDimension() < 3) {
3766 Int_t nx = fXaxis.GetNbins()+2;
3769 return binx + nx*biny;
3770 }
3771 if (GetDimension() < 4) {
3772 Int_t nx = fXaxis.GetNbins()+2;
3773 Int_t ny = fYaxis.GetNbins()+2;
3777 return binx + nx*(biny +ny*binz);
3778 }
3779 return -1;
3780}
3781
3782////////////////////////////////////////////////////////////////////////////////
3783/// Find first bin with content > threshold for axis (1=x, 2=y, 3=z)
3784/// if no bins with content > threshold is found the function returns -1.
3785/// The search will occur between the specified first and last bin. Specifying
3786/// the value of the last bin to search to less than zero will search until the
3787/// last defined bin.
3788
3790{
3791 if (fBuffer) ((TH1*)this)->BufferEmpty();
3792
3793 if (axis < 1 || (axis > 1 && GetDimension() == 1 ) ||
3794 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3 ) ) {
3795 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3796 axis = 1;
3797 }
3798 if (firstBin < 1) {
3799 firstBin = 1;
3800 }
3802 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3803 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3804
3805 if (axis == 1) {
3808 }
3809 for (Int_t binx = firstBin; binx <= lastBin; binx++) {
3810 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3811 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3813 }
3814 }
3815 }
3816 }
3817 else if (axis == 2) {
3820 }
3821 for (Int_t biny = firstBin; biny <= lastBin; biny++) {
3822 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3823 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3825 }
3826 }
3827 }
3828 }
3829 else if (axis == 3) {
3832 }
3833 for (Int_t binz = firstBin; binz <= lastBin; binz++) {
3834 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3835 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3837 }
3838 }
3839 }
3840 }
3841
3842 return -1;
3843}
3844
3845////////////////////////////////////////////////////////////////////////////////
3846/// Find last bin with content > threshold for axis (1=x, 2=y, 3=z)
3847/// if no bins with content > threshold is found the function returns -1.
3848/// The search will occur between the specified first and last bin. Specifying
3849/// the value of the last bin to search to less than zero will search until the
3850/// last defined bin.
3851
3853{
3854 if (fBuffer) ((TH1*)this)->BufferEmpty();
3855
3856
3857 if (axis < 1 || ( axis > 1 && GetDimension() == 1 ) ||
3858 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3) ) {
3859 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3860 axis = 1;
3861 }
3862 if (firstBin < 1) {
3863 firstBin = 1;
3864 }
3866 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3867 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3868
3869 if (axis == 1) {
3872 }
3873 for (Int_t binx = lastBin; binx >= firstBin; binx--) {
3874 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3875 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3877 }
3878 }
3879 }
3880 }
3881 else if (axis == 2) {
3884 }
3885 for (Int_t biny = lastBin; biny >= firstBin; biny--) {
3886 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3887 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3889 }
3890 }
3891 }
3892 }
3893 else if (axis == 3) {
3896 }
3897 for (Int_t binz = lastBin; binz >= firstBin; binz--) {
3898 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3899 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3901 }
3902 }
3903 }
3904 }
3905
3906 return -1;
3907}
3908
3909////////////////////////////////////////////////////////////////////////////////
3910/// Search object named name in the list of functions.
3911
3912TObject *TH1::FindObject(const char *name) const
3913{
3914 if (fFunctions) return fFunctions->FindObject(name);
3915 return nullptr;
3916}
3917
3918////////////////////////////////////////////////////////////////////////////////
3919/// Search object obj in the list of functions.
3920
3921TObject *TH1::FindObject(const TObject *obj) const
3922{
3923 if (fFunctions) return fFunctions->FindObject(obj);
3924 return nullptr;
3925}
3926
3927////////////////////////////////////////////////////////////////////////////////
3928/// Fit histogram with function fname.
3929///
3930///
3931/// fname is the name of a function available in the global ROOT list of functions
3932/// `gROOT->GetListOfFunctions`. Note that this is not thread safe.
3933/// The list include any TF1 object created by the user plus some pre-defined functions
3934/// which are automatically created by ROOT the first time a pre-defined function is requested from `gROOT`
3935/// (i.e. when calling `gROOT->GetFunction(const char *name)`).
3936/// These pre-defined functions are:
3937/// - `gaus, gausn` where gausn is the normalized Gaussian
3938/// - `landau, landaun`
3939/// - `expo`
3940/// - `pol1,...9, chebyshev1,...9`.
3941///
3942/// For printing the list of all available functions do:
3943///
3944/// TF1::InitStandardFunctions(); // not needed if `gROOT->GetFunction` is called before
3945/// TF2::InitStandardFunctions(); TF3::InitStandardFunctions(); // For 2D or 3D
3946/// gROOT->GetListOfFunctions()->ls()
3947///
3948/// `fname` can also be a formula that is accepted by the linear fitter containing the special operator `++`,
3949/// representing linear components separated by `++` sign, for example `x++sin(x)` for fitting `[0]*x+[1]*sin(x)`
3950///
3951/// This function finds a pointer to the TF1 object with name `fname` and calls TH1::Fit(TF1 *, Option_t *, Option_t *,
3952/// Double_t, Double_t). See there for the fitting options and the details about fitting histograms
3953
3955{
3956 char *linear;
3957 linear= (char*)strstr(fname, "++");
3958 Int_t ndim=GetDimension();
3959 if (linear){
3960 if (ndim<2){
3962 return Fit(&f1,option,goption,xxmin,xxmax);
3963 }
3964 else if (ndim<3){
3965 TF2 f2(fname, fname);
3966 return Fit(&f2,option,goption,xxmin,xxmax);
3967 }
3968 else{
3969 TF3 f3(fname, fname);
3970 return Fit(&f3,option,goption,xxmin,xxmax);
3971 }
3972 }
3973 else{
3974 TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
3975 if (!f1) { Printf("Unknown function: %s",fname); return -1; }
3976 return Fit(f1,option,goption,xxmin,xxmax);
3977 }
3978}
3979
3980////////////////////////////////////////////////////////////////////////////////
3981/// Fit histogram with the function pointer f1.
3982///
3983/// \param[in] f1 pointer to the function object
3984/// \param[in] option string defining the fit options (see table below).
3985/// \param[in] goption specify a list of graphics options. See TH1::Draw for a complete list of these options.
3986/// \param[in] xxmin lower fitting range
3987/// \param[in] xxmax upper fitting range
3988/// \return A smart pointer to the TFitResult class
3989///
3990/// \anchor HFitOpt
3991/// ### Histogram Fitting Options
3992///
3993/// Here is the full list of fit options that can be given in the parameter `option`.
3994/// Several options can be used together by concatanating the strings without the need of any delimiters.
3995///
3996/// option | description
3997/// -------|------------
3998/// "L" | Uses a log likelihood method (default is chi-square method). To be used when the histogram represents counts.
3999/// "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.
4000/// "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.
4001/// "MULTI" | Uses Loglikelihood method based on multi-nomial distribution. In this case the function must be normalized and one fits only the function shape.
4002/// "W" | Fit using the chi-square method and ignoring the bin uncertainties and skip empty bins.
4003/// "WW" | Fit using the chi-square method and ignoring the bin uncertainties and include the empty bins.
4004/// "I" | Uses the integral of function in the bin instead of the default bin center value.
4005/// "F" | Uses the default minimizer (e.g. Minuit) when fitting a linear function (e.g. polN) instead of the linear fitter.
4006/// "U" | Uses a user specified objective function (e.g. user providedlikelihood function) defined using `TVirtualFitter::SetFCN`
4007/// "E" | Performs a better parameter errors estimation using the Minos technique for all fit parameters.
4008/// "M" | Uses the IMPROVE algorithm (available only in TMinuit). This algorithm attempts improve the found local minimum by searching for a better one.
4009/// "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`.
4010/// "Q" | Quiet mode (minimum printing)
4011/// "V" | Verbose mode (default is between Q and V)
4012/// "+" | 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.
4013/// "N" | Does not store the graphics function, does not draw the histogram with the function after fitting.
4014/// "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.
4015/// "R" | Fit using a fitting range specified in the function range with `TF1::SetRange`.
4016/// "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.
4017/// "C" | In case of linear fitting, do no calculate the chisquare (saves CPU time).
4018/// "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.
4019/// "WIDTH" | Scales the histogran bin content by the bin width (useful for variable bins histograms)
4020/// "SERIAL" | Runs in serial mode. By default 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
4021/// "MULTITHREAD" | Forces usage of multi-thread execution whenever possible
4022///
4023/// The default fitting of an histogram (when no option is given) is perfomed as following:
4024/// - a chi-square fit (see below Chi-square Fits) computed using the bin histogram errors and excluding bins with zero errors (empty bins);
4025/// - the full range of the histogram is used, unless TAxis::SetRange or TAxis::SetRangeUser was called before;
4026/// - the default Minimizer with its default configuration is used (see below Minimizer Configuration) except for linear function;
4027/// - for linear functions (`polN`, `chenbyshev` or formula expressions combined using operator `++`) a linear minimization is used.
4028/// - only the status of the fit is returned;
4029/// - the fit is performed in Multithread whenever is enabled in ROOT;
4030/// - only the last fitted function is saved in the histogram;
4031/// - the histogram is drawn after fitting overalyed with the resulting fitting function
4032///
4033/// \anchor HFitMinimizer
4034/// ### Minimizer Configuration
4035///
4036/// The Fit is perfomed using the default Minimizer, defined in the `ROOT::Math::MinimizerOptions` class.
4037/// It is possible to change the default minimizer and its configuration parameters by calling these static functions before fitting (before calling `TH1::Fit`):
4038/// - `ROOT::Math::MinimizerOptions::SetDefaultMinimizer(minimizerName, minimizerAgorithm)` for changing the minmizer and/or the corresponding algorithm.
4039/// For example `ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");` will set the usage of the BFGS algorithm of the GSL multi-dimensional minimization
4040/// The current defaults are ("Minuit","Migrad").
4041/// See the documentation of the `ROOT::Math::MinimizerOptions` for the available minimizers in ROOT and their corresponding algorithms.
4042/// - `ROOT::Math::MinimizerOptions::SetDefaultTolerance` for setting a different tolerance value for the minimization.
4043/// - `ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls` for setting the maximum number of function calls.
4044/// - `ROOT::Math::MinimizerOptions::SetDefaultPrintLevel` for changing the minimizer print level from level=0 (minimal printing) to level=3 maximum printing
4045///
4046/// Other options are possible depending on the Minimizer used, see the corresponding documentation.
4047/// The default minimizer can be also set in the resource file in etc/system.rootrc. For example
4048///
4049/// ~~~ {.cpp}
4050/// Root.Fitter: Minuit2
4051/// ~~~
4052///
4053/// \anchor HFitChi2
4054/// ### Chi-square Fits
4055///
4056/// By default a chi-square (least-square) fit is performed on the histogram. The so-called modified least-square method
4057/// is used where the residual for each bin is computed using as error the observed value (the bin error) returned by `TH1::GetBinError`
4058///
4059/// \f[
4060/// Chi2 = \sum_{i}{ \left(\frac{y(i) - f(x(i) | p )}{e(i)} \right)^2 }
4061/// \f]
4062///
4063/// 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
4064/// an un-weighted histogram). Bins with zero errors are excluded from the fit. See also later the note on the treatment
4065/// of empty bins. When using option "I" the residual is computed not using the function value at the bin center, `f(x(i)|p)`,
4066/// but the integral of the function in the bin, Integral{ f(x|p)dx }, divided by the bin volume.
4067/// When using option `P` (Pearson chi2), the expected error computed as `e(i) = sqrt(f(x(i)|p))` is used.
4068/// In this case empty bins are considered in the fit.
4069/// Both chi-square methods should not be used when the bin content represent counts, especially in case of low bin statistics,
4070/// because they could return a biased result.
4071///
4072/// \anchor HFitNLL
4073/// ### Likelihood Fits
4074///
4075/// When using option "L" a likelihood fit is used instead of the default chi-square fit.
4076/// The likelihood is built assuming a Poisson probability density function for each bin.
4077/// The negative log-likelihood to be minimized is
4078///
4079/// \f[
4080/// NLL = - \sum_{i}{ \log {\mathrm P} ( y(i) | f(x(i) | p ) ) }
4081/// \f]
4082/// 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)`.
4083/// The exact likelihood used is the Poisson likelihood described in this paper:
4084/// S. Baker and R. D. Cousins, “Clarification of the use of chi-square and likelihood functions in fits to histograms,”
4085/// Nucl. Instrum. Meth. 221 (1984) 437.
4086///
4087/// \f[
4088/// NLL = \sum_{i}{( f(x(i) | p ) + y(i)\log(y(i)/ f(x(i) | p )) - y(i)) }
4089/// \f]
4090/// By using this formulation, `2*NLL` can be interpreted as the chi-square resulting from the fit.
4091///
4092/// This method should be always used when the bin content represents counts (i.e. errors are sqrt(N) ).
4093/// The likelihood method has the advantage of treating correctly bins with low statistics. In case of high
4094/// statistics/bin the distribution of the bin content becomes a normal distribution and the likelihood and the chi2 fit
4095/// give the same result.
4096///
4097/// The likelihood method, although a bit slower, it is therefore the recommended method,
4098/// when the histogram represent counts (Poisson statistics), where the chi-square methods may
4099/// give incorrect results, especially in case of low statistics.
4100/// In case of a weighted histogram, it is possible to perform also a likelihood fit by using the
4101/// option "WL". Note a weighted histogram is a histogram which has been filled with weights and it
4102/// has the information on the sum of the weight square for each bin ( TH1::Sumw2() has been called).
4103/// The bin error for a weighted histogram is the square root of the sum of the weight square.
4104///
4105/// \anchor HFitRes
4106/// ### Fit Result
4107///
4108/// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
4109/// By default the TFitResultPtr contains only the status of the fit which is return by an
4110/// automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
4111///
4112/// ~~~ {.cpp}
4113/// Int_t fitStatus = h->Fit(myFunc);
4114/// ~~~
4115///
4116/// If the option "S" is instead used, TFitResultPtr behaves as a smart
4117/// pointer to the TFitResult object. This is useful for retrieving the full result information from the fit, such as the covariance matrix,
4118/// as shown in this example code:
4119///
4120/// ~~~ {.cpp}
4121/// TFitResultPtr r = h->Fit(myFunc,"S");
4122/// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
4123/// Double_t chi2 = r->Chi2(); // to retrieve the fit chi2
4124/// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
4125/// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
4126/// r->Print("V"); // print full information of fit including covariance matrix
4127/// r->Write(); // store the result in a file
4128/// ~~~
4129///
4130/// The fit parameters, error and chi-square (but not covariance matrix) can be retrieved also
4131/// directly from the fitted function that is passed to this call.
4132/// Given a pointer to an associated fitted function `myfunc`, one can retrieve the function/fit
4133/// parameters with calls such as:
4134///
4135/// ~~~ {.cpp}
4136/// Double_t chi2 = myfunc->GetChisquare();
4137/// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
4138/// Double_t err0 = myfunc->GetParError(0); //error on first parameter
4139/// ~~~
4140///
4141/// ##### Associated functions
4142///
4143/// One or more objects (typically a TF1*) can be added to the list
4144/// of functions (fFunctions) associated to each histogram.
4145/// When TH1::Fit is invoked, the fitted function is added to the histogram list of functions (fFunctions).
4146/// If the histogram is made persistent, the list of associated functions is also persistent.
4147/// Given a histogram h, one can retrieve an associated function with:
4148///
4149/// ~~~ {.cpp}
4150/// TF1 *myfunc = h->GetFunction("myfunc");
4151/// ~~~
4152/// or by quering directly the list obtained by calling `TH1::GetListOfFunctions`.
4153///
4154/// \anchor HFitStatus
4155/// ### Fit status
4156///
4157/// The status of the fit is obtained converting the TFitResultPtr to an integer
4158/// independently if the fit option "S" is used or not:
4159///
4160/// ~~~ {.cpp}
4161/// TFitResultPtr r = h->Fit(myFunc,opt);
4162/// Int_t fitStatus = r;
4163/// ~~~
4164///
4165/// - `status = 0` : the fit has been performed successfully (i.e no error occurred).
4166/// - `status < 0` : there is an error not connected with the minimization procedure, for example when a wrong function is used.
4167/// - `status > 0` : return status from Minimizer, depends on used Minimizer. For example for TMinuit and Minuit2 we have:
4168/// - `status = migradStatus + 10*minosStatus + 100*hesseStatus + 1000*improveStatus`.
4169/// 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
4170/// only in Minos but not in Migrad a fitStatus of 40 will be returned.
4171/// Minuit2 returns 0 in case of success and different values in migrad,minos or
4172/// hesse depending on the error. See in this case the documentation of
4173/// Minuit2Minimizer::Minimize for the migrad return status, Minuit2Minimizer::GetMinosError for the
4174/// minos return status and Minuit2Minimizer::Hesse for the hesse return status.
4175/// If other minimizers are used see their specific documentation for the status code returned.
4176/// For example in the case of Fumili, see TFumili::Minimize.
4177///
4178/// \anchor HFitRange
4179/// ### Fitting in a range
4180///
4181/// In order to fit in a sub-range of the histogram you have two options:
4182/// - pass to this function the lower (`xxmin`) and upper (`xxmax`) values for the fitting range;
4183/// - define a specific range in the fitted function and use the fitting option "R".
4184/// For example, if your histogram has a defined range between -4 and 4 and you want to fit a gaussian
4185/// only in the interval 1 to 3, you can do:
4186///
4187/// ~~~ {.cpp}
4188/// TF1 *f1 = new TF1("f1", "gaus", 1, 3);
4189/// histo->Fit("f1", "R");
4190/// ~~~
4191///
4192/// The fitting range is also limited by the histogram range defined using TAxis::SetRange
4193/// or TAxis::SetRangeUser. Therefore the fitting range is the smallest range between the
4194/// histogram one and the one defined by one of the two previous options described above.
4195///
4196/// \anchor HFitInitial
4197/// ### Setting initial conditions
4198///
4199/// Parameters must be initialized before invoking the Fit function.
4200/// The setting of the parameter initial values is automatic for the
4201/// predefined functions such as poln, expo, gaus, landau. One can however disable
4202/// this automatic computation by using the option "B".
4203/// Note that if a predefined function is defined with an argument,
4204/// eg, gaus(0), expo(1), you must specify the initial values for
4205/// the parameters.
4206/// You can specify boundary limits for some or all parameters via
4207///
4208/// ~~~ {.cpp}
4209/// f1->SetParLimits(p_number, parmin, parmax);
4210/// ~~~
4211///
4212/// if `parmin >= parmax`, the parameter is fixed
4213/// Note that you are not forced to fix the limits for all parameters.
4214/// For example, if you fit a function with 6 parameters, you can do:
4215///
4216/// ~~~ {.cpp}
4217/// func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
4218/// func->SetParLimits(3, -10, -4);
4219/// func->FixParameter(4, 0);
4220/// func->SetParLimits(5, 1, 1);
4221/// ~~~
4222///
4223/// With this setup, parameters 0->2 can vary freely
4224/// Parameter 3 has boundaries [-10,-4] with initial value -8
4225/// Parameter 4 is fixed to 0
4226/// Parameter 5 is fixed to 100.
4227/// When the lower limit and upper limit are equal, the parameter is fixed.
4228/// However to fix a parameter to 0, one must call the FixParameter function.
4229///
4230/// \anchor HFitStatBox
4231/// ### Fit Statistics Box
4232///
4233/// The statistics box can display the result of the fit.
4234/// You can change the statistics box to display the fit parameters with
4235/// the TStyle::SetOptFit(mode) method. This mode has four digits.
4236/// mode = pcev (default = 0111)
4237///
4238/// v = 1; print name/values of parameters
4239/// e = 1; print errors (if e=1, v must be 1)
4240/// c = 1; print Chisquare/Number of degrees of freedom
4241/// p = 1; print Probability
4242///
4243/// For example: gStyle->SetOptFit(1011);
4244/// prints the fit probability, parameter names/values, and errors.
4245/// You can change the position of the statistics box with these lines
4246/// (where g is a pointer to the TGraph):
4247///
4248/// TPaveStats *st = (TPaveStats*)g->GetListOfFunctions()->FindObject("stats");
4249/// st->SetX1NDC(newx1); //new x start position
4250/// st->SetX2NDC(newx2); //new x end position
4251///
4252/// \anchor HFitExtra
4253/// ### Additional Notes on Fitting
4254///
4255/// #### Fitting a histogram of dimension N with a function of dimension N-1
4256///
4257/// It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
4258/// 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.
4259/// For correct error scaling, the obtained parameter error are corrected as in the case when the
4260/// option "W" is used.
4261///
4262/// #### User defined objective functions
4263///
4264/// By default when fitting a chi square function is used for fitting. When option "L" is used
4265/// a Poisson likelihood function is used. Using option "MULTI" a multinomial likelihood fit is used.
4266/// Thes functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
4267/// are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
4268/// the file math/mathcore/src/FitUtil.cxx.
4269/// It is possible to specify a user defined fitting function, using option "U" and
4270/// calling the following functions:
4271///
4272/// ~~~ {.cpp}
4273/// TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction);
4274/// ~~~
4275///
4276/// where MyFittingFunction is of type:
4277///
4278/// ~~~ {.cpp}
4279/// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
4280/// ~~~
4281///
4282/// #### Note on treatment of empty bins
4283///
4284/// Empty bins, which have the content equal to zero AND error equal to zero,
4285/// are excluded by default from the chi-square fit, but they are considered in the likelihood fit.
4286/// since they affect the likelihood if the function value in these bins is not negligible.
4287/// Note that if the histogram is having bins with zero content and non zero-errors they are considered as
4288/// any other bins in the fit. Instead bins with zero error and non-zero content are by default excluded in the chi-squared fit.
4289/// In general, one should not fit a histogram with non-empty bins and zero errors.
4290///
4291/// 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
4292/// fit). When using option "WW" the empty bins will be also considered in the chi-square fit with an error of 1.
4293/// Note that in this fitting case (option "W" or "WW") the resulting fitted parameter errors
4294/// are corrected by the obtained chi2 value using this scaling expression:
4295/// `errorp *= sqrt(chisquare/(ndf-1))` as it is done when fitting a TGraph with
4296/// no point errors.
4297///
4298/// #### Excluding points
4299///
4300/// You can use TF1::RejectPoint inside your fitting function to exclude some points
4301/// within a certain range from the fit. See the tutorial `fit/fitExclude.C`.
4302///
4303///
4304/// #### Warning when using the option "0"
4305///
4306/// When selecting the option "0", the fitted function is added to
4307/// the list of functions of the histogram, but it is not drawn when the histogram is drawn.
4308/// You can undo this behaviour resetting its corresponding bit in the TF1 object as following:
4309///
4310/// ~~~ {.cpp}
4311/// h.Fit("myFunction", "0"); // fit, store function but do not draw
4312/// h.Draw(); // function is not drawn
4313/// h.GetFunction("myFunction")->ResetBit(TF1::kNotDraw);
4314/// h.Draw(); // function is visible again
4315/// ~~~
4317
4319{
4320 // implementation of Fit method is in file hist/src/HFitImpl.cxx
4323
4324 // create range and minimizer options with default values
4327
4328 // need to empty the buffer before
4329 // (t.b.d. do a ML unbinned fit with buffer data)
4330 if (fBuffer) BufferEmpty();
4331
4333}
4334
4335////////////////////////////////////////////////////////////////////////////////
4336/// Display a panel with all histogram fit options.
4337///
4338/// See class TFitPanel for example
4339
4340void TH1::FitPanel()
4341{
4342 if (!gPad)
4343 gROOT->MakeDefCanvas();
4344
4345 if (!gPad) {
4346 Error("FitPanel", "Unable to create a default canvas");
4347 return;
4348 }
4349
4350
4351 // use plugin manager to create instance of TFitEditor
4352 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
4353 if (handler && handler->LoadPlugin() != -1) {
4354 if (handler->ExecPlugin(2, gPad, this) == 0)
4355 Error("FitPanel", "Unable to create the FitPanel");
4356 }
4357 else
4358 Error("FitPanel", "Unable to find the FitPanel plug-in");
4359}
4360
4361////////////////////////////////////////////////////////////////////////////////
4362/// Return a histogram containing the asymmetry of this histogram with h2,
4363/// where the asymmetry is defined as:
4364///
4365/// ~~~ {.cpp}
4366/// Asymmetry = (h1 - h2)/(h1 + h2) where h1 = this
4367/// ~~~
4368///
4369/// works for 1D, 2D, etc. histograms
4370/// c2 is an optional argument that gives a relative weight between the two
4371/// histograms, and dc2 is the error on this weight. This is useful, for example,
4372/// when forming an asymmetry between two histograms from 2 different data sets that
4373/// need to be normalized to each other in some way. The function calculates
4374/// the errors assuming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
4375///
4376/// example: assuming 'h1' and 'h2' are already filled
4377///
4378/// ~~~ {.cpp}
4379/// h3 = h1->GetAsymmetry(h2)
4380/// ~~~
4381///
4382/// then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
4383/// h1 and h2 are left intact.
4384///
4385/// Note that it is the user's responsibility to manage the created histogram.
4386/// The name of the returned histogram will be `Asymmetry_nameOfh1-nameOfh2`
4387///
4388/// code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
4389///
4390/// clone the histograms so top and bottom will have the
4391/// correct dimensions:
4392/// Sumw2 just makes sure the errors will be computed properly
4393/// when we form sums and ratios below.
4394
4396{
4397 TH1 *h1 = this;
4398 TString name = TString::Format("Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4399 TH1 *asym = (TH1*)Clone(name);
4400
4401 // set also the title
4402 TString title = TString::Format("(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4403 asym->SetTitle(title);
4404
4405 asym->Sumw2();
4406
4407 TDirectory::TContext ctx{nullptr};
4408 TH1 *top = (TH1*)asym->Clone();
4409 TH1 *bottom = (TH1*)asym->Clone();
4410
4411 // form the top and bottom of the asymmetry, and then divide:
4412 top->Add(h1,h2,1,-c2);
4413 bottom->Add(h1,h2,1,c2);
4414 asym->Divide(top,bottom);
4415
4416 Int_t xmax = asym->GetNbinsX();
4417 Int_t ymax = asym->GetNbinsY();
4418 Int_t zmax = asym->GetNbinsZ();
4419
4420 if (h1->fBuffer) h1->BufferEmpty(1);
4421 if (h2->fBuffer) h2->BufferEmpty(1);
4422 if (bottom->fBuffer) bottom->BufferEmpty(1);
4423
4424 // now loop over bins to calculate the correct errors
4425 // the reason this error calculation looks complex is because of c2
4426 for(Int_t i=1; i<= xmax; i++){
4427 for(Int_t j=1; j<= ymax; j++){
4428 for(Int_t k=1; k<= zmax; k++){
4429 Int_t bin = GetBin(i, j, k);
4430 // here some bin contents are written into variables to make the error
4431 // calculation a little more legible:
4433 Double_t b = h2->RetrieveBinContent(bin);
4434 Double_t bot = bottom->RetrieveBinContent(bin);
4435
4436 // make sure there are some events, if not, then the errors are set = 0
4437 // automatically.
4438 //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
4439 if(bot < 1e-6){}
4440 else{
4441 // computation of errors by Christos Leonidopoulos
4444 Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4445 asym->SetBinError(i,j,k,error);
4446 }
4447 }
4448 }
4449 }
4450 delete top;
4451 delete bottom;
4452
4453 return asym;
4454}
4455
4456////////////////////////////////////////////////////////////////////////////////
4457/// Static function
4458/// return the default buffer size for automatic histograms
4459/// the parameter fgBufferSize may be changed via SetDefaultBufferSize
4460
4462{
4463 return fgBufferSize;
4464}
4465
4466////////////////////////////////////////////////////////////////////////////////
4467/// Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
4468/// see TH1::SetDefaultSumw2.
4469
4471{
4472 return fgDefaultSumw2;
4473}
4474
4475////////////////////////////////////////////////////////////////////////////////
4476/// Return the current number of entries.
4477
4479{
4480 if (fBuffer) {
4481 Int_t nentries = (Int_t) fBuffer[0];
4482 if (nentries > 0) return nentries;
4483 }
4484
4485 return fEntries;
4486}
4487
4488////////////////////////////////////////////////////////////////////////////////
4489/// Number of effective entries of the histogram.
4490///
4491/// \f[
4492/// neff = \frac{(\sum Weights )^2}{(\sum Weight^2 )}
4493/// \f]
4494///
4495/// In case of an unweighted histogram this number is equivalent to the
4496/// number of entries of the histogram.
4497/// For a weighted histogram, this number corresponds to the hypothetical number of unweighted entries
4498/// a histogram would need to have the same statistical power as this weighted histogram.
4499/// Note: The underflow/overflow are included if one has set the TH1::StatOverFlows flag
4500/// and if the statistics has been computed at filling time.
4501/// If a range is set in the histogram the number is computed from the given range.
4502
4504{
4505 Stat_t s[kNstat];
4506 this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
4507 return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4508}
4509
4510////////////////////////////////////////////////////////////////////////////////
4511/// Shortcut to set the three histogram colors with a single call.
4512///
4513/// By default: linecolor = markercolor = fillcolor = -1
4514/// If a color is < 0 this method does not change the corresponding color if positive or null it set the color.
4515///
4516/// For instance:
4517/// ~~~ {.cpp}
4518/// h->SetColors(kRed, kRed);
4519/// ~~~
4520/// will set the line color and the marker color to red.
4521
4523{
4524 if (linecolor >= 0)
4526 if (markercolor >= 0)
4528 if (fillcolor >= 0)
4530}
4531
4532
4533////////////////////////////////////////////////////////////////////////////////
4534/// Set highlight (enable/disable) mode for the histogram
4535/// by default highlight mode is disable
4536
4537void TH1::SetHighlight(Bool_t set)
4538{
4539 if (IsHighlight() == set)
4540 return;
4541 if (fDimension > 2) {
4542 Info("SetHighlight", "Supported only 1-D or 2-D histograms");
4543 return;
4544 }
4545
4546 SetBit(kIsHighlight, set);
4547
4548 if (fPainter)
4550}
4551
4552////////////////////////////////////////////////////////////////////////////////
4553/// Redefines TObject::GetObjectInfo.
4554/// Displays the histogram info (bin number, contents, integral up to bin
4555/// corresponding to cursor position px,py
4556
4557char *TH1::GetObjectInfo(Int_t px, Int_t py) const
4558{
4559 return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
4560}
4561
4562////////////////////////////////////////////////////////////////////////////////
4563/// Return pointer to painter.
4564/// If painter does not exist, it is created
4565
4567{
4568 if (!fPainter) {
4569 TString opt = option;
4570 opt.ToLower();
4571 if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
4572 //try to create TGLHistPainter
4573 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
4574
4575 if (handler && handler->LoadPlugin() != -1)
4576 fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
4577 }
4578 }
4579
4581
4582 return fPainter;
4583}
4584
4585////////////////////////////////////////////////////////////////////////////////
4586/// Compute Quantiles for this histogram.
4587/// A quantile x_p := Q(p) is defined as the value x_p such that the cumulative
4588/// probability distribution Function F of variable X yields:
4589///
4590/// ~~~ {.cpp}
4591/// F(x_p) = Pr(X <= x_p) = p with 0 <= p <= 1.
4592/// x_p = Q(p) = F_inv(p)
4593/// ~~~
4594///
4595/// For instance the median x_0.5 of a distribution is defined as that value
4596/// of the random variable X for which the distribution function equals 0.5:
4597///
4598/// ~~~ {.cpp}
4599/// F(x_0.5) = Probability(X < x_0.5) = 0.5
4600/// x_0.5 = Q(0.5)
4601/// ~~~
4602///
4603/// \author Eddy Offermann
4604/// code from Eddy Offermann, Renaissance
4605///
4606/// \param[in] n maximum size of the arrays xp and p (if given)
4607/// \param[out] xp array to be filled with nq quantiles evaluated at (p). Memory has to be preallocated by caller.
4608/// - If `p == nullptr`, the quantiles are computed at the (first `n`) probabilities p given by the CDF of the histogram;
4609/// `n` must thus be smaller or equal Nbins+1, otherwise the extra values of `xp` will not be filled and `nq` will be smaller than `n`.
4610/// If all bins have non-zero entries, the quantiles happen to be the bin centres.
4611/// Empty bins will, however, be skipped in the quantiles.
4612/// If the CDF is e.g. [0., 0., 0.1, ...], the quantiles would be, [3., 3., 3., ...], with the third bin starting
4613/// at 3.
4614/// \param[in] p array of cumulative probabilities where quantiles should be evaluated.
4615/// - if `p == nullptr`, the CDF of the histogram will be used to compute the quantiles, and will
4616/// have a size of n.
4617/// - Otherwise, it is assumed to contain at least n values.
4618/// \return number of quantiles computed
4619/// \note Unlike in TF1::GetQuantiles, `p` is here an optional argument
4620///
4621/// Note that the Integral of the histogram is automatically recomputed
4622/// if the number of entries is different of the number of entries when
4623/// the integral was computed last time. In case you do not use the Fill
4624/// functions to fill your histogram, but SetBinContent, you must call
4625/// TH1::ComputeIntegral before calling this function.
4626///
4627/// Getting quantiles xp from two histograms and storing results in a TGraph,
4628/// a so-called QQ-plot
4629///
4630/// ~~~ {.cpp}
4631/// TGraph *gr = new TGraph(nprob);
4632/// h1->GetQuantiles(nprob,gr->GetX());
4633/// h2->GetQuantiles(nprob,gr->GetY());
4634/// gr->Draw("alp");
4635/// ~~~
4636///
4637/// Example:
4638///
4639/// ~~~ {.cpp}
4640/// void quantiles() {
4641/// // demo for quantiles
4642/// const Int_t nq = 20;
4643/// TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
4644/// h->FillRandom("gaus",5000);
4645/// h->GetXaxis()->SetTitle("x");
4646/// h->GetYaxis()->SetTitle("Counts");
4647///
4648/// Double_t p[nq]; // probabilities where to evaluate the quantiles in [0,1]
4649/// Double_t xp[nq]; // array of positions X to store the resulting quantiles
4650/// for (Int_t i=0;i<nq;i++) p[i] = Float_t(i+1)/nq;
4651/// h->GetQuantiles(nq,xp,p);
4652///
4653/// //show the original histogram in the top pad
4654/// TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
4655/// c1->Divide(1,2);
4656/// c1->cd(1);
4657/// h->Draw();
4658///
4659/// // show the quantiles in the bottom pad
4660/// c1->cd(2);
4661/// gPad->SetGrid();
4662/// TGraph *gr = new TGraph(nq,p,xp);
4663/// gr->SetMarkerStyle(21);
4664/// gr->GetXaxis()->SetTitle("p");
4665/// gr->GetYaxis()->SetTitle("x");
4666/// gr->Draw("alp");
4667/// }
4668/// ~~~
4669
4671{
4672 if (GetDimension() > 1) {
4673 Error("GetQuantiles","Only available for 1-d histograms");
4674 return 0;
4675 }
4676
4677 const Int_t nbins = GetXaxis()->GetNbins();
4678 if (!fIntegral) ComputeIntegral();
4679 if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4680
4681 Int_t i, ibin;
4682 Int_t nq = n;
4683 std::unique_ptr<Double_t[]> localProb;
4684 if (p == nullptr) {
4685 nq = nbins+1;
4686 localProb.reset(new Double_t[nq]);
4687 localProb[0] = 0;
4688 for (i=1;i<nq;i++) {
4689 localProb[i] = fIntegral[i] / fIntegral[nbins];
4690 }
4691 }
4692 Double_t const *const prob = p ? p : localProb.get();
4693
4694 for (i = 0; i < nq; i++) {
4696 if (fIntegral[ibin] == prob[i]) {
4697 if (prob[i] == 0.) {
4698 for (; ibin+1 <= nbins && fIntegral[ibin+1] == 0.; ++ibin) {
4699
4700 }
4701 xp[i] = fXaxis.GetBinUpEdge(ibin);
4702 }
4703 else if (prob[i] == 1.) {
4704 xp[i] = fXaxis.GetBinUpEdge(ibin);
4705 }
4706 else {
4707 // Find equal integral in later bins (ie their entries are zero)
4708 Double_t width = 0;
4709 for (Int_t j = ibin+1; j <= nbins; ++j) {
4710 if (prob[i] == fIntegral[j]) {
4712 }
4713 else
4714 break;
4715 }
4717 }
4718 }
4719 else {
4720 xp[i] = GetBinLowEdge(ibin+1);
4722 if (dint > 0) xp[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4723 }
4724 }
4725
4726 return nq;
4727}
4728
4729////////////////////////////////////////////////////////////////////////////////
4735 return 1;
4736}
4737
4738////////////////////////////////////////////////////////////////////////////////
4739/// Compute Initial values of parameters for a gaussian.
4740
4741void H1InitGaus()
4742{
4743 Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4744 Int_t bin;
4745 const Double_t sqrtpi = 2.506628;
4746
4747 // - Compute mean value and StdDev of the histogram in the given range
4749 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4750 Int_t hxfirst = hFitter->GetXfirst();
4751 Int_t hxlast = hFitter->GetXlast();
4752 Double_t valmax = curHist->GetBinContent(hxfirst);
4753 Double_t binwidx = curHist->GetBinWidth(hxfirst);
4754 allcha = sumx = sumx2 = 0;
4755 for (bin=hxfirst;bin<=hxlast;bin++) {
4756 x = curHist->GetBinCenter(bin);
4757 val = TMath::Abs(curHist->GetBinContent(bin));
4758 if (val > valmax) valmax = val;
4759 sumx += val*x;
4760 sumx2 += val*x*x;
4761 allcha += val;
4762 }
4763 if (allcha == 0) return;
4764 mean = sumx/allcha;
4765 stddev = sumx2/allcha - mean*mean;
4766 if (stddev > 0) stddev = TMath::Sqrt(stddev);
4767 else stddev = 0;
4768 if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4769 //if the distribution is really gaussian, the best approximation
4770 //is binwidx*allcha/(sqrtpi*stddev)
4771 //However, in case of non-gaussian tails, this underestimates
4772 //the normalisation constant. In this case the maximum value
4773 //is a better approximation.
4774 //We take the average of both quantities
4776
4777 //In case the mean value is outside the histo limits and
4778 //the StdDev is bigger than the range, we take
4779 // mean = center of bins
4780 // stddev = half range
4781 Double_t xmin = curHist->GetXaxis()->GetXmin();
4782 Double_t xmax = curHist->GetXaxis()->GetXmax();
4783 if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4784 mean = 0.5*(xmax+xmin);
4785 stddev = 0.5*(xmax-xmin);
4786 }
4787 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4789 f1->SetParameter(1,mean);
4791 f1->SetParLimits(2,0,10*stddev);
4792}
4793
4794////////////////////////////////////////////////////////////////////////////////
4795/// Compute Initial values of parameters for an exponential.
4796
4797void H1InitExpo()
4798{
4800 Int_t ifail;
4802 Int_t hxfirst = hFitter->GetXfirst();
4803 Int_t hxlast = hFitter->GetXlast();
4804 Int_t nchanx = hxlast - hxfirst + 1;
4805
4807
4808 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4810 f1->SetParameter(1,slope);
4811
4812}
4813
4814////////////////////////////////////////////////////////////////////////////////
4815/// Compute Initial values of parameters for a polynom.
4816
4817void H1InitPolynom()
4818{
4819 Double_t fitpar[25];
4820
4822 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4823 Int_t hxfirst = hFitter->GetXfirst();
4824 Int_t hxlast = hFitter->GetXlast();
4825 Int_t nchanx = hxlast - hxfirst + 1;
4826 Int_t npar = f1->GetNpar();
4827
4828 if (nchanx <=1 || npar == 1) {
4829 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4830 fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4831 } else {
4833 }
4834 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4835}
4836
4837////////////////////////////////////////////////////////////////////////////////
4838/// Least squares lpolynomial fitting without weights.
4839///
4840/// \param[in] n number of points to fit
4841/// \param[in] m number of parameters
4842/// \param[in] a array of parameters
4843///
4844/// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
4845/// (E.Keil. revised by B.Schorr, 23.10.1981.)
4846
4848{
4849 const Double_t zero = 0.;
4850 const Double_t one = 1.;
4851 const Int_t idim = 20;
4852
4853 Double_t b[400] /* was [20][20] */;
4854 Int_t i, k, l, ifail;
4856 Double_t da[20], xk, yk;
4857
4858 if (m <= 2) {
4859 H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4860 return;
4861 }
4862 if (m > idim || m > n) return;
4863 b[0] = Double_t(n);
4864 da[0] = zero;
4865 for (l = 2; l <= m; ++l) {
4866 b[l-1] = zero;
4867 b[m + l*20 - 21] = zero;
4868 da[l-1] = zero;
4869 }
4871 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4872 Int_t hxfirst = hFitter->GetXfirst();
4873 Int_t hxlast = hFitter->GetXlast();
4874 for (k = hxfirst; k <= hxlast; ++k) {
4875 xk = curHist->GetBinCenter(k);
4876 yk = curHist->GetBinContent(k);
4877 power = one;
4878 da[0] += yk;
4879 for (l = 2; l <= m; ++l) {
4880 power *= xk;
4881 b[l-1] += power;
4882 da[l-1] += power*yk;
4883 }
4884 for (l = 2; l <= m; ++l) {
4885 power *= xk;
4886 b[m + l*20 - 21] += power;
4887 }
4888 }
4889 for (i = 3; i <= m; ++i) {
4890 for (k = i; k <= m; ++k) {
4891 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4892 }
4893 }
4895
4896 for (i=0; i<m; ++i) a[i] = da[i];
4897
4898}
4899
4900////////////////////////////////////////////////////////////////////////////////
4901/// Least square linear fit without weights.
4902///
4903/// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
4904/// (added to LSQ by B. Schorr, 15.02.1982.)
4905
4907{
4909 Int_t i, n;
4911 Double_t fn, xk, yk;
4912 Double_t det;
4913
4914 n = TMath::Abs(ndata);
4915 ifail = -2;
4916 xbar = ybar = x2bar = xybar = 0;
4918 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4919 Int_t hxfirst = hFitter->GetXfirst();
4920 Int_t hxlast = hFitter->GetXlast();
4921 for (i = hxfirst; i <= hxlast; ++i) {
4922 xk = curHist->GetBinCenter(i);
4923 yk = curHist->GetBinContent(i);
4924 if (ndata < 0) {
4925 if (yk <= 0) yk = 1e-9;
4926 yk = TMath::Log(yk);
4927 }
4928 xbar += xk;
4929 ybar += yk;
4930 x2bar += xk*xk;
4931 xybar += xk*yk;
4932 }
4933 fn = Double_t(n);
4934 det = fn*x2bar - xbar*xbar;
4935 ifail = -1;
4936 if (det <= 0) {
4937 a0 = ybar/fn;
4938 a1 = 0;
4939 return;
4940 }
4941 ifail = 0;
4942 a0 = (x2bar*ybar - xbar*xybar) / det;
4943 a1 = (fn*xybar - xbar*ybar) / det;
4944
4945}
4946
4947////////////////////////////////////////////////////////////////////////////////
4948/// Extracted from CERN Program library routine DSEQN.
4949///
4950/// Translated to C++ by Rene Brun
4951
4953{
4955 Int_t nmjp1, i, j, l;
4956 Int_t im1, jp1, nm1, nmi;
4957 Double_t s1, s21, s22;
4958 const Double_t one = 1.;
4959
4960 /* Parameter adjustments */
4961 b_dim1 = idim;
4962 b_offset = b_dim1 + 1;
4963 b -= b_offset;
4964 a_dim1 = idim;
4965 a_offset = a_dim1 + 1;
4966 a -= a_offset;
4967
4968 if (idim < n) return;
4969
4970 ifail = 0;
4971 for (j = 1; j <= n; ++j) {
4972 if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
4973 a[j + j*a_dim1] = one / a[j + j*a_dim1];
4974 if (j == n) continue;
4975 jp1 = j + 1;
4976 for (l = jp1; l <= n; ++l) {
4977 a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4978 s1 = -a[l + (j+1)*a_dim1];
4979 for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4980 a[l + (j+1)*a_dim1] = -s1;
4981 }
4982 }
4983 if (k <= 0) return;
4984
4985 for (l = 1; l <= k; ++l) {
4986 b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
4987 }
4988 if (n == 1) return;
4989 for (l = 1; l <= k; ++l) {
4990 for (i = 2; i <= n; ++i) {
4991 im1 = i - 1;
4992 s21 = -b[i + l*b_dim1];
4993 for (j = 1; j <= im1; ++j) {
4994 s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
4995 }
4996 b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
4997 }
4998 nm1 = n - 1;
4999 for (i = 1; i <= nm1; ++i) {
5000 nmi = n - i;
5001 s22 = -b[nmi + l*b_dim1];
5002 for (j = 1; j <= i; ++j) {
5003 nmjp1 = n - j + 1;
5004 s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
5005 }
5006 b[nmi + l*b_dim1] = -s22;
5007 }
5008 }
5009}
5010
5011////////////////////////////////////////////////////////////////////////////////
5012/// Return Global bin number corresponding to binx,y,z.
5013///
5014/// 2-D and 3-D histograms are represented with a one dimensional
5015/// structure.
5016/// This has the advantage that all existing functions, such as
5017/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
5018///
5019/// In case of a TH1x, returns binx directly.
5020/// see TH1::GetBinXYZ for the inverse transformation.
5021///
5022/// Convention for numbering bins
5023///
5024/// For all histogram types: nbins, xlow, xup
5025///
5026/// - bin = 0; underflow bin
5027/// - bin = 1; first bin with low-edge xlow INCLUDED
5028/// - bin = nbins; last bin with upper-edge xup EXCLUDED
5029/// - bin = nbins+1; overflow bin
5030///
5031/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
5032/// For example, assuming a 3-D histogram with binx,biny,binz, the function
5033///
5034/// ~~~ {.cpp}
5035/// Int_t bin = h->GetBin(binx,biny,binz);
5036/// ~~~
5037///
5038/// returns a global/linearized bin number. This global bin is useful
5039/// to access the bin information independently of the dimension.
5040
5042{
5043 Int_t ofx = fXaxis.GetNbins() + 1; // overflow bin
5044 if (binx < 0) binx = 0;
5045 if (binx > ofx) binx = ofx;
5046
5047 return binx;
5048}
5049
5050////////////////////////////////////////////////////////////////////////////////
5051/// Return binx, biny, binz corresponding to the global bin number globalbin
5052/// see TH1::GetBin function above
5053
5055{
5056 Int_t nx = fXaxis.GetNbins()+2;
5057 Int_t ny = fYaxis.GetNbins()+2;
5058
5059 if (GetDimension() == 1) {
5060 binx = binglobal%nx;
5061 biny = 0;
5062 binz = 0;
5063 return;
5064 }
5065 if (GetDimension() == 2) {
5066 binx = binglobal%nx;
5067 biny = ((binglobal-binx)/nx)%ny;
5068 binz = 0;
5069 return;
5070 }
5071 if (GetDimension() == 3) {
5072 binx = binglobal%nx;
5073 biny = ((binglobal-binx)/nx)%ny;
5074 binz = ((binglobal-binx)/nx -biny)/ny;
5075 }
5076}
5077
5078////////////////////////////////////////////////////////////////////////////////
5079/// Return a random number distributed according the histogram bin contents.
5080/// This function checks if the bins integral exists. If not, the integral
5081/// is evaluated, normalized to one.
5082///
5083/// @param rng (optional) Random number generator pointer used (default is gRandom)
5084/// @param option (optional) Set it to "width" if your non-uniform bin contents represent a density rather than counts
5085///
5086/// The integral is automatically recomputed if the number of entries
5087/// is not the same then when the integral was computed.
5088/// @note Only valid for 1-d histograms. Use GetRandom2 or GetRandom3 otherwise.
5089/// If the histogram has a bin with negative content, a NaN is returned.
5090
5092{
5093 if (fDimension > 1) {
5094 Error("GetRandom","Function only valid for 1-d histograms");
5095 return 0;
5096 }
5098 Double_t integral = 0;
5099 // compute integral checking that all bins have positive content (see ROOT-5894)
5100 if (fIntegral) {
5101 if (fIntegral[nbinsx + 1] != fEntries)
5102 integral = const_cast<TH1 *>(this)->ComputeIntegral(true, option);
5103 else integral = fIntegral[nbinsx];
5104 } else {
5105 integral = const_cast<TH1 *>(this)->ComputeIntegral(true, option);
5106 }
5107 if (integral == 0) return 0;
5108 // return a NaN in case some bins have negative content
5109 if (integral == TMath::QuietNaN() ) return TMath::QuietNaN();
5110
5111 Double_t r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
5114 if (r1 > fIntegral[ibin]) x +=
5116 return x;
5117}
5118
5119////////////////////////////////////////////////////////////////////////////////
5120/// Return content of bin number bin.
5121///
5122/// Implemented in TH1C,S,F,D
5123///
5124/// Convention for numbering bins
5125///
5126/// For all histogram types: nbins, xlow, xup
5127///
5128/// - bin = 0; underflow bin
5129/// - bin = 1; first bin with low-edge xlow INCLUDED
5130/// - bin = nbins; last bin with upper-edge xup EXCLUDED
5131/// - bin = nbins+1; overflow bin
5132///
5133/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
5134/// For example, assuming a 3-D histogram with binx,biny,binz, the function
5135///
5136/// ~~~ {.cpp}
5137/// Int_t bin = h->GetBin(binx,biny,binz);
5138/// ~~~
5139///
5140/// returns a global/linearized bin number. This global bin is useful
5141/// to access the bin information independently of the dimension.
5142
5144{
5145 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
5146 if (bin < 0) bin = 0;
5147 if (bin >= fNcells) bin = fNcells-1;
5148
5149 return RetrieveBinContent(bin);
5150}
5151
5152////////////////////////////////////////////////////////////////////////////////
5153/// Compute first binx in the range [firstx,lastx] for which
5154/// diff = abs(bin_content-c) <= maxdiff
5155///
5156/// In case several bins in the specified range with diff=0 are found
5157/// the first bin found is returned in binx.
5158/// In case several bins in the specified range satisfy diff <=maxdiff
5159/// the bin with the smallest difference is returned in binx.
5160/// In all cases the function returns the smallest difference.
5161///
5162/// NOTE1: if firstx <= 0, firstx is set to bin 1
5163/// if (lastx < firstx then firstx is set to the number of bins
5164/// ie if firstx=0 and lastx=0 (default) the search is on all bins.
5165///
5166/// NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
5167
5169{
5170 if (fDimension > 1) {
5171 binx = 0;
5172 Error("GetBinWithContent","function is only valid for 1-D histograms");
5173 return 0;
5174 }
5175
5176 if (fBuffer) ((TH1*)this)->BufferEmpty();
5177
5178 if (firstx <= 0) firstx = 1;
5179 if (lastx < firstx) lastx = fXaxis.GetNbins();
5180 Int_t binminx = 0;
5181 Double_t diff, curmax = 1.e240;
5182 for (Int_t i=firstx;i<=lastx;i++) {
5184 if (diff <= 0) {binx = i; return diff;}
5185 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
5186 }
5187 binx = binminx;
5188 return curmax;
5189}
5190
5191////////////////////////////////////////////////////////////////////////////////
5192/// Given a point x, approximates the value via linear interpolation
5193/// based on the two nearest bin centers
5194///
5195/// Andy Mastbaum 10/21/08
5196
5198{
5199 if (fBuffer) ((TH1*)this)->BufferEmpty();
5200
5202 Double_t x0,x1,y0,y1;
5203
5204 if(x<=GetBinCenter(1)) {
5205 return RetrieveBinContent(1);
5206 } else if(x>=GetBinCenter(GetNbinsX())) {
5207 return RetrieveBinContent(GetNbinsX());
5208 } else {
5209 if(x<=GetBinCenter(xbin)) {
5211 x0 = GetBinCenter(xbin-1);
5213 x1 = GetBinCenter(xbin);
5214 } else {
5216 x0 = GetBinCenter(xbin);
5218 x1 = GetBinCenter(xbin+1);
5219 }
5220 return y0 + (x-x0)*((y1-y0)/(x1-x0));
5221 }
5222}
5223
5224////////////////////////////////////////////////////////////////////////////////
5225/// 2d Interpolation. Not yet implemented.
5226
5228{
5229 Error("Interpolate","This function must be called with 1 argument for a TH1");
5230 return 0;
5231}
5232
5233////////////////////////////////////////////////////////////////////////////////
5234/// 3d Interpolation. Not yet implemented.
5235
5237{
5238 Error("Interpolate","This function must be called with 1 argument for a TH1");
5239 return 0;
5240}
5241
5242///////////////////////////////////////////////////////////////////////////////
5243/// Check if a histogram is empty
5244/// (this is a protected method used mainly by TH1Merger )
5245
5246Bool_t TH1::IsEmpty() const
5247{
5248 // if fTsumw or fentries are not zero histogram is not empty
5249 // need to use GetEntries() instead of fEntries in case of bugger histograms
5250 // so we will flash the buffer
5251 if (fTsumw != 0) return kFALSE;
5252 if (GetEntries() != 0) return kFALSE;
5253 // case fTSumw == 0 amd entries are also zero
5254 // this should not really happening, but if one sets content by hand
5255 // it can happen. a call to ResetStats() should be done in such cases
5256 double sumw = 0;
5257 for (int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
5258 return (sumw != 0) ? kFALSE : kTRUE;
5259}
5260
5261////////////////////////////////////////////////////////////////////////////////
5262/// Return true if the bin is overflow.
5263
5265{
5266 Int_t binx, biny, binz;
5267 GetBinXYZ(bin, binx, biny, binz);
5268
5269 if (iaxis == 0) {
5270 if ( fDimension == 1 )
5271 return binx >= GetNbinsX() + 1;
5272 if ( fDimension == 2 )
5273 return (binx >= GetNbinsX() + 1) ||
5274 (biny >= GetNbinsY() + 1);
5275 if ( fDimension == 3 )
5276 return (binx >= GetNbinsX() + 1) ||
5277 (biny >= GetNbinsY() + 1) ||
5278 (binz >= GetNbinsZ() + 1);
5279 return kFALSE;
5280 }
5281 if (iaxis == 1)
5282 return binx >= GetNbinsX() + 1;
5283 if (iaxis == 2)
5284 return biny >= GetNbinsY() + 1;
5285 if (iaxis == 3)
5286 return binz >= GetNbinsZ() + 1;
5287
5288 Error("IsBinOverflow","Invalid axis value");
5289 return kFALSE;
5290}
5291
5292////////////////////////////////////////////////////////////////////////////////
5293/// Return true if the bin is underflow.
5294/// If iaxis = 0 make OR with all axes otherwise check only for the given axis
5295
5297{
5298 Int_t binx, biny, binz;
5299 GetBinXYZ(bin, binx, biny, binz);
5300
5301 if (iaxis == 0) {
5302 if ( fDimension == 1 )
5303 return (binx <= 0);
5304 else if ( fDimension == 2 )
5305 return (binx <= 0 || biny <= 0);
5306 else if ( fDimension == 3 )
5307 return (binx <= 0 || biny <= 0 || binz <= 0);
5308 else
5309 return kFALSE;
5310 }
5311 if (iaxis == 1)
5312 return (binx <= 0);
5313 if (iaxis == 2)
5314 return (biny <= 0);
5315 if (iaxis == 3)
5316 return (binz <= 0);
5317
5318 Error("IsBinUnderflow","Invalid axis value");
5319 return kFALSE;
5320}
5321
5322////////////////////////////////////////////////////////////////////////////////
5323/// Reduce the number of bins for the axis passed in the option to the number of bins having a label.
5324/// The method will remove only the extra bins existing after the last "labeled" bin.
5325/// Note that if there are "un-labeled" bins present between "labeled" bins they will not be removed
5326
5328{
5330 TAxis *axis = nullptr;
5331 if (iaxis == 1) axis = GetXaxis();
5332 if (iaxis == 2) axis = GetYaxis();
5333 if (iaxis == 3) axis = GetZaxis();
5334 if (!axis) {
5335 Error("LabelsDeflate","Invalid axis option %s",ax);
5336 return;
5337 }
5338 if (!axis->GetLabels()) return;
5339
5340 // find bin with last labels
5341 // bin number is object ID in list of labels
5342 // therefore max bin number is number of bins of the deflated histograms
5343 TIter next(axis->GetLabels());
5344 TObject *obj;
5345 Int_t nbins = 0;
5346 while ((obj = next())) {
5347 Int_t ibin = obj->GetUniqueID();
5348 if (ibin > nbins) nbins = ibin;
5349 }
5350 if (nbins < 1) nbins = 1;
5351
5352 // Do nothing in case it was the last bin
5353 if (nbins==axis->GetNbins()) return;
5354
5355 TH1 *hold = (TH1*)IsA()->New();
5356 R__ASSERT(hold);
5357 hold->SetDirectory(nullptr);
5358 Copy(*hold);
5359
5360 Bool_t timedisp = axis->GetTimeDisplay();
5361 Double_t xmin = axis->GetXmin();
5362 Double_t xmax = axis->GetBinUpEdge(nbins);
5363 if (xmax <= xmin) xmax = xmin +nbins;
5364 axis->SetRange(0,0);
5365 axis->Set(nbins,xmin,xmax);
5366 SetBinsLength(-1); // reset the number of cells
5368 if (errors) fSumw2.Set(fNcells);
5369 axis->SetTimeDisplay(timedisp);
5370 // reset histogram content
5371 Reset("ICE");
5372
5373 //now loop on all bins and refill
5374 // NOTE that if the bins without labels have content
5375 // it will be put in the underflow/overflow.
5376 // For this reason we use AddBinContent method
5378 Int_t bin,binx,biny,binz;
5379 for (bin=0; bin < hold->fNcells; ++bin) {
5380 hold->GetBinXYZ(bin,binx,biny,binz);
5382 Double_t cu = hold->RetrieveBinContent(bin);
5384 if (errors) {
5385 fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5386 }
5387 }
5389 delete hold;
5390}
5391
5392////////////////////////////////////////////////////////////////////////////////
5393/// Double the number of bins for axis.
5394/// Refill histogram.
5395/// This function is called by TAxis::FindBin(const char *label)
5396
5398{
5400 TAxis *axis = nullptr;
5401 if (iaxis == 1) axis = GetXaxis();
5402 if (iaxis == 2) axis = GetYaxis();
5403 if (iaxis == 3) axis = GetZaxis();
5404 if (!axis) return;
5405
5406 TH1 *hold = (TH1*)IsA()->New();
5407 hold->SetDirectory(nullptr);
5408 Copy(*hold);
5409 hold->ResetBit(kMustCleanup);
5410
5411 Bool_t timedisp = axis->GetTimeDisplay();
5412 Int_t nbins = axis->GetNbins();
5413 Double_t xmin = axis->GetXmin();
5414 Double_t xmax = axis->GetXmax();
5415 xmax = xmin + 2*(xmax-xmin);
5416 axis->SetRange(0,0);
5417 // double the bins and recompute ncells
5418 axis->Set(2*nbins,xmin,xmax);
5419 SetBinsLength(-1);
5421 if (errors) fSumw2.Set(fNcells);
5422 axis->SetTimeDisplay(timedisp);
5423
5424 Reset("ICE"); // reset content and error
5425
5426 //now loop on all bins and refill
5428 Int_t bin,ibin,binx,biny,binz;
5429 for (ibin =0; ibin < hold->fNcells; ibin++) {
5430 // get the binx,y,z values . The x-y-z (axis) bin values will stay the same between new-old after the expanding
5431 hold->GetBinXYZ(ibin,binx,biny,binz);
5432 bin = GetBin(binx,biny,binz);
5433
5434 // underflow and overflow will be cleaned up because their meaning has been altered
5435 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5436 continue;
5437 }
5438 else {
5439 AddBinContent(bin, hold->RetrieveBinContent(ibin));
5440 if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5441 }
5442 }
5444 delete hold;
5445}
5446
5447////////////////////////////////////////////////////////////////////////////////
5448/// Sort bins with labels or set option(s) to draw axis with labels
5449/// \param[in] option
5450/// - "a" sort by alphabetic order
5451/// - ">" sort by decreasing values
5452/// - "<" sort by increasing values
5453/// - "h" draw labels horizontal
5454/// - "v" draw labels vertical
5455/// - "u" draw labels up (end of label right adjusted)
5456/// - "d" draw labels down (start of label left adjusted)
5457///
5458/// In case not all bins have labels sorting will work only in the case
5459/// the first `n` consecutive bins have all labels and sorting will be performed on
5460/// those label bins.
5461///
5462/// \param[in] ax axis
5463
5465{
5467 TAxis *axis = nullptr;
5468 if (iaxis == 1)
5469 axis = GetXaxis();
5470 if (iaxis == 2)
5471 axis = GetYaxis();
5472 if (iaxis == 3)
5473 axis = GetZaxis();
5474 if (!axis)
5475 return;
5476 THashList *labels = axis->GetLabels();
5477 if (!labels) {
5478 Warning("LabelsOption", "Axis %s has no labels!",axis->GetName());
5479 return;
5480 }
5481 TString opt = option;
5482 opt.ToLower();
5483 Int_t iopt = -1;
5484 if (opt.Contains("h")) {
5489 iopt = 0;
5490 }
5491 if (opt.Contains("v")) {
5496 iopt = 1;
5497 }
5498 if (opt.Contains("u")) {
5499 axis->SetBit(TAxis::kLabelsUp);
5503 iopt = 2;
5504 }
5505 if (opt.Contains("d")) {
5510 iopt = 3;
5511 }
5512 Int_t sort = -1;
5513 if (opt.Contains("a"))
5514 sort = 0;
5515 if (opt.Contains(">"))
5516 sort = 1;
5517 if (opt.Contains("<"))
5518 sort = 2;
5519 if (sort < 0) {
5520 if (iopt < 0)
5521 Error("LabelsOption", "%s is an invalid label placement option!",opt.Data());
5522 return;
5523 }
5524
5525 // Code works only if first n bins have labels if we uncomment following line
5526 // but we don't want to support this special case
5527 // Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5528
5529 // support only cases where each bin has a labels (should be when axis is alphanumeric)
5530 Int_t n = labels->GetSize();
5531 if (n != axis->GetNbins()) {
5532 // check if labels are all consecutive and starts from the first bin
5533 // in that case the current code will work fine
5534 Int_t firstLabelBin = axis->GetNbins()+1;
5535 Int_t lastLabelBin = -1;
5536 for (Int_t i = 0; i < n; ++i) {
5537 Int_t bin = labels->At(i)->GetUniqueID();
5538 if (bin < firstLabelBin) firstLabelBin = bin;
5539 if (bin > lastLabelBin) lastLabelBin = bin;
5540 }
5541 if (firstLabelBin != 1 || lastLabelBin-firstLabelBin +1 != n) {
5542 Error("LabelsOption", "%s of Histogram %s contains bins without labels. Sorting will not work correctly - return",
5543 axis->GetName(), GetName());
5544 return;
5545 }
5546 // case where label bins are consecutive starting from first bin will work
5547 // calling before a TH1::LabelsDeflate() will avoid this error message
5548 Warning("LabelsOption", "axis %s of Histogram %s has extra following bins without labels. Sorting will work only for first label bins",
5549 axis->GetName(), GetName());
5550 }
5551 std::vector<Int_t> a(n);
5552 std::vector<Int_t> b(n);
5553
5554
5555 Int_t i, j, k;
5556 std::vector<Double_t> cont;
5557 std::vector<Double_t> errors2;
5558 THashList *labold = new THashList(labels->GetSize(), 1);
5559 TIter nextold(labels);
5560 TObject *obj = nullptr;
5561 labold->AddAll(labels);
5562 labels->Clear();
5563
5564 // delete buffer if it is there since bins will be reordered.
5565 if (fBuffer)
5566 BufferEmpty(1);
5567
5568 if (sort > 0) {
5569 //---sort by values of bins
5570 if (GetDimension() == 1) {
5571 cont.resize(n);
5572 if (fSumw2.fN)
5573 errors2.resize(n);
5574 for (i = 0; i < n; i++) {
5575 cont[i] = RetrieveBinContent(i + 1);
5576 if (!errors2.empty())
5577 errors2[i] = GetBinErrorSqUnchecked(i + 1);
5578 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5579 a[i] = i;
5580 }
5581 if (sort == 1)
5582 TMath::Sort(n, cont.data(), a.data(), kTRUE); // sort by decreasing values
5583 else
5584 TMath::Sort(n, cont.data(), a.data(), kFALSE); // sort by increasing values
5585 for (i = 0; i < n; i++) {
5586 // use UpdateBinCOntent to not screw up histogram entries
5587 UpdateBinContent(i + 1, cont[b[a[i]] - 1]); // b[a[i]] returns bin number. .we need to subtract 1
5588 if (gDebug)
5589 Info("LabelsOption","setting bin %d value %f from bin %d label %s at pos %d ",
5590 i+1,cont[b[a[i]] - 1],b[a[i]],labold->At(a[i])->GetName(),a[i]);
5591 if (!errors2.empty())
5592 fSumw2.fArray[i + 1] = errors2[b[a[i]] - 1];
5593 }
5594 for (i = 0; i < n; i++) {
5595 obj = labold->At(a[i]);
5596 labels->Add(obj);
5597 obj->SetUniqueID(i + 1);
5598 }
5599 } else if (GetDimension() == 2) {
5600 std::vector<Double_t> pcont(n + 2);
5601 Int_t nx = fXaxis.GetNbins() + 2;
5602 Int_t ny = fYaxis.GetNbins() + 2;
5603 cont.resize((nx + 2) * (ny + 2));
5604 if (fSumw2.fN)
5605 errors2.resize((nx + 2) * (ny + 2));
5606 for (i = 0; i < nx; i++) {
5607 for (j = 0; j < ny; j++) {
5608 Int_t bin = GetBin(i,j);
5609 cont[i + nx * j] = RetrieveBinContent(bin);
5610 if (!errors2.empty())
5611 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5612 if (axis == GetXaxis())
5613 k = i - 1;
5614 else
5615 k = j - 1;
5616 if (k >= 0 && k < n) { // we consider underflow/overflows in y for ordering the bins
5617 pcont[k] += cont[i + nx * j];
5618 a[k] = k;
5619 }
5620 }
5621 }
5622 if (sort == 1)
5623 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5624 else
5625 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5626 for (i = 0; i < n; i++) {
5627 // iterate on old label list to find corresponding bin match
5628 TIter next(labold);
5629 UInt_t bin = a[i] + 1;
5630 while ((obj = next())) {
5631 if (obj->GetUniqueID() == (UInt_t)bin)
5632 break;
5633 else
5634 obj = nullptr;
5635 }
5636 if (!obj) {
5637 // this should not really happen
5638 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5639 return;
5640 }
5641
5642 labels->Add(obj);
5643 if (gDebug)
5644 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from order " << a[i] << " bin "
5645 << b[a[i]] << "content " << pcont[a[i]] << std::endl;
5646 }
5647 // need to set here new ordered labels - otherwise loop before does not work since labold and labels list
5648 // contain same objects
5649 for (i = 0; i < n; i++) {
5650 labels->At(i)->SetUniqueID(i + 1);
5651 }
5652 // set now the bin contents
5653 if (axis == GetXaxis()) {
5654 for (i = 0; i < n; i++) {
5655 Int_t ix = a[i] + 1;
5656 for (j = 0; j < ny; j++) {
5657 Int_t bin = GetBin(i + 1, j);
5658 UpdateBinContent(bin, cont[ix + nx * j]);
5659 if (!errors2.empty())
5660 fSumw2.fArray[bin] = errors2[ix + nx * j];
5661 }
5662 }
5663 } else {
5664 // using y axis
5665 for (i = 0; i < nx; i++) {
5666 for (j = 0; j < n; j++) {
5667 Int_t iy = a[j] + 1;
5668 Int_t bin = GetBin(i, j + 1);
5669 UpdateBinContent(bin, cont[i + nx * iy]);
5670 if (!errors2.empty())
5671 fSumw2.fArray[bin] = errors2[i + nx * iy];
5672 }
5673 }
5674 }
5675 } else {
5676 // sorting histograms: 3D case
5677 std::vector<Double_t> pcont(n + 2);
5678 Int_t nx = fXaxis.GetNbins() + 2;
5679 Int_t ny = fYaxis.GetNbins() + 2;
5680 Int_t nz = fZaxis.GetNbins() + 2;
5681 Int_t l = 0;
5682 cont.resize((nx + 2) * (ny + 2) * (nz + 2));
5683 if (fSumw2.fN)
5684 errors2.resize((nx + 2) * (ny + 2) * (nz + 2));
5685 for (i = 0; i < nx; i++) {
5686 for (j = 0; j < ny; j++) {
5687 for (k = 0; k < nz; k++) {
5688 Int_t bin = GetBin(i,j,k);
5690 if (axis == GetXaxis())
5691 l = i - 1;
5692 else if (axis == GetYaxis())
5693 l = j - 1;
5694 else
5695 l = k - 1;
5696 if (l >= 0 && l < n) { // we consider underflow/overflows in y for ordering the bins
5697 pcont[l] += c;
5698 a[l] = l;
5699 }
5700 cont[i + nx * (j + ny * k)] = c;
5701 if (!errors2.empty())
5702 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5703 }
5704 }
5705 }
5706 if (sort == 1)
5707 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5708 else
5709 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5710 for (i = 0; i < n; i++) {
5711 // iterate on the old label list to find corresponding bin match
5712 TIter next(labold);
5713 UInt_t bin = a[i] + 1;
5714 obj = nullptr;
5715 while ((obj = next())) {
5716 if (obj->GetUniqueID() == (UInt_t)bin) {
5717 break;
5718 }
5719 else
5720 obj = nullptr;
5721 }
5722 if (!obj) {
5723 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5724 return;
5725 }
5726 labels->Add(obj);
5727 if (gDebug)
5728 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from bin " << a[i] << "content "
5729 << pcont[a[i]] << std::endl;
5730 }
5731
5732 // need to set here new ordered labels - otherwise loop before does not work since labold and llabels list
5733 // contain same objects
5734 for (i = 0; i < n; i++) {
5735 labels->At(i)->SetUniqueID(i + 1);
5736 }
5737 // set now the bin contents
5738 if (axis == GetXaxis()) {
5739 for (i = 0; i < n; i++) {
5740 Int_t ix = a[i] + 1;
5741 for (j = 0; j < ny; j++) {
5742 for (k = 0; k < nz; k++) {
5743 Int_t bin = GetBin(i + 1, j, k);
5744 UpdateBinContent(bin, cont[ix + nx * (j + ny * k)]);
5745 if (!errors2.empty())
5746 fSumw2.fArray[bin] = errors2[ix + nx * (j + ny * k)];
5747 }
5748 }
5749 }
5750 } else if (axis == GetYaxis()) {
5751 // using y axis
5752 for (i = 0; i < nx; i++) {
5753 for (j = 0; j < n; j++) {
5754 Int_t iy = a[j] + 1;
5755 for (k = 0; k < nz; k++) {
5756 Int_t bin = GetBin(i, j + 1, k);
5757 UpdateBinContent(bin, cont[i + nx * (iy + ny * k)]);
5758 if (!errors2.empty())
5759 fSumw2.fArray[bin] = errors2[i + nx * (iy + ny * k)];
5760 }
5761 }
5762 }
5763 } else {
5764 // using z axis
5765 for (i = 0; i < nx; i++) {
5766 for (j = 0; j < ny; j++) {
5767 for (k = 0; k < n; k++) {
5768 Int_t iz = a[k] + 1;
5769 Int_t bin = GetBin(i, j , k +1);
5770 UpdateBinContent(bin, cont[i + nx * (j + ny * iz)]);
5771 if (!errors2.empty())
5772 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * iz)];
5773 }
5774 }
5775 }
5776 }
5777 }
5778 } else {
5779 //---alphabetic sort
5780 // sort labels using vector of strings and TMath::Sort
5781 // I need to array because labels order in list is not necessary that of the bins
5782 std::vector<std::string> vecLabels(n);
5783 for (i = 0; i < n; i++) {
5784 vecLabels[i] = labold->At(i)->GetName();
5785 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5786 a[i] = i;
5787 }
5788 // sort in ascending order for strings
5789 TMath::Sort(n, vecLabels.data(), a.data(), kFALSE);
5790 // set the new labels
5791 for (i = 0; i < n; i++) {
5792 TObject *labelObj = labold->At(a[i]);
5793 labels->Add(labold->At(a[i]));
5794 // set the corresponding bin. NB bin starts from 1
5795 labelObj->SetUniqueID(i + 1);
5796 if (gDebug)
5797 std::cout << "bin " << i + 1 << " setting new labels for axis " << labold->At(a[i])->GetName() << " from "
5798 << b[a[i]] << std::endl;
5799 }
5800
5801 if (GetDimension() == 1) {
5802 cont.resize(n + 2);
5803 if (fSumw2.fN)
5804 errors2.resize(n + 2);
5805 for (i = 0; i < n; i++) {
5806 cont[i] = RetrieveBinContent(b[a[i]]);
5807 if (!errors2.empty())
5809 }
5810 for (i = 0; i < n; i++) {
5811 UpdateBinContent(i + 1, cont[i]);
5812 if (!errors2.empty())
5813 fSumw2.fArray[i+1] = errors2[i];
5814 }
5815 } else if (GetDimension() == 2) {
5816 Int_t nx = fXaxis.GetNbins() + 2;
5817 Int_t ny = fYaxis.GetNbins() + 2;
5818 cont.resize(nx * ny);
5819 if (fSumw2.fN)
5820 errors2.resize(nx * ny);
5821 // copy old bin contents and then set to new ordered bins
5822 // N.B. bin in histograms starts from 1, but in y we consider under/overflows
5823 for (i = 0; i < nx; i++) {
5824 for (j = 0; j < ny; j++) { // ny is nbins+2
5825 Int_t bin = GetBin(i, j);
5826 cont[i + nx * j] = RetrieveBinContent(bin);
5827 if (!errors2.empty())
5828 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5829 }
5830 }
5831 if (axis == GetXaxis()) {
5832 for (i = 0; i < n; i++) {
5833 for (j = 0; j < ny; j++) {
5834 Int_t bin = GetBin(i + 1 , j);
5835 UpdateBinContent(bin, cont[b[a[i]] + nx * j]);
5836 if (!errors2.empty())
5837 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * j];
5838 }
5839 }
5840 } else {
5841 for (i = 0; i < nx; i++) {
5842 for (j = 0; j < n; j++) {
5843 Int_t bin = GetBin(i, j + 1);
5844 UpdateBinContent(bin, cont[i + nx * b[a[j]]]);
5845 if (!errors2.empty())
5846 fSumw2.fArray[bin] = errors2[i + nx * b[a[j]]];
5847 }
5848 }
5849 }
5850 } else {
5851 // case of 3D (needs to be tested)
5852 Int_t nx = fXaxis.GetNbins() + 2;
5853 Int_t ny = fYaxis.GetNbins() + 2;
5854 Int_t nz = fZaxis.GetNbins() + 2;
5855 cont.resize(nx * ny * nz);
5856 if (fSumw2.fN)
5857 errors2.resize(nx * ny * nz);
5858 for (i = 0; i < nx; i++) {
5859 for (j = 0; j < ny; j++) {
5860 for (k = 0; k < nz; k++) {
5861 Int_t bin = GetBin(i, j, k);
5862 cont[i + nx * (j + ny * k)] = RetrieveBinContent(bin);
5863 if (!errors2.empty())
5864 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5865 }
5866 }
5867 }
5868 if (axis == GetXaxis()) {
5869 // labels on x axis
5870 for (i = 0; i < n; i++) { // for x we loop only on bins with the labels
5871 for (j = 0; j < ny; j++) {
5872 for (k = 0; k < nz; k++) {
5873 Int_t bin = GetBin(i + 1, j, k);
5874 UpdateBinContent(bin, cont[b[a[i]] + nx * (j + ny * k)]);
5875 if (!errors2.empty())
5876 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * (j + ny * k)];
5877 }
5878 }
5879 }
5880 } else if (axis == GetYaxis()) {
5881 // labels on y axis
5882 for (i = 0; i < nx; i++) {
5883 for (j = 0; j < n; j++) {
5884 for (k = 0; k < nz; k++) {
5885 Int_t bin = GetBin(i, j+1, k);
5886 UpdateBinContent(bin, cont[i + nx * (b[a[j]] + ny * k)]);
5887 if (!errors2.empty())
5888 fSumw2.fArray[bin] = errors2[i + nx * (b[a[j]] + ny * k)];
5889 }
5890 }
5891 }
5892 } else {
5893 // labels on z axis
5894 for (i = 0; i < nx; i++) {
5895 for (j = 0; j < ny; j++) {
5896 for (k = 0; k < n; k++) {
5897 Int_t bin = GetBin(i, j, k+1);
5898 UpdateBinContent(bin, cont[i + nx * (j + ny * b[a[k]])]);
5899 if (!errors2.empty())
5900 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * b[a[k]])];
5901 }
5902 }
5903 }
5904 }
5905 }
5906 }
5907 // need to set to zero the statistics if axis has been sorted
5908 // see for example TH3::PutStats for definition of s vector
5909 bool labelsAreSorted = kFALSE;
5910 for (i = 0; i < n; ++i) {
5911 if (a[i] != i) {
5913 break;
5914 }
5915 }
5916 if (labelsAreSorted) {
5917 double s[TH1::kNstat];
5918 GetStats(s);
5919 if (iaxis == 1) {
5920 s[2] = 0; // fTsumwx
5921 s[3] = 0; // fTsumwx2
5922 s[6] = 0; // fTsumwxy
5923 s[9] = 0; // fTsumwxz
5924 } else if (iaxis == 2) {
5925 s[4] = 0; // fTsumwy
5926 s[5] = 0; // fTsumwy2
5927 s[6] = 0; // fTsumwxy
5928 s[10] = 0; // fTsumwyz
5929 } else if (iaxis == 3) {
5930 s[7] = 0; // fTsumwz
5931 s[8] = 0; // fTsumwz2
5932 s[9] = 0; // fTsumwxz
5933 s[10] = 0; // fTsumwyz
5934 }
5935 PutStats(s);
5936 }
5937 delete labold;
5938}
5939
5940////////////////////////////////////////////////////////////////////////////////
5941/// Test if two double are almost equal.
5942
5943static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5944{
5945 return TMath::Abs(a - b) < epsilon;
5946}
5947
5948////////////////////////////////////////////////////////////////////////////////
5949/// Test if a double is almost an integer.
5950
5951static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5952{
5953 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5954 AlmostEqual(a - TMath::Floor(a), 1, epsilon);
5955}
5956
5957////////////////////////////////////////////////////////////////////////////////
5958/// Test if the binning is equidistant.
5959
5960static inline bool IsEquidistantBinning(const TAxis& axis)
5961{
5962 // check if axis bin are equals
5963 if (!axis.GetXbins()->fN) return true; //
5964 // not able to check if there is only one axis entry
5965 bool isEquidistant = true;
5966 const Double_t firstBinWidth = axis.GetBinWidth(1);
5967 for (int i = 1; i < axis.GetNbins(); ++i) {
5968 const Double_t binWidth = axis.GetBinWidth(i);
5969 const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5970 isEquidistant &= match;
5971 if (!match)
5972 break;
5973 }
5974 return isEquidistant;
5975}
5976
5977////////////////////////////////////////////////////////////////////////////////
5978/// Same limits and bins.
5979
5981 return axis1.GetNbins() == axis2.GetNbins() &&
5982 TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
5983 TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
5984}
5985
5986////////////////////////////////////////////////////////////////////////////////
5987/// Finds new limits for the axis for the Merge function.
5988/// returns false if the limits are incompatible
5989
5991{
5993 return kTRUE;
5994
5996 return kFALSE; // not equidistant user binning not supported
5997
5998 Double_t width1 = destAxis.GetBinWidth(0);
5999 Double_t width2 = anAxis.GetBinWidth(0);
6000 if (width1 == 0 || width2 == 0)
6001 return kFALSE; // no binning not supported
6002
6003 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
6004 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
6006
6007 // check the bin size
6009 return kFALSE;
6010
6011 // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
6012 // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
6013
6014
6015 // check the limits
6016 Double_t delta;
6017 delta = (destAxis.GetXmin() - xmin)/width1;
6018 if (!AlmostInteger(delta))
6019 xmin -= (TMath::Ceil(delta) - delta)*width1;
6020
6021 delta = (anAxis.GetXmin() - xmin)/width2;
6022 if (!AlmostInteger(delta))
6023 xmin -= (TMath::Ceil(delta) - delta)*width2;
6024
6025
6026 delta = (destAxis.GetXmin() - xmin)/width1;
6027 if (!AlmostInteger(delta))
6028 return kFALSE;
6029
6030
6031 delta = (xmax - destAxis.GetXmax())/width1;
6032 if (!AlmostInteger(delta))
6033 xmax += (TMath::Ceil(delta) - delta)*width1;
6034
6035
6036 delta = (xmax - anAxis.GetXmax())/width2;
6037 if (!AlmostInteger(delta))
6038 xmax += (TMath::Ceil(delta) - delta)*width2;
6039
6040
6041 delta = (xmax - destAxis.GetXmax())/width1;
6042 if (!AlmostInteger(delta))
6043 return kFALSE;
6044#ifdef DEBUG
6045 if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
6046 printf("TH1::RecomputeAxisLimits - Impossible\n");
6047 return kFALSE;
6048 }
6049#endif
6050
6051
6053
6054 //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
6055
6056 return kTRUE;
6057}
6058
6059////////////////////////////////////////////////////////////////////////////////
6060/// Add all histograms in the collection to this histogram.
6061/// This function computes the min/max for the x axis,
6062/// compute a new number of bins, if necessary,
6063/// add bin contents, errors and statistics.
6064/// If all histograms have bin labels, bins with identical labels
6065/// will be merged, no matter what their order is.
6066/// If overflows are present and limits are different the function will fail.
6067/// The function returns the total number of entries in the result histogram
6068/// if the merge is successful, -1 otherwise.
6069///
6070/// Possible option:
6071/// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
6072/// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
6073/// (enabled by default) slows down the merging
6074///
6075/// IMPORTANT remark. The axis x may have different number
6076/// of bins and different limits, BUT the largest bin width must be
6077/// a multiple of the smallest bin width and the upper limit must also
6078/// be a multiple of the bin width.
6079/// Example:
6080///
6081/// ~~~ {.cpp}
6082/// void atest() {
6083/// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
6084/// TH1F *h2 = new TH1F("h2","h2",220,0,110);
6085/// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
6086/// TRandom r;
6087/// for (Int_t i=0;i<10000;i++) {
6088/// h1->Fill(r.Gaus(-55,10));
6089/// h2->Fill(r.Gaus(55,10));
6090/// h3->Fill(r.Gaus(0,10));
6091/// }
6092///
6093/// TList *list = new TList;
6094/// list->Add(h1);
6095/// list->Add(h2);
6096/// list->Add(h3);
6097/// TH1F *h = (TH1F*)h1->Clone("h");
6098/// h->Reset();
6099/// h->Merge(list);
6100/// h->Draw();
6101/// }
6102/// ~~~
6103
6105{
6106 if (!li) return 0;
6107 if (li->IsEmpty()) return (Long64_t) GetEntries();
6108
6109 // use TH1Merger class
6110 TH1Merger merger(*this,*li,opt);
6111 Bool_t ret = merger();
6112
6113 return (ret) ? GetEntries() : -1;
6114}
6115
6116
6117////////////////////////////////////////////////////////////////////////////////
6118/// Performs the operation:
6119///
6120/// `this = this*c1*f1`
6121///
6122/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
6123///
6124/// Only bins inside the function range are recomputed.
6125/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6126/// you should call Sumw2 before making this operation.
6127/// This is particularly important if you fit the histogram after TH1::Multiply
6128///
6129/// The function return kFALSE if the Multiply operation failed
6130
6132{
6133 if (!f1) {
6134 Error("Multiply","Attempt to multiply by a non-existing function");
6135 return kFALSE;
6136 }
6137
6138 // delete buffer if it is there since it will become invalid
6139 if (fBuffer) BufferEmpty(1);
6140
6141 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
6142 Int_t ny = GetNbinsY() + 2;
6143 Int_t nz = GetNbinsZ() + 2;
6144 if (fDimension < 2) ny = 1;
6145 if (fDimension < 3) nz = 1;
6146
6147 // reset min-maximum
6148 SetMinimum();
6149 SetMaximum();
6150
6151 // - Loop on bins (including underflows/overflows)
6152 Double_t xx[3];
6153 Double_t *params = nullptr;
6154 f1->InitArgs(xx,params);
6155
6156 for (Int_t binz = 0; binz < nz; ++binz) {
6157 xx[2] = fZaxis.GetBinCenter(binz);
6158 for (Int_t biny = 0; biny < ny; ++biny) {
6159 xx[1] = fYaxis.GetBinCenter(biny);
6160 for (Int_t binx = 0; binx < nx; ++binx) {
6161 xx[0] = fXaxis.GetBinCenter(binx);
6162 if (!f1->IsInside(xx)) continue;
6164 Int_t bin = binx + nx * (biny + ny *binz);
6165 Double_t cu = c1*f1->EvalPar(xx);
6166 if (TF1::RejectedPoint()) continue;
6168 if (fSumw2.fN) {
6169 fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
6170 }
6171 }
6172 }
6173 }
6174 ResetStats();
6175 return kTRUE;
6176}
6177
6178////////////////////////////////////////////////////////////////////////////////
6179/// Multiply this histogram by h1.
6180///
6181/// `this = this*h1`
6182///
6183/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6184/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
6185/// if not already set.
6186///
6187/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6188/// you should call Sumw2 before making this operation.
6189/// This is particularly important if you fit the histogram after TH1::Multiply
6190///
6191/// The function return kFALSE if the Multiply operation failed
6192
6193Bool_t TH1::Multiply(const TH1 *h1)
6194{
6195 if (!h1) {
6196 Error("Multiply","Attempt to multiply by a non-existing histogram");
6197 return kFALSE;
6198 }
6199
6200 // delete buffer if it is there since it will become invalid
6201 if (fBuffer) BufferEmpty(1);
6202
6203 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins) {
6204 return false;
6205 }
6206
6207 // Create Sumw2 if h1 has Sumw2 set
6208 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
6209
6210 // - Reset min- maximum
6211 SetMinimum();
6212 SetMaximum();
6213
6214 // - Loop on bins (including underflows/overflows)
6215 for (Int_t i = 0; i < fNcells; ++i) {
6218 UpdateBinContent(i, c0 * c1);
6219 if (fSumw2.fN) {
6221 }
6222 }
6223 ResetStats();
6224 return kTRUE;
6225}
6226
6227////////////////////////////////////////////////////////////////////////////////
6228/// Replace contents of this histogram by multiplication of h1 by h2.
6229///
6230/// `this = (c1*h1)*(c2*h2)`
6231///
6232/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6233/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
6234/// if not already set.
6235///
6236/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6237/// you should call Sumw2 before making this operation.
6238/// This is particularly important if you fit the histogram after TH1::Multiply
6239///
6240/// The function return kFALSE if the Multiply operation failed
6241
6243{
6244 TString opt = option;
6245 opt.ToLower();
6246 // Bool_t binomial = kFALSE;
6247 // if (opt.Contains("b")) binomial = kTRUE;
6248 if (!h1 || !h2) {
6249 Error("Multiply","Attempt to multiply by a non-existing histogram");
6250 return kFALSE;
6251 }
6252
6253 // delete buffer if it is there since it will become invalid
6254 if (fBuffer) BufferEmpty(1);
6255
6256 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins ||
6257 LoggedInconsistency("Multiply", h1, h2) >= kDifferentNumberOfBins) {
6258 return false;
6259 }
6260
6261 // Create Sumw2 if h1 or h2 have Sumw2 set
6262 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
6263
6264 // - Reset min - maximum
6265 SetMinimum();
6266 SetMaximum();
6267
6268 // - Loop on bins (including underflows/overflows)
6269 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
6270 for (Int_t i = 0; i < fNcells; ++i) {
6272 Double_t b2 = h2->RetrieveBinContent(i);
6273 UpdateBinContent(i, c1 * b1 * c2 * b2);
6274 if (fSumw2.fN) {
6275 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
6276 }
6277 }
6278 ResetStats();
6279 return kTRUE;
6280}
6281
6282////////////////////////////////////////////////////////////////////////////////
6283/// @brief Normalize a histogram to its integral or to its maximum.
6284/// @note Works for TH1, TH2, TH3, ...
6285/// @param option: normalization strategy ("", "max" or "sum")
6286/// - "": Scale to `1/(sum*bin_width)`.
6287/// - max: Scale to `1/GetMaximum()`
6288/// - sum: Scale to `1/sum`.
6289///
6290/// In case the norm is zero, it raises an error.
6291/// @sa https://root-forum.cern.ch/t/different-ways-of-normalizing-histograms/15582/
6292
6294{
6295 TString opt = option;
6296 opt.ToLower();
6297 if (!opt.IsNull() && (opt != "max") && (opt != "sum")) {
6298 Error("Normalize", "Unrecognized option %s", option);
6299 return;
6300 }
6301
6302 const Double_t norm = (opt == "max") ? GetMaximum() : Integral(opt.IsNull() ? "width" : "");
6303
6304 if (norm == 0) {
6305 Error("Normalize", "Attempt to normalize histogram with zero integral");
6306 } else {
6307 Scale(1.0 / norm, "");
6308 // An alternative could have been to call Integral("") and Scale(1/norm, "width"), but this
6309 // will lead to a different value of GetEntries.
6310 // Instead, doing simultaneously Integral("width") and Scale(1/norm, "width") leads to an error since you are
6311 // dividing twice by bin width.
6312 }
6313}
6314
6315////////////////////////////////////////////////////////////////////////////////
6316/// Control routine to paint any kind of histograms.
6317///
6318/// This function is automatically called by TCanvas::Update.
6319/// (see TH1::Draw for the list of options)
6320
6322{
6324
6325 if (fPainter) {
6326 if (option && strlen(option) > 0)
6328 else
6330 }
6331}
6332
6333////////////////////////////////////////////////////////////////////////////////
6334/// Rebin this histogram
6335///
6336/// #### case 1 xbins=0
6337///
6338/// If newname is blank (default), the current histogram is modified and
6339/// a pointer to it is returned.
6340///
6341/// If newname is not blank, the current histogram is not modified, and a
6342/// new histogram is returned which is a Clone of the current histogram
6343/// with its name set to newname.
6344///
6345/// The parameter ngroup indicates how many bins of this have to be merged
6346/// into one bin of the result.
6347///
6348/// If the original histogram has errors stored (via Sumw2), the resulting
6349/// histograms has new errors correctly calculated.
6350///
6351/// examples: if h1 is an existing TH1F histogram with 100 bins
6352///
6353/// ~~~ {.cpp}
6354/// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
6355/// h1->Rebin(5); //merges five bins in one in h1
6356/// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
6357/// // merging 5 bins of h1 in one bin
6358/// ~~~
6359///
6360/// NOTE: If ngroup is not an exact divider of the number of bins,
6361/// the top limit of the rebinned histogram is reduced
6362/// to the upper edge of the last bin that can make a complete
6363/// group. The remaining bins are added to the overflow bin.
6364/// Statistics will be recomputed from the new bin contents.
6365///
6366/// #### case 2 xbins!=0
6367///
6368/// A new histogram is created (you should specify newname).
6369/// The parameter ngroup is the number of variable size bins in the created histogram.
6370/// The array xbins must contain ngroup+1 elements that represent the low-edges
6371/// of the bins.
6372/// If the original histogram has errors stored (via Sumw2), the resulting
6373/// histograms has new errors correctly calculated.
6374///
6375/// NOTE: The bin edges specified in xbins should correspond to bin edges
6376/// in the original histogram. If a bin edge in the new histogram is
6377/// in the middle of a bin in the original histogram, all entries in
6378/// the split bin in the original histogram will be transferred to the
6379/// lower of the two possible bins in the new histogram. This is
6380/// probably not what you want. A warning message is emitted in this
6381/// case
6382///
6383/// examples: if h1 is an existing TH1F histogram with 100 bins
6384///
6385/// ~~~ {.cpp}
6386/// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
6387/// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
6388/// ~~~
6389
6390TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
6391{
6392 Int_t nbins = fXaxis.GetNbins();
6395 if ((ngroup <= 0) || (ngroup > nbins)) {
6396 Error("Rebin", "Illegal value of ngroup=%d",ngroup);
6397 return nullptr;
6398 }
6399
6400 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
6401 Error("Rebin", "Operation valid on 1-D histograms only");
6402 return nullptr;
6403 }
6404 if (!newname && xbins) {
6405 Error("Rebin","if xbins is specified, newname must be given");
6406 return nullptr;
6407 }
6408
6409 Int_t newbins = nbins/ngroup;
6410 if (!xbins) {
6411 Int_t nbg = nbins/ngroup;
6412 if (nbg*ngroup != nbins) {
6413 Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
6414 }
6415 }
6416 else {
6417 // in the case that xbins is given (rebinning in variable bins), ngroup is
6418 // the new number of bins and number of grouped bins is not constant.
6419 // when looping for setting the contents for the new histogram we
6420 // need to loop on all bins of original histogram. Then set ngroup=nbins
6421 newbins = ngroup;
6422 ngroup = nbins;
6423 }
6424
6425 // Save old bin contents into a new array
6426 Double_t entries = fEntries;
6427 Double_t *oldBins = new Double_t[nbins+2];
6428 Int_t bin, i;
6429 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
6430 Double_t *oldErrors = nullptr;
6431 if (fSumw2.fN != 0) {
6432 oldErrors = new Double_t[nbins+2];
6433 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
6434 }
6435 // rebin will not include underflow/overflow if new axis range is larger than old axis range
6436 if (xbins) {
6437 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
6438 Warning("Rebin","underflow entries will not be used when rebinning");
6439 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
6440 Warning("Rebin","overflow entries will not be used when rebinning");
6441 }
6442
6443
6444 // create a clone of the old histogram if newname is specified
6445 TH1 *hnew = this;
6446 if ((newname && strlen(newname) > 0) || xbins) {
6447 hnew = (TH1*)Clone(newname);
6448 }
6449
6450 //reset can extend bit to avoid an axis extension in SetBinContent
6451 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
6452
6453 // save original statistics
6454 Double_t stat[kNstat];
6455 GetStats(stat);
6456 bool resetStat = false;
6457 // change axis specs and rebuild bin contents array::RebinAx
6458 if(!xbins && (newbins*ngroup != nbins)) {
6460 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
6461 }
6462 // save the TAttAxis members (reset by SetBins)
6474
6475 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
6476 Double_t *bins = new Double_t[newbins+1];
6477 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
6478 hnew->SetBins(newbins,bins); //this also changes errors array (if any)
6479 delete [] bins;
6480 } else if (xbins) {
6481 hnew->SetBins(newbins,xbins);
6482 } else {
6483 hnew->SetBins(newbins,xmin,xmax);
6484 }
6485
6486 // Restore axis attributes
6498
6499 // copy merged bin contents (ignore under/overflows)
6500 // Start merging only once the new lowest edge is reached
6501 Int_t startbin = 1;
6502 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
6503 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
6504 startbin++;
6505 }
6508 for (bin = 1;bin<=newbins;bin++) {
6509 binContent = 0;
6510 binError = 0;
6511 Int_t imax = ngroup;
6512 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6513 // check bin edges for the cases when we provide an array of bins
6514 // be careful in case bins can have zero width
6516 hnew->GetXaxis()->GetBinLowEdge(bin),
6517 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6518 {
6519 Warning("Rebin","Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6520 }
6521 for (i=0;i<ngroup;i++) {
6522 if( (oldbin+i > nbins) ||
6523 ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6524 imax = i;
6525 break;
6526 }
6529 }
6530 hnew->SetBinContent(bin,binContent);
6531 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6532 oldbin += imax;
6533 }
6534
6535 // sum underflow and overflow contents until startbin
6536 binContent = 0;
6537 binError = 0;
6538 for (i = 0; i < startbin; ++i) {
6539 binContent += oldBins[i];
6540 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6541 }
6542 hnew->SetBinContent(0,binContent);
6543 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6544 // sum overflow
6545 binContent = 0;
6546 binError = 0;
6547 for (i = oldbin; i <= nbins+1; ++i) {
6548 binContent += oldBins[i];
6549 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6550 }
6551 hnew->SetBinContent(newbins+1,binContent);
6552 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6553
6554 hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6555
6556 // restore statistics and entries modified by SetBinContent
6557 hnew->SetEntries(entries);
6558 if (!resetStat) hnew->PutStats(stat);
6559 delete [] oldBins;
6560 if (oldErrors) delete [] oldErrors;
6561 return hnew;
6562}
6563
6564////////////////////////////////////////////////////////////////////////////////
6565/// finds new limits for the axis so that *point* is within the range and
6566/// the limits are compatible with the previous ones (see TH1::Merge).
6567/// new limits are put into *newMin* and *newMax* variables.
6568/// axis - axis whose limits are to be recomputed
6569/// point - point that should fit within the new axis limits
6570/// newMin - new minimum will be stored here
6571/// newMax - new maximum will be stored here.
6572/// false if failed (e.g. if the initial axis limits are wrong
6573/// or the new range is more than \f$ 2^{64} \f$ times the old one).
6574
6576{
6577 Double_t xmin = axis->GetXmin();
6578 Double_t xmax = axis->GetXmax();
6579 if (xmin >= xmax) return kFALSE;
6581
6582 //recompute new axis limits by doubling the current range
6583 Int_t ntimes = 0;
6584 while (point < xmin) {
6585 if (ntimes++ > 64)
6586 return kFALSE;
6587 xmin = xmin - range;
6588 range *= 2;
6589 }
6590 while (point >= xmax) {
6591 if (ntimes++ > 64)
6592 return kFALSE;
6593 xmax = xmax + range;
6594 range *= 2;
6595 }
6596 newMin = xmin;
6597 newMax = xmax;
6598 // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6599 // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6600
6601 return kTRUE;
6602}
6603
6604////////////////////////////////////////////////////////////////////////////////
6605/// Histogram is resized along axis such that x is in the axis range.
6606/// The new axis limits are recomputed by doubling iteratively
6607/// the current axis range until the specified value x is within the limits.
6608/// The algorithm makes a copy of the histogram, then loops on all bins
6609/// of the old histogram to fill the extended histogram.
6610/// Takes into account errors (Sumw2) if any.
6611/// The algorithm works for 1-d, 2-D and 3-D histograms.
6612/// The axis must be extendable before invoking this function.
6613/// Ex:
6614///
6615/// ~~~ {.cpp}
6616/// h->GetXaxis()->SetCanExtend(kTRUE);
6617/// ~~~
6618
6619void TH1::ExtendAxis(Double_t x, TAxis *axis)
6620{
6621 if (!axis->CanExtend()) return;
6622 if (TMath::IsNaN(x)) { // x may be a NaN
6624 return;
6625 }
6626
6627 if (axis->GetXmin() >= axis->GetXmax()) return;
6628 if (axis->GetNbins() <= 0) return;
6629
6631 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6632 return;
6633
6634 //save a copy of this histogram
6635 TH1 *hold = (TH1*)IsA()->New();
6636 hold->SetDirectory(nullptr);
6637 Copy(*hold);
6638 //set new axis limits
6639 axis->SetLimits(xmin,xmax);
6640
6641
6642 //now loop on all bins and refill
6644
6645 Reset("ICE"); //reset only Integral, contents and Errors
6646
6647 int iaxis = 0;
6648 if (axis == &fXaxis) iaxis = 1;
6649 if (axis == &fYaxis) iaxis = 2;
6650 if (axis == &fZaxis) iaxis = 3;
6651 bool firstw = kTRUE;
6652 Int_t binx,biny, binz = 0;
6653 Int_t ix = 0,iy = 0,iz = 0;
6654 Double_t bx,by,bz;
6655 Int_t ncells = hold->GetNcells();
6656 for (Int_t bin = 0; bin < ncells; ++bin) {
6657 hold->GetBinXYZ(bin,binx,biny,binz);
6658 bx = hold->GetXaxis()->GetBinCenter(binx);
6659 ix = fXaxis.FindFixBin(bx);
6660 if (fDimension > 1) {
6661 by = hold->GetYaxis()->GetBinCenter(biny);
6662 iy = fYaxis.FindFixBin(by);
6663 if (fDimension > 2) {
6664 bz = hold->GetZaxis()->GetBinCenter(binz);
6665 iz = fZaxis.FindFixBin(bz);
6666 }
6667 }
6668 // exclude underflow/overflow
6669 double content = hold->RetrieveBinContent(bin);
6670 if (content == 0) continue;
6671 if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6672 if (firstw) {
6673 Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6674 " their content will be lost",GetName() );
6675 firstw= kFALSE;
6676 }
6677 continue;
6678 }
6679 Int_t ibin= GetBin(ix,iy,iz);
6681 if (errors) {
6682 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6683 }
6684 }
6685 delete hold;
6686}
6687
6688////////////////////////////////////////////////////////////////////////////////
6689/// Recursively remove object from the list of functions
6690
6692{
6693 // Rely on TROOT::RecursiveRemove to take the readlock.
6694
6695 if (fFunctions) {
6697 }
6698}
6699
6700////////////////////////////////////////////////////////////////////////////////
6701/// Multiply this histogram by a constant c1.
6702///
6703/// `this = c1*this`
6704///
6705/// Note that both contents and errors (if any) are scaled.
6706/// This function uses the services of TH1::Add
6707///
6708/// IMPORTANT NOTE: Sumw2() is called automatically when scaling.
6709/// If you are not interested in the histogram statistics you can call
6710/// Sumw2(kFALSE) or use the option "nosw2"
6711///
6712/// One can scale a histogram such that the bins integral is equal to
6713/// the normalization parameter via TH1::Scale(Double_t norm), where norm
6714/// is the desired normalization divided by the integral of the histogram.
6715///
6716/// If option contains "width" the bin contents and errors are divided
6717/// by the bin width.
6718
6720{
6721
6722 TString opt = option; opt.ToLower();
6723 // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6724 if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6725 if (opt.Contains("width")) Add(this, this, c1, -1);
6726 else {
6727 if (fBuffer) BufferEmpty(1);
6728 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6729 if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6730 // update global histograms statistics
6731 Double_t s[kNstat] = {0};
6732 GetStats(s);
6733 for (Int_t i=0 ; i < kNstat; i++) {
6734 if (i == 1) s[i] = c1*c1*s[i];
6735 else s[i] = c1*s[i];
6736 }
6737 PutStats(s);
6738 SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6739 }
6740
6741 // if contours set, must also scale contours
6743 if (ncontours == 0) return;
6745 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6746}
6747
6748////////////////////////////////////////////////////////////////////////////////
6749/// Returns true if all axes are extendable.
6750
6752{
6754 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6755 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6756
6757 return canExtend;
6758}
6759
6760////////////////////////////////////////////////////////////////////////////////
6761/// Make the histogram axes extendable / not extendable according to the bit mask
6762/// returns the previous bit mask specifying which axes are extendable
6763
6765{
6767
6771
6772 if (GetDimension() > 1) {
6776 }
6777
6778 if (GetDimension() > 2) {
6782 }
6783
6784 return oldExtendBitMask;
6785}
6786
6787///////////////////////////////////////////////////////////////////////////////
6788/// Internal function used in TH1::Fill to see which axis is full alphanumeric,
6789/// i.e. can be extended and is alphanumeric
6791{
6795 bitMask |= kYaxis;
6797 bitMask |= kZaxis;
6798
6799 return bitMask;
6800}
6801
6802////////////////////////////////////////////////////////////////////////////////
6803/// Static function to set the default buffer size for automatic histograms.
6804/// When a histogram is created with one of its axis lower limit greater
6805/// or equal to its upper limit, the function SetBuffer is automatically
6806/// called with the default buffer size.
6807
6809{
6810 fgBufferSize = bufsize > 0 ? bufsize : 0;
6811}
6812
6813////////////////////////////////////////////////////////////////////////////////
6814/// When this static function is called with `sumw2=kTRUE`, all new
6815/// histograms will automatically activate the storage
6816/// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6817
6819{
6821}
6822
6823////////////////////////////////////////////////////////////////////////////////
6824/// Change/set the title.
6825///
6826/// If title is in the form `stringt;stringx;stringy;stringz;stringc`
6827/// the histogram title is set to `stringt`, the x axis title to `stringx`,
6828/// the y axis title to `stringy`, the z axis title to `stringz`, and the c
6829/// axis title for the palette is ignored at this stage.
6830/// Note that you can use e.g. `stringt;stringx` if you only want to specify
6831/// title and x axis title.
6832///
6833/// To insert the character `;` in one of the titles, one should use `#;`
6834/// or `#semicolon`.
6835
6836void TH1::SetTitle(const char *title)
6837{
6838 fTitle = title;
6839 fTitle.ReplaceAll("#;",2,"#semicolon",10);
6840
6841 // Decode fTitle. It may contain X, Y and Z titles
6843 Int_t isc = str1.Index(";");
6844 Int_t lns = str1.Length();
6845
6846 if (isc >=0 ) {
6847 fTitle = str1(0,isc);
6848 str1 = str1(isc+1, lns);
6849 isc = str1.Index(";");
6850 if (isc >=0 ) {
6851 str2 = str1(0,isc);
6852 str2.ReplaceAll("#semicolon",10,";",1);
6853 fXaxis.SetTitle(str2.Data());
6854 lns = str1.Length();
6855 str1 = str1(isc+1, lns);
6856 isc = str1.Index(";");
6857 if (isc >=0 ) {
6858 str2 = str1(0,isc);
6859 str2.ReplaceAll("#semicolon",10,";",1);
6860 fYaxis.SetTitle(str2.Data());
6861 lns = str1.Length();
6862 str1 = str1(isc+1, lns);
6863 isc = str1.Index(";");
6864 if (isc >=0 ) {
6865 str2 = str1(0,isc);
6866 str2.ReplaceAll("#semicolon",10,";",1);
6867 fZaxis.SetTitle(str2.Data());
6868 } else {
6869 str1.ReplaceAll("#semicolon",10,";",1);
6870 fZaxis.SetTitle(str1.Data());
6871 }
6872 } else {
6873 str1.ReplaceAll("#semicolon",10,";",1);
6874 fYaxis.SetTitle(str1.Data());
6875 }
6876 } else {
6877 str1.ReplaceAll("#semicolon",10,";",1);
6878 fXaxis.SetTitle(str1.Data());
6879 }
6880 }
6881
6882 fTitle.ReplaceAll("#semicolon",10,";",1);
6883
6884 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6885}
6886
6887////////////////////////////////////////////////////////////////////////////////
6888/// Smooth array xx, translation of Hbook routine `hsmoof.F`.
6889/// Based on algorithm 353QH twice presented by J. Friedman
6890/// in [Proc. of the 1974 CERN School of Computing, Norway, 11-24 August, 1974](https://cds.cern.ch/record/186223).
6891/// 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).
6892
6894{
6895 if (nn < 3 ) {
6896 ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6897 return;
6898 }
6899
6900 Int_t ii;
6901 std::array<double, 3> hh{};
6902
6903 std::vector<double> yy(nn);
6904 std::vector<double> zz(nn);
6905 std::vector<double> rr(nn);
6906
6907 for (Int_t pass=0;pass<ntimes;pass++) {
6908 // first copy original data into temp array
6909 std::copy(xx, xx+nn, zz.begin() );
6910
6911 for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6912
6913 // do 353 i.e. running median 3, 5, and 3 in a single loop
6914 for (int kk = 0; kk < 3; kk++) {
6915 std::copy(zz.begin(), zz.end(), yy.begin());
6916 int medianType = (kk != 1) ? 3 : 5;
6917 int ifirst = (kk != 1 ) ? 1 : 2;
6918 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6919 //nn2 = nn - ik - 1;
6920 // do all elements beside the first and last point for median 3
6921 // and first two and last 2 for median 5
6922 for ( ii = ifirst; ii < ilast; ii++) {
6923 zz[ii] = TMath::Median(medianType, yy.data() + ii - ifirst);
6924 }
6925
6926 if (kk == 0) { // first median 3
6927 // first point
6928 hh[0] = zz[1];
6929 hh[1] = zz[0];
6930 hh[2] = 3*zz[1] - 2*zz[2];
6931 zz[0] = TMath::Median(3, hh.data());
6932 // last point
6933 hh[0] = zz[nn - 2];
6934 hh[1] = zz[nn - 1];
6935 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6936 zz[nn - 1] = TMath::Median(3, hh.data());
6937 }
6938
6939 if (kk == 1) { // median 5
6940 // second point with window length 3
6941 zz[1] = TMath::Median(3, yy.data());
6942 // second-to-last point with window length 3
6943 zz[nn - 2] = TMath::Median(3, yy.data() + nn - 3);
6944 }
6945
6946 // In the third iteration (kk == 2), the first and last point stay
6947 // the same (see paper linked in the documentation).
6948 }
6949
6950 std::copy ( zz.begin(), zz.end(), yy.begin() );
6951
6952 // quadratic interpolation for flat segments
6953 for (ii = 2; ii < (nn - 2); ii++) {
6954 if (zz[ii - 1] != zz[ii]) continue;
6955 if (zz[ii] != zz[ii + 1]) continue;
6956 const double tmp0 = zz[ii - 2] - zz[ii];
6957 const double tmp1 = zz[ii + 2] - zz[ii];
6958 if (tmp0 * tmp1 <= 0) continue;
6959 int jk = 1;
6960 if ( std::abs(tmp1) > std::abs(tmp0) ) jk = -1;
6961 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6962 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6963 }
6964
6965 // running means
6966 //std::copy(zz.begin(), zz.end(), yy.begin());
6967 for (ii = 1; ii < nn - 1; ii++) {
6968 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6969 }
6970 zz[0] = yy[0];
6971 zz[nn - 1] = yy[nn - 1];
6972
6973 if (noent == 0) {
6974
6975 // save computed values
6976 std::copy(zz.begin(), zz.end(), rr.begin());
6977
6978 // COMPUTE residuals
6979 for (ii = 0; ii < nn; ii++) {
6980 zz[ii] = xx[ii] - zz[ii];
6981 }
6982 }
6983
6984 } // end loop on noent
6985
6986
6987 double xmin = TMath::MinElement(nn,xx);
6988 for (ii = 0; ii < nn; ii++) {
6989 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6990 // make smoothing defined positive - not better using 0 ?
6991 else xx[ii] = std::max((rr[ii] + zz[ii]),0.0 );
6992 }
6993 }
6994}
6995
6996////////////////////////////////////////////////////////////////////////////////
6997/// Smooth bin contents of this histogram.
6998/// if option contains "R" smoothing is applied only to the bins
6999/// defined in the X axis range (default is to smooth all bins)
7000/// Bin contents are replaced by their smooth values.
7001/// Errors (if any) are not modified.
7002/// the smoothing procedure is repeated ntimes (default=1)
7003
7005{
7006 if (fDimension != 1) {
7007 Error("Smooth","Smooth only supported for 1-d histograms");
7008 return;
7009 }
7010 Int_t nbins = fXaxis.GetNbins();
7011 if (nbins < 3) {
7012 Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
7013 return;
7014 }
7015
7016 // delete buffer if it is there since it will become invalid
7017 if (fBuffer) BufferEmpty(1);
7018
7019 Int_t firstbin = 1, lastbin = nbins;
7020 TString opt = option;
7021 opt.ToLower();
7022 if (opt.Contains("r")) {
7025 }
7026 nbins = lastbin - firstbin + 1;
7027 Double_t *xx = new Double_t[nbins];
7029 Int_t i;
7030 for (i=0;i<nbins;i++) {
7032 }
7033
7034 TH1::SmoothArray(nbins,xx,ntimes);
7035
7036 for (i=0;i<nbins;i++) {
7038 }
7039 fEntries = nent;
7040 delete [] xx;
7041
7042 if (gPad) gPad->Modified();
7043}
7044
7045////////////////////////////////////////////////////////////////////////////////
7046/// if flag=kTRUE, underflows and overflows are used by the Fill functions
7047/// in the computation of statistics (mean value, StdDev).
7048/// By default, underflows or overflows are not used.
7049
7051{
7053}
7054
7055////////////////////////////////////////////////////////////////////////////////
7056/// Stream a class object.
7057
7058void TH1::Streamer(TBuffer &b)
7059{
7060 if (b.IsReading()) {
7061 UInt_t R__s, R__c;
7062 Version_t R__v = b.ReadVersion(&R__s, &R__c);
7063 if (fDirectory) fDirectory->Remove(this);
7064 fDirectory = nullptr;
7065 if (R__v > 2) {
7066 b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
7067
7069 fXaxis.SetParent(this);
7070 fYaxis.SetParent(this);
7071 fZaxis.SetParent(this);
7072 TIter next(fFunctions);
7073 TObject *obj;
7074 while ((obj=next())) {
7075 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
7076 }
7077 return;
7078 }
7079 //process old versions before automatic schema evolution
7084 b >> fNcells;
7085 fXaxis.Streamer(b);
7086 fYaxis.Streamer(b);
7087 fZaxis.Streamer(b);
7088 fXaxis.SetParent(this);
7089 fYaxis.SetParent(this);
7090 fZaxis.SetParent(this);
7091 b >> fBarOffset;
7092 b >> fBarWidth;
7093 b >> fEntries;
7094 b >> fTsumw;
7095 b >> fTsumw2;
7096 b >> fTsumwx;
7097 b >> fTsumwx2;
7098 if (R__v < 2) {
7100 Float_t *contour=nullptr;
7101 b >> maximum; fMaximum = maximum;
7102 b >> minimum; fMinimum = minimum;
7103 b >> norm; fNormFactor = norm;
7104 Int_t n = b.ReadArray(contour);
7105 fContour.Set(n);
7106 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
7107 delete [] contour;
7108 } else {
7109 b >> fMaximum;
7110 b >> fMinimum;
7111 b >> fNormFactor;
7113 }
7114 fSumw2.Streamer(b);
7116 fFunctions->Delete();
7118 b.CheckByteCount(R__s, R__c, TH1::IsA());
7119
7120 } else {
7121 b.WriteClassBuffer(TH1::Class(),this);
7122 }
7123}
7124
7125////////////////////////////////////////////////////////////////////////////////
7126/// Print some global quantities for this histogram.
7127/// \param[in] option
7128/// - "base" is given, number of bins and ranges are also printed
7129/// - "range" is given, bin contents and errors are also printed
7130/// for all bins in the current range (default 1-->nbins)
7131/// - "all" is given, bin contents and errors are also printed
7132/// for all bins including under and overflows.
7133
7134void TH1::Print(Option_t *option) const
7135{
7136 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7137 printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
7138 TString opt = option;
7139 opt.ToLower();
7140 Int_t all;
7141 if (opt.Contains("all")) all = 0;
7142 else if (opt.Contains("range")) all = 1;
7143 else if (opt.Contains("base")) all = 2;
7144 else return;
7145
7146 Int_t bin, binx, biny, binz;
7148 if (all == 0) {
7149 lastx = fXaxis.GetNbins()+1;
7150 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
7151 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
7152 } else {
7154 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
7155 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
7156 }
7157
7158 if (all== 2) {
7159 printf(" Title = %s\n", GetTitle());
7160 printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
7161 if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
7162 if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
7163 printf("\n");
7164 return;
7165 }
7166
7167 Double_t w,e;
7168 Double_t x,y,z;
7169 if (fDimension == 1) {
7170 for (binx=firstx;binx<=lastx;binx++) {
7173 e = GetBinError(binx);
7174 if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
7175 else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
7176 }
7177 }
7178 if (fDimension == 2) {
7179 for (biny=firsty;biny<=lasty;biny++) {
7181 for (binx=firstx;binx<=lastx;binx++) {
7182 bin = GetBin(binx,biny);
7184 w = RetrieveBinContent(bin);
7185 e = GetBinError(bin);
7186 if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
7187 else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
7188 }
7189 }
7190 }
7191 if (fDimension == 3) {
7192 for (binz=firstz;binz<=lastz;binz++) {
7194 for (biny=firsty;biny<=lasty;biny++) {
7196 for (binx=firstx;binx<=lastx;binx++) {
7197 bin = GetBin(binx,biny,binz);
7199 w = RetrieveBinContent(bin);
7200 e = GetBinError(bin);
7201 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);
7202 else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
7203 }
7204 }
7205 }
7206 }
7207}
7208
7209////////////////////////////////////////////////////////////////////////////////
7210/// Using the current bin info, recompute the arrays for contents and errors
7211
7212void TH1::Rebuild(Option_t *)
7213{
7214 SetBinsLength();
7215 if (fSumw2.fN) {
7217 }
7218}
7219
7220////////////////////////////////////////////////////////////////////////////////
7221/// Reset this histogram: contents, errors, etc.
7222/// \param[in] option
7223/// - if "ICE" is specified, resets only Integral, Contents and Errors.
7224/// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
7225/// This option is used
7226/// - if "M" is specified, resets also Minimum and Maximum
7227
7229{
7230 // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
7231 // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
7232
7233 TString opt = option;
7234 opt.ToUpper();
7235 fSumw2.Reset();
7236 if (fIntegral) {
7237 delete [] fIntegral;
7238 fIntegral = nullptr;
7239 }
7240
7241 if (opt.Contains("M")) {
7242 SetMinimum();
7243 SetMaximum();
7244 }
7245
7246 if (opt.Contains("ICE") && !opt.Contains("S")) return;
7247
7248 // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
7249 // But what is the sense of calling BufferEmpty() ? For making the axes ?
7250 // BufferEmpty will update contents that later will be
7251 // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
7252 // It may be needed for computing the axis limits....
7253 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
7254
7255 // need to reset also the statistics
7256 // (needs to be done after calling BufferEmpty() )
7257 fTsumw = 0;
7258 fTsumw2 = 0;
7259 fTsumwx = 0;
7260 fTsumwx2 = 0;
7261 fEntries = 0;
7262
7263 if (opt == "ICES") return;
7264
7265
7266 TObject *stats = fFunctions->FindObject("stats");
7267 fFunctions->Remove(stats);
7268 //special logic to support the case where the same object is
7269 //added multiple times in fFunctions.
7270 //This case happens when the same object is added with different
7271 //drawing modes
7272 TObject *obj;
7273 while ((obj = fFunctions->First())) {
7274 while(fFunctions->Remove(obj)) { }
7275 delete obj;
7276 }
7277 if(stats) fFunctions->Add(stats);
7278 fContour.Set(0);
7279}
7280
7281////////////////////////////////////////////////////////////////////////////////
7282/// Save the histogram as .csv, .tsv or .txt. In case of any other extension, fall
7283/// back to TObject::SaveAs, which saves as a .C macro (but with the file name
7284/// extension specified by the user)
7285///
7286/// The Under/Overflow bins are also exported (as first and last lines)
7287/// The fist 2 columns are the lower and upper edges of the bins
7288/// Column 3 contains the bin contents
7289/// The last column contains the error in y. If errors are not present, the column
7290/// is left empty
7291///
7292/// The result can be immediately imported into Excel, gnuplot, Python or whatever,
7293/// without the needing to install pyroot, etc.
7294///
7295/// \param filename the name of the file where to store the histogram
7296/// \param option some tuning options
7297///
7298/// The file extension defines the delimiter used:
7299/// - `.csv` : comma
7300/// - `.tsv` : tab
7301/// - `.txt` : space
7302///
7303/// If option = "title" a title line is generated. If the y-axis has a title,
7304/// this title is displayed as column 3 name, otherwise, it shows "BinContent"
7305
7306void TH1::SaveAs(const char *filename, Option_t *option) const
7307{
7308 char del = '\0';
7309 TString ext = "";
7311 TString opt = option;
7312
7313 if (filename) {
7314 if (fname.EndsWith(".csv")) {
7315 del = ',';
7316 ext = "csv";
7317 } else if (fname.EndsWith(".tsv")) {
7318 del = '\t';
7319 ext = "tsv";
7320 } else if (fname.EndsWith(".txt")) {
7321 del = ' ';
7322 ext = "txt";
7323 }
7324 }
7325 if (!del) {
7327 return;
7328 }
7329 std::ofstream out;
7330 out.open(filename, std::ios::out);
7331 if (!out.good()) {
7332 Error("SaveAs", "cannot open file: %s", filename);
7333 return;
7334 }
7335 if (opt.Contains("title")) {
7336 if (std::strcmp(GetYaxis()->GetTitle(), "") == 0) {
7337 out << "# " << "BinLowEdge" << del << "BinUpEdge" << del
7338 << "BinContent"
7339 << del << "ey" << std::endl;
7340 } else {
7341 out << "# " << "BinLowEdge" << del << "BinUpEdge" << del << GetYaxis()->GetTitle() << del << "ey" << std::endl;
7342 }
7343 }
7344 if (fSumw2.fN) {
7345 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7346 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7347 << GetBinError(i) << std::endl;
7348 }
7349 } else {
7350 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7351 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7352 << std::endl;
7353 }
7354 }
7355 out.close();
7356 Info("SaveAs", "%s file: %s has been generated", ext.Data(), filename);
7357}
7358
7359////////////////////////////////////////////////////////////////////////////////
7360/// Provide variable name for histogram for saving as primitive
7361/// Histogram pointer has by default the histogram name with an incremental suffix.
7362/// If the histogram belongs to a graph or a stack the suffix is not added because
7363/// the graph and stack objects are not aware of this new name. Same thing if
7364/// the histogram is drawn with the option COLZ because the TPaletteAxis drawn
7365/// when this option is selected, does not know this new name either.
7366
7368{
7369 thread_local Int_t storeNumber = 0;
7370
7371 TString opt = option;
7372 opt.ToLower();
7373 TString histName = GetName();
7374 // for TProfile and TH2Poly also fDirectory should be tested
7375 if (!histName.Contains("Graph") && !histName.Contains("_stack_") && !opt.Contains("colz") &&
7376 (!testfdir || !fDirectory)) {
7377 storeNumber++;
7378 histName += "__";
7379 histName += storeNumber;
7380 }
7381 if (histName.IsNull())
7382 histName = "unnamed";
7383 return gInterpreter->MapCppName(histName);
7384}
7385
7386////////////////////////////////////////////////////////////////////////////////
7387/// Save primitive as a C++ statement(s) on output stream out
7388
7389void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
7390{
7391 // empty the buffer before if it exists
7392 if (fBuffer)
7393 BufferEmpty();
7394
7396
7399 SetName(hname);
7400
7401 out <<" \n";
7402
7403 // Check if the histogram has equidistant X bins or not. If not, we
7404 // create an array holding the bins.
7405 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray)
7406 sxaxis = SavePrimitiveVector(out, hname + "_x", GetXaxis()->GetXbins()->fN, GetXaxis()->GetXbins()->fArray);
7407 // If the histogram is 2 or 3 dimensional, check if the histogram
7408 // has equidistant Y bins or not. If not, we create an array
7409 // holding the bins.
7410 if (fDimension > 1 && GetYaxis()->GetXbins()->fN && GetYaxis()->GetXbins()->fArray)
7411 syaxis = SavePrimitiveVector(out, hname + "_y", GetYaxis()->GetXbins()->fN, GetYaxis()->GetXbins()->fArray);
7412 // IF the histogram is 3 dimensional, check if the histogram
7413 // has equidistant Z bins or not. If not, we create an array
7414 // holding the bins.
7415 if (fDimension > 2 && GetZaxis()->GetXbins()->fN && GetZaxis()->GetXbins()->fArray)
7416 szaxis = SavePrimitiveVector(out, hname + "_z", GetZaxis()->GetXbins()->fN, GetZaxis()->GetXbins()->fArray);
7417
7418 const auto old_precision{out.precision()};
7419 constexpr auto max_precision{std::numeric_limits<double>::digits10 + 1};
7420 out << std::setprecision(max_precision);
7421
7422 out << " " << ClassName() << " *" << hname << " = new " << ClassName() << "(\"" << TString(savedName).ReplaceSpecialCppChars() << "\", \""
7423 << TString(GetTitle()).ReplaceSpecialCppChars() << "\", " << GetXaxis()->GetNbins();
7424 if (!sxaxis.IsNull())
7425 out << ", " << sxaxis << ".data()";
7426 else
7427 out << ", " << GetXaxis()->GetXmin() << ", " << GetXaxis()->GetXmax();
7428 if (fDimension > 1) {
7429 out << ", " << GetYaxis()->GetNbins();
7430 if (!syaxis.IsNull())
7431 out << ", " << syaxis << ".data()";
7432 else
7433 out << ", " << GetYaxis()->GetXmin() << ", " << GetYaxis()->GetXmax();
7434 }
7435 if (fDimension > 2) {
7436 out << ", " << GetZaxis()->GetNbins();
7437 if (!szaxis.IsNull())
7438 out << ", " << szaxis << ".data()";
7439 else
7440 out << ", " << GetZaxis()->GetXmin() << ", " << GetZaxis()->GetXmax();
7441 }
7442 out << ");\n";
7443
7445 Int_t numbins = 0, numerrors = 0;
7446
7447 std::vector<Double_t> content(fNcells), errors(save_errors ? fNcells : 0);
7448 for (Int_t bin = 0; bin < fNcells; bin++) {
7449 content[bin] = RetrieveBinContent(bin);
7450 if (content[bin])
7451 numbins++;
7452 if (save_errors) {
7453 errors[bin] = GetBinError(bin);
7454 if (errors[bin])
7455 numerrors++;
7456 }
7457 }
7458
7459 if ((numbins < 100) && (numerrors < 100)) {
7460 // in case of few non-empty bins store them as before
7461 for (Int_t bin = 0; bin < fNcells; bin++) {
7462 if (content[bin])
7463 out << " " << hname << "->SetBinContent(" << bin << "," << content[bin] << ");\n";
7464 }
7465 if (save_errors)
7466 for (Int_t bin = 0; bin < fNcells; bin++) {
7467 if (errors[bin])
7468 out << " " << hname << "->SetBinError(" << bin << "," << errors[bin] << ");\n";
7469 }
7470 } else {
7471 if (numbins > 0) {
7473 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
7474 out << " if (" << vectname << "[bin])\n";
7475 out << " " << hname << "->SetBinContent(bin, " << vectname << "[bin]);\n";
7476 }
7477 if (numerrors > 0) {
7479 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
7480 out << " if (" << vectname << "[bin])\n";
7481 out << " " << hname << "->SetBinError(bin, " << vectname << "[bin]);\n";
7482 }
7483 }
7484
7486 out << std::setprecision(old_precision);
7487 SetName(savedName.Data());
7488}
7489
7490////////////////////////////////////////////////////////////////////////////////
7491/// Helper function for the SavePrimitive functions from TH1
7492/// or classes derived from TH1, eg TProfile, TProfile2D.
7493
7494void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
7495{
7496 if (TMath::Abs(GetBarOffset()) > 1e-5)
7497 out << " " << hname << "->SetBarOffset(" << GetBarOffset() << ");\n";
7498 if (TMath::Abs(GetBarWidth() - 1) > 1e-5)
7499 out << " " << hname << "->SetBarWidth(" << GetBarWidth() << ");\n";
7500 if (fMinimum != -1111)
7501 out << " " << hname << "->SetMinimum(" << fMinimum << ");\n";
7502 if (fMaximum != -1111)
7503 out << " " << hname << "->SetMaximum(" << fMaximum << ");\n";
7504 if (fNormFactor != 0)
7505 out << " " << hname << "->SetNormFactor(" << fNormFactor << ");\n";
7506 if (fEntries != 0)
7507 out << " " << hname << "->SetEntries(" << fEntries << ");\n";
7508 if (!fDirectory)
7509 out << " " << hname << "->SetDirectory(nullptr);\n";
7510 if (TestBit(kNoStats))
7511 out << " " << hname << "->SetStats(0);\n";
7512 if (fOption.Length() != 0)
7513 out << " " << hname << "->SetOption(\n" << TString(fOption).ReplaceSpecialCppChars() << "\");\n";
7514
7515 // save contour levels
7517 if (ncontours > 0) {
7519 if (TestBit(kUserContour)) {
7520 std::vector<Double_t> levels(ncontours);
7521 for (Int_t bin = 0; bin < ncontours; bin++)
7522 levels[bin] = GetContourLevel(bin);
7524 }
7525 out << " " << hname << "->SetContour(" << ncontours;
7526 if (!vectname.IsNull())
7527 out << ", " << vectname << ".data()";
7528 out << ");\n";
7529 }
7530
7532
7533 // save attributes
7534 SaveFillAttributes(out, hname, -1, -1);
7535 SaveLineAttributes(out, hname, 1, 1, 1);
7536 SaveMarkerAttributes(out, hname, 1, 1, 1);
7537 fXaxis.SaveAttributes(out, hname, "->GetXaxis()");
7538 fYaxis.SaveAttributes(out, hname, "->GetYaxis()");
7539 fZaxis.SaveAttributes(out, hname, "->GetZaxis()");
7540
7542}
7543
7544////////////////////////////////////////////////////////////////////////////////
7545/// Save list of functions
7546/// Also can be used by TGraph classes
7547
7548void TH1::SavePrimitiveFunctions(std::ostream &out, const char *varname, TList *lst)
7549{
7550 thread_local Int_t funcNumber = 0;
7551
7552 TObjLink *lnk = lst ? lst->FirstLink() : nullptr;
7553 while (lnk) {
7554 auto obj = lnk->GetObject();
7555 obj->SavePrimitive(out, TString::Format("nodraw #%d\n", ++funcNumber).Data());
7556 TString objvarname = obj->GetName();
7558 if (obj->InheritsFrom(TF1::Class())) {
7560 objvarname = gInterpreter->MapCppName(objvarname);
7561 out << " " << objvarname << "->SetParent(" << varname << ");\n";
7562 } else if (obj->InheritsFrom("TPaveStats")) {
7563 objvarname = "ptstats";
7564 withopt = kFALSE; // pave stats preserve own draw options
7565 out << " " << objvarname << "->SetParent(" << varname << ");\n";
7566 } else if (obj->InheritsFrom("TPolyMarker")) {
7567 objvarname = "pmarker";
7568 }
7569
7570 out << " " << varname << "->GetListOfFunctions()->Add(" << objvarname;
7571 if (withopt)
7572 out << ",\"" << TString(lnk->GetOption()).ReplaceSpecialCppChars() << "\"";
7573 out << ");\n";
7574
7575 lnk = lnk->Next();
7576 }
7577}
7578
7579////////////////////////////////////////////////////////////////////////////////
7620 }
7621}
7622
7623////////////////////////////////////////////////////////////////////////////////
7624/// For axis = 1,2 or 3 returns the mean value of the histogram along
7625/// X,Y or Z axis.
7626///
7627/// For axis = 11, 12, 13 returns the standard error of the mean value
7628/// of the histogram along X, Y or Z axis
7629///
7630/// Note that the mean value/StdDev is computed using the bins in the currently
7631/// defined range (see TAxis::SetRange). By default the range includes
7632/// all bins from 1 to nbins included, excluding underflows and overflows.
7633/// To force the underflows and overflows in the computation, one must
7634/// call the static function TH1::StatOverflows(kTRUE) before filling
7635/// the histogram.
7636///
7637/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7638/// are calculated. By default, if no range has been set, the returned mean is
7639/// the (unbinned) one calculated at fill time. If a range has been set, however,
7640/// the mean is calculated using the bins in range, as described above; THIS
7641/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7642/// the range. To ensure that the returned mean (and all other statistics) is
7643/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7644/// See TH1::GetStats.
7645///
7646/// Return mean value of this histogram along the X axis.
7647
7648Double_t TH1::GetMean(Int_t axis) const
7649{
7650 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7651 Double_t stats[kNstat];
7652 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7653 GetStats(stats);
7654 if (stats[0] == 0) return 0;
7655 if (axis<4){
7656 Int_t ax[3] = {2,4,7};
7657 return stats[ax[axis-1]]/stats[0];
7658 } else {
7659 // mean error = StdDev / sqrt( Neff )
7660 Double_t stddev = GetStdDev(axis-10);
7662 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7663 }
7664}
7665
7666////////////////////////////////////////////////////////////////////////////////
7667/// Return standard error of mean of this histogram along the X axis.
7668///
7669/// Note that the mean value/StdDev is computed using the bins in the currently
7670/// defined range (see TAxis::SetRange). By default the range includes
7671/// all bins from 1 to nbins included, excluding underflows and overflows.
7672/// To force the underflows and overflows in the computation, one must
7673/// call the static function TH1::StatOverflows(kTRUE) before filling
7674/// the histogram.
7675///
7676/// Also note, that although the definition of standard error doesn't include the
7677/// assumption of normality, many uses of this feature implicitly assume it.
7678///
7679/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7680/// are calculated. By default, if no range has been set, the returned value is
7681/// the (unbinned) one calculated at fill time. If a range has been set, however,
7682/// the value is calculated using the bins in range, as described above; THIS
7683/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7684/// the range. To ensure that the returned value (and all other statistics) is
7685/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7686/// See TH1::GetStats.
7687
7689{
7690 return GetMean(axis+10);
7691}
7692
7693////////////////////////////////////////////////////////////////////////////////
7694/// Returns the Standard Deviation (Sigma).
7695/// The Sigma estimate is computed as
7696/// \f[
7697/// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7698/// \f]
7699/// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7700/// X, Y or Z axis
7701/// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7702/// X, Y or Z axis for Normal distribution
7703///
7704/// Note that the mean value/sigma is computed using the bins in the currently
7705/// defined range (see TAxis::SetRange). By default the range includes
7706/// all bins from 1 to nbins included, excluding underflows and overflows.
7707/// To force the underflows and overflows in the computation, one must
7708/// call the static function TH1::StatOverflows(kTRUE) before filling
7709/// the histogram.
7710///
7711/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7712/// are calculated. By default, if no range has been set, the returned standard
7713/// deviation is the (unbinned) one calculated at fill time. If a range has been
7714/// set, however, the standard deviation is calculated using the bins in range,
7715/// as described above; THIS IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use
7716/// TAxis::SetRange(0, 0) to unset the range. To ensure that the returned standard
7717/// deviation (and all other statistics) is always that of the binned data stored
7718/// in the histogram, call TH1::ResetStats. See TH1::GetStats.
7719
7720Double_t TH1::GetStdDev(Int_t axis) const
7721{
7722 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7723
7724 Double_t x, stddev2, stats[kNstat];
7725 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7726 GetStats(stats);
7727 if (stats[0] == 0) return 0;
7728 Int_t ax[3] = {2,4,7};
7729 Int_t axm = ax[axis%10 - 1];
7730 x = stats[axm]/stats[0];
7731 // for negative stddev (e.g. when having negative weights) - return stdev=0
7732 stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7733 if (axis<10)
7734 return TMath::Sqrt(stddev2);
7735 else {
7736 // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7737 // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7739 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7740 }
7741}
7742
7743////////////////////////////////////////////////////////////////////////////////
7744/// Return error of standard deviation estimation for Normal distribution
7745///
7746/// Note that the mean value/StdDev is computed using the bins in the currently
7747/// defined range (see TAxis::SetRange). By default the range includes
7748/// all bins from 1 to nbins included, excluding underflows and overflows.
7749/// To force the underflows and overflows in the computation, one must
7750/// call the static function TH1::StatOverflows(kTRUE) before filling
7751/// the histogram.
7752///
7753/// Value returned is standard deviation of sample standard deviation.
7754/// Note that it is an approximated value which is valid only in the case that the
7755/// original data distribution is Normal. The correct one would require
7756/// the 4-th momentum value, which cannot be accurately estimated from a histogram since
7757/// the x-information for all entries is not kept.
7758///
7759/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7760/// are calculated. By default, if no range has been set, the returned value is
7761/// the (unbinned) one calculated at fill time. If a range has been set, however,
7762/// the value is calculated using the bins in range, as described above; THIS
7763/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7764/// the range. To ensure that the returned value (and all other statistics) is
7765/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7766/// See TH1::GetStats.
7767
7769{
7770 return GetStdDev(axis+10);
7771}
7772
7773////////////////////////////////////////////////////////////////////////////////
7774/// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7775/// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7776/// of the histogram along x, y or z axis
7777///
7778///Note, that since third and fourth moment are not calculated
7779///at the fill time, skewness and its standard error are computed bin by bin
7780///
7781/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7782/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7783
7785{
7786
7787 if (axis > 0 && axis <= 3){
7788
7789 Double_t mean = GetMean(axis);
7790 Double_t stddev = GetStdDev(axis);
7792
7799 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7802 if (firstBinX == 1) firstBinX = 0;
7803 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7804 }
7806 if (firstBinY == 1) firstBinY = 0;
7807 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7808 }
7810 if (firstBinZ == 1) firstBinZ = 0;
7811 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7812 }
7813 }
7814
7815 Double_t x = 0;
7816 Double_t sum=0;
7817 Double_t np=0;
7818 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7819 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7820 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7821 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7822 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7823 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7825 np+=w;
7826 sum+=w*(x-mean)*(x-mean)*(x-mean);
7827 }
7828 }
7829 }
7830 sum/=np*stddev3;
7831 return sum;
7832 }
7833 else if (axis > 10 && axis <= 13) {
7834 //compute standard error of skewness
7835 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7837 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7838 }
7839 else {
7840 Error("GetSkewness", "illegal value of parameter");
7841 return 0;
7842 }
7843}
7844
7845////////////////////////////////////////////////////////////////////////////////
7846/// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7847/// Kurtosis(gaussian(0, 1)) = 0.
7848/// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7849/// of the histogram along x, y or z axis
7850////
7851/// Note, that since third and fourth moment are not calculated
7852/// at the fill time, kurtosis and its standard error are computed bin by bin
7853///
7854/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7855/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7856
7858{
7859 if (axis > 0 && axis <= 3){
7860
7861 Double_t mean = GetMean(axis);
7862 Double_t stddev = GetStdDev(axis);
7864
7871 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7874 if (firstBinX == 1) firstBinX = 0;
7875 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7876 }
7878 if (firstBinY == 1) firstBinY = 0;
7879 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7880 }
7882 if (firstBinZ == 1) firstBinZ = 0;
7883 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7884 }
7885 }
7886
7887 Double_t x = 0;
7888 Double_t sum=0;
7889 Double_t np=0;
7890 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7891 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7892 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7893 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7894 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7895 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7897 np+=w;
7898 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7899 }
7900 }
7901 }
7902 sum/=(np*stddev4);
7903 return sum-3;
7904
7905 } else if (axis > 10 && axis <= 13) {
7906 //compute standard error of skewness
7907 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7909 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7910 }
7911 else {
7912 Error("GetKurtosis", "illegal value of parameter");
7913 return 0;
7914 }
7915}
7916
7917////////////////////////////////////////////////////////////////////////////////
7918/// fill the array stats from the contents of this histogram
7919/// The array stats must be correctly dimensioned in the calling program.
7920///
7921/// ~~~ {.cpp}
7922/// stats[0] = sumw
7923/// stats[1] = sumw2
7924/// stats[2] = sumwx
7925/// stats[3] = sumwx2
7926/// ~~~
7927///
7928/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7929/// is simply a copy of the statistics quantities computed at filling time.
7930/// If a sub-range is specified, the function recomputes these quantities
7931/// from the bin contents in the current axis range.
7932///
7933/// IMPORTANT NOTE: This means that the returned statistics are context-dependent.
7934/// If TAxis::kAxisRange, the returned statistics are dependent on the binning;
7935/// otherwise, they are a copy of the histogram statistics computed at fill time,
7936/// which are unbinned by default (calling TH1::ResetStats forces them to use
7937/// binned statistics). You can reset TAxis::kAxisRange using TAxis::SetRange(0, 0).
7938///
7939/// Note that the mean value/StdDev is computed using the bins in the currently
7940/// defined range (see TAxis::SetRange). By default the range includes
7941/// all bins from 1 to nbins included, excluding underflows and overflows.
7942/// To force the underflows and overflows in the computation, one must
7943/// call the static function TH1::StatOverflows(kTRUE) before filling
7944/// the histogram.
7945
7946void TH1::GetStats(Double_t *stats) const
7947{
7948 if (fBuffer) ((TH1*)this)->BufferEmpty();
7949
7950 // Loop on bins (possibly including underflows/overflows)
7951 Int_t bin, binx;
7952 Double_t w,err;
7953 Double_t x;
7954 // identify the case of labels with extension of axis range
7955 // in this case the statistics in x does not make any sense
7956 Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && fXaxis.CanExtend() );
7957 // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7958 if ( (fTsumw == 0 && fEntries > 0) || fXaxis.TestBit(TAxis::kAxisRange) ) {
7959 for (bin=0;bin<4;bin++) stats[bin] = 0;
7960
7963 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7965 if (firstBinX == 1) firstBinX = 0;
7966 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7967 }
7968 for (binx = firstBinX; binx <= lastBinX; binx++) {
7970 //w = TMath::Abs(RetrieveBinContent(binx));
7971 // not sure what to do here if w < 0
7973 err = TMath::Abs(GetBinError(binx));
7974 stats[0] += w;
7975 stats[1] += err*err;
7976 // statistics in x makes sense only for not labels histograms
7977 if (!labelHist) {
7978 stats[2] += w*x;
7979 stats[3] += w*x*x;
7980 }
7981 }
7982 // if (stats[0] < 0) {
7983 // // in case total is negative do something ??
7984 // stats[0] = 0;
7985 // }
7986 } else {
7987 stats[0] = fTsumw;
7988 stats[1] = fTsumw2;
7989 stats[2] = fTsumwx;
7990 stats[3] = fTsumwx2;
7991 }
7992}
7993
7994////////////////////////////////////////////////////////////////////////////////
7995/// Replace current statistics with the values in array stats
7996
7997void TH1::PutStats(Double_t *stats)
7998{
7999 fTsumw = stats[0];
8000 fTsumw2 = stats[1];
8001 fTsumwx = stats[2];
8002 fTsumwx2 = stats[3];
8003}
8004
8005////////////////////////////////////////////////////////////////////////////////
8006/// Reset the statistics including the number of entries
8007/// and replace with values calculated from bin content
8008///
8009/// The number of entries is set to the total bin content or (in case of weighted histogram)
8010/// to number of effective entries
8011///
8012/// \note By default, before calling this function, statistics are those
8013/// computed at fill time, which are unbinned. See TH1::GetStats.
8014
8015void TH1::ResetStats()
8016{
8017 Double_t stats[kNstat] = {0};
8018 fTsumw = 0;
8019 fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
8020 GetStats(stats);
8021 PutStats(stats);
8022 // histogram entries should include always underflows and overflows
8025 else {
8026 Double_t sumw2 = 0;
8027 Double_t * p_sumw2 = (fSumw2.fN > 0) ? &sumw2 : nullptr;
8029 // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
8031 }
8032}
8033
8034////////////////////////////////////////////////////////////////////////////////
8035/// Return the sum of all weights and optionally also the sum of weight squares
8036/// \param includeOverflow true to include under/overflows bins, false to exclude those.
8037/// \note Different from TH1::GetSumOfWeights, that always excludes those
8038
8040{
8041 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
8042
8043 const Int_t start = (includeOverflow ? 0 : 1);
8044 const Int_t lastX = fXaxis.GetNbins() + (includeOverflow ? 1 : 0);
8045 const Int_t lastY = (fDimension > 1) ? (fYaxis.GetNbins() + (includeOverflow ? 1 : 0)) : start;
8046 const Int_t lastZ = (fDimension > 2) ? (fZaxis.GetNbins() + (includeOverflow ? 1 : 0)) : start;
8047 Double_t sum =0;
8048 Double_t sum2 = 0;
8049 for(auto binz = start; binz <= lastZ; binz++) {
8050 for(auto biny = start; biny <= lastY; biny++) {
8051 for(auto binx = start; binx <= lastX; binx++) {
8052 const auto bin = GetBin(binx, biny, binz);
8053 sum += RetrieveBinContent(bin);
8055 }
8056 }
8057 }
8058 if (sumWeightSquare) {
8059 if (fSumw2.fN > 0)
8061 else
8063 }
8064 return sum;
8065}
8066
8067////////////////////////////////////////////////////////////////////////////////
8068///Return integral of bin contents. Only bins in the bins range are considered.
8069///
8070/// By default the integral is computed as the sum of bin contents in the range.
8071/// if option "width" is specified, the integral is the sum of
8072/// the bin contents multiplied by the bin width in x.
8073
8075{
8077}
8078
8079////////////////////////////////////////////////////////////////////////////////
8080/// Return integral of bin contents in range [binx1,binx2].
8081///
8082/// By default the integral is computed as the sum of bin contents in the range.
8083/// if option "width" is specified, the integral is the sum of
8084/// the bin contents multiplied by the bin width in x.
8085
8087{
8088 double err = 0;
8089 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
8090}
8091
8092////////////////////////////////////////////////////////////////////////////////
8093/// Return integral of bin contents in range [binx1,binx2] and its error.
8094///
8095/// By default the integral is computed as the sum of bin contents in the range.
8096/// if option "width" is specified, the integral is the sum of
8097/// the bin contents multiplied by the bin width in x.
8098/// the error is computed using error propagation from the bin errors assuming that
8099/// all the bins are uncorrelated
8100
8102{
8103 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
8104}
8105
8106////////////////////////////////////////////////////////////////////////////////
8107/// Internal function compute integral and optionally the error between the limits
8108/// specified by the bin number values working for all histograms (1D, 2D and 3D)
8109
8111 Option_t *option, Bool_t doError) const
8112{
8113 if (fBuffer) ((TH1*)this)->BufferEmpty();
8114
8115 Int_t nx = GetNbinsX() + 2;
8116 if (binx1 < 0) binx1 = 0;
8117 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
8118
8119 if (GetDimension() > 1) {
8120 Int_t ny = GetNbinsY() + 2;
8121 if (biny1 < 0) biny1 = 0;
8122 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
8123 } else {
8124 biny1 = 0; biny2 = 0;
8125 }
8126
8127 if (GetDimension() > 2) {
8128 Int_t nz = GetNbinsZ() + 2;
8129 if (binz1 < 0) binz1 = 0;
8130 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
8131 } else {
8132 binz1 = 0; binz2 = 0;
8133 }
8134
8135 // - Loop on bins in specified range
8136 TString opt = option;
8137 opt.ToLower();
8139 if (opt.Contains("width")) width = kTRUE;
8140
8141
8142 Double_t dx = 1., dy = .1, dz =.1;
8143 Double_t integral = 0;
8144 Double_t igerr2 = 0;
8145 for (Int_t binx = binx1; binx <= binx2; ++binx) {
8146 if (width) dx = fXaxis.GetBinWidth(binx);
8147 for (Int_t biny = biny1; biny <= biny2; ++biny) {
8148 if (width) dy = fYaxis.GetBinWidth(biny);
8149 for (Int_t binz = binz1; binz <= binz2; ++binz) {
8150 Int_t bin = GetBin(binx, biny, binz);
8151 Double_t dv = 0.0;
8152 if (width) {
8154 dv = dx * dy * dz;
8155 integral += RetrieveBinContent(bin) * dv;
8156 } else {
8157 integral += RetrieveBinContent(bin);
8158 }
8159 if (doError) {
8160 if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
8161 else igerr2 += GetBinErrorSqUnchecked(bin);
8162 }
8163 }
8164 }
8165 }
8166
8167 if (doError) error = TMath::Sqrt(igerr2);
8168 return integral;
8169}
8170
8171////////////////////////////////////////////////////////////////////////////////
8172/// Statistical test of compatibility in shape between
8173/// this histogram and h2, using the Anderson-Darling 2 sample test.
8174///
8175/// The AD 2 sample test formula are derived from the paper
8176/// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
8177///
8178/// The test is implemented in root in the ROOT::Math::GoFTest class
8179/// It is the same formula ( (6) in the paper), and also shown in
8180/// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
8181///
8182/// Binned data are considered as un-binned data
8183/// with identical observation happening in the bin center.
8184///
8185/// \param[in] h2 Pointer to 1D histogram
8186/// \param[in] option is a character string to specify options
8187/// - "D" Put out a line of "Debug" printout
8188/// - "T" Return the normalized A-D test statistic
8189///
8190/// - Note1: Underflow and overflow are not considered in the test
8191/// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
8192/// - Note3: The histograms are not required to have the same X axis
8193/// - Note4: The test works only for 1-dimensional histograms
8194
8196{
8197 Double_t advalue = 0;
8199
8200 TString opt = option;
8201 opt.ToUpper();
8202 if (opt.Contains("D") ) {
8203 printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
8204 }
8205 if (opt.Contains("T") ) return advalue;
8206
8207 return pvalue;
8208}
8209
8210////////////////////////////////////////////////////////////////////////////////
8211/// Same function as above but returning also the test statistic value
8212
8214{
8215 if (GetDimension() != 1 || h2->GetDimension() != 1) {
8216 Error("AndersonDarlingTest","Histograms must be 1-D");
8217 return -1;
8218 }
8219
8220 // empty the buffer. Probably we could add as an unbinned test
8221 if (fBuffer) ((TH1*)this)->BufferEmpty();
8222
8223 // use the BinData class
8226
8227 ROOT::Fit::FillData(data1, this, nullptr);
8228 ROOT::Fit::FillData(data2, h2, nullptr);
8229
8230 double pvalue;
8232
8233 return pvalue;
8234}
8235
8236////////////////////////////////////////////////////////////////////////////////
8237/// Statistical test of compatibility in shape between
8238/// this histogram and h2, using Kolmogorov test.
8239/// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
8240/// and not for binned data as in the case of the histogram (see NOTE 3 below).
8241/// So, before using this method blindly, read the NOTE 3.
8242///
8243/// Default: Ignore under- and overflow bins in comparison
8244///
8245/// \param[in] h2 histogram
8246/// \param[in] option is a character string to specify options
8247/// - "U" include Underflows in test (also for 2-dim)
8248/// - "O" include Overflows (also valid for 2-dim)
8249/// - "N" include comparison of normalizations
8250/// - "D" Put out a line of "Debug" printout
8251/// - "M" Return the Maximum Kolmogorov distance instead of prob
8252/// - "X" Run the pseudo experiments post-processor with the following procedure:
8253/// make pseudoexperiments based on random values from the parent distribution,
8254/// compare the KS distance of the pseudoexperiment to the parent
8255/// distribution, and count all the KS values above the value
8256/// obtained from the original data to Monte Carlo distribution.
8257/// The number of pseudo-experiments nEXPT is by default 1000, and
8258/// it can be changed by specifying the option as "X=number",
8259/// for example "X=10000" for 10000 toys.
8260/// The function returns the probability.
8261/// (thanks to Ben Kilminster to submit this procedure). Note that
8262/// this option "X" is much slower.
8263///
8264/// The returned function value is the probability of test
8265/// (much less than one means NOT compatible)
8266///
8267/// Code adapted by Rene Brun from original HBOOK routine HDIFF
8268///
8269/// NOTE1
8270/// A good description of the Kolmogorov test can be seen at:
8271/// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
8272///
8273/// NOTE2
8274/// see also alternative function TH1::Chi2Test
8275/// The Kolmogorov test is assumed to give better results than Chi2Test
8276/// in case of histograms with low statistics.
8277///
8278/// NOTE3 (Jan Conrad, Fred James)
8279/// "The returned value PROB is calculated such that it will be
8280/// uniformly distributed between zero and one for compatible histograms,
8281/// provided the data are not binned (or the number of bins is very large
8282/// compared with the number of events). Users who have access to unbinned
8283/// data and wish exact confidence levels should therefore not put their data
8284/// into histograms, but should call directly TMath::KolmogorovTest. On
8285/// the other hand, since TH1 is a convenient way of collecting data and
8286/// saving space, this function has been provided. However, the values of
8287/// PROB for binned data will be shifted slightly higher than expected,
8288/// depending on the effects of the binning. For example, when comparing two
8289/// uniform distributions of 500 events in 100 bins, the values of PROB,
8290/// instead of being exactly uniformly distributed between zero and one, have
8291/// a mean value of about 0.56. We can apply a useful
8292/// rule: As long as the bin width is small compared with any significant
8293/// physical effect (for example the experimental resolution) then the binning
8294/// cannot have an important effect. Therefore, we believe that for all
8295/// practical purposes, the probability value PROB is calculated correctly
8296/// provided the user is aware that:
8297///
8298/// 1. The value of PROB should not be expected to have exactly the correct
8299/// distribution for binned data.
8300/// 2. The user is responsible for seeing to it that the bin widths are
8301/// small compared with any physical phenomena of interest.
8302/// 3. The effect of binning (if any) is always to make the value of PROB
8303/// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
8304/// will assure that at most 5% of truly compatible histograms are rejected,
8305/// and usually somewhat less."
8306///
8307/// Note also that for GoF test of unbinned data ROOT provides also the class
8308/// ROOT::Math::GoFTest. The class has also method for doing one sample tests
8309/// (i.e. comparing the data with a given distribution).
8310
8312{
8313 TString opt = option;
8314 opt.ToUpper();
8315
8316 Double_t prob = 0;
8317 TH1 *h1 = (TH1*)this;
8318 if (h2 == nullptr) return 0;
8319 const TAxis *axis1 = h1->GetXaxis();
8320 const TAxis *axis2 = h2->GetXaxis();
8321 Int_t ncx1 = axis1->GetNbins();
8322 Int_t ncx2 = axis2->GetNbins();
8323
8324 // Check consistency of dimensions
8325 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
8326 Error("KolmogorovTest","Histograms must be 1-D\n");
8327 return 0;
8328 }
8329
8330 // Check consistency in number of channels
8331 if (ncx1 != ncx2) {
8332 Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
8333 return 0;
8334 }
8335
8336 // empty the buffer. Probably we could add as an unbinned test
8337 if (fBuffer) ((TH1*)this)->BufferEmpty();
8338
8339 // Check consistency in bin edges
8340 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
8341 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
8342 Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
8343 return 0;
8344 }
8345 }
8346
8349 Double_t sum1 = 0, sum2 = 0;
8350 Double_t ew1, ew2, w1 = 0, w2 = 0;
8351 Int_t bin;
8352 Int_t ifirst = 1;
8353 Int_t ilast = ncx1;
8354 // integral of all bins (use underflow/overflow if option)
8355 if (opt.Contains("U")) ifirst = 0;
8356 if (opt.Contains("O")) ilast = ncx1 +1;
8357 for (bin = ifirst; bin <= ilast; bin++) {
8358 sum1 += h1->RetrieveBinContent(bin);
8359 sum2 += h2->RetrieveBinContent(bin);
8360 ew1 = h1->GetBinError(bin);
8361 ew2 = h2->GetBinError(bin);
8362 w1 += ew1*ew1;
8363 w2 += ew2*ew2;
8364 }
8365 if (sum1 == 0) {
8366 Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
8367 return 0;
8368 }
8369 if (sum2 == 0) {
8370 Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
8371 return 0;
8372 }
8373
8374 // calculate the effective entries.
8375 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
8376 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
8377 Double_t esum1 = 0, esum2 = 0;
8378 if (w1 > 0)
8379 esum1 = sum1 * sum1 / w1;
8380 else
8381 afunc1 = kTRUE; // use later for calculating z
8382
8383 if (w2 > 0)
8384 esum2 = sum2 * sum2 / w2;
8385 else
8386 afunc2 = kTRUE; // use later for calculating z
8387
8388 if (afunc2 && afunc1) {
8389 Error("KolmogorovTest","Errors are zero for both histograms\n");
8390 return 0;
8391 }
8392
8393
8394 Double_t s1 = 1/sum1;
8395 Double_t s2 = 1/sum2;
8396
8397 // Find largest difference for Kolmogorov Test
8398 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
8399
8400 for (bin=ifirst;bin<=ilast;bin++) {
8401 rsum1 += s1*h1->RetrieveBinContent(bin);
8402 rsum2 += s2*h2->RetrieveBinContent(bin);
8404 }
8405
8406 // Get Kolmogorov probability
8407 Double_t z, prb1=0, prb2=0, prb3=0;
8408
8409 // case h1 is exact (has zero errors)
8410 if (afunc1)
8411 z = dfmax*TMath::Sqrt(esum2);
8412 // case h2 has zero errors
8413 else if (afunc2)
8414 z = dfmax*TMath::Sqrt(esum1);
8415 else
8416 // for comparison between two data sets
8418
8420
8421 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
8422 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
8423 // Combine probabilities for shape and normalization,
8424 prb1 = prob;
8427 prb2 = TMath::Prob(chi2,1);
8428 // see Eadie et al., section 11.6.2
8429 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
8430 else prob = 0;
8431 }
8432 // X option. Run Pseudo-experiments to determine NULL distribution of the
8433 // KS distance. We can find the probability from the number of pseudo-experiment that have a
8434 // KS distance larger than the one opbserved in the data.
8435 // We use the histogram with the largest statistics as a parent distribution for the NULL.
8436 // Note if one histogram has zero errors is considered as a function. In that case we use it
8437 // as parent distribution for the toys.
8438 //
8439 Int_t nEXPT = 1000;
8440 if (opt.Contains("X")) {
8441 // get number of pseudo-experiment of specified
8442 if (opt.Contains("X=")) {
8443 int numpos = opt.Index("X=") + 2; // 2 is length of X=
8444 int numlen = 0;
8445 int len = opt.Length();
8446 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) )
8447 numlen++;
8448 TString snum = opt(numpos,numlen);
8449 int num = atoi(snum.Data());
8450 if (num <= 0)
8451 Warning("KolmogorovTest","invalid number of toys given: %d - use 1000",num);
8452 else
8453 nEXPT = num;
8454 }
8455
8457 TH1D hparent;
8458 // we cannot have afunc1 and func2 both True
8459 if (afunc1 || esum1 > esum2 ) h1->Copy(hparent);
8460 else h2->Copy(hparent);
8461
8462 // copy h1Expt from h1 and h2. It is just needed to get the correct binning
8463
8464
8465 if (hparent.GetMinimum() < 0.0) {
8466 // we need to create a new histogram
8467 // With negative bins we can't draw random samples in a meaningful way.
8468 Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
8469 "skewed. Reduce number of bins for histogram?");
8470 while (hparent.GetMinimum() < 0.0) {
8471 Int_t idx = hparent.GetMinimumBin();
8472 hparent.SetBinContent(idx, 0.0);
8473 }
8474 }
8475
8476 // make nEXPT experiments (this should be a parameter)
8477 prb3 = 0;
8478 TH1D h1Expt;
8479 h1->Copy(h1Expt);
8480 TH1D h2Expt;
8481 h1->Copy(h2Expt);
8482 // loop on pseudoexperients and generate the two histograms h1Expt and h2Expt according to the
8483 // parent distribution. In case the parent distribution is not an histogram but a function randomize only one
8484 // histogram
8485 for (Int_t i=0; i < nEXPT; i++) {
8486 if (!afunc1) {
8487 h1Expt.Reset();
8488 h1Expt.FillRandom(&hparent, (Int_t)esum1);
8489 }
8490 if (!afunc2) {
8491 h2Expt.Reset();
8492 h2Expt.FillRandom(&hparent, (Int_t)esum2);
8493 }
8494 // note we cannot have both afunc1 and afunc2 to be true
8495 if (afunc1)
8496 dSEXPT = hparent.KolmogorovTest(&h2Expt,"M");
8497 else if (afunc2)
8498 dSEXPT = hparent.KolmogorovTest(&h1Expt,"M");
8499 else
8500 dSEXPT = h1Expt.KolmogorovTest(&h2Expt,"M");
8501 // count number of cases toy KS distance (TS) is larger than oberved one
8502 if (dSEXPT>dfmax) prb3 += 1.0;
8503 }
8504 // compute p-value
8505 prb3 /= (Double_t)nEXPT;
8506 }
8507
8508
8509 // debug printout
8510 if (opt.Contains("D")) {
8511 printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
8512 printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
8513 printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
8514 if (opt.Contains("N"))
8515 printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
8516 if (opt.Contains("X"))
8517 printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
8518 }
8519 // This numerical error condition should never occur:
8520 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
8521 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
8522
8523 if(opt.Contains("M")) return dfmax;
8524 else if(opt.Contains("X")) return prb3;
8525 else return prob;
8526}
8527
8528////////////////////////////////////////////////////////////////////////////////
8529/// Replace bin contents by the contents of array content
8530
8531void TH1::SetContent(const Double_t *content)
8532{
8533 fEntries = fNcells;
8534 fTsumw = 0;
8535 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
8536}
8537
8538////////////////////////////////////////////////////////////////////////////////
8539/// Return contour values into array levels if pointer levels is non zero.
8540///
8541/// The function returns the number of contour levels.
8542/// see GetContourLevel to return one contour only
8543
8545{
8547 if (levels) {
8548 if (nlevels == 0) {
8549 nlevels = 20;
8551 } else {
8553 }
8554 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
8555 }
8556 return nlevels;
8557}
8558
8559////////////////////////////////////////////////////////////////////////////////
8560/// Return value of contour number level.
8561/// Use GetContour to return the array of all contour levels
8562
8564{
8565 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
8566}
8567
8568////////////////////////////////////////////////////////////////////////////////
8569/// Return the value of contour number "level" in Pad coordinates.
8570/// ie: if the Pad is in log scale along Z it returns le log of the contour level
8571/// value. See GetContour to return the array of all contour levels
8572
8574{
8575 if (level <0 || level >= fContour.fN) return 0;
8576 Double_t zlevel = fContour.fArray[level];
8577
8578 // In case of user defined contours and Pad in log scale along Z,
8579 // fContour.fArray doesn't contain the log of the contour whereas it does
8580 // in case of equidistant contours.
8581 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
8582 if (zlevel <= 0) return 0;
8584 }
8585 return zlevel;
8586}
8587
8588////////////////////////////////////////////////////////////////////////////////
8589/// Set the maximum number of entries to be kept in the buffer.
8590
8591void TH1::SetBuffer(Int_t bufsize, Option_t * /*option*/)
8592{
8593 if (fBuffer) {
8594 BufferEmpty();
8595 delete [] fBuffer;
8596 fBuffer = nullptr;
8597 }
8598 if (bufsize <= 0) {
8599 fBufferSize = 0;
8600 return;
8601 }
8602 if (bufsize < 100) bufsize = 100;
8603 fBufferSize = 1 + bufsize*(fDimension+1);
8605 memset(fBuffer, 0, sizeof(Double_t)*fBufferSize);
8606}
8607
8608////////////////////////////////////////////////////////////////////////////////
8609/// Set the number and values of contour levels.
8610///
8611/// By default the number of contour levels is set to 20. The contours values
8612/// in the array "levels" should be specified in increasing order.
8613///
8614/// if argument levels = 0 or missing, `nlevels` equidistant contours are computed
8615/// between `zmin` and `zmax - dz`, both included, with step
8616/// `dz = (zmax - zmin)/nlevels`. Note that contour lines are not centered, but
8617/// contour surfaces (when drawing with `COLZ`) will be, since contour color `i` covers
8618/// the region of values between contour line `i` and `i+1`.
8619
8621{
8622 Int_t level;
8624 if (nlevels <=0 ) {
8625 fContour.Set(0);
8626 return;
8627 }
8629
8630 // - Contour levels are specified
8631 if (levels) {
8633 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
8634 } else {
8635 // - contour levels are computed automatically as equidistant contours
8636 Double_t zmin = GetMinimum();
8637 Double_t zmax = GetMaximum();
8638 if ((zmin == zmax) && (zmin != 0)) {
8639 zmax += 0.01*TMath::Abs(zmax);
8640 zmin -= 0.01*TMath::Abs(zmin);
8641 }
8642 Double_t dz = (zmax-zmin)/Double_t(nlevels);
8643 if (gPad && gPad->GetLogz()) {
8644 if (zmax <= 0) return;
8645 if (zmin <= 0) zmin = 0.001*zmax;
8646 zmin = TMath::Log10(zmin);
8647 zmax = TMath::Log10(zmax);
8648 dz = (zmax-zmin)/Double_t(nlevels);
8649 }
8650 for (level=0; level<nlevels; level++) {
8651 fContour.fArray[level] = zmin + dz*Double_t(level);
8652 }
8653 }
8654}
8655
8656////////////////////////////////////////////////////////////////////////////////
8657/// Set value for one contour level.
8658
8660{
8661 if (level < 0 || level >= fContour.fN) return;
8663 fContour.fArray[level] = value;
8664}
8665
8666////////////////////////////////////////////////////////////////////////////////
8667/// Return maximum value smaller than maxval of bins in the range,
8668/// unless the value has been overridden by TH1::SetMaximum,
8669/// in which case it returns that value. This happens, for example,
8670/// when the histogram is drawn and the y or z axis limits are changed
8671///
8672/// To get the maximum value of bins in the histogram regardless of
8673/// whether the value has been overridden (using TH1::SetMaximum), use
8674///
8675/// ~~~ {.cpp}
8676/// h->GetBinContent(h->GetMaximumBin())
8677/// ~~~
8678///
8679/// TH1::GetMaximumBin can be used to get the location of the maximum
8680/// value.
8681
8683{
8684 if (fMaximum != -1111) return fMaximum;
8685
8686 // empty the buffer
8687 if (fBuffer) ((TH1*)this)->BufferEmpty();
8688
8689 Int_t bin, binx, biny, binz;
8690 Int_t xfirst = fXaxis.GetFirst();
8691 Int_t xlast = fXaxis.GetLast();
8692 Int_t yfirst = fYaxis.GetFirst();
8693 Int_t ylast = fYaxis.GetLast();
8694 Int_t zfirst = fZaxis.GetFirst();
8695 Int_t zlast = fZaxis.GetLast();
8697 for (binz=zfirst;binz<=zlast;binz++) {
8698 for (biny=yfirst;biny<=ylast;biny++) {
8699 for (binx=xfirst;binx<=xlast;binx++) {
8700 bin = GetBin(binx,biny,binz);
8702 if (value > maximum && value < maxval) maximum = value;
8703 }
8704 }
8705 }
8706 return maximum;
8707}
8708
8709////////////////////////////////////////////////////////////////////////////////
8710/// Return location of bin with maximum value in the range.
8711///
8712/// TH1::GetMaximum can be used to get the maximum value.
8713
8715{
8718}
8719
8720////////////////////////////////////////////////////////////////////////////////
8721/// Return location of bin with maximum value in the range.
8722
8724{
8725 // empty the buffer
8726 if (fBuffer) ((TH1*)this)->BufferEmpty();
8727
8728 Int_t bin, binx, biny, binz;
8729 Int_t locm;
8730 Int_t xfirst = fXaxis.GetFirst();
8731 Int_t xlast = fXaxis.GetLast();
8732 Int_t yfirst = fYaxis.GetFirst();
8733 Int_t ylast = fYaxis.GetLast();
8734 Int_t zfirst = fZaxis.GetFirst();
8735 Int_t zlast = fZaxis.GetLast();
8737 locm = locmax = locmay = locmaz = 0;
8738 for (binz=zfirst;binz<=zlast;binz++) {
8739 for (biny=yfirst;biny<=ylast;biny++) {
8740 for (binx=xfirst;binx<=xlast;binx++) {
8741 bin = GetBin(binx,biny,binz);
8743 if (value > maximum) {
8744 maximum = value;
8745 locm = bin;
8746 locmax = binx;
8747 locmay = biny;
8748 locmaz = binz;
8749 }
8750 }
8751 }
8752 }
8753 return locm;
8754}
8755
8756////////////////////////////////////////////////////////////////////////////////
8757/// Return minimum value larger than minval of bins in the range,
8758/// unless the value has been overridden by TH1::SetMinimum,
8759/// in which case it returns that value. This happens, for example,
8760/// when the histogram is drawn and the y or z axis limits are changed
8761///
8762/// To get the minimum value of bins in the histogram regardless of
8763/// whether the value has been overridden (using TH1::SetMinimum), use
8764///
8765/// ~~~ {.cpp}
8766/// h->GetBinContent(h->GetMinimumBin())
8767/// ~~~
8768///
8769/// TH1::GetMinimumBin can be used to get the location of the
8770/// minimum value.
8771
8773{
8774 if (fMinimum != -1111) return fMinimum;
8775
8776 // empty the buffer
8777 if (fBuffer) ((TH1*)this)->BufferEmpty();
8778
8779 Int_t bin, binx, biny, binz;
8780 Int_t xfirst = fXaxis.GetFirst();
8781 Int_t xlast = fXaxis.GetLast();
8782 Int_t yfirst = fYaxis.GetFirst();
8783 Int_t ylast = fYaxis.GetLast();
8784 Int_t zfirst = fZaxis.GetFirst();
8785 Int_t zlast = fZaxis.GetLast();
8787 for (binz=zfirst;binz<=zlast;binz++) {
8788 for (biny=yfirst;biny<=ylast;biny++) {
8789 for (binx=xfirst;binx<=xlast;binx++) {
8790 bin = GetBin(binx,biny,binz);
8793 }
8794 }
8795 }
8796 return minimum;
8797}
8798
8799////////////////////////////////////////////////////////////////////////////////
8800/// Return location of bin with minimum value in the range.
8801
8803{
8806}
8807
8808////////////////////////////////////////////////////////////////////////////////
8809/// Return location of bin with minimum value in the range.
8810
8812{
8813 // empty the buffer
8814 if (fBuffer) ((TH1*)this)->BufferEmpty();
8815
8816 Int_t bin, binx, biny, binz;
8817 Int_t locm;
8818 Int_t xfirst = fXaxis.GetFirst();
8819 Int_t xlast = fXaxis.GetLast();
8820 Int_t yfirst = fYaxis.GetFirst();
8821 Int_t ylast = fYaxis.GetLast();
8822 Int_t zfirst = fZaxis.GetFirst();
8823 Int_t zlast = fZaxis.GetLast();
8825 locm = locmix = locmiy = locmiz = 0;
8826 for (binz=zfirst;binz<=zlast;binz++) {
8827 for (biny=yfirst;biny<=ylast;biny++) {
8828 for (binx=xfirst;binx<=xlast;binx++) {
8829 bin = GetBin(binx,biny,binz);
8831 if (value < minimum) {
8832 minimum = value;
8833 locm = bin;
8834 locmix = binx;
8835 locmiy = biny;
8836 locmiz = binz;
8837 }
8838 }
8839 }
8840 }
8841 return locm;
8842}
8843
8844///////////////////////////////////////////////////////////////////////////////
8845/// Retrieve the minimum and maximum values in the histogram
8846///
8847/// This will not return a cached value and will always search the
8848/// histogram for the min and max values. The user can condition whether
8849/// or not to call this with the GetMinimumStored() and GetMaximumStored()
8850/// methods. If the cache is empty, then the value will be -1111. Users
8851/// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8852/// For example, the following recipe will make efficient use of this method
8853/// and the cached minimum and maximum values.
8854//
8855/// \code{.cpp}
8856/// Double_t currentMin = pHist->GetMinimumStored();
8857/// Double_t currentMax = pHist->GetMaximumStored();
8858/// if ((currentMin == -1111) || (currentMax == -1111)) {
8859/// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8860/// pHist->SetMinimum(currentMin);
8861/// pHist->SetMaximum(currentMax);
8862/// }
8863/// \endcode
8864///
8865/// \param min reference to variable that will hold found minimum value
8866/// \param max reference to variable that will hold found maximum value
8867
8868void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8869{
8870 // empty the buffer
8871 if (fBuffer) ((TH1*)this)->BufferEmpty();
8872
8873 Int_t bin, binx, biny, binz;
8874 Int_t xfirst = fXaxis.GetFirst();
8875 Int_t xlast = fXaxis.GetLast();
8876 Int_t yfirst = fYaxis.GetFirst();
8877 Int_t ylast = fYaxis.GetLast();
8878 Int_t zfirst = fZaxis.GetFirst();
8879 Int_t zlast = fZaxis.GetLast();
8880 min=TMath::Infinity();
8881 max=-TMath::Infinity();
8883 for (binz=zfirst;binz<=zlast;binz++) {
8884 for (biny=yfirst;biny<=ylast;biny++) {
8885 for (binx=xfirst;binx<=xlast;binx++) {
8886 bin = GetBin(binx,biny,binz);
8888 if (value < min) min = value;
8889 if (value > max) max = value;
8890 }
8891 }
8892 }
8893}
8894
8895////////////////////////////////////////////////////////////////////////////////
8896/// Redefine x axis parameters.
8897///
8898/// The X axis parameters are modified.
8899/// The bins content array is resized
8900/// if errors (Sumw2) the errors array is resized
8901/// The previous bin contents are lost
8902/// To change only the axis limits, see TAxis::SetRange
8903
8905{
8906 if (GetDimension() != 1) {
8907 Error("SetBins","Operation only valid for 1-d histograms");
8908 return;
8909 }
8910 fXaxis.SetRange(0,0);
8912 fYaxis.Set(1,0,1);
8913 fZaxis.Set(1,0,1);
8914 fNcells = nx+2;
8916 if (fSumw2.fN) {
8918 }
8919}
8920
8921////////////////////////////////////////////////////////////////////////////////
8922/// Redefine x axis parameters with variable bin sizes.
8923///
8924/// The X axis parameters are modified.
8925/// The bins content array is resized
8926/// if errors (Sumw2) the errors array is resized
8927/// The previous bin contents are lost
8928/// To change only the axis limits, see TAxis::SetRange
8929/// xBins is supposed to be of length nx+1
8930
8931void TH1::SetBins(Int_t nx, const Double_t *xBins)
8932{
8933 if (GetDimension() != 1) {
8934 Error("SetBins","Operation only valid for 1-d histograms");
8935 return;
8936 }
8937 fXaxis.SetRange(0,0);
8938 fXaxis.Set(nx,xBins);
8939 fYaxis.Set(1,0,1);
8940 fZaxis.Set(1,0,1);
8941 fNcells = nx+2;
8943 if (fSumw2.fN) {
8945 }
8946}
8947
8948////////////////////////////////////////////////////////////////////////////////
8949/// Redefine x and y axis parameters.
8950///
8951/// The X and Y axis parameters are modified.
8952/// The bins content array is resized
8953/// if errors (Sumw2) the errors array is resized
8954/// The previous bin contents are lost
8955/// To change only the axis limits, see TAxis::SetRange
8956
8958{
8959 if (GetDimension() != 2) {
8960 Error("SetBins","Operation only valid for 2-D histograms");
8961 return;
8962 }
8963 fXaxis.SetRange(0,0);
8964 fYaxis.SetRange(0,0);
8967 fZaxis.Set(1,0,1);
8968 fNcells = (nx+2)*(ny+2);
8970 if (fSumw2.fN) {
8972 }
8973}
8974
8975////////////////////////////////////////////////////////////////////////////////
8976/// Redefine x and y axis parameters with variable bin sizes.
8977///
8978/// The X and Y axis parameters are modified.
8979/// The bins content array is resized
8980/// if errors (Sumw2) the errors array is resized
8981/// The previous bin contents are lost
8982/// To change only the axis limits, see TAxis::SetRange
8983/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
8984
8985void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
8986{
8987 if (GetDimension() != 2) {
8988 Error("SetBins","Operation only valid for 2-D histograms");
8989 return;
8990 }
8991 fXaxis.SetRange(0,0);
8992 fYaxis.SetRange(0,0);
8993 fXaxis.Set(nx,xBins);
8994 fYaxis.Set(ny,yBins);
8995 fZaxis.Set(1,0,1);
8996 fNcells = (nx+2)*(ny+2);
8998 if (fSumw2.fN) {
9000 }
9001}
9002
9003////////////////////////////////////////////////////////////////////////////////
9004/// Redefine x, y and z axis parameters.
9005///
9006/// The X, Y and Z axis parameters are modified.
9007/// The bins content array is resized
9008/// if errors (Sumw2) the errors array is resized
9009/// The previous bin contents are lost
9010/// To change only the axis limits, see TAxis::SetRange
9011
9013{
9014 if (GetDimension() != 3) {
9015 Error("SetBins","Operation only valid for 3-D histograms");
9016 return;
9017 }
9018 fXaxis.SetRange(0,0);
9019 fYaxis.SetRange(0,0);
9020 fZaxis.SetRange(0,0);
9023 fZaxis.Set(nz,zmin,zmax);
9024 fNcells = (nx+2)*(ny+2)*(nz+2);
9026 if (fSumw2.fN) {
9028 }
9029}
9030
9031////////////////////////////////////////////////////////////////////////////////
9032/// Redefine x, y and z axis parameters with variable bin sizes.
9033///
9034/// The X, Y and Z axis parameters are modified.
9035/// The bins content array is resized
9036/// if errors (Sumw2) the errors array is resized
9037/// The previous bin contents are lost
9038/// To change only the axis limits, see TAxis::SetRange
9039/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
9040/// zBins is supposed to be of length nz+1
9041
9042void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
9043{
9044 if (GetDimension() != 3) {
9045 Error("SetBins","Operation only valid for 3-D histograms");
9046 return;
9047 }
9048 fXaxis.SetRange(0,0);
9049 fYaxis.SetRange(0,0);
9050 fZaxis.SetRange(0,0);
9051 fXaxis.Set(nx,xBins);
9052 fYaxis.Set(ny,yBins);
9053 fZaxis.Set(nz,zBins);
9054 fNcells = (nx+2)*(ny+2)*(nz+2);
9056 if (fSumw2.fN) {
9058 }
9059}
9060
9061////////////////////////////////////////////////////////////////////////////////
9062/// By default, when a histogram is created, it is added to the list
9063/// of histogram objects in the current directory in memory.
9064/// Remove reference to this histogram from current directory and add
9065/// reference to new directory dir. dir can be 0 in which case the
9066/// histogram does not belong to any directory.
9067///
9068/// Note that the directory is not a real property of the histogram and
9069/// it will not be copied when the histogram is copied or cloned.
9070/// If the user wants to have the copied (cloned) histogram in the same
9071/// directory, he needs to set again the directory using SetDirectory to the
9072/// copied histograms
9073
9075{
9076 if (fDirectory == dir) return;
9077 if (fDirectory) fDirectory->Remove(this);
9078 fDirectory = dir;
9079 if (fDirectory) {
9081 fDirectory->Append(this);
9082 }
9083}
9084
9085////////////////////////////////////////////////////////////////////////////////
9086/// Replace bin errors by values in array error.
9087
9088void TH1::SetError(const Double_t *error)
9089{
9090 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
9091}
9092
9093////////////////////////////////////////////////////////////////////////////////
9094/// Change the name of this histogram
9096
9097void TH1::SetName(const char *name)
9098{
9099 // Histograms are named objects in a THashList.
9100 // We must update the hashlist if we change the name
9101 // We protect this operation
9103 if (fDirectory) fDirectory->Remove(this);
9104 fName = name;
9105 if (fDirectory) fDirectory->Append(this);
9106}
9107
9108////////////////////////////////////////////////////////////////////////////////
9109/// Change the name and title of this histogram
9110
9111void TH1::SetNameTitle(const char *name, const char *title)
9112{
9113 // Histograms are named objects in a THashList.
9114 // We must update the hashlist if we change the name
9115 SetName(name);
9116 SetTitle(title);
9117}
9118
9119////////////////////////////////////////////////////////////////////////////////
9120/// Set statistics option on/off.
9121///
9122/// By default, the statistics box is drawn.
9123/// The paint options can be selected via gStyle->SetOptStat.
9124/// This function sets/resets the kNoStats bit in the histogram object.
9125/// It has priority over the Style option.
9126
9127void TH1::SetStats(Bool_t stats)
9128{
9130 if (!stats) {
9132 //remove the "stats" object from the list of functions
9133 if (fFunctions) {
9134 TObject *obj = fFunctions->FindObject("stats");
9135 if (obj) {
9136 fFunctions->Remove(obj);
9137 delete obj;
9138 }
9139 }
9140 }
9141}
9142
9143////////////////////////////////////////////////////////////////////////////////
9144/// Create structure to store sum of squares of weights.
9145///
9146/// if histogram is already filled, the sum of squares of weights
9147/// is filled with the existing bin contents
9148///
9149/// The error per bin will be computed as sqrt(sum of squares of weight)
9150/// for each bin.
9151///
9152/// This function is automatically called when the histogram is created
9153/// if the static function TH1::SetDefaultSumw2 has been called before.
9154/// If flag = false the structure containing the sum of the square of weights
9155/// is rest and it will be empty, but it is not deleted (i.e. GetSumw2()->fN = 0)
9156
9158{
9159 if (!flag) {
9160 // clear the array if existing - do nothing otherwise
9161 if (fSumw2.fN > 0 ) fSumw2.Set(0);
9162 return;
9163 }
9164
9165 if (fSumw2.fN == fNcells) {
9166 if (!fgDefaultSumw2 )
9167 Warning("Sumw2","Sum of squares of weights structure already created");
9168 return;
9169 }
9170
9172
9173 if (fEntries > 0)
9174 for (Int_t i = 0; i < fNcells; ++i)
9176}
9177
9178////////////////////////////////////////////////////////////////////////////////
9179/// Return pointer to function with name.
9180///
9181///
9182/// Functions such as TH1::Fit store the fitted function in the list of
9183/// functions of this histogram.
9184
9185TF1 *TH1::GetFunction(const char *name) const
9186{
9187 return (TF1*)fFunctions->FindObject(name);
9188}
9189
9190////////////////////////////////////////////////////////////////////////////////
9191/// Return value of error associated to bin number bin.
9192///
9193/// if the sum of squares of weights has been defined (via Sumw2),
9194/// this function returns the sqrt(sum of w2).
9195/// otherwise it returns the sqrt(contents) for this bin.
9196
9198{
9199 if (bin < 0) bin = 0;
9200 if (bin >= fNcells) bin = fNcells-1;
9201 if (fBuffer) ((TH1*)this)->BufferEmpty();
9202 if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
9203
9205}
9206
9207////////////////////////////////////////////////////////////////////////////////
9208/// Return lower error associated to bin number bin.
9209///
9210/// The error will depend on the statistic option used will return
9211/// the binContent - lower interval value
9212
9214{
9215 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9216 // in case of weighted histogram check if it is really weighted
9217 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9218
9219 if (bin < 0) bin = 0;
9220 if (bin >= fNcells) bin = fNcells-1;
9221 if (fBuffer) ((TH1*)this)->BufferEmpty();
9222
9223 Double_t alpha = 1.- 0.682689492;
9224 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9225
9227 Int_t n = int(c);
9228 if (n < 0) {
9229 Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
9230 ((TH1*)this)->fBinStatErrOpt = kNormal;
9231 return GetBinError(bin);
9232 }
9233
9234 if (n == 0) return 0;
9235 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
9236}
9237
9238////////////////////////////////////////////////////////////////////////////////
9239/// Return upper error associated to bin number bin.
9240///
9241/// The error will depend on the statistic option used will return
9242/// the binContent - upper interval value
9243
9245{
9246 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9247 // in case of weighted histogram check if it is really weighted
9248 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9249 if (bin < 0) bin = 0;
9250 if (bin >= fNcells) bin = fNcells-1;
9251 if (fBuffer) ((TH1*)this)->BufferEmpty();
9252
9253 Double_t alpha = 1.- 0.682689492;
9254 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9255
9257 Int_t n = int(c);
9258 if (n < 0) {
9259 Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
9260 ((TH1*)this)->fBinStatErrOpt = kNormal;
9261 return GetBinError(bin);
9262 }
9263
9264 // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
9265 // decide to return always (1-alpha)/2 upper interval
9266 //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
9267 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
9268}
9269
9270//L.M. These following getters are useless and should be probably deprecated
9271////////////////////////////////////////////////////////////////////////////////
9272/// Return bin center for 1D histogram.
9273/// Better to use h1.GetXaxis()->GetBinCenter(bin)
9274
9276{
9277 if (fDimension == 1) return fXaxis.GetBinCenter(bin);
9278 Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
9279 return TMath::QuietNaN();
9280}
9281
9282////////////////////////////////////////////////////////////////////////////////
9283/// Return bin lower edge for 1D histogram.
9284/// Better to use h1.GetXaxis()->GetBinLowEdge(bin)
9285
9287{
9288 if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
9289 Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
9290 return TMath::QuietNaN();
9291}
9292
9293////////////////////////////////////////////////////////////////////////////////
9294/// Return bin width for 1D histogram.
9295/// Better to use h1.GetXaxis()->GetBinWidth(bin)
9296
9298{
9299 if (fDimension == 1) return fXaxis.GetBinWidth(bin);
9300 Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
9301 return TMath::QuietNaN();
9302}
9303
9304////////////////////////////////////////////////////////////////////////////////
9305/// Fill array with center of bins for 1D histogram
9306/// Better to use h1.GetXaxis()->GetCenter(center)
9307
9308void TH1::GetCenter(Double_t *center) const
9309{
9310 if (fDimension == 1) {
9311 fXaxis.GetCenter(center);
9312 return;
9313 }
9314 Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
9315}
9316
9317////////////////////////////////////////////////////////////////////////////////
9318/// Fill array with low edge of bins for 1D histogram
9319/// Better to use h1.GetXaxis()->GetLowEdge(edge)
9320
9321void TH1::GetLowEdge(Double_t *edge) const
9322{
9323 if (fDimension == 1) {
9325 return;
9326 }
9327 Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
9328}
9329
9330////////////////////////////////////////////////////////////////////////////////
9331/// Set the bin Error
9332/// Note that this resets the bin eror option to be of Normal Type and for the
9333/// non-empty bin the bin error is set by default to the square root of their content.
9334/// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
9335/// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
9336/// will not be recalculated after setting the content and a default error = 0 will be used for those bins.
9337///
9338/// See convention for numbering bins in TH1::GetBin
9339
9340void TH1::SetBinError(Int_t bin, Double_t error)
9341{
9342 if (bin < 0 || bin>= fNcells) return;
9343 if (!fSumw2.fN) Sumw2();
9344 fSumw2.fArray[bin] = error * error;
9345 // reset the bin error option
9347}
9348
9349////////////////////////////////////////////////////////////////////////////////
9350/// Set bin content
9351/// see convention for numbering bins in TH1::GetBin
9352/// In case the bin number is greater than the number of bins and
9353/// the timedisplay option is set or CanExtendAllAxes(),
9354/// the number of bins is automatically doubled to accommodate the new bin
9355
9357{
9358 fEntries++;
9359 fTsumw = 0;
9360 if (bin < 0) return;
9361 if (bin >= fNcells-1) {
9363 while (bin >= fNcells-1) LabelsInflate();
9364 } else {
9365 if (bin == fNcells-1) UpdateBinContent(bin, content);
9366 return;
9367 }
9368 }
9370}
9371
9372////////////////////////////////////////////////////////////////////////////////
9373/// See convention for numbering bins in TH1::GetBin
9374
9376{
9377 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9378 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9379 SetBinError(GetBin(binx, biny), error);
9380}
9381
9382////////////////////////////////////////////////////////////////////////////////
9383/// See convention for numbering bins in TH1::GetBin
9384
9386{
9387 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9388 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9389 if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
9390 SetBinError(GetBin(binx, biny, binz), error);
9391}
9392
9393////////////////////////////////////////////////////////////////////////////////
9394/// This function calculates the background spectrum in this histogram.
9395/// The background is returned as a histogram.
9396///
9397/// \param[in] niter number of iterations (default value = 2)
9398/// Increasing niter make the result smoother and lower.
9399/// \param[in] option may contain one of the following options
9400/// - to set the direction parameter
9401/// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
9402/// - filterOrder-order of clipping filter (default "BackOrder2")
9403/// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
9404/// - "nosmoothing" - if selected, the background is not smoothed
9405/// By default the background is smoothed.
9406/// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
9407/// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
9408/// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
9409/// - "nocompton" - if selected the estimation of Compton edge
9410/// will be not be included (by default the compton estimation is set)
9411/// - "same" if this option is specified, the resulting background
9412/// histogram is superimposed on the picture in the current pad.
9413/// This option is given by default.
9414///
9415/// NOTE that the background is only evaluated in the current range of this histogram.
9416/// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
9417/// the returned histogram will be created with the same number of bins
9418/// as this input histogram, but only bins from binmin to binmax will be filled
9419/// with the estimated background.
9420
9422{
9423 return (TH1*)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticBackground((TH1*)0x%zx,%d,\"%s\")",
9424 (size_t)this, niter, option).Data());
9425}
9426
9427////////////////////////////////////////////////////////////////////////////////
9428/// Interface to TSpectrum::Search.
9429/// The function finds peaks in this histogram where the width is > sigma
9430/// and the peak maximum greater than threshold*maximum bin content of this.
9431/// For more details see TSpectrum::Search.
9432/// Note the difference in the default value for option compared to TSpectrum::Search
9433/// option="" by default (instead of "goff").
9434
9436{
9437 return (Int_t)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticSearch((TH1*)0x%zx,%g,\"%s\",%g)",
9438 (size_t)this, sigma, option, threshold).Data());
9439}
9440
9441////////////////////////////////////////////////////////////////////////////////
9442/// For a given transform (first parameter), fills the histogram (second parameter)
9443/// with the transform output data, specified in the third parameter
9444/// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
9445/// and the user is responsible for deleting it.
9446///
9447/// Available options:
9448/// - "RE" - real part of the output
9449/// - "IM" - imaginary part of the output
9450/// - "MAG" - magnitude of the output
9451/// - "PH" - phase of the output
9452
9454{
9455 if (!fft || !fft->GetN() ) {
9456 ::Error("TransformHisto","Invalid FFT transform class");
9457 return nullptr;
9458 }
9459
9460 if (fft->GetNdim()>2){
9461 ::Error("TransformHisto","Only 1d and 2D transform are supported");
9462 return nullptr;
9463 }
9464 Int_t binx,biny;
9465 TString opt = option;
9466 opt.ToUpper();
9467 Int_t *n = fft->GetN();
9468 TH1 *hout=nullptr;
9469 if (h_output) {
9470 hout = h_output;
9471 }
9472 else {
9473 TString name = TString::Format("out_%s", opt.Data());
9474 if (fft->GetNdim()==1)
9475 hout = new TH1D(name, name,n[0], 0, n[0]);
9476 else if (fft->GetNdim()==2)
9477 hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
9478 }
9479 R__ASSERT(hout != nullptr);
9480 TString type=fft->GetType();
9481 Int_t ind[2];
9482 if (opt.Contains("RE")){
9483 if (type.Contains("2C") || type.Contains("2HC")) {
9484 Double_t re, im;
9485 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9486 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9487 ind[0] = binx-1; ind[1] = biny-1;
9488 fft->GetPointComplex(ind, re, im);
9489 hout->SetBinContent(binx, biny, re);
9490 }
9491 }
9492 } else {
9493 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9494 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9495 ind[0] = binx-1; ind[1] = biny-1;
9496 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
9497 }
9498 }
9499 }
9500 }
9501 if (opt.Contains("IM")) {
9502 if (type.Contains("2C") || type.Contains("2HC")) {
9503 Double_t re, im;
9504 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9505 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9506 ind[0] = binx-1; ind[1] = biny-1;
9507 fft->GetPointComplex(ind, re, im);
9508 hout->SetBinContent(binx, biny, im);
9509 }
9510 }
9511 } else {
9512 ::Error("TransformHisto","No complex numbers in the output");
9513 return nullptr;
9514 }
9515 }
9516 if (opt.Contains("MA")) {
9517 if (type.Contains("2C") || type.Contains("2HC")) {
9518 Double_t re, im;
9519 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9520 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9521 ind[0] = binx-1; ind[1] = biny-1;
9522 fft->GetPointComplex(ind, re, im);
9523 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
9524 }
9525 }
9526 } else {
9527 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9528 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9529 ind[0] = binx-1; ind[1] = biny-1;
9530 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
9531 }
9532 }
9533 }
9534 }
9535 if (opt.Contains("PH")) {
9536 if (type.Contains("2C") || type.Contains("2HC")){
9537 Double_t re, im, ph;
9538 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
9539 for (biny=1; biny<=hout->GetNbinsY(); biny++){
9540 ind[0] = binx-1; ind[1] = biny-1;
9541 fft->GetPointComplex(ind, re, im);
9542 if (TMath::Abs(re) > 1e-13){
9543 ph = TMath::ATan(im/re);
9544 //find the correct quadrant
9545 if (re<0 && im<0)
9546 ph -= TMath::Pi();
9547 if (re<0 && im>=0)
9548 ph += TMath::Pi();
9549 } else {
9550 if (TMath::Abs(im) < 1e-13)
9551 ph = 0;
9552 else if (im>0)
9553 ph = TMath::Pi()*0.5;
9554 else
9555 ph = -TMath::Pi()*0.5;
9556 }
9557 hout->SetBinContent(binx, biny, ph);
9558 }
9559 }
9560 } else {
9561 printf("Pure real output, no phase");
9562 return nullptr;
9563 }
9564 }
9565
9566 return hout;
9567}
9568
9569////////////////////////////////////////////////////////////////////////////////
9570/// Print value overload
9571
9572std::string cling::printValue(TH1 *val) {
9573 std::ostringstream strm;
9574 strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
9575 return strm.str();
9576}
9577
9578//______________________________________________________________________________
9579// TH1C methods
9580// TH1C : histograms with one byte per channel. Maximum bin content = 127
9581//______________________________________________________________________________
9582
9583
9584////////////////////////////////////////////////////////////////////////////////
9585/// Constructor.
9586
9587TH1C::TH1C()
9588{
9589 fDimension = 1;
9590 SetBinsLength(3);
9591 if (fgDefaultSumw2) Sumw2();
9592}
9593
9594////////////////////////////////////////////////////////////////////////////////
9595/// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
9596/// (see TH1::TH1 for explanation of parameters)
9597
9598TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9599: TH1(name,title,nbins,xlow,xup)
9600{
9601 fDimension = 1;
9603
9604 if (xlow >= xup) SetBuffer(fgBufferSize);
9605 if (fgDefaultSumw2) Sumw2();
9606}
9607
9608////////////////////////////////////////////////////////////////////////////////
9609/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9610/// (see TH1::TH1 for explanation of parameters)
9611
9612TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9613: TH1(name,title,nbins,xbins)
9614{
9615 fDimension = 1;
9617 if (fgDefaultSumw2) Sumw2();
9618}
9619
9620////////////////////////////////////////////////////////////////////////////////
9621/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9622/// (see TH1::TH1 for explanation of parameters)
9623
9624TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9625: TH1(name,title,nbins,xbins)
9626{
9627 fDimension = 1;
9629 if (fgDefaultSumw2) Sumw2();
9630}
9631
9632////////////////////////////////////////////////////////////////////////////////
9633/// Destructor.
9634
9636{
9637}
9638
9639////////////////////////////////////////////////////////////////////////////////
9640/// Copy constructor.
9641/// The list of functions is not copied. (Use Clone() if needed)
9642
9643TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
9644{
9645 h1c.TH1C::Copy(*this);
9646}
9647
9648////////////////////////////////////////////////////////////////////////////////
9649/// Increment bin content by 1.
9650/// Passing an out-of-range bin leads to undefined behavior
9651
9652void TH1C::AddBinContent(Int_t bin)
9653{
9654 if (fArray[bin] < 127) fArray[bin]++;
9655}
9656
9657////////////////////////////////////////////////////////////////////////////////
9658/// Increment bin content by w.
9659/// \warning The value of w is cast to `Int_t` before being added.
9660/// Passing an out-of-range bin leads to undefined behavior
9661
9663{
9664 Int_t newval = fArray[bin] + Int_t(w);
9665 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
9666 if (newval < -127) fArray[bin] = -127;
9667 if (newval > 127) fArray[bin] = 127;
9668}
9669
9670////////////////////////////////////////////////////////////////////////////////
9671/// Copy this to newth1
9672
9673void TH1C::Copy(TObject &newth1) const
9674{
9676}
9677
9678////////////////////////////////////////////////////////////////////////////////
9679/// Reset.
9680
9682{
9685}
9686
9687////////////////////////////////////////////////////////////////////////////////
9688/// Set total number of bins including under/overflow
9689/// Reallocate bin contents array
9690
9692{
9693 if (n < 0) n = fXaxis.GetNbins() + 2;
9694 fNcells = n;
9695 TArrayC::Set(n);
9696}
9697
9698////////////////////////////////////////////////////////////////////////////////
9699/// Operator =
9700
9701TH1C& TH1C::operator=(const TH1C &h1)
9702{
9703 if (this != &h1)
9704 h1.TH1C::Copy(*this);
9705 return *this;
9706}
9707
9708////////////////////////////////////////////////////////////////////////////////
9709/// Operator *
9710
9712{
9713 TH1C hnew = h1;
9714 hnew.Scale(c1);
9715 hnew.SetDirectory(nullptr);
9716 return hnew;
9717}
9718
9719////////////////////////////////////////////////////////////////////////////////
9720/// Operator +
9721
9722TH1C operator+(const TH1C &h1, const TH1C &h2)
9723{
9724 TH1C hnew = h1;
9725 hnew.Add(&h2,1);
9726 hnew.SetDirectory(nullptr);
9727 return hnew;
9728}
9729
9730////////////////////////////////////////////////////////////////////////////////
9731/// Operator -
9732
9733TH1C operator-(const TH1C &h1, const TH1C &h2)
9734{
9735 TH1C hnew = h1;
9736 hnew.Add(&h2,-1);
9737 hnew.SetDirectory(nullptr);
9738 return hnew;
9739}
9740
9741////////////////////////////////////////////////////////////////////////////////
9742/// Operator *
9743
9744TH1C operator*(const TH1C &h1, const TH1C &h2)
9745{
9746 TH1C hnew = h1;
9747 hnew.Multiply(&h2);
9748 hnew.SetDirectory(nullptr);
9749 return hnew;
9750}
9751
9752////////////////////////////////////////////////////////////////////////////////
9753/// Operator /
9754
9755TH1C operator/(const TH1C &h1, const TH1C &h2)
9756{
9757 TH1C hnew = h1;
9758 hnew.Divide(&h2);
9759 hnew.SetDirectory(nullptr);
9760 return hnew;
9761}
9762
9763//______________________________________________________________________________
9764// TH1S methods
9765// TH1S : histograms with one short per channel. Maximum bin content = 32767
9766//______________________________________________________________________________
9767
9768
9769////////////////////////////////////////////////////////////////////////////////
9770/// Constructor.
9771
9772TH1S::TH1S()
9773{
9774 fDimension = 1;
9775 SetBinsLength(3);
9776 if (fgDefaultSumw2) Sumw2();
9777}
9778
9779////////////////////////////////////////////////////////////////////////////////
9780/// Create a 1-Dim histogram with fix bins of type short
9781/// (see TH1::TH1 for explanation of parameters)
9782
9783TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9784: TH1(name,title,nbins,xlow,xup)
9785{
9786 fDimension = 1;
9788
9789 if (xlow >= xup) SetBuffer(fgBufferSize);
9790 if (fgDefaultSumw2) Sumw2();
9791}
9792
9793////////////////////////////////////////////////////////////////////////////////
9794/// Create a 1-Dim histogram with variable bins of type short
9795/// (see TH1::TH1 for explanation of parameters)
9796
9797TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9798: TH1(name,title,nbins,xbins)
9799{
9800 fDimension = 1;
9802 if (fgDefaultSumw2) Sumw2();
9803}
9804
9805////////////////////////////////////////////////////////////////////////////////
9806/// Create a 1-Dim histogram with variable bins of type short
9807/// (see TH1::TH1 for explanation of parameters)
9808
9809TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9810: TH1(name,title,nbins,xbins)
9811{
9812 fDimension = 1;
9814 if (fgDefaultSumw2) Sumw2();
9815}
9816
9817////////////////////////////////////////////////////////////////////////////////
9818/// Destructor.
9819
9821{
9822}
9823
9824////////////////////////////////////////////////////////////////////////////////
9825/// Copy constructor.
9826/// The list of functions is not copied. (Use Clone() if needed)
9827
9828TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9829{
9830 h1s.TH1S::Copy(*this);
9831}
9832
9833////////////////////////////////////////////////////////////////////////////////
9834/// Increment bin content by 1.
9835/// Passing an out-of-range bin leads to undefined behavior
9836
9837void TH1S::AddBinContent(Int_t bin)
9838{
9839 if (fArray[bin] < 32767) fArray[bin]++;
9840}
9841
9842////////////////////////////////////////////////////////////////////////////////
9843/// Increment bin content by w.
9844/// \warning The value of w is cast to `Int_t` before being added.
9845/// Passing an out-of-range bin leads to undefined behavior
9846
9848{
9849 Int_t newval = fArray[bin] + Int_t(w);
9850 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9851 if (newval < -32767) fArray[bin] = -32767;
9852 if (newval > 32767) fArray[bin] = 32767;
9853}
9854
9855////////////////////////////////////////////////////////////////////////////////
9856/// Copy this to newth1
9857
9858void TH1S::Copy(TObject &newth1) const
9859{
9861}
9862
9863////////////////////////////////////////////////////////////////////////////////
9864/// Reset.
9865
9867{
9870}
9871
9872////////////////////////////////////////////////////////////////////////////////
9873/// Set total number of bins including under/overflow
9874/// Reallocate bin contents array
9875
9877{
9878 if (n < 0) n = fXaxis.GetNbins() + 2;
9879 fNcells = n;
9880 TArrayS::Set(n);
9881}
9882
9883////////////////////////////////////////////////////////////////////////////////
9884/// Operator =
9885
9886TH1S& TH1S::operator=(const TH1S &h1)
9887{
9888 if (this != &h1)
9889 h1.TH1S::Copy(*this);
9890 return *this;
9891}
9892
9893////////////////////////////////////////////////////////////////////////////////
9894/// Operator *
9895
9897{
9898 TH1S hnew = h1;
9899 hnew.Scale(c1);
9900 hnew.SetDirectory(nullptr);
9901 return hnew;
9902}
9903
9904////////////////////////////////////////////////////////////////////////////////
9905/// Operator +
9906
9907TH1S operator+(const TH1S &h1, const TH1S &h2)
9908{
9909 TH1S hnew = h1;
9910 hnew.Add(&h2,1);
9911 hnew.SetDirectory(nullptr);
9912 return hnew;
9913}
9914
9915////////////////////////////////////////////////////////////////////////////////
9916/// Operator -
9917
9918TH1S operator-(const TH1S &h1, const TH1S &h2)
9919{
9920 TH1S hnew = h1;
9921 hnew.Add(&h2,-1);
9922 hnew.SetDirectory(nullptr);
9923 return hnew;
9924}
9925
9926////////////////////////////////////////////////////////////////////////////////
9927/// Operator *
9928
9929TH1S operator*(const TH1S &h1, const TH1S &h2)
9930{
9931 TH1S hnew = h1;
9932 hnew.Multiply(&h2);
9933 hnew.SetDirectory(nullptr);
9934 return hnew;
9935}
9936
9937////////////////////////////////////////////////////////////////////////////////
9938/// Operator /
9939
9940TH1S operator/(const TH1S &h1, const TH1S &h2)
9941{
9942 TH1S hnew = h1;
9943 hnew.Divide(&h2);
9944 hnew.SetDirectory(nullptr);
9945 return hnew;
9946}
9947
9948//______________________________________________________________________________
9949// TH1I methods
9950// TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9951// 2147483647 = INT_MAX
9952//______________________________________________________________________________
9953
9954
9955////////////////////////////////////////////////////////////////////////////////
9956/// Constructor.
9957
9958TH1I::TH1I()
9959{
9960 fDimension = 1;
9961 SetBinsLength(3);
9962 if (fgDefaultSumw2) Sumw2();
9963}
9964
9965////////////////////////////////////////////////////////////////////////////////
9966/// Create a 1-Dim histogram with fix bins of type integer
9967/// (see TH1::TH1 for explanation of parameters)
9968
9969TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9970: TH1(name,title,nbins,xlow,xup)
9971{
9972 fDimension = 1;
9974
9975 if (xlow >= xup) SetBuffer(fgBufferSize);
9976 if (fgDefaultSumw2) Sumw2();
9977}
9978
9979////////////////////////////////////////////////////////////////////////////////
9980/// Create a 1-Dim histogram with variable bins of type integer
9981/// (see TH1::TH1 for explanation of parameters)
9982
9983TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9984: TH1(name,title,nbins,xbins)
9985{
9986 fDimension = 1;
9988 if (fgDefaultSumw2) Sumw2();
9989}
9990
9991////////////////////////////////////////////////////////////////////////////////
9992/// Create a 1-Dim histogram with variable bins of type integer
9993/// (see TH1::TH1 for explanation of parameters)
9994
9995TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9996: TH1(name,title,nbins,xbins)
9997{
9998 fDimension = 1;
10000 if (fgDefaultSumw2) Sumw2();
10001}
10002
10003////////////////////////////////////////////////////////////////////////////////
10004/// Destructor.
10005
10007{
10008}
10009
10010////////////////////////////////////////////////////////////////////////////////
10011/// Copy constructor.
10012/// The list of functions is not copied. (Use Clone() if needed)
10013
10014TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
10015{
10016 h1i.TH1I::Copy(*this);
10017}
10018
10019////////////////////////////////////////////////////////////////////////////////
10020/// Increment bin content by 1.
10021/// Passing an out-of-range bin leads to undefined behavior
10022
10023void TH1I::AddBinContent(Int_t bin)
10024{
10025 if (fArray[bin] < INT_MAX) fArray[bin]++;
10026}
10027
10028////////////////////////////////////////////////////////////////////////////////
10029/// Increment bin content by w
10030/// \warning The value of w is cast to `Long64_t` before being added.
10031/// Passing an out-of-range bin leads to undefined behavior
10032
10034{
10035 Long64_t newval = fArray[bin] + Long64_t(w);
10036 if (newval > -INT_MAX && newval < INT_MAX) {fArray[bin] = Int_t(newval); return;}
10037 if (newval < -INT_MAX) fArray[bin] = -INT_MAX;
10038 if (newval > INT_MAX) fArray[bin] = INT_MAX;
10039}
10040
10041////////////////////////////////////////////////////////////////////////////////
10042/// Copy this to newth1
10043
10044void TH1I::Copy(TObject &newth1) const
10045{
10047}
10048
10049////////////////////////////////////////////////////////////////////////////////
10050/// Reset.
10051
10053{
10056}
10057
10058////////////////////////////////////////////////////////////////////////////////
10059/// Set total number of bins including under/overflow
10060/// Reallocate bin contents array
10061
10063{
10064 if (n < 0) n = fXaxis.GetNbins() + 2;
10065 fNcells = n;
10066 TArrayI::Set(n);
10067}
10068
10069////////////////////////////////////////////////////////////////////////////////
10070/// Operator =
10071
10072TH1I& TH1I::operator=(const TH1I &h1)
10073{
10074 if (this != &h1)
10075 h1.TH1I::Copy(*this);
10076 return *this;
10077}
10078
10079
10080////////////////////////////////////////////////////////////////////////////////
10081/// Operator *
10082
10084{
10085 TH1I hnew = h1;
10086 hnew.Scale(c1);
10087 hnew.SetDirectory(nullptr);
10088 return hnew;
10089}
10090
10091////////////////////////////////////////////////////////////////////////////////
10092/// Operator +
10093
10094TH1I operator+(const TH1I &h1, const TH1I &h2)
10095{
10096 TH1I hnew = h1;
10097 hnew.Add(&h2,1);
10098 hnew.SetDirectory(nullptr);
10099 return hnew;
10100}
10101
10102////////////////////////////////////////////////////////////////////////////////
10103/// Operator -
10104
10105TH1I operator-(const TH1I &h1, const TH1I &h2)
10106{
10107 TH1I hnew = h1;
10108 hnew.Add(&h2,-1);
10109 hnew.SetDirectory(nullptr);
10110 return hnew;
10111}
10112
10113////////////////////////////////////////////////////////////////////////////////
10114/// Operator *
10115
10116TH1I operator*(const TH1I &h1, const TH1I &h2)
10117{
10118 TH1I hnew = h1;
10119 hnew.Multiply(&h2);
10120 hnew.SetDirectory(nullptr);
10121 return hnew;
10122}
10123
10124////////////////////////////////////////////////////////////////////////////////
10125/// Operator /
10126
10127TH1I operator/(const TH1I &h1, const TH1I &h2)
10128{
10129 TH1I hnew = h1;
10130 hnew.Divide(&h2);
10131 hnew.SetDirectory(nullptr);
10132 return hnew;
10133}
10134
10135//______________________________________________________________________________
10136// TH1L methods
10137// TH1L : histograms with one long64 per channel. Maximum bin content = 9223372036854775807
10138// 9223372036854775807 = LLONG_MAX
10139//______________________________________________________________________________
10140
10141
10142////////////////////////////////////////////////////////////////////////////////
10143/// Constructor.
10144
10145TH1L::TH1L()
10146{
10147 fDimension = 1;
10148 SetBinsLength(3);
10149 if (fgDefaultSumw2) Sumw2();
10150}
10151
10152////////////////////////////////////////////////////////////////////////////////
10153/// Create a 1-Dim histogram with fix bins of type long64
10154/// (see TH1::TH1 for explanation of parameters)
10155
10156TH1L::TH1L(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10157: TH1(name,title,nbins,xlow,xup)
10158{
10159 fDimension = 1;
10161
10162 if (xlow >= xup) SetBuffer(fgBufferSize);
10163 if (fgDefaultSumw2) Sumw2();
10164}
10165
10166////////////////////////////////////////////////////////////////////////////////
10167/// Create a 1-Dim histogram with variable bins of type long64
10168/// (see TH1::TH1 for explanation of parameters)
10169
10170TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10171: TH1(name,title,nbins,xbins)
10172{
10173 fDimension = 1;
10175 if (fgDefaultSumw2) Sumw2();
10176}
10177
10178////////////////////////////////////////////////////////////////////////////////
10179/// Create a 1-Dim histogram with variable bins of type long64
10180/// (see TH1::TH1 for explanation of parameters)
10181
10182TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10183: TH1(name,title,nbins,xbins)
10184{
10185 fDimension = 1;
10187 if (fgDefaultSumw2) Sumw2();
10188}
10189
10190////////////////////////////////////////////////////////////////////////////////
10191/// Destructor.
10192
10194{
10195}
10196
10197////////////////////////////////////////////////////////////////////////////////
10198/// Copy constructor.
10199/// The list of functions is not copied. (Use Clone() if needed)
10200
10201TH1L::TH1L(const TH1L &h1l) : TH1(), TArrayL64()
10202{
10203 h1l.TH1L::Copy(*this);
10204}
10205
10206////////////////////////////////////////////////////////////////////////////////
10207/// Increment bin content by 1.
10208/// Passing an out-of-range bin leads to undefined behavior
10209
10210void TH1L::AddBinContent(Int_t bin)
10211{
10212 if (fArray[bin] < LLONG_MAX) fArray[bin]++;
10213}
10214
10215////////////////////////////////////////////////////////////////////////////////
10216/// Increment bin content by w.
10217/// \warning The value of w is cast to `Long64_t` before being added.
10218/// Passing an out-of-range bin leads to undefined behavior
10219
10221{
10222 Long64_t newval = fArray[bin] + Long64_t(w);
10223 if (newval > -LLONG_MAX && newval < LLONG_MAX) {fArray[bin] = newval; return;}
10224 if (newval < -LLONG_MAX) fArray[bin] = -LLONG_MAX;
10225 if (newval > LLONG_MAX) fArray[bin] = LLONG_MAX;
10226}
10227
10228////////////////////////////////////////////////////////////////////////////////
10229/// Copy this to newth1
10230
10231void TH1L::Copy(TObject &newth1) const
10232{
10234}
10235
10236////////////////////////////////////////////////////////////////////////////////
10237/// Reset.
10238
10240{
10243}
10244
10245////////////////////////////////////////////////////////////////////////////////
10246/// Set total number of bins including under/overflow
10247/// Reallocate bin contents array
10248
10250{
10251 if (n < 0) n = fXaxis.GetNbins() + 2;
10252 fNcells = n;
10254}
10255
10256////////////////////////////////////////////////////////////////////////////////
10257/// Operator =
10258
10259TH1L& TH1L::operator=(const TH1L &h1)
10260{
10261 if (this != &h1)
10262 h1.TH1L::Copy(*this);
10263 return *this;
10264}
10265
10266
10267////////////////////////////////////////////////////////////////////////////////
10268/// Operator *
10269
10271{
10272 TH1L hnew = h1;
10273 hnew.Scale(c1);
10274 hnew.SetDirectory(nullptr);
10275 return hnew;
10276}
10277
10278////////////////////////////////////////////////////////////////////////////////
10279/// Operator +
10280
10281TH1L operator+(const TH1L &h1, const TH1L &h2)
10282{
10283 TH1L hnew = h1;
10284 hnew.Add(&h2,1);
10285 hnew.SetDirectory(nullptr);
10286 return hnew;
10287}
10288
10289////////////////////////////////////////////////////////////////////////////////
10290/// Operator -
10291
10292TH1L operator-(const TH1L &h1, const TH1L &h2)
10293{
10294 TH1L hnew = h1;
10295 hnew.Add(&h2,-1);
10296 hnew.SetDirectory(nullptr);
10297 return hnew;
10298}
10299
10300////////////////////////////////////////////////////////////////////////////////
10301/// Operator *
10302
10303TH1L operator*(const TH1L &h1, const TH1L &h2)
10304{
10305 TH1L hnew = h1;
10306 hnew.Multiply(&h2);
10307 hnew.SetDirectory(nullptr);
10308 return hnew;
10309}
10310
10311////////////////////////////////////////////////////////////////////////////////
10312/// Operator /
10313
10314TH1L operator/(const TH1L &h1, const TH1L &h2)
10315{
10316 TH1L hnew = h1;
10317 hnew.Divide(&h2);
10318 hnew.SetDirectory(nullptr);
10319 return hnew;
10320}
10321
10322//______________________________________________________________________________
10323// TH1F methods
10324// TH1F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216
10325//______________________________________________________________________________
10326
10327
10328////////////////////////////////////////////////////////////////////////////////
10329/// Constructor.
10330
10331TH1F::TH1F()
10332{
10333 fDimension = 1;
10334 SetBinsLength(3);
10335 if (fgDefaultSumw2) Sumw2();
10336}
10337
10338////////////////////////////////////////////////////////////////////////////////
10339/// Create a 1-Dim histogram with fix bins of type float
10340/// (see TH1::TH1 for explanation of parameters)
10341
10342TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10343: TH1(name,title,nbins,xlow,xup)
10344{
10345 fDimension = 1;
10347
10348 if (xlow >= xup) SetBuffer(fgBufferSize);
10349 if (fgDefaultSumw2) Sumw2();
10350}
10351
10352////////////////////////////////////////////////////////////////////////////////
10353/// Create a 1-Dim histogram with variable bins of type float
10354/// (see TH1::TH1 for explanation of parameters)
10355
10356TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10357: TH1(name,title,nbins,xbins)
10358{
10359 fDimension = 1;
10361 if (fgDefaultSumw2) Sumw2();
10362}
10363
10364////////////////////////////////////////////////////////////////////////////////
10365/// Create a 1-Dim histogram with variable bins of type float
10366/// (see TH1::TH1 for explanation of parameters)
10367
10368TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10369: TH1(name,title,nbins,xbins)
10370{
10371 fDimension = 1;
10373 if (fgDefaultSumw2) Sumw2();
10374}
10375
10376////////////////////////////////////////////////////////////////////////////////
10377/// Create a histogram from a TVectorF
10378/// by default the histogram name is "TVectorF" and title = ""
10379
10380TH1F::TH1F(const TVectorF &v)
10381: TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
10382{
10384 fDimension = 1;
10385 Int_t ivlow = v.GetLwb();
10386 for (Int_t i=0;i<fNcells-2;i++) {
10387 SetBinContent(i+1,v(i+ivlow));
10388 }
10390 if (fgDefaultSumw2) Sumw2();
10391}
10392
10393////////////////////////////////////////////////////////////////////////////////
10394/// Copy Constructor.
10395/// The list of functions is not copied. (Use Clone() if needed)
10396
10397TH1F::TH1F(const TH1F &h1f) : TH1(), TArrayF()
10398{
10399 h1f.TH1F::Copy(*this);
10400}
10401
10402////////////////////////////////////////////////////////////////////////////////
10403/// Destructor.
10404
10406{
10407}
10408
10409////////////////////////////////////////////////////////////////////////////////
10410/// Copy this to newth1.
10411
10412void TH1F::Copy(TObject &newth1) const
10413{
10415}
10416
10417////////////////////////////////////////////////////////////////////////////////
10418/// Reset.
10419
10421{
10424}
10425
10426////////////////////////////////////////////////////////////////////////////////
10427/// Set total number of bins including under/overflow
10428/// Reallocate bin contents array
10429
10431{
10432 if (n < 0) n = fXaxis.GetNbins() + 2;
10433 fNcells = n;
10434 TArrayF::Set(n);
10435}
10436
10437////////////////////////////////////////////////////////////////////////////////
10438/// Operator =
10439
10441{
10442 if (this != &h1f)
10443 h1f.TH1F::Copy(*this);
10444 return *this;
10445}
10446
10447////////////////////////////////////////////////////////////////////////////////
10448/// Operator *
10449
10451{
10452 TH1F hnew = h1;
10453 hnew.Scale(c1);
10454 hnew.SetDirectory(nullptr);
10455 return hnew;
10456}
10457
10458////////////////////////////////////////////////////////////////////////////////
10459/// Operator +
10460
10461TH1F operator+(const TH1F &h1, const TH1F &h2)
10462{
10463 TH1F hnew = h1;
10464 hnew.Add(&h2,1);
10465 hnew.SetDirectory(nullptr);
10466 return hnew;
10467}
10468
10469////////////////////////////////////////////////////////////////////////////////
10470/// Operator -
10471
10472TH1F operator-(const TH1F &h1, const TH1F &h2)
10473{
10474 TH1F hnew = h1;
10475 hnew.Add(&h2,-1);
10476 hnew.SetDirectory(nullptr);
10477 return hnew;
10478}
10479
10480////////////////////////////////////////////////////////////////////////////////
10481/// Operator *
10482
10483TH1F operator*(const TH1F &h1, const TH1F &h2)
10484{
10485 TH1F hnew = h1;
10486 hnew.Multiply(&h2);
10487 hnew.SetDirectory(nullptr);
10488 return hnew;
10489}
10490
10491////////////////////////////////////////////////////////////////////////////////
10492/// Operator /
10493
10494TH1F operator/(const TH1F &h1, const TH1F &h2)
10495{
10496 TH1F hnew = h1;
10497 hnew.Divide(&h2);
10498 hnew.SetDirectory(nullptr);
10499 return hnew;
10500}
10501
10502//______________________________________________________________________________
10503// TH1D methods
10504// TH1D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992
10505//______________________________________________________________________________
10506
10507
10508////////////////////////////////////////////////////////////////////////////////
10509/// Constructor.
10510
10511TH1D::TH1D()
10512{
10513 fDimension = 1;
10514 SetBinsLength(3);
10515 if (fgDefaultSumw2) Sumw2();
10516}
10517
10518////////////////////////////////////////////////////////////////////////////////
10519/// Create a 1-Dim histogram with fix bins of type double
10520/// (see TH1::TH1 for explanation of parameters)
10521
10522TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10523: TH1(name,title,nbins,xlow,xup)
10524{
10525 fDimension = 1;
10527
10528 if (xlow >= xup) SetBuffer(fgBufferSize);
10529 if (fgDefaultSumw2) Sumw2();
10530}
10531
10532////////////////////////////////////////////////////////////////////////////////
10533/// Create a 1-Dim histogram with variable bins of type double
10534/// (see TH1::TH1 for explanation of parameters)
10535
10536TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10537: TH1(name,title,nbins,xbins)
10538{
10539 fDimension = 1;
10541 if (fgDefaultSumw2) Sumw2();
10542}
10543
10544////////////////////////////////////////////////////////////////////////////////
10545/// Create a 1-Dim histogram with variable bins of type double
10546/// (see TH1::TH1 for explanation of parameters)
10547
10548TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10549: TH1(name,title,nbins,xbins)
10550{
10551 fDimension = 1;
10553 if (fgDefaultSumw2) Sumw2();
10554}
10555
10556////////////////////////////////////////////////////////////////////////////////
10557/// Create a histogram from a TVectorD
10558/// by default the histogram name is "TVectorD" and title = ""
10559
10560TH1D::TH1D(const TVectorD &v)
10561: TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
10562{
10564 fDimension = 1;
10565 Int_t ivlow = v.GetLwb();
10566 for (Int_t i=0;i<fNcells-2;i++) {
10567 SetBinContent(i+1,v(i+ivlow));
10568 }
10570 if (fgDefaultSumw2) Sumw2();
10571}
10572
10573////////////////////////////////////////////////////////////////////////////////
10574/// Destructor.
10575
10577{
10578}
10579
10580////////////////////////////////////////////////////////////////////////////////
10581/// Constructor.
10582
10583TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
10584{
10585 // intentially call virtual method to warn if TProfile is copying
10586 h1d.Copy(*this);
10587}
10588
10589////////////////////////////////////////////////////////////////////////////////
10590/// Copy this to newth1
10591
10592void TH1D::Copy(TObject &newth1) const
10593{
10595}
10596
10597////////////////////////////////////////////////////////////////////////////////
10598/// Reset.
10599
10601{
10604}
10605
10606////////////////////////////////////////////////////////////////////////////////
10607/// Set total number of bins including under/overflow
10608/// Reallocate bin contents array
10609
10611{
10612 if (n < 0) n = fXaxis.GetNbins() + 2;
10613 fNcells = n;
10614 TArrayD::Set(n);
10615}
10616
10617////////////////////////////////////////////////////////////////////////////////
10618/// Operator =
10619
10621{
10622 // intentially call virtual method to warn if TProfile is copying
10623 if (this != &h1d)
10624 h1d.Copy(*this);
10625 return *this;
10626}
10627
10628////////////////////////////////////////////////////////////////////////////////
10629/// Operator *
10630
10632{
10633 TH1D hnew = h1;
10634 hnew.Scale(c1);
10635 hnew.SetDirectory(nullptr);
10636 return hnew;
10637}
10638
10639////////////////////////////////////////////////////////////////////////////////
10640/// Operator +
10641
10642TH1D operator+(const TH1D &h1, const TH1D &h2)
10643{
10644 TH1D hnew = h1;
10645 hnew.Add(&h2,1);
10646 hnew.SetDirectory(nullptr);
10647 return hnew;
10648}
10649
10650////////////////////////////////////////////////////////////////////////////////
10651/// Operator -
10652
10653TH1D operator-(const TH1D &h1, const TH1D &h2)
10654{
10655 TH1D hnew = h1;
10656 hnew.Add(&h2,-1);
10657 hnew.SetDirectory(nullptr);
10658 return hnew;
10659}
10660
10661////////////////////////////////////////////////////////////////////////////////
10662/// Operator *
10663
10664TH1D operator*(const TH1D &h1, const TH1D &h2)
10665{
10666 TH1D hnew = h1;
10667 hnew.Multiply(&h2);
10668 hnew.SetDirectory(nullptr);
10669 return hnew;
10670}
10671
10672////////////////////////////////////////////////////////////////////////////////
10673/// Operator /
10674
10675TH1D operator/(const TH1D &h1, const TH1D &h2)
10676{
10677 TH1D hnew = h1;
10678 hnew.Divide(&h2);
10679 hnew.SetDirectory(nullptr);
10680 return hnew;
10681}
10682
10683////////////////////////////////////////////////////////////////////////////////
10684///return pointer to histogram with name
10685///hid if id >=0
10686///h_id if id <0
10687
10688TH1 *R__H(Int_t hid)
10689{
10690 TString hname;
10691 if(hid >= 0) hname.Form("h%d",hid);
10692 else hname.Form("h_%d",hid);
10693 return (TH1*)gDirectory->Get(hname);
10694}
10695
10696////////////////////////////////////////////////////////////////////////////////
10697///return pointer to histogram with name hname
10698
10699TH1 *R__H(const char * hname)
10700{
10701 return (TH1*)gDirectory->Get(hname);
10702}
10703
10704
10705/// \fn void TH1::SetBarOffset(Float_t offset)
10706/// Set the bar offset as fraction of the bin width for drawing mode "B".
10707/// This shifts bars to the right on the x axis, and helps to draw bars next to each other.
10708/// \see THistPainter, SetBarWidth()
10709
10710/// \fn void TH1::SetBarWidth(Float_t width)
10711/// Set the width of bars as fraction of the bin width for drawing mode "B".
10712/// This allows for making bars narrower than the bin width. With SetBarOffset(), this helps to draw multiple bars next to each other.
10713/// \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
Style number (short)
Definition RtypesCore.h:96
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Color_t
Color number (short)
Definition RtypesCore.h:99
short Version_t
Class version identifier (short)
Definition RtypesCore.h:79
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
short Short_t
Signed Short integer 2 bytes (short)
Definition RtypesCore.h:53
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:385
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:145
static bool IsEquidistantBinning(const TAxis &axis)
Test if the binning is equidistant.
Definition TH1.cxx:5958
void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
Least square linear fit without weights.
Definition TH1.cxx:4904
void H1InitGaus()
Compute Initial values of parameters for a gaussian.
Definition TH1.cxx:4739
void H1InitExpo()
Compute Initial values of parameters for an exponential.
Definition TH1.cxx:4795
TH1C operator+(const TH1C &h1, const TH1C &h2)
Operator +.
Definition TH1.cxx:9720
TH1C operator-(const TH1C &h1, const TH1C &h2)
Operator -.
Definition TH1.cxx:9731
TH1C operator/(const TH1C &h1, const TH1C &h2)
Operator /.
Definition TH1.cxx:9753
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:4950
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:5941
static Bool_t AlmostInteger(Double_t a, Double_t epsilon=0.00000001)
Test if a double is almost an integer.
Definition TH1.cxx:5949
TF1 * gF1
Definition TH1.cxx:604
TH1 * R__H(Int_t hid)
return pointer to histogram with name hid if id >=0 h_id if id <0
Definition TH1.cxx:10686
TH1C operator*(Double_t c1, const TH1C &h1)
Operator *.
Definition TH1.cxx:9709
void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
Least squares lpolynomial fitting without weights.
Definition TH1.cxx:4845
void H1InitPolynom()
Compute Initial values of parameters for a polynom.
Definition TH1.cxx:4815
float xmin
int nentries
float ymin
float xmax
float ymax
#define gInterpreter
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:783
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:426
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:2509
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
#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
const_iterator begin() const
const_iterator end() const
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:104
Array of doubles (64 bits per element).
Definition TArrayD.h:27
Double_t * fArray
Definition TArrayD.h:30
void Streamer(TBuffer &) override
Stream a TArrayD object.
Definition TArrayD.cxx:148
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:105
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:104
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:104
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:104
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
virtual Color_t GetTitleColor() const
Definition TAttAxis.h:47
virtual Color_t GetLabelColor() const
Definition TAttAxis.h:39
virtual Int_t GetNdivisions() const
Definition TAttAxis.h:37
virtual Color_t GetAxisColor() const
Definition TAttAxis.h:38
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition TAttAxis.cxx:279
virtual Style_t GetTitleFont() const
Definition TAttAxis.h:48
virtual Float_t GetLabelOffset() const
Definition TAttAxis.h:41
virtual void SetAxisColor(Color_t color=1, Float_t alpha=1.)
Set color of the line axis and tick marks.
Definition TAttAxis.cxx:141
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
Definition TAttAxis.cxx:184
virtual Style_t GetLabelFont() const
Definition TAttAxis.h:40
virtual void SetTitleFont(Style_t font=62)
Set the title font.
Definition TAttAxis.cxx:308
virtual void SetLabelOffset(Float_t offset=0.005)
Set distance between the axis and the labels.
Definition TAttAxis.cxx:172
virtual void SetLabelFont(Style_t font=62)
Set labels' font.
Definition TAttAxis.cxx:161
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title.
Definition TAttAxis.cxx:290
virtual void SetTitleColor(Color_t color=1)
Set color of axis title.
Definition TAttAxis.cxx:299
virtual Float_t GetTitleSize() const
Definition TAttAxis.h:45
virtual Float_t GetLabelSize() const
Definition TAttAxis.h:42
virtual Float_t GetTickLength() const
Definition TAttAxis.h:46
virtual void ResetAttAxis(Option_t *option="")
Reset axis attributes.
Definition TAttAxis.cxx:78
virtual Float_t GetTitleOffset() const
Definition TAttAxis.h:44
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length.
Definition TAttAxis.cxx:265
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition TAttAxis.cxx:214
virtual void SetLabelColor(Color_t color=1, Float_t alpha=1.)
Set color of labels.
Definition TAttAxis.cxx:151
virtual void Streamer(TBuffer &)
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:32
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition TAttFill.cxx:203
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:33
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:240
virtual void Streamer(TBuffer &)
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:36
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:46
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:38
virtual Style_t GetLineStyle() const
Return the line style.
Definition TAttLine.h:37
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition TAttLine.cxx:176
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:289
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:34
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition TAttMarker.h:41
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:33
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition TAttMarker.h:35
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition TAttMarker.h:43
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:48
Class to manage histogram axis.
Definition TAxis.h:32
virtual void GetCenter(Double_t *center) const
Return an array with the center of all bins.
Definition TAxis.cxx:558
virtual Bool_t GetTimeDisplay() const
Definition TAxis.h:133
Bool_t IsAlphanumeric() const
Definition TAxis.h:90
const char * GetTitle() const override
Returns title of object.
Definition TAxis.h:137
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:482
Bool_t CanExtend() const
Definition TAxis.h:88
virtual void SetParent(TObject *obj)
Definition TAxis.h:169
const TArrayD * GetXbins() const
Definition TAxis.h:138
void SetCanExtend(Bool_t canExtend)
Definition TAxis.h:92
void Copy(TObject &axis) const override
Copy axis structure to another axis.
Definition TAxis.cxx:211
Double_t GetXmax() const
Definition TAxis.h:142
@ kLabelsUp
Definition TAxis.h:75
@ kLabelsDown
Definition TAxis.h:74
@ kLabelsHori
Definition TAxis.h:72
@ kAxisRange
Definition TAxis.h:66
@ kLabelsVert
Definition TAxis.h:73
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:522
virtual void SetTimeDisplay(Int_t value)
Definition TAxis.h:173
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Definition TAxis.cxx:790
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x
Definition TAxis.cxx:422
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:715
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:473
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition TAxis.h:166
Double_t GetXmin() const
Definition TAxis.h:141
void Streamer(TBuffer &) override
Stream an object of class TAxis.
Definition TAxis.cxx:1224
Int_t GetNbins() const
Definition TAxis.h:127
virtual void GetLowEdge(Double_t *edge) const
Return an array with the low edge of all bins.
Definition TAxis.cxx:567
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis using bin numbers.
Definition TAxis.cxx:1061
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:546
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:532
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:462
THashList * GetLabels() const
Definition TAxis.h:123
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:5048
ROOT::NewFunc_t GetNew() const
Return the wrapper around new ThisClass().
Definition TClass.cxx:7612
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.
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.
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
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:503
1-Dim function class
Definition TF1.h:182
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:3723
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function Note that this histogram is managed ...
Definition TF1.cxx:1634
static TClass * Class()
virtual Int_t GetNpar() const
Definition TF1.h:446
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
IntegralOneDim or analytical integral.
Definition TF1.cxx:2580
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition TF1.cxx:2530
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2329
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=nullptr)
Evaluate function with given coordinates and parameters.
Definition TF1.cxx:1498
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set lower and upper limits for parameter ipar.
Definition TF1.cxx:3562
static Bool_t RejectedPoint()
See TF1::RejectPoint above.
Definition TF1.cxx:3732
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:1446
virtual void SetParameter(Int_t param, Double_t value)
Definition TF1.h:608
virtual Bool_t IsInside(const Double_t *x) const
return kTRUE if the point is inside the function range
Definition TF1.h:567
A 2-Dim function with parameters.
Definition TF2.h:29
TF3 defines a 3D 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:714
~TH1C() override
Destructor.
Definition TH1.cxx:9633
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9689
TH1C & operator=(const TH1C &h1)
Operator =.
Definition TH1.cxx:9699
TH1C()
Constructor.
Definition TH1.cxx:9585
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9671
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9650
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:9679
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:926
~TH1D() override
Destructor.
Definition TH1.cxx:10574
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10608
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10590
TH1D()
Constructor.
Definition TH1.cxx:10509
TH1D & operator=(const TH1D &h1)
Operator =.
Definition TH1.cxx:10618
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:878
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:912
TH1F & operator=(const TH1F &h1)
Operator =.
Definition TH1.cxx:10438
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10410
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10428
~TH1F() override
Destructor.
Definition TH1.cxx:10403
TH1F()
Constructor.
Definition TH1.cxx:10329
1-D histogram with an int per channel (see TH1 documentation)
Definition TH1.h:796
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10060
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:10021
~TH1I() override
Destructor.
Definition TH1.cxx:10004
TH1I()
Constructor.
Definition TH1.cxx:9956
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10042
TH1I & operator=(const TH1I &h1)
Operator =.
Definition TH1.cxx:10070
1-D histogram with a long64 per channel (see TH1 documentation)
Definition TH1.h:837
TH1L & operator=(const TH1L &h1)
Operator =.
Definition TH1.cxx:10257
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:10208
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10247
~TH1L() override
Destructor.
Definition TH1.cxx:10191
TH1L()
Constructor.
Definition TH1.cxx:10143
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10229
1-D histogram with a short per channel (see TH1 documentation)
Definition TH1.h:755
TH1S & operator=(const TH1S &h1)
Operator =.
Definition TH1.cxx:9884
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9856
TH1S()
Constructor.
Definition TH1.cxx:9770
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9874
~TH1S() override
Destructor.
Definition TH1.cxx:9818
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9835
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
~TH1() override
Histogram default destructor.
Definition TH1.cxx:650
virtual void SetError(const Double_t *error)
Replace bin errors by values in array error.
Definition TH1.cxx:9086
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:9072
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition TH1.cxx:4338
Double_t * fBuffer
[fBufferSize] entry buffer
Definition TH1.h:169
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:1358
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition TH1.cxx:4501
char * GetObjectInfo(Int_t px, Int_t py) const override
Redefines TObject::GetObjectInfo.
Definition TH1.cxx:4555
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition TH1.cxx:7002
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:9273
virtual void Rebuild(Option_t *option="")
Using the current bin info, recompute the arrays for contents and errors.
Definition TH1.cxx:7210
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:612
static Bool_t fgStatOverflows
! Flag to use under/overflows in statistics
Definition TH1.h:178
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:3850
TAxis * GetZaxis()
Definition TH1.h:573
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a line.
Definition TH1.cxx:2854
virtual Bool_t Multiply(TF1 *f1, Double_t c1=1)
Performs the operation:
Definition TH1.cxx:6129
Int_t fNcells
Number of bins(1D), cells (2D) +U/Overflows.
Definition TH1.h:150
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:7944
virtual void Normalize(Option_t *option="")
Normalize a histogram to its integral or to its maximum.
Definition TH1.cxx:6291
void Copy(TObject &hnew) const override
Copy this histogram structure to newth1.
Definition TH1.cxx:2703
void SetTitle(const char *title) override
Change/set the title.
Definition TH1.cxx:6834
Double_t fTsumw
Total Sum of weights.
Definition TH1.h:157
virtual Float_t GetBarWidth() const
Definition TH1.h:501
Double_t fTsumw2
Total Sum of squares of weights.
Definition TH1.h:158
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:7048
virtual Float_t GetBarOffset() const
Definition TH1.h:500
Double_t GetSumOfAllWeights(const bool includeOverflow, Double_t *sumWeightSquare=nullptr) const
Return the sum of all weights and optionally also the sum of weight squares.
Definition TH1.cxx:8037
TList * fFunctions
->Pointer to list of functions (fits and user)
Definition TH1.h:167
static Bool_t fgAddDirectory
! Flag to add histograms to the directory
Definition TH1.h:177
@ kNstat
Size of statistics data (up to TProfile3D)
Definition TH1.h:422
static TClass * Class()
static Int_t GetDefaultBufferSize()
Static function return the default buffer size for automatic histograms the parameter fgBufferSize ma...
Definition TH1.cxx:4459
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:8108
Double_t fTsumwx2
Total Sum of weight*X*X.
Definition TH1.h:160
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition TH1.cxx:7718
TH1()
Histogram default constructor.
Definition TH1.cxx:622
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:9451
void UseCurrentStyle() override
Copy current attributes from/to current style.
Definition TH1.cxx:7580
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:5462
virtual Int_t GetNbinsY() const
Definition TH1.h:542
Short_t fBarOffset
(1000*offset) for bar charts or legos
Definition TH1.h:154
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:2084
static bool CheckBinLimits(const TAxis *a1, const TAxis *a2)
Check bin limits.
Definition TH1.cxx:1556
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:9195
static Int_t FitOptionsMake(Option_t *option, Foption_t &Foption)
Decode string choptin and fill fitOption structure.
Definition TH1.cxx:4730
virtual Int_t GetNbinsZ() const
Definition TH1.h:543
virtual Double_t GetNormFactor() const
Definition TH1.h:545
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:7646
virtual Double_t GetSkewness(Int_t axis=1) const
Definition TH1.cxx:7782
virtual void ClearUnderflowAndOverflow()
Remove all the content from the underflow and overflow bins, without changing the number of entries A...
Definition TH1.cxx:2538
virtual void FillRandom(TF1 *f1, Int_t ntimes=5000, TRandom *rng=nullptr)
Definition TH1.cxx:3575
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition TH1.cxx:8571
virtual TH1 * DrawNormalized(Option_t *option="", Double_t norm=1) const
Draw a normalized copy of this histogram.
Definition TH1.cxx:3191
@ kNeutral
Adapt to the global flag.
Definition TH1.h:133
virtual Int_t GetDimension() const
Definition TH1.h:527
void Streamer(TBuffer &) override
Stream a class object.
Definition TH1.cxx:7056
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1309
@ kIsAverage
Bin contents are average (used by Add)
Definition TH1.h:409
@ kUserContour
User specified contour levels.
Definition TH1.h:404
@ kNoStats
Don't draw stats box.
Definition TH1.h:403
@ kAutoBinPTwo
different than 1.
Definition TH1.h:412
@ kIsNotW
Histogram is forced to be not weighted even when the histogram is filled with weighted.
Definition TH1.h:410
@ kIsHighlight
bit set if histo is highlight
Definition TH1.h:413
virtual void SetContourLevel(Int_t level, Double_t value)
Set value for one contour level.
Definition TH1.cxx:8657
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition TH1.cxx:6749
TDirectory * fDirectory
! Pointer to directory holding this histogram
Definition TH1.h:170
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition TH1.cxx:7226
void SetNameTitle(const char *name, const char *title) override
Change the name and title of this histogram.
Definition TH1.cxx:9109
TAxis * GetXaxis()
Definition TH1.h:571
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:5052
TH1 * GetCumulative(Bool_t forward=kTRUE, const char *suffix="_cumulative") const
Return a pointer to a histogram containing the cumulative content.
Definition TH1.cxx:2648
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:1323
virtual Int_t GetNcells() const
Definition TH1.h:544
virtual Int_t ShowPeaks(Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
Interface to TSpectrum::Search.
Definition TH1.cxx:9433
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition TH1.cxx:5988
virtual Double_t GetSumOfWeights() const
Return the sum of weights across all bins excluding under/overflows.
Definition TH1.h:559
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition TH1.cxx:7995
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition TH1.cxx:4564
TObject * FindObject(const char *name) const override
Search object named name in the list of functions.
Definition TH1.cxx:3910
void Print(Option_t *option="") const override
Print some global quantities for this histogram.
Definition TH1.cxx:7132
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
Definition TH1.cxx:4468
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:3787
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:3952
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:5039
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:8680
virtual Int_t GetNbinsX() const
Definition TH1.h:541
virtual void SetMaximum(Double_t maximum=-1111)
Definition TH1.h:652
virtual TH1 * FFT(TH1 *h_output, Option_t *option)
This function allows to do discrete Fourier transforms of TH1 and TH2.
Definition TH1.cxx:3331
virtual void LabelsInflate(Option_t *axis="X")
Double the number of bins for axis.
Definition TH1.cxx:5395
virtual TH1 * ShowBackground(Int_t niter=20, Option_t *option="same")
This function calculates the background spectrum in this histogram.
Definition TH1.cxx:9419
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
Definition TH1.cxx:5978
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:836
Double_t fMaximum
Maximum value for plotting.
Definition TH1.h:161
Int_t fBufferSize
fBuffer size
Definition TH1.h:168
TString ProvideSaveName(Option_t *option, Bool_t testfdir=kFALSE)
Provide variable name for histogram for saving as primitive Histogram pointer has by default the hist...
Definition TH1.cxx:7365
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:8099
Int_t fDimension
! Histogram dimension (1, 2 or 3 dim)
Definition TH1.h:171
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:9338
EBinErrorOpt fBinStatErrOpt
Option for bin statistical errors.
Definition TH1.h:174
static Int_t fgBufferSize
! Default buffer size for automatic histograms
Definition TH1.h:176
virtual void SetBinsLength(Int_t=-1)
Definition TH1.h:628
Double_t fNormFactor
Normalization factor.
Definition TH1.h:163
@ kFullyConsistent
Definition TH1.h:139
@ kDifferentNumberOfBins
Definition TH1.h:143
@ kDifferentDimensions
Definition TH1.h:144
@ kDifferentBinLimits
Definition TH1.h:141
@ kDifferentAxisLimits
Definition TH1.h:142
@ kDifferentLabels
Definition TH1.h:140
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3391
TAxis * GetYaxis()
Definition TH1.h:572
TArrayD fContour
Array to display contour levels.
Definition TH1.h:164
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition TH1.cxx:9211
void Browse(TBrowser *b) override
Browse the Histogram object.
Definition TH1.cxx:772
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition TH1.cxx:8529
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx:3095
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:7492
Short_t fBarWidth
(1000*width) for bar charts or legos
Definition TH1.h:155
virtual Double_t GetBinErrorSqUnchecked(Int_t bin) const
Definition TH1.h:705
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:653
Bool_t IsBinUnderflow(Int_t bin, Int_t axis=0) const
Return true if the bin is underflow.
Definition TH1.cxx:5294
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TH1.cxx:7387
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check that axis have same labels.
Definition TH1.cxx:1583
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:5195
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:6816
virtual void SetBuffer(Int_t bufsize, Option_t *option="")
Set the maximum number of entries to be kept in the buffer.
Definition TH1.cxx:8589
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition TH1.cxx:5262
UInt_t GetAxisLabelStatus() const
Internal function used in TH1::Fill to see which axis is full alphanumeric, i.e.
Definition TH1.cxx:6788
Double_t * fIntegral
! Integral of bins used by GetRandom
Definition TH1.h:172
Double_t fMinimum
Minimum value for plotting.
Definition TH1.h:162
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition TH1.cxx:8072
static void SetDefaultBufferSize(Int_t bufsize=1000)
Static function to set the default buffer size for automatic histograms.
Definition TH1.cxx:6806
@ kXaxis
Definition TH1.h:123
@ kNoAxis
NOTE: Must always be 0 !!!
Definition TH1.h:122
@ kZaxis
Definition TH1.h:125
@ kYaxis
Definition TH1.h:124
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:9354
virtual void DirectoryAutoAdd(TDirectory *)
Callback to perform the automatic addition of the histogram to the given directory.
Definition TH1.cxx:2832
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:9319
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:9284
void Build()
Creates histogram basic data structure.
Definition TH1.cxx:781
virtual Double_t GetEntries() const
Return the current number of entries.
Definition TH1.cxx:4476
virtual Double_t RetrieveBinContent(Int_t bin) const =0
Raw retrieval of bin content on internal data structure see convention for numbering bins in TH1::Get...
virtual TF1 * GetFunction(const char *name) const
Return pointer to function with name.
Definition TH1.cxx:9183
virtual TH1 * Rebin(Int_t ngroup=2, const char *newname="", const Double_t *xbins=nullptr)
Rebin this histogram.
Definition TH1.cxx:6388
virtual Int_t BufferFill(Double_t x, Double_t w)
accumulate arguments in buffer.
Definition TH1.cxx:1521
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:5166
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:6762
TList * GetListOfFunctions() const
Definition TH1.h:488
void SetName(const char *name) override
Change the name of this histogram.
Definition TH1.cxx:9095
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition TH1.cxx:3160
virtual Double_t GetRandom(TRandom *rng=nullptr, Option_t *option="") const
Return a random number distributed according the histogram bin contents.
Definition TH1.cxx:5089
Bool_t IsEmpty() const
Check if a histogram is empty (this is a protected method used mainly by TH1Merger )
Definition TH1.cxx:5244
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition TH1.cxx:7686
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6319
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:8193
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculated from bin cont...
Definition TH1.cxx:8013
virtual void SetBinErrorOption(EBinErrorOpt type)
Definition TH1.h:629
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Definition TH1.cxx:3222
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:2517
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:2025
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:3520
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition TH1.cxx:8866
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition TH1.cxx:8712
static Int_t AutoP2GetBins(Int_t n)
Auxiliary function to get the next power of 2 integer value larger then n.
Definition TH1.cxx:1336
Double_t fEntries
Number of entries.
Definition TH1.h:156
virtual Long64_t Merge(TCollection *list)
Definition TH1.h:592
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:4520
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TH1.cxx:3287
virtual Double_t * GetIntegral()
Return a pointer to the array of bins integral.
Definition TH1.cxx:2618
TAxis fZaxis
Z axis descriptor.
Definition TH1.h:153
EStatOverflows fStatOverflows
Per object flag to use under/overflows in statistics.
Definition TH1.h:175
TClass * IsA() const override
Definition TH1.h:693
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:3494
static bool CheckEqualAxes(const TAxis *a1, const TAxis *a2)
Check that the axis are the same.
Definition TH1.cxx:1626
@ kPoisson2
Errors from Poisson interval at 95% CL (~ 2 sigma)
Definition TH1.h:117
@ kNormal
Errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition TH1.h:115
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5141
virtual Int_t GetContour(Double_t *levels=nullptr)
Return contour values into array levels if pointer levels is non zero.
Definition TH1.cxx:8542
TAxis fXaxis
X axis descriptor.
Definition TH1.h:151
virtual Bool_t IsHighlight() const
Definition TH1.h:585
virtual void ExtendAxis(Double_t x, TAxis *axis)
Histogram is resized along axis such that x is in the axis range.
Definition TH1.cxx:6617
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:9295
TArrayD fSumw2
Array of sum of squares of weights.
Definition TH1.h:165
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:4393
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition TH1.cxx:8561
virtual void SetContour(Int_t nlevels, const Double_t *levels=nullptr)
Set the number and values of contour levels.
Definition TH1.cxx:8618
virtual void SetHighlight(Bool_t set=kTRUE)
Set highlight (enable/disable) mode for the histogram by default highlight mode is disable.
Definition TH1.cxx:4535
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition TH1.cxx:9242
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition TH1.cxx:6717
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition TH1.cxx:8800
virtual Double_t ComputeIntegral(Bool_t onlyPositive=false, Option_t *option="")
Compute integral (normalized cumulative sum of bins) w/o under/overflows The result is stored in fInt...
Definition TH1.cxx:2563
virtual Int_t GetSumw2N() const
Definition TH1.h:562
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:3725
Bool_t GetStatOverflowsBehaviour() const
Definition TH1.h:391
void SaveAs(const char *filename="hist", Option_t *option="") const override
Save the histogram as .csv, .tsv or .txt.
Definition TH1.cxx:7304
virtual Int_t GetQuantiles(Int_t n, Double_t *xp, const Double_t *p=nullptr)
Compute Quantiles for this histogram.
Definition TH1.cxx:4668
virtual void AddBinContent(Int_t bin)=0
Increment bin content by 1.
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx:2784
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition TH1.cxx:7766
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:2871
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:8770
int LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge=false) const
Definition TH1.cxx:893
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:1655
static Int_t CheckConsistency(const TH1 *h1, const TH1 *h2)
Check histogram compatibility.
Definition TH1.cxx:1694
void RecursiveRemove(TObject *obj) override
Recursively remove object from the list of functions.
Definition TH1.cxx:6689
TAxis fYaxis
Y axis descriptor.
Definition TH1.h:152
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:8309
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:6891
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:9306
TVirtualHistPainter * fPainter
! Pointer to histogram painter
Definition TH1.h:173
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition TH1.cxx:8902
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:3758
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:9155
virtual void SetEntries(Double_t n)
Definition TH1.h:639
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:6573
static bool CheckAxisLimits(const TAxis *a1, const TAxis *a2)
Check that the axis limits of the histograms are the same.
Definition TH1.cxx:1612
static Bool_t AddDirectoryStatus()
Check whether TH1-derived classes should register themselves to the current gDirectory.
Definition TH1.cxx:764
static Bool_t fgDefaultSumw2
! Flag to call TH1::Sumw2 automatically at histogram creation time
Definition TH1.h:179
static void SavePrimitiveFunctions(std::ostream &out, const char *varname, TList *lst)
Save list of functions Also can be used by TGraph classes.
Definition TH1.cxx:7546
virtual void UpdateBinContent(Int_t bin, Double_t content)=0
Raw update of bin content on internal data structure see convention for numbering bins in TH1::GetBin...
Double_t fTsumwx
Total Sum of weight*X.
Definition TH1.h:159
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:5325
TString fOption
Histogram options.
Definition TH1.h:166
virtual void Eval(TF1 *f1, Option_t *option="")
Evaluate function f1 at the center of bins of this histogram.
Definition TH1.cxx:3239
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:613
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition TH1.cxx:1429
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition TH1.cxx:9125
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition TH1.cxx:7855
2-D histogram with a double per channel (see TH1 documentation)
Definition TH2.h:400
static THLimitsFinder * GetLimitsFinder()
Return pointer to the current finder.
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:1323
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:708
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition TList.cxx:894
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:952
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:789
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:600
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:487
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:93
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:173
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
void Streamer(TBuffer &) override
Stream an object of class TObject.
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
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:149
Mother of all ROOT objects.
Definition TObject.h:42
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:459
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:477
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:224
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition TObject.cxx:906
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1081
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:201
virtual void SaveAs(const char *filename="", Option_t *option="") const
Save this object in the file specified by filename.
Definition TObject.cxx:705
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:885
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:546
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1095
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:896
static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option=nullptr)
Save invocation of primitive Draw() method Skipped if option contains "nodraw" string.
Definition TObject.cxx:842
static TString SavePrimitiveVector(std::ostream &out, const char *prefix, Int_t len, Double_t *arr, Int_t flag=0)
Save array in the output stream "out" as vector.
Definition TObject.cxx:793
void ResetBit(UInt_t f)
Definition TObject.h:203
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:71
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:81
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:73
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1069
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:558
virtual Double_t PoissonD(Double_t mean)
Generates a random number according to a Poisson law.
Definition TRandom.cxx:460
virtual ULong64_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition TRandom.cxx:403
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
void ToLower()
Change string to lower-case.
Definition TString.cxx:1189
TString & ReplaceSpecialCppChars()
Find special characters which are typically used in printf() calls and replace them by appropriate es...
Definition TString.cxx:1121
const char * Data() const
Definition TString.h:384
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:713
@ kIgnoreCase
Definition TString.h:285
void ToUpper()
Change string to upper case.
Definition TString.cxx:1202
Bool_t IsNull() const
Definition TString.h:422
virtual void Streamer(TBuffer &)
Stream a string object.
Definition TString.cxx:1418
TString & Append(const char *cs)
Definition TString.h:581
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:2384
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:641
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:660
Int_t GetOptStat() const
Definition TStyle.h:247
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:1641
void SetHistFillColor(Color_t color=1)
Definition TStyle.h:383
Color_t GetHistLineColor() const
Definition TStyle.h:235
Bool_t IsReading() const
Definition TStyle.h:300
Float_t GetBarOffset() const
Definition TStyle.h:184
void SetHistLineStyle(Style_t styl=0)
Definition TStyle.h:386
Style_t GetHistFillStyle() const
Definition TStyle.h:236
Color_t GetHistFillColor() const
Definition TStyle.h:234
Float_t GetBarWidth() const
Definition TStyle.h:185
Bool_t GetCanvasPreferGL() const
Definition TStyle.h:189
void SetHistLineColor(Color_t color=1)
Definition TStyle.h:384
void SetBarOffset(Float_t baroff=0.5)
Definition TStyle.h:339
Style_t GetHistLineStyle() const
Definition TStyle.h:237
void SetBarWidth(Float_t barwidth=0.5)
Definition TStyle.h:340
void SetHistFillStyle(Style_t styl=0)
Definition TStyle.h:385
Width_t GetHistLineWidth() const
Definition TStyle.h:238
Int_t GetOptFit() const
Definition TStyle.h:246
void SetHistLineWidth(Width_t width=1)
Definition TStyle.h:387
TVectorT.
Definition TVectorT.h:29
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.
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.
Abstract Base Class for Fitting.
static TVirtualFitter * GetFitter()
static: return the current Fitter
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.
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:409
bool ObjectAutoRegistrationEnabled()
Test whether objects in this thread auto-register themselves, e.g.
Definition TROOT.cxx:768
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:977
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:903
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:704
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
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:1359
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Definition TMath.h:913
Double_t Floor(Double_t x)
Rounds x downward, returning the largest integral value that is not greater than x.
Definition TMath.h:691
Double_t ATan(Double_t)
Returns the principal value of the arc tangent of x, expressed in radians.
Definition TMath.h:651
Double_t Ceil(Double_t x)
Rounds x upward, returning the smallest integral value that is not less than x.
Definition TMath.h:679
T MinElement(Long64_t n, const T *a)
Returns minimum of array a of length n.
Definition TMath.h:971
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:767
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
constexpr Double_t Pi()
Definition TMath.h:40
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Comparing floating points.
Definition TMath.h:429
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Comparing floating points.
Definition TMath.h:421
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:413
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:329
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:773
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
Definition TMath.h:928
th1 Draw()
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2338