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 // ROOT's Python bindings use TCollection::IsOwner to decide whether objects
627 // inserted into a collection (like `TH1::fFunctions`) should be deleted
628 // (see `_TCollection_Add` pythonization). To ensure the Python bindings
629 // get the correct ownership signal, set the ownership on TH1::fFunctions.
630 // Although, in reality, TH1's destructor actually handles ownership, this
631 // solution still works, since the destructor removes all entries before
632 // deleting the collection.
633 fFunctions->SetOwner(true);
634 fNcells = 0;
635 fIntegral = nullptr;
636 fPainter = nullptr;
637 fEntries = 0;
638 fNormFactor = 0;
640 fMaximum = -1111;
641 fMinimum = -1111;
642 fBufferSize = 0;
643 fBuffer = nullptr;
646 fXaxis.SetName("xaxis");
647 fYaxis.SetName("yaxis");
648 fZaxis.SetName("zaxis");
649 fXaxis.SetParent(this);
650 fYaxis.SetParent(this);
651 fZaxis.SetParent(this);
653}
654
655////////////////////////////////////////////////////////////////////////////////
656/// Histogram default destructor.
657
659{
661 return;
662 }
663 delete[] fIntegral;
664 fIntegral = nullptr;
665 delete[] fBuffer;
666 fBuffer = nullptr;
667 if (fFunctions) {
669
671 TObject* obj = nullptr;
672 //special logic to support the case where the same object is
673 //added multiple times in fFunctions.
674 //This case happens when the same object is added with different
675 //drawing modes
676 //In the loop below we must be careful with objects (eg TCutG) that may
677 // have been added to the list of functions of several histograms
678 //and may have been already deleted.
679 while ((obj = fFunctions->First())) {
680 while(fFunctions->Remove(obj)) { }
682 break;
683 }
684 delete obj;
685 obj = nullptr;
686 }
687 delete fFunctions;
688 fFunctions = nullptr;
689 }
690 if (fDirectory) {
691 fDirectory->Remove(this);
692 fDirectory = nullptr;
693 }
694 delete fPainter;
695 fPainter = nullptr;
696}
697
698////////////////////////////////////////////////////////////////////////////////
699/// Constructor for fix bin size histograms.
700/// Creates the main histogram structure.
701///
702/// \param[in] name name of histogram (avoid blanks)
703/// \param[in] title histogram title.
704/// If title is of the form `stringt;stringx;stringy;stringz`,
705/// the histogram title is set to `stringt`,
706/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
707/// \param[in] nbins number of bins
708/// \param[in] xlow low edge of first bin
709/// \param[in] xup upper edge of last bin (not included in last bin)
710/// \note if xup <= xlow, automatic bins are calculated when buffer size is reached
711
712TH1::TH1(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
713 :TNamed(name,title)
714{
715 Build();
716 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
717 fXaxis.Set(nbins,xlow,xup);
718 fNcells = fXaxis.GetNbins()+2;
719}
720
721////////////////////////////////////////////////////////////////////////////////
722/// Constructor for variable bin size histograms using an input array of type float.
723/// Creates the main histogram structure.
724///
725/// \param[in] name name of histogram (avoid blanks)
726/// \param[in] title histogram title.
727/// If title is of the form `stringt;stringx;stringy;stringz`
728/// the histogram title is set to `stringt`,
729/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
730/// \param[in] nbins number of bins
731/// \param[in] xbins array of low-edges for each bin.
732/// This is an array of type float and size nbins+1
733
734TH1::TH1(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
735 :TNamed(name,title)
736{
737 Build();
738 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
739 if (xbins) fXaxis.Set(nbins,xbins);
740 else fXaxis.Set(nbins,0,1);
741 fNcells = fXaxis.GetNbins()+2;
742}
743
744////////////////////////////////////////////////////////////////////////////////
745/// Constructor for variable bin size histograms using an input array of type double.
746///
747/// \param[in] name name of histogram (avoid blanks)
748/// \param[in] title histogram title.
749/// If title is of the form `stringt;stringx;stringy;stringz`
750/// the histogram title is set to `stringt`,
751/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
752/// \param[in] nbins number of bins
753/// \param[in] xbins array of low-edges for each bin.
754/// This is an array of type double and size nbins+1
755
756TH1::TH1(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
757 :TNamed(name,title)
758{
759 Build();
760 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
761 if (xbins) fXaxis.Set(nbins,xbins);
762 else fXaxis.Set(nbins,0,1);
763 fNcells = fXaxis.GetNbins()+2;
764}
765
766////////////////////////////////////////////////////////////////////////////////
767/// Check whether TH1-derived classes should register themselves to the current gDirectory.
768/// \note Even if this returns true, the state of
769/// ROOT::Experimental::ObjectAutoRegistrationEnabled() might prevent the registration of
770/// histograms, since it has higher precedence.
771
776
777////////////////////////////////////////////////////////////////////////////////
778/// Browse the Histogram object.
779
781{
782 Draw(b ? b->GetDrawOption() : "");
783 gPad->Update();
784}
785
786////////////////////////////////////////////////////////////////////////////////
787/// Creates histogram basic data structure.
788
790{
791 fDirectory = nullptr;
792 fPainter = nullptr;
793 fIntegral = nullptr;
794 fEntries = 0;
795 fNormFactor = 0;
797 fMaximum = -1111;
798 fMinimum = -1111;
799 fBufferSize = 0;
800 fBuffer = nullptr;
803 fXaxis.SetName("xaxis");
804 fYaxis.SetName("yaxis");
805 fZaxis.SetName("zaxis");
806 fYaxis.Set(1,0.,1.);
807 fZaxis.Set(1,0.,1.);
808 fXaxis.SetParent(this);
809 fYaxis.SetParent(this);
810 fZaxis.SetParent(this);
811
813
814 fFunctions = new TList;
815 // ROOT's Python bindings use TCollection::IsOwner to decide whether objects
816 // inserted into a collection (like `TH1::fFunctions`) should be deleted
817 // (see `_TCollection_Add` pythonization). To ensure the Python bindings
818 // get the correct ownership signal, set the ownership on TH1::fFunctions.
819 // Although, in reality, TH1's destructor actually handles ownership, this
820 // solution still works, since the destructor removes all entries before
821 // deleting the collection.
822 fFunctions->SetOwner(true);
823
825
828 if (fDirectory) {
830 fDirectory->Append(this,kTRUE);
831 }
832 }
833}
834
835////////////////////////////////////////////////////////////////////////////////
836/// Performs the operation: `this = this + c1*f1`
837/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
838///
839/// By default, the function is computed at the centre of the bin.
840/// if option "I" is specified (1-d histogram only), the integral of the
841/// function in each bin is used instead of the value of the function at
842/// the centre of the bin.
843///
844/// Only bins inside the function range are recomputed.
845///
846/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
847/// you should call Sumw2 before making this operation.
848/// This is particularly important if you fit the histogram after TH1::Add
849///
850/// The function return kFALSE if the Add operation failed
851
853{
854 if (!f1) {
855 Error("Add","Attempt to add a non-existing function");
856 return kFALSE;
857 }
858
859 TString opt = option;
860 opt.ToLower();
861 Bool_t integral = kFALSE;
862 if (opt.Contains("i") && fDimension == 1) integral = kTRUE;
863
864 Int_t ncellsx = GetNbinsX() + 2; // cells = normal bins + underflow bin + overflow bin
865 Int_t ncellsy = GetNbinsY() + 2;
866 Int_t ncellsz = GetNbinsZ() + 2;
867 if (fDimension < 2) ncellsy = 1;
868 if (fDimension < 3) ncellsz = 1;
869
870 // delete buffer if it is there since it will become invalid
871 if (fBuffer) BufferEmpty(1);
872
873 // - Add statistics
874 Double_t s1[10];
875 for (Int_t i = 0; i < 10; ++i) s1[i] = 0;
876 PutStats(s1);
877 SetMinimum();
878 SetMaximum();
879
880 // - Loop on bins (including underflows/overflows)
882 Double_t cu=0;
883 Double_t xx[3];
884 Double_t *params = nullptr;
885 f1->InitArgs(xx,params);
886 for (binz = 0; binz < ncellsz; ++binz) {
888 for (biny = 0; biny < ncellsy; ++biny) {
890 for (binx = 0; binx < ncellsx; ++binx) {
892 if (!f1->IsInside(xx)) continue;
894 bin = binx + ncellsx * (biny + ncellsy * binz);
895 if (integral) {
897 } else {
898 cu = c1*f1->EvalPar(xx);
899 }
900 if (TF1::RejectedPoint()) continue;
902 }
903 }
904 }
905
906 return kTRUE;
907}
908
909int TH1::LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge) const
910{
911 const auto inconsistency = CheckConsistency(h1, h2);
912
914 if (useMerge)
915 Info(name, "Histograms have different dimensions - trying to use TH1::Merge");
916 else {
917 Error(name, "Histograms have different dimensions");
918 }
920 if (useMerge)
921 Info(name, "Histograms have different number of bins - trying to use TH1::Merge");
922 else {
923 Error(name, "Histograms have different number of bins");
924 }
925 } else if (inconsistency & kDifferentAxisLimits) {
926 if (useMerge)
927 Info(name, "Histograms have different axis limits - trying to use TH1::Merge");
928 else
929 Warning(name, "Histograms have different axis limits");
930 } else if (inconsistency & kDifferentBinLimits) {
931 if (useMerge)
932 Info(name, "Histograms have different bin limits - trying to use TH1::Merge");
933 else
934 Warning(name, "Histograms have different bin limits");
935 } else if (inconsistency & kDifferentLabels) {
936 // in case of different labels -
937 if (useMerge)
938 Info(name, "Histograms have different labels - trying to use TH1::Merge");
939 else
940 Info(name, "Histograms have different labels");
941 }
942
943 return inconsistency;
944}
945
946////////////////////////////////////////////////////////////////////////////////
947/// Performs the operation: `this = this + c1*h1`
948/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
949///
950/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
951/// if not already set.
952///
953/// Note also that adding histogram with labels is not supported, histogram will be
954/// added merging them by bin number independently of the labels.
955/// For adding histogram with labels one should use TH1::Merge
956///
957/// SPECIAL CASE (Average/Efficiency histograms)
958/// For histograms representing averages or efficiencies, one should compute the average
959/// of the two histograms and not the sum. One can mark a histogram to be an average
960/// histogram by setting its bit kIsAverage with
961/// myhist.SetBit(TH1::kIsAverage);
962/// Note that the two histograms must have their kIsAverage bit set
963///
964/// IMPORTANT NOTE1: If you intend to use the errors of this histogram later
965/// you should call Sumw2 before making this operation.
966/// This is particularly important if you fit the histogram after TH1::Add
967///
968/// IMPORTANT NOTE2: if h1 has a normalisation factor, the normalisation factor
969/// is used , ie this = this + c1*factor*h1
970/// Use the other TH1::Add function if you do not want this feature
971///
972/// IMPORTANT NOTE3: You should be careful about the statistics of the
973/// returned histogram, whose statistics may be binned or unbinned,
974/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
975/// and whether TH1::ResetStats has been called on either this or h1.
976/// See TH1::GetStats.
977///
978/// The function return kFALSE if the Add operation failed
979
981{
982 if (!h1) {
983 Error("Add","Attempt to add a non-existing histogram");
984 return kFALSE;
985 }
986
987 // delete buffer if it is there since it will become invalid
988 if (fBuffer) BufferEmpty(1);
989
990 bool useMerge = false;
991 const bool considerMerge = (c1 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
992 const auto inconsistency = LoggedInconsistency("Add", this, h1, considerMerge);
993 // If there is a bad inconsistency and we can't even consider merging, just give up
995 return false;
996 }
997 // If there is an inconsistency, we try to use merging
1000 }
1001
1002 if (useMerge) {
1003 TList l;
1004 l.Add(const_cast<TH1*>(h1));
1005 auto iret = Merge(&l);
1006 return (iret >= 0);
1007 }
1008
1009 // Create Sumw2 if h1 has Sumw2 set
1010 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
1011 // In addition, create Sumw2 if is not a simple addition, otherwise errors will not be correctly computed
1012 if (fSumw2.fN == 0 && c1 != 1.0) Sumw2();
1013
1014 // - Add statistics (for c1=1)
1015 Double_t entries = GetEntries() + h1->GetEntries();
1016
1017 // statistics can be preserved only in case of positive coefficients
1018 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1019 Bool_t resetStats = (c1 < 0);
1020 Double_t s1[kNstat] = {0};
1021 Double_t s2[kNstat] = {0};
1022 if (!resetStats) {
1023 // need to initialize to zero s1 and s2 since
1024 // GetStats fills only used elements depending on dimension and type
1025 GetStats(s1);
1026 h1->GetStats(s2);
1027 }
1028
1029 SetMinimum();
1030 SetMaximum();
1031
1032 // - Loop on bins (including underflows/overflows)
1033 Double_t factor = 1;
1034 if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();
1035 Double_t c1sq = c1 * c1;
1036 Double_t factsq = factor * factor;
1037
1038 for (Int_t bin = 0; bin < fNcells; ++bin) {
1039 //special case where histograms have the kIsAverage bit set
1040 if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
1045 Double_t w1 = 1., w2 = 1.;
1046
1047 // consider all special cases when bin errors are zero
1048 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1049 if (e1sq) w1 = 1. / e1sq;
1050 else if (h1->fSumw2.fN) {
1051 w1 = 1.E200; // use an arbitrary huge value
1052 if (y1 == 0) {
1053 // use an estimated error from the global histogram scale
1054 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1055 w1 = 1./(sf*sf);
1056 }
1057 }
1058 if (e2sq) w2 = 1. / e2sq;
1059 else if (fSumw2.fN) {
1060 w2 = 1.E200; // use an arbitrary huge value
1061 if (y2 == 0) {
1062 // use an estimated error from the global histogram scale
1063 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1064 w2 = 1./(sf*sf);
1065 }
1066 }
1067
1068 double y = (w1*y1 + w2*y2)/(w1 + w2);
1070 if (fSumw2.fN) {
1071 double err2 = 1./(w1 + w2);
1072 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1073 fSumw2.fArray[bin] = err2;
1074 }
1075 } else { // normal case of addition between histograms
1078 }
1079 }
1080
1081 // update statistics (do here to avoid changes by SetBinContent)
1082 if (resetStats) {
1083 // statistics need to be reset in case coefficient are negative
1084 ResetStats();
1085 }
1086 else {
1087 for (Int_t i=0;i<kNstat;i++) {
1088 if (i == 1) s1[i] += c1*c1*s2[i];
1089 else s1[i] += c1*s2[i];
1090 }
1091 PutStats(s1);
1092 if (c1 == 1.0)
1093 SetEntries(entries);
1094 else {
1095 // compute entries as effective entries in case of
1096 // weights different than 1
1097 double sumw2 = 0;
1098 double sumw = GetSumOfAllWeights(true, &sumw2);
1099 if (sumw2 > 0) SetEntries( sumw*sumw/sumw2);
1100 }
1101 }
1102 return kTRUE;
1103}
1104
1105////////////////////////////////////////////////////////////////////////////////
1106/// Replace contents of this histogram by the addition of h1 and h2.
1107///
1108/// `this = c1*h1 + c2*h2`
1109/// if errors are defined (see TH1::Sumw2), errors are also recalculated
1110///
1111/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
1112/// if not already set.
1113///
1114/// Note also that adding histogram with labels is not supported, histogram will be
1115/// added merging them by bin number independently of the labels.
1116/// For adding histogram ith labels one should use TH1::Merge
1117///
1118/// SPECIAL CASE (Average/Efficiency histograms)
1119/// For histograms representing averages or efficiencies, one should compute the average
1120/// of the two histograms and not the sum. One can mark a histogram to be an average
1121/// histogram by setting its bit kIsAverage with
1122/// myhist.SetBit(TH1::kIsAverage);
1123/// Note that the two histograms must have their kIsAverage bit set
1124///
1125/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
1126/// you should call Sumw2 before making this operation.
1127/// This is particularly important if you fit the histogram after TH1::Add
1128///
1129/// IMPORTANT NOTE2: You should be careful about the statistics of the
1130/// returned histogram, whose statistics may be binned or unbinned,
1131/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
1132/// and whether TH1::ResetStats has been called on either this or h1.
1133/// See TH1::GetStats.
1134///
1135/// ANOTHER SPECIAL CASE : h1 = h2 and c2 < 0
1136/// do a scaling this = c1 * h1 / (bin Volume)
1137///
1138/// The function returns kFALSE if the Add operation failed
1139
1141{
1142
1143 if (!h1 || !h2) {
1144 Error("Add","Attempt to add a non-existing histogram");
1145 return kFALSE;
1146 }
1147
1148 // delete buffer if it is there since it will become invalid
1149 if (fBuffer) BufferEmpty(1);
1150
1152 if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
1153
1154 if (h1 != h2) {
1155 bool useMerge = false;
1156 const bool considerMerge = (c1 == 1. && c2 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
1157
1158 // We can combine inconsistencies like this, since they are ordered and a
1159 // higher inconsistency is worse
1160 auto const inconsistency = std::max(LoggedInconsistency("Add", this, h1, considerMerge),
1161 LoggedInconsistency("Add", h1, h2, considerMerge));
1162
1163 // If there is a bad inconsistency and we can't even consider merging, just give up
1165 return false;
1166 }
1167 // If there is an inconsistency, we try to use merging
1170 }
1171
1172 if (useMerge) {
1173 TList l;
1174 // why TList takes non-const pointers ????
1175 l.Add(const_cast<TH1*>(h1));
1176 l.Add(const_cast<TH1*>(h2));
1177 Reset("ICE");
1178 auto iret = Merge(&l);
1179 return (iret >= 0);
1180 }
1181 }
1182
1183 // Create Sumw2 if h1 or h2 have Sumw2 set
1184 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
1185 // Create also Sumw2 if not a simple addition (c1 = 1, c2 = 1)
1186 if (fSumw2.fN == 0 && (c1 != 1.0 || c2 != 1.0)) Sumw2();
1187 // - Add statistics
1189
1190 // TODO remove
1191 // statistics can be preserved only in case of positive coefficients
1192 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1193 // also in case of scaling with the width we cannot preserve the statistics
1194 Double_t s1[kNstat] = {0};
1195 Double_t s2[kNstat] = {0};
1197
1198
1199 Bool_t resetStats = (c1*c2 < 0) || normWidth;
1200 if (!resetStats) {
1201 // need to initialize to zero s1 and s2 since
1202 // GetStats fills only used elements depending on dimension and type
1203 h1->GetStats(s1);
1204 h2->GetStats(s2);
1205 for (Int_t i=0;i<kNstat;i++) {
1206 if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
1207 //else s3[i] = TMath::Abs(c1)*s1[i] + TMath::Abs(c2)*s2[i];
1208 else s3[i] = c1*s1[i] + c2*s2[i];
1209 }
1210 }
1211
1212 SetMinimum();
1213 SetMaximum();
1214
1215 if (normWidth) { // DEPRECATED CASE: belongs to fitting / drawing modules
1216
1217 Int_t nbinsx = GetNbinsX() + 2; // normal bins + underflow, overflow
1218 Int_t nbinsy = GetNbinsY() + 2;
1219 Int_t nbinsz = GetNbinsZ() + 2;
1220
1221 if (fDimension < 2) nbinsy = 1;
1222 if (fDimension < 3) nbinsz = 1;
1223
1224 Int_t bin, binx, biny, binz;
1225 for (binz = 0; binz < nbinsz; ++binz) {
1227 for (biny = 0; biny < nbinsy; ++biny) {
1229 for (binx = 0; binx < nbinsx; ++binx) {
1231 bin = GetBin(binx, biny, binz);
1232 Double_t w = wx*wy*wz;
1234 if (fSumw2.fN) {
1236 fSumw2.fArray[bin] = c1*c1*e1*e1;
1237 }
1238 }
1239 }
1240 }
1241 } else if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
1242 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
1243 // special case where histograms have the kIsAverage bit set
1248 Double_t w1 = 1., w2 = 1.;
1249
1250 // consider all special cases when bin errors are zero
1251 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1252 if (e1sq) w1 = 1./ e1sq;
1253 else if (h1->fSumw2.fN) {
1254 w1 = 1.E200; // use an arbitrary huge value
1255 if (y1 == 0 ) { // use an estimated error from the global histogram scale
1256 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1257 w1 = 1./(sf*sf);
1258 }
1259 }
1260 if (e2sq) w2 = 1./ e2sq;
1261 else if (h2->fSumw2.fN) {
1262 w2 = 1.E200; // use an arbitrary huge value
1263 if (y2 == 0) { // use an estimated error from the global histogram scale
1264 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1265 w2 = 1./(sf*sf);
1266 }
1267 }
1268
1269 double y = (w1*y1 + w2*y2)/(w1 + w2);
1270 UpdateBinContent(i, y);
1271 if (fSumw2.fN) {
1272 double err2 = 1./(w1 + w2);
1273 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1274 fSumw2.fArray[i] = err2;
1275 }
1276 }
1277 } else { // case of simple histogram addition
1278 Double_t c1sq = c1 * c1;
1279 Double_t c2sq = c2 * c2;
1280 for (Int_t i = 0; i < fNcells; ++i) { // Loop on cells (bins including underflows/overflows)
1282 if (fSumw2.fN) {
1284 }
1285 }
1286 }
1287
1288 if (resetStats) {
1289 // statistics need to be reset in case coefficient are negative
1290 ResetStats();
1291 }
1292 else {
1293 // update statistics
1294 PutStats(s3);
1295 // previous entries are correct only if c1=1 and c2=1
1296 if (c1 == 1.0 && c2 == 1.0)
1298 else {
1299 // compute entries as effective entries in case of
1300 // weights different than 1
1301 double sumw2 = 0;
1302 double sumw = GetSumOfAllWeights(true, &sumw2);
1303 if (sumw2 > 0) SetEntries( sumw*sumw/sumw2);
1304 }
1305 }
1306
1307 return kTRUE;
1308}
1309
1310////////////////////////////////////////////////////////////////////////////////
1311/// Sets the flag controlling the automatic add of histograms in memory.
1312///
1313/// By default (fAddDirectory = kTRUE), histograms are automatically added
1314/// to the current directory (gDirectory).
1315/// Note that one histogram can be removed from its support directory
1316/// by calling h->SetDirectory(nullptr) or h->SetDirectory(dir) to add it
1317/// to the list of objects in the directory dir.
1318///
1319/// This is a static function. To call it, use `TH1::AddDirectory`
1320///
1321/// \deprecated Use ROOT::Experimental::ObjectAutoRegistrationEnabled(). It can be
1322/// set using an entry in rootrc or an environment variable, is initialised in a
1323/// thread-safe manner and covers more cases.
1324
1326{
1327 fgAddDirectory = add;
1328}
1329
1330////////////////////////////////////////////////////////////////////////////////
1331/// Auxiliary function to get the power of 2 next (larger) or previous (smaller)
1332/// a given x
1333///
1334/// next = kTRUE : next larger
1335/// next = kFALSE : previous smaller
1336///
1337/// Used by the autobin power of 2 algorithm
1338
1340{
1341 Int_t nn;
1342 Double_t f2 = std::frexp(x, &nn);
1343 return ((next && x > 0.) || (!next && x <= 0.)) ? std::ldexp(std::copysign(1., f2), nn)
1344 : std::ldexp(std::copysign(1., f2), --nn);
1345}
1346
1347////////////////////////////////////////////////////////////////////////////////
1348/// Auxiliary function to get the next power of 2 integer value larger then n
1349///
1350/// Used by the autobin power of 2 algorithm
1351
1353{
1354 Int_t nn;
1355 Double_t f2 = std::frexp(n, &nn);
1356 if (TMath::Abs(f2 - .5) > 0.001)
1357 return (Int_t)std::ldexp(1., nn);
1358 return n;
1359}
1360
1361////////////////////////////////////////////////////////////////////////////////
1362/// Buffer-based estimate of the histogram range using the power of 2 algorithm.
1363///
1364/// Used by the autobin power of 2 algorithm.
1365///
1366/// Works on arguments (min and max from fBuffer) and internal inputs: fXmin,
1367/// fXmax, NBinsX (from fXaxis), ...
1368/// Result save internally in fXaxis.
1369///
1370/// Overloaded by TH2 and TH3.
1371///
1372/// Return -1 if internal inputs are inconsistent, 0 otherwise.
1373
1375{
1376 // We need meaningful raw limits
1377 if (xmi >= xma)
1378 return -1;
1379
1380 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this, xmi, xma);
1383
1384 // Now adjust
1385 if (TMath::Abs(xhma) > TMath::Abs(xhmi)) {
1386 // Start from the upper limit
1389 } else {
1390 // Start from the lower limit
1393 }
1394
1395 // Round the bins to the next power of 2; take into account the possible inflation
1396 // of the range
1397 Double_t rr = (xhma - xhmi) / (xma - xmi);
1399
1400 // Adjust using the same bin width and offsets
1401 Double_t bw = (xhma - xhmi) / nb;
1402 // Bins to left free on each side
1403 Double_t autoside = gEnv->GetValue("Hist.Binning.Auto.Side", 0.05);
1404 Int_t nbside = (Int_t)(nb * autoside);
1405
1406 // Side up
1407 Int_t nbup = (xhma - xma) / bw;
1408 if (nbup % 2 != 0)
1409 nbup++; // Must be even
1410 if (nbup != nbside) {
1411 // Accounts also for both case: larger or smaller
1412 xhma -= bw * (nbup - nbside);
1413 nb -= (nbup - nbside);
1414 }
1415
1416 // Side low
1417 Int_t nblw = (xmi - xhmi) / bw;
1418 if (nblw % 2 != 0)
1419 nblw++; // Must be even
1420 if (nblw != nbside) {
1421 // Accounts also for both case: larger or smaller
1422 xhmi += bw * (nblw - nbside);
1423 nb -= (nblw - nbside);
1424 }
1425
1426 // Set everything and project
1427 SetBins(nb, xhmi, xhma);
1428
1429 // Done
1430 return 0;
1431}
1432
1433/// Fill histogram with all entries in the buffer.
1434///
1435/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
1436/// - action = 0 histogram is reset and filled from the buffer. When the histogram is filled from the
1437/// buffer the value fBuffer[0] is set to a negative number (= - number of entries)
1438/// When calling with action == 0 the histogram is NOT refilled when fBuffer[0] is < 0
1439/// While when calling with action = -1 the histogram is reset and ALWAYS refilled independently if
1440/// the histogram was filled before. This is needed when drawing the histogram
1441/// - action = 1 histogram is filled and buffer is deleted
1442/// The buffer is automatically deleted when filling the histogram and the entries is
1443/// larger than the buffer size
1444
1446{
1447 // do we need to compute the bin size?
1448 if (!fBuffer) return 0;
1450
1451 // nbentries correspond to the number of entries of histogram
1452
1453 if (nbentries == 0) {
1454 // if action is 1 we delete the buffer
1455 // this will avoid infinite recursion
1456 if (action > 0) {
1457 delete [] fBuffer;
1458 fBuffer = nullptr;
1459 fBufferSize = 0;
1460 }
1461 return 0;
1462 }
1463 if (nbentries < 0 && action == 0) return 0; // case histogram has been already filled from the buffer
1464
1465 Double_t *buffer = fBuffer;
1466 if (nbentries < 0) {
1468 // a reset might call BufferEmpty() giving an infinite recursion
1469 // Protect it by setting fBuffer = nullptr
1470 fBuffer = nullptr;
1471 //do not reset the list of functions
1472 Reset("ICES");
1473 fBuffer = buffer;
1474 }
1475 if (CanExtendAllAxes() || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
1476 //find min, max of entries in buffer
1479 for (Int_t i=0;i<nbentries;i++) {
1480 Double_t x = fBuffer[2*i+2];
1481 // skip infinity or NaN values
1482 if (!std::isfinite(x)) continue;
1483 if (x < xmin) xmin = x;
1484 if (x > xmax) xmax = x;
1485 }
1486 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
1487 Int_t rc = -1;
1489 if ((rc = AutoP2FindLimits(xmin, xmax)) < 0)
1490 Warning("BufferEmpty",
1491 "inconsistency found by power-of-2 autobin algorithm: fallback to standard method");
1492 }
1493 if (rc < 0)
1494 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this, xmin, xmax);
1495 } else {
1496 fBuffer = nullptr;
1499 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax, &fXaxis);
1500 fBuffer = buffer;
1501 fBufferSize = keep;
1502 }
1503 }
1504
1505 // call DoFillN which will not put entries in the buffer as FillN does
1506 // set fBuffer to zero to avoid re-emptying the buffer from functions called
1507 // by DoFillN (e.g Sumw2)
1508 buffer = fBuffer; fBuffer = nullptr;
1509 DoFillN(nbentries,&buffer[2],&buffer[1],2);
1510 fBuffer = buffer;
1511
1512 // if action == 1 - delete the buffer
1513 if (action > 0) {
1514 delete [] fBuffer;
1515 fBuffer = nullptr;
1516 fBufferSize = 0;
1517 } else {
1518 // if number of entries is consistent with buffer - set it negative to avoid
1519 // refilling the histogram every time BufferEmpty(0) is called
1520 // In case it is not consistent, by setting fBuffer[0]=0 is like resetting the buffer
1521 // (it will not be used anymore the next time BufferEmpty is called)
1522 if (nbentries == (Int_t)fEntries)
1523 fBuffer[0] = -nbentries;
1524 else
1525 fBuffer[0] = 0;
1526 }
1527 return nbentries;
1528}
1529
1530////////////////////////////////////////////////////////////////////////////////
1531/// accumulate arguments in buffer. When buffer is full, empty the buffer
1532///
1533/// - `fBuffer[0]` = number of entries in buffer
1534/// - `fBuffer[1]` = w of first entry
1535/// - `fBuffer[2]` = x of first entry
1536
1538{
1539 if (!fBuffer) return -2;
1541
1542
1543 if (nbentries < 0) {
1544 // reset nbentries to a positive value so next time BufferEmpty() is called
1545 // the histogram will be refilled
1547 fBuffer[0] = nbentries;
1548 if (fEntries > 0) {
1549 // set fBuffer to zero to avoid calling BufferEmpty in Reset
1550 Double_t *buffer = fBuffer; fBuffer=nullptr;
1551 Reset("ICES"); // do not reset list of functions
1552 fBuffer = buffer;
1553 }
1554 }
1555 if (2*nbentries+2 >= fBufferSize) {
1556 BufferEmpty(1);
1557 if (!fBuffer)
1558 // to avoid infinite recursion Fill->BufferFill->Fill
1559 return Fill(x,w);
1560 // this cannot happen
1561 R__ASSERT(0);
1562 }
1563 fBuffer[2*nbentries+1] = w;
1564 fBuffer[2*nbentries+2] = x;
1565 fBuffer[0] += 1;
1566 return -2;
1567}
1568
1569////////////////////////////////////////////////////////////////////////////////
1570/// Check bin limits.
1571
1572bool TH1::CheckBinLimits(const TAxis* a1, const TAxis * a2)
1573{
1574 const TArrayD * h1Array = a1->GetXbins();
1575 const TArrayD * h2Array = a2->GetXbins();
1576 Int_t fN = h1Array->fN;
1577 if ( fN != 0 ) {
1578 if ( h2Array->fN != fN ) {
1579 return false;
1580 }
1581 else {
1582 for ( int i = 0; i < fN; ++i ) {
1583 // for i==fN (nbin+1) a->GetBinWidth() returns last bin width
1584 // we do not need to exclude that case
1585 double binWidth = a1->GetBinWidth(i);
1586 if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), binWidth*1E-10 ) ) {
1587 return false;
1588 }
1589 }
1590 }
1591 }
1592
1593 return true;
1594}
1595
1596////////////////////////////////////////////////////////////////////////////////
1597/// Check that axis have same labels.
1598
1599bool TH1::CheckBinLabels(const TAxis* a1, const TAxis * a2)
1600{
1601 THashList *l1 = a1->GetLabels();
1602 THashList *l2 = a2->GetLabels();
1603
1604 if (!l1 && !l2 )
1605 return true;
1606 if (!l1 || !l2 ) {
1607 return false;
1608 }
1609 // check now labels sizes are the same
1610 if (l1->GetSize() != l2->GetSize() ) {
1611 return false;
1612 }
1613 for (int i = 1; i <= a1->GetNbins(); ++i) {
1614 TString label1 = a1->GetBinLabel(i);
1615 TString label2 = a2->GetBinLabel(i);
1616 if (label1 != label2) {
1617 return false;
1618 }
1619 }
1620
1621 return true;
1622}
1623
1624////////////////////////////////////////////////////////////////////////////////
1625/// Check that the axis limits of the histograms are the same.
1626/// If a first and last bin is passed the axis is compared between the given range
1627
1628bool TH1::CheckAxisLimits(const TAxis *a1, const TAxis *a2 )
1629{
1630 double firstBin = a1->GetBinWidth(1);
1631 double lastBin = a1->GetBinWidth( a1->GetNbins() );
1632 if ( ! TMath::AreEqualAbs(a1->GetXmin(), a2->GetXmin(), firstBin* 1.E-10) ||
1633 ! TMath::AreEqualAbs(a1->GetXmax(), a2->GetXmax(), lastBin*1.E-10) ) {
1634 return false;
1635 }
1636 return true;
1637}
1638
1639////////////////////////////////////////////////////////////////////////////////
1640/// Check that the axis are the same
1641
1642bool TH1::CheckEqualAxes(const TAxis *a1, const TAxis *a2 )
1643{
1644 if (a1->GetNbins() != a2->GetNbins() ) {
1645 ::Info("CheckEqualAxes","Axes have different number of bins : nbin1 = %d nbin2 = %d",a1->GetNbins(),a2->GetNbins() );
1646 return false;
1647 }
1648 if(!CheckAxisLimits(a1,a2)) {
1649 ::Info("CheckEqualAxes","Axes have different limits");
1650 return false;
1651 }
1652 if(!CheckBinLimits(a1,a2)) {
1653 ::Info("CheckEqualAxes","Axes have different bin limits");
1654 return false;
1655 }
1656
1657 // check labels
1658 if(!CheckBinLabels(a1,a2)) {
1659 ::Info("CheckEqualAxes","Axes have different labels");
1660 return false;
1661 }
1662
1663 return true;
1664}
1665
1666////////////////////////////////////////////////////////////////////////////////
1667/// Check that two sub axis are the same.
1668/// The limits are defined by first bin and last bin
1669/// N.B. no check is done in this case for variable bins
1670
1672{
1673 // By default is assumed that no bins are given for the second axis
1675 Double_t xmin1 = a1->GetBinLowEdge(firstBin1);
1676 Double_t xmax1 = a1->GetBinUpEdge(lastBin1);
1677
1678 Int_t nbins2 = a2->GetNbins();
1679 Double_t xmin2 = a2->GetXmin();
1680 Double_t xmax2 = a2->GetXmax();
1681
1682 if (firstBin2 < lastBin2) {
1683 // in this case assume no bins are given for the second axis
1685 xmin2 = a1->GetBinLowEdge(firstBin1);
1686 xmax2 = a1->GetBinUpEdge(lastBin1);
1687 }
1688
1689 if (nbins1 != nbins2 ) {
1690 ::Info("CheckConsistentSubAxes","Axes have different number of bins");
1691 return false;
1692 }
1693
1694 Double_t firstBin = a1->GetBinWidth(firstBin1);
1695 Double_t lastBin = a1->GetBinWidth(lastBin1);
1696 if ( ! TMath::AreEqualAbs(xmin1,xmin2,1.E-10 * firstBin) ||
1697 ! TMath::AreEqualAbs(xmax1,xmax2,1.E-10 * lastBin) ) {
1698 ::Info("CheckConsistentSubAxes","Axes have different limits");
1699 return false;
1700 }
1701
1702 return true;
1703}
1704
1705////////////////////////////////////////////////////////////////////////////////
1706/// Check histogram compatibility.
1707/// The returned integer is part of EInconsistencyBits
1708/// The value 0 means that the histograms are compatible
1709
1711{
1712 if (h1 == h2) return kFullyConsistent;
1713
1714 if (h1->GetDimension() != h2->GetDimension() ) {
1715 return kDifferentDimensions;
1716 }
1717 Int_t dim = h1->GetDimension();
1718
1719 // returns kTRUE if number of bins and bin limits are identical
1720 Int_t nbinsx = h1->GetNbinsX();
1721 Int_t nbinsy = h1->GetNbinsY();
1722 Int_t nbinsz = h1->GetNbinsZ();
1723
1724 // Check whether the histograms have the same number of bins.
1725 if (nbinsx != h2->GetNbinsX() ||
1726 (dim > 1 && nbinsy != h2->GetNbinsY()) ||
1727 (dim > 2 && nbinsz != h2->GetNbinsZ()) ) {
1729 }
1730
1731 bool ret = true;
1732
1733 // check axis limits
1734 ret &= CheckAxisLimits(h1->GetXaxis(), h2->GetXaxis());
1735 if (dim > 1) ret &= CheckAxisLimits(h1->GetYaxis(), h2->GetYaxis());
1736 if (dim > 2) ret &= CheckAxisLimits(h1->GetZaxis(), h2->GetZaxis());
1737 if (!ret) return kDifferentAxisLimits;
1738
1739 // check bin limits
1740 ret &= CheckBinLimits(h1->GetXaxis(), h2->GetXaxis());
1741 if (dim > 1) ret &= CheckBinLimits(h1->GetYaxis(), h2->GetYaxis());
1742 if (dim > 2) ret &= CheckBinLimits(h1->GetZaxis(), h2->GetZaxis());
1743 if (!ret) return kDifferentBinLimits;
1744
1745 // check labels if histograms are both not empty
1746 if ( !h1->IsEmpty() && !h2->IsEmpty() ) {
1747 ret &= CheckBinLabels(h1->GetXaxis(), h2->GetXaxis());
1748 if (dim > 1) ret &= CheckBinLabels(h1->GetYaxis(), h2->GetYaxis());
1749 if (dim > 2) ret &= CheckBinLabels(h1->GetZaxis(), h2->GetZaxis());
1750 if (!ret) return kDifferentLabels;
1751 }
1752
1753 return kFullyConsistent;
1754}
1755
1756////////////////////////////////////////////////////////////////////////////////
1757/// \f$ \chi^{2} \f$ test for comparing weighted and unweighted histograms.
1758///
1759/// Compares the histograms' adjusted (normalized) residuals.
1760/// Function: Returns p-value. Other return values are specified by the 3rd parameter
1761///
1762/// \param[in] h2 the second histogram
1763/// \param[in] option
1764/// - "UU" = experiment experiment comparison (unweighted-unweighted)
1765/// - "UW" = experiment MC comparison (unweighted-weighted). Note that
1766/// the first histogram should be unweighted
1767/// - "WW" = MC MC comparison (weighted-weighted)
1768/// - "NORM" = to be used when one or both of the histograms is scaled
1769/// but the histogram originally was unweighted
1770/// - by default underflows and overflows are not included:
1771/// * "OF" = overflows included
1772/// * "UF" = underflows included
1773/// - "P" = print chi2, ndf, p_value, igood
1774/// - "CHI2" = returns chi2 instead of p-value
1775/// - "CHI2/NDF" = returns \f$ \chi^{2} \f$/ndf
1776/// \param[in] res not empty - computes normalized residuals and returns them in this array
1777///
1778/// The current implementation is based on the papers \f$ \chi^{2} \f$ test for comparison
1779/// of weighted and unweighted histograms" in Proceedings of PHYSTAT05 and
1780/// "Comparison weighted and unweighted histograms", arXiv:physics/0605123
1781/// by N.Gagunashvili. This function has been implemented by Daniel Haertl in August 2006.
1782///
1783/// #### Introduction:
1784///
1785/// A frequently used technique in data analysis is the comparison of
1786/// histograms. First suggested by Pearson [1] the \f$ \chi^{2} \f$ test of
1787/// homogeneity is used widely for comparing usual (unweighted) histograms.
1788/// This paper describes the implementation modified \f$ \chi^{2} \f$ tests
1789/// for comparison of weighted and unweighted histograms and two weighted
1790/// histograms [2] as well as usual Pearson's \f$ \chi^{2} \f$ test for
1791/// comparison two usual (unweighted) histograms.
1792///
1793/// #### Overview:
1794///
1795/// Comparison of two histograms expect hypotheses that two histograms
1796/// represent identical distributions. To make a decision p-value should
1797/// be calculated. The hypotheses of identity is rejected if the p-value is
1798/// lower then some significance level. Traditionally significance levels
1799/// 0.1, 0.05 and 0.01 are used. The comparison procedure should include an
1800/// analysis of the residuals which is often helpful in identifying the
1801/// bins of histograms responsible for a significant overall \f$ \chi^{2} \f$ value.
1802/// Residuals are the difference between bin contents and expected bin
1803/// contents. Most convenient for analysis are the normalized residuals. If
1804/// hypotheses of identity are valid then normalized residuals are
1805/// approximately independent and identically distributed random variables
1806/// having N(0,1) distribution. Analysis of residuals expect test of above
1807/// mentioned properties of residuals. Notice that indirectly the analysis
1808/// of residuals increase the power of \f$ \chi^{2} \f$ test.
1809///
1810/// #### Methods of comparison:
1811///
1812/// \f$ \chi^{2} \f$ test for comparison two (unweighted) histograms:
1813/// Let us consider two histograms with the same binning and the number
1814/// of bins equal to r. Let us denote the number of events in the ith bin
1815/// in the first histogram as ni and as mi in the second one. The total
1816/// number of events in the first histogram is equal to:
1817/// \f[
1818/// N = \sum_{i=1}^{r} n_{i}
1819/// \f]
1820/// and
1821/// \f[
1822/// M = \sum_{i=1}^{r} m_{i}
1823/// \f]
1824/// in the second histogram. The hypothesis of identity (homogeneity) [3]
1825/// is that the two histograms represent random values with identical
1826/// distributions. It is equivalent that there exist r constants p1,...,pr,
1827/// such that
1828/// \f[
1829///\sum_{i=1}^{r} p_{i}=1
1830/// \f]
1831/// and the probability of belonging to the ith bin for some measured value
1832/// in both experiments is equal to pi. The number of events in the ith
1833/// bin is a random variable with a distribution approximated by a Poisson
1834/// probability distribution
1835/// \f[
1836///\frac{e^{-Np_{i}}(Np_{i})^{n_{i}}}{n_{i}!}
1837/// \f]
1838///for the first histogram and with distribution
1839/// \f[
1840///\frac{e^{-Mp_{i}}(Mp_{i})^{m_{i}}}{m_{i}!}
1841/// \f]
1842/// for the second histogram. If the hypothesis of homogeneity is valid,
1843/// then the maximum likelihood estimator of pi, i=1,...,r, is
1844/// \f[
1845///\hat{p}_{i}= \frac{n_{i}+m_{i}}{N+M}
1846/// \f]
1847/// and then
1848/// \f[
1849/// 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}}
1850/// \f]
1851/// has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [3].
1852/// The comparison procedure can include an analysis of the residuals which
1853/// is often helpful in identifying the bins of histograms responsible for
1854/// a significant overall \f$ \chi^{2} \f$ value. Most convenient for
1855/// analysis are the adjusted (normalized) residuals [4]
1856/// \f[
1857/// 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))}}
1858/// \f]
1859/// If hypotheses of homogeneity are valid then residuals ri are
1860/// approximately independent and identically distributed random variables
1861/// having N(0,1) distribution. The application of the \f$ \chi^{2} \f$ test has
1862/// restrictions related to the value of the expected frequencies Npi,
1863/// Mpi, i=1,...,r. A conservative rule formulated in [5] is that all the
1864/// expectations must be 1 or greater for both histograms. In practical
1865/// cases when expected frequencies are not known the estimated expected
1866/// frequencies \f$ M\hat{p}_{i}, N\hat{p}_{i}, i=1,...,r \f$ can be used.
1867///
1868/// #### Unweighted and weighted histograms comparison:
1869///
1870/// A simple modification of the ideas described above can be used for the
1871/// comparison of the usual (unweighted) and weighted histograms. Let us
1872/// denote the number of events in the ith bin in the unweighted
1873/// histogram as ni and the common weight of events in the ith bin of the
1874/// weighted histogram as wi. The total number of events in the
1875/// unweighted histogram is equal to
1876///\f[
1877/// N = \sum_{i=1}^{r} n_{i}
1878///\f]
1879/// and the total weight of events in the weighted histogram is equal to
1880///\f[
1881/// W = \sum_{i=1}^{r} w_{i}
1882///\f]
1883/// Let us formulate the hypothesis of identity of an unweighted histogram
1884/// to a weighted histogram so that there exist r constants p1,...,pr, such
1885/// that
1886///\f[
1887/// \sum_{i=1}^{r} p_{i} = 1
1888///\f]
1889/// for the unweighted histogram. The weight wi is a random variable with a
1890/// distribution approximated by the normal probability distribution
1891/// \f$ N(Wp_{i},\sigma_{i}^{2}) \f$ where \f$ \sigma_{i}^{2} \f$ is the variance of the weight wi.
1892/// If we replace the variance \f$ \sigma_{i}^{2} \f$
1893/// with estimate \f$ s_{i}^{2} \f$ (sum of squares of weights of
1894/// events in the ith bin) and the hypothesis of identity is valid, then the
1895/// maximum likelihood estimator of pi,i=1,...,r, is
1896///\f[
1897/// \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}}
1898///\f]
1899/// We may then use the test statistic
1900///\f[
1901/// 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}}
1902///\f]
1903/// and it has approximately a \f$ \sigma^{2}_{(r-1)} \f$ distribution [2]. This test, as well
1904/// as the original one [3], has a restriction on the expected frequencies. The
1905/// expected frequencies recommended for the weighted histogram is more than 25.
1906/// The value of the minimal expected frequency can be decreased down to 10 for
1907/// the case when the weights of the events are close to constant. In the case
1908/// of a weighted histogram if the number of events is unknown, then we can
1909/// apply this recommendation for the equivalent number of events as
1910///\f[
1911/// n_{i}^{equiv} = \frac{ w_{i}^{2} }{ s_{i}^{2} }
1912///\f]
1913/// The minimal expected frequency for an unweighted histogram must be 1. Notice
1914/// that any usual (unweighted) histogram can be considered as a weighted
1915/// histogram with events that have constant weights equal to 1.
1916/// The variance \f$ z_{i}^{2} \f$ of the difference between the weight wi
1917/// and the estimated expectation value of the weight is approximately equal to:
1918///\f[
1919/// 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}
1920///\f]
1921/// The residuals
1922///\f[
1923/// r_{i} = \frac{w_{i}-W\hat{p}_{i}}{z_{i}}
1924///\f]
1925/// have approximately a normal distribution with mean equal to 0 and standard
1926/// deviation equal to 1.
1927///
1928/// #### Two weighted histograms comparison:
1929///
1930/// Let us denote the common weight of events of the ith bin in the first
1931/// histogram as w1i and as w2i in the second one. The total weight of events
1932/// in the first histogram is equal to
1933///\f[
1934/// W_{1} = \sum_{i=1}^{r} w_{1i}
1935///\f]
1936/// and
1937///\f[
1938/// W_{2} = \sum_{i=1}^{r} w_{2i}
1939///\f]
1940/// in the second histogram. Let us formulate the hypothesis of identity of
1941/// weighted histograms so that there exist r constants p1,...,pr, such that
1942///\f[
1943/// \sum_{i=1}^{r} p_{i} = 1
1944///\f]
1945/// and also expectation value of weight w1i equal to W1pi and expectation value
1946/// of weight w2i equal to W2pi. Weights in both the histograms are random
1947/// variables with distributions which can be approximated by a normal
1948/// probability distribution \f$ N(W_{1}p_{i},\sigma_{1i}^{2}) \f$ for the first histogram
1949/// and by a distribution \f$ N(W_{2}p_{i},\sigma_{2i}^{2}) \f$ for the second.
1950/// Here \f$ \sigma_{1i}^{2} \f$ and \f$ \sigma_{2i}^{2} \f$ are the variances
1951/// of w1i and w2i with estimators \f$ s_{1i}^{2} \f$ and \f$ s_{2i}^{2} \f$ respectively.
1952/// If the hypothesis of identity is valid, then the maximum likelihood and
1953/// Least Square Method estimator of pi,i=1,...,r, is
1954///\f[
1955/// \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}}
1956///\f]
1957/// We may then use the test statistic
1958///\f[
1959/// 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}}
1960///\f]
1961/// and it has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [2].
1962/// The normalized or studentised residuals [6]
1963///\f[
1964/// 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})}}}
1965///\f]
1966/// have approximately a normal distribution with mean equal to 0 and standard
1967/// deviation 1. A recommended minimal expected frequency is equal to 10 for
1968/// the proposed test.
1969///
1970/// #### Numerical examples:
1971///
1972/// The method described herein is now illustrated with an example.
1973/// We take a distribution
1974///\f[
1975/// \phi(x) = \frac{2}{(x-10)^{2}+1} + \frac{1}{(x-14)^{2}+1} (1)
1976///\f]
1977/// defined on the interval [4,16]. Events distributed according to the formula
1978/// (1) are simulated to create the unweighted histogram. Uniformly distributed
1979/// events are simulated for the weighted histogram with weights calculated by
1980/// formula (1). Each histogram has the same number of bins: 20. Fig.1 shows
1981/// the result of comparison of the unweighted histogram with 200 events
1982/// (minimal expected frequency equal to one) and the weighted histogram with
1983/// 500 events (minimal expected frequency equal to 25)
1984/// Begin_Macro
1985/// ../../../tutorials/math/chi2test.C
1986/// End_Macro
1987/// Fig 1. An example of comparison of the unweighted histogram with 200 events
1988/// and the weighted histogram with 500 events:
1989/// 1. unweighted histogram;
1990/// 2. weighted histogram;
1991/// 3. normalized residuals plot;
1992/// 4. normal Q-Q plot of residuals.
1993///
1994/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1995/// 21.09 with p-value equal to 0.33, therefore the hypothesis of identity of
1996/// the two histograms can be accepted for 0.05 significant level. The behavior
1997/// of the normalized residuals plot (see Fig. 1c) and the normal Q-Q plot
1998/// (see Fig. 1d) of residuals are regular and we cannot identify the outliers
1999/// or bins with a big influence on \f$ \chi^{2} \f$.
2000///
2001/// The second example presents the same two histograms but 17 events was added
2002/// to content of bin number 15 in unweighted histogram. Fig.2 shows the result
2003/// of comparison of the unweighted histogram with 217 events (minimal expected
2004/// frequency equal to one) and the weighted histogram with 500 events (minimal
2005/// expected frequency equal to 25)
2006/// Begin_Macro
2007/// ../../../tutorials/math/chi2test.C(17)
2008/// End_Macro
2009/// Fig 2. An example of comparison of the unweighted histogram with 217 events
2010/// and the weighted histogram with 500 events:
2011/// 1. unweighted histogram;
2012/// 2. weighted histogram;
2013/// 3. normalized residuals plot;
2014/// 4. normal Q-Q plot of residuals.
2015///
2016/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
2017/// 32.33 with p-value equal to 0.029, therefore the hypothesis of identity of
2018/// the two histograms is rejected for 0.05 significant level. The behavior of
2019/// the normalized residuals plot (see Fig. 2c) and the normal Q-Q plot (see
2020/// Fig. 2d) of residuals are not regular and we can identify the outlier or
2021/// bin with a big influence on \f$ \chi^{2} \f$.
2022///
2023/// #### References:
2024///
2025/// - [1] Pearson, K., 1904. On the Theory of Contingency and Its Relation to
2026/// Association and Normal Correlation. Drapers' Co. Memoirs, Biometric
2027/// Series No. 1, London.
2028/// - [2] Gagunashvili, N., 2006. \f$ \sigma^{2} \f$ test for comparison
2029/// of weighted and unweighted histograms. Statistical Problems in Particle
2030/// Physics, Astrophysics and Cosmology, Proceedings of PHYSTAT05,
2031/// Oxford, UK, 12-15 September 2005, Imperial College Press, London, 43-44.
2032/// Gagunashvili,N., Comparison of weighted and unweighted histograms,
2033/// arXiv:physics/0605123, 2006.
2034/// - [3] Cramer, H., 1946. Mathematical methods of statistics.
2035/// Princeton University Press, Princeton.
2036/// - [4] Haberman, S.J., 1973. The analysis of residuals in cross-classified tables.
2037/// Biometrics 29, 205-220.
2038/// - [5] Lewontin, R.C. and Felsenstein, J., 1965. The robustness of homogeneity
2039/// test in 2xN tables. Biometrics 21, 19-33.
2040/// - [6] Seber, G.A.F., Lee, A.J., 2003, Linear Regression Analysis.
2041/// John Wiley & Sons Inc., New York.
2042
2043Double_t TH1::Chi2Test(const TH1* h2, Option_t *option, Double_t *res) const
2044{
2045 Double_t chi2 = 0;
2046 Int_t ndf = 0, igood = 0;
2047
2048 TString opt = option;
2049 opt.ToUpper();
2050
2051 Double_t prob = Chi2TestX(h2,chi2,ndf,igood,option,res);
2052
2053 if(opt.Contains("P")) {
2054 printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
2055 }
2056 if(opt.Contains("CHI2/NDF")) {
2057 if (ndf == 0) return 0;
2058 return chi2/ndf;
2059 }
2060 if(opt.Contains("CHI2")) {
2061 return chi2;
2062 }
2063
2064 return prob;
2065}
2066
2067////////////////////////////////////////////////////////////////////////////////
2068/// The computation routine of the Chisquare test. For the method description,
2069/// see Chi2Test() function.
2070///
2071/// \return p-value
2072/// \param[in] h2 the second histogram
2073/// \param[in] option
2074/// - "UU" = experiment experiment comparison (unweighted-unweighted)
2075/// - "UW" = experiment MC comparison (unweighted-weighted). Note that the first
2076/// histogram should be unweighted
2077/// - "WW" = MC MC comparison (weighted-weighted)
2078/// - "NORM" = if one or both histograms is scaled
2079/// - "OF" = overflows included
2080/// - "UF" = underflows included
2081/// by default underflows and overflows are not included
2082/// \param[out] igood test output
2083/// - igood=0 - no problems
2084/// - For unweighted unweighted comparison
2085/// - igood=1'There is a bin in the 1st histogram with less than 1 event'
2086/// - igood=2'There is a bin in the 2nd histogram with less than 1 event'
2087/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2088/// - For unweighted weighted comparison
2089/// - igood=1'There is a bin in the 1st histogram with less then 1 event'
2090/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective number of events'
2091/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2092/// - For weighted weighted comparison
2093/// - igood=1'There is a bin in the 1st histogram with less then 10 effective
2094/// number of events'
2095/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective
2096/// number of events'
2097/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2098/// \param[out] chi2 chisquare of the test
2099/// \param[out] ndf number of degrees of freedom (important, when both histograms have the same empty bins)
2100/// \param[out] res normalized residuals for further analysis
2101
2102Double_t TH1::Chi2TestX(const TH1* h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option, Double_t *res) const
2103{
2104
2108
2109 Double_t sum1 = 0.0, sumw1 = 0.0;
2110 Double_t sum2 = 0.0, sumw2 = 0.0;
2111
2112 chi2 = 0.0;
2113 ndf = 0;
2114
2115 TString opt = option;
2116 opt.ToUpper();
2117
2118 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
2119
2120 const TAxis *xaxis1 = GetXaxis();
2121 const TAxis *xaxis2 = h2->GetXaxis();
2122 const TAxis *yaxis1 = GetYaxis();
2123 const TAxis *yaxis2 = h2->GetYaxis();
2124 const TAxis *zaxis1 = GetZaxis();
2125 const TAxis *zaxis2 = h2->GetZaxis();
2126
2127 Int_t nbinx1 = xaxis1->GetNbins();
2128 Int_t nbinx2 = xaxis2->GetNbins();
2129 Int_t nbiny1 = yaxis1->GetNbins();
2130 Int_t nbiny2 = yaxis2->GetNbins();
2131 Int_t nbinz1 = zaxis1->GetNbins();
2132 Int_t nbinz2 = zaxis2->GetNbins();
2133
2134 //check dimensions
2135 if (this->GetDimension() != h2->GetDimension() ){
2136 Error("Chi2TestX","Histograms have different dimensions.");
2137 return 0.0;
2138 }
2139
2140 //check number of channels
2141 if (nbinx1 != nbinx2) {
2142 Error("Chi2TestX","different number of x channels");
2143 }
2144 if (nbiny1 != nbiny2) {
2145 Error("Chi2TestX","different number of y channels");
2146 }
2147 if (nbinz1 != nbinz2) {
2148 Error("Chi2TestX","different number of z channels");
2149 }
2150
2151 //check for ranges
2152 i_start = j_start = k_start = 1;
2153 i_end = nbinx1;
2154 j_end = nbiny1;
2155 k_end = nbinz1;
2156
2157 if (xaxis1->TestBit(TAxis::kAxisRange)) {
2158 i_start = xaxis1->GetFirst();
2159 i_end = xaxis1->GetLast();
2160 }
2161 if (yaxis1->TestBit(TAxis::kAxisRange)) {
2162 j_start = yaxis1->GetFirst();
2163 j_end = yaxis1->GetLast();
2164 }
2165 if (zaxis1->TestBit(TAxis::kAxisRange)) {
2166 k_start = zaxis1->GetFirst();
2167 k_end = zaxis1->GetLast();
2168 }
2169
2170
2171 if (opt.Contains("OF")) {
2172 if (GetDimension() == 3) k_end = ++nbinz1;
2173 if (GetDimension() >= 2) j_end = ++nbiny1;
2174 if (GetDimension() >= 1) i_end = ++nbinx1;
2175 }
2176
2177 if (opt.Contains("UF")) {
2178 if (GetDimension() == 3) k_start = 0;
2179 if (GetDimension() >= 2) j_start = 0;
2180 if (GetDimension() >= 1) i_start = 0;
2181 }
2182
2183 ndf = (i_end - i_start + 1) * (j_end - j_start + 1) * (k_end - k_start + 1) - 1;
2184
2185 Bool_t comparisonUU = opt.Contains("UU");
2186 Bool_t comparisonUW = opt.Contains("UW");
2187 Bool_t comparisonWW = opt.Contains("WW");
2188 Bool_t scaledHistogram = opt.Contains("NORM");
2189
2190 if (scaledHistogram && !comparisonUU) {
2191 Info("Chi2TestX", "NORM option should be used together with UU option. It is ignored");
2192 }
2193
2194 // look at histo global bin content and effective entries
2195 Stat_t s[kNstat];
2196 GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2197 Double_t sumBinContent1 = s[0];
2198 Double_t effEntries1 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2199
2200 h2->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2201 Double_t sumBinContent2 = s[0];
2202 Double_t effEntries2 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2203
2204 if (!comparisonUU && !comparisonUW && !comparisonWW ) {
2205 // deduce automatically from type of histogram
2208 else comparisonUW = true;
2209 }
2210 else comparisonWW = true;
2211 }
2212 // check unweighted histogram
2213 if (comparisonUW) {
2215 Warning("Chi2TestX","First histogram is not unweighted and option UW has been requested");
2216 }
2217 }
2218 if ( (!scaledHistogram && comparisonUU) ) {
2220 Warning("Chi2TestX","Both histograms are not unweighted and option UU has been requested");
2221 }
2222 }
2223
2224
2225 //get number of events in histogram
2227 for (Int_t i = i_start; i <= i_end; ++i) {
2228 for (Int_t j = j_start; j <= j_end; ++j) {
2229 for (Int_t k = k_start; k <= k_end; ++k) {
2230
2231 Int_t bin = GetBin(i, j, k);
2232
2237
2238 if (e1sq > 0.0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2239 else cnt1 = 0.0;
2240
2241 if (e2sq > 0.0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2242 else cnt2 = 0.0;
2243
2244 // sum contents
2245 sum1 += cnt1;
2246 sum2 += cnt2;
2247 sumw1 += e1sq;
2248 sumw2 += e2sq;
2249 }
2250 }
2251 }
2252 if (sumw1 <= 0.0 || sumw2 <= 0.0) {
2253 Error("Chi2TestX", "Cannot use option NORM when one histogram has all zero errors");
2254 return 0.0;
2255 }
2256
2257 } else {
2258 for (Int_t i = i_start; i <= i_end; ++i) {
2259 for (Int_t j = j_start; j <= j_end; ++j) {
2260 for (Int_t k = k_start; k <= k_end; ++k) {
2261
2262 Int_t bin = GetBin(i, j, k);
2263
2265 sum2 += h2->RetrieveBinContent(bin);
2266
2269 }
2270 }
2271 }
2272 }
2273 //checks that the histograms are not empty
2274 if (sum1 == 0.0 || sum2 == 0.0) {
2275 Error("Chi2TestX","one histogram is empty");
2276 return 0.0;
2277 }
2278
2279 if ( comparisonWW && ( sumw1 <= 0.0 && sumw2 <= 0.0 ) ){
2280 Error("Chi2TestX","Hist1 and Hist2 have both all zero errors\n");
2281 return 0.0;
2282 }
2283
2284 //THE TEST
2285 Int_t m = 0, n = 0;
2286 //Experiment - experiment comparison
2287 if (comparisonUU) {
2288 Int_t resIndex = 0;
2289 Double_t sum = sum1 + sum2;
2290 for (Int_t i = i_start; i <= i_end; ++i) {
2291 for (Int_t j = j_start; j <= j_end; ++j) {
2292 for (Int_t k = k_start; k <= k_end; ++k) {
2293
2294 Int_t bin = GetBin(i, j, k);
2295
2298
2299 if (scaledHistogram) {
2300 // scale bin value to effective bin entries
2303
2304 if (e1sq > 0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2305 else cnt1 = 0;
2306
2307 if (e2sq > 0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2308 else cnt2 = 0;
2309 }
2310
2311 if (Int_t(cnt1) == 0 && Int_t(cnt2) == 0) --ndf; // no data means one degree of freedom less
2312 else {
2313
2316 //Double_t nexp2 = binsum*sum2/sum;
2317
2318 if (res) res[resIndex] = (cnt1 - nexp1) / TMath::Sqrt(nexp1);
2319
2320 if (cnt1 < 1) ++m;
2321 if (cnt2 < 1) ++n;
2322
2323 //Habermann correction for residuals
2324 Double_t correc = (1. - sum1 / sum) * (1. - cntsum / sum);
2325 if (res) res[resIndex] /= TMath::Sqrt(correc);
2326 if (res) resIndex++;
2327 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2328 chi2 += delta * delta / cntsum;
2329 }
2330 }
2331 }
2332 }
2333 chi2 /= sum1 * sum2;
2334
2335 // flag error only when of the two histogram is zero
2336 if (m) {
2337 igood += 1;
2338 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2339 }
2340 if (n) {
2341 igood += 2;
2342 Info("Chi2TestX","There is a bin in h2 with less than 1 event.\n");
2343 }
2344
2346 return prob;
2347
2348 }
2349
2350 // unweighted - weighted comparison
2351 // case of error = 0 and content not zero is treated without problems by excluding second chi2 sum
2352 // and can be considered as a data-theory comparison
2353 if ( comparisonUW ) {
2354 Int_t resIndex = 0;
2355 for (Int_t i = i_start; i <= i_end; ++i) {
2356 for (Int_t j = j_start; j <= j_end; ++j) {
2357 for (Int_t k = k_start; k <= k_end; ++k) {
2358
2359 Int_t bin = GetBin(i, j, k);
2360
2364
2365 // case both histogram have zero bin contents
2366 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2367 --ndf; //no data means one degree of freedom less
2368 continue;
2369 }
2370
2371 // case weighted histogram has zero bin content and error
2372 if (cnt2 * cnt2 == 0 && e2sq == 0) {
2373 if (sumw2 > 0) {
2374 // use as approximated error as 1 scaled by a scaling ratio
2375 // estimated from the total sum weight and sum weight squared
2376 e2sq = sumw2 / sum2;
2377 }
2378 else {
2379 // return error because infinite discrepancy here:
2380 // bin1 != 0 and bin2 =0 in a histogram with all errors zero
2381 Error("Chi2TestX","Hist2 has in bin (%d,%d,%d) zero content and zero errors\n", i, j, k);
2382 chi2 = 0; return 0;
2383 }
2384 }
2385
2386 if (cnt1 < 1) m++;
2387 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2388
2389 Double_t var1 = sum2 * cnt2 - sum1 * e2sq;
2390 Double_t var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2391
2392 // if cnt1 is zero and cnt2 = 1 and sum1 = sum2 var1 = 0 && var2 == 0
2393 // approximate by incrementing cnt1
2394 // LM (this need to be fixed for numerical errors)
2395 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2396 sum1++;
2397 cnt1++;
2398 var1 = sum2 * cnt2 - sum1 * e2sq;
2399 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2400 }
2402
2403 while (var1 + var2 == 0) {
2404 sum1++;
2405 cnt1++;
2406 var1 = sum2 * cnt2 - sum1 * e2sq;
2407 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2408 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2409 sum1++;
2410 cnt1++;
2411 var1 = sum2 * cnt2 - sum1 * e2sq;
2412 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2413 }
2415 }
2416
2417 Double_t probb = (var1 + var2) / (2. * sum2 * sum2);
2418
2421
2424
2425 chi2 += delta1 * delta1 / nexp1;
2426
2427 if (e2sq > 0) {
2428 chi2 += delta2 * delta2 / e2sq;
2429 }
2430
2431 if (res) {
2432 if (e2sq > 0) {
2433 Double_t temp1 = sum2 * e2sq / var2;
2434 Double_t temp2 = 1.0 + (sum1 * e2sq - sum2 * cnt2) / var2;
2435 temp2 = temp1 * temp1 * sum1 * probb * (1.0 - probb) + temp2 * temp2 * e2sq / 4.0;
2436 // invert sign here
2437 res[resIndex] = - delta2 / TMath::Sqrt(temp2);
2438 }
2439 else
2440 res[resIndex] = delta1 / TMath::Sqrt(nexp1);
2441 resIndex++;
2442 }
2443 }
2444 }
2445 }
2446
2447 if (m) {
2448 igood += 1;
2449 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2450 }
2451 if (n) {
2452 igood += 2;
2453 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2454 }
2455
2456 Double_t prob = TMath::Prob(chi2, ndf);
2457
2458 return prob;
2459 }
2460
2461 // weighted - weighted comparison
2462 if (comparisonWW) {
2463 Int_t resIndex = 0;
2464 for (Int_t i = i_start; i <= i_end; ++i) {
2465 for (Int_t j = j_start; j <= j_end; ++j) {
2466 for (Int_t k = k_start; k <= k_end; ++k) {
2467
2468 Int_t bin = GetBin(i, j, k);
2473
2474 // case both histogram have zero bin contents
2475 // (use square of content to avoid numerical errors)
2476 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2477 --ndf; //no data means one degree of freedom less
2478 continue;
2479 }
2480
2481 if (e1sq == 0 && e2sq == 0) {
2482 // cannot treat case of booth histogram have zero zero errors
2483 Error("Chi2TestX","h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
2484 chi2 = 0; return 0;
2485 }
2486
2487 Double_t sigma = sum1 * sum1 * e2sq + sum2 * sum2 * e1sq;
2488 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2489 chi2 += delta * delta / sigma;
2490
2491 if (res) {
2492 Double_t temp = cnt1 * sum1 * e2sq + cnt2 * sum2 * e1sq;
2493 Double_t probb = temp / sigma;
2494 Double_t z = 0;
2495 if (e1sq > e2sq) {
2496 Double_t d1 = cnt1 - sum1 * probb;
2497 Double_t s1 = e1sq * ( 1. - e2sq * sum1 * sum1 / sigma );
2498 z = d1 / TMath::Sqrt(s1);
2499 }
2500 else {
2501 Double_t d2 = cnt2 - sum2 * probb;
2502 Double_t s2 = e2sq * ( 1. - e1sq * sum2 * sum2 / sigma );
2503 z = -d2 / TMath::Sqrt(s2);
2504 }
2505 res[resIndex] = z;
2506 resIndex++;
2507 }
2508
2509 if (e1sq > 0 && cnt1 * cnt1 / e1sq < 10) m++;
2510 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2511 }
2512 }
2513 }
2514 if (m) {
2515 igood += 1;
2516 Info("Chi2TestX","There is a bin in h1 with less than 10 effective events.\n");
2517 }
2518 if (n) {
2519 igood += 2;
2520 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2521 }
2522 Double_t prob = TMath::Prob(chi2, ndf);
2523 return prob;
2524 }
2525 return 0;
2526}
2527////////////////////////////////////////////////////////////////////////////////
2528/// Compute and return the chisquare of this histogram with respect to a function
2529/// The chisquare is computed by weighting each histogram point by the bin error
2530/// By default the full range of the histogram is used, unless TAxis::SetRange or TAxis::SetRangeUser was called before.
2531/// Use option "R" for restricting the chisquare calculation to the given range of the function
2532/// Use option "L" for using the chisquare based on the poisson likelihood (Baker-Cousins Chisquare)
2533/// Use option "P" for using the Pearson chisquare based on the expected bin errors
2534/// Use option "I" for using the integral of the function in each bin instead of the value at the bin center
2535
2537{
2538 if (!func) {
2539 Error("Chisquare","Function pointer is Null - return -1");
2540 return -1;
2541 }
2542
2543 TString opt(option); opt.ToUpper();
2544 bool useRange = opt.Contains("R");
2545 bool useIntegral = opt.Contains("I");
2546 ROOT::Fit::EChisquareType type = ROOT::Fit::EChisquareType::kNeyman; // default chi2 with observed error
2549
2550 return ROOT::Fit::Chisquare(*this, *func, useRange, type, useIntegral);
2551}
2552
2553////////////////////////////////////////////////////////////////////////////////
2554/// Remove all the content from the underflow and overflow bins, without changing the number of entries
2555/// After calling this method, every undeflow and overflow bins will have content 0.0
2556/// The Sumw2 is also cleared, since there is no more content in the bins
2557
2559{
2560 for (Int_t bin = 0; bin < fNcells; ++bin)
2562 UpdateBinContent(bin, 0.0);
2563 if (fSumw2.fN) fSumw2.fArray[bin] = 0.0;
2564 }
2565}
2566
2567////////////////////////////////////////////////////////////////////////////////
2568/// Compute integral (normalized cumulative sum of bins) w/o under/overflows
2569/// The result is stored in fIntegral and used by the GetRandom functions.
2570/// This function is automatically called by GetRandom when the fIntegral
2571/// array does not exist or when the number of entries in the histogram
2572/// has changed since the previous call to GetRandom.
2573/// The resulting integral is normalized to 1.
2574/// If the routine is called with the onlyPositive flag set an error will
2575/// be produced in case of negative bin content and a NaN value returned
2576/// \param onlyPositive If set to true, an error will be produced and NaN will be returned
2577/// when a bin with negative number of entries is encountered.
2578/// \param option
2579/// - `""` (default) Compute the cumulative density function assuming current bin contents represent counts.
2580/// - `"width"` Computes the cumulative density function assuming current bin contents represent densities.
2581/// \return 1 if success, 0 if integral is zero, NAN if onlyPositive-test fails
2582
2584{
2585 if (fBuffer) BufferEmpty();
2587 // delete previously computed integral (if any)
2588 if (fIntegral) delete [] fIntegral;
2589
2590 // - Allocate space to store the integral and compute integral
2594 Int_t nbins = nbinsx * nbinsy * nbinsz;
2595
2596 fIntegral = new Double_t[nbins + 2];
2597 Int_t ibin = 0; fIntegral[ibin] = 0;
2598
2599 for (Int_t binz=1; binz <= nbinsz; ++binz) {
2601 for (Int_t biny=1; biny <= nbinsy; ++biny) {
2603 for (Int_t binx=1; binx <= nbinsx; ++binx) {
2605 ++ibin;
2607 if (useArea)
2608 y *= xWidth * yWidth * zWidth;
2609
2610 if (onlyPositive && y < 0) {
2611 Error("ComputeIntegral","Bin content is negative - return a NaN value");
2612 fIntegral[nbins] = TMath::QuietNaN();
2613 break;
2614 }
2615 fIntegral[ibin] = fIntegral[ibin - 1] + y;
2616 }
2617 }
2618 }
2619
2620 // - Normalize integral to 1
2621 if (fIntegral[nbins] == 0 ) {
2622 Error("ComputeIntegral", "Integral = 0, no hits in histogram bins (excluding over/underflow).");
2623 return 0;
2624 }
2625 for (Int_t bin=1; bin <= nbins; ++bin) fIntegral[bin] /= fIntegral[nbins];
2626 fIntegral[nbins+1] = fEntries;
2627 return fIntegral[nbins];
2628}
2629
2630////////////////////////////////////////////////////////////////////////////////
2631/// Return a pointer to the array of bins integral.
2632/// if the pointer fIntegral is null, TH1::ComputeIntegral is called
2633/// The array dimension is the number of bins in the histograms
2634/// including underflow and overflow (fNCells)
2635/// the last value integral[fNCells] is set to the number of entries of
2636/// the histogram
2637
2639{
2640 if (!fIntegral) ComputeIntegral();
2641 return fIntegral;
2642}
2643
2644////////////////////////////////////////////////////////////////////////////////
2645/// Return a pointer to a histogram containing the cumulative content.
2646/// The cumulative can be computed both in the forward (default) or backward
2647/// direction; the name of the new histogram is constructed from
2648/// the name of this histogram with the suffix "suffix" appended provided
2649/// by the user. If not provided a default suffix="_cumulative" is used.
2650///
2651/// The cumulative distribution is formed by filling each bin of the
2652/// resulting histogram with the sum of that bin and all previous
2653/// (forward == kTRUE) or following (forward = kFALSE) bins.
2654///
2655/// Note: while cumulative distributions make sense in one dimension, you
2656/// may not be getting what you expect in more than 1D because the concept
2657/// of a cumulative distribution is much trickier to define; make sure you
2658/// understand the order of summation before you use this method with
2659/// histograms of dimension >= 2.
2660///
2661/// Note 2: By default the cumulative is computed from bin 1 to Nbins
2662/// If an axis range is set, values between the minimum and maximum of the range
2663/// are set.
2664/// Setting an axis range can also be used for including underflow and overflow in
2665/// the cumulative (e.g. by setting h->GetXaxis()->SetRange(0, h->GetNbinsX()+1); )
2667
2668TH1 *TH1::GetCumulative(Bool_t forward, const char* suffix) const
2669{
2670 const Int_t firstX = fXaxis.GetFirst();
2671 const Int_t lastX = fXaxis.GetLast();
2672 const Int_t firstY = (fDimension > 1) ? fYaxis.GetFirst() : 1;
2673 const Int_t lastY = (fDimension > 1) ? fYaxis.GetLast() : 1;
2674 const Int_t firstZ = (fDimension > 1) ? fZaxis.GetFirst() : 1;
2675 const Int_t lastZ = (fDimension > 1) ? fZaxis.GetLast() : 1;
2676
2678 hintegrated->Reset();
2679 Double_t sum = 0.;
2680 Double_t esum = 0;
2681 if (forward) { // Forward computation
2682 for (Int_t binz = firstZ; binz <= lastZ; ++binz) {
2683 for (Int_t biny = firstY; biny <= lastY; ++biny) {
2684 for (Int_t binx = firstX; binx <= lastX; ++binx) {
2685 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2687 hintegrated->AddBinContent(bin, sum);
2688 if (fSumw2.fN) {
2690 hintegrated->fSumw2.fArray[bin] = esum;
2691 }
2692 }
2693 }
2694 }
2695 } else { // Backward computation
2696 for (Int_t binz = lastZ; binz >= firstZ; --binz) {
2697 for (Int_t biny = lastY; biny >= firstY; --biny) {
2698 for (Int_t binx = lastX; binx >= firstX; --binx) {
2699 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2701 hintegrated->AddBinContent(bin, sum);
2702 if (fSumw2.fN) {
2704 hintegrated->fSumw2.fArray[bin] = esum;
2705 }
2706 }
2707 }
2708 }
2709 }
2710 return hintegrated;
2711}
2712
2713////////////////////////////////////////////////////////////////////////////////
2714/// Copy this histogram structure to newth1.
2715///
2716/// Note that this function does not copy the list of associated functions.
2717/// Use TObject::Clone to make a full copy of a histogram.
2718///
2719/// Note also that the histogram it will be created in gDirectory (if AddDirectoryStatus()=true)
2720/// or will not be added to any directory if AddDirectoryStatus()=false
2721/// independently of the current directory stored in the original histogram
2722
2723void TH1::Copy(TObject &obj) const
2724{
2725 if (((TH1&)obj).fDirectory) {
2726 // We are likely to change the hash value of this object
2727 // with TNamed::Copy, to keep things correct, we need to
2728 // clean up its existing entries.
2729 ((TH1&)obj).fDirectory->Remove(&obj);
2730 ((TH1&)obj).fDirectory = nullptr;
2731 }
2732 TNamed::Copy(obj);
2733 ((TH1&)obj).fDimension = fDimension;
2734 ((TH1&)obj).fNormFactor= fNormFactor;
2735 ((TH1&)obj).fNcells = fNcells;
2736 ((TH1&)obj).fBarOffset = fBarOffset;
2737 ((TH1&)obj).fBarWidth = fBarWidth;
2738 ((TH1&)obj).fOption = fOption;
2739 ((TH1&)obj).fBinStatErrOpt = fBinStatErrOpt;
2740 ((TH1&)obj).fBufferSize= fBufferSize;
2741 // copy the Buffer
2742 // delete first a previously existing buffer
2743 if (((TH1&)obj).fBuffer != nullptr) {
2744 delete [] ((TH1&)obj).fBuffer;
2745 ((TH1&)obj).fBuffer = nullptr;
2746 }
2747 if (fBuffer) {
2748 Double_t *buf = new Double_t[fBufferSize];
2749 for (Int_t i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
2750 // obj.fBuffer has been deleted before
2751 ((TH1&)obj).fBuffer = buf;
2752 }
2753
2754 // copy bin contents (this should be done by the derived classes, since TH1 does not store the bin content)
2755 // Do this in case derived from TArray
2756 TArray* a = dynamic_cast<TArray*>(&obj);
2757 if (a) {
2758 a->Set(fNcells);
2759 for (Int_t i = 0; i < fNcells; i++)
2761 }
2762
2763 ((TH1&)obj).fEntries = fEntries;
2764
2765 // which will call BufferEmpty(0) and set fBuffer[0] to a Maybe one should call
2766 // assignment operator on the TArrayD
2767
2768 ((TH1&)obj).fTsumw = fTsumw;
2769 ((TH1&)obj).fTsumw2 = fTsumw2;
2770 ((TH1&)obj).fTsumwx = fTsumwx;
2771 ((TH1&)obj).fTsumwx2 = fTsumwx2;
2772 ((TH1&)obj).fMaximum = fMaximum;
2773 ((TH1&)obj).fMinimum = fMinimum;
2774
2775 TAttLine::Copy(((TH1&)obj));
2776 TAttFill::Copy(((TH1&)obj));
2777 TAttMarker::Copy(((TH1&)obj));
2778 fXaxis.Copy(((TH1&)obj).fXaxis);
2779 fYaxis.Copy(((TH1&)obj).fYaxis);
2780 fZaxis.Copy(((TH1&)obj).fZaxis);
2781 ((TH1&)obj).fXaxis.SetParent(&obj);
2782 ((TH1&)obj).fYaxis.SetParent(&obj);
2783 ((TH1&)obj).fZaxis.SetParent(&obj);
2784 fContour.Copy(((TH1&)obj).fContour);
2785 fSumw2.Copy(((TH1&)obj).fSumw2);
2786 // fFunctions->Copy(((TH1&)obj).fFunctions);
2787 // when copying an histogram if the AddDirectoryStatus() is true it
2788 // will be added to gDirectory independently of the fDirectory stored.
2789 // and if the AddDirectoryStatus() is false it will not be added to
2790 // any directory (fDirectory = nullptr)
2792 gDirectory->Append(&obj);
2793 ((TH1&)obj).fFunctions->UseRWLock();
2794 ((TH1&)obj).fDirectory = gDirectory;
2795 } else
2796 ((TH1&)obj).fDirectory = nullptr;
2797
2798}
2799
2800////////////////////////////////////////////////////////////////////////////////
2801/// Make a complete copy of the underlying object. If 'newname' is set,
2802/// the copy's name will be set to that name.
2803
2804TObject* TH1::Clone(const char* newname) const
2805{
2806 TH1* obj = (TH1*)IsA()->GetNew()(nullptr);
2807 Copy(*obj);
2808
2809 // Now handle the parts that Copy doesn't do
2810 if(fFunctions) {
2811 // The Copy above might have published 'obj' to the ListOfCleanups.
2812 // Clone can call RecursiveRemove, for example via TCheckHashRecursiveRemoveConsistency
2813 // when dictionary information is initialized, so we need to
2814 // keep obj->fFunction valid during its execution and
2815 // protect the update with the write lock.
2816
2817 // Reset stats parent - else cloning the stats will clone this histogram, too.
2818 auto oldstats = dynamic_cast<TVirtualPaveStats*>(fFunctions->FindObject("stats"));
2819 TObject *oldparent = nullptr;
2820 if (oldstats) {
2821 oldparent = oldstats->GetParent();
2822 oldstats->SetParent(nullptr);
2823 }
2824
2825 auto newlist = (TList*)fFunctions->Clone();
2826
2827 if (oldstats)
2828 oldstats->SetParent(oldparent);
2829 auto newstats = dynamic_cast<TVirtualPaveStats*>(obj->fFunctions->FindObject("stats"));
2830 if (newstats)
2831 newstats->SetParent(obj);
2832
2833 auto oldlist = obj->fFunctions;
2834 {
2836 obj->fFunctions = newlist;
2837 }
2838 delete oldlist;
2839 }
2840 if(newname && strlen(newname) ) {
2841 obj->SetName(newname);
2842 }
2843 return obj;
2844}
2845
2846////////////////////////////////////////////////////////////////////////////////
2847/// Callback to perform the automatic addition of the histogram to the given directory.
2848///
2849/// This callback is used to register a histogram to the current directory when a TKey
2850/// is read or an object is being cloned using TDirectory::CloneObject().
2851
2853{
2855 if (addStatus) {
2856 SetDirectory(dir);
2857 if (dir) {
2859 }
2860 }
2861}
2862
2863////////////////////////////////////////////////////////////////////////////////
2864/// Compute distance from point px,py to a line.
2865///
2866/// Compute the closest distance of approach from point px,py to elements
2867/// of a histogram.
2868/// The distance is computed in pixels units.
2869///
2870/// #### Algorithm:
2871/// Currently, this simple model computes the distance from the mouse
2872/// to the histogram contour only.
2873
2875{
2876 if (!fPainter) return 9999;
2877 return fPainter->DistancetoPrimitive(px,py);
2878}
2879
2880////////////////////////////////////////////////////////////////////////////////
2881/// Performs the operation: `this = this/(c1*f1)`
2882/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2883///
2884/// Only bins inside the function range are recomputed.
2885/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2886/// you should call Sumw2 before making this operation.
2887/// This is particularly important if you fit the histogram after TH1::Divide
2888///
2889/// The function return kFALSE if the divide operation failed
2890
2892{
2893 if (!f1) {
2894 Error("Divide","Attempt to divide by a non-existing function");
2895 return kFALSE;
2896 }
2897
2898 // delete buffer if it is there since it will become invalid
2899 if (fBuffer) BufferEmpty(1);
2900
2901 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of
2902 Int_t ny = GetNbinsY() + 2;
2903 Int_t nz = GetNbinsZ() + 2;
2904 if (fDimension < 2) ny = 1;
2905 if (fDimension < 3) nz = 1;
2906
2907
2908 SetMinimum();
2909 SetMaximum();
2910
2911 // - Loop on bins (including underflows/overflows)
2912 Int_t bin, binx, biny, binz;
2913 Double_t cu, w;
2914 Double_t xx[3];
2915 Double_t *params = nullptr;
2916 f1->InitArgs(xx,params);
2917 for (binz = 0; binz < nz; ++binz) {
2918 xx[2] = fZaxis.GetBinCenter(binz);
2919 for (biny = 0; biny < ny; ++biny) {
2920 xx[1] = fYaxis.GetBinCenter(biny);
2921 for (binx = 0; binx < nx; ++binx) {
2922 xx[0] = fXaxis.GetBinCenter(binx);
2923 if (!f1->IsInside(xx)) continue;
2925 bin = binx + nx * (biny + ny * binz);
2926 cu = c1 * f1->EvalPar(xx);
2927 if (TF1::RejectedPoint()) continue;
2928 if (cu) w = RetrieveBinContent(bin) / cu;
2929 else w = 0;
2931 if (fSumw2.fN) {
2932 if (cu != 0) fSumw2.fArray[bin] = GetBinErrorSqUnchecked(bin) / (cu * cu);
2933 else fSumw2.fArray[bin] = 0;
2934 }
2935 }
2936 }
2937 }
2938 ResetStats();
2939 return kTRUE;
2940}
2941
2942////////////////////////////////////////////////////////////////////////////////
2943/// Divide this histogram by h1.
2944///
2945/// `this = this/h1`
2946/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2947/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
2948/// if not already set.
2949/// The resulting errors are calculated assuming uncorrelated histograms.
2950/// See the other TH1::Divide that gives the possibility to optionally
2951/// compute binomial errors.
2952///
2953/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2954/// you should call Sumw2 before making this operation.
2955/// This is particularly important if you fit the histogram after TH1::Scale
2956///
2957/// The function return kFALSE if the divide operation failed
2958
2959Bool_t TH1::Divide(const TH1 *h1)
2960{
2961 if (!h1) {
2962 Error("Divide", "Input histogram passed does not exist (NULL).");
2963 return kFALSE;
2964 }
2965
2966 // delete buffer if it is there since it will become invalid
2967 if (fBuffer) BufferEmpty(1);
2968
2969 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins) {
2970 return false;
2971 }
2972
2973 // Create Sumw2 if h1 has Sumw2 set
2974 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
2975
2976 // - Loop on bins (including underflows/overflows)
2977 for (Int_t i = 0; i < fNcells; ++i) {
2980 if (c1) UpdateBinContent(i, c0 / c1);
2981 else UpdateBinContent(i, 0);
2982
2983 if(fSumw2.fN) {
2984 if (c1 == 0) { fSumw2.fArray[i] = 0; continue; }
2985 Double_t c1sq = c1 * c1;
2987 }
2988 }
2989 ResetStats();
2990 return kTRUE;
2991}
2992
2993////////////////////////////////////////////////////////////////////////////////
2994/// Replace contents of this histogram by the division of h1 by h2.
2995///
2996/// `this = c1*h1/(c2*h2)`
2997///
2998/// If errors are defined (see TH1::Sumw2), errors are also recalculated
2999/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
3000/// if not already set.
3001/// The resulting errors are calculated assuming uncorrelated histograms.
3002/// However, if option ="B" is specified, Binomial errors are computed.
3003/// In this case c1 and c2 do not make real sense and they are ignored.
3004///
3005/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
3006/// you should call Sumw2 before making this operation.
3007/// This is particularly important if you fit the histogram after TH1::Divide
3008///
3009/// Please note also that in the binomial case errors are calculated using standard
3010/// binomial statistics, which means when b1 = b2, the error is zero.
3011/// If you prefer to have efficiency errors not going to zero when the efficiency is 1, you must
3012/// use the function TGraphAsymmErrors::BayesDivide, which will return an asymmetric and non-zero lower
3013/// error for the case b1=b2.
3014///
3015/// The function return kFALSE if the divide operation failed
3016
3018{
3019
3020 TString opt = option;
3021 opt.ToLower();
3022 Bool_t binomial = kFALSE;
3023 if (opt.Contains("b")) binomial = kTRUE;
3024 if (!h1 || !h2) {
3025 Error("Divide", "At least one of the input histograms passed does not exist (NULL).");
3026 return kFALSE;
3027 }
3028
3029 // delete buffer if it is there since it will become invalid
3030 if (fBuffer) BufferEmpty(1);
3031
3032 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins ||
3033 LoggedInconsistency("Divide", h1, h2) >= kDifferentNumberOfBins) {
3034 return false;
3035 }
3036
3037 if (!c2) {
3038 Error("Divide","Coefficient of dividing histogram cannot be zero");
3039 return kFALSE;
3040 }
3041
3042 // Create Sumw2 if h1 or h2 have Sumw2 set, or if binomial errors are explicitly requested
3043 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0 || binomial)) Sumw2();
3044
3045 SetMinimum();
3046 SetMaximum();
3047
3048 // - Loop on bins (including underflows/overflows)
3049 for (Int_t i = 0; i < fNcells; ++i) {
3051 Double_t b2 = h2->RetrieveBinContent(i);
3052 if (b2) UpdateBinContent(i, c1 * b1 / (c2 * b2));
3053 else UpdateBinContent(i, 0);
3054
3055 if (fSumw2.fN) {
3056 if (b2 == 0) { fSumw2.fArray[i] = 0; continue; }
3057 Double_t b1sq = b1 * b1; Double_t b2sq = b2 * b2;
3058 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
3061 if (binomial) {
3062 if (b1 != b2) {
3063 // in the case of binomial statistics c1 and c2 must be 1 otherwise it does not make sense
3064 // c1 and c2 are ignored
3065 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));//this is the formula in Hbook/Hoper1
3066 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2); // old formula from G. Flucke
3067 // formula which works also for weighted histogram (see http://root-forum.cern.ch/viewtopic.php?t=3753 )
3068 fSumw2.fArray[i] = TMath::Abs( ( (1. - 2.* b1 / b2) * e1sq + b1sq * e2sq / b2sq ) / b2sq );
3069 } else {
3070 //in case b1=b2 error is zero
3071 //use TGraphAsymmErrors::BayesDivide for getting the asymmetric error not equal to zero
3072 fSumw2.fArray[i] = 0;
3073 }
3074 } else {
3075 fSumw2.fArray[i] = c1sq * c2sq * (e1sq * b2sq + e2sq * b1sq) / (c2sq * c2sq * b2sq * b2sq);
3076 }
3077 }
3078 }
3079 ResetStats();
3080 if (binomial)
3081 // in case of binomial division use denominator for number of entries
3082 SetEntries ( h2->GetEntries() );
3083
3084 return kTRUE;
3085}
3086
3087////////////////////////////////////////////////////////////////////////////////
3088/// Draw this histogram with options.
3089///
3090/// Histograms are drawn via the THistPainter class. Each histogram has
3091/// a pointer to its own painter (to be usable in a multithreaded program).
3092/// The same histogram can be drawn with different options in different pads.
3093/// If a histogram is updated after it has been drawn, the updated data will
3094/// be shown the next time the pad is updated. One does not need to
3095/// redraw the histogram.
3096///
3097/// When a histogram is deleted, the histogram is **automatically removed from
3098/// all pads where it was drawn**. If a histogram should be modified or deleted
3099/// without affecting what is drawn, it should be drawn using DrawCopy().
3100///
3101/// By default, TH1::Draw clears the current pad. Passing the option "SAME", the
3102/// histogram will be drawn on top of what's in the pad.
3103/// One can use TH1::SetMaximum and TH1::SetMinimum to force a particular
3104/// value for the maximum or the minimum scale on the plot.
3105///
3106/// TH1::UseCurrentStyle can be used to change all histogram graphics
3107/// attributes to correspond to the current selected style.
3108/// This function must be called for each histogram.
3109/// In case one reads and draws many histograms from a file, one can force
3110/// the histograms to inherit automatically the current graphics style
3111/// by calling before gROOT->ForceStyle();
3112///
3113/// See the THistPainter class for a description of all the drawing options.
3114
3116{
3117 TString opt1 = option; opt1.ToLower();
3119 Int_t index = opt1.Index("same");
3120
3121 // Check if the string "same" is part of a TCutg name.
3122 if (index>=0) {
3123 Int_t indb = opt1.Index("[");
3124 if (indb>=0) {
3125 Int_t indk = opt1.Index("]");
3126 if (index>indb && index<indk) index = -1;
3127 }
3128 }
3129
3130 // If there is no pad or an empty pad the "same" option is ignored.
3131 if (gPad) {
3132 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
3133 if (index>=0) {
3134 if (gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
3135 gPad->GetY1() == 0 && gPad->GetY2() == 1 &&
3136 gPad->GetListOfPrimitives()->GetSize()==0) opt2.Remove(index,4);
3137 } else {
3138 //the following statement is necessary in case one attempts to draw
3139 //a temporary histogram already in the current pad
3140 if (TestBit(kCanDelete)) gPad->Remove(this);
3141 gPad->Clear();
3142 }
3143 gPad->IncrementPaletteColor(1, opt1);
3144 } else {
3145 if (index>=0) opt2.Remove(index,4);
3146 }
3147
3148 AppendPad(opt2.Data());
3149}
3150
3151////////////////////////////////////////////////////////////////////////////////
3152/// Copy this histogram and Draw in the current pad.
3153///
3154/// Once the histogram is drawn into the pad, the original and its drawn copy can be modified or deleted without
3155/// affecting each other. The copied histogram will be owned by the pad, and is deleted when the pad is cleared.
3156///
3157/// DrawCopy() is useful if the original histogram is a temporary, e.g. from code such as
3158/// ~~~ {.cpp}
3159/// void someFunction(...) {
3160/// TH1D histogram(...);
3161/// histogram.DrawCopy();
3162///
3163/// // or equivalently
3164/// std::unique_ptr<TH1F> histogram(...);
3165/// histogram->DrawCopy();
3166/// }
3167/// ~~~
3168/// If Draw() has been used, the histograms would disappear from the canvas at the end of this function.
3169///
3170/// By default a postfix "_copy" is added to the histogram name. Pass an empty postfix in case
3171/// you want to draw a histogram with the same name.
3172///
3173/// See Draw() for the list of options.
3174///
3175/// In contrast to TObject::DrawClone(), DrawCopy
3176/// - Ignores `gROOT->SetSelectedPad()`.
3177/// - Does not register the histogram to any directory.
3178/// - And can cycle through a colour palette when multiple objects are drawn with auto colouring.
3179
3180TH1 *TH1::DrawCopy(Option_t *option, const char * name_postfix) const
3181{
3182 TString opt = option;
3183 opt.ToLower();
3184 if (gPad && !opt.Contains("same")) gPad->Clear();
3186 if (name_postfix) newName.Form("%s%s", GetName(), name_postfix);
3187 TH1 *newth1 = (TH1 *)Clone(newName.Data());
3188 newth1->SetDirectory(nullptr);
3189 newth1->SetBit(kCanDelete);
3190 if (gPad) gPad->IncrementPaletteColor(1, opt);
3191
3192 newth1->AppendPad(option);
3193 return newth1;
3194}
3195
3196////////////////////////////////////////////////////////////////////////////////
3197/// Draw a normalized copy of this histogram.
3198///
3199/// A clone of this histogram is normalized to norm and drawn with option.
3200/// A pointer to the normalized histogram is returned.
3201/// The contents of the histogram copy are scaled such that the new
3202/// sum of weights (excluding under and overflow) is equal to norm.
3203/// Note that the returned normalized histogram is not added to the list
3204/// of histograms in the current directory in memory.
3205/// It is the user's responsibility to delete this histogram.
3206/// The kCanDelete bit is set for the returned object. If a pad containing
3207/// this copy is cleared, the histogram will be automatically deleted.
3208///
3209/// See Draw for the list of options
3210
3212{
3214 if (sum == 0) {
3215 Error("DrawNormalized","Sum of weights is null. Cannot normalize histogram: %s",GetName());
3216 return nullptr;
3217 }
3218
3219 TDirectory::TContext ctx{nullptr};
3220 TH1 *h = (TH1*)Clone();
3222 // in case of drawing with error options - scale correctly the error
3223 TString opt(option); opt.ToUpper();
3224 if (fSumw2.fN == 0) {
3225 h->Sumw2();
3226 // do not use in this case the "Error option " for drawing which is enabled by default since the normalized histogram has now errors
3227 if (opt.IsNull() || opt == "SAME") opt += "HIST";
3228 }
3229 h->Scale(norm/sum);
3230 if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
3231 if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
3232 h->Draw(opt);
3233
3234 return h;
3235}
3236
3237////////////////////////////////////////////////////////////////////////////////
3238/// Display a panel with all histogram drawing options.
3239///
3240/// See class TDrawPanelHist for example
3241
3242void TH1::DrawPanel()
3243{
3244 if (!fPainter) {Draw(); if (gPad) gPad->Update();}
3245 if (fPainter) fPainter->DrawPanel();
3246}
3247
3248////////////////////////////////////////////////////////////////////////////////
3249/// Evaluate function f1 at the center of bins of this histogram.
3250///
3251/// - If option "R" is specified, the function is evaluated only
3252/// for the bins included in the function range.
3253/// - If option "A" is specified, the value of the function is added to the
3254/// existing bin contents
3255/// - If option "S" is specified, the value of the function is used to
3256/// generate a value, distributed according to the Poisson
3257/// distribution, with f1 as the mean.
3258
3260{
3261 Double_t x[3];
3262 Int_t range, stat, add;
3263 if (!f1) return;
3264
3265 TString opt = option;
3266 opt.ToLower();
3267 if (opt.Contains("a")) add = 1;
3268 else add = 0;
3269 if (opt.Contains("s")) stat = 1;
3270 else stat = 0;
3271 if (opt.Contains("r")) range = 1;
3272 else range = 0;
3273
3274 // delete buffer if it is there since it will become invalid
3275 if (fBuffer) BufferEmpty(1);
3276
3280 if (!add) Reset();
3281
3282 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
3283 x[2] = fZaxis.GetBinCenter(binz);
3284 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
3285 x[1] = fYaxis.GetBinCenter(biny);
3286 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
3288 x[0] = fXaxis.GetBinCenter(binx);
3289 if (range && !f1->IsInside(x)) continue;
3290 Double_t fu = f1->Eval(x[0], x[1], x[2]);
3291 if (stat) fu = gRandom->PoissonD(fu);
3294 }
3295 }
3296 }
3297}
3298
3299////////////////////////////////////////////////////////////////////////////////
3300/// Execute action corresponding to one event.
3301///
3302/// This member function is called when a histogram is clicked with the locator
3303///
3304/// If Left button clicked on the bin top value, then the content of this bin
3305/// is modified according to the new position of the mouse when it is released.
3306
3307void TH1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3308{
3309 if (fPainter) fPainter->ExecuteEvent(event, px, py);
3310}
3311
3312////////////////////////////////////////////////////////////////////////////////
3313/// This function allows to do discrete Fourier transforms of TH1 and TH2.
3314/// Available transform types and flags are described below.
3315///
3316/// To extract more information about the transform, use the function
3317/// TVirtualFFT::GetCurrentTransform() to get a pointer to the current
3318/// transform object.
3319///
3320/// \param[out] h_output histogram for the output. If a null pointer is passed, a new histogram is created
3321/// and returned, otherwise, the provided histogram is used and should be big enough
3322/// \param[in] option option parameters consists of 3 parts:
3323/// - option on what to return
3324/// - "RE" - returns a histogram of the real part of the output
3325/// - "IM" - returns a histogram of the imaginary part of the output
3326/// - "MAG"- returns a histogram of the magnitude of the output
3327/// - "PH" - returns a histogram of the phase of the output
3328/// - option of transform type
3329/// - "R2C" - real to complex transforms - default
3330/// - "R2HC" - real to halfcomplex (special format of storing output data,
3331/// results the same as for R2C)
3332/// - "DHT" - discrete Hartley transform
3333/// real to real transforms (sine and cosine):
3334/// - "R2R_0", "R2R_1", "R2R_2", "R2R_3" - discrete cosine transforms of types I-IV
3335/// - "R2R_4", "R2R_5", "R2R_6", "R2R_7" - discrete sine transforms of types I-IV
3336/// To specify the type of each dimension of a 2-dimensional real to real
3337/// transform, use options of form "R2R_XX", for example, "R2R_02" for a transform,
3338/// which is of type "R2R_0" in 1st dimension and "R2R_2" in the 2nd.
3339/// - option of transform flag
3340/// - "ES" (from "estimate") - no time in preparing the transform, but probably sub-optimal
3341/// performance
3342/// - "M" (from "measure") - some time spend in finding the optimal way to do the transform
3343/// - "P" (from "patient") - more time spend in finding the optimal way to do the transform
3344/// - "EX" (from "exhaustive") - the most optimal way is found
3345/// This option should be chosen depending on how many transforms of the same size and
3346/// type are going to be done. Planning is only done once, for the first transform of this
3347/// size and type. Default is "ES".
3348///
3349/// Examples of valid options: "Mag R2C M" "Re R2R_11" "Im R2C ES" "PH R2HC EX"
3350
3352{
3353
3354 Int_t ndim[3];
3355 ndim[0] = this->GetNbinsX();
3356 ndim[1] = this->GetNbinsY();
3357 ndim[2] = this->GetNbinsZ();
3358
3360 TString opt = option;
3361 opt.ToUpper();
3362 if (!opt.Contains("2R")){
3363 if (!opt.Contains("2C") && !opt.Contains("2HC") && !opt.Contains("DHT")) {
3364 //no type specified, "R2C" by default
3365 opt.Append("R2C");
3366 }
3367 fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
3368 }
3369 else {
3370 //find the kind of transform
3371 Int_t ind = opt.Index("R2R", 3);
3372 Int_t *kind = new Int_t[2];
3373 char t;
3374 t = opt[ind+4];
3375 kind[0] = atoi(&t);
3376 if (h_output->GetDimension()>1) {
3377 t = opt[ind+5];
3378 kind[1] = atoi(&t);
3379 }
3380 fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
3381 delete [] kind;
3382 }
3383
3384 if (!fft) return nullptr;
3385 Int_t in=0;
3386 for (Int_t binx = 1; binx<=ndim[0]; binx++) {
3387 for (Int_t biny=1; biny<=ndim[1]; biny++) {
3388 for (Int_t binz=1; binz<=ndim[2]; binz++) {
3389 fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
3390 in++;
3391 }
3392 }
3393 }
3394 fft->Transform();
3396 return h_output;
3397}
3398
3399////////////////////////////////////////////////////////////////////////////////
3400/// Increment bin with abscissa X by 1.
3401///
3402/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3403/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3404///
3405/// If the storage of the sum of squares of weights has been triggered,
3406/// via the function Sumw2, then the sum of the squares of weights is incremented
3407/// by 1 in the bin corresponding to x.
3408///
3409/// The function returns the corresponding bin number which has its content incremented by 1
3410
3412{
3413 if (fBuffer) return BufferFill(x,1);
3414
3415 Int_t bin;
3416 fEntries++;
3417 bin =fXaxis.FindBin(x);
3418 if (bin <0) return -1;
3420 if (fSumw2.fN) ++fSumw2.fArray[bin];
3421 if (bin == 0 || bin > fXaxis.GetNbins()) {
3422 if (!GetStatOverflowsBehaviour()) return -1;
3423 }
3424 ++fTsumw;
3425 ++fTsumw2;
3426 fTsumwx += x;
3427 fTsumwx2 += x*x;
3428 return bin;
3429}
3430
3431////////////////////////////////////////////////////////////////////////////////
3432/// Increment bin with abscissa X with a weight w.
3433///
3434/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3435/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3436///
3437/// If the weight is not equal to 1, the storage of the sum of squares of
3438/// weights is automatically triggered and the sum of the squares of weights is incremented
3439/// by \f$ w^2 \f$ in the bin corresponding to x.
3440///
3441/// The function returns the corresponding bin number which has its content incremented by w
3442
3444{
3445
3446 if (fBuffer) return BufferFill(x,w);
3447
3448 Int_t bin;
3449 fEntries++;
3450 bin =fXaxis.FindBin(x);
3451 if (bin <0) return -1;
3452 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW) ) Sumw2(); // must be called before AddBinContent
3453 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3455 if (bin == 0 || bin > fXaxis.GetNbins()) {
3456 if (!GetStatOverflowsBehaviour()) return -1;
3457 }
3458 Double_t z= w;
3459 fTsumw += z;
3460 fTsumw2 += z*z;
3461 fTsumwx += z*x;
3462 fTsumwx2 += z*x*x;
3463 return bin;
3464}
3465
3466////////////////////////////////////////////////////////////////////////////////
3467/// Increment bin with namex with a weight w
3468///
3469/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3470/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3471///
3472/// If the weight is not equal to 1, the storage of the sum of squares of
3473/// weights is automatically triggered and the sum of the squares of weights is incremented
3474/// by \f$ w^2 \f$ in the bin corresponding to x.
3475///
3476/// The function returns the corresponding bin number which has its content
3477/// incremented by w.
3478
3479Int_t TH1::Fill(const char *namex, Double_t w)
3480{
3481 Int_t bin;
3482 fEntries++;
3484 if (bin <0) return -1;
3485 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3486 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3488 if (bin == 0 || bin > fXaxis.GetNbins()) return -1;
3489 Double_t z= w;
3490 fTsumw += z;
3491 fTsumw2 += z*z;
3492 // this make sense if the histogram is not expanding (the x axis cannot be extended)
3493 if (!fXaxis.CanExtend() || !fXaxis.IsAlphanumeric()) {
3495 fTsumwx += z*x;
3496 fTsumwx2 += z*x*x;
3497 }
3498 return bin;
3499}
3500
3501////////////////////////////////////////////////////////////////////////////////
3502/// Fill this histogram with an array x and weights w.
3503///
3504/// \param[in] ntimes number of entries in arrays x and w (array size must be ntimes*stride)
3505/// \param[in] x array of values to be histogrammed
3506/// \param[in] w array of weighs
3507/// \param[in] stride step size through arrays x and w
3508///
3509/// If the weight is not equal to 1, the storage of the sum of squares of
3510/// weights is automatically triggered and the sum of the squares of weights is incremented
3511/// by \f$ w^2 \f$ in the bin corresponding to x.
3512/// if w is NULL each entry is assumed a weight=1
3513
3514void TH1::FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3515{
3516 //If a buffer is activated, fill buffer
3517 if (fBuffer) {
3518 ntimes *= stride;
3519 Int_t i = 0;
3520 for (i=0;i<ntimes;i+=stride) {
3521 if (!fBuffer) break; // buffer can be deleted in BufferFill when is empty
3522 if (w) BufferFill(x[i],w[i]);
3523 else BufferFill(x[i], 1.);
3524 }
3525 // fill the remaining entries if the buffer has been deleted
3526 if (i < ntimes && !fBuffer) {
3527 auto weights = w ? &w[i] : nullptr;
3528 DoFillN((ntimes-i)/stride,&x[i],weights,stride);
3529 }
3530 return;
3531 }
3532 // call internal method
3533 DoFillN(ntimes, x, w, stride);
3534}
3535
3536////////////////////////////////////////////////////////////////////////////////
3537/// Internal method to fill histogram content from a vector
3538/// called directly by TH1::BufferEmpty
3539
3540void TH1::DoFillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3541{
3542 Int_t bin,i;
3543
3544 fEntries += ntimes;
3545 Double_t ww = 1;
3546 Int_t nbins = fXaxis.GetNbins();
3547 ntimes *= stride;
3548 for (i=0;i<ntimes;i+=stride) {
3549 bin =fXaxis.FindBin(x[i]);
3550 if (bin <0) continue;
3551 if (w) ww = w[i];
3552 if (!fSumw2.fN && ww != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3553 if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
3554 AddBinContent(bin, ww);
3555 if (bin == 0 || bin > nbins) {
3556 if (!GetStatOverflowsBehaviour()) continue;
3557 }
3558 Double_t z= ww;
3559 fTsumw += z;
3560 fTsumw2 += z*z;
3561 fTsumwx += z*x[i];
3562 fTsumwx2 += z*x[i]*x[i];
3563 }
3564}
3565
3566////////////////////////////////////////////////////////////////////////////////
3567/// Fill histogram following distribution in function fname.
3568///
3569/// @param fname : Function name used for filling the histogram
3570/// @param ntimes : number of times the histogram is filled
3571/// @param rng : (optional) Random number generator used to sample
3572///
3573///
3574/// The distribution contained in the function fname (TF1) is integrated
3575/// over the channel contents for the bin range of this histogram.
3576/// It is normalized to 1.
3577///
3578/// Getting one random number implies:
3579/// - Generating a random number between 0 and 1 (say r1)
3580/// - Look in which bin in the normalized integral r1 corresponds to
3581/// - Fill histogram channel
3582/// ntimes random numbers are generated
3583///
3584/// One can also call TF1::GetRandom to get a random variate from a function.
3585
3586void TH1::FillRandom(const char *fname, Int_t ntimes, TRandom * rng)
3587{
3588 // - Search for fname in the list of ROOT defined functions
3589 TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
3590 if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
3591
3594
3596{
3597 Int_t bin, binx, ibin, loop;
3598 Double_t r1, x;
3599
3600 // - Allocate temporary space to store the integral and compute integral
3601
3602 TAxis * xAxis = &fXaxis;
3603
3604 // in case axis of histogram is not defined use the function axis
3605 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
3607 f1->GetRange(xmin,xmax);
3608 Info("FillRandom","Using function axis and range [%g,%g]",xmin, xmax);
3609 xAxis = f1->GetHistogram()->GetXaxis();
3610 }
3611
3612 Int_t first = xAxis->GetFirst();
3613 Int_t last = xAxis->GetLast();
3614 Int_t nbinsx = last-first+1;
3615
3616 Double_t *integral = new Double_t[nbinsx+1];
3617 integral[0] = 0;
3618 for (binx=1;binx<=nbinsx;binx++) {
3619 Double_t fint = f1->Integral(xAxis->GetBinLowEdge(binx+first-1),xAxis->GetBinUpEdge(binx+first-1), 0.);
3620 integral[binx] = integral[binx-1] + fint;
3621 }
3622
3623 // - Normalize integral to 1
3624 if (integral[nbinsx] == 0 ) {
3625 delete [] integral;
3626 Error("FillRandom", "Integral = zero"); return;
3627 }
3628 for (bin=1;bin<=nbinsx;bin++) integral[bin] /= integral[nbinsx];
3629
3630 // --------------Start main loop ntimes
3631 for (loop=0;loop<ntimes;loop++) {
3632 r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
3633 ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
3634 //binx = 1 + ibin;
3635 //x = xAxis->GetBinCenter(binx); //this is not OK when SetBuffer is used
3636 x = xAxis->GetBinLowEdge(ibin+first)
3637 +xAxis->GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
3638 Fill(x);
3639 }
3640 delete [] integral;
3641}
3642
3643////////////////////////////////////////////////////////////////////////////////
3644/// Fill histogram following distribution in histogram h.
3645///
3646/// @param h : Histogram pointer used for sampling random number
3647/// @param ntimes : number of times the histogram is filled
3648/// @param rng : (optional) Random number generator used for sampling
3649///
3650/// The distribution contained in the histogram h (TH1) is integrated
3651/// over the channel contents for the bin range of this histogram.
3652/// It is normalized to 1.
3653///
3654/// Getting one random number implies:
3655/// - Generating a random number between 0 and 1 (say r1)
3656/// - Look in which bin in the normalized integral r1 corresponds to
3657/// - Fill histogram channel ntimes random numbers are generated
3658///
3659/// SPECIAL CASE when the target histogram has the same binning as the source.
3660/// in this case we simply use a poisson distribution where
3661/// the mean value per bin = bincontent/integral.
3662
3664{
3665 if (!h) { Error("FillRandom", "Null histogram"); return; }
3666 if (fDimension != h->GetDimension()) {
3667 Error("FillRandom", "Histograms with different dimensions"); return;
3668 }
3669 if (std::isnan(h->ComputeIntegral(true))) {
3670 Error("FillRandom", "Histograms contains negative bins, does not represent probabilities");
3671 return;
3672 }
3673
3674 //in case the target histogram has the same binning and ntimes much greater
3675 //than the number of bins we can use a fast method
3676 Int_t first = fXaxis.GetFirst();
3677 Int_t last = fXaxis.GetLast();
3678 Int_t nbins = last-first+1;
3679 if (ntimes > 10*nbins) {
3680 auto inconsistency = CheckConsistency(this,h);
3681 if (inconsistency != kFullyConsistent) return; // do nothing
3682 Double_t sumw = h->Integral(first,last);
3683 if (sumw == 0) return;
3684 Double_t sumgen = 0;
3685 for (Int_t bin=first;bin<=last;bin++) {
3686 Double_t mean = h->RetrieveBinContent(bin)*ntimes/sumw;
3687 Double_t cont = (rng) ? rng->Poisson(mean) : gRandom->Poisson(mean);
3688 sumgen += cont;
3690 if (fSumw2.fN) fSumw2.fArray[bin] += cont;
3691 }
3692
3693 // fix for the fluctuations in the total number n
3694 // since we use Poisson instead of multinomial
3695 // add a correction to have ntimes as generated entries
3696 Int_t i;
3697 if (sumgen < ntimes) {
3698 // add missing entries
3699 for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
3700 {
3701 Double_t x = h->GetRandom();
3702 Fill(x);
3703 }
3704 }
3705 else if (sumgen > ntimes) {
3706 // remove extra entries
3707 i = Int_t(sumgen+0.5);
3708 while( i > ntimes) {
3709 Double_t x = h->GetRandom(rng);
3712 // skip in case bin is empty
3713 if (y > 0) {
3714 SetBinContent(ibin, y-1.);
3715 i--;
3716 }
3717 }
3718 }
3719
3720 ResetStats();
3721 return;
3722 }
3723 // case of different axis and not too large ntimes
3724
3725 if (h->ComputeIntegral() ==0) return;
3726 Int_t loop;
3727 Double_t x;
3728 for (loop=0;loop<ntimes;loop++) {
3729 x = h->GetRandom();
3730 Fill(x);
3731 }
3732}
3733
3734////////////////////////////////////////////////////////////////////////////////
3735/// Return Global bin number corresponding to x,y,z
3736///
3737/// 2-D and 3-D histograms are represented with a one dimensional
3738/// structure. This has the advantage that all existing functions, such as
3739/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3740/// This function tries to extend the axis if the given point belongs to an
3741/// under-/overflow bin AND if CanExtendAllAxes() is true.
3742///
3743/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3744
3746{
3747 if (GetDimension() < 2) {
3748 return fXaxis.FindBin(x);
3749 }
3750 if (GetDimension() < 3) {
3751 Int_t nx = fXaxis.GetNbins()+2;
3754 return binx + nx*biny;
3755 }
3756 if (GetDimension() < 4) {
3757 Int_t nx = fXaxis.GetNbins()+2;
3758 Int_t ny = fYaxis.GetNbins()+2;
3761 Int_t binz = fZaxis.FindBin(z);
3762 return binx + nx*(biny +ny*binz);
3763 }
3764 return -1;
3765}
3766
3767////////////////////////////////////////////////////////////////////////////////
3768/// Return Global bin number corresponding to x,y,z.
3769///
3770/// 2-D and 3-D histograms are represented with a one dimensional
3771/// structure. This has the advantage that all existing functions, such as
3772/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3773/// This function DOES NOT try to extend the axis if the given point belongs
3774/// to an under-/overflow bin.
3775///
3776/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3777
3779{
3780 if (GetDimension() < 2) {
3781 return fXaxis.FindFixBin(x);
3782 }
3783 if (GetDimension() < 3) {
3784 Int_t nx = fXaxis.GetNbins()+2;
3787 return binx + nx*biny;
3788 }
3789 if (GetDimension() < 4) {
3790 Int_t nx = fXaxis.GetNbins()+2;
3791 Int_t ny = fYaxis.GetNbins()+2;
3795 return binx + nx*(biny +ny*binz);
3796 }
3797 return -1;
3798}
3799
3800////////////////////////////////////////////////////////////////////////////////
3801/// Find first bin with content > threshold for axis (1=x, 2=y, 3=z)
3802/// if no bins with content > threshold is found the function returns -1.
3803/// The search will occur between the specified first and last bin. Specifying
3804/// the value of the last bin to search to less than zero will search until the
3805/// last defined bin.
3806
3808{
3809 if (fBuffer) ((TH1*)this)->BufferEmpty();
3810
3811 if (axis < 1 || (axis > 1 && GetDimension() == 1 ) ||
3812 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3 ) ) {
3813 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3814 axis = 1;
3815 }
3816 if (firstBin < 1) {
3817 firstBin = 1;
3818 }
3820 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3821 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3822
3823 if (axis == 1) {
3826 }
3827 for (Int_t binx = firstBin; binx <= lastBin; binx++) {
3828 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3829 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3831 }
3832 }
3833 }
3834 }
3835 else if (axis == 2) {
3838 }
3839 for (Int_t biny = firstBin; biny <= lastBin; biny++) {
3840 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3841 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3843 }
3844 }
3845 }
3846 }
3847 else if (axis == 3) {
3850 }
3851 for (Int_t binz = firstBin; binz <= lastBin; binz++) {
3852 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3853 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3855 }
3856 }
3857 }
3858 }
3859
3860 return -1;
3861}
3862
3863////////////////////////////////////////////////////////////////////////////////
3864/// Find last bin with content > threshold for axis (1=x, 2=y, 3=z)
3865/// if no bins with content > threshold is found the function returns -1.
3866/// The search will occur between the specified first and last bin. Specifying
3867/// the value of the last bin to search to less than zero will search until the
3868/// last defined bin.
3869
3871{
3872 if (fBuffer) ((TH1*)this)->BufferEmpty();
3873
3874
3875 if (axis < 1 || ( axis > 1 && GetDimension() == 1 ) ||
3876 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3) ) {
3877 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3878 axis = 1;
3879 }
3880 if (firstBin < 1) {
3881 firstBin = 1;
3882 }
3884 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3885 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3886
3887 if (axis == 1) {
3890 }
3891 for (Int_t binx = lastBin; binx >= firstBin; binx--) {
3892 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3893 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3895 }
3896 }
3897 }
3898 }
3899 else if (axis == 2) {
3902 }
3903 for (Int_t biny = lastBin; biny >= firstBin; biny--) {
3904 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3905 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3907 }
3908 }
3909 }
3910 }
3911 else if (axis == 3) {
3914 }
3915 for (Int_t binz = lastBin; binz >= firstBin; binz--) {
3916 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3917 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3919 }
3920 }
3921 }
3922 }
3923
3924 return -1;
3925}
3926
3927////////////////////////////////////////////////////////////////////////////////
3928/// Search object named name in the list of functions.
3929
3930TObject *TH1::FindObject(const char *name) const
3931{
3932 if (fFunctions) return fFunctions->FindObject(name);
3933 return nullptr;
3934}
3935
3936////////////////////////////////////////////////////////////////////////////////
3937/// Search object obj in the list of functions.
3938
3939TObject *TH1::FindObject(const TObject *obj) const
3940{
3941 if (fFunctions) return fFunctions->FindObject(obj);
3942 return nullptr;
3943}
3944
3945////////////////////////////////////////////////////////////////////////////////
3946/// Fit histogram with function fname.
3947///
3948///
3949/// fname is the name of a function available in the global ROOT list of functions
3950/// `gROOT->GetListOfFunctions`. Note that this is not thread safe.
3951/// The list include any TF1 object created by the user plus some pre-defined functions
3952/// which are automatically created by ROOT the first time a pre-defined function is requested from `gROOT`
3953/// (i.e. when calling `gROOT->GetFunction(const char *name)`).
3954/// These pre-defined functions are:
3955/// - `gaus, gausn` where gausn is the normalized Gaussian
3956/// - `landau, landaun`
3957/// - `expo`
3958/// - `pol1,...9, chebyshev1,...9`.
3959///
3960/// For printing the list of all available functions do:
3961///
3962/// TF1::InitStandardFunctions(); // not needed if `gROOT->GetFunction` is called before
3963/// TF2::InitStandardFunctions(); TF3::InitStandardFunctions(); // For 2D or 3D
3964/// gROOT->GetListOfFunctions()->ls()
3965///
3966/// `fname` can also be a formula that is accepted by the linear fitter containing the special operator `++`,
3967/// representing linear components separated by `++` sign, for example `x++sin(x)` for fitting `[0]*x+[1]*sin(x)`
3968///
3969/// This function finds a pointer to the TF1 object with name `fname` and calls TH1::Fit(TF1 *, Option_t *, Option_t *,
3970/// Double_t, Double_t). See there for the fitting options and the details about fitting histograms
3971
3973{
3974 char *linear;
3975 linear= (char*)strstr(fname, "++");
3976 Int_t ndim=GetDimension();
3977 if (linear){
3978 if (ndim<2){
3980 return Fit(&f1,option,goption,xxmin,xxmax);
3981 }
3982 else if (ndim<3){
3983 TF2 f2(fname, fname);
3984 return Fit(&f2,option,goption,xxmin,xxmax);
3985 }
3986 else{
3987 TF3 f3(fname, fname);
3988 return Fit(&f3,option,goption,xxmin,xxmax);
3989 }
3990 }
3991 else{
3992 TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
3993 if (!f1) { Printf("Unknown function: %s",fname); return -1; }
3994 return Fit(f1,option,goption,xxmin,xxmax);
3995 }
3996}
3997
3998////////////////////////////////////////////////////////////////////////////////
3999/// Fit histogram with the function pointer f1.
4000///
4001/// \param[in] f1 pointer to the function object
4002/// \param[in] option string defining the fit options (see table below).
4003/// \param[in] goption specify a list of graphics options. See TH1::Draw for a complete list of these options.
4004/// \param[in] xxmin lower fitting range
4005/// \param[in] xxmax upper fitting range
4006/// \return A smart pointer to the TFitResult class
4007///
4008/// \anchor HFitOpt
4009/// ### Histogram Fitting Options
4010///
4011/// Here is the full list of fit options that can be given in the parameter `option`.
4012/// Several options can be used together by concatanating the strings without the need of any delimiters.
4013///
4014/// option | description
4015/// -------|------------
4016/// "L" | Uses a log likelihood method (default is chi-square method). To be used when the histogram represents counts.
4017/// "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.
4018/// "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.
4019/// "MULTI" | Uses Loglikelihood method based on multi-nomial distribution. In this case the function must be normalized and one fits only the function shape.
4020/// "W" | Fit using the chi-square method and ignoring the bin uncertainties and skip empty bins.
4021/// "WW" | Fit using the chi-square method and ignoring the bin uncertainties and include the empty bins.
4022/// "I" | Uses the integral of function in the bin instead of the default bin center value.
4023/// "F" | Uses the default minimizer (e.g. Minuit) when fitting a linear function (e.g. polN) instead of the linear fitter.
4024/// "U" | Uses a user specified objective function (e.g. user providedlikelihood function) defined using `TVirtualFitter::SetFCN`
4025/// "E" | Performs a better parameter errors estimation using the Minos technique for all fit parameters.
4026/// "M" | Uses the IMPROVE algorithm (available only in TMinuit). This algorithm attempts improve the found local minimum by searching for a better one.
4027/// "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`.
4028/// "Q" | Quiet mode (minimum printing)
4029/// "V" | Verbose mode (default is between Q and V)
4030/// "+" | 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.
4031/// "N" | Does not store the graphics function, does not draw the histogram with the function after fitting.
4032/// "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.
4033/// "R" | Fit using a fitting range specified in the function range with `TF1::SetRange`.
4034/// "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.
4035/// "C" | In case of linear fitting, do no calculate the chisquare (saves CPU time).
4036/// "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.
4037/// "WIDTH" | Scales the histogran bin content by the bin width (useful for variable bins histograms)
4038/// "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
4039/// "MULTITHREAD" | Forces usage of multi-thread execution whenever possible
4040///
4041/// The default fitting of an histogram (when no option is given) is perfomed as following:
4042/// - a chi-square fit (see below Chi-square Fits) computed using the bin histogram errors and excluding bins with zero errors (empty bins);
4043/// - the full range of the histogram is used, unless TAxis::SetRange or TAxis::SetRangeUser was called before;
4044/// - the default Minimizer with its default configuration is used (see below Minimizer Configuration) except for linear function;
4045/// - for linear functions (`polN`, `chenbyshev` or formula expressions combined using operator `++`) a linear minimization is used.
4046/// - only the status of the fit is returned;
4047/// - the fit is performed in Multithread whenever is enabled in ROOT;
4048/// - only the last fitted function is saved in the histogram;
4049/// - the histogram is drawn after fitting overalyed with the resulting fitting function
4050///
4051/// \anchor HFitMinimizer
4052/// ### Minimizer Configuration
4053///
4054/// The Fit is perfomed using the default Minimizer, defined in the `ROOT::Math::MinimizerOptions` class.
4055/// It is possible to change the default minimizer and its configuration parameters by calling these static functions before fitting (before calling `TH1::Fit`):
4056/// - `ROOT::Math::MinimizerOptions::SetDefaultMinimizer(minimizerName, minimizerAgorithm)` for changing the minmizer and/or the corresponding algorithm.
4057/// For example `ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");` will set the usage of the BFGS algorithm of the GSL multi-dimensional minimization
4058/// The current defaults are ("Minuit","Migrad").
4059/// See the documentation of the `ROOT::Math::MinimizerOptions` for the available minimizers in ROOT and their corresponding algorithms.
4060/// - `ROOT::Math::MinimizerOptions::SetDefaultTolerance` for setting a different tolerance value for the minimization.
4061/// - `ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls` for setting the maximum number of function calls.
4062/// - `ROOT::Math::MinimizerOptions::SetDefaultPrintLevel` for changing the minimizer print level from level=0 (minimal printing) to level=3 maximum printing
4063///
4064/// Other options are possible depending on the Minimizer used, see the corresponding documentation.
4065/// The default minimizer can be also set in the resource file in etc/system.rootrc. For example
4066///
4067/// ~~~ {.cpp}
4068/// Root.Fitter: Minuit2
4069/// ~~~
4070///
4071/// \anchor HFitChi2
4072/// ### Chi-square Fits
4073///
4074/// By default a chi-square (least-square) fit is performed on the histogram. The so-called modified least-square method
4075/// is used where the residual for each bin is computed using as error the observed value (the bin error) returned by `TH1::GetBinError`
4076///
4077/// \f[
4078/// Chi2 = \sum_{i}{ \left(\frac{y(i) - f(x(i) | p )}{e(i)} \right)^2 }
4079/// \f]
4080///
4081/// 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
4082/// an un-weighted histogram). Bins with zero errors are excluded from the fit. See also later the note on the treatment
4083/// of empty bins. When using option "I" the residual is computed not using the function value at the bin center, `f(x(i)|p)`,
4084/// but the integral of the function in the bin, Integral{ f(x|p)dx }, divided by the bin volume.
4085/// When using option `P` (Pearson chi2), the expected error computed as `e(i) = sqrt(f(x(i)|p))` is used.
4086/// In this case empty bins are considered in the fit.
4087/// Both chi-square methods should not be used when the bin content represent counts, especially in case of low bin statistics,
4088/// because they could return a biased result.
4089///
4090/// \anchor HFitNLL
4091/// ### Likelihood Fits
4092///
4093/// When using option "L" a likelihood fit is used instead of the default chi-square fit.
4094/// The likelihood is built assuming a Poisson probability density function for each bin.
4095/// The negative log-likelihood to be minimized is
4096///
4097/// \f[
4098/// NLL = - \sum_{i}{ \log {\mathrm P} ( y(i) | f(x(i) | p ) ) }
4099/// \f]
4100/// 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)`.
4101/// The exact likelihood used is the Poisson likelihood described in this paper:
4102/// S. Baker and R. D. Cousins, “Clarification of the use of chi-square and likelihood functions in fits to histograms,”
4103/// Nucl. Instrum. Meth. 221 (1984) 437.
4104///
4105/// \f[
4106/// NLL = \sum_{i}{( f(x(i) | p ) + y(i)\log(y(i)/ f(x(i) | p )) - y(i)) }
4107/// \f]
4108/// By using this formulation, `2*NLL` can be interpreted as the chi-square resulting from the fit.
4109///
4110/// This method should be always used when the bin content represents counts (i.e. errors are sqrt(N) ).
4111/// The likelihood method has the advantage of treating correctly bins with low statistics. In case of high
4112/// statistics/bin the distribution of the bin content becomes a normal distribution and the likelihood and the chi2 fit
4113/// give the same result.
4114///
4115/// The likelihood method, although a bit slower, it is therefore the recommended method,
4116/// when the histogram represent counts (Poisson statistics), where the chi-square methods may
4117/// give incorrect results, especially in case of low statistics.
4118/// In case of a weighted histogram, it is possible to perform also a likelihood fit by using the
4119/// option "WL". Note a weighted histogram is a histogram which has been filled with weights and it
4120/// has the information on the sum of the weight square for each bin ( TH1::Sumw2() has been called).
4121/// The bin error for a weighted histogram is the square root of the sum of the weight square.
4122///
4123/// \anchor HFitRes
4124/// ### Fit Result
4125///
4126/// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
4127/// By default the TFitResultPtr contains only the status of the fit which is return by an
4128/// automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
4129///
4130/// ~~~ {.cpp}
4131/// Int_t fitStatus = h->Fit(myFunc);
4132/// ~~~
4133///
4134/// If the option "S" is instead used, TFitResultPtr behaves as a smart
4135/// pointer to the TFitResult object. This is useful for retrieving the full result information from the fit, such as the covariance matrix,
4136/// as shown in this example code:
4137///
4138/// ~~~ {.cpp}
4139/// TFitResultPtr r = h->Fit(myFunc,"S");
4140/// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
4141/// Double_t chi2 = r->Chi2(); // to retrieve the fit chi2
4142/// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
4143/// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
4144/// r->Print("V"); // print full information of fit including covariance matrix
4145/// r->Write(); // store the result in a file
4146/// ~~~
4147///
4148/// The fit parameters, error and chi-square (but not covariance matrix) can be retrieved also
4149/// directly from the fitted function that is passed to this call.
4150/// Given a pointer to an associated fitted function `myfunc`, one can retrieve the function/fit
4151/// parameters with calls such as:
4152///
4153/// ~~~ {.cpp}
4154/// Double_t chi2 = myfunc->GetChisquare();
4155/// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
4156/// Double_t err0 = myfunc->GetParError(0); //error on first parameter
4157/// ~~~
4158///
4159/// ##### Associated functions
4160///
4161/// One or more objects (typically a TF1*) can be added to the list
4162/// of functions (fFunctions) associated to each histogram.
4163/// When TH1::Fit is invoked, the fitted function is added to the histogram list of functions (fFunctions).
4164/// If the histogram is made persistent, the list of associated functions is also persistent.
4165/// Given a histogram h, one can retrieve an associated function with:
4166///
4167/// ~~~ {.cpp}
4168/// TF1 *myfunc = h->GetFunction("myfunc");
4169/// ~~~
4170/// or by quering directly the list obtained by calling `TH1::GetListOfFunctions`.
4171///
4172/// \anchor HFitStatus
4173/// ### Fit status
4174///
4175/// The status of the fit is obtained converting the TFitResultPtr to an integer
4176/// independently if the fit option "S" is used or not:
4177///
4178/// ~~~ {.cpp}
4179/// TFitResultPtr r = h->Fit(myFunc,opt);
4180/// Int_t fitStatus = r;
4181/// ~~~
4182///
4183/// - `status = 0` : the fit has been performed successfully (i.e no error occurred).
4184/// - `status < 0` : there is an error not connected with the minimization procedure, for example when a wrong function is used.
4185/// - `status > 0` : return status from Minimizer, depends on used Minimizer. For example for TMinuit and Minuit2 we have:
4186/// - `status = migradStatus + 10*minosStatus + 100*hesseStatus + 1000*improveStatus`.
4187/// 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
4188/// only in Minos but not in Migrad a fitStatus of 40 will be returned.
4189/// Minuit2 returns 0 in case of success and different values in migrad,minos or
4190/// hesse depending on the error. See in this case the documentation of
4191/// Minuit2Minimizer::Minimize for the migrad return status, Minuit2Minimizer::GetMinosError for the
4192/// minos return status and Minuit2Minimizer::Hesse for the hesse return status.
4193/// If other minimizers are used see their specific documentation for the status code returned.
4194/// For example in the case of Fumili, see TFumili::Minimize.
4195///
4196/// \anchor HFitRange
4197/// ### Fitting in a range
4198///
4199/// In order to fit in a sub-range of the histogram you have two options:
4200/// - pass to this function the lower (`xxmin`) and upper (`xxmax`) values for the fitting range;
4201/// - define a specific range in the fitted function and use the fitting option "R".
4202/// For example, if your histogram has a defined range between -4 and 4 and you want to fit a gaussian
4203/// only in the interval 1 to 3, you can do:
4204///
4205/// ~~~ {.cpp}
4206/// TF1 *f1 = new TF1("f1", "gaus", 1, 3);
4207/// histo->Fit("f1", "R");
4208/// ~~~
4209///
4210/// The fitting range is also limited by the histogram range defined using TAxis::SetRange
4211/// or TAxis::SetRangeUser. Therefore the fitting range is the smallest range between the
4212/// histogram one and the one defined by one of the two previous options described above.
4213///
4214/// \anchor HFitInitial
4215/// ### Setting initial conditions
4216///
4217/// Parameters must be initialized before invoking the Fit function.
4218/// The setting of the parameter initial values is automatic for the
4219/// predefined functions such as poln, expo, gaus, landau. One can however disable
4220/// this automatic computation by using the option "B".
4221/// Note that if a predefined function is defined with an argument,
4222/// eg, gaus(0), expo(1), you must specify the initial values for
4223/// the parameters.
4224/// You can specify boundary limits for some or all parameters via
4225///
4226/// ~~~ {.cpp}
4227/// f1->SetParLimits(p_number, parmin, parmax);
4228/// ~~~
4229///
4230/// if `parmin >= parmax`, the parameter is fixed
4231/// Note that you are not forced to fix the limits for all parameters.
4232/// For example, if you fit a function with 6 parameters, you can do:
4233///
4234/// ~~~ {.cpp}
4235/// func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
4236/// func->SetParLimits(3, -10, -4);
4237/// func->FixParameter(4, 0);
4238/// func->SetParLimits(5, 1, 1);
4239/// ~~~
4240///
4241/// With this setup, parameters 0->2 can vary freely
4242/// Parameter 3 has boundaries [-10,-4] with initial value -8
4243/// Parameter 4 is fixed to 0
4244/// Parameter 5 is fixed to 100.
4245/// When the lower limit and upper limit are equal, the parameter is fixed.
4246/// However to fix a parameter to 0, one must call the FixParameter function.
4247///
4248/// \anchor HFitStatBox
4249/// ### Fit Statistics Box
4250///
4251/// The statistics box can display the result of the fit.
4252/// You can change the statistics box to display the fit parameters with
4253/// the TStyle::SetOptFit(mode) method. This mode has four digits.
4254/// mode = pcev (default = 0111)
4255///
4256/// v = 1; print name/values of parameters
4257/// e = 1; print errors (if e=1, v must be 1)
4258/// c = 1; print Chisquare/Number of degrees of freedom
4259/// p = 1; print Probability
4260///
4261/// For example: gStyle->SetOptFit(1011);
4262/// prints the fit probability, parameter names/values, and errors.
4263/// You can change the position of the statistics box with these lines
4264/// (where g is a pointer to the TGraph):
4265///
4266/// TPaveStats *st = (TPaveStats*)g->GetListOfFunctions()->FindObject("stats");
4267/// st->SetX1NDC(newx1); //new x start position
4268/// st->SetX2NDC(newx2); //new x end position
4269///
4270/// \anchor HFitExtra
4271/// ### Additional Notes on Fitting
4272///
4273/// #### Fitting a histogram of dimension N with a function of dimension N-1
4274///
4275/// It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
4276/// 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.
4277/// For correct error scaling, the obtained parameter error are corrected as in the case when the
4278/// option "W" is used.
4279///
4280/// #### User defined objective functions
4281///
4282/// By default when fitting a chi square function is used for fitting. When option "L" is used
4283/// a Poisson likelihood function is used. Using option "MULTI" a multinomial likelihood fit is used.
4284/// Thes functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
4285/// are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
4286/// the file math/mathcore/src/FitUtil.cxx.
4287/// It is possible to specify a user defined fitting function, using option "U" and
4288/// calling the following functions:
4289///
4290/// ~~~ {.cpp}
4291/// TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction);
4292/// ~~~
4293///
4294/// where MyFittingFunction is of type:
4295///
4296/// ~~~ {.cpp}
4297/// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
4298/// ~~~
4299///
4300/// #### Note on treatment of empty bins
4301///
4302/// Empty bins, which have the content equal to zero AND error equal to zero,
4303/// are excluded by default from the chi-square fit, but they are considered in the likelihood fit.
4304/// since they affect the likelihood if the function value in these bins is not negligible.
4305/// Note that if the histogram is having bins with zero content and non zero-errors they are considered as
4306/// any other bins in the fit. Instead bins with zero error and non-zero content are by default excluded in the chi-squared fit.
4307/// In general, one should not fit a histogram with non-empty bins and zero errors.
4308///
4309/// 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
4310/// fit). When using option "WW" the empty bins will be also considered in the chi-square fit with an error of 1.
4311/// Note that in this fitting case (option "W" or "WW") the resulting fitted parameter errors
4312/// are corrected by the obtained chi2 value using this scaling expression:
4313/// `errorp *= sqrt(chisquare/(ndf-1))` as it is done when fitting a TGraph with
4314/// no point errors.
4315///
4316/// #### Excluding points
4317///
4318/// You can use TF1::RejectPoint inside your fitting function to exclude some points
4319/// within a certain range from the fit. See the tutorial `fit/fitExclude.C`.
4320///
4321///
4322/// #### Warning when using the option "0"
4323///
4324/// When selecting the option "0", the fitted function is added to
4325/// the list of functions of the histogram, but it is not drawn when the histogram is drawn.
4326/// You can undo this behaviour resetting its corresponding bit in the TF1 object as following:
4327///
4328/// ~~~ {.cpp}
4329/// h.Fit("myFunction", "0"); // fit, store function but do not draw
4330/// h.Draw(); // function is not drawn
4331/// h.GetFunction("myFunction")->ResetBit(TF1::kNotDraw);
4332/// h.Draw(); // function is visible again
4333/// ~~~
4335
4337{
4338 // implementation of Fit method is in file hist/src/HFitImpl.cxx
4341
4342 // create range and minimizer options with default values
4345
4346 // need to empty the buffer before
4347 // (t.b.d. do a ML unbinned fit with buffer data)
4348 if (fBuffer) BufferEmpty();
4349
4351}
4352
4353////////////////////////////////////////////////////////////////////////////////
4354/// Display a panel with all histogram fit options.
4355///
4356/// See class TFitPanel for example
4357
4358void TH1::FitPanel()
4359{
4360 if (!gPad)
4361 gROOT->MakeDefCanvas();
4362
4363 if (!gPad) {
4364 Error("FitPanel", "Unable to create a default canvas");
4365 return;
4366 }
4367
4368
4369 // use plugin manager to create instance of TFitEditor
4370 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
4371 if (handler && handler->LoadPlugin() != -1) {
4372 if (handler->ExecPlugin(2, gPad, this) == 0)
4373 Error("FitPanel", "Unable to create the FitPanel");
4374 }
4375 else
4376 Error("FitPanel", "Unable to find the FitPanel plug-in");
4377}
4378
4379////////////////////////////////////////////////////////////////////////////////
4380/// Return a histogram containing the asymmetry of this histogram with h2,
4381/// where the asymmetry is defined as:
4382///
4383/// ~~~ {.cpp}
4384/// Asymmetry = (h1 - h2)/(h1 + h2) where h1 = this
4385/// ~~~
4386///
4387/// works for 1D, 2D, etc. histograms
4388/// c2 is an optional argument that gives a relative weight between the two
4389/// histograms, and dc2 is the error on this weight. This is useful, for example,
4390/// when forming an asymmetry between two histograms from 2 different data sets that
4391/// need to be normalized to each other in some way. The function calculates
4392/// the errors assuming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
4393///
4394/// example: assuming 'h1' and 'h2' are already filled
4395///
4396/// ~~~ {.cpp}
4397/// h3 = h1->GetAsymmetry(h2)
4398/// ~~~
4399///
4400/// then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
4401/// h1 and h2 are left intact.
4402///
4403/// Note that it is the user's responsibility to manage the created histogram.
4404/// The name of the returned histogram will be `Asymmetry_nameOfh1-nameOfh2`
4405///
4406/// code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
4407///
4408/// clone the histograms so top and bottom will have the
4409/// correct dimensions:
4410/// Sumw2 just makes sure the errors will be computed properly
4411/// when we form sums and ratios below.
4412
4414{
4415 TH1 *h1 = this;
4416 TString name = TString::Format("Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4417 TH1 *asym = (TH1*)Clone(name);
4418
4419 // set also the title
4420 TString title = TString::Format("(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4421 asym->SetTitle(title);
4422
4423 asym->Sumw2();
4424
4425 TDirectory::TContext ctx{nullptr};
4426 TH1 *top = (TH1*)asym->Clone();
4427 TH1 *bottom = (TH1*)asym->Clone();
4428
4429 // form the top and bottom of the asymmetry, and then divide:
4430 top->Add(h1,h2,1,-c2);
4431 bottom->Add(h1,h2,1,c2);
4432 asym->Divide(top,bottom);
4433
4434 Int_t xmax = asym->GetNbinsX();
4435 Int_t ymax = asym->GetNbinsY();
4436 Int_t zmax = asym->GetNbinsZ();
4437
4438 if (h1->fBuffer) h1->BufferEmpty(1);
4439 if (h2->fBuffer) h2->BufferEmpty(1);
4440 if (bottom->fBuffer) bottom->BufferEmpty(1);
4441
4442 // now loop over bins to calculate the correct errors
4443 // the reason this error calculation looks complex is because of c2
4444 for(Int_t i=1; i<= xmax; i++){
4445 for(Int_t j=1; j<= ymax; j++){
4446 for(Int_t k=1; k<= zmax; k++){
4447 Int_t bin = GetBin(i, j, k);
4448 // here some bin contents are written into variables to make the error
4449 // calculation a little more legible:
4453
4454 // make sure there are some events, if not, then the errors are set = 0
4455 // automatically.
4456 //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
4457 if(bot < 1e-6){}
4458 else{
4459 // computation of errors by Christos Leonidopoulos
4462 Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4463 asym->SetBinError(i,j,k,error);
4464 }
4465 }
4466 }
4467 }
4468 delete top;
4469 delete bottom;
4470
4471 return asym;
4472}
4473
4474////////////////////////////////////////////////////////////////////////////////
4475/// Static function
4476/// return the default buffer size for automatic histograms
4477/// the parameter fgBufferSize may be changed via SetDefaultBufferSize
4478
4480{
4481 return fgBufferSize;
4482}
4483
4484////////////////////////////////////////////////////////////////////////////////
4485/// Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
4486/// see TH1::SetDefaultSumw2.
4487
4489{
4490 return fgDefaultSumw2;
4491}
4492
4493////////////////////////////////////////////////////////////////////////////////
4494/// Return the current number of entries.
4495
4497{
4498 if (fBuffer) {
4499 Int_t nentries = (Int_t) fBuffer[0];
4500 if (nentries > 0) return nentries;
4501 }
4502
4503 return fEntries;
4504}
4505
4506////////////////////////////////////////////////////////////////////////////////
4507/// Number of effective entries of the histogram.
4508///
4509/// \f[
4510/// neff = \frac{(\sum Weights )^2}{(\sum Weight^2 )}
4511/// \f]
4512///
4513/// In case of an unweighted histogram this number is equivalent to the
4514/// number of entries of the histogram.
4515/// For a weighted histogram, this number corresponds to the hypothetical number of unweighted entries
4516/// a histogram would need to have the same statistical power as this weighted histogram.
4517/// Note: The underflow/overflow are included if one has set the TH1::StatOverFlows flag
4518/// and if the statistics has been computed at filling time.
4519/// If a range is set in the histogram the number is computed from the given range.
4520
4522{
4523 Stat_t s[kNstat];
4524 this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
4525 return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4526}
4527
4528////////////////////////////////////////////////////////////////////////////////
4529/// Shortcut to set the three histogram colors with a single call.
4530///
4531/// By default: linecolor = markercolor = fillcolor = -1
4532/// If a color is < 0 this method does not change the corresponding color if positive or null it set the color.
4533///
4534/// For instance:
4535/// ~~~ {.cpp}
4536/// h->SetColors(kRed, kRed);
4537/// ~~~
4538/// will set the line color and the marker color to red.
4539
4541{
4542 if (linecolor >= 0)
4544 if (markercolor >= 0)
4546 if (fillcolor >= 0)
4548}
4549
4550
4551////////////////////////////////////////////////////////////////////////////////
4552/// Set highlight (enable/disable) mode for the histogram
4553/// by default highlight mode is disable
4554
4555void TH1::SetHighlight(Bool_t set)
4556{
4557 if (IsHighlight() == set)
4558 return;
4559 if (fDimension > 2) {
4560 Info("SetHighlight", "Supported only 1-D or 2-D histograms");
4561 return;
4562 }
4563
4564 SetBit(kIsHighlight, set);
4565
4566 if (fPainter)
4568}
4569
4570////////////////////////////////////////////////////////////////////////////////
4571/// Redefines TObject::GetObjectInfo.
4572/// Displays the histogram info (bin number, contents, integral up to bin
4573/// corresponding to cursor position px,py
4574
4575char *TH1::GetObjectInfo(Int_t px, Int_t py) const
4576{
4577 return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
4578}
4579
4580////////////////////////////////////////////////////////////////////////////////
4581/// Return pointer to painter.
4582/// If painter does not exist, it is created
4583
4585{
4586 if (!fPainter) {
4587 TString opt = option;
4588 opt.ToLower();
4589 if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
4590 //try to create TGLHistPainter
4591 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
4592
4593 if (handler && handler->LoadPlugin() != -1)
4594 fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
4595 }
4596 }
4597
4599
4600 return fPainter;
4601}
4602
4603////////////////////////////////////////////////////////////////////////////////
4604/// Compute Quantiles for this histogram.
4605/// A quantile x_p := Q(p) is defined as the value x_p such that the cumulative
4606/// probability distribution Function F of variable X yields:
4607///
4608/// ~~~ {.cpp}
4609/// F(x_p) = Pr(X <= x_p) = p with 0 <= p <= 1.
4610/// x_p = Q(p) = F_inv(p)
4611/// ~~~
4612///
4613/// For instance the median x_0.5 of a distribution is defined as that value
4614/// of the random variable X for which the distribution function equals 0.5:
4615///
4616/// ~~~ {.cpp}
4617/// F(x_0.5) = Probability(X < x_0.5) = 0.5
4618/// x_0.5 = Q(0.5)
4619/// ~~~
4620///
4621/// \author Eddy Offermann
4622/// code from Eddy Offermann, Renaissance
4623///
4624/// \param[in] n maximum size of the arrays xp and p (if given)
4625/// \param[out] xp array to be filled with nq quantiles evaluated at (p). Memory has to be preallocated by caller.
4626/// - If `p == nullptr`, the quantiles are computed at the (first `n`) probabilities p given by the CDF of the histogram;
4627/// `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`.
4628/// If all bins have non-zero entries, the quantiles happen to be the bin centres.
4629/// Empty bins will, however, be skipped in the quantiles.
4630/// If the CDF is e.g. [0., 0., 0.1, ...], the quantiles would be, [3., 3., 3., ...], with the third bin starting
4631/// at 3.
4632/// \param[in] p array of cumulative probabilities where quantiles should be evaluated.
4633/// - if `p == nullptr`, the CDF of the histogram will be used to compute the quantiles, and will
4634/// have a size of n.
4635/// - Otherwise, it is assumed to contain at least n values.
4636/// \return number of quantiles computed
4637/// \note Unlike in TF1::GetQuantiles, `p` is here an optional argument
4638///
4639/// Note that the Integral of the histogram is automatically recomputed
4640/// if the number of entries is different of the number of entries when
4641/// the integral was computed last time. In case you do not use the Fill
4642/// functions to fill your histogram, but SetBinContent, you must call
4643/// TH1::ComputeIntegral before calling this function.
4644///
4645/// Getting quantiles xp from two histograms and storing results in a TGraph,
4646/// a so-called QQ-plot
4647///
4648/// ~~~ {.cpp}
4649/// TGraph *gr = new TGraph(nprob);
4650/// h1->GetQuantiles(nprob,gr->GetX());
4651/// h2->GetQuantiles(nprob,gr->GetY());
4652/// gr->Draw("alp");
4653/// ~~~
4654///
4655/// Example:
4656///
4657/// ~~~ {.cpp}
4658/// void quantiles() {
4659/// // demo for quantiles
4660/// const Int_t nq = 20;
4661/// TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
4662/// h->FillRandom("gaus",5000);
4663/// h->GetXaxis()->SetTitle("x");
4664/// h->GetYaxis()->SetTitle("Counts");
4665///
4666/// Double_t p[nq]; // probabilities where to evaluate the quantiles in [0,1]
4667/// Double_t xp[nq]; // array of positions X to store the resulting quantiles
4668/// for (Int_t i=0;i<nq;i++) p[i] = Float_t(i+1)/nq;
4669/// h->GetQuantiles(nq,xp,p);
4670///
4671/// //show the original histogram in the top pad
4672/// TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
4673/// c1->Divide(1,2);
4674/// c1->cd(1);
4675/// h->Draw();
4676///
4677/// // show the quantiles in the bottom pad
4678/// c1->cd(2);
4679/// gPad->SetGrid();
4680/// TGraph *gr = new TGraph(nq,p,xp);
4681/// gr->SetMarkerStyle(21);
4682/// gr->GetXaxis()->SetTitle("p");
4683/// gr->GetYaxis()->SetTitle("x");
4684/// gr->Draw("alp");
4685/// }
4686/// ~~~
4687
4689{
4690 if (GetDimension() > 1) {
4691 Error("GetQuantiles","Only available for 1-d histograms");
4692 return 0;
4693 }
4694
4695 const Int_t nbins = GetXaxis()->GetNbins();
4696 if (!fIntegral) ComputeIntegral();
4697 if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4698
4699 Int_t i, ibin;
4700 Int_t nq = n;
4701 std::unique_ptr<Double_t[]> localProb;
4702 if (p == nullptr) {
4703 nq = nbins+1;
4704 localProb.reset(new Double_t[nq]);
4705 localProb[0] = 0;
4706 for (i=1;i<nq;i++) {
4707 localProb[i] = fIntegral[i] / fIntegral[nbins];
4708 }
4709 }
4710 Double_t const *const prob = p ? p : localProb.get();
4711
4712 for (i = 0; i < nq; i++) {
4714 if (fIntegral[ibin] == prob[i]) {
4715 if (prob[i] == 0.) {
4716 for (; ibin+1 <= nbins && fIntegral[ibin+1] == 0.; ++ibin) {
4717
4718 }
4719 xp[i] = fXaxis.GetBinUpEdge(ibin);
4720 }
4721 else if (prob[i] == 1.) {
4722 xp[i] = fXaxis.GetBinUpEdge(ibin);
4723 }
4724 else {
4725 // Find equal integral in later bins (ie their entries are zero)
4726 Double_t width = 0;
4727 for (Int_t j = ibin+1; j <= nbins; ++j) {
4728 if (prob[i] == fIntegral[j]) {
4730 }
4731 else
4732 break;
4733 }
4735 }
4736 }
4737 else {
4738 xp[i] = GetBinLowEdge(ibin+1);
4740 if (dint > 0) xp[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4741 }
4742 }
4743
4744 return nq;
4745}
4746
4747////////////////////////////////////////////////////////////////////////////////
4753 return 1;
4754}
4755
4756////////////////////////////////////////////////////////////////////////////////
4757/// Compute Initial values of parameters for a gaussian.
4758
4759void H1InitGaus()
4760{
4761 Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4762 Int_t bin;
4763 const Double_t sqrtpi = 2.506628;
4764
4765 // - Compute mean value and StdDev of the histogram in the given range
4767 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4768 Int_t hxfirst = hFitter->GetXfirst();
4769 Int_t hxlast = hFitter->GetXlast();
4770 Double_t valmax = curHist->GetBinContent(hxfirst);
4771 Double_t binwidx = curHist->GetBinWidth(hxfirst);
4772 allcha = sumx = sumx2 = 0;
4773 for (bin=hxfirst;bin<=hxlast;bin++) {
4774 x = curHist->GetBinCenter(bin);
4775 val = TMath::Abs(curHist->GetBinContent(bin));
4776 if (val > valmax) valmax = val;
4777 sumx += val*x;
4778 sumx2 += val*x*x;
4779 allcha += val;
4780 }
4781 if (allcha == 0) return;
4782 mean = sumx/allcha;
4783 stddev = sumx2/allcha - mean*mean;
4784 if (stddev > 0) stddev = TMath::Sqrt(stddev);
4785 else stddev = 0;
4786 if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4787 //if the distribution is really gaussian, the best approximation
4788 //is binwidx*allcha/(sqrtpi*stddev)
4789 //However, in case of non-gaussian tails, this underestimates
4790 //the normalisation constant. In this case the maximum value
4791 //is a better approximation.
4792 //We take the average of both quantities
4794
4795 //In case the mean value is outside the histo limits and
4796 //the StdDev is bigger than the range, we take
4797 // mean = center of bins
4798 // stddev = half range
4799 Double_t xmin = curHist->GetXaxis()->GetXmin();
4800 Double_t xmax = curHist->GetXaxis()->GetXmax();
4801 if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4802 mean = 0.5*(xmax+xmin);
4803 stddev = 0.5*(xmax-xmin);
4804 }
4805 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4807 f1->SetParameter(1,mean);
4809 f1->SetParLimits(2,0,10*stddev);
4810}
4811
4812////////////////////////////////////////////////////////////////////////////////
4813/// Compute Initial values of parameters for an exponential.
4814
4815void H1InitExpo()
4816{
4818 Int_t ifail;
4820 Int_t hxfirst = hFitter->GetXfirst();
4821 Int_t hxlast = hFitter->GetXlast();
4822 Int_t nchanx = hxlast - hxfirst + 1;
4823
4825
4826 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4828 f1->SetParameter(1,slope);
4829
4830}
4831
4832////////////////////////////////////////////////////////////////////////////////
4833/// Compute Initial values of parameters for a polynom.
4834
4835void H1InitPolynom()
4836{
4837 Double_t fitpar[25];
4838
4840 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4841 Int_t hxfirst = hFitter->GetXfirst();
4842 Int_t hxlast = hFitter->GetXlast();
4843 Int_t nchanx = hxlast - hxfirst + 1;
4844 Int_t npar = f1->GetNpar();
4845
4846 if (nchanx <=1 || npar == 1) {
4847 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4848 fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4849 } else {
4851 }
4852 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4853}
4854
4855////////////////////////////////////////////////////////////////////////////////
4856/// Least squares lpolynomial fitting without weights.
4857///
4858/// \param[in] n number of points to fit
4859/// \param[in] m number of parameters
4860/// \param[in] a array of parameters
4861///
4862/// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
4863/// (E.Keil. revised by B.Schorr, 23.10.1981.)
4864
4866{
4867 const Double_t zero = 0.;
4868 const Double_t one = 1.;
4869 const Int_t idim = 20;
4870
4871 Double_t b[400] /* was [20][20] */;
4872 Int_t i, k, l, ifail;
4874 Double_t da[20], xk, yk;
4875
4876 if (m <= 2) {
4877 H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4878 return;
4879 }
4880 if (m > idim || m > n) return;
4881 b[0] = Double_t(n);
4882 da[0] = zero;
4883 for (l = 2; l <= m; ++l) {
4884 b[l-1] = zero;
4885 b[m + l*20 - 21] = zero;
4886 da[l-1] = zero;
4887 }
4889 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4890 Int_t hxfirst = hFitter->GetXfirst();
4891 Int_t hxlast = hFitter->GetXlast();
4892 for (k = hxfirst; k <= hxlast; ++k) {
4893 xk = curHist->GetBinCenter(k);
4894 yk = curHist->GetBinContent(k);
4895 power = one;
4896 da[0] += yk;
4897 for (l = 2; l <= m; ++l) {
4898 power *= xk;
4899 b[l-1] += power;
4900 da[l-1] += power*yk;
4901 }
4902 for (l = 2; l <= m; ++l) {
4903 power *= xk;
4904 b[m + l*20 - 21] += power;
4905 }
4906 }
4907 for (i = 3; i <= m; ++i) {
4908 for (k = i; k <= m; ++k) {
4909 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4910 }
4911 }
4913
4914 for (i=0; i<m; ++i) a[i] = da[i];
4915
4916}
4917
4918////////////////////////////////////////////////////////////////////////////////
4919/// Least square linear fit without weights.
4920///
4921/// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
4922/// (added to LSQ by B. Schorr, 15.02.1982.)
4923
4925{
4927 Int_t i, n;
4929 Double_t fn, xk, yk;
4930 Double_t det;
4931
4932 n = TMath::Abs(ndata);
4933 ifail = -2;
4934 xbar = ybar = x2bar = xybar = 0;
4936 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4937 Int_t hxfirst = hFitter->GetXfirst();
4938 Int_t hxlast = hFitter->GetXlast();
4939 for (i = hxfirst; i <= hxlast; ++i) {
4940 xk = curHist->GetBinCenter(i);
4941 yk = curHist->GetBinContent(i);
4942 if (ndata < 0) {
4943 if (yk <= 0) yk = 1e-9;
4944 yk = TMath::Log(yk);
4945 }
4946 xbar += xk;
4947 ybar += yk;
4948 x2bar += xk*xk;
4949 xybar += xk*yk;
4950 }
4951 fn = Double_t(n);
4952 det = fn*x2bar - xbar*xbar;
4953 ifail = -1;
4954 if (det <= 0) {
4955 a0 = ybar/fn;
4956 a1 = 0;
4957 return;
4958 }
4959 ifail = 0;
4960 a0 = (x2bar*ybar - xbar*xybar) / det;
4961 a1 = (fn*xybar - xbar*ybar) / det;
4962
4963}
4964
4965////////////////////////////////////////////////////////////////////////////////
4966/// Extracted from CERN Program library routine DSEQN.
4967///
4968/// Translated to C++ by Rene Brun
4969
4971{
4973 Int_t nmjp1, i, j, l;
4974 Int_t im1, jp1, nm1, nmi;
4975 Double_t s1, s21, s22;
4976 const Double_t one = 1.;
4977
4978 /* Parameter adjustments */
4979 b_dim1 = idim;
4980 b_offset = b_dim1 + 1;
4981 b -= b_offset;
4982 a_dim1 = idim;
4983 a_offset = a_dim1 + 1;
4984 a -= a_offset;
4985
4986 if (idim < n) return;
4987
4988 ifail = 0;
4989 for (j = 1; j <= n; ++j) {
4990 if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
4991 a[j + j*a_dim1] = one / a[j + j*a_dim1];
4992 if (j == n) continue;
4993 jp1 = j + 1;
4994 for (l = jp1; l <= n; ++l) {
4995 a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4996 s1 = -a[l + (j+1)*a_dim1];
4997 for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4998 a[l + (j+1)*a_dim1] = -s1;
4999 }
5000 }
5001 if (k <= 0) return;
5002
5003 for (l = 1; l <= k; ++l) {
5004 b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
5005 }
5006 if (n == 1) return;
5007 for (l = 1; l <= k; ++l) {
5008 for (i = 2; i <= n; ++i) {
5009 im1 = i - 1;
5010 s21 = -b[i + l*b_dim1];
5011 for (j = 1; j <= im1; ++j) {
5012 s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
5013 }
5014 b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
5015 }
5016 nm1 = n - 1;
5017 for (i = 1; i <= nm1; ++i) {
5018 nmi = n - i;
5019 s22 = -b[nmi + l*b_dim1];
5020 for (j = 1; j <= i; ++j) {
5021 nmjp1 = n - j + 1;
5022 s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
5023 }
5024 b[nmi + l*b_dim1] = -s22;
5025 }
5026 }
5027}
5028
5029////////////////////////////////////////////////////////////////////////////////
5030/// Return Global bin number corresponding to binx,y,z.
5031///
5032/// 2-D and 3-D histograms are represented with a one dimensional
5033/// structure.
5034/// This has the advantage that all existing functions, such as
5035/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
5036///
5037/// In case of a TH1x, returns binx directly.
5038/// see TH1::GetBinXYZ for the inverse transformation.
5039///
5040/// Convention for numbering bins
5041///
5042/// For all histogram types: nbins, xlow, xup
5043///
5044/// - bin = 0; underflow bin
5045/// - bin = 1; first bin with low-edge xlow INCLUDED
5046/// - bin = nbins; last bin with upper-edge xup EXCLUDED
5047/// - bin = nbins+1; overflow bin
5048///
5049/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
5050/// For example, assuming a 3-D histogram with binx,biny,binz, the function
5051///
5052/// ~~~ {.cpp}
5053/// Int_t bin = h->GetBin(binx,biny,binz);
5054/// ~~~
5055///
5056/// returns a global/linearized bin number. This global bin is useful
5057/// to access the bin information independently of the dimension.
5058
5060{
5061 Int_t ofx = fXaxis.GetNbins() + 1; // overflow bin
5062 if (binx < 0) binx = 0;
5063 if (binx > ofx) binx = ofx;
5064
5065 return binx;
5066}
5067
5068////////////////////////////////////////////////////////////////////////////////
5069/// Return binx, biny, binz corresponding to the global bin number globalbin
5070/// see TH1::GetBin function above
5071
5073{
5074 Int_t nx = fXaxis.GetNbins()+2;
5075 Int_t ny = fYaxis.GetNbins()+2;
5076
5077 if (GetDimension() == 1) {
5078 binx = binglobal%nx;
5079 biny = 0;
5080 binz = 0;
5081 return;
5082 }
5083 if (GetDimension() == 2) {
5084 binx = binglobal%nx;
5085 biny = ((binglobal-binx)/nx)%ny;
5086 binz = 0;
5087 return;
5088 }
5089 if (GetDimension() == 3) {
5090 binx = binglobal%nx;
5091 biny = ((binglobal-binx)/nx)%ny;
5092 binz = ((binglobal-binx)/nx -biny)/ny;
5093 }
5094}
5095
5096////////////////////////////////////////////////////////////////////////////////
5097/// Return a random number distributed according the histogram bin contents.
5098/// This function checks if the bins integral exists. If not, the integral
5099/// is evaluated, normalized to one.
5100///
5101/// @param rng (optional) Random number generator pointer used (default is gRandom)
5102/// @param option (optional) Set it to "width" if your non-uniform bin contents represent a density rather than counts
5103///
5104/// The integral is automatically recomputed if the number of entries
5105/// is not the same then when the integral was computed.
5106/// @note Only valid for 1-d histograms. Use GetRandom2 or GetRandom3 otherwise.
5107/// If the histogram has a bin with negative content, a NaN is returned.
5108
5110{
5111 if (fDimension > 1) {
5112 Error("GetRandom","Function only valid for 1-d histograms");
5113 return 0;
5114 }
5116 Double_t integral = 0;
5117 // compute integral checking that all bins have positive content (see ROOT-5894)
5118 if (fIntegral) {
5119 if (fIntegral[nbinsx + 1] != fEntries)
5120 integral = const_cast<TH1 *>(this)->ComputeIntegral(true, option);
5121 else integral = fIntegral[nbinsx];
5122 } else {
5123 integral = const_cast<TH1 *>(this)->ComputeIntegral(true, option);
5124 }
5125 if (integral == 0) return 0;
5126 // return a NaN in case some bins have negative content
5127 if (integral == TMath::QuietNaN() ) return TMath::QuietNaN();
5128
5129 Double_t r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
5132 if (r1 > fIntegral[ibin]) x +=
5134 return x;
5135}
5136
5137////////////////////////////////////////////////////////////////////////////////
5138/// Return content of bin number bin.
5139///
5140/// Implemented in TH1C,S,F,D
5141///
5142/// Convention for numbering bins
5143///
5144/// For all histogram types: nbins, xlow, xup
5145///
5146/// - bin = 0; underflow bin
5147/// - bin = 1; first bin with low-edge xlow INCLUDED
5148/// - bin = nbins; last bin with upper-edge xup EXCLUDED
5149/// - bin = nbins+1; overflow bin
5150///
5151/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
5152/// For example, assuming a 3-D histogram with binx,biny,binz, the function
5153///
5154/// ~~~ {.cpp}
5155/// Int_t bin = h->GetBin(binx,biny,binz);
5156/// ~~~
5157///
5158/// returns a global/linearized bin number. This global bin is useful
5159/// to access the bin information independently of the dimension.
5160
5162{
5163 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
5164 if (bin < 0) bin = 0;
5165 if (bin >= fNcells) bin = fNcells-1;
5166
5167 return RetrieveBinContent(bin);
5168}
5169
5170////////////////////////////////////////////////////////////////////////////////
5171/// Compute first binx in the range [firstx,lastx] for which
5172/// diff = abs(bin_content-c) <= maxdiff
5173///
5174/// In case several bins in the specified range with diff=0 are found
5175/// the first bin found is returned in binx.
5176/// In case several bins in the specified range satisfy diff <=maxdiff
5177/// the bin with the smallest difference is returned in binx.
5178/// In all cases the function returns the smallest difference.
5179///
5180/// NOTE1: if firstx <= 0, firstx is set to bin 1
5181/// if (lastx < firstx then firstx is set to the number of bins
5182/// ie if firstx=0 and lastx=0 (default) the search is on all bins.
5183///
5184/// NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
5185
5187{
5188 if (fDimension > 1) {
5189 binx = 0;
5190 Error("GetBinWithContent","function is only valid for 1-D histograms");
5191 return 0;
5192 }
5193
5194 if (fBuffer) ((TH1*)this)->BufferEmpty();
5195
5196 if (firstx <= 0) firstx = 1;
5197 if (lastx < firstx) lastx = fXaxis.GetNbins();
5198 Int_t binminx = 0;
5199 Double_t diff, curmax = 1.e240;
5200 for (Int_t i=firstx;i<=lastx;i++) {
5202 if (diff <= 0) {binx = i; return diff;}
5203 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
5204 }
5205 binx = binminx;
5206 return curmax;
5207}
5208
5209////////////////////////////////////////////////////////////////////////////////
5210/// Given a point x, approximates the value via linear interpolation
5211/// based on the two nearest bin centers
5212///
5213/// Andy Mastbaum 10/21/08
5214
5216{
5217 if (fBuffer) ((TH1*)this)->BufferEmpty();
5218
5220 Double_t x0,x1,y0,y1;
5221
5222 if(x<=GetBinCenter(1)) {
5223 return RetrieveBinContent(1);
5224 } else if(x>=GetBinCenter(GetNbinsX())) {
5225 return RetrieveBinContent(GetNbinsX());
5226 } else {
5227 if(x<=GetBinCenter(xbin)) {
5229 x0 = GetBinCenter(xbin-1);
5231 x1 = GetBinCenter(xbin);
5232 } else {
5234 x0 = GetBinCenter(xbin);
5236 x1 = GetBinCenter(xbin+1);
5237 }
5238 return y0 + (x-x0)*((y1-y0)/(x1-x0));
5239 }
5240}
5241
5242////////////////////////////////////////////////////////////////////////////////
5243/// 2d Interpolation. Not yet implemented.
5244
5246{
5247 Error("Interpolate","This function must be called with 1 argument for a TH1");
5248 return 0;
5249}
5250
5251////////////////////////////////////////////////////////////////////////////////
5252/// 3d Interpolation. Not yet implemented.
5253
5255{
5256 Error("Interpolate","This function must be called with 1 argument for a TH1");
5257 return 0;
5258}
5259
5260///////////////////////////////////////////////////////////////////////////////
5261/// Check if a histogram is empty
5262/// (this is a protected method used mainly by TH1Merger )
5263
5264Bool_t TH1::IsEmpty() const
5265{
5266 // if fTsumw or fentries are not zero histogram is not empty
5267 // need to use GetEntries() instead of fEntries in case of bugger histograms
5268 // so we will flash the buffer
5269 if (fTsumw != 0) return kFALSE;
5270 if (GetEntries() != 0) return kFALSE;
5271 // case fTSumw == 0 amd entries are also zero
5272 // this should not really happening, but if one sets content by hand
5273 // it can happen. a call to ResetStats() should be done in such cases
5274 double sumw = 0;
5275 for (int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
5276 return (sumw != 0) ? kFALSE : kTRUE;
5277}
5278
5279////////////////////////////////////////////////////////////////////////////////
5280/// Return true if the bin is overflow.
5281
5283{
5284 Int_t binx, biny, binz;
5286
5287 if (iaxis == 0) {
5288 if ( fDimension == 1 )
5289 return binx >= GetNbinsX() + 1;
5290 if ( fDimension == 2 )
5291 return (binx >= GetNbinsX() + 1) ||
5292 (biny >= GetNbinsY() + 1);
5293 if ( fDimension == 3 )
5294 return (binx >= GetNbinsX() + 1) ||
5295 (biny >= GetNbinsY() + 1) ||
5296 (binz >= GetNbinsZ() + 1);
5297 return kFALSE;
5298 }
5299 if (iaxis == 1)
5300 return binx >= GetNbinsX() + 1;
5301 if (iaxis == 2)
5302 return biny >= GetNbinsY() + 1;
5303 if (iaxis == 3)
5304 return binz >= GetNbinsZ() + 1;
5305
5306 Error("IsBinOverflow","Invalid axis value");
5307 return kFALSE;
5308}
5309
5310////////////////////////////////////////////////////////////////////////////////
5311/// Return true if the bin is underflow.
5312/// If iaxis = 0 make OR with all axes otherwise check only for the given axis
5313
5315{
5316 Int_t binx, biny, binz;
5318
5319 if (iaxis == 0) {
5320 if ( fDimension == 1 )
5321 return (binx <= 0);
5322 else if ( fDimension == 2 )
5323 return (binx <= 0 || biny <= 0);
5324 else if ( fDimension == 3 )
5325 return (binx <= 0 || biny <= 0 || binz <= 0);
5326 else
5327 return kFALSE;
5328 }
5329 if (iaxis == 1)
5330 return (binx <= 0);
5331 if (iaxis == 2)
5332 return (biny <= 0);
5333 if (iaxis == 3)
5334 return (binz <= 0);
5335
5336 Error("IsBinUnderflow","Invalid axis value");
5337 return kFALSE;
5338}
5339
5340////////////////////////////////////////////////////////////////////////////////
5341/// Reduce the number of bins for the axis passed in the option to the number of bins having a label.
5342/// The method will remove only the extra bins existing after the last "labeled" bin.
5343/// Note that if there are "un-labeled" bins present between "labeled" bins they will not be removed
5344
5346{
5348 TAxis *axis = nullptr;
5349 if (iaxis == 1) axis = GetXaxis();
5350 if (iaxis == 2) axis = GetYaxis();
5351 if (iaxis == 3) axis = GetZaxis();
5352 if (!axis) {
5353 Error("LabelsDeflate","Invalid axis option %s",ax);
5354 return;
5355 }
5356 if (!axis->GetLabels()) return;
5357
5358 // find bin with last labels
5359 // bin number is object ID in list of labels
5360 // therefore max bin number is number of bins of the deflated histograms
5361 TIter next(axis->GetLabels());
5362 TObject *obj;
5363 Int_t nbins = 0;
5364 while ((obj = next())) {
5365 Int_t ibin = obj->GetUniqueID();
5366 if (ibin > nbins) nbins = ibin;
5367 }
5368 if (nbins < 1) nbins = 1;
5369
5370 // Do nothing in case it was the last bin
5371 if (nbins==axis->GetNbins()) return;
5372
5373 TH1 *hold = (TH1*)IsA()->New();
5374 R__ASSERT(hold);
5375 hold->SetDirectory(nullptr);
5376 Copy(*hold);
5377
5378 Bool_t timedisp = axis->GetTimeDisplay();
5379 Double_t xmin = axis->GetXmin();
5380 Double_t xmax = axis->GetBinUpEdge(nbins);
5381 if (xmax <= xmin) xmax = xmin +nbins;
5382 axis->SetRange(0,0);
5383 axis->Set(nbins,xmin,xmax);
5384 SetBinsLength(-1); // reset the number of cells
5386 if (errors) fSumw2.Set(fNcells);
5387 axis->SetTimeDisplay(timedisp);
5388 // reset histogram content
5389 Reset("ICE");
5390
5391 //now loop on all bins and refill
5392 // NOTE that if the bins without labels have content
5393 // it will be put in the underflow/overflow.
5394 // For this reason we use AddBinContent method
5397 for (bin=0; bin < hold->fNcells; ++bin) {
5398 hold->GetBinXYZ(bin,binx,biny,binz);
5400 Double_t cu = hold->RetrieveBinContent(bin);
5402 if (errors) {
5403 fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5404 }
5405 }
5407 delete hold;
5408}
5409
5410////////////////////////////////////////////////////////////////////////////////
5411/// Double the number of bins for axis.
5412/// Refill histogram.
5413/// This function is called by TAxis::FindBin(const char *label)
5414
5416{
5418 TAxis *axis = nullptr;
5419 if (iaxis == 1) axis = GetXaxis();
5420 if (iaxis == 2) axis = GetYaxis();
5421 if (iaxis == 3) axis = GetZaxis();
5422 if (!axis) return;
5423
5424 TH1 *hold = (TH1*)IsA()->New();
5425 hold->SetDirectory(nullptr);
5426 Copy(*hold);
5427 hold->ResetBit(kMustCleanup);
5428
5429 Bool_t timedisp = axis->GetTimeDisplay();
5430 Int_t nbins = axis->GetNbins();
5431 Double_t xmin = axis->GetXmin();
5432 Double_t xmax = axis->GetXmax();
5433 xmax = xmin + 2*(xmax-xmin);
5434 axis->SetRange(0,0);
5435 // double the bins and recompute ncells
5436 axis->Set(2*nbins,xmin,xmax);
5437 SetBinsLength(-1);
5439 if (errors) fSumw2.Set(fNcells);
5440 axis->SetTimeDisplay(timedisp);
5441
5442 Reset("ICE"); // reset content and error
5443
5444 //now loop on all bins and refill
5447 for (ibin =0; ibin < hold->fNcells; ibin++) {
5448 // get the binx,y,z values . The x-y-z (axis) bin values will stay the same between new-old after the expanding
5449 hold->GetBinXYZ(ibin,binx,biny,binz);
5450 bin = GetBin(binx,biny,binz);
5451
5452 // underflow and overflow will be cleaned up because their meaning has been altered
5453 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5454 continue;
5455 }
5456 else {
5457 AddBinContent(bin, hold->RetrieveBinContent(ibin));
5458 if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5459 }
5460 }
5462 delete hold;
5463}
5464
5465////////////////////////////////////////////////////////////////////////////////
5466/// Sort bins with labels or set option(s) to draw axis with labels
5467/// \param[in] option
5468/// - "a" sort by alphabetic order
5469/// - ">" sort by decreasing values
5470/// - "<" sort by increasing values
5471/// - "h" draw labels horizontal
5472/// - "v" draw labels vertical
5473/// - "u" draw labels up (end of label right adjusted)
5474/// - "d" draw labels down (start of label left adjusted)
5475///
5476/// In case not all bins have labels sorting will work only in the case
5477/// the first `n` consecutive bins have all labels and sorting will be performed on
5478/// those label bins.
5479///
5480/// \param[in] ax axis
5481
5483{
5485 TAxis *axis = nullptr;
5486 if (iaxis == 1)
5487 axis = GetXaxis();
5488 if (iaxis == 2)
5489 axis = GetYaxis();
5490 if (iaxis == 3)
5491 axis = GetZaxis();
5492 if (!axis)
5493 return;
5494 THashList *labels = axis->GetLabels();
5495 if (!labels) {
5496 Warning("LabelsOption", "Axis %s has no labels!",axis->GetName());
5497 return;
5498 }
5499 TString opt = option;
5500 opt.ToLower();
5501 Int_t iopt = -1;
5502 if (opt.Contains("h")) {
5507 iopt = 0;
5508 }
5509 if (opt.Contains("v")) {
5514 iopt = 1;
5515 }
5516 if (opt.Contains("u")) {
5517 axis->SetBit(TAxis::kLabelsUp);
5521 iopt = 2;
5522 }
5523 if (opt.Contains("d")) {
5528 iopt = 3;
5529 }
5530 Int_t sort = -1;
5531 if (opt.Contains("a"))
5532 sort = 0;
5533 if (opt.Contains(">"))
5534 sort = 1;
5535 if (opt.Contains("<"))
5536 sort = 2;
5537 if (sort < 0) {
5538 if (iopt < 0)
5539 Error("LabelsOption", "%s is an invalid label placement option!",opt.Data());
5540 return;
5541 }
5542
5543 // Code works only if first n bins have labels if we uncomment following line
5544 // but we don't want to support this special case
5545 // Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5546
5547 // support only cases where each bin has a labels (should be when axis is alphanumeric)
5548 Int_t n = labels->GetSize();
5549 if (n != axis->GetNbins()) {
5550 // check if labels are all consecutive and starts from the first bin
5551 // in that case the current code will work fine
5552 Int_t firstLabelBin = axis->GetNbins()+1;
5553 Int_t lastLabelBin = -1;
5554 for (Int_t i = 0; i < n; ++i) {
5555 Int_t bin = labels->At(i)->GetUniqueID();
5558 }
5559 if (firstLabelBin != 1 || lastLabelBin-firstLabelBin +1 != n) {
5560 Error("LabelsOption", "%s of Histogram %s contains bins without labels. Sorting will not work correctly - return",
5561 axis->GetName(), GetName());
5562 return;
5563 }
5564 // case where label bins are consecutive starting from first bin will work
5565 // calling before a TH1::LabelsDeflate() will avoid this error message
5566 Warning("LabelsOption", "axis %s of Histogram %s has extra following bins without labels. Sorting will work only for first label bins",
5567 axis->GetName(), GetName());
5568 }
5569 std::vector<Int_t> a(n);
5570 std::vector<Int_t> b(n);
5571
5572
5573 Int_t i, j, k;
5574 std::vector<Double_t> cont;
5575 std::vector<Double_t> errors2;
5576 THashList *labold = new THashList(labels->GetSize(), 1);
5577 TIter nextold(labels);
5578 TObject *obj = nullptr;
5579 labold->AddAll(labels);
5580 labels->Clear();
5581
5582 // delete buffer if it is there since bins will be reordered.
5583 if (fBuffer)
5584 BufferEmpty(1);
5585
5586 if (sort > 0) {
5587 //---sort by values of bins
5588 if (GetDimension() == 1) {
5589 cont.resize(n);
5590 if (fSumw2.fN)
5591 errors2.resize(n);
5592 for (i = 0; i < n; i++) {
5593 cont[i] = RetrieveBinContent(i + 1);
5594 if (!errors2.empty())
5595 errors2[i] = GetBinErrorSqUnchecked(i + 1);
5596 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5597 a[i] = i;
5598 }
5599 if (sort == 1)
5600 TMath::Sort(n, cont.data(), a.data(), kTRUE); // sort by decreasing values
5601 else
5602 TMath::Sort(n, cont.data(), a.data(), kFALSE); // sort by increasing values
5603 for (i = 0; i < n; i++) {
5604 // use UpdateBinCOntent to not screw up histogram entries
5605 UpdateBinContent(i + 1, cont[b[a[i]] - 1]); // b[a[i]] returns bin number. .we need to subtract 1
5606 if (gDebug)
5607 Info("LabelsOption","setting bin %d value %f from bin %d label %s at pos %d ",
5608 i+1,cont[b[a[i]] - 1],b[a[i]],labold->At(a[i])->GetName(),a[i]);
5609 if (!errors2.empty())
5610 fSumw2.fArray[i + 1] = errors2[b[a[i]] - 1];
5611 }
5612 for (i = 0; i < n; i++) {
5613 obj = labold->At(a[i]);
5614 labels->Add(obj);
5615 obj->SetUniqueID(i + 1);
5616 }
5617 } else if (GetDimension() == 2) {
5618 std::vector<Double_t> pcont(n + 2);
5619 Int_t nx = fXaxis.GetNbins() + 2;
5620 Int_t ny = fYaxis.GetNbins() + 2;
5621 cont.resize((nx + 2) * (ny + 2));
5622 if (fSumw2.fN)
5623 errors2.resize((nx + 2) * (ny + 2));
5624 for (i = 0; i < nx; i++) {
5625 for (j = 0; j < ny; j++) {
5626 Int_t bin = GetBin(i,j);
5627 cont[i + nx * j] = RetrieveBinContent(bin);
5628 if (!errors2.empty())
5630 if (axis == GetXaxis())
5631 k = i - 1;
5632 else
5633 k = j - 1;
5634 if (k >= 0 && k < n) { // we consider underflow/overflows in y for ordering the bins
5635 pcont[k] += cont[i + nx * j];
5636 a[k] = k;
5637 }
5638 }
5639 }
5640 if (sort == 1)
5641 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5642 else
5643 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5644 for (i = 0; i < n; i++) {
5645 // iterate on old label list to find corresponding bin match
5646 TIter next(labold);
5647 UInt_t bin = a[i] + 1;
5648 while ((obj = next())) {
5649 if (obj->GetUniqueID() == (UInt_t)bin)
5650 break;
5651 else
5652 obj = nullptr;
5653 }
5654 if (!obj) {
5655 // this should not really happen
5656 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5657 return;
5658 }
5659
5660 labels->Add(obj);
5661 if (gDebug)
5662 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from order " << a[i] << " bin "
5663 << b[a[i]] << "content " << pcont[a[i]] << std::endl;
5664 }
5665 // need to set here new ordered labels - otherwise loop before does not work since labold and labels list
5666 // contain same objects
5667 for (i = 0; i < n; i++) {
5668 labels->At(i)->SetUniqueID(i + 1);
5669 }
5670 // set now the bin contents
5671 if (axis == GetXaxis()) {
5672 for (i = 0; i < n; i++) {
5673 Int_t ix = a[i] + 1;
5674 for (j = 0; j < ny; j++) {
5675 Int_t bin = GetBin(i + 1, j);
5676 UpdateBinContent(bin, cont[ix + nx * j]);
5677 if (!errors2.empty())
5678 fSumw2.fArray[bin] = errors2[ix + nx * j];
5679 }
5680 }
5681 } else {
5682 // using y axis
5683 for (i = 0; i < nx; i++) {
5684 for (j = 0; j < n; j++) {
5685 Int_t iy = a[j] + 1;
5686 Int_t bin = GetBin(i, j + 1);
5687 UpdateBinContent(bin, cont[i + nx * iy]);
5688 if (!errors2.empty())
5689 fSumw2.fArray[bin] = errors2[i + nx * iy];
5690 }
5691 }
5692 }
5693 } else {
5694 // sorting histograms: 3D case
5695 std::vector<Double_t> pcont(n + 2);
5696 Int_t nx = fXaxis.GetNbins() + 2;
5697 Int_t ny = fYaxis.GetNbins() + 2;
5698 Int_t nz = fZaxis.GetNbins() + 2;
5699 Int_t l = 0;
5700 cont.resize((nx + 2) * (ny + 2) * (nz + 2));
5701 if (fSumw2.fN)
5702 errors2.resize((nx + 2) * (ny + 2) * (nz + 2));
5703 for (i = 0; i < nx; i++) {
5704 for (j = 0; j < ny; j++) {
5705 for (k = 0; k < nz; k++) {
5706 Int_t bin = GetBin(i,j,k);
5708 if (axis == GetXaxis())
5709 l = i - 1;
5710 else if (axis == GetYaxis())
5711 l = j - 1;
5712 else
5713 l = k - 1;
5714 if (l >= 0 && l < n) { // we consider underflow/overflows in y for ordering the bins
5715 pcont[l] += c;
5716 a[l] = l;
5717 }
5718 cont[i + nx * (j + ny * k)] = c;
5719 if (!errors2.empty())
5720 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5721 }
5722 }
5723 }
5724 if (sort == 1)
5725 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5726 else
5727 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5728 for (i = 0; i < n; i++) {
5729 // iterate on the old label list to find corresponding bin match
5730 TIter next(labold);
5731 UInt_t bin = a[i] + 1;
5732 obj = nullptr;
5733 while ((obj = next())) {
5734 if (obj->GetUniqueID() == (UInt_t)bin) {
5735 break;
5736 }
5737 else
5738 obj = nullptr;
5739 }
5740 if (!obj) {
5741 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5742 return;
5743 }
5744 labels->Add(obj);
5745 if (gDebug)
5746 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from bin " << a[i] << "content "
5747 << pcont[a[i]] << std::endl;
5748 }
5749
5750 // need to set here new ordered labels - otherwise loop before does not work since labold and llabels list
5751 // contain same objects
5752 for (i = 0; i < n; i++) {
5753 labels->At(i)->SetUniqueID(i + 1);
5754 }
5755 // set now the bin contents
5756 if (axis == GetXaxis()) {
5757 for (i = 0; i < n; i++) {
5758 Int_t ix = a[i] + 1;
5759 for (j = 0; j < ny; j++) {
5760 for (k = 0; k < nz; k++) {
5761 Int_t bin = GetBin(i + 1, j, k);
5762 UpdateBinContent(bin, cont[ix + nx * (j + ny * k)]);
5763 if (!errors2.empty())
5764 fSumw2.fArray[bin] = errors2[ix + nx * (j + ny * k)];
5765 }
5766 }
5767 }
5768 } else if (axis == GetYaxis()) {
5769 // using y axis
5770 for (i = 0; i < nx; i++) {
5771 for (j = 0; j < n; j++) {
5772 Int_t iy = a[j] + 1;
5773 for (k = 0; k < nz; k++) {
5774 Int_t bin = GetBin(i, j + 1, k);
5775 UpdateBinContent(bin, cont[i + nx * (iy + ny * k)]);
5776 if (!errors2.empty())
5777 fSumw2.fArray[bin] = errors2[i + nx * (iy + ny * k)];
5778 }
5779 }
5780 }
5781 } else {
5782 // using z axis
5783 for (i = 0; i < nx; i++) {
5784 for (j = 0; j < ny; j++) {
5785 for (k = 0; k < n; k++) {
5786 Int_t iz = a[k] + 1;
5787 Int_t bin = GetBin(i, j , k +1);
5788 UpdateBinContent(bin, cont[i + nx * (j + ny * iz)]);
5789 if (!errors2.empty())
5790 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * iz)];
5791 }
5792 }
5793 }
5794 }
5795 }
5796 } else {
5797 //---alphabetic sort
5798 // sort labels using vector of strings and TMath::Sort
5799 // I need to array because labels order in list is not necessary that of the bins
5800 std::vector<std::string> vecLabels(n);
5801 for (i = 0; i < n; i++) {
5802 vecLabels[i] = labold->At(i)->GetName();
5803 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5804 a[i] = i;
5805 }
5806 // sort in ascending order for strings
5807 TMath::Sort(n, vecLabels.data(), a.data(), kFALSE);
5808 // set the new labels
5809 for (i = 0; i < n; i++) {
5810 TObject *labelObj = labold->At(a[i]);
5811 labels->Add(labold->At(a[i]));
5812 // set the corresponding bin. NB bin starts from 1
5813 labelObj->SetUniqueID(i + 1);
5814 if (gDebug)
5815 std::cout << "bin " << i + 1 << " setting new labels for axis " << labold->At(a[i])->GetName() << " from "
5816 << b[a[i]] << std::endl;
5817 }
5818
5819 if (GetDimension() == 1) {
5820 cont.resize(n + 2);
5821 if (fSumw2.fN)
5822 errors2.resize(n + 2);
5823 for (i = 0; i < n; i++) {
5824 cont[i] = RetrieveBinContent(b[a[i]]);
5825 if (!errors2.empty())
5827 }
5828 for (i = 0; i < n; i++) {
5829 UpdateBinContent(i + 1, cont[i]);
5830 if (!errors2.empty())
5831 fSumw2.fArray[i+1] = errors2[i];
5832 }
5833 } else if (GetDimension() == 2) {
5834 Int_t nx = fXaxis.GetNbins() + 2;
5835 Int_t ny = fYaxis.GetNbins() + 2;
5836 cont.resize(nx * ny);
5837 if (fSumw2.fN)
5838 errors2.resize(nx * ny);
5839 // copy old bin contents and then set to new ordered bins
5840 // N.B. bin in histograms starts from 1, but in y we consider under/overflows
5841 for (i = 0; i < nx; i++) {
5842 for (j = 0; j < ny; j++) { // ny is nbins+2
5843 Int_t bin = GetBin(i, j);
5844 cont[i + nx * j] = RetrieveBinContent(bin);
5845 if (!errors2.empty())
5847 }
5848 }
5849 if (axis == GetXaxis()) {
5850 for (i = 0; i < n; i++) {
5851 for (j = 0; j < ny; j++) {
5852 Int_t bin = GetBin(i + 1 , j);
5853 UpdateBinContent(bin, cont[b[a[i]] + nx * j]);
5854 if (!errors2.empty())
5855 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * j];
5856 }
5857 }
5858 } else {
5859 for (i = 0; i < nx; i++) {
5860 for (j = 0; j < n; j++) {
5861 Int_t bin = GetBin(i, j + 1);
5862 UpdateBinContent(bin, cont[i + nx * b[a[j]]]);
5863 if (!errors2.empty())
5864 fSumw2.fArray[bin] = errors2[i + nx * b[a[j]]];
5865 }
5866 }
5867 }
5868 } else {
5869 // case of 3D (needs to be tested)
5870 Int_t nx = fXaxis.GetNbins() + 2;
5871 Int_t ny = fYaxis.GetNbins() + 2;
5872 Int_t nz = fZaxis.GetNbins() + 2;
5873 cont.resize(nx * ny * nz);
5874 if (fSumw2.fN)
5875 errors2.resize(nx * ny * nz);
5876 for (i = 0; i < nx; i++) {
5877 for (j = 0; j < ny; j++) {
5878 for (k = 0; k < nz; k++) {
5879 Int_t bin = GetBin(i, j, k);
5880 cont[i + nx * (j + ny * k)] = RetrieveBinContent(bin);
5881 if (!errors2.empty())
5882 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5883 }
5884 }
5885 }
5886 if (axis == GetXaxis()) {
5887 // labels on x axis
5888 for (i = 0; i < n; i++) { // for x we loop only on bins with the labels
5889 for (j = 0; j < ny; j++) {
5890 for (k = 0; k < nz; k++) {
5891 Int_t bin = GetBin(i + 1, j, k);
5892 UpdateBinContent(bin, cont[b[a[i]] + nx * (j + ny * k)]);
5893 if (!errors2.empty())
5894 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * (j + ny * k)];
5895 }
5896 }
5897 }
5898 } else if (axis == GetYaxis()) {
5899 // labels on y axis
5900 for (i = 0; i < nx; i++) {
5901 for (j = 0; j < n; j++) {
5902 for (k = 0; k < nz; k++) {
5903 Int_t bin = GetBin(i, j+1, k);
5904 UpdateBinContent(bin, cont[i + nx * (b[a[j]] + ny * k)]);
5905 if (!errors2.empty())
5906 fSumw2.fArray[bin] = errors2[i + nx * (b[a[j]] + ny * k)];
5907 }
5908 }
5909 }
5910 } else {
5911 // labels on z axis
5912 for (i = 0; i < nx; i++) {
5913 for (j = 0; j < ny; j++) {
5914 for (k = 0; k < n; k++) {
5915 Int_t bin = GetBin(i, j, k+1);
5916 UpdateBinContent(bin, cont[i + nx * (j + ny * b[a[k]])]);
5917 if (!errors2.empty())
5918 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * b[a[k]])];
5919 }
5920 }
5921 }
5922 }
5923 }
5924 }
5925 // need to set to zero the statistics if axis has been sorted
5926 // see for example TH3::PutStats for definition of s vector
5927 bool labelsAreSorted = kFALSE;
5928 for (i = 0; i < n; ++i) {
5929 if (a[i] != i) {
5931 break;
5932 }
5933 }
5934 if (labelsAreSorted) {
5935 double s[TH1::kNstat];
5936 GetStats(s);
5937 if (iaxis == 1) {
5938 s[2] = 0; // fTsumwx
5939 s[3] = 0; // fTsumwx2
5940 s[6] = 0; // fTsumwxy
5941 s[9] = 0; // fTsumwxz
5942 } else if (iaxis == 2) {
5943 s[4] = 0; // fTsumwy
5944 s[5] = 0; // fTsumwy2
5945 s[6] = 0; // fTsumwxy
5946 s[10] = 0; // fTsumwyz
5947 } else if (iaxis == 3) {
5948 s[7] = 0; // fTsumwz
5949 s[8] = 0; // fTsumwz2
5950 s[9] = 0; // fTsumwxz
5951 s[10] = 0; // fTsumwyz
5952 }
5953 PutStats(s);
5954 }
5955 delete labold;
5956}
5957
5958////////////////////////////////////////////////////////////////////////////////
5959/// Test if two double are almost equal.
5960
5961static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5962{
5963 return TMath::Abs(a - b) < epsilon;
5964}
5965
5966////////////////////////////////////////////////////////////////////////////////
5967/// Test if a double is almost an integer.
5968
5969static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5970{
5971 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5972 AlmostEqual(a - TMath::Floor(a), 1, epsilon);
5973}
5974
5975////////////////////////////////////////////////////////////////////////////////
5976/// Test if the binning is equidistant.
5977
5978static inline bool IsEquidistantBinning(const TAxis& axis)
5979{
5980 // check if axis bin are equals
5981 if (!axis.GetXbins()->fN) return true; //
5982 // not able to check if there is only one axis entry
5983 bool isEquidistant = true;
5984 const Double_t firstBinWidth = axis.GetBinWidth(1);
5985 for (int i = 1; i < axis.GetNbins(); ++i) {
5986 const Double_t binWidth = axis.GetBinWidth(i);
5987 const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5988 isEquidistant &= match;
5989 if (!match)
5990 break;
5991 }
5992 return isEquidistant;
5993}
5994
5995////////////////////////////////////////////////////////////////////////////////
5996/// Same limits and bins.
5997
5999 return axis1.GetNbins() == axis2.GetNbins() &&
6000 TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
6001 TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
6002}
6003
6004////////////////////////////////////////////////////////////////////////////////
6005/// Finds new limits for the axis for the Merge function.
6006/// returns false if the limits are incompatible
6007
6009{
6011 return kTRUE;
6012
6014 return kFALSE; // not equidistant user binning not supported
6015
6016 Double_t width1 = destAxis.GetBinWidth(0);
6017 Double_t width2 = anAxis.GetBinWidth(0);
6018 if (width1 == 0 || width2 == 0)
6019 return kFALSE; // no binning not supported
6020
6021 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
6022 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
6024
6025 // check the bin size
6027 return kFALSE;
6028
6029 // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
6030 // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
6031
6032
6033 // check the limits
6034 Double_t delta;
6035 delta = (destAxis.GetXmin() - xmin)/width1;
6036 if (!AlmostInteger(delta))
6037 xmin -= (TMath::Ceil(delta) - delta)*width1;
6038
6039 delta = (anAxis.GetXmin() - xmin)/width2;
6040 if (!AlmostInteger(delta))
6041 xmin -= (TMath::Ceil(delta) - delta)*width2;
6042
6043
6044 delta = (destAxis.GetXmin() - xmin)/width1;
6045 if (!AlmostInteger(delta))
6046 return kFALSE;
6047
6048
6049 delta = (xmax - destAxis.GetXmax())/width1;
6050 if (!AlmostInteger(delta))
6051 xmax += (TMath::Ceil(delta) - delta)*width1;
6052
6053
6054 delta = (xmax - anAxis.GetXmax())/width2;
6055 if (!AlmostInteger(delta))
6056 xmax += (TMath::Ceil(delta) - delta)*width2;
6057
6058
6059 delta = (xmax - destAxis.GetXmax())/width1;
6060 if (!AlmostInteger(delta))
6061 return kFALSE;
6062#ifdef DEBUG
6063 if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
6064 printf("TH1::RecomputeAxisLimits - Impossible\n");
6065 return kFALSE;
6066 }
6067#endif
6068
6069
6071
6072 //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
6073
6074 return kTRUE;
6075}
6076
6077////////////////////////////////////////////////////////////////////////////////
6078/// Add all histograms in the collection to this histogram.
6079/// This function computes the min/max for the x axis,
6080/// compute a new number of bins, if necessary,
6081/// add bin contents, errors and statistics.
6082/// If all histograms have bin labels, bins with identical labels
6083/// will be merged, no matter what their order is.
6084/// If overflows are present and limits are different the function will fail.
6085/// The function returns the total number of entries in the result histogram
6086/// if the merge is successful, -1 otherwise.
6087///
6088/// Possible option:
6089/// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
6090/// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
6091/// (enabled by default) slows down the merging
6092///
6093/// IMPORTANT remark. The axis x may have different number
6094/// of bins and different limits, BUT the largest bin width must be
6095/// a multiple of the smallest bin width and the upper limit must also
6096/// be a multiple of the bin width.
6097/// Example:
6098///
6099/// ~~~ {.cpp}
6100/// void atest() {
6101/// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
6102/// TH1F *h2 = new TH1F("h2","h2",220,0,110);
6103/// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
6104/// TRandom r;
6105/// for (Int_t i=0;i<10000;i++) {
6106/// h1->Fill(r.Gaus(-55,10));
6107/// h2->Fill(r.Gaus(55,10));
6108/// h3->Fill(r.Gaus(0,10));
6109/// }
6110///
6111/// TList *list = new TList;
6112/// list->Add(h1);
6113/// list->Add(h2);
6114/// list->Add(h3);
6115/// TH1F *h = (TH1F*)h1->Clone("h");
6116/// h->Reset();
6117/// h->Merge(list);
6118/// h->Draw();
6119/// }
6120/// ~~~
6121
6123{
6124 if (!li) return 0;
6125 if (li->IsEmpty()) return (Long64_t) GetEntries();
6126
6127 // use TH1Merger class
6128 TH1Merger merger(*this,*li,opt);
6129 Bool_t ret = merger();
6130
6131 return (ret) ? GetEntries() : -1;
6132}
6133
6134
6135////////////////////////////////////////////////////////////////////////////////
6136/// Performs the operation:
6137///
6138/// `this = this*c1*f1`
6139///
6140/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
6141///
6142/// Only bins inside the function range are recomputed.
6143/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6144/// you should call Sumw2 before making this operation.
6145/// This is particularly important if you fit the histogram after TH1::Multiply
6146///
6147/// The function return kFALSE if the Multiply operation failed
6148
6150{
6151 if (!f1) {
6152 Error("Multiply","Attempt to multiply by a non-existing function");
6153 return kFALSE;
6154 }
6155
6156 // delete buffer if it is there since it will become invalid
6157 if (fBuffer) BufferEmpty(1);
6158
6159 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
6160 Int_t ny = GetNbinsY() + 2;
6161 Int_t nz = GetNbinsZ() + 2;
6162 if (fDimension < 2) ny = 1;
6163 if (fDimension < 3) nz = 1;
6164
6165 // reset min-maximum
6166 SetMinimum();
6167 SetMaximum();
6168
6169 // - Loop on bins (including underflows/overflows)
6170 Double_t xx[3];
6171 Double_t *params = nullptr;
6172 f1->InitArgs(xx,params);
6173
6174 for (Int_t binz = 0; binz < nz; ++binz) {
6175 xx[2] = fZaxis.GetBinCenter(binz);
6176 for (Int_t biny = 0; biny < ny; ++biny) {
6177 xx[1] = fYaxis.GetBinCenter(biny);
6178 for (Int_t binx = 0; binx < nx; ++binx) {
6179 xx[0] = fXaxis.GetBinCenter(binx);
6180 if (!f1->IsInside(xx)) continue;
6182 Int_t bin = binx + nx * (biny + ny *binz);
6183 Double_t cu = c1*f1->EvalPar(xx);
6184 if (TF1::RejectedPoint()) continue;
6186 if (fSumw2.fN) {
6188 }
6189 }
6190 }
6191 }
6192 ResetStats();
6193 return kTRUE;
6194}
6195
6196////////////////////////////////////////////////////////////////////////////////
6197/// Multiply this histogram by h1.
6198///
6199/// `this = this*h1`
6200///
6201/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6202/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
6203/// if not already set.
6204///
6205/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6206/// you should call Sumw2 before making this operation.
6207/// This is particularly important if you fit the histogram after TH1::Multiply
6208///
6209/// The function return kFALSE if the Multiply operation failed
6210
6211Bool_t TH1::Multiply(const TH1 *h1)
6212{
6213 if (!h1) {
6214 Error("Multiply","Attempt to multiply by a non-existing histogram");
6215 return kFALSE;
6216 }
6217
6218 // delete buffer if it is there since it will become invalid
6219 if (fBuffer) BufferEmpty(1);
6220
6221 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins) {
6222 return false;
6223 }
6224
6225 // Create Sumw2 if h1 has Sumw2 set
6226 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
6227
6228 // - Reset min- maximum
6229 SetMinimum();
6230 SetMaximum();
6231
6232 // - Loop on bins (including underflows/overflows)
6233 for (Int_t i = 0; i < fNcells; ++i) {
6236 UpdateBinContent(i, c0 * c1);
6237 if (fSumw2.fN) {
6239 }
6240 }
6241 ResetStats();
6242 return kTRUE;
6243}
6244
6245////////////////////////////////////////////////////////////////////////////////
6246/// Replace contents of this histogram by multiplication of h1 by h2.
6247///
6248/// `this = (c1*h1)*(c2*h2)`
6249///
6250/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6251/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
6252/// if not already set.
6253///
6254/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6255/// you should call Sumw2 before making this operation.
6256/// This is particularly important if you fit the histogram after TH1::Multiply
6257///
6258/// The function return kFALSE if the Multiply operation failed
6259
6261{
6262 TString opt = option;
6263 opt.ToLower();
6264 // Bool_t binomial = kFALSE;
6265 // if (opt.Contains("b")) binomial = kTRUE;
6266 if (!h1 || !h2) {
6267 Error("Multiply","Attempt to multiply by a non-existing histogram");
6268 return kFALSE;
6269 }
6270
6271 // delete buffer if it is there since it will become invalid
6272 if (fBuffer) BufferEmpty(1);
6273
6274 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins ||
6275 LoggedInconsistency("Multiply", h1, h2) >= kDifferentNumberOfBins) {
6276 return false;
6277 }
6278
6279 // Create Sumw2 if h1 or h2 have Sumw2 set
6280 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
6281
6282 // - Reset min - maximum
6283 SetMinimum();
6284 SetMaximum();
6285
6286 // - Loop on bins (including underflows/overflows)
6287 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
6288 for (Int_t i = 0; i < fNcells; ++i) {
6290 Double_t b2 = h2->RetrieveBinContent(i);
6291 UpdateBinContent(i, c1 * b1 * c2 * b2);
6292 if (fSumw2.fN) {
6293 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
6294 }
6295 }
6296 ResetStats();
6297 return kTRUE;
6298}
6299
6300////////////////////////////////////////////////////////////////////////////////
6301/// @brief Normalize a histogram to its integral or to its maximum.
6302/// @note Works for TH1, TH2, TH3, ...
6303/// @param option: normalization strategy ("", "max" or "sum")
6304/// - "": Scale to `1/(sum*bin_width)`.
6305/// - max: Scale to `1/GetMaximum()`
6306/// - sum: Scale to `1/sum`.
6307///
6308/// In case the norm is zero, it raises an error.
6309/// @sa https://root-forum.cern.ch/t/different-ways-of-normalizing-histograms/15582/
6310
6312{
6313 TString opt = option;
6314 opt.ToLower();
6315 if (!opt.IsNull() && (opt != "max") && (opt != "sum")) {
6316 Error("Normalize", "Unrecognized option %s", option);
6317 return;
6318 }
6319
6320 const Double_t norm = (opt == "max") ? GetMaximum() : Integral(opt.IsNull() ? "width" : "");
6321
6322 if (norm == 0) {
6323 Error("Normalize", "Attempt to normalize histogram with zero integral");
6324 } else {
6325 Scale(1.0 / norm, "");
6326 // An alternative could have been to call Integral("") and Scale(1/norm, "width"), but this
6327 // will lead to a different value of GetEntries.
6328 // Instead, doing simultaneously Integral("width") and Scale(1/norm, "width") leads to an error since you are
6329 // dividing twice by bin width.
6330 }
6331}
6332
6333////////////////////////////////////////////////////////////////////////////////
6334/// Control routine to paint any kind of histograms.
6335///
6336/// This function is automatically called by TCanvas::Update.
6337/// (see TH1::Draw for the list of options)
6338
6340{
6342
6343 if (fPainter) {
6344 if (option && strlen(option) > 0)
6346 else
6348 }
6349}
6350
6351////////////////////////////////////////////////////////////////////////////////
6352/// Rebin this histogram
6353///
6354/// #### case 1 xbins=0
6355///
6356/// If newname is blank (default), the current histogram is modified and
6357/// a pointer to it is returned.
6358///
6359/// If newname is not blank, the current histogram is not modified, and a
6360/// new histogram is returned which is a Clone of the current histogram
6361/// with its name set to newname.
6362///
6363/// The parameter ngroup indicates how many bins of this have to be merged
6364/// into one bin of the result.
6365///
6366/// If the original histogram has errors stored (via Sumw2), the resulting
6367/// histograms has new errors correctly calculated.
6368///
6369/// examples: if h1 is an existing TH1F histogram with 100 bins
6370///
6371/// ~~~ {.cpp}
6372/// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
6373/// h1->Rebin(5); //merges five bins in one in h1
6374/// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
6375/// // merging 5 bins of h1 in one bin
6376/// ~~~
6377///
6378/// NOTE: If ngroup is not an exact divider of the number of bins,
6379/// the top limit of the rebinned histogram is reduced
6380/// to the upper edge of the last bin that can make a complete
6381/// group. The remaining bins are added to the overflow bin.
6382/// Statistics will be recomputed from the new bin contents.
6383///
6384/// #### case 2 xbins!=0
6385///
6386/// A new histogram is created (you should specify newname).
6387/// The parameter ngroup is the number of variable size bins in the created histogram.
6388/// The array xbins must contain ngroup+1 elements that represent the low-edges
6389/// of the bins.
6390/// If the original histogram has errors stored (via Sumw2), the resulting
6391/// histograms has new errors correctly calculated.
6392///
6393/// NOTE: The bin edges specified in xbins should correspond to bin edges
6394/// in the original histogram. If a bin edge in the new histogram is
6395/// in the middle of a bin in the original histogram, all entries in
6396/// the split bin in the original histogram will be transferred to the
6397/// lower of the two possible bins in the new histogram. This is
6398/// probably not what you want. A warning message is emitted in this
6399/// case
6400///
6401/// examples: if h1 is an existing TH1F histogram with 100 bins
6402///
6403/// ~~~ {.cpp}
6404/// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
6405/// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
6406/// ~~~
6407
6408TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
6409{
6410 Int_t nbins = fXaxis.GetNbins();
6413 if ((ngroup <= 0) || (ngroup > nbins)) {
6414 Error("Rebin", "Illegal value of ngroup=%d",ngroup);
6415 return nullptr;
6416 }
6417
6418 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
6419 Error("Rebin", "Operation valid on 1-D histograms only");
6420 return nullptr;
6421 }
6422 if (!newname && xbins) {
6423 Error("Rebin","if xbins is specified, newname must be given");
6424 return nullptr;
6425 }
6426
6427 Int_t newbins = nbins/ngroup;
6428 if (!xbins) {
6429 Int_t nbg = nbins/ngroup;
6430 if (nbg*ngroup != nbins) {
6431 Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
6432 }
6433 }
6434 else {
6435 // in the case that xbins is given (rebinning in variable bins), ngroup is
6436 // the new number of bins and number of grouped bins is not constant.
6437 // when looping for setting the contents for the new histogram we
6438 // need to loop on all bins of original histogram. Then set ngroup=nbins
6439 newbins = ngroup;
6440 ngroup = nbins;
6441 }
6442
6443 // Save old bin contents into a new array
6444 Double_t entries = fEntries;
6445 Double_t *oldBins = new Double_t[nbins+2];
6446 Int_t bin, i;
6447 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
6448 Double_t *oldErrors = nullptr;
6449 if (fSumw2.fN != 0) {
6450 oldErrors = new Double_t[nbins+2];
6451 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
6452 }
6453 // rebin will not include underflow/overflow if new axis range is larger than old axis range
6454 if (xbins) {
6455 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
6456 Warning("Rebin","underflow entries will not be used when rebinning");
6457 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
6458 Warning("Rebin","overflow entries will not be used when rebinning");
6459 }
6460
6461
6462 // create a clone of the old histogram if newname is specified
6463 TH1 *hnew = this;
6464 if ((newname && strlen(newname) > 0) || xbins) {
6465 hnew = (TH1*)Clone(newname);
6466 }
6467
6468 //reset can extend bit to avoid an axis extension in SetBinContent
6469 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
6470
6471 // save original statistics
6472 Double_t stat[kNstat];
6473 GetStats(stat);
6474 bool resetStat = false;
6475 // change axis specs and rebuild bin contents array::RebinAx
6476 if(!xbins && (newbins*ngroup != nbins)) {
6478 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
6479 }
6480 // save the TAttAxis members (reset by SetBins)
6492
6493 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
6494 Double_t *bins = new Double_t[newbins+1];
6495 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
6496 hnew->SetBins(newbins,bins); //this also changes errors array (if any)
6497 delete [] bins;
6498 } else if (xbins) {
6499 hnew->SetBins(newbins,xbins);
6500 } else {
6501 hnew->SetBins(newbins,xmin,xmax);
6502 }
6503
6504 // Restore axis attributes
6516
6517 // copy merged bin contents (ignore under/overflows)
6518 // Start merging only once the new lowest edge is reached
6519 Int_t startbin = 1;
6520 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
6521 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
6522 startbin++;
6523 }
6526 for (bin = 1;bin<=newbins;bin++) {
6527 binContent = 0;
6528 binError = 0;
6529 Int_t imax = ngroup;
6530 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6531 // check bin edges for the cases when we provide an array of bins
6532 // be careful in case bins can have zero width
6534 hnew->GetXaxis()->GetBinLowEdge(bin),
6535 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6536 {
6537 Warning("Rebin","Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6538 }
6539 for (i=0;i<ngroup;i++) {
6540 if( (oldbin+i > nbins) ||
6541 ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6542 imax = i;
6543 break;
6544 }
6547 }
6548 hnew->SetBinContent(bin,binContent);
6549 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6550 oldbin += imax;
6551 }
6552
6553 // sum underflow and overflow contents until startbin
6554 binContent = 0;
6555 binError = 0;
6556 for (i = 0; i < startbin; ++i) {
6557 binContent += oldBins[i];
6558 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6559 }
6560 hnew->SetBinContent(0,binContent);
6561 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6562 // sum overflow
6563 binContent = 0;
6564 binError = 0;
6565 for (i = oldbin; i <= nbins+1; ++i) {
6566 binContent += oldBins[i];
6567 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6568 }
6569 hnew->SetBinContent(newbins+1,binContent);
6570 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6571
6572 hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6573
6574 // restore statistics and entries modified by SetBinContent
6575 hnew->SetEntries(entries);
6576 if (!resetStat) hnew->PutStats(stat);
6577 delete [] oldBins;
6578 if (oldErrors) delete [] oldErrors;
6579 return hnew;
6580}
6581
6582////////////////////////////////////////////////////////////////////////////////
6583/// finds new limits for the axis so that *point* is within the range and
6584/// the limits are compatible with the previous ones (see TH1::Merge).
6585/// new limits are put into *newMin* and *newMax* variables.
6586/// axis - axis whose limits are to be recomputed
6587/// point - point that should fit within the new axis limits
6588/// newMin - new minimum will be stored here
6589/// newMax - new maximum will be stored here.
6590/// false if failed (e.g. if the initial axis limits are wrong
6591/// or the new range is more than \f$ 2^{64} \f$ times the old one).
6592
6594{
6595 Double_t xmin = axis->GetXmin();
6596 Double_t xmax = axis->GetXmax();
6597 if (xmin >= xmax) return kFALSE;
6599
6600 //recompute new axis limits by doubling the current range
6601 Int_t ntimes = 0;
6602 while (point < xmin) {
6603 if (ntimes++ > 64)
6604 return kFALSE;
6605 xmin = xmin - range;
6606 range *= 2;
6607 }
6608 while (point >= xmax) {
6609 if (ntimes++ > 64)
6610 return kFALSE;
6611 xmax = xmax + range;
6612 range *= 2;
6613 }
6614 newMin = xmin;
6615 newMax = xmax;
6616 // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6617 // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6618
6619 return kTRUE;
6620}
6621
6622////////////////////////////////////////////////////////////////////////////////
6623/// Histogram is resized along axis such that x is in the axis range.
6624/// The new axis limits are recomputed by doubling iteratively
6625/// the current axis range until the specified value x is within the limits.
6626/// The algorithm makes a copy of the histogram, then loops on all bins
6627/// of the old histogram to fill the extended histogram.
6628/// Takes into account errors (Sumw2) if any.
6629/// The algorithm works for 1-d, 2-D and 3-D histograms.
6630/// The axis must be extendable before invoking this function.
6631/// Ex:
6632///
6633/// ~~~ {.cpp}
6634/// h->GetXaxis()->SetCanExtend(kTRUE);
6635/// ~~~
6636
6637void TH1::ExtendAxis(Double_t x, TAxis *axis)
6638{
6639 if (!axis->CanExtend()) return;
6640 if (TMath::IsNaN(x)) { // x may be a NaN
6642 return;
6643 }
6644
6645 if (axis->GetXmin() >= axis->GetXmax()) return;
6646 if (axis->GetNbins() <= 0) return;
6647
6649 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6650 return;
6651
6652 //save a copy of this histogram
6653 TH1 *hold = (TH1*)IsA()->New();
6654 hold->SetDirectory(nullptr);
6655 Copy(*hold);
6656 //set new axis limits
6657 axis->SetLimits(xmin,xmax);
6658
6659
6660 //now loop on all bins and refill
6662
6663 Reset("ICE"); //reset only Integral, contents and Errors
6664
6665 int iaxis = 0;
6666 if (axis == &fXaxis) iaxis = 1;
6667 if (axis == &fYaxis) iaxis = 2;
6668 if (axis == &fZaxis) iaxis = 3;
6669 bool firstw = kTRUE;
6670 Int_t binx,biny, binz = 0;
6671 Int_t ix = 0,iy = 0,iz = 0;
6672 Double_t bx,by,bz;
6673 Int_t ncells = hold->GetNcells();
6674 for (Int_t bin = 0; bin < ncells; ++bin) {
6675 hold->GetBinXYZ(bin,binx,biny,binz);
6676 bx = hold->GetXaxis()->GetBinCenter(binx);
6677 ix = fXaxis.FindFixBin(bx);
6678 if (fDimension > 1) {
6679 by = hold->GetYaxis()->GetBinCenter(biny);
6680 iy = fYaxis.FindFixBin(by);
6681 if (fDimension > 2) {
6682 bz = hold->GetZaxis()->GetBinCenter(binz);
6683 iz = fZaxis.FindFixBin(bz);
6684 }
6685 }
6686 // exclude underflow/overflow
6687 double content = hold->RetrieveBinContent(bin);
6688 if (content == 0) continue;
6690 if (firstw) {
6691 Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6692 " their content will be lost",GetName() );
6693 firstw= kFALSE;
6694 }
6695 continue;
6696 }
6697 Int_t ibin= GetBin(ix,iy,iz);
6699 if (errors) {
6700 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6701 }
6702 }
6703 delete hold;
6704}
6705
6706////////////////////////////////////////////////////////////////////////////////
6707/// Recursively remove object from the list of functions
6708
6710{
6711 // Rely on TROOT::RecursiveRemove to take the readlock.
6712
6713 if (fFunctions) {
6715 }
6716}
6717
6718////////////////////////////////////////////////////////////////////////////////
6719/// Multiply this histogram by a constant c1.
6720///
6721/// `this = c1*this`
6722///
6723/// Note that both contents and errors (if any) are scaled.
6724/// This function uses the services of TH1::Add
6725///
6726/// IMPORTANT NOTE: Sumw2() is called automatically when scaling.
6727/// If you are not interested in the histogram statistics you can call
6728/// Sumw2(kFALSE) or use the option "nosw2"
6729///
6730/// One can scale a histogram such that the bins integral is equal to
6731/// the normalization parameter via TH1::Scale(Double_t norm), where norm
6732/// is the desired normalization divided by the integral of the histogram.
6733///
6734/// If option contains "width" the bin contents and errors are divided
6735/// by the bin width.
6736
6738{
6739
6740 TString opt = option; opt.ToLower();
6741 // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6742 if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6743 if (opt.Contains("width")) Add(this, this, c1, -1);
6744 else {
6745 if (fBuffer) BufferEmpty(1);
6746 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6747 if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6748 // update global histograms statistics
6749 Double_t s[kNstat] = {0};
6750 GetStats(s);
6751 for (Int_t i=0 ; i < kNstat; i++) {
6752 if (i == 1) s[i] = c1*c1*s[i];
6753 else s[i] = c1*s[i];
6754 }
6755 PutStats(s);
6756 SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6757 }
6758
6759 // if contours set, must also scale contours
6761 if (ncontours == 0) return;
6763 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6764}
6765
6766////////////////////////////////////////////////////////////////////////////////
6767/// Returns true if all axes are extendable.
6768
6770{
6772 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6773 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6774
6775 return canExtend;
6776}
6777
6778////////////////////////////////////////////////////////////////////////////////
6779/// Make the histogram axes extendable / not extendable according to the bit mask
6780/// returns the previous bit mask specifying which axes are extendable
6781
6783{
6785
6789
6790 if (GetDimension() > 1) {
6794 }
6795
6796 if (GetDimension() > 2) {
6800 }
6801
6802 return oldExtendBitMask;
6803}
6804
6805///////////////////////////////////////////////////////////////////////////////
6806/// Internal function used in TH1::Fill to see which axis is full alphanumeric,
6807/// i.e. can be extended and is alphanumeric
6809{
6813 bitMask |= kYaxis;
6815 bitMask |= kZaxis;
6816
6817 return bitMask;
6818}
6819
6820////////////////////////////////////////////////////////////////////////////////
6821/// Static function to set the default buffer size for automatic histograms.
6822/// When a histogram is created with one of its axis lower limit greater
6823/// or equal to its upper limit, the function SetBuffer is automatically
6824/// called with the default buffer size.
6825
6827{
6828 fgBufferSize = bufsize > 0 ? bufsize : 0;
6829}
6830
6831////////////////////////////////////////////////////////////////////////////////
6832/// When this static function is called with `sumw2=kTRUE`, all new
6833/// histograms will automatically activate the storage
6834/// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6835
6837{
6839}
6840
6841////////////////////////////////////////////////////////////////////////////////
6842/// Change/set the title.
6843///
6844/// If title is in the form `stringt;stringx;stringy;stringz;stringc`
6845/// the histogram title is set to `stringt`, the x axis title to `stringx`,
6846/// the y axis title to `stringy`, the z axis title to `stringz`, and the c
6847/// axis title for the palette is ignored at this stage.
6848/// Note that you can use e.g. `stringt;stringx` if you only want to specify
6849/// title and x axis title.
6850///
6851/// To insert the character `;` in one of the titles, one should use `#;`
6852/// or `#semicolon`.
6853
6854void TH1::SetTitle(const char *title)
6855{
6856 fTitle = title;
6857 fTitle.ReplaceAll("#;",2,"#semicolon",10);
6858
6859 // Decode fTitle. It may contain X, Y and Z titles
6861 Int_t isc = str1.Index(";");
6862 Int_t lns = str1.Length();
6863
6864 if (isc >=0 ) {
6865 fTitle = str1(0,isc);
6866 str1 = str1(isc+1, lns);
6867 isc = str1.Index(";");
6868 if (isc >=0 ) {
6869 str2 = str1(0,isc);
6870 str2.ReplaceAll("#semicolon",10,";",1);
6871 fXaxis.SetTitle(str2.Data());
6872 lns = str1.Length();
6873 str1 = str1(isc+1, lns);
6874 isc = str1.Index(";");
6875 if (isc >=0 ) {
6876 str2 = str1(0,isc);
6877 str2.ReplaceAll("#semicolon",10,";",1);
6878 fYaxis.SetTitle(str2.Data());
6879 lns = str1.Length();
6880 str1 = str1(isc+1, lns);
6881 isc = str1.Index(";");
6882 if (isc >=0 ) {
6883 str2 = str1(0,isc);
6884 str2.ReplaceAll("#semicolon",10,";",1);
6885 fZaxis.SetTitle(str2.Data());
6886 } else {
6887 str1.ReplaceAll("#semicolon",10,";",1);
6888 fZaxis.SetTitle(str1.Data());
6889 }
6890 } else {
6891 str1.ReplaceAll("#semicolon",10,";",1);
6892 fYaxis.SetTitle(str1.Data());
6893 }
6894 } else {
6895 str1.ReplaceAll("#semicolon",10,";",1);
6896 fXaxis.SetTitle(str1.Data());
6897 }
6898 }
6899
6900 fTitle.ReplaceAll("#semicolon",10,";",1);
6901
6902 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6903}
6904
6905////////////////////////////////////////////////////////////////////////////////
6906/// Smooth array xx, translation of Hbook routine `hsmoof.F`.
6907/// Based on algorithm 353QH twice presented by J. Friedman
6908/// in [Proc. of the 1974 CERN School of Computing, Norway, 11-24 August, 1974](https://cds.cern.ch/record/186223).
6909/// 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).
6910
6912{
6913 if (nn < 3 ) {
6914 ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6915 return;
6916 }
6917
6918 Int_t ii;
6919 std::array<double, 3> hh{};
6920
6921 std::vector<double> yy(nn);
6922 std::vector<double> zz(nn);
6923 std::vector<double> rr(nn);
6924
6925 for (Int_t pass=0;pass<ntimes;pass++) {
6926 // first copy original data into temp array
6927 std::copy(xx, xx+nn, zz.begin() );
6928
6929 for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6930
6931 // do 353 i.e. running median 3, 5, and 3 in a single loop
6932 for (int kk = 0; kk < 3; kk++) {
6933 std::copy(zz.begin(), zz.end(), yy.begin());
6934 int medianType = (kk != 1) ? 3 : 5;
6935 int ifirst = (kk != 1 ) ? 1 : 2;
6936 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6937 //nn2 = nn - ik - 1;
6938 // do all elements beside the first and last point for median 3
6939 // and first two and last 2 for median 5
6940 for ( ii = ifirst; ii < ilast; ii++) {
6941 zz[ii] = TMath::Median(medianType, yy.data() + ii - ifirst);
6942 }
6943
6944 if (kk == 0) { // first median 3
6945 // first point
6946 hh[0] = zz[1];
6947 hh[1] = zz[0];
6948 hh[2] = 3*zz[1] - 2*zz[2];
6949 zz[0] = TMath::Median(3, hh.data());
6950 // last point
6951 hh[0] = zz[nn - 2];
6952 hh[1] = zz[nn - 1];
6953 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6954 zz[nn - 1] = TMath::Median(3, hh.data());
6955 }
6956
6957 if (kk == 1) { // median 5
6958 // second point with window length 3
6959 zz[1] = TMath::Median(3, yy.data());
6960 // second-to-last point with window length 3
6961 zz[nn - 2] = TMath::Median(3, yy.data() + nn - 3);
6962 }
6963
6964 // In the third iteration (kk == 2), the first and last point stay
6965 // the same (see paper linked in the documentation).
6966 }
6967
6968 std::copy ( zz.begin(), zz.end(), yy.begin() );
6969
6970 // quadratic interpolation for flat segments
6971 for (ii = 2; ii < (nn - 2); ii++) {
6972 if (zz[ii - 1] != zz[ii]) continue;
6973 if (zz[ii] != zz[ii + 1]) continue;
6974 const double tmp0 = zz[ii - 2] - zz[ii];
6975 const double tmp1 = zz[ii + 2] - zz[ii];
6976 if (tmp0 * tmp1 <= 0) continue;
6977 int jk = 1;
6978 if ( std::abs(tmp1) > std::abs(tmp0) ) jk = -1;
6979 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6980 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6981 }
6982
6983 // running means
6984 //std::copy(zz.begin(), zz.end(), yy.begin());
6985 for (ii = 1; ii < nn - 1; ii++) {
6986 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6987 }
6988 zz[0] = yy[0];
6989 zz[nn - 1] = yy[nn - 1];
6990
6991 if (noent == 0) {
6992
6993 // save computed values
6994 std::copy(zz.begin(), zz.end(), rr.begin());
6995
6996 // COMPUTE residuals
6997 for (ii = 0; ii < nn; ii++) {
6998 zz[ii] = xx[ii] - zz[ii];
6999 }
7000 }
7001
7002 } // end loop on noent
7003
7004
7005 double xmin = TMath::MinElement(nn,xx);
7006 for (ii = 0; ii < nn; ii++) {
7007 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
7008 // make smoothing defined positive - not better using 0 ?
7009 else xx[ii] = std::max((rr[ii] + zz[ii]),0.0 );
7010 }
7011 }
7012}
7013
7014////////////////////////////////////////////////////////////////////////////////
7015/// Smooth bin contents of this histogram.
7016/// if option contains "R" smoothing is applied only to the bins
7017/// defined in the X axis range (default is to smooth all bins)
7018/// Bin contents are replaced by their smooth values.
7019/// Errors (if any) are not modified.
7020/// the smoothing procedure is repeated ntimes (default=1)
7021
7023{
7024 if (fDimension != 1) {
7025 Error("Smooth","Smooth only supported for 1-d histograms");
7026 return;
7027 }
7028 Int_t nbins = fXaxis.GetNbins();
7029 if (nbins < 3) {
7030 Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
7031 return;
7032 }
7033
7034 // delete buffer if it is there since it will become invalid
7035 if (fBuffer) BufferEmpty(1);
7036
7037 Int_t firstbin = 1, lastbin = nbins;
7038 TString opt = option;
7039 opt.ToLower();
7040 if (opt.Contains("r")) {
7043 }
7044 nbins = lastbin - firstbin + 1;
7045 Double_t *xx = new Double_t[nbins];
7047 Int_t i;
7048 for (i=0;i<nbins;i++) {
7050 }
7051
7052 TH1::SmoothArray(nbins,xx,ntimes);
7053
7054 for (i=0;i<nbins;i++) {
7056 }
7057 fEntries = nent;
7058 delete [] xx;
7059
7060 if (gPad) gPad->Modified();
7061}
7062
7063////////////////////////////////////////////////////////////////////////////////
7064/// if flag=kTRUE, underflows and overflows are used by the Fill functions
7065/// in the computation of statistics (mean value, StdDev).
7066/// By default, underflows or overflows are not used.
7067
7069{
7071}
7072
7073////////////////////////////////////////////////////////////////////////////////
7074/// Stream a class object.
7075
7076void TH1::Streamer(TBuffer &b)
7077{
7078 if (b.IsReading()) {
7079 UInt_t R__s, R__c;
7080 Version_t R__v = b.ReadVersion(&R__s, &R__c);
7081 if (fDirectory) fDirectory->Remove(this);
7082 fDirectory = nullptr;
7083 if (R__v > 2) {
7084 b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
7085
7087 fXaxis.SetParent(this);
7088 fYaxis.SetParent(this);
7089 fZaxis.SetParent(this);
7090 TIter next(fFunctions);
7091 TObject *obj;
7092 while ((obj=next())) {
7093 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
7094 }
7095 return;
7096 }
7097 //process old versions before automatic schema evolution
7102 b >> fNcells;
7103 fXaxis.Streamer(b);
7104 fYaxis.Streamer(b);
7105 fZaxis.Streamer(b);
7106 fXaxis.SetParent(this);
7107 fYaxis.SetParent(this);
7108 fZaxis.SetParent(this);
7109 b >> fBarOffset;
7110 b >> fBarWidth;
7111 b >> fEntries;
7112 b >> fTsumw;
7113 b >> fTsumw2;
7114 b >> fTsumwx;
7115 b >> fTsumwx2;
7116 if (R__v < 2) {
7118 Float_t *contour=nullptr;
7119 b >> maximum; fMaximum = maximum;
7120 b >> minimum; fMinimum = minimum;
7121 b >> norm; fNormFactor = norm;
7122 Int_t n = b.ReadArray(contour);
7123 fContour.Set(n);
7124 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
7125 delete [] contour;
7126 } else {
7127 b >> fMaximum;
7128 b >> fMinimum;
7129 b >> fNormFactor;
7131 }
7132 fSumw2.Streamer(b);
7134 fFunctions->Delete();
7136 b.CheckByteCount(R__s, R__c, TH1::IsA());
7137
7138 } else {
7139 b.WriteClassBuffer(TH1::Class(),this);
7140 }
7141}
7142
7143////////////////////////////////////////////////////////////////////////////////
7144/// Print some global quantities for this histogram.
7145/// \param[in] option
7146/// - "base" is given, number of bins and ranges are also printed
7147/// - "range" is given, bin contents and errors are also printed
7148/// for all bins in the current range (default 1-->nbins)
7149/// - "all" is given, bin contents and errors are also printed
7150/// for all bins including under and overflows.
7151
7152void TH1::Print(Option_t *option) const
7153{
7154 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7155 printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
7156 TString opt = option;
7157 opt.ToLower();
7158 Int_t all;
7159 if (opt.Contains("all")) all = 0;
7160 else if (opt.Contains("range")) all = 1;
7161 else if (opt.Contains("base")) all = 2;
7162 else return;
7163
7164 Int_t bin, binx, biny, binz;
7166 if (all == 0) {
7167 lastx = fXaxis.GetNbins()+1;
7168 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
7169 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
7170 } else {
7172 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
7173 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
7174 }
7175
7176 if (all== 2) {
7177 printf(" Title = %s\n", GetTitle());
7178 printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
7179 if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
7180 if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
7181 printf("\n");
7182 return;
7183 }
7184
7185 Double_t w,e;
7186 Double_t x,y,z;
7187 if (fDimension == 1) {
7188 for (binx=firstx;binx<=lastx;binx++) {
7191 e = GetBinError(binx);
7192 if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
7193 else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
7194 }
7195 }
7196 if (fDimension == 2) {
7197 for (biny=firsty;biny<=lasty;biny++) {
7199 for (binx=firstx;binx<=lastx;binx++) {
7200 bin = GetBin(binx,biny);
7203 e = GetBinError(bin);
7204 if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
7205 else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
7206 }
7207 }
7208 }
7209 if (fDimension == 3) {
7210 for (binz=firstz;binz<=lastz;binz++) {
7212 for (biny=firsty;biny<=lasty;biny++) {
7214 for (binx=firstx;binx<=lastx;binx++) {
7215 bin = GetBin(binx,biny,binz);
7218 e = GetBinError(bin);
7219 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);
7220 else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
7221 }
7222 }
7223 }
7224 }
7225}
7226
7227////////////////////////////////////////////////////////////////////////////////
7228/// Using the current bin info, recompute the arrays for contents and errors
7229
7230void TH1::Rebuild(Option_t *)
7231{
7232 SetBinsLength();
7233 if (fSumw2.fN) {
7235 }
7236}
7237
7238////////////////////////////////////////////////////////////////////////////////
7239/// Reset this histogram: contents, errors, etc.
7240/// \param[in] option
7241/// - if "ICE" is specified, resets only Integral, Contents and Errors.
7242/// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
7243/// This option is used
7244/// - if "M" is specified, resets also Minimum and Maximum
7245
7247{
7248 // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
7249 // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
7250
7251 TString opt = option;
7252 opt.ToUpper();
7253 fSumw2.Reset();
7254 if (fIntegral) {
7255 delete [] fIntegral;
7256 fIntegral = nullptr;
7257 }
7258
7259 if (opt.Contains("M")) {
7260 SetMinimum();
7261 SetMaximum();
7262 }
7263
7264 if (opt.Contains("ICE") && !opt.Contains("S")) return;
7265
7266 // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
7267 // But what is the sense of calling BufferEmpty() ? For making the axes ?
7268 // BufferEmpty will update contents that later will be
7269 // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
7270 // It may be needed for computing the axis limits....
7271 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
7272
7273 // need to reset also the statistics
7274 // (needs to be done after calling BufferEmpty() )
7275 fTsumw = 0;
7276 fTsumw2 = 0;
7277 fTsumwx = 0;
7278 fTsumwx2 = 0;
7279 fEntries = 0;
7280
7281 if (opt == "ICES") return;
7282
7283
7284 TObject *stats = fFunctions->FindObject("stats");
7285 fFunctions->Remove(stats);
7286 //special logic to support the case where the same object is
7287 //added multiple times in fFunctions.
7288 //This case happens when the same object is added with different
7289 //drawing modes
7290 TObject *obj;
7291 while ((obj = fFunctions->First())) {
7292 while(fFunctions->Remove(obj)) { }
7293 delete obj;
7294 }
7295 if(stats) fFunctions->Add(stats);
7296 fContour.Set(0);
7297}
7298
7299////////////////////////////////////////////////////////////////////////////////
7300/// Save the histogram as .csv, .tsv or .txt. In case of any other extension, fall
7301/// back to TObject::SaveAs, which saves as a .C macro (but with the file name
7302/// extension specified by the user)
7303///
7304/// The Under/Overflow bins are also exported (as first and last lines)
7305/// The fist 2 columns are the lower and upper edges of the bins
7306/// Column 3 contains the bin contents
7307/// The last column contains the error in y. If errors are not present, the column
7308/// is left empty
7309///
7310/// The result can be immediately imported into Excel, gnuplot, Python or whatever,
7311/// without the needing to install pyroot, etc.
7312///
7313/// \param filename the name of the file where to store the histogram
7314/// \param option some tuning options
7315///
7316/// The file extension defines the delimiter used:
7317/// - `.csv` : comma
7318/// - `.tsv` : tab
7319/// - `.txt` : space
7320///
7321/// If option = "title" a title line is generated. If the y-axis has a title,
7322/// this title is displayed as column 3 name, otherwise, it shows "BinContent"
7323
7324void TH1::SaveAs(const char *filename, Option_t *option) const
7325{
7326 char del = '\0';
7327 TString ext = "";
7329 TString opt = option;
7330
7331 if (filename) {
7332 if (fname.EndsWith(".csv")) {
7333 del = ',';
7334 ext = "csv";
7335 } else if (fname.EndsWith(".tsv")) {
7336 del = '\t';
7337 ext = "tsv";
7338 } else if (fname.EndsWith(".txt")) {
7339 del = ' ';
7340 ext = "txt";
7341 }
7342 }
7343 if (!del) {
7345 return;
7346 }
7347 std::ofstream out;
7348 out.open(filename, std::ios::out);
7349 if (!out.good()) {
7350 Error("SaveAs", "cannot open file: %s", filename);
7351 return;
7352 }
7353 if (opt.Contains("title")) {
7354 if (std::strcmp(GetYaxis()->GetTitle(), "") == 0) {
7355 out << "# " << "BinLowEdge" << del << "BinUpEdge" << del
7356 << "BinContent"
7357 << del << "ey" << std::endl;
7358 } else {
7359 out << "# " << "BinLowEdge" << del << "BinUpEdge" << del << GetYaxis()->GetTitle() << del << "ey" << std::endl;
7360 }
7361 }
7362 if (fSumw2.fN) {
7363 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7364 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7365 << GetBinError(i) << std::endl;
7366 }
7367 } else {
7368 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7369 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7370 << std::endl;
7371 }
7372 }
7373 out.close();
7374 Info("SaveAs", "%s file: %s has been generated", ext.Data(), filename);
7375}
7376
7377////////////////////////////////////////////////////////////////////////////////
7378/// Provide variable name for histogram for saving as primitive
7379/// Histogram pointer has by default the histogram name with an incremental suffix.
7380/// If the histogram belongs to a graph or a stack the suffix is not added because
7381/// the graph and stack objects are not aware of this new name. Same thing if
7382/// the histogram is drawn with the option COLZ because the TPaletteAxis drawn
7383/// when this option is selected, does not know this new name either.
7384
7386{
7387 thread_local Int_t storeNumber = 0;
7388
7389 TString opt = option;
7390 opt.ToLower();
7391 TString histName = GetName();
7392 // for TProfile and TH2Poly also fDirectory should be tested
7393 if (!histName.Contains("Graph") && !histName.Contains("_stack_") && !opt.Contains("colz") &&
7394 (!testfdir || !fDirectory)) {
7395 storeNumber++;
7396 histName += "__";
7397 histName += storeNumber;
7398 }
7399 if (histName.IsNull())
7400 histName = "unnamed";
7401 return gInterpreter->MapCppName(histName);
7402}
7403
7404////////////////////////////////////////////////////////////////////////////////
7405/// Save primitive as a C++ statement(s) on output stream out
7406
7407void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
7408{
7409 // empty the buffer before if it exists
7410 if (fBuffer)
7411 BufferEmpty();
7412
7414
7417 SetName(hname);
7418
7419 out <<" \n";
7420
7421 // Check if the histogram has equidistant X bins or not. If not, we
7422 // create an array holding the bins.
7423 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray)
7424 sxaxis = SavePrimitiveVector(out, hname + "_x", GetXaxis()->GetXbins()->fN, GetXaxis()->GetXbins()->fArray);
7425 // If the histogram is 2 or 3 dimensional, check if the histogram
7426 // has equidistant Y bins or not. If not, we create an array
7427 // holding the bins.
7428 if (fDimension > 1 && GetYaxis()->GetXbins()->fN && GetYaxis()->GetXbins()->fArray)
7429 syaxis = SavePrimitiveVector(out, hname + "_y", GetYaxis()->GetXbins()->fN, GetYaxis()->GetXbins()->fArray);
7430 // IF the histogram is 3 dimensional, check if the histogram
7431 // has equidistant Z bins or not. If not, we create an array
7432 // holding the bins.
7433 if (fDimension > 2 && GetZaxis()->GetXbins()->fN && GetZaxis()->GetXbins()->fArray)
7434 szaxis = SavePrimitiveVector(out, hname + "_z", GetZaxis()->GetXbins()->fN, GetZaxis()->GetXbins()->fArray);
7435
7436 const auto old_precision{out.precision()};
7437 constexpr auto max_precision{std::numeric_limits<double>::digits10 + 1};
7438 out << std::setprecision(max_precision);
7439
7440 out << " " << ClassName() << " *" << hname << " = new " << ClassName() << "(\"" << TString(savedName).ReplaceSpecialCppChars() << "\", \""
7441 << TString(GetTitle()).ReplaceSpecialCppChars() << "\", " << GetXaxis()->GetNbins();
7442 if (!sxaxis.IsNull())
7443 out << ", " << sxaxis << ".data()";
7444 else
7445 out << ", " << GetXaxis()->GetXmin() << ", " << GetXaxis()->GetXmax();
7446 if (fDimension > 1) {
7447 out << ", " << GetYaxis()->GetNbins();
7448 if (!syaxis.IsNull())
7449 out << ", " << syaxis << ".data()";
7450 else
7451 out << ", " << GetYaxis()->GetXmin() << ", " << GetYaxis()->GetXmax();
7452 }
7453 if (fDimension > 2) {
7454 out << ", " << GetZaxis()->GetNbins();
7455 if (!szaxis.IsNull())
7456 out << ", " << szaxis << ".data()";
7457 else
7458 out << ", " << GetZaxis()->GetXmin() << ", " << GetZaxis()->GetXmax();
7459 }
7460 out << ");\n";
7461
7463 Int_t numbins = 0, numerrors = 0;
7464
7465 std::vector<Double_t> content(fNcells), errors(save_errors ? fNcells : 0);
7466 for (Int_t bin = 0; bin < fNcells; bin++) {
7468 if (content[bin])
7469 numbins++;
7470 if (save_errors) {
7472 if (errors[bin])
7473 numerrors++;
7474 }
7475 }
7476
7477 if ((numbins < 100) && (numerrors < 100)) {
7478 // in case of few non-empty bins store them as before
7479 for (Int_t bin = 0; bin < fNcells; bin++) {
7480 if (content[bin])
7481 out << " " << hname << "->SetBinContent(" << bin << "," << content[bin] << ");\n";
7482 }
7483 if (save_errors)
7484 for (Int_t bin = 0; bin < fNcells; bin++) {
7485 if (errors[bin])
7486 out << " " << hname << "->SetBinError(" << bin << "," << errors[bin] << ");\n";
7487 }
7488 } else {
7489 if (numbins > 0) {
7491 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
7492 out << " if (" << vectname << "[bin])\n";
7493 out << " " << hname << "->SetBinContent(bin, " << vectname << "[bin]);\n";
7494 }
7495 if (numerrors > 0) {
7497 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
7498 out << " if (" << vectname << "[bin])\n";
7499 out << " " << hname << "->SetBinError(bin, " << vectname << "[bin]);\n";
7500 }
7501 }
7502
7504 out << std::setprecision(old_precision);
7505 SetName(savedName.Data());
7506}
7507
7508////////////////////////////////////////////////////////////////////////////////
7509/// Helper function for the SavePrimitive functions from TH1
7510/// or classes derived from TH1, eg TProfile, TProfile2D.
7511
7512void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
7513{
7514 if (TMath::Abs(GetBarOffset()) > 1e-5)
7515 out << " " << hname << "->SetBarOffset(" << GetBarOffset() << ");\n";
7516 if (TMath::Abs(GetBarWidth() - 1) > 1e-5)
7517 out << " " << hname << "->SetBarWidth(" << GetBarWidth() << ");\n";
7518 if (fMinimum != -1111)
7519 out << " " << hname << "->SetMinimum(" << fMinimum << ");\n";
7520 if (fMaximum != -1111)
7521 out << " " << hname << "->SetMaximum(" << fMaximum << ");\n";
7522 if (fNormFactor != 0)
7523 out << " " << hname << "->SetNormFactor(" << fNormFactor << ");\n";
7524 if (fEntries != 0)
7525 out << " " << hname << "->SetEntries(" << fEntries << ");\n";
7526 if (!fDirectory)
7527 out << " " << hname << "->SetDirectory(nullptr);\n";
7528 if (TestBit(kNoStats))
7529 out << " " << hname << "->SetStats(0);\n";
7530 if (fOption.Length() != 0)
7531 out << " " << hname << "->SetOption(\n" << TString(fOption).ReplaceSpecialCppChars() << "\");\n";
7532
7533 // save contour levels
7535 if (ncontours > 0) {
7537 if (TestBit(kUserContour)) {
7538 std::vector<Double_t> levels(ncontours);
7539 for (Int_t bin = 0; bin < ncontours; bin++)
7542 }
7543 out << " " << hname << "->SetContour(" << ncontours;
7544 if (!vectname.IsNull())
7545 out << ", " << vectname << ".data()";
7546 out << ");\n";
7547 }
7548
7550
7551 // save attributes
7552 SaveFillAttributes(out, hname, -1, -1);
7553 SaveLineAttributes(out, hname, 1, 1, 1);
7554 SaveMarkerAttributes(out, hname, 1, 1, 1);
7555 fXaxis.SaveAttributes(out, hname, "->GetXaxis()");
7556 fYaxis.SaveAttributes(out, hname, "->GetYaxis()");
7557 fZaxis.SaveAttributes(out, hname, "->GetZaxis()");
7558
7560}
7561
7562////////////////////////////////////////////////////////////////////////////////
7563/// Save list of functions
7564/// Also can be used by TGraph classes
7565
7566void TH1::SavePrimitiveFunctions(std::ostream &out, const char *varname, TList *lst)
7567{
7568 thread_local Int_t funcNumber = 0;
7569
7570 TObjLink *lnk = lst ? lst->FirstLink() : nullptr;
7571 while (lnk) {
7572 auto obj = lnk->GetObject();
7573 obj->SavePrimitive(out, TString::Format("nodraw #%d\n", ++funcNumber).Data());
7574 TString objvarname = obj->GetName();
7576 if (obj->InheritsFrom(TF1::Class())) {
7578 objvarname = gInterpreter->MapCppName(objvarname);
7579 out << " " << objvarname << "->SetParent(" << varname << ");\n";
7580 } else if (obj->InheritsFrom("TPaveStats")) {
7581 objvarname = "ptstats";
7582 withopt = kFALSE; // pave stats preserve own draw options
7583 out << " " << objvarname << "->SetParent(" << varname << ");\n";
7584 } else if (obj->InheritsFrom("TPolyMarker")) {
7585 objvarname = "pmarker";
7586 }
7587
7588 out << " " << varname << "->GetListOfFunctions()->Add(" << objvarname;
7589 if (withopt)
7590 out << ",\"" << TString(lnk->GetOption()).ReplaceSpecialCppChars() << "\"";
7591 out << ");\n";
7592
7593 lnk = lnk->Next();
7594 }
7595}
7596
7597////////////////////////////////////////////////////////////////////////////////
7638 }
7639}
7640
7641////////////////////////////////////////////////////////////////////////////////
7642/// For axis = 1,2 or 3 returns the mean value of the histogram along
7643/// X,Y or Z axis.
7644///
7645/// For axis = 11, 12, 13 returns the standard error of the mean value
7646/// of the histogram along X, Y or Z axis
7647///
7648/// Note that the mean value/StdDev is computed using the bins in the currently
7649/// defined range (see TAxis::SetRange). By default the range includes
7650/// all bins from 1 to nbins included, excluding underflows and overflows.
7651/// To force the underflows and overflows in the computation, one must
7652/// call the static function TH1::StatOverflows(kTRUE) before filling
7653/// the histogram.
7654///
7655/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7656/// are calculated. By default, if no range has been set, the returned mean is
7657/// the (unbinned) one calculated at fill time. If a range has been set, however,
7658/// the mean is calculated using the bins in range, as described above; THIS
7659/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7660/// the range. To ensure that the returned mean (and all other statistics) is
7661/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7662/// See TH1::GetStats.
7663///
7664/// Return mean value of this histogram along the X axis.
7665
7666Double_t TH1::GetMean(Int_t axis) const
7667{
7668 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7669 Double_t stats[kNstat];
7670 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7671 GetStats(stats);
7672 if (stats[0] == 0) return 0;
7673 if (axis<4){
7674 Int_t ax[3] = {2,4,7};
7675 return stats[ax[axis-1]]/stats[0];
7676 } else {
7677 // mean error = StdDev / sqrt( Neff )
7678 Double_t stddev = GetStdDev(axis-10);
7680 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7681 }
7682}
7683
7684////////////////////////////////////////////////////////////////////////////////
7685/// Return standard error of mean of this histogram along the X axis.
7686///
7687/// Note that the mean value/StdDev is computed using the bins in the currently
7688/// defined range (see TAxis::SetRange). By default the range includes
7689/// all bins from 1 to nbins included, excluding underflows and overflows.
7690/// To force the underflows and overflows in the computation, one must
7691/// call the static function TH1::StatOverflows(kTRUE) before filling
7692/// the histogram.
7693///
7694/// Also note, that although the definition of standard error doesn't include the
7695/// assumption of normality, many uses of this feature implicitly assume it.
7696///
7697/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7698/// are calculated. By default, if no range has been set, the returned value is
7699/// the (unbinned) one calculated at fill time. If a range has been set, however,
7700/// the value is calculated using the bins in range, as described above; THIS
7701/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7702/// the range. To ensure that the returned value (and all other statistics) is
7703/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7704/// See TH1::GetStats.
7705
7707{
7708 return GetMean(axis+10);
7709}
7710
7711////////////////////////////////////////////////////////////////////////////////
7712/// Returns the Standard Deviation (Sigma).
7713/// The Sigma estimate is computed as
7714/// \f[
7715/// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7716/// \f]
7717/// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7718/// X, Y or Z axis
7719/// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7720/// X, Y or Z axis for Normal distribution
7721///
7722/// Note that the mean value/sigma is computed using the bins in the currently
7723/// defined range (see TAxis::SetRange). By default the range includes
7724/// all bins from 1 to nbins included, excluding underflows and overflows.
7725/// To force the underflows and overflows in the computation, one must
7726/// call the static function TH1::StatOverflows(kTRUE) before filling
7727/// the histogram.
7728///
7729/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7730/// are calculated. By default, if no range has been set, the returned standard
7731/// deviation is the (unbinned) one calculated at fill time. If a range has been
7732/// set, however, the standard deviation is calculated using the bins in range,
7733/// as described above; THIS IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use
7734/// TAxis::SetRange(0, 0) to unset the range. To ensure that the returned standard
7735/// deviation (and all other statistics) is always that of the binned data stored
7736/// in the histogram, call TH1::ResetStats. See TH1::GetStats.
7737
7738Double_t TH1::GetStdDev(Int_t axis) const
7739{
7740 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7741
7742 Double_t x, stddev2, stats[kNstat];
7743 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7744 GetStats(stats);
7745 if (stats[0] == 0) return 0;
7746 Int_t ax[3] = {2,4,7};
7747 Int_t axm = ax[axis%10 - 1];
7748 x = stats[axm]/stats[0];
7749 // for negative stddev (e.g. when having negative weights) - return stdev=0
7750 stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7751 if (axis<10)
7752 return TMath::Sqrt(stddev2);
7753 else {
7754 // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7755 // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7757 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7758 }
7759}
7760
7761////////////////////////////////////////////////////////////////////////////////
7762/// Return error of standard deviation estimation for Normal distribution
7763///
7764/// Note that the mean value/StdDev is computed using the bins in the currently
7765/// defined range (see TAxis::SetRange). By default the range includes
7766/// all bins from 1 to nbins included, excluding underflows and overflows.
7767/// To force the underflows and overflows in the computation, one must
7768/// call the static function TH1::StatOverflows(kTRUE) before filling
7769/// the histogram.
7770///
7771/// Value returned is standard deviation of sample standard deviation.
7772/// Note that it is an approximated value which is valid only in the case that the
7773/// original data distribution is Normal. The correct one would require
7774/// the 4-th momentum value, which cannot be accurately estimated from a histogram since
7775/// the x-information for all entries is not kept.
7776///
7777/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7778/// are calculated. By default, if no range has been set, the returned value is
7779/// the (unbinned) one calculated at fill time. If a range has been set, however,
7780/// the value is calculated using the bins in range, as described above; THIS
7781/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7782/// the range. To ensure that the returned value (and all other statistics) is
7783/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7784/// See TH1::GetStats.
7785
7787{
7788 return GetStdDev(axis+10);
7789}
7790
7791////////////////////////////////////////////////////////////////////////////////
7792/// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7793/// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7794/// of the histogram along x, y or z axis
7795///
7796///Note, that since third and fourth moment are not calculated
7797///at the fill time, skewness and its standard error are computed bin by bin
7798///
7799/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7800/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7801
7803{
7804
7805 if (axis > 0 && axis <= 3){
7806
7807 Double_t mean = GetMean(axis);
7808 Double_t stddev = GetStdDev(axis);
7810
7817 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7820 if (firstBinX == 1) firstBinX = 0;
7821 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7822 }
7824 if (firstBinY == 1) firstBinY = 0;
7825 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7826 }
7828 if (firstBinZ == 1) firstBinZ = 0;
7829 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7830 }
7831 }
7832
7833 Double_t x = 0;
7834 Double_t sum=0;
7835 Double_t np=0;
7836 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7837 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7838 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7839 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7840 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7841 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7843 np+=w;
7844 sum+=w*(x-mean)*(x-mean)*(x-mean);
7845 }
7846 }
7847 }
7848 sum/=np*stddev3;
7849 return sum;
7850 }
7851 else if (axis > 10 && axis <= 13) {
7852 //compute standard error of skewness
7853 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7855 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7856 }
7857 else {
7858 Error("GetSkewness", "illegal value of parameter");
7859 return 0;
7860 }
7861}
7862
7863////////////////////////////////////////////////////////////////////////////////
7864/// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7865/// Kurtosis(gaussian(0, 1)) = 0.
7866/// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7867/// of the histogram along x, y or z axis
7868////
7869/// Note, that since third and fourth moment are not calculated
7870/// at the fill time, kurtosis and its standard error are computed bin by bin
7871///
7872/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7873/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7874
7876{
7877 if (axis > 0 && axis <= 3){
7878
7879 Double_t mean = GetMean(axis);
7880 Double_t stddev = GetStdDev(axis);
7882
7889 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7892 if (firstBinX == 1) firstBinX = 0;
7893 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7894 }
7896 if (firstBinY == 1) firstBinY = 0;
7897 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7898 }
7900 if (firstBinZ == 1) firstBinZ = 0;
7901 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7902 }
7903 }
7904
7905 Double_t x = 0;
7906 Double_t sum=0;
7907 Double_t np=0;
7908 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7909 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7910 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7911 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7912 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7913 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7915 np+=w;
7916 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7917 }
7918 }
7919 }
7920 sum/=(np*stddev4);
7921 return sum-3;
7922
7923 } else if (axis > 10 && axis <= 13) {
7924 //compute standard error of skewness
7925 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7927 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7928 }
7929 else {
7930 Error("GetKurtosis", "illegal value of parameter");
7931 return 0;
7932 }
7933}
7934
7935////////////////////////////////////////////////////////////////////////////////
7936/// fill the array stats from the contents of this histogram
7937/// The array stats must be correctly dimensioned in the calling program.
7938///
7939/// ~~~ {.cpp}
7940/// stats[0] = sumw
7941/// stats[1] = sumw2
7942/// stats[2] = sumwx
7943/// stats[3] = sumwx2
7944/// ~~~
7945///
7946/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7947/// is simply a copy of the statistics quantities computed at filling time.
7948/// If a sub-range is specified, the function recomputes these quantities
7949/// from the bin contents in the current axis range.
7950///
7951/// IMPORTANT NOTE: This means that the returned statistics are context-dependent.
7952/// If TAxis::kAxisRange, the returned statistics are dependent on the binning;
7953/// otherwise, they are a copy of the histogram statistics computed at fill time,
7954/// which are unbinned by default (calling TH1::ResetStats forces them to use
7955/// binned statistics). You can reset TAxis::kAxisRange using TAxis::SetRange(0, 0).
7956///
7957/// Note that the mean value/StdDev is computed using the bins in the currently
7958/// defined range (see TAxis::SetRange). By default the range includes
7959/// all bins from 1 to nbins included, excluding underflows and overflows.
7960/// To force the underflows and overflows in the computation, one must
7961/// call the static function TH1::StatOverflows(kTRUE) before filling
7962/// the histogram.
7963
7964void TH1::GetStats(Double_t *stats) const
7965{
7966 if (fBuffer) ((TH1*)this)->BufferEmpty();
7967
7968 // Loop on bins (possibly including underflows/overflows)
7969 Int_t bin, binx;
7970 Double_t w,err;
7971 Double_t x;
7972 // identify the case of labels with extension of axis range
7973 // in this case the statistics in x does not make any sense
7974 Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && fXaxis.CanExtend() );
7975 // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7976 if ( (fTsumw == 0 && fEntries > 0) || fXaxis.TestBit(TAxis::kAxisRange) ) {
7977 for (bin=0;bin<4;bin++) stats[bin] = 0;
7978
7981 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7983 if (firstBinX == 1) firstBinX = 0;
7984 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7985 }
7986 for (binx = firstBinX; binx <= lastBinX; binx++) {
7988 //w = TMath::Abs(RetrieveBinContent(binx));
7989 // not sure what to do here if w < 0
7991 err = TMath::Abs(GetBinError(binx));
7992 stats[0] += w;
7993 stats[1] += err*err;
7994 // statistics in x makes sense only for not labels histograms
7995 if (!labelHist) {
7996 stats[2] += w*x;
7997 stats[3] += w*x*x;
7998 }
7999 }
8000 // if (stats[0] < 0) {
8001 // // in case total is negative do something ??
8002 // stats[0] = 0;
8003 // }
8004 } else {
8005 stats[0] = fTsumw;
8006 stats[1] = fTsumw2;
8007 stats[2] = fTsumwx;
8008 stats[3] = fTsumwx2;
8009 }
8010}
8011
8012////////////////////////////////////////////////////////////////////////////////
8013/// Replace current statistics with the values in array stats
8014
8015void TH1::PutStats(Double_t *stats)
8016{
8017 fTsumw = stats[0];
8018 fTsumw2 = stats[1];
8019 fTsumwx = stats[2];
8020 fTsumwx2 = stats[3];
8021}
8022
8023////////////////////////////////////////////////////////////////////////////////
8024/// Reset the statistics including the number of entries
8025/// and replace with values calculated from bin content
8026///
8027/// The number of entries is set to the total bin content or (in case of weighted histogram)
8028/// to number of effective entries
8029///
8030/// \note By default, before calling this function, statistics are those
8031/// computed at fill time, which are unbinned. See TH1::GetStats.
8032
8033void TH1::ResetStats()
8034{
8035 Double_t stats[kNstat] = {0};
8036 fTsumw = 0;
8037 fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
8038 GetStats(stats);
8039 PutStats(stats);
8040 // histogram entries should include always underflows and overflows
8043 else {
8044 Double_t sumw2 = 0;
8045 Double_t * p_sumw2 = (fSumw2.fN > 0) ? &sumw2 : nullptr;
8047 // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
8049 }
8050}
8051
8052////////////////////////////////////////////////////////////////////////////////
8053/// Return the sum of all weights and optionally also the sum of weight squares
8054/// \param includeOverflow true to include under/overflows bins, false to exclude those.
8055/// \note Different from TH1::GetSumOfWeights, that always excludes those
8056
8058{
8059 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
8060
8061 const Int_t start = (includeOverflow ? 0 : 1);
8062 const Int_t lastX = fXaxis.GetNbins() + (includeOverflow ? 1 : 0);
8063 const Int_t lastY = (fDimension > 1) ? (fYaxis.GetNbins() + (includeOverflow ? 1 : 0)) : start;
8064 const Int_t lastZ = (fDimension > 2) ? (fZaxis.GetNbins() + (includeOverflow ? 1 : 0)) : start;
8065 Double_t sum =0;
8066 Double_t sum2 = 0;
8067 for(auto binz = start; binz <= lastZ; binz++) {
8068 for(auto biny = start; biny <= lastY; biny++) {
8069 for(auto binx = start; binx <= lastX; binx++) {
8070 const auto bin = GetBin(binx, biny, binz);
8073 }
8074 }
8075 }
8076 if (sumWeightSquare) {
8077 if (fSumw2.fN > 0)
8079 else
8081 }
8082 return sum;
8083}
8084
8085////////////////////////////////////////////////////////////////////////////////
8086///Return integral of bin contents. Only bins in the bins range are considered.
8087///
8088/// By default the integral is computed as the sum of bin contents in the range.
8089/// if option "width" is specified, the integral is the sum of
8090/// the bin contents multiplied by the bin width in x.
8091
8093{
8095}
8096
8097////////////////////////////////////////////////////////////////////////////////
8098/// Return integral of bin contents in range [binx1,binx2].
8099///
8100/// By default the integral is computed as the sum of bin contents in the range.
8101/// if option "width" is specified, the integral is the sum of
8102/// the bin contents multiplied by the bin width in x.
8103
8105{
8106 double err = 0;
8107 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
8108}
8109
8110////////////////////////////////////////////////////////////////////////////////
8111/// Return integral of bin contents in range [binx1,binx2] and its error.
8112///
8113/// By default the integral is computed as the sum of bin contents in the range.
8114/// if option "width" is specified, the integral is the sum of
8115/// the bin contents multiplied by the bin width in x.
8116/// the error is computed using error propagation from the bin errors assuming that
8117/// all the bins are uncorrelated
8118
8120{
8121 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
8122}
8123
8124////////////////////////////////////////////////////////////////////////////////
8125/// Internal function compute integral and optionally the error between the limits
8126/// specified by the bin number values working for all histograms (1D, 2D and 3D)
8127
8129 Option_t *option, Bool_t doError) const
8130{
8131 if (fBuffer) ((TH1*)this)->BufferEmpty();
8132
8133 Int_t nx = GetNbinsX() + 2;
8134 if (binx1 < 0) binx1 = 0;
8135 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
8136
8137 if (GetDimension() > 1) {
8138 Int_t ny = GetNbinsY() + 2;
8139 if (biny1 < 0) biny1 = 0;
8140 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
8141 } else {
8142 biny1 = 0; biny2 = 0;
8143 }
8144
8145 if (GetDimension() > 2) {
8146 Int_t nz = GetNbinsZ() + 2;
8147 if (binz1 < 0) binz1 = 0;
8148 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
8149 } else {
8150 binz1 = 0; binz2 = 0;
8151 }
8152
8153 // - Loop on bins in specified range
8154 TString opt = option;
8155 opt.ToLower();
8157 if (opt.Contains("width")) width = kTRUE;
8158
8159
8160 Double_t dx = 1., dy = .1, dz =.1;
8161 Double_t integral = 0;
8162 Double_t igerr2 = 0;
8163 for (Int_t binx = binx1; binx <= binx2; ++binx) {
8164 if (width) dx = fXaxis.GetBinWidth(binx);
8165 for (Int_t biny = biny1; biny <= biny2; ++biny) {
8166 if (width) dy = fYaxis.GetBinWidth(biny);
8167 for (Int_t binz = binz1; binz <= binz2; ++binz) {
8169 Double_t dv = 0.0;
8170 if (width) {
8172 dv = dx * dy * dz;
8173 integral += RetrieveBinContent(bin) * dv;
8174 } else {
8175 integral += RetrieveBinContent(bin);
8176 }
8177 if (doError) {
8180 }
8181 }
8182 }
8183 }
8184
8185 if (doError) error = TMath::Sqrt(igerr2);
8186 return integral;
8187}
8188
8189////////////////////////////////////////////////////////////////////////////////
8190/// Statistical test of compatibility in shape between
8191/// this histogram and h2, using the Anderson-Darling 2 sample test.
8192///
8193/// The AD 2 sample test formula are derived from the paper
8194/// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
8195///
8196/// The test is implemented in root in the ROOT::Math::GoFTest class
8197/// It is the same formula ( (6) in the paper), and also shown in
8198/// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
8199///
8200/// Binned data are considered as un-binned data
8201/// with identical observation happening in the bin center.
8202///
8203/// \param[in] h2 Pointer to 1D histogram
8204/// \param[in] option is a character string to specify options
8205/// - "D" Put out a line of "Debug" printout
8206/// - "T" Return the normalized A-D test statistic
8207///
8208/// - Note1: Underflow and overflow are not considered in the test
8209/// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
8210/// - Note3: The histograms are not required to have the same X axis
8211/// - Note4: The test works only for 1-dimensional histograms
8212
8214{
8215 Double_t advalue = 0;
8217
8218 TString opt = option;
8219 opt.ToUpper();
8220 if (opt.Contains("D") ) {
8221 printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
8222 }
8223 if (opt.Contains("T") ) return advalue;
8224
8225 return pvalue;
8226}
8227
8228////////////////////////////////////////////////////////////////////////////////
8229/// Same function as above but returning also the test statistic value
8230
8232{
8233 if (GetDimension() != 1 || h2->GetDimension() != 1) {
8234 Error("AndersonDarlingTest","Histograms must be 1-D");
8235 return -1;
8236 }
8237
8238 // empty the buffer. Probably we could add as an unbinned test
8239 if (fBuffer) ((TH1*)this)->BufferEmpty();
8240
8241 // use the BinData class
8244
8245 ROOT::Fit::FillData(data1, this, nullptr);
8246 ROOT::Fit::FillData(data2, h2, nullptr);
8247
8248 double pvalue;
8250
8251 return pvalue;
8252}
8253
8254////////////////////////////////////////////////////////////////////////////////
8255/// Statistical test of compatibility in shape between
8256/// this histogram and h2, using Kolmogorov test.
8257/// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
8258/// and not for binned data as in the case of the histogram (see NOTE 3 below).
8259/// So, before using this method blindly, read the NOTE 3.
8260///
8261/// Default: Ignore under- and overflow bins in comparison
8262///
8263/// \param[in] h2 histogram
8264/// \param[in] option is a character string to specify options
8265/// - "U" include Underflows in test (also for 2-dim)
8266/// - "O" include Overflows (also valid for 2-dim)
8267/// - "N" include comparison of normalizations
8268/// - "D" Put out a line of "Debug" printout
8269/// - "M" Return the Maximum Kolmogorov distance instead of prob
8270/// - "X" Run the pseudo experiments post-processor with the following procedure:
8271/// make pseudoexperiments based on random values from the parent distribution,
8272/// compare the KS distance of the pseudoexperiment to the parent
8273/// distribution, and count all the KS values above the value
8274/// obtained from the original data to Monte Carlo distribution.
8275/// The number of pseudo-experiments nEXPT is by default 1000, and
8276/// it can be changed by specifying the option as "X=number",
8277/// for example "X=10000" for 10000 toys.
8278/// The function returns the probability.
8279/// (thanks to Ben Kilminster to submit this procedure). Note that
8280/// this option "X" is much slower.
8281///
8282/// The returned function value is the probability of test
8283/// (much less than one means NOT compatible)
8284///
8285/// Code adapted by Rene Brun from original HBOOK routine HDIFF
8286///
8287/// NOTE1
8288/// A good description of the Kolmogorov test can be seen at:
8289/// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
8290///
8291/// NOTE2
8292/// see also alternative function TH1::Chi2Test
8293/// The Kolmogorov test is assumed to give better results than Chi2Test
8294/// in case of histograms with low statistics.
8295///
8296/// NOTE3 (Jan Conrad, Fred James)
8297/// "The returned value PROB is calculated such that it will be
8298/// uniformly distributed between zero and one for compatible histograms,
8299/// provided the data are not binned (or the number of bins is very large
8300/// compared with the number of events). Users who have access to unbinned
8301/// data and wish exact confidence levels should therefore not put their data
8302/// into histograms, but should call directly TMath::KolmogorovTest. On
8303/// the other hand, since TH1 is a convenient way of collecting data and
8304/// saving space, this function has been provided. However, the values of
8305/// PROB for binned data will be shifted slightly higher than expected,
8306/// depending on the effects of the binning. For example, when comparing two
8307/// uniform distributions of 500 events in 100 bins, the values of PROB,
8308/// instead of being exactly uniformly distributed between zero and one, have
8309/// a mean value of about 0.56. We can apply a useful
8310/// rule: As long as the bin width is small compared with any significant
8311/// physical effect (for example the experimental resolution) then the binning
8312/// cannot have an important effect. Therefore, we believe that for all
8313/// practical purposes, the probability value PROB is calculated correctly
8314/// provided the user is aware that:
8315///
8316/// 1. The value of PROB should not be expected to have exactly the correct
8317/// distribution for binned data.
8318/// 2. The user is responsible for seeing to it that the bin widths are
8319/// small compared with any physical phenomena of interest.
8320/// 3. The effect of binning (if any) is always to make the value of PROB
8321/// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
8322/// will assure that at most 5% of truly compatible histograms are rejected,
8323/// and usually somewhat less."
8324///
8325/// Note also that for GoF test of unbinned data ROOT provides also the class
8326/// ROOT::Math::GoFTest. The class has also method for doing one sample tests
8327/// (i.e. comparing the data with a given distribution).
8328
8330{
8331 TString opt = option;
8332 opt.ToUpper();
8333
8334 Double_t prob = 0;
8335 TH1 *h1 = (TH1*)this;
8336 if (h2 == nullptr) return 0;
8337 const TAxis *axis1 = h1->GetXaxis();
8338 const TAxis *axis2 = h2->GetXaxis();
8339 Int_t ncx1 = axis1->GetNbins();
8340 Int_t ncx2 = axis2->GetNbins();
8341
8342 // Check consistency of dimensions
8343 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
8344 Error("KolmogorovTest","Histograms must be 1-D\n");
8345 return 0;
8346 }
8347
8348 // Check consistency in number of channels
8349 if (ncx1 != ncx2) {
8350 Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
8351 return 0;
8352 }
8353
8354 // empty the buffer. Probably we could add as an unbinned test
8355 if (fBuffer) ((TH1*)this)->BufferEmpty();
8356
8357 // Check consistency in bin edges
8358 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
8359 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
8360 Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
8361 return 0;
8362 }
8363 }
8364
8367 Double_t sum1 = 0, sum2 = 0;
8368 Double_t ew1, ew2, w1 = 0, w2 = 0;
8369 Int_t bin;
8370 Int_t ifirst = 1;
8371 Int_t ilast = ncx1;
8372 // integral of all bins (use underflow/overflow if option)
8373 if (opt.Contains("U")) ifirst = 0;
8374 if (opt.Contains("O")) ilast = ncx1 +1;
8375 for (bin = ifirst; bin <= ilast; bin++) {
8377 sum2 += h2->RetrieveBinContent(bin);
8378 ew1 = h1->GetBinError(bin);
8379 ew2 = h2->GetBinError(bin);
8380 w1 += ew1*ew1;
8381 w2 += ew2*ew2;
8382 }
8383 if (sum1 == 0) {
8384 Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
8385 return 0;
8386 }
8387 if (sum2 == 0) {
8388 Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
8389 return 0;
8390 }
8391
8392 // calculate the effective entries.
8393 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
8394 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
8395 Double_t esum1 = 0, esum2 = 0;
8396 if (w1 > 0)
8397 esum1 = sum1 * sum1 / w1;
8398 else
8399 afunc1 = kTRUE; // use later for calculating z
8400
8401 if (w2 > 0)
8402 esum2 = sum2 * sum2 / w2;
8403 else
8404 afunc2 = kTRUE; // use later for calculating z
8405
8406 if (afunc2 && afunc1) {
8407 Error("KolmogorovTest","Errors are zero for both histograms\n");
8408 return 0;
8409 }
8410
8411
8412 Double_t s1 = 1/sum1;
8413 Double_t s2 = 1/sum2;
8414
8415 // Find largest difference for Kolmogorov Test
8416 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
8417
8418 for (bin=ifirst;bin<=ilast;bin++) {
8422 }
8423
8424 // Get Kolmogorov probability
8425 Double_t z, prb1=0, prb2=0, prb3=0;
8426
8427 // case h1 is exact (has zero errors)
8428 if (afunc1)
8429 z = dfmax*TMath::Sqrt(esum2);
8430 // case h2 has zero errors
8431 else if (afunc2)
8432 z = dfmax*TMath::Sqrt(esum1);
8433 else
8434 // for comparison between two data sets
8436
8438
8439 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
8440 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
8441 // Combine probabilities for shape and normalization,
8442 prb1 = prob;
8445 prb2 = TMath::Prob(chi2,1);
8446 // see Eadie et al., section 11.6.2
8447 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
8448 else prob = 0;
8449 }
8450 // X option. Run Pseudo-experiments to determine NULL distribution of the
8451 // KS distance. We can find the probability from the number of pseudo-experiment that have a
8452 // KS distance larger than the one opbserved in the data.
8453 // We use the histogram with the largest statistics as a parent distribution for the NULL.
8454 // Note if one histogram has zero errors is considered as a function. In that case we use it
8455 // as parent distribution for the toys.
8456 //
8457 Int_t nEXPT = 1000;
8458 if (opt.Contains("X")) {
8459 // get number of pseudo-experiment of specified
8460 if (opt.Contains("X=")) {
8461 int numpos = opt.Index("X=") + 2; // 2 is length of X=
8462 int numlen = 0;
8463 int len = opt.Length();
8464 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) )
8465 numlen++;
8466 TString snum = opt(numpos,numlen);
8467 int num = atoi(snum.Data());
8468 if (num <= 0)
8469 Warning("KolmogorovTest","invalid number of toys given: %d - use 1000",num);
8470 else
8471 nEXPT = num;
8472 }
8473
8475 TH1D hparent;
8476 // we cannot have afunc1 and func2 both True
8477 if (afunc1 || esum1 > esum2 ) h1->Copy(hparent);
8478 else h2->Copy(hparent);
8479
8480 // copy h1Expt from h1 and h2. It is just needed to get the correct binning
8481
8482
8483 if (hparent.GetMinimum() < 0.0) {
8484 // we need to create a new histogram
8485 // With negative bins we can't draw random samples in a meaningful way.
8486 Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
8487 "skewed. Reduce number of bins for histogram?");
8488 while (hparent.GetMinimum() < 0.0) {
8489 Int_t idx = hparent.GetMinimumBin();
8490 hparent.SetBinContent(idx, 0.0);
8491 }
8492 }
8493
8494 // make nEXPT experiments (this should be a parameter)
8495 prb3 = 0;
8496 TH1D h1Expt;
8497 h1->Copy(h1Expt);
8498 TH1D h2Expt;
8499 h1->Copy(h2Expt);
8500 // loop on pseudoexperients and generate the two histograms h1Expt and h2Expt according to the
8501 // parent distribution. In case the parent distribution is not an histogram but a function randomize only one
8502 // histogram
8503 for (Int_t i=0; i < nEXPT; i++) {
8504 if (!afunc1) {
8505 h1Expt.Reset();
8506 h1Expt.FillRandom(&hparent, (Int_t)esum1);
8507 }
8508 if (!afunc2) {
8509 h2Expt.Reset();
8510 h2Expt.FillRandom(&hparent, (Int_t)esum2);
8511 }
8512 // note we cannot have both afunc1 and afunc2 to be true
8513 if (afunc1)
8514 dSEXPT = hparent.KolmogorovTest(&h2Expt,"M");
8515 else if (afunc2)
8516 dSEXPT = hparent.KolmogorovTest(&h1Expt,"M");
8517 else
8518 dSEXPT = h1Expt.KolmogorovTest(&h2Expt,"M");
8519 // count number of cases toy KS distance (TS) is larger than oberved one
8520 if (dSEXPT>dfmax) prb3 += 1.0;
8521 }
8522 // compute p-value
8523 prb3 /= (Double_t)nEXPT;
8524 }
8525
8526
8527 // debug printout
8528 if (opt.Contains("D")) {
8529 printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
8530 printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
8531 printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
8532 if (opt.Contains("N"))
8533 printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
8534 if (opt.Contains("X"))
8535 printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
8536 }
8537 // This numerical error condition should never occur:
8538 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
8539 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
8540
8541 if(opt.Contains("M")) return dfmax;
8542 else if(opt.Contains("X")) return prb3;
8543 else return prob;
8544}
8545
8546////////////////////////////////////////////////////////////////////////////////
8547/// Replace bin contents by the contents of array content
8548
8549void TH1::SetContent(const Double_t *content)
8550{
8551 fEntries = fNcells;
8552 fTsumw = 0;
8553 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
8554}
8555
8556////////////////////////////////////////////////////////////////////////////////
8557/// Return contour values into array levels if pointer levels is non zero.
8558///
8559/// The function returns the number of contour levels.
8560/// see GetContourLevel to return one contour only
8561
8563{
8565 if (levels) {
8566 if (nlevels == 0) {
8567 nlevels = 20;
8569 } else {
8571 }
8572 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
8573 }
8574 return nlevels;
8575}
8576
8577////////////////////////////////////////////////////////////////////////////////
8578/// Return value of contour number level.
8579/// Use GetContour to return the array of all contour levels
8580
8582{
8583 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
8584}
8585
8586////////////////////////////////////////////////////////////////////////////////
8587/// Return the value of contour number "level" in Pad coordinates.
8588/// ie: if the Pad is in log scale along Z it returns le log of the contour level
8589/// value. See GetContour to return the array of all contour levels
8590
8592{
8593 if (level <0 || level >= fContour.fN) return 0;
8594 Double_t zlevel = fContour.fArray[level];
8595
8596 // In case of user defined contours and Pad in log scale along Z,
8597 // fContour.fArray doesn't contain the log of the contour whereas it does
8598 // in case of equidistant contours.
8599 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
8600 if (zlevel <= 0) return 0;
8602 }
8603 return zlevel;
8604}
8605
8606////////////////////////////////////////////////////////////////////////////////
8607/// Set the maximum number of entries to be kept in the buffer.
8608
8609void TH1::SetBuffer(Int_t bufsize, Option_t * /*option*/)
8610{
8611 if (fBuffer) {
8612 BufferEmpty();
8613 delete [] fBuffer;
8614 fBuffer = nullptr;
8615 }
8616 if (bufsize <= 0) {
8617 fBufferSize = 0;
8618 return;
8619 }
8620 if (bufsize < 100) bufsize = 100;
8621 fBufferSize = 1 + bufsize*(fDimension+1);
8623 memset(fBuffer, 0, sizeof(Double_t)*fBufferSize);
8624}
8625
8626////////////////////////////////////////////////////////////////////////////////
8627/// Set the number and values of contour levels.
8628///
8629/// By default the number of contour levels is set to 20. The contours values
8630/// in the array "levels" should be specified in increasing order.
8631///
8632/// if argument levels = 0 or missing, `nlevels` equidistant contours are computed
8633/// between `zmin` and `zmax - dz`, both included, with step
8634/// `dz = (zmax - zmin)/nlevels`. Note that contour lines are not centered, but
8635/// contour surfaces (when drawing with `COLZ`) will be, since contour color `i` covers
8636/// the region of values between contour line `i` and `i+1`.
8637
8639{
8640 Int_t level;
8642 if (nlevels <=0 ) {
8643 fContour.Set(0);
8644 return;
8645 }
8647
8648 // - Contour levels are specified
8649 if (levels) {
8651 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
8652 } else {
8653 // - contour levels are computed automatically as equidistant contours
8654 Double_t zmin = GetMinimum();
8655 Double_t zmax = GetMaximum();
8656 if ((zmin == zmax) && (zmin != 0)) {
8657 zmax += 0.01*TMath::Abs(zmax);
8658 zmin -= 0.01*TMath::Abs(zmin);
8659 }
8660 Double_t dz = (zmax-zmin)/Double_t(nlevels);
8661 if (gPad && gPad->GetLogz()) {
8662 if (zmax <= 0) return;
8663 if (zmin <= 0) zmin = 0.001*zmax;
8664 zmin = TMath::Log10(zmin);
8665 zmax = TMath::Log10(zmax);
8666 dz = (zmax-zmin)/Double_t(nlevels);
8667 }
8668 for (level=0; level<nlevels; level++) {
8669 fContour.fArray[level] = zmin + dz*Double_t(level);
8670 }
8671 }
8672}
8673
8674////////////////////////////////////////////////////////////////////////////////
8675/// Set value for one contour level.
8676
8678{
8679 if (level < 0 || level >= fContour.fN) return;
8681 fContour.fArray[level] = value;
8682}
8683
8684////////////////////////////////////////////////////////////////////////////////
8685/// Return maximum value smaller than maxval of bins in the range,
8686/// unless the value has been overridden by TH1::SetMaximum,
8687/// in which case it returns that value. This happens, for example,
8688/// when the histogram is drawn and the y or z axis limits are changed
8689///
8690/// To get the maximum value of bins in the histogram regardless of
8691/// whether the value has been overridden (using TH1::SetMaximum), use
8692///
8693/// ~~~ {.cpp}
8694/// h->GetBinContent(h->GetMaximumBin())
8695/// ~~~
8696///
8697/// TH1::GetMaximumBin can be used to get the location of the maximum
8698/// value.
8699
8701{
8702 if (fMaximum != -1111) return fMaximum;
8703
8704 // empty the buffer
8705 if (fBuffer) ((TH1*)this)->BufferEmpty();
8706
8707 Int_t bin, binx, biny, binz;
8708 Int_t xfirst = fXaxis.GetFirst();
8709 Int_t xlast = fXaxis.GetLast();
8710 Int_t yfirst = fYaxis.GetFirst();
8711 Int_t ylast = fYaxis.GetLast();
8712 Int_t zfirst = fZaxis.GetFirst();
8713 Int_t zlast = fZaxis.GetLast();
8715 for (binz=zfirst;binz<=zlast;binz++) {
8716 for (biny=yfirst;biny<=ylast;biny++) {
8717 for (binx=xfirst;binx<=xlast;binx++) {
8718 bin = GetBin(binx,biny,binz);
8720 if (value > maximum && value < maxval) maximum = value;
8721 }
8722 }
8723 }
8724 return maximum;
8725}
8726
8727////////////////////////////////////////////////////////////////////////////////
8728/// Return location of bin with maximum value in the range.
8729///
8730/// TH1::GetMaximum can be used to get the maximum value.
8731
8733{
8736}
8737
8738////////////////////////////////////////////////////////////////////////////////
8739/// Return location of bin with maximum value in the range.
8740
8742{
8743 // empty the buffer
8744 if (fBuffer) ((TH1*)this)->BufferEmpty();
8745
8746 Int_t bin, binx, biny, binz;
8747 Int_t locm;
8748 Int_t xfirst = fXaxis.GetFirst();
8749 Int_t xlast = fXaxis.GetLast();
8750 Int_t yfirst = fYaxis.GetFirst();
8751 Int_t ylast = fYaxis.GetLast();
8752 Int_t zfirst = fZaxis.GetFirst();
8753 Int_t zlast = fZaxis.GetLast();
8755 locm = locmax = locmay = locmaz = 0;
8756 for (binz=zfirst;binz<=zlast;binz++) {
8757 for (biny=yfirst;biny<=ylast;biny++) {
8758 for (binx=xfirst;binx<=xlast;binx++) {
8759 bin = GetBin(binx,biny,binz);
8761 if (value > maximum) {
8762 maximum = value;
8763 locm = bin;
8764 locmax = binx;
8765 locmay = biny;
8766 locmaz = binz;
8767 }
8768 }
8769 }
8770 }
8771 return locm;
8772}
8773
8774////////////////////////////////////////////////////////////////////////////////
8775/// Return minimum value larger than minval of bins in the range,
8776/// unless the value has been overridden by TH1::SetMinimum,
8777/// in which case it returns that value. This happens, for example,
8778/// when the histogram is drawn and the y or z axis limits are changed
8779///
8780/// To get the minimum value of bins in the histogram regardless of
8781/// whether the value has been overridden (using TH1::SetMinimum), use
8782///
8783/// ~~~ {.cpp}
8784/// h->GetBinContent(h->GetMinimumBin())
8785/// ~~~
8786///
8787/// TH1::GetMinimumBin can be used to get the location of the
8788/// minimum value.
8789
8791{
8792 if (fMinimum != -1111) return fMinimum;
8793
8794 // empty the buffer
8795 if (fBuffer) ((TH1*)this)->BufferEmpty();
8796
8797 Int_t bin, binx, biny, binz;
8798 Int_t xfirst = fXaxis.GetFirst();
8799 Int_t xlast = fXaxis.GetLast();
8800 Int_t yfirst = fYaxis.GetFirst();
8801 Int_t ylast = fYaxis.GetLast();
8802 Int_t zfirst = fZaxis.GetFirst();
8803 Int_t zlast = fZaxis.GetLast();
8805 for (binz=zfirst;binz<=zlast;binz++) {
8806 for (biny=yfirst;biny<=ylast;biny++) {
8807 for (binx=xfirst;binx<=xlast;binx++) {
8808 bin = GetBin(binx,biny,binz);
8811 }
8812 }
8813 }
8814 return minimum;
8815}
8816
8817////////////////////////////////////////////////////////////////////////////////
8818/// Return location of bin with minimum value in the range.
8819
8821{
8824}
8825
8826////////////////////////////////////////////////////////////////////////////////
8827/// Return location of bin with minimum value in the range.
8828
8830{
8831 // empty the buffer
8832 if (fBuffer) ((TH1*)this)->BufferEmpty();
8833
8834 Int_t bin, binx, biny, binz;
8835 Int_t locm;
8836 Int_t xfirst = fXaxis.GetFirst();
8837 Int_t xlast = fXaxis.GetLast();
8838 Int_t yfirst = fYaxis.GetFirst();
8839 Int_t ylast = fYaxis.GetLast();
8840 Int_t zfirst = fZaxis.GetFirst();
8841 Int_t zlast = fZaxis.GetLast();
8843 locm = locmix = locmiy = locmiz = 0;
8844 for (binz=zfirst;binz<=zlast;binz++) {
8845 for (biny=yfirst;biny<=ylast;biny++) {
8846 for (binx=xfirst;binx<=xlast;binx++) {
8847 bin = GetBin(binx,biny,binz);
8849 if (value < minimum) {
8850 minimum = value;
8851 locm = bin;
8852 locmix = binx;
8853 locmiy = biny;
8854 locmiz = binz;
8855 }
8856 }
8857 }
8858 }
8859 return locm;
8860}
8861
8862///////////////////////////////////////////////////////////////////////////////
8863/// Retrieve the minimum and maximum values in the histogram
8864///
8865/// This will not return a cached value and will always search the
8866/// histogram for the min and max values. The user can condition whether
8867/// or not to call this with the GetMinimumStored() and GetMaximumStored()
8868/// methods. If the cache is empty, then the value will be -1111. Users
8869/// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8870/// For example, the following recipe will make efficient use of this method
8871/// and the cached minimum and maximum values.
8872//
8873/// \code{.cpp}
8874/// Double_t currentMin = pHist->GetMinimumStored();
8875/// Double_t currentMax = pHist->GetMaximumStored();
8876/// if ((currentMin == -1111) || (currentMax == -1111)) {
8877/// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8878/// pHist->SetMinimum(currentMin);
8879/// pHist->SetMaximum(currentMax);
8880/// }
8881/// \endcode
8882///
8883/// \param min reference to variable that will hold found minimum value
8884/// \param max reference to variable that will hold found maximum value
8885
8886void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8887{
8888 // empty the buffer
8889 if (fBuffer) ((TH1*)this)->BufferEmpty();
8890
8891 Int_t bin, binx, biny, binz;
8892 Int_t xfirst = fXaxis.GetFirst();
8893 Int_t xlast = fXaxis.GetLast();
8894 Int_t yfirst = fYaxis.GetFirst();
8895 Int_t ylast = fYaxis.GetLast();
8896 Int_t zfirst = fZaxis.GetFirst();
8897 Int_t zlast = fZaxis.GetLast();
8898 min=TMath::Infinity();
8899 max=-TMath::Infinity();
8901 for (binz=zfirst;binz<=zlast;binz++) {
8902 for (biny=yfirst;biny<=ylast;biny++) {
8903 for (binx=xfirst;binx<=xlast;binx++) {
8904 bin = GetBin(binx,biny,binz);
8906 if (value < min) min = value;
8907 if (value > max) max = value;
8908 }
8909 }
8910 }
8911}
8912
8913////////////////////////////////////////////////////////////////////////////////
8914/// Redefine x axis parameters.
8915///
8916/// The X axis parameters are modified.
8917/// The bins content array is resized
8918/// if errors (Sumw2) the errors array is resized
8919/// The previous bin contents are lost
8920/// To change only the axis limits, see TAxis::SetRange
8921
8923{
8924 if (GetDimension() != 1) {
8925 Error("SetBins","Operation only valid for 1-d histograms");
8926 return;
8927 }
8928 fXaxis.SetRange(0,0);
8930 fYaxis.Set(1,0,1);
8931 fZaxis.Set(1,0,1);
8932 fNcells = nx+2;
8934 if (fSumw2.fN) {
8936 }
8937}
8938
8939////////////////////////////////////////////////////////////////////////////////
8940/// Redefine x axis parameters with variable bin sizes.
8941///
8942/// The X axis parameters are modified.
8943/// The bins content array is resized
8944/// if errors (Sumw2) the errors array is resized
8945/// The previous bin contents are lost
8946/// To change only the axis limits, see TAxis::SetRange
8947/// xBins is supposed to be of length nx+1
8948
8949void TH1::SetBins(Int_t nx, const Double_t *xBins)
8950{
8951 if (GetDimension() != 1) {
8952 Error("SetBins","Operation only valid for 1-d histograms");
8953 return;
8954 }
8955 fXaxis.SetRange(0,0);
8956 fXaxis.Set(nx,xBins);
8957 fYaxis.Set(1,0,1);
8958 fZaxis.Set(1,0,1);
8959 fNcells = nx+2;
8961 if (fSumw2.fN) {
8963 }
8964}
8965
8966////////////////////////////////////////////////////////////////////////////////
8967/// Redefine x and y axis parameters.
8968///
8969/// The X and Y axis parameters are modified.
8970/// The bins content array is resized
8971/// if errors (Sumw2) the errors array is resized
8972/// The previous bin contents are lost
8973/// To change only the axis limits, see TAxis::SetRange
8974
8976{
8977 if (GetDimension() != 2) {
8978 Error("SetBins","Operation only valid for 2-D histograms");
8979 return;
8980 }
8981 fXaxis.SetRange(0,0);
8982 fYaxis.SetRange(0,0);
8985 fZaxis.Set(1,0,1);
8986 fNcells = (nx+2)*(ny+2);
8988 if (fSumw2.fN) {
8990 }
8991}
8992
8993////////////////////////////////////////////////////////////////////////////////
8994/// Redefine x and y axis parameters with variable bin sizes.
8995///
8996/// The X and Y axis parameters are modified.
8997/// The bins content array is resized
8998/// if errors (Sumw2) the errors array is resized
8999/// The previous bin contents are lost
9000/// To change only the axis limits, see TAxis::SetRange
9001/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
9002
9003void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
9004{
9005 if (GetDimension() != 2) {
9006 Error("SetBins","Operation only valid for 2-D histograms");
9007 return;
9008 }
9009 fXaxis.SetRange(0,0);
9010 fYaxis.SetRange(0,0);
9011 fXaxis.Set(nx,xBins);
9012 fYaxis.Set(ny,yBins);
9013 fZaxis.Set(1,0,1);
9014 fNcells = (nx+2)*(ny+2);
9016 if (fSumw2.fN) {
9018 }
9019}
9020
9021////////////////////////////////////////////////////////////////////////////////
9022/// Redefine x, y and z axis parameters.
9023///
9024/// The X, Y and Z axis parameters are modified.
9025/// The bins content array is resized
9026/// if errors (Sumw2) the errors array is resized
9027/// The previous bin contents are lost
9028/// To change only the axis limits, see TAxis::SetRange
9029
9031{
9032 if (GetDimension() != 3) {
9033 Error("SetBins","Operation only valid for 3-D histograms");
9034 return;
9035 }
9036 fXaxis.SetRange(0,0);
9037 fYaxis.SetRange(0,0);
9038 fZaxis.SetRange(0,0);
9041 fZaxis.Set(nz,zmin,zmax);
9042 fNcells = (nx+2)*(ny+2)*(nz+2);
9044 if (fSumw2.fN) {
9046 }
9047}
9048
9049////////////////////////////////////////////////////////////////////////////////
9050/// Redefine x, y and z axis parameters with variable bin sizes.
9051///
9052/// The X, Y and Z axis parameters are modified.
9053/// The bins content array is resized
9054/// if errors (Sumw2) the errors array is resized
9055/// The previous bin contents are lost
9056/// To change only the axis limits, see TAxis::SetRange
9057/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
9058/// zBins is supposed to be of length nz+1
9059
9060void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
9061{
9062 if (GetDimension() != 3) {
9063 Error("SetBins","Operation only valid for 3-D histograms");
9064 return;
9065 }
9066 fXaxis.SetRange(0,0);
9067 fYaxis.SetRange(0,0);
9068 fZaxis.SetRange(0,0);
9069 fXaxis.Set(nx,xBins);
9070 fYaxis.Set(ny,yBins);
9071 fZaxis.Set(nz,zBins);
9072 fNcells = (nx+2)*(ny+2)*(nz+2);
9074 if (fSumw2.fN) {
9076 }
9077}
9078
9079////////////////////////////////////////////////////////////////////////////////
9080/// By default, when a histogram is created, it is added to the list
9081/// of histogram objects in the current directory in memory.
9082/// Remove reference to this histogram from current directory and add
9083/// reference to new directory dir. dir can be 0 in which case the
9084/// histogram does not belong to any directory.
9085///
9086/// Note that the directory is not a real property of the histogram and
9087/// it will not be copied when the histogram is copied or cloned.
9088/// If the user wants to have the copied (cloned) histogram in the same
9089/// directory, he needs to set again the directory using SetDirectory to the
9090/// copied histograms
9091
9093{
9094 if (fDirectory == dir) return;
9095 if (fDirectory) fDirectory->Remove(this);
9096 fDirectory = dir;
9097 if (fDirectory) {
9099 fDirectory->Append(this);
9100 }
9101}
9102
9103////////////////////////////////////////////////////////////////////////////////
9104/// Replace bin errors by values in array error.
9105
9106void TH1::SetError(const Double_t *error)
9107{
9108 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
9109}
9110
9111////////////////////////////////////////////////////////////////////////////////
9112/// Change the name of this histogram
9114
9115void TH1::SetName(const char *name)
9116{
9117 // Histograms are named objects in a THashList.
9118 // We must update the hashlist if we change the name
9119 // We protect this operation
9121 if (fDirectory) fDirectory->Remove(this);
9122 fName = name;
9123 if (fDirectory) fDirectory->Append(this);
9124}
9125
9126////////////////////////////////////////////////////////////////////////////////
9127/// Change the name and title of this histogram
9128
9129void TH1::SetNameTitle(const char *name, const char *title)
9130{
9131 // Histograms are named objects in a THashList.
9132 // We must update the hashlist if we change the name
9133 SetName(name);
9134 SetTitle(title);
9135}
9136
9137////////////////////////////////////////////////////////////////////////////////
9138/// Set statistics option on/off.
9139///
9140/// By default, the statistics box is drawn.
9141/// The paint options can be selected via gStyle->SetOptStat.
9142/// This function sets/resets the kNoStats bit in the histogram object.
9143/// It has priority over the Style option.
9144
9145void TH1::SetStats(Bool_t stats)
9146{
9148 if (!stats) {
9150 //remove the "stats" object from the list of functions
9151 if (fFunctions) {
9152 TObject *obj = fFunctions->FindObject("stats");
9153 if (obj) {
9154 fFunctions->Remove(obj);
9155 delete obj;
9156 }
9157 }
9158 }
9159}
9160
9161////////////////////////////////////////////////////////////////////////////////
9162/// Create structure to store sum of squares of weights.
9163///
9164/// if histogram is already filled, the sum of squares of weights
9165/// is filled with the existing bin contents
9166///
9167/// The error per bin will be computed as sqrt(sum of squares of weight)
9168/// for each bin.
9169///
9170/// This function is automatically called when the histogram is created
9171/// if the static function TH1::SetDefaultSumw2 has been called before.
9172/// If flag = false the structure containing the sum of the square of weights
9173/// is rest and it will be empty, but it is not deleted (i.e. GetSumw2()->fN = 0)
9174
9176{
9177 if (!flag) {
9178 // clear the array if existing - do nothing otherwise
9179 if (fSumw2.fN > 0 ) fSumw2.Set(0);
9180 return;
9181 }
9182
9183 if (fSumw2.fN == fNcells) {
9184 if (!fgDefaultSumw2 )
9185 Warning("Sumw2","Sum of squares of weights structure already created");
9186 return;
9187 }
9188
9190
9191 if (fEntries > 0)
9192 for (Int_t i = 0; i < fNcells; ++i)
9194}
9195
9196////////////////////////////////////////////////////////////////////////////////
9197/// Return pointer to function with name.
9198///
9199///
9200/// Functions such as TH1::Fit store the fitted function in the list of
9201/// functions of this histogram.
9202
9203TF1 *TH1::GetFunction(const char *name) const
9204{
9205 return (TF1*)fFunctions->FindObject(name);
9206}
9207
9208////////////////////////////////////////////////////////////////////////////////
9209/// Return value of error associated to bin number bin.
9210///
9211/// if the sum of squares of weights has been defined (via Sumw2),
9212/// this function returns the sqrt(sum of w2).
9213/// otherwise it returns the sqrt(contents) for this bin.
9214
9216{
9217 if (bin < 0) bin = 0;
9218 if (bin >= fNcells) bin = fNcells-1;
9219 if (fBuffer) ((TH1*)this)->BufferEmpty();
9220 if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
9221
9223}
9224
9225////////////////////////////////////////////////////////////////////////////////
9226/// Return lower error associated to bin number bin.
9227///
9228/// The error will depend on the statistic option used will return
9229/// the binContent - lower interval value
9230
9232{
9233 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9234 // in case of weighted histogram check if it is really weighted
9235 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9236
9237 if (bin < 0) bin = 0;
9238 if (bin >= fNcells) bin = fNcells-1;
9239 if (fBuffer) ((TH1*)this)->BufferEmpty();
9240
9241 Double_t alpha = 1.- 0.682689492;
9242 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9243
9245 Int_t n = int(c);
9246 if (n < 0) {
9247 Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
9248 ((TH1*)this)->fBinStatErrOpt = kNormal;
9249 return GetBinError(bin);
9250 }
9251
9252 if (n == 0) return 0;
9253 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
9254}
9255
9256////////////////////////////////////////////////////////////////////////////////
9257/// Return upper error associated to bin number bin.
9258///
9259/// The error will depend on the statistic option used will return
9260/// the binContent - upper interval value
9261
9263{
9264 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9265 // in case of weighted histogram check if it is really weighted
9266 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9267 if (bin < 0) bin = 0;
9268 if (bin >= fNcells) bin = fNcells-1;
9269 if (fBuffer) ((TH1*)this)->BufferEmpty();
9270
9271 Double_t alpha = 1.- 0.682689492;
9272 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9273
9275 Int_t n = int(c);
9276 if (n < 0) {
9277 Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
9278 ((TH1*)this)->fBinStatErrOpt = kNormal;
9279 return GetBinError(bin);
9280 }
9281
9282 // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
9283 // decide to return always (1-alpha)/2 upper interval
9284 //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
9285 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
9286}
9287
9288//L.M. These following getters are useless and should be probably deprecated
9289////////////////////////////////////////////////////////////////////////////////
9290/// Return bin center for 1D histogram.
9291/// Better to use h1.GetXaxis()->GetBinCenter(bin)
9292
9294{
9295 if (fDimension == 1) return fXaxis.GetBinCenter(bin);
9296 Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
9297 return TMath::QuietNaN();
9298}
9299
9300////////////////////////////////////////////////////////////////////////////////
9301/// Return bin lower edge for 1D histogram.
9302/// Better to use h1.GetXaxis()->GetBinLowEdge(bin)
9303
9305{
9306 if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
9307 Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
9308 return TMath::QuietNaN();
9309}
9310
9311////////////////////////////////////////////////////////////////////////////////
9312/// Return bin width for 1D histogram.
9313/// Better to use h1.GetXaxis()->GetBinWidth(bin)
9314
9316{
9317 if (fDimension == 1) return fXaxis.GetBinWidth(bin);
9318 Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
9319 return TMath::QuietNaN();
9320}
9321
9322////////////////////////////////////////////////////////////////////////////////
9323/// Fill array with center of bins for 1D histogram
9324/// Better to use h1.GetXaxis()->GetCenter(center)
9325
9326void TH1::GetCenter(Double_t *center) const
9327{
9328 if (fDimension == 1) {
9329 fXaxis.GetCenter(center);
9330 return;
9331 }
9332 Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
9333}
9334
9335////////////////////////////////////////////////////////////////////////////////
9336/// Fill array with low edge of bins for 1D histogram
9337/// Better to use h1.GetXaxis()->GetLowEdge(edge)
9338
9339void TH1::GetLowEdge(Double_t *edge) const
9340{
9341 if (fDimension == 1) {
9343 return;
9344 }
9345 Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
9346}
9347
9348////////////////////////////////////////////////////////////////////////////////
9349/// Set the bin Error
9350/// Note that this resets the bin eror option to be of Normal Type and for the
9351/// non-empty bin the bin error is set by default to the square root of their content.
9352/// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
9353/// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
9354/// will not be recalculated after setting the content and a default error = 0 will be used for those bins.
9355///
9356/// See convention for numbering bins in TH1::GetBin
9357
9359{
9360 if (bin < 0 || bin>= fNcells) return;
9361 if (!fSumw2.fN) Sumw2();
9362 fSumw2.fArray[bin] = error * error;
9363 // reset the bin error option
9365}
9366
9367////////////////////////////////////////////////////////////////////////////////
9368/// Set bin content
9369/// see convention for numbering bins in TH1::GetBin
9370/// In case the bin number is greater than the number of bins and
9371/// the timedisplay option is set or CanExtendAllAxes(),
9372/// the number of bins is automatically doubled to accommodate the new bin
9373
9375{
9376 fEntries++;
9377 fTsumw = 0;
9378 if (bin < 0) return;
9379 if (bin >= fNcells-1) {
9381 while (bin >= fNcells-1) LabelsInflate();
9382 } else {
9384 return;
9385 }
9386 }
9388}
9389
9390////////////////////////////////////////////////////////////////////////////////
9391/// See convention for numbering bins in TH1::GetBin
9392
9394{
9395 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9396 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9397 SetBinError(GetBin(binx, biny), error);
9398}
9399
9400////////////////////////////////////////////////////////////////////////////////
9401/// See convention for numbering bins in TH1::GetBin
9402
9404{
9405 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9406 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9407 if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
9408 SetBinError(GetBin(binx, biny, binz), error);
9409}
9410
9411////////////////////////////////////////////////////////////////////////////////
9412/// This function calculates the background spectrum in this histogram.
9413/// The background is returned as a histogram.
9414///
9415/// \param[in] niter number of iterations (default value = 2)
9416/// Increasing niter make the result smoother and lower.
9417/// \param[in] option may contain one of the following options
9418/// - to set the direction parameter
9419/// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
9420/// - filterOrder-order of clipping filter (default "BackOrder2")
9421/// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
9422/// - "nosmoothing" - if selected, the background is not smoothed
9423/// By default the background is smoothed.
9424/// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
9425/// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
9426/// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
9427/// - "nocompton" - if selected the estimation of Compton edge
9428/// will be not be included (by default the compton estimation is set)
9429/// - "same" if this option is specified, the resulting background
9430/// histogram is superimposed on the picture in the current pad.
9431/// This option is given by default.
9432///
9433/// NOTE that the background is only evaluated in the current range of this histogram.
9434/// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
9435/// the returned histogram will be created with the same number of bins
9436/// as this input histogram, but only bins from binmin to binmax will be filled
9437/// with the estimated background.
9438
9440{
9441 return (TH1*)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticBackground((TH1*)0x%zx,%d,\"%s\")",
9442 (size_t)this, niter, option).Data());
9443}
9444
9445////////////////////////////////////////////////////////////////////////////////
9446/// Interface to TSpectrum::Search.
9447/// The function finds peaks in this histogram where the width is > sigma
9448/// and the peak maximum greater than threshold*maximum bin content of this.
9449/// For more details see TSpectrum::Search.
9450/// Note the difference in the default value for option compared to TSpectrum::Search
9451/// option="" by default (instead of "goff").
9452
9454{
9455 return (Int_t)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticSearch((TH1*)0x%zx,%g,\"%s\",%g)",
9456 (size_t)this, sigma, option, threshold).Data());
9457}
9458
9459////////////////////////////////////////////////////////////////////////////////
9460/// For a given transform (first parameter), fills the histogram (second parameter)
9461/// with the transform output data, specified in the third parameter
9462/// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
9463/// and the user is responsible for deleting it.
9464///
9465/// Available options:
9466/// - "RE" - real part of the output
9467/// - "IM" - imaginary part of the output
9468/// - "MAG" - magnitude of the output
9469/// - "PH" - phase of the output
9470
9472{
9473 if (!fft || !fft->GetN() ) {
9474 ::Error("TransformHisto","Invalid FFT transform class");
9475 return nullptr;
9476 }
9477
9478 if (fft->GetNdim()>2){
9479 ::Error("TransformHisto","Only 1d and 2D transform are supported");
9480 return nullptr;
9481 }
9482 Int_t binx,biny;
9483 TString opt = option;
9484 opt.ToUpper();
9485 Int_t *n = fft->GetN();
9486 TH1 *hout=nullptr;
9487 if (h_output) {
9488 hout = h_output;
9489 }
9490 else {
9491 TString name = TString::Format("out_%s", opt.Data());
9492 if (fft->GetNdim()==1)
9493 hout = new TH1D(name, name,n[0], 0, n[0]);
9494 else if (fft->GetNdim()==2)
9495 hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
9496 }
9497 R__ASSERT(hout != nullptr);
9498 TString type=fft->GetType();
9499 Int_t ind[2];
9500 if (opt.Contains("RE")){
9501 if (type.Contains("2C") || type.Contains("2HC")) {
9502 Double_t re, im;
9503 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9504 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9505 ind[0] = binx-1; ind[1] = biny-1;
9506 fft->GetPointComplex(ind, re, im);
9507 hout->SetBinContent(binx, biny, re);
9508 }
9509 }
9510 } else {
9511 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9512 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9513 ind[0] = binx-1; ind[1] = biny-1;
9514 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
9515 }
9516 }
9517 }
9518 }
9519 if (opt.Contains("IM")) {
9520 if (type.Contains("2C") || type.Contains("2HC")) {
9521 Double_t re, im;
9522 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9523 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9524 ind[0] = binx-1; ind[1] = biny-1;
9525 fft->GetPointComplex(ind, re, im);
9526 hout->SetBinContent(binx, biny, im);
9527 }
9528 }
9529 } else {
9530 ::Error("TransformHisto","No complex numbers in the output");
9531 return nullptr;
9532 }
9533 }
9534 if (opt.Contains("MA")) {
9535 if (type.Contains("2C") || type.Contains("2HC")) {
9536 Double_t re, im;
9537 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9538 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9539 ind[0] = binx-1; ind[1] = biny-1;
9540 fft->GetPointComplex(ind, re, im);
9541 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
9542 }
9543 }
9544 } else {
9545 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9546 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9547 ind[0] = binx-1; ind[1] = biny-1;
9548 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
9549 }
9550 }
9551 }
9552 }
9553 if (opt.Contains("PH")) {
9554 if (type.Contains("2C") || type.Contains("2HC")){
9555 Double_t re, im, ph;
9556 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
9557 for (biny=1; biny<=hout->GetNbinsY(); biny++){
9558 ind[0] = binx-1; ind[1] = biny-1;
9559 fft->GetPointComplex(ind, re, im);
9560 if (TMath::Abs(re) > 1e-13){
9561 ph = TMath::ATan(im/re);
9562 //find the correct quadrant
9563 if (re<0 && im<0)
9564 ph -= TMath::Pi();
9565 if (re<0 && im>=0)
9566 ph += TMath::Pi();
9567 } else {
9568 if (TMath::Abs(im) < 1e-13)
9569 ph = 0;
9570 else if (im>0)
9571 ph = TMath::Pi()*0.5;
9572 else
9573 ph = -TMath::Pi()*0.5;
9574 }
9575 hout->SetBinContent(binx, biny, ph);
9576 }
9577 }
9578 } else {
9579 printf("Pure real output, no phase");
9580 return nullptr;
9581 }
9582 }
9583
9584 return hout;
9585}
9586
9587////////////////////////////////////////////////////////////////////////////////
9588/// Print value overload
9589
9590std::string cling::printValue(TH1 *val) {
9591 std::ostringstream strm;
9592 strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
9593 return strm.str();
9594}
9595
9596//______________________________________________________________________________
9597// TH1C methods
9598// TH1C : histograms with one byte per channel. Maximum bin content = 127
9599//______________________________________________________________________________
9600
9601
9602////////////////////////////////////////////////////////////////////////////////
9603/// Constructor.
9604
9605TH1C::TH1C()
9606{
9607 fDimension = 1;
9608 SetBinsLength(3);
9609 if (fgDefaultSumw2) Sumw2();
9610}
9611
9612////////////////////////////////////////////////////////////////////////////////
9613/// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
9614/// (see TH1::TH1 for explanation of parameters)
9615
9616TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9617: TH1(name,title,nbins,xlow,xup)
9618{
9619 fDimension = 1;
9621
9622 if (xlow >= xup) SetBuffer(fgBufferSize);
9623 if (fgDefaultSumw2) Sumw2();
9624}
9625
9626////////////////////////////////////////////////////////////////////////////////
9627/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9628/// (see TH1::TH1 for explanation of parameters)
9629
9630TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9631: TH1(name,title,nbins,xbins)
9632{
9633 fDimension = 1;
9635 if (fgDefaultSumw2) Sumw2();
9636}
9637
9638////////////////////////////////////////////////////////////////////////////////
9639/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9640/// (see TH1::TH1 for explanation of parameters)
9641
9642TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9643: TH1(name,title,nbins,xbins)
9644{
9645 fDimension = 1;
9647 if (fgDefaultSumw2) Sumw2();
9648}
9649
9650////////////////////////////////////////////////////////////////////////////////
9651/// Destructor.
9652
9654{
9655}
9656
9657////////////////////////////////////////////////////////////////////////////////
9658/// Copy constructor.
9659/// The list of functions is not copied. (Use Clone() if needed)
9660
9661TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
9662{
9663 h1c.TH1C::Copy(*this);
9664}
9665
9666////////////////////////////////////////////////////////////////////////////////
9667/// Increment bin content by 1.
9668/// Passing an out-of-range bin leads to undefined behavior
9669
9671{
9672 if (fArray[bin] < 127) fArray[bin]++;
9673}
9674
9675////////////////////////////////////////////////////////////////////////////////
9676/// Increment bin content by w.
9677/// \warning The value of w is cast to `Int_t` before being added.
9678/// Passing an out-of-range bin leads to undefined behavior
9679
9681{
9682 Int_t newval = fArray[bin] + Int_t(w);
9683 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
9684 if (newval < -127) fArray[bin] = -127;
9685 if (newval > 127) fArray[bin] = 127;
9686}
9687
9688////////////////////////////////////////////////////////////////////////////////
9689/// Copy this to newth1
9690
9691void TH1C::Copy(TObject &newth1) const
9692{
9694}
9695
9696////////////////////////////////////////////////////////////////////////////////
9697/// Reset.
9698
9700{
9703}
9704
9705////////////////////////////////////////////////////////////////////////////////
9706/// Set total number of bins including under/overflow
9707/// Reallocate bin contents array
9708
9710{
9711 if (n < 0) n = fXaxis.GetNbins() + 2;
9712 fNcells = n;
9713 TArrayC::Set(n);
9714}
9715
9716////////////////////////////////////////////////////////////////////////////////
9717/// Operator =
9718
9719TH1C& TH1C::operator=(const TH1C &h1)
9720{
9721 if (this != &h1)
9722 h1.TH1C::Copy(*this);
9723 return *this;
9724}
9725
9726////////////////////////////////////////////////////////////////////////////////
9727/// Operator *
9728
9730{
9731 TH1C hnew = h1;
9732 hnew.Scale(c1);
9733 hnew.SetDirectory(nullptr);
9734 return hnew;
9735}
9736
9737////////////////////////////////////////////////////////////////////////////////
9738/// Operator +
9739
9740TH1C operator+(const TH1C &h1, const TH1C &h2)
9741{
9742 TH1C hnew = h1;
9743 hnew.Add(&h2,1);
9744 hnew.SetDirectory(nullptr);
9745 return hnew;
9746}
9747
9748////////////////////////////////////////////////////////////////////////////////
9749/// Operator -
9750
9751TH1C operator-(const TH1C &h1, const TH1C &h2)
9752{
9753 TH1C hnew = h1;
9754 hnew.Add(&h2,-1);
9755 hnew.SetDirectory(nullptr);
9756 return hnew;
9757}
9758
9759////////////////////////////////////////////////////////////////////////////////
9760/// Operator *
9761
9762TH1C operator*(const TH1C &h1, const TH1C &h2)
9763{
9764 TH1C hnew = h1;
9765 hnew.Multiply(&h2);
9766 hnew.SetDirectory(nullptr);
9767 return hnew;
9768}
9769
9770////////////////////////////////////////////////////////////////////////////////
9771/// Operator /
9772
9773TH1C operator/(const TH1C &h1, const TH1C &h2)
9774{
9775 TH1C hnew = h1;
9776 hnew.Divide(&h2);
9777 hnew.SetDirectory(nullptr);
9778 return hnew;
9779}
9780
9781//______________________________________________________________________________
9782// TH1S methods
9783// TH1S : histograms with one short per channel. Maximum bin content = 32767
9784//______________________________________________________________________________
9785
9786
9787////////////////////////////////////////////////////////////////////////////////
9788/// Constructor.
9789
9790TH1S::TH1S()
9791{
9792 fDimension = 1;
9793 SetBinsLength(3);
9794 if (fgDefaultSumw2) Sumw2();
9795}
9796
9797////////////////////////////////////////////////////////////////////////////////
9798/// Create a 1-Dim histogram with fix bins of type short
9799/// (see TH1::TH1 for explanation of parameters)
9800
9801TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9802: TH1(name,title,nbins,xlow,xup)
9803{
9804 fDimension = 1;
9806
9807 if (xlow >= xup) SetBuffer(fgBufferSize);
9808 if (fgDefaultSumw2) Sumw2();
9809}
9810
9811////////////////////////////////////////////////////////////////////////////////
9812/// Create a 1-Dim histogram with variable bins of type short
9813/// (see TH1::TH1 for explanation of parameters)
9814
9815TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9816: TH1(name,title,nbins,xbins)
9817{
9818 fDimension = 1;
9820 if (fgDefaultSumw2) Sumw2();
9821}
9822
9823////////////////////////////////////////////////////////////////////////////////
9824/// Create a 1-Dim histogram with variable bins of type short
9825/// (see TH1::TH1 for explanation of parameters)
9826
9827TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9828: TH1(name,title,nbins,xbins)
9829{
9830 fDimension = 1;
9832 if (fgDefaultSumw2) Sumw2();
9833}
9834
9835////////////////////////////////////////////////////////////////////////////////
9836/// Destructor.
9837
9839{
9840}
9841
9842////////////////////////////////////////////////////////////////////////////////
9843/// Copy constructor.
9844/// The list of functions is not copied. (Use Clone() if needed)
9845
9846TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9847{
9848 h1s.TH1S::Copy(*this);
9849}
9850
9851////////////////////////////////////////////////////////////////////////////////
9852/// Increment bin content by 1.
9853/// Passing an out-of-range bin leads to undefined behavior
9854
9856{
9857 if (fArray[bin] < 32767) fArray[bin]++;
9858}
9859
9860////////////////////////////////////////////////////////////////////////////////
9861/// Increment bin content by w.
9862/// \warning The value of w is cast to `Int_t` before being added.
9863/// Passing an out-of-range bin leads to undefined behavior
9864
9866{
9867 Int_t newval = fArray[bin] + Int_t(w);
9868 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9869 if (newval < -32767) fArray[bin] = -32767;
9870 if (newval > 32767) fArray[bin] = 32767;
9871}
9872
9873////////////////////////////////////////////////////////////////////////////////
9874/// Copy this to newth1
9875
9876void TH1S::Copy(TObject &newth1) const
9877{
9879}
9880
9881////////////////////////////////////////////////////////////////////////////////
9882/// Reset.
9883
9885{
9888}
9889
9890////////////////////////////////////////////////////////////////////////////////
9891/// Set total number of bins including under/overflow
9892/// Reallocate bin contents array
9893
9895{
9896 if (n < 0) n = fXaxis.GetNbins() + 2;
9897 fNcells = n;
9898 TArrayS::Set(n);
9899}
9900
9901////////////////////////////////////////////////////////////////////////////////
9902/// Operator =
9903
9904TH1S& TH1S::operator=(const TH1S &h1)
9905{
9906 if (this != &h1)
9907 h1.TH1S::Copy(*this);
9908 return *this;
9909}
9910
9911////////////////////////////////////////////////////////////////////////////////
9912/// Operator *
9913
9915{
9916 TH1S hnew = h1;
9917 hnew.Scale(c1);
9918 hnew.SetDirectory(nullptr);
9919 return hnew;
9920}
9921
9922////////////////////////////////////////////////////////////////////////////////
9923/// Operator +
9924
9925TH1S operator+(const TH1S &h1, const TH1S &h2)
9926{
9927 TH1S hnew = h1;
9928 hnew.Add(&h2,1);
9929 hnew.SetDirectory(nullptr);
9930 return hnew;
9931}
9932
9933////////////////////////////////////////////////////////////////////////////////
9934/// Operator -
9935
9936TH1S operator-(const TH1S &h1, const TH1S &h2)
9937{
9938 TH1S hnew = h1;
9939 hnew.Add(&h2,-1);
9940 hnew.SetDirectory(nullptr);
9941 return hnew;
9942}
9943
9944////////////////////////////////////////////////////////////////////////////////
9945/// Operator *
9946
9947TH1S operator*(const TH1S &h1, const TH1S &h2)
9948{
9949 TH1S hnew = h1;
9950 hnew.Multiply(&h2);
9951 hnew.SetDirectory(nullptr);
9952 return hnew;
9953}
9954
9955////////////////////////////////////////////////////////////////////////////////
9956/// Operator /
9957
9958TH1S operator/(const TH1S &h1, const TH1S &h2)
9959{
9960 TH1S hnew = h1;
9961 hnew.Divide(&h2);
9962 hnew.SetDirectory(nullptr);
9963 return hnew;
9964}
9965
9966//______________________________________________________________________________
9967// TH1I methods
9968// TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9969// 2147483647 = INT_MAX
9970//______________________________________________________________________________
9971
9972
9973////////////////////////////////////////////////////////////////////////////////
9974/// Constructor.
9975
9976TH1I::TH1I()
9977{
9978 fDimension = 1;
9979 SetBinsLength(3);
9980 if (fgDefaultSumw2) Sumw2();
9981}
9982
9983////////////////////////////////////////////////////////////////////////////////
9984/// Create a 1-Dim histogram with fix bins of type integer
9985/// (see TH1::TH1 for explanation of parameters)
9986
9987TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9988: TH1(name,title,nbins,xlow,xup)
9989{
9990 fDimension = 1;
9992
9993 if (xlow >= xup) SetBuffer(fgBufferSize);
9994 if (fgDefaultSumw2) Sumw2();
9995}
9996
9997////////////////////////////////////////////////////////////////////////////////
9998/// Create a 1-Dim histogram with variable bins of type integer
9999/// (see TH1::TH1 for explanation of parameters)
10000
10001TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10002: TH1(name,title,nbins,xbins)
10003{
10004 fDimension = 1;
10006 if (fgDefaultSumw2) Sumw2();
10007}
10008
10009////////////////////////////////////////////////////////////////////////////////
10010/// Create a 1-Dim histogram with variable bins of type integer
10011/// (see TH1::TH1 for explanation of parameters)
10012
10013TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10014: TH1(name,title,nbins,xbins)
10015{
10016 fDimension = 1;
10018 if (fgDefaultSumw2) Sumw2();
10019}
10020
10021////////////////////////////////////////////////////////////////////////////////
10022/// Destructor.
10023
10025{
10026}
10027
10028////////////////////////////////////////////////////////////////////////////////
10029/// Copy constructor.
10030/// The list of functions is not copied. (Use Clone() if needed)
10031
10032TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
10033{
10034 h1i.TH1I::Copy(*this);
10035}
10036
10037////////////////////////////////////////////////////////////////////////////////
10038/// Increment bin content by 1.
10039/// Passing an out-of-range bin leads to undefined behavior
10040
10042{
10043 if (fArray[bin] < INT_MAX) fArray[bin]++;
10044}
10045
10046////////////////////////////////////////////////////////////////////////////////
10047/// Increment bin content by w
10048/// \warning The value of w is cast to `Long64_t` before being added.
10049/// Passing an out-of-range bin leads to undefined behavior
10050
10052{
10054 if (newval > -INT_MAX && newval < INT_MAX) {fArray[bin] = Int_t(newval); return;}
10055 if (newval < -INT_MAX) fArray[bin] = -INT_MAX;
10056 if (newval > INT_MAX) fArray[bin] = INT_MAX;
10057}
10058
10059////////////////////////////////////////////////////////////////////////////////
10060/// Copy this to newth1
10061
10062void TH1I::Copy(TObject &newth1) const
10063{
10065}
10066
10067////////////////////////////////////////////////////////////////////////////////
10068/// Reset.
10069
10071{
10074}
10075
10076////////////////////////////////////////////////////////////////////////////////
10077/// Set total number of bins including under/overflow
10078/// Reallocate bin contents array
10079
10081{
10082 if (n < 0) n = fXaxis.GetNbins() + 2;
10083 fNcells = n;
10084 TArrayI::Set(n);
10085}
10086
10087////////////////////////////////////////////////////////////////////////////////
10088/// Operator =
10089
10090TH1I& TH1I::operator=(const TH1I &h1)
10091{
10092 if (this != &h1)
10093 h1.TH1I::Copy(*this);
10094 return *this;
10095}
10096
10097
10098////////////////////////////////////////////////////////////////////////////////
10099/// Operator *
10100
10102{
10103 TH1I hnew = h1;
10104 hnew.Scale(c1);
10105 hnew.SetDirectory(nullptr);
10106 return hnew;
10107}
10108
10109////////////////////////////////////////////////////////////////////////////////
10110/// Operator +
10111
10112TH1I operator+(const TH1I &h1, const TH1I &h2)
10113{
10114 TH1I hnew = h1;
10115 hnew.Add(&h2,1);
10116 hnew.SetDirectory(nullptr);
10117 return hnew;
10118}
10119
10120////////////////////////////////////////////////////////////////////////////////
10121/// Operator -
10122
10123TH1I operator-(const TH1I &h1, const TH1I &h2)
10124{
10125 TH1I hnew = h1;
10126 hnew.Add(&h2,-1);
10127 hnew.SetDirectory(nullptr);
10128 return hnew;
10129}
10130
10131////////////////////////////////////////////////////////////////////////////////
10132/// Operator *
10133
10134TH1I operator*(const TH1I &h1, const TH1I &h2)
10135{
10136 TH1I hnew = h1;
10137 hnew.Multiply(&h2);
10138 hnew.SetDirectory(nullptr);
10139 return hnew;
10140}
10141
10142////////////////////////////////////////////////////////////////////////////////
10143/// Operator /
10144
10145TH1I operator/(const TH1I &h1, const TH1I &h2)
10146{
10147 TH1I hnew = h1;
10148 hnew.Divide(&h2);
10149 hnew.SetDirectory(nullptr);
10150 return hnew;
10151}
10152
10153//______________________________________________________________________________
10154// TH1L methods
10155// TH1L : histograms with one long64 per channel. Maximum bin content = 9223372036854775807
10156// 9223372036854775807 = LLONG_MAX
10157//______________________________________________________________________________
10158
10159
10160////////////////////////////////////////////////////////////////////////////////
10161/// Constructor.
10162
10163TH1L::TH1L()
10164{
10165 fDimension = 1;
10166 SetBinsLength(3);
10167 if (fgDefaultSumw2) Sumw2();
10168}
10169
10170////////////////////////////////////////////////////////////////////////////////
10171/// Create a 1-Dim histogram with fix bins of type long64
10172/// (see TH1::TH1 for explanation of parameters)
10173
10174TH1L::TH1L(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10175: TH1(name,title,nbins,xlow,xup)
10176{
10177 fDimension = 1;
10179
10180 if (xlow >= xup) SetBuffer(fgBufferSize);
10181 if (fgDefaultSumw2) Sumw2();
10182}
10183
10184////////////////////////////////////////////////////////////////////////////////
10185/// Create a 1-Dim histogram with variable bins of type long64
10186/// (see TH1::TH1 for explanation of parameters)
10187
10188TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10189: TH1(name,title,nbins,xbins)
10190{
10191 fDimension = 1;
10193 if (fgDefaultSumw2) Sumw2();
10194}
10195
10196////////////////////////////////////////////////////////////////////////////////
10197/// Create a 1-Dim histogram with variable bins of type long64
10198/// (see TH1::TH1 for explanation of parameters)
10199
10200TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10201: TH1(name,title,nbins,xbins)
10202{
10203 fDimension = 1;
10205 if (fgDefaultSumw2) Sumw2();
10206}
10207
10208////////////////////////////////////////////////////////////////////////////////
10209/// Destructor.
10210
10212{
10213}
10214
10215////////////////////////////////////////////////////////////////////////////////
10216/// Copy constructor.
10217/// The list of functions is not copied. (Use Clone() if needed)
10218
10219TH1L::TH1L(const TH1L &h1l) : TH1(), TArrayL64()
10220{
10221 h1l.TH1L::Copy(*this);
10222}
10223
10224////////////////////////////////////////////////////////////////////////////////
10225/// Increment bin content by 1.
10226/// Passing an out-of-range bin leads to undefined behavior
10227
10229{
10230 if (fArray[bin] < LLONG_MAX) fArray[bin]++;
10231}
10232
10233////////////////////////////////////////////////////////////////////////////////
10234/// Increment bin content by w.
10235/// \warning The value of w is cast to `Long64_t` before being added.
10236/// Passing an out-of-range bin leads to undefined behavior
10237
10239{
10241 if (newval > -LLONG_MAX && newval < LLONG_MAX) {fArray[bin] = newval; return;}
10242 if (newval < -LLONG_MAX) fArray[bin] = -LLONG_MAX;
10244}
10245
10246////////////////////////////////////////////////////////////////////////////////
10247/// Copy this to newth1
10248
10249void TH1L::Copy(TObject &newth1) const
10250{
10252}
10253
10254////////////////////////////////////////////////////////////////////////////////
10255/// Reset.
10256
10258{
10261}
10262
10263////////////////////////////////////////////////////////////////////////////////
10264/// Set total number of bins including under/overflow
10265/// Reallocate bin contents array
10266
10268{
10269 if (n < 0) n = fXaxis.GetNbins() + 2;
10270 fNcells = n;
10272}
10273
10274////////////////////////////////////////////////////////////////////////////////
10275/// Operator =
10276
10277TH1L& TH1L::operator=(const TH1L &h1)
10278{
10279 if (this != &h1)
10280 h1.TH1L::Copy(*this);
10281 return *this;
10282}
10283
10284
10285////////////////////////////////////////////////////////////////////////////////
10286/// Operator *
10287
10289{
10290 TH1L hnew = h1;
10291 hnew.Scale(c1);
10292 hnew.SetDirectory(nullptr);
10293 return hnew;
10294}
10295
10296////////////////////////////////////////////////////////////////////////////////
10297/// Operator +
10298
10299TH1L operator+(const TH1L &h1, const TH1L &h2)
10300{
10301 TH1L hnew = h1;
10302 hnew.Add(&h2,1);
10303 hnew.SetDirectory(nullptr);
10304 return hnew;
10305}
10306
10307////////////////////////////////////////////////////////////////////////////////
10308/// Operator -
10309
10310TH1L operator-(const TH1L &h1, const TH1L &h2)
10311{
10312 TH1L hnew = h1;
10313 hnew.Add(&h2,-1);
10314 hnew.SetDirectory(nullptr);
10315 return hnew;
10316}
10317
10318////////////////////////////////////////////////////////////////////////////////
10319/// Operator *
10320
10321TH1L operator*(const TH1L &h1, const TH1L &h2)
10322{
10323 TH1L hnew = h1;
10324 hnew.Multiply(&h2);
10325 hnew.SetDirectory(nullptr);
10326 return hnew;
10327}
10328
10329////////////////////////////////////////////////////////////////////////////////
10330/// Operator /
10331
10332TH1L operator/(const TH1L &h1, const TH1L &h2)
10333{
10334 TH1L hnew = h1;
10335 hnew.Divide(&h2);
10336 hnew.SetDirectory(nullptr);
10337 return hnew;
10338}
10339
10340//______________________________________________________________________________
10341// TH1F methods
10342// TH1F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216
10343//______________________________________________________________________________
10344
10345
10346////////////////////////////////////////////////////////////////////////////////
10347/// Constructor.
10348
10349TH1F::TH1F()
10350{
10351 fDimension = 1;
10352 SetBinsLength(3);
10353 if (fgDefaultSumw2) Sumw2();
10354}
10355
10356////////////////////////////////////////////////////////////////////////////////
10357/// Create a 1-Dim histogram with fix bins of type float
10358/// (see TH1::TH1 for explanation of parameters)
10359
10360TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10361: TH1(name,title,nbins,xlow,xup)
10362{
10363 fDimension = 1;
10365
10366 if (xlow >= xup) SetBuffer(fgBufferSize);
10367 if (fgDefaultSumw2) Sumw2();
10368}
10369
10370////////////////////////////////////////////////////////////////////////////////
10371/// Create a 1-Dim histogram with variable bins of type float
10372/// (see TH1::TH1 for explanation of parameters)
10373
10374TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10375: TH1(name,title,nbins,xbins)
10376{
10377 fDimension = 1;
10379 if (fgDefaultSumw2) Sumw2();
10380}
10381
10382////////////////////////////////////////////////////////////////////////////////
10383/// Create a 1-Dim histogram with variable bins of type float
10384/// (see TH1::TH1 for explanation of parameters)
10385
10386TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10387: TH1(name,title,nbins,xbins)
10388{
10389 fDimension = 1;
10391 if (fgDefaultSumw2) Sumw2();
10392}
10393
10394////////////////////////////////////////////////////////////////////////////////
10395/// Create a histogram from a TVectorF
10396/// by default the histogram name is "TVectorF" and title = ""
10397
10398TH1F::TH1F(const TVectorF &v)
10399: TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
10400{
10402 fDimension = 1;
10403 Int_t ivlow = v.GetLwb();
10404 for (Int_t i=0;i<fNcells-2;i++) {
10405 SetBinContent(i+1,v(i+ivlow));
10406 }
10408 if (fgDefaultSumw2) Sumw2();
10409}
10410
10411////////////////////////////////////////////////////////////////////////////////
10412/// Copy Constructor.
10413/// The list of functions is not copied. (Use Clone() if needed)
10414
10415TH1F::TH1F(const TH1F &h1f) : TH1(), TArrayF()
10416{
10417 h1f.TH1F::Copy(*this);
10418}
10419
10420////////////////////////////////////////////////////////////////////////////////
10421/// Destructor.
10422
10424{
10425}
10426
10427////////////////////////////////////////////////////////////////////////////////
10428/// Copy this to newth1.
10429
10430void TH1F::Copy(TObject &newth1) const
10431{
10433}
10434
10435////////////////////////////////////////////////////////////////////////////////
10436/// Reset.
10437
10439{
10442}
10443
10444////////////////////////////////////////////////////////////////////////////////
10445/// Set total number of bins including under/overflow
10446/// Reallocate bin contents array
10447
10449{
10450 if (n < 0) n = fXaxis.GetNbins() + 2;
10451 fNcells = n;
10452 TArrayF::Set(n);
10453}
10454
10455////////////////////////////////////////////////////////////////////////////////
10456/// Operator =
10457
10459{
10460 if (this != &h1f)
10461 h1f.TH1F::Copy(*this);
10462 return *this;
10463}
10464
10465////////////////////////////////////////////////////////////////////////////////
10466/// Operator *
10467
10469{
10470 TH1F hnew = h1;
10471 hnew.Scale(c1);
10472 hnew.SetDirectory(nullptr);
10473 return hnew;
10474}
10475
10476////////////////////////////////////////////////////////////////////////////////
10477/// Operator +
10478
10479TH1F operator+(const TH1F &h1, const TH1F &h2)
10480{
10481 TH1F hnew = h1;
10482 hnew.Add(&h2,1);
10483 hnew.SetDirectory(nullptr);
10484 return hnew;
10485}
10486
10487////////////////////////////////////////////////////////////////////////////////
10488/// Operator -
10489
10490TH1F operator-(const TH1F &h1, const TH1F &h2)
10491{
10492 TH1F hnew = h1;
10493 hnew.Add(&h2,-1);
10494 hnew.SetDirectory(nullptr);
10495 return hnew;
10496}
10497
10498////////////////////////////////////////////////////////////////////////////////
10499/// Operator *
10500
10501TH1F operator*(const TH1F &h1, const TH1F &h2)
10502{
10503 TH1F hnew = h1;
10504 hnew.Multiply(&h2);
10505 hnew.SetDirectory(nullptr);
10506 return hnew;
10507}
10508
10509////////////////////////////////////////////////////////////////////////////////
10510/// Operator /
10511
10512TH1F operator/(const TH1F &h1, const TH1F &h2)
10513{
10514 TH1F hnew = h1;
10515 hnew.Divide(&h2);
10516 hnew.SetDirectory(nullptr);
10517 return hnew;
10518}
10519
10520//______________________________________________________________________________
10521// TH1D methods
10522// TH1D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992
10523//______________________________________________________________________________
10524
10525
10526////////////////////////////////////////////////////////////////////////////////
10527/// Constructor.
10528
10529TH1D::TH1D()
10530{
10531 fDimension = 1;
10532 SetBinsLength(3);
10533 if (fgDefaultSumw2) Sumw2();
10534}
10535
10536////////////////////////////////////////////////////////////////////////////////
10537/// Create a 1-Dim histogram with fix bins of type double
10538/// (see TH1::TH1 for explanation of parameters)
10539
10540TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10541: TH1(name,title,nbins,xlow,xup)
10542{
10543 fDimension = 1;
10545
10546 if (xlow >= xup) SetBuffer(fgBufferSize);
10547 if (fgDefaultSumw2) Sumw2();
10548}
10549
10550////////////////////////////////////////////////////////////////////////////////
10551/// Create a 1-Dim histogram with variable bins of type double
10552/// (see TH1::TH1 for explanation of parameters)
10553
10554TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10555: TH1(name,title,nbins,xbins)
10556{
10557 fDimension = 1;
10559 if (fgDefaultSumw2) Sumw2();
10560}
10561
10562////////////////////////////////////////////////////////////////////////////////
10563/// Create a 1-Dim histogram with variable bins of type double
10564/// (see TH1::TH1 for explanation of parameters)
10565
10566TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10567: TH1(name,title,nbins,xbins)
10568{
10569 fDimension = 1;
10571 if (fgDefaultSumw2) Sumw2();
10572}
10573
10574////////////////////////////////////////////////////////////////////////////////
10575/// Create a histogram from a TVectorD
10576/// by default the histogram name is "TVectorD" and title = ""
10577
10578TH1D::TH1D(const TVectorD &v)
10579: TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
10580{
10582 fDimension = 1;
10583 Int_t ivlow = v.GetLwb();
10584 for (Int_t i=0;i<fNcells-2;i++) {
10585 SetBinContent(i+1,v(i+ivlow));
10586 }
10588 if (fgDefaultSumw2) Sumw2();
10589}
10590
10591////////////////////////////////////////////////////////////////////////////////
10592/// Destructor.
10593
10595{
10596}
10597
10598////////////////////////////////////////////////////////////////////////////////
10599/// Constructor.
10600
10601TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
10602{
10603 // intentially call virtual method to warn if TProfile is copying
10604 h1d.Copy(*this);
10605}
10606
10607////////////////////////////////////////////////////////////////////////////////
10608/// Copy this to newth1
10609
10610void TH1D::Copy(TObject &newth1) const
10611{
10613}
10614
10615////////////////////////////////////////////////////////////////////////////////
10616/// Reset.
10617
10619{
10622}
10623
10624////////////////////////////////////////////////////////////////////////////////
10625/// Set total number of bins including under/overflow
10626/// Reallocate bin contents array
10627
10629{
10630 if (n < 0) n = fXaxis.GetNbins() + 2;
10631 fNcells = n;
10632 TArrayD::Set(n);
10633}
10634
10635////////////////////////////////////////////////////////////////////////////////
10636/// Operator =
10637
10639{
10640 // intentially call virtual method to warn if TProfile is copying
10641 if (this != &h1d)
10642 h1d.Copy(*this);
10643 return *this;
10644}
10645
10646////////////////////////////////////////////////////////////////////////////////
10647/// Operator *
10648
10650{
10651 TH1D hnew = h1;
10652 hnew.Scale(c1);
10653 hnew.SetDirectory(nullptr);
10654 return hnew;
10655}
10656
10657////////////////////////////////////////////////////////////////////////////////
10658/// Operator +
10659
10660TH1D operator+(const TH1D &h1, const TH1D &h2)
10661{
10662 TH1D hnew = h1;
10663 hnew.Add(&h2,1);
10664 hnew.SetDirectory(nullptr);
10665 return hnew;
10666}
10667
10668////////////////////////////////////////////////////////////////////////////////
10669/// Operator -
10670
10671TH1D operator-(const TH1D &h1, const TH1D &h2)
10672{
10673 TH1D hnew = h1;
10674 hnew.Add(&h2,-1);
10675 hnew.SetDirectory(nullptr);
10676 return hnew;
10677}
10678
10679////////////////////////////////////////////////////////////////////////////////
10680/// Operator *
10681
10682TH1D operator*(const TH1D &h1, const TH1D &h2)
10683{
10684 TH1D hnew = h1;
10685 hnew.Multiply(&h2);
10686 hnew.SetDirectory(nullptr);
10687 return hnew;
10688}
10689
10690////////////////////////////////////////////////////////////////////////////////
10691/// Operator /
10692
10693TH1D operator/(const TH1D &h1, const TH1D &h2)
10694{
10695 TH1D hnew = h1;
10696 hnew.Divide(&h2);
10697 hnew.SetDirectory(nullptr);
10698 return hnew;
10699}
10700
10701////////////////////////////////////////////////////////////////////////////////
10702///return pointer to histogram with name
10703///hid if id >=0
10704///h_id if id <0
10705
10706TH1 *R__H(Int_t hid)
10707{
10708 TString hname;
10709 if(hid >= 0) hname.Form("h%d",hid);
10710 else hname.Form("h_%d",hid);
10711 return (TH1*)gDirectory->Get(hname);
10712}
10713
10714////////////////////////////////////////////////////////////////////////////////
10715///return pointer to histogram with name hname
10716
10717TH1 *R__H(const char * hname)
10718{
10719 return (TH1*)gDirectory->Get(hname);
10720}
10721
10722
10723/// \fn void TH1::SetBarOffset(Float_t offset)
10724/// Set the bar offset as fraction of the bin width for drawing mode "B".
10725/// This shifts bars to the right on the x axis, and helps to draw bars next to each other.
10726/// \see THistPainter, SetBarWidth()
10727
10728/// \fn void TH1::SetBarWidth(Float_t width)
10729/// Set the width of bars as fraction of the bin width for drawing mode "B".
10730/// This allows for making bars narrower than the bin width. With SetBarOffset(), this helps to draw multiple bars next to each other.
10731/// \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:126
#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:148
static bool IsEquidistantBinning(const TAxis &axis)
Test if the binning is equidistant.
Definition TH1.cxx:5976
void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
Least square linear fit without weights.
Definition TH1.cxx:4922
void H1InitGaus()
Compute Initial values of parameters for a gaussian.
Definition TH1.cxx:4757
void H1InitExpo()
Compute Initial values of parameters for an exponential.
Definition TH1.cxx:4813
TH1C operator+(const TH1C &h1, const TH1C &h2)
Operator +.
Definition TH1.cxx:9738
TH1C operator-(const TH1C &h1, const TH1C &h2)
Operator -.
Definition TH1.cxx:9749
TH1C operator/(const TH1C &h1, const TH1C &h2)
Operator /.
Definition TH1.cxx:9771
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:4968
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:5959
static Bool_t AlmostInteger(Double_t a, Double_t epsilon=0.00000001)
Test if a double is almost an integer.
Definition TH1.cxx:5967
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:10704
TH1C operator*(Double_t c1, const TH1C &h1)
Operator *.
Definition TH1.cxx:9727
void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
Least squares lpolynomial fitting without weights.
Definition TH1.cxx:4863
void H1InitPolynom()
Compute Initial values of parameters for a polynom.
Definition TH1.cxx:4833
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:777
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:417
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:2510
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.
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
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:511
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:9651
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9707
TH1C & operator=(const TH1C &h1)
Operator =.
Definition TH1.cxx:9717
TH1C()
Constructor.
Definition TH1.cxx:9603
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9689
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9668
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:9697
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:926
~TH1D() override
Destructor.
Definition TH1.cxx:10592
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10626
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10608
TH1D()
Constructor.
Definition TH1.cxx:10527
TH1D & operator=(const TH1D &h1)
Operator =.
Definition TH1.cxx:10636
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:10456
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10428
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10446
~TH1F() override
Destructor.
Definition TH1.cxx:10421
TH1F()
Constructor.
Definition TH1.cxx:10347
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:10078
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:10039
~TH1I() override
Destructor.
Definition TH1.cxx:10022
TH1I()
Constructor.
Definition TH1.cxx:9974
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10060
TH1I & operator=(const TH1I &h1)
Operator =.
Definition TH1.cxx:10088
1-D histogram with a long64 per channel (see TH1 documentation)
Definition TH1.h:837
TH1L & operator=(const TH1L &h1)
Operator =.
Definition TH1.cxx:10275
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:10226
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10265
~TH1L() override
Destructor.
Definition TH1.cxx:10209
TH1L()
Constructor.
Definition TH1.cxx:10161
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10247
1-D histogram with a short per channel (see TH1 documentation)
Definition TH1.h:755
TH1S & operator=(const TH1S &h1)
Operator =.
Definition TH1.cxx:9902
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9874
TH1S()
Constructor.
Definition TH1.cxx:9788
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9892
~TH1S() override
Destructor.
Definition TH1.cxx:9836
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9853
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
~TH1() override
Histogram default destructor.
Definition TH1.cxx:658
virtual void SetError(const Double_t *error)
Replace bin errors by values in array error.
Definition TH1.cxx:9104
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:9090
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition TH1.cxx:4356
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:1374
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition TH1.cxx:4519
char * GetObjectInfo(Int_t px, Int_t py) const override
Redefines TObject::GetObjectInfo.
Definition TH1.cxx:4573
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition TH1.cxx:7020
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:9291
virtual void Rebuild(Option_t *option="")
Using the current bin info, recompute the arrays for contents and errors.
Definition TH1.cxx:7228
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:3868
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:2872
virtual Bool_t Multiply(TF1 *f1, Double_t c1=1)
Performs the operation:
Definition TH1.cxx:6147
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:7962
virtual void Normalize(Option_t *option="")
Normalize a histogram to its integral or to its maximum.
Definition TH1.cxx:6309
void Copy(TObject &hnew) const override
Copy this histogram structure to newth1.
Definition TH1.cxx:2721
void SetTitle(const char *title) override
Change/set the title.
Definition TH1.cxx:6852
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:7066
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:8055
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
static TClass * Class()
static Int_t GetDefaultBufferSize()
Static function return the default buffer size for automatic histograms the parameter fgBufferSize ma...
Definition TH1.cxx:4477
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:8126
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:7736
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:9469
void UseCurrentStyle() override
Copy current attributes from/to current style.
Definition TH1.cxx:7598
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:5480
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:2100
static bool CheckBinLimits(const TAxis *a1, const TAxis *a2)
Check bin limits.
Definition TH1.cxx:1572
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:9213
static Int_t FitOptionsMake(Option_t *option, Foption_t &Foption)
Decode string choptin and fill fitOption structure.
Definition TH1.cxx:4748
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:7664
virtual Double_t GetSkewness(Int_t axis=1) const
Definition TH1.cxx:7800
virtual void ClearUnderflowAndOverflow()
Remove all the content from the underflow and overflow bins, without changing the number of entries A...
Definition TH1.cxx:2556
virtual void FillRandom(TF1 *f1, Int_t ntimes=5000, TRandom *rng=nullptr)
Definition TH1.cxx:3593
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition TH1.cxx:8589
virtual TH1 * DrawNormalized(Option_t *option="", Double_t norm=1) const
Draw a normalized copy of this histogram.
Definition TH1.cxx:3209
@ 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:7074
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1325
@ 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:8675
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition TH1.cxx:6767
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:7244
void SetNameTitle(const char *name, const char *title) override
Change the name and title of this histogram.
Definition TH1.cxx:9127
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:5070
TH1 * GetCumulative(Bool_t forward=kTRUE, const char *suffix="_cumulative") const
Return a pointer to a histogram containing the cumulative content.
Definition TH1.cxx:2666
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:1339
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:9451
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition TH1.cxx:6006
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:8013
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition TH1.cxx:4582
TObject * FindObject(const char *name) const override
Search object named name in the list of functions.
Definition TH1.cxx:3928
void Print(Option_t *option="") const override
Print some global quantities for this histogram.
Definition TH1.cxx:7150
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
Definition TH1.cxx:4486
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:3805
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:3970
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:5057
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:8698
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:3349
virtual void LabelsInflate(Option_t *axis="X")
Double the number of bins for axis.
Definition TH1.cxx:5413
virtual TH1 * ShowBackground(Int_t niter=20, Option_t *option="same")
This function calculates the background spectrum in this histogram.
Definition TH1.cxx:9437
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
Definition TH1.cxx:5996
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:852
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:7383
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:8117
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:9356
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:3409
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:9229
void Browse(TBrowser *b) override
Browse the Histogram object.
Definition TH1.cxx:780
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition TH1.cxx:8547
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx:3113
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:7510
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:5312
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TH1.cxx:7405
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check that axis have same labels.
Definition TH1.cxx:1599
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:5213
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:6834
virtual void SetBuffer(Int_t bufsize, Option_t *option="")
Set the maximum number of entries to be kept in the buffer.
Definition TH1.cxx:8607
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition TH1.cxx:5280
UInt_t GetAxisLabelStatus() const
Internal function used in TH1::Fill to see which axis is full alphanumeric, i.e.
Definition TH1.cxx:6806
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:8090
@ 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
static void SetDefaultBufferSize(Int_t bufsize=1000)
Static function to set the default buffer size for automatic histograms.
Definition TH1.cxx:6824
@ kNstat
Size of statistics data (up to TProfile3D)
Definition TH1.h:422
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:9372
virtual void DirectoryAutoAdd(TDirectory *)
Callback to perform the automatic addition of the histogram to the given directory.
Definition TH1.cxx:2850
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:9337
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:9302
void Build()
Creates histogram basic data structure.
Definition TH1.cxx:789
virtual Double_t GetEntries() const
Return the current number of entries.
Definition TH1.cxx:4494
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:9201
virtual TH1 * Rebin(Int_t ngroup=2, const char *newname="", const Double_t *xbins=nullptr)
Rebin this histogram.
Definition TH1.cxx:6406
virtual Int_t BufferFill(Double_t x, Double_t w)
accumulate arguments in buffer.
Definition TH1.cxx:1537
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:5184
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:6780
TList * GetListOfFunctions() const
Definition TH1.h:488
void SetName(const char *name) override
Change the name of this histogram.
Definition TH1.cxx:9113
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition TH1.cxx:3178
virtual Double_t GetRandom(TRandom *rng=nullptr, Option_t *option="") const
Return a random number distributed according the histogram bin contents.
Definition TH1.cxx:5107
Bool_t IsEmpty() const
Check if a histogram is empty (this is a protected method used mainly by TH1Merger )
Definition TH1.cxx:5262
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition TH1.cxx:7704
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6337
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:8211
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculated from bin cont...
Definition TH1.cxx:8031
virtual void SetBinErrorOption(EBinErrorOpt type)
Definition TH1.h:629
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Definition TH1.cxx:3240
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:2534
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:2041
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:3538
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition TH1.cxx:8884
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition TH1.cxx:8730
static Int_t AutoP2GetBins(Int_t n)
Auxiliary function to get the next power of 2 integer value larger then n.
Definition TH1.cxx:1352
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:4538
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TH1.cxx:3305
virtual Double_t * GetIntegral()
Return a pointer to the array of bins integral.
Definition TH1.cxx:2636
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:3512
static bool CheckEqualAxes(const TAxis *a1, const TAxis *a2)
Check that the axis are the same.
Definition TH1.cxx:1642
@ 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:5159
virtual Int_t GetContour(Double_t *levels=nullptr)
Return contour values into array levels if pointer levels is non zero.
Definition TH1.cxx:8560
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:6635
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:9313
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:4411
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition TH1.cxx:8579
virtual void SetContour(Int_t nlevels, const Double_t *levels=nullptr)
Set the number and values of contour levels.
Definition TH1.cxx:8636
virtual void SetHighlight(Bool_t set=kTRUE)
Set highlight (enable/disable) mode for the histogram by default highlight mode is disable.
Definition TH1.cxx:4553
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition TH1.cxx:9260
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition TH1.cxx:6735
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition TH1.cxx:8818
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:2581
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:3743
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:7322
virtual Int_t GetQuantiles(Int_t n, Double_t *xp, const Double_t *p=nullptr)
Compute Quantiles for this histogram.
Definition TH1.cxx:4686
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:2802
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition TH1.cxx:7784
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:2889
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:8788
int LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge=false) const
Definition TH1.cxx:909
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:1671
static Int_t CheckConsistency(const TH1 *h1, const TH1 *h2)
Check histogram compatibility.
Definition TH1.cxx:1710
void RecursiveRemove(TObject *obj) override
Recursively remove object from the list of functions.
Definition TH1.cxx:6707
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:8327
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:6909
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:9324
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:8920
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:3776
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:9173
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:6591
static bool CheckAxisLimits(const TAxis *a1, const TAxis *a2)
Check that the axis limits of the histograms are the same.
Definition TH1.cxx:1628
static Bool_t AddDirectoryStatus()
Check whether TH1-derived classes should register themselves to the current gDirectory.
Definition TH1.cxx:772
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:7564
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:5343
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:3257
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:1445
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition TH1.cxx:9143
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition TH1.cxx:7873
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:462
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:480
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:227
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition TObject.cxx:909
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1084
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:204
virtual void SaveAs(const char *filename="", Option_t *option="") const
Save this object in the file specified by filename.
Definition TObject.cxx:708
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:888
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:549
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1098
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:899
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:845
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:796
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:1072
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:2385
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:762
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, bool useIntegral=false)
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