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/** \class TH1
79 \ingroup Histograms
80TH1 is the base class of all histogram classes in %ROOT.
81
82It provides the common interface for operations such as binning, filling, drawing, which
83will be detailed below.
84
85-# [Creating histograms](\ref creating-histograms)
86 - [Labelling axes](\ref labelling-axis)
87-# [Binning](\ref binning)
88 - [Fix or variable bin size](\ref fix-var)
89 - [Convention for numbering bins](\ref convention)
90 - [Alphanumeric Bin Labels](\ref alpha)
91 - [Histograms with automatic bins](\ref auto-bin)
92 - [Rebinning](\ref rebinning)
93-# [Filling histograms](\ref filling-histograms)
94 - [Associated errors](\ref associated-errors)
95 - [Associated functions](\ref associated-functions)
96 - [Projections of histograms](\ref prof-hist)
97 - [Random Numbers and histograms](\ref random-numbers)
98 - [Making a copy of a histogram](\ref making-a-copy)
99 - [Normalizing histograms](\ref normalizing)
100-# [Drawing histograms](\ref drawing-histograms)
101 - [Setting Drawing histogram contour levels (2-D hists only)](\ref cont-level)
102 - [Setting histogram graphics attributes](\ref graph-att)
103 - [Customising how axes are drawn](\ref axis-drawing)
104-# [Fitting histograms](\ref fitting-histograms)
105-# [Saving/reading histograms to/from a ROOT file](\ref saving-histograms)
106-# [Operations on histograms](\ref operations-on-histograms)
107-# [Miscellaneous operations](\ref misc)
108
109ROOT supports the following histogram types:
110
111 - 1-D histograms:
112 - TH1C : histograms with one byte per channel. Maximum bin content = 127
113 - TH1S : histograms with one short per channel. Maximum bin content = 32767
114 - TH1I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
115 - TH1L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
116 - TH1F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax "***")
117 - TH1D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax "****")
118 - 2-D histograms:
119 - TH2C : histograms with one byte per channel. Maximum bin content = 127
120 - TH2S : histograms with one short per channel. Maximum bin content = 32767
121 - TH2I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
122 - TH2L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
123 - TH2F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax "***")
124 - TH2D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax "****")
125 - 3-D histograms:
126 - TH3C : histograms with one byte per channel. Maximum bin content = 127
127 - TH3S : histograms with one short per channel. Maximum bin content = 32767
128 - TH3I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
129 - TH3L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
130 - TH3F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax "***")
131 - TH3D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax "****")
132 - Profile histograms: See classes TProfile, TProfile2D and TProfile3D.
133 Profile histograms are used to display the mean value of Y and its standard deviation
134 for each bin in X. Profile histograms are in many cases an elegant
135 replacement of two-dimensional histograms : the inter-relation of two
136 measured quantities X and Y can always be visualized by a two-dimensional
137 histogram or scatter-plot; If Y is an unknown (but single-valued)
138 approximate function of X, this function is displayed by a profile
139 histogram with much better precision than by a scatter-plot.
140
141<sup>
142\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>
143\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>
144\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>
145\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)
146</sup>
147
148The inheritance hierarchy looks as follows:
149
150\image html classTH1__inherit__graph_org.svg width=100%
151
152\anchor creating-histograms
153## Creating histograms
154
155Histograms are created by invoking one of the constructors, e.g.
156~~~ {.cpp}
157 TH1F *h1 = new TH1F("h1", "h1 title", 100, 0, 4.4);
158 TH2F *h2 = new TH2F("h2", "h2 title", 40, 0, 4, 30, -3, 3);
159~~~
160Histograms may also be created by:
161
162 - calling the Clone() function, see below
163 - making a projection from a 2-D or 3-D histogram, see below
164 - reading a histogram from a file
165
166 When a histogram is created, a reference to it is automatically added
167 to the list of in-memory objects for the current file or directory.
168 Then the pointer to this histogram in the current directory can be found
169 by its name, doing:
170~~~ {.cpp}
171 TH1F *h1 = (TH1F*)gDirectory->FindObject(name);
172~~~
173
174 This default behaviour can be changed by:
175~~~ {.cpp}
176 h->SetDirectory(nullptr); // for the current histogram h
177 TH1::AddDirectory(kFALSE); // sets a global switch disabling the referencing
178~~~
179 When the histogram is deleted, the reference to it is removed from
180 the list of objects in memory.
181 When a file is closed, all histograms in memory associated with this file
182 are automatically deleted.
183
184\anchor labelling-axis
185### Labelling axes
186
187 Axis titles can be specified in the title argument of the constructor.
188 They must be separated by ";":
189~~~ {.cpp}
190 TH1F* h=new TH1F("h", "Histogram title;X Axis;Y Axis", 100, 0, 1);
191~~~
192 The histogram title and the axis titles can be any TLatex string, and
193 are persisted if a histogram is written to a file.
194
195 Any title can be omitted:
196~~~ {.cpp}
197 TH1F* h=new TH1F("h", "Histogram title;;Y Axis", 100, 0, 1);
198 TH1F* h=new TH1F("h", ";;Y Axis", 100, 0, 1);
199~~~
200 The method SetTitle() has the same syntax:
201~~~ {.cpp}
202 h->SetTitle("Histogram title;Another X title Axis");
203~~~
204Alternatively, the title of each axis can be set directly:
205~~~ {.cpp}
206 h->GetXaxis()->SetTitle("X axis title");
207 h->GetYaxis()->SetTitle("Y axis title");
208~~~
209For bin labels see \ref binning.
210
211\anchor binning
212## Binning
213
214\anchor fix-var
215### Fix or variable bin size
216
217 All histogram types support either fix or variable bin sizes.
218 2-D histograms may have fix size bins along X and variable size bins
219 along Y or vice-versa. The functions to fill, manipulate, draw or access
220 histograms are identical in both cases.
221
222 Each histogram always contains 3 axis objects of type TAxis: fXaxis, fYaxis and fZaxis.
223 To access the axis parameters, use:
224~~~ {.cpp}
225 TAxis *xaxis = h->GetXaxis(); etc.
226 Double_t binCenter = xaxis->GetBinCenter(bin), etc.
227~~~
228 See class TAxis for a description of all the access functions.
229 The axis range is always stored internally in double precision.
230
231\anchor convention
232### Convention for numbering bins
233
234 For all histogram types: nbins, xlow, xup
235~~~ {.cpp}
236 bin = 0; underflow bin
237 bin = 1; first bin with low-edge xlow INCLUDED
238 bin = nbins; last bin with upper-edge xup EXCLUDED
239 bin = nbins+1; overflow bin
240~~~
241 In case of 2-D or 3-D histograms, a "global bin" number is defined.
242 For example, assuming a 3-D histogram with (binx, biny, binz), the function
243~~~ {.cpp}
244 Int_t gbin = h->GetBin(binx, biny, binz);
245~~~
246 returns a global/linearized gbin number. This global gbin is useful
247 to access the bin content/error information independently of the dimension.
248 Note that to access the information other than bin content and errors
249 one should use the TAxis object directly with e.g.:
250~~~ {.cpp}
251 Double_t xcenter = h3->GetZaxis()->GetBinCenter(27);
252~~~
253 returns the center along z of bin number 27 (not the global bin)
254 in the 3-D histogram h3.
255
256\anchor alpha
257### Alphanumeric Bin Labels
258
259 By default, a histogram axis is drawn with its numeric bin labels.
260 One can specify alphanumeric labels instead with:
261
262 - call TAxis::SetBinLabel(bin, label);
263 This can always be done before or after filling.
264 When the histogram is drawn, bin labels will be automatically drawn.
265 See examples labels1.C and labels2.C
266 - call to a Fill function with one of the arguments being a string, e.g.
267~~~ {.cpp}
268 hist1->Fill(somename, weight);
269 hist2->Fill(x, somename, weight);
270 hist2->Fill(somename, y, weight);
271 hist2->Fill(somenamex, somenamey, weight);
272~~~
273 See examples hlabels1.C and hlabels2.C
274 - via TTree::Draw. see for example cernstaff.C
275~~~ {.cpp}
276 tree.Draw("Nation::Division");
277~~~
278 where "Nation" and "Division" are two branches of a Tree.
279
280When using the options 2 or 3 above, the labels are automatically
281 added to the list (THashList) of labels for a given axis.
282 By default, an axis is drawn with the order of bins corresponding
283 to the filling sequence. It is possible to reorder the axis
284
285 - alphabetically
286 - by increasing or decreasing values
287
288 The reordering can be triggered via the TAxis context menu by selecting
289 the menu item "LabelsOption" or by calling directly
290 TH1::LabelsOption(option, axis) where
291
292 - axis may be "X", "Y" or "Z"
293 - option may be:
294 - "a" sort by alphabetic order
295 - ">" sort by decreasing values
296 - "<" sort by increasing values
297 - "h" draw labels horizontal
298 - "v" draw labels vertical
299 - "u" draw labels up (end of label right adjusted)
300 - "d" draw labels down (start of label left adjusted)
301
302 When using the option 2 above, new labels are added by doubling the current
303 number of bins in case one label does not exist yet.
304 When the Filling is terminated, it is possible to trim the number
305 of bins to match the number of active labels by calling
306~~~ {.cpp}
307 TH1::LabelsDeflate(axis) with axis = "X", "Y" or "Z"
308~~~
309 This operation is automatic when using TTree::Draw.
310 Once bin labels have been created, they become persistent if the histogram
311 is written to a file or when generating the C++ code via SavePrimitive.
312
313\anchor auto-bin
314### Histograms with automatic bins
315
316 When a histogram is created with an axis lower limit greater or equal
317 to its upper limit, the SetBuffer is automatically called with an
318 argument fBufferSize equal to fgBufferSize (default value=1000).
319 fgBufferSize may be reset via the static function TH1::SetDefaultBufferSize.
320 The axis limits will be automatically computed when the buffer will
321 be full or when the function BufferEmpty is called.
322
323\anchor rebinning
324### Rebinning
325
326 At any time, a histogram can be rebinned via TH1::Rebin. This function
327 returns a new histogram with the rebinned contents.
328 If bin errors were stored, they are recomputed during the rebinning.
329
330
331\anchor filling-histograms
332## Filling histograms
333
334 A histogram is typically filled with statements like:
335~~~ {.cpp}
336 h1->Fill(x);
337 h1->Fill(x, w); //fill with weight
338 h2->Fill(x, y)
339 h2->Fill(x, y, w)
340 h3->Fill(x, y, z)
341 h3->Fill(x, y, z, w)
342~~~
343 or via one of the Fill functions accepting names described above.
344 The Fill functions compute the bin number corresponding to the given
345 x, y or z argument and increment this bin by the given weight.
346 The Fill functions return the bin number for 1-D histograms or global
347 bin number for 2-D and 3-D histograms.
348 If TH1::Sumw2 has been called before filling, the sum of squares of
349 weights is also stored.
350 One can also increment directly a bin number via TH1::AddBinContent
351 or replace the existing content via TH1::SetBinContent. Passing an
352 out-of-range bin to TH1::AddBinContent leads to undefined behavior.
353 To access the bin content of a given bin, do:
354~~~ {.cpp}
355 Double_t binContent = h->GetBinContent(bin);
356~~~
357
358 By default, the bin number is computed using the current axis ranges.
359 If the automatic binning option has been set via
360~~~ {.cpp}
361 h->SetCanExtend(TH1::kAllAxes);
362~~~
363 then, the Fill Function will automatically extend the axis range to
364 accommodate the new value specified in the Fill argument. The method
365 used is to double the bin size until the new value fits in the range,
366 merging bins two by two. This automatic binning options is extensively
367 used by the TTree::Draw function when histogramming Tree variables
368 with an unknown range.
369 This automatic binning option is supported for 1-D, 2-D and 3-D histograms.
370
371 During filling, some statistics parameters are incremented to compute
372 the mean value and Root Mean Square with the maximum precision.
373
374 In case of histograms of type TH1C, TH1S, TH2C, TH2S, TH3C, TH3S
375 a check is made that the bin contents do not exceed the maximum positive
376 capacity (127 or 32767). Histograms of all types may have positive
377 or/and negative bin contents.
378
379\anchor associated-errors
380### Associated errors
381 By default, for each bin, the sum of weights is computed at fill time.
382 One can also call TH1::Sumw2 to force the storage and computation
383 of the sum of the square of weights per bin.
384 If Sumw2 has been called, the error per bin is computed as the
385 sqrt(sum of squares of weights), otherwise the error is set equal
386 to the sqrt(bin content).
387 To return the error for a given bin number, do:
388~~~ {.cpp}
389 Double_t error = h->GetBinError(bin);
390~~~
391
392\anchor associated-functions
393### Associated functions
394 One or more objects (typically a TF1*) can be added to the list
395 of functions (fFunctions) associated to each histogram.
396 When TH1::Fit is invoked, the fitted function is added to this list.
397 Given a histogram (or TGraph) `h`, one can retrieve an associated function
398 with:
399~~~ {.cpp}
400 TF1 *myfunc = h->GetFunction("myfunc");
401~~~
402
403
404\anchor operations-on-histograms
405## Operations on histograms
406
407 Many types of operations are supported on histograms or between histograms
408
409 - Addition of a histogram to the current histogram.
410 - Additions of two histograms with coefficients and storage into the current
411 histogram.
412 - Multiplications and Divisions are supported in the same way as additions.
413 - The Add, Divide and Multiply functions also exist to add, divide or multiply
414 a histogram by a function.
415
416 If a histogram has associated error bars (TH1::Sumw2 has been called),
417 the resulting error bars are also computed assuming independent histograms.
418 In case of divisions, Binomial errors are also supported.
419 One can mark a histogram to be an "average" histogram by setting its bit kIsAverage via
420 myhist.SetBit(TH1::kIsAverage);
421 When adding (see TH1::Add) average histograms, the histograms are averaged and not summed.
422
423
424\anchor prof-hist
425### Projections of histograms
426
427 One can:
428
429 - make a 1-D projection of a 2-D histogram or Profile
430 see functions TH2::ProjectionX,Y, TH2::ProfileX,Y, TProfile::ProjectionX
431 - make a 1-D, 2-D or profile out of a 3-D histogram
432 see functions TH3::ProjectionZ, TH3::Project3D.
433
434 One can fit these projections via:
435~~~ {.cpp}
436 TH2::FitSlicesX,Y, TH3::FitSlicesZ.
437~~~
438
439\anchor random-numbers
440### Random Numbers and histograms
441
442 TH1::FillRandom can be used to randomly fill a histogram using
443 the contents of an existing TF1 function or another
444 TH1 histogram (for all dimensions).
445 For example, the following two statements create and fill a histogram
446 10000 times with a default gaussian distribution of mean 0 and sigma 1:
447~~~ {.cpp}
448 TH1F h1("h1", "histo from a gaussian", 100, -3, 3);
449 h1.FillRandom("gaus", 10000);
450~~~
451 TH1::GetRandom can be used to return a random number distributed
452 according to the contents of a histogram.
453
454\anchor making-a-copy
455### Making a copy of a histogram
456 Like for any other ROOT object derived from TObject, one can use
457 the Clone() function. This makes an identical copy of the original
458 histogram including all associated errors and functions, e.g.:
459~~~ {.cpp}
460 TH1F *hnew = (TH1F*)h->Clone("hnew");
461~~~
462
463\anchor normalizing
464### Normalizing histograms
465
466 One can scale a histogram such that the bins integral is equal to
467 the normalization parameter via TH1::Scale(Double_t norm), where norm
468 is the desired normalization divided by the integral of the histogram.
471\anchor drawing-histograms
472## Drawing histograms
473
474 Histograms are drawn via the THistPainter class. Each histogram has
475 a pointer to its own painter (to be usable in a multithreaded program).
476 Many drawing options are supported.
477 See THistPainter::Paint() for more details.
478
479 The same histogram can be drawn with different options in different pads.
480 When a histogram drawn in a pad is deleted, the histogram is
481 automatically removed from the pad or pads where it was drawn.
482 If a histogram is drawn in a pad, then filled again, the new status
483 of the histogram will be automatically shown in the pad next time
484 the pad is updated. One does not need to redraw the histogram.
485 To draw the current version of a histogram in a pad, one can use
486~~~ {.cpp}
487 h->DrawCopy();
488~~~
489 This makes a clone (see Clone below) of the histogram. Once the clone
490 is drawn, the original histogram may be modified or deleted without
491 affecting the aspect of the clone.
492
493 One can use TH1::SetMaximum() and TH1::SetMinimum() to force a particular
494 value for the maximum or the minimum scale on the plot. (For 1-D
495 histograms this means the y-axis, while for 2-D histograms these
496 functions affect the z-axis).
497
498 TH1::UseCurrentStyle() can be used to change all histogram graphics
499 attributes to correspond to the current selected style.
500 This function must be called for each histogram.
501 In case one reads and draws many histograms from a file, one can force
502 the histograms to inherit automatically the current graphics style
503 by calling before gROOT->ForceStyle().
504
505\anchor cont-level
506### Setting Drawing histogram contour levels (2-D hists only)
507
508 By default contours are automatically generated at equidistant
509 intervals. A default value of 20 levels is used. This can be modified
510 via TH1::SetContour() or TH1::SetContourLevel().
511 the contours level info is used by the drawing options "cont", "surf",
512 and "lego".
513
514\anchor graph-att
515### Setting histogram graphics attributes
517 The histogram classes inherit from the attribute classes:
518 TAttLine, TAttFill, and TAttMarker.
519 See the member functions of these classes for the list of options.
520
521\anchor axis-drawing
522### Customizing how axes are drawn
523
524 Use the functions of TAxis, such as
525~~~ {.cpp}
526 histogram.GetXaxis()->SetTicks("+");
527 histogram.GetYaxis()->SetRangeUser(1., 5.);
528~~~
529
530\anchor fitting-histograms
531## Fitting histograms
532
533 Histograms (1-D, 2-D, 3-D and Profiles) can be fitted with a user
534 specified function or a pre-defined function via TH1::Fit.
535 See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for the fitting documentation and the possible [fitting options](\ref HFitOpt)
536
537 The FitPanel can also be used for fitting an histogram. See the [FitPanel documentation](https://root.cern/manual/fitting/#using-the-fit-panel).
538
539\anchor saving-histograms
540## Saving/reading histograms to/from a ROOT file
541
542 The following statements create a ROOT file and store a histogram
543 on the file. Because TH1 derives from TNamed, the key identifier on
544 the file is the histogram name:
545~~~ {.cpp}
546 TFile f("histos.root", "new");
547 TH1F h1("hgaus", "histo from a gaussian", 100, -3, 3);
548 h1.FillRandom("gaus", 10000);
549 h1->Write();
550~~~
551 To read this histogram in another Root session, do:
552~~~ {.cpp}
553 TFile f("histos.root");
554 TH1F *h = (TH1F*)f.Get("hgaus");
555~~~
556 One can save all histograms in memory to the file by:
557~~~ {.cpp}
558 file->Write();
559~~~
560
561
562\anchor misc
563## Miscellaneous operations
564
565~~~ {.cpp}
566 TH1::KolmogorovTest(): statistical test of compatibility in shape
567 between two histograms
568 TH1::Smooth() smooths the bin contents of a 1-d histogram
569 TH1::Integral() returns the integral of bin contents in a given bin range
570 TH1::GetMean(int axis) returns the mean value along axis
571 TH1::GetStdDev(int axis) returns the sigma distribution along axis
572 TH1::GetEntries() returns the number of entries
573 TH1::Reset() resets the bin contents and errors of a histogram
574~~~
575 IMPORTANT NOTE: The returned values for GetMean and GetStdDev depend on how the
576 histogram statistics are calculated. By default, if no range has been set, the
577 returned values are the (unbinned) ones calculated at fill time. If a range has been
578 set, however, the values are calculated using the bins in range; THIS IS TRUE EVEN
579 IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset the range.
580 To ensure that the returned values are always those of the binned data stored in the
581 histogram, call TH1::ResetStats. See TH1::GetStats.
582*/
583
584TF1 *gF1=nullptr; //left for back compatibility (use TVirtualFitter::GetUserFunc instead)
585
590
591extern void H1InitGaus();
592extern void H1InitExpo();
593extern void H1InitPolynom();
594extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
597
598
599////////////////////////////////////////////////////////////////////////////////
600/// Histogram default constructor.
601
603{
604 fDirectory = nullptr;
605 fFunctions = new TList;
606 fNcells = 0;
607 fIntegral = nullptr;
608 fPainter = nullptr;
609 fEntries = 0;
610 fNormFactor = 0;
612 fMaximum = -1111;
613 fMinimum = -1111;
614 fBufferSize = 0;
615 fBuffer = nullptr;
618 fXaxis.SetName("xaxis");
619 fYaxis.SetName("yaxis");
620 fZaxis.SetName("zaxis");
621 fXaxis.SetParent(this);
622 fYaxis.SetParent(this);
623 fZaxis.SetParent(this);
625}
626
627////////////////////////////////////////////////////////////////////////////////
628/// Histogram default destructor.
629
631{
633 return;
634 }
635 delete[] fIntegral;
636 fIntegral = nullptr;
637 delete[] fBuffer;
638 fBuffer = nullptr;
639 if (fFunctions) {
641
643 TObject* obj = nullptr;
644 //special logic to support the case where the same object is
645 //added multiple times in fFunctions.
646 //This case happens when the same object is added with different
647 //drawing modes
648 //In the loop below we must be careful with objects (eg TCutG) that may
649 // have been added to the list of functions of several histograms
650 //and may have been already deleted.
651 while ((obj = fFunctions->First())) {
652 while(fFunctions->Remove(obj)) { }
654 break;
655 }
656 delete obj;
657 obj = nullptr;
658 }
659 delete fFunctions;
660 fFunctions = nullptr;
661 }
662 if (fDirectory) {
663 fDirectory->Remove(this);
664 fDirectory = nullptr;
665 }
666 delete fPainter;
667 fPainter = nullptr;
668}
669
670////////////////////////////////////////////////////////////////////////////////
671/// Constructor for fix bin size histograms.
672/// Creates the main histogram structure.
673///
674/// \param[in] name name of histogram (avoid blanks)
675/// \param[in] title histogram title.
676/// If title is of the form `stringt;stringx;stringy;stringz`,
677/// the histogram title is set to `stringt`,
678/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
679/// \param[in] nbins number of bins
680/// \param[in] xlow low edge of first bin
681/// \param[in] xup upper edge of last bin (not included in last bin)
682
683
684TH1::TH1(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
685 :TNamed(name,title)
686{
687 Build();
688 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
689 fXaxis.Set(nbins,xlow,xup);
690 fNcells = fXaxis.GetNbins()+2;
691}
692
693////////////////////////////////////////////////////////////////////////////////
694/// Constructor for variable bin size histograms using an input array of type float.
695/// Creates the main histogram structure.
696///
697/// \param[in] name name of histogram (avoid blanks)
698/// \param[in] title histogram title.
699/// If title is of the form `stringt;stringx;stringy;stringz`
700/// the histogram title is set to `stringt`,
701/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
702/// \param[in] nbins number of bins
703/// \param[in] xbins array of low-edges for each bin.
704/// This is an array of type float and size nbins+1
705
706TH1::TH1(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
707 :TNamed(name,title)
708{
709 Build();
710 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
711 if (xbins) fXaxis.Set(nbins,xbins);
712 else fXaxis.Set(nbins,0,1);
713 fNcells = fXaxis.GetNbins()+2;
714}
715
716////////////////////////////////////////////////////////////////////////////////
717/// Constructor for variable bin size histograms using an input array of type double.
718///
719/// \param[in] name name of histogram (avoid blanks)
720/// \param[in] title histogram title.
721/// If title is of the form `stringt;stringx;stringy;stringz`
722/// the histogram title is set to `stringt`,
723/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
724/// \param[in] nbins number of bins
725/// \param[in] xbins array of low-edges for each bin.
726/// This is an array of type double and size nbins+1
727
728TH1::TH1(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
729 :TNamed(name,title)
730{
731 Build();
732 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
733 if (xbins) fXaxis.Set(nbins,xbins);
734 else fXaxis.Set(nbins,0,1);
735 fNcells = fXaxis.GetNbins()+2;
736}
737
738////////////////////////////////////////////////////////////////////////////////
739/// Static function: cannot be inlined on Windows/NT.
740
745
746////////////////////////////////////////////////////////////////////////////////
747/// Browse the Histogram object.
748
750{
751 Draw(b ? b->GetDrawOption() : "");
752 gPad->Update();
753}
754
755////////////////////////////////////////////////////////////////////////////////
756/// Creates histogram basic data structure.
757
759{
760 fDirectory = nullptr;
761 fPainter = nullptr;
762 fIntegral = nullptr;
763 fEntries = 0;
764 fNormFactor = 0;
766 fMaximum = -1111;
767 fMinimum = -1111;
768 fBufferSize = 0;
769 fBuffer = nullptr;
772 fXaxis.SetName("xaxis");
773 fYaxis.SetName("yaxis");
774 fZaxis.SetName("zaxis");
775 fYaxis.Set(1,0.,1.);
776 fZaxis.Set(1,0.,1.);
777 fXaxis.SetParent(this);
778 fYaxis.SetParent(this);
779 fZaxis.SetParent(this);
780
782
783 fFunctions = new TList;
784
786
789 if (fDirectory) {
791 fDirectory->Append(this,kTRUE);
792 }
793 }
794}
795
796////////////////////////////////////////////////////////////////////////////////
797/// Performs the operation: `this = this + c1*f1`
798/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
799///
800/// By default, the function is computed at the centre of the bin.
801/// if option "I" is specified (1-d histogram only), the integral of the
802/// function in each bin is used instead of the value of the function at
803/// the centre of the bin.
804///
805/// Only bins inside the function range are recomputed.
806///
807/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
808/// you should call Sumw2 before making this operation.
809/// This is particularly important if you fit the histogram after TH1::Add
810///
811/// The function return kFALSE if the Add operation failed
812
814{
815 if (!f1) {
816 Error("Add","Attempt to add a non-existing function");
817 return kFALSE;
818 }
819
820 TString opt = option;
821 opt.ToLower();
822 Bool_t integral = kFALSE;
823 if (opt.Contains("i") && fDimension == 1) integral = kTRUE;
824
825 Int_t ncellsx = GetNbinsX() + 2; // cells = normal bins + underflow bin + overflow bin
826 Int_t ncellsy = GetNbinsY() + 2;
827 Int_t ncellsz = GetNbinsZ() + 2;
828 if (fDimension < 2) ncellsy = 1;
829 if (fDimension < 3) ncellsz = 1;
830
831 // delete buffer if it is there since it will become invalid
832 if (fBuffer) BufferEmpty(1);
833
834 // - Add statistics
835 Double_t s1[10];
836 for (Int_t i = 0; i < 10; ++i) s1[i] = 0;
837 PutStats(s1);
838 SetMinimum();
839 SetMaximum();
840
841 // - Loop on bins (including underflows/overflows)
842 Int_t bin, binx, biny, binz;
843 Double_t cu=0;
844 Double_t xx[3];
845 Double_t *params = nullptr;
846 f1->InitArgs(xx,params);
847 for (binz = 0; binz < ncellsz; ++binz) {
849 for (biny = 0; biny < ncellsy; ++biny) {
851 for (binx = 0; binx < ncellsx; ++binx) {
853 if (!f1->IsInside(xx)) continue;
855 bin = binx + ncellsx * (biny + ncellsy * binz);
856 if (integral) {
858 } else {
859 cu = c1*f1->EvalPar(xx);
860 }
861 if (TF1::RejectedPoint()) continue;
862 AddBinContent(bin,cu);
863 }
864 }
865 }
866
867 return kTRUE;
868}
869
870int TH1::LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge) const
871{
872 const auto inconsistency = CheckConsistency(h1, h2);
873
875 if (useMerge)
876 Info(name, "Histograms have different dimensions - trying to use TH1::Merge");
877 else {
878 Error(name, "Histograms have different dimensions");
879 }
881 if (useMerge)
882 Info(name, "Histograms have different number of bins - trying to use TH1::Merge");
883 else {
884 Error(name, "Histograms have different number of bins");
885 }
886 } else if (inconsistency & kDifferentAxisLimits) {
887 if (useMerge)
888 Info(name, "Histograms have different axis limits - trying to use TH1::Merge");
889 else
890 Warning(name, "Histograms have different axis limits");
891 } else if (inconsistency & kDifferentBinLimits) {
892 if (useMerge)
893 Info(name, "Histograms have different bin limits - trying to use TH1::Merge");
894 else
895 Warning(name, "Histograms have different bin limits");
896 } else if (inconsistency & kDifferentLabels) {
897 // in case of different labels -
898 if (useMerge)
899 Info(name, "Histograms have different labels - trying to use TH1::Merge");
900 else
901 Info(name, "Histograms have different labels");
902 }
903
904 return inconsistency;
905}
906
907////////////////////////////////////////////////////////////////////////////////
908/// Performs the operation: `this = this + c1*h1`
909/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
910///
911/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
912/// if not already set.
913///
914/// Note also that adding histogram with labels is not supported, histogram will be
915/// added merging them by bin number independently of the labels.
916/// For adding histogram with labels one should use TH1::Merge
917///
918/// SPECIAL CASE (Average/Efficiency histograms)
919/// For histograms representing averages or efficiencies, one should compute the average
920/// of the two histograms and not the sum. One can mark a histogram to be an average
921/// histogram by setting its bit kIsAverage with
922/// myhist.SetBit(TH1::kIsAverage);
923/// Note that the two histograms must have their kIsAverage bit set
924///
925/// IMPORTANT NOTE1: If you intend to use the errors of this histogram later
926/// you should call Sumw2 before making this operation.
927/// This is particularly important if you fit the histogram after TH1::Add
928///
929/// IMPORTANT NOTE2: if h1 has a normalisation factor, the normalisation factor
930/// is used , ie this = this + c1*factor*h1
931/// Use the other TH1::Add function if you do not want this feature
932///
933/// IMPORTANT NOTE3: You should be careful about the statistics of the
934/// returned histogram, whose statistics may be binned or unbinned,
935/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
936/// and whether TH1::ResetStats has been called on either this or h1.
937/// See TH1::GetStats.
938///
939/// The function return kFALSE if the Add operation failed
940
942{
943 if (!h1) {
944 Error("Add","Attempt to add a non-existing histogram");
945 return kFALSE;
946 }
947
948 // delete buffer if it is there since it will become invalid
949 if (fBuffer) BufferEmpty(1);
950
951 bool useMerge = false;
952 const bool considerMerge = (c1 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
953 const auto inconsistency = LoggedInconsistency("Add", this, h1, considerMerge);
954 // If there is a bad inconsistency and we can't even consider merging, just give up
956 return false;
957 }
958 // If there is an inconsistency, we try to use merging
961 }
962
963 if (useMerge) {
964 TList l;
965 l.Add(const_cast<TH1*>(h1));
966 auto iret = Merge(&l);
967 return (iret >= 0);
968 }
969
970 // Create Sumw2 if h1 has Sumw2 set
971 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
972
973 // - Add statistics
974 Double_t entries = TMath::Abs( GetEntries() + c1 * h1->GetEntries() );
975
976 // statistics can be preserved only in case of positive coefficients
977 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
978 Bool_t resetStats = (c1 < 0);
979 Double_t s1[kNstat] = {0};
980 Double_t s2[kNstat] = {0};
981 if (!resetStats) {
982 // need to initialize to zero s1 and s2 since
983 // GetStats fills only used elements depending on dimension and type
984 GetStats(s1);
985 h1->GetStats(s2);
986 }
987
988 SetMinimum();
989 SetMaximum();
990
991 // - Loop on bins (including underflows/overflows)
992 Double_t factor = 1;
993 if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();
994 Double_t c1sq = c1 * c1;
995 Double_t factsq = factor * factor;
996
997 for (Int_t bin = 0; bin < fNcells; ++bin) {
998 //special case where histograms have the kIsAverage bit set
999 if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
1001 Double_t y2 = this->RetrieveBinContent(bin);
1004 Double_t w1 = 1., w2 = 1.;
1005
1006 // consider all special cases when bin errors are zero
1007 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1008 if (e1sq) w1 = 1. / e1sq;
1009 else if (h1->fSumw2.fN) {
1010 w1 = 1.E200; // use an arbitrary huge value
1011 if (y1 == 0) {
1012 // use an estimated error from the global histogram scale
1013 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1014 w1 = 1./(sf*sf);
1015 }
1016 }
1017 if (e2sq) w2 = 1. / e2sq;
1018 else if (fSumw2.fN) {
1019 w2 = 1.E200; // use an arbitrary huge value
1020 if (y2 == 0) {
1021 // use an estimated error from the global histogram scale
1022 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1023 w2 = 1./(sf*sf);
1024 }
1025 }
1026
1027 double y = (w1*y1 + w2*y2)/(w1 + w2);
1028 UpdateBinContent(bin, y);
1029 if (fSumw2.fN) {
1030 double err2 = 1./(w1 + w2);
1031 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1032 fSumw2.fArray[bin] = err2;
1033 }
1034 } else { // normal case of addition between histograms
1035 AddBinContent(bin, c1 * factor * h1->RetrieveBinContent(bin));
1036 if (fSumw2.fN) fSumw2.fArray[bin] += c1sq * factsq * h1->GetBinErrorSqUnchecked(bin);
1037 }
1038 }
1039
1040 // update statistics (do here to avoid changes by SetBinContent)
1041 if (resetStats) {
1042 // statistics need to be reset in case coefficient are negative
1043 ResetStats();
1044 }
1045 else {
1046 for (Int_t i=0;i<kNstat;i++) {
1047 if (i == 1) s1[i] += c1*c1*s2[i];
1048 else s1[i] += c1*s2[i];
1049 }
1050 PutStats(s1);
1051 SetEntries(entries);
1052 }
1053 return kTRUE;
1054}
1055
1056////////////////////////////////////////////////////////////////////////////////
1057/// Replace contents of this histogram by the addition of h1 and h2.
1058///
1059/// `this = c1*h1 + c2*h2`
1060/// if errors are defined (see TH1::Sumw2), errors are also recalculated
1061///
1062/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
1063/// if not already set.
1064///
1065/// Note also that adding histogram with labels is not supported, histogram will be
1066/// added merging them by bin number independently of the labels.
1067/// For adding histogram ith labels one should use TH1::Merge
1068///
1069/// SPECIAL CASE (Average/Efficiency histograms)
1070/// For histograms representing averages or efficiencies, one should compute the average
1071/// of the two histograms and not the sum. One can mark a histogram to be an average
1072/// histogram by setting its bit kIsAverage with
1073/// myhist.SetBit(TH1::kIsAverage);
1074/// Note that the two histograms must have their kIsAverage bit set
1075///
1076/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
1077/// you should call Sumw2 before making this operation.
1078/// This is particularly important if you fit the histogram after TH1::Add
1079///
1080/// IMPORTANT NOTE2: You should be careful about the statistics of the
1081/// returned histogram, whose statistics may be binned or unbinned,
1082/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
1083/// and whether TH1::ResetStats has been called on either this or h1.
1084/// See TH1::GetStats.
1085///
1086/// ANOTHER SPECIAL CASE : h1 = h2 and c2 < 0
1087/// do a scaling this = c1 * h1 / (bin Volume)
1088///
1089/// The function returns kFALSE if the Add operation failed
1090
1092{
1093
1094 if (!h1 || !h2) {
1095 Error("Add","Attempt to add a non-existing histogram");
1096 return kFALSE;
1097 }
1098
1099 // delete buffer if it is there since it will become invalid
1100 if (fBuffer) BufferEmpty(1);
1101
1103 if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
1104
1105 if (h1 != h2) {
1106 bool useMerge = false;
1107 const bool considerMerge = (c1 == 1. && c2 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
1108
1109 // We can combine inconsistencies like this, since they are ordered and a
1110 // higher inconsistency is worse
1111 auto const inconsistency = std::max(LoggedInconsistency("Add", this, h1, considerMerge),
1112 LoggedInconsistency("Add", h1, h2, considerMerge));
1113
1114 // If there is a bad inconsistency and we can't even consider merging, just give up
1116 return false;
1117 }
1118 // If there is an inconsistency, we try to use merging
1121 }
1122
1123 if (useMerge) {
1124 TList l;
1125 // why TList takes non-const pointers ????
1126 l.Add(const_cast<TH1*>(h1));
1127 l.Add(const_cast<TH1*>(h2));
1128 Reset("ICE");
1129 auto iret = Merge(&l);
1130 return (iret >= 0);
1131 }
1132 }
1133
1134 // Create Sumw2 if h1 or h2 have Sumw2 set
1135 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
1136
1137 // - Add statistics
1138 Double_t nEntries = TMath::Abs( c1*h1->GetEntries() + c2*h2->GetEntries() );
1139
1140 // TODO remove
1141 // statistics can be preserved only in case of positive coefficients
1142 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1143 // also in case of scaling with the width we cannot preserve the statistics
1144 Double_t s1[kNstat] = {0};
1145 Double_t s2[kNstat] = {0};
1147
1148
1149 Bool_t resetStats = (c1*c2 < 0) || normWidth;
1150 if (!resetStats) {
1151 // need to initialize to zero s1 and s2 since
1152 // GetStats fills only used elements depending on dimension and type
1153 h1->GetStats(s1);
1154 h2->GetStats(s2);
1155 for (Int_t i=0;i<kNstat;i++) {
1156 if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
1157 //else s3[i] = TMath::Abs(c1)*s1[i] + TMath::Abs(c2)*s2[i];
1158 else s3[i] = c1*s1[i] + c2*s2[i];
1159 }
1160 }
1161
1162 SetMinimum();
1163 SetMaximum();
1164
1165 if (normWidth) { // DEPRECATED CASE: belongs to fitting / drawing modules
1166
1167 Int_t nbinsx = GetNbinsX() + 2; // normal bins + underflow, overflow
1168 Int_t nbinsy = GetNbinsY() + 2;
1169 Int_t nbinsz = GetNbinsZ() + 2;
1170
1171 if (fDimension < 2) nbinsy = 1;
1172 if (fDimension < 3) nbinsz = 1;
1173
1174 Int_t bin, binx, biny, binz;
1175 for (binz = 0; binz < nbinsz; ++binz) {
1177 for (biny = 0; biny < nbinsy; ++biny) {
1179 for (binx = 0; binx < nbinsx; ++binx) {
1181 bin = GetBin(binx, biny, binz);
1182 Double_t w = wx*wy*wz;
1183 UpdateBinContent(bin, c1 * h1->RetrieveBinContent(bin) / w);
1184 if (fSumw2.fN) {
1185 Double_t e1 = h1->GetBinError(bin)/w;
1186 fSumw2.fArray[bin] = c1*c1*e1*e1;
1187 }
1188 }
1189 }
1190 }
1191 } else if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
1192 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
1193 // special case where histograms have the kIsAverage bit set
1195 Double_t y2 = h2->RetrieveBinContent(i);
1197 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
1198 Double_t w1 = 1., w2 = 1.;
1199
1200 // consider all special cases when bin errors are zero
1201 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1202 if (e1sq) w1 = 1./ e1sq;
1203 else if (h1->fSumw2.fN) {
1204 w1 = 1.E200; // use an arbitrary huge value
1205 if (y1 == 0 ) { // use an estimated error from the global histogram scale
1206 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1207 w1 = 1./(sf*sf);
1208 }
1209 }
1210 if (e2sq) w2 = 1./ e2sq;
1211 else if (h2->fSumw2.fN) {
1212 w2 = 1.E200; // use an arbitrary huge value
1213 if (y2 == 0) { // use an estimated error from the global histogram scale
1214 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1215 w2 = 1./(sf*sf);
1216 }
1217 }
1218
1219 double y = (w1*y1 + w2*y2)/(w1 + w2);
1220 UpdateBinContent(i, y);
1221 if (fSumw2.fN) {
1222 double err2 = 1./(w1 + w2);
1223 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1224 fSumw2.fArray[i] = err2;
1225 }
1226 }
1227 } else { // case of simple histogram addition
1228 Double_t c1sq = c1 * c1;
1229 Double_t c2sq = c2 * c2;
1230 for (Int_t i = 0; i < fNcells; ++i) { // Loop on cells (bins including underflows/overflows)
1231 UpdateBinContent(i, c1 * h1->RetrieveBinContent(i) + c2 * h2->RetrieveBinContent(i));
1232 if (fSumw2.fN) {
1233 fSumw2.fArray[i] = c1sq * h1->GetBinErrorSqUnchecked(i) + c2sq * h2->GetBinErrorSqUnchecked(i);
1234 }
1235 }
1236 }
1237
1238 if (resetStats) {
1239 // statistics need to be reset in case coefficient are negative
1240 ResetStats();
1241 }
1242 else {
1243 // update statistics (do here to avoid changes by SetBinContent) FIXME remove???
1244 PutStats(s3);
1246 }
1247
1248 return kTRUE;
1249}
1250
1251////////////////////////////////////////////////////////////////////////////////
1252/// Sets the flag controlling the automatic add of histograms in memory
1253///
1254/// By default (fAddDirectory = kTRUE), histograms are automatically added
1255/// to the list of objects in memory.
1256/// Note that one histogram can be removed from its support directory
1257/// by calling h->SetDirectory(nullptr) or h->SetDirectory(dir) to add it
1258/// to the list of objects in the directory dir.
1259///
1260/// NOTE that this is a static function. To call it, use;
1261/// TH1::AddDirectory
1262
1264{
1265 fgAddDirectory = add;
1266}
1267
1268////////////////////////////////////////////////////////////////////////////////
1269/// Auxiliary function to get the power of 2 next (larger) or previous (smaller)
1270/// a given x
1271///
1272/// next = kTRUE : next larger
1273/// next = kFALSE : previous smaller
1274///
1275/// Used by the autobin power of 2 algorithm
1276
1278{
1279 Int_t nn;
1280 Double_t f2 = std::frexp(x, &nn);
1281 return ((next && x > 0.) || (!next && x <= 0.)) ? std::ldexp(std::copysign(1., f2), nn)
1282 : std::ldexp(std::copysign(1., f2), --nn);
1283}
1284
1285////////////////////////////////////////////////////////////////////////////////
1286/// Auxiliary function to get the next power of 2 integer value larger then n
1287///
1288/// Used by the autobin power of 2 algorithm
1289
1291{
1292 Int_t nn;
1293 Double_t f2 = std::frexp(n, &nn);
1294 if (TMath::Abs(f2 - .5) > 0.001)
1295 return (Int_t)std::ldexp(1., nn);
1296 return n;
1297}
1298
1299////////////////////////////////////////////////////////////////////////////////
1300/// Buffer-based estimate of the histogram range using the power of 2 algorithm.
1301///
1302/// Used by the autobin power of 2 algorithm.
1303///
1304/// Works on arguments (min and max from fBuffer) and internal inputs: fXmin,
1305/// fXmax, NBinsX (from fXaxis), ...
1306/// Result save internally in fXaxis.
1307///
1308/// Overloaded by TH2 and TH3.
1309///
1310/// Return -1 if internal inputs are inconsistent, 0 otherwise.
1311
1313{
1314 // We need meaningful raw limits
1315 if (xmi >= xma)
1316 return -1;
1317
1318 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this, xmi, xma);
1321
1322 // Now adjust
1323 if (TMath::Abs(xhma) > TMath::Abs(xhmi)) {
1324 // Start from the upper limit
1327 } else {
1328 // Start from the lower limit
1331 }
1332
1333 // Round the bins to the next power of 2; take into account the possible inflation
1334 // of the range
1335 Double_t rr = (xhma - xhmi) / (xma - xmi);
1337
1338 // Adjust using the same bin width and offsets
1339 Double_t bw = (xhma - xhmi) / nb;
1340 // Bins to left free on each side
1341 Double_t autoside = gEnv->GetValue("Hist.Binning.Auto.Side", 0.05);
1342 Int_t nbside = (Int_t)(nb * autoside);
1343
1344 // Side up
1345 Int_t nbup = (xhma - xma) / bw;
1346 if (nbup % 2 != 0)
1347 nbup++; // Must be even
1348 if (nbup != nbside) {
1349 // Accounts also for both case: larger or smaller
1350 xhma -= bw * (nbup - nbside);
1351 nb -= (nbup - nbside);
1352 }
1353
1354 // Side low
1355 Int_t nblw = (xmi - xhmi) / bw;
1356 if (nblw % 2 != 0)
1357 nblw++; // Must be even
1358 if (nblw != nbside) {
1359 // Accounts also for both case: larger or smaller
1360 xhmi += bw * (nblw - nbside);
1361 nb -= (nblw - nbside);
1362 }
1363
1364 // Set everything and project
1365 SetBins(nb, xhmi, xhma);
1366
1367 // Done
1368 return 0;
1369}
1370
1371/// Fill histogram with all entries in the buffer.
1372///
1373/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
1374/// - action = 0 histogram is reset and filled from the buffer. When the histogram is filled from the
1375/// buffer the value fBuffer[0] is set to a negative number (= - number of entries)
1376/// When calling with action == 0 the histogram is NOT refilled when fBuffer[0] is < 0
1377/// While when calling with action = -1 the histogram is reset and ALWAYS refilled independently if
1378/// the histogram was filled before. This is needed when drawing the histogram
1379/// - action = 1 histogram is filled and buffer is deleted
1380/// The buffer is automatically deleted when filling the histogram and the entries is
1381/// larger than the buffer size
1382
1384{
1385 // do we need to compute the bin size?
1386 if (!fBuffer) return 0;
1388
1389 // nbentries correspond to the number of entries of histogram
1390
1391 if (nbentries == 0) {
1392 // if action is 1 we delete the buffer
1393 // this will avoid infinite recursion
1394 if (action > 0) {
1395 delete [] fBuffer;
1396 fBuffer = nullptr;
1397 fBufferSize = 0;
1398 }
1399 return 0;
1400 }
1401 if (nbentries < 0 && action == 0) return 0; // case histogram has been already filled from the buffer
1402
1403 Double_t *buffer = fBuffer;
1404 if (nbentries < 0) {
1406 // a reset might call BufferEmpty() giving an infinite recursion
1407 // Protect it by setting fBuffer = nullptr
1408 fBuffer = nullptr;
1409 //do not reset the list of functions
1410 Reset("ICES");
1411 fBuffer = buffer;
1412 }
1413 if (CanExtendAllAxes() || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
1414 //find min, max of entries in buffer
1417 for (Int_t i=0;i<nbentries;i++) {
1418 Double_t x = fBuffer[2*i+2];
1419 // skip infinity or NaN values
1420 if (!std::isfinite(x)) continue;
1421 if (x < xmin) xmin = x;
1422 if (x > xmax) xmax = x;
1423 }
1424 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
1425 Int_t rc = -1;
1427 if ((rc = AutoP2FindLimits(xmin, xmax)) < 0)
1428 Warning("BufferEmpty",
1429 "inconsistency found by power-of-2 autobin algorithm: fallback to standard method");
1430 }
1431 if (rc < 0)
1432 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this, xmin, xmax);
1433 } else {
1434 fBuffer = nullptr;
1437 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax, &fXaxis);
1438 fBuffer = buffer;
1439 fBufferSize = keep;
1440 }
1441 }
1442
1443 // call DoFillN which will not put entries in the buffer as FillN does
1444 // set fBuffer to zero to avoid re-emptying the buffer from functions called
1445 // by DoFillN (e.g Sumw2)
1446 buffer = fBuffer; fBuffer = nullptr;
1447 DoFillN(nbentries,&buffer[2],&buffer[1],2);
1448 fBuffer = buffer;
1449
1450 // if action == 1 - delete the buffer
1451 if (action > 0) {
1452 delete [] fBuffer;
1453 fBuffer = nullptr;
1454 fBufferSize = 0;
1455 } else {
1456 // if number of entries is consistent with buffer - set it negative to avoid
1457 // refilling the histogram every time BufferEmpty(0) is called
1458 // In case it is not consistent, by setting fBuffer[0]=0 is like resetting the buffer
1459 // (it will not be used anymore the next time BufferEmpty is called)
1460 if (nbentries == (Int_t)fEntries)
1461 fBuffer[0] = -nbentries;
1462 else
1463 fBuffer[0] = 0;
1464 }
1465 return nbentries;
1466}
1467
1468////////////////////////////////////////////////////////////////////////////////
1469/// accumulate arguments in buffer. When buffer is full, empty the buffer
1470///
1471/// - `fBuffer[0]` = number of entries in buffer
1472/// - `fBuffer[1]` = w of first entry
1473/// - `fBuffer[2]` = x of first entry
1474
1476{
1477 if (!fBuffer) return -2;
1479
1480
1481 if (nbentries < 0) {
1482 // reset nbentries to a positive value so next time BufferEmpty() is called
1483 // the histogram will be refilled
1485 fBuffer[0] = nbentries;
1486 if (fEntries > 0) {
1487 // set fBuffer to zero to avoid calling BufferEmpty in Reset
1488 Double_t *buffer = fBuffer; fBuffer=nullptr;
1489 Reset("ICES"); // do not reset list of functions
1490 fBuffer = buffer;
1491 }
1492 }
1493 if (2*nbentries+2 >= fBufferSize) {
1494 BufferEmpty(1);
1495 if (!fBuffer)
1496 // to avoid infinite recursion Fill->BufferFill->Fill
1497 return Fill(x,w);
1498 // this cannot happen
1499 R__ASSERT(0);
1500 }
1501 fBuffer[2*nbentries+1] = w;
1502 fBuffer[2*nbentries+2] = x;
1503 fBuffer[0] += 1;
1504 return -2;
1505}
1506
1507////////////////////////////////////////////////////////////////////////////////
1508/// Check bin limits.
1509
1510bool TH1::CheckBinLimits(const TAxis* a1, const TAxis * a2)
1511{
1512 const TArrayD * h1Array = a1->GetXbins();
1513 const TArrayD * h2Array = a2->GetXbins();
1514 Int_t fN = h1Array->fN;
1515 if ( fN != 0 ) {
1516 if ( h2Array->fN != fN ) {
1517 return false;
1518 }
1519 else {
1520 for ( int i = 0; i < fN; ++i ) {
1521 // for i==fN (nbin+1) a->GetBinWidth() returns last bin width
1522 // we do not need to exclude that case
1523 double binWidth = a1->GetBinWidth(i);
1524 if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), binWidth*1E-10 ) ) {
1525 return false;
1526 }
1527 }
1528 }
1529 }
1530
1531 return true;
1532}
1533
1534////////////////////////////////////////////////////////////////////////////////
1535/// Check that axis have same labels.
1536
1537bool TH1::CheckBinLabels(const TAxis* a1, const TAxis * a2)
1538{
1539 THashList *l1 = a1->GetLabels();
1540 THashList *l2 = a2->GetLabels();
1541
1542 if (!l1 && !l2 )
1543 return true;
1544 if (!l1 || !l2 ) {
1545 return false;
1546 }
1547 // check now labels sizes are the same
1548 if (l1->GetSize() != l2->GetSize() ) {
1549 return false;
1550 }
1551 for (int i = 1; i <= a1->GetNbins(); ++i) {
1552 TString label1 = a1->GetBinLabel(i);
1553 TString label2 = a2->GetBinLabel(i);
1554 if (label1 != label2) {
1555 return false;
1556 }
1557 }
1558
1559 return true;
1560}
1561
1562////////////////////////////////////////////////////////////////////////////////
1563/// Check that the axis limits of the histograms are the same.
1564/// If a first and last bin is passed the axis is compared between the given range
1565
1566bool TH1::CheckAxisLimits(const TAxis *a1, const TAxis *a2 )
1567{
1568 double firstBin = a1->GetBinWidth(1);
1569 double lastBin = a1->GetBinWidth( a1->GetNbins() );
1570 if ( ! TMath::AreEqualAbs(a1->GetXmin(), a2->GetXmin(), firstBin* 1.E-10) ||
1571 ! TMath::AreEqualAbs(a1->GetXmax(), a2->GetXmax(), lastBin*1.E-10) ) {
1572 return false;
1573 }
1574 return true;
1575}
1576
1577////////////////////////////////////////////////////////////////////////////////
1578/// Check that the axis are the same
1579
1580bool TH1::CheckEqualAxes(const TAxis *a1, const TAxis *a2 )
1581{
1582 if (a1->GetNbins() != a2->GetNbins() ) {
1583 ::Info("CheckEqualAxes","Axes have different number of bins : nbin1 = %d nbin2 = %d",a1->GetNbins(),a2->GetNbins() );
1584 return false;
1585 }
1586 if(!CheckAxisLimits(a1,a2)) {
1587 ::Info("CheckEqualAxes","Axes have different limits");
1588 return false;
1589 }
1590 if(!CheckBinLimits(a1,a2)) {
1591 ::Info("CheckEqualAxes","Axes have different bin limits");
1592 return false;
1593 }
1594
1595 // check labels
1596 if(!CheckBinLabels(a1,a2)) {
1597 ::Info("CheckEqualAxes","Axes have different labels");
1598 return false;
1599 }
1600
1601 return true;
1602}
1603
1604////////////////////////////////////////////////////////////////////////////////
1605/// Check that two sub axis are the same.
1606/// The limits are defined by first bin and last bin
1607/// N.B. no check is done in this case for variable bins
1608
1610{
1611 // By default is assumed that no bins are given for the second axis
1613 Double_t xmin1 = a1->GetBinLowEdge(firstBin1);
1614 Double_t xmax1 = a1->GetBinUpEdge(lastBin1);
1615
1616 Int_t nbins2 = a2->GetNbins();
1617 Double_t xmin2 = a2->GetXmin();
1618 Double_t xmax2 = a2->GetXmax();
1619
1620 if (firstBin2 < lastBin2) {
1621 // in this case assume no bins are given for the second axis
1623 xmin2 = a1->GetBinLowEdge(firstBin1);
1624 xmax2 = a1->GetBinUpEdge(lastBin1);
1625 }
1626
1627 if (nbins1 != nbins2 ) {
1628 ::Info("CheckConsistentSubAxes","Axes have different number of bins");
1629 return false;
1630 }
1631
1632 Double_t firstBin = a1->GetBinWidth(firstBin1);
1633 Double_t lastBin = a1->GetBinWidth(lastBin1);
1634 if ( ! TMath::AreEqualAbs(xmin1,xmin2,1.E-10 * firstBin) ||
1635 ! TMath::AreEqualAbs(xmax1,xmax2,1.E-10 * lastBin) ) {
1636 ::Info("CheckConsistentSubAxes","Axes have different limits");
1637 return false;
1638 }
1639
1640 return true;
1641}
1642
1643////////////////////////////////////////////////////////////////////////////////
1644/// Check histogram compatibility.
1645/// The returned integer is part of EInconsistencyBits
1646/// The value 0 means that the histograms are compatible
1647
1649{
1650 if (h1 == h2) return kFullyConsistent;
1651
1652 if (h1->GetDimension() != h2->GetDimension() ) {
1653 return kDifferentDimensions;
1654 }
1655 Int_t dim = h1->GetDimension();
1656
1657 // returns kTRUE if number of bins and bin limits are identical
1658 Int_t nbinsx = h1->GetNbinsX();
1659 Int_t nbinsy = h1->GetNbinsY();
1660 Int_t nbinsz = h1->GetNbinsZ();
1661
1662 // Check whether the histograms have the same number of bins.
1663 if (nbinsx != h2->GetNbinsX() ||
1664 (dim > 1 && nbinsy != h2->GetNbinsY()) ||
1665 (dim > 2 && nbinsz != h2->GetNbinsZ()) ) {
1667 }
1668
1669 bool ret = true;
1670
1671 // check axis limits
1672 ret &= CheckAxisLimits(h1->GetXaxis(), h2->GetXaxis());
1673 if (dim > 1) ret &= CheckAxisLimits(h1->GetYaxis(), h2->GetYaxis());
1674 if (dim > 2) ret &= CheckAxisLimits(h1->GetZaxis(), h2->GetZaxis());
1675 if (!ret) return kDifferentAxisLimits;
1676
1677 // check bin limits
1678 ret &= CheckBinLimits(h1->GetXaxis(), h2->GetXaxis());
1679 if (dim > 1) ret &= CheckBinLimits(h1->GetYaxis(), h2->GetYaxis());
1680 if (dim > 2) ret &= CheckBinLimits(h1->GetZaxis(), h2->GetZaxis());
1681 if (!ret) return kDifferentBinLimits;
1682
1683 // check labels if histograms are both not empty
1684 if ( !h1->IsEmpty() && !h2->IsEmpty() ) {
1685 ret &= CheckBinLabels(h1->GetXaxis(), h2->GetXaxis());
1686 if (dim > 1) ret &= CheckBinLabels(h1->GetYaxis(), h2->GetYaxis());
1687 if (dim > 2) ret &= CheckBinLabels(h1->GetZaxis(), h2->GetZaxis());
1688 if (!ret) return kDifferentLabels;
1689 }
1690
1691 return kFullyConsistent;
1692}
1693
1694////////////////////////////////////////////////////////////////////////////////
1695/// \f$ \chi^{2} \f$ test for comparing weighted and unweighted histograms.
1696///
1697/// Compares the histograms' adjusted (normalized) residuals.
1698/// Function: Returns p-value. Other return values are specified by the 3rd parameter
1699///
1700/// \param[in] h2 the second histogram
1701/// \param[in] option
1702/// - "UU" = experiment experiment comparison (unweighted-unweighted)
1703/// - "UW" = experiment MC comparison (unweighted-weighted). Note that
1704/// the first histogram should be unweighted
1705/// - "WW" = MC MC comparison (weighted-weighted)
1706/// - "NORM" = to be used when one or both of the histograms is scaled
1707/// but the histogram originally was unweighted
1708/// - by default underflows and overflows are not included:
1709/// * "OF" = overflows included
1710/// * "UF" = underflows included
1711/// - "P" = print chi2, ndf, p_value, igood
1712/// - "CHI2" = returns chi2 instead of p-value
1713/// - "CHI2/NDF" = returns \f$ \chi^{2} \f$/ndf
1714/// \param[in] res not empty - computes normalized residuals and returns them in this array
1715///
1716/// The current implementation is based on the papers \f$ \chi^{2} \f$ test for comparison
1717/// of weighted and unweighted histograms" in Proceedings of PHYSTAT05 and
1718/// "Comparison weighted and unweighted histograms", arXiv:physics/0605123
1719/// by N.Gagunashvili. This function has been implemented by Daniel Haertl in August 2006.
1720///
1721/// #### Introduction:
1722///
1723/// A frequently used technique in data analysis is the comparison of
1724/// histograms. First suggested by Pearson [1] the \f$ \chi^{2} \f$ test of
1725/// homogeneity is used widely for comparing usual (unweighted) histograms.
1726/// This paper describes the implementation modified \f$ \chi^{2} \f$ tests
1727/// for comparison of weighted and unweighted histograms and two weighted
1728/// histograms [2] as well as usual Pearson's \f$ \chi^{2} \f$ test for
1729/// comparison two usual (unweighted) histograms.
1730///
1731/// #### Overview:
1732///
1733/// Comparison of two histograms expect hypotheses that two histograms
1734/// represent identical distributions. To make a decision p-value should
1735/// be calculated. The hypotheses of identity is rejected if the p-value is
1736/// lower then some significance level. Traditionally significance levels
1737/// 0.1, 0.05 and 0.01 are used. The comparison procedure should include an
1738/// analysis of the residuals which is often helpful in identifying the
1739/// bins of histograms responsible for a significant overall \f$ \chi^{2} \f$ value.
1740/// Residuals are the difference between bin contents and expected bin
1741/// contents. Most convenient for analysis are the normalized residuals. If
1742/// hypotheses of identity are valid then normalized residuals are
1743/// approximately independent and identically distributed random variables
1744/// having N(0,1) distribution. Analysis of residuals expect test of above
1745/// mentioned properties of residuals. Notice that indirectly the analysis
1746/// of residuals increase the power of \f$ \chi^{2} \f$ test.
1747///
1748/// #### Methods of comparison:
1749///
1750/// \f$ \chi^{2} \f$ test for comparison two (unweighted) histograms:
1751/// Let us consider two histograms with the same binning and the number
1752/// of bins equal to r. Let us denote the number of events in the ith bin
1753/// in the first histogram as ni and as mi in the second one. The total
1754/// number of events in the first histogram is equal to:
1755/// \f[
1756/// N = \sum_{i=1}^{r} n_{i}
1757/// \f]
1758/// and
1759/// \f[
1760/// M = \sum_{i=1}^{r} m_{i}
1761/// \f]
1762/// in the second histogram. The hypothesis of identity (homogeneity) [3]
1763/// is that the two histograms represent random values with identical
1764/// distributions. It is equivalent that there exist r constants p1,...,pr,
1765/// such that
1766/// \f[
1767///\sum_{i=1}^{r} p_{i}=1
1768/// \f]
1769/// and the probability of belonging to the ith bin for some measured value
1770/// in both experiments is equal to pi. The number of events in the ith
1771/// bin is a random variable with a distribution approximated by a Poisson
1772/// probability distribution
1773/// \f[
1774///\frac{e^{-Np_{i}}(Np_{i})^{n_{i}}}{n_{i}!}
1775/// \f]
1776///for the first histogram and with distribution
1777/// \f[
1778///\frac{e^{-Mp_{i}}(Mp_{i})^{m_{i}}}{m_{i}!}
1779/// \f]
1780/// for the second histogram. If the hypothesis of homogeneity is valid,
1781/// then the maximum likelihood estimator of pi, i=1,...,r, is
1782/// \f[
1783///\hat{p}_{i}= \frac{n_{i}+m_{i}}{N+M}
1784/// \f]
1785/// and then
1786/// \f[
1787/// 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}}
1788/// \f]
1789/// has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [3].
1790/// The comparison procedure can include an analysis of the residuals which
1791/// is often helpful in identifying the bins of histograms responsible for
1792/// a significant overall \f$ \chi^{2} \f$ value. Most convenient for
1793/// analysis are the adjusted (normalized) residuals [4]
1794/// \f[
1795/// 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))}}
1796/// \f]
1797/// If hypotheses of homogeneity are valid then residuals ri are
1798/// approximately independent and identically distributed random variables
1799/// having N(0,1) distribution. The application of the \f$ \chi^{2} \f$ test has
1800/// restrictions related to the value of the expected frequencies Npi,
1801/// Mpi, i=1,...,r. A conservative rule formulated in [5] is that all the
1802/// expectations must be 1 or greater for both histograms. In practical
1803/// cases when expected frequencies are not known the estimated expected
1804/// frequencies \f$ M\hat{p}_{i}, N\hat{p}_{i}, i=1,...,r \f$ can be used.
1805///
1806/// #### Unweighted and weighted histograms comparison:
1807///
1808/// A simple modification of the ideas described above can be used for the
1809/// comparison of the usual (unweighted) and weighted histograms. Let us
1810/// denote the number of events in the ith bin in the unweighted
1811/// histogram as ni and the common weight of events in the ith bin of the
1812/// weighted histogram as wi. The total number of events in the
1813/// unweighted histogram is equal to
1814///\f[
1815/// N = \sum_{i=1}^{r} n_{i}
1816///\f]
1817/// and the total weight of events in the weighted histogram is equal to
1818///\f[
1819/// W = \sum_{i=1}^{r} w_{i}
1820///\f]
1821/// Let us formulate the hypothesis of identity of an unweighted histogram
1822/// to a weighted histogram so that there exist r constants p1,...,pr, such
1823/// that
1824///\f[
1825/// \sum_{i=1}^{r} p_{i} = 1
1826///\f]
1827/// for the unweighted histogram. The weight wi is a random variable with a
1828/// distribution approximated by the normal probability distribution
1829/// \f$ N(Wp_{i},\sigma_{i}^{2}) \f$ where \f$ \sigma_{i}^{2} \f$ is the variance of the weight wi.
1830/// If we replace the variance \f$ \sigma_{i}^{2} \f$
1831/// with estimate \f$ s_{i}^{2} \f$ (sum of squares of weights of
1832/// events in the ith bin) and the hypothesis of identity is valid, then the
1833/// maximum likelihood estimator of pi,i=1,...,r, is
1834///\f[
1835/// \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}}
1836///\f]
1837/// We may then use the test statistic
1838///\f[
1839/// 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}}
1840///\f]
1841/// and it has approximately a \f$ \sigma^{2}_{(r-1)} \f$ distribution [2]. This test, as well
1842/// as the original one [3], has a restriction on the expected frequencies. The
1843/// expected frequencies recommended for the weighted histogram is more than 25.
1844/// The value of the minimal expected frequency can be decreased down to 10 for
1845/// the case when the weights of the events are close to constant. In the case
1846/// of a weighted histogram if the number of events is unknown, then we can
1847/// apply this recommendation for the equivalent number of events as
1848///\f[
1849/// n_{i}^{equiv} = \frac{ w_{i}^{2} }{ s_{i}^{2} }
1850///\f]
1851/// The minimal expected frequency for an unweighted histogram must be 1. Notice
1852/// that any usual (unweighted) histogram can be considered as a weighted
1853/// histogram with events that have constant weights equal to 1.
1854/// The variance \f$ z_{i}^{2} \f$ of the difference between the weight wi
1855/// and the estimated expectation value of the weight is approximately equal to:
1856///\f[
1857/// 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}
1858///\f]
1859/// The residuals
1860///\f[
1861/// r_{i} = \frac{w_{i}-W\hat{p}_{i}}{z_{i}}
1862///\f]
1863/// have approximately a normal distribution with mean equal to 0 and standard
1864/// deviation equal to 1.
1865///
1866/// #### Two weighted histograms comparison:
1867///
1868/// Let us denote the common weight of events of the ith bin in the first
1869/// histogram as w1i and as w2i in the second one. The total weight of events
1870/// in the first histogram is equal to
1871///\f[
1872/// W_{1} = \sum_{i=1}^{r} w_{1i}
1873///\f]
1874/// and
1875///\f[
1876/// W_{2} = \sum_{i=1}^{r} w_{2i}
1877///\f]
1878/// in the second histogram. Let us formulate the hypothesis of identity of
1879/// weighted histograms so that there exist r constants p1,...,pr, such that
1880///\f[
1881/// \sum_{i=1}^{r} p_{i} = 1
1882///\f]
1883/// and also expectation value of weight w1i equal to W1pi and expectation value
1884/// of weight w2i equal to W2pi. Weights in both the histograms are random
1885/// variables with distributions which can be approximated by a normal
1886/// probability distribution \f$ N(W_{1}p_{i},\sigma_{1i}^{2}) \f$ for the first histogram
1887/// and by a distribution \f$ N(W_{2}p_{i},\sigma_{2i}^{2}) \f$ for the second.
1888/// Here \f$ \sigma_{1i}^{2} \f$ and \f$ \sigma_{2i}^{2} \f$ are the variances
1889/// of w1i and w2i with estimators \f$ s_{1i}^{2} \f$ and \f$ s_{2i}^{2} \f$ respectively.
1890/// If the hypothesis of identity is valid, then the maximum likelihood and
1891/// Least Square Method estimator of pi,i=1,...,r, is
1892///\f[
1893/// \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}}
1894///\f]
1895/// We may then use the test statistic
1896///\f[
1897/// 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}}
1898///\f]
1899/// and it has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [2].
1900/// The normalized or studentised residuals [6]
1901///\f[
1902/// 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})}}}
1903///\f]
1904/// have approximately a normal distribution with mean equal to 0 and standard
1905/// deviation 1. A recommended minimal expected frequency is equal to 10 for
1906/// the proposed test.
1907///
1908/// #### Numerical examples:
1909///
1910/// The method described herein is now illustrated with an example.
1911/// We take a distribution
1912///\f[
1913/// \phi(x) = \frac{2}{(x-10)^{2}+1} + \frac{1}{(x-14)^{2}+1} (1)
1914///\f]
1915/// defined on the interval [4,16]. Events distributed according to the formula
1916/// (1) are simulated to create the unweighted histogram. Uniformly distributed
1917/// events are simulated for the weighted histogram with weights calculated by
1918/// formula (1). Each histogram has the same number of bins: 20. Fig.1 shows
1919/// the result of comparison of the unweighted histogram with 200 events
1920/// (minimal expected frequency equal to one) and the weighted histogram with
1921/// 500 events (minimal expected frequency equal to 25)
1922/// Begin_Macro
1923/// ../../../tutorials/math/chi2test.C
1924/// End_Macro
1925/// Fig 1. An example of comparison of the unweighted histogram with 200 events
1926/// and the weighted histogram with 500 events:
1927/// 1. unweighted histogram;
1928/// 2. weighted histogram;
1929/// 3. normalized residuals plot;
1930/// 4. normal Q-Q plot of residuals.
1931///
1932/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1933/// 21.09 with p-value equal to 0.33, therefore the hypothesis of identity of
1934/// the two histograms can be accepted for 0.05 significant level. The behavior
1935/// of the normalized residuals plot (see Fig. 1c) and the normal Q-Q plot
1936/// (see Fig. 1d) of residuals are regular and we cannot identify the outliers
1937/// or bins with a big influence on \f$ \chi^{2} \f$.
1938///
1939/// The second example presents the same two histograms but 17 events was added
1940/// to content of bin number 15 in unweighted histogram. Fig.2 shows the result
1941/// of comparison of the unweighted histogram with 217 events (minimal expected
1942/// frequency equal to one) and the weighted histogram with 500 events (minimal
1943/// expected frequency equal to 25)
1944/// Begin_Macro
1945/// ../../../tutorials/math/chi2test.C(17)
1946/// End_Macro
1947/// Fig 2. An example of comparison of the unweighted histogram with 217 events
1948/// and the weighted histogram with 500 events:
1949/// 1. unweighted histogram;
1950/// 2. weighted histogram;
1951/// 3. normalized residuals plot;
1952/// 4. normal Q-Q plot of residuals.
1953///
1954/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1955/// 32.33 with p-value equal to 0.029, therefore the hypothesis of identity of
1956/// the two histograms is rejected for 0.05 significant level. The behavior of
1957/// the normalized residuals plot (see Fig. 2c) and the normal Q-Q plot (see
1958/// Fig. 2d) of residuals are not regular and we can identify the outlier or
1959/// bin with a big influence on \f$ \chi^{2} \f$.
1960///
1961/// #### References:
1962///
1963/// - [1] Pearson, K., 1904. On the Theory of Contingency and Its Relation to
1964/// Association and Normal Correlation. Drapers' Co. Memoirs, Biometric
1965/// Series No. 1, London.
1966/// - [2] Gagunashvili, N., 2006. \f$ \sigma^{2} \f$ test for comparison
1967/// of weighted and unweighted histograms. Statistical Problems in Particle
1968/// Physics, Astrophysics and Cosmology, Proceedings of PHYSTAT05,
1969/// Oxford, UK, 12-15 September 2005, Imperial College Press, London, 43-44.
1970/// Gagunashvili,N., Comparison of weighted and unweighted histograms,
1971/// arXiv:physics/0605123, 2006.
1972/// - [3] Cramer, H., 1946. Mathematical methods of statistics.
1973/// Princeton University Press, Princeton.
1974/// - [4] Haberman, S.J., 1973. The analysis of residuals in cross-classified tables.
1975/// Biometrics 29, 205-220.
1976/// - [5] Lewontin, R.C. and Felsenstein, J., 1965. The robustness of homogeneity
1977/// test in 2xN tables. Biometrics 21, 19-33.
1978/// - [6] Seber, G.A.F., Lee, A.J., 2003, Linear Regression Analysis.
1979/// John Wiley & Sons Inc., New York.
1980
1981Double_t TH1::Chi2Test(const TH1* h2, Option_t *option, Double_t *res) const
1982{
1983 Double_t chi2 = 0;
1984 Int_t ndf = 0, igood = 0;
1985
1986 TString opt = option;
1987 opt.ToUpper();
1988
1990
1991 if(opt.Contains("P")) {
1992 printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
1993 }
1994 if(opt.Contains("CHI2/NDF")) {
1995 if (ndf == 0) return 0;
1996 return chi2/ndf;
1997 }
1998 if(opt.Contains("CHI2")) {
1999 return chi2;
2000 }
2001
2002 return prob;
2003}
2004
2005////////////////////////////////////////////////////////////////////////////////
2006/// The computation routine of the Chisquare test. For the method description,
2007/// see Chi2Test() function.
2008///
2009/// \return p-value
2010/// \param[in] h2 the second histogram
2011/// \param[in] option
2012/// - "UU" = experiment experiment comparison (unweighted-unweighted)
2013/// - "UW" = experiment MC comparison (unweighted-weighted). Note that the first
2014/// histogram should be unweighted
2015/// - "WW" = MC MC comparison (weighted-weighted)
2016/// - "NORM" = if one or both histograms is scaled
2017/// - "OF" = overflows included
2018/// - "UF" = underflows included
2019/// by default underflows and overflows are not included
2020/// \param[out] igood test output
2021/// - igood=0 - no problems
2022/// - For unweighted unweighted comparison
2023/// - igood=1'There is a bin in the 1st histogram with less than 1 event'
2024/// - igood=2'There is a bin in the 2nd histogram with less than 1 event'
2025/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2026/// - For unweighted weighted comparison
2027/// - igood=1'There is a bin in the 1st histogram with less then 1 event'
2028/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective number of events'
2029/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2030/// - For weighted weighted comparison
2031/// - igood=1'There is a bin in the 1st histogram with less then 10 effective
2032/// number of events'
2033/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective
2034/// number of events'
2035/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2036/// \param[out] chi2 chisquare of the test
2037/// \param[out] ndf number of degrees of freedom (important, when both histograms have the same empty bins)
2038/// \param[out] res normalized residuals for further analysis
2039
2041{
2042
2046
2047 Double_t sum1 = 0.0, sumw1 = 0.0;
2048 Double_t sum2 = 0.0, sumw2 = 0.0;
2049
2050 chi2 = 0.0;
2051 ndf = 0;
2052
2053 TString opt = option;
2054 opt.ToUpper();
2055
2056 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
2057
2058 const TAxis *xaxis1 = GetXaxis();
2059 const TAxis *xaxis2 = h2->GetXaxis();
2060 const TAxis *yaxis1 = GetYaxis();
2061 const TAxis *yaxis2 = h2->GetYaxis();
2062 const TAxis *zaxis1 = GetZaxis();
2063 const TAxis *zaxis2 = h2->GetZaxis();
2064
2065 Int_t nbinx1 = xaxis1->GetNbins();
2066 Int_t nbinx2 = xaxis2->GetNbins();
2067 Int_t nbiny1 = yaxis1->GetNbins();
2068 Int_t nbiny2 = yaxis2->GetNbins();
2069 Int_t nbinz1 = zaxis1->GetNbins();
2070 Int_t nbinz2 = zaxis2->GetNbins();
2071
2072 //check dimensions
2073 if (this->GetDimension() != h2->GetDimension() ){
2074 Error("Chi2TestX","Histograms have different dimensions.");
2075 return 0.0;
2076 }
2077
2078 //check number of channels
2079 if (nbinx1 != nbinx2) {
2080 Error("Chi2TestX","different number of x channels");
2081 }
2082 if (nbiny1 != nbiny2) {
2083 Error("Chi2TestX","different number of y channels");
2084 }
2085 if (nbinz1 != nbinz2) {
2086 Error("Chi2TestX","different number of z channels");
2087 }
2088
2089 //check for ranges
2090 i_start = j_start = k_start = 1;
2091 i_end = nbinx1;
2092 j_end = nbiny1;
2093 k_end = nbinz1;
2094
2095 if (xaxis1->TestBit(TAxis::kAxisRange)) {
2096 i_start = xaxis1->GetFirst();
2097 i_end = xaxis1->GetLast();
2098 }
2099 if (yaxis1->TestBit(TAxis::kAxisRange)) {
2100 j_start = yaxis1->GetFirst();
2101 j_end = yaxis1->GetLast();
2102 }
2103 if (zaxis1->TestBit(TAxis::kAxisRange)) {
2104 k_start = zaxis1->GetFirst();
2105 k_end = zaxis1->GetLast();
2106 }
2107
2108
2109 if (opt.Contains("OF")) {
2110 if (GetDimension() == 3) k_end = ++nbinz1;
2111 if (GetDimension() >= 2) j_end = ++nbiny1;
2112 if (GetDimension() >= 1) i_end = ++nbinx1;
2113 }
2114
2115 if (opt.Contains("UF")) {
2116 if (GetDimension() == 3) k_start = 0;
2117 if (GetDimension() >= 2) j_start = 0;
2118 if (GetDimension() >= 1) i_start = 0;
2119 }
2120
2121 ndf = (i_end - i_start + 1) * (j_end - j_start + 1) * (k_end - k_start + 1) - 1;
2122
2123 Bool_t comparisonUU = opt.Contains("UU");
2124 Bool_t comparisonUW = opt.Contains("UW");
2125 Bool_t comparisonWW = opt.Contains("WW");
2126 Bool_t scaledHistogram = opt.Contains("NORM");
2127
2128 if (scaledHistogram && !comparisonUU) {
2129 Info("Chi2TestX", "NORM option should be used together with UU option. It is ignored");
2130 }
2131
2132 // look at histo global bin content and effective entries
2133 Stat_t s[kNstat];
2134 GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2135 Double_t sumBinContent1 = s[0];
2136 Double_t effEntries1 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2137
2138 h2->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2139 Double_t sumBinContent2 = s[0];
2140 Double_t effEntries2 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2141
2142 if (!comparisonUU && !comparisonUW && !comparisonWW ) {
2143 // deduce automatically from type of histogram
2146 else comparisonUW = true;
2147 }
2148 else comparisonWW = true;
2149 }
2150 // check unweighted histogram
2151 if (comparisonUW) {
2153 Warning("Chi2TestX","First histogram is not unweighted and option UW has been requested");
2154 }
2155 }
2156 if ( (!scaledHistogram && comparisonUU) ) {
2158 Warning("Chi2TestX","Both histograms are not unweighted and option UU has been requested");
2159 }
2160 }
2161
2162
2163 //get number of events in histogram
2165 for (Int_t i = i_start; i <= i_end; ++i) {
2166 for (Int_t j = j_start; j <= j_end; ++j) {
2167 for (Int_t k = k_start; k <= k_end; ++k) {
2168
2169 Int_t bin = GetBin(i, j, k);
2170
2172 Double_t cnt2 = h2->RetrieveBinContent(bin);
2174 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2175
2176 if (e1sq > 0.0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2177 else cnt1 = 0.0;
2178
2179 if (e2sq > 0.0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2180 else cnt2 = 0.0;
2181
2182 // sum contents
2183 sum1 += cnt1;
2184 sum2 += cnt2;
2185 sumw1 += e1sq;
2186 sumw2 += e2sq;
2187 }
2188 }
2189 }
2190 if (sumw1 <= 0.0 || sumw2 <= 0.0) {
2191 Error("Chi2TestX", "Cannot use option NORM when one histogram has all zero errors");
2192 return 0.0;
2193 }
2194
2195 } else {
2196 for (Int_t i = i_start; i <= i_end; ++i) {
2197 for (Int_t j = j_start; j <= j_end; ++j) {
2198 for (Int_t k = k_start; k <= k_end; ++k) {
2199
2200 Int_t bin = GetBin(i, j, k);
2201
2202 sum1 += RetrieveBinContent(bin);
2203 sum2 += h2->RetrieveBinContent(bin);
2204
2206 if ( comparisonUW || comparisonWW ) sumw2 += h2->GetBinErrorSqUnchecked(bin);
2207 }
2208 }
2209 }
2210 }
2211 //checks that the histograms are not empty
2212 if (sum1 == 0.0 || sum2 == 0.0) {
2213 Error("Chi2TestX","one histogram is empty");
2214 return 0.0;
2215 }
2216
2217 if ( comparisonWW && ( sumw1 <= 0.0 && sumw2 <= 0.0 ) ){
2218 Error("Chi2TestX","Hist1 and Hist2 have both all zero errors\n");
2219 return 0.0;
2220 }
2221
2222 //THE TEST
2223 Int_t m = 0, n = 0;
2224 //Experiment - experiment comparison
2225 if (comparisonUU) {
2226 Int_t resIndex = 0;
2227 Double_t sum = sum1 + sum2;
2228 for (Int_t i = i_start; i <= i_end; ++i) {
2229 for (Int_t j = j_start; j <= j_end; ++j) {
2230 for (Int_t k = k_start; k <= k_end; ++k) {
2231
2232 Int_t bin = GetBin(i, j, k);
2233
2235 Double_t cnt2 = h2->RetrieveBinContent(bin);
2236
2237 if (scaledHistogram) {
2238 // scale bin value to effective bin entries
2240 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2241
2242 if (e1sq > 0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2243 else cnt1 = 0;
2244
2245 if (e2sq > 0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2246 else cnt2 = 0;
2247 }
2248
2249 if (Int_t(cnt1) == 0 && Int_t(cnt2) == 0) --ndf; // no data means one degree of freedom less
2250 else {
2251
2254 //Double_t nexp2 = binsum*sum2/sum;
2255
2256 if (res) res[resIndex] = (cnt1 - nexp1) / TMath::Sqrt(nexp1);
2257
2258 if (cnt1 < 1) ++m;
2259 if (cnt2 < 1) ++n;
2260
2261 //Habermann correction for residuals
2262 Double_t correc = (1. - sum1 / sum) * (1. - cntsum / sum);
2263 if (res) res[resIndex] /= TMath::Sqrt(correc);
2264 if (res) resIndex++;
2265 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2266 chi2 += delta * delta / cntsum;
2267 }
2268 }
2269 }
2270 }
2271 chi2 /= sum1 * sum2;
2272
2273 // flag error only when of the two histogram is zero
2274 if (m) {
2275 igood += 1;
2276 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2277 }
2278 if (n) {
2279 igood += 2;
2280 Info("Chi2TestX","There is a bin in h2 with less than 1 event.\n");
2281 }
2282
2284 return prob;
2285
2286 }
2287
2288 // unweighted - weighted comparison
2289 // case of error = 0 and content not zero is treated without problems by excluding second chi2 sum
2290 // and can be considered as a data-theory comparison
2291 if ( comparisonUW ) {
2292 Int_t resIndex = 0;
2293 for (Int_t i = i_start; i <= i_end; ++i) {
2294 for (Int_t j = j_start; j <= j_end; ++j) {
2295 for (Int_t k = k_start; k <= k_end; ++k) {
2296
2297 Int_t bin = GetBin(i, j, k);
2298
2300 Double_t cnt2 = h2->RetrieveBinContent(bin);
2301 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2302
2303 // case both histogram have zero bin contents
2304 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2305 --ndf; //no data means one degree of freedom less
2306 continue;
2307 }
2308
2309 // case weighted histogram has zero bin content and error
2310 if (cnt2 * cnt2 == 0 && e2sq == 0) {
2311 if (sumw2 > 0) {
2312 // use as approximated error as 1 scaled by a scaling ratio
2313 // estimated from the total sum weight and sum weight squared
2314 e2sq = sumw2 / sum2;
2315 }
2316 else {
2317 // return error because infinite discrepancy here:
2318 // bin1 != 0 and bin2 =0 in a histogram with all errors zero
2319 Error("Chi2TestX","Hist2 has in bin (%d,%d,%d) zero content and zero errors\n", i, j, k);
2320 chi2 = 0; return 0;
2321 }
2322 }
2323
2324 if (cnt1 < 1) m++;
2325 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2326
2327 Double_t var1 = sum2 * cnt2 - sum1 * e2sq;
2328 Double_t var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2329
2330 // if cnt1 is zero and cnt2 = 1 and sum1 = sum2 var1 = 0 && var2 == 0
2331 // approximate by incrementing cnt1
2332 // LM (this need to be fixed for numerical errors)
2333 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2334 sum1++;
2335 cnt1++;
2336 var1 = sum2 * cnt2 - sum1 * e2sq;
2337 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2338 }
2340
2341 while (var1 + var2 == 0) {
2342 sum1++;
2343 cnt1++;
2344 var1 = sum2 * cnt2 - sum1 * e2sq;
2345 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2346 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2347 sum1++;
2348 cnt1++;
2349 var1 = sum2 * cnt2 - sum1 * e2sq;
2350 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2351 }
2353 }
2354
2355 Double_t probb = (var1 + var2) / (2. * sum2 * sum2);
2356
2359
2362
2363 chi2 += delta1 * delta1 / nexp1;
2364
2365 if (e2sq > 0) {
2366 chi2 += delta2 * delta2 / e2sq;
2367 }
2368
2369 if (res) {
2370 if (e2sq > 0) {
2371 Double_t temp1 = sum2 * e2sq / var2;
2372 Double_t temp2 = 1.0 + (sum1 * e2sq - sum2 * cnt2) / var2;
2373 temp2 = temp1 * temp1 * sum1 * probb * (1.0 - probb) + temp2 * temp2 * e2sq / 4.0;
2374 // invert sign here
2375 res[resIndex] = - delta2 / TMath::Sqrt(temp2);
2376 }
2377 else
2378 res[resIndex] = delta1 / TMath::Sqrt(nexp1);
2379 resIndex++;
2380 }
2381 }
2382 }
2383 }
2384
2385 if (m) {
2386 igood += 1;
2387 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2388 }
2389 if (n) {
2390 igood += 2;
2391 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2392 }
2393
2395
2396 return prob;
2397 }
2398
2399 // weighted - weighted comparison
2400 if (comparisonWW) {
2401 Int_t resIndex = 0;
2402 for (Int_t i = i_start; i <= i_end; ++i) {
2403 for (Int_t j = j_start; j <= j_end; ++j) {
2404 for (Int_t k = k_start; k <= k_end; ++k) {
2405
2406 Int_t bin = GetBin(i, j, k);
2408 Double_t cnt2 = h2->RetrieveBinContent(bin);
2410 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2411
2412 // case both histogram have zero bin contents
2413 // (use square of content to avoid numerical errors)
2414 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2415 --ndf; //no data means one degree of freedom less
2416 continue;
2417 }
2418
2419 if (e1sq == 0 && e2sq == 0) {
2420 // cannot treat case of booth histogram have zero zero errors
2421 Error("Chi2TestX","h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
2422 chi2 = 0; return 0;
2423 }
2424
2425 Double_t sigma = sum1 * sum1 * e2sq + sum2 * sum2 * e1sq;
2426 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2427 chi2 += delta * delta / sigma;
2428
2429 if (res) {
2430 Double_t temp = cnt1 * sum1 * e2sq + cnt2 * sum2 * e1sq;
2431 Double_t probb = temp / sigma;
2432 Double_t z = 0;
2433 if (e1sq > e2sq) {
2434 Double_t d1 = cnt1 - sum1 * probb;
2435 Double_t s1 = e1sq * ( 1. - e2sq * sum1 * sum1 / sigma );
2436 z = d1 / TMath::Sqrt(s1);
2437 }
2438 else {
2439 Double_t d2 = cnt2 - sum2 * probb;
2440 Double_t s2 = e2sq * ( 1. - e1sq * sum2 * sum2 / sigma );
2441 z = -d2 / TMath::Sqrt(s2);
2442 }
2443 res[resIndex] = z;
2444 resIndex++;
2445 }
2446
2447 if (e1sq > 0 && cnt1 * cnt1 / e1sq < 10) m++;
2448 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2449 }
2450 }
2451 }
2452 if (m) {
2453 igood += 1;
2454 Info("Chi2TestX","There is a bin in h1 with less than 10 effective events.\n");
2455 }
2456 if (n) {
2457 igood += 2;
2458 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2459 }
2461 return prob;
2462 }
2463 return 0;
2464}
2465////////////////////////////////////////////////////////////////////////////////
2466/// Compute and return the chisquare of this histogram with respect to a function
2467/// The chisquare is computed by weighting each histogram point by the bin error
2468/// By default the full range of the histogram is used, unless TAxis::SetRange or TAxis::SetRangeUser was called before.
2469/// Use option "R" for restricting the chisquare calculation to the given range of the function
2470/// Use option "L" for using the chisquare based on the poisson likelihood (Baker-Cousins Chisquare)
2471/// Use option "P" for using the Pearson chisquare based on the expected bin errors
2472
2474{
2475 if (!func) {
2476 Error("Chisquare","Function pointer is Null - return -1");
2477 return -1;
2478 }
2479
2480 TString opt(option); opt.ToUpper();
2481 bool useRange = opt.Contains("R");
2482 ROOT::Fit::EChisquareType type = ROOT::Fit::EChisquareType::kNeyman; // default chi2 with observed error
2485
2486 return ROOT::Fit::Chisquare(*this, *func, useRange, type);
2487}
2488
2489////////////////////////////////////////////////////////////////////////////////
2490/// Remove all the content from the underflow and overflow bins, without changing the number of entries
2491/// After calling this method, every undeflow and overflow bins will have content 0.0
2492/// The Sumw2 is also cleared, since there is no more content in the bins
2493
2495{
2496 for (Int_t bin = 0; bin < fNcells; ++bin)
2497 if (IsBinUnderflow(bin) || IsBinOverflow(bin)) {
2498 UpdateBinContent(bin, 0.0);
2499 if (fSumw2.fN) fSumw2.fArray[bin] = 0.0;
2500 }
2501}
2502
2503////////////////////////////////////////////////////////////////////////////////
2504/// Compute integral (normalized cumulative sum of bins) w/o under/overflows
2505/// The result is stored in fIntegral and used by the GetRandom functions.
2506/// This function is automatically called by GetRandom when the fIntegral
2507/// array does not exist or when the number of entries in the histogram
2508/// has changed since the previous call to GetRandom.
2509/// The resulting integral is normalized to 1.
2510/// If the routine is called with the onlyPositive flag set an error will
2511/// be produced in case of negative bin content and a NaN value returned
2512/// \param onlyPositive If set to true, an error will be produced and NaN will be returned
2513/// when a bin with negative number of entries is encountered.
2514/// \param option
2515/// - `""` (default) Compute the cumulative density function assuming current bin contents represent counts.
2516/// - `"width"` Computes the cumulative density function assuming current bin contents represent densities.
2517/// \return 1 if success, 0 if integral is zero, NAN if onlyPositive-test fails
2518
2520{
2521 if (fBuffer) BufferEmpty();
2523 // delete previously computed integral (if any)
2524 if (fIntegral) delete [] fIntegral;
2525
2526 // - Allocate space to store the integral and compute integral
2530 Int_t nbins = nbinsx * nbinsy * nbinsz;
2531
2532 fIntegral = new Double_t[nbins + 2];
2533 Int_t ibin = 0; fIntegral[ibin] = 0;
2534
2535 for (Int_t binz=1; binz <= nbinsz; ++binz) {
2537 for (Int_t biny=1; biny <= nbinsy; ++biny) {
2539 for (Int_t binx=1; binx <= nbinsx; ++binx) {
2541 ++ibin;
2543 if (useArea)
2544 y *= xWidth * yWidth * zWidth;
2545
2546 if (onlyPositive && y < 0) {
2547 Error("ComputeIntegral","Bin content is negative - return a NaN value");
2548 fIntegral[nbins] = TMath::QuietNaN();
2549 break;
2550 }
2551 fIntegral[ibin] = fIntegral[ibin - 1] + y;
2552 }
2553 }
2554 }
2555
2556 // - Normalize integral to 1
2557 if (fIntegral[nbins] == 0 ) {
2558 Error("ComputeIntegral", "Integral = 0, no hits in histogram bins (excluding over/underflow).");
2559 return 0;
2560 }
2561 for (Int_t bin=1; bin <= nbins; ++bin) fIntegral[bin] /= fIntegral[nbins];
2562 fIntegral[nbins+1] = fEntries;
2563 return fIntegral[nbins];
2564}
2565
2566////////////////////////////////////////////////////////////////////////////////
2567/// Return a pointer to the array of bins integral.
2568/// if the pointer fIntegral is null, TH1::ComputeIntegral is called
2569/// The array dimension is the number of bins in the histograms
2570/// including underflow and overflow (fNCells)
2571/// the last value integral[fNCells] is set to the number of entries of
2572/// the histogram
2573
2575{
2576 if (!fIntegral) ComputeIntegral();
2577 return fIntegral;
2578}
2579
2580////////////////////////////////////////////////////////////////////////////////
2581/// Return a pointer to a histogram containing the cumulative content.
2582/// The cumulative can be computed both in the forward (default) or backward
2583/// direction; the name of the new histogram is constructed from
2584/// the name of this histogram with the suffix "suffix" appended provided
2585/// by the user. If not provided a default suffix="_cumulative" is used.
2586///
2587/// The cumulative distribution is formed by filling each bin of the
2588/// resulting histogram with the sum of that bin and all previous
2589/// (forward == kTRUE) or following (forward = kFALSE) bins.
2590///
2591/// Note: while cumulative distributions make sense in one dimension, you
2592/// may not be getting what you expect in more than 1D because the concept
2593/// of a cumulative distribution is much trickier to define; make sure you
2594/// understand the order of summation before you use this method with
2595/// histograms of dimension >= 2.
2596///
2597/// Note 2: By default the cumulative is computed from bin 1 to Nbins
2598/// If an axis range is set, values between the minimum and maximum of the range
2599/// are set.
2600/// Setting an axis range can also be used for including underflow and overflow in
2601/// the cumulative (e.g. by setting h->GetXaxis()->SetRange(0, h->GetNbinsX()+1); )
2603
2604TH1 *TH1::GetCumulative(Bool_t forward, const char* suffix) const
2605{
2606 const Int_t firstX = fXaxis.GetFirst();
2607 const Int_t lastX = fXaxis.GetLast();
2608 const Int_t firstY = (fDimension > 1) ? fYaxis.GetFirst() : 1;
2609 const Int_t lastY = (fDimension > 1) ? fYaxis.GetLast() : 1;
2610 const Int_t firstZ = (fDimension > 1) ? fZaxis.GetFirst() : 1;
2611 const Int_t lastZ = (fDimension > 1) ? fZaxis.GetLast() : 1;
2612
2614 hintegrated->Reset();
2615 Double_t sum = 0.;
2616 Double_t esum = 0;
2617 if (forward) { // Forward computation
2618 for (Int_t binz = firstZ; binz <= lastZ; ++binz) {
2619 for (Int_t biny = firstY; biny <= lastY; ++biny) {
2620 for (Int_t binx = firstX; binx <= lastX; ++binx) {
2621 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2622 sum += RetrieveBinContent(bin);
2623 hintegrated->AddBinContent(bin, sum);
2624 if (fSumw2.fN) {
2626 hintegrated->fSumw2.fArray[bin] = esum;
2627 }
2628 }
2629 }
2630 }
2631 } else { // Backward computation
2632 for (Int_t binz = lastZ; binz >= firstZ; --binz) {
2633 for (Int_t biny = lastY; biny >= firstY; --biny) {
2634 for (Int_t binx = lastX; binx >= firstX; --binx) {
2635 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2636 sum += RetrieveBinContent(bin);
2637 hintegrated->AddBinContent(bin, sum);
2638 if (fSumw2.fN) {
2640 hintegrated->fSumw2.fArray[bin] = esum;
2641 }
2642 }
2643 }
2644 }
2645 }
2646 return hintegrated;
2647}
2648
2649////////////////////////////////////////////////////////////////////////////////
2650/// Copy this histogram structure to newth1.
2651///
2652/// Note that this function does not copy the list of associated functions.
2653/// Use TObject::Clone to make a full copy of a histogram.
2654///
2655/// Note also that the histogram it will be created in gDirectory (if AddDirectoryStatus()=true)
2656/// or will not be added to any directory if AddDirectoryStatus()=false
2657/// independently of the current directory stored in the original histogram
2658
2659void TH1::Copy(TObject &obj) const
2660{
2661 if (((TH1&)obj).fDirectory) {
2662 // We are likely to change the hash value of this object
2663 // with TNamed::Copy, to keep things correct, we need to
2664 // clean up its existing entries.
2665 ((TH1&)obj).fDirectory->Remove(&obj);
2666 ((TH1&)obj).fDirectory = nullptr;
2667 }
2668 TNamed::Copy(obj);
2669 ((TH1&)obj).fDimension = fDimension;
2670 ((TH1&)obj).fNormFactor= fNormFactor;
2671 ((TH1&)obj).fNcells = fNcells;
2672 ((TH1&)obj).fBarOffset = fBarOffset;
2673 ((TH1&)obj).fBarWidth = fBarWidth;
2674 ((TH1&)obj).fOption = fOption;
2675 ((TH1&)obj).fBinStatErrOpt = fBinStatErrOpt;
2676 ((TH1&)obj).fBufferSize= fBufferSize;
2677 // copy the Buffer
2678 // delete first a previously existing buffer
2679 if (((TH1&)obj).fBuffer != nullptr) {
2680 delete [] ((TH1&)obj).fBuffer;
2681 ((TH1&)obj).fBuffer = nullptr;
2682 }
2683 if (fBuffer) {
2684 Double_t *buf = new Double_t[fBufferSize];
2685 for (Int_t i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
2686 // obj.fBuffer has been deleted before
2687 ((TH1&)obj).fBuffer = buf;
2688 }
2689
2690 // copy bin contents (this should be done by the derived classes, since TH1 does not store the bin content)
2691 // Do this in case derived from TArray
2692 TArray* a = dynamic_cast<TArray*>(&obj);
2693 if (a) {
2694 a->Set(fNcells);
2695 for (Int_t i = 0; i < fNcells; i++)
2697 }
2698
2699 ((TH1&)obj).fEntries = fEntries;
2700
2701 // which will call BufferEmpty(0) and set fBuffer[0] to a Maybe one should call
2702 // assignment operator on the TArrayD
2703
2704 ((TH1&)obj).fTsumw = fTsumw;
2705 ((TH1&)obj).fTsumw2 = fTsumw2;
2706 ((TH1&)obj).fTsumwx = fTsumwx;
2707 ((TH1&)obj).fTsumwx2 = fTsumwx2;
2708 ((TH1&)obj).fMaximum = fMaximum;
2709 ((TH1&)obj).fMinimum = fMinimum;
2710
2711 TAttLine::Copy(((TH1&)obj));
2712 TAttFill::Copy(((TH1&)obj));
2713 TAttMarker::Copy(((TH1&)obj));
2714 fXaxis.Copy(((TH1&)obj).fXaxis);
2715 fYaxis.Copy(((TH1&)obj).fYaxis);
2716 fZaxis.Copy(((TH1&)obj).fZaxis);
2717 ((TH1&)obj).fXaxis.SetParent(&obj);
2718 ((TH1&)obj).fYaxis.SetParent(&obj);
2719 ((TH1&)obj).fZaxis.SetParent(&obj);
2720 fContour.Copy(((TH1&)obj).fContour);
2721 fSumw2.Copy(((TH1&)obj).fSumw2);
2722 // fFunctions->Copy(((TH1&)obj).fFunctions);
2723 // when copying an histogram if the AddDirectoryStatus() is true it
2724 // will be added to gDirectory independently of the fDirectory stored.
2725 // and if the AddDirectoryStatus() is false it will not be added to
2726 // any directory (fDirectory = nullptr)
2727 if (fgAddDirectory && gDirectory) {
2728 gDirectory->Append(&obj);
2729 ((TH1&)obj).fFunctions->UseRWLock();
2730 ((TH1&)obj).fDirectory = gDirectory;
2731 } else
2732 ((TH1&)obj).fDirectory = nullptr;
2733
2734}
2735
2736////////////////////////////////////////////////////////////////////////////////
2737/// Make a complete copy of the underlying object. If 'newname' is set,
2738/// the copy's name will be set to that name.
2739
2740TObject* TH1::Clone(const char* newname) const
2741{
2742 TH1* obj = (TH1*)IsA()->GetNew()(nullptr);
2743 Copy(*obj);
2744
2745 // Now handle the parts that Copy doesn't do
2746 if(fFunctions) {
2747 // The Copy above might have published 'obj' to the ListOfCleanups.
2748 // Clone can call RecursiveRemove, for example via TCheckHashRecursiveRemoveConsistency
2749 // when dictionary information is initialized, so we need to
2750 // keep obj->fFunction valid during its execution and
2751 // protect the update with the write lock.
2752
2753 // Reset stats parent - else cloning the stats will clone this histogram, too.
2754 auto oldstats = dynamic_cast<TVirtualPaveStats*>(fFunctions->FindObject("stats"));
2755 TObject *oldparent = nullptr;
2756 if (oldstats) {
2757 oldparent = oldstats->GetParent();
2758 oldstats->SetParent(nullptr);
2759 }
2760
2761 auto newlist = (TList*)fFunctions->Clone();
2762
2763 if (oldstats)
2764 oldstats->SetParent(oldparent);
2765 auto newstats = dynamic_cast<TVirtualPaveStats*>(obj->fFunctions->FindObject("stats"));
2766 if (newstats)
2767 newstats->SetParent(obj);
2768
2769 auto oldlist = obj->fFunctions;
2770 {
2772 obj->fFunctions = newlist;
2773 }
2774 delete oldlist;
2775 }
2776 if(newname && strlen(newname) ) {
2777 obj->SetName(newname);
2778 }
2779 return obj;
2780}
2781
2782////////////////////////////////////////////////////////////////////////////////
2783/// Perform the automatic addition of the histogram to the given directory
2784///
2785/// Note this function is called in place when the semantic requires
2786/// this object to be added to a directory (I.e. when being read from
2787/// a TKey or being Cloned)
2788
2790{
2792 if (addStatus) {
2793 SetDirectory(dir);
2794 if (dir) {
2796 }
2797 }
2798}
2799
2800////////////////////////////////////////////////////////////////////////////////
2801/// Compute distance from point px,py to a line.
2802///
2803/// Compute the closest distance of approach from point px,py to elements
2804/// of a histogram.
2805/// The distance is computed in pixels units.
2806///
2807/// #### Algorithm:
2808/// Currently, this simple model computes the distance from the mouse
2809/// to the histogram contour only.
2810
2812{
2813 if (!fPainter) return 9999;
2814 return fPainter->DistancetoPrimitive(px,py);
2815}
2816
2817////////////////////////////////////////////////////////////////////////////////
2818/// Performs the operation: `this = this/(c1*f1)`
2819/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2820///
2821/// Only bins inside the function range are recomputed.
2822/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2823/// you should call Sumw2 before making this operation.
2824/// This is particularly important if you fit the histogram after TH1::Divide
2825///
2826/// The function return kFALSE if the divide operation failed
2827
2829{
2830 if (!f1) {
2831 Error("Divide","Attempt to divide by a non-existing function");
2832 return kFALSE;
2833 }
2834
2835 // delete buffer if it is there since it will become invalid
2836 if (fBuffer) BufferEmpty(1);
2837
2838 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of
2839 Int_t ny = GetNbinsY() + 2;
2840 Int_t nz = GetNbinsZ() + 2;
2841 if (fDimension < 2) ny = 1;
2842 if (fDimension < 3) nz = 1;
2843
2844
2845 SetMinimum();
2846 SetMaximum();
2847
2848 // - Loop on bins (including underflows/overflows)
2849 Int_t bin, binx, biny, binz;
2850 Double_t cu, w;
2851 Double_t xx[3];
2852 Double_t *params = nullptr;
2853 f1->InitArgs(xx,params);
2854 for (binz = 0; binz < nz; ++binz) {
2855 xx[2] = fZaxis.GetBinCenter(binz);
2856 for (biny = 0; biny < ny; ++biny) {
2857 xx[1] = fYaxis.GetBinCenter(biny);
2858 for (binx = 0; binx < nx; ++binx) {
2859 xx[0] = fXaxis.GetBinCenter(binx);
2860 if (!f1->IsInside(xx)) continue;
2862 bin = binx + nx * (biny + ny * binz);
2863 cu = c1 * f1->EvalPar(xx);
2864 if (TF1::RejectedPoint()) continue;
2865 if (cu) w = RetrieveBinContent(bin) / cu;
2866 else w = 0;
2867 UpdateBinContent(bin, w);
2868 if (fSumw2.fN) {
2869 if (cu != 0) fSumw2.fArray[bin] = GetBinErrorSqUnchecked(bin) / (cu * cu);
2870 else fSumw2.fArray[bin] = 0;
2871 }
2872 }
2873 }
2874 }
2875 ResetStats();
2876 return kTRUE;
2877}
2878
2879////////////////////////////////////////////////////////////////////////////////
2880/// Divide this histogram by h1.
2881///
2882/// `this = this/h1`
2883/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2884/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
2885/// if not already set.
2886/// The resulting errors are calculated assuming uncorrelated histograms.
2887/// See the other TH1::Divide that gives the possibility to optionally
2888/// compute binomial errors.
2889///
2890/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2891/// you should call Sumw2 before making this operation.
2892/// This is particularly important if you fit the histogram after TH1::Scale
2893///
2894/// The function return kFALSE if the divide operation failed
2895
2896Bool_t TH1::Divide(const TH1 *h1)
2897{
2898 if (!h1) {
2899 Error("Divide", "Input histogram passed does not exist (NULL).");
2900 return kFALSE;
2901 }
2902
2903 // delete buffer if it is there since it will become invalid
2904 if (fBuffer) BufferEmpty(1);
2905
2906 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins) {
2907 return false;
2908 }
2909
2910 // Create Sumw2 if h1 has Sumw2 set
2911 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
2912
2913 // - Loop on bins (including underflows/overflows)
2914 for (Int_t i = 0; i < fNcells; ++i) {
2917 if (c1) UpdateBinContent(i, c0 / c1);
2918 else UpdateBinContent(i, 0);
2919
2920 if(fSumw2.fN) {
2921 if (c1 == 0) { fSumw2.fArray[i] = 0; continue; }
2922 Double_t c1sq = c1 * c1;
2923 fSumw2.fArray[i] = (GetBinErrorSqUnchecked(i) * c1sq + h1->GetBinErrorSqUnchecked(i) * c0 * c0) / (c1sq * c1sq);
2924 }
2925 }
2926 ResetStats();
2927 return kTRUE;
2928}
2929
2930////////////////////////////////////////////////////////////////////////////////
2931/// Replace contents of this histogram by the division of h1 by h2.
2932///
2933/// `this = c1*h1/(c2*h2)`
2934///
2935/// If errors are defined (see TH1::Sumw2), errors are also recalculated
2936/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
2937/// if not already set.
2938/// The resulting errors are calculated assuming uncorrelated histograms.
2939/// However, if option ="B" is specified, Binomial errors are computed.
2940/// In this case c1 and c2 do not make real sense and they are ignored.
2941///
2942/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2943/// you should call Sumw2 before making this operation.
2944/// This is particularly important if you fit the histogram after TH1::Divide
2945///
2946/// Please note also that in the binomial case errors are calculated using standard
2947/// binomial statistics, which means when b1 = b2, the error is zero.
2948/// If you prefer to have efficiency errors not going to zero when the efficiency is 1, you must
2949/// use the function TGraphAsymmErrors::BayesDivide, which will return an asymmetric and non-zero lower
2950/// error for the case b1=b2.
2951///
2952/// The function return kFALSE if the divide operation failed
2953
2955{
2956
2957 TString opt = option;
2958 opt.ToLower();
2959 Bool_t binomial = kFALSE;
2960 if (opt.Contains("b")) binomial = kTRUE;
2961 if (!h1 || !h2) {
2962 Error("Divide", "At least one of the input histograms 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 LoggedInconsistency("Divide", h1, h2) >= kDifferentNumberOfBins) {
2971 return false;
2972 }
2973
2974 if (!c2) {
2975 Error("Divide","Coefficient of dividing histogram cannot be zero");
2976 return kFALSE;
2977 }
2978
2979 // Create Sumw2 if h1 or h2 have Sumw2 set, or if binomial errors are explicitly requested
2980 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0 || binomial)) Sumw2();
2981
2982 SetMinimum();
2983 SetMaximum();
2984
2985 // - Loop on bins (including underflows/overflows)
2986 for (Int_t i = 0; i < fNcells; ++i) {
2988 Double_t b2 = h2->RetrieveBinContent(i);
2989 if (b2) UpdateBinContent(i, c1 * b1 / (c2 * b2));
2990 else UpdateBinContent(i, 0);
2991
2992 if (fSumw2.fN) {
2993 if (b2 == 0) { fSumw2.fArray[i] = 0; continue; }
2994 Double_t b1sq = b1 * b1; Double_t b2sq = b2 * b2;
2995 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
2997 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
2998 if (binomial) {
2999 if (b1 != b2) {
3000 // in the case of binomial statistics c1 and c2 must be 1 otherwise it does not make sense
3001 // c1 and c2 are ignored
3002 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));//this is the formula in Hbook/Hoper1
3003 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2); // old formula from G. Flucke
3004 // formula which works also for weighted histogram (see http://root-forum.cern.ch/viewtopic.php?t=3753 )
3005 fSumw2.fArray[i] = TMath::Abs( ( (1. - 2.* b1 / b2) * e1sq + b1sq * e2sq / b2sq ) / b2sq );
3006 } else {
3007 //in case b1=b2 error is zero
3008 //use TGraphAsymmErrors::BayesDivide for getting the asymmetric error not equal to zero
3009 fSumw2.fArray[i] = 0;
3010 }
3011 } else {
3012 fSumw2.fArray[i] = c1sq * c2sq * (e1sq * b2sq + e2sq * b1sq) / (c2sq * c2sq * b2sq * b2sq);
3013 }
3014 }
3015 }
3016 ResetStats();
3017 if (binomial)
3018 // in case of binomial division use denominator for number of entries
3019 SetEntries ( h2->GetEntries() );
3020
3021 return kTRUE;
3022}
3023
3024////////////////////////////////////////////////////////////////////////////////
3025/// Draw this histogram with options.
3026///
3027/// Histograms are drawn via the THistPainter class. Each histogram has
3028/// a pointer to its own painter (to be usable in a multithreaded program).
3029/// The same histogram can be drawn with different options in different pads.
3030/// When a histogram drawn in a pad is deleted, the histogram is
3031/// automatically removed from the pad or pads where it was drawn.
3032/// If a histogram is drawn in a pad, then filled again, the new status
3033/// of the histogram will be automatically shown in the pad next time
3034/// the pad is updated. One does not need to redraw the histogram.
3035/// To draw the current version of a histogram in a pad, one can use
3036/// `h->DrawCopy();`
3037/// This makes a clone of the histogram. Once the clone is drawn, the original
3038/// histogram may be modified or deleted without affecting the aspect of the
3039/// clone.
3040/// By default, TH1::Draw clears the current pad.
3041///
3042/// One can use TH1::SetMaximum and TH1::SetMinimum to force a particular
3043/// value for the maximum or the minimum scale on the plot.
3044///
3045/// TH1::UseCurrentStyle can be used to change all histogram graphics
3046/// attributes to correspond to the current selected style.
3047/// This function must be called for each histogram.
3048/// In case one reads and draws many histograms from a file, one can force
3049/// the histograms to inherit automatically the current graphics style
3050/// by calling before gROOT->ForceStyle();
3051///
3052/// See the THistPainter class for a description of all the drawing options.
3053
3055{
3056 TString opt1 = option; opt1.ToLower();
3058 Int_t index = opt1.Index("same");
3059
3060 // Check if the string "same" is part of a TCutg name.
3061 if (index>=0) {
3062 Int_t indb = opt1.Index("[");
3063 if (indb>=0) {
3064 Int_t indk = opt1.Index("]");
3065 if (index>indb && index<indk) index = -1;
3066 }
3067 }
3068
3069 // If there is no pad or an empty pad the "same" option is ignored.
3070 if (gPad) {
3071 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
3072 if (index>=0) {
3073 if (gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
3074 gPad->GetY1() == 0 && gPad->GetY2() == 1 &&
3075 gPad->GetListOfPrimitives()->GetSize()==0) opt2.Remove(index,4);
3076 } else {
3077 //the following statement is necessary in case one attempts to draw
3078 //a temporary histogram already in the current pad
3079 if (TestBit(kCanDelete)) gPad->Remove(this);
3080 gPad->Clear();
3081 }
3082 gPad->IncrementPaletteColor(1, opt1);
3083 } else {
3084 if (index>=0) opt2.Remove(index,4);
3085 }
3086
3087 AppendPad(opt2.Data());
3088}
3089
3090////////////////////////////////////////////////////////////////////////////////
3091/// Copy this histogram and Draw in the current pad.
3092///
3093/// Once the histogram is drawn into the pad, any further modification
3094/// using graphics input will be made on the copy of the histogram,
3095/// and not to the original object.
3096/// By default a postfix "_copy" is added to the histogram name. Pass an empty postfix in case
3097/// you want to draw a histogram with the same name
3098///
3099/// See Draw for the list of options
3100
3101TH1 *TH1::DrawCopy(Option_t *option, const char * name_postfix) const
3102{
3103 TString opt = option;
3104 opt.ToLower();
3105 if (gPad && !opt.Contains("same")) gPad->Clear();
3107 if (name_postfix) newName.Form("%s%s", GetName(), name_postfix);
3108 TH1 *newth1 = (TH1 *)Clone(newName.Data());
3109 newth1->SetDirectory(nullptr);
3110 newth1->SetBit(kCanDelete);
3111 if (gPad) gPad->IncrementPaletteColor(1, opt);
3112
3113 newth1->AppendPad(option);
3114 return newth1;
3115}
3116
3117////////////////////////////////////////////////////////////////////////////////
3118/// Draw a normalized copy of this histogram.
3119///
3120/// A clone of this histogram is normalized to norm and drawn with option.
3121/// A pointer to the normalized histogram is returned.
3122/// The contents of the histogram copy are scaled such that the new
3123/// sum of weights (excluding under and overflow) is equal to norm.
3124/// Note that the returned normalized histogram is not added to the list
3125/// of histograms in the current directory in memory.
3126/// It is the user's responsibility to delete this histogram.
3127/// The kCanDelete bit is set for the returned object. If a pad containing
3128/// this copy is cleared, the histogram will be automatically deleted.
3129///
3130/// See Draw for the list of options
3131
3133{
3135 if (sum == 0) {
3136 Error("DrawNormalized","Sum of weights is null. Cannot normalize histogram: %s",GetName());
3137 return nullptr;
3138 }
3141 TH1 *h = (TH1*)Clone();
3143 // in case of drawing with error options - scale correctly the error
3144 TString opt(option); opt.ToUpper();
3145 if (fSumw2.fN == 0) {
3146 h->Sumw2();
3147 // do not use in this case the "Error option " for drawing which is enabled by default since the normalized histogram has now errors
3148 if (opt.IsNull() || opt == "SAME") opt += "HIST";
3149 }
3150 h->Scale(norm/sum);
3151 if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
3152 if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
3153 h->Draw(opt);
3155 return h;
3156}
3157
3158////////////////////////////////////////////////////////////////////////////////
3159/// Display a panel with all histogram drawing options.
3160///
3161/// See class TDrawPanelHist for example
3162
3163void TH1::DrawPanel()
3164{
3165 if (!fPainter) {Draw(); if (gPad) gPad->Update();}
3166 if (fPainter) fPainter->DrawPanel();
3167}
3168
3169////////////////////////////////////////////////////////////////////////////////
3170/// Evaluate function f1 at the center of bins of this histogram.
3171///
3172/// - If option "R" is specified, the function is evaluated only
3173/// for the bins included in the function range.
3174/// - If option "A" is specified, the value of the function is added to the
3175/// existing bin contents
3176/// - If option "S" is specified, the value of the function is used to
3177/// generate a value, distributed according to the Poisson
3178/// distribution, with f1 as the mean.
3179
3181{
3182 Double_t x[3];
3183 Int_t range, stat, add;
3184 if (!f1) return;
3185
3186 TString opt = option;
3187 opt.ToLower();
3188 if (opt.Contains("a")) add = 1;
3189 else add = 0;
3190 if (opt.Contains("s")) stat = 1;
3191 else stat = 0;
3192 if (opt.Contains("r")) range = 1;
3193 else range = 0;
3194
3195 // delete buffer if it is there since it will become invalid
3196 if (fBuffer) BufferEmpty(1);
3197
3201 if (!add) Reset();
3202
3203 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
3204 x[2] = fZaxis.GetBinCenter(binz);
3205 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
3206 x[1] = fYaxis.GetBinCenter(biny);
3207 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
3208 Int_t bin = GetBin(binx,biny,binz);
3209 x[0] = fXaxis.GetBinCenter(binx);
3210 if (range && !f1->IsInside(x)) continue;
3211 Double_t fu = f1->Eval(x[0], x[1], x[2]);
3212 if (stat) fu = gRandom->PoissonD(fu);
3213 AddBinContent(bin, fu);
3214 if (fSumw2.fN) fSumw2.fArray[bin] += TMath::Abs(fu);
3215 }
3216 }
3217 }
3218}
3219
3220////////////////////////////////////////////////////////////////////////////////
3221/// Execute action corresponding to one event.
3222///
3223/// This member function is called when a histogram is clicked with the locator
3224///
3225/// If Left button clicked on the bin top value, then the content of this bin
3226/// is modified according to the new position of the mouse when it is released.
3227
3228void TH1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3229{
3230 if (fPainter) fPainter->ExecuteEvent(event, px, py);
3231}
3232
3233////////////////////////////////////////////////////////////////////////////////
3234/// This function allows to do discrete Fourier transforms of TH1 and TH2.
3235/// Available transform types and flags are described below.
3236///
3237/// To extract more information about the transform, use the function
3238/// TVirtualFFT::GetCurrentTransform() to get a pointer to the current
3239/// transform object.
3240///
3241/// \param[out] h_output histogram for the output. If a null pointer is passed, a new histogram is created
3242/// and returned, otherwise, the provided histogram is used and should be big enough
3243/// \param[in] option option parameters consists of 3 parts:
3244/// - option on what to return
3245/// - "RE" - returns a histogram of the real part of the output
3246/// - "IM" - returns a histogram of the imaginary part of the output
3247/// - "MAG"- returns a histogram of the magnitude of the output
3248/// - "PH" - returns a histogram of the phase of the output
3249/// - option of transform type
3250/// - "R2C" - real to complex transforms - default
3251/// - "R2HC" - real to halfcomplex (special format of storing output data,
3252/// results the same as for R2C)
3253/// - "DHT" - discrete Hartley transform
3254/// real to real transforms (sine and cosine):
3255/// - "R2R_0", "R2R_1", "R2R_2", "R2R_3" - discrete cosine transforms of types I-IV
3256/// - "R2R_4", "R2R_5", "R2R_6", "R2R_7" - discrete sine transforms of types I-IV
3257/// To specify the type of each dimension of a 2-dimensional real to real
3258/// transform, use options of form "R2R_XX", for example, "R2R_02" for a transform,
3259/// which is of type "R2R_0" in 1st dimension and "R2R_2" in the 2nd.
3260/// - option of transform flag
3261/// - "ES" (from "estimate") - no time in preparing the transform, but probably sub-optimal
3262/// performance
3263/// - "M" (from "measure") - some time spend in finding the optimal way to do the transform
3264/// - "P" (from "patient") - more time spend in finding the optimal way to do the transform
3265/// - "EX" (from "exhaustive") - the most optimal way is found
3266/// This option should be chosen depending on how many transforms of the same size and
3267/// type are going to be done. Planning is only done once, for the first transform of this
3268/// size and type. Default is "ES".
3269///
3270/// Examples of valid options: "Mag R2C M" "Re R2R_11" "Im R2C ES" "PH R2HC EX"
3271
3273{
3274
3275 Int_t ndim[3];
3276 ndim[0] = this->GetNbinsX();
3277 ndim[1] = this->GetNbinsY();
3278 ndim[2] = this->GetNbinsZ();
3279
3281 TString opt = option;
3282 opt.ToUpper();
3283 if (!opt.Contains("2R")){
3284 if (!opt.Contains("2C") && !opt.Contains("2HC") && !opt.Contains("DHT")) {
3285 //no type specified, "R2C" by default
3286 opt.Append("R2C");
3287 }
3288 fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
3289 }
3290 else {
3291 //find the kind of transform
3292 Int_t ind = opt.Index("R2R", 3);
3293 Int_t *kind = new Int_t[2];
3294 char t;
3295 t = opt[ind+4];
3296 kind[0] = atoi(&t);
3297 if (h_output->GetDimension()>1) {
3298 t = opt[ind+5];
3299 kind[1] = atoi(&t);
3300 }
3301 fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
3302 delete [] kind;
3303 }
3304
3305 if (!fft) return nullptr;
3306 Int_t in=0;
3307 for (Int_t binx = 1; binx<=ndim[0]; binx++) {
3308 for (Int_t biny=1; biny<=ndim[1]; biny++) {
3309 for (Int_t binz=1; binz<=ndim[2]; binz++) {
3310 fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
3311 in++;
3312 }
3313 }
3314 }
3315 fft->Transform();
3317 return h_output;
3318}
3319
3320////////////////////////////////////////////////////////////////////////////////
3321/// Increment bin with abscissa X by 1.
3322///
3323/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3324/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3325///
3326/// If the storage of the sum of squares of weights has been triggered,
3327/// via the function Sumw2, then the sum of the squares of weights is incremented
3328/// by 1 in the bin corresponding to x.
3329///
3330/// The function returns the corresponding bin number which has its content incremented by 1
3331
3333{
3334 if (fBuffer) return BufferFill(x,1);
3335
3336 Int_t bin;
3337 fEntries++;
3338 bin =fXaxis.FindBin(x);
3339 if (bin <0) return -1;
3340 AddBinContent(bin);
3341 if (fSumw2.fN) ++fSumw2.fArray[bin];
3342 if (bin == 0 || bin > fXaxis.GetNbins()) {
3343 if (!GetStatOverflowsBehaviour()) return -1;
3344 }
3345 ++fTsumw;
3346 ++fTsumw2;
3347 fTsumwx += x;
3348 fTsumwx2 += x*x;
3349 return bin;
3350}
3351
3352////////////////////////////////////////////////////////////////////////////////
3353/// Increment bin with abscissa X with a weight w.
3354///
3355/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3356/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3357///
3358/// If the weight is not equal to 1, the storage of the sum of squares of
3359/// weights is automatically triggered and the sum of the squares of weights is incremented
3360/// by \f$ w^2 \f$ in the bin corresponding to x.
3361///
3362/// The function returns the corresponding bin number which has its content incremented by w
3363
3365{
3366
3367 if (fBuffer) return BufferFill(x,w);
3368
3369 Int_t bin;
3370 fEntries++;
3371 bin =fXaxis.FindBin(x);
3372 if (bin <0) return -1;
3373 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW) ) Sumw2(); // must be called before AddBinContent
3374 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3375 AddBinContent(bin, w);
3376 if (bin == 0 || bin > fXaxis.GetNbins()) {
3377 if (!GetStatOverflowsBehaviour()) return -1;
3378 }
3379 Double_t z= w;
3380 fTsumw += z;
3381 fTsumw2 += z*z;
3382 fTsumwx += z*x;
3383 fTsumwx2 += z*x*x;
3384 return bin;
3385}
3386
3387////////////////////////////////////////////////////////////////////////////////
3388/// Increment bin with namex with a weight w
3389///
3390/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3391/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3392///
3393/// If the weight is not equal to 1, the storage of the sum of squares of
3394/// weights is automatically triggered and the sum of the squares of weights is incremented
3395/// by \f$ w^2 \f$ in the bin corresponding to x.
3396///
3397/// The function returns the corresponding bin number which has its content
3398/// incremented by w.
3399
3400Int_t TH1::Fill(const char *namex, Double_t w)
3401{
3402 Int_t bin;
3403 fEntries++;
3404 bin =fXaxis.FindBin(namex);
3405 if (bin <0) return -1;
3406 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3407 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3408 AddBinContent(bin, w);
3409 if (bin == 0 || bin > fXaxis.GetNbins()) return -1;
3410 Double_t z= w;
3411 fTsumw += z;
3412 fTsumw2 += z*z;
3413 // this make sense if the histogram is not expanding (the x axis cannot be extended)
3414 if (!fXaxis.CanExtend() || !fXaxis.IsAlphanumeric()) {
3416 fTsumwx += z*x;
3417 fTsumwx2 += z*x*x;
3418 }
3419 return bin;
3420}
3421
3422////////////////////////////////////////////////////////////////////////////////
3423/// Fill this histogram with an array x and weights w.
3424///
3425/// \param[in] ntimes number of entries in arrays x and w (array size must be ntimes*stride)
3426/// \param[in] x array of values to be histogrammed
3427/// \param[in] w array of weighs
3428/// \param[in] stride step size through arrays x and w
3429///
3430/// If the weight is not equal to 1, the storage of the sum of squares of
3431/// weights is automatically triggered and the sum of the squares of weights is incremented
3432/// by \f$ w^2 \f$ in the bin corresponding to x.
3433/// if w is NULL each entry is assumed a weight=1
3434
3435void TH1::FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3436{
3437 //If a buffer is activated, fill buffer
3438 if (fBuffer) {
3439 ntimes *= stride;
3440 Int_t i = 0;
3441 for (i=0;i<ntimes;i+=stride) {
3442 if (!fBuffer) break; // buffer can be deleted in BufferFill when is empty
3443 if (w) BufferFill(x[i],w[i]);
3444 else BufferFill(x[i], 1.);
3445 }
3446 // fill the remaining entries if the buffer has been deleted
3447 if (i < ntimes && !fBuffer) {
3448 auto weights = w ? &w[i] : nullptr;
3449 DoFillN((ntimes-i)/stride,&x[i],weights,stride);
3450 }
3451 return;
3452 }
3453 // call internal method
3454 DoFillN(ntimes, x, w, stride);
3455}
3456
3457////////////////////////////////////////////////////////////////////////////////
3458/// Internal method to fill histogram content from a vector
3459/// called directly by TH1::BufferEmpty
3460
3461void TH1::DoFillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3462{
3463 Int_t bin,i;
3464
3465 fEntries += ntimes;
3466 Double_t ww = 1;
3467 Int_t nbins = fXaxis.GetNbins();
3468 ntimes *= stride;
3469 for (i=0;i<ntimes;i+=stride) {
3470 bin =fXaxis.FindBin(x[i]);
3471 if (bin <0) continue;
3472 if (w) ww = w[i];
3473 if (!fSumw2.fN && ww != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3474 if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
3475 AddBinContent(bin, ww);
3476 if (bin == 0 || bin > nbins) {
3477 if (!GetStatOverflowsBehaviour()) continue;
3478 }
3479 Double_t z= ww;
3480 fTsumw += z;
3481 fTsumw2 += z*z;
3482 fTsumwx += z*x[i];
3483 fTsumwx2 += z*x[i]*x[i];
3484 }
3485}
3486
3487////////////////////////////////////////////////////////////////////////////////
3488/// Fill histogram following distribution in function fname.
3489///
3490/// @param fname : Function name used for filling the histogram
3491/// @param ntimes : number of times the histogram is filled
3492/// @param rng : (optional) Random number generator used to sample
3493///
3494///
3495/// The distribution contained in the function fname (TF1) is integrated
3496/// over the channel contents for the bin range of this histogram.
3497/// It is normalized to 1.
3498///
3499/// Getting one random number implies:
3500/// - Generating a random number between 0 and 1 (say r1)
3501/// - Look in which bin in the normalized integral r1 corresponds to
3502/// - Fill histogram channel
3503/// ntimes random numbers are generated
3504///
3505/// One can also call TF1::GetRandom to get a random variate from a function.
3506
3507void TH1::FillRandom(const char *fname, Int_t ntimes, TRandom * rng)
3508{
3509 // - Search for fname in the list of ROOT defined functions
3510 TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
3511 if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
3512
3515
3517{
3518 Int_t bin, binx, ibin, loop;
3519 Double_t r1, x;
3520
3521 // - Allocate temporary space to store the integral and compute integral
3522
3523 TAxis * xAxis = &fXaxis;
3524
3525 // in case axis of histogram is not defined use the function axis
3526 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
3528 f1->GetRange(xmin,xmax);
3529 Info("FillRandom","Using function axis and range [%g,%g]",xmin, xmax);
3530 xAxis = f1->GetHistogram()->GetXaxis();
3531 }
3532
3533 Int_t first = xAxis->GetFirst();
3534 Int_t last = xAxis->GetLast();
3535 Int_t nbinsx = last-first+1;
3536
3537 Double_t *integral = new Double_t[nbinsx+1];
3538 integral[0] = 0;
3539 for (binx=1;binx<=nbinsx;binx++) {
3540 Double_t fint = f1->Integral(xAxis->GetBinLowEdge(binx+first-1),xAxis->GetBinUpEdge(binx+first-1), 0.);
3541 integral[binx] = integral[binx-1] + fint;
3542 }
3543
3544 // - Normalize integral to 1
3545 if (integral[nbinsx] == 0 ) {
3546 delete [] integral;
3547 Error("FillRandom", "Integral = zero"); return;
3548 }
3549 for (bin=1;bin<=nbinsx;bin++) integral[bin] /= integral[nbinsx];
3550
3551 // --------------Start main loop ntimes
3552 for (loop=0;loop<ntimes;loop++) {
3553 r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
3554 ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
3555 //binx = 1 + ibin;
3556 //x = xAxis->GetBinCenter(binx); //this is not OK when SetBuffer is used
3557 x = xAxis->GetBinLowEdge(ibin+first)
3558 +xAxis->GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
3559 Fill(x);
3560 }
3561 delete [] integral;
3562}
3563
3564////////////////////////////////////////////////////////////////////////////////
3565/// Fill histogram following distribution in histogram h.
3566///
3567/// @param h : Histogram pointer used for sampling random number
3568/// @param ntimes : number of times the histogram is filled
3569/// @param rng : (optional) Random number generator used for sampling
3570///
3571/// The distribution contained in the histogram h (TH1) is integrated
3572/// over the channel contents for the bin range of this histogram.
3573/// It is normalized to 1.
3574///
3575/// Getting one random number implies:
3576/// - Generating a random number between 0 and 1 (say r1)
3577/// - Look in which bin in the normalized integral r1 corresponds to
3578/// - Fill histogram channel ntimes random numbers are generated
3579///
3580/// SPECIAL CASE when the target histogram has the same binning as the source.
3581/// in this case we simply use a poisson distribution where
3582/// the mean value per bin = bincontent/integral.
3583
3585{
3586 if (!h) { Error("FillRandom", "Null histogram"); return; }
3587 if (fDimension != h->GetDimension()) {
3588 Error("FillRandom", "Histograms with different dimensions"); return;
3589 }
3590 if (std::isnan(h->ComputeIntegral(true))) {
3591 Error("FillRandom", "Histograms contains negative bins, does not represent probabilities");
3592 return;
3593 }
3594
3595 //in case the target histogram has the same binning and ntimes much greater
3596 //than the number of bins we can use a fast method
3597 Int_t first = fXaxis.GetFirst();
3598 Int_t last = fXaxis.GetLast();
3599 Int_t nbins = last-first+1;
3600 if (ntimes > 10*nbins) {
3601 auto inconsistency = CheckConsistency(this,h);
3602 if (inconsistency != kFullyConsistent) return; // do nothing
3603 Double_t sumw = h->Integral(first,last);
3604 if (sumw == 0) return;
3605 Double_t sumgen = 0;
3606 for (Int_t bin=first;bin<=last;bin++) {
3607 Double_t mean = h->RetrieveBinContent(bin)*ntimes/sumw;
3608 Double_t cont = (rng) ? rng->Poisson(mean) : gRandom->Poisson(mean);
3609 sumgen += cont;
3610 AddBinContent(bin,cont);
3611 if (fSumw2.fN) fSumw2.fArray[bin] += cont;
3612 }
3613
3614 // fix for the fluctuations in the total number n
3615 // since we use Poisson instead of multinomial
3616 // add a correction to have ntimes as generated entries
3617 Int_t i;
3618 if (sumgen < ntimes) {
3619 // add missing entries
3620 for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
3621 {
3622 Double_t x = h->GetRandom();
3623 Fill(x);
3624 }
3625 }
3626 else if (sumgen > ntimes) {
3627 // remove extra entries
3628 i = Int_t(sumgen+0.5);
3629 while( i > ntimes) {
3630 Double_t x = h->GetRandom(rng);
3633 // skip in case bin is empty
3634 if (y > 0) {
3635 SetBinContent(ibin, y-1.);
3636 i--;
3637 }
3638 }
3639 }
3640
3641 ResetStats();
3642 return;
3643 }
3644 // case of different axis and not too large ntimes
3645
3646 if (h->ComputeIntegral() ==0) return;
3647 Int_t loop;
3648 Double_t x;
3649 for (loop=0;loop<ntimes;loop++) {
3650 x = h->GetRandom();
3651 Fill(x);
3652 }
3653}
3654
3655////////////////////////////////////////////////////////////////////////////////
3656/// Return Global bin number corresponding to x,y,z
3657///
3658/// 2-D and 3-D histograms are represented with a one dimensional
3659/// structure. This has the advantage that all existing functions, such as
3660/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3661/// This function tries to extend the axis if the given point belongs to an
3662/// under-/overflow bin AND if CanExtendAllAxes() is true.
3663///
3664/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3665
3667{
3668 if (GetDimension() < 2) {
3669 return fXaxis.FindBin(x);
3670 }
3671 if (GetDimension() < 3) {
3672 Int_t nx = fXaxis.GetNbins()+2;
3675 return binx + nx*biny;
3676 }
3677 if (GetDimension() < 4) {
3678 Int_t nx = fXaxis.GetNbins()+2;
3679 Int_t ny = fYaxis.GetNbins()+2;
3682 Int_t binz = fZaxis.FindBin(z);
3683 return binx + nx*(biny +ny*binz);
3684 }
3685 return -1;
3686}
3687
3688////////////////////////////////////////////////////////////////////////////////
3689/// Return Global bin number corresponding to x,y,z.
3690///
3691/// 2-D and 3-D histograms are represented with a one dimensional
3692/// structure. This has the advantage that all existing functions, such as
3693/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3694/// This function DOES NOT try to extend the axis if the given point belongs
3695/// to an under-/overflow bin.
3696///
3697/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3698
3700{
3701 if (GetDimension() < 2) {
3702 return fXaxis.FindFixBin(x);
3703 }
3704 if (GetDimension() < 3) {
3705 Int_t nx = fXaxis.GetNbins()+2;
3708 return binx + nx*biny;
3709 }
3710 if (GetDimension() < 4) {
3711 Int_t nx = fXaxis.GetNbins()+2;
3712 Int_t ny = fYaxis.GetNbins()+2;
3716 return binx + nx*(biny +ny*binz);
3717 }
3718 return -1;
3719}
3720
3721////////////////////////////////////////////////////////////////////////////////
3722/// Find first bin with content > threshold for axis (1=x, 2=y, 3=z)
3723/// if no bins with content > threshold is found the function returns -1.
3724/// The search will occur between the specified first and last bin. Specifying
3725/// the value of the last bin to search to less than zero will search until the
3726/// last defined bin.
3727
3729{
3730 if (fBuffer) ((TH1*)this)->BufferEmpty();
3731
3732 if (axis < 1 || (axis > 1 && GetDimension() == 1 ) ||
3733 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3 ) ) {
3734 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3735 axis = 1;
3736 }
3737 if (firstBin < 1) {
3738 firstBin = 1;
3739 }
3741 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3742 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3743
3744 if (axis == 1) {
3747 }
3748 for (Int_t binx = firstBin; binx <= lastBin; binx++) {
3749 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3750 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3752 }
3753 }
3754 }
3755 }
3756 else if (axis == 2) {
3759 }
3760 for (Int_t biny = firstBin; biny <= lastBin; biny++) {
3761 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3762 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3764 }
3765 }
3766 }
3767 }
3768 else if (axis == 3) {
3771 }
3772 for (Int_t binz = firstBin; binz <= lastBin; binz++) {
3773 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3774 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3776 }
3777 }
3778 }
3779 }
3780
3781 return -1;
3782}
3783
3784////////////////////////////////////////////////////////////////////////////////
3785/// Find last bin with content > threshold for axis (1=x, 2=y, 3=z)
3786/// if no bins with content > threshold is found the function returns -1.
3787/// The search will occur between the specified first and last bin. Specifying
3788/// the value of the last bin to search to less than zero will search until the
3789/// last defined bin.
3790
3792{
3793 if (fBuffer) ((TH1*)this)->BufferEmpty();
3794
3795
3796 if (axis < 1 || ( axis > 1 && GetDimension() == 1 ) ||
3797 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3) ) {
3798 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3799 axis = 1;
3800 }
3801 if (firstBin < 1) {
3802 firstBin = 1;
3803 }
3805 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3806 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3807
3808 if (axis == 1) {
3811 }
3812 for (Int_t binx = lastBin; binx >= firstBin; binx--) {
3813 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3814 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3816 }
3817 }
3818 }
3819 }
3820 else if (axis == 2) {
3823 }
3824 for (Int_t biny = lastBin; biny >= firstBin; biny--) {
3825 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3826 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3828 }
3829 }
3830 }
3831 }
3832 else if (axis == 3) {
3835 }
3836 for (Int_t binz = lastBin; binz >= firstBin; binz--) {
3837 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3838 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3840 }
3841 }
3842 }
3843 }
3844
3845 return -1;
3846}
3847
3848////////////////////////////////////////////////////////////////////////////////
3849/// Search object named name in the list of functions.
3850
3851TObject *TH1::FindObject(const char *name) const
3852{
3853 if (fFunctions) return fFunctions->FindObject(name);
3854 return nullptr;
3855}
3856
3857////////////////////////////////////////////////////////////////////////////////
3858/// Search object obj in the list of functions.
3859
3860TObject *TH1::FindObject(const TObject *obj) const
3861{
3862 if (fFunctions) return fFunctions->FindObject(obj);
3863 return nullptr;
3864}
3865
3866////////////////////////////////////////////////////////////////////////////////
3867/// Fit histogram with function fname.
3868///
3869///
3870/// fname is the name of a function available in the global ROOT list of functions
3871/// `gROOT->GetListOfFunctions`. Note that this is not thread safe.
3872/// The list include any TF1 object created by the user plus some pre-defined functions
3873/// which are automatically created by ROOT the first time a pre-defined function is requested from `gROOT`
3874/// (i.e. when calling `gROOT->GetFunction(const char *name)`).
3875/// These pre-defined functions are:
3876/// - `gaus, gausn` where gausn is the normalized Gaussian
3877/// - `landau, landaun`
3878/// - `expo`
3879/// - `pol1,...9, chebyshev1,...9`.
3880///
3881/// For printing the list of all available functions do:
3882///
3883/// TF1::InitStandardFunctions(); // not needed if `gROOT->GetFunction` is called before
3884/// TF2::InitStandardFunctions(); TF3::InitStandardFunctions(); // For 2D or 3D
3885/// gROOT->GetListOfFunctions()->ls()
3886///
3887/// `fname` can also be a formula that is accepted by the linear fitter containing the special operator `++`,
3888/// representing linear components separated by `++` sign, for example `x++sin(x)` for fitting `[0]*x+[1]*sin(x)`
3889///
3890/// This function finds a pointer to the TF1 object with name `fname` and calls TH1::Fit(TF1 *, Option_t *, Option_t *,
3891/// Double_t, Double_t). See there for the fitting options and the details about fitting histograms
3892
3894{
3895 char *linear;
3896 linear= (char*)strstr(fname, "++");
3897 Int_t ndim=GetDimension();
3898 if (linear){
3899 if (ndim<2){
3901 return Fit(&f1,option,goption,xxmin,xxmax);
3902 }
3903 else if (ndim<3){
3904 TF2 f2(fname, fname);
3905 return Fit(&f2,option,goption,xxmin,xxmax);
3906 }
3907 else{
3908 TF3 f3(fname, fname);
3909 return Fit(&f3,option,goption,xxmin,xxmax);
3910 }
3911 }
3912 else{
3913 TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
3914 if (!f1) { Printf("Unknown function: %s",fname); return -1; }
3915 return Fit(f1,option,goption,xxmin,xxmax);
3916 }
3917}
3918
3919////////////////////////////////////////////////////////////////////////////////
3920/// Fit histogram with the function pointer f1.
3921///
3922/// \param[in] f1 pointer to the function object
3923/// \param[in] option string defining the fit options (see table below).
3924/// \param[in] goption specify a list of graphics options. See TH1::Draw for a complete list of these options.
3925/// \param[in] xxmin lower fitting range
3926/// \param[in] xxmax upper fitting range
3927/// \return A smart pointer to the TFitResult class
3928///
3929/// \anchor HFitOpt
3930/// ### Histogram Fitting Options
3931///
3932/// Here is the full list of fit options that can be given in the parameter `option`.
3933/// Several options can be used together by concatanating the strings without the need of any delimiters.
3934///
3935/// option | description
3936/// -------|------------
3937/// "L" | Uses a log likelihood method (default is chi-square method). To be used when the histogram represents counts.
3938/// "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.
3939/// "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.
3940/// "MULTI" | Uses Loglikelihood method based on multi-nomial distribution. In this case the function must be normalized and one fits only the function shape.
3941/// "W" | Fit using the chi-square method and ignoring the bin uncertainties and skip empty bins.
3942/// "WW" | Fit using the chi-square method and ignoring the bin uncertainties and include the empty bins.
3943/// "I" | Uses the integral of function in the bin instead of the default bin center value.
3944/// "F" | Uses the default minimizer (e.g. Minuit) when fitting a linear function (e.g. polN) instead of the linear fitter.
3945/// "U" | Uses a user specified objective function (e.g. user providedlikelihood function) defined using `TVirtualFitter::SetFCN`
3946/// "E" | Performs a better parameter errors estimation using the Minos technique for all fit parameters.
3947/// "M" | Uses the IMPROVE algorithm (available only in TMinuit). This algorithm attempts improve the found local minimum by searching for a better one.
3948/// "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`.
3949/// "Q" | Quiet mode (minimum printing)
3950/// "V" | Verbose mode (default is between Q and V)
3951/// "+" | 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.
3952/// "N" | Does not store the graphics function, does not draw the histogram with the function after fitting.
3953/// "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.
3954/// "R" | Fit using a fitting range specified in the function range with `TF1::SetRange`.
3955/// "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.
3956/// "C" | In case of linear fitting, do no calculate the chisquare (saves CPU time).
3957/// "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.
3958/// "WIDTH" | Scales the histogran bin content by the bin width (useful for variable bins histograms)
3959/// "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
3960/// "MULTITHREAD" | Forces usage of multi-thread execution whenever possible
3961///
3962/// The default fitting of an histogram (when no option is given) is perfomed as following:
3963/// - a chi-square fit (see below Chi-square Fits) computed using the bin histogram errors and excluding bins with zero errors (empty bins);
3964/// - the full range of the histogram is used, unless TAxis::SetRange or TAxis::SetRangeUser was called before;
3965/// - the default Minimizer with its default configuration is used (see below Minimizer Configuration) except for linear function;
3966/// - for linear functions (`polN`, `chenbyshev` or formula expressions combined using operator `++`) a linear minimization is used.
3967/// - only the status of the fit is returned;
3968/// - the fit is performed in Multithread whenever is enabled in ROOT;
3969/// - only the last fitted function is saved in the histogram;
3970/// - the histogram is drawn after fitting overalyed with the resulting fitting function
3971///
3972/// \anchor HFitMinimizer
3973/// ### Minimizer Configuration
3974///
3975/// The Fit is perfomed using the default Minimizer, defined in the `ROOT::Math::MinimizerOptions` class.
3976/// It is possible to change the default minimizer and its configuration parameters by calling these static functions before fitting (before calling `TH1::Fit`):
3977/// - `ROOT::Math::MinimizerOptions::SetDefaultMinimizer(minimizerName, minimizerAgorithm)` for changing the minmizer and/or the corresponding algorithm.
3978/// For example `ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");` will set the usage of the BFGS algorithm of the GSL multi-dimensional minimization
3979/// The current defaults are ("Minuit","Migrad").
3980/// See the documentation of the `ROOT::Math::MinimizerOptions` for the available minimizers in ROOT and their corresponding algorithms.
3981/// - `ROOT::Math::MinimizerOptions::SetDefaultTolerance` for setting a different tolerance value for the minimization.
3982/// - `ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls` for setting the maximum number of function calls.
3983/// - `ROOT::Math::MinimizerOptions::SetDefaultPrintLevel` for changing the minimizer print level from level=0 (minimal printing) to level=3 maximum printing
3984///
3985/// Other options are possible depending on the Minimizer used, see the corresponding documentation.
3986/// The default minimizer can be also set in the resource file in etc/system.rootrc. For example
3987///
3988/// ~~~ {.cpp}
3989/// Root.Fitter: Minuit2
3990/// ~~~
3991///
3992/// \anchor HFitChi2
3993/// ### Chi-square Fits
3994///
3995/// By default a chi-square (least-square) fit is performed on the histogram. The so-called modified least-square method
3996/// is used where the residual for each bin is computed using as error the observed value (the bin error) returned by `TH1::GetBinError`
3997///
3998/// \f[
3999/// Chi2 = \sum_{i}{ \left(\frac{y(i) - f(x(i) | p )}{e(i)} \right)^2 }
4000/// \f]
4001///
4002/// 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
4003/// an un-weighted histogram). Bins with zero errors are excluded from the fit. See also later the note on the treatment
4004/// of empty bins. When using option "I" the residual is computed not using the function value at the bin center, `f(x(i)|p)`,
4005/// but the integral of the function in the bin, Integral{ f(x|p)dx }, divided by the bin volume.
4006/// When using option `P` (Pearson chi2), the expected error computed as `e(i) = sqrt(f(x(i)|p))` is used.
4007/// In this case empty bins are considered in the fit.
4008/// Both chi-square methods should not be used when the bin content represent counts, especially in case of low bin statistics,
4009/// because they could return a biased result.
4010///
4011/// \anchor HFitNLL
4012/// ### Likelihood Fits
4013///
4014/// When using option "L" a likelihood fit is used instead of the default chi-square fit.
4015/// The likelihood is built assuming a Poisson probability density function for each bin.
4016/// The negative log-likelihood to be minimized is
4017///
4018/// \f[
4019/// NLL = - \sum_{i}{ \log {\mathrm P} ( y(i) | f(x(i) | p ) ) }
4020/// \f]
4021/// 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)`.
4022/// The exact likelihood used is the Poisson likelihood described in this paper:
4023/// S. Baker and R. D. Cousins, “Clarification of the use of chi-square and likelihood functions in fits to histograms,”
4024/// Nucl. Instrum. Meth. 221 (1984) 437.
4025///
4026/// \f[
4027/// NLL = \sum_{i}{( f(x(i) | p ) + y(i)\log(y(i)/ f(x(i) | p )) - y(i)) }
4028/// \f]
4029/// By using this formulation, `2*NLL` can be interpreted as the chi-square resulting from the fit.
4030///
4031/// This method should be always used when the bin content represents counts (i.e. errors are sqrt(N) ).
4032/// The likelihood method has the advantage of treating correctly bins with low statistics. In case of high
4033/// statistics/bin the distribution of the bin content becomes a normal distribution and the likelihood and the chi2 fit
4034/// give the same result.
4035///
4036/// The likelihood method, although a bit slower, it is therefore the recommended method,
4037/// when the histogram represent counts (Poisson statistics), where the chi-square methods may
4038/// give incorrect results, especially in case of low statistics.
4039/// In case of a weighted histogram, it is possible to perform also a likelihood fit by using the
4040/// option "WL". Note a weighted histogram is a histogram which has been filled with weights and it
4041/// has the information on the sum of the weight square for each bin ( TH1::Sumw2() has been called).
4042/// The bin error for a weighted histogram is the square root of the sum of the weight square.
4043///
4044/// \anchor HFitRes
4045/// ### Fit Result
4046///
4047/// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
4048/// By default the TFitResultPtr contains only the status of the fit which is return by an
4049/// automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
4050///
4051/// ~~~ {.cpp}
4052/// Int_t fitStatus = h->Fit(myFunc);
4053/// ~~~
4054///
4055/// If the option "S" is instead used, TFitResultPtr behaves as a smart
4056/// pointer to the TFitResult object. This is useful for retrieving the full result information from the fit, such as the covariance matrix,
4057/// as shown in this example code:
4058///
4059/// ~~~ {.cpp}
4060/// TFitResultPtr r = h->Fit(myFunc,"S");
4061/// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
4062/// Double_t chi2 = r->Chi2(); // to retrieve the fit chi2
4063/// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
4064/// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
4065/// r->Print("V"); // print full information of fit including covariance matrix
4066/// r->Write(); // store the result in a file
4067/// ~~~
4068///
4069/// The fit parameters, error and chi-square (but not covariance matrix) can be retrieved also
4070/// directly from the fitted function that is passed to this call.
4071/// Given a pointer to an associated fitted function `myfunc`, one can retrieve the function/fit
4072/// parameters with calls such as:
4073///
4074/// ~~~ {.cpp}
4075/// Double_t chi2 = myfunc->GetChisquare();
4076/// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
4077/// Double_t err0 = myfunc->GetParError(0); //error on first parameter
4078/// ~~~
4079///
4080/// ##### Associated functions
4081///
4082/// One or more objects (typically a TF1*) can be added to the list
4083/// of functions (fFunctions) associated to each histogram.
4084/// When TH1::Fit is invoked, the fitted function is added to the histogram list of functions (fFunctions).
4085/// If the histogram is made persistent, the list of associated functions is also persistent.
4086/// Given a histogram h, one can retrieve an associated function with:
4087///
4088/// ~~~ {.cpp}
4089/// TF1 *myfunc = h->GetFunction("myfunc");
4090/// ~~~
4091/// or by quering directly the list obtained by calling `TH1::GetListOfFunctions`.
4092///
4093/// \anchor HFitStatus
4094/// ### Fit status
4095///
4096/// The status of the fit is obtained converting the TFitResultPtr to an integer
4097/// independently if the fit option "S" is used or not:
4098///
4099/// ~~~ {.cpp}
4100/// TFitResultPtr r = h->Fit(myFunc,opt);
4101/// Int_t fitStatus = r;
4102/// ~~~
4103///
4104/// - `status = 0` : the fit has been performed successfully (i.e no error occurred).
4105/// - `status < 0` : there is an error not connected with the minimization procedure, for example when a wrong function is used.
4106/// - `status > 0` : return status from Minimizer, depends on used Minimizer. For example for TMinuit and Minuit2 we have:
4107/// - `status = migradStatus + 10*minosStatus + 100*hesseStatus + 1000*improveStatus`.
4108/// 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
4109/// only in Minos but not in Migrad a fitStatus of 40 will be returned.
4110/// Minuit2 returns 0 in case of success and different values in migrad,minos or
4111/// hesse depending on the error. See in this case the documentation of
4112/// Minuit2Minimizer::Minimize for the migrad return status, Minuit2Minimizer::GetMinosError for the
4113/// minos return status and Minuit2Minimizer::Hesse for the hesse return status.
4114/// If other minimizers are used see their specific documentation for the status code returned.
4115/// For example in the case of Fumili, see TFumili::Minimize.
4116///
4117/// \anchor HFitRange
4118/// ### Fitting in a range
4119///
4120/// In order to fit in a sub-range of the histogram you have two options:
4121/// - pass to this function the lower (`xxmin`) and upper (`xxmax`) values for the fitting range;
4122/// - define a specific range in the fitted function and use the fitting option "R".
4123/// For example, if your histogram has a defined range between -4 and 4 and you want to fit a gaussian
4124/// only in the interval 1 to 3, you can do:
4125///
4126/// ~~~ {.cpp}
4127/// TF1 *f1 = new TF1("f1", "gaus", 1, 3);
4128/// histo->Fit("f1", "R");
4129/// ~~~
4130///
4131/// The fitting range is also limited by the histogram range defined using TAxis::SetRange
4132/// or TAxis::SetRangeUser. Therefore the fitting range is the smallest range between the
4133/// histogram one and the one defined by one of the two previous options described above.
4134///
4135/// \anchor HFitInitial
4136/// ### Setting initial conditions
4137///
4138/// Parameters must be initialized before invoking the Fit function.
4139/// The setting of the parameter initial values is automatic for the
4140/// predefined functions such as poln, expo, gaus, landau. One can however disable
4141/// this automatic computation by using the option "B".
4142/// Note that if a predefined function is defined with an argument,
4143/// eg, gaus(0), expo(1), you must specify the initial values for
4144/// the parameters.
4145/// You can specify boundary limits for some or all parameters via
4146///
4147/// ~~~ {.cpp}
4148/// f1->SetParLimits(p_number, parmin, parmax);
4149/// ~~~
4150///
4151/// if `parmin >= parmax`, the parameter is fixed
4152/// Note that you are not forced to fix the limits for all parameters.
4153/// For example, if you fit a function with 6 parameters, you can do:
4154///
4155/// ~~~ {.cpp}
4156/// func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
4157/// func->SetParLimits(3, -10, -4);
4158/// func->FixParameter(4, 0);
4159/// func->SetParLimits(5, 1, 1);
4160/// ~~~
4161///
4162/// With this setup, parameters 0->2 can vary freely
4163/// Parameter 3 has boundaries [-10,-4] with initial value -8
4164/// Parameter 4 is fixed to 0
4165/// Parameter 5 is fixed to 100.
4166/// When the lower limit and upper limit are equal, the parameter is fixed.
4167/// However to fix a parameter to 0, one must call the FixParameter function.
4168///
4169/// \anchor HFitStatBox
4170/// ### Fit Statistics Box
4171///
4172/// The statistics box can display the result of the fit.
4173/// You can change the statistics box to display the fit parameters with
4174/// the TStyle::SetOptFit(mode) method. This mode has four digits.
4175/// mode = pcev (default = 0111)
4176///
4177/// v = 1; print name/values of parameters
4178/// e = 1; print errors (if e=1, v must be 1)
4179/// c = 1; print Chisquare/Number of degrees of freedom
4180/// p = 1; print Probability
4181///
4182/// For example: gStyle->SetOptFit(1011);
4183/// prints the fit probability, parameter names/values, and errors.
4184/// You can change the position of the statistics box with these lines
4185/// (where g is a pointer to the TGraph):
4186///
4187/// TPaveStats *st = (TPaveStats*)g->GetListOfFunctions()->FindObject("stats");
4188/// st->SetX1NDC(newx1); //new x start position
4189/// st->SetX2NDC(newx2); //new x end position
4190///
4191/// \anchor HFitExtra
4192/// ### Additional Notes on Fitting
4193///
4194/// #### Fitting a histogram of dimension N with a function of dimension N-1
4195///
4196/// It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
4197/// 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.
4198/// For correct error scaling, the obtained parameter error are corrected as in the case when the
4199/// option "W" is used.
4200///
4201/// #### User defined objective functions
4202///
4203/// By default when fitting a chi square function is used for fitting. When option "L" is used
4204/// a Poisson likelihood function is used. Using option "MULTI" a multinomial likelihood fit is used.
4205/// Thes functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
4206/// are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
4207/// the file math/mathcore/src/FitUtil.cxx.
4208/// It is possible to specify a user defined fitting function, using option "U" and
4209/// calling the following functions:
4210///
4211/// ~~~ {.cpp}
4212/// TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction);
4213/// ~~~
4214///
4215/// where MyFittingFunction is of type:
4216///
4217/// ~~~ {.cpp}
4218/// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
4219/// ~~~
4220///
4221/// #### Note on treatment of empty bins
4222///
4223/// Empty bins, which have the content equal to zero AND error equal to zero,
4224/// are excluded by default from the chi-square fit, but they are considered in the likelihood fit.
4225/// since they affect the likelihood if the function value in these bins is not negligible.
4226/// Note that if the histogram is having bins with zero content and non zero-errors they are considered as
4227/// any other bins in the fit. Instead bins with zero error and non-zero content are by default excluded in the chi-squared fit.
4228/// In general, one should not fit a histogram with non-empty bins and zero errors.
4229///
4230/// 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
4231/// fit). When using option "WW" the empty bins will be also considered in the chi-square fit with an error of 1.
4232/// Note that in this fitting case (option "W" or "WW") the resulting fitted parameter errors
4233/// are corrected by the obtained chi2 value using this scaling expression:
4234/// `errorp *= sqrt(chisquare/(ndf-1))` as it is done when fitting a TGraph with
4235/// no point errors.
4236///
4237/// #### Excluding points
4238///
4239/// You can use TF1::RejectPoint inside your fitting function to exclude some points
4240/// within a certain range from the fit. See the tutorial `fit/fitExclude.C`.
4241///
4242///
4243/// #### Warning when using the option "0"
4244///
4245/// When selecting the option "0", the fitted function is added to
4246/// the list of functions of the histogram, but it is not drawn when the histogram is drawn.
4247/// You can undo this behaviour resetting its corresponding bit in the TF1 object as following:
4248///
4249/// ~~~ {.cpp}
4250/// h.Fit("myFunction", "0"); // fit, store function but do not draw
4251/// h.Draw(); // function is not drawn
4252/// h.GetFunction("myFunction")->ResetBit(TF1::kNotDraw);
4253/// h.Draw(); // function is visible again
4254/// ~~~
4256
4258{
4259 // implementation of Fit method is in file hist/src/HFitImpl.cxx
4262
4263 // create range and minimizer options with default values
4266
4267 // need to empty the buffer before
4268 // (t.b.d. do a ML unbinned fit with buffer data)
4269 if (fBuffer) BufferEmpty();
4270
4272}
4273
4274////////////////////////////////////////////////////////////////////////////////
4275/// Display a panel with all histogram fit options.
4276///
4277/// See class TFitPanel for example
4278
4279void TH1::FitPanel()
4280{
4281 if (!gPad)
4282 gROOT->MakeDefCanvas();
4283
4284 if (!gPad) {
4285 Error("FitPanel", "Unable to create a default canvas");
4286 return;
4287 }
4288
4289
4290 // use plugin manager to create instance of TFitEditor
4291 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
4292 if (handler && handler->LoadPlugin() != -1) {
4293 if (handler->ExecPlugin(2, gPad, this) == 0)
4294 Error("FitPanel", "Unable to create the FitPanel");
4295 }
4296 else
4297 Error("FitPanel", "Unable to find the FitPanel plug-in");
4298}
4299
4300////////////////////////////////////////////////////////////////////////////////
4301/// Return a histogram containing the asymmetry of this histogram with h2,
4302/// where the asymmetry is defined as:
4303///
4304/// ~~~ {.cpp}
4305/// Asymmetry = (h1 - h2)/(h1 + h2) where h1 = this
4306/// ~~~
4307///
4308/// works for 1D, 2D, etc. histograms
4309/// c2 is an optional argument that gives a relative weight between the two
4310/// histograms, and dc2 is the error on this weight. This is useful, for example,
4311/// when forming an asymmetry between two histograms from 2 different data sets that
4312/// need to be normalized to each other in some way. The function calculates
4313/// the errors assuming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
4314///
4315/// example: assuming 'h1' and 'h2' are already filled
4316///
4317/// ~~~ {.cpp}
4318/// h3 = h1->GetAsymmetry(h2)
4319/// ~~~
4320///
4321/// then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
4322/// h1 and h2 are left intact.
4323///
4324/// Note that it is the user's responsibility to manage the created histogram.
4325/// The name of the returned histogram will be `Asymmetry_nameOfh1-nameOfh2`
4326///
4327/// code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
4328///
4329/// clone the histograms so top and bottom will have the
4330/// correct dimensions:
4331/// Sumw2 just makes sure the errors will be computed properly
4332/// when we form sums and ratios below.
4333
4335{
4336 TH1 *h1 = this;
4337 TString name = TString::Format("Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4338 TH1 *asym = (TH1*)Clone(name);
4339
4340 // set also the title
4341 TString title = TString::Format("(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4342 asym->SetTitle(title);
4343
4344 asym->Sumw2();
4347 TH1 *top = (TH1*)asym->Clone();
4348 TH1 *bottom = (TH1*)asym->Clone();
4350
4351 // form the top and bottom of the asymmetry, and then divide:
4352 top->Add(h1,h2,1,-c2);
4353 bottom->Add(h1,h2,1,c2);
4354 asym->Divide(top,bottom);
4355
4356 Int_t xmax = asym->GetNbinsX();
4357 Int_t ymax = asym->GetNbinsY();
4358 Int_t zmax = asym->GetNbinsZ();
4359
4360 if (h1->fBuffer) h1->BufferEmpty(1);
4361 if (h2->fBuffer) h2->BufferEmpty(1);
4362 if (bottom->fBuffer) bottom->BufferEmpty(1);
4363
4364 // now loop over bins to calculate the correct errors
4365 // the reason this error calculation looks complex is because of c2
4366 for(Int_t i=1; i<= xmax; i++){
4367 for(Int_t j=1; j<= ymax; j++){
4368 for(Int_t k=1; k<= zmax; k++){
4369 Int_t bin = GetBin(i, j, k);
4370 // here some bin contents are written into variables to make the error
4371 // calculation a little more legible:
4373 Double_t b = h2->RetrieveBinContent(bin);
4374 Double_t bot = bottom->RetrieveBinContent(bin);
4375
4376 // make sure there are some events, if not, then the errors are set = 0
4377 // automatically.
4378 //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
4379 if(bot < 1e-6){}
4380 else{
4381 // computation of errors by Christos Leonidopoulos
4383 Double_t dbsq = h2->GetBinErrorSqUnchecked(bin);
4384 Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4385 asym->SetBinError(i,j,k,error);
4386 }
4387 }
4388 }
4389 }
4390 delete top;
4391 delete bottom;
4392
4393 return asym;
4394}
4395
4396////////////////////////////////////////////////////////////////////////////////
4397/// Static function
4398/// return the default buffer size for automatic histograms
4399/// the parameter fgBufferSize may be changed via SetDefaultBufferSize
4400
4402{
4403 return fgBufferSize;
4404}
4405
4406////////////////////////////////////////////////////////////////////////////////
4407/// Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
4408/// see TH1::SetDefaultSumw2.
4409
4411{
4412 return fgDefaultSumw2;
4413}
4414
4415////////////////////////////////////////////////////////////////////////////////
4416/// Return the current number of entries.
4417
4419{
4420 if (fBuffer) {
4421 Int_t nentries = (Int_t) fBuffer[0];
4422 if (nentries > 0) return nentries;
4423 }
4424
4425 return fEntries;
4426}
4427
4428////////////////////////////////////////////////////////////////////////////////
4429/// Number of effective entries of the histogram.
4430///
4431/// \f[
4432/// neff = \frac{(\sum Weights )^2}{(\sum Weight^2 )}
4433/// \f]
4434///
4435/// In case of an unweighted histogram this number is equivalent to the
4436/// number of entries of the histogram.
4437/// For a weighted histogram, this number corresponds to the hypothetical number of unweighted entries
4438/// a histogram would need to have the same statistical power as this weighted histogram.
4439/// Note: The underflow/overflow are included if one has set the TH1::StatOverFlows flag
4440/// and if the statistics has been computed at filling time.
4441/// If a range is set in the histogram the number is computed from the given range.
4442
4444{
4445 Stat_t s[kNstat];
4446 this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
4447 return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4448}
4449
4450////////////////////////////////////////////////////////////////////////////////
4451/// Shortcut to set the three histogram colors with a single call.
4452///
4453/// By default: linecolor = markercolor = fillcolor = -1
4454/// If a color is < 0 this method does not change the corresponding color if positive or null it set the color.
4455///
4456/// For instance:
4457/// ~~~ {.cpp}
4458/// h->SetColors(kRed, kRed);
4459/// ~~~
4460/// will set the line color and the marker color to red.
4461
4463{
4464 if (linecolor >= 0)
4466 if (markercolor >= 0)
4468 if (fillcolor >= 0)
4470}
4471
4472
4473////////////////////////////////////////////////////////////////////////////////
4474/// Set highlight (enable/disable) mode for the histogram
4475/// by default highlight mode is disable
4476
4477void TH1::SetHighlight(Bool_t set)
4478{
4479 if (IsHighlight() == set)
4480 return;
4481 if (fDimension > 2) {
4482 Info("SetHighlight", "Supported only 1-D or 2-D histograms");
4483 return;
4484 }
4485
4486 SetBit(kIsHighlight, set);
4487
4488 if (fPainter)
4490}
4491
4492////////////////////////////////////////////////////////////////////////////////
4493/// Redefines TObject::GetObjectInfo.
4494/// Displays the histogram info (bin number, contents, integral up to bin
4495/// corresponding to cursor position px,py
4496
4497char *TH1::GetObjectInfo(Int_t px, Int_t py) const
4498{
4499 return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
4500}
4501
4502////////////////////////////////////////////////////////////////////////////////
4503/// Return pointer to painter.
4504/// If painter does not exist, it is created
4505
4507{
4508 if (!fPainter) {
4509 TString opt = option;
4510 opt.ToLower();
4511 if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
4512 //try to create TGLHistPainter
4513 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
4514
4515 if (handler && handler->LoadPlugin() != -1)
4516 fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
4517 }
4518 }
4519
4521
4522 return fPainter;
4523}
4524
4525////////////////////////////////////////////////////////////////////////////////
4526/// Compute Quantiles for this histogram.
4527/// A quantile x_p := Q(p) is defined as the value x_p such that the cumulative
4528/// probability distribution Function F of variable X yields:
4529///
4530/// ~~~ {.cpp}
4531/// F(x_p) = Pr(X <= x_p) = p with 0 <= p <= 1.
4532/// x_p = Q(p) = F_inv(p)
4533/// ~~~
4534///
4535/// For instance the median x_0.5 of a distribution is defined as that value
4536/// of the random variable X for which the distribution function equals 0.5:
4537///
4538/// ~~~ {.cpp}
4539/// F(x_0.5) = Probability(X < x_0.5) = 0.5
4540/// x_0.5 = Q(0.5)
4541/// ~~~
4542///
4543/// \author Eddy Offermann
4544/// code from Eddy Offermann, Renaissance
4545///
4546/// \param[in] n maximum size of the arrays xp and p (if given)
4547/// \param[out] xp array to be filled with nq quantiles evaluated at (p). Memory has to be preallocated by caller.
4548/// - If `p == nullptr`, the quantiles are computed at the (first `n`) probabilities p given by the CDF of the histogram;
4549/// `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`.
4550/// If all bins have non-zero entries, the quantiles happen to be the bin centres.
4551/// Empty bins will, however, be skipped in the quantiles.
4552/// If the CDF is e.g. [0., 0., 0.1, ...], the quantiles would be, [3., 3., 3., ...], with the third bin starting
4553/// at 3.
4554/// \param[in] p array of cumulative probabilities where quantiles should be evaluated.
4555/// - if `p == nullptr`, the CDF of the histogram will be used to compute the quantiles, and will
4556/// have a size of n.
4557/// - Otherwise, it is assumed to contain at least n values.
4558/// \return number of quantiles computed
4559/// \note Unlike in TF1::GetQuantiles, `p` is here an optional argument
4560///
4561/// Note that the Integral of the histogram is automatically recomputed
4562/// if the number of entries is different of the number of entries when
4563/// the integral was computed last time. In case you do not use the Fill
4564/// functions to fill your histogram, but SetBinContent, you must call
4565/// TH1::ComputeIntegral before calling this function.
4566///
4567/// Getting quantiles xp from two histograms and storing results in a TGraph,
4568/// a so-called QQ-plot
4569///
4570/// ~~~ {.cpp}
4571/// TGraph *gr = new TGraph(nprob);
4572/// h1->GetQuantiles(nprob,gr->GetX());
4573/// h2->GetQuantiles(nprob,gr->GetY());
4574/// gr->Draw("alp");
4575/// ~~~
4576///
4577/// Example:
4578///
4579/// ~~~ {.cpp}
4580/// void quantiles() {
4581/// // demo for quantiles
4582/// const Int_t nq = 20;
4583/// TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
4584/// h->FillRandom("gaus",5000);
4585/// h->GetXaxis()->SetTitle("x");
4586/// h->GetYaxis()->SetTitle("Counts");
4587///
4588/// Double_t p[nq]; // probabilities where to evaluate the quantiles in [0,1]
4589/// Double_t xp[nq]; // array of positions X to store the resulting quantiles
4590/// for (Int_t i=0;i<nq;i++) p[i] = Float_t(i+1)/nq;
4591/// h->GetQuantiles(nq,xp,p);
4592///
4593/// //show the original histogram in the top pad
4594/// TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
4595/// c1->Divide(1,2);
4596/// c1->cd(1);
4597/// h->Draw();
4598///
4599/// // show the quantiles in the bottom pad
4600/// c1->cd(2);
4601/// gPad->SetGrid();
4602/// TGraph *gr = new TGraph(nq,p,xp);
4603/// gr->SetMarkerStyle(21);
4604/// gr->GetXaxis()->SetTitle("p");
4605/// gr->GetYaxis()->SetTitle("x");
4606/// gr->Draw("alp");
4607/// }
4608/// ~~~
4609
4611{
4612 if (GetDimension() > 1) {
4613 Error("GetQuantiles","Only available for 1-d histograms");
4614 return 0;
4615 }
4616
4617 const Int_t nbins = GetXaxis()->GetNbins();
4618 if (!fIntegral) ComputeIntegral();
4619 if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4620
4621 Int_t i, ibin;
4622 Int_t nq = n;
4623 std::unique_ptr<Double_t[]> localProb;
4624 if (p == nullptr) {
4625 nq = nbins+1;
4626 localProb.reset(new Double_t[nq]);
4627 localProb[0] = 0;
4628 for (i=1;i<nq;i++) {
4629 localProb[i] = fIntegral[i] / fIntegral[nbins];
4630 }
4631 }
4632 Double_t const *const prob = p ? p : localProb.get();
4633
4634 for (i = 0; i < nq; i++) {
4636 if (fIntegral[ibin] == prob[i]) {
4637 if (prob[i] == 0.) {
4638 for (; ibin+1 <= nbins && fIntegral[ibin+1] == 0.; ++ibin) {
4639
4640 }
4641 xp[i] = fXaxis.GetBinUpEdge(ibin);
4642 }
4643 else if (prob[i] == 1.) {
4644 xp[i] = fXaxis.GetBinUpEdge(ibin);
4645 }
4646 else {
4647 // Find equal integral in later bins (ie their entries are zero)
4648 Double_t width = 0;
4649 for (Int_t j = ibin+1; j <= nbins; ++j) {
4650 if (prob[i] == fIntegral[j]) {
4652 }
4653 else
4654 break;
4655 }
4657 }
4658 }
4659 else {
4660 xp[i] = GetBinLowEdge(ibin+1);
4662 if (dint > 0) xp[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4663 }
4664 }
4665
4666 return nq;
4667}
4668
4669////////////////////////////////////////////////////////////////////////////////
4675 return 1;
4676}
4677
4678////////////////////////////////////////////////////////////////////////////////
4679/// Compute Initial values of parameters for a gaussian.
4680
4681void H1InitGaus()
4682{
4683 Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4684 Int_t bin;
4685 const Double_t sqrtpi = 2.506628;
4686
4687 // - Compute mean value and StdDev of the histogram in the given range
4689 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4690 Int_t hxfirst = hFitter->GetXfirst();
4691 Int_t hxlast = hFitter->GetXlast();
4692 Double_t valmax = curHist->GetBinContent(hxfirst);
4693 Double_t binwidx = curHist->GetBinWidth(hxfirst);
4694 allcha = sumx = sumx2 = 0;
4695 for (bin=hxfirst;bin<=hxlast;bin++) {
4696 x = curHist->GetBinCenter(bin);
4697 val = TMath::Abs(curHist->GetBinContent(bin));
4698 if (val > valmax) valmax = val;
4699 sumx += val*x;
4700 sumx2 += val*x*x;
4701 allcha += val;
4702 }
4703 if (allcha == 0) return;
4704 mean = sumx/allcha;
4705 stddev = sumx2/allcha - mean*mean;
4706 if (stddev > 0) stddev = TMath::Sqrt(stddev);
4707 else stddev = 0;
4708 if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4709 //if the distribution is really gaussian, the best approximation
4710 //is binwidx*allcha/(sqrtpi*stddev)
4711 //However, in case of non-gaussian tails, this underestimates
4712 //the normalisation constant. In this case the maximum value
4713 //is a better approximation.
4714 //We take the average of both quantities
4716
4717 //In case the mean value is outside the histo limits and
4718 //the StdDev is bigger than the range, we take
4719 // mean = center of bins
4720 // stddev = half range
4721 Double_t xmin = curHist->GetXaxis()->GetXmin();
4722 Double_t xmax = curHist->GetXaxis()->GetXmax();
4723 if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4724 mean = 0.5*(xmax+xmin);
4725 stddev = 0.5*(xmax-xmin);
4726 }
4727 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4729 f1->SetParameter(1,mean);
4731 f1->SetParLimits(2,0,10*stddev);
4732}
4733
4734////////////////////////////////////////////////////////////////////////////////
4735/// Compute Initial values of parameters for an exponential.
4736
4737void H1InitExpo()
4738{
4740 Int_t ifail;
4742 Int_t hxfirst = hFitter->GetXfirst();
4743 Int_t hxlast = hFitter->GetXlast();
4744 Int_t nchanx = hxlast - hxfirst + 1;
4745
4747
4748 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4750 f1->SetParameter(1,slope);
4751
4752}
4753
4754////////////////////////////////////////////////////////////////////////////////
4755/// Compute Initial values of parameters for a polynom.
4756
4757void H1InitPolynom()
4758{
4759 Double_t fitpar[25];
4760
4762 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4763 Int_t hxfirst = hFitter->GetXfirst();
4764 Int_t hxlast = hFitter->GetXlast();
4765 Int_t nchanx = hxlast - hxfirst + 1;
4766 Int_t npar = f1->GetNpar();
4767
4768 if (nchanx <=1 || npar == 1) {
4769 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4770 fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4771 } else {
4773 }
4774 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4775}
4776
4777////////////////////////////////////////////////////////////////////////////////
4778/// Least squares lpolynomial fitting without weights.
4779///
4780/// \param[in] n number of points to fit
4781/// \param[in] m number of parameters
4782/// \param[in] a array of parameters
4783///
4784/// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
4785/// (E.Keil. revised by B.Schorr, 23.10.1981.)
4786
4788{
4789 const Double_t zero = 0.;
4790 const Double_t one = 1.;
4791 const Int_t idim = 20;
4792
4793 Double_t b[400] /* was [20][20] */;
4794 Int_t i, k, l, ifail;
4796 Double_t da[20], xk, yk;
4797
4798 if (m <= 2) {
4799 H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4800 return;
4801 }
4802 if (m > idim || m > n) return;
4803 b[0] = Double_t(n);
4804 da[0] = zero;
4805 for (l = 2; l <= m; ++l) {
4806 b[l-1] = zero;
4807 b[m + l*20 - 21] = zero;
4808 da[l-1] = zero;
4809 }
4811 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4812 Int_t hxfirst = hFitter->GetXfirst();
4813 Int_t hxlast = hFitter->GetXlast();
4814 for (k = hxfirst; k <= hxlast; ++k) {
4815 xk = curHist->GetBinCenter(k);
4816 yk = curHist->GetBinContent(k);
4817 power = one;
4818 da[0] += yk;
4819 for (l = 2; l <= m; ++l) {
4820 power *= xk;
4821 b[l-1] += power;
4822 da[l-1] += power*yk;
4823 }
4824 for (l = 2; l <= m; ++l) {
4825 power *= xk;
4826 b[m + l*20 - 21] += power;
4827 }
4828 }
4829 for (i = 3; i <= m; ++i) {
4830 for (k = i; k <= m; ++k) {
4831 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4832 }
4833 }
4835
4836 for (i=0; i<m; ++i) a[i] = da[i];
4837
4838}
4839
4840////////////////////////////////////////////////////////////////////////////////
4841/// Least square linear fit without weights.
4842///
4843/// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
4844/// (added to LSQ by B. Schorr, 15.02.1982.)
4845
4847{
4849 Int_t i, n;
4851 Double_t fn, xk, yk;
4852 Double_t det;
4853
4854 n = TMath::Abs(ndata);
4855 ifail = -2;
4856 xbar = ybar = x2bar = xybar = 0;
4858 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4859 Int_t hxfirst = hFitter->GetXfirst();
4860 Int_t hxlast = hFitter->GetXlast();
4861 for (i = hxfirst; i <= hxlast; ++i) {
4862 xk = curHist->GetBinCenter(i);
4863 yk = curHist->GetBinContent(i);
4864 if (ndata < 0) {
4865 if (yk <= 0) yk = 1e-9;
4866 yk = TMath::Log(yk);
4867 }
4868 xbar += xk;
4869 ybar += yk;
4870 x2bar += xk*xk;
4871 xybar += xk*yk;
4872 }
4873 fn = Double_t(n);
4874 det = fn*x2bar - xbar*xbar;
4875 ifail = -1;
4876 if (det <= 0) {
4877 a0 = ybar/fn;
4878 a1 = 0;
4879 return;
4880 }
4881 ifail = 0;
4882 a0 = (x2bar*ybar - xbar*xybar) / det;
4883 a1 = (fn*xybar - xbar*ybar) / det;
4884
4885}
4886
4887////////////////////////////////////////////////////////////////////////////////
4888/// Extracted from CERN Program library routine DSEQN.
4889///
4890/// Translated to C++ by Rene Brun
4891
4893{
4895 Int_t nmjp1, i, j, l;
4896 Int_t im1, jp1, nm1, nmi;
4897 Double_t s1, s21, s22;
4898 const Double_t one = 1.;
4899
4900 /* Parameter adjustments */
4901 b_dim1 = idim;
4902 b_offset = b_dim1 + 1;
4903 b -= b_offset;
4904 a_dim1 = idim;
4905 a_offset = a_dim1 + 1;
4906 a -= a_offset;
4907
4908 if (idim < n) return;
4909
4910 ifail = 0;
4911 for (j = 1; j <= n; ++j) {
4912 if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
4913 a[j + j*a_dim1] = one / a[j + j*a_dim1];
4914 if (j == n) continue;
4915 jp1 = j + 1;
4916 for (l = jp1; l <= n; ++l) {
4917 a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4918 s1 = -a[l + (j+1)*a_dim1];
4919 for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4920 a[l + (j+1)*a_dim1] = -s1;
4921 }
4922 }
4923 if (k <= 0) return;
4924
4925 for (l = 1; l <= k; ++l) {
4926 b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
4927 }
4928 if (n == 1) return;
4929 for (l = 1; l <= k; ++l) {
4930 for (i = 2; i <= n; ++i) {
4931 im1 = i - 1;
4932 s21 = -b[i + l*b_dim1];
4933 for (j = 1; j <= im1; ++j) {
4934 s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
4935 }
4936 b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
4937 }
4938 nm1 = n - 1;
4939 for (i = 1; i <= nm1; ++i) {
4940 nmi = n - i;
4941 s22 = -b[nmi + l*b_dim1];
4942 for (j = 1; j <= i; ++j) {
4943 nmjp1 = n - j + 1;
4944 s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
4945 }
4946 b[nmi + l*b_dim1] = -s22;
4947 }
4948 }
4949}
4950
4951////////////////////////////////////////////////////////////////////////////////
4952/// Return Global bin number corresponding to binx,y,z.
4953///
4954/// 2-D and 3-D histograms are represented with a one dimensional
4955/// structure.
4956/// This has the advantage that all existing functions, such as
4957/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
4958///
4959/// In case of a TH1x, returns binx directly.
4960/// see TH1::GetBinXYZ for the inverse transformation.
4961///
4962/// Convention for numbering bins
4963///
4964/// For all histogram types: nbins, xlow, xup
4965///
4966/// - bin = 0; underflow bin
4967/// - bin = 1; first bin with low-edge xlow INCLUDED
4968/// - bin = nbins; last bin with upper-edge xup EXCLUDED
4969/// - bin = nbins+1; overflow bin
4970///
4971/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4972/// For example, assuming a 3-D histogram with binx,biny,binz, the function
4973///
4974/// ~~~ {.cpp}
4975/// Int_t bin = h->GetBin(binx,biny,binz);
4976/// ~~~
4977///
4978/// returns a global/linearized bin number. This global bin is useful
4979/// to access the bin information independently of the dimension.
4980
4982{
4983 Int_t ofx = fXaxis.GetNbins() + 1; // overflow bin
4984 if (binx < 0) binx = 0;
4985 if (binx > ofx) binx = ofx;
4986
4987 return binx;
4988}
4989
4990////////////////////////////////////////////////////////////////////////////////
4991/// Return binx, biny, binz corresponding to the global bin number globalbin
4992/// see TH1::GetBin function above
4993
4995{
4996 Int_t nx = fXaxis.GetNbins()+2;
4997 Int_t ny = fYaxis.GetNbins()+2;
4998
4999 if (GetDimension() == 1) {
5000 binx = binglobal%nx;
5001 biny = 0;
5002 binz = 0;
5003 return;
5004 }
5005 if (GetDimension() == 2) {
5006 binx = binglobal%nx;
5007 biny = ((binglobal-binx)/nx)%ny;
5008 binz = 0;
5009 return;
5010 }
5011 if (GetDimension() == 3) {
5012 binx = binglobal%nx;
5013 biny = ((binglobal-binx)/nx)%ny;
5014 binz = ((binglobal-binx)/nx -biny)/ny;
5015 }
5016}
5017
5018////////////////////////////////////////////////////////////////////////////////
5019/// Return a random number distributed according the histogram bin contents.
5020/// This function checks if the bins integral exists. If not, the integral
5021/// is evaluated, normalized to one.
5022///
5023/// @param rng (optional) Random number generator pointer used (default is gRandom)
5024/// @param option (optional) Set it to "width" if your non-uniform bin contents represent a density rather than counts
5025///
5026/// The integral is automatically recomputed if the number of entries
5027/// is not the same then when the integral was computed.
5028/// @note Only valid for 1-d histograms. Use GetRandom2 or GetRandom3 otherwise.
5029/// If the histogram has a bin with negative content, a NaN is returned.
5030
5032{
5033 if (fDimension > 1) {
5034 Error("GetRandom","Function only valid for 1-d histograms");
5035 return 0;
5036 }
5038 Double_t integral = 0;
5039 // compute integral checking that all bins have positive content (see ROOT-5894)
5040 if (fIntegral) {
5041 if (fIntegral[nbinsx + 1] != fEntries)
5042 integral = const_cast<TH1 *>(this)->ComputeIntegral(true, option);
5043 else integral = fIntegral[nbinsx];
5044 } else {
5045 integral = const_cast<TH1 *>(this)->ComputeIntegral(true, option);
5046 }
5047 if (integral == 0) return 0;
5048 // return a NaN in case some bins have negative content
5049 if (integral == TMath::QuietNaN() ) return TMath::QuietNaN();
5050
5051 Double_t r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
5054 if (r1 > fIntegral[ibin]) x +=
5056 return x;
5057}
5058
5059////////////////////////////////////////////////////////////////////////////////
5060/// Return content of bin number bin.
5061///
5062/// Implemented in TH1C,S,F,D
5063///
5064/// Convention for numbering bins
5065///
5066/// For all histogram types: nbins, xlow, xup
5067///
5068/// - bin = 0; underflow bin
5069/// - bin = 1; first bin with low-edge xlow INCLUDED
5070/// - bin = nbins; last bin with upper-edge xup EXCLUDED
5071/// - bin = nbins+1; overflow bin
5072///
5073/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
5074/// For example, assuming a 3-D histogram with binx,biny,binz, the function
5075///
5076/// ~~~ {.cpp}
5077/// Int_t bin = h->GetBin(binx,biny,binz);
5078/// ~~~
5079///
5080/// returns a global/linearized bin number. This global bin is useful
5081/// to access the bin information independently of the dimension.
5082
5084{
5085 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
5086 if (bin < 0) bin = 0;
5087 if (bin >= fNcells) bin = fNcells-1;
5088
5089 return RetrieveBinContent(bin);
5090}
5091
5092////////////////////////////////////////////////////////////////////////////////
5093/// Compute first binx in the range [firstx,lastx] for which
5094/// diff = abs(bin_content-c) <= maxdiff
5095///
5096/// In case several bins in the specified range with diff=0 are found
5097/// the first bin found is returned in binx.
5098/// In case several bins in the specified range satisfy diff <=maxdiff
5099/// the bin with the smallest difference is returned in binx.
5100/// In all cases the function returns the smallest difference.
5101///
5102/// NOTE1: if firstx <= 0, firstx is set to bin 1
5103/// if (lastx < firstx then firstx is set to the number of bins
5104/// ie if firstx=0 and lastx=0 (default) the search is on all bins.
5105///
5106/// NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
5107
5109{
5110 if (fDimension > 1) {
5111 binx = 0;
5112 Error("GetBinWithContent","function is only valid for 1-D histograms");
5113 return 0;
5114 }
5115
5116 if (fBuffer) ((TH1*)this)->BufferEmpty();
5117
5118 if (firstx <= 0) firstx = 1;
5119 if (lastx < firstx) lastx = fXaxis.GetNbins();
5120 Int_t binminx = 0;
5121 Double_t diff, curmax = 1.e240;
5122 for (Int_t i=firstx;i<=lastx;i++) {
5124 if (diff <= 0) {binx = i; return diff;}
5125 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
5126 }
5127 binx = binminx;
5128 return curmax;
5129}
5130
5131////////////////////////////////////////////////////////////////////////////////
5132/// Given a point x, approximates the value via linear interpolation
5133/// based on the two nearest bin centers
5134///
5135/// Andy Mastbaum 10/21/08
5136
5138{
5139 if (fBuffer) ((TH1*)this)->BufferEmpty();
5140
5142 Double_t x0,x1,y0,y1;
5143
5144 if(x<=GetBinCenter(1)) {
5145 return RetrieveBinContent(1);
5146 } else if(x>=GetBinCenter(GetNbinsX())) {
5147 return RetrieveBinContent(GetNbinsX());
5148 } else {
5149 if(x<=GetBinCenter(xbin)) {
5151 x0 = GetBinCenter(xbin-1);
5153 x1 = GetBinCenter(xbin);
5154 } else {
5156 x0 = GetBinCenter(xbin);
5158 x1 = GetBinCenter(xbin+1);
5159 }
5160 return y0 + (x-x0)*((y1-y0)/(x1-x0));
5161 }
5162}
5163
5164////////////////////////////////////////////////////////////////////////////////
5165/// 2d Interpolation. Not yet implemented.
5166
5168{
5169 Error("Interpolate","This function must be called with 1 argument for a TH1");
5170 return 0;
5171}
5172
5173////////////////////////////////////////////////////////////////////////////////
5174/// 3d Interpolation. Not yet implemented.
5175
5177{
5178 Error("Interpolate","This function must be called with 1 argument for a TH1");
5179 return 0;
5180}
5181
5182///////////////////////////////////////////////////////////////////////////////
5183/// Check if a histogram is empty
5184/// (this is a protected method used mainly by TH1Merger )
5185
5186Bool_t TH1::IsEmpty() const
5187{
5188 // if fTsumw or fentries are not zero histogram is not empty
5189 // need to use GetEntries() instead of fEntries in case of bugger histograms
5190 // so we will flash the buffer
5191 if (fTsumw != 0) return kFALSE;
5192 if (GetEntries() != 0) return kFALSE;
5193 // case fTSumw == 0 amd entries are also zero
5194 // this should not really happening, but if one sets content by hand
5195 // it can happen. a call to ResetStats() should be done in such cases
5196 double sumw = 0;
5197 for (int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
5198 return (sumw != 0) ? kFALSE : kTRUE;
5199}
5200
5201////////////////////////////////////////////////////////////////////////////////
5202/// Return true if the bin is overflow.
5203
5205{
5206 Int_t binx, biny, binz;
5207 GetBinXYZ(bin, binx, biny, binz);
5208
5209 if (iaxis == 0) {
5210 if ( fDimension == 1 )
5211 return binx >= GetNbinsX() + 1;
5212 if ( fDimension == 2 )
5213 return (binx >= GetNbinsX() + 1) ||
5214 (biny >= GetNbinsY() + 1);
5215 if ( fDimension == 3 )
5216 return (binx >= GetNbinsX() + 1) ||
5217 (biny >= GetNbinsY() + 1) ||
5218 (binz >= GetNbinsZ() + 1);
5219 return kFALSE;
5220 }
5221 if (iaxis == 1)
5222 return binx >= GetNbinsX() + 1;
5223 if (iaxis == 2)
5224 return biny >= GetNbinsY() + 1;
5225 if (iaxis == 3)
5226 return binz >= GetNbinsZ() + 1;
5227
5228 Error("IsBinOverflow","Invalid axis value");
5229 return kFALSE;
5230}
5231
5232////////////////////////////////////////////////////////////////////////////////
5233/// Return true if the bin is underflow.
5234/// If iaxis = 0 make OR with all axes otherwise check only for the given axis
5235
5237{
5238 Int_t binx, biny, binz;
5239 GetBinXYZ(bin, binx, biny, binz);
5240
5241 if (iaxis == 0) {
5242 if ( fDimension == 1 )
5243 return (binx <= 0);
5244 else if ( fDimension == 2 )
5245 return (binx <= 0 || biny <= 0);
5246 else if ( fDimension == 3 )
5247 return (binx <= 0 || biny <= 0 || binz <= 0);
5248 else
5249 return kFALSE;
5250 }
5251 if (iaxis == 1)
5252 return (binx <= 0);
5253 if (iaxis == 2)
5254 return (biny <= 0);
5255 if (iaxis == 3)
5256 return (binz <= 0);
5257
5258 Error("IsBinUnderflow","Invalid axis value");
5259 return kFALSE;
5260}
5261
5262////////////////////////////////////////////////////////////////////////////////
5263/// Reduce the number of bins for the axis passed in the option to the number of bins having a label.
5264/// The method will remove only the extra bins existing after the last "labeled" bin.
5265/// Note that if there are "un-labeled" bins present between "labeled" bins they will not be removed
5266
5268{
5270 TAxis *axis = nullptr;
5271 if (iaxis == 1) axis = GetXaxis();
5272 if (iaxis == 2) axis = GetYaxis();
5273 if (iaxis == 3) axis = GetZaxis();
5274 if (!axis) {
5275 Error("LabelsDeflate","Invalid axis option %s",ax);
5276 return;
5277 }
5278 if (!axis->GetLabels()) return;
5279
5280 // find bin with last labels
5281 // bin number is object ID in list of labels
5282 // therefore max bin number is number of bins of the deflated histograms
5283 TIter next(axis->GetLabels());
5284 TObject *obj;
5285 Int_t nbins = 0;
5286 while ((obj = next())) {
5287 Int_t ibin = obj->GetUniqueID();
5288 if (ibin > nbins) nbins = ibin;
5289 }
5290 if (nbins < 1) nbins = 1;
5291
5292 // Do nothing in case it was the last bin
5293 if (nbins==axis->GetNbins()) return;
5294
5295 TH1 *hold = (TH1*)IsA()->New();
5296 R__ASSERT(hold);
5297 hold->SetDirectory(nullptr);
5298 Copy(*hold);
5299
5300 Bool_t timedisp = axis->GetTimeDisplay();
5301 Double_t xmin = axis->GetXmin();
5302 Double_t xmax = axis->GetBinUpEdge(nbins);
5303 if (xmax <= xmin) xmax = xmin +nbins;
5304 axis->SetRange(0,0);
5305 axis->Set(nbins,xmin,xmax);
5306 SetBinsLength(-1); // reset the number of cells
5308 if (errors) fSumw2.Set(fNcells);
5309 axis->SetTimeDisplay(timedisp);
5310 // reset histogram content
5311 Reset("ICE");
5312
5313 //now loop on all bins and refill
5314 // NOTE that if the bins without labels have content
5315 // it will be put in the underflow/overflow.
5316 // For this reason we use AddBinContent method
5318 Int_t bin,binx,biny,binz;
5319 for (bin=0; bin < hold->fNcells; ++bin) {
5320 hold->GetBinXYZ(bin,binx,biny,binz);
5322 Double_t cu = hold->RetrieveBinContent(bin);
5324 if (errors) {
5325 fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5326 }
5327 }
5329 delete hold;
5330}
5331
5332////////////////////////////////////////////////////////////////////////////////
5333/// Double the number of bins for axis.
5334/// Refill histogram.
5335/// This function is called by TAxis::FindBin(const char *label)
5336
5338{
5340 TAxis *axis = nullptr;
5341 if (iaxis == 1) axis = GetXaxis();
5342 if (iaxis == 2) axis = GetYaxis();
5343 if (iaxis == 3) axis = GetZaxis();
5344 if (!axis) return;
5345
5346 TH1 *hold = (TH1*)IsA()->New();
5347 hold->SetDirectory(nullptr);
5348 Copy(*hold);
5349 hold->ResetBit(kMustCleanup);
5350
5351 Bool_t timedisp = axis->GetTimeDisplay();
5352 Int_t nbins = axis->GetNbins();
5353 Double_t xmin = axis->GetXmin();
5354 Double_t xmax = axis->GetXmax();
5355 xmax = xmin + 2*(xmax-xmin);
5356 axis->SetRange(0,0);
5357 // double the bins and recompute ncells
5358 axis->Set(2*nbins,xmin,xmax);
5359 SetBinsLength(-1);
5361 if (errors) fSumw2.Set(fNcells);
5362 axis->SetTimeDisplay(timedisp);
5363
5364 Reset("ICE"); // reset content and error
5365
5366 //now loop on all bins and refill
5368 Int_t bin,ibin,binx,biny,binz;
5369 for (ibin =0; ibin < hold->fNcells; ibin++) {
5370 // get the binx,y,z values . The x-y-z (axis) bin values will stay the same between new-old after the expanding
5371 hold->GetBinXYZ(ibin,binx,biny,binz);
5372 bin = GetBin(binx,biny,binz);
5373
5374 // underflow and overflow will be cleaned up because their meaning has been altered
5375 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5376 continue;
5377 }
5378 else {
5379 AddBinContent(bin, hold->RetrieveBinContent(ibin));
5380 if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5381 }
5382 }
5384 delete hold;
5385}
5386
5387////////////////////////////////////////////////////////////////////////////////
5388/// Sort bins with labels or set option(s) to draw axis with labels
5389/// \param[in] option
5390/// - "a" sort by alphabetic order
5391/// - ">" sort by decreasing values
5392/// - "<" sort by increasing values
5393/// - "h" draw labels horizontal
5394/// - "v" draw labels vertical
5395/// - "u" draw labels up (end of label right adjusted)
5396/// - "d" draw labels down (start of label left adjusted)
5397///
5398/// In case not all bins have labels sorting will work only in the case
5399/// the first `n` consecutive bins have all labels and sorting will be performed on
5400/// those label bins.
5401///
5402/// \param[in] ax axis
5403
5405{
5407 TAxis *axis = nullptr;
5408 if (iaxis == 1)
5409 axis = GetXaxis();
5410 if (iaxis == 2)
5411 axis = GetYaxis();
5412 if (iaxis == 3)
5413 axis = GetZaxis();
5414 if (!axis)
5415 return;
5416 THashList *labels = axis->GetLabels();
5417 if (!labels) {
5418 Warning("LabelsOption", "Axis %s has no labels!",axis->GetName());
5419 return;
5420 }
5421 TString opt = option;
5422 opt.ToLower();
5423 Int_t iopt = -1;
5424 if (opt.Contains("h")) {
5429 iopt = 0;
5430 }
5431 if (opt.Contains("v")) {
5436 iopt = 1;
5437 }
5438 if (opt.Contains("u")) {
5439 axis->SetBit(TAxis::kLabelsUp);
5443 iopt = 2;
5444 }
5445 if (opt.Contains("d")) {
5450 iopt = 3;
5451 }
5452 Int_t sort = -1;
5453 if (opt.Contains("a"))
5454 sort = 0;
5455 if (opt.Contains(">"))
5456 sort = 1;
5457 if (opt.Contains("<"))
5458 sort = 2;
5459 if (sort < 0) {
5460 if (iopt < 0)
5461 Error("LabelsOption", "%s is an invalid label placement option!",opt.Data());
5462 return;
5463 }
5464
5465 // Code works only if first n bins have labels if we uncomment following line
5466 // but we don't want to support this special case
5467 // Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5468
5469 // support only cases where each bin has a labels (should be when axis is alphanumeric)
5470 Int_t n = labels->GetSize();
5471 if (n != axis->GetNbins()) {
5472 // check if labels are all consecutive and starts from the first bin
5473 // in that case the current code will work fine
5474 Int_t firstLabelBin = axis->GetNbins()+1;
5475 Int_t lastLabelBin = -1;
5476 for (Int_t i = 0; i < n; ++i) {
5477 Int_t bin = labels->At(i)->GetUniqueID();
5478 if (bin < firstLabelBin) firstLabelBin = bin;
5479 if (bin > lastLabelBin) lastLabelBin = bin;
5480 }
5481 if (firstLabelBin != 1 || lastLabelBin-firstLabelBin +1 != n) {
5482 Error("LabelsOption", "%s of Histogram %s contains bins without labels. Sorting will not work correctly - return",
5483 axis->GetName(), GetName());
5484 return;
5485 }
5486 // case where label bins are consecutive starting from first bin will work
5487 // calling before a TH1::LabelsDeflate() will avoid this error message
5488 Warning("LabelsOption", "axis %s of Histogram %s has extra following bins without labels. Sorting will work only for first label bins",
5489 axis->GetName(), GetName());
5490 }
5491 std::vector<Int_t> a(n);
5492 std::vector<Int_t> b(n);
5493
5494
5495 Int_t i, j, k;
5496 std::vector<Double_t> cont;
5497 std::vector<Double_t> errors2;
5498 THashList *labold = new THashList(labels->GetSize(), 1);
5499 TIter nextold(labels);
5500 TObject *obj = nullptr;
5501 labold->AddAll(labels);
5502 labels->Clear();
5503
5504 // delete buffer if it is there since bins will be reordered.
5505 if (fBuffer)
5506 BufferEmpty(1);
5507
5508 if (sort > 0) {
5509 //---sort by values of bins
5510 if (GetDimension() == 1) {
5511 cont.resize(n);
5512 if (fSumw2.fN)
5513 errors2.resize(n);
5514 for (i = 0; i < n; i++) {
5515 cont[i] = RetrieveBinContent(i + 1);
5516 if (!errors2.empty())
5517 errors2[i] = GetBinErrorSqUnchecked(i + 1);
5518 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5519 a[i] = i;
5520 }
5521 if (sort == 1)
5522 TMath::Sort(n, cont.data(), a.data(), kTRUE); // sort by decreasing values
5523 else
5524 TMath::Sort(n, cont.data(), a.data(), kFALSE); // sort by increasing values
5525 for (i = 0; i < n; i++) {
5526 // use UpdateBinCOntent to not screw up histogram entries
5527 UpdateBinContent(i + 1, cont[b[a[i]] - 1]); // b[a[i]] returns bin number. .we need to subtract 1
5528 if (gDebug)
5529 Info("LabelsOption","setting bin %d value %f from bin %d label %s at pos %d ",
5530 i+1,cont[b[a[i]] - 1],b[a[i]],labold->At(a[i])->GetName(),a[i]);
5531 if (!errors2.empty())
5532 fSumw2.fArray[i + 1] = errors2[b[a[i]] - 1];
5533 }
5534 for (i = 0; i < n; i++) {
5535 obj = labold->At(a[i]);
5536 labels->Add(obj);
5537 obj->SetUniqueID(i + 1);
5538 }
5539 } else if (GetDimension() == 2) {
5540 std::vector<Double_t> pcont(n + 2);
5541 Int_t nx = fXaxis.GetNbins() + 2;
5542 Int_t ny = fYaxis.GetNbins() + 2;
5543 cont.resize((nx + 2) * (ny + 2));
5544 if (fSumw2.fN)
5545 errors2.resize((nx + 2) * (ny + 2));
5546 for (i = 0; i < nx; i++) {
5547 for (j = 0; j < ny; j++) {
5548 Int_t bin = GetBin(i,j);
5549 cont[i + nx * j] = RetrieveBinContent(bin);
5550 if (!errors2.empty())
5551 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5552 if (axis == GetXaxis())
5553 k = i - 1;
5554 else
5555 k = j - 1;
5556 if (k >= 0 && k < n) { // we consider underflow/overflows in y for ordering the bins
5557 pcont[k] += cont[i + nx * j];
5558 a[k] = k;
5559 }
5560 }
5561 }
5562 if (sort == 1)
5563 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5564 else
5565 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5566 for (i = 0; i < n; i++) {
5567 // iterate on old label list to find corresponding bin match
5568 TIter next(labold);
5569 UInt_t bin = a[i] + 1;
5570 while ((obj = next())) {
5571 if (obj->GetUniqueID() == (UInt_t)bin)
5572 break;
5573 else
5574 obj = nullptr;
5575 }
5576 if (!obj) {
5577 // this should not really happen
5578 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5579 return;
5580 }
5581
5582 labels->Add(obj);
5583 if (gDebug)
5584 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from order " << a[i] << " bin "
5585 << b[a[i]] << "content " << pcont[a[i]] << std::endl;
5586 }
5587 // need to set here new ordered labels - otherwise loop before does not work since labold and labels list
5588 // contain same objects
5589 for (i = 0; i < n; i++) {
5590 labels->At(i)->SetUniqueID(i + 1);
5591 }
5592 // set now the bin contents
5593 if (axis == GetXaxis()) {
5594 for (i = 0; i < n; i++) {
5595 Int_t ix = a[i] + 1;
5596 for (j = 0; j < ny; j++) {
5597 Int_t bin = GetBin(i + 1, j);
5598 UpdateBinContent(bin, cont[ix + nx * j]);
5599 if (!errors2.empty())
5600 fSumw2.fArray[bin] = errors2[ix + nx * j];
5601 }
5602 }
5603 } else {
5604 // using y axis
5605 for (i = 0; i < nx; i++) {
5606 for (j = 0; j < n; j++) {
5607 Int_t iy = a[j] + 1;
5608 Int_t bin = GetBin(i, j + 1);
5609 UpdateBinContent(bin, cont[i + nx * iy]);
5610 if (!errors2.empty())
5611 fSumw2.fArray[bin] = errors2[i + nx * iy];
5612 }
5613 }
5614 }
5615 } else {
5616 // sorting histograms: 3D case
5617 std::vector<Double_t> pcont(n + 2);
5618 Int_t nx = fXaxis.GetNbins() + 2;
5619 Int_t ny = fYaxis.GetNbins() + 2;
5620 Int_t nz = fZaxis.GetNbins() + 2;
5621 Int_t l = 0;
5622 cont.resize((nx + 2) * (ny + 2) * (nz + 2));
5623 if (fSumw2.fN)
5624 errors2.resize((nx + 2) * (ny + 2) * (nz + 2));
5625 for (i = 0; i < nx; i++) {
5626 for (j = 0; j < ny; j++) {
5627 for (k = 0; k < nz; k++) {
5628 Int_t bin = GetBin(i,j,k);
5630 if (axis == GetXaxis())
5631 l = i - 1;
5632 else if (axis == GetYaxis())
5633 l = j - 1;
5634 else
5635 l = k - 1;
5636 if (l >= 0 && l < n) { // we consider underflow/overflows in y for ordering the bins
5637 pcont[l] += c;
5638 a[l] = l;
5639 }
5640 cont[i + nx * (j + ny * k)] = c;
5641 if (!errors2.empty())
5642 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5643 }
5644 }
5645 }
5646 if (sort == 1)
5647 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5648 else
5649 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5650 for (i = 0; i < n; i++) {
5651 // iterate on the old label list to find corresponding bin match
5652 TIter next(labold);
5653 UInt_t bin = a[i] + 1;
5654 obj = nullptr;
5655 while ((obj = next())) {
5656 if (obj->GetUniqueID() == (UInt_t)bin) {
5657 break;
5658 }
5659 else
5660 obj = nullptr;
5661 }
5662 if (!obj) {
5663 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5664 return;
5665 }
5666 labels->Add(obj);
5667 if (gDebug)
5668 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from bin " << a[i] << "content "
5669 << pcont[a[i]] << std::endl;
5670 }
5671
5672 // need to set here new ordered labels - otherwise loop before does not work since labold and llabels list
5673 // contain same objects
5674 for (i = 0; i < n; i++) {
5675 labels->At(i)->SetUniqueID(i + 1);
5676 }
5677 // set now the bin contents
5678 if (axis == GetXaxis()) {
5679 for (i = 0; i < n; i++) {
5680 Int_t ix = a[i] + 1;
5681 for (j = 0; j < ny; j++) {
5682 for (k = 0; k < nz; k++) {
5683 Int_t bin = GetBin(i + 1, j, k);
5684 UpdateBinContent(bin, cont[ix + nx * (j + ny * k)]);
5685 if (!errors2.empty())
5686 fSumw2.fArray[bin] = errors2[ix + nx * (j + ny * k)];
5687 }
5688 }
5689 }
5690 } else if (axis == GetYaxis()) {
5691 // using y axis
5692 for (i = 0; i < nx; i++) {
5693 for (j = 0; j < n; j++) {
5694 Int_t iy = a[j] + 1;
5695 for (k = 0; k < nz; k++) {
5696 Int_t bin = GetBin(i, j + 1, k);
5697 UpdateBinContent(bin, cont[i + nx * (iy + ny * k)]);
5698 if (!errors2.empty())
5699 fSumw2.fArray[bin] = errors2[i + nx * (iy + ny * k)];
5700 }
5701 }
5702 }
5703 } else {
5704 // using z axis
5705 for (i = 0; i < nx; i++) {
5706 for (j = 0; j < ny; j++) {
5707 for (k = 0; k < n; k++) {
5708 Int_t iz = a[k] + 1;
5709 Int_t bin = GetBin(i, j , k +1);
5710 UpdateBinContent(bin, cont[i + nx * (j + ny * iz)]);
5711 if (!errors2.empty())
5712 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * iz)];
5713 }
5714 }
5715 }
5716 }
5717 }
5718 } else {
5719 //---alphabetic sort
5720 // sort labels using vector of strings and TMath::Sort
5721 // I need to array because labels order in list is not necessary that of the bins
5722 std::vector<std::string> vecLabels(n);
5723 for (i = 0; i < n; i++) {
5724 vecLabels[i] = labold->At(i)->GetName();
5725 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5726 a[i] = i;
5727 }
5728 // sort in ascending order for strings
5729 TMath::Sort(n, vecLabels.data(), a.data(), kFALSE);
5730 // set the new labels
5731 for (i = 0; i < n; i++) {
5732 TObject *labelObj = labold->At(a[i]);
5733 labels->Add(labold->At(a[i]));
5734 // set the corresponding bin. NB bin starts from 1
5735 labelObj->SetUniqueID(i + 1);
5736 if (gDebug)
5737 std::cout << "bin " << i + 1 << " setting new labels for axis " << labold->At(a[i])->GetName() << " from "
5738 << b[a[i]] << std::endl;
5739 }
5740
5741 if (GetDimension() == 1) {
5742 cont.resize(n + 2);
5743 if (fSumw2.fN)
5744 errors2.resize(n + 2);
5745 for (i = 0; i < n; i++) {
5746 cont[i] = RetrieveBinContent(b[a[i]]);
5747 if (!errors2.empty())
5749 }
5750 for (i = 0; i < n; i++) {
5751 UpdateBinContent(i + 1, cont[i]);
5752 if (!errors2.empty())
5753 fSumw2.fArray[i+1] = errors2[i];
5754 }
5755 } else if (GetDimension() == 2) {
5756 Int_t nx = fXaxis.GetNbins() + 2;
5757 Int_t ny = fYaxis.GetNbins() + 2;
5758 cont.resize(nx * ny);
5759 if (fSumw2.fN)
5760 errors2.resize(nx * ny);
5761 // copy old bin contents and then set to new ordered bins
5762 // N.B. bin in histograms starts from 1, but in y we consider under/overflows
5763 for (i = 0; i < nx; i++) {
5764 for (j = 0; j < ny; j++) { // ny is nbins+2
5765 Int_t bin = GetBin(i, j);
5766 cont[i + nx * j] = RetrieveBinContent(bin);
5767 if (!errors2.empty())
5768 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5769 }
5770 }
5771 if (axis == GetXaxis()) {
5772 for (i = 0; i < n; i++) {
5773 for (j = 0; j < ny; j++) {
5774 Int_t bin = GetBin(i + 1 , j);
5775 UpdateBinContent(bin, cont[b[a[i]] + nx * j]);
5776 if (!errors2.empty())
5777 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * j];
5778 }
5779 }
5780 } else {
5781 for (i = 0; i < nx; i++) {
5782 for (j = 0; j < n; j++) {
5783 Int_t bin = GetBin(i, j + 1);
5784 UpdateBinContent(bin, cont[i + nx * b[a[j]]]);
5785 if (!errors2.empty())
5786 fSumw2.fArray[bin] = errors2[i + nx * b[a[j]]];
5787 }
5788 }
5789 }
5790 } else {
5791 // case of 3D (needs to be tested)
5792 Int_t nx = fXaxis.GetNbins() + 2;
5793 Int_t ny = fYaxis.GetNbins() + 2;
5794 Int_t nz = fZaxis.GetNbins() + 2;
5795 cont.resize(nx * ny * nz);
5796 if (fSumw2.fN)
5797 errors2.resize(nx * ny * nz);
5798 for (i = 0; i < nx; i++) {
5799 for (j = 0; j < ny; j++) {
5800 for (k = 0; k < nz; k++) {
5801 Int_t bin = GetBin(i, j, k);
5802 cont[i + nx * (j + ny * k)] = RetrieveBinContent(bin);
5803 if (!errors2.empty())
5804 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5805 }
5806 }
5807 }
5808 if (axis == GetXaxis()) {
5809 // labels on x axis
5810 for (i = 0; i < n; i++) { // for x we loop only on bins with the labels
5811 for (j = 0; j < ny; j++) {
5812 for (k = 0; k < nz; k++) {
5813 Int_t bin = GetBin(i + 1, j, k);
5814 UpdateBinContent(bin, cont[b[a[i]] + nx * (j + ny * k)]);
5815 if (!errors2.empty())
5816 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * (j + ny * k)];
5817 }
5818 }
5819 }
5820 } else if (axis == GetYaxis()) {
5821 // labels on y axis
5822 for (i = 0; i < nx; i++) {
5823 for (j = 0; j < n; j++) {
5824 for (k = 0; k < nz; k++) {
5825 Int_t bin = GetBin(i, j+1, k);
5826 UpdateBinContent(bin, cont[i + nx * (b[a[j]] + ny * k)]);
5827 if (!errors2.empty())
5828 fSumw2.fArray[bin] = errors2[i + nx * (b[a[j]] + ny * k)];
5829 }
5830 }
5831 }
5832 } else {
5833 // labels on z axis
5834 for (i = 0; i < nx; i++) {
5835 for (j = 0; j < ny; j++) {
5836 for (k = 0; k < n; k++) {
5837 Int_t bin = GetBin(i, j, k+1);
5838 UpdateBinContent(bin, cont[i + nx * (j + ny * b[a[k]])]);
5839 if (!errors2.empty())
5840 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * b[a[k]])];
5841 }
5842 }
5843 }
5844 }
5845 }
5846 }
5847 // need to set to zero the statistics if axis has been sorted
5848 // see for example TH3::PutStats for definition of s vector
5849 bool labelsAreSorted = kFALSE;
5850 for (i = 0; i < n; ++i) {
5851 if (a[i] != i) {
5853 break;
5854 }
5855 }
5856 if (labelsAreSorted) {
5857 double s[TH1::kNstat];
5858 GetStats(s);
5859 if (iaxis == 1) {
5860 s[2] = 0; // fTsumwx
5861 s[3] = 0; // fTsumwx2
5862 s[6] = 0; // fTsumwxy
5863 s[9] = 0; // fTsumwxz
5864 } else if (iaxis == 2) {
5865 s[4] = 0; // fTsumwy
5866 s[5] = 0; // fTsumwy2
5867 s[6] = 0; // fTsumwxy
5868 s[10] = 0; // fTsumwyz
5869 } else if (iaxis == 3) {
5870 s[7] = 0; // fTsumwz
5871 s[8] = 0; // fTsumwz2
5872 s[9] = 0; // fTsumwxz
5873 s[10] = 0; // fTsumwyz
5874 }
5875 PutStats(s);
5876 }
5877 delete labold;
5878}
5879
5880////////////////////////////////////////////////////////////////////////////////
5881/// Test if two double are almost equal.
5882
5883static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5884{
5885 return TMath::Abs(a - b) < epsilon;
5886}
5887
5888////////////////////////////////////////////////////////////////////////////////
5889/// Test if a double is almost an integer.
5890
5891static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5892{
5893 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5894 AlmostEqual(a - TMath::Floor(a), 1, epsilon);
5895}
5896
5897////////////////////////////////////////////////////////////////////////////////
5898/// Test if the binning is equidistant.
5899
5900static inline bool IsEquidistantBinning(const TAxis& axis)
5901{
5902 // check if axis bin are equals
5903 if (!axis.GetXbins()->fN) return true; //
5904 // not able to check if there is only one axis entry
5905 bool isEquidistant = true;
5906 const Double_t firstBinWidth = axis.GetBinWidth(1);
5907 for (int i = 1; i < axis.GetNbins(); ++i) {
5908 const Double_t binWidth = axis.GetBinWidth(i);
5909 const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5910 isEquidistant &= match;
5911 if (!match)
5912 break;
5913 }
5914 return isEquidistant;
5915}
5916
5917////////////////////////////////////////////////////////////////////////////////
5918/// Same limits and bins.
5919
5921 return axis1.GetNbins() == axis2.GetNbins() &&
5922 TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
5923 TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
5924}
5925
5926////////////////////////////////////////////////////////////////////////////////
5927/// Finds new limits for the axis for the Merge function.
5928/// returns false if the limits are incompatible
5929
5931{
5933 return kTRUE;
5934
5936 return kFALSE; // not equidistant user binning not supported
5937
5938 Double_t width1 = destAxis.GetBinWidth(0);
5939 Double_t width2 = anAxis.GetBinWidth(0);
5940 if (width1 == 0 || width2 == 0)
5941 return kFALSE; // no binning not supported
5942
5943 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
5944 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
5946
5947 // check the bin size
5949 return kFALSE;
5950
5951 // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
5952 // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
5953
5954
5955 // check the limits
5956 Double_t delta;
5957 delta = (destAxis.GetXmin() - xmin)/width1;
5958 if (!AlmostInteger(delta))
5959 xmin -= (TMath::Ceil(delta) - delta)*width1;
5960
5961 delta = (anAxis.GetXmin() - xmin)/width2;
5962 if (!AlmostInteger(delta))
5963 xmin -= (TMath::Ceil(delta) - delta)*width2;
5964
5965
5966 delta = (destAxis.GetXmin() - xmin)/width1;
5967 if (!AlmostInteger(delta))
5968 return kFALSE;
5969
5970
5971 delta = (xmax - destAxis.GetXmax())/width1;
5972 if (!AlmostInteger(delta))
5973 xmax += (TMath::Ceil(delta) - delta)*width1;
5974
5975
5976 delta = (xmax - anAxis.GetXmax())/width2;
5977 if (!AlmostInteger(delta))
5978 xmax += (TMath::Ceil(delta) - delta)*width2;
5979
5980
5981 delta = (xmax - destAxis.GetXmax())/width1;
5982 if (!AlmostInteger(delta))
5983 return kFALSE;
5984#ifdef DEBUG
5985 if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
5986 printf("TH1::RecomputeAxisLimits - Impossible\n");
5987 return kFALSE;
5988 }
5989#endif
5990
5991
5993
5994 //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
5995
5996 return kTRUE;
5997}
5998
5999////////////////////////////////////////////////////////////////////////////////
6000/// Add all histograms in the collection to this histogram.
6001/// This function computes the min/max for the x axis,
6002/// compute a new number of bins, if necessary,
6003/// add bin contents, errors and statistics.
6004/// If all histograms have bin labels, bins with identical labels
6005/// will be merged, no matter what their order is.
6006/// If overflows are present and limits are different the function will fail.
6007/// The function returns the total number of entries in the result histogram
6008/// if the merge is successful, -1 otherwise.
6009///
6010/// Possible option:
6011/// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
6012/// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
6013/// (enabled by default) slows down the merging
6014///
6015/// IMPORTANT remark. The axis x may have different number
6016/// of bins and different limits, BUT the largest bin width must be
6017/// a multiple of the smallest bin width and the upper limit must also
6018/// be a multiple of the bin width.
6019/// Example:
6020///
6021/// ~~~ {.cpp}
6022/// void atest() {
6023/// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
6024/// TH1F *h2 = new TH1F("h2","h2",220,0,110);
6025/// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
6026/// TRandom r;
6027/// for (Int_t i=0;i<10000;i++) {
6028/// h1->Fill(r.Gaus(-55,10));
6029/// h2->Fill(r.Gaus(55,10));
6030/// h3->Fill(r.Gaus(0,10));
6031/// }
6032///
6033/// TList *list = new TList;
6034/// list->Add(h1);
6035/// list->Add(h2);
6036/// list->Add(h3);
6037/// TH1F *h = (TH1F*)h1->Clone("h");
6038/// h->Reset();
6039/// h->Merge(list);
6040/// h->Draw();
6041/// }
6042/// ~~~
6043
6045{
6046 if (!li) return 0;
6047 if (li->IsEmpty()) return (Long64_t) GetEntries();
6048
6049 // use TH1Merger class
6050 TH1Merger merger(*this,*li,opt);
6051 Bool_t ret = merger();
6052
6053 return (ret) ? GetEntries() : -1;
6054}
6055
6056
6057////////////////////////////////////////////////////////////////////////////////
6058/// Performs the operation:
6059///
6060/// `this = this*c1*f1`
6061///
6062/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
6063///
6064/// Only bins inside the function range are recomputed.
6065/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6066/// you should call Sumw2 before making this operation.
6067/// This is particularly important if you fit the histogram after TH1::Multiply
6068///
6069/// The function return kFALSE if the Multiply operation failed
6070
6072{
6073 if (!f1) {
6074 Error("Multiply","Attempt to multiply by a non-existing function");
6075 return kFALSE;
6076 }
6077
6078 // delete buffer if it is there since it will become invalid
6079 if (fBuffer) BufferEmpty(1);
6080
6081 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
6082 Int_t ny = GetNbinsY() + 2;
6083 Int_t nz = GetNbinsZ() + 2;
6084 if (fDimension < 2) ny = 1;
6085 if (fDimension < 3) nz = 1;
6086
6087 // reset min-maximum
6088 SetMinimum();
6089 SetMaximum();
6090
6091 // - Loop on bins (including underflows/overflows)
6092 Double_t xx[3];
6093 Double_t *params = nullptr;
6094 f1->InitArgs(xx,params);
6095
6096 for (Int_t binz = 0; binz < nz; ++binz) {
6097 xx[2] = fZaxis.GetBinCenter(binz);
6098 for (Int_t biny = 0; biny < ny; ++biny) {
6099 xx[1] = fYaxis.GetBinCenter(biny);
6100 for (Int_t binx = 0; binx < nx; ++binx) {
6101 xx[0] = fXaxis.GetBinCenter(binx);
6102 if (!f1->IsInside(xx)) continue;
6104 Int_t bin = binx + nx * (biny + ny *binz);
6105 Double_t cu = c1*f1->EvalPar(xx);
6106 if (TF1::RejectedPoint()) continue;
6108 if (fSumw2.fN) {
6109 fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
6110 }
6111 }
6112 }
6113 }
6114 ResetStats();
6115 return kTRUE;
6116}
6117
6118////////////////////////////////////////////////////////////////////////////////
6119/// Multiply this histogram by h1.
6120///
6121/// `this = this*h1`
6122///
6123/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6124/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
6125/// if not already set.
6126///
6127/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6128/// you should call Sumw2 before making this operation.
6129/// This is particularly important if you fit the histogram after TH1::Multiply
6130///
6131/// The function return kFALSE if the Multiply operation failed
6132
6133Bool_t TH1::Multiply(const TH1 *h1)
6134{
6135 if (!h1) {
6136 Error("Multiply","Attempt to multiply by a non-existing histogram");
6137 return kFALSE;
6138 }
6139
6140 // delete buffer if it is there since it will become invalid
6141 if (fBuffer) BufferEmpty(1);
6142
6143 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins) {
6144 return false;
6145 }
6146
6147 // Create Sumw2 if h1 has Sumw2 set
6148 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
6149
6150 // - Reset min- maximum
6151 SetMinimum();
6152 SetMaximum();
6153
6154 // - Loop on bins (including underflows/overflows)
6155 for (Int_t i = 0; i < fNcells; ++i) {
6158 UpdateBinContent(i, c0 * c1);
6159 if (fSumw2.fN) {
6161 }
6162 }
6163 ResetStats();
6164 return kTRUE;
6165}
6166
6167////////////////////////////////////////////////////////////////////////////////
6168/// Replace contents of this histogram by multiplication of h1 by h2.
6169///
6170/// `this = (c1*h1)*(c2*h2)`
6171///
6172/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6173/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
6174/// if not already set.
6175///
6176/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6177/// you should call Sumw2 before making this operation.
6178/// This is particularly important if you fit the histogram after TH1::Multiply
6179///
6180/// The function return kFALSE if the Multiply operation failed
6181
6183{
6184 TString opt = option;
6185 opt.ToLower();
6186 // Bool_t binomial = kFALSE;
6187 // if (opt.Contains("b")) binomial = kTRUE;
6188 if (!h1 || !h2) {
6189 Error("Multiply","Attempt to multiply by a non-existing histogram");
6190 return kFALSE;
6191 }
6192
6193 // delete buffer if it is there since it will become invalid
6194 if (fBuffer) BufferEmpty(1);
6195
6196 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins ||
6197 LoggedInconsistency("Multiply", h1, h2) >= kDifferentNumberOfBins) {
6198 return false;
6199 }
6200
6201 // Create Sumw2 if h1 or h2 have Sumw2 set
6202 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
6203
6204 // - Reset min - maximum
6205 SetMinimum();
6206 SetMaximum();
6207
6208 // - Loop on bins (including underflows/overflows)
6209 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
6210 for (Int_t i = 0; i < fNcells; ++i) {
6212 Double_t b2 = h2->RetrieveBinContent(i);
6213 UpdateBinContent(i, c1 * b1 * c2 * b2);
6214 if (fSumw2.fN) {
6215 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
6216 }
6217 }
6218 ResetStats();
6219 return kTRUE;
6220}
6221
6222////////////////////////////////////////////////////////////////////////////////
6223/// @brief Normalize a histogram to its integral or to its maximum.
6224/// @note Works for TH1, TH2, TH3, ...
6225/// @param option: normalization strategy ("", "max" or "sum")
6226/// - "": Scale to `1/(sum*bin_width)`.
6227/// - max: Scale to `1/GetMaximum()`
6228/// - sum: Scale to `1/sum`.
6229///
6230/// In case the norm is zero, it raises an error.
6231/// @sa https://root-forum.cern.ch/t/different-ways-of-normalizing-histograms/15582/
6232
6234{
6235 TString opt = option;
6236 opt.ToLower();
6237 if (!opt.IsNull() && (opt != "max") && (opt != "sum")) {
6238 Error("Normalize", "Unrecognized option %s", option);
6239 return;
6240 }
6241
6242 const Double_t norm = (opt == "max") ? GetMaximum() : Integral(opt.IsNull() ? "width" : "");
6243
6244 if (norm == 0) {
6245 Error("Normalize", "Attempt to normalize histogram with zero integral");
6246 } else {
6247 Scale(1.0 / norm, "");
6248 // An alternative could have been to call Integral("") and Scale(1/norm, "width"), but this
6249 // will lead to a different value of GetEntries.
6250 // Instead, doing simultaneously Integral("width") and Scale(1/norm, "width") leads to an error since you are
6251 // dividing twice by bin width.
6252 }
6253}
6254
6255////////////////////////////////////////////////////////////////////////////////
6256/// Control routine to paint any kind of histograms.
6257///
6258/// This function is automatically called by TCanvas::Update.
6259/// (see TH1::Draw for the list of options)
6260
6262{
6264
6265 if (fPainter) {
6266 if (option && strlen(option) > 0)
6268 else
6270 }
6271}
6272
6273////////////////////////////////////////////////////////////////////////////////
6274/// Rebin this histogram
6275///
6276/// #### case 1 xbins=0
6277///
6278/// If newname is blank (default), the current histogram is modified and
6279/// a pointer to it is returned.
6280///
6281/// If newname is not blank, the current histogram is not modified, and a
6282/// new histogram is returned which is a Clone of the current histogram
6283/// with its name set to newname.
6284///
6285/// The parameter ngroup indicates how many bins of this have to be merged
6286/// into one bin of the result.
6287///
6288/// If the original histogram has errors stored (via Sumw2), the resulting
6289/// histograms has new errors correctly calculated.
6290///
6291/// examples: if h1 is an existing TH1F histogram with 100 bins
6292///
6293/// ~~~ {.cpp}
6294/// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
6295/// h1->Rebin(5); //merges five bins in one in h1
6296/// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
6297/// // merging 5 bins of h1 in one bin
6298/// ~~~
6299///
6300/// NOTE: If ngroup is not an exact divider of the number of bins,
6301/// the top limit of the rebinned histogram is reduced
6302/// to the upper edge of the last bin that can make a complete
6303/// group. The remaining bins are added to the overflow bin.
6304/// Statistics will be recomputed from the new bin contents.
6305///
6306/// #### case 2 xbins!=0
6307///
6308/// A new histogram is created (you should specify newname).
6309/// The parameter ngroup is the number of variable size bins in the created histogram.
6310/// The array xbins must contain ngroup+1 elements that represent the low-edges
6311/// of the bins.
6312/// If the original histogram has errors stored (via Sumw2), the resulting
6313/// histograms has new errors correctly calculated.
6314///
6315/// NOTE: The bin edges specified in xbins should correspond to bin edges
6316/// in the original histogram. If a bin edge in the new histogram is
6317/// in the middle of a bin in the original histogram, all entries in
6318/// the split bin in the original histogram will be transferred to the
6319/// lower of the two possible bins in the new histogram. This is
6320/// probably not what you want. A warning message is emitted in this
6321/// case
6322///
6323/// examples: if h1 is an existing TH1F histogram with 100 bins
6324///
6325/// ~~~ {.cpp}
6326/// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
6327/// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
6328/// ~~~
6329
6330TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
6331{
6332 Int_t nbins = fXaxis.GetNbins();
6335 if ((ngroup <= 0) || (ngroup > nbins)) {
6336 Error("Rebin", "Illegal value of ngroup=%d",ngroup);
6337 return nullptr;
6338 }
6339
6340 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
6341 Error("Rebin", "Operation valid on 1-D histograms only");
6342 return nullptr;
6343 }
6344 if (!newname && xbins) {
6345 Error("Rebin","if xbins is specified, newname must be given");
6346 return nullptr;
6347 }
6348
6349 Int_t newbins = nbins/ngroup;
6350 if (!xbins) {
6351 Int_t nbg = nbins/ngroup;
6352 if (nbg*ngroup != nbins) {
6353 Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
6354 }
6355 }
6356 else {
6357 // in the case that xbins is given (rebinning in variable bins), ngroup is
6358 // the new number of bins and number of grouped bins is not constant.
6359 // when looping for setting the contents for the new histogram we
6360 // need to loop on all bins of original histogram. Then set ngroup=nbins
6361 newbins = ngroup;
6362 ngroup = nbins;
6363 }
6364
6365 // Save old bin contents into a new array
6366 Double_t entries = fEntries;
6367 Double_t *oldBins = new Double_t[nbins+2];
6368 Int_t bin, i;
6369 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
6370 Double_t *oldErrors = nullptr;
6371 if (fSumw2.fN != 0) {
6372 oldErrors = new Double_t[nbins+2];
6373 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
6374 }
6375 // rebin will not include underflow/overflow if new axis range is larger than old axis range
6376 if (xbins) {
6377 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
6378 Warning("Rebin","underflow entries will not be used when rebinning");
6379 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
6380 Warning("Rebin","overflow entries will not be used when rebinning");
6381 }
6382
6383
6384 // create a clone of the old histogram if newname is specified
6385 TH1 *hnew = this;
6386 if ((newname && strlen(newname) > 0) || xbins) {
6387 hnew = (TH1*)Clone(newname);
6388 }
6389
6390 //reset can extend bit to avoid an axis extension in SetBinContent
6391 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
6392
6393 // save original statistics
6394 Double_t stat[kNstat];
6395 GetStats(stat);
6396 bool resetStat = false;
6397 // change axis specs and rebuild bin contents array::RebinAx
6398 if(!xbins && (newbins*ngroup != nbins)) {
6400 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
6401 }
6402 // save the TAttAxis members (reset by SetBins)
6414
6415 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
6416 Double_t *bins = new Double_t[newbins+1];
6417 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
6418 hnew->SetBins(newbins,bins); //this also changes errors array (if any)
6419 delete [] bins;
6420 } else if (xbins) {
6421 hnew->SetBins(newbins,xbins);
6422 } else {
6423 hnew->SetBins(newbins,xmin,xmax);
6424 }
6425
6426 // Restore axis attributes
6438
6439 // copy merged bin contents (ignore under/overflows)
6440 // Start merging only once the new lowest edge is reached
6441 Int_t startbin = 1;
6442 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
6443 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
6444 startbin++;
6445 }
6448 for (bin = 1;bin<=newbins;bin++) {
6449 binContent = 0;
6450 binError = 0;
6451 Int_t imax = ngroup;
6452 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6453 // check bin edges for the cases when we provide an array of bins
6454 // be careful in case bins can have zero width
6456 hnew->GetXaxis()->GetBinLowEdge(bin),
6457 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6458 {
6459 Warning("Rebin","Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6460 }
6461 for (i=0;i<ngroup;i++) {
6462 if( (oldbin+i > nbins) ||
6463 ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6464 imax = i;
6465 break;
6466 }
6469 }
6470 hnew->SetBinContent(bin,binContent);
6471 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6472 oldbin += imax;
6473 }
6474
6475 // sum underflow and overflow contents until startbin
6476 binContent = 0;
6477 binError = 0;
6478 for (i = 0; i < startbin; ++i) {
6479 binContent += oldBins[i];
6480 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6481 }
6482 hnew->SetBinContent(0,binContent);
6483 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6484 // sum overflow
6485 binContent = 0;
6486 binError = 0;
6487 for (i = oldbin; i <= nbins+1; ++i) {
6488 binContent += oldBins[i];
6489 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6490 }
6491 hnew->SetBinContent(newbins+1,binContent);
6492 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6493
6494 hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6495
6496 // restore statistics and entries modified by SetBinContent
6497 hnew->SetEntries(entries);
6498 if (!resetStat) hnew->PutStats(stat);
6499 delete [] oldBins;
6500 if (oldErrors) delete [] oldErrors;
6501 return hnew;
6502}
6503
6504////////////////////////////////////////////////////////////////////////////////
6505/// finds new limits for the axis so that *point* is within the range and
6506/// the limits are compatible with the previous ones (see TH1::Merge).
6507/// new limits are put into *newMin* and *newMax* variables.
6508/// axis - axis whose limits are to be recomputed
6509/// point - point that should fit within the new axis limits
6510/// newMin - new minimum will be stored here
6511/// newMax - new maximum will be stored here.
6512/// false if failed (e.g. if the initial axis limits are wrong
6513/// or the new range is more than \f$ 2^{64} \f$ times the old one).
6514
6516{
6517 Double_t xmin = axis->GetXmin();
6518 Double_t xmax = axis->GetXmax();
6519 if (xmin >= xmax) return kFALSE;
6521
6522 //recompute new axis limits by doubling the current range
6523 Int_t ntimes = 0;
6524 while (point < xmin) {
6525 if (ntimes++ > 64)
6526 return kFALSE;
6527 xmin = xmin - range;
6528 range *= 2;
6529 }
6530 while (point >= xmax) {
6531 if (ntimes++ > 64)
6532 return kFALSE;
6533 xmax = xmax + range;
6534 range *= 2;
6535 }
6536 newMin = xmin;
6537 newMax = xmax;
6538 // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6539 // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6540
6541 return kTRUE;
6542}
6543
6544////////////////////////////////////////////////////////////////////////////////
6545/// Histogram is resized along axis such that x is in the axis range.
6546/// The new axis limits are recomputed by doubling iteratively
6547/// the current axis range until the specified value x is within the limits.
6548/// The algorithm makes a copy of the histogram, then loops on all bins
6549/// of the old histogram to fill the extended histogram.
6550/// Takes into account errors (Sumw2) if any.
6551/// The algorithm works for 1-d, 2-D and 3-D histograms.
6552/// The axis must be extendable before invoking this function.
6553/// Ex:
6554///
6555/// ~~~ {.cpp}
6556/// h->GetXaxis()->SetCanExtend(kTRUE);
6557/// ~~~
6558
6559void TH1::ExtendAxis(Double_t x, TAxis *axis)
6560{
6561 if (!axis->CanExtend()) return;
6562 if (TMath::IsNaN(x)) { // x may be a NaN
6564 return;
6565 }
6566
6567 if (axis->GetXmin() >= axis->GetXmax()) return;
6568 if (axis->GetNbins() <= 0) return;
6569
6571 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6572 return;
6573
6574 //save a copy of this histogram
6575 TH1 *hold = (TH1*)IsA()->New();
6576 hold->SetDirectory(nullptr);
6577 Copy(*hold);
6578 //set new axis limits
6579 axis->SetLimits(xmin,xmax);
6580
6581
6582 //now loop on all bins and refill
6584
6585 Reset("ICE"); //reset only Integral, contents and Errors
6586
6587 int iaxis = 0;
6588 if (axis == &fXaxis) iaxis = 1;
6589 if (axis == &fYaxis) iaxis = 2;
6590 if (axis == &fZaxis) iaxis = 3;
6591 bool firstw = kTRUE;
6592 Int_t binx,biny, binz = 0;
6593 Int_t ix = 0,iy = 0,iz = 0;
6594 Double_t bx,by,bz;
6595 Int_t ncells = hold->GetNcells();
6596 for (Int_t bin = 0; bin < ncells; ++bin) {
6597 hold->GetBinXYZ(bin,binx,biny,binz);
6598 bx = hold->GetXaxis()->GetBinCenter(binx);
6599 ix = fXaxis.FindFixBin(bx);
6600 if (fDimension > 1) {
6601 by = hold->GetYaxis()->GetBinCenter(biny);
6602 iy = fYaxis.FindFixBin(by);
6603 if (fDimension > 2) {
6604 bz = hold->GetZaxis()->GetBinCenter(binz);
6605 iz = fZaxis.FindFixBin(bz);
6606 }
6607 }
6608 // exclude underflow/overflow
6609 double content = hold->RetrieveBinContent(bin);
6610 if (content == 0) continue;
6611 if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6612 if (firstw) {
6613 Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6614 " their content will be lost",GetName() );
6615 firstw= kFALSE;
6616 }
6617 continue;
6618 }
6619 Int_t ibin= GetBin(ix,iy,iz);
6621 if (errors) {
6622 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6623 }
6624 }
6625 delete hold;
6626}
6627
6628////////////////////////////////////////////////////////////////////////////////
6629/// Recursively remove object from the list of functions
6630
6632{
6633 // Rely on TROOT::RecursiveRemove to take the readlock.
6634
6635 if (fFunctions) {
6637 }
6638}
6639
6640////////////////////////////////////////////////////////////////////////////////
6641/// Multiply this histogram by a constant c1.
6642///
6643/// `this = c1*this`
6644///
6645/// Note that both contents and errors (if any) are scaled.
6646/// This function uses the services of TH1::Add
6647///
6648/// IMPORTANT NOTE: Sumw2() is called automatically when scaling.
6649/// If you are not interested in the histogram statistics you can call
6650/// Sumw2(kFALSE) or use the option "nosw2"
6651///
6652/// One can scale a histogram such that the bins integral is equal to
6653/// the normalization parameter via TH1::Scale(Double_t norm), where norm
6654/// is the desired normalization divided by the integral of the histogram.
6655///
6656/// If option contains "width" the bin contents and errors are divided
6657/// by the bin width.
6658
6660{
6661
6662 TString opt = option; opt.ToLower();
6663 // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6664 if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6665 if (opt.Contains("width")) Add(this, this, c1, -1);
6666 else {
6667 if (fBuffer) BufferEmpty(1);
6668 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6669 if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6670 // update global histograms statistics
6671 Double_t s[kNstat] = {0};
6672 GetStats(s);
6673 for (Int_t i=0 ; i < kNstat; i++) {
6674 if (i == 1) s[i] = c1*c1*s[i];
6675 else s[i] = c1*s[i];
6676 }
6677 PutStats(s);
6678 SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6679 }
6680
6681 // if contours set, must also scale contours
6683 if (ncontours == 0) return;
6685 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6686}
6687
6688////////////////////////////////////////////////////////////////////////////////
6689/// Returns true if all axes are extendable.
6690
6692{
6694 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6695 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6696
6697 return canExtend;
6698}
6699
6700////////////////////////////////////////////////////////////////////////////////
6701/// Make the histogram axes extendable / not extendable according to the bit mask
6702/// returns the previous bit mask specifying which axes are extendable
6703
6705{
6707
6711
6712 if (GetDimension() > 1) {
6716 }
6717
6718 if (GetDimension() > 2) {
6722 }
6723
6724 return oldExtendBitMask;
6725}
6726
6727///////////////////////////////////////////////////////////////////////////////
6728/// Internal function used in TH1::Fill to see which axis is full alphanumeric,
6729/// i.e. can be extended and is alphanumeric
6731{
6735 bitMask |= kYaxis;
6737 bitMask |= kZaxis;
6738
6739 return bitMask;
6740}
6741
6742////////////////////////////////////////////////////////////////////////////////
6743/// Static function to set the default buffer size for automatic histograms.
6744/// When a histogram is created with one of its axis lower limit greater
6745/// or equal to its upper limit, the function SetBuffer is automatically
6746/// called with the default buffer size.
6747
6749{
6750 fgBufferSize = bufsize > 0 ? bufsize : 0;
6751}
6752
6753////////////////////////////////////////////////////////////////////////////////
6754/// When this static function is called with `sumw2=kTRUE`, all new
6755/// histograms will automatically activate the storage
6756/// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6757
6759{
6761}
6762
6763////////////////////////////////////////////////////////////////////////////////
6764/// Change/set the title.
6765///
6766/// If title is in the form `stringt;stringx;stringy;stringz;stringc`
6767/// the histogram title is set to `stringt`, the x axis title to `stringx`,
6768/// the y axis title to `stringy`, the z axis title to `stringz`, and the c
6769/// axis title for the palette is ignored at this stage.
6770/// Note that you can use e.g. `stringt;stringx` if you only want to specify
6771/// title and x axis title.
6772///
6773/// To insert the character `;` in one of the titles, one should use `#;`
6774/// or `#semicolon`.
6775
6776void TH1::SetTitle(const char *title)
6777{
6778 fTitle = title;
6779 fTitle.ReplaceAll("#;",2,"#semicolon",10);
6780
6781 // Decode fTitle. It may contain X, Y and Z titles
6783 Int_t isc = str1.Index(";");
6784 Int_t lns = str1.Length();
6785
6786 if (isc >=0 ) {
6787 fTitle = str1(0,isc);
6788 str1 = str1(isc+1, lns);
6789 isc = str1.Index(";");
6790 if (isc >=0 ) {
6791 str2 = str1(0,isc);
6792 str2.ReplaceAll("#semicolon",10,";",1);
6793 fXaxis.SetTitle(str2.Data());
6794 lns = str1.Length();
6795 str1 = str1(isc+1, lns);
6796 isc = str1.Index(";");
6797 if (isc >=0 ) {
6798 str2 = str1(0,isc);
6799 str2.ReplaceAll("#semicolon",10,";",1);
6800 fYaxis.SetTitle(str2.Data());
6801 lns = str1.Length();
6802 str1 = str1(isc+1, lns);
6803 isc = str1.Index(";");
6804 if (isc >=0 ) {
6805 str2 = str1(0,isc);
6806 str2.ReplaceAll("#semicolon",10,";",1);
6807 fZaxis.SetTitle(str2.Data());
6808 } else {
6809 str1.ReplaceAll("#semicolon",10,";",1);
6810 fZaxis.SetTitle(str1.Data());
6811 }
6812 } else {
6813 str1.ReplaceAll("#semicolon",10,";",1);
6814 fYaxis.SetTitle(str1.Data());
6815 }
6816 } else {
6817 str1.ReplaceAll("#semicolon",10,";",1);
6818 fXaxis.SetTitle(str1.Data());
6819 }
6820 }
6821
6822 fTitle.ReplaceAll("#semicolon",10,";",1);
6823
6824 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6825}
6826
6827////////////////////////////////////////////////////////////////////////////////
6828/// Smooth array xx, translation of Hbook routine `hsmoof.F`.
6829/// Based on algorithm 353QH twice presented by J. Friedman
6830/// in [Proc. of the 1974 CERN School of Computing, Norway, 11-24 August, 1974](https://cds.cern.ch/record/186223).
6831/// 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).
6832
6834{
6835 if (nn < 3 ) {
6836 ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6837 return;
6838 }
6839
6840 Int_t ii;
6841 std::array<double, 3> hh{};
6842
6843 std::vector<double> yy(nn);
6844 std::vector<double> zz(nn);
6845 std::vector<double> rr(nn);
6846
6847 for (Int_t pass=0;pass<ntimes;pass++) {
6848 // first copy original data into temp array
6849 std::copy(xx, xx+nn, zz.begin() );
6850
6851 for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6852
6853 // do 353 i.e. running median 3, 5, and 3 in a single loop
6854 for (int kk = 0; kk < 3; kk++) {
6855 std::copy(zz.begin(), zz.end(), yy.begin());
6856 int medianType = (kk != 1) ? 3 : 5;
6857 int ifirst = (kk != 1 ) ? 1 : 2;
6858 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6859 //nn2 = nn - ik - 1;
6860 // do all elements beside the first and last point for median 3
6861 // and first two and last 2 for median 5
6862 for ( ii = ifirst; ii < ilast; ii++) {
6863 zz[ii] = TMath::Median(medianType, yy.data() + ii - ifirst);
6864 }
6865
6866 if (kk == 0) { // first median 3
6867 // first point
6868 hh[0] = zz[1];
6869 hh[1] = zz[0];
6870 hh[2] = 3*zz[1] - 2*zz[2];
6871 zz[0] = TMath::Median(3, hh.data());
6872 // last point
6873 hh[0] = zz[nn - 2];
6874 hh[1] = zz[nn - 1];
6875 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6876 zz[nn - 1] = TMath::Median(3, hh.data());
6877 }
6878
6879 if (kk == 1) { // median 5
6880 // second point with window length 3
6881 zz[1] = TMath::Median(3, yy.data());
6882 // second-to-last point with window length 3
6883 zz[nn - 2] = TMath::Median(3, yy.data() + nn - 3);
6884 }
6885
6886 // In the third iteration (kk == 2), the first and last point stay
6887 // the same (see paper linked in the documentation).
6888 }
6889
6890 std::copy ( zz.begin(), zz.end(), yy.begin() );
6891
6892 // quadratic interpolation for flat segments
6893 for (ii = 2; ii < (nn - 2); ii++) {
6894 if (zz[ii - 1] != zz[ii]) continue;
6895 if (zz[ii] != zz[ii + 1]) continue;
6896 const double tmp0 = zz[ii - 2] - zz[ii];
6897 const double tmp1 = zz[ii + 2] - zz[ii];
6898 if (tmp0 * tmp1 <= 0) continue;
6899 int jk = 1;
6900 if ( std::abs(tmp1) > std::abs(tmp0) ) jk = -1;
6901 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6902 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6903 }
6904
6905 // running means
6906 //std::copy(zz.begin(), zz.end(), yy.begin());
6907 for (ii = 1; ii < nn - 1; ii++) {
6908 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6909 }
6910 zz[0] = yy[0];
6911 zz[nn - 1] = yy[nn - 1];
6912
6913 if (noent == 0) {
6914
6915 // save computed values
6916 std::copy(zz.begin(), zz.end(), rr.begin());
6917
6918 // COMPUTE residuals
6919 for (ii = 0; ii < nn; ii++) {
6920 zz[ii] = xx[ii] - zz[ii];
6921 }
6922 }
6923
6924 } // end loop on noent
6925
6926
6927 double xmin = TMath::MinElement(nn,xx);
6928 for (ii = 0; ii < nn; ii++) {
6929 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6930 // make smoothing defined positive - not better using 0 ?
6931 else xx[ii] = std::max((rr[ii] + zz[ii]),0.0 );
6932 }
6933 }
6934}
6935
6936////////////////////////////////////////////////////////////////////////////////
6937/// Smooth bin contents of this histogram.
6938/// if option contains "R" smoothing is applied only to the bins
6939/// defined in the X axis range (default is to smooth all bins)
6940/// Bin contents are replaced by their smooth values.
6941/// Errors (if any) are not modified.
6942/// the smoothing procedure is repeated ntimes (default=1)
6943
6945{
6946 if (fDimension != 1) {
6947 Error("Smooth","Smooth only supported for 1-d histograms");
6948 return;
6949 }
6950 Int_t nbins = fXaxis.GetNbins();
6951 if (nbins < 3) {
6952 Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
6953 return;
6954 }
6955
6956 // delete buffer if it is there since it will become invalid
6957 if (fBuffer) BufferEmpty(1);
6958
6959 Int_t firstbin = 1, lastbin = nbins;
6960 TString opt = option;
6961 opt.ToLower();
6962 if (opt.Contains("r")) {
6965 }
6966 nbins = lastbin - firstbin + 1;
6967 Double_t *xx = new Double_t[nbins];
6969 Int_t i;
6970 for (i=0;i<nbins;i++) {
6972 }
6973
6974 TH1::SmoothArray(nbins,xx,ntimes);
6975
6976 for (i=0;i<nbins;i++) {
6978 }
6979 fEntries = nent;
6980 delete [] xx;
6981
6982 if (gPad) gPad->Modified();
6983}
6984
6985////////////////////////////////////////////////////////////////////////////////
6986/// if flag=kTRUE, underflows and overflows are used by the Fill functions
6987/// in the computation of statistics (mean value, StdDev).
6988/// By default, underflows or overflows are not used.
6989
6991{
6993}
6994
6995////////////////////////////////////////////////////////////////////////////////
6996/// Stream a class object.
6997
6998void TH1::Streamer(TBuffer &b)
6999{
7000 if (b.IsReading()) {
7001 UInt_t R__s, R__c;
7002 Version_t R__v = b.ReadVersion(&R__s, &R__c);
7003 if (fDirectory) fDirectory->Remove(this);
7004 fDirectory = nullptr;
7005 if (R__v > 2) {
7006 b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
7007
7009 fXaxis.SetParent(this);
7010 fYaxis.SetParent(this);
7011 fZaxis.SetParent(this);
7012 TIter next(fFunctions);
7013 TObject *obj;
7014 while ((obj=next())) {
7015 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
7016 }
7017 return;
7018 }
7019 //process old versions before automatic schema evolution
7024 b >> fNcells;
7025 fXaxis.Streamer(b);
7026 fYaxis.Streamer(b);
7027 fZaxis.Streamer(b);
7028 fXaxis.SetParent(this);
7029 fYaxis.SetParent(this);
7030 fZaxis.SetParent(this);
7031 b >> fBarOffset;
7032 b >> fBarWidth;
7033 b >> fEntries;
7034 b >> fTsumw;
7035 b >> fTsumw2;
7036 b >> fTsumwx;
7037 b >> fTsumwx2;
7038 if (R__v < 2) {
7040 Float_t *contour=nullptr;
7041 b >> maximum; fMaximum = maximum;
7042 b >> minimum; fMinimum = minimum;
7043 b >> norm; fNormFactor = norm;
7044 Int_t n = b.ReadArray(contour);
7045 fContour.Set(n);
7046 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
7047 delete [] contour;
7048 } else {
7049 b >> fMaximum;
7050 b >> fMinimum;
7051 b >> fNormFactor;
7053 }
7054 fSumw2.Streamer(b);
7056 fFunctions->Delete();
7058 b.CheckByteCount(R__s, R__c, TH1::IsA());
7059
7060 } else {
7061 b.WriteClassBuffer(TH1::Class(),this);
7062 }
7063}
7064
7065////////////////////////////////////////////////////////////////////////////////
7066/// Print some global quantities for this histogram.
7067/// \param[in] option
7068/// - "base" is given, number of bins and ranges are also printed
7069/// - "range" is given, bin contents and errors are also printed
7070/// for all bins in the current range (default 1-->nbins)
7071/// - "all" is given, bin contents and errors are also printed
7072/// for all bins including under and overflows.
7073
7074void TH1::Print(Option_t *option) const
7075{
7076 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7077 printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
7078 TString opt = option;
7079 opt.ToLower();
7080 Int_t all;
7081 if (opt.Contains("all")) all = 0;
7082 else if (opt.Contains("range")) all = 1;
7083 else if (opt.Contains("base")) all = 2;
7084 else return;
7085
7086 Int_t bin, binx, biny, binz;
7088 if (all == 0) {
7089 lastx = fXaxis.GetNbins()+1;
7090 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
7091 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
7092 } else {
7094 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
7095 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
7096 }
7097
7098 if (all== 2) {
7099 printf(" Title = %s\n", GetTitle());
7100 printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
7101 if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
7102 if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
7103 printf("\n");
7104 return;
7105 }
7106
7107 Double_t w,e;
7108 Double_t x,y,z;
7109 if (fDimension == 1) {
7110 for (binx=firstx;binx<=lastx;binx++) {
7113 e = GetBinError(binx);
7114 if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
7115 else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
7116 }
7117 }
7118 if (fDimension == 2) {
7119 for (biny=firsty;biny<=lasty;biny++) {
7121 for (binx=firstx;binx<=lastx;binx++) {
7122 bin = GetBin(binx,biny);
7124 w = RetrieveBinContent(bin);
7125 e = GetBinError(bin);
7126 if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
7127 else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
7128 }
7129 }
7130 }
7131 if (fDimension == 3) {
7132 for (binz=firstz;binz<=lastz;binz++) {
7134 for (biny=firsty;biny<=lasty;biny++) {
7136 for (binx=firstx;binx<=lastx;binx++) {
7137 bin = GetBin(binx,biny,binz);
7139 w = RetrieveBinContent(bin);
7140 e = GetBinError(bin);
7141 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);
7142 else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
7143 }
7144 }
7145 }
7146 }
7147}
7148
7149////////////////////////////////////////////////////////////////////////////////
7150/// Using the current bin info, recompute the arrays for contents and errors
7151
7152void TH1::Rebuild(Option_t *)
7153{
7154 SetBinsLength();
7155 if (fSumw2.fN) {
7157 }
7158}
7159
7160////////////////////////////////////////////////////////////////////////////////
7161/// Reset this histogram: contents, errors, etc.
7162/// \param[in] option
7163/// - if "ICE" is specified, resets only Integral, Contents and Errors.
7164/// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
7165/// This option is used
7166/// - if "M" is specified, resets also Minimum and Maximum
7167
7169{
7170 // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
7171 // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
7172
7173 TString opt = option;
7174 opt.ToUpper();
7175 fSumw2.Reset();
7176 if (fIntegral) {
7177 delete [] fIntegral;
7178 fIntegral = nullptr;
7179 }
7180
7181 if (opt.Contains("M")) {
7182 SetMinimum();
7183 SetMaximum();
7184 }
7185
7186 if (opt.Contains("ICE") && !opt.Contains("S")) return;
7187
7188 // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
7189 // But what is the sense of calling BufferEmpty() ? For making the axes ?
7190 // BufferEmpty will update contents that later will be
7191 // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
7192 // It may be needed for computing the axis limits....
7193 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
7194
7195 // need to reset also the statistics
7196 // (needs to be done after calling BufferEmpty() )
7197 fTsumw = 0;
7198 fTsumw2 = 0;
7199 fTsumwx = 0;
7200 fTsumwx2 = 0;
7201 fEntries = 0;
7202
7203 if (opt == "ICES") return;
7204
7205
7206 TObject *stats = fFunctions->FindObject("stats");
7207 fFunctions->Remove(stats);
7208 //special logic to support the case where the same object is
7209 //added multiple times in fFunctions.
7210 //This case happens when the same object is added with different
7211 //drawing modes
7212 TObject *obj;
7213 while ((obj = fFunctions->First())) {
7214 while(fFunctions->Remove(obj)) { }
7215 delete obj;
7216 }
7217 if(stats) fFunctions->Add(stats);
7218 fContour.Set(0);
7219}
7220
7221////////////////////////////////////////////////////////////////////////////////
7222/// Save the histogram as .csv, .tsv or .txt. In case of any other extension, fall
7223/// back to TObject::SaveAs, which saves as a .C macro (but with the file name
7224/// extension specified by the user)
7225///
7226/// The Under/Overflow bins are also exported (as first and last lines)
7227/// The fist 2 columns are the lower and upper edges of the bins
7228/// Column 3 contains the bin contents
7229/// The last column contains the error in y. If errors are not present, the column
7230/// is left empty
7231///
7232/// The result can be immediately imported into Excel, gnuplot, Python or whatever,
7233/// without the needing to install pyroot, etc.
7234///
7235/// \param filename the name of the file where to store the histogram
7236/// \param option some tuning options
7237///
7238/// The file extension defines the delimiter used:
7239/// - `.csv` : comma
7240/// - `.tsv` : tab
7241/// - `.txt` : space
7242///
7243/// If option = "title" a title line is generated. If the y-axis has a title,
7244/// this title is displayed as column 3 name, otherwise, it shows "BinContent"
7245
7246void TH1::SaveAs(const char *filename, Option_t *option) const
7247{
7248 char del = '\0';
7249 TString ext = "";
7251 TString opt = option;
7252
7253 if (filename) {
7254 if (fname.EndsWith(".csv")) {
7255 del = ',';
7256 ext = "csv";
7257 } else if (fname.EndsWith(".tsv")) {
7258 del = '\t';
7259 ext = "tsv";
7260 } else if (fname.EndsWith(".txt")) {
7261 del = ' ';
7262 ext = "txt";
7263 }
7264 }
7265 if (!del) {
7267 return;
7268 }
7269 std::ofstream out;
7270 out.open(filename, std::ios::out);
7271 if (!out.good()) {
7272 Error("SaveAs", "cannot open file: %s", filename);
7273 return;
7274 }
7275 if (opt.Contains("title")) {
7276 if (std::strcmp(GetYaxis()->GetTitle(), "") == 0) {
7277 out << "# " << "BinLowEdge" << del << "BinUpEdge" << del
7278 << "BinContent"
7279 << del << "ey" << std::endl;
7280 } else {
7281 out << "# " << "BinLowEdge" << del << "BinUpEdge" << del << GetYaxis()->GetTitle() << del << "ey" << std::endl;
7282 }
7283 }
7284 if (fSumw2.fN) {
7285 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7286 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7287 << GetBinError(i) << std::endl;
7288 }
7289 } else {
7290 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7291 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7292 << std::endl;
7293 }
7294 }
7295 out.close();
7296 Info("SaveAs", "%s file: %s has been generated", ext.Data(), filename);
7297}
7298
7299////////////////////////////////////////////////////////////////////////////////
7300/// Provide variable name for histogram for saving as primitive
7301/// Histogram pointer has by default the histogram name with an incremental suffix.
7302/// If the histogram belongs to a graph or a stack the suffix is not added because
7303/// the graph and stack objects are not aware of this new name. Same thing if
7304/// the histogram is drawn with the option COLZ because the TPaletteAxis drawn
7305/// when this option is selected, does not know this new name either.
7306
7308{
7309 thread_local Int_t storeNumber = 0;
7310
7311 TString opt = option;
7312 opt.ToLower();
7313 TString histName = GetName();
7314 // for TProfile and TH2Poly also fDirectory should be tested
7315 if (!histName.Contains("Graph") && !histName.Contains("_stack_") && !opt.Contains("colz") &&
7316 (!testfdir || !fDirectory)) {
7317 storeNumber++;
7318 histName += "__";
7319 histName += storeNumber;
7320 }
7321 if (histName.IsNull())
7322 histName = "unnamed";
7323 return gInterpreter->MapCppName(histName);
7324}
7325
7326////////////////////////////////////////////////////////////////////////////////
7327/// Save primitive as a C++ statement(s) on output stream out
7328
7329void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
7330{
7331 // empty the buffer before if it exists
7332 if (fBuffer)
7333 BufferEmpty();
7334
7336
7339 SetName(hname);
7340
7341 out <<" \n";
7342
7343 // Check if the histogram has equidistant X bins or not. If not, we
7344 // create an array holding the bins.
7345 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray)
7346 sxaxis = SavePrimitiveVector(out, hname + "_x", GetXaxis()->GetXbins()->fN, GetXaxis()->GetXbins()->fArray);
7347 // If the histogram is 2 or 3 dimensional, check if the histogram
7348 // has equidistant Y bins or not. If not, we create an array
7349 // holding the bins.
7350 if (fDimension > 1 && GetYaxis()->GetXbins()->fN && GetYaxis()->GetXbins()->fArray)
7351 syaxis = SavePrimitiveVector(out, hname + "_y", GetYaxis()->GetXbins()->fN, GetYaxis()->GetXbins()->fArray);
7352 // IF the histogram is 3 dimensional, check if the histogram
7353 // has equidistant Z bins or not. If not, we create an array
7354 // holding the bins.
7355 if (fDimension > 2 && GetZaxis()->GetXbins()->fN && GetZaxis()->GetXbins()->fArray)
7356 szaxis = SavePrimitiveVector(out, hname + "_z", GetZaxis()->GetXbins()->fN, GetZaxis()->GetXbins()->fArray);
7357
7358 const auto old_precision{out.precision()};
7359 constexpr auto max_precision{std::numeric_limits<double>::digits10 + 1};
7360 out << std::setprecision(max_precision);
7361
7362 out << " " << ClassName() << " *" << hname << " = new " << ClassName() << "(\"" << TString(savedName).ReplaceSpecialCppChars() << "\", \""
7363 << TString(GetTitle()).ReplaceSpecialCppChars() << "\", " << GetXaxis()->GetNbins();
7364 if (!sxaxis.IsNull())
7365 out << ", " << sxaxis << ".data()";
7366 else
7367 out << ", " << GetXaxis()->GetXmin() << ", " << GetXaxis()->GetXmax();
7368 if (fDimension > 1) {
7369 out << ", " << GetYaxis()->GetNbins();
7370 if (!syaxis.IsNull())
7371 out << ", " << syaxis << ".data()";
7372 else
7373 out << ", " << GetYaxis()->GetXmin() << ", " << GetYaxis()->GetXmax();
7374 }
7375 if (fDimension > 2) {
7376 out << ", " << GetZaxis()->GetNbins();
7377 if (!szaxis.IsNull())
7378 out << ", " << szaxis << ".data()";
7379 else
7380 out << ", " << GetZaxis()->GetXmin() << ", " << GetZaxis()->GetXmax();
7381 }
7382 out << ");\n";
7383
7385 Int_t numbins = 0, numerrors = 0;
7386
7387 std::vector<Double_t> content(fNcells), errors(save_errors ? fNcells : 0);
7388 for (Int_t bin = 0; bin < fNcells; bin++) {
7389 content[bin] = RetrieveBinContent(bin);
7390 if (content[bin])
7391 numbins++;
7392 if (save_errors) {
7393 errors[bin] = GetBinError(bin);
7394 if (errors[bin])
7395 numerrors++;
7396 }
7397 }
7398
7399 if ((numbins < 100) && (numerrors < 100)) {
7400 // in case of few non-empty bins store them as before
7401 for (Int_t bin = 0; bin < fNcells; bin++) {
7402 if (content[bin])
7403 out << " " << hname << "->SetBinContent(" << bin << "," << content[bin] << ");\n";
7404 }
7405 if (save_errors)
7406 for (Int_t bin = 0; bin < fNcells; bin++) {
7407 if (errors[bin])
7408 out << " " << hname << "->SetBinError(" << bin << "," << errors[bin] << ");\n";
7409 }
7410 } else {
7411 if (numbins > 0) {
7413 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
7414 out << " if (" << vectname << "[bin])\n";
7415 out << " " << hname << "->SetBinContent(bin, " << vectname << "[bin]);\n";
7416 }
7417 if (numerrors > 0) {
7419 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
7420 out << " if (" << vectname << "[bin])\n";
7421 out << " " << hname << "->SetBinError(bin, " << vectname << "[bin]);\n";
7422 }
7423 }
7424
7426 out << std::setprecision(old_precision);
7427 SetName(savedName.Data());
7428}
7429
7430////////////////////////////////////////////////////////////////////////////////
7431/// Helper function for the SavePrimitive functions from TH1
7432/// or classes derived from TH1, eg TProfile, TProfile2D.
7433
7434void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
7435{
7436 if (TMath::Abs(GetBarOffset()) > 1e-5)
7437 out << " " << hname << "->SetBarOffset(" << GetBarOffset() << ");\n";
7438 if (TMath::Abs(GetBarWidth() - 1) > 1e-5)
7439 out << " " << hname << "->SetBarWidth(" << GetBarWidth() << ");\n";
7440 if (fMinimum != -1111)
7441 out << " " << hname << "->SetMinimum(" << fMinimum << ");\n";
7442 if (fMaximum != -1111)
7443 out << " " << hname << "->SetMaximum(" << fMaximum << ");\n";
7444 if (fNormFactor != 0)
7445 out << " " << hname << "->SetNormFactor(" << fNormFactor << ");\n";
7446 if (fEntries != 0)
7447 out << " " << hname << "->SetEntries(" << fEntries << ");\n";
7448 if (!fDirectory)
7449 out << " " << hname << "->SetDirectory(nullptr);\n";
7450 if (TestBit(kNoStats))
7451 out << " " << hname << "->SetStats(0);\n";
7452 if (fOption.Length() != 0)
7453 out << " " << hname << "->SetOption(\n" << TString(fOption).ReplaceSpecialCppChars() << "\");\n";
7454
7455 // save contour levels
7457 if (ncontours > 0) {
7459 if (TestBit(kUserContour)) {
7460 std::vector<Double_t> levels(ncontours);
7461 for (Int_t bin = 0; bin < ncontours; bin++)
7462 levels[bin] = GetContourLevel(bin);
7464 }
7465 out << " " << hname << "->SetContour(" << ncontours;
7466 if (!vectname.IsNull())
7467 out << ", " << vectname << ".data()";
7468 out << ");\n";
7469 }
7470
7472
7473 // save attributes
7474 SaveFillAttributes(out, hname, -1, -1);
7475 SaveLineAttributes(out, hname, 1, 1, 1);
7476 SaveMarkerAttributes(out, hname, 1, 1, 1);
7477 fXaxis.SaveAttributes(out, hname, "->GetXaxis()");
7478 fYaxis.SaveAttributes(out, hname, "->GetYaxis()");
7479 fZaxis.SaveAttributes(out, hname, "->GetZaxis()");
7480
7482}
7483
7484////////////////////////////////////////////////////////////////////////////////
7485/// Save list of functions
7486/// Also can be used by TGraph classes
7487
7488void TH1::SavePrimitiveFunctions(std::ostream &out, const char *varname, TList *lst)
7489{
7490 thread_local Int_t funcNumber = 0;
7491
7492 TObjLink *lnk = lst ? lst->FirstLink() : nullptr;
7493 while (lnk) {
7494 auto obj = lnk->GetObject();
7495 obj->SavePrimitive(out, TString::Format("nodraw #%d\n", ++funcNumber).Data());
7496 TString objvarname = obj->GetName();
7498 if (obj->InheritsFrom(TF1::Class())) {
7500 objvarname = gInterpreter->MapCppName(objvarname);
7501 out << " " << objvarname << "->SetParent(" << varname << ");\n";
7502 } else if (obj->InheritsFrom("TPaveStats")) {
7503 objvarname = "ptstats";
7504 withopt = kFALSE; // pave stats preserve own draw options
7505 out << " " << objvarname << "->SetParent(" << varname << ");\n";
7506 } else if (obj->InheritsFrom("TPolyMarker")) {
7507 objvarname = "pmarker";
7508 }
7509
7510 out << " " << varname << "->GetListOfFunctions()->Add(" << objvarname;
7511 if (withopt)
7512 out << ",\"" << TString(lnk->GetOption()).ReplaceSpecialCppChars() << "\"";
7513 out << ");\n";
7514
7515 lnk = lnk->Next();
7516 }
7517}
7518
7519////////////////////////////////////////////////////////////////////////////////
7560 }
7561}
7562
7563////////////////////////////////////////////////////////////////////////////////
7564/// For axis = 1,2 or 3 returns the mean value of the histogram along
7565/// X,Y or Z axis.
7566///
7567/// For axis = 11, 12, 13 returns the standard error of the mean value
7568/// of the histogram along X, Y or Z axis
7569///
7570/// Note that the mean value/StdDev is computed using the bins in the currently
7571/// defined range (see TAxis::SetRange). By default the range includes
7572/// all bins from 1 to nbins included, excluding underflows and overflows.
7573/// To force the underflows and overflows in the computation, one must
7574/// call the static function TH1::StatOverflows(kTRUE) before filling
7575/// the histogram.
7576///
7577/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7578/// are calculated. By default, if no range has been set, the returned mean is
7579/// the (unbinned) one calculated at fill time. If a range has been set, however,
7580/// the mean is calculated using the bins in range, as described above; THIS
7581/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7582/// the range. To ensure that the returned mean (and all other statistics) is
7583/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7584/// See TH1::GetStats.
7585///
7586/// Return mean value of this histogram along the X axis.
7587
7588Double_t TH1::GetMean(Int_t axis) const
7589{
7590 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7591 Double_t stats[kNstat];
7592 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7593 GetStats(stats);
7594 if (stats[0] == 0) return 0;
7595 if (axis<4){
7596 Int_t ax[3] = {2,4,7};
7597 return stats[ax[axis-1]]/stats[0];
7598 } else {
7599 // mean error = StdDev / sqrt( Neff )
7600 Double_t stddev = GetStdDev(axis-10);
7602 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7603 }
7604}
7605
7606////////////////////////////////////////////////////////////////////////////////
7607/// Return standard error of mean of this histogram along the X axis.
7608///
7609/// Note that the mean value/StdDev is computed using the bins in the currently
7610/// defined range (see TAxis::SetRange). By default the range includes
7611/// all bins from 1 to nbins included, excluding underflows and overflows.
7612/// To force the underflows and overflows in the computation, one must
7613/// call the static function TH1::StatOverflows(kTRUE) before filling
7614/// the histogram.
7615///
7616/// Also note, that although the definition of standard error doesn't include the
7617/// assumption of normality, many uses of this feature implicitly assume it.
7618///
7619/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7620/// are calculated. By default, if no range has been set, the returned value is
7621/// the (unbinned) one calculated at fill time. If a range has been set, however,
7622/// the value is calculated using the bins in range, as described above; THIS
7623/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7624/// the range. To ensure that the returned value (and all other statistics) is
7625/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7626/// See TH1::GetStats.
7627
7629{
7630 return GetMean(axis+10);
7631}
7632
7633////////////////////////////////////////////////////////////////////////////////
7634/// Returns the Standard Deviation (Sigma).
7635/// The Sigma estimate is computed as
7636/// \f[
7637/// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7638/// \f]
7639/// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7640/// X, Y or Z axis
7641/// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7642/// X, Y or Z axis for Normal distribution
7643///
7644/// Note that the mean value/sigma is computed using the bins in the currently
7645/// defined range (see TAxis::SetRange). By default the range includes
7646/// all bins from 1 to nbins included, excluding underflows and overflows.
7647/// To force the underflows and overflows in the computation, one must
7648/// call the static function TH1::StatOverflows(kTRUE) before filling
7649/// the histogram.
7650///
7651/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7652/// are calculated. By default, if no range has been set, the returned standard
7653/// deviation is the (unbinned) one calculated at fill time. If a range has been
7654/// set, however, the standard deviation is calculated using the bins in range,
7655/// as described above; THIS IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use
7656/// TAxis::SetRange(0, 0) to unset the range. To ensure that the returned standard
7657/// deviation (and all other statistics) is always that of the binned data stored
7658/// in the histogram, call TH1::ResetStats. See TH1::GetStats.
7659
7660Double_t TH1::GetStdDev(Int_t axis) const
7661{
7662 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7663
7664 Double_t x, stddev2, stats[kNstat];
7665 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7666 GetStats(stats);
7667 if (stats[0] == 0) return 0;
7668 Int_t ax[3] = {2,4,7};
7669 Int_t axm = ax[axis%10 - 1];
7670 x = stats[axm]/stats[0];
7671 // for negative stddev (e.g. when having negative weights) - return stdev=0
7672 stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7673 if (axis<10)
7674 return TMath::Sqrt(stddev2);
7675 else {
7676 // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7677 // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7679 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7680 }
7681}
7682
7683////////////////////////////////////////////////////////////////////////////////
7684/// Return error of standard deviation estimation for Normal distribution
7685///
7686/// Note that the mean value/StdDev is computed using the bins in the currently
7687/// defined range (see TAxis::SetRange). By default the range includes
7688/// all bins from 1 to nbins included, excluding underflows and overflows.
7689/// To force the underflows and overflows in the computation, one must
7690/// call the static function TH1::StatOverflows(kTRUE) before filling
7691/// the histogram.
7692///
7693/// Value returned is standard deviation of sample standard deviation.
7694/// Note that it is an approximated value which is valid only in the case that the
7695/// original data distribution is Normal. The correct one would require
7696/// the 4-th momentum value, which cannot be accurately estimated from a histogram since
7697/// the x-information for all entries is not kept.
7698///
7699/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7700/// are calculated. By default, if no range has been set, the returned value is
7701/// the (unbinned) one calculated at fill time. If a range has been set, however,
7702/// the value is calculated using the bins in range, as described above; THIS
7703/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7704/// the range. To ensure that the returned value (and all other statistics) is
7705/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7706/// See TH1::GetStats.
7707
7709{
7710 return GetStdDev(axis+10);
7711}
7712
7713////////////////////////////////////////////////////////////////////////////////
7714/// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7715/// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7716/// of the histogram along x, y or z axis
7717///
7718///Note, that since third and fourth moment are not calculated
7719///at the fill time, skewness and its standard error are computed bin by bin
7720///
7721/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7722/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7723
7725{
7726
7727 if (axis > 0 && axis <= 3){
7728
7729 Double_t mean = GetMean(axis);
7730 Double_t stddev = GetStdDev(axis);
7732
7739 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7742 if (firstBinX == 1) firstBinX = 0;
7743 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7744 }
7746 if (firstBinY == 1) firstBinY = 0;
7747 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7748 }
7750 if (firstBinZ == 1) firstBinZ = 0;
7751 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7752 }
7753 }
7754
7755 Double_t x = 0;
7756 Double_t sum=0;
7757 Double_t np=0;
7758 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7759 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7760 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7761 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7762 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7763 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7765 np+=w;
7766 sum+=w*(x-mean)*(x-mean)*(x-mean);
7767 }
7768 }
7769 }
7770 sum/=np*stddev3;
7771 return sum;
7772 }
7773 else if (axis > 10 && axis <= 13) {
7774 //compute standard error of skewness
7775 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7777 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7778 }
7779 else {
7780 Error("GetSkewness", "illegal value of parameter");
7781 return 0;
7782 }
7783}
7784
7785////////////////////////////////////////////////////////////////////////////////
7786/// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7787/// Kurtosis(gaussian(0, 1)) = 0.
7788/// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7789/// of the histogram along x, y or z axis
7790////
7791/// Note, that since third and fourth moment are not calculated
7792/// at the fill time, kurtosis and its standard error are computed bin by bin
7793///
7794/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7795/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7796
7798{
7799 if (axis > 0 && axis <= 3){
7800
7801 Double_t mean = GetMean(axis);
7802 Double_t stddev = GetStdDev(axis);
7804
7811 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7814 if (firstBinX == 1) firstBinX = 0;
7815 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7816 }
7818 if (firstBinY == 1) firstBinY = 0;
7819 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7820 }
7822 if (firstBinZ == 1) firstBinZ = 0;
7823 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7824 }
7825 }
7826
7827 Double_t x = 0;
7828 Double_t sum=0;
7829 Double_t np=0;
7830 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7831 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7832 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7833 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7834 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7835 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7837 np+=w;
7838 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7839 }
7840 }
7841 }
7842 sum/=(np*stddev4);
7843 return sum-3;
7844
7845 } else if (axis > 10 && axis <= 13) {
7846 //compute standard error of skewness
7847 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7849 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7850 }
7851 else {
7852 Error("GetKurtosis", "illegal value of parameter");
7853 return 0;
7854 }
7855}
7856
7857////////////////////////////////////////////////////////////////////////////////
7858/// fill the array stats from the contents of this histogram
7859/// The array stats must be correctly dimensioned in the calling program.
7860///
7861/// ~~~ {.cpp}
7862/// stats[0] = sumw
7863/// stats[1] = sumw2
7864/// stats[2] = sumwx
7865/// stats[3] = sumwx2
7866/// ~~~
7867///
7868/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7869/// is simply a copy of the statistics quantities computed at filling time.
7870/// If a sub-range is specified, the function recomputes these quantities
7871/// from the bin contents in the current axis range.
7872///
7873/// IMPORTANT NOTE: This means that the returned statistics are context-dependent.
7874/// If TAxis::kAxisRange, the returned statistics are dependent on the binning;
7875/// otherwise, they are a copy of the histogram statistics computed at fill time,
7876/// which are unbinned by default (calling TH1::ResetStats forces them to use
7877/// binned statistics). You can reset TAxis::kAxisRange using TAxis::SetRange(0, 0).
7878///
7879/// Note that the mean value/StdDev is computed using the bins in the currently
7880/// defined range (see TAxis::SetRange). By default the range includes
7881/// all bins from 1 to nbins included, excluding underflows and overflows.
7882/// To force the underflows and overflows in the computation, one must
7883/// call the static function TH1::StatOverflows(kTRUE) before filling
7884/// the histogram.
7885
7886void TH1::GetStats(Double_t *stats) const
7887{
7888 if (fBuffer) ((TH1*)this)->BufferEmpty();
7889
7890 // Loop on bins (possibly including underflows/overflows)
7891 Int_t bin, binx;
7892 Double_t w,err;
7893 Double_t x;
7894 // identify the case of labels with extension of axis range
7895 // in this case the statistics in x does not make any sense
7896 Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && fXaxis.CanExtend() );
7897 // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7898 if ( (fTsumw == 0 && fEntries > 0) || fXaxis.TestBit(TAxis::kAxisRange) ) {
7899 for (bin=0;bin<4;bin++) stats[bin] = 0;
7900
7903 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7905 if (firstBinX == 1) firstBinX = 0;
7906 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7907 }
7908 for (binx = firstBinX; binx <= lastBinX; binx++) {
7910 //w = TMath::Abs(RetrieveBinContent(binx));
7911 // not sure what to do here if w < 0
7913 err = TMath::Abs(GetBinError(binx));
7914 stats[0] += w;
7915 stats[1] += err*err;
7916 // statistics in x makes sense only for not labels histograms
7917 if (!labelHist) {
7918 stats[2] += w*x;
7919 stats[3] += w*x*x;
7920 }
7921 }
7922 // if (stats[0] < 0) {
7923 // // in case total is negative do something ??
7924 // stats[0] = 0;
7925 // }
7926 } else {
7927 stats[0] = fTsumw;
7928 stats[1] = fTsumw2;
7929 stats[2] = fTsumwx;
7930 stats[3] = fTsumwx2;
7931 }
7932}
7933
7934////////////////////////////////////////////////////////////////////////////////
7935/// Replace current statistics with the values in array stats
7936
7937void TH1::PutStats(Double_t *stats)
7938{
7939 fTsumw = stats[0];
7940 fTsumw2 = stats[1];
7941 fTsumwx = stats[2];
7942 fTsumwx2 = stats[3];
7943}
7944
7945////////////////////////////////////////////////////////////////////////////////
7946/// Reset the statistics including the number of entries
7947/// and replace with values calculated from bin content
7948///
7949/// The number of entries is set to the total bin content or (in case of weighted histogram)
7950/// to number of effective entries
7951///
7952/// \note By default, before calling this function, statistics are those
7953/// computed at fill time, which are unbinned. See TH1::GetStats.
7954
7955void TH1::ResetStats()
7956{
7957 Double_t stats[kNstat] = {0};
7958 fTsumw = 0;
7959 fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
7960 GetStats(stats);
7961 PutStats(stats);
7963 // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
7964 if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
7965}
7966
7967////////////////////////////////////////////////////////////////////////////////
7968/// Return the sum of all weights
7969/// \param includeOverflow true to include under/overflows bins, false to exclude those.
7970/// \note Different from TH1::GetSumOfWeights, that always excludes those
7971
7973{
7974 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7975
7976 const Int_t start = (includeOverflow ? 0 : 1);
7977 const Int_t lastX = fXaxis.GetNbins() + (includeOverflow ? 1 : 0);
7978 const Int_t lastY = fYaxis.GetNbins() + (includeOverflow ? 1 : 0);
7979 const Int_t lastZ = fZaxis.GetNbins() + (includeOverflow ? 1 : 0);
7980 Double_t sum =0;
7981 for(auto binz = start; binz <= lastZ; binz++) {
7982 for(auto biny = start; biny <= lastY; biny++) {
7983 for(auto binx = start; binx <= lastX; binx++) {
7984 const auto bin = GetBin(binx, biny, binz);
7985 sum += RetrieveBinContent(bin);
7986 }
7987 }
7988 }
7989 return sum;
7990}
7991
7992////////////////////////////////////////////////////////////////////////////////
7993///Return integral of bin contents. Only bins in the bins range are considered.
7994///
7995/// By default the integral is computed as the sum of bin contents in the range.
7996/// if option "width" is specified, the integral is the sum of
7997/// the bin contents multiplied by the bin width in x.
7998
8000{
8002}
8003
8004////////////////////////////////////////////////////////////////////////////////
8005/// Return integral of bin contents in range [binx1,binx2].
8006///
8007/// By default the integral is computed as the sum of bin contents in the range.
8008/// if option "width" is specified, the integral is the sum of
8009/// the bin contents multiplied by the bin width in x.
8010
8012{
8013 double err = 0;
8014 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
8015}
8016
8017////////////////////////////////////////////////////////////////////////////////
8018/// Return integral of bin contents in range [binx1,binx2] and its error.
8019///
8020/// By default the integral is computed as the sum of bin contents in the range.
8021/// if option "width" is specified, the integral is the sum of
8022/// the bin contents multiplied by the bin width in x.
8023/// the error is computed using error propagation from the bin errors assuming that
8024/// all the bins are uncorrelated
8025
8027{
8028 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
8029}
8030
8031////////////////////////////////////////////////////////////////////////////////
8032/// Internal function compute integral and optionally the error between the limits
8033/// specified by the bin number values working for all histograms (1D, 2D and 3D)
8034
8036 Option_t *option, Bool_t doError) const
8037{
8038 if (fBuffer) ((TH1*)this)->BufferEmpty();
8039
8040 Int_t nx = GetNbinsX() + 2;
8041 if (binx1 < 0) binx1 = 0;
8042 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
8043
8044 if (GetDimension() > 1) {
8045 Int_t ny = GetNbinsY() + 2;
8046 if (biny1 < 0) biny1 = 0;
8047 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
8048 } else {
8049 biny1 = 0; biny2 = 0;
8050 }
8051
8052 if (GetDimension() > 2) {
8053 Int_t nz = GetNbinsZ() + 2;
8054 if (binz1 < 0) binz1 = 0;
8055 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
8056 } else {
8057 binz1 = 0; binz2 = 0;
8058 }
8059
8060 // - Loop on bins in specified range
8061 TString opt = option;
8062 opt.ToLower();
8064 if (opt.Contains("width")) width = kTRUE;
8065
8066
8067 Double_t dx = 1., dy = .1, dz =.1;
8068 Double_t integral = 0;
8069 Double_t igerr2 = 0;
8070 for (Int_t binx = binx1; binx <= binx2; ++binx) {
8071 if (width) dx = fXaxis.GetBinWidth(binx);
8072 for (Int_t biny = biny1; biny <= biny2; ++biny) {
8073 if (width) dy = fYaxis.GetBinWidth(biny);
8074 for (Int_t binz = binz1; binz <= binz2; ++binz) {
8075 Int_t bin = GetBin(binx, biny, binz);
8076 Double_t dv = 0.0;
8077 if (width) {
8079 dv = dx * dy * dz;
8080 integral += RetrieveBinContent(bin) * dv;
8081 } else {
8082 integral += RetrieveBinContent(bin);
8083 }
8084 if (doError) {
8085 if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
8086 else igerr2 += GetBinErrorSqUnchecked(bin);
8087 }
8088 }
8089 }
8090 }
8091
8092 if (doError) error = TMath::Sqrt(igerr2);
8093 return integral;
8094}
8095
8096////////////////////////////////////////////////////////////////////////////////
8097/// Statistical test of compatibility in shape between
8098/// this histogram and h2, using the Anderson-Darling 2 sample test.
8099///
8100/// The AD 2 sample test formula are derived from the paper
8101/// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
8102///
8103/// The test is implemented in root in the ROOT::Math::GoFTest class
8104/// It is the same formula ( (6) in the paper), and also shown in
8105/// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
8106///
8107/// Binned data are considered as un-binned data
8108/// with identical observation happening in the bin center.
8109///
8110/// \param[in] h2 Pointer to 1D histogram
8111/// \param[in] option is a character string to specify options
8112/// - "D" Put out a line of "Debug" printout
8113/// - "T" Return the normalized A-D test statistic
8114///
8115/// - Note1: Underflow and overflow are not considered in the test
8116/// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
8117/// - Note3: The histograms are not required to have the same X axis
8118/// - Note4: The test works only for 1-dimensional histograms
8119
8121{
8122 Double_t advalue = 0;
8124
8125 TString opt = option;
8126 opt.ToUpper();
8127 if (opt.Contains("D") ) {
8128 printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
8129 }
8130 if (opt.Contains("T") ) return advalue;
8131
8132 return pvalue;
8133}
8134
8135////////////////////////////////////////////////////////////////////////////////
8136/// Same function as above but returning also the test statistic value
8137
8139{
8140 if (GetDimension() != 1 || h2->GetDimension() != 1) {
8141 Error("AndersonDarlingTest","Histograms must be 1-D");
8142 return -1;
8143 }
8144
8145 // empty the buffer. Probably we could add as an unbinned test
8146 if (fBuffer) ((TH1*)this)->BufferEmpty();
8147
8148 // use the BinData class
8151
8152 ROOT::Fit::FillData(data1, this, nullptr);
8153 ROOT::Fit::FillData(data2, h2, nullptr);
8154
8155 double pvalue;
8157
8158 return pvalue;
8159}
8160
8161////////////////////////////////////////////////////////////////////////////////
8162/// Statistical test of compatibility in shape between
8163/// this histogram and h2, using Kolmogorov test.
8164/// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
8165/// and not for binned data as in the case of the histogram (see NOTE 3 below).
8166/// So, before using this method blindly, read the NOTE 3.
8167///
8168/// Default: Ignore under- and overflow bins in comparison
8169///
8170/// \param[in] h2 histogram
8171/// \param[in] option is a character string to specify options
8172/// - "U" include Underflows in test (also for 2-dim)
8173/// - "O" include Overflows (also valid for 2-dim)
8174/// - "N" include comparison of normalizations
8175/// - "D" Put out a line of "Debug" printout
8176/// - "M" Return the Maximum Kolmogorov distance instead of prob
8177/// - "X" Run the pseudo experiments post-processor with the following procedure:
8178/// make pseudoexperiments based on random values from the parent distribution,
8179/// compare the KS distance of the pseudoexperiment to the parent
8180/// distribution, and count all the KS values above the value
8181/// obtained from the original data to Monte Carlo distribution.
8182/// The number of pseudo-experiments nEXPT is by default 1000, and
8183/// it can be changed by specifying the option as "X=number",
8184/// for example "X=10000" for 10000 toys.
8185/// The function returns the probability.
8186/// (thanks to Ben Kilminster to submit this procedure). Note that
8187/// this option "X" is much slower.
8188///
8189/// The returned function value is the probability of test
8190/// (much less than one means NOT compatible)
8191///
8192/// Code adapted by Rene Brun from original HBOOK routine HDIFF
8193///
8194/// NOTE1
8195/// A good description of the Kolmogorov test can be seen at:
8196/// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
8197///
8198/// NOTE2
8199/// see also alternative function TH1::Chi2Test
8200/// The Kolmogorov test is assumed to give better results than Chi2Test
8201/// in case of histograms with low statistics.
8202///
8203/// NOTE3 (Jan Conrad, Fred James)
8204/// "The returned value PROB is calculated such that it will be
8205/// uniformly distributed between zero and one for compatible histograms,
8206/// provided the data are not binned (or the number of bins is very large
8207/// compared with the number of events). Users who have access to unbinned
8208/// data and wish exact confidence levels should therefore not put their data
8209/// into histograms, but should call directly TMath::KolmogorovTest. On
8210/// the other hand, since TH1 is a convenient way of collecting data and
8211/// saving space, this function has been provided. However, the values of
8212/// PROB for binned data will be shifted slightly higher than expected,
8213/// depending on the effects of the binning. For example, when comparing two
8214/// uniform distributions of 500 events in 100 bins, the values of PROB,
8215/// instead of being exactly uniformly distributed between zero and one, have
8216/// a mean value of about 0.56. We can apply a useful
8217/// rule: As long as the bin width is small compared with any significant
8218/// physical effect (for example the experimental resolution) then the binning
8219/// cannot have an important effect. Therefore, we believe that for all
8220/// practical purposes, the probability value PROB is calculated correctly
8221/// provided the user is aware that:
8222///
8223/// 1. The value of PROB should not be expected to have exactly the correct
8224/// distribution for binned data.
8225/// 2. The user is responsible for seeing to it that the bin widths are
8226/// small compared with any physical phenomena of interest.
8227/// 3. The effect of binning (if any) is always to make the value of PROB
8228/// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
8229/// will assure that at most 5% of truly compatible histograms are rejected,
8230/// and usually somewhat less."
8231///
8232/// Note also that for GoF test of unbinned data ROOT provides also the class
8233/// ROOT::Math::GoFTest. The class has also method for doing one sample tests
8234/// (i.e. comparing the data with a given distribution).
8235
8237{
8238 TString opt = option;
8239 opt.ToUpper();
8240
8241 Double_t prob = 0;
8242 TH1 *h1 = (TH1*)this;
8243 if (h2 == nullptr) return 0;
8244 const TAxis *axis1 = h1->GetXaxis();
8245 const TAxis *axis2 = h2->GetXaxis();
8246 Int_t ncx1 = axis1->GetNbins();
8247 Int_t ncx2 = axis2->GetNbins();
8248
8249 // Check consistency of dimensions
8250 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
8251 Error("KolmogorovTest","Histograms must be 1-D\n");
8252 return 0;
8253 }
8254
8255 // Check consistency in number of channels
8256 if (ncx1 != ncx2) {
8257 Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
8258 return 0;
8259 }
8260
8261 // empty the buffer. Probably we could add as an unbinned test
8262 if (fBuffer) ((TH1*)this)->BufferEmpty();
8263
8264 // Check consistency in bin edges
8265 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
8266 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
8267 Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
8268 return 0;
8269 }
8270 }
8271
8274 Double_t sum1 = 0, sum2 = 0;
8275 Double_t ew1, ew2, w1 = 0, w2 = 0;
8276 Int_t bin;
8277 Int_t ifirst = 1;
8278 Int_t ilast = ncx1;
8279 // integral of all bins (use underflow/overflow if option)
8280 if (opt.Contains("U")) ifirst = 0;
8281 if (opt.Contains("O")) ilast = ncx1 +1;
8282 for (bin = ifirst; bin <= ilast; bin++) {
8283 sum1 += h1->RetrieveBinContent(bin);
8284 sum2 += h2->RetrieveBinContent(bin);
8285 ew1 = h1->GetBinError(bin);
8286 ew2 = h2->GetBinError(bin);
8287 w1 += ew1*ew1;
8288 w2 += ew2*ew2;
8289 }
8290 if (sum1 == 0) {
8291 Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
8292 return 0;
8293 }
8294 if (sum2 == 0) {
8295 Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
8296 return 0;
8297 }
8298
8299 // calculate the effective entries.
8300 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
8301 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
8302 Double_t esum1 = 0, esum2 = 0;
8303 if (w1 > 0)
8304 esum1 = sum1 * sum1 / w1;
8305 else
8306 afunc1 = kTRUE; // use later for calculating z
8307
8308 if (w2 > 0)
8309 esum2 = sum2 * sum2 / w2;
8310 else
8311 afunc2 = kTRUE; // use later for calculating z
8312
8313 if (afunc2 && afunc1) {
8314 Error("KolmogorovTest","Errors are zero for both histograms\n");
8315 return 0;
8316 }
8317
8318
8319 Double_t s1 = 1/sum1;
8320 Double_t s2 = 1/sum2;
8321
8322 // Find largest difference for Kolmogorov Test
8323 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
8324
8325 for (bin=ifirst;bin<=ilast;bin++) {
8326 rsum1 += s1*h1->RetrieveBinContent(bin);
8327 rsum2 += s2*h2->RetrieveBinContent(bin);
8329 }
8330
8331 // Get Kolmogorov probability
8332 Double_t z, prb1=0, prb2=0, prb3=0;
8333
8334 // case h1 is exact (has zero errors)
8335 if (afunc1)
8336 z = dfmax*TMath::Sqrt(esum2);
8337 // case h2 has zero errors
8338 else if (afunc2)
8339 z = dfmax*TMath::Sqrt(esum1);
8340 else
8341 // for comparison between two data sets
8343
8345
8346 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
8347 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
8348 // Combine probabilities for shape and normalization,
8349 prb1 = prob;
8352 prb2 = TMath::Prob(chi2,1);
8353 // see Eadie et al., section 11.6.2
8354 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
8355 else prob = 0;
8356 }
8357 // X option. Run Pseudo-experiments to determine NULL distribution of the
8358 // KS distance. We can find the probability from the number of pseudo-experiment that have a
8359 // KS distance larger than the one opbserved in the data.
8360 // We use the histogram with the largest statistics as a parent distribution for the NULL.
8361 // Note if one histogram has zero errors is considered as a function. In that case we use it
8362 // as parent distribution for the toys.
8363 //
8364 Int_t nEXPT = 1000;
8365 if (opt.Contains("X")) {
8366 // get number of pseudo-experiment of specified
8367 if (opt.Contains("X=")) {
8368 int numpos = opt.Index("X=") + 2; // 2 is length of X=
8369 int numlen = 0;
8370 int len = opt.Length();
8371 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) )
8372 numlen++;
8373 TString snum = opt(numpos,numlen);
8374 int num = atoi(snum.Data());
8375 if (num <= 0)
8376 Warning("KolmogorovTest","invalid number of toys given: %d - use 1000",num);
8377 else
8378 nEXPT = num;
8379 }
8380
8382 TH1D hparent;
8383 // we cannot have afunc1 and func2 both True
8384 if (afunc1 || esum1 > esum2 ) h1->Copy(hparent);
8385 else h2->Copy(hparent);
8386
8387 // copy h1Expt from h1 and h2. It is just needed to get the correct binning
8388
8389
8390 if (hparent.GetMinimum() < 0.0) {
8391 // we need to create a new histogram
8392 // With negative bins we can't draw random samples in a meaningful way.
8393 Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
8394 "skewed. Reduce number of bins for histogram?");
8395 while (hparent.GetMinimum() < 0.0) {
8396 Int_t idx = hparent.GetMinimumBin();
8397 hparent.SetBinContent(idx, 0.0);
8398 }
8399 }
8400
8401 // make nEXPT experiments (this should be a parameter)
8402 prb3 = 0;
8403 TH1D h1Expt;
8404 h1->Copy(h1Expt);
8405 TH1D h2Expt;
8406 h1->Copy(h2Expt);
8407 // loop on pseudoexperients and generate the two histograms h1Expt and h2Expt according to the
8408 // parent distribution. In case the parent distribution is not an histogram but a function randomize only one
8409 // histogram
8410 for (Int_t i=0; i < nEXPT; i++) {
8411 if (!afunc1) {
8412 h1Expt.Reset();
8413 h1Expt.FillRandom(&hparent, (Int_t)esum1);
8414 }
8415 if (!afunc2) {
8416 h2Expt.Reset();
8417 h2Expt.FillRandom(&hparent, (Int_t)esum2);
8418 }
8419 // note we cannot have both afunc1 and afunc2 to be true
8420 if (afunc1)
8421 dSEXPT = hparent.KolmogorovTest(&h2Expt,"M");
8422 else if (afunc2)
8423 dSEXPT = hparent.KolmogorovTest(&h1Expt,"M");
8424 else
8425 dSEXPT = h1Expt.KolmogorovTest(&h2Expt,"M");
8426 // count number of cases toy KS distance (TS) is larger than oberved one
8427 if (dSEXPT>dfmax) prb3 += 1.0;
8428 }
8429 // compute p-value
8430 prb3 /= (Double_t)nEXPT;
8431 }
8432
8433
8434 // debug printout
8435 if (opt.Contains("D")) {
8436 printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
8437 printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
8438 printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
8439 if (opt.Contains("N"))
8440 printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
8441 if (opt.Contains("X"))
8442 printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
8443 }
8444 // This numerical error condition should never occur:
8445 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
8446 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
8447
8448 if(opt.Contains("M")) return dfmax;
8449 else if(opt.Contains("X")) return prb3;
8450 else return prob;
8451}
8452
8453////////////////////////////////////////////////////////////////////////////////
8454/// Replace bin contents by the contents of array content
8455
8456void TH1::SetContent(const Double_t *content)
8457{
8458 fEntries = fNcells;
8459 fTsumw = 0;
8460 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
8461}
8462
8463////////////////////////////////////////////////////////////////////////////////
8464/// Return contour values into array levels if pointer levels is non zero.
8465///
8466/// The function returns the number of contour levels.
8467/// see GetContourLevel to return one contour only
8468
8470{
8472 if (levels) {
8473 if (nlevels == 0) {
8474 nlevels = 20;
8476 } else {
8478 }
8479 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
8480 }
8481 return nlevels;
8482}
8483
8484////////////////////////////////////////////////////////////////////////////////
8485/// Return value of contour number level.
8486/// Use GetContour to return the array of all contour levels
8487
8489{
8490 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
8491}
8492
8493////////////////////////////////////////////////////////////////////////////////
8494/// Return the value of contour number "level" in Pad coordinates.
8495/// ie: if the Pad is in log scale along Z it returns le log of the contour level
8496/// value. See GetContour to return the array of all contour levels
8497
8499{
8500 if (level <0 || level >= fContour.fN) return 0;
8501 Double_t zlevel = fContour.fArray[level];
8502
8503 // In case of user defined contours and Pad in log scale along Z,
8504 // fContour.fArray doesn't contain the log of the contour whereas it does
8505 // in case of equidistant contours.
8506 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
8507 if (zlevel <= 0) return 0;
8509 }
8510 return zlevel;
8511}
8512
8513////////////////////////////////////////////////////////////////////////////////
8514/// Set the maximum number of entries to be kept in the buffer.
8515
8516void TH1::SetBuffer(Int_t bufsize, Option_t * /*option*/)
8517{
8518 if (fBuffer) {
8519 BufferEmpty();
8520 delete [] fBuffer;
8521 fBuffer = nullptr;
8522 }
8523 if (bufsize <= 0) {
8524 fBufferSize = 0;
8525 return;
8526 }
8527 if (bufsize < 100) bufsize = 100;
8528 fBufferSize = 1 + bufsize*(fDimension+1);
8530 memset(fBuffer, 0, sizeof(Double_t)*fBufferSize);
8531}
8532
8533////////////////////////////////////////////////////////////////////////////////
8534/// Set the number and values of contour levels.
8535///
8536/// By default the number of contour levels is set to 20. The contours values
8537/// in the array "levels" should be specified in increasing order.
8538///
8539/// if argument levels = 0 or missing, `nlevels` equidistant contours are computed
8540/// between `zmin` and `zmax - dz`, both included, with step
8541/// `dz = (zmax - zmin)/nlevels`. Note that contour lines are not centered, but
8542/// contour surfaces (when drawing with `COLZ`) will be, since contour color `i` covers
8543/// the region of values between contour line `i` and `i+1`.
8544
8546{
8547 Int_t level;
8549 if (nlevels <=0 ) {
8550 fContour.Set(0);
8551 return;
8552 }
8554
8555 // - Contour levels are specified
8556 if (levels) {
8558 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
8559 } else {
8560 // - contour levels are computed automatically as equidistant contours
8561 Double_t zmin = GetMinimum();
8562 Double_t zmax = GetMaximum();
8563 if ((zmin == zmax) && (zmin != 0)) {
8564 zmax += 0.01*TMath::Abs(zmax);
8565 zmin -= 0.01*TMath::Abs(zmin);
8566 }
8567 Double_t dz = (zmax-zmin)/Double_t(nlevels);
8568 if (gPad && gPad->GetLogz()) {
8569 if (zmax <= 0) return;
8570 if (zmin <= 0) zmin = 0.001*zmax;
8571 zmin = TMath::Log10(zmin);
8572 zmax = TMath::Log10(zmax);
8573 dz = (zmax-zmin)/Double_t(nlevels);
8574 }
8575 for (level=0; level<nlevels; level++) {
8576 fContour.fArray[level] = zmin + dz*Double_t(level);
8577 }
8578 }
8579}
8580
8581////////////////////////////////////////////////////////////////////////////////
8582/// Set value for one contour level.
8583
8585{
8586 if (level < 0 || level >= fContour.fN) return;
8588 fContour.fArray[level] = value;
8589}
8590
8591////////////////////////////////////////////////////////////////////////////////
8592/// Return maximum value smaller than maxval of bins in the range,
8593/// unless the value has been overridden by TH1::SetMaximum,
8594/// in which case it returns that value. This happens, for example,
8595/// when the histogram is drawn and the y or z axis limits are changed
8596///
8597/// To get the maximum value of bins in the histogram regardless of
8598/// whether the value has been overridden (using TH1::SetMaximum), use
8599///
8600/// ~~~ {.cpp}
8601/// h->GetBinContent(h->GetMaximumBin())
8602/// ~~~
8603///
8604/// TH1::GetMaximumBin can be used to get the location of the maximum
8605/// value.
8606
8608{
8609 if (fMaximum != -1111) return fMaximum;
8610
8611 // empty the buffer
8612 if (fBuffer) ((TH1*)this)->BufferEmpty();
8613
8614 Int_t bin, binx, biny, binz;
8615 Int_t xfirst = fXaxis.GetFirst();
8616 Int_t xlast = fXaxis.GetLast();
8617 Int_t yfirst = fYaxis.GetFirst();
8618 Int_t ylast = fYaxis.GetLast();
8619 Int_t zfirst = fZaxis.GetFirst();
8620 Int_t zlast = fZaxis.GetLast();
8622 for (binz=zfirst;binz<=zlast;binz++) {
8623 for (biny=yfirst;biny<=ylast;biny++) {
8624 for (binx=xfirst;binx<=xlast;binx++) {
8625 bin = GetBin(binx,biny,binz);
8627 if (value > maximum && value < maxval) maximum = value;
8628 }
8629 }
8630 }
8631 return maximum;
8632}
8633
8634////////////////////////////////////////////////////////////////////////////////
8635/// Return location of bin with maximum value in the range.
8636///
8637/// TH1::GetMaximum can be used to get the maximum value.
8638
8640{
8643}
8644
8645////////////////////////////////////////////////////////////////////////////////
8646/// Return location of bin with maximum value in the range.
8647
8649{
8650 // empty the buffer
8651 if (fBuffer) ((TH1*)this)->BufferEmpty();
8652
8653 Int_t bin, binx, biny, binz;
8654 Int_t locm;
8655 Int_t xfirst = fXaxis.GetFirst();
8656 Int_t xlast = fXaxis.GetLast();
8657 Int_t yfirst = fYaxis.GetFirst();
8658 Int_t ylast = fYaxis.GetLast();
8659 Int_t zfirst = fZaxis.GetFirst();
8660 Int_t zlast = fZaxis.GetLast();
8662 locm = locmax = locmay = locmaz = 0;
8663 for (binz=zfirst;binz<=zlast;binz++) {
8664 for (biny=yfirst;biny<=ylast;biny++) {
8665 for (binx=xfirst;binx<=xlast;binx++) {
8666 bin = GetBin(binx,biny,binz);
8668 if (value > maximum) {
8669 maximum = value;
8670 locm = bin;
8671 locmax = binx;
8672 locmay = biny;
8673 locmaz = binz;
8674 }
8675 }
8676 }
8677 }
8678 return locm;
8679}
8680
8681////////////////////////////////////////////////////////////////////////////////
8682/// Return minimum value larger than minval of bins in the range,
8683/// unless the value has been overridden by TH1::SetMinimum,
8684/// in which case it returns that value. This happens, for example,
8685/// when the histogram is drawn and the y or z axis limits are changed
8686///
8687/// To get the minimum value of bins in the histogram regardless of
8688/// whether the value has been overridden (using TH1::SetMinimum), use
8689///
8690/// ~~~ {.cpp}
8691/// h->GetBinContent(h->GetMinimumBin())
8692/// ~~~
8693///
8694/// TH1::GetMinimumBin can be used to get the location of the
8695/// minimum value.
8696
8698{
8699 if (fMinimum != -1111) return fMinimum;
8700
8701 // empty the buffer
8702 if (fBuffer) ((TH1*)this)->BufferEmpty();
8703
8704 Int_t bin, binx, biny, binz;
8705 Int_t xfirst = fXaxis.GetFirst();
8706 Int_t xlast = fXaxis.GetLast();
8707 Int_t yfirst = fYaxis.GetFirst();
8708 Int_t ylast = fYaxis.GetLast();
8709 Int_t zfirst = fZaxis.GetFirst();
8710 Int_t zlast = fZaxis.GetLast();
8712 for (binz=zfirst;binz<=zlast;binz++) {
8713 for (biny=yfirst;biny<=ylast;biny++) {
8714 for (binx=xfirst;binx<=xlast;binx++) {
8715 bin = GetBin(binx,biny,binz);
8718 }
8719 }
8720 }
8721 return minimum;
8722}
8723
8724////////////////////////////////////////////////////////////////////////////////
8725/// Return location of bin with minimum value in the range.
8726
8728{
8731}
8732
8733////////////////////////////////////////////////////////////////////////////////
8734/// Return location of bin with minimum value in the range.
8735
8737{
8738 // empty the buffer
8739 if (fBuffer) ((TH1*)this)->BufferEmpty();
8740
8741 Int_t bin, binx, biny, binz;
8742 Int_t locm;
8743 Int_t xfirst = fXaxis.GetFirst();
8744 Int_t xlast = fXaxis.GetLast();
8745 Int_t yfirst = fYaxis.GetFirst();
8746 Int_t ylast = fYaxis.GetLast();
8747 Int_t zfirst = fZaxis.GetFirst();
8748 Int_t zlast = fZaxis.GetLast();
8750 locm = locmix = locmiy = locmiz = 0;
8751 for (binz=zfirst;binz<=zlast;binz++) {
8752 for (biny=yfirst;biny<=ylast;biny++) {
8753 for (binx=xfirst;binx<=xlast;binx++) {
8754 bin = GetBin(binx,biny,binz);
8756 if (value < minimum) {
8757 minimum = value;
8758 locm = bin;
8759 locmix = binx;
8760 locmiy = biny;
8761 locmiz = binz;
8762 }
8763 }
8764 }
8765 }
8766 return locm;
8767}
8768
8769///////////////////////////////////////////////////////////////////////////////
8770/// Retrieve the minimum and maximum values in the histogram
8771///
8772/// This will not return a cached value and will always search the
8773/// histogram for the min and max values. The user can condition whether
8774/// or not to call this with the GetMinimumStored() and GetMaximumStored()
8775/// methods. If the cache is empty, then the value will be -1111. Users
8776/// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8777/// For example, the following recipe will make efficient use of this method
8778/// and the cached minimum and maximum values.
8779//
8780/// \code{.cpp}
8781/// Double_t currentMin = pHist->GetMinimumStored();
8782/// Double_t currentMax = pHist->GetMaximumStored();
8783/// if ((currentMin == -1111) || (currentMax == -1111)) {
8784/// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8785/// pHist->SetMinimum(currentMin);
8786/// pHist->SetMaximum(currentMax);
8787/// }
8788/// \endcode
8789///
8790/// \param min reference to variable that will hold found minimum value
8791/// \param max reference to variable that will hold found maximum value
8792
8793void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8794{
8795 // empty the buffer
8796 if (fBuffer) ((TH1*)this)->BufferEmpty();
8797
8798 Int_t bin, binx, biny, binz;
8799 Int_t xfirst = fXaxis.GetFirst();
8800 Int_t xlast = fXaxis.GetLast();
8801 Int_t yfirst = fYaxis.GetFirst();
8802 Int_t ylast = fYaxis.GetLast();
8803 Int_t zfirst = fZaxis.GetFirst();
8804 Int_t zlast = fZaxis.GetLast();
8805 min=TMath::Infinity();
8806 max=-TMath::Infinity();
8808 for (binz=zfirst;binz<=zlast;binz++) {
8809 for (biny=yfirst;biny<=ylast;biny++) {
8810 for (binx=xfirst;binx<=xlast;binx++) {
8811 bin = GetBin(binx,biny,binz);
8813 if (value < min) min = value;
8814 if (value > max) max = value;
8815 }
8816 }
8817 }
8818}
8819
8820////////////////////////////////////////////////////////////////////////////////
8821/// Redefine x axis parameters.
8822///
8823/// The X axis parameters are modified.
8824/// The bins content array is resized
8825/// if errors (Sumw2) the errors array is resized
8826/// The previous bin contents are lost
8827/// To change only the axis limits, see TAxis::SetRange
8828
8830{
8831 if (GetDimension() != 1) {
8832 Error("SetBins","Operation only valid for 1-d histograms");
8833 return;
8834 }
8835 fXaxis.SetRange(0,0);
8837 fYaxis.Set(1,0,1);
8838 fZaxis.Set(1,0,1);
8839 fNcells = nx+2;
8841 if (fSumw2.fN) {
8843 }
8844}
8845
8846////////////////////////////////////////////////////////////////////////////////
8847/// Redefine x axis parameters with variable bin sizes.
8848///
8849/// The X axis parameters are modified.
8850/// The bins content array is resized
8851/// if errors (Sumw2) the errors array is resized
8852/// The previous bin contents are lost
8853/// To change only the axis limits, see TAxis::SetRange
8854/// xBins is supposed to be of length nx+1
8855
8856void TH1::SetBins(Int_t nx, const Double_t *xBins)
8857{
8858 if (GetDimension() != 1) {
8859 Error("SetBins","Operation only valid for 1-d histograms");
8860 return;
8861 }
8862 fXaxis.SetRange(0,0);
8863 fXaxis.Set(nx,xBins);
8864 fYaxis.Set(1,0,1);
8865 fZaxis.Set(1,0,1);
8866 fNcells = nx+2;
8868 if (fSumw2.fN) {
8870 }
8871}
8872
8873////////////////////////////////////////////////////////////////////////////////
8874/// Redefine x and y axis parameters.
8875///
8876/// The X and Y axis parameters are modified.
8877/// The bins content array is resized
8878/// if errors (Sumw2) the errors array is resized
8879/// The previous bin contents are lost
8880/// To change only the axis limits, see TAxis::SetRange
8881
8883{
8884 if (GetDimension() != 2) {
8885 Error("SetBins","Operation only valid for 2-D histograms");
8886 return;
8887 }
8888 fXaxis.SetRange(0,0);
8889 fYaxis.SetRange(0,0);
8892 fZaxis.Set(1,0,1);
8893 fNcells = (nx+2)*(ny+2);
8895 if (fSumw2.fN) {
8897 }
8898}
8899
8900////////////////////////////////////////////////////////////////////////////////
8901/// Redefine x and y axis parameters with variable bin sizes.
8902///
8903/// The X and Y axis parameters are modified.
8904/// The bins content array is resized
8905/// if errors (Sumw2) the errors array is resized
8906/// The previous bin contents are lost
8907/// To change only the axis limits, see TAxis::SetRange
8908/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
8909
8910void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
8911{
8912 if (GetDimension() != 2) {
8913 Error("SetBins","Operation only valid for 2-D histograms");
8914 return;
8915 }
8916 fXaxis.SetRange(0,0);
8917 fYaxis.SetRange(0,0);
8918 fXaxis.Set(nx,xBins);
8919 fYaxis.Set(ny,yBins);
8920 fZaxis.Set(1,0,1);
8921 fNcells = (nx+2)*(ny+2);
8923 if (fSumw2.fN) {
8925 }
8926}
8927
8928////////////////////////////////////////////////////////////////////////////////
8929/// Redefine x, y and z axis parameters.
8930///
8931/// The X, Y and Z axis parameters are modified.
8932/// The bins content array is resized
8933/// if errors (Sumw2) the errors array is resized
8934/// The previous bin contents are lost
8935/// To change only the axis limits, see TAxis::SetRange
8936
8938{
8939 if (GetDimension() != 3) {
8940 Error("SetBins","Operation only valid for 3-D histograms");
8941 return;
8942 }
8943 fXaxis.SetRange(0,0);
8944 fYaxis.SetRange(0,0);
8945 fZaxis.SetRange(0,0);
8948 fZaxis.Set(nz,zmin,zmax);
8949 fNcells = (nx+2)*(ny+2)*(nz+2);
8951 if (fSumw2.fN) {
8953 }
8954}
8955
8956////////////////////////////////////////////////////////////////////////////////
8957/// Redefine x, y and z axis parameters with variable bin sizes.
8958///
8959/// The X, Y and Z axis parameters are modified.
8960/// The bins content array is resized
8961/// if errors (Sumw2) the errors array is resized
8962/// The previous bin contents are lost
8963/// To change only the axis limits, see TAxis::SetRange
8964/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
8965/// zBins is supposed to be of length nz+1
8966
8967void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
8968{
8969 if (GetDimension() != 3) {
8970 Error("SetBins","Operation only valid for 3-D histograms");
8971 return;
8972 }
8973 fXaxis.SetRange(0,0);
8974 fYaxis.SetRange(0,0);
8975 fZaxis.SetRange(0,0);
8976 fXaxis.Set(nx,xBins);
8977 fYaxis.Set(ny,yBins);
8978 fZaxis.Set(nz,zBins);
8979 fNcells = (nx+2)*(ny+2)*(nz+2);
8981 if (fSumw2.fN) {
8983 }
8984}
8985
8986////////////////////////////////////////////////////////////////////////////////
8987/// By default, when a histogram is created, it is added to the list
8988/// of histogram objects in the current directory in memory.
8989/// Remove reference to this histogram from current directory and add
8990/// reference to new directory dir. dir can be 0 in which case the
8991/// histogram does not belong to any directory.
8992///
8993/// Note that the directory is not a real property of the histogram and
8994/// it will not be copied when the histogram is copied or cloned.
8995/// If the user wants to have the copied (cloned) histogram in the same
8996/// directory, he needs to set again the directory using SetDirectory to the
8997/// copied histograms
8998
9000{
9001 if (fDirectory == dir) return;
9002 if (fDirectory) fDirectory->Remove(this);
9003 fDirectory = dir;
9004 if (fDirectory) {
9006 fDirectory->Append(this);
9007 }
9008}
9009
9010////////////////////////////////////////////////////////////////////////////////
9011/// Replace bin errors by values in array error.
9012
9013void TH1::SetError(const Double_t *error)
9014{
9015 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
9016}
9017
9018////////////////////////////////////////////////////////////////////////////////
9019/// Change the name of this histogram
9021
9022void TH1::SetName(const char *name)
9023{
9024 // Histograms are named objects in a THashList.
9025 // We must update the hashlist if we change the name
9026 // We protect this operation
9028 if (fDirectory) fDirectory->Remove(this);
9029 fName = name;
9030 if (fDirectory) fDirectory->Append(this);
9031}
9032
9033////////////////////////////////////////////////////////////////////////////////
9034/// Change the name and title of this histogram
9035
9036void TH1::SetNameTitle(const char *name, const char *title)
9037{
9038 // Histograms are named objects in a THashList.
9039 // We must update the hashlist if we change the name
9040 SetName(name);
9041 SetTitle(title);
9042}
9043
9044////////////////////////////////////////////////////////////////////////////////
9045/// Set statistics option on/off.
9046///
9047/// By default, the statistics box is drawn.
9048/// The paint options can be selected via gStyle->SetOptStat.
9049/// This function sets/resets the kNoStats bit in the histogram object.
9050/// It has priority over the Style option.
9051
9052void TH1::SetStats(Bool_t stats)
9053{
9055 if (!stats) {
9057 //remove the "stats" object from the list of functions
9058 if (fFunctions) {
9059 TObject *obj = fFunctions->FindObject("stats");
9060 if (obj) {
9061 fFunctions->Remove(obj);
9062 delete obj;
9063 }
9064 }
9065 }
9066}
9067
9068////////////////////////////////////////////////////////////////////////////////
9069/// Create structure to store sum of squares of weights.
9070///
9071/// if histogram is already filled, the sum of squares of weights
9072/// is filled with the existing bin contents
9073///
9074/// The error per bin will be computed as sqrt(sum of squares of weight)
9075/// for each bin.
9076///
9077/// This function is automatically called when the histogram is created
9078/// if the static function TH1::SetDefaultSumw2 has been called before.
9079/// If flag = false the structure containing the sum of the square of weights
9080/// is rest and it will be empty, but it is not deleted (i.e. GetSumw2()->fN = 0)
9081
9083{
9084 if (!flag) {
9085 // clear the array if existing - do nothing otherwise
9086 if (fSumw2.fN > 0 ) fSumw2.Set(0);
9087 return;
9088 }
9089
9090 if (fSumw2.fN == fNcells) {
9091 if (!fgDefaultSumw2 )
9092 Warning("Sumw2","Sum of squares of weights structure already created");
9093 return;
9094 }
9095
9097
9098 if (fEntries > 0)
9099 for (Int_t i = 0; i < fNcells; ++i)
9101}
9102
9103////////////////////////////////////////////////////////////////////////////////
9104/// Return pointer to function with name.
9105///
9106///
9107/// Functions such as TH1::Fit store the fitted function in the list of
9108/// functions of this histogram.
9109
9110TF1 *TH1::GetFunction(const char *name) const
9111{
9112 return (TF1*)fFunctions->FindObject(name);
9113}
9114
9115////////////////////////////////////////////////////////////////////////////////
9116/// Return value of error associated to bin number bin.
9117///
9118/// if the sum of squares of weights has been defined (via Sumw2),
9119/// this function returns the sqrt(sum of w2).
9120/// otherwise it returns the sqrt(contents) for this bin.
9121
9123{
9124 if (bin < 0) bin = 0;
9125 if (bin >= fNcells) bin = fNcells-1;
9126 if (fBuffer) ((TH1*)this)->BufferEmpty();
9127 if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
9128
9130}
9131
9132////////////////////////////////////////////////////////////////////////////////
9133/// Return lower error associated to bin number bin.
9134///
9135/// The error will depend on the statistic option used will return
9136/// the binContent - lower interval value
9137
9139{
9140 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9141 // in case of weighted histogram check if it is really weighted
9142 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9143
9144 if (bin < 0) bin = 0;
9145 if (bin >= fNcells) bin = fNcells-1;
9146 if (fBuffer) ((TH1*)this)->BufferEmpty();
9147
9148 Double_t alpha = 1.- 0.682689492;
9149 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9150
9152 Int_t n = int(c);
9153 if (n < 0) {
9154 Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
9155 ((TH1*)this)->fBinStatErrOpt = kNormal;
9156 return GetBinError(bin);
9157 }
9158
9159 if (n == 0) return 0;
9160 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
9161}
9162
9163////////////////////////////////////////////////////////////////////////////////
9164/// Return upper error associated to bin number bin.
9165///
9166/// The error will depend on the statistic option used will return
9167/// the binContent - upper interval value
9168
9170{
9171 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9172 // in case of weighted histogram check if it is really weighted
9173 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9174 if (bin < 0) bin = 0;
9175 if (bin >= fNcells) bin = fNcells-1;
9176 if (fBuffer) ((TH1*)this)->BufferEmpty();
9177
9178 Double_t alpha = 1.- 0.682689492;
9179 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9180
9182 Int_t n = int(c);
9183 if (n < 0) {
9184 Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
9185 ((TH1*)this)->fBinStatErrOpt = kNormal;
9186 return GetBinError(bin);
9187 }
9188
9189 // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
9190 // decide to return always (1-alpha)/2 upper interval
9191 //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
9192 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
9193}
9194
9195//L.M. These following getters are useless and should be probably deprecated
9196////////////////////////////////////////////////////////////////////////////////
9197/// Return bin center for 1D histogram.
9198/// Better to use h1.GetXaxis()->GetBinCenter(bin)
9199
9201{
9202 if (fDimension == 1) return fXaxis.GetBinCenter(bin);
9203 Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
9204 return TMath::QuietNaN();
9205}
9206
9207////////////////////////////////////////////////////////////////////////////////
9208/// Return bin lower edge for 1D histogram.
9209/// Better to use h1.GetXaxis()->GetBinLowEdge(bin)
9210
9212{
9213 if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
9214 Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
9215 return TMath::QuietNaN();
9216}
9217
9218////////////////////////////////////////////////////////////////////////////////
9219/// Return bin width for 1D histogram.
9220/// Better to use h1.GetXaxis()->GetBinWidth(bin)
9221
9223{
9224 if (fDimension == 1) return fXaxis.GetBinWidth(bin);
9225 Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
9226 return TMath::QuietNaN();
9227}
9228
9229////////////////////////////////////////////////////////////////////////////////
9230/// Fill array with center of bins for 1D histogram
9231/// Better to use h1.GetXaxis()->GetCenter(center)
9232
9233void TH1::GetCenter(Double_t *center) const
9234{
9235 if (fDimension == 1) {
9236 fXaxis.GetCenter(center);
9237 return;
9238 }
9239 Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
9240}
9241
9242////////////////////////////////////////////////////////////////////////////////
9243/// Fill array with low edge of bins for 1D histogram
9244/// Better to use h1.GetXaxis()->GetLowEdge(edge)
9245
9246void TH1::GetLowEdge(Double_t *edge) const
9247{
9248 if (fDimension == 1) {
9250 return;
9251 }
9252 Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
9253}
9254
9255////////////////////////////////////////////////////////////////////////////////
9256/// Set the bin Error
9257/// Note that this resets the bin eror option to be of Normal Type and for the
9258/// non-empty bin the bin error is set by default to the square root of their content.
9259/// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
9260/// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
9261/// will not be recalculated after setting the content and a default error = 0 will be used for those bins.
9262///
9263/// See convention for numbering bins in TH1::GetBin
9264
9265void TH1::SetBinError(Int_t bin, Double_t error)
9266{
9267 if (bin < 0 || bin>= fNcells) return;
9268 if (!fSumw2.fN) Sumw2();
9269 fSumw2.fArray[bin] = error * error;
9270 // reset the bin error option
9272}
9273
9274////////////////////////////////////////////////////////////////////////////////
9275/// Set bin content
9276/// see convention for numbering bins in TH1::GetBin
9277/// In case the bin number is greater than the number of bins and
9278/// the timedisplay option is set or CanExtendAllAxes(),
9279/// the number of bins is automatically doubled to accommodate the new bin
9280
9282{
9283 fEntries++;
9284 fTsumw = 0;
9285 if (bin < 0) return;
9286 if (bin >= fNcells-1) {
9288 while (bin >= fNcells-1) LabelsInflate();
9289 } else {
9290 if (bin == fNcells-1) UpdateBinContent(bin, content);
9291 return;
9292 }
9293 }
9295}
9296
9297////////////////////////////////////////////////////////////////////////////////
9298/// See convention for numbering bins in TH1::GetBin
9299
9301{
9302 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9303 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9304 SetBinError(GetBin(binx, biny), error);
9305}
9306
9307////////////////////////////////////////////////////////////////////////////////
9308/// See convention for numbering bins in TH1::GetBin
9309
9311{
9312 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9313 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9314 if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
9315 SetBinError(GetBin(binx, biny, binz), error);
9316}
9317
9318////////////////////////////////////////////////////////////////////////////////
9319/// This function calculates the background spectrum in this histogram.
9320/// The background is returned as a histogram.
9321///
9322/// \param[in] niter number of iterations (default value = 2)
9323/// Increasing niter make the result smoother and lower.
9324/// \param[in] option may contain one of the following options
9325/// - to set the direction parameter
9326/// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
9327/// - filterOrder-order of clipping filter (default "BackOrder2")
9328/// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
9329/// - "nosmoothing" - if selected, the background is not smoothed
9330/// By default the background is smoothed.
9331/// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
9332/// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
9333/// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
9334/// - "nocompton" - if selected the estimation of Compton edge
9335/// will be not be included (by default the compton estimation is set)
9336/// - "same" if this option is specified, the resulting background
9337/// histogram is superimposed on the picture in the current pad.
9338/// This option is given by default.
9339///
9340/// NOTE that the background is only evaluated in the current range of this histogram.
9341/// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
9342/// the returned histogram will be created with the same number of bins
9343/// as this input histogram, but only bins from binmin to binmax will be filled
9344/// with the estimated background.
9345
9347{
9348 return (TH1*)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticBackground((TH1*)0x%zx,%d,\"%s\")",
9349 (size_t)this, niter, option).Data());
9350}
9351
9352////////////////////////////////////////////////////////////////////////////////
9353/// Interface to TSpectrum::Search.
9354/// The function finds peaks in this histogram where the width is > sigma
9355/// and the peak maximum greater than threshold*maximum bin content of this.
9356/// For more details see TSpectrum::Search.
9357/// Note the difference in the default value for option compared to TSpectrum::Search
9358/// option="" by default (instead of "goff").
9359
9361{
9362 return (Int_t)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticSearch((TH1*)0x%zx,%g,\"%s\",%g)",
9363 (size_t)this, sigma, option, threshold).Data());
9364}
9365
9366////////////////////////////////////////////////////////////////////////////////
9367/// For a given transform (first parameter), fills the histogram (second parameter)
9368/// with the transform output data, specified in the third parameter
9369/// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
9370/// and the user is responsible for deleting it.
9371///
9372/// Available options:
9373/// - "RE" - real part of the output
9374/// - "IM" - imaginary part of the output
9375/// - "MAG" - magnitude of the output
9376/// - "PH" - phase of the output
9377
9379{
9380 if (!fft || !fft->GetN() ) {
9381 ::Error("TransformHisto","Invalid FFT transform class");
9382 return nullptr;
9383 }
9384
9385 if (fft->GetNdim()>2){
9386 ::Error("TransformHisto","Only 1d and 2D transform are supported");
9387 return nullptr;
9388 }
9389 Int_t binx,biny;
9390 TString opt = option;
9391 opt.ToUpper();
9392 Int_t *n = fft->GetN();
9393 TH1 *hout=nullptr;
9394 if (h_output) {
9395 hout = h_output;
9396 }
9397 else {
9398 TString name = TString::Format("out_%s", opt.Data());
9399 if (fft->GetNdim()==1)
9400 hout = new TH1D(name, name,n[0], 0, n[0]);
9401 else if (fft->GetNdim()==2)
9402 hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
9403 }
9404 R__ASSERT(hout != nullptr);
9405 TString type=fft->GetType();
9406 Int_t ind[2];
9407 if (opt.Contains("RE")){
9408 if (type.Contains("2C") || type.Contains("2HC")) {
9409 Double_t re, im;
9410 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9411 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9412 ind[0] = binx-1; ind[1] = biny-1;
9413 fft->GetPointComplex(ind, re, im);
9414 hout->SetBinContent(binx, biny, re);
9415 }
9416 }
9417 } else {
9418 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9419 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9420 ind[0] = binx-1; ind[1] = biny-1;
9421 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
9422 }
9423 }
9424 }
9425 }
9426 if (opt.Contains("IM")) {
9427 if (type.Contains("2C") || type.Contains("2HC")) {
9428 Double_t re, im;
9429 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9430 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9431 ind[0] = binx-1; ind[1] = biny-1;
9432 fft->GetPointComplex(ind, re, im);
9433 hout->SetBinContent(binx, biny, im);
9434 }
9435 }
9436 } else {
9437 ::Error("TransformHisto","No complex numbers in the output");
9438 return nullptr;
9439 }
9440 }
9441 if (opt.Contains("MA")) {
9442 if (type.Contains("2C") || type.Contains("2HC")) {
9443 Double_t re, im;
9444 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9445 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9446 ind[0] = binx-1; ind[1] = biny-1;
9447 fft->GetPointComplex(ind, re, im);
9448 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
9449 }
9450 }
9451 } else {
9452 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9453 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9454 ind[0] = binx-1; ind[1] = biny-1;
9455 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
9456 }
9457 }
9458 }
9459 }
9460 if (opt.Contains("PH")) {
9461 if (type.Contains("2C") || type.Contains("2HC")){
9462 Double_t re, im, ph;
9463 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
9464 for (biny=1; biny<=hout->GetNbinsY(); biny++){
9465 ind[0] = binx-1; ind[1] = biny-1;
9466 fft->GetPointComplex(ind, re, im);
9467 if (TMath::Abs(re) > 1e-13){
9468 ph = TMath::ATan(im/re);
9469 //find the correct quadrant
9470 if (re<0 && im<0)
9471 ph -= TMath::Pi();
9472 if (re<0 && im>=0)
9473 ph += TMath::Pi();
9474 } else {
9475 if (TMath::Abs(im) < 1e-13)
9476 ph = 0;
9477 else if (im>0)
9478 ph = TMath::Pi()*0.5;
9479 else
9480 ph = -TMath::Pi()*0.5;
9481 }
9482 hout->SetBinContent(binx, biny, ph);
9483 }
9484 }
9485 } else {
9486 printf("Pure real output, no phase");
9487 return nullptr;
9488 }
9489 }
9490
9491 return hout;
9492}
9493
9494////////////////////////////////////////////////////////////////////////////////
9495/// Print value overload
9496
9497std::string cling::printValue(TH1 *val) {
9498 std::ostringstream strm;
9499 strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
9500 return strm.str();
9501}
9502
9503//______________________________________________________________________________
9504// TH1C methods
9505// TH1C : histograms with one byte per channel. Maximum bin content = 127
9506//______________________________________________________________________________
9507
9508
9509////////////////////////////////////////////////////////////////////////////////
9510/// Constructor.
9511
9512TH1C::TH1C()
9513{
9514 fDimension = 1;
9515 SetBinsLength(3);
9516 if (fgDefaultSumw2) Sumw2();
9517}
9518
9519////////////////////////////////////////////////////////////////////////////////
9520/// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
9521/// (see TH1::TH1 for explanation of parameters)
9522
9523TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9524: TH1(name,title,nbins,xlow,xup)
9525{
9526 fDimension = 1;
9528
9529 if (xlow >= xup) SetBuffer(fgBufferSize);
9530 if (fgDefaultSumw2) Sumw2();
9531}
9532
9533////////////////////////////////////////////////////////////////////////////////
9534/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9535/// (see TH1::TH1 for explanation of parameters)
9536
9537TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9538: TH1(name,title,nbins,xbins)
9539{
9540 fDimension = 1;
9542 if (fgDefaultSumw2) Sumw2();
9543}
9544
9545////////////////////////////////////////////////////////////////////////////////
9546/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9547/// (see TH1::TH1 for explanation of parameters)
9548
9549TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9550: TH1(name,title,nbins,xbins)
9551{
9552 fDimension = 1;
9554 if (fgDefaultSumw2) Sumw2();
9555}
9556
9557////////////////////////////////////////////////////////////////////////////////
9558/// Destructor.
9559
9561{
9562}
9563
9564////////////////////////////////////////////////////////////////////////////////
9565/// Copy constructor.
9566/// The list of functions is not copied. (Use Clone() if needed)
9567
9568TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
9569{
9570 h1c.TH1C::Copy(*this);
9571}
9572
9573////////////////////////////////////////////////////////////////////////////////
9574/// Increment bin content by 1.
9575/// Passing an out-of-range bin leads to undefined behavior
9576
9577void TH1C::AddBinContent(Int_t bin)
9578{
9579 if (fArray[bin] < 127) fArray[bin]++;
9580}
9581
9582////////////////////////////////////////////////////////////////////////////////
9583/// Increment bin content by w.
9584/// \warning The value of w is cast to `Int_t` before being added.
9585/// Passing an out-of-range bin leads to undefined behavior
9586
9588{
9589 Int_t newval = fArray[bin] + Int_t(w);
9590 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
9591 if (newval < -127) fArray[bin] = -127;
9592 if (newval > 127) fArray[bin] = 127;
9593}
9594
9595////////////////////////////////////////////////////////////////////////////////
9596/// Copy this to newth1
9597
9598void TH1C::Copy(TObject &newth1) const
9599{
9601}
9602
9603////////////////////////////////////////////////////////////////////////////////
9604/// Reset.
9605
9607{
9610}
9611
9612////////////////////////////////////////////////////////////////////////////////
9613/// Set total number of bins including under/overflow
9614/// Reallocate bin contents array
9615
9617{
9618 if (n < 0) n = fXaxis.GetNbins() + 2;
9619 fNcells = n;
9620 TArrayC::Set(n);
9621}
9622
9623////////////////////////////////////////////////////////////////////////////////
9624/// Operator =
9625
9626TH1C& TH1C::operator=(const TH1C &h1)
9627{
9628 if (this != &h1)
9629 h1.TH1C::Copy(*this);
9630 return *this;
9631}
9632
9633////////////////////////////////////////////////////////////////////////////////
9634/// Operator *
9635
9637{
9638 TH1C hnew = h1;
9639 hnew.Scale(c1);
9640 hnew.SetDirectory(nullptr);
9641 return hnew;
9642}
9643
9644////////////////////////////////////////////////////////////////////////////////
9645/// Operator +
9646
9647TH1C operator+(const TH1C &h1, const TH1C &h2)
9648{
9649 TH1C hnew = h1;
9650 hnew.Add(&h2,1);
9651 hnew.SetDirectory(nullptr);
9652 return hnew;
9653}
9654
9655////////////////////////////////////////////////////////////////////////////////
9656/// Operator -
9657
9658TH1C operator-(const TH1C &h1, const TH1C &h2)
9659{
9660 TH1C hnew = h1;
9661 hnew.Add(&h2,-1);
9662 hnew.SetDirectory(nullptr);
9663 return hnew;
9664}
9665
9666////////////////////////////////////////////////////////////////////////////////
9667/// Operator *
9668
9669TH1C operator*(const TH1C &h1, const TH1C &h2)
9670{
9671 TH1C hnew = h1;
9672 hnew.Multiply(&h2);
9673 hnew.SetDirectory(nullptr);
9674 return hnew;
9675}
9676
9677////////////////////////////////////////////////////////////////////////////////
9678/// Operator /
9679
9680TH1C operator/(const TH1C &h1, const TH1C &h2)
9681{
9682 TH1C hnew = h1;
9683 hnew.Divide(&h2);
9684 hnew.SetDirectory(nullptr);
9685 return hnew;
9686}
9687
9688//______________________________________________________________________________
9689// TH1S methods
9690// TH1S : histograms with one short per channel. Maximum bin content = 32767
9691//______________________________________________________________________________
9692
9693
9694////////////////////////////////////////////////////////////////////////////////
9695/// Constructor.
9696
9697TH1S::TH1S()
9698{
9699 fDimension = 1;
9700 SetBinsLength(3);
9701 if (fgDefaultSumw2) Sumw2();
9702}
9703
9704////////////////////////////////////////////////////////////////////////////////
9705/// Create a 1-Dim histogram with fix bins of type short
9706/// (see TH1::TH1 for explanation of parameters)
9707
9708TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9709: TH1(name,title,nbins,xlow,xup)
9710{
9711 fDimension = 1;
9713
9714 if (xlow >= xup) SetBuffer(fgBufferSize);
9715 if (fgDefaultSumw2) Sumw2();
9716}
9717
9718////////////////////////////////////////////////////////////////////////////////
9719/// Create a 1-Dim histogram with variable bins of type short
9720/// (see TH1::TH1 for explanation of parameters)
9721
9722TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9723: TH1(name,title,nbins,xbins)
9724{
9725 fDimension = 1;
9727 if (fgDefaultSumw2) Sumw2();
9728}
9729
9730////////////////////////////////////////////////////////////////////////////////
9731/// Create a 1-Dim histogram with variable bins of type short
9732/// (see TH1::TH1 for explanation of parameters)
9733
9734TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9735: TH1(name,title,nbins,xbins)
9736{
9737 fDimension = 1;
9739 if (fgDefaultSumw2) Sumw2();
9740}
9741
9742////////////////////////////////////////////////////////////////////////////////
9743/// Destructor.
9744
9746{
9747}
9748
9749////////////////////////////////////////////////////////////////////////////////
9750/// Copy constructor.
9751/// The list of functions is not copied. (Use Clone() if needed)
9752
9753TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9754{
9755 h1s.TH1S::Copy(*this);
9756}
9757
9758////////////////////////////////////////////////////////////////////////////////
9759/// Increment bin content by 1.
9760/// Passing an out-of-range bin leads to undefined behavior
9761
9762void TH1S::AddBinContent(Int_t bin)
9763{
9764 if (fArray[bin] < 32767) fArray[bin]++;
9765}
9766
9767////////////////////////////////////////////////////////////////////////////////
9768/// Increment bin content by w.
9769/// \warning The value of w is cast to `Int_t` before being added.
9770/// Passing an out-of-range bin leads to undefined behavior
9771
9773{
9774 Int_t newval = fArray[bin] + Int_t(w);
9775 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9776 if (newval < -32767) fArray[bin] = -32767;
9777 if (newval > 32767) fArray[bin] = 32767;
9778}
9779
9780////////////////////////////////////////////////////////////////////////////////
9781/// Copy this to newth1
9782
9783void TH1S::Copy(TObject &newth1) const
9784{
9786}
9787
9788////////////////////////////////////////////////////////////////////////////////
9789/// Reset.
9790
9792{
9795}
9796
9797////////////////////////////////////////////////////////////////////////////////
9798/// Set total number of bins including under/overflow
9799/// Reallocate bin contents array
9800
9802{
9803 if (n < 0) n = fXaxis.GetNbins() + 2;
9804 fNcells = n;
9805 TArrayS::Set(n);
9806}
9807
9808////////////////////////////////////////////////////////////////////////////////
9809/// Operator =
9810
9811TH1S& TH1S::operator=(const TH1S &h1)
9812{
9813 if (this != &h1)
9814 h1.TH1S::Copy(*this);
9815 return *this;
9816}
9817
9818////////////////////////////////////////////////////////////////////////////////
9819/// Operator *
9820
9822{
9823 TH1S hnew = h1;
9824 hnew.Scale(c1);
9825 hnew.SetDirectory(nullptr);
9826 return hnew;
9827}
9828
9829////////////////////////////////////////////////////////////////////////////////
9830/// Operator +
9831
9832TH1S operator+(const TH1S &h1, const TH1S &h2)
9833{
9834 TH1S hnew = h1;
9835 hnew.Add(&h2,1);
9836 hnew.SetDirectory(nullptr);
9837 return hnew;
9838}
9839
9840////////////////////////////////////////////////////////////////////////////////
9841/// Operator -
9842
9843TH1S operator-(const TH1S &h1, const TH1S &h2)
9844{
9845 TH1S hnew = h1;
9846 hnew.Add(&h2,-1);
9847 hnew.SetDirectory(nullptr);
9848 return hnew;
9849}
9850
9851////////////////////////////////////////////////////////////////////////////////
9852/// Operator *
9853
9854TH1S operator*(const TH1S &h1, const TH1S &h2)
9855{
9856 TH1S hnew = h1;
9857 hnew.Multiply(&h2);
9858 hnew.SetDirectory(nullptr);
9859 return hnew;
9860}
9861
9862////////////////////////////////////////////////////////////////////////////////
9863/// Operator /
9864
9865TH1S operator/(const TH1S &h1, const TH1S &h2)
9866{
9867 TH1S hnew = h1;
9868 hnew.Divide(&h2);
9869 hnew.SetDirectory(nullptr);
9870 return hnew;
9871}
9872
9873//______________________________________________________________________________
9874// TH1I methods
9875// TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9876// 2147483647 = INT_MAX
9877//______________________________________________________________________________
9878
9879
9880////////////////////////////////////////////////////////////////////////////////
9881/// Constructor.
9882
9883TH1I::TH1I()
9884{
9885 fDimension = 1;
9886 SetBinsLength(3);
9887 if (fgDefaultSumw2) Sumw2();
9888}
9889
9890////////////////////////////////////////////////////////////////////////////////
9891/// Create a 1-Dim histogram with fix bins of type integer
9892/// (see TH1::TH1 for explanation of parameters)
9893
9894TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9895: TH1(name,title,nbins,xlow,xup)
9896{
9897 fDimension = 1;
9899
9900 if (xlow >= xup) SetBuffer(fgBufferSize);
9901 if (fgDefaultSumw2) Sumw2();
9902}
9903
9904////////////////////////////////////////////////////////////////////////////////
9905/// Create a 1-Dim histogram with variable bins of type integer
9906/// (see TH1::TH1 for explanation of parameters)
9907
9908TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9909: TH1(name,title,nbins,xbins)
9910{
9911 fDimension = 1;
9913 if (fgDefaultSumw2) Sumw2();
9914}
9915
9916////////////////////////////////////////////////////////////////////////////////
9917/// Create a 1-Dim histogram with variable bins of type integer
9918/// (see TH1::TH1 for explanation of parameters)
9919
9920TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9921: TH1(name,title,nbins,xbins)
9922{
9923 fDimension = 1;
9925 if (fgDefaultSumw2) Sumw2();
9926}
9927
9928////////////////////////////////////////////////////////////////////////////////
9929/// Destructor.
9930
9932{
9933}
9934
9935////////////////////////////////////////////////////////////////////////////////
9936/// Copy constructor.
9937/// The list of functions is not copied. (Use Clone() if needed)
9938
9939TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
9940{
9941 h1i.TH1I::Copy(*this);
9942}
9943
9944////////////////////////////////////////////////////////////////////////////////
9945/// Increment bin content by 1.
9946/// Passing an out-of-range bin leads to undefined behavior
9947
9948void TH1I::AddBinContent(Int_t bin)
9949{
9950 if (fArray[bin] < INT_MAX) fArray[bin]++;
9951}
9952
9953////////////////////////////////////////////////////////////////////////////////
9954/// Increment bin content by w
9955/// \warning The value of w is cast to `Long64_t` before being added.
9956/// Passing an out-of-range bin leads to undefined behavior
9957
9959{
9960 Long64_t newval = fArray[bin] + Long64_t(w);
9961 if (newval > -INT_MAX && newval < INT_MAX) {fArray[bin] = Int_t(newval); return;}
9962 if (newval < -INT_MAX) fArray[bin] = -INT_MAX;
9963 if (newval > INT_MAX) fArray[bin] = INT_MAX;
9964}
9965
9966////////////////////////////////////////////////////////////////////////////////
9967/// Copy this to newth1
9968
9969void TH1I::Copy(TObject &newth1) const
9970{
9972}
9973
9974////////////////////////////////////////////////////////////////////////////////
9975/// Reset.
9976
9978{
9981}
9982
9983////////////////////////////////////////////////////////////////////////////////
9984/// Set total number of bins including under/overflow
9985/// Reallocate bin contents array
9986
9988{
9989 if (n < 0) n = fXaxis.GetNbins() + 2;
9990 fNcells = n;
9991 TArrayI::Set(n);
9992}
9993
9994////////////////////////////////////////////////////////////////////////////////
9995/// Operator =
9996
9997TH1I& TH1I::operator=(const TH1I &h1)
9998{
9999 if (this != &h1)
10000 h1.TH1I::Copy(*this);
10001 return *this;
10002}
10003
10004
10005////////////////////////////////////////////////////////////////////////////////
10006/// Operator *
10007
10009{
10010 TH1I hnew = h1;
10011 hnew.Scale(c1);
10012 hnew.SetDirectory(nullptr);
10013 return hnew;
10014}
10015
10016////////////////////////////////////////////////////////////////////////////////
10017/// Operator +
10018
10019TH1I operator+(const TH1I &h1, const TH1I &h2)
10020{
10021 TH1I hnew = h1;
10022 hnew.Add(&h2,1);
10023 hnew.SetDirectory(nullptr);
10024 return hnew;
10025}
10026
10027////////////////////////////////////////////////////////////////////////////////
10028/// Operator -
10029
10030TH1I operator-(const TH1I &h1, const TH1I &h2)
10031{
10032 TH1I hnew = h1;
10033 hnew.Add(&h2,-1);
10034 hnew.SetDirectory(nullptr);
10035 return hnew;
10036}
10037
10038////////////////////////////////////////////////////////////////////////////////
10039/// Operator *
10040
10041TH1I operator*(const TH1I &h1, const TH1I &h2)
10042{
10043 TH1I hnew = h1;
10044 hnew.Multiply(&h2);
10045 hnew.SetDirectory(nullptr);
10046 return hnew;
10047}
10048
10049////////////////////////////////////////////////////////////////////////////////
10050/// Operator /
10051
10052TH1I operator/(const TH1I &h1, const TH1I &h2)
10053{
10054 TH1I hnew = h1;
10055 hnew.Divide(&h2);
10056 hnew.SetDirectory(nullptr);
10057 return hnew;
10058}
10059
10060//______________________________________________________________________________
10061// TH1L methods
10062// TH1L : histograms with one long64 per channel. Maximum bin content = 9223372036854775807
10063// 9223372036854775807 = LLONG_MAX
10064//______________________________________________________________________________
10065
10066
10067////////////////////////////////////////////////////////////////////////////////
10068/// Constructor.
10069
10070TH1L::TH1L()
10071{
10072 fDimension = 1;
10073 SetBinsLength(3);
10074 if (fgDefaultSumw2) Sumw2();
10075}
10076
10077////////////////////////////////////////////////////////////////////////////////
10078/// Create a 1-Dim histogram with fix bins of type long64
10079/// (see TH1::TH1 for explanation of parameters)
10080
10081TH1L::TH1L(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10082: TH1(name,title,nbins,xlow,xup)
10083{
10084 fDimension = 1;
10086
10087 if (xlow >= xup) SetBuffer(fgBufferSize);
10088 if (fgDefaultSumw2) Sumw2();
10089}
10090
10091////////////////////////////////////////////////////////////////////////////////
10092/// Create a 1-Dim histogram with variable bins of type long64
10093/// (see TH1::TH1 for explanation of parameters)
10094
10095TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10096: TH1(name,title,nbins,xbins)
10097{
10098 fDimension = 1;
10100 if (fgDefaultSumw2) Sumw2();
10101}
10102
10103////////////////////////////////////////////////////////////////////////////////
10104/// Create a 1-Dim histogram with variable bins of type long64
10105/// (see TH1::TH1 for explanation of parameters)
10106
10107TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10108: TH1(name,title,nbins,xbins)
10109{
10110 fDimension = 1;
10112 if (fgDefaultSumw2) Sumw2();
10113}
10114
10115////////////////////////////////////////////////////////////////////////////////
10116/// Destructor.
10117
10119{
10120}
10121
10122////////////////////////////////////////////////////////////////////////////////
10123/// Copy constructor.
10124/// The list of functions is not copied. (Use Clone() if needed)
10125
10126TH1L::TH1L(const TH1L &h1l) : TH1(), TArrayL64()
10127{
10128 h1l.TH1L::Copy(*this);
10129}
10130
10131////////////////////////////////////////////////////////////////////////////////
10132/// Increment bin content by 1.
10133/// Passing an out-of-range bin leads to undefined behavior
10134
10135void TH1L::AddBinContent(Int_t bin)
10136{
10137 if (fArray[bin] < LLONG_MAX) fArray[bin]++;
10138}
10139
10140////////////////////////////////////////////////////////////////////////////////
10141/// Increment bin content by w.
10142/// \warning The value of w is cast to `Long64_t` before being added.
10143/// Passing an out-of-range bin leads to undefined behavior
10144
10146{
10147 Long64_t newval = fArray[bin] + Long64_t(w);
10148 if (newval > -LLONG_MAX && newval < LLONG_MAX) {fArray[bin] = newval; return;}
10149 if (newval < -LLONG_MAX) fArray[bin] = -LLONG_MAX;
10150 if (newval > LLONG_MAX) fArray[bin] = LLONG_MAX;
10151}
10152
10153////////////////////////////////////////////////////////////////////////////////
10154/// Copy this to newth1
10155
10156void TH1L::Copy(TObject &newth1) const
10157{
10159}
10160
10161////////////////////////////////////////////////////////////////////////////////
10162/// Reset.
10163
10165{
10168}
10169
10170////////////////////////////////////////////////////////////////////////////////
10171/// Set total number of bins including under/overflow
10172/// Reallocate bin contents array
10173
10175{
10176 if (n < 0) n = fXaxis.GetNbins() + 2;
10177 fNcells = n;
10179}
10180
10181////////////////////////////////////////////////////////////////////////////////
10182/// Operator =
10183
10184TH1L& TH1L::operator=(const TH1L &h1)
10185{
10186 if (this != &h1)
10187 h1.TH1L::Copy(*this);
10188 return *this;
10189}
10190
10191
10192////////////////////////////////////////////////////////////////////////////////
10193/// Operator *
10194
10196{
10197 TH1L hnew = h1;
10198 hnew.Scale(c1);
10199 hnew.SetDirectory(nullptr);
10200 return hnew;
10201}
10202
10203////////////////////////////////////////////////////////////////////////////////
10204/// Operator +
10205
10206TH1L operator+(const TH1L &h1, const TH1L &h2)
10207{
10208 TH1L hnew = h1;
10209 hnew.Add(&h2,1);
10210 hnew.SetDirectory(nullptr);
10211 return hnew;
10212}
10213
10214////////////////////////////////////////////////////////////////////////////////
10215/// Operator -
10216
10217TH1L operator-(const TH1L &h1, const TH1L &h2)
10218{
10219 TH1L hnew = h1;
10220 hnew.Add(&h2,-1);
10221 hnew.SetDirectory(nullptr);
10222 return hnew;
10223}
10224
10225////////////////////////////////////////////////////////////////////////////////
10226/// Operator *
10227
10228TH1L operator*(const TH1L &h1, const TH1L &h2)
10229{
10230 TH1L hnew = h1;
10231 hnew.Multiply(&h2);
10232 hnew.SetDirectory(nullptr);
10233 return hnew;
10234}
10235
10236////////////////////////////////////////////////////////////////////////////////
10237/// Operator /
10238
10239TH1L operator/(const TH1L &h1, const TH1L &h2)
10240{
10241 TH1L hnew = h1;
10242 hnew.Divide(&h2);
10243 hnew.SetDirectory(nullptr);
10244 return hnew;
10245}
10246
10247//______________________________________________________________________________
10248// TH1F methods
10249// TH1F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216
10250//______________________________________________________________________________
10251
10252
10253////////////////////////////////////////////////////////////////////////////////
10254/// Constructor.
10255
10256TH1F::TH1F()
10257{
10258 fDimension = 1;
10259 SetBinsLength(3);
10260 if (fgDefaultSumw2) Sumw2();
10261}
10262
10263////////////////////////////////////////////////////////////////////////////////
10264/// Create a 1-Dim histogram with fix bins of type float
10265/// (see TH1::TH1 for explanation of parameters)
10266
10267TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10268: TH1(name,title,nbins,xlow,xup)
10269{
10270 fDimension = 1;
10272
10273 if (xlow >= xup) SetBuffer(fgBufferSize);
10274 if (fgDefaultSumw2) Sumw2();
10275}
10276
10277////////////////////////////////////////////////////////////////////////////////
10278/// Create a 1-Dim histogram with variable bins of type float
10279/// (see TH1::TH1 for explanation of parameters)
10280
10281TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10282: TH1(name,title,nbins,xbins)
10283{
10284 fDimension = 1;
10286 if (fgDefaultSumw2) Sumw2();
10287}
10288
10289////////////////////////////////////////////////////////////////////////////////
10290/// Create a 1-Dim histogram with variable bins of type float
10291/// (see TH1::TH1 for explanation of parameters)
10292
10293TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10294: TH1(name,title,nbins,xbins)
10295{
10296 fDimension = 1;
10298 if (fgDefaultSumw2) Sumw2();
10299}
10300
10301////////////////////////////////////////////////////////////////////////////////
10302/// Create a histogram from a TVectorF
10303/// by default the histogram name is "TVectorF" and title = ""
10304
10305TH1F::TH1F(const TVectorF &v)
10306: TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
10307{
10309 fDimension = 1;
10310 Int_t ivlow = v.GetLwb();
10311 for (Int_t i=0;i<fNcells-2;i++) {
10312 SetBinContent(i+1,v(i+ivlow));
10313 }
10315 if (fgDefaultSumw2) Sumw2();
10316}
10317
10318////////////////////////////////////////////////////////////////////////////////
10319/// Copy Constructor.
10320/// The list of functions is not copied. (Use Clone() if needed)
10321
10322TH1F::TH1F(const TH1F &h1f) : TH1(), TArrayF()
10323{
10324 h1f.TH1F::Copy(*this);
10325}
10326
10327////////////////////////////////////////////////////////////////////////////////
10328/// Destructor.
10329
10331{
10332}
10333
10334////////////////////////////////////////////////////////////////////////////////
10335/// Copy this to newth1.
10336
10337void TH1F::Copy(TObject &newth1) const
10338{
10340}
10341
10342////////////////////////////////////////////////////////////////////////////////
10343/// Reset.
10344
10346{
10349}
10350
10351////////////////////////////////////////////////////////////////////////////////
10352/// Set total number of bins including under/overflow
10353/// Reallocate bin contents array
10354
10356{
10357 if (n < 0) n = fXaxis.GetNbins() + 2;
10358 fNcells = n;
10359 TArrayF::Set(n);
10360}
10361
10362////////////////////////////////////////////////////////////////////////////////
10363/// Operator =
10364
10366{
10367 if (this != &h1f)
10368 h1f.TH1F::Copy(*this);
10369 return *this;
10370}
10371
10372////////////////////////////////////////////////////////////////////////////////
10373/// Operator *
10374
10376{
10377 TH1F hnew = h1;
10378 hnew.Scale(c1);
10379 hnew.SetDirectory(nullptr);
10380 return hnew;
10381}
10382
10383////////////////////////////////////////////////////////////////////////////////
10384/// Operator +
10385
10386TH1F operator+(const TH1F &h1, const TH1F &h2)
10387{
10388 TH1F hnew = h1;
10389 hnew.Add(&h2,1);
10390 hnew.SetDirectory(nullptr);
10391 return hnew;
10392}
10393
10394////////////////////////////////////////////////////////////////////////////////
10395/// Operator -
10396
10397TH1F operator-(const TH1F &h1, const TH1F &h2)
10398{
10399 TH1F hnew = h1;
10400 hnew.Add(&h2,-1);
10401 hnew.SetDirectory(nullptr);
10402 return hnew;
10403}
10404
10405////////////////////////////////////////////////////////////////////////////////
10406/// Operator *
10407
10408TH1F operator*(const TH1F &h1, const TH1F &h2)
10409{
10410 TH1F hnew = h1;
10411 hnew.Multiply(&h2);
10412 hnew.SetDirectory(nullptr);
10413 return hnew;
10414}
10415
10416////////////////////////////////////////////////////////////////////////////////
10417/// Operator /
10418
10419TH1F operator/(const TH1F &h1, const TH1F &h2)
10420{
10421 TH1F hnew = h1;
10422 hnew.Divide(&h2);
10423 hnew.SetDirectory(nullptr);
10424 return hnew;
10425}
10426
10427//______________________________________________________________________________
10428// TH1D methods
10429// TH1D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992
10430//______________________________________________________________________________
10431
10432
10433////////////////////////////////////////////////////////////////////////////////
10434/// Constructor.
10435
10436TH1D::TH1D()
10437{
10438 fDimension = 1;
10439 SetBinsLength(3);
10440 if (fgDefaultSumw2) Sumw2();
10441}
10442
10443////////////////////////////////////////////////////////////////////////////////
10444/// Create a 1-Dim histogram with fix bins of type double
10445/// (see TH1::TH1 for explanation of parameters)
10446
10447TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10448: TH1(name,title,nbins,xlow,xup)
10449{
10450 fDimension = 1;
10452
10453 if (xlow >= xup) SetBuffer(fgBufferSize);
10454 if (fgDefaultSumw2) Sumw2();
10455}
10456
10457////////////////////////////////////////////////////////////////////////////////
10458/// Create a 1-Dim histogram with variable bins of type double
10459/// (see TH1::TH1 for explanation of parameters)
10460
10461TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10462: TH1(name,title,nbins,xbins)
10463{
10464 fDimension = 1;
10466 if (fgDefaultSumw2) Sumw2();
10467}
10468
10469////////////////////////////////////////////////////////////////////////////////
10470/// Create a 1-Dim histogram with variable bins of type double
10471/// (see TH1::TH1 for explanation of parameters)
10472
10473TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10474: TH1(name,title,nbins,xbins)
10475{
10476 fDimension = 1;
10478 if (fgDefaultSumw2) Sumw2();
10479}
10480
10481////////////////////////////////////////////////////////////////////////////////
10482/// Create a histogram from a TVectorD
10483/// by default the histogram name is "TVectorD" and title = ""
10484
10485TH1D::TH1D(const TVectorD &v)
10486: TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
10487{
10489 fDimension = 1;
10490 Int_t ivlow = v.GetLwb();
10491 for (Int_t i=0;i<fNcells-2;i++) {
10492 SetBinContent(i+1,v(i+ivlow));
10493 }
10495 if (fgDefaultSumw2) Sumw2();
10496}
10497
10498////////////////////////////////////////////////////////////////////////////////
10499/// Destructor.
10500
10502{
10503}
10504
10505////////////////////////////////////////////////////////////////////////////////
10506/// Constructor.
10507
10508TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
10509{
10510 // intentially call virtual method to warn if TProfile is copying
10511 h1d.Copy(*this);
10512}
10513
10514////////////////////////////////////////////////////////////////////////////////
10515/// Copy this to newth1
10516
10517void TH1D::Copy(TObject &newth1) const
10518{
10520}
10521
10522////////////////////////////////////////////////////////////////////////////////
10523/// Reset.
10524
10526{
10529}
10530
10531////////////////////////////////////////////////////////////////////////////////
10532/// Set total number of bins including under/overflow
10533/// Reallocate bin contents array
10534
10536{
10537 if (n < 0) n = fXaxis.GetNbins() + 2;
10538 fNcells = n;
10539 TArrayD::Set(n);
10540}
10541
10542////////////////////////////////////////////////////////////////////////////////
10543/// Operator =
10544
10546{
10547 // intentially call virtual method to warn if TProfile is copying
10548 if (this != &h1d)
10549 h1d.Copy(*this);
10550 return *this;
10551}
10552
10553////////////////////////////////////////////////////////////////////////////////
10554/// Operator *
10555
10557{
10558 TH1D hnew = h1;
10559 hnew.Scale(c1);
10560 hnew.SetDirectory(nullptr);
10561 return hnew;
10562}
10563
10564////////////////////////////////////////////////////////////////////////////////
10565/// Operator +
10566
10567TH1D operator+(const TH1D &h1, const TH1D &h2)
10568{
10569 TH1D hnew = h1;
10570 hnew.Add(&h2,1);
10571 hnew.SetDirectory(nullptr);
10572 return hnew;
10573}
10574
10575////////////////////////////////////////////////////////////////////////////////
10576/// Operator -
10577
10578TH1D operator-(const TH1D &h1, const TH1D &h2)
10579{
10580 TH1D hnew = h1;
10581 hnew.Add(&h2,-1);
10582 hnew.SetDirectory(nullptr);
10583 return hnew;
10584}
10585
10586////////////////////////////////////////////////////////////////////////////////
10587/// Operator *
10588
10589TH1D operator*(const TH1D &h1, const TH1D &h2)
10590{
10591 TH1D hnew = h1;
10592 hnew.Multiply(&h2);
10593 hnew.SetDirectory(nullptr);
10594 return hnew;
10595}
10596
10597////////////////////////////////////////////////////////////////////////////////
10598/// Operator /
10599
10600TH1D operator/(const TH1D &h1, const TH1D &h2)
10601{
10602 TH1D hnew = h1;
10603 hnew.Divide(&h2);
10604 hnew.SetDirectory(nullptr);
10605 return hnew;
10606}
10607
10608////////////////////////////////////////////////////////////////////////////////
10609///return pointer to histogram with name
10610///hid if id >=0
10611///h_id if id <0
10612
10613TH1 *R__H(Int_t hid)
10614{
10615 TString hname;
10616 if(hid >= 0) hname.Form("h%d",hid);
10617 else hname.Form("h_%d",hid);
10618 return (TH1*)gDirectory->Get(hname);
10619}
10620
10621////////////////////////////////////////////////////////////////////////////////
10622///return pointer to histogram with name hname
10623
10624TH1 *R__H(const char * hname)
10625{
10626 return (TH1*)gDirectory->Get(hname);
10627}
10628
10629
10630/// \fn void TH1::SetBarOffset(Float_t offset)
10631/// Set the bar offset as fraction of the bin width for drawing mode "B".
10632/// This shifts bars to the right on the x axis, and helps to draw bars next to each other.
10633/// \see THistPainter, SetBarWidth()
10634
10635/// \fn void TH1::SetBarWidth(Float_t width)
10636/// Set the width of bars as fraction of the bin width for drawing mode "B".
10637/// This allows for making bars narrower than the bin width. With SetBarOffset(), this helps to draw multiple bars next to each other.
10638/// \see THistPainter, SetBarOffset()
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define s1(x)
Definition RSha256.hxx:91
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
short Style_t
Style number (short)
Definition RtypesCore.h:96
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Color_t
Color number (short)
Definition RtypesCore.h:99
short Version_t
Class version identifier (short)
Definition RtypesCore.h:79
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
short Short_t
Signed Short integer 2 bytes (short)
Definition RtypesCore.h:53
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:385
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t SetLineWidth
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t SetFillStyle
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t del
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t SetLineColor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t SetFillColor
Option_t Option_t SetMarkerStyle
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char y1
char name[80]
Definition TGX11.cxx:110
static bool IsEquidistantBinning(const TAxis &axis)
Test if the binning is equidistant.
Definition TH1.cxx:5898
void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
Least square linear fit without weights.
Definition TH1.cxx:4844
void H1InitGaus()
Compute Initial values of parameters for a gaussian.
Definition TH1.cxx:4679
void H1InitExpo()
Compute Initial values of parameters for an exponential.
Definition TH1.cxx:4735
TH1C operator+(const TH1C &h1, const TH1C &h2)
Operator +.
Definition TH1.cxx:9645
TH1C operator-(const TH1C &h1, const TH1C &h2)
Operator -.
Definition TH1.cxx:9656
TH1C operator/(const TH1C &h1, const TH1C &h2)
Operator /.
Definition TH1.cxx:9678
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:4890
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:5881
static Bool_t AlmostInteger(Double_t a, Double_t epsilon=0.00000001)
Test if a double is almost an integer.
Definition TH1.cxx:5889
TF1 * gF1
Definition TH1.cxx:584
TH1 * R__H(Int_t hid)
return pointer to histogram with name hid if id >=0 h_id if id <0
Definition TH1.cxx:10611
TH1C operator*(Double_t c1, const TH1C &h1)
Operator *.
Definition TH1.cxx:9634
void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
Least squares lpolynomial fitting without weights.
Definition TH1.cxx:4785
void H1InitPolynom()
Compute Initial values of parameters for a polynom.
Definition TH1.cxx:4755
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:627
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:414
R__EXTERN TRandom * gRandom
Definition TRandom.h:62
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2509
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
#define R__LOCKGUARD(mutex)
#define gPad
#define R__WRITE_LOCKGUARD(mutex)
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition BinData.h:52
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition DataRange.h:35
void AndersonDarling2SamplesTest(Double_t &pvalue, Double_t &testStat) const
Performs the Anderson-Darling 2-Sample Test.
Definition GoFTest.cxx:646
const_iterator begin() const
const_iterator end() const
Array of chars or bytes (8 bits per element).
Definition TArrayC.h:27
Char_t * fArray
Definition TArrayC.h:30
void Reset(Char_t val=0)
Definition TArrayC.h:47
void Set(Int_t n) override
Set size of this array to n chars.
Definition TArrayC.cxx:104
Array of doubles (64 bits per element).
Definition TArrayD.h:27
Double_t * fArray
Definition TArrayD.h:30
void Streamer(TBuffer &) override
Stream a TArrayD object.
Definition TArrayD.cxx:148
void Copy(TArrayD &array) const
Definition TArrayD.h:42
void Set(Int_t n) override
Set size of this array to n doubles.
Definition TArrayD.cxx:105
const Double_t * GetArray() const
Definition TArrayD.h:43
void Reset()
Definition TArrayD.h:47
Array of floats (32 bits per element).
Definition TArrayF.h:27
void Reset()
Definition TArrayF.h:47
void Set(Int_t n) override
Set size of this array to n floats.
Definition TArrayF.cxx:104
Array of integers (32 bits per element).
Definition TArrayI.h:27
Int_t * fArray
Definition TArrayI.h:30
void Set(Int_t n) override
Set size of this array to n ints.
Definition TArrayI.cxx:104
void Reset()
Definition TArrayI.h:47
Array of long64s (64 bits per element).
Definition TArrayL64.h:27
Long64_t * fArray
Definition TArrayL64.h:30
void Set(Int_t n) override
Set size of this array to n long64s.
void Reset()
Definition TArrayL64.h:47
Array of shorts (16 bits per element).
Definition TArrayS.h:27
void Set(Int_t n) override
Set size of this array to n shorts.
Definition TArrayS.cxx:104
void Reset()
Definition TArrayS.h:47
Short_t * fArray
Definition TArrayS.h:30
Abstract array base class.
Definition TArray.h:31
Int_t fN
Definition TArray.h:38
virtual void Set(Int_t n)=0
virtual Color_t GetTitleColor() const
Definition TAttAxis.h:47
virtual Color_t GetLabelColor() const
Definition TAttAxis.h:39
virtual Int_t GetNdivisions() const
Definition TAttAxis.h:37
virtual Color_t GetAxisColor() const
Definition TAttAxis.h:38
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition TAttAxis.cxx:279
virtual Style_t GetTitleFont() const
Definition TAttAxis.h:48
virtual Float_t GetLabelOffset() const
Definition TAttAxis.h:41
virtual void SetAxisColor(Color_t color=1, Float_t alpha=1.)
Set color of the line axis and tick marks.
Definition TAttAxis.cxx:141
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
Definition TAttAxis.cxx:184
virtual Style_t GetLabelFont() const
Definition TAttAxis.h:40
virtual void SetTitleFont(Style_t font=62)
Set the title font.
Definition TAttAxis.cxx:308
virtual void SetLabelOffset(Float_t offset=0.005)
Set distance between the axis and the labels.
Definition TAttAxis.cxx:172
virtual void SetLabelFont(Style_t font=62)
Set labels' font.
Definition TAttAxis.cxx:161
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title.
Definition TAttAxis.cxx:290
virtual void SetTitleColor(Color_t color=1)
Set color of axis title.
Definition TAttAxis.cxx:299
virtual Float_t GetTitleSize() const
Definition TAttAxis.h:45
virtual Float_t GetLabelSize() const
Definition TAttAxis.h:42
virtual Float_t GetTickLength() const
Definition TAttAxis.h:46
virtual void ResetAttAxis(Option_t *option="")
Reset axis attributes.
Definition TAttAxis.cxx:78
virtual Float_t GetTitleOffset() const
Definition TAttAxis.h:44
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length.
Definition TAttAxis.cxx:265
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition TAttAxis.cxx:214
virtual void SetLabelColor(Color_t color=1, Float_t alpha=1.)
Set color of labels.
Definition TAttAxis.cxx:151
virtual void Streamer(TBuffer &)
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:31
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition TAttFill.cxx:206
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:32
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:238
virtual void Streamer(TBuffer &)
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:35
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:44
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:37
virtual Style_t GetLineStyle() const
Return the line style.
Definition TAttLine.h:36
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:274
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:33
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition TAttMarker.h:39
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:32
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition TAttMarker.h:34
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition TAttMarker.h:41
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:46
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:5017
ROOT::NewFunc_t GetNew() const
Return the wrapper around new ThisClass().
Definition TClass.cxx:7552
Collection abstract base class.
Definition TCollection.h:65
virtual bool UseRWLock(Bool_t enable=true)
Set this collection to use a RW lock upon access, making it thread safe.
TObject * Clone(const char *newname="") const override
Make a clone of an collection using the Streamer facility.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Describe directory structure in memory.
Definition TDirectory.h:45
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:503
1-Dim function class
Definition TF1.h:182
static void RejectPoint(Bool_t reject=kTRUE)
Static function to set the global flag to reject points the fgRejectPoint global flag is tested by al...
Definition TF1.cxx:3723
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function Note that this histogram is managed ...
Definition TF1.cxx:1634
static TClass * Class()
virtual Int_t GetNpar() const
Definition TF1.h:446
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
IntegralOneDim or analytical integral.
Definition TF1.cxx:2580
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition TF1.cxx:2530
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2329
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=nullptr)
Evaluate function with given coordinates and parameters.
Definition TF1.cxx:1498
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set lower and upper limits for parameter ipar.
Definition TF1.cxx:3562
static Bool_t RejectedPoint()
See TF1::RejectPoint above.
Definition TF1.cxx:3732
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this function.
Definition TF1.cxx:1446
virtual void SetParameter(Int_t param, Double_t value)
Definition TF1.h:608
virtual Bool_t IsInside(const Double_t *x) const
return kTRUE if the point is inside the function range
Definition TF1.h:567
A 2-Dim function with parameters.
Definition TF2.h:29
TF3 defines a 3D Function with Parameters.
Definition TF3.h:28
Provides an indirection to the TFitResult class and with a semantics identical to a TFitResult pointe...
1-D histogram with a byte per channel (see TH1 documentation)
Definition TH1.h:714
~TH1C() override
Destructor.
Definition TH1.cxx:9558
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9614
TH1C & operator=(const TH1C &h1)
Operator =.
Definition TH1.cxx:9624
TH1C()
Constructor.
Definition TH1.cxx:9510
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9596
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9575
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:9604
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:926
~TH1D() override
Destructor.
Definition TH1.cxx:10499
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10533
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10515
TH1D()
Constructor.
Definition TH1.cxx:10434
TH1D & operator=(const TH1D &h1)
Operator =.
Definition TH1.cxx:10543
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:10363
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10335
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10353
~TH1F() override
Destructor.
Definition TH1.cxx:10328
TH1F()
Constructor.
Definition TH1.cxx:10254
1-D histogram with an int per channel (see TH1 documentation)
Definition TH1.h:796
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9985
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9946
~TH1I() override
Destructor.
Definition TH1.cxx:9929
TH1I()
Constructor.
Definition TH1.cxx:9881
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9967
TH1I & operator=(const TH1I &h1)
Operator =.
Definition TH1.cxx:9995
1-D histogram with a long64 per channel (see TH1 documentation)
Definition TH1.h:837
TH1L & operator=(const TH1L &h1)
Operator =.
Definition TH1.cxx:10182
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:10133
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10172
~TH1L() override
Destructor.
Definition TH1.cxx:10116
TH1L()
Constructor.
Definition TH1.cxx:10068
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10154
1-D histogram with a short per channel (see TH1 documentation)
Definition TH1.h:755
TH1S & operator=(const TH1S &h1)
Operator =.
Definition TH1.cxx:9809
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9781
TH1S()
Constructor.
Definition TH1.cxx:9695
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9799
~TH1S() override
Destructor.
Definition TH1.cxx:9743
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9760
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
~TH1() override
Histogram default destructor.
Definition TH1.cxx:630
virtual void SetError(const Double_t *error)
Replace bin errors by values in array error.
Definition TH1.cxx:9011
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:8997
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition TH1.cxx:4277
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:1312
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition TH1.cxx:4441
char * GetObjectInfo(Int_t px, Int_t py) const override
Redefines TObject::GetObjectInfo.
Definition TH1.cxx:4495
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition TH1.cxx:6942
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:9198
virtual void Rebuild(Option_t *option="")
Using the current bin info, recompute the arrays for contents and errors.
Definition TH1.cxx:7150
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:3789
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:2809
virtual Bool_t Multiply(TF1 *f1, Double_t c1=1)
Performs the operation:
Definition TH1.cxx:6069
@ 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
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:7884
virtual void Normalize(Option_t *option="")
Normalize a histogram to its integral or to its maximum.
Definition TH1.cxx:6231
void Copy(TObject &hnew) const override
Copy this histogram structure to newth1.
Definition TH1.cxx:2657
void SetTitle(const char *title) override
Change/set the title.
Definition TH1.cxx:6774
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:6988
virtual Float_t GetBarOffset() const
Definition TH1.h:500
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:4399
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:8033
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:7658
TH1()
Histogram default constructor.
Definition TH1.cxx:602
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:9376
void UseCurrentStyle() override
Copy current attributes from/to current style.
Definition TH1.cxx:7520
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:5402
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:2038
static bool CheckBinLimits(const TAxis *a1, const TAxis *a2)
Check bin limits.
Definition TH1.cxx:1510
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:9120
static Int_t FitOptionsMake(Option_t *option, Foption_t &Foption)
Decode string choptin and fill fitOption structure.
Definition TH1.cxx:4670
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:7586
virtual Double_t GetSkewness(Int_t axis=1) const
Definition TH1.cxx:7722
virtual void ClearUnderflowAndOverflow()
Remove all the content from the underflow and overflow bins, without changing the number of entries A...
Definition TH1.cxx:2492
virtual void FillRandom(TF1 *f1, Int_t ntimes=5000, TRandom *rng=nullptr)
Definition TH1.cxx:3514
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition TH1.cxx:8496
virtual TH1 * DrawNormalized(Option_t *option="", Double_t norm=1) const
Draw a normalized copy of this histogram.
Definition TH1.cxx:3130
@ 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:6996
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1263
Double_t GetSumOfAllWeights(const bool includeOverflow) const
Return the sum of all weights.
Definition TH1.cxx:7970
@ 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:8582
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition TH1.cxx:6689
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:7166
void SetNameTitle(const char *name, const char *title) override
Change the name and title of this histogram.
Definition TH1.cxx:9034
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:4992
TH1 * GetCumulative(Bool_t forward=kTRUE, const char *suffix="_cumulative") const
Return a pointer to a histogram containing the cumulative content.
Definition TH1.cxx:2602
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:1277
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:9358
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition TH1.cxx:5928
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:7935
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition TH1.cxx:4504
TObject * FindObject(const char *name) const override
Search object named name in the list of functions.
Definition TH1.cxx:3849
void Print(Option_t *option="") const override
Print some global quantities for this histogram.
Definition TH1.cxx:7072
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
Definition TH1.cxx:4408
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:3726
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:3891
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:4979
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:8605
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:3270
virtual void LabelsInflate(Option_t *axis="X")
Double the number of bins for axis.
Definition TH1.cxx:5335
virtual TH1 * ShowBackground(Int_t niter=20, Option_t *option="same")
This function calculates the background spectrum in this histogram.
Definition TH1.cxx:9344
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
Definition TH1.cxx:5918
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:813
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:7305
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:8024
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:9263
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:3330
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:9136
void Browse(TBrowser *b) override
Browse the Histogram object.
Definition TH1.cxx:749
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition TH1.cxx:8454
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx:3052
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:7432
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:5234
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TH1.cxx:7327
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check that axis have same labels.
Definition TH1.cxx:1537
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:5135
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:6756
virtual void SetBuffer(Int_t bufsize, Option_t *option="")
Set the maximum number of entries to be kept in the buffer.
Definition TH1.cxx:8514
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition TH1.cxx:5202
UInt_t GetAxisLabelStatus() const
Internal function used in TH1::Fill to see which axis is full alphanumeric, i.e.
Definition TH1.cxx:6728
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:7997
static void SetDefaultBufferSize(Int_t bufsize=1000)
Static function to set the default buffer size for automatic histograms.
Definition TH1.cxx:6746
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:9279
virtual void DirectoryAutoAdd(TDirectory *)
Perform the automatic addition of the histogram to the given directory.
Definition TH1.cxx:2787
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:9244
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:9209
void Build()
Creates histogram basic data structure.
Definition TH1.cxx:758
virtual Double_t GetEntries() const
Return the current number of entries.
Definition TH1.cxx:4416
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:9108
virtual TH1 * Rebin(Int_t ngroup=2, const char *newname="", const Double_t *xbins=nullptr)
Rebin this histogram.
Definition TH1.cxx:6328
virtual Int_t BufferFill(Double_t x, Double_t w)
accumulate arguments in buffer.
Definition TH1.cxx:1475
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:5106
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:6702
TList * GetListOfFunctions() const
Definition TH1.h:488
void SetName(const char *name) override
Change the name of this histogram.
Definition TH1.cxx:9020
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition TH1.cxx:3099
virtual Double_t GetRandom(TRandom *rng=nullptr, Option_t *option="") const
Return a random number distributed according the histogram bin contents.
Definition TH1.cxx:5029
Bool_t IsEmpty() const
Check if a histogram is empty (this is a protected method used mainly by TH1Merger )
Definition TH1.cxx:5184
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition TH1.cxx:7626
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6259
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:8118
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculated from bin cont...
Definition TH1.cxx:7953
virtual void SetBinErrorOption(EBinErrorOpt type)
Definition TH1.h:629
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Definition TH1.cxx:3161
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:2471
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:1979
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:3459
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition TH1.cxx:8791
@ kNstat
Size of statistics data (up to TProfile3D)
Definition TH1.h:422
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition TH1.cxx:8637
static Int_t AutoP2GetBins(Int_t n)
Auxiliary function to get the next power of 2 integer value larger then n.
Definition TH1.cxx:1290
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:4460
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TH1.cxx:3226
virtual Double_t * GetIntegral()
Return a pointer to the array of bins integral.
Definition TH1.cxx:2572
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:3433
static bool CheckEqualAxes(const TAxis *a1, const TAxis *a2)
Check that the axis are the same.
Definition TH1.cxx:1580
@ 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:5081
virtual Int_t GetContour(Double_t *levels=nullptr)
Return contour values into array levels if pointer levels is non zero.
Definition TH1.cxx:8467
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:6557
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:9220
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:4332
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition TH1.cxx:8486
virtual void SetContour(Int_t nlevels, const Double_t *levels=nullptr)
Set the number and values of contour levels.
Definition TH1.cxx:8543
virtual void SetHighlight(Bool_t set=kTRUE)
Set highlight (enable/disable) mode for the histogram by default highlight mode is disable.
Definition TH1.cxx:4475
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition TH1.cxx:9167
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition TH1.cxx:6657
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition TH1.cxx:8725
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:2517
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:3664
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:7244
virtual Int_t GetQuantiles(Int_t n, Double_t *xp, const Double_t *p=nullptr)
Compute Quantiles for this histogram.
Definition TH1.cxx:4608
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:2738
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition TH1.cxx:7706
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:2826
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:8695
int LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge=false) const
Definition TH1.cxx:870
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:1609
static Int_t CheckConsistency(const TH1 *h1, const TH1 *h2)
Check histogram compatibility.
Definition TH1.cxx:1648
void RecursiveRemove(TObject *obj) override
Recursively remove object from the list of functions.
Definition TH1.cxx:6629
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:8234
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:6831
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:9231
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:8827
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:3697
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:9080
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:6513
static bool CheckAxisLimits(const TAxis *a1, const TAxis *a2)
Check that the axis limits of the histograms are the same.
Definition TH1.cxx:1566
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition TH1.cxx:741
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:7486
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:5265
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:3178
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:1383
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition TH1.cxx:9050
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition TH1.cxx:7795
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:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:457
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:475
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition TObject.cxx:902
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1074
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:203
virtual void SaveAs(const char *filename="", Option_t *option="") const
Save this object in the file specified by filename.
Definition TObject.cxx:705
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:881
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:543
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1088
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:892
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:839
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:790
void ResetBit(UInt_t f)
Definition TObject.h:201
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:68
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:78
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:70
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1062
Longptr_t ExecPlugin(int nargs)
Int_t LoadPlugin()
Load the plugin library for this handler.
static TClass * Class()
This is the base class for the ROOT Random number generators.
Definition TRandom.h:27
Double_t Rndm() override
Machine independent random number generator.
Definition TRandom.cxx:558
virtual Double_t PoissonD(Double_t mean)
Generates a random number according to a Poisson law.
Definition TRandom.cxx:460
virtual ULong64_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition TRandom.cxx:403
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
void ToLower()
Change string to lower-case.
Definition TString.cxx:1189
TString & ReplaceSpecialCppChars()
Find special characters which are typically used in printf() calls and replace them by appropriate es...
Definition TString.cxx:1121
const char * Data() const
Definition TString.h:384
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:713
@ kIgnoreCase
Definition TString.h:285
void ToUpper()
Change string to upper case.
Definition TString.cxx:1202
Bool_t IsNull() const
Definition TString.h:422
virtual void Streamer(TBuffer &)
Stream a string object.
Definition TString.cxx:1418
TString & Append(const char *cs)
Definition TString.h:581
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:641
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:660
Int_t GetOptStat() const
Definition TStyle.h:247
void SetOptStat(Int_t stat=1)
The type of information printed in the histogram statistics box can be selected via the parameter mod...
Definition TStyle.cxx:1641
void SetHistFillColor(Color_t color=1)
Definition TStyle.h:383
Color_t GetHistLineColor() const
Definition TStyle.h:235
Bool_t IsReading() const
Definition TStyle.h:300
Float_t GetBarOffset() const
Definition TStyle.h:184
void SetHistLineStyle(Style_t styl=0)
Definition TStyle.h:386
Style_t GetHistFillStyle() const
Definition TStyle.h:236
Color_t GetHistFillColor() const
Definition TStyle.h:234
Float_t GetBarWidth() const
Definition TStyle.h:185
Bool_t GetCanvasPreferGL() const
Definition TStyle.h:189
void SetHistLineColor(Color_t color=1)
Definition TStyle.h:384
void SetBarOffset(Float_t baroff=0.5)
Definition TStyle.h:339
Style_t GetHistLineStyle() const
Definition TStyle.h:237
void SetBarWidth(Float_t barwidth=0.5)
Definition TStyle.h:340
void SetHistFillStyle(Style_t styl=0)
Definition TStyle.h:385
Width_t GetHistLineWidth() const
Definition TStyle.h:238
Int_t GetOptFit() const
Definition TStyle.h:246
void SetHistLineWidth(Width_t width=1)
Definition TStyle.h:387
TVectorT.
Definition TVectorT.h:29
TVirtualFFT is an interface class for Fast Fourier Transforms.
Definition TVirtualFFT.h:88
static TVirtualFFT * FFT(Int_t ndim, Int_t *n, Option_t *option)
Returns a pointer to the FFT of requested size and type.
static TVirtualFFT * SineCosine(Int_t ndim, Int_t *n, Int_t *r2rkind, Option_t *option)
Returns a pointer to a sine or cosine transform of requested size and kind.
Abstract Base Class for Fitting.
static TVirtualFitter * GetFitter()
static: return the current Fitter
Abstract interface to a histogram painter.
virtual void DrawPanel()=0
Int_t DistancetoPrimitive(Int_t px, Int_t py) override=0
Computes distance from point (px,py) to the object.
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override=0
Execute action corresponding to an event at (px,py).
virtual void SetHighlight()=0
static TVirtualHistPainter * HistPainter(TH1 *obj)
Static function returning a pointer to the current histogram painter.
void Paint(Option_t *option="") override=0
This method must be overridden if a class wants to paint itself.
double gamma_quantile_c(double z, double alpha, double theta)
Inverse ( ) of the cumulative distribution function of the upper tail of the gamma distribution (gamm...
double gamma_quantile(double z, double alpha, double theta)
Inverse ( ) of the cumulative distribution function of the lower tail of the gamma distribution (gamm...
const Double_t sigma
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TH1F * h1
Definition legend1.C:5
TF1 * f1
Definition legend1.C:11
return c2
Definition legend2.C:14
R__ALWAYS_INLINE bool HasBeenDeleted(const TObject *obj)
Check if the TObject's memory has been deleted.
Definition TObject.h:405
TFitResultPtr FitObject(TH1 *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
fitting function for a TH1 (called from TH1::Fit)
Definition HFitImpl.cxx:977
double Chisquare(const TH1 &h1, TF1 &f1, bool useRange, EChisquareType type)
compute the chi2 value for an histogram given a function (see TH1::Chisquare for the documentation)
void FitOptionsMake(EFitObjectType type, const char *option, Foption_t &fitOption)
Decode list of options into fitOption.
Definition HFitImpl.cxx:685
void FillData(BinData &dv, const TH1 *hist, TF1 *func=nullptr)
fill the data vector from a TH1.
R__EXTERN TVirtualRWMutex * gCoreMutex
Bool_t IsNaN(Double_t x)
Definition TMath.h:903
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:704
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition TMath.cxx:637
Double_t Median(Long64_t n, const T *a, const Double_t *w=nullptr, Long64_t *work=nullptr)
Same as RMS.
Definition TMath.h:1359
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Definition TMath.h:913
Double_t Floor(Double_t x)
Rounds x downward, returning the largest integral value that is not greater than x.
Definition TMath.h:691
Double_t ATan(Double_t)
Returns the principal value of the arc tangent of x, expressed in radians.
Definition TMath.h:651
Double_t Ceil(Double_t x)
Rounds x upward, returning the smallest integral value that is not less than x.
Definition TMath.h:679
T MinElement(Long64_t n, const T *a)
Returns minimum of array a of length n.
Definition TMath.h:971
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:767
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
constexpr Double_t Pi()
Definition TMath.h:40
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Comparing floating points.
Definition TMath.h:429
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Comparing floating points.
Definition TMath.h:421
Double_t KolmogorovProb(Double_t z)
Calculates the Kolmogorov distribution function,.
Definition TMath.cxx:679
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Sort the n elements of the array a of generic templated type Element.
Definition TMathBase.h:413
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition TMathBase.h:329
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:773
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
Definition TMath.h:928
th1 Draw()
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2338