Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TH1.cxx
Go to the documentation of this file.
1// @(#)root/hist:$Id$
2// Author: Rene Brun 26/12/94
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <array>
13#include <cctype>
14#include <climits>
15#include <cmath>
16#include <cstdio>
17#include <cstdlib>
18#include <cstring>
19#include <iostream>
20#include <sstream>
21#include <fstream>
22
23#include "TROOT.h"
24#include "TBuffer.h"
25#include "TEnv.h"
26#include "TClass.h"
27#include "TMath.h"
28#include "THashList.h"
29#include "TH1.h"
30#include "TH2.h"
31#include "TH3.h"
32#include "TF2.h"
33#include "TF3.h"
34#include "TPluginManager.h"
35#include "TVirtualPad.h"
36#include "TRandom.h"
37#include "TVirtualFitter.h"
38#include "THLimitsFinder.h"
39#include "TProfile.h"
40#include "TStyle.h"
41#include "TVectorF.h"
42#include "TVectorD.h"
43#include "TBrowser.h"
44#include "TError.h"
45#include "TVirtualHistPainter.h"
46#include "TVirtualFFT.h"
47#include "TVirtualPaveStats.h"
48
49#include "HFitInterface.h"
50#include "Fit/DataRange.h"
51#include "Fit/BinData.h"
52#include "Math/GoFTest.h"
55
56#include "TH1Merger.h"
57
58/** \addtogroup Histograms
59@{
60\class TH1C
61\brief 1-D histogram with a byte per channel (see TH1 documentation)
62\class TH1S
63\brief 1-D histogram with a short per channel (see TH1 documentation)
64\class TH1I
65\brief 1-D histogram with an int per channel (see TH1 documentation)
66\class TH1L
67\brief 1-D histogram with a long64 per channel (see TH1 documentation)
68\class TH1F
69\brief 1-D histogram with a float per channel (see TH1 documentation)
70\class TH1D
71\brief 1-D histogram with a double per channel (see TH1 documentation)
72@}
73*/
74
75/** \class TH1
76 \ingroup Histograms
77TH1 is the base class of all histogram classes in %ROOT.
78
79It provides the common interface for operations such as binning, filling, drawing, which
80will be detailed below.
81
82-# [Creating histograms](\ref creating-histograms)
83 - [Labelling axes](\ref labelling-axis)
84-# [Binning](\ref binning)
85 - [Fix or variable bin size](\ref fix-var)
86 - [Convention for numbering bins](\ref convention)
87 - [Alphanumeric Bin Labels](\ref alpha)
88 - [Histograms with automatic bins](\ref auto-bin)
89 - [Rebinning](\ref rebinning)
90-# [Filling histograms](\ref filling-histograms)
91 - [Associated errors](\ref associated-errors)
92 - [Associated functions](\ref associated-functions)
93 - [Projections of histograms](\ref prof-hist)
94 - [Random Numbers and histograms](\ref random-numbers)
95 - [Making a copy of a histogram](\ref making-a-copy)
96 - [Normalizing histograms](\ref normalizing)
97-# [Drawing histograms](\ref drawing-histograms)
98 - [Setting Drawing histogram contour levels (2-D hists only)](\ref cont-level)
99 - [Setting histogram graphics attributes](\ref graph-att)
100 - [Customising how axes are drawn](\ref axis-drawing)
101-# [Fitting histograms](\ref fitting-histograms)
102-# [Saving/reading histograms to/from a ROOT file](\ref saving-histograms)
103-# [Operations on histograms](\ref operations-on-histograms)
104-# [Miscellaneous operations](\ref misc)
105
106ROOT supports the following histogram types:
107
108 - 1-D histograms:
109 - TH1C : histograms with one byte per channel. Maximum bin content = 127
110 - TH1S : histograms with one short per channel. Maximum bin content = 32767
111 - TH1I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
112 - TH1L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "*")
113 - TH1F : histograms with one float per channel. Maximum precision 7 digits
114 - TH1D : histograms with one double per channel. Maximum precision 14 digits
115 - 2-D histograms:
116 - TH2C : histograms with one byte per channel. Maximum bin content = 127
117 - TH2S : histograms with one short per channel. Maximum bin content = 32767
118 - TH2I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
119 - TH2L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "*")
120 - TH2F : histograms with one float per channel. Maximum precision 7 digits
121 - TH2D : histograms with one double per channel. Maximum precision 14 digits
122 - 3-D histograms:
123 - TH3C : histograms with one byte per channel. Maximum bin content = 127
124 - TH3S : histograms with one short per channel. Maximum bin content = 32767
125 - TH3I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
126 - TH3L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "*")
127 - TH3F : histograms with one float per channel. Maximum precision 7 digits
128 - TH3D : histograms with one double per channel. Maximum precision 14 digits
129 - Profile histograms: See classes TProfile, TProfile2D and TProfile3D.
130 Profile histograms are used to display the mean value of Y and its standard deviation
131 for each bin in X. Profile histograms are in many cases an elegant
132 replacement of two-dimensional histograms : the inter-relation of two
133 measured quantities X and Y can always be visualized by a two-dimensional
134 histogram or scatter-plot; If Y is an unknown (but single-valued)
135 approximate function of X, this function is displayed by a profile
136 histogram with much better precision than by a scatter-plot.
137
138<sup>
139\anchor intmax (*) INT_MAX = 2147483647 is the [maximum value for a variable of type int.](https://docs.microsoft.com/en-us/cpp/c-language/cpp-integer-limits)
140\anchor llongmax (*) LLONG_MAX = 9223372036854775807 is the [maximum value for a variable of type long64.](https://docs.microsoft.com/en-us/cpp/c-language/cpp-integer-limits)
141</sup>
142
143The inheritance hierarchy looks as follows:
144
145\image html classTH1__inherit__graph_org.svg width=100%
146
147\anchor creating-histograms
148## Creating histograms
149
150Histograms are created by invoking one of the constructors, e.g.
151~~~ {.cpp}
152 TH1F *h1 = new TH1F("h1", "h1 title", 100, 0, 4.4);
153 TH2F *h2 = new TH2F("h2", "h2 title", 40, 0, 4, 30, -3, 3);
154~~~
155Histograms may also be created by:
156
157 - calling the Clone() function, see below
158 - making a projection from a 2-D or 3-D histogram, see below
159 - reading a histogram from a file
160
161 When a histogram is created, a reference to it is automatically added
162 to the list of in-memory objects for the current file or directory.
163 Then the pointer to this histogram in the current directory can be found
164 by its name, doing:
165~~~ {.cpp}
166 TH1F *h1 = (TH1F*)gDirectory->FindObject(name);
167~~~
168
169 This default behaviour can be changed by:
170~~~ {.cpp}
171 h->SetDirectory(nullptr); // for the current histogram h
172 TH1::AddDirectory(kFALSE); // sets a global switch disabling the referencing
173~~~
174 When the histogram is deleted, the reference to it is removed from
175 the list of objects in memory.
176 When a file is closed, all histograms in memory associated with this file
177 are automatically deleted.
178
179\anchor labelling-axis
180### Labelling axes
181
182 Axis titles can be specified in the title argument of the constructor.
183 They must be separated by ";":
184~~~ {.cpp}
185 TH1F* h=new TH1F("h", "Histogram title;X Axis;Y Axis", 100, 0, 1);
186~~~
187 The histogram title and the axis titles can be any TLatex string, and
188 are persisted if a histogram is written to a file.
189
190 Any title can be omitted:
191~~~ {.cpp}
192 TH1F* h=new TH1F("h", "Histogram title;;Y Axis", 100, 0, 1);
193 TH1F* h=new TH1F("h", ";;Y Axis", 100, 0, 1);
194~~~
195 The method SetTitle() has the same syntax:
196~~~ {.cpp}
197 h->SetTitle("Histogram title;Another X title Axis");
198~~~
199Alternatively, the title of each axis can be set directly:
200~~~ {.cpp}
201 h->GetXaxis()->SetTitle("X axis title");
202 h->GetYaxis()->SetTitle("Y axis title");
203~~~
204For bin labels see \ref binning.
205
206\anchor binning
207## Binning
208
209\anchor fix-var
210### Fix or variable bin size
211
212 All histogram types support either fix or variable bin sizes.
213 2-D histograms may have fix size bins along X and variable size bins
214 along Y or vice-versa. The functions to fill, manipulate, draw or access
215 histograms are identical in both cases.
216
217 Each histogram always contains 3 axis objects of type TAxis: fXaxis, fYaxis and fZaxis.
218 To access the axis parameters, use:
219~~~ {.cpp}
220 TAxis *xaxis = h->GetXaxis(); etc.
221 Double_t binCenter = xaxis->GetBinCenter(bin), etc.
222~~~
223 See class TAxis for a description of all the access functions.
224 The axis range is always stored internally in double precision.
225
226\anchor convention
227### Convention for numbering bins
228
229 For all histogram types: nbins, xlow, xup
230~~~ {.cpp}
231 bin = 0; underflow bin
232 bin = 1; first bin with low-edge xlow INCLUDED
233 bin = nbins; last bin with upper-edge xup EXCLUDED
234 bin = nbins+1; overflow bin
235~~~
236 In case of 2-D or 3-D histograms, a "global bin" number is defined.
237 For example, assuming a 3-D histogram with (binx, biny, binz), the function
238~~~ {.cpp}
239 Int_t gbin = h->GetBin(binx, biny, binz);
240~~~
241 returns a global/linearized gbin number. This global gbin is useful
242 to access the bin content/error information independently of the dimension.
243 Note that to access the information other than bin content and errors
244 one should use the TAxis object directly with e.g.:
245~~~ {.cpp}
246 Double_t xcenter = h3->GetZaxis()->GetBinCenter(27);
247~~~
248 returns the center along z of bin number 27 (not the global bin)
249 in the 3-D histogram h3.
250
251\anchor alpha
252### Alphanumeric Bin Labels
253
254 By default, a histogram axis is drawn with its numeric bin labels.
255 One can specify alphanumeric labels instead with:
256
257 - call TAxis::SetBinLabel(bin, label);
258 This can always be done before or after filling.
259 When the histogram is drawn, bin labels will be automatically drawn.
260 See examples labels1.C and labels2.C
261 - call to a Fill function with one of the arguments being a string, e.g.
262~~~ {.cpp}
263 hist1->Fill(somename, weight);
264 hist2->Fill(x, somename, weight);
265 hist2->Fill(somename, y, weight);
266 hist2->Fill(somenamex, somenamey, weight);
267~~~
268 See examples hlabels1.C and hlabels2.C
269 - via TTree::Draw. see for example cernstaff.C
270~~~ {.cpp}
271 tree.Draw("Nation::Division");
272~~~
273 where "Nation" and "Division" are two branches of a Tree.
274
275When using the options 2 or 3 above, the labels are automatically
276 added to the list (THashList) of labels for a given axis.
277 By default, an axis is drawn with the order of bins corresponding
278 to the filling sequence. It is possible to reorder the axis
279
280 - alphabetically
281 - by increasing or decreasing values
282
283 The reordering can be triggered via the TAxis context menu by selecting
284 the menu item "LabelsOption" or by calling directly
285 TH1::LabelsOption(option, axis) where
286
287 - axis may be "X", "Y" or "Z"
288 - option may be:
289 - "a" sort by alphabetic order
290 - ">" sort by decreasing values
291 - "<" sort by increasing values
292 - "h" draw labels horizontal
293 - "v" draw labels vertical
294 - "u" draw labels up (end of label right adjusted)
295 - "d" draw labels down (start of label left adjusted)
296
297 When using the option 2 above, new labels are added by doubling the current
298 number of bins in case one label does not exist yet.
299 When the Filling is terminated, it is possible to trim the number
300 of bins to match the number of active labels by calling
301~~~ {.cpp}
302 TH1::LabelsDeflate(axis) with axis = "X", "Y" or "Z"
303~~~
304 This operation is automatic when using TTree::Draw.
305 Once bin labels have been created, they become persistent if the histogram
306 is written to a file or when generating the C++ code via SavePrimitive.
307
308\anchor auto-bin
309### Histograms with automatic bins
310
311 When a histogram is created with an axis lower limit greater or equal
312 to its upper limit, the SetBuffer is automatically called with an
313 argument fBufferSize equal to fgBufferSize (default value=1000).
314 fgBufferSize may be reset via the static function TH1::SetDefaultBufferSize.
315 The axis limits will be automatically computed when the buffer will
316 be full or when the function BufferEmpty is called.
317
318\anchor rebinning
319### Rebinning
320
321 At any time, a histogram can be rebinned via TH1::Rebin. This function
322 returns a new histogram with the rebinned contents.
323 If bin errors were stored, they are recomputed during the rebinning.
324
325
326\anchor filling-histograms
327## Filling histograms
328
329 A histogram is typically filled with statements like:
330~~~ {.cpp}
331 h1->Fill(x);
332 h1->Fill(x, w); //fill with weight
333 h2->Fill(x, y)
334 h2->Fill(x, y, w)
335 h3->Fill(x, y, z)
336 h3->Fill(x, y, z, w)
337~~~
338 or via one of the Fill functions accepting names described above.
339 The Fill functions compute the bin number corresponding to the given
340 x, y or z argument and increment this bin by the given weight.
341 The Fill functions return the bin number for 1-D histograms or global
342 bin number for 2-D and 3-D histograms.
343 If TH1::Sumw2 has been called before filling, the sum of squares of
344 weights is also stored.
345 One can also increment directly a bin number via TH1::AddBinContent
346 or replace the existing content via TH1::SetBinContent. Passing an
347 out-of-range bin to TH1::AddBinContent leads to undefined behavior.
348 To access the bin content of a given bin, do:
349~~~ {.cpp}
350 Double_t binContent = h->GetBinContent(bin);
351~~~
352
353 By default, the bin number is computed using the current axis ranges.
354 If the automatic binning option has been set via
355~~~ {.cpp}
356 h->SetCanExtend(TH1::kAllAxes);
357~~~
358 then, the Fill Function will automatically extend the axis range to
359 accomodate the new value specified in the Fill argument. The method
360 used is to double the bin size until the new value fits in the range,
361 merging bins two by two. This automatic binning options is extensively
362 used by the TTree::Draw function when histogramming Tree variables
363 with an unknown range.
364 This automatic binning option is supported for 1-D, 2-D and 3-D histograms.
365
366 During filling, some statistics parameters are incremented to compute
367 the mean value and Root Mean Square with the maximum precision.
368
369 In case of histograms of type TH1C, TH1S, TH2C, TH2S, TH3C, TH3S
370 a check is made that the bin contents do not exceed the maximum positive
371 capacity (127 or 32767). Histograms of all types may have positive
372 or/and negative bin contents.
373
374\anchor associated-errors
375### Associated errors
376 By default, for each bin, the sum of weights is computed at fill time.
377 One can also call TH1::Sumw2 to force the storage and computation
378 of the sum of the square of weights per bin.
379 If Sumw2 has been called, the error per bin is computed as the
380 sqrt(sum of squares of weights), otherwise the error is set equal
381 to the sqrt(bin content).
382 To return the error for a given bin number, do:
383~~~ {.cpp}
384 Double_t error = h->GetBinError(bin);
385~~~
386
387\anchor associated-functions
388### Associated functions
389 One or more object (typically a TF1*) can be added to the list
390 of functions (fFunctions) associated to each histogram.
391 When TH1::Fit is invoked, the fitted function is added to this list.
392 Given a histogram h, one can retrieve an associated function
393 with:
394~~~ {.cpp}
395 TF1 *myfunc = h->GetFunction("myfunc");
396~~~
397
398
399\anchor operations-on-histograms
400## Operations on histograms
401
402 Many types of operations are supported on histograms or between histograms
403
404 - Addition of a histogram to the current histogram.
405 - Additions of two histograms with coefficients and storage into the current
406 histogram.
407 - Multiplications and Divisions are supported in the same way as additions.
408 - The Add, Divide and Multiply functions also exist to add, divide or multiply
409 a histogram by a function.
410
411 If a histogram has associated error bars (TH1::Sumw2 has been called),
412 the resulting error bars are also computed assuming independent histograms.
413 In case of divisions, Binomial errors are also supported.
414 One can mark a histogram to be an "average" histogram by setting its bit kIsAverage via
415 myhist.SetBit(TH1::kIsAverage);
416 When adding (see TH1::Add) average histograms, the histograms are averaged and not summed.
417
418
419\anchor prof-hist
420### Projections of histograms
421
422 One can:
423
424 - make a 1-D projection of a 2-D histogram or Profile
425 see functions TH2::ProjectionX,Y, TH2::ProfileX,Y, TProfile::ProjectionX
426 - make a 1-D, 2-D or profile out of a 3-D histogram
427 see functions TH3::ProjectionZ, TH3::Project3D.
428
429 One can fit these projections via:
430~~~ {.cpp}
431 TH2::FitSlicesX,Y, TH3::FitSlicesZ.
432~~~
433
434\anchor random-numbers
435### Random Numbers and histograms
436
437 TH1::FillRandom can be used to randomly fill a histogram using
438 the contents of an existing TF1 function or another
439 TH1 histogram (for all dimensions).
440 For example, the following two statements create and fill a histogram
441 10000 times with a default gaussian distribution of mean 0 and sigma 1:
442~~~ {.cpp}
443 TH1F h1("h1", "histo from a gaussian", 100, -3, 3);
444 h1.FillRandom("gaus", 10000);
445~~~
446 TH1::GetRandom can be used to return a random number distributed
447 according to the contents of a histogram.
448
449\anchor making-a-copy
450### Making a copy of a histogram
451 Like for any other ROOT object derived from TObject, one can use
452 the Clone() function. This makes an identical copy of the original
453 histogram including all associated errors and functions, e.g.:
454~~~ {.cpp}
455 TH1F *hnew = (TH1F*)h->Clone("hnew");
456~~~
457
458\anchor normalizing
459### Normalizing histograms
460
461 One can scale a histogram such that the bins integral is equal to
462 the normalization parameter via TH1::Scale(Double_t norm), where norm
463 is the desired normalization divided by the integral of the histogram.
464
465
466\anchor drawing-histograms
467## Drawing histograms
468
469 Histograms are drawn via the THistPainter class. Each histogram has
470 a pointer to its own painter (to be usable in a multithreaded program).
471 Many drawing options are supported.
472 See THistPainter::Paint() for more details.
473
474 The same histogram can be drawn with different options in different pads.
475 When a histogram drawn in a pad is deleted, the histogram is
476 automatically removed from the pad or pads where it was drawn.
477 If a histogram is drawn in a pad, then filled again, the new status
478 of the histogram will be automatically shown in the pad next time
479 the pad is updated. One does not need to redraw the histogram.
480 To draw the current version of a histogram in a pad, one can use
481~~~ {.cpp}
482 h->DrawCopy();
483~~~
484 This makes a clone (see Clone below) of the histogram. Once the clone
485 is drawn, the original histogram may be modified or deleted without
486 affecting the aspect of the clone.
487
488 One can use TH1::SetMaximum() and TH1::SetMinimum() to force a particular
489 value for the maximum or the minimum scale on the plot. (For 1-D
490 histograms this means the y-axis, while for 2-D histograms these
491 functions affect the z-axis).
492
493 TH1::UseCurrentStyle() can be used to change all histogram graphics
494 attributes to correspond to the current selected style.
495 This function must be called for each histogram.
496 In case one reads and draws many histograms from a file, one can force
497 the histograms to inherit automatically the current graphics style
498 by calling before gROOT->ForceStyle().
499
500\anchor cont-level
501### Setting Drawing histogram contour levels (2-D hists only)
502
503 By default contours are automatically generated at equidistant
504 intervals. A default value of 20 levels is used. This can be modified
505 via TH1::SetContour() or TH1::SetContourLevel().
506 the contours level info is used by the drawing options "cont", "surf",
507 and "lego".
508
509\anchor graph-att
510### Setting histogram graphics attributes
511
512 The histogram classes inherit from the attribute classes:
513 TAttLine, TAttFill, and TAttMarker.
514 See the member functions of these classes for the list of options.
515
516\anchor axis-drawing
517### Customizing how axes are drawn
518
519 Use the functions of TAxis, such as
520~~~ {.cpp}
521 histogram.GetXaxis()->SetTicks("+");
522 histogram.GetYaxis()->SetRangeUser(1., 5.);
523~~~
524
525\anchor fitting-histograms
526## Fitting histograms
527
528 Histograms (1-D, 2-D, 3-D and Profiles) can be fitted with a user
529 specified function or a pre-defined function via TH1::Fit.
530 See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for the fitting documentation and the possible [fitting options](\ref HFitOpt)
531
532 The FitPanel can also be used for fitting an histogram. See the [FitPanel documentation](https://root.cern/manual/fitting/#using-the-fit-panel).
533
534\anchor saving-histograms
535## Saving/reading histograms to/from a ROOT file
536
537 The following statements create a ROOT file and store a histogram
538 on the file. Because TH1 derives from TNamed, the key identifier on
539 the file is the histogram name:
540~~~ {.cpp}
541 TFile f("histos.root", "new");
542 TH1F h1("hgaus", "histo from a gaussian", 100, -3, 3);
543 h1.FillRandom("gaus", 10000);
544 h1->Write();
545~~~
546 To read this histogram in another Root session, do:
547~~~ {.cpp}
548 TFile f("histos.root");
549 TH1F *h = (TH1F*)f.Get("hgaus");
550~~~
551 One can save all histograms in memory to the file by:
552~~~ {.cpp}
553 file->Write();
554~~~
555
556
557\anchor misc
558## Miscellaneous operations
559
560~~~ {.cpp}
561 TH1::KolmogorovTest(): statistical test of compatibility in shape
562 between two histograms
563 TH1::Smooth() smooths the bin contents of a 1-d histogram
564 TH1::Integral() returns the integral of bin contents in a given bin range
565 TH1::GetMean(int axis) returns the mean value along axis
566 TH1::GetStdDev(int axis) returns the sigma distribution along axis
567 TH1::GetEntries() returns the number of entries
568 TH1::Reset() resets the bin contents and errors of a histogram
569~~~
570 IMPORTANT NOTE: The returned values for GetMean and GetStdDev depend on how the
571 histogram statistics are calculated. By default, if no range has been set, the
572 returned values are the (unbinned) ones calculated at fill time. If a range has been
573 set, however, the values are calculated using the bins in range; THIS IS TRUE EVEN
574 IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset the range.
575 To ensure that the returned values are always those of the binned data stored in the
576 histogram, call TH1::ResetStats. See TH1::GetStats.
577*/
578
579TF1 *gF1=nullptr; //left for back compatibility (use TVirtualFitter::GetUserFunc instead)
580
585
586extern void H1InitGaus();
587extern void H1InitExpo();
588extern void H1InitPolynom();
589extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
590extern void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail);
591extern void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b);
592
593namespace {
594
595/// Enumeration specifying inconsistencies between two histograms,
596/// in increasing severity.
597enum EInconsistencyBits {
598 kFullyConsistent = 0,
599 kDifferentLabels = BIT(0),
600 kDifferentBinLimits = BIT(1),
601 kDifferentAxisLimits = BIT(2),
602 kDifferentNumberOfBins = BIT(3),
603 kDifferentDimensions = BIT(4)
604};
605
606} // namespace
607
609
610////////////////////////////////////////////////////////////////////////////////
611/// Histogram default constructor.
612
614{
615 fDirectory = nullptr;
616 fFunctions = new TList;
617 fNcells = 0;
618 fIntegral = nullptr;
619 fPainter = nullptr;
620 fEntries = 0;
621 fNormFactor = 0;
623 fMaximum = -1111;
624 fMinimum = -1111;
625 fBufferSize = 0;
626 fBuffer = nullptr;
629 fXaxis.SetName("xaxis");
630 fYaxis.SetName("yaxis");
631 fZaxis.SetName("zaxis");
632 fXaxis.SetParent(this);
633 fYaxis.SetParent(this);
634 fZaxis.SetParent(this);
636}
637
638////////////////////////////////////////////////////////////////////////////////
639/// Histogram default destructor.
640
642{
644 return;
645 }
646 delete[] fIntegral;
647 fIntegral = nullptr;
648 delete[] fBuffer;
649 fBuffer = nullptr;
650 if (fFunctions) {
652
654 TObject* obj = nullptr;
655 //special logic to support the case where the same object is
656 //added multiple times in fFunctions.
657 //This case happens when the same object is added with different
658 //drawing modes
659 //In the loop below we must be careful with objects (eg TCutG) that may
660 // have been added to the list of functions of several histograms
661 //and may have been already deleted.
662 while ((obj = fFunctions->First())) {
663 while(fFunctions->Remove(obj)) { }
665 break;
666 }
667 delete obj;
668 obj = nullptr;
669 }
670 delete fFunctions;
671 fFunctions = nullptr;
672 }
673 if (fDirectory) {
674 fDirectory->Remove(this);
675 fDirectory = nullptr;
676 }
677 delete fPainter;
678 fPainter = nullptr;
679}
680
681////////////////////////////////////////////////////////////////////////////////
682/// Constructor for fix bin size histograms.
683/// Creates the main histogram structure.
684///
685/// \param[in] name name of histogram (avoid blanks)
686/// \param[in] title histogram title.
687/// If title is of the form `stringt;stringx;stringy;stringz`,
688/// the histogram title is set to `stringt`,
689/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
690/// \param[in] nbins number of bins
691/// \param[in] xlow low edge of first bin
692/// \param[in] xup upper edge of last bin (not included in last bin)
693
694
695TH1::TH1(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
696 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
697{
698 Build();
699 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
700 fXaxis.Set(nbins,xlow,xup);
701 fNcells = fXaxis.GetNbins()+2;
702}
703
704////////////////////////////////////////////////////////////////////////////////
705/// Constructor for variable bin size histograms using an input array of type float.
706/// Creates the main histogram structure.
707///
708/// \param[in] name name of histogram (avoid blanks)
709/// \param[in] title histogram title.
710/// If title is of the form `stringt;stringx;stringy;stringz`
711/// the histogram title is set to `stringt`,
712/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
713/// \param[in] nbins number of bins
714/// \param[in] xbins array of low-edges for each bin.
715/// This is an array of type float and size nbins+1
716
717TH1::TH1(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
718 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
719{
720 Build();
721 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
722 if (xbins) fXaxis.Set(nbins,xbins);
723 else fXaxis.Set(nbins,0,1);
724 fNcells = fXaxis.GetNbins()+2;
725}
726
727////////////////////////////////////////////////////////////////////////////////
728/// Constructor for variable bin size histograms using an input array of type double.
729///
730/// \param[in] name name of histogram (avoid blanks)
731/// \param[in] title histogram title.
732/// If title is of the form `stringt;stringx;stringy;stringz`
733/// the histogram title is set to `stringt`,
734/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
735/// \param[in] nbins number of bins
736/// \param[in] xbins array of low-edges for each bin.
737/// This is an array of type double and size nbins+1
738
739TH1::TH1(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
740 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
741{
742 Build();
743 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
744 if (xbins) fXaxis.Set(nbins,xbins);
745 else fXaxis.Set(nbins,0,1);
746 fNcells = fXaxis.GetNbins()+2;
747}
748
749////////////////////////////////////////////////////////////////////////////////
750/// Static function: cannot be inlined on Windows/NT.
751
753{
754 return fgAddDirectory;
755}
756
757////////////////////////////////////////////////////////////////////////////////
758/// Browse the Histogram object.
759
761{
762 Draw(b ? b->GetDrawOption() : "");
763 gPad->Update();
764}
765
766////////////////////////////////////////////////////////////////////////////////
767/// Creates histogram basic data structure.
768
770{
771 fDirectory = nullptr;
772 fPainter = nullptr;
773 fIntegral = nullptr;
774 fEntries = 0;
775 fNormFactor = 0;
777 fMaximum = -1111;
778 fMinimum = -1111;
779 fBufferSize = 0;
780 fBuffer = nullptr;
783 fXaxis.SetName("xaxis");
784 fYaxis.SetName("yaxis");
785 fZaxis.SetName("zaxis");
786 fYaxis.Set(1,0.,1.);
787 fZaxis.Set(1,0.,1.);
788 fXaxis.SetParent(this);
789 fYaxis.SetParent(this);
790 fZaxis.SetParent(this);
791
793
794 fFunctions = new TList;
795
797
800 if (fDirectory) {
802 fDirectory->Append(this,kTRUE);
803 }
804 }
805}
806
807////////////////////////////////////////////////////////////////////////////////
808/// Performs the operation: `this = this + c1*f1`
809/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
810///
811/// By default, the function is computed at the centre of the bin.
812/// if option "I" is specified (1-d histogram only), the integral of the
813/// function in each bin is used instead of the value of the function at
814/// the centre of the bin.
815///
816/// Only bins inside the function range are recomputed.
817///
818/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
819/// you should call Sumw2 before making this operation.
820/// This is particularly important if you fit the histogram after TH1::Add
821///
822/// The function return kFALSE if the Add operation failed
823
825{
826 if (!f1) {
827 Error("Add","Attempt to add a non-existing function");
828 return kFALSE;
829 }
830
831 TString opt = option;
832 opt.ToLower();
833 Bool_t integral = kFALSE;
834 if (opt.Contains("i") && fDimension == 1) integral = kTRUE;
835
836 Int_t ncellsx = GetNbinsX() + 2; // cells = normal bins + underflow bin + overflow bin
837 Int_t ncellsy = GetNbinsY() + 2;
838 Int_t ncellsz = GetNbinsZ() + 2;
839 if (fDimension < 2) ncellsy = 1;
840 if (fDimension < 3) ncellsz = 1;
841
842 // delete buffer if it is there since it will become invalid
843 if (fBuffer) BufferEmpty(1);
844
845 // - Add statistics
846 Double_t s1[10];
847 for (Int_t i = 0; i < 10; ++i) s1[i] = 0;
848 PutStats(s1);
849 SetMinimum();
850 SetMaximum();
851
852 // - Loop on bins (including underflows/overflows)
853 Int_t bin, binx, biny, binz;
854 Double_t cu=0;
855 Double_t xx[3];
856 Double_t *params = nullptr;
857 f1->InitArgs(xx,params);
858 for (binz = 0; binz < ncellsz; ++binz) {
859 xx[2] = fZaxis.GetBinCenter(binz);
860 for (biny = 0; biny < ncellsy; ++biny) {
861 xx[1] = fYaxis.GetBinCenter(biny);
862 for (binx = 0; binx < ncellsx; ++binx) {
863 xx[0] = fXaxis.GetBinCenter(binx);
864 if (!f1->IsInside(xx)) continue;
866 bin = binx + ncellsx * (biny + ncellsy * binz);
867 if (integral) {
868 cu = c1*f1->Integral(fXaxis.GetBinLowEdge(binx), fXaxis.GetBinUpEdge(binx), 0.) / fXaxis.GetBinWidth(binx);
869 } else {
870 cu = c1*f1->EvalPar(xx);
871 }
872 if (TF1::RejectedPoint()) continue;
873 AddBinContent(bin,cu);
874 }
875 }
876 }
877
878 return kTRUE;
879}
880
881int TH1::LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge) const
882{
883 const auto inconsistency = CheckConsistency(h1, h2);
884
885 if (inconsistency & kDifferentDimensions) {
886 if (useMerge)
887 Info(name, "Histograms have different dimensions - trying to use TH1::Merge");
888 else {
889 Error(name, "Histograms have different dimensions");
890 }
891 } else if (inconsistency & kDifferentNumberOfBins) {
892 if (useMerge)
893 Info(name, "Histograms have different number of bins - trying to use TH1::Merge");
894 else {
895 Error(name, "Histograms have different number of bins");
896 }
897 } else if (inconsistency & kDifferentAxisLimits) {
898 if (useMerge)
899 Info(name, "Histograms have different axis limits - trying to use TH1::Merge");
900 else
901 Warning(name, "Histograms have different axis limits");
902 } else if (inconsistency & kDifferentBinLimits) {
903 if (useMerge)
904 Info(name, "Histograms have different bin limits - trying to use TH1::Merge");
905 else
906 Warning(name, "Histograms have different bin limits");
907 } else if (inconsistency & kDifferentLabels) {
908 // in case of different labels -
909 if (useMerge)
910 Info(name, "Histograms have different labels - trying to use TH1::Merge");
911 else
912 Info(name, "Histograms have different labels");
913 }
914
915 return inconsistency;
916}
917
918////////////////////////////////////////////////////////////////////////////////
919/// Performs the operation: `this = this + c1*h1`
920/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
921///
922/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
923/// if not already set.
924///
925/// Note also that adding histogram with labels is not supported, histogram will be
926/// added merging them by bin number independently of the labels.
927/// For adding histogram with labels one should use TH1::Merge
928///
929/// SPECIAL CASE (Average/Efficiency histograms)
930/// For histograms representing averages or efficiencies, one should compute the average
931/// of the two histograms and not the sum. One can mark a histogram to be an average
932/// histogram by setting its bit kIsAverage with
933/// myhist.SetBit(TH1::kIsAverage);
934/// Note that the two histograms must have their kIsAverage bit set
935///
936/// IMPORTANT NOTE1: If you intend to use the errors of this histogram later
937/// you should call Sumw2 before making this operation.
938/// This is particularly important if you fit the histogram after TH1::Add
939///
940/// IMPORTANT NOTE2: if h1 has a normalisation factor, the normalisation factor
941/// is used , ie this = this + c1*factor*h1
942/// Use the other TH1::Add function if you do not want this feature
943///
944/// IMPORTANT NOTE3: You should be careful about the statistics of the
945/// returned histogram, whose statistics may be binned or unbinned,
946/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
947/// and whether TH1::ResetStats has been called on either this or h1.
948/// See TH1::GetStats.
949///
950/// The function return kFALSE if the Add operation failed
951
953{
954 if (!h1) {
955 Error("Add","Attempt to add a non-existing histogram");
956 return kFALSE;
957 }
958
959 // delete buffer if it is there since it will become invalid
960 if (fBuffer) BufferEmpty(1);
961
962 bool useMerge = false;
963 const bool considerMerge = (c1 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
964 const auto inconsistency = LoggedInconsistency("Add", this, h1, considerMerge);
965 // If there is a bad inconsistency and we can't even consider merging, just give up
966 if(inconsistency >= kDifferentNumberOfBins && !considerMerge) {
967 return false;
968 }
969 // If there is an inconsistency, we try to use merging
970 if(inconsistency > kFullyConsistent) {
971 useMerge = considerMerge;
972 }
973
974 if (useMerge) {
975 TList l;
976 l.Add(const_cast<TH1*>(h1));
977 auto iret = Merge(&l);
978 return (iret >= 0);
979 }
980
981 // Create Sumw2 if h1 has Sumw2 set
982 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
983
984 // - Add statistics
985 Double_t entries = TMath::Abs( GetEntries() + c1 * h1->GetEntries() );
986
987 // statistics can be preserved only in case of positive coefficients
988 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
989 Bool_t resetStats = (c1 < 0);
990 Double_t s1[kNstat] = {0};
991 Double_t s2[kNstat] = {0};
992 if (!resetStats) {
993 // need to initialize to zero s1 and s2 since
994 // GetStats fills only used elements depending on dimension and type
995 GetStats(s1);
996 h1->GetStats(s2);
997 }
998
999 SetMinimum();
1000 SetMaximum();
1001
1002 // - Loop on bins (including underflows/overflows)
1003 Double_t factor = 1;
1004 if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();;
1005 Double_t c1sq = c1 * c1;
1006 Double_t factsq = factor * factor;
1007
1008 for (Int_t bin = 0; bin < fNcells; ++bin) {
1009 //special case where histograms have the kIsAverage bit set
1010 if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
1012 Double_t y2 = this->RetrieveBinContent(bin);
1013 Double_t e1sq = h1->GetBinErrorSqUnchecked(bin);
1014 Double_t e2sq = this->GetBinErrorSqUnchecked(bin);
1015 Double_t w1 = 1., w2 = 1.;
1016
1017 // consider all special cases when bin errors are zero
1018 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1019 if (e1sq) w1 = 1. / e1sq;
1020 else if (h1->fSumw2.fN) {
1021 w1 = 1.E200; // use an arbitrary huge value
1022 if (y1 == 0) {
1023 // use an estimated error from the global histogram scale
1024 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1025 w1 = 1./(sf*sf);
1026 }
1027 }
1028 if (e2sq) w2 = 1. / e2sq;
1029 else if (fSumw2.fN) {
1030 w2 = 1.E200; // use an arbitrary huge value
1031 if (y2 == 0) {
1032 // use an estimated error from the global histogram scale
1033 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1034 w2 = 1./(sf*sf);
1035 }
1036 }
1037
1038 double y = (w1*y1 + w2*y2)/(w1 + w2);
1039 UpdateBinContent(bin, y);
1040 if (fSumw2.fN) {
1041 double err2 = 1./(w1 + w2);
1042 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1043 fSumw2.fArray[bin] = err2;
1044 }
1045 } else { // normal case of addition between histograms
1046 AddBinContent(bin, c1 * factor * h1->RetrieveBinContent(bin));
1047 if (fSumw2.fN) fSumw2.fArray[bin] += c1sq * factsq * h1->GetBinErrorSqUnchecked(bin);
1048 }
1049 }
1050
1051 // update statistics (do here to avoid changes by SetBinContent)
1052 if (resetStats) {
1053 // statistics need to be reset in case coefficient are negative
1054 ResetStats();
1055 }
1056 else {
1057 for (Int_t i=0;i<kNstat;i++) {
1058 if (i == 1) s1[i] += c1*c1*s2[i];
1059 else s1[i] += c1*s2[i];
1060 }
1061 PutStats(s1);
1062 SetEntries(entries);
1063 }
1064 return kTRUE;
1065}
1066
1067////////////////////////////////////////////////////////////////////////////////
1068/// Replace contents of this histogram by the addition of h1 and h2.
1069///
1070/// `this = c1*h1 + c2*h2`
1071/// if errors are defined (see TH1::Sumw2), errors are also recalculated
1072///
1073/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
1074/// if not already set.
1075///
1076/// Note also that adding histogram with labels is not supported, histogram will be
1077/// added merging them by bin number independently of the labels.
1078/// For adding histogram ith labels one should use TH1::Merge
1079///
1080/// SPECIAL CASE (Average/Efficiency histograms)
1081/// For histograms representing averages or efficiencies, one should compute the average
1082/// of the two histograms and not the sum. One can mark a histogram to be an average
1083/// histogram by setting its bit kIsAverage with
1084/// myhist.SetBit(TH1::kIsAverage);
1085/// Note that the two histograms must have their kIsAverage bit set
1086///
1087/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
1088/// you should call Sumw2 before making this operation.
1089/// This is particularly important if you fit the histogram after TH1::Add
1090///
1091/// IMPORTANT NOTE2: You should be careful about the statistics of the
1092/// returned histogram, whose statistics may be binned or unbinned,
1093/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
1094/// and whether TH1::ResetStats has been called on either this or h1.
1095/// See TH1::GetStats.
1096///
1097/// ANOTHER SPECIAL CASE : h1 = h2 and c2 < 0
1098/// do a scaling this = c1 * h1 / (bin Volume)
1099///
1100/// The function returns kFALSE if the Add operation failed
1101
1103{
1104
1105 if (!h1 || !h2) {
1106 Error("Add","Attempt to add a non-existing histogram");
1107 return kFALSE;
1108 }
1109
1110 // delete buffer if it is there since it will become invalid
1111 if (fBuffer) BufferEmpty(1);
1112
1113 Bool_t normWidth = kFALSE;
1114 if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
1115
1116 if (h1 != h2) {
1117 bool useMerge = false;
1118 const bool considerMerge = (c1 == 1. && c2 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
1119
1120 // We can combine inconsistencies like this, since they are ordered and a
1121 // higher inconsistency is worse
1122 auto const inconsistency = std::max(LoggedInconsistency("Add", this, h1, considerMerge),
1123 LoggedInconsistency("Add", h1, h2, considerMerge));
1124
1125 // If there is a bad inconsistency and we can't even consider merging, just give up
1126 if(inconsistency >= kDifferentNumberOfBins && !considerMerge) {
1127 return false;
1128 }
1129 // If there is an inconsistency, we try to use merging
1130 if(inconsistency > kFullyConsistent) {
1131 useMerge = considerMerge;
1132 }
1133
1134 if (useMerge) {
1135 TList l;
1136 // why TList takes non-const pointers ????
1137 l.Add(const_cast<TH1*>(h1));
1138 l.Add(const_cast<TH1*>(h2));
1139 Reset("ICE");
1140 auto iret = Merge(&l);
1141 return (iret >= 0);
1142 }
1143 }
1144
1145 // Create Sumw2 if h1 or h2 have Sumw2 set
1146 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
1147
1148 // - Add statistics
1149 Double_t nEntries = TMath::Abs( c1*h1->GetEntries() + c2*h2->GetEntries() );
1150
1151 // TODO remove
1152 // statistics can be preserved only in case of positive coefficients
1153 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1154 // also in case of scaling with the width we cannot preserve the statistics
1155 Double_t s1[kNstat] = {0};
1156 Double_t s2[kNstat] = {0};
1157 Double_t s3[kNstat];
1158
1159
1160 Bool_t resetStats = (c1*c2 < 0) || normWidth;
1161 if (!resetStats) {
1162 // need to initialize to zero s1 and s2 since
1163 // GetStats fills only used elements depending on dimension and type
1164 h1->GetStats(s1);
1165 h2->GetStats(s2);
1166 for (Int_t i=0;i<kNstat;i++) {
1167 if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
1168 //else s3[i] = TMath::Abs(c1)*s1[i] + TMath::Abs(c2)*s2[i];
1169 else s3[i] = c1*s1[i] + c2*s2[i];
1170 }
1171 }
1172
1173 SetMinimum();
1174 SetMaximum();
1175
1176 if (normWidth) { // DEPRECATED CASE: belongs to fitting / drawing modules
1177
1178 Int_t nbinsx = GetNbinsX() + 2; // normal bins + underflow, overflow
1179 Int_t nbinsy = GetNbinsY() + 2;
1180 Int_t nbinsz = GetNbinsZ() + 2;
1181
1182 if (fDimension < 2) nbinsy = 1;
1183 if (fDimension < 3) nbinsz = 1;
1184
1185 Int_t bin, binx, biny, binz;
1186 for (binz = 0; binz < nbinsz; ++binz) {
1187 Double_t wz = h1->GetZaxis()->GetBinWidth(binz);
1188 for (biny = 0; biny < nbinsy; ++biny) {
1189 Double_t wy = h1->GetYaxis()->GetBinWidth(biny);
1190 for (binx = 0; binx < nbinsx; ++binx) {
1191 Double_t wx = h1->GetXaxis()->GetBinWidth(binx);
1192 bin = GetBin(binx, biny, binz);
1193 Double_t w = wx*wy*wz;
1194 UpdateBinContent(bin, c1 * h1->RetrieveBinContent(bin) / w);
1195 if (fSumw2.fN) {
1196 Double_t e1 = h1->GetBinError(bin)/w;
1197 fSumw2.fArray[bin] = c1*c1*e1*e1;
1198 }
1199 }
1200 }
1201 }
1202 } else if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
1203 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
1204 // special case where histograms have the kIsAverage bit set
1206 Double_t y2 = h2->RetrieveBinContent(i);
1208 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
1209 Double_t w1 = 1., w2 = 1.;
1210
1211 // consider all special cases when bin errors are zero
1212 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1213 if (e1sq) w1 = 1./ e1sq;
1214 else if (h1->fSumw2.fN) {
1215 w1 = 1.E200; // use an arbitrary huge value
1216 if (y1 == 0 ) { // use an estimated error from the global histogram scale
1217 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1218 w1 = 1./(sf*sf);
1219 }
1220 }
1221 if (e2sq) w2 = 1./ e2sq;
1222 else if (h2->fSumw2.fN) {
1223 w2 = 1.E200; // use an arbitrary huge value
1224 if (y2 == 0) { // use an estimated error from the global histogram scale
1225 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1226 w2 = 1./(sf*sf);
1227 }
1228 }
1229
1230 double y = (w1*y1 + w2*y2)/(w1 + w2);
1231 UpdateBinContent(i, y);
1232 if (fSumw2.fN) {
1233 double err2 = 1./(w1 + w2);
1234 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1235 fSumw2.fArray[i] = err2;
1236 }
1237 }
1238 } else { // case of simple histogram addition
1239 Double_t c1sq = c1 * c1;
1240 Double_t c2sq = c2 * c2;
1241 for (Int_t i = 0; i < fNcells; ++i) { // Loop on cells (bins including underflows/overflows)
1242 UpdateBinContent(i, c1 * h1->RetrieveBinContent(i) + c2 * h2->RetrieveBinContent(i));
1243 if (fSumw2.fN) {
1244 fSumw2.fArray[i] = c1sq * h1->GetBinErrorSqUnchecked(i) + c2sq * h2->GetBinErrorSqUnchecked(i);
1245 }
1246 }
1247 }
1248
1249 if (resetStats) {
1250 // statistics need to be reset in case coefficient are negative
1251 ResetStats();
1252 }
1253 else {
1254 // update statistics (do here to avoid changes by SetBinContent) FIXME remove???
1255 PutStats(s3);
1256 SetEntries(nEntries);
1257 }
1258
1259 return kTRUE;
1260}
1261
1262////////////////////////////////////////////////////////////////////////////////
1263/// Increment bin content by 1.
1264/// Passing an out-of-range bin leads to undefined behavior
1265
1267{
1268 AbstractMethod("AddBinContent");
1269}
1270
1271////////////////////////////////////////////////////////////////////////////////
1272/// Increment bin content by a weight w.
1273/// Passing an out-of-range bin leads to undefined behavior
1274
1276{
1277 AbstractMethod("AddBinContent");
1278}
1279
1280////////////////////////////////////////////////////////////////////////////////
1281/// Sets the flag controlling the automatic add of histograms in memory
1282///
1283/// By default (fAddDirectory = kTRUE), histograms are automatically added
1284/// to the list of objects in memory.
1285/// Note that one histogram can be removed from its support directory
1286/// by calling h->SetDirectory(nullptr) or h->SetDirectory(dir) to add it
1287/// to the list of objects in the directory dir.
1288///
1289/// NOTE that this is a static function. To call it, use;
1290/// TH1::AddDirectory
1291
1293{
1294 fgAddDirectory = add;
1295}
1296
1297////////////////////////////////////////////////////////////////////////////////
1298/// Auxiliary function to get the power of 2 next (larger) or previous (smaller)
1299/// a given x
1300///
1301/// next = kTRUE : next larger
1302/// next = kFALSE : previous smaller
1303///
1304/// Used by the autobin power of 2 algorithm
1305
1307{
1308 Int_t nn;
1309 Double_t f2 = std::frexp(x, &nn);
1310 return ((next && x > 0.) || (!next && x <= 0.)) ? std::ldexp(std::copysign(1., f2), nn)
1311 : std::ldexp(std::copysign(1., f2), --nn);
1312}
1313
1314////////////////////////////////////////////////////////////////////////////////
1315/// Auxiliary function to get the next power of 2 integer value larger then n
1316///
1317/// Used by the autobin power of 2 algorithm
1318
1320{
1321 Int_t nn;
1322 Double_t f2 = std::frexp(n, &nn);
1323 if (TMath::Abs(f2 - .5) > 0.001)
1324 return (Int_t)std::ldexp(1., nn);
1325 return n;
1326}
1327
1328////////////////////////////////////////////////////////////////////////////////
1329/// Buffer-based estimate of the histogram range using the power of 2 algorithm.
1330///
1331/// Used by the autobin power of 2 algorithm.
1332///
1333/// Works on arguments (min and max from fBuffer) and internal inputs: fXmin,
1334/// fXmax, NBinsX (from fXaxis), ...
1335/// Result save internally in fXaxis.
1336///
1337/// Overloaded by TH2 and TH3.
1338///
1339/// Return -1 if internal inputs are inconsistent, 0 otherwise.
1340
1342{
1343 // We need meaningful raw limits
1344 if (xmi >= xma)
1345 return -1;
1346
1348 Double_t xhmi = fXaxis.GetXmin();
1349 Double_t xhma = fXaxis.GetXmax();
1350
1351 // Now adjust
1352 if (TMath::Abs(xhma) > TMath::Abs(xhmi)) {
1353 // Start from the upper limit
1354 xhma = TH1::AutoP2GetPower2(xhma);
1355 xhmi = xhma - TH1::AutoP2GetPower2(xhma - xhmi);
1356 } else {
1357 // Start from the lower limit
1358 xhmi = TH1::AutoP2GetPower2(xhmi, kFALSE);
1359 xhma = xhmi + TH1::AutoP2GetPower2(xhma - xhmi);
1360 }
1361
1362 // Round the bins to the next power of 2; take into account the possible inflation
1363 // of the range
1364 Double_t rr = (xhma - xhmi) / (xma - xmi);
1365 Int_t nb = TH1::AutoP2GetBins((Int_t)(rr * GetNbinsX()));
1366
1367 // Adjust using the same bin width and offsets
1368 Double_t bw = (xhma - xhmi) / nb;
1369 // Bins to left free on each side
1370 Double_t autoside = gEnv->GetValue("Hist.Binning.Auto.Side", 0.05);
1371 Int_t nbside = (Int_t)(nb * autoside);
1372
1373 // Side up
1374 Int_t nbup = (xhma - xma) / bw;
1375 if (nbup % 2 != 0)
1376 nbup++; // Must be even
1377 if (nbup != nbside) {
1378 // Accounts also for both case: larger or smaller
1379 xhma -= bw * (nbup - nbside);
1380 nb -= (nbup - nbside);
1381 }
1382
1383 // Side low
1384 Int_t nblw = (xmi - xhmi) / bw;
1385 if (nblw % 2 != 0)
1386 nblw++; // Must be even
1387 if (nblw != nbside) {
1388 // Accounts also for both case: larger or smaller
1389 xhmi += bw * (nblw - nbside);
1390 nb -= (nblw - nbside);
1391 }
1392
1393 // Set everything and project
1394 SetBins(nb, xhmi, xhma);
1395
1396 // Done
1397 return 0;
1398}
1399
1400/// Fill histogram with all entries in the buffer.
1401///
1402/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
1403/// - action = 0 histogram is reset and filled from the buffer. When the histogram is filled from the
1404/// buffer the value fBuffer[0] is set to a negative number (= - number of entries)
1405/// When calling with action == 0 the histogram is NOT refilled when fBuffer[0] is < 0
1406/// While when calling with action = -1 the histogram is reset and ALWAYS refilled independently if
1407/// the histogram was filled before. This is needed when drawing the histogram
1408/// - action = 1 histogram is filled and buffer is deleted
1409/// The buffer is automatically deleted when filling the histogram and the entries is
1410/// larger than the buffer size
1411
1413{
1414 // do we need to compute the bin size?
1415 if (!fBuffer) return 0;
1416 Int_t nbentries = (Int_t)fBuffer[0];
1417
1418 // nbentries correspond to the number of entries of histogram
1419
1420 if (nbentries == 0) {
1421 // if action is 1 we delete the buffer
1422 // this will avoid infinite recursion
1423 if (action > 0) {
1424 delete [] fBuffer;
1425 fBuffer = nullptr;
1426 fBufferSize = 0;
1427 }
1428 return 0;
1429 }
1430 if (nbentries < 0 && action == 0) return 0; // case histogram has been already filled from the buffer
1431
1432 Double_t *buffer = fBuffer;
1433 if (nbentries < 0) {
1434 nbentries = -nbentries;
1435 // a reset might call BufferEmpty() giving an infinite recursion
1436 // Protect it by setting fBuffer = nullptr
1437 fBuffer = nullptr;
1438 //do not reset the list of functions
1439 Reset("ICES");
1440 fBuffer = buffer;
1441 }
1442 if (CanExtendAllAxes() || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
1443 //find min, max of entries in buffer
1446 for (Int_t i=0;i<nbentries;i++) {
1447 Double_t x = fBuffer[2*i+2];
1448 // skip infinity or NaN values
1449 if (!std::isfinite(x)) continue;
1450 if (x < xmin) xmin = x;
1451 if (x > xmax) xmax = x;
1452 }
1453 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
1454 Int_t rc = -1;
1456 if ((rc = AutoP2FindLimits(xmin, xmax)) < 0)
1457 Warning("BufferEmpty",
1458 "inconsistency found by power-of-2 autobin algorithm: fallback to standard method");
1459 }
1460 if (rc < 0)
1462 } else {
1463 fBuffer = nullptr;
1464 Int_t keep = fBufferSize; fBufferSize = 0;
1466 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax, &fXaxis);
1467 fBuffer = buffer;
1468 fBufferSize = keep;
1469 }
1470 }
1471
1472 // call DoFillN which will not put entries in the buffer as FillN does
1473 // set fBuffer to zero to avoid re-emptying the buffer from functions called
1474 // by DoFillN (e.g Sumw2)
1475 buffer = fBuffer; fBuffer = nullptr;
1476 DoFillN(nbentries,&buffer[2],&buffer[1],2);
1477 fBuffer = buffer;
1478
1479 // if action == 1 - delete the buffer
1480 if (action > 0) {
1481 delete [] fBuffer;
1482 fBuffer = nullptr;
1483 fBufferSize = 0;
1484 } else {
1485 // if number of entries is consistent with buffer - set it negative to avoid
1486 // refilling the histogram every time BufferEmpty(0) is called
1487 // In case it is not consistent, by setting fBuffer[0]=0 is like resetting the buffer
1488 // (it will not be used anymore the next time BufferEmpty is called)
1489 if (nbentries == (Int_t)fEntries)
1490 fBuffer[0] = -nbentries;
1491 else
1492 fBuffer[0] = 0;
1493 }
1494 return nbentries;
1495}
1496
1497////////////////////////////////////////////////////////////////////////////////
1498/// accumulate arguments in buffer. When buffer is full, empty the buffer
1499///
1500/// - `fBuffer[0]` = number of entries in buffer
1501/// - `fBuffer[1]` = w of first entry
1502/// - `fBuffer[2]` = x of first entry
1503
1505{
1506 if (!fBuffer) return -2;
1507 Int_t nbentries = (Int_t)fBuffer[0];
1508
1509
1510 if (nbentries < 0) {
1511 // reset nbentries to a positive value so next time BufferEmpty() is called
1512 // the histogram will be refilled
1513 nbentries = -nbentries;
1514 fBuffer[0] = nbentries;
1515 if (fEntries > 0) {
1516 // set fBuffer to zero to avoid calling BufferEmpty in Reset
1517 Double_t *buffer = fBuffer; fBuffer=nullptr;
1518 Reset("ICES"); // do not reset list of functions
1519 fBuffer = buffer;
1520 }
1521 }
1522 if (2*nbentries+2 >= fBufferSize) {
1523 BufferEmpty(1);
1524 if (!fBuffer)
1525 // to avoid infinite recursion Fill->BufferFill->Fill
1526 return Fill(x,w);
1527 // this cannot happen
1528 R__ASSERT(0);
1529 }
1530 fBuffer[2*nbentries+1] = w;
1531 fBuffer[2*nbentries+2] = x;
1532 fBuffer[0] += 1;
1533 return -2;
1534}
1535
1536////////////////////////////////////////////////////////////////////////////////
1537/// Check bin limits.
1538
1539bool TH1::CheckBinLimits(const TAxis* a1, const TAxis * a2)
1540{
1541 const TArrayD * h1Array = a1->GetXbins();
1542 const TArrayD * h2Array = a2->GetXbins();
1543 Int_t fN = h1Array->fN;
1544 if ( fN != 0 ) {
1545 if ( h2Array->fN != fN ) {
1546 return false;
1547 }
1548 else {
1549 for ( int i = 0; i < fN; ++i ) {
1550 // for i==fN (nbin+1) a->GetBinWidth() returns last bin width
1551 // we do not need to exclude that case
1552 double binWidth = a1->GetBinWidth(i);
1553 if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), binWidth*1E-10 ) ) {
1554 return false;
1555 }
1556 }
1557 }
1558 }
1559
1560 return true;
1561}
1562
1563////////////////////////////////////////////////////////////////////////////////
1564/// Check that axis have same labels.
1565
1566bool TH1::CheckBinLabels(const TAxis* a1, const TAxis * a2)
1567{
1568 THashList *l1 = a1->GetLabels();
1569 THashList *l2 = a2->GetLabels();
1570
1571 if (!l1 && !l2 )
1572 return true;
1573 if (!l1 || !l2 ) {
1574 return false;
1575 }
1576 // check now labels sizes are the same
1577 if (l1->GetSize() != l2->GetSize() ) {
1578 return false;
1579 }
1580 for (int i = 1; i <= a1->GetNbins(); ++i) {
1581 TString label1 = a1->GetBinLabel(i);
1582 TString label2 = a2->GetBinLabel(i);
1583 if (label1 != label2) {
1584 return false;
1585 }
1586 }
1587
1588 return true;
1589}
1590
1591////////////////////////////////////////////////////////////////////////////////
1592/// Check that the axis limits of the histograms are the same.
1593/// If a first and last bin is passed the axis is compared between the given range
1594
1595bool TH1::CheckAxisLimits(const TAxis *a1, const TAxis *a2 )
1596{
1597 double firstBin = a1->GetBinWidth(1);
1598 double lastBin = a1->GetBinWidth( a1->GetNbins() );
1599 if ( ! TMath::AreEqualAbs(a1->GetXmin(), a2->GetXmin(), firstBin* 1.E-10) ||
1600 ! TMath::AreEqualAbs(a1->GetXmax(), a2->GetXmax(), lastBin*1.E-10) ) {
1601 return false;
1602 }
1603 return true;
1604}
1605
1606////////////////////////////////////////////////////////////////////////////////
1607/// Check that the axis are the same
1608
1609bool TH1::CheckEqualAxes(const TAxis *a1, const TAxis *a2 )
1610{
1611 if (a1->GetNbins() != a2->GetNbins() ) {
1612 ::Info("CheckEqualAxes","Axes have different number of bins : nbin1 = %d nbin2 = %d",a1->GetNbins(),a2->GetNbins() );
1613 return false;
1614 }
1615 if(!CheckAxisLimits(a1,a2)) {
1616 ::Info("CheckEqualAxes","Axes have different limits");
1617 return false;
1618 }
1619 if(!CheckBinLimits(a1,a2)) {
1620 ::Info("CheckEqualAxes","Axes have different bin limits");
1621 return false;
1622 }
1623
1624 // check labels
1625 if(!CheckBinLabels(a1,a2)) {
1626 ::Info("CheckEqualAxes","Axes have different labels");
1627 return false;
1628 }
1629
1630 return true;
1631}
1632
1633////////////////////////////////////////////////////////////////////////////////
1634/// Check that two sub axis are the same.
1635/// The limits are defined by first bin and last bin
1636/// N.B. no check is done in this case for variable bins
1637
1638bool TH1::CheckConsistentSubAxes(const TAxis *a1, Int_t firstBin1, Int_t lastBin1, const TAxis * a2, Int_t firstBin2, Int_t lastBin2 )
1639{
1640 // By default is assumed that no bins are given for the second axis
1641 Int_t nbins1 = lastBin1-firstBin1 + 1;
1642 Double_t xmin1 = a1->GetBinLowEdge(firstBin1);
1643 Double_t xmax1 = a1->GetBinUpEdge(lastBin1);
1644
1645 Int_t nbins2 = a2->GetNbins();
1646 Double_t xmin2 = a2->GetXmin();
1647 Double_t xmax2 = a2->GetXmax();
1648
1649 if (firstBin2 < lastBin2) {
1650 // in this case assume no bins are given for the second axis
1651 nbins2 = lastBin1-firstBin1 + 1;
1652 xmin2 = a1->GetBinLowEdge(firstBin1);
1653 xmax2 = a1->GetBinUpEdge(lastBin1);
1654 }
1655
1656 if (nbins1 != nbins2 ) {
1657 ::Info("CheckConsistentSubAxes","Axes have different number of bins");
1658 return false;
1659 }
1660
1661 Double_t firstBin = a1->GetBinWidth(firstBin1);
1662 Double_t lastBin = a1->GetBinWidth(lastBin1);
1663 if ( ! TMath::AreEqualAbs(xmin1,xmin2,1.E-10 * firstBin) ||
1664 ! TMath::AreEqualAbs(xmax1,xmax2,1.E-10 * lastBin) ) {
1665 ::Info("CheckConsistentSubAxes","Axes have different limits");
1666 return false;
1667 }
1668
1669 return true;
1670}
1671
1672////////////////////////////////////////////////////////////////////////////////
1673/// Check histogram compatibility.
1674
1675int TH1::CheckConsistency(const TH1* h1, const TH1* h2)
1676{
1677 if (h1 == h2) return kFullyConsistent;
1678
1679 if (h1->GetDimension() != h2->GetDimension() ) {
1680 return kDifferentDimensions;
1681 }
1682 Int_t dim = h1->GetDimension();
1683
1684 // returns kTRUE if number of bins and bin limits are identical
1685 Int_t nbinsx = h1->GetNbinsX();
1686 Int_t nbinsy = h1->GetNbinsY();
1687 Int_t nbinsz = h1->GetNbinsZ();
1688
1689 // Check whether the histograms have the same number of bins.
1690 if (nbinsx != h2->GetNbinsX() ||
1691 (dim > 1 && nbinsy != h2->GetNbinsY()) ||
1692 (dim > 2 && nbinsz != h2->GetNbinsZ()) ) {
1693 return kDifferentNumberOfBins;
1694 }
1695
1696 bool ret = true;
1697
1698 // check axis limits
1699 ret &= CheckAxisLimits(h1->GetXaxis(), h2->GetXaxis());
1700 if (dim > 1) ret &= CheckAxisLimits(h1->GetYaxis(), h2->GetYaxis());
1701 if (dim > 2) ret &= CheckAxisLimits(h1->GetZaxis(), h2->GetZaxis());
1702 if (!ret) return kDifferentAxisLimits;
1703
1704 // check bin limits
1705 ret &= CheckBinLimits(h1->GetXaxis(), h2->GetXaxis());
1706 if (dim > 1) ret &= CheckBinLimits(h1->GetYaxis(), h2->GetYaxis());
1707 if (dim > 2) ret &= CheckBinLimits(h1->GetZaxis(), h2->GetZaxis());
1708 if (!ret) return kDifferentBinLimits;
1709
1710 // check labels if histograms are both not empty
1711 if ( !h1->IsEmpty() && !h2->IsEmpty() ) {
1712 ret &= CheckBinLabels(h1->GetXaxis(), h2->GetXaxis());
1713 if (dim > 1) ret &= CheckBinLabels(h1->GetYaxis(), h2->GetYaxis());
1714 if (dim > 2) ret &= CheckBinLabels(h1->GetZaxis(), h2->GetZaxis());
1715 if (!ret) return kDifferentLabels;
1716 }
1717
1718 return kFullyConsistent;
1719}
1720
1721////////////////////////////////////////////////////////////////////////////////
1722/// \f$ \chi^{2} \f$ test for comparing weighted and unweighted histograms.
1723///
1724/// Compares the histograms' adjusted (normalized) residuals.
1725/// Function: Returns p-value. Other return values are specified by the 3rd parameter
1726///
1727/// \param[in] h2 the second histogram
1728/// \param[in] option
1729/// - "UU" = experiment experiment comparison (unweighted-unweighted)
1730/// - "UW" = experiment MC comparison (unweighted-weighted). Note that
1731/// the first histogram should be unweighted
1732/// - "WW" = MC MC comparison (weighted-weighted)
1733/// - "NORM" = to be used when one or both of the histograms is scaled
1734/// but the histogram originally was unweighted
1735/// - by default underflows and overflows are not included:
1736/// * "OF" = overflows included
1737/// * "UF" = underflows included
1738/// - "P" = print chi2, ndf, p_value, igood
1739/// - "CHI2" = returns chi2 instead of p-value
1740/// - "CHI2/NDF" = returns \f$ \chi^{2} \f$/ndf
1741/// \param[in] res not empty - computes normalized residuals and returns them in this array
1742///
1743/// The current implementation is based on the papers \f$ \chi^{2} \f$ test for comparison
1744/// of weighted and unweighted histograms" in Proceedings of PHYSTAT05 and
1745/// "Comparison weighted and unweighted histograms", arXiv:physics/0605123
1746/// by N.Gagunashvili. This function has been implemented by Daniel Haertl in August 2006.
1747///
1748/// #### Introduction:
1749///
1750/// A frequently used technique in data analysis is the comparison of
1751/// histograms. First suggested by Pearson [1] the \f$ \chi^{2} \f$ test of
1752/// homogeneity is used widely for comparing usual (unweighted) histograms.
1753/// This paper describes the implementation modified \f$ \chi^{2} \f$ tests
1754/// for comparison of weighted and unweighted histograms and two weighted
1755/// histograms [2] as well as usual Pearson's \f$ \chi^{2} \f$ test for
1756/// comparison two usual (unweighted) histograms.
1757///
1758/// #### Overview:
1759///
1760/// Comparison of two histograms expect hypotheses that two histograms
1761/// represent identical distributions. To make a decision p-value should
1762/// be calculated. The hypotheses of identity is rejected if the p-value is
1763/// lower then some significance level. Traditionally significance levels
1764/// 0.1, 0.05 and 0.01 are used. The comparison procedure should include an
1765/// analysis of the residuals which is often helpful in identifying the
1766/// bins of histograms responsible for a significant overall \f$ \chi^{2} \f$ value.
1767/// Residuals are the difference between bin contents and expected bin
1768/// contents. Most convenient for analysis are the normalized residuals. If
1769/// hypotheses of identity are valid then normalized residuals are
1770/// approximately independent and identically distributed random variables
1771/// having N(0,1) distribution. Analysis of residuals expect test of above
1772/// mentioned properties of residuals. Notice that indirectly the analysis
1773/// of residuals increase the power of \f$ \chi^{2} \f$ test.
1774///
1775/// #### Methods of comparison:
1776///
1777/// \f$ \chi^{2} \f$ test for comparison two (unweighted) histograms:
1778/// Let us consider two histograms with the same binning and the number
1779/// of bins equal to r. Let us denote the number of events in the ith bin
1780/// in the first histogram as ni and as mi in the second one. The total
1781/// number of events in the first histogram is equal to:
1782/// \f[
1783/// N = \sum_{i=1}^{r} n_{i}
1784/// \f]
1785/// and
1786/// \f[
1787/// M = \sum_{i=1}^{r} m_{i}
1788/// \f]
1789/// in the second histogram. The hypothesis of identity (homogeneity) [3]
1790/// is that the two histograms represent random values with identical
1791/// distributions. It is equivalent that there exist r constants p1,...,pr,
1792/// such that
1793/// \f[
1794///\sum_{i=1}^{r} p_{i}=1
1795/// \f]
1796/// and the probability of belonging to the ith bin for some measured value
1797/// in both experiments is equal to pi. The number of events in the ith
1798/// bin is a random variable with a distribution approximated by a Poisson
1799/// probability distribution
1800/// \f[
1801///\frac{e^{-Np_{i}}(Np_{i})^{n_{i}}}{n_{i}!}
1802/// \f]
1803///for the first histogram and with distribution
1804/// \f[
1805///\frac{e^{-Mp_{i}}(Mp_{i})^{m_{i}}}{m_{i}!}
1806/// \f]
1807/// for the second histogram. If the hypothesis of homogeneity is valid,
1808/// then the maximum likelihood estimator of pi, i=1,...,r, is
1809/// \f[
1810///\hat{p}_{i}= \frac{n_{i}+m_{i}}{N+M}
1811/// \f]
1812/// and then
1813/// \f[
1814/// 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}}
1815/// \f]
1816/// has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [3].
1817/// The comparison procedure can include an analysis of the residuals which
1818/// is often helpful in identifying the bins of histograms responsible for
1819/// a significant overall \f$ \chi^{2} \f$ value. Most convenient for
1820/// analysis are the adjusted (normalized) residuals [4]
1821/// \f[
1822/// 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))}}
1823/// \f]
1824/// If hypotheses of homogeneity are valid then residuals ri are
1825/// approximately independent and identically distributed random variables
1826/// having N(0,1) distribution. The application of the \f$ \chi^{2} \f$ test has
1827/// restrictions related to the value of the expected frequencies Npi,
1828/// Mpi, i=1,...,r. A conservative rule formulated in [5] is that all the
1829/// expectations must be 1 or greater for both histograms. In practical
1830/// cases when expected frequencies are not known the estimated expected
1831/// frequencies \f$ M\hat{p}_{i}, N\hat{p}_{i}, i=1,...,r \f$ can be used.
1832///
1833/// #### Unweighted and weighted histograms comparison:
1834///
1835/// A simple modification of the ideas described above can be used for the
1836/// comparison of the usual (unweighted) and weighted histograms. Let us
1837/// denote the number of events in the ith bin in the unweighted
1838/// histogram as ni and the common weight of events in the ith bin of the
1839/// weighted histogram as wi. The total number of events in the
1840/// unweighted histogram is equal to
1841///\f[
1842/// N = \sum_{i=1}^{r} n_{i}
1843///\f]
1844/// and the total weight of events in the weighted histogram is equal to
1845///\f[
1846/// W = \sum_{i=1}^{r} w_{i}
1847///\f]
1848/// Let us formulate the hypothesis of identity of an unweighted histogram
1849/// to a weighted histogram so that there exist r constants p1,...,pr, such
1850/// that
1851///\f[
1852/// \sum_{i=1}^{r} p_{i} = 1
1853///\f]
1854/// for the unweighted histogram. The weight wi is a random variable with a
1855/// distribution approximated by the normal probability distribution
1856/// \f$ N(Wp_{i},\sigma_{i}^{2}) \f$ where \f$ \sigma_{i}^{2} \f$ is the variance of the weight wi.
1857/// If we replace the variance \f$ \sigma_{i}^{2} \f$
1858/// with estimate \f$ s_{i}^{2} \f$ (sum of squares of weights of
1859/// events in the ith bin) and the hypothesis of identity is valid, then the
1860/// maximum likelihood estimator of pi,i=1,...,r, is
1861///\f[
1862/// \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}}
1863///\f]
1864/// We may then use the test statistic
1865///\f[
1866/// 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}}
1867///\f]
1868/// and it has approximately a \f$ \sigma^{2}_{(r-1)} \f$ distribution [2]. This test, as well
1869/// as the original one [3], has a restriction on the expected frequencies. The
1870/// expected frequencies recommended for the weighted histogram is more than 25.
1871/// The value of the minimal expected frequency can be decreased down to 10 for
1872/// the case when the weights of the events are close to constant. In the case
1873/// of a weighted histogram if the number of events is unknown, then we can
1874/// apply this recommendation for the equivalent number of events as
1875///\f[
1876/// n_{i}^{equiv} = \frac{ w_{i}^{2} }{ s_{i}^{2} }
1877///\f]
1878/// The minimal expected frequency for an unweighted histogram must be 1. Notice
1879/// that any usual (unweighted) histogram can be considered as a weighted
1880/// histogram with events that have constant weights equal to 1.
1881/// The variance \f$ z_{i}^{2} \f$ of the difference between the weight wi
1882/// and the estimated expectation value of the weight is approximately equal to:
1883///\f[
1884/// 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}
1885///\f]
1886/// The residuals
1887///\f[
1888/// r_{i} = \frac{w_{i}-W\hat{p}_{i}}{z_{i}}
1889///\f]
1890/// have approximately a normal distribution with mean equal to 0 and standard
1891/// deviation equal to 1.
1892///
1893/// #### Two weighted histograms comparison:
1894///
1895/// Let us denote the common weight of events of the ith bin in the first
1896/// histogram as w1i and as w2i in the second one. The total weight of events
1897/// in the first histogram is equal to
1898///\f[
1899/// W_{1} = \sum_{i=1}^{r} w_{1i}
1900///\f]
1901/// and
1902///\f[
1903/// W_{2} = \sum_{i=1}^{r} w_{2i}
1904///\f]
1905/// in the second histogram. Let us formulate the hypothesis of identity of
1906/// weighted histograms so that there exist r constants p1,...,pr, such that
1907///\f[
1908/// \sum_{i=1}^{r} p_{i} = 1
1909///\f]
1910/// and also expectation value of weight w1i equal to W1pi and expectation value
1911/// of weight w2i equal to W2pi. Weights in both the histograms are random
1912/// variables with distributions which can be approximated by a normal
1913/// probability distribution \f$ N(W_{1}p_{i},\sigma_{1i}^{2}) \f$ for the first histogram
1914/// and by a distribution \f$ N(W_{2}p_{i},\sigma_{2i}^{2}) \f$ for the second.
1915/// Here \f$ \sigma_{1i}^{2} \f$ and \f$ \sigma_{2i}^{2} \f$ are the variances
1916/// of w1i and w2i with estimators \f$ s_{1i}^{2} \f$ and \f$ s_{2i}^{2} \f$ respectively.
1917/// If the hypothesis of identity is valid, then the maximum likelihood and
1918/// Least Square Method estimator of pi,i=1,...,r, is
1919///\f[
1920/// \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}}
1921///\f]
1922/// We may then use the test statistic
1923///\f[
1924/// 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}}
1925///\f]
1926/// and it has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [2].
1927/// The normalized or studentised residuals [6]
1928///\f[
1929/// 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})}}}
1930///\f]
1931/// have approximately a normal distribution with mean equal to 0 and standard
1932/// deviation 1. A recommended minimal expected frequency is equal to 10 for
1933/// the proposed test.
1934///
1935/// #### Numerical examples:
1936///
1937/// The method described herein is now illustrated with an example.
1938/// We take a distribution
1939///\f[
1940/// \phi(x) = \frac{2}{(x-10)^{2}+1} + \frac{1}{(x-14)^{2}+1} (1)
1941///\f]
1942/// defined on the interval [4,16]. Events distributed according to the formula
1943/// (1) are simulated to create the unweighted histogram. Uniformly distributed
1944/// events are simulated for the weighted histogram with weights calculated by
1945/// formula (1). Each histogram has the same number of bins: 20. Fig.1 shows
1946/// the result of comparison of the unweighted histogram with 200 events
1947/// (minimal expected frequency equal to one) and the weighted histogram with
1948/// 500 events (minimal expected frequency equal to 25)
1949/// Begin_Macro
1950/// ../../../tutorials/math/chi2test.C
1951/// End_Macro
1952/// Fig 1. An example of comparison of the unweighted histogram with 200 events
1953/// and the weighted histogram with 500 events:
1954/// 1. unweighted histogram;
1955/// 2. weighted histogram;
1956/// 3. normalized residuals plot;
1957/// 4. normal Q-Q plot of residuals.
1958///
1959/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1960/// 21.09 with p-value equal to 0.33, therefore the hypothesis of identity of
1961/// the two histograms can be accepted for 0.05 significant level. The behavior
1962/// of the normalized residuals plot (see Fig. 1c) and the normal Q-Q plot
1963/// (see Fig. 1d) of residuals are regular and we cannot identify the outliers
1964/// or bins with a big influence on \f$ \chi^{2} \f$.
1965///
1966/// The second example presents the same two histograms but 17 events was added
1967/// to content of bin number 15 in unweighted histogram. Fig.2 shows the result
1968/// of comparison of the unweighted histogram with 217 events (minimal expected
1969/// frequency equal to one) and the weighted histogram with 500 events (minimal
1970/// expected frequency equal to 25)
1971/// Begin_Macro
1972/// ../../../tutorials/math/chi2test.C(17)
1973/// End_Macro
1974/// Fig 2. An example of comparison of the unweighted histogram with 217 events
1975/// and the weighted histogram with 500 events:
1976/// 1. unweighted histogram;
1977/// 2. weighted histogram;
1978/// 3. normalized residuals plot;
1979/// 4. normal Q-Q plot of residuals.
1980///
1981/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1982/// 32.33 with p-value equal to 0.029, therefore the hypothesis of identity of
1983/// the two histograms is rejected for 0.05 significant level. The behavior of
1984/// the normalized residuals plot (see Fig. 2c) and the normal Q-Q plot (see
1985/// Fig. 2d) of residuals are not regular and we can identify the outlier or
1986/// bin with a big influence on \f$ \chi^{2} \f$.
1987///
1988/// #### References:
1989///
1990/// - [1] Pearson, K., 1904. On the Theory of Contingency and Its Relation to
1991/// Association and Normal Correlation. Drapers' Co. Memoirs, Biometric
1992/// Series No. 1, London.
1993/// - [2] Gagunashvili, N., 2006. \f$ \sigma^{2} \f$ test for comparison
1994/// of weighted and unweighted histograms. Statistical Problems in Particle
1995/// Physics, Astrophysics and Cosmology, Proceedings of PHYSTAT05,
1996/// Oxford, UK, 12-15 September 2005, Imperial College Press, London, 43-44.
1997/// Gagunashvili,N., Comparison of weighted and unweighted histograms,
1998/// arXiv:physics/0605123, 2006.
1999/// - [3] Cramer, H., 1946. Mathematical methods of statistics.
2000/// Princeton University Press, Princeton.
2001/// - [4] Haberman, S.J., 1973. The analysis of residuals in cross-classified tables.
2002/// Biometrics 29, 205-220.
2003/// - [5] Lewontin, R.C. and Felsenstein, J., 1965. The robustness of homogeneity
2004/// test in 2xN tables. Biometrics 21, 19-33.
2005/// - [6] Seber, G.A.F., Lee, A.J., 2003, Linear Regression Analysis.
2006/// John Wiley & Sons Inc., New York.
2007
2008Double_t TH1::Chi2Test(const TH1* h2, Option_t *option, Double_t *res) const
2009{
2010 Double_t chi2 = 0;
2011 Int_t ndf = 0, igood = 0;
2012
2013 TString opt = option;
2014 opt.ToUpper();
2015
2016 Double_t prob = Chi2TestX(h2,chi2,ndf,igood,option,res);
2017
2018 if(opt.Contains("P")) {
2019 printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
2020 }
2021 if(opt.Contains("CHI2/NDF")) {
2022 if (ndf == 0) return 0;
2023 return chi2/ndf;
2024 }
2025 if(opt.Contains("CHI2")) {
2026 return chi2;
2027 }
2028
2029 return prob;
2030}
2031
2032////////////////////////////////////////////////////////////////////////////////
2033/// The computation routine of the Chisquare test. For the method description,
2034/// see Chi2Test() function.
2035///
2036/// \return p-value
2037/// \param[in] h2 the second histogram
2038/// \param[in] option
2039/// - "UU" = experiment experiment comparison (unweighted-unweighted)
2040/// - "UW" = experiment MC comparison (unweighted-weighted). Note that the first
2041/// histogram should be unweighted
2042/// - "WW" = MC MC comparison (weighted-weighted)
2043/// - "NORM" = if one or both histograms is scaled
2044/// - "OF" = overflows included
2045/// - "UF" = underflows included
2046/// by default underflows and overflows are not included
2047/// \param[out] igood test output
2048/// - igood=0 - no problems
2049/// - For unweighted unweighted comparison
2050/// - igood=1'There is a bin in the 1st histogram with less than 1 event'
2051/// - igood=2'There is a bin in the 2nd histogram with less than 1 event'
2052/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2053/// - For unweighted weighted comparison
2054/// - igood=1'There is a bin in the 1st histogram with less then 1 event'
2055/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective number of events'
2056/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2057/// - For weighted weighted comparison
2058/// - igood=1'There is a bin in the 1st histogram with less then 10 effective
2059/// number of events'
2060/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective
2061/// number of events'
2062/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2063/// \param[out] chi2 chisquare of the test
2064/// \param[out] ndf number of degrees of freedom (important, when both histograms have the same empty bins)
2065/// \param[out] res normalized residuals for further analysis
2066
2067Double_t TH1::Chi2TestX(const TH1* h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option, Double_t *res) const
2068{
2069
2070 Int_t i_start, i_end;
2071 Int_t j_start, j_end;
2072 Int_t k_start, k_end;
2073
2074 Double_t sum1 = 0.0, sumw1 = 0.0;
2075 Double_t sum2 = 0.0, sumw2 = 0.0;
2076
2077 chi2 = 0.0;
2078 ndf = 0;
2079
2080 TString opt = option;
2081 opt.ToUpper();
2082
2083 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
2084
2085 const TAxis *xaxis1 = GetXaxis();
2086 const TAxis *xaxis2 = h2->GetXaxis();
2087 const TAxis *yaxis1 = GetYaxis();
2088 const TAxis *yaxis2 = h2->GetYaxis();
2089 const TAxis *zaxis1 = GetZaxis();
2090 const TAxis *zaxis2 = h2->GetZaxis();
2091
2092 Int_t nbinx1 = xaxis1->GetNbins();
2093 Int_t nbinx2 = xaxis2->GetNbins();
2094 Int_t nbiny1 = yaxis1->GetNbins();
2095 Int_t nbiny2 = yaxis2->GetNbins();
2096 Int_t nbinz1 = zaxis1->GetNbins();
2097 Int_t nbinz2 = zaxis2->GetNbins();
2098
2099 //check dimensions
2100 if (this->GetDimension() != h2->GetDimension() ){
2101 Error("Chi2TestX","Histograms have different dimensions.");
2102 return 0.0;
2103 }
2104
2105 //check number of channels
2106 if (nbinx1 != nbinx2) {
2107 Error("Chi2TestX","different number of x channels");
2108 }
2109 if (nbiny1 != nbiny2) {
2110 Error("Chi2TestX","different number of y channels");
2111 }
2112 if (nbinz1 != nbinz2) {
2113 Error("Chi2TestX","different number of z channels");
2114 }
2115
2116 //check for ranges
2117 i_start = j_start = k_start = 1;
2118 i_end = nbinx1;
2119 j_end = nbiny1;
2120 k_end = nbinz1;
2121
2122 if (xaxis1->TestBit(TAxis::kAxisRange)) {
2123 i_start = xaxis1->GetFirst();
2124 i_end = xaxis1->GetLast();
2125 }
2126 if (yaxis1->TestBit(TAxis::kAxisRange)) {
2127 j_start = yaxis1->GetFirst();
2128 j_end = yaxis1->GetLast();
2129 }
2130 if (zaxis1->TestBit(TAxis::kAxisRange)) {
2131 k_start = zaxis1->GetFirst();
2132 k_end = zaxis1->GetLast();
2133 }
2134
2135
2136 if (opt.Contains("OF")) {
2137 if (GetDimension() == 3) k_end = ++nbinz1;
2138 if (GetDimension() >= 2) j_end = ++nbiny1;
2139 if (GetDimension() >= 1) i_end = ++nbinx1;
2140 }
2141
2142 if (opt.Contains("UF")) {
2143 if (GetDimension() == 3) k_start = 0;
2144 if (GetDimension() >= 2) j_start = 0;
2145 if (GetDimension() >= 1) i_start = 0;
2146 }
2147
2148 ndf = (i_end - i_start + 1) * (j_end - j_start + 1) * (k_end - k_start + 1) - 1;
2149
2150 Bool_t comparisonUU = opt.Contains("UU");
2151 Bool_t comparisonUW = opt.Contains("UW");
2152 Bool_t comparisonWW = opt.Contains("WW");
2153 Bool_t scaledHistogram = opt.Contains("NORM");
2154
2155 if (scaledHistogram && !comparisonUU) {
2156 Info("Chi2TestX", "NORM option should be used together with UU option. It is ignored");
2157 }
2158
2159 // look at histo global bin content and effective entries
2160 Stat_t s[kNstat];
2161 GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2162 Double_t sumBinContent1 = s[0];
2163 Double_t effEntries1 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2164
2165 h2->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2166 Double_t sumBinContent2 = s[0];
2167 Double_t effEntries2 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2168
2169 if (!comparisonUU && !comparisonUW && !comparisonWW ) {
2170 // deduce automatically from type of histogram
2171 if (TMath::Abs(sumBinContent1 - effEntries1) < 1) {
2172 if ( TMath::Abs(sumBinContent2 - effEntries2) < 1) comparisonUU = true;
2173 else comparisonUW = true;
2174 }
2175 else comparisonWW = true;
2176 }
2177 // check unweighted histogram
2178 if (comparisonUW) {
2179 if (TMath::Abs(sumBinContent1 - effEntries1) >= 1) {
2180 Warning("Chi2TestX","First histogram is not unweighted and option UW has been requested");
2181 }
2182 }
2183 if ( (!scaledHistogram && comparisonUU) ) {
2184 if ( ( TMath::Abs(sumBinContent1 - effEntries1) >= 1) || (TMath::Abs(sumBinContent2 - effEntries2) >= 1) ) {
2185 Warning("Chi2TestX","Both histograms are not unweighted and option UU has been requested");
2186 }
2187 }
2188
2189
2190 //get number of events in histogram
2191 if (comparisonUU && scaledHistogram) {
2192 for (Int_t i = i_start; i <= i_end; ++i) {
2193 for (Int_t j = j_start; j <= j_end; ++j) {
2194 for (Int_t k = k_start; k <= k_end; ++k) {
2195
2196 Int_t bin = GetBin(i, j, k);
2197
2198 Double_t cnt1 = RetrieveBinContent(bin);
2199 Double_t cnt2 = h2->RetrieveBinContent(bin);
2200 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2201 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2202
2203 if (e1sq > 0.0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2204 else cnt1 = 0.0;
2205
2206 if (e2sq > 0.0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2207 else cnt2 = 0.0;
2208
2209 // sum contents
2210 sum1 += cnt1;
2211 sum2 += cnt2;
2212 sumw1 += e1sq;
2213 sumw2 += e2sq;
2214 }
2215 }
2216 }
2217 if (sumw1 <= 0.0 || sumw2 <= 0.0) {
2218 Error("Chi2TestX", "Cannot use option NORM when one histogram has all zero errors");
2219 return 0.0;
2220 }
2221
2222 } else {
2223 for (Int_t i = i_start; i <= i_end; ++i) {
2224 for (Int_t j = j_start; j <= j_end; ++j) {
2225 for (Int_t k = k_start; k <= k_end; ++k) {
2226
2227 Int_t bin = GetBin(i, j, k);
2228
2229 sum1 += RetrieveBinContent(bin);
2230 sum2 += h2->RetrieveBinContent(bin);
2231
2232 if ( comparisonWW ) sumw1 += GetBinErrorSqUnchecked(bin);
2233 if ( comparisonUW || comparisonWW ) sumw2 += h2->GetBinErrorSqUnchecked(bin);
2234 }
2235 }
2236 }
2237 }
2238 //checks that the histograms are not empty
2239 if (sum1 == 0.0 || sum2 == 0.0) {
2240 Error("Chi2TestX","one histogram is empty");
2241 return 0.0;
2242 }
2243
2244 if ( comparisonWW && ( sumw1 <= 0.0 && sumw2 <= 0.0 ) ){
2245 Error("Chi2TestX","Hist1 and Hist2 have both all zero errors\n");
2246 return 0.0;
2247 }
2248
2249 //THE TEST
2250 Int_t m = 0, n = 0;
2251
2252 //Experiment - experiment comparison
2253 if (comparisonUU) {
2254 Double_t sum = sum1 + sum2;
2255 for (Int_t i = i_start; i <= i_end; ++i) {
2256 for (Int_t j = j_start; j <= j_end; ++j) {
2257 for (Int_t k = k_start; k <= k_end; ++k) {
2258
2259 Int_t bin = GetBin(i, j, k);
2260
2261 Double_t cnt1 = RetrieveBinContent(bin);
2262 Double_t cnt2 = h2->RetrieveBinContent(bin);
2263
2264 if (scaledHistogram) {
2265 // scale bin value to effective bin entries
2266 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2267 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2268
2269 if (e1sq > 0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2270 else cnt1 = 0;
2271
2272 if (e2sq > 0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2273 else cnt2 = 0;
2274 }
2275
2276 if (Int_t(cnt1) == 0 && Int_t(cnt2) == 0) --ndf; // no data means one degree of freedom less
2277 else {
2278
2279 Double_t cntsum = cnt1 + cnt2;
2280 Double_t nexp1 = cntsum * sum1 / sum;
2281 //Double_t nexp2 = binsum*sum2/sum;
2282
2283 if (res) res[i - i_start] = (cnt1 - nexp1) / TMath::Sqrt(nexp1);
2284
2285 if (cnt1 < 1) ++m;
2286 if (cnt2 < 1) ++n;
2287
2288 //Habermann correction for residuals
2289 Double_t correc = (1. - sum1 / sum) * (1. - cntsum / sum);
2290 if (res) res[i - i_start] /= TMath::Sqrt(correc);
2291
2292 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2293 chi2 += delta * delta / cntsum;
2294 }
2295 }
2296 }
2297 }
2298 chi2 /= sum1 * sum2;
2299
2300 // flag error only when of the two histogram is zero
2301 if (m) {
2302 igood += 1;
2303 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2304 }
2305 if (n) {
2306 igood += 2;
2307 Info("Chi2TestX","There is a bin in h2 with less than 1 event.\n");
2308 }
2309
2310 Double_t prob = TMath::Prob(chi2,ndf);
2311 return prob;
2312
2313 }
2314
2315 // unweighted - weighted comparison
2316 // case of error = 0 and content not zero is treated without problems by excluding second chi2 sum
2317 // and can be considered as a data-theory comparison
2318 if ( comparisonUW ) {
2319 for (Int_t i = i_start; i <= i_end; ++i) {
2320 for (Int_t j = j_start; j <= j_end; ++j) {
2321 for (Int_t k = k_start; k <= k_end; ++k) {
2322
2323 Int_t bin = GetBin(i, j, k);
2324
2325 Double_t cnt1 = RetrieveBinContent(bin);
2326 Double_t cnt2 = h2->RetrieveBinContent(bin);
2327 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2328
2329 // case both histogram have zero bin contents
2330 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2331 --ndf; //no data means one degree of freedom less
2332 continue;
2333 }
2334
2335 // case weighted histogram has zero bin content and error
2336 if (cnt2 * cnt2 == 0 && e2sq == 0) {
2337 if (sumw2 > 0) {
2338 // use as approximated error as 1 scaled by a scaling ratio
2339 // estimated from the total sum weight and sum weight squared
2340 e2sq = sumw2 / sum2;
2341 }
2342 else {
2343 // return error because infinite discrepancy here:
2344 // bin1 != 0 and bin2 =0 in a histogram with all errors zero
2345 Error("Chi2TestX","Hist2 has in bin (%d,%d,%d) zero content and zero errors\n", i, j, k);
2346 chi2 = 0; return 0;
2347 }
2348 }
2349
2350 if (cnt1 < 1) m++;
2351 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2352
2353 Double_t var1 = sum2 * cnt2 - sum1 * e2sq;
2354 Double_t var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2355
2356 // if cnt1 is zero and cnt2 = 1 and sum1 = sum2 var1 = 0 && var2 == 0
2357 // approximate by incrementing cnt1
2358 // LM (this need to be fixed for numerical errors)
2359 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2360 sum1++;
2361 cnt1++;
2362 var1 = sum2 * cnt2 - sum1 * e2sq;
2363 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2364 }
2365 var2 = TMath::Sqrt(var2);
2366
2367 while (var1 + var2 == 0) {
2368 sum1++;
2369 cnt1++;
2370 var1 = sum2 * cnt2 - sum1 * e2sq;
2371 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2372 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2373 sum1++;
2374 cnt1++;
2375 var1 = sum2 * cnt2 - sum1 * e2sq;
2376 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2377 }
2378 var2 = TMath::Sqrt(var2);
2379 }
2380
2381 Double_t probb = (var1 + var2) / (2. * sum2 * sum2);
2382
2383 Double_t nexp1 = probb * sum1;
2384 Double_t nexp2 = probb * sum2;
2385
2386 Double_t delta1 = cnt1 - nexp1;
2387 Double_t delta2 = cnt2 - nexp2;
2388
2389 chi2 += delta1 * delta1 / nexp1;
2390
2391 if (e2sq > 0) {
2392 chi2 += delta2 * delta2 / e2sq;
2393 }
2394
2395 if (res) {
2396 if (e2sq > 0) {
2397 Double_t temp1 = sum2 * e2sq / var2;
2398 Double_t temp2 = 1.0 + (sum1 * e2sq - sum2 * cnt2) / var2;
2399 temp2 = temp1 * temp1 * sum1 * probb * (1.0 - probb) + temp2 * temp2 * e2sq / 4.0;
2400 // invert sign here
2401 res[i - i_start] = - delta2 / TMath::Sqrt(temp2);
2402 }
2403 else
2404 res[i - i_start] = delta1 / TMath::Sqrt(nexp1);
2405 }
2406 }
2407 }
2408 }
2409
2410 if (m) {
2411 igood += 1;
2412 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2413 }
2414 if (n) {
2415 igood += 2;
2416 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2417 }
2418
2419 Double_t prob = TMath::Prob(chi2, ndf);
2420
2421 return prob;
2422 }
2423
2424 // weighted - weighted comparison
2425 if (comparisonWW) {
2426 for (Int_t i = i_start; i <= i_end; ++i) {
2427 for (Int_t j = j_start; j <= j_end; ++j) {
2428 for (Int_t k = k_start; k <= k_end; ++k) {
2429
2430 Int_t bin = GetBin(i, j, k);
2431 Double_t cnt1 = RetrieveBinContent(bin);
2432 Double_t cnt2 = h2->RetrieveBinContent(bin);
2433 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2434 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2435
2436 // case both histogram have zero bin contents
2437 // (use square of content to avoid numerical errors)
2438 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2439 --ndf; //no data means one degree of freedom less
2440 continue;
2441 }
2442
2443 if (e1sq == 0 && e2sq == 0) {
2444 // cannot treat case of booth histogram have zero zero errors
2445 Error("Chi2TestX","h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
2446 chi2 = 0; return 0;
2447 }
2448
2449 Double_t sigma = sum1 * sum1 * e2sq + sum2 * sum2 * e1sq;
2450 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2451 chi2 += delta * delta / sigma;
2452
2453 if (res) {
2454 Double_t temp = cnt1 * sum1 * e2sq + cnt2 * sum2 * e1sq;
2455 Double_t probb = temp / sigma;
2456 Double_t z = 0;
2457 if (e1sq > e2sq) {
2458 Double_t d1 = cnt1 - sum1 * probb;
2459 Double_t s1 = e1sq * ( 1. - e2sq * sum1 * sum1 / sigma );
2460 z = d1 / TMath::Sqrt(s1);
2461 }
2462 else {
2463 Double_t d2 = cnt2 - sum2 * probb;
2464 Double_t s2 = e2sq * ( 1. - e1sq * sum2 * sum2 / sigma );
2465 z = -d2 / TMath::Sqrt(s2);
2466 }
2467 res[i - i_start] = z;
2468 }
2469
2470 if (e1sq > 0 && cnt1 * cnt1 / e1sq < 10) m++;
2471 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2472 }
2473 }
2474 }
2475 if (m) {
2476 igood += 1;
2477 Info("Chi2TestX","There is a bin in h1 with less than 10 effective events.\n");
2478 }
2479 if (n) {
2480 igood += 2;
2481 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2482 }
2483 Double_t prob = TMath::Prob(chi2, ndf);
2484 return prob;
2485 }
2486 return 0;
2487}
2488////////////////////////////////////////////////////////////////////////////////
2489/// Compute and return the chisquare of this histogram with respect to a function
2490/// The chisquare is computed by weighting each histogram point by the bin error
2491/// By default the full range of the histogram is used.
2492/// Use option "R" for restricting the chisquare calculation to the given range of the function
2493/// Use option "L" for using the chisquare based on the poisson likelihood (Baker-Cousins Chisquare)
2494/// Use option "P" for using the Pearson chisquare based on the expected bin errors
2495
2497{
2498 if (!func) {
2499 Error("Chisquare","Function pointer is Null - return -1");
2500 return -1;
2501 }
2502
2503 TString opt(option); opt.ToUpper();
2504 bool useRange = opt.Contains("R");
2505 ROOT::Fit::EChisquareType type = ROOT::Fit::EChisquareType::kNeyman; // default chi2 with observed error
2508
2509 return ROOT::Fit::Chisquare(*this, *func, useRange, type);
2510}
2511
2512////////////////////////////////////////////////////////////////////////////////
2513/// Remove all the content from the underflow and overflow bins, without changing the number of entries
2514/// After calling this method, every undeflow and overflow bins will have content 0.0
2515/// The Sumw2 is also cleared, since there is no more content in the bins
2516
2518{
2519 for (Int_t bin = 0; bin < fNcells; ++bin)
2520 if (IsBinUnderflow(bin) || IsBinOverflow(bin)) {
2521 UpdateBinContent(bin, 0.0);
2522 if (fSumw2.fN) fSumw2.fArray[bin] = 0.0;
2523 }
2524}
2525
2526////////////////////////////////////////////////////////////////////////////////
2527/// Compute integral (cumulative sum of bins)
2528/// The result stored in fIntegral is used by the GetRandom functions.
2529/// This function is automatically called by GetRandom when the fIntegral
2530/// array does not exist or when the number of entries in the histogram
2531/// has changed since the previous call to GetRandom.
2532/// The resulting integral is normalized to 1
2533/// If the routine is called with the onlyPositive flag set an error will
2534/// be produced in case of negative bin content and a NaN value returned
2535
2537{
2538 if (fBuffer) BufferEmpty();
2539
2540 // delete previously computed integral (if any)
2541 if (fIntegral) delete [] fIntegral;
2542
2543 // - Allocate space to store the integral and compute integral
2544 Int_t nbinsx = GetNbinsX();
2545 Int_t nbinsy = GetNbinsY();
2546 Int_t nbinsz = GetNbinsZ();
2547 Int_t nbins = nbinsx * nbinsy * nbinsz;
2548
2549 fIntegral = new Double_t[nbins + 2];
2550 Int_t ibin = 0; fIntegral[ibin] = 0;
2551
2552 for (Int_t binz=1; binz <= nbinsz; ++binz) {
2553 for (Int_t biny=1; biny <= nbinsy; ++biny) {
2554 for (Int_t binx=1; binx <= nbinsx; ++binx) {
2555 ++ibin;
2556 Double_t y = RetrieveBinContent(GetBin(binx, biny, binz));
2557 if (onlyPositive && y < 0) {
2558 Error("ComputeIntegral","Bin content is negative - return a NaN value");
2559 fIntegral[nbins] = TMath::QuietNaN();
2560 break;
2561 }
2562 fIntegral[ibin] = fIntegral[ibin - 1] + y;
2563 }
2564 }
2565 }
2566
2567 // - Normalize integral to 1
2568 if (fIntegral[nbins] == 0 ) {
2569 Error("ComputeIntegral", "Integral = zero"); return 0;
2570 }
2571 for (Int_t bin=1; bin <= nbins; ++bin) fIntegral[bin] /= fIntegral[nbins];
2572 fIntegral[nbins+1] = fEntries;
2573 return fIntegral[nbins];
2574}
2575
2576////////////////////////////////////////////////////////////////////////////////
2577/// Return a pointer to the array of bins integral.
2578/// if the pointer fIntegral is null, TH1::ComputeIntegral is called
2579/// The array dimension is the number of bins in the histograms
2580/// including underflow and overflow (fNCells)
2581/// the last value integral[fNCells] is set to the number of entries of
2582/// the histogram
2583
2585{
2586 if (!fIntegral) ComputeIntegral();
2587 return fIntegral;
2588}
2589
2590////////////////////////////////////////////////////////////////////////////////
2591/// Return a pointer to a histogram containing the cumulative content.
2592/// The cumulative can be computed both in the forward (default) or backward
2593/// direction; the name of the new histogram is constructed from
2594/// the name of this histogram with the suffix "suffix" appended provided
2595/// by the user. If not provided a default suffix="_cumulative" is used.
2596///
2597/// The cumulative distribution is formed by filling each bin of the
2598/// resulting histogram with the sum of that bin and all previous
2599/// (forward == kTRUE) or following (forward = kFALSE) bins.
2600///
2601/// Note: while cumulative distributions make sense in one dimension, you
2602/// may not be getting what you expect in more than 1D because the concept
2603/// of a cumulative distribution is much trickier to define; make sure you
2604/// understand the order of summation before you use this method with
2605/// histograms of dimension >= 2.
2606///
2607/// Note 2: By default the cumulative is computed from bin 1 to Nbins
2608/// If an axis range is set, values between the minimum and maximum of the range
2609/// are set.
2610/// Setting an axis range can also be used for including underflow and overflow in
2611/// the cumulative (e.g. by setting h->GetXaxis()->SetRange(0, h->GetNbinsX()+1); )
2613
2614TH1 *TH1::GetCumulative(Bool_t forward, const char* suffix) const
2615{
2616 const Int_t firstX = fXaxis.GetFirst();
2617 const Int_t lastX = fXaxis.GetLast();
2618 const Int_t firstY = (fDimension > 1) ? fYaxis.GetFirst() : 1;
2619 const Int_t lastY = (fDimension > 1) ? fYaxis.GetLast() : 1;
2620 const Int_t firstZ = (fDimension > 1) ? fZaxis.GetFirst() : 1;
2621 const Int_t lastZ = (fDimension > 1) ? fZaxis.GetLast() : 1;
2622
2623 TH1* hintegrated = (TH1*) Clone(fName + suffix);
2624 hintegrated->Reset();
2625 Double_t sum = 0.;
2626 Double_t esum = 0;
2627 if (forward) { // Forward computation
2628 for (Int_t binz = firstZ; binz <= lastZ; ++binz) {
2629 for (Int_t biny = firstY; biny <= lastY; ++biny) {
2630 for (Int_t binx = firstX; binx <= lastX; ++binx) {
2631 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2632 sum += RetrieveBinContent(bin);
2633 hintegrated->AddBinContent(bin, sum);
2634 if (fSumw2.fN) {
2635 esum += GetBinErrorSqUnchecked(bin);
2636 hintegrated->fSumw2.fArray[bin] = esum;
2637 }
2638 }
2639 }
2640 }
2641 } else { // Backward computation
2642 for (Int_t binz = lastZ; binz >= firstZ; --binz) {
2643 for (Int_t biny = lastY; biny >= firstY; --biny) {
2644 for (Int_t binx = lastX; binx >= firstX; --binx) {
2645 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2646 sum += RetrieveBinContent(bin);
2647 hintegrated->AddBinContent(bin, sum);
2648 if (fSumw2.fN) {
2649 esum += GetBinErrorSqUnchecked(bin);
2650 hintegrated->fSumw2.fArray[bin] = esum;
2651 }
2652 }
2653 }
2654 }
2655 }
2656 return hintegrated;
2657}
2658
2659////////////////////////////////////////////////////////////////////////////////
2660/// Copy this histogram structure to newth1.
2661///
2662/// Note that this function does not copy the list of associated functions.
2663/// Use TObject::Clone to make a full copy of a histogram.
2664///
2665/// Note also that the histogram it will be created in gDirectory (if AddDirectoryStatus()=true)
2666/// or will not be added to any directory if AddDirectoryStatus()=false
2667/// independently of the current directory stored in the original histogram
2668
2669void TH1::Copy(TObject &obj) const
2670{
2671 if (((TH1&)obj).fDirectory) {
2672 // We are likely to change the hash value of this object
2673 // with TNamed::Copy, to keep things correct, we need to
2674 // clean up its existing entries.
2675 ((TH1&)obj).fDirectory->Remove(&obj);
2676 ((TH1&)obj).fDirectory = nullptr;
2677 }
2678 TNamed::Copy(obj);
2679 ((TH1&)obj).fDimension = fDimension;
2680 ((TH1&)obj).fNormFactor= fNormFactor;
2681 ((TH1&)obj).fNcells = fNcells;
2682 ((TH1&)obj).fBarOffset = fBarOffset;
2683 ((TH1&)obj).fBarWidth = fBarWidth;
2684 ((TH1&)obj).fOption = fOption;
2685 ((TH1&)obj).fBinStatErrOpt = fBinStatErrOpt;
2686 ((TH1&)obj).fBufferSize= fBufferSize;
2687 // copy the Buffer
2688 // delete first a previously existing buffer
2689 if (((TH1&)obj).fBuffer != nullptr) {
2690 delete [] ((TH1&)obj).fBuffer;
2691 ((TH1&)obj).fBuffer = nullptr;
2692 }
2693 if (fBuffer) {
2694 Double_t *buf = new Double_t[fBufferSize];
2695 for (Int_t i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
2696 // obj.fBuffer has been deleted before
2697 ((TH1&)obj).fBuffer = buf;
2698 }
2699
2700 // copy bin contents (this should be done by the derived classes, since TH1 does not store the bin content)
2701 // Do this in case derived from TArray
2702 TArray* a = dynamic_cast<TArray*>(&obj);
2703 if (a) {
2704 a->Set(fNcells);
2705 for (Int_t i = 0; i < fNcells; i++)
2707 }
2708
2709 ((TH1&)obj).fEntries = fEntries;
2710
2711 // which will call BufferEmpty(0) and set fBuffer[0] to a Maybe one should call
2712 // assignment operator on the TArrayD
2713
2714 ((TH1&)obj).fTsumw = fTsumw;
2715 ((TH1&)obj).fTsumw2 = fTsumw2;
2716 ((TH1&)obj).fTsumwx = fTsumwx;
2717 ((TH1&)obj).fTsumwx2 = fTsumwx2;
2718 ((TH1&)obj).fMaximum = fMaximum;
2719 ((TH1&)obj).fMinimum = fMinimum;
2720
2721 TAttLine::Copy(((TH1&)obj));
2722 TAttFill::Copy(((TH1&)obj));
2723 TAttMarker::Copy(((TH1&)obj));
2724 fXaxis.Copy(((TH1&)obj).fXaxis);
2725 fYaxis.Copy(((TH1&)obj).fYaxis);
2726 fZaxis.Copy(((TH1&)obj).fZaxis);
2727 ((TH1&)obj).fXaxis.SetParent(&obj);
2728 ((TH1&)obj).fYaxis.SetParent(&obj);
2729 ((TH1&)obj).fZaxis.SetParent(&obj);
2730 fContour.Copy(((TH1&)obj).fContour);
2731 fSumw2.Copy(((TH1&)obj).fSumw2);
2732 // fFunctions->Copy(((TH1&)obj).fFunctions);
2733 // when copying an histogram if the AddDirectoryStatus() is true it
2734 // will be added to gDirectory independently of the fDirectory stored.
2735 // and if the AddDirectoryStatus() is false it will not be added to
2736 // any directory (fDirectory = nullptr)
2737 if (fgAddDirectory && gDirectory) {
2738 gDirectory->Append(&obj);
2739 ((TH1&)obj).fFunctions->UseRWLock();
2740 ((TH1&)obj).fDirectory = gDirectory;
2741 } else
2742 ((TH1&)obj).fDirectory = nullptr;
2743
2744}
2745
2746////////////////////////////////////////////////////////////////////////////////
2747/// Make a complete copy of the underlying object. If 'newname' is set,
2748/// the copy's name will be set to that name.
2749
2750TObject* TH1::Clone(const char* newname) const
2751{
2752 TH1* obj = (TH1*)IsA()->GetNew()(nullptr);
2753 Copy(*obj);
2754
2755 // Now handle the parts that Copy doesn't do
2756 if(fFunctions) {
2757 // The Copy above might have published 'obj' to the ListOfCleanups.
2758 // Clone can call RecursiveRemove, for example via TCheckHashRecursiveRemoveConsistency
2759 // when dictionary information is initialized, so we need to
2760 // keep obj->fFunction valid during its execution and
2761 // protect the update with the write lock.
2762
2763 // Reset stats parent - else cloning the stats will clone this histogram, too.
2764 auto oldstats = dynamic_cast<TVirtualPaveStats*>(fFunctions->FindObject("stats"));
2765 TObject *oldparent = nullptr;
2766 if (oldstats) {
2767 oldparent = oldstats->GetParent();
2768 oldstats->SetParent(nullptr);
2769 }
2770
2771 auto newlist = (TList*)fFunctions->Clone();
2772
2773 if (oldstats)
2774 oldstats->SetParent(oldparent);
2775 auto newstats = dynamic_cast<TVirtualPaveStats*>(obj->fFunctions->FindObject("stats"));
2776 if (newstats)
2777 newstats->SetParent(obj);
2778
2779 auto oldlist = obj->fFunctions;
2780 {
2782 obj->fFunctions = newlist;
2783 }
2784 delete oldlist;
2785 }
2786 if(newname && strlen(newname) ) {
2787 obj->SetName(newname);
2788 }
2789 return obj;
2790}
2791
2792////////////////////////////////////////////////////////////////////////////////
2793/// Perform the automatic addition of the histogram to the given directory
2794///
2795/// Note this function is called in place when the semantic requires
2796/// this object to be added to a directory (I.e. when being read from
2797/// a TKey or being Cloned)
2798
2800{
2801 Bool_t addStatus = TH1::AddDirectoryStatus();
2802 if (addStatus) {
2803 SetDirectory(dir);
2804 if (dir) {
2806 }
2807 }
2808}
2809
2810////////////////////////////////////////////////////////////////////////////////
2811/// Compute distance from point px,py to a line.
2812///
2813/// Compute the closest distance of approach from point px,py to elements
2814/// of a histogram.
2815/// The distance is computed in pixels units.
2816///
2817/// #### Algorithm:
2818/// Currently, this simple model computes the distance from the mouse
2819/// to the histogram contour only.
2820
2822{
2823 if (!fPainter) return 9999;
2824 return fPainter->DistancetoPrimitive(px,py);
2825}
2826
2827////////////////////////////////////////////////////////////////////////////////
2828/// Performs the operation: `this = this/(c1*f1)`
2829/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2830///
2831/// Only bins inside the function range are recomputed.
2832/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2833/// you should call Sumw2 before making this operation.
2834/// This is particularly important if you fit the histogram after TH1::Divide
2835///
2836/// The function return kFALSE if the divide operation failed
2837
2839{
2840 if (!f1) {
2841 Error("Divide","Attempt to divide by a non-existing function");
2842 return kFALSE;
2843 }
2844
2845 // delete buffer if it is there since it will become invalid
2846 if (fBuffer) BufferEmpty(1);
2847
2848 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of
2849 Int_t ny = GetNbinsY() + 2;
2850 Int_t nz = GetNbinsZ() + 2;
2851 if (fDimension < 2) ny = 1;
2852 if (fDimension < 3) nz = 1;
2853
2854
2855 SetMinimum();
2856 SetMaximum();
2857
2858 // - Loop on bins (including underflows/overflows)
2859 Int_t bin, binx, biny, binz;
2860 Double_t cu, w;
2861 Double_t xx[3];
2862 Double_t *params = nullptr;
2863 f1->InitArgs(xx,params);
2864 for (binz = 0; binz < nz; ++binz) {
2865 xx[2] = fZaxis.GetBinCenter(binz);
2866 for (biny = 0; biny < ny; ++biny) {
2867 xx[1] = fYaxis.GetBinCenter(biny);
2868 for (binx = 0; binx < nx; ++binx) {
2869 xx[0] = fXaxis.GetBinCenter(binx);
2870 if (!f1->IsInside(xx)) continue;
2872 bin = binx + nx * (biny + ny * binz);
2873 cu = c1 * f1->EvalPar(xx);
2874 if (TF1::RejectedPoint()) continue;
2875 if (cu) w = RetrieveBinContent(bin) / cu;
2876 else w = 0;
2877 UpdateBinContent(bin, w);
2878 if (fSumw2.fN) {
2879 if (cu != 0) fSumw2.fArray[bin] = GetBinErrorSqUnchecked(bin) / (cu * cu);
2880 else fSumw2.fArray[bin] = 0;
2881 }
2882 }
2883 }
2884 }
2885 ResetStats();
2886 return kTRUE;
2887}
2888
2889////////////////////////////////////////////////////////////////////////////////
2890/// Divide this histogram by h1.
2891///
2892/// `this = this/h1`
2893/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2894/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
2895/// if not already set.
2896/// The resulting errors are calculated assuming uncorrelated histograms.
2897/// See the other TH1::Divide that gives the possibility to optionally
2898/// compute binomial errors.
2899///
2900/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2901/// you should call Sumw2 before making this operation.
2902/// This is particularly important if you fit the histogram after TH1::Scale
2903///
2904/// The function return kFALSE if the divide operation failed
2905
2906Bool_t TH1::Divide(const TH1 *h1)
2907{
2908 if (!h1) {
2909 Error("Divide", "Input histogram passed does not exist (NULL).");
2910 return kFALSE;
2911 }
2912
2913 // delete buffer if it is there since it will become invalid
2914 if (fBuffer) BufferEmpty(1);
2915
2916 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins) {
2917 return false;
2918 }
2919
2920 // Create Sumw2 if h1 has Sumw2 set
2921 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
2922
2923 // - Loop on bins (including underflows/overflows)
2924 for (Int_t i = 0; i < fNcells; ++i) {
2927 if (c1) UpdateBinContent(i, c0 / c1);
2928 else UpdateBinContent(i, 0);
2929
2930 if(fSumw2.fN) {
2931 if (c1 == 0) { fSumw2.fArray[i] = 0; continue; }
2932 Double_t c1sq = c1 * c1;
2933 fSumw2.fArray[i] = (GetBinErrorSqUnchecked(i) * c1sq + h1->GetBinErrorSqUnchecked(i) * c0 * c0) / (c1sq * c1sq);
2934 }
2935 }
2936 ResetStats();
2937 return kTRUE;
2938}
2939
2940////////////////////////////////////////////////////////////////////////////////
2941/// Replace contents of this histogram by the division of h1 by h2.
2942///
2943/// `this = c1*h1/(c2*h2)`
2944///
2945/// If errors are defined (see TH1::Sumw2), errors are also recalculated
2946/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
2947/// if not already set.
2948/// The resulting errors are calculated assuming uncorrelated histograms.
2949/// However, if option ="B" is specified, Binomial errors are computed.
2950/// In this case c1 and c2 do not make real sense and they are ignored.
2951///
2952/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2953/// you should call Sumw2 before making this operation.
2954/// This is particularly important if you fit the histogram after TH1::Divide
2955///
2956/// Please note also that in the binomial case errors are calculated using standard
2957/// binomial statistics, which means when b1 = b2, the error is zero.
2958/// If you prefer to have efficiency errors not going to zero when the efficiency is 1, you must
2959/// use the function TGraphAsymmErrors::BayesDivide, which will return an asymmetric and non-zero lower
2960/// error for the case b1=b2.
2961///
2962/// The function return kFALSE if the divide operation failed
2963
2965{
2966
2967 TString opt = option;
2968 opt.ToLower();
2969 Bool_t binomial = kFALSE;
2970 if (opt.Contains("b")) binomial = kTRUE;
2971 if (!h1 || !h2) {
2972 Error("Divide", "At least one of the input histograms passed does not exist (NULL).");
2973 return kFALSE;
2974 }
2975
2976 // delete buffer if it is there since it will become invalid
2977 if (fBuffer) BufferEmpty(1);
2978
2979 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins ||
2980 LoggedInconsistency("Divide", h1, h2) >= kDifferentNumberOfBins) {
2981 return false;
2982 }
2983
2984 if (!c2) {
2985 Error("Divide","Coefficient of dividing histogram cannot be zero");
2986 return kFALSE;
2987 }
2988
2989 // Create Sumw2 if h1 or h2 have Sumw2 set, or if binomial errors are explicitly requested
2990 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0 || binomial)) Sumw2();
2991
2992 SetMinimum();
2993 SetMaximum();
2994
2995 // - Loop on bins (including underflows/overflows)
2996 for (Int_t i = 0; i < fNcells; ++i) {
2998 Double_t b2 = h2->RetrieveBinContent(i);
2999 if (b2) UpdateBinContent(i, c1 * b1 / (c2 * b2));
3000 else UpdateBinContent(i, 0);
3001
3002 if (fSumw2.fN) {
3003 if (b2 == 0) { fSumw2.fArray[i] = 0; continue; }
3004 Double_t b1sq = b1 * b1; Double_t b2sq = b2 * b2;
3005 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
3007 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
3008 if (binomial) {
3009 if (b1 != b2) {
3010 // in the case of binomial statistics c1 and c2 must be 1 otherwise it does not make sense
3011 // c1 and c2 are ignored
3012 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));//this is the formula in Hbook/Hoper1
3013 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2); // old formula from G. Flucke
3014 // formula which works also for weighted histogram (see http://root-forum.cern.ch/viewtopic.php?t=3753 )
3015 fSumw2.fArray[i] = TMath::Abs( ( (1. - 2.* b1 / b2) * e1sq + b1sq * e2sq / b2sq ) / b2sq );
3016 } else {
3017 //in case b1=b2 error is zero
3018 //use TGraphAsymmErrors::BayesDivide for getting the asymmetric error not equal to zero
3019 fSumw2.fArray[i] = 0;
3020 }
3021 } else {
3022 fSumw2.fArray[i] = c1sq * c2sq * (e1sq * b2sq + e2sq * b1sq) / (c2sq * c2sq * b2sq * b2sq);
3023 }
3024 }
3025 }
3026 ResetStats();
3027 if (binomial)
3028 // in case of binomial division use denominator for number of entries
3029 SetEntries ( h2->GetEntries() );
3030
3031 return kTRUE;
3032}
3033
3034////////////////////////////////////////////////////////////////////////////////
3035/// Draw this histogram with options.
3036///
3037/// Histograms are drawn via the THistPainter class. Each histogram has
3038/// a pointer to its own painter (to be usable in a multithreaded program).
3039/// The same histogram can be drawn with different options in different pads.
3040/// When a histogram drawn in a pad is deleted, the histogram is
3041/// automatically removed from the pad or pads where it was drawn.
3042/// If a histogram is drawn in a pad, then filled again, the new status
3043/// of the histogram will be automatically shown in the pad next time
3044/// the pad is updated. One does not need to redraw the histogram.
3045/// To draw the current version of a histogram in a pad, one can use
3046/// `h->DrawCopy();`
3047/// This makes a clone of the histogram. Once the clone is drawn, the original
3048/// histogram may be modified or deleted without affecting the aspect of the
3049/// clone.
3050/// By default, TH1::Draw clears the current pad.
3051///
3052/// One can use TH1::SetMaximum and TH1::SetMinimum to force a particular
3053/// value for the maximum or the minimum scale on the plot.
3054///
3055/// TH1::UseCurrentStyle can be used to change all histogram graphics
3056/// attributes to correspond to the current selected style.
3057/// This function must be called for each histogram.
3058/// In case one reads and draws many histograms from a file, one can force
3059/// the histograms to inherit automatically the current graphics style
3060/// by calling before gROOT->ForceStyle();
3061///
3062/// See the THistPainter class for a description of all the drawing options.
3063
3065{
3066 TString opt1 = option; opt1.ToLower();
3067 TString opt2 = option;
3068 Int_t index = opt1.Index("same");
3069
3070 // Check if the string "same" is part of a TCutg name.
3071 if (index>=0) {
3072 Int_t indb = opt1.Index("[");
3073 if (indb>=0) {
3074 Int_t indk = opt1.Index("]");
3075 if (index>indb && index<indk) index = -1;
3076 }
3077 }
3078
3079 // If there is no pad or an empty pad the "same" option is ignored.
3080 if (gPad) {
3081 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
3082 if (index>=0) {
3083 if (gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
3084 gPad->GetY1() == 0 && gPad->GetY2() == 1 &&
3085 gPad->GetListOfPrimitives()->GetSize()==0) opt2.Remove(index,4);
3086 } else {
3087 //the following statement is necessary in case one attempts to draw
3088 //a temporary histogram already in the current pad
3089 if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(this);
3090 gPad->Clear();
3091 }
3092 gPad->IncrementPaletteColor(1, opt1);
3093 } else {
3094 if (index>=0) opt2.Remove(index,4);
3095 }
3096
3097 AppendPad(opt2.Data());
3098}
3099
3100////////////////////////////////////////////////////////////////////////////////
3101/// Copy this histogram and Draw in the current pad.
3102///
3103/// Once the histogram is drawn into the pad, any further modification
3104/// using graphics input will be made on the copy of the histogram,
3105/// and not to the original object.
3106/// By default a postfix "_copy" is added to the histogram name. Pass an empty postfix in case
3107/// you want to draw a histogram with the same name
3108///
3109/// See Draw for the list of options
3110
3111TH1 *TH1::DrawCopy(Option_t *option, const char * name_postfix) const
3112{
3113 TString opt = option;
3114 opt.ToLower();
3115 if (gPad && !opt.Contains("same")) gPad->Clear();
3116 TString newName;
3117 if (name_postfix) newName.Form("%s%s", GetName(), name_postfix);
3118 TH1 *newth1 = (TH1 *)Clone(newName.Data());
3119 newth1->SetDirectory(nullptr);
3120 newth1->SetBit(kCanDelete);
3121 if (gPad) gPad->IncrementPaletteColor(1, opt);
3122
3123 newth1->AppendPad(option);
3124 return newth1;
3125}
3126
3127////////////////////////////////////////////////////////////////////////////////
3128/// Draw a normalized copy of this histogram.
3129///
3130/// A clone of this histogram is normalized to norm and drawn with option.
3131/// A pointer to the normalized histogram is returned.
3132/// The contents of the histogram copy are scaled such that the new
3133/// sum of weights (excluding under and overflow) is equal to norm.
3134/// Note that the returned normalized histogram is not added to the list
3135/// of histograms in the current directory in memory.
3136/// It is the user's responsibility to delete this histogram.
3137/// The kCanDelete bit is set for the returned object. If a pad containing
3138/// this copy is cleared, the histogram will be automatically deleted.
3139///
3140/// See Draw for the list of options
3141
3143{
3145 if (sum == 0) {
3146 Error("DrawNormalized","Sum of weights is null. Cannot normalize histogram: %s",GetName());
3147 return nullptr;
3148 }
3149 Bool_t addStatus = TH1::AddDirectoryStatus();
3151 TH1 *h = (TH1*)Clone();
3153 // in case of drawing with error options - scale correctly the error
3154 TString opt(option); opt.ToUpper();
3155 if (fSumw2.fN == 0) {
3156 h->Sumw2();
3157 // do not use in this case the "Error option " for drawing which is enabled by default since the normalized histogram has now errors
3158 if (opt.IsNull() || opt == "SAME") opt += "HIST";
3159 }
3160 h->Scale(norm/sum);
3161 if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
3162 if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
3163 h->Draw(opt);
3164 TH1::AddDirectory(addStatus);
3165 return h;
3166}
3167
3168////////////////////////////////////////////////////////////////////////////////
3169/// Display a panel with all histogram drawing options.
3170///
3171/// See class TDrawPanelHist for example
3172
3173void TH1::DrawPanel()
3174{
3175 if (!fPainter) {Draw(); if (gPad) gPad->Update();}
3176 if (fPainter) fPainter->DrawPanel();
3177}
3178
3179////////////////////////////////////////////////////////////////////////////////
3180/// Evaluate function f1 at the center of bins of this histogram.
3181///
3182/// - If option "R" is specified, the function is evaluated only
3183/// for the bins included in the function range.
3184/// - If option "A" is specified, the value of the function is added to the
3185/// existing bin contents
3186/// - If option "S" is specified, the value of the function is used to
3187/// generate a value, distributed according to the Poisson
3188/// distribution, with f1 as the mean.
3189
3191{
3192 Double_t x[3];
3193 Int_t range, stat, add;
3194 if (!f1) return;
3195
3196 TString opt = option;
3197 opt.ToLower();
3198 if (opt.Contains("a")) add = 1;
3199 else add = 0;
3200 if (opt.Contains("s")) stat = 1;
3201 else stat = 0;
3202 if (opt.Contains("r")) range = 1;
3203 else range = 0;
3204
3205 // delete buffer if it is there since it will become invalid
3206 if (fBuffer) BufferEmpty(1);
3207
3208 Int_t nbinsx = fXaxis.GetNbins();
3209 Int_t nbinsy = fYaxis.GetNbins();
3210 Int_t nbinsz = fZaxis.GetNbins();
3211 if (!add) Reset();
3212
3213 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
3214 x[2] = fZaxis.GetBinCenter(binz);
3215 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
3216 x[1] = fYaxis.GetBinCenter(biny);
3217 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
3218 Int_t bin = GetBin(binx,biny,binz);
3219 x[0] = fXaxis.GetBinCenter(binx);
3220 if (range && !f1->IsInside(x)) continue;
3221 Double_t fu = f1->Eval(x[0], x[1], x[2]);
3222 if (stat) fu = gRandom->PoissonD(fu);
3223 AddBinContent(bin, fu);
3224 if (fSumw2.fN) fSumw2.fArray[bin] += TMath::Abs(fu);
3225 }
3226 }
3227 }
3228}
3229
3230////////////////////////////////////////////////////////////////////////////////
3231/// Execute action corresponding to one event.
3232///
3233/// This member function is called when a histogram is clicked with the locator
3234///
3235/// If Left button clicked on the bin top value, then the content of this bin
3236/// is modified according to the new position of the mouse when it is released.
3237
3238void TH1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3239{
3240 if (fPainter) fPainter->ExecuteEvent(event, px, py);
3241}
3242
3243////////////////////////////////////////////////////////////////////////////////
3244/// This function allows to do discrete Fourier transforms of TH1 and TH2.
3245/// Available transform types and flags are described below.
3246///
3247/// To extract more information about the transform, use the function
3248/// TVirtualFFT::GetCurrentTransform() to get a pointer to the current
3249/// transform object.
3250///
3251/// \param[out] h_output histogram for the output. If a null pointer is passed, a new histogram is created
3252/// and returned, otherwise, the provided histogram is used and should be big enough
3253/// \param[in] option option parameters consists of 3 parts:
3254/// - option on what to return
3255/// - "RE" - returns a histogram of the real part of the output
3256/// - "IM" - returns a histogram of the imaginary part of the output
3257/// - "MAG"- returns a histogram of the magnitude of the output
3258/// - "PH" - returns a histogram of the phase of the output
3259/// - option of transform type
3260/// - "R2C" - real to complex transforms - default
3261/// - "R2HC" - real to halfcomplex (special format of storing output data,
3262/// results the same as for R2C)
3263/// - "DHT" - discrete Hartley transform
3264/// real to real transforms (sine and cosine):
3265/// - "R2R_0", "R2R_1", "R2R_2", "R2R_3" - discrete cosine transforms of types I-IV
3266/// - "R2R_4", "R2R_5", "R2R_6", "R2R_7" - discrete sine transforms of types I-IV
3267/// To specify the type of each dimension of a 2-dimensional real to real
3268/// transform, use options of form "R2R_XX", for example, "R2R_02" for a transform,
3269/// which is of type "R2R_0" in 1st dimension and "R2R_2" in the 2nd.
3270/// - option of transform flag
3271/// - "ES" (from "estimate") - no time in preparing the transform, but probably sub-optimal
3272/// performance
3273/// - "M" (from "measure") - some time spend in finding the optimal way to do the transform
3274/// - "P" (from "patient") - more time spend in finding the optimal way to do the transform
3275/// - "EX" (from "exhaustive") - the most optimal way is found
3276/// This option should be chosen depending on how many transforms of the same size and
3277/// type are going to be done. Planning is only done once, for the first transform of this
3278/// size and type. Default is "ES".
3279///
3280/// Examples of valid options: "Mag R2C M" "Re R2R_11" "Im R2C ES" "PH R2HC EX"
3281
3282TH1* TH1::FFT(TH1* h_output, Option_t *option)
3283{
3284
3285 Int_t ndim[3];
3286 ndim[0] = this->GetNbinsX();
3287 ndim[1] = this->GetNbinsY();
3288 ndim[2] = this->GetNbinsZ();
3289
3290 TVirtualFFT *fft;
3291 TString opt = option;
3292 opt.ToUpper();
3293 if (!opt.Contains("2R")){
3294 if (!opt.Contains("2C") && !opt.Contains("2HC") && !opt.Contains("DHT")) {
3295 //no type specified, "R2C" by default
3296 opt.Append("R2C");
3297 }
3298 fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
3299 }
3300 else {
3301 //find the kind of transform
3302 Int_t ind = opt.Index("R2R", 3);
3303 Int_t *kind = new Int_t[2];
3304 char t;
3305 t = opt[ind+4];
3306 kind[0] = atoi(&t);
3307 if (h_output->GetDimension()>1) {
3308 t = opt[ind+5];
3309 kind[1] = atoi(&t);
3310 }
3311 fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
3312 delete [] kind;
3313 }
3314
3315 if (!fft) return nullptr;
3316 Int_t in=0;
3317 for (Int_t binx = 1; binx<=ndim[0]; binx++) {
3318 for (Int_t biny=1; biny<=ndim[1]; biny++) {
3319 for (Int_t binz=1; binz<=ndim[2]; binz++) {
3320 fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
3321 in++;
3322 }
3323 }
3324 }
3325 fft->Transform();
3326 h_output = TransformHisto(fft, h_output, option);
3327 return h_output;
3328}
3329
3330////////////////////////////////////////////////////////////////////////////////
3331/// Increment bin with abscissa X by 1.
3332///
3333/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3334/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3335///
3336/// If the storage of the sum of squares of weights has been triggered,
3337/// via the function Sumw2, then the sum of the squares of weights is incremented
3338/// by 1 in the bin corresponding to x.
3339///
3340/// The function returns the corresponding bin number which has its content incremented by 1
3341
3343{
3344 if (fBuffer) return BufferFill(x,1);
3345
3346 Int_t bin;
3347 fEntries++;
3348 bin =fXaxis.FindBin(x);
3349 if (bin <0) return -1;
3350 AddBinContent(bin);
3351 if (fSumw2.fN) ++fSumw2.fArray[bin];
3352 if (bin == 0 || bin > fXaxis.GetNbins()) {
3353 if (!GetStatOverflowsBehaviour()) return -1;
3354 }
3355 ++fTsumw;
3356 ++fTsumw2;
3357 fTsumwx += x;
3358 fTsumwx2 += x*x;
3359 return bin;
3360}
3361
3362////////////////////////////////////////////////////////////////////////////////
3363/// Increment bin with abscissa X with a weight w.
3364///
3365/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3366/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3367///
3368/// If the weight is not equal to 1, the storage of the sum of squares of
3369/// weights is automatically triggered and the sum of the squares of weights is incremented
3370/// by \f$ w^2 \f$ in the bin corresponding to x.
3371///
3372/// The function returns the corresponding bin number which has its content incremented by w
3373
3375{
3376
3377 if (fBuffer) return BufferFill(x,w);
3378
3379 Int_t bin;
3380 fEntries++;
3381 bin =fXaxis.FindBin(x);
3382 if (bin <0) return -1;
3383 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW) ) Sumw2(); // must be called before AddBinContent
3384 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3385 AddBinContent(bin, w);
3386 if (bin == 0 || bin > fXaxis.GetNbins()) {
3387 if (!GetStatOverflowsBehaviour()) return -1;
3388 }
3389 Double_t z= w;
3390 fTsumw += z;
3391 fTsumw2 += z*z;
3392 fTsumwx += z*x;
3393 fTsumwx2 += z*x*x;
3394 return bin;
3395}
3396
3397////////////////////////////////////////////////////////////////////////////////
3398/// Increment bin with namex with a weight w
3399///
3400/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3401/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3402///
3403/// If the weight is not equal to 1, the storage of the sum of squares of
3404/// weights is automatically triggered and the sum of the squares of weights is incremented
3405/// by \f$ w^2 \f$ in the bin corresponding to x.
3406///
3407/// The function returns the corresponding bin number which has its content
3408/// incremented by w.
3409
3410Int_t TH1::Fill(const char *namex, Double_t w)
3411{
3412 Int_t bin;
3413 fEntries++;
3414 bin =fXaxis.FindBin(namex);
3415 if (bin <0) return -1;
3416 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3417 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3418 AddBinContent(bin, w);
3419 if (bin == 0 || bin > fXaxis.GetNbins()) return -1;
3420 Double_t z= w;
3421 fTsumw += z;
3422 fTsumw2 += z*z;
3423 // this make sense if the histogram is not expanding (the x axis cannot be extended)
3424 if (!fXaxis.CanExtend() || !fXaxis.IsAlphanumeric()) {
3426 fTsumwx += z*x;
3427 fTsumwx2 += z*x*x;
3428 }
3429 return bin;
3430}
3431
3432////////////////////////////////////////////////////////////////////////////////
3433/// Fill this histogram with an array x and weights w.
3434///
3435/// \param[in] ntimes number of entries in arrays x and w (array size must be ntimes*stride)
3436/// \param[in] x array of values to be histogrammed
3437/// \param[in] w array of weighs
3438/// \param[in] stride step size through arrays x and w
3439///
3440/// If the weight is not equal to 1, the storage of the sum of squares of
3441/// weights is automatically triggered and the sum of the squares of weights is incremented
3442/// by \f$ w^2 \f$ in the bin corresponding to x.
3443/// if w is NULL each entry is assumed a weight=1
3444
3445void TH1::FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3446{
3447 //If a buffer is activated, fill buffer
3448 if (fBuffer) {
3449 ntimes *= stride;
3450 Int_t i = 0;
3451 for (i=0;i<ntimes;i+=stride) {
3452 if (!fBuffer) break; // buffer can be deleted in BufferFill when is empty
3453 if (w) BufferFill(x[i],w[i]);
3454 else BufferFill(x[i], 1.);
3455 }
3456 // fill the remaining entries if the buffer has been deleted
3457 if (i < ntimes && !fBuffer) {
3458 auto weights = w ? &w[i] : nullptr;
3459 DoFillN((ntimes-i)/stride,&x[i],weights,stride);
3460 }
3461 return;
3462 }
3463 // call internal method
3464 DoFillN(ntimes, x, w, stride);
3465}
3466
3467////////////////////////////////////////////////////////////////////////////////
3468/// Internal method to fill histogram content from a vector
3469/// called directly by TH1::BufferEmpty
3470
3471void TH1::DoFillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3472{
3473 Int_t bin,i;
3474
3475 fEntries += ntimes;
3476 Double_t ww = 1;
3477 Int_t nbins = fXaxis.GetNbins();
3478 ntimes *= stride;
3479 for (i=0;i<ntimes;i+=stride) {
3480 bin =fXaxis.FindBin(x[i]);
3481 if (bin <0) continue;
3482 if (w) ww = w[i];
3483 if (!fSumw2.fN && ww != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3484 if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
3485 AddBinContent(bin, ww);
3486 if (bin == 0 || bin > nbins) {
3487 if (!GetStatOverflowsBehaviour()) continue;
3488 }
3489 Double_t z= ww;
3490 fTsumw += z;
3491 fTsumw2 += z*z;
3492 fTsumwx += z*x[i];
3493 fTsumwx2 += z*x[i]*x[i];
3494 }
3495}
3496
3497////////////////////////////////////////////////////////////////////////////////
3498/// Fill histogram following distribution in function fname.
3499///
3500/// @param fname : Function name used for filling the histogram
3501/// @param ntimes : number of times the histogram is filled
3502/// @param rng : (optional) Random number generator used to sample
3503///
3504///
3505/// The distribution contained in the function fname (TF1) is integrated
3506/// over the channel contents for the bin range of this histogram.
3507/// It is normalized to 1.
3508///
3509/// Getting one random number implies:
3510/// - Generating a random number between 0 and 1 (say r1)
3511/// - Look in which bin in the normalized integral r1 corresponds to
3512/// - Fill histogram channel
3513/// ntimes random numbers are generated
3514///
3515/// One can also call TF1::GetRandom to get a random variate from a function.
3516
3517void TH1::FillRandom(const char *fname, Int_t ntimes, TRandom * rng)
3518{
3519 Int_t bin, binx, ibin, loop;
3520 Double_t r1, x;
3521 // - Search for fname in the list of ROOT defined functions
3522 TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
3523 if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
3524
3525 // - Allocate temporary space to store the integral and compute integral
3526
3527 TAxis * xAxis = &fXaxis;
3528
3529 // in case axis of histogram is not defined use the function axis
3530 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
3532 f1->GetRange(xmin,xmax);
3533 Info("FillRandom","Using function axis and range [%g,%g]",xmin, xmax);
3534 xAxis = f1->GetHistogram()->GetXaxis();
3535 }
3536
3537 Int_t first = xAxis->GetFirst();
3538 Int_t last = xAxis->GetLast();
3539 Int_t nbinsx = last-first+1;
3540
3541 Double_t *integral = new Double_t[nbinsx+1];
3542 integral[0] = 0;
3543 for (binx=1;binx<=nbinsx;binx++) {
3544 Double_t fint = f1->Integral(xAxis->GetBinLowEdge(binx+first-1),xAxis->GetBinUpEdge(binx+first-1), 0.);
3545 integral[binx] = integral[binx-1] + fint;
3546 }
3547
3548 // - Normalize integral to 1
3549 if (integral[nbinsx] == 0 ) {
3550 delete [] integral;
3551 Error("FillRandom", "Integral = zero"); return;
3552 }
3553 for (bin=1;bin<=nbinsx;bin++) integral[bin] /= integral[nbinsx];
3554
3555 // --------------Start main loop ntimes
3556 for (loop=0;loop<ntimes;loop++) {
3557 r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
3558 ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
3559 //binx = 1 + ibin;
3560 //x = xAxis->GetBinCenter(binx); //this is not OK when SetBuffer is used
3561 x = xAxis->GetBinLowEdge(ibin+first)
3562 +xAxis->GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
3563 Fill(x);
3564 }
3565 delete [] integral;
3566}
3567
3568////////////////////////////////////////////////////////////////////////////////
3569/// Fill histogram following distribution in histogram h.
3570///
3571/// @param h : Histogram pointer used for sampling random number
3572/// @param ntimes : number of times the histogram is filled
3573/// @param rng : (optional) Random number generator used for sampling
3574///
3575/// The distribution contained in the histogram h (TH1) is integrated
3576/// over the channel contents for the bin range of this histogram.
3577/// It is normalized to 1.
3578///
3579/// Getting one random number implies:
3580/// - Generating a random number between 0 and 1 (say r1)
3581/// - Look in which bin in the normalized integral r1 corresponds to
3582/// - Fill histogram channel ntimes random numbers are generated
3583///
3584/// SPECIAL CASE when the target histogram has the same binning as the source.
3585/// in this case we simply use a poisson distribution where
3586/// the mean value per bin = bincontent/integral.
3587
3588void TH1::FillRandom(TH1 *h, Int_t ntimes, TRandom * rng)
3589{
3590 if (!h) { Error("FillRandom", "Null histogram"); return; }
3591 if (fDimension != h->GetDimension()) {
3592 Error("FillRandom", "Histograms with different dimensions"); return;
3593 }
3594 if (std::isnan(h->ComputeIntegral(true))) {
3595 Error("FillRandom", "Histograms contains negative bins, does not represent probabilities");
3596 return;
3597 }
3598
3599 //in case the target histogram has the same binning and ntimes much greater
3600 //than the number of bins we can use a fast method
3601 Int_t first = fXaxis.GetFirst();
3602 Int_t last = fXaxis.GetLast();
3603 Int_t nbins = last-first+1;
3604 if (ntimes > 10*nbins) {
3605 auto inconsistency = CheckConsistency(this,h);
3606 if (inconsistency != kFullyConsistent) return; // do nothing
3607 Double_t sumw = h->Integral(first,last);
3608 if (sumw == 0) return;
3609 Double_t sumgen = 0;
3610 for (Int_t bin=first;bin<=last;bin++) {
3611 Double_t mean = h->RetrieveBinContent(bin)*ntimes/sumw;
3612 Double_t cont = (rng) ? rng->Poisson(mean) : gRandom->Poisson(mean);
3613 sumgen += cont;
3614 AddBinContent(bin,cont);
3615 if (fSumw2.fN) fSumw2.fArray[bin] += cont;
3616 }
3617
3618 // fix for the fluctuations in the total number n
3619 // since we use Poisson instead of multinomial
3620 // add a correction to have ntimes as generated entries
3621 Int_t i;
3622 if (sumgen < ntimes) {
3623 // add missing entries
3624 for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
3625 {
3626 Double_t x = h->GetRandom();
3627 Fill(x);
3628 }
3629 }
3630 else if (sumgen > ntimes) {
3631 // remove extra entries
3632 i = Int_t(sumgen+0.5);
3633 while( i > ntimes) {
3634 Double_t x = h->GetRandom(rng);
3635 Int_t ibin = fXaxis.FindBin(x);
3637 // skip in case bin is empty
3638 if (y > 0) {
3639 SetBinContent(ibin, y-1.);
3640 i--;
3641 }
3642 }
3643 }
3644
3645 ResetStats();
3646 return;
3647 }
3648 // case of different axis and not too large ntimes
3649
3650 if (h->ComputeIntegral() ==0) return;
3651 Int_t loop;
3652 Double_t x;
3653 for (loop=0;loop<ntimes;loop++) {
3654 x = h->GetRandom();
3655 Fill(x);
3656 }
3657}
3658
3659////////////////////////////////////////////////////////////////////////////////
3660/// Return Global bin number corresponding to x,y,z
3661///
3662/// 2-D and 3-D histograms are represented with a one dimensional
3663/// structure. This has the advantage that all existing functions, such as
3664/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3665/// This function tries to extend the axis if the given point belongs to an
3666/// under-/overflow bin AND if CanExtendAllAxes() is true.
3667///
3668/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3669
3671{
3672 if (GetDimension() < 2) {
3673 return fXaxis.FindBin(x);
3674 }
3675 if (GetDimension() < 3) {
3676 Int_t nx = fXaxis.GetNbins()+2;
3677 Int_t binx = fXaxis.FindBin(x);
3678 Int_t biny = fYaxis.FindBin(y);
3679 return binx + nx*biny;
3680 }
3681 if (GetDimension() < 4) {
3682 Int_t nx = fXaxis.GetNbins()+2;
3683 Int_t ny = fYaxis.GetNbins()+2;
3684 Int_t binx = fXaxis.FindBin(x);
3685 Int_t biny = fYaxis.FindBin(y);
3686 Int_t binz = fZaxis.FindBin(z);
3687 return binx + nx*(biny +ny*binz);
3688 }
3689 return -1;
3690}
3691
3692////////////////////////////////////////////////////////////////////////////////
3693/// Return Global bin number corresponding to x,y,z.
3694///
3695/// 2-D and 3-D histograms are represented with a one dimensional
3696/// structure. This has the advantage that all existing functions, such as
3697/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3698/// This function DOES NOT try to extend the axis if the given point belongs
3699/// to an under-/overflow bin.
3700///
3701/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3702
3704{
3705 if (GetDimension() < 2) {
3706 return fXaxis.FindFixBin(x);
3707 }
3708 if (GetDimension() < 3) {
3709 Int_t nx = fXaxis.GetNbins()+2;
3710 Int_t binx = fXaxis.FindFixBin(x);
3711 Int_t biny = fYaxis.FindFixBin(y);
3712 return binx + nx*biny;
3713 }
3714 if (GetDimension() < 4) {
3715 Int_t nx = fXaxis.GetNbins()+2;
3716 Int_t ny = fYaxis.GetNbins()+2;
3717 Int_t binx = fXaxis.FindFixBin(x);
3718 Int_t biny = fYaxis.FindFixBin(y);
3719 Int_t binz = fZaxis.FindFixBin(z);
3720 return binx + nx*(biny +ny*binz);
3721 }
3722 return -1;
3723}
3724
3725////////////////////////////////////////////////////////////////////////////////
3726/// Find first bin with content > threshold for axis (1=x, 2=y, 3=z)
3727/// if no bins with content > threshold is found the function returns -1.
3728/// The search will occur between the specified first and last bin. Specifying
3729/// the value of the last bin to search to less than zero will search until the
3730/// last defined bin.
3731
3732Int_t TH1::FindFirstBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3733{
3734 if (fBuffer) ((TH1*)this)->BufferEmpty();
3735
3736 if (axis < 1 || (axis > 1 && GetDimension() == 1 ) ||
3737 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3 ) ) {
3738 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3739 axis = 1;
3740 }
3741 if (firstBin < 1) {
3742 firstBin = 1;
3743 }
3744 Int_t nbinsx = fXaxis.GetNbins();
3745 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3746 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3747
3748 if (axis == 1) {
3749 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3750 lastBin = fXaxis.GetNbins();
3751 }
3752 for (Int_t binx = firstBin; binx <= lastBin; binx++) {
3753 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3754 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3755 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binx;
3756 }
3757 }
3758 }
3759 }
3760 else if (axis == 2) {
3761 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3762 lastBin = fYaxis.GetNbins();
3763 }
3764 for (Int_t biny = firstBin; biny <= lastBin; biny++) {
3765 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3766 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3767 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return biny;
3768 }
3769 }
3770 }
3771 }
3772 else if (axis == 3) {
3773 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3774 lastBin = fZaxis.GetNbins();
3775 }
3776 for (Int_t binz = firstBin; binz <= lastBin; binz++) {
3777 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3778 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3779 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binz;
3780 }
3781 }
3782 }
3783 }
3784
3785 return -1;
3786}
3787
3788////////////////////////////////////////////////////////////////////////////////
3789/// Find last bin with content > threshold for axis (1=x, 2=y, 3=z)
3790/// if no bins with content > threshold is found the function returns -1.
3791/// The search will occur between the specified first and last bin. Specifying
3792/// the value of the last bin to search to less than zero will search until the
3793/// last defined bin.
3794
3795Int_t TH1::FindLastBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3796{
3797 if (fBuffer) ((TH1*)this)->BufferEmpty();
3798
3799
3800 if (axis < 1 || ( axis > 1 && GetDimension() == 1 ) ||
3801 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3) ) {
3802 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3803 axis = 1;
3804 }
3805 if (firstBin < 1) {
3806 firstBin = 1;
3807 }
3808 Int_t nbinsx = fXaxis.GetNbins();
3809 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3810 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3811
3812 if (axis == 1) {
3813 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3814 lastBin = fXaxis.GetNbins();
3815 }
3816 for (Int_t binx = lastBin; binx >= firstBin; binx--) {
3817 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3818 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3819 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binx;
3820 }
3821 }
3822 }
3823 }
3824 else if (axis == 2) {
3825 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3826 lastBin = fYaxis.GetNbins();
3827 }
3828 for (Int_t biny = lastBin; biny >= firstBin; biny--) {
3829 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3830 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3831 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return biny;
3832 }
3833 }
3834 }
3835 }
3836 else if (axis == 3) {
3837 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3838 lastBin = fZaxis.GetNbins();
3839 }
3840 for (Int_t binz = lastBin; binz >= firstBin; binz--) {
3841 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3842 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3843 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binz;
3844 }
3845 }
3846 }
3847 }
3848
3849 return -1;
3850}
3851
3852////////////////////////////////////////////////////////////////////////////////
3853/// Search object named name in the list of functions.
3854
3855TObject *TH1::FindObject(const char *name) const
3856{
3857 if (fFunctions) return fFunctions->FindObject(name);
3858 return nullptr;
3859}
3860
3861////////////////////////////////////////////////////////////////////////////////
3862/// Search object obj in the list of functions.
3863
3864TObject *TH1::FindObject(const TObject *obj) const
3865{
3866 if (fFunctions) return fFunctions->FindObject(obj);
3867 return nullptr;
3868}
3869
3870////////////////////////////////////////////////////////////////////////////////
3871/// Fit histogram with function fname.
3872///
3873///
3874/// fname is the name of a function available in the global ROOT list of functions
3875/// `gROOT->GetListOfFunctions`
3876/// The list include any TF1 object created by the user plus some pre-defined functions
3877/// which are automatically created by ROOT the first time a pre-defined function is requested from `gROOT`
3878/// (i.e. when calling `gROOT->GetFunction(const char *name)`).
3879/// These pre-defined functions are:
3880/// - `gaus, gausn` where gausn is the normalized Gaussian
3881/// - `landau, landaun`
3882/// - `expo`
3883/// - `pol1,...9, chebyshev1,...9`.
3884///
3885/// For printing the list of all available functions do:
3886///
3887/// TF1::InitStandardFunctions(); // not needed if `gROOT->GetFunction` is called before
3888/// gROOT->GetListOfFunctions()->ls()
3889///
3890/// `fname` can also be a formula that is accepted by the linear fitter containing the special operator `++`,
3891/// representing linear components separated by `++` sign, for example `x++sin(x)` for fitting `[0]*x+[1]*sin(x)`
3892///
3893/// This function finds a pointer to the TF1 object with name `fname` and calls TH1::Fit(TF1 *, Option_t *, Option_t *,
3894/// Double_t, Double_t). See there for the fitting options and the details about fitting histograms
3895
3896TFitResultPtr TH1::Fit(const char *fname ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
3897{
3898 char *linear;
3899 linear= (char*)strstr(fname, "++");
3900 Int_t ndim=GetDimension();
3901 if (linear){
3902 if (ndim<2){
3903 TF1 f1(fname, fname, xxmin, xxmax);
3904 return Fit(&f1,option,goption,xxmin,xxmax);
3905 }
3906 else if (ndim<3){
3907 TF2 f2(fname, fname);
3908 return Fit(&f2,option,goption,xxmin,xxmax);
3909 }
3910 else{
3911 TF3 f3(fname, fname);
3912 return Fit(&f3,option,goption,xxmin,xxmax);
3913 }
3914 }
3915 else{
3916 TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
3917 if (!f1) { Printf("Unknown function: %s",fname); return -1; }
3918 return Fit(f1,option,goption,xxmin,xxmax);
3919 }
3920}
3921
3922////////////////////////////////////////////////////////////////////////////////
3923/// Fit histogram with the function pointer f1.
3924///
3925/// \param[in] f1 pointer to the function object
3926/// \param[in] option string defining the fit options (see table below).
3927/// \param[in] goption specify a list of graphics options. See TH1::Draw for a complete list of these options.
3928/// \param[in] xxmin lower fitting range
3929/// \param[in] xxmax upper fitting range
3930/// \return A smart pointer to the TFitResult class
3931///
3932/// \anchor HFitOpt
3933/// ### Histogram Fitting Options
3934///
3935/// Here is the full list of fit options that can be given in the parameter `option`.
3936/// Several options can be used together by concatanating the strings without the need of any delimiters.
3937///
3938/// option | description
3939/// -------|------------
3940/// "L" | Uses a log likelihood method (default is chi-square method). To be used when the histogram represents counts.
3941/// "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.
3942/// "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.
3943/// "MULTI" | Uses Loglikelihood method based on multi-nomial distribution. In this case the function must be normalized and one fits only the function shape.
3944/// "W" | Fit using the chi-square method and ignoring the bin uncertainties and skip empty bins.
3945/// "WW" | Fit using the chi-square method and ignoring the bin uncertainties and include the empty bins.
3946/// "I" | Uses the integral of function in the bin instead of the default bin center value.
3947/// "F" | Uses the default minimizer (e.g. Minuit) when fitting a linear function (e.g. polN) instead of the linear fitter.
3948/// "U" | Uses a user specified objective function (e.g. user providedlikelihood function) defined using `TVirtualFitter::SetFCN`
3949/// "E" | Performs a better parameter errors estimation using the Minos technique for all fit parameters.
3950/// "M" | Uses the IMPROVE algorithm (available only in TMinuit). This algorithm attempts improve the found local minimum by searching for a better one.
3951/// "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`.
3952/// "Q" | Quiet mode (minimum printing)
3953/// "V" | Verbose mode (default is between Q and V)
3954/// "+" | 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.
3955/// "N" | Does not store the graphics function, does not draw the histogram with the function after fitting.
3956/// "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.
3957/// "R" | Fit using a fitting range specified in the function range with `TF1::SetRange`.
3958/// "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.
3959/// "C" | In case of linear fitting, do no calculate the chisquare (saves CPU time).
3960/// "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.
3961/// "WIDTH" | Scales the histogran bin content by the bin width (useful for variable bins histograms)
3962/// "SERIAL" | Runs in serial mode. By defult if ROOT is built with MT support and MT is enables, the fit is perfomed in multi-thread - "E" Perform better Errors estimation using Minos technique
3963/// "MULTITHREAD" | Forces usage of multi-thread execution whenever possible
3964///
3965/// The default fitting of an histogram (when no option is given) is perfomed as following:
3966/// - a chi-square fit (see below Chi-square Fits) computed using the bin histogram errors and excluding bins with zero errors (empty bins);
3967/// - the full range of the histogram is used;
3968/// - the default Minimizer with its default configuration is used (see below Minimizer Configuration) except for linear function;
3969/// - for linear functions (`polN`, `chenbyshev` or formula expressions combined using operator `++`) a linear minimization is used.
3970/// - only the status of the fit is returned;
3971/// - the fit is performed in Multithread whenever is enabled in ROOT;
3972/// - only the last fitted function is saved in the histogram;
3973/// - the histogram is drawn after fitting overalyed with the resulting fitting function
3974///
3975/// \anchor HFitMinimizer
3976/// ### Minimizer Configuration
3977///
3978/// The Fit is perfomed using the default Minimizer, defined in the `ROOT::Math::MinimizerOptions` class.
3979/// It is possible to change the default minimizer and its configuration parameters by calling these static functions before fitting (before calling `TH1::Fit`):
3980/// - `ROOT::Math::MinimizerOptions::SetDefaultMinimizer(minimizerName, minimizerAgorithm)` for changing the minmizer and/or the corresponding algorithm.
3981/// For example `ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");` will set the usage of the BFGS algorithm of the GSL multi-dimensional minimization
3982/// The current defaults are ("Minuit","Migrad").
3983/// See the documentation of the `ROOT::Math::MinimizerOptions` for the available minimizers in ROOT and their corresponding algorithms.
3984/// - `ROOT::Math::MinimizerOptions::SetDefaultTolerance` for setting a different tolerance value for the minimization.
3985/// - `ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls` for setting the maximum number of function calls.
3986/// - `ROOT::Math::MinimizerOptions::SetDefaultPrintLevel` for changing the minimizer print level from level=0 (minimal printing) to level=3 maximum printing
3987///
3988/// Other options are possible depending on the Minimizer used, see the corresponding documentation.
3989/// The default minimizer can be also set in the resource file in etc/system.rootrc. For example
3990///
3991/// ~~~ {.cpp}
3992/// Root.Fitter: Minuit2
3993/// ~~~
3994///
3995/// \anchor HFitChi2
3996/// ### Chi-square Fits
3997///
3998/// By default a chi-square (least-square) fit is performed on the histogram. The so-called modified least-square method
3999/// is used where the residual for each bin is computed using as error the observed value (the bin error) returned by `TH1::GetBinError`
4000///
4001/// \f[
4002/// Chi2 = \sum_{i}{ \left(\frac{y(i) - f(x(i) | p )}{e(i)} \right)^2 }
4003/// \f]
4004///
4005/// 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
4006/// an un-weighted histogram). Bins with zero errors are excluded from the fit. See also later the note on the treatment
4007/// of empty bins. When using option "I" the residual is computed not using the function value at the bin center, `f(x(i)|p)`,
4008/// but the integral of the function in the bin, Integral{ f(x|p)dx }, divided by the bin volume.
4009/// When using option `P` (Pearson chi2), the expected error computed as `e(i) = sqrt(f(x(i)|p))` is used.
4010/// In this case empty bins are considered in the fit.
4011/// Both chi-square methods should not be used when the bin content represent counts, especially in case of low bin statistics,
4012/// because they could return a biased result.
4013///
4014/// \anchor HFitNLL
4015/// ### Likelihood Fits
4016///
4017/// When using option "L" a likelihood fit is used instead of the default chi-square fit.
4018/// The likelihood is built assuming a Poisson probability density function for each bin.
4019/// The negative log-likelihood to be minimized is
4020///
4021/// \f[
4022/// NLL = - \sum_{i}{ \log {\mathrm P} ( y(i) | f(x(i) | p ) ) }
4023/// \f]
4024/// 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)`.
4025/// The exact likelihood used is the Poisson likelihood described in this paper:
4026/// S. Baker and R. D. Cousins, “Clarification of the use of chi-square and likelihood functions in fits to histograms,”
4027/// Nucl. Instrum. Meth. 221 (1984) 437.
4028///
4029/// \f[
4030/// NLL = \sum_{i}{( f(x(i) | p ) + y(i)\log(y(i)/ f(x(i) | p )) - y(i)) }
4031/// \f]
4032/// By using this formulation, `2*NLL` can be interpreted as the chi-square resulting from the fit.
4033///
4034/// This method should be always used when the bin content represents counts (i.e. errors are sqrt(N) ).
4035/// The likelihood method has the advantage of treating correctly bins with low statistics. In case of high
4036/// statistics/bin the distribution of the bin content becomes a normal distribution and the likelihood and the chi2 fit
4037/// give the same result.
4038///
4039/// The likelihood method, although a bit slower, it is therefore the recommended method,
4040/// when the histogram represent counts (Poisson statistics), where the chi-square methods may
4041/// give incorrect results, especially in case of low statistics.
4042/// In case of a weighted histogram, it is possible to perform also a likelihood fit by using the
4043/// option "WL". Note a weighted histogram is a histogram which has been filled with weights and it
4044/// has the information on the sum of the weight square for each bin ( TH1::Sumw2() has been called).
4045/// The bin error for a weighted histogram is the square root of the sum of the weight square.
4046///
4047/// \anchor HFitRes
4048/// ### Fit Result
4049///
4050/// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
4051/// By default the TFitResultPtr contains only the status of the fit which is return by an
4052/// automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
4053///
4054/// ~~~ {.cpp}
4055/// Int_t fitStatus = h->Fit(myFunc);
4056/// ~~~
4057///
4058/// If the option "S" is instead used, TFitResultPtr behaves as a smart
4059/// pointer to the TFitResult object. This is useful for retrieving the full result information from the fit, such as the covariance matrix,
4060/// as shown in this example code:
4061///
4062/// ~~~ {.cpp}
4063/// TFitResultPtr r = h->Fit(myFunc,"S");
4064/// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
4065/// Double_t chi2 = r->Chi2(); // to retrieve the fit chi2
4066/// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
4067/// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
4068/// r->Print("V"); // print full information of fit including covariance matrix
4069/// r->Write(); // store the result in a file
4070/// ~~~
4071///
4072/// The fit parameters, error and chi-square (but not covariance matrix) can be retrieved also
4073/// directly from the fitted function that is passed to this call.
4074/// Given a pointer to an associated fitted function `myfunc`, one can retrieve the function/fit
4075/// parameters with calls such as:
4076///
4077/// ~~~ {.cpp}
4078/// Double_t chi2 = myfunc->GetChisquare();
4079/// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
4080/// Double_t err0 = myfunc->GetParError(0); //error on first parameter
4081/// ~~~
4082///
4083/// ##### Associated functions
4084///
4085/// One or more object ( can be added to the list
4086/// of functions (fFunctions) associated to each histogram.
4087/// When TH1::Fit is invoked, the fitted function is added to the histogram list of functions (fFunctions).
4088/// If the histogram is made persistent, the list of associated functions is also persistent.
4089/// Given a histogram h, one can retrieve an associated function with:
4090///
4091/// ~~~ {.cpp}
4092/// TF1 *myfunc = h->GetFunction("myfunc");
4093/// ~~~
4094/// or by quering directly the list obtained by calling `TH1::GetListOfFunctions`.
4095///
4096/// \anchor HFitStatus
4097/// ### Fit status
4098///
4099/// The status of the fit is obtained converting the TFitResultPtr to an integer
4100/// independently if the fit option "S" is used or not:
4101///
4102/// ~~~ {.cpp}
4103/// TFitResultPtr r = h->Fit(myFunc,opt);
4104/// Int_t fitStatus = r;
4105/// ~~~
4106///
4107/// - `status = 0` : the fit has been performed successfully (i.e no error occurred).
4108/// - `status < 0` : there is an error not connected with the minimization procedure, for example when a wrong function is used.
4109/// - `status > 0` : return status from Minimizer, depends on used Minimizer. For example for TMinuit and Minuit2 we have:
4110/// - `status = migradStatus + 10*minosStatus + 100*hesseStatus + 1000*improveStatus`.
4111/// 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
4112/// only in Minos but not in Migrad a fitStatus of 40 will be returned.
4113/// Minuit2 returns 0 in case of success and different values in migrad,minos or
4114/// hesse depending on the error. See in this case the documentation of
4115/// Minuit2Minimizer::Minimize for the migrad return status, Minuit2Minimizer::GetMinosError for the
4116/// minos return status and Minuit2Minimizer::Hesse for the hesse return status.
4117/// If other minimizers are used see their specific documentation for the status code returned.
4118/// For example in the case of Fumili, see TFumili::Minimize.
4119///
4120/// \anchor HFitRange
4121/// ### Fitting in a range
4122///
4123/// In order to fit in a sub-range of the histogram you have two options:
4124/// - pass to this function the lower (`xxmin`) and upper (`xxmax`) values for the fitting range;
4125/// - define a specific range in the fitted function and use the fitting option "R".
4126/// For example, if your histogram has a defined range between -4 and 4 and you want to fit a gaussian
4127/// only in the interval 1 to 3, you can do:
4128///
4129/// ~~~ {.cpp}
4130/// TF1 *f1 = new TF1("f1", "gaus", 1, 3);
4131/// histo->Fit("f1", "R");
4132/// ~~~
4133///
4134/// The fitting range is also limited by the histogram range defined using TAxis::SetRange
4135/// or TAxis::SetRangeUser. Therefore the fitting range is the smallest range between the
4136/// histogram one and the one defined by one of the two previous options described above.
4137///
4138/// \anchor HFitInitial
4139/// ### Setting initial conditions
4140///
4141/// Parameters must be initialized before invoking the Fit function.
4142/// The setting of the parameter initial values is automatic for the
4143/// predefined functions such as poln, expo, gaus, landau. One can however disable
4144/// this automatic computation by using the option "B".
4145/// Note that if a predefined function is defined with an argument,
4146/// eg, gaus(0), expo(1), you must specify the initial values for
4147/// the parameters.
4148/// You can specify boundary limits for some or all parameters via
4149///
4150/// ~~~ {.cpp}
4151/// f1->SetParLimits(p_number, parmin, parmax);
4152/// ~~~
4153///
4154/// if `parmin >= parmax`, the parameter is fixed
4155/// Note that you are not forced to fix the limits for all parameters.
4156/// For example, if you fit a function with 6 parameters, you can do:
4157///
4158/// ~~~ {.cpp}
4159/// func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
4160/// func->SetParLimits(3, -10, -4);
4161/// func->FixParameter(4, 0);
4162/// func->SetParLimits(5, 1, 1);
4163/// ~~~
4164///
4165/// With this setup, parameters 0->2 can vary freely
4166/// Parameter 3 has boundaries [-10,-4] with initial value -8
4167/// Parameter 4 is fixed to 0
4168/// Parameter 5 is fixed to 100.
4169/// When the lower limit and upper limit are equal, the parameter is fixed.
4170/// However to fix a parameter to 0, one must call the FixParameter function.
4171///
4172/// \anchor HFitStatBox
4173/// ### Fit Statistics Box
4174///
4175/// The statistics box can display the result of the fit.
4176/// You can change the statistics box to display the fit parameters with
4177/// the TStyle::SetOptFit(mode) method. This mode has four digits.
4178/// mode = pcev (default = 0111)
4179///
4180/// v = 1; print name/values of parameters
4181/// e = 1; print errors (if e=1, v must be 1)
4182/// c = 1; print Chisquare/Number of degrees of freedom
4183/// p = 1; print Probability
4184///
4185/// For example: gStyle->SetOptFit(1011);
4186/// prints the fit probability, parameter names/values, and errors.
4187/// You can change the position of the statistics box with these lines
4188/// (where g is a pointer to the TGraph):
4189///
4190/// TPaveStats *st = (TPaveStats*)g->GetListOfFunctions()->FindObject("stats");
4191/// st->SetX1NDC(newx1); //new x start position
4192/// st->SetX2NDC(newx2); //new x end position
4193///
4194/// \anchor HFitExtra
4195/// ### Additional Notes on Fitting
4196///
4197/// #### Fitting a histogram of dimension N with a function of dimension N-1
4198///
4199/// It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
4200/// 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.
4201/// For correct error scaling, the obtained parameter error are corrected as in the case when the
4202/// option "W" is used.
4203///
4204/// #### User defined objective functions
4205///
4206/// By default when fitting a chi square function is used for fitting. When option "L" is used
4207/// a Poisson likelihood function is used. Using option "MULTI" a multinomial likelihood fit is used.
4208/// Thes functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
4209/// are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
4210/// the file math/mathcore/src/FitUtil.cxx.
4211/// It is possible to specify a user defined fitting function, using option "U" and
4212/// calling the following functions:
4213///
4214/// ~~~ {.cpp}
4215/// TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction);
4216/// ~~~
4217///
4218/// where MyFittingFunction is of type:
4219///
4220/// ~~~ {.cpp}
4221/// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
4222/// ~~~
4223///
4224/// #### Note on treatment of empty bins
4225///
4226/// Empty bins, which have the content equal to zero AND error equal to zero,
4227/// are excluded by default from the chi-square fit, but they are considered in the likelihood fit.
4228/// since they affect the likelihood if the function value in these bins is not negligible.
4229/// Note that if the histogram is having bins with zero content and non zero-errors they are considered as
4230/// any other bins in the fit. Instead bins with zero error and non-zero content are by default excluded in the chi-squared fit.
4231/// In general, one should not fit a histogram with non-empty bins and zero errors.
4232///
4233/// 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
4234/// fit). When using option "WW" the empty bins will be also considered in the chi-square fit with an error of 1.
4235/// Note that in this fitting case (option "W" or "WW") the resulting fitted parameter errors
4236/// are corrected by the obtained chi2 value using this scaling expression:
4237/// `errorp *= sqrt(chisquare/(ndf-1))` as it is done when fitting a TGraph with
4238/// no point errors.
4239///
4240/// #### Excluding points
4241///
4242/// You can use TF1::RejectPoint inside your fitting function to exclude some points
4243/// within a certain range from the fit. See the tutorial `fit/fitExclude.C`.
4244///
4245///
4246/// #### Warning when using the option "0"
4247///
4248/// When selecting the option "0", the fitted function is added to
4249/// the list of functions of the histogram, but it is not drawn when the histogram is drawn.
4250/// You can undo this behaviour resetting its corresponding bit in the TF1 object as following:
4251///
4252/// ~~~ {.cpp}
4253/// h.Fit("myFunction", "0"); // fit, store function but do not draw
4254/// h.Draw(); // function is not drawn
4255/// h.GetFunction("myFunction")->ResetBit(TF1::kNotDraw);
4256/// h.Draw(); // function is visible again
4257/// ~~~
4259
4261{
4262 // implementation of Fit method is in file hist/src/HFitImpl.cxx
4263 Foption_t fitOption;
4265
4266 // create range and minimizer options with default values
4267 ROOT::Fit::DataRange range(xxmin,xxmax);
4269
4270 // need to empty the buffer before
4271 // (t.b.d. do a ML unbinned fit with buffer data)
4272 if (fBuffer) BufferEmpty();
4273
4274 return ROOT::Fit::FitObject(this, f1 , fitOption , minOption, goption, range);
4275}
4276
4277////////////////////////////////////////////////////////////////////////////////
4278/// Display a panel with all histogram fit options.
4279///
4280/// See class TFitPanel for example
4281
4282void TH1::FitPanel()
4283{
4284 if (!gPad)
4285 gROOT->MakeDefCanvas();
4286
4287 if (!gPad) {
4288 Error("FitPanel", "Unable to create a default canvas");
4289 return;
4290 }
4291
4292
4293 // use plugin manager to create instance of TFitEditor
4294 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
4295 if (handler && handler->LoadPlugin() != -1) {
4296 if (handler->ExecPlugin(2, gPad, this) == 0)
4297 Error("FitPanel", "Unable to create the FitPanel");
4298 }
4299 else
4300 Error("FitPanel", "Unable to find the FitPanel plug-in");
4301}
4302
4303////////////////////////////////////////////////////////////////////////////////
4304/// Return a histogram containing the asymmetry of this histogram with h2,
4305/// where the asymmetry is defined as:
4306///
4307/// ~~~ {.cpp}
4308/// Asymmetry = (h1 - h2)/(h1 + h2) where h1 = this
4309/// ~~~
4310///
4311/// works for 1D, 2D, etc. histograms
4312/// c2 is an optional argument that gives a relative weight between the two
4313/// histograms, and dc2 is the error on this weight. This is useful, for example,
4314/// when forming an asymmetry between two histograms from 2 different data sets that
4315/// need to be normalized to each other in some way. The function calculates
4316/// the errors assuming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
4317///
4318/// example: assuming 'h1' and 'h2' are already filled
4319///
4320/// ~~~ {.cpp}
4321/// h3 = h1->GetAsymmetry(h2)
4322/// ~~~
4323///
4324/// then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
4325/// h1 and h2 are left intact.
4326///
4327/// Note that it is the user's responsibility to manage the created histogram.
4328/// The name of the returned histogram will be `Asymmetry_nameOfh1-nameOfh2`
4329///
4330/// code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
4331///
4332/// clone the histograms so top and bottom will have the
4333/// correct dimensions:
4334/// Sumw2 just makes sure the errors will be computed properly
4335/// when we form sums and ratios below.
4336
4338{
4339 TH1 *h1 = this;
4340 TString name = TString::Format("Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4341 TH1 *asym = (TH1*)Clone(name);
4342
4343 // set also the title
4344 TString title = TString::Format("(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4345 asym->SetTitle(title);
4346
4347 asym->Sumw2();
4348 Bool_t addStatus = TH1::AddDirectoryStatus();
4350 TH1 *top = (TH1*)asym->Clone();
4351 TH1 *bottom = (TH1*)asym->Clone();
4352 TH1::AddDirectory(addStatus);
4353
4354 // form the top and bottom of the asymmetry, and then divide:
4355 top->Add(h1,h2,1,-c2);
4356 bottom->Add(h1,h2,1,c2);
4357 asym->Divide(top,bottom);
4358
4359 Int_t xmax = asym->GetNbinsX();
4360 Int_t ymax = asym->GetNbinsY();
4361 Int_t zmax = asym->GetNbinsZ();
4362
4363 if (h1->fBuffer) h1->BufferEmpty(1);
4364 if (h2->fBuffer) h2->BufferEmpty(1);
4365 if (bottom->fBuffer) bottom->BufferEmpty(1);
4366
4367 // now loop over bins to calculate the correct errors
4368 // the reason this error calculation looks complex is because of c2
4369 for(Int_t i=1; i<= xmax; i++){
4370 for(Int_t j=1; j<= ymax; j++){
4371 for(Int_t k=1; k<= zmax; k++){
4372 Int_t bin = GetBin(i, j, k);
4373 // here some bin contents are written into variables to make the error
4374 // calculation a little more legible:
4376 Double_t b = h2->RetrieveBinContent(bin);
4377 Double_t bot = bottom->RetrieveBinContent(bin);
4378
4379 // make sure there are some events, if not, then the errors are set = 0
4380 // automatically.
4381 //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
4382 if(bot < 1e-6){}
4383 else{
4384 // computation of errors by Christos Leonidopoulos
4385 Double_t dasq = h1->GetBinErrorSqUnchecked(bin);
4386 Double_t dbsq = h2->GetBinErrorSqUnchecked(bin);
4387 Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4388 asym->SetBinError(i,j,k,error);
4389 }
4390 }
4391 }
4392 }
4393 delete top;
4394 delete bottom;
4395
4396 return asym;
4397}
4398
4399////////////////////////////////////////////////////////////////////////////////
4400/// Static function
4401/// return the default buffer size for automatic histograms
4402/// the parameter fgBufferSize may be changed via SetDefaultBufferSize
4403
4405{
4406 return fgBufferSize;
4407}
4408
4409////////////////////////////////////////////////////////////////////////////////
4410/// Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
4411/// see TH1::SetDefaultSumw2.
4412
4414{
4415 return fgDefaultSumw2;
4416}
4417
4418////////////////////////////////////////////////////////////////////////////////
4419/// Return the current number of entries.
4420
4422{
4423 if (fBuffer) {
4424 Int_t nentries = (Int_t) fBuffer[0];
4425 if (nentries > 0) return nentries;
4426 }
4427
4428 return fEntries;
4429}
4430
4431////////////////////////////////////////////////////////////////////////////////
4432/// Number of effective entries of the histogram.
4433///
4434/// \f[
4435/// neff = \frac{(\sum Weights )^2}{(\sum Weight^2 )}
4436/// \f]
4437///
4438/// In case of an unweighted histogram this number is equivalent to the
4439/// number of entries of the histogram.
4440/// For a weighted histogram, this number corresponds to the hypothetical number of unweighted entries
4441/// a histogram would need to have the same statistical power as this weighted histogram.
4442/// Note: The underflow/overflow are included if one has set the TH1::StatOverFlows flag
4443/// and if the statistics has been computed at filling time.
4444/// If a range is set in the histogram the number is computed from the given range.
4445
4447{
4448 Stat_t s[kNstat];
4449 this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
4450 return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4451}
4452
4453////////////////////////////////////////////////////////////////////////////////
4454/// Set highlight (enable/disable) mode for the histogram
4455/// by default highlight mode is disable
4456
4457void TH1::SetHighlight(Bool_t set)
4458{
4459 if (IsHighlight() == set)
4460 return;
4461 if (fDimension > 2) {
4462 Info("SetHighlight", "Supported only 1-D or 2-D histograms");
4463 return;
4464 }
4465
4466 SetBit(kIsHighlight, set);
4467
4468 if (fPainter)
4470}
4471
4472////////////////////////////////////////////////////////////////////////////////
4473/// Redefines TObject::GetObjectInfo.
4474/// Displays the histogram info (bin number, contents, integral up to bin
4475/// corresponding to cursor position px,py
4476
4477char *TH1::GetObjectInfo(Int_t px, Int_t py) const
4478{
4479 return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
4480}
4481
4482////////////////////////////////////////////////////////////////////////////////
4483/// Return pointer to painter.
4484/// If painter does not exist, it is created
4485
4487{
4488 if (!fPainter) {
4489 TString opt = option;
4490 opt.ToLower();
4491 if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
4492 //try to create TGLHistPainter
4493 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
4494
4495 if (handler && handler->LoadPlugin() != -1)
4496 fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
4497 }
4498 }
4499
4501
4502 return fPainter;
4503}
4504
4505////////////////////////////////////////////////////////////////////////////////
4506/// Compute Quantiles for this histogram
4507/// Quantile x_q of a probability distribution Function F is defined as
4508///
4509/// ~~~ {.cpp}
4510/// F(x_q) = q with 0 <= q <= 1.
4511/// ~~~
4512///
4513/// For instance the median x_0.5 of a distribution is defined as that value
4514/// of the random variable for which the distribution function equals 0.5:
4515///
4516/// ~~~ {.cpp}
4517/// F(x_0.5) = Probability(x < x_0.5) = 0.5
4518/// ~~~
4519///
4520/// code from Eddy Offermann, Renaissance
4521///
4522/// \param[in] nprobSum maximum size of array q and size of array probSum (if given)
4523/// \param[in] probSum array of positions where quantiles will be computed.
4524/// - if probSum is null, probSum will be computed internally and will
4525/// have a size = number of bins + 1 in h. it will correspond to the
4526/// quantiles calculated at the lowest edge of the histogram (quantile=0) and
4527/// all the upper edges of the bins.
4528/// - if probSum is not null, it is assumed to contain at least nprobSum values.
4529/// \param[out] q array q filled with nq quantiles
4530/// \return value nq (<=nprobSum) with the number of quantiles computed
4531///
4532/// Note that the Integral of the histogram is automatically recomputed
4533/// if the number of entries is different of the number of entries when
4534/// the integral was computed last time. In case you do not use the Fill
4535/// functions to fill your histogram, but SetBinContent, you must call
4536/// TH1::ComputeIntegral before calling this function.
4537///
4538/// Getting quantiles q from two histograms and storing results in a TGraph,
4539/// a so-called QQ-plot
4540///
4541/// ~~~ {.cpp}
4542/// TGraph *gr = new TGraph(nprob);
4543/// h1->GetQuantiles(nprob,gr->GetX());
4544/// h2->GetQuantiles(nprob,gr->GetY());
4545/// gr->Draw("alp");
4546/// ~~~
4547///
4548/// Example:
4549///
4550/// ~~~ {.cpp}
4551/// void quantiles() {
4552/// // demo for quantiles
4553/// const Int_t nq = 20;
4554/// TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
4555/// h->FillRandom("gaus",5000);
4556///
4557/// Double_t xq[nq]; // position where to compute the quantiles in [0,1]
4558/// Double_t yq[nq]; // array to contain the quantiles
4559/// for (Int_t i=0;i<nq;i++) xq[i] = Float_t(i+1)/nq;
4560/// h->GetQuantiles(nq,yq,xq);
4561///
4562/// //show the original histogram in the top pad
4563/// TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
4564/// c1->Divide(1,2);
4565/// c1->cd(1);
4566/// h->Draw();
4567///
4568/// // show the quantiles in the bottom pad
4569/// c1->cd(2);
4570/// gPad->SetGrid();
4571/// TGraph *gr = new TGraph(nq,xq,yq);
4572/// gr->SetMarkerStyle(21);
4573/// gr->Draw("alp");
4574/// }
4575/// ~~~
4576
4577Int_t TH1::GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
4578{
4579 if (GetDimension() > 1) {
4580 Error("GetQuantiles","Only available for 1-d histograms");
4581 return 0;
4582 }
4583
4584 const Int_t nbins = GetXaxis()->GetNbins();
4585 if (!fIntegral) ComputeIntegral();
4586 if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4587
4588 Int_t i, ibin;
4589 Double_t *prob = (Double_t*)probSum;
4590 Int_t nq = nprobSum;
4591 if (probSum == nullptr) {
4592 nq = nbins+1;
4593 prob = new Double_t[nq];
4594 prob[0] = 0;
4595 for (i=1;i<nq;i++) {
4596 prob[i] = fIntegral[i]/fIntegral[nbins];
4597 }
4598 }
4599
4600 for (i = 0; i < nq; i++) {
4601 ibin = TMath::BinarySearch(nbins,fIntegral,prob[i]);
4602 while (ibin < nbins-1 && fIntegral[ibin+1] == prob[i]) {
4603 if (fIntegral[ibin+2] == prob[i]) ibin++;
4604 else break;
4605 }
4606 q[i] = GetBinLowEdge(ibin+1);
4607 const Double_t dint = fIntegral[ibin+1]-fIntegral[ibin];
4608 if (dint > 0) q[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4609 }
4610
4611 if (!probSum) delete [] prob;
4612 return nq;
4613}
4614
4615////////////////////////////////////////////////////////////////////////////////
4616/// Decode string choptin and fill fitOption structure.
4617
4618Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
4619{
4621 return 1;
4622}
4623
4624////////////////////////////////////////////////////////////////////////////////
4625/// Compute Initial values of parameters for a gaussian.
4626
4627void H1InitGaus()
4628{
4629 Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4630 Int_t bin;
4631 const Double_t sqrtpi = 2.506628;
4632
4633 // - Compute mean value and StdDev of the histogram in the given range
4635 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4636 Int_t hxfirst = hFitter->GetXfirst();
4637 Int_t hxlast = hFitter->GetXlast();
4638 Double_t valmax = curHist->GetBinContent(hxfirst);
4639 Double_t binwidx = curHist->GetBinWidth(hxfirst);
4640 allcha = sumx = sumx2 = 0;
4641 for (bin=hxfirst;bin<=hxlast;bin++) {
4642 x = curHist->GetBinCenter(bin);
4643 val = TMath::Abs(curHist->GetBinContent(bin));
4644 if (val > valmax) valmax = val;
4645 sumx += val*x;
4646 sumx2 += val*x*x;
4647 allcha += val;
4648 }
4649 if (allcha == 0) return;
4650 mean = sumx/allcha;
4651 stddev = sumx2/allcha - mean*mean;
4652 if (stddev > 0) stddev = TMath::Sqrt(stddev);
4653 else stddev = 0;
4654 if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4655 //if the distribution is really gaussian, the best approximation
4656 //is binwidx*allcha/(sqrtpi*stddev)
4657 //However, in case of non-gaussian tails, this underestimates
4658 //the normalisation constant. In this case the maximum value
4659 //is a better approximation.
4660 //We take the average of both quantities
4661 Double_t constant = 0.5*(valmax+binwidx*allcha/(sqrtpi*stddev));
4662
4663 //In case the mean value is outside the histo limits and
4664 //the StdDev is bigger than the range, we take
4665 // mean = center of bins
4666 // stddev = half range
4667 Double_t xmin = curHist->GetXaxis()->GetXmin();
4668 Double_t xmax = curHist->GetXaxis()->GetXmax();
4669 if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4670 mean = 0.5*(xmax+xmin);
4671 stddev = 0.5*(xmax-xmin);
4672 }
4673 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4674 f1->SetParameter(0,constant);
4675 f1->SetParameter(1,mean);
4676 f1->SetParameter(2,stddev);
4677 f1->SetParLimits(2,0,10*stddev);
4678}
4679
4680////////////////////////////////////////////////////////////////////////////////
4681/// Compute Initial values of parameters for an exponential.
4682
4683void H1InitExpo()
4684{
4685 Double_t constant, slope;
4686 Int_t ifail;
4688 Int_t hxfirst = hFitter->GetXfirst();
4689 Int_t hxlast = hFitter->GetXlast();
4690 Int_t nchanx = hxlast - hxfirst + 1;
4691
4692 H1LeastSquareLinearFit(-nchanx, constant, slope, ifail);
4693
4694 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4695 f1->SetParameter(0,constant);
4696 f1->SetParameter(1,slope);
4697
4698}
4699
4700////////////////////////////////////////////////////////////////////////////////
4701/// Compute Initial values of parameters for a polynom.
4702
4703void H1InitPolynom()
4704{
4705 Double_t fitpar[25];
4706
4708 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4709 Int_t hxfirst = hFitter->GetXfirst();
4710 Int_t hxlast = hFitter->GetXlast();
4711 Int_t nchanx = hxlast - hxfirst + 1;
4712 Int_t npar = f1->GetNpar();
4713
4714 if (nchanx <=1 || npar == 1) {
4715 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4716 fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4717 } else {
4718 H1LeastSquareFit( nchanx, npar, fitpar);
4719 }
4720 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4721}
4722
4723////////////////////////////////////////////////////////////////////////////////
4724/// Least squares lpolynomial fitting without weights.
4725///
4726/// \param[in] n number of points to fit
4727/// \param[in] m number of parameters
4728/// \param[in] a array of parameters
4729///
4730/// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
4731/// (E.Keil. revised by B.Schorr, 23.10.1981.)
4732
4734{
4735 const Double_t zero = 0.;
4736 const Double_t one = 1.;
4737 const Int_t idim = 20;
4738
4739 Double_t b[400] /* was [20][20] */;
4740 Int_t i, k, l, ifail;
4741 Double_t power;
4742 Double_t da[20], xk, yk;
4743
4744 if (m <= 2) {
4745 H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4746 return;
4747 }
4748 if (m > idim || m > n) return;
4749 b[0] = Double_t(n);
4750 da[0] = zero;
4751 for (l = 2; l <= m; ++l) {
4752 b[l-1] = zero;
4753 b[m + l*20 - 21] = zero;
4754 da[l-1] = zero;
4755 }
4757 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4758 Int_t hxfirst = hFitter->GetXfirst();
4759 Int_t hxlast = hFitter->GetXlast();
4760 for (k = hxfirst; k <= hxlast; ++k) {
4761 xk = curHist->GetBinCenter(k);
4762 yk = curHist->GetBinContent(k);
4763 power = one;
4764 da[0] += yk;
4765 for (l = 2; l <= m; ++l) {
4766 power *= xk;
4767 b[l-1] += power;
4768 da[l-1] += power*yk;
4769 }
4770 for (l = 2; l <= m; ++l) {
4771 power *= xk;
4772 b[m + l*20 - 21] += power;
4773 }
4774 }
4775 for (i = 3; i <= m; ++i) {
4776 for (k = i; k <= m; ++k) {
4777 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4778 }
4779 }
4780 H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
4781
4782 for (i=0; i<m; ++i) a[i] = da[i];
4783
4784}
4785
4786////////////////////////////////////////////////////////////////////////////////
4787/// Least square linear fit without weights.
4788///
4789/// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
4790/// (added to LSQ by B. Schorr, 15.02.1982.)
4791
4792void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
4793{
4794 Double_t xbar, ybar, x2bar;
4795 Int_t i, n;
4796 Double_t xybar;
4797 Double_t fn, xk, yk;
4798 Double_t det;
4799
4800 n = TMath::Abs(ndata);
4801 ifail = -2;
4802 xbar = ybar = x2bar = xybar = 0;
4804 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4805 Int_t hxfirst = hFitter->GetXfirst();
4806 Int_t hxlast = hFitter->GetXlast();
4807 for (i = hxfirst; i <= hxlast; ++i) {
4808 xk = curHist->GetBinCenter(i);
4809 yk = curHist->GetBinContent(i);
4810 if (ndata < 0) {
4811 if (yk <= 0) yk = 1e-9;
4812 yk = TMath::Log(yk);
4813 }
4814 xbar += xk;
4815 ybar += yk;
4816 x2bar += xk*xk;
4817 xybar += xk*yk;
4818 }
4819 fn = Double_t(n);
4820 det = fn*x2bar - xbar*xbar;
4821 ifail = -1;
4822 if (det <= 0) {
4823 a0 = ybar/fn;
4824 a1 = 0;
4825 return;
4826 }
4827 ifail = 0;
4828 a0 = (x2bar*ybar - xbar*xybar) / det;
4829 a1 = (fn*xybar - xbar*ybar) / det;
4830
4831}
4832
4833////////////////////////////////////////////////////////////////////////////////
4834/// Extracted from CERN Program library routine DSEQN.
4835///
4836/// Translated to C++ by Rene Brun
4837
4838void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b)
4839{
4840 Int_t a_dim1, a_offset, b_dim1, b_offset;
4841 Int_t nmjp1, i, j, l;
4842 Int_t im1, jp1, nm1, nmi;
4843 Double_t s1, s21, s22;
4844 const Double_t one = 1.;
4845
4846 /* Parameter adjustments */
4847 b_dim1 = idim;
4848 b_offset = b_dim1 + 1;
4849 b -= b_offset;
4850 a_dim1 = idim;
4851 a_offset = a_dim1 + 1;
4852 a -= a_offset;
4853
4854 if (idim < n) return;
4855
4856 ifail = 0;
4857 for (j = 1; j <= n; ++j) {
4858 if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
4859 a[j + j*a_dim1] = one / a[j + j*a_dim1];
4860 if (j == n) continue;
4861 jp1 = j + 1;
4862 for (l = jp1; l <= n; ++l) {
4863 a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4864 s1 = -a[l + (j+1)*a_dim1];
4865 for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4866 a[l + (j+1)*a_dim1] = -s1;
4867 }
4868 }
4869 if (k <= 0) return;
4870
4871 for (l = 1; l <= k; ++l) {
4872 b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
4873 }
4874 if (n == 1) return;
4875 for (l = 1; l <= k; ++l) {
4876 for (i = 2; i <= n; ++i) {
4877 im1 = i - 1;
4878 s21 = -b[i + l*b_dim1];
4879 for (j = 1; j <= im1; ++j) {
4880 s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
4881 }
4882 b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
4883 }
4884 nm1 = n - 1;
4885 for (i = 1; i <= nm1; ++i) {
4886 nmi = n - i;
4887 s22 = -b[nmi + l*b_dim1];
4888 for (j = 1; j <= i; ++j) {
4889 nmjp1 = n - j + 1;
4890 s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
4891 }
4892 b[nmi + l*b_dim1] = -s22;
4893 }
4894 }
4895}
4896
4897////////////////////////////////////////////////////////////////////////////////
4898/// Return Global bin number corresponding to binx,y,z.
4899///
4900/// 2-D and 3-D histograms are represented with a one dimensional
4901/// structure.
4902/// This has the advantage that all existing functions, such as
4903/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
4904///
4905/// In case of a TH1x, returns binx directly.
4906/// see TH1::GetBinXYZ for the inverse transformation.
4907///
4908/// Convention for numbering bins
4909///
4910/// For all histogram types: nbins, xlow, xup
4911///
4912/// - bin = 0; underflow bin
4913/// - bin = 1; first bin with low-edge xlow INCLUDED
4914/// - bin = nbins; last bin with upper-edge xup EXCLUDED
4915/// - bin = nbins+1; overflow bin
4916///
4917/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4918/// For example, assuming a 3-D histogram with binx,biny,binz, the function
4919///
4920/// ~~~ {.cpp}
4921/// Int_t bin = h->GetBin(binx,biny,binz);
4922/// ~~~
4923///
4924/// returns a global/linearized bin number. This global bin is useful
4925/// to access the bin information independently of the dimension.
4926
4927Int_t TH1::GetBin(Int_t binx, Int_t, Int_t) const
4928{
4929 Int_t ofx = fXaxis.GetNbins() + 1; // overflow bin
4930 if (binx < 0) binx = 0;
4931 if (binx > ofx) binx = ofx;
4932
4933 return binx;
4934}
4935
4936////////////////////////////////////////////////////////////////////////////////
4937/// Return binx, biny, binz corresponding to the global bin number globalbin
4938/// see TH1::GetBin function above
4939
4940void TH1::GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz) const
4941{
4942 Int_t nx = fXaxis.GetNbins()+2;
4943 Int_t ny = fYaxis.GetNbins()+2;
4944
4945 if (GetDimension() == 1) {
4946 binx = binglobal%nx;
4947 biny = 0;
4948 binz = 0;
4949 return;
4950 }
4951 if (GetDimension() == 2) {
4952 binx = binglobal%nx;
4953 biny = ((binglobal-binx)/nx)%ny;
4954 binz = 0;
4955 return;
4956 }
4957 if (GetDimension() == 3) {
4958 binx = binglobal%nx;
4959 biny = ((binglobal-binx)/nx)%ny;
4960 binz = ((binglobal-binx)/nx -biny)/ny;
4961 }
4962}
4963
4964////////////////////////////////////////////////////////////////////////////////
4965/// Return a random number distributed according the histogram bin contents.
4966/// This function checks if the bins integral exists. If not, the integral
4967/// is evaluated, normalized to one.
4968///
4969/// @param rng (optional) Random number generator pointer used (default is gRandom)
4970///
4971/// The integral is automatically recomputed if the number of entries
4972/// is not the same then when the integral was computed.
4973/// NB Only valid for 1-d histograms. Use GetRandom2 or 3 otherwise.
4974/// If the histogram has a bin with negative content a NaN is returned
4975
4976Double_t TH1::GetRandom(TRandom * rng) const
4977{
4978 if (fDimension > 1) {
4979 Error("GetRandom","Function only valid for 1-d histograms");
4980 return 0;
4981 }
4982 Int_t nbinsx = GetNbinsX();
4983 Double_t integral = 0;
4984 // compute integral checking that all bins have positive content (see ROOT-5894)
4985 if (fIntegral) {
4986 if (fIntegral[nbinsx+1] != fEntries) integral = ((TH1*)this)->ComputeIntegral(true);
4987 else integral = fIntegral[nbinsx];
4988 } else {
4989 integral = ((TH1*)this)->ComputeIntegral(true);
4990 }
4991 if (integral == 0) return 0;
4992 // return a NaN in case some bins have negative content
4993 if (integral == TMath::QuietNaN() ) return TMath::QuietNaN();
4994
4995 Double_t r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
4996 Int_t ibin = TMath::BinarySearch(nbinsx,fIntegral,r1);
4997 Double_t x = GetBinLowEdge(ibin+1);
4998 if (r1 > fIntegral[ibin]) x +=
4999 GetBinWidth(ibin+1)*(r1-fIntegral[ibin])/(fIntegral[ibin+1] - fIntegral[ibin]);
5000 return x;
5001}
5002
5003////////////////////////////////////////////////////////////////////////////////
5004/// Return content of bin number bin.
5005///
5006/// Implemented in TH1C,S,F,D
5007///
5008/// Convention for numbering bins
5009///
5010/// For all histogram types: nbins, xlow, xup
5011///
5012/// - bin = 0; underflow bin
5013/// - bin = 1; first bin with low-edge xlow INCLUDED
5014/// - bin = nbins; last bin with upper-edge xup EXCLUDED
5015/// - bin = nbins+1; overflow bin
5016///
5017/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
5018/// For example, assuming a 3-D histogram with binx,biny,binz, the function
5019///
5020/// ~~~ {.cpp}
5021/// Int_t bin = h->GetBin(binx,biny,binz);
5022/// ~~~
5023///
5024/// returns a global/linearized bin number. This global bin is useful
5025/// to access the bin information independently of the dimension.
5026
5028{
5029 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
5030 if (bin < 0) bin = 0;
5031 if (bin >= fNcells) bin = fNcells-1;
5032
5033 return RetrieveBinContent(bin);
5034}
5035
5036////////////////////////////////////////////////////////////////////////////////
5037/// Compute first binx in the range [firstx,lastx] for which
5038/// diff = abs(bin_content-c) <= maxdiff
5039///
5040/// In case several bins in the specified range with diff=0 are found
5041/// the first bin found is returned in binx.
5042/// In case several bins in the specified range satisfy diff <=maxdiff
5043/// the bin with the smallest difference is returned in binx.
5044/// In all cases the function returns the smallest difference.
5045///
5046/// NOTE1: if firstx <= 0, firstx is set to bin 1
5047/// if (lastx < firstx then firstx is set to the number of bins
5048/// ie if firstx=0 and lastx=0 (default) the search is on all bins.
5049///
5050/// NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
5051
5052Double_t TH1::GetBinWithContent(Double_t c, Int_t &binx, Int_t firstx, Int_t lastx,Double_t maxdiff) const
5053{
5054 if (fDimension > 1) {
5055 binx = 0;
5056 Error("GetBinWithContent","function is only valid for 1-D histograms");
5057 return 0;
5058 }
5059
5060 if (fBuffer) ((TH1*)this)->BufferEmpty();
5061
5062 if (firstx <= 0) firstx = 1;
5063 if (lastx < firstx) lastx = fXaxis.GetNbins();
5064 Int_t binminx = 0;
5065 Double_t diff, curmax = 1.e240;
5066 for (Int_t i=firstx;i<=lastx;i++) {
5067 diff = TMath::Abs(RetrieveBinContent(i)-c);
5068 if (diff <= 0) {binx = i; return diff;}
5069 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
5070 }
5071 binx = binminx;
5072 return curmax;
5073}
5074
5075////////////////////////////////////////////////////////////////////////////////
5076/// Given a point x, approximates the value via linear interpolation
5077/// based on the two nearest bin centers
5078///
5079/// Andy Mastbaum 10/21/08
5080
5082{
5083 if (fBuffer) ((TH1*)this)->BufferEmpty();
5084
5085 Int_t xbin = fXaxis.FindFixBin(x);
5086 Double_t x0,x1,y0,y1;
5087
5088 if(x<=GetBinCenter(1)) {
5089 return RetrieveBinContent(1);
5090 } else if(x>=GetBinCenter(GetNbinsX())) {
5091 return RetrieveBinContent(GetNbinsX());
5092 } else {
5093 if(x<=GetBinCenter(xbin)) {
5094 y0 = RetrieveBinContent(xbin-1);
5095 x0 = GetBinCenter(xbin-1);
5096 y1 = RetrieveBinContent(xbin);
5097 x1 = GetBinCenter(xbin);
5098 } else {
5099 y0 = RetrieveBinContent(xbin);
5100 x0 = GetBinCenter(xbin);
5101 y1 = RetrieveBinContent(xbin+1);
5102 x1 = GetBinCenter(xbin+1);
5103 }
5104 return y0 + (x-x0)*((y1-y0)/(x1-x0));
5105 }
5106}
5107
5108////////////////////////////////////////////////////////////////////////////////
5109/// 2d Interpolation. Not yet implemented.
5110
5112{
5113 Error("Interpolate","This function must be called with 1 argument for a TH1");
5114 return 0;
5115}
5116
5117////////////////////////////////////////////////////////////////////////////////
5118/// 3d Interpolation. Not yet implemented.
5119
5121{
5122 Error("Interpolate","This function must be called with 1 argument for a TH1");
5123 return 0;
5124}
5125
5126///////////////////////////////////////////////////////////////////////////////
5127/// Check if a histogram is empty
5128/// (this is a protected method used mainly by TH1Merger )
5129
5130Bool_t TH1::IsEmpty() const
5131{
5132 // if fTsumw or fentries are not zero histogram is not empty
5133 // need to use GetEntries() instead of fEntries in case of bugger histograms
5134 // so we will flash the buffer
5135 if (fTsumw != 0) return kFALSE;
5136 if (GetEntries() != 0) return kFALSE;
5137 // case fTSumw == 0 amd entries are also zero
5138 // this should not really happening, but if one sets content by hand
5139 // it can happen. a call to ResetStats() should be done in such cases
5140 double sumw = 0;
5141 for (int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
5142 return (sumw != 0) ? kFALSE : kTRUE;
5143}
5144
5145////////////////////////////////////////////////////////////////////////////////
5146/// Return true if the bin is overflow.
5147
5148Bool_t TH1::IsBinOverflow(Int_t bin, Int_t iaxis) const
5149{
5150 Int_t binx, biny, binz;
5151 GetBinXYZ(bin, binx, biny, binz);
5152
5153 if (iaxis == 0) {
5154 if ( fDimension == 1 )
5155 return binx >= GetNbinsX() + 1;
5156 if ( fDimension == 2 )
5157 return (binx >= GetNbinsX() + 1) ||
5158 (biny >= GetNbinsY() + 1);
5159 if ( fDimension == 3 )
5160 return (binx >= GetNbinsX() + 1) ||
5161 (biny >= GetNbinsY() + 1) ||
5162 (binz >= GetNbinsZ() + 1);
5163 return kFALSE;
5164 }
5165 if (iaxis == 1)
5166 return binx >= GetNbinsX() + 1;
5167 if (iaxis == 2)
5168 return biny >= GetNbinsY() + 1;
5169 if (iaxis == 3)
5170 return binz >= GetNbinsZ() + 1;
5171
5172 Error("IsBinOverflow","Invalid axis value");
5173 return kFALSE;
5174}
5175
5176////////////////////////////////////////////////////////////////////////////////
5177/// Return true if the bin is underflow.
5178/// If iaxis = 0 make OR with all axes otherwise check only for the given axis
5179
5180Bool_t TH1::IsBinUnderflow(Int_t bin, Int_t iaxis) const
5181{
5182 Int_t binx, biny, binz;
5183 GetBinXYZ(bin, binx, biny, binz);
5184
5185 if (iaxis == 0) {
5186 if ( fDimension == 1 )
5187 return (binx <= 0);
5188 else if ( fDimension == 2 )
5189 return (binx <= 0 || biny <= 0);
5190 else if ( fDimension == 3 )
5191 return (binx <= 0 || biny <= 0 || binz <= 0);
5192 else
5193 return kFALSE;
5194 }
5195 if (iaxis == 1)
5196 return (binx <= 0);
5197 if (iaxis == 2)
5198 return (biny <= 0);
5199 if (iaxis == 3)
5200 return (binz <= 0);
5201
5202 Error("IsBinUnderflow","Invalid axis value");
5203 return kFALSE;
5204}
5205
5206////////////////////////////////////////////////////////////////////////////////
5207/// Reduce the number of bins for the axis passed in the option to the number of bins having a label.
5208/// The method will remove only the extra bins existing after the last "labeled" bin.
5209/// Note that if there are "un-labeled" bins present between "labeled" bins they will not be removed
5210
5212{
5213 Int_t iaxis = AxisChoice(ax);
5214 TAxis *axis = nullptr;
5215 if (iaxis == 1) axis = GetXaxis();
5216 if (iaxis == 2) axis = GetYaxis();
5217 if (iaxis == 3) axis = GetZaxis();
5218 if (!axis) {
5219 Error("LabelsDeflate","Invalid axis option %s",ax);
5220 return;
5221 }
5222 if (!axis->GetLabels()) return;
5223
5224 // find bin with last labels
5225 // bin number is object ID in list of labels
5226 // therefore max bin number is number of bins of the deflated histograms
5227 TIter next(axis->GetLabels());
5228 TObject *obj;
5229 Int_t nbins = 0;
5230 while ((obj = next())) {
5231 Int_t ibin = obj->GetUniqueID();
5232 if (ibin > nbins) nbins = ibin;
5233 }
5234 if (nbins < 1) nbins = 1;
5235
5236 // Do nothing in case it was the last bin
5237 if (nbins==axis->GetNbins()) return;
5238
5239 TH1 *hold = (TH1*)IsA()->New();
5240 R__ASSERT(hold);
5241 hold->SetDirectory(nullptr);
5242 Copy(*hold);
5243
5244 Bool_t timedisp = axis->GetTimeDisplay();
5245 Double_t xmin = axis->GetXmin();
5246 Double_t xmax = axis->GetBinUpEdge(nbins);
5247 if (xmax <= xmin) xmax = xmin +nbins;
5248 axis->SetRange(0,0);
5249 axis->Set(nbins,xmin,xmax);
5250 SetBinsLength(-1); // reset the number of cells
5251 Int_t errors = fSumw2.fN;
5252 if (errors) fSumw2.Set(fNcells);
5253 axis->SetTimeDisplay(timedisp);
5254 // reset histogram content
5255 Reset("ICE");
5256
5257 //now loop on all bins and refill
5258 // NOTE that if the bins without labels have content
5259 // it will be put in the underflow/overflow.
5260 // For this reason we use AddBinContent method
5261 Double_t oldEntries = fEntries;
5262 Int_t bin,binx,biny,binz;
5263 for (bin=0; bin < hold->fNcells; ++bin) {
5264 hold->GetBinXYZ(bin,binx,biny,binz);
5265 Int_t ibin = GetBin(binx,biny,binz);
5266 Double_t cu = hold->RetrieveBinContent(bin);
5267 AddBinContent(ibin,cu);
5268 if (errors) {
5269 fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5270 }
5271 }
5272 fEntries = oldEntries;
5273 delete hold;
5274}
5275
5276////////////////////////////////////////////////////////////////////////////////
5277/// Double the number of bins for axis.
5278/// Refill histogram.
5279/// This function is called by TAxis::FindBin(const char *label)
5280
5282{
5283 Int_t iaxis = AxisChoice(ax);
5284 TAxis *axis = nullptr;
5285 if (iaxis == 1) axis = GetXaxis();
5286 if (iaxis == 2) axis = GetYaxis();
5287 if (iaxis == 3) axis = GetZaxis();
5288 if (!axis) return;
5289
5290 TH1 *hold = (TH1*)IsA()->New();
5291 hold->SetDirectory(nullptr);
5292 Copy(*hold);
5293 hold->ResetBit(kMustCleanup);
5294
5295 Bool_t timedisp = axis->GetTimeDisplay();
5296 Int_t nbins = axis->GetNbins();
5297 Double_t xmin = axis->GetXmin();
5298 Double_t xmax = axis->GetXmax();
5299 xmax = xmin + 2*(xmax-xmin);
5300 axis->SetRange(0,0);
5301 // double the bins and recompute ncells
5302 axis->Set(2*nbins,xmin,xmax);
5303 SetBinsLength(-1);
5304 Int_t errors = fSumw2.fN;
5305 if (errors) fSumw2.Set(fNcells);
5306 axis->SetTimeDisplay(timedisp);
5307
5308 Reset("ICE"); // reset content and error
5309
5310 //now loop on all bins and refill
5311 Double_t oldEntries = fEntries;
5312 Int_t bin,ibin,binx,biny,binz;
5313 for (ibin =0; ibin < hold->fNcells; ibin++) {
5314 // get the binx,y,z values . The x-y-z (axis) bin values will stay the same between new-old after the expanding
5315 hold->GetBinXYZ(ibin,binx,biny,binz);
5316 bin = GetBin(binx,biny,binz);
5317
5318 // underflow and overflow will be cleaned up because their meaning has been altered
5319 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5320 continue;
5321 }
5322 else {
5323 AddBinContent(bin, hold->RetrieveBinContent(ibin));
5324 if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5325 }
5326 }
5327 fEntries = oldEntries;
5328 delete hold;
5329}
5330
5331////////////////////////////////////////////////////////////////////////////////
5332/// Sort bins with labels or set option(s) to draw axis with labels
5333/// \param[in] option
5334/// - "a" sort by alphabetic order
5335/// - ">" sort by decreasing values
5336/// - "<" sort by increasing values
5337/// - "h" draw labels horizontal
5338/// - "v" draw labels vertical
5339/// - "u" draw labels up (end of label right adjusted)
5340/// - "d" draw labels down (start of label left adjusted)
5341///
5342/// In case not all bins have labels sorting will work only in the case
5343/// the first `n` consecutive bins have all labels and sorting will be performed on
5344/// those label bins.
5345///
5346/// \param[in] ax axis
5347
5349{
5350 Int_t iaxis = AxisChoice(ax);
5351 TAxis *axis = nullptr;
5352 if (iaxis == 1)
5353 axis = GetXaxis();
5354 if (iaxis == 2)
5355 axis = GetYaxis();
5356 if (iaxis == 3)
5357 axis = GetZaxis();
5358 if (!axis)
5359 return;
5360 THashList *labels = axis->GetLabels();
5361 if (!labels) {
5362 Warning("LabelsOption", "Axis %s has no labels!",axis->GetName());
5363 return;
5364 }
5365 TString opt = option;
5366 opt.ToLower();
5367 Int_t iopt = -1;
5368 if (opt.Contains("h")) {
5373 iopt = 0;
5374 }
5375 if (opt.Contains("v")) {
5380 iopt = 1;
5381 }
5382 if (opt.Contains("u")) {
5383 axis->SetBit(TAxis::kLabelsUp);
5387 iopt = 2;
5388 }
5389 if (opt.Contains("d")) {
5394 iopt = 3;
5395 }
5396 Int_t sort = -1;
5397 if (opt.Contains("a"))
5398 sort = 0;
5399 if (opt.Contains(">"))
5400 sort = 1;
5401 if (opt.Contains("<"))
5402 sort = 2;
5403 if (sort < 0) {
5404 if (iopt < 0)
5405 Error("LabelsOption", "%s is an invalid label placement option!",opt.Data());
5406 return;
5407 }
5408
5409 // Code works only if first n bins have labels if we uncomment following line
5410 // but we don't want to support this special case
5411 // Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5412
5413 // support only cases where each bin has a labels (should be when axis is alphanumeric)
5414 Int_t n = labels->GetSize();
5415 if (n != axis->GetNbins()) {
5416 // check if labels are all consecutive and starts from the first bin
5417 // in that case the current code will work fine
5418 Int_t firstLabelBin = axis->GetNbins()+1;
5419 Int_t lastLabelBin = -1;
5420 for (Int_t i = 0; i < n; ++i) {
5421 Int_t bin = labels->At(i)->GetUniqueID();
5422 if (bin < firstLabelBin) firstLabelBin = bin;
5423 if (bin > lastLabelBin) lastLabelBin = bin;
5424 }
5425 if (firstLabelBin != 1 || lastLabelBin-firstLabelBin +1 != n) {
5426 Error("LabelsOption", "%s of Histogram %s contains bins without labels. Sorting will not work correctly - return",
5427 axis->GetName(), GetName());
5428 return;
5429 }
5430 // case where label bins are consecutive starting from first bin will work
5431 // calling before a TH1::LabelsDeflate() will avoid this error message
5432 Warning("LabelsOption", "axis %s of Histogram %s has extra following bins without labels. Sorting will work only for first label bins",
5433 axis->GetName(), GetName());
5434 }
5435 std::vector<Int_t> a(n);
5436 std::vector<Int_t> b(n);
5437
5438
5439 Int_t i, j, k;
5440 std::vector<Double_t> cont;
5441 std::vector<Double_t> errors2;
5442 THashList *labold = new THashList(labels->GetSize(), 1);
5443 TIter nextold(labels);
5444 TObject *obj = nullptr;
5445 labold->AddAll(labels);
5446 labels->Clear();
5447
5448 // delete buffer if it is there since bins will be reordered.
5449 if (fBuffer)
5450 BufferEmpty(1);
5451
5452 if (sort > 0) {
5453 //---sort by values of bins
5454 if (GetDimension() == 1) {
5455 cont.resize(n);
5456 if (fSumw2.fN)
5457 errors2.resize(n);
5458 for (i = 0; i < n; i++) {
5459 cont[i] = RetrieveBinContent(i + 1);
5460 if (!errors2.empty())
5461 errors2[i] = GetBinErrorSqUnchecked(i + 1);
5462 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5463 a[i] = i;
5464 }
5465 if (sort == 1)
5466 TMath::Sort(n, cont.data(), a.data(), kTRUE); // sort by decreasing values
5467 else
5468 TMath::Sort(n, cont.data(), a.data(), kFALSE); // sort by increasing values
5469 for (i = 0; i < n; i++) {
5470 // use UpdateBinCOntent to not screw up histogram entries
5471 UpdateBinContent(i + 1, cont[b[a[i]] - 1]); // b[a[i]] returns bin number. .we need to subtract 1
5472 if (gDebug)
5473 Info("LabelsOption","setting bin %d value %f from bin %d label %s at pos %d ",
5474 i+1,cont[b[a[i]] - 1],b[a[i]],labold->At(a[i])->GetName(),a[i]);
5475 if (!errors2.empty())
5476 fSumw2.fArray[i + 1] = errors2[b[a[i]] - 1];
5477 }
5478 for (i = 0; i < n; i++) {
5479 obj = labold->At(a[i]);
5480 labels->Add(obj);
5481 obj->SetUniqueID(i + 1);
5482 }
5483 } else if (GetDimension() == 2) {
5484 std::vector<Double_t> pcont(n + 2);
5485 Int_t nx = fXaxis.GetNbins() + 2;
5486 Int_t ny = fYaxis.GetNbins() + 2;
5487 cont.resize((nx + 2) * (ny + 2));
5488 if (fSumw2.fN)
5489 errors2.resize((nx + 2) * (ny + 2));
5490 for (i = 0; i < nx; i++) {
5491 for (j = 0; j < ny; j++) {
5492 Int_t bin = GetBin(i,j);
5493 cont[i + nx * j] = RetrieveBinContent(bin);
5494 if (!errors2.empty())
5495 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5496 if (axis == GetXaxis())
5497 k = i - 1;
5498 else
5499 k = j - 1;
5500 if (k >= 0 && k < n) { // we consider underflow/overflows in y for ordering the bins
5501 pcont[k] += cont[i + nx * j];
5502 a[k] = k;
5503 }
5504 }
5505 }
5506 if (sort == 1)
5507 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5508 else
5509 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5510 for (i = 0; i < n; i++) {
5511 // iterate on old label list to find corresponding bin match
5512 TIter next(labold);
5513 UInt_t bin = a[i] + 1;
5514 while ((obj = next())) {
5515 if (obj->GetUniqueID() == (UInt_t)bin)
5516 break;
5517 else
5518 obj = nullptr;
5519 }
5520 if (!obj) {
5521 // this should not really happen
5522 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5523 return;
5524 }
5525
5526 labels->Add(obj);
5527 if (gDebug)
5528 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from order " << a[i] << " bin "
5529 << b[a[i]] << "content " << pcont[a[i]] << std::endl;
5530 }
5531 // need to set here new ordered labels - otherwise loop before does not work since labold and labels list
5532 // contain same objects
5533 for (i = 0; i < n; i++) {
5534 labels->At(i)->SetUniqueID(i + 1);
5535 }
5536 // set now the bin contents
5537 if (axis == GetXaxis()) {
5538 for (i = 0; i < n; i++) {
5539 Int_t ix = a[i] + 1;
5540 for (j = 0; j < ny; j++) {
5541 Int_t bin = GetBin(i + 1, j);
5542 UpdateBinContent(bin, cont[ix + nx * j]);
5543 if (!errors2.empty())
5544 fSumw2.fArray[bin] = errors2[ix + nx * j];
5545 }
5546 }
5547 } else {
5548 // using y axis
5549 for (i = 0; i < nx; i++) {
5550 for (j = 0; j < n; j++) {
5551 Int_t iy = a[j] + 1;
5552 Int_t bin = GetBin(i, j + 1);
5553 UpdateBinContent(bin, cont[i + nx * iy]);
5554 if (!errors2.empty())
5555 fSumw2.fArray[bin] = errors2[i + nx * iy];
5556 }
5557 }
5558 }
5559 } else {
5560 // sorting histograms: 3D case
5561 std::vector<Double_t> pcont(n + 2);
5562 Int_t nx = fXaxis.GetNbins() + 2;
5563 Int_t ny = fYaxis.GetNbins() + 2;
5564 Int_t nz = fZaxis.GetNbins() + 2;
5565 Int_t l = 0;
5566 cont.resize((nx + 2) * (ny + 2) * (nz + 2));
5567 if (fSumw2.fN)
5568 errors2.resize((nx + 2) * (ny + 2) * (nz + 2));
5569 for (i = 0; i < nx; i++) {
5570 for (j = 0; j < ny; j++) {
5571 for (k = 0; k < nz; k++) {
5572 Int_t bin = GetBin(i,j,k);
5574 if (axis == GetXaxis())
5575 l = i - 1;
5576 else if (axis == GetYaxis())
5577 l = j - 1;
5578 else
5579 l = k - 1;
5580 if (l >= 0 && l < n) { // we consider underflow/overflows in y for ordering the bins
5581 pcont[l] += c;
5582 a[l] = l;
5583 }
5584 cont[i + nx * (j + ny * k)] = c;
5585 if (!errors2.empty())
5586 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5587 }
5588 }
5589 }
5590 if (sort == 1)
5591 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5592 else
5593 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5594 for (i = 0; i < n; i++) {
5595 // iterate on the old label list to find corresponding bin match
5596 TIter next(labold);
5597 UInt_t bin = a[i] + 1;
5598 obj = nullptr;
5599 while ((obj = next())) {
5600 if (obj->GetUniqueID() == (UInt_t)bin) {
5601 break;
5602 }
5603 else
5604 obj = nullptr;
5605 }
5606 if (!obj) {
5607 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5608 return;
5609 }
5610 labels->Add(obj);
5611 if (gDebug)
5612 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from bin " << a[i] << "content "
5613 << pcont[a[i]] << std::endl;
5614 }
5615
5616 // need to set here new ordered labels - otherwise loop before does not work since labold and llabels list
5617 // contain same objects
5618 for (i = 0; i < n; i++) {
5619 labels->At(i)->SetUniqueID(i + 1);
5620 }
5621 // set now the bin contents
5622 if (axis == GetXaxis()) {
5623 for (i = 0; i < n; i++) {
5624 Int_t ix = a[i] + 1;
5625 for (j = 0; j < ny; j++) {
5626 for (k = 0; k < nz; k++) {
5627 Int_t bin = GetBin(i + 1, j, k);
5628 UpdateBinContent(bin, cont[ix + nx * (j + ny * k)]);
5629 if (!errors2.empty())
5630 fSumw2.fArray[bin] = errors2[ix + nx * (j + ny * k)];
5631 }
5632 }
5633 }
5634 } else if (axis == GetYaxis()) {
5635 // using y axis
5636 for (i = 0; i < nx; i++) {
5637 for (j = 0; j < n; j++) {
5638 Int_t iy = a[j] + 1;
5639 for (k = 0; k < nz; k++) {
5640 Int_t bin = GetBin(i, j + 1, k);
5641 UpdateBinContent(bin, cont[i + nx * (iy + ny * k)]);
5642 if (!errors2.empty())
5643 fSumw2.fArray[bin] = errors2[i + nx * (iy + ny * k)];
5644 }
5645 }
5646 }
5647 } else {
5648 // using z axis
5649 for (i = 0; i < nx; i++) {
5650 for (j = 0; j < ny; j++) {
5651 for (k = 0; k < n; k++) {
5652 Int_t iz = a[k] + 1;
5653 Int_t bin = GetBin(i, j , k +1);
5654 UpdateBinContent(bin, cont[i + nx * (j + ny * iz)]);
5655 if (!errors2.empty())
5656 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * iz)];
5657 }
5658 }
5659 }
5660 }
5661 }
5662 } else {
5663 //---alphabetic sort
5664 // sort labels using vector of strings and TMath::Sort
5665 // I need to array because labels order in list is not necessary that of the bins
5666 std::vector<std::string> vecLabels(n);
5667 for (i = 0; i < n; i++) {
5668 vecLabels[i] = labold->At(i)->GetName();
5669 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5670 a[i] = i;
5671 }
5672 // sort in ascending order for strings
5673 TMath::Sort(n, vecLabels.data(), a.data(), kFALSE);
5674 // set the new labels
5675 for (i = 0; i < n; i++) {
5676 TObject *labelObj = labold->At(a[i]);
5677 labels->Add(labold->At(a[i]));
5678 // set the corresponding bin. NB bin starts from 1
5679 labelObj->SetUniqueID(i + 1);
5680 if (gDebug)
5681 std::cout << "bin " << i + 1 << " setting new labels for axis " << labold->At(a[i])->GetName() << " from "
5682 << b[a[i]] << std::endl;
5683 }
5684
5685 if (GetDimension() == 1) {
5686 cont.resize(n + 2);
5687 if (fSumw2.fN)
5688 errors2.resize(n + 2);
5689 for (i = 0; i < n; i++) {
5690 cont[i] = RetrieveBinContent(b[a[i]]);
5691 if (!errors2.empty())
5692 errors2[i] = GetBinErrorSqUnchecked(b[a[i]]);
5693 }
5694 for (i = 0; i < n; i++) {
5695 UpdateBinContent(i + 1, cont[i]);
5696 if (!errors2.empty())
5697 fSumw2.fArray[i+1] = errors2[i];
5698 }
5699 } else if (GetDimension() == 2) {
5700 Int_t nx = fXaxis.GetNbins() + 2;
5701 Int_t ny = fYaxis.GetNbins() + 2;
5702 cont.resize(nx * ny);
5703 if (fSumw2.fN)
5704 errors2.resize(nx * ny);
5705 // copy old bin contents and then set to new ordered bins
5706 // N.B. bin in histograms starts from 1, but in y we consider under/overflows
5707 for (i = 0; i < nx; i++) {
5708 for (j = 0; j < ny; j++) { // ny is nbins+2
5709 Int_t bin = GetBin(i, j);
5710 cont[i + nx * j] = RetrieveBinContent(bin);
5711 if (!errors2.empty())
5712 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5713 }
5714 }
5715 if (axis == GetXaxis()) {
5716 for (i = 0; i < n; i++) {
5717 for (j = 0; j < ny; j++) {
5718 Int_t bin = GetBin(i + 1 , j);
5719 UpdateBinContent(bin, cont[b[a[i]] + nx * j]);
5720 if (!errors2.empty())
5721 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * j];
5722 }
5723 }
5724 } else {
5725 for (i = 0; i < nx; i++) {
5726 for (j = 0; j < n; j++) {
5727 Int_t bin = GetBin(i, j + 1);
5728 UpdateBinContent(bin, cont[i + nx * b[a[j]]]);
5729 if (!errors2.empty())
5730 fSumw2.fArray[bin] = errors2[i + nx * b[a[j]]];
5731 }
5732 }
5733 }
5734 } else {
5735 // case of 3D (needs to be tested)
5736 Int_t nx = fXaxis.GetNbins() + 2;
5737 Int_t ny = fYaxis.GetNbins() + 2;
5738 Int_t nz = fZaxis.GetNbins() + 2;
5739 cont.resize(nx * ny * nz);
5740 if (fSumw2.fN)
5741 errors2.resize(nx * ny * nz);
5742 for (i = 0; i < nx; i++) {
5743 for (j = 0; j < ny; j++) {
5744 for (k = 0; k < nz; k++) {
5745 Int_t bin = GetBin(i, j, k);
5746 cont[i + nx * (j + ny * k)] = RetrieveBinContent(bin);
5747 if (!errors2.empty())
5748 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5749 }
5750 }
5751 }
5752 if (axis == GetXaxis()) {
5753 // labels on x axis
5754 for (i = 0; i < n; i++) { // for x we loop only on bins with the labels
5755 for (j = 0; j < ny; j++) {
5756 for (k = 0; k < nz; k++) {
5757 Int_t bin = GetBin(i + 1, j, k);
5758 UpdateBinContent(bin, cont[b[a[i]] + nx * (j + ny * k)]);
5759 if (!errors2.empty())
5760 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * (j + ny * k)];
5761 }
5762 }
5763 }
5764 } else if (axis == GetYaxis()) {
5765 // labels on y axis
5766 for (i = 0; i < nx; i++) {
5767 for (j = 0; j < n; j++) {
5768 for (k = 0; k < nz; k++) {
5769 Int_t bin = GetBin(i, j+1, k);
5770 UpdateBinContent(bin, cont[i + nx * (b[a[j]] + ny * k)]);
5771 if (!errors2.empty())
5772 fSumw2.fArray[bin] = errors2[i + nx * (b[a[j]] + ny * k)];
5773 }
5774 }
5775 }
5776 } else {
5777 // labels on z axis
5778 for (i = 0; i < nx; i++) {
5779 for (j = 0; j < ny; j++) {
5780 for (k = 0; k < n; k++) {
5781 Int_t bin = GetBin(i, j, k+1);
5782 UpdateBinContent(bin, cont[i + nx * (j + ny * b[a[k]])]);
5783 if (!errors2.empty())
5784 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * b[a[k]])];
5785 }
5786 }
5787 }
5788 }
5789 }
5790 }
5791 // need to set to zero the statistics if axis has been sorted
5792 // see for example TH3::PutStats for definition of s vector
5793 bool labelsAreSorted = kFALSE;
5794 for (i = 0; i < n; ++i) {
5795 if (a[i] != i) {
5796 labelsAreSorted = kTRUE;
5797 break;
5798 }
5799 }
5800 if (labelsAreSorted) {
5801 double s[TH1::kNstat];
5802 GetStats(s);
5803 if (iaxis == 1) {
5804 s[2] = 0; // fTsumwx
5805 s[3] = 0; // fTsumwx2
5806 s[6] = 0; // fTsumwxy
5807 s[9] = 0; // fTsumwxz
5808 } else if (iaxis == 2) {
5809 s[4] = 0; // fTsumwy
5810 s[5] = 0; // fTsumwy2
5811 s[6] = 0; // fTsumwxy
5812 s[10] = 0; // fTsumwyz
5813 } else if (iaxis == 3) {
5814 s[7] = 0; // fTsumwz
5815 s[8] = 0; // fTsumwz2
5816 s[9] = 0; // fTsumwxz
5817 s[10] = 0; // fTsumwyz
5818 }
5819 PutStats(s);
5820 }
5821 delete labold;
5822}
5823
5824////////////////////////////////////////////////////////////////////////////////
5825/// Test if two double are almost equal.
5826
5827static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5828{
5829 return TMath::Abs(a - b) < epsilon;
5830}
5831
5832////////////////////////////////////////////////////////////////////////////////
5833/// Test if a double is almost an integer.
5834
5835static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5836{
5837 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5838 AlmostEqual(a - TMath::Floor(a), 1, epsilon);
5839}
5840
5841////////////////////////////////////////////////////////////////////////////////
5842/// Test if the binning is equidistant.
5843
5844static inline bool IsEquidistantBinning(const TAxis& axis)
5845{
5846 // check if axis bin are equals
5847 if (!axis.GetXbins()->fN) return true; //
5848 // not able to check if there is only one axis entry
5849 bool isEquidistant = true;
5850 const Double_t firstBinWidth = axis.GetBinWidth(1);
5851 for (int i = 1; i < axis.GetNbins(); ++i) {
5852 const Double_t binWidth = axis.GetBinWidth(i);
5853 const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5854 isEquidistant &= match;
5855 if (!match)
5856 break;
5857 }
5858 return isEquidistant;
5859}
5860
5861////////////////////////////////////////////////////////////////////////////////
5862/// Same limits and bins.
5863
5864Bool_t TH1::SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2){
5865 return axis1.GetNbins() == axis2.GetNbins() &&
5866 TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
5867 TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
5868}
5869
5870////////////////////////////////////////////////////////////////////////////////
5871/// Finds new limits for the axis for the Merge function.
5872/// returns false if the limits are incompatible
5873
5874Bool_t TH1::RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
5875{
5876 if (SameLimitsAndNBins(destAxis, anAxis))
5877 return kTRUE;
5878
5879 if (!IsEquidistantBinning(destAxis) || !IsEquidistantBinning(anAxis))
5880 return kFALSE; // not equidistant user binning not supported
5881
5882 Double_t width1 = destAxis.GetBinWidth(0);
5883 Double_t width2 = anAxis.GetBinWidth(0);
5884 if (width1 == 0 || width2 == 0)
5885 return kFALSE; // no binning not supported
5886
5887 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
5888 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
5889 Double_t width = TMath::Max(width1, width2);
5890
5891 // check the bin size
5892 if (!AlmostInteger(width/width1) || !AlmostInteger(width/width2))
5893 return kFALSE;
5894
5895 // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
5896 // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
5897
5898
5899 // check the limits
5900 Double_t delta;
5901 delta = (destAxis.GetXmin() - xmin)/width1;
5902 if (!AlmostInteger(delta))
5903 xmin -= (TMath::Ceil(delta) - delta)*width1;
5904
5905 delta = (anAxis.GetXmin() - xmin)/width2;
5906 if (!AlmostInteger(delta))
5907 xmin -= (TMath::Ceil(delta) - delta)*width2;
5908
5909
5910 delta = (destAxis.GetXmin() - xmin)/width1;
5911 if (!AlmostInteger(delta))
5912 return kFALSE;
5913
5914
5915 delta = (xmax - destAxis.GetXmax())/width1;
5916 if (!AlmostInteger(delta))
5917 xmax += (TMath::Ceil(delta) - delta)*width1;
5918
5919
5920 delta = (xmax - anAxis.GetXmax())/width2;
5921 if (!AlmostInteger(delta))
5922 xmax += (TMath::Ceil(delta) - delta)*width2;
5923
5924
5925 delta = (xmax - destAxis.GetXmax())/width1;
5926 if (!AlmostInteger(delta))
5927 return kFALSE;
5928#ifdef DEBUG
5929 if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
5930 printf("TH1::RecomputeAxisLimits - Impossible\n");
5931 return kFALSE;
5932 }
5933#endif
5934
5935
5936 destAxis.Set(TMath::Nint((xmax - xmin)/width), xmin, xmax);
5937
5938 //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
5939
5940 return kTRUE;
5941}
5942
5943////////////////////////////////////////////////////////////////////////////////
5944/// Add all histograms in the collection to this histogram.
5945/// This function computes the min/max for the x axis,
5946/// compute a new number of bins, if necessary,
5947/// add bin contents, errors and statistics.
5948/// If all histograms have bin labels, bins with identical labels
5949/// will be merged, no matter what their order is.
5950/// If overflows are present and limits are different the function will fail.
5951/// The function returns the total number of entries in the result histogram
5952/// if the merge is successful, -1 otherwise.
5953///
5954/// Possible option:
5955/// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
5956/// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
5957/// (enabled by default) slows down the merging
5958///
5959/// IMPORTANT remark. The axis x may have different number
5960/// of bins and different limits, BUT the largest bin width must be
5961/// a multiple of the smallest bin width and the upper limit must also
5962/// be a multiple of the bin width.
5963/// Example:
5964///
5965/// ~~~ {.cpp}
5966/// void atest() {
5967/// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
5968/// TH1F *h2 = new TH1F("h2","h2",220,0,110);
5969/// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
5970/// TRandom r;
5971/// for (Int_t i=0;i<10000;i++) {
5972/// h1->Fill(r.Gaus(-55,10));
5973/// h2->Fill(r.Gaus(55,10));
5974/// h3->Fill(r.Gaus(0,10));
5975/// }
5976///
5977/// TList *list = new TList;
5978/// list->Add(h1);
5979/// list->Add(h2);
5980/// list->Add(h3);
5981/// TH1F *h = (TH1F*)h1->Clone("h");
5982/// h->Reset();
5983/// h->Merge(list);
5984/// h->Draw();
5985/// }
5986/// ~~~
5987
5989{
5990 if (!li) return 0;
5991 if (li->IsEmpty()) return (Long64_t) GetEntries();
5992
5993 // use TH1Merger class
5994 TH1Merger merger(*this,*li,opt);
5995 Bool_t ret = merger();
5996
5997 return (ret) ? GetEntries() : -1;
5998}
5999
6000
6001////////////////////////////////////////////////////////////////////////////////
6002/// Performs the operation:
6003///
6004/// `this = this*c1*f1`
6005///
6006/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
6007///
6008/// Only bins inside the function range are recomputed.
6009/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6010/// you should call Sumw2 before making this operation.
6011/// This is particularly important if you fit the histogram after TH1::Multiply
6012///
6013/// The function return kFALSE if the Multiply operation failed
6014
6016{
6017 if (!f1) {
6018 Error("Multiply","Attempt to multiply by a non-existing function");
6019 return kFALSE;
6020 }
6021
6022 // delete buffer if it is there since it will become invalid
6023 if (fBuffer) BufferEmpty(1);
6024
6025 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
6026 Int_t ny = GetNbinsY() + 2;
6027 Int_t nz = GetNbinsZ() + 2;
6028 if (fDimension < 2) ny = 1;
6029 if (fDimension < 3) nz = 1;
6030
6031 // reset min-maximum
6032 SetMinimum();
6033 SetMaximum();
6034
6035 // - Loop on bins (including underflows/overflows)
6036 Double_t xx[3];
6037 Double_t *params = nullptr;
6038 f1->InitArgs(xx,params);
6039
6040 for (Int_t binz = 0; binz < nz; ++binz) {
6041 xx[2] = fZaxis.GetBinCenter(binz);
6042 for (Int_t biny = 0; biny < ny; ++biny) {
6043 xx[1] = fYaxis.GetBinCenter(biny);
6044 for (Int_t binx = 0; binx < nx; ++binx) {
6045 xx[0] = fXaxis.GetBinCenter(binx);
6046 if (!f1->IsInside(xx)) continue;
6048 Int_t bin = binx + nx * (biny + ny *binz);
6049 Double_t cu = c1*f1->EvalPar(xx);
6050 if (TF1::RejectedPoint()) continue;
6051 UpdateBinContent(bin, RetrieveBinContent(bin) * cu);
6052 if (fSumw2.fN) {
6053 fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
6054 }
6055 }
6056 }
6057 }
6058 ResetStats();
6059 return kTRUE;
6060}
6061
6062////////////////////////////////////////////////////////////////////////////////
6063/// Multiply this histogram by h1.
6064///
6065/// `this = this*h1`
6066///
6067/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6068/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
6069/// if not already set.
6070///
6071/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6072/// you should call Sumw2 before making this operation.
6073/// This is particularly important if you fit the histogram after TH1::Multiply
6074///
6075/// The function return kFALSE if the Multiply operation failed
6076
6077Bool_t TH1::Multiply(const TH1 *h1)
6078{
6079 if (!h1) {
6080 Error("Multiply","Attempt to multiply by a non-existing histogram");
6081 return kFALSE;
6082 }
6083
6084 // delete buffer if it is there since it will become invalid
6085 if (fBuffer) BufferEmpty(1);
6086
6087 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins) {
6088 return false;
6089 }
6090
6091 // Create Sumw2 if h1 has Sumw2 set
6092 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
6093
6094 // - Reset min- maximum
6095 SetMinimum();
6096 SetMaximum();
6097
6098 // - Loop on bins (including underflows/overflows)
6099 for (Int_t i = 0; i < fNcells; ++i) {
6102 UpdateBinContent(i, c0 * c1);
6103 if (fSumw2.fN) {
6105 }
6106 }
6107 ResetStats();
6108 return kTRUE;
6109}
6110
6111////////////////////////////////////////////////////////////////////////////////
6112/// Replace contents of this histogram by multiplication of h1 by h2.
6113///
6114/// `this = (c1*h1)*(c2*h2)`
6115///
6116/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6117/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
6118/// if not already set.
6119///
6120/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6121/// you should call Sumw2 before making this operation.
6122/// This is particularly important if you fit the histogram after TH1::Multiply
6123///
6124/// The function return kFALSE if the Multiply operation failed
6125
6127{
6128 TString opt = option;
6129 opt.ToLower();
6130 // Bool_t binomial = kFALSE;
6131 // if (opt.Contains("b")) binomial = kTRUE;
6132 if (!h1 || !h2) {
6133 Error("Multiply","Attempt to multiply by a non-existing histogram");
6134 return kFALSE;
6135 }
6136
6137 // delete buffer if it is there since it will become invalid
6138 if (fBuffer) BufferEmpty(1);
6139
6140 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins ||
6141 LoggedInconsistency("Multiply", h1, h2) >= kDifferentNumberOfBins) {
6142 return false;
6143 }
6144
6145 // Create Sumw2 if h1 or h2 have Sumw2 set
6146 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
6147
6148 // - Reset min - maximum
6149 SetMinimum();
6150 SetMaximum();
6151
6152 // - Loop on bins (including underflows/overflows)
6153 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
6154 for (Int_t i = 0; i < fNcells; ++i) {
6156 Double_t b2 = h2->RetrieveBinContent(i);
6157 UpdateBinContent(i, c1 * b1 * c2 * b2);
6158 if (fSumw2.fN) {
6159 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
6160 }
6161 }
6162 ResetStats();
6163 return kTRUE;
6164}
6165
6166////////////////////////////////////////////////////////////////////////////////
6167/// Control routine to paint any kind of histograms.
6168///
6169/// This function is automatically called by TCanvas::Update.
6170/// (see TH1::Draw for the list of options)
6171
6173{
6175
6176 if (fPainter) {
6177 if (option && strlen(option) > 0)
6179 else
6181 }
6182}
6183
6184////////////////////////////////////////////////////////////////////////////////
6185/// Rebin this histogram
6186///
6187/// #### case 1 xbins=0
6188///
6189/// If newname is blank (default), the current histogram is modified and
6190/// a pointer to it is returned.
6191///
6192/// If newname is not blank, the current histogram is not modified, and a
6193/// new histogram is returned which is a Clone of the current histogram
6194/// with its name set to newname.
6195///
6196/// The parameter ngroup indicates how many bins of this have to be merged
6197/// into one bin of the result.
6198///
6199/// If the original histogram has errors stored (via Sumw2), the resulting
6200/// histograms has new errors correctly calculated.
6201///
6202/// examples: if h1 is an existing TH1F histogram with 100 bins
6203///
6204/// ~~~ {.cpp}
6205/// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
6206/// h1->Rebin(5); //merges five bins in one in h1
6207/// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
6208/// // merging 5 bins of h1 in one bin
6209/// ~~~
6210///
6211/// NOTE: If ngroup is not an exact divider of the number of bins,
6212/// the top limit of the rebinned histogram is reduced
6213/// to the upper edge of the last bin that can make a complete
6214/// group. The remaining bins are added to the overflow bin.
6215/// Statistics will be recomputed from the new bin contents.
6216///
6217/// #### case 2 xbins!=0
6218///
6219/// A new histogram is created (you should specify newname).
6220/// The parameter ngroup is the number of variable size bins in the created histogram.
6221/// The array xbins must contain ngroup+1 elements that represent the low-edges
6222/// of the bins.
6223/// If the original histogram has errors stored (via Sumw2), the resulting
6224/// histograms has new errors correctly calculated.
6225///
6226/// NOTE: The bin edges specified in xbins should correspond to bin edges
6227/// in the original histogram. If a bin edge in the new histogram is
6228/// in the middle of a bin in the original histogram, all entries in
6229/// the split bin in the original histogram will be transfered to the
6230/// lower of the two possible bins in the new histogram. This is
6231/// probably not what you want. A warning message is emitted in this
6232/// case
6233///
6234/// examples: if h1 is an existing TH1F histogram with 100 bins
6235///
6236/// ~~~ {.cpp}
6237/// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
6238/// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
6239/// ~~~
6240
6241TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
6242{
6243 Int_t nbins = fXaxis.GetNbins();
6246 if ((ngroup <= 0) || (ngroup > nbins)) {
6247 Error("Rebin", "Illegal value of ngroup=%d",ngroup);
6248 return nullptr;
6249 }
6250
6251 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
6252 Error("Rebin", "Operation valid on 1-D histograms only");
6253 return nullptr;
6254 }
6255 if (!newname && xbins) {
6256 Error("Rebin","if xbins is specified, newname must be given");
6257 return nullptr;
6258 }
6259
6260 Int_t newbins = nbins/ngroup;
6261 if (!xbins) {
6262 Int_t nbg = nbins/ngroup;
6263 if (nbg*ngroup != nbins) {
6264 Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
6265 }
6266 }
6267 else {
6268 // in the case that xbins is given (rebinning in variable bins), ngroup is
6269 // the new number of bins and number of grouped bins is not constant.
6270 // when looping for setting the contents for the new histogram we
6271 // need to loop on all bins of original histogram. Then set ngroup=nbins
6272 newbins = ngroup;
6273 ngroup = nbins;
6274 }
6275
6276 // Save old bin contents into a new array
6277 Double_t entries = fEntries;
6278 Double_t *oldBins = new Double_t[nbins+2];
6279 Int_t bin, i;
6280 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
6281 Double_t *oldErrors = nullptr;
6282 if (fSumw2.fN != 0) {
6283 oldErrors = new Double_t[nbins+2];
6284 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
6285 }
6286 // rebin will not include underflow/overflow if new axis range is larger than old axis range
6287 if (xbins) {
6288 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
6289 Warning("Rebin","underflow entries will not be used when rebinning");
6290 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
6291 Warning("Rebin","overflow entries will not be used when rebinning");
6292 }
6293
6294
6295 // create a clone of the old histogram if newname is specified
6296 TH1 *hnew = this;
6297 if ((newname && strlen(newname) > 0) || xbins) {
6298 hnew = (TH1*)Clone(newname);
6299 }
6300
6301 //reset can extend bit to avoid an axis extension in SetBinContent
6302 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
6303
6304 // save original statistics
6305 Double_t stat[kNstat];
6306 GetStats(stat);
6307 bool resetStat = false;
6308 // change axis specs and rebuild bin contents array::RebinAx
6309 if(!xbins && (newbins*ngroup != nbins)) {
6310 xmax = fXaxis.GetBinUpEdge(newbins*ngroup);
6311 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
6312 }
6313 // save the TAttAxis members (reset by SetBins)
6314 Int_t nDivisions = fXaxis.GetNdivisions();
6315 Color_t axisColor = fXaxis.GetAxisColor();
6316 Color_t labelColor = fXaxis.GetLabelColor();
6317 Style_t labelFont = fXaxis.GetLabelFont();
6318 Float_t labelOffset = fXaxis.GetLabelOffset();
6319 Float_t labelSize = fXaxis.GetLabelSize();
6320 Float_t tickLength = fXaxis.GetTickLength();
6321 Float_t titleOffset = fXaxis.GetTitleOffset();
6322 Float_t titleSize = fXaxis.GetTitleSize();
6323 Color_t titleColor = fXaxis.GetTitleColor();
6324 Style_t titleFont = fXaxis.GetTitleFont();
6325
6326 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
6327 Double_t *bins = new Double_t[newbins+1];
6328 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
6329 hnew->SetBins(newbins,bins); //this also changes errors array (if any)
6330 delete [] bins;
6331 } else if (xbins) {
6332 hnew->SetBins(newbins,xbins);
6333 } else {
6334 hnew->SetBins(newbins,xmin,xmax);
6335 }
6336
6337 // Restore axis attributes
6338 fXaxis.SetNdivisions(nDivisions);
6339 fXaxis.SetAxisColor(axisColor);
6340 fXaxis.SetLabelColor(labelColor);
6341 fXaxis.SetLabelFont(labelFont);
6342 fXaxis.SetLabelOffset(labelOffset);
6343 fXaxis.SetLabelSize(labelSize);
6344 fXaxis.SetTickLength(tickLength);
6345 fXaxis.SetTitleOffset(titleOffset);
6346 fXaxis.SetTitleSize(titleSize);
6347 fXaxis.SetTitleColor(titleColor);
6348 fXaxis.SetTitleFont(titleFont);
6349
6350 // copy merged bin contents (ignore under/overflows)
6351 // Start merging only once the new lowest edge is reached
6352 Int_t startbin = 1;
6353 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
6354 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
6355 startbin++;
6356 }
6357 Int_t oldbin = startbin;
6358 Double_t binContent, binError;
6359 for (bin = 1;bin<=newbins;bin++) {
6360 binContent = 0;
6361 binError = 0;
6362 Int_t imax = ngroup;
6363 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6364 // check bin edges for the cases when we provide an array of bins
6365 // be careful in case bins can have zero width
6366 if (xbins && !TMath::AreEqualAbs(fXaxis.GetBinLowEdge(oldbin),
6367 hnew->GetXaxis()->GetBinLowEdge(bin),
6368 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6369 {
6370 Warning("Rebin","Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6371 }
6372 for (i=0;i<ngroup;i++) {
6373 if( (oldbin+i > nbins) ||
6374 ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6375 imax = i;
6376 break;
6377 }
6378 binContent += oldBins[oldbin+i];
6379 if (oldErrors) binError += oldErrors[oldbin+i]*oldErrors[oldbin+i];
6380 }
6381 hnew->SetBinContent(bin,binContent);
6382 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6383 oldbin += imax;
6384 }
6385
6386 // sum underflow and overflow contents until startbin
6387 binContent = 0;
6388 binError = 0;
6389 for (i = 0; i < startbin; ++i) {
6390 binContent += oldBins[i];
6391 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6392 }
6393 hnew->SetBinContent(0,binContent);
6394 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6395 // sum overflow
6396 binContent = 0;
6397 binError = 0;
6398 for (i = oldbin; i <= nbins+1; ++i) {
6399 binContent += oldBins[i];
6400 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6401 }
6402 hnew->SetBinContent(newbins+1,binContent);
6403 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6404
6405 hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6406
6407 // restore statistics and entries modified by SetBinContent
6408 hnew->SetEntries(entries);
6409 if (!resetStat) hnew->PutStats(stat);
6410 delete [] oldBins;
6411 if (oldErrors) delete [] oldErrors;
6412 return hnew;
6413}
6414
6415////////////////////////////////////////////////////////////////////////////////
6416/// finds new limits for the axis so that *point* is within the range and
6417/// the limits are compatible with the previous ones (see TH1::Merge).
6418/// new limits are put into *newMin* and *newMax* variables.
6419/// axis - axis whose limits are to be recomputed
6420/// point - point that should fit within the new axis limits
6421/// newMin - new minimum will be stored here
6422/// newMax - new maximum will be stored here.
6423/// false if failed (e.g. if the initial axis limits are wrong
6424/// or the new range is more than \f$ 2^{64} \f$ times the old one).
6425
6426Bool_t TH1::FindNewAxisLimits(const TAxis* axis, const Double_t point, Double_t& newMin, Double_t &newMax)
6427{
6428 Double_t xmin = axis->GetXmin();
6429 Double_t xmax = axis->GetXmax();
6430 if (xmin >= xmax) return kFALSE;
6431 Double_t range = xmax-xmin;
6432
6433 //recompute new axis limits by doubling the current range
6434 Int_t ntimes = 0;
6435 while (point < xmin) {
6436 if (ntimes++ > 64)
6437 return kFALSE;
6438 xmin = xmin - range;
6439 range *= 2;
6440 }
6441 while (point >= xmax) {
6442 if (ntimes++ > 64)
6443 return kFALSE;
6444 xmax = xmax + range;
6445 range *= 2;
6446 }
6447 newMin = xmin;
6448 newMax = xmax;
6449 // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6450 // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6451
6452 return kTRUE;
6453}
6454
6455////////////////////////////////////////////////////////////////////////////////
6456/// Histogram is resized along axis such that x is in the axis range.
6457/// The new axis limits are recomputed by doubling iteratively
6458/// the current axis range until the specified value x is within the limits.
6459/// The algorithm makes a copy of the histogram, then loops on all bins
6460/// of the old histogram to fill the extended histogram.
6461/// Takes into account errors (Sumw2) if any.
6462/// The algorithm works for 1-d, 2-D and 3-D histograms.
6463/// The axis must be extendable before invoking this function.
6464/// Ex:
6465///
6466/// ~~~ {.cpp}
6467/// h->GetXaxis()->SetCanExtend(kTRUE);
6468/// ~~~
6469
6470void TH1::ExtendAxis(Double_t x, TAxis *axis)
6471{
6472 if (!axis->CanExtend()) return;
6473 if (TMath::IsNaN(x)) { // x may be a NaN
6475 return;
6476 }
6477
6478 if (axis->GetXmin() >= axis->GetXmax()) return;
6479 if (axis->GetNbins() <= 0) return;
6480
6482 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6483 return;
6484
6485 //save a copy of this histogram
6486 TH1 *hold = (TH1*)IsA()->New();
6487 hold->SetDirectory(nullptr);
6488 Copy(*hold);
6489 //set new axis limits
6490 axis->SetLimits(xmin,xmax);
6491
6492
6493 //now loop on all bins and refill
6494 Int_t errors = GetSumw2N();
6495
6496 Reset("ICE"); //reset only Integral, contents and Errors
6497
6498 int iaxis = 0;
6499 if (axis == &fXaxis) iaxis = 1;
6500 if (axis == &fYaxis) iaxis = 2;
6501 if (axis == &fZaxis) iaxis = 3;
6502 bool firstw = kTRUE;
6503 Int_t binx,biny, binz = 0;
6504 Int_t ix = 0,iy = 0,iz = 0;
6505 Double_t bx,by,bz;
6506 Int_t ncells = hold->GetNcells();
6507 for (Int_t bin = 0; bin < ncells; ++bin) {
6508 hold->GetBinXYZ(bin,binx,biny,binz);
6509 bx = hold->GetXaxis()->GetBinCenter(binx);
6510 ix = fXaxis.FindFixBin(bx);
6511 if (fDimension > 1) {
6512 by = hold->GetYaxis()->GetBinCenter(biny);
6513 iy = fYaxis.FindFixBin(by);
6514 if (fDimension > 2) {
6515 bz = hold->GetZaxis()->GetBinCenter(binz);
6516 iz = fZaxis.FindFixBin(bz);
6517 }
6518 }
6519 // exclude underflow/overflow
6520 double content = hold->RetrieveBinContent(bin);
6521 if (content == 0) continue;
6522 if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6523 if (firstw) {
6524 Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6525 " their content will be lost",GetName() );
6526 firstw= kFALSE;
6527 }
6528 continue;
6529 }
6530 Int_t ibin= GetBin(ix,iy,iz);
6531 AddBinContent(ibin, content);
6532 if (errors) {
6533 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6534 }
6535 }
6536 delete hold;
6537}
6538
6539////////////////////////////////////////////////////////////////////////////////
6540/// Recursively remove object from the list of functions
6541
6543{
6544 // Rely on TROOT::RecursiveRemove to take the readlock.
6545
6546 if (fFunctions) {
6548 }
6549}
6550
6551////////////////////////////////////////////////////////////////////////////////
6552/// Multiply this histogram by a constant c1.
6553///
6554/// `this = c1*this`
6555///
6556/// Note that both contents and errors (if any) are scaled.
6557/// This function uses the services of TH1::Add
6558///
6559/// IMPORTANT NOTE: Sumw2() is called automatically when scaling.
6560/// If you are not interested in the histogram statistics you can call
6561/// Sumw2(kFALSE) or use the option "nosw2"
6562///
6563/// One can scale a histogram such that the bins integral is equal to
6564/// the normalization parameter via TH1::Scale(Double_t norm), where norm
6565/// is the desired normalization divided by the integral of the histogram.
6566///
6567/// If option contains "width" the bin contents and errors are divided
6568/// by the bin width.
6569
6571{
6572
6573 TString opt = option; opt.ToLower();
6574 // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6575 if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6576 if (opt.Contains("width")) Add(this, this, c1, -1);
6577 else {
6578 if (fBuffer) BufferEmpty(1);
6579 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6580 if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6581 // update global histograms statistics
6582 Double_t s[kNstat] = {0};
6583 GetStats(s);
6584 for (Int_t i=0 ; i < kNstat; i++) {
6585 if (i == 1) s[i] = c1*c1*s[i];
6586 else s[i] = c1*s[i];
6587 }
6588 PutStats(s);
6589 SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6590 }
6591
6592 // if contours set, must also scale contours
6593 Int_t ncontours = GetContour();
6594 if (ncontours == 0) return;
6595 Double_t* levels = fContour.GetArray();
6596 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6597}
6598
6599////////////////////////////////////////////////////////////////////////////////
6600/// Returns true if all axes are extendable.
6601
6603{
6604 Bool_t canExtend = fXaxis.CanExtend();
6605 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6606 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6607
6608 return canExtend;
6609}
6610
6611////////////////////////////////////////////////////////////////////////////////
6612/// Make the histogram axes extendable / not extendable according to the bit mask
6613/// returns the previous bit mask specifying which axes are extendable
6614
6615UInt_t TH1::SetCanExtend(UInt_t extendBitMask)
6616{
6617 UInt_t oldExtendBitMask = kNoAxis;
6618
6619 if (fXaxis.CanExtend()) oldExtendBitMask |= kXaxis;
6620 if (extendBitMask & kXaxis) fXaxis.SetCanExtend(kTRUE);
6622
6623 if (GetDimension() > 1) {
6624 if (fYaxis.CanExtend()) oldExtendBitMask |= kYaxis;
6625 if (extendBitMask & kYaxis) fYaxis.SetCanExtend(kTRUE);
6627 }
6628
6629 if (GetDimension() > 2) {
6630 if (fZaxis.CanExtend()) oldExtendBitMask |= kZaxis;
6631 if (extendBitMask & kZaxis) fZaxis.SetCanExtend(kTRUE);
6633 }
6634
6635 return oldExtendBitMask;
6636}
6637
6638///////////////////////////////////////////////////////////////////////////////
6639/// Internal function used in TH1::Fill to see which axis is full alphanumeric,
6640/// i.e. can be extended and is alphanumeric
6642{
6643 UInt_t bitMask = kNoAxis;
6644 if (fXaxis.CanExtend() && fXaxis.IsAlphanumeric() ) bitMask |= kXaxis;
6646 bitMask |= kYaxis;
6648 bitMask |= kZaxis;
6649
6650 return bitMask;
6651}
6652
6653////////////////////////////////////////////////////////////////////////////////
6654/// Static function to set the default buffer size for automatic histograms.
6655/// When a histogram is created with one of its axis lower limit greater
6656/// or equal to its upper limit, the function SetBuffer is automatically
6657/// called with the default buffer size.
6658
6659void TH1::SetDefaultBufferSize(Int_t buffersize)
6660{
6661 fgBufferSize = buffersize > 0 ? buffersize : 0;
6662}
6663
6664////////////////////////////////////////////////////////////////////////////////
6665/// When this static function is called with `sumw2=kTRUE`, all new
6666/// histograms will automatically activate the storage
6667/// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6668
6669void TH1::SetDefaultSumw2(Bool_t sumw2)
6670{
6671 fgDefaultSumw2 = sumw2;
6672}
6673
6674////////////////////////////////////////////////////////////////////////////////
6675/// Change/set the title.
6676///
6677/// If title is in the form `stringt;stringx;stringy;stringz`
6678/// the histogram title is set to `stringt`, the x axis title to `stringx`,
6679/// the y axis title to `stringy`, and the z axis title to `stringz`.
6680///
6681/// To insert the character `;` in one of the titles, one should use `#;`
6682/// or `#semicolon`.
6683
6684void TH1::SetTitle(const char *title)
6685{
6686 fTitle = title;
6687 fTitle.ReplaceAll("#;",2,"#semicolon",10);
6688
6689 // Decode fTitle. It may contain X, Y and Z titles
6690 TString str1 = fTitle, str2;
6691 Int_t isc = str1.Index(";");
6692 Int_t lns = str1.Length();
6693
6694 if (isc >=0 ) {
6695 fTitle = str1(0,isc);
6696 str1 = str1(isc+1, lns);
6697 isc = str1.Index(";");
6698 if (isc >=0 ) {
6699 str2 = str1(0,isc);
6700 str2.ReplaceAll("#semicolon",10,";",1);
6701 fXaxis.SetTitle(str2.Data());
6702 lns = str1.Length();
6703 str1 = str1(isc+1, lns);
6704 isc = str1.Index(";");
6705 if (isc >=0 ) {
6706 str2 = str1(0,isc);
6707 str2.ReplaceAll("#semicolon",10,";",1);
6708 fYaxis.SetTitle(str2.Data());
6709 lns = str1.Length();
6710 str1 = str1(isc+1, lns);
6711 str1.ReplaceAll("#semicolon",10,";",1);
6712 fZaxis.SetTitle(str1.Data());
6713 } else {
6714 str1.ReplaceAll("#semicolon",10,";",1);
6715 fYaxis.SetTitle(str1.Data());
6716 }
6717 } else {
6718 str1.ReplaceAll("#semicolon",10,";",1);
6719 fXaxis.SetTitle(str1.Data());
6720 }
6721 }
6722
6723 fTitle.ReplaceAll("#semicolon",10,";",1);
6724
6725 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6726}
6727
6728////////////////////////////////////////////////////////////////////////////////
6729/// Smooth array xx, translation of Hbook routine `hsmoof.F`.
6730/// Based on algorithm 353QH twice presented by J. Friedman
6731/// in [Proc. of the 1974 CERN School of Computing, Norway, 11-24 August, 1974](https://cds.cern.ch/record/186223).
6732/// 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).
6733
6734void TH1::SmoothArray(Int_t nn, Double_t *xx, Int_t ntimes)
6735{
6736 if (nn < 3 ) {
6737 ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6738 return;
6739 }
6740
6741 Int_t ii;
6742 std::array<double, 3> hh{};
6743
6744 std::vector<double> yy(nn);
6745 std::vector<double> zz(nn);
6746 std::vector<double> rr(nn);
6747
6748 for (Int_t pass=0;pass<ntimes;pass++) {
6749 // first copy original data into temp array
6750 std::copy(xx, xx+nn, zz.begin() );
6751
6752 for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6753
6754 // do 353 i.e. running median 3, 5, and 3 in a single loop
6755 for (int kk = 0; kk < 3; kk++) {
6756 std::copy(zz.begin(), zz.end(), yy.begin());
6757 int medianType = (kk != 1) ? 3 : 5;
6758 int ifirst = (kk != 1 ) ? 1 : 2;
6759 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6760 //nn2 = nn - ik - 1;
6761 // do all elements beside the first and last point for median 3
6762 // and first two and last 2 for median 5
6763 for ( ii = ifirst; ii < ilast; ii++) {
6764 zz[ii] = TMath::Median(medianType, yy.data() + ii - ifirst);
6765 }
6766
6767 if (kk == 0) { // first median 3
6768 // first point
6769 hh[0] = zz[1];
6770 hh[1] = zz[0];
6771 hh[2] = 3*zz[1] - 2*zz[2];
6772 zz[0] = TMath::Median(3, hh.data());
6773 // last point
6774 hh[0] = zz[nn - 2];
6775 hh[1] = zz[nn - 1];
6776 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6777 zz[nn - 1] = TMath::Median(3, hh.data());
6778 }
6779
6780 if (kk == 1) { // median 5
6781 // second point with window length 3
6782 zz[1] = TMath::Median(3, yy.data());
6783 // second-to-last point with window length 3
6784 zz[nn - 2] = TMath::Median(3, yy.data() + nn - 3);
6785 }
6786
6787 // In the third iteration (kk == 2), the first and last point stay
6788 // the same (see paper linked in the documentation).
6789 }
6790
6791 std::copy ( zz.begin(), zz.end(), yy.begin() );
6792
6793 // quadratic interpolation for flat segments
6794 for (ii = 2; ii < (nn - 2); ii++) {
6795 if (zz[ii - 1] != zz[ii]) continue;
6796 if (zz[ii] != zz[ii + 1]) continue;
6797 const double tmp0 = zz[ii - 2] - zz[ii];
6798 const double tmp1 = zz[ii + 2] - zz[ii];
6799 if (tmp0 * tmp1 <= 0) continue;
6800 int jk = 1;
6801 if ( std::abs(tmp0) > std::abs(tmp0) ) jk = -1;
6802 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6803 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6804 }
6805
6806 // running means
6807 //std::copy(zz.begin(), zz.end(), yy.begin());
6808 for (ii = 1; ii < nn - 1; ii++) {
6809 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6810 }
6811 zz[0] = yy[0];
6812 zz[nn - 1] = yy[nn - 1];
6813
6814 if (noent == 0) {
6815
6816 // save computed values
6817 std::copy(zz.begin(), zz.end(), rr.begin());
6818
6819 // COMPUTE residuals
6820 for (ii = 0; ii < nn; ii++) {
6821 zz[ii] = xx[ii] - zz[ii];
6822 }
6823 }
6824
6825 } // end loop on noent
6826
6827
6828 double xmin = TMath::MinElement(nn,xx);
6829 for (ii = 0; ii < nn; ii++) {
6830 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6831 // make smoothing defined positive - not better using 0 ?
6832 else xx[ii] = std::max((rr[ii] + zz[ii]),0.0 );
6833 }
6834 }
6835}
6836
6837////////////////////////////////////////////////////////////////////////////////
6838/// Smooth bin contents of this histogram.
6839/// if option contains "R" smoothing is applied only to the bins
6840/// defined in the X axis range (default is to smooth all bins)
6841/// Bin contents are replaced by their smooth values.
6842/// Errors (if any) are not modified.
6843/// the smoothing procedure is repeated ntimes (default=1)
6844
6845void TH1::Smooth(Int_t ntimes, Option_t *option)
6846{
6847 if (fDimension != 1) {
6848 Error("Smooth","Smooth only supported for 1-d histograms");
6849 return;
6850 }
6851 Int_t nbins = fXaxis.GetNbins();
6852 if (nbins < 3) {
6853 Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
6854 return;
6855 }
6856
6857 // delete buffer if it is there since it will become invalid
6858 if (fBuffer) BufferEmpty(1);
6859
6860 Int_t firstbin = 1, lastbin = nbins;
6861 TString opt = option;
6862 opt.ToLower();
6863 if (opt.Contains("r")) {
6864 firstbin= fXaxis.GetFirst();
6865 lastbin = fXaxis.GetLast();
6866 }
6867 nbins = lastbin - firstbin + 1;
6868 Double_t *xx = new Double_t[nbins];
6869 Double_t nent = fEntries;
6870 Int_t i;
6871 for (i=0;i<nbins;i++) {
6872 xx[i] = RetrieveBinContent(i+firstbin);
6873 }
6874
6875 TH1::SmoothArray(nbins,xx,ntimes);
6876
6877 for (i=0;i<nbins;i++) {
6878 UpdateBinContent(i+firstbin,xx[i]);
6879 }
6880 fEntries = nent;
6881 delete [] xx;
6882
6883 if (gPad) gPad->Modified();
6884}
6885
6886////////////////////////////////////////////////////////////////////////////////
6887/// if flag=kTRUE, underflows and overflows are used by the Fill functions
6888/// in the computation of statistics (mean value, StdDev).
6889/// By default, underflows or overflows are not used.
6890
6891void TH1::StatOverflows(Bool_t flag)
6892{
6893 fgStatOverflows = flag;
6894}
6895
6896////////////////////////////////////////////////////////////////////////////////
6897/// Stream a class object.
6898
6899void TH1::Streamer(TBuffer &b)
6900{
6901 if (b.IsReading()) {
6902 UInt_t R__s, R__c;
6903 Version_t R__v = b.ReadVersion(&R__s, &R__c);
6904 if (fDirectory) fDirectory->Remove(this);
6905 fDirectory = nullptr;
6906 if (R__v > 2) {
6907 b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
6908
6910 fXaxis.SetParent(this);
6911 fYaxis.SetParent(this);
6912 fZaxis.SetParent(this);
6913 TIter next(fFunctions);
6914 TObject *obj;
6915 while ((obj=next())) {
6916 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
6917 }
6918 return;
6919 }
6920 //process old versions before automatic schema evolution
6925 b >> fNcells;
6926 fXaxis.Streamer(b);
6927 fYaxis.Streamer(b);
6928 fZaxis.Streamer(b);
6929 fXaxis.SetParent(this);
6930 fYaxis.SetParent(this);
6931 fZaxis.SetParent(this);
6932 b >> fBarOffset;
6933 b >> fBarWidth;
6934 b >> fEntries;
6935 b >> fTsumw;
6936 b >> fTsumw2;
6937 b >> fTsumwx;
6938 b >> fTsumwx2;
6939 if (R__v < 2) {
6940 Float_t maximum, minimum, norm;
6941 Float_t *contour=nullptr;
6942 b >> maximum; fMaximum = maximum;
6943 b >> minimum; fMinimum = minimum;
6944 b >> norm; fNormFactor = norm;
6945 Int_t n = b.ReadArray(contour);
6946 fContour.Set(n);
6947 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
6948 delete [] contour;
6949 } else {
6950 b >> fMaximum;
6951 b >> fMinimum;
6952 b >> fNormFactor;
6954 }
6955 fSumw2.Streamer(b);
6957 fFunctions->Delete();
6959 b.CheckByteCount(R__s, R__c, TH1::IsA());
6960
6961 } else {
6962 b.WriteClassBuffer(TH1::Class(),this);
6963 }
6964}
6965
6966////////////////////////////////////////////////////////////////////////////////
6967/// Print some global quantities for this histogram.
6968/// \param[in] option
6969/// - "base" is given, number of bins and ranges are also printed
6970/// - "range" is given, bin contents and errors are also printed
6971/// for all bins in the current range (default 1-->nbins)
6972/// - "all" is given, bin contents and errors are also printed
6973/// for all bins including under and overflows.
6974
6975void TH1::Print(Option_t *option) const
6976{
6977 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
6978 printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
6979 TString opt = option;
6980 opt.ToLower();
6981 Int_t all;
6982 if (opt.Contains("all")) all = 0;
6983 else if (opt.Contains("range")) all = 1;
6984 else if (opt.Contains("base")) all = 2;
6985 else return;
6986
6987 Int_t bin, binx, biny, binz;
6988 Int_t firstx=0,lastx=0,firsty=0,lasty=0,firstz=0,lastz=0;
6989 if (all == 0) {
6990 lastx = fXaxis.GetNbins()+1;
6991 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
6992 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
6993 } else {
6994 firstx = fXaxis.GetFirst(); lastx = fXaxis.GetLast();
6995 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
6996 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
6997 }
6998
6999 if (all== 2) {
7000 printf(" Title = %s\n", GetTitle());
7001 printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
7002 if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
7003 if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
7004 printf("\n");
7005 return;
7006 }
7007
7008 Double_t w,e;
7009 Double_t x,y,z;
7010 if (fDimension == 1) {
7011 for (binx=firstx;binx<=lastx;binx++) {
7012 x = fXaxis.GetBinCenter(binx);
7013 w = RetrieveBinContent(binx);
7014 e = GetBinError(binx);
7015 if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
7016 else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
7017 }
7018 }
7019 if (fDimension == 2) {
7020 for (biny=firsty;biny<=lasty;biny++) {
7021 y = fYaxis.GetBinCenter(biny);
7022 for (binx=firstx;binx<=lastx;binx++) {
7023 bin = GetBin(binx,biny);
7024 x = fXaxis.GetBinCenter(binx);
7025 w = RetrieveBinContent(bin);
7026 e = GetBinError(bin);
7027 if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
7028 else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
7029 }
7030 }
7031 }
7032 if (fDimension == 3) {
7033 for (binz=firstz;binz<=lastz;binz++) {
7034 z = fZaxis.GetBinCenter(binz);
7035 for (biny=firsty;biny<=lasty;biny++) {
7036 y = fYaxis.GetBinCenter(biny);
7037 for (binx=firstx;binx<=lastx;binx++) {
7038 bin = GetBin(binx,biny,binz);
7039 x = fXaxis.GetBinCenter(binx);
7040 w = RetrieveBinContent(bin);
7041 e = GetBinError(bin);
7042 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);
7043 else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
7044 }
7045 }
7046 }
7047 }
7048}
7049
7050////////////////////////////////////////////////////////////////////////////////
7051/// Using the current bin info, recompute the arrays for contents and errors
7052
7053void TH1::Rebuild(Option_t *)
7054{
7055 SetBinsLength();
7056 if (fSumw2.fN) {
7058 }
7059}
7060
7061////////////////////////////////////////////////////////////////////////////////
7062/// Reset this histogram: contents, errors, etc.
7063/// \param[in] option
7064/// - if "ICE" is specified, resets only Integral, Contents and Errors.
7065/// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
7066/// This option is used
7067/// - if "M" is specified, resets also Minimum and Maximum
7068
7070{
7071 // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
7072 // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
7073
7074 TString opt = option;
7075 opt.ToUpper();
7076 fSumw2.Reset();
7077 if (fIntegral) {
7078 delete [] fIntegral;
7079 fIntegral = nullptr;
7080 }
7081
7082 if (opt.Contains("M")) {
7083 SetMinimum();
7084 SetMaximum();
7085 }
7086
7087 if (opt.Contains("ICE") && !opt.Contains("S")) return;
7088
7089 // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
7090 // But what is the sense of calling BufferEmpty() ? For making the axes ?
7091 // BufferEmpty will update contents that later will be
7092 // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
7093 // It may be needed for computing the axis limits....
7094 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
7095
7096 // need to reset also the statistics
7097 // (needs to be done after calling BufferEmpty() )
7098 fTsumw = 0;
7099 fTsumw2 = 0;
7100 fTsumwx = 0;
7101 fTsumwx2 = 0;
7102 fEntries = 0;
7103
7104 if (opt == "ICES") return;
7105
7106
7107 TObject *stats = fFunctions->FindObject("stats");
7108 fFunctions->Remove(stats);
7109 //special logic to support the case where the same object is
7110 //added multiple times in fFunctions.
7111 //This case happens when the same object is added with different
7112 //drawing modes
7113 TObject *obj;
7114 while ((obj = fFunctions->First())) {
7115 while(fFunctions->Remove(obj)) { }
7116 delete obj;
7117 }
7118 if(stats) fFunctions->Add(stats);
7119 fContour.Set(0);
7120}
7121
7122////////////////////////////////////////////////////////////////////////////////
7123/// Save the histogram as .csv, .tsv or .txt. In case of any other extension, fall
7124/// back to TObject::SaveAs, which saves as a .C macro (but with the file name
7125/// extension specified by the user)
7126///
7127/// The Under/Overflow bins are also exported (as first and last lines)
7128/// The fist 2 columns are the lower and upper edges of the bins
7129/// Column 3 contains the bin contents
7130/// The last column contains the error in y. If errors are not present, the column
7131/// is left empty
7132///
7133/// The result can be immediately imported into Excel, gnuplot, Python or whatever,
7134/// without the needing to install pyroot, etc.
7135///
7136/// \param filename the name of the file where to store the histogram
7137/// \param option some tuning options
7138///
7139/// The file extension defines the delimiter used:
7140/// - `.csv` : comma
7141/// - `.tsv` : tab
7142/// - `.txt` : space
7143///
7144/// If option = "title" a title line is generated. If the y-axis has a title,
7145/// this title is displayed as column 3 name, otherwise, it shows "BinContent"
7146
7147void TH1::SaveAs(const char *filename, Option_t *option) const
7148{
7149 char del = '\0';
7150 TString ext = "";
7151 TString fname = filename;
7152 TString opt = option;
7153
7154 if (filename) {
7155 if (fname.EndsWith(".csv")) {
7156 del = ',';
7157 ext = "csv";
7158 } else if (fname.EndsWith(".tsv")) {
7159 del = '\t';
7160 ext = "tsv";
7161 } else if (fname.EndsWith(".txt")) {
7162 del = ' ';
7163 ext = "txt";
7164 }
7165 }
7166 if (!del) {
7167 Info("SaveAs", "The file extension is not any of '.csv', '.tsv', '.txt'. Falling back to TObject::SaveAs");
7169 return;
7170 }
7171 std::ofstream out;
7172 out.open(filename, std::ios::out);
7173 if (!out.good()) {
7174 Error("SaveAs", "cannot open file: %s", filename);
7175 return;
7176 }
7177 if (opt.Contains("title")) {
7178 if (std::strcmp(GetYaxis()->GetTitle(), "") == 0) {
7179 out << "#\tBinLowEdge\tBinUpEdge\t"
7180 << "BinContent"
7181 << "\tey" << std::endl;
7182 } else {
7183 out << "#\tBinLowEdge\tBinUpEdge\t" << GetYaxis()->GetTitle() << "\tey" << std::endl;
7184 }
7185 }
7186 if (fSumw2.fN) {
7187 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7188 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7189 << GetBinError(i) << std::endl;
7190 }
7191 } else {
7192 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7193 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7194 << std::endl;
7195 }
7196 }
7197 out.close();
7198 Info("SaveAs", "%s file: %s has been generated", ext.Data(), filename);
7199}
7200
7201////////////////////////////////////////////////////////////////////////////////
7202/// Save primitive as a C++ statement(s) on output stream out
7203
7204void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
7205{
7206 // empty the buffer before if it exists
7207 if (fBuffer) BufferEmpty();
7208
7209 Bool_t nonEqiX = kFALSE;
7210 Bool_t nonEqiY = kFALSE;
7211 Bool_t nonEqiZ = kFALSE;
7212 Int_t i;
7213 static Int_t nxaxis = 0;
7214 static Int_t nyaxis = 0;
7215 static Int_t nzaxis = 0;
7216 TString sxaxis="xAxis",syaxis="yAxis",szaxis="zAxis";
7217
7218 // Check if the histogram has equidistant X bins or not. If not, we
7219 // create an array holding the bins.
7220 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
7221 nonEqiX = kTRUE;
7222 nxaxis++;
7223 sxaxis += nxaxis;
7224 out << " Double_t "<<sxaxis<<"[" << GetXaxis()->GetXbins()->fN
7225 << "] = {";
7226 for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
7227 if (i != 0) out << ", ";
7228 out << GetXaxis()->GetXbins()->fArray[i];
7229 }
7230 out << "}; " << std::endl;
7231 }
7232 // If the histogram is 2 or 3 dimensional, check if the histogram
7233 // has equidistant Y bins or not. If not, we create an array
7234 // holding the bins.
7235 if (fDimension > 1 && GetYaxis()->GetXbins()->fN &&
7236 GetYaxis()->GetXbins()->fArray) {
7237 nonEqiY = kTRUE;
7238 nyaxis++;
7239 syaxis += nyaxis;
7240 out << " Double_t "<<syaxis<<"[" << GetYaxis()->GetXbins()->fN
7241 << "] = {";
7242 for (i = 0; i < GetYaxis()->GetXbins()->fN; i++) {
7243 if (i != 0) out << ", ";
7244 out << GetYaxis()->GetXbins()->fArray[i];
7245 }
7246 out << "}; " << std::endl;
7247 }
7248 // IF the histogram is 3 dimensional, check if the histogram
7249 // has equidistant Z bins or not. If not, we create an array
7250 // holding the bins.
7251 if (fDimension > 2 && GetZaxis()->GetXbins()->fN &&
7252 GetZaxis()->GetXbins()->fArray) {
7253 nonEqiZ = kTRUE;
7254 nzaxis++;
7255 szaxis += nzaxis;
7256 out << " Double_t "<<szaxis<<"[" << GetZaxis()->GetXbins()->fN
7257 << "] = {";
7258 for (i = 0; i < GetZaxis()->GetXbins()->fN; i++) {
7259 if (i != 0) out << ", ";
7260 out << GetZaxis()->GetXbins()->fArray[i];
7261 }
7262 out << "}; " << std::endl;
7263 }
7264
7265 char quote = '"';
7266 out <<" "<<std::endl;
7267 out <<" "<< ClassName() <<" *";
7268
7269 // Histogram pointer has by default the histogram name with an incremental suffix.
7270 // If the histogram belongs to a graph or a stack the suffix is not added because
7271 // the graph and stack objects are not aware of this new name. Same thing if
7272 // the histogram is drawn with the option COLZ because the TPaletteAxis drawn
7273 // when this option is selected, does not know this new name either.
7274 TString opt = option;
7275 opt.ToLower();
7276 static Int_t hcounter = 0;
7277 TString histName = GetName();
7278 if ( !histName.Contains("Graph")
7279 && !histName.Contains("_stack_")
7280 && !opt.Contains("colz")) {
7281 hcounter++;
7282 histName += "__";
7283 histName += hcounter;
7284 }
7285 histName = gInterpreter-> MapCppName(histName);
7286 const char *hname = histName.Data();
7287 if (!strlen(hname)) hname = "unnamed";
7288 TString savedName = GetName();
7289 this->SetName(hname);
7290 TString t(GetTitle());
7291 t.ReplaceAll("\\","\\\\");
7292 t.ReplaceAll("\"","\\\"");
7293 out << hname << " = new " << ClassName() << "(" << quote
7294 << hname << quote << "," << quote<< t.Data() << quote
7295 << "," << GetXaxis()->GetNbins();
7296 if (nonEqiX)
7297 out << ", "<<sxaxis;
7298 else
7299 out << "," << GetXaxis()->GetXmin()
7300 << "," << GetXaxis()->GetXmax();
7301 if (fDimension > 1) {
7302 out << "," << GetYaxis()->GetNbins();
7303 if (nonEqiY)
7304 out << ", "<<syaxis;
7305 else
7306 out << "," << GetYaxis()->GetXmin()
7307 << "," << GetYaxis()->GetXmax();
7308 }
7309 if (fDimension > 2) {
7310 out << "," << GetZaxis()->GetNbins();
7311 if (nonEqiZ)
7312 out << ", "<<szaxis;
7313 else
7314 out << "," << GetZaxis()->GetXmin()
7315 << "," << GetZaxis()->GetXmax();
7316 }
7317 out << ");" << std::endl;
7318
7319 // save bin contents
7320 Int_t bin;
7321 for (bin=0;bin<fNcells;bin++) {
7322 Double_t bc = RetrieveBinContent(bin);
7323 if (bc) {
7324 out<<" "<<hname<<"->SetBinContent("<<bin<<","<<bc<<");"<<std::endl;
7325 }
7326 }
7327
7328 // save bin errors
7329 if (fSumw2.fN) {
7330 for (bin=0;bin<fNcells;bin++) {
7331 Double_t be = GetBinError(bin);
7332 if (be) {
7333 out<<" "<<hname<<"->SetBinError("<<bin<<","<<be<<");"<<std::endl;
7334 }
7335 }
7336 }
7337
7338 TH1::SavePrimitiveHelp(out, hname, option);
7339 this->SetName(savedName.Data());
7340}
7341
7342////////////////////////////////////////////////////////////////////////////////
7343/// Helper function for the SavePrimitive functions from TH1
7344/// or classes derived from TH1, eg TProfile, TProfile2D.
7345
7346void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
7347{
7348 char quote = '"';
7349 if (TMath::Abs(GetBarOffset()) > 1e-5) {
7350 out<<" "<<hname<<"->SetBarOffset("<<GetBarOffset()<<");"<<std::endl;
7351 }
7352 if (TMath::Abs(GetBarWidth()-1) > 1e-5) {
7353 out<<" "<<hname<<"->SetBarWidth("<<GetBarWidth()<<");"<<std::endl;
7354 }
7355 if (fMinimum != -1111) {
7356 out<<" "<<hname<<"->SetMinimum("<<fMinimum<<");"<<std::endl;
7357 }
7358 if (fMaximum != -1111) {
7359 out<<" "<<hname<<"->SetMaximum("<<fMaximum<<");"<<std::endl;
7360 }
7361 if (fNormFactor != 0) {
7362 out<<" "<<hname<<"->SetNormFactor("<<fNormFactor<<");"<<std::endl;
7363 }
7364 if (fEntries != 0) {
7365 out<<" "<<hname<<"->SetEntries("<<fEntries<<");"<<std::endl;
7366 }
7367 if (!fDirectory) {
7368 out<<" "<<hname<<"->SetDirectory(nullptr);"<<std::endl;
7369 }
7370 if (TestBit(kNoStats)) {
7371 out<<" "<<hname<<"->SetStats(0);"<<std::endl;
7372 }
7373 if (fOption.Length() != 0) {
7374 out<<" "<<hname<<"->SetOption("<<quote<<fOption.Data()<<quote<<");"<<std::endl;
7375 }
7376
7377 // save contour levels
7378 Int_t ncontours = GetContour();
7379 if (ncontours > 0) {
7380 out<<" "<<hname<<"->SetContour("<<ncontours<<");"<<std::endl;
7381 Double_t zlevel;
7382 for (Int_t bin=0;bin<ncontours;bin++) {
7383 if (gPad->GetLogz()) {
7384 zlevel = TMath::Power(10,GetContourLevel(bin));
7385 } else {
7386 zlevel = GetContourLevel(bin);
7387 }
7388 out<<" "<<hname<<"->SetContourLevel("<<bin<<","<<zlevel<<");"<<std::endl;
7389 }
7390 }
7391
7392 // save list of functions
7393 auto lnk = fFunctions->FirstLink();
7394 static Int_t funcNumber = 0;
7395 while (lnk) {
7396 auto obj = lnk->GetObject();
7397 obj->SavePrimitive(out, TString::Format("nodraw #%d\n",++funcNumber).Data());
7398 if (obj->InheritsFrom(TF1::Class())) {
7399 TString fname;
7400 fname.Form("%s%d",obj->GetName(),funcNumber);
7401 out << " " << fname << "->SetParent(" << hname << ");\n";
7402 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7403 << fname <<");"<<std::endl;
7404 } else if (obj->InheritsFrom("TPaveStats")) {
7405 out<<" "<<hname<<"->GetListOfFunctions()->Add(ptstats);"<<std::endl;
7406 out<<" ptstats->SetParent("<<hname<<");"<<std::endl;
7407 } else if (obj->InheritsFrom("TPolyMarker")) {
7408 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7409 <<"pmarker ,"<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
7410 } else {
7411 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7412 <<obj->GetName()
7413 <<","<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
7414 }
7415 lnk = lnk->Next();
7416 }
7417
7418 // save attributes
7419 SaveFillAttributes(out,hname,0,1001);
7420 SaveLineAttributes(out,hname,1,1,1);
7421 SaveMarkerAttributes(out,hname,1,1,1);
7422 fXaxis.SaveAttributes(out,hname,"->GetXaxis()");
7423 fYaxis.SaveAttributes(out,hname,"->GetYaxis()");
7424 fZaxis.SaveAttributes(out,hname,"->GetZaxis()");
7425 TString opt = option;
7426 opt.ToLower();
7427 if (!opt.Contains("nodraw")) {
7428 out<<" "<<hname<<"->Draw("
7429 <<quote<<option<<quote<<");"<<std::endl;
7430 }
7431}
7432
7433////////////////////////////////////////////////////////////////////////////////
7434/// Copy current attributes from/to current style
7435
7437{
7438 if (!gStyle) return;
7439 if (gStyle->IsReading()) {
7440 fXaxis.ResetAttAxis("X");
7441 fYaxis.ResetAttAxis("Y");
7442 fZaxis.ResetAttAxis("Z");
7453 Int_t dostat = gStyle->GetOptStat();
7454 if (gStyle->GetOptFit() && !dostat) dostat = 1000000001;
7455 SetStats(dostat);
7456 } else {
7468 }
7469 TIter next(GetListOfFunctions());
7470 TObject *obj;
7471
7472 while ((obj = next())) {
7473 obj->UseCurrentStyle();
7474 }
7475}
7476
7477////////////////////////////////////////////////////////////////////////////////
7478/// For axis = 1,2 or 3 returns the mean value of the histogram along
7479/// X,Y or Z axis.
7480///
7481/// For axis = 11, 12, 13 returns the standard error of the mean value
7482/// of the histogram along X, Y or Z axis
7483///
7484/// Note that the mean value/StdDev is computed using the bins in the currently
7485/// defined range (see TAxis::SetRange). By default the range includes
7486/// all bins from 1 to nbins included, excluding underflows and overflows.
7487/// To force the underflows and overflows in the computation, one must
7488/// call the static function TH1::StatOverflows(kTRUE) before filling
7489/// the histogram.
7490///
7491/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7492/// are calculated. By default, if no range has been set, the returned mean is
7493/// the (unbinned) one calculated at fill time. If a range has been set, however,
7494/// the mean is calculated using the bins in range, as described above; THIS
7495/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7496/// the range. To ensure that the returned mean (and all other statistics) is
7497/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7498/// See TH1::GetStats.
7499///
7500/// Return mean value of this histogram along the X axis.
7501
7502Double_t TH1::GetMean(Int_t axis) const
7503{
7504 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7505 Double_t stats[kNstat];
7506 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7507 GetStats(stats);
7508 if (stats[0] == 0) return 0;
7509 if (axis<4){
7510 Int_t ax[3] = {2,4,7};
7511 return stats[ax[axis-1]]/stats[0];
7512 } else {
7513 // mean error = StdDev / sqrt( Neff )
7514 Double_t stddev = GetStdDev(axis-10);
7516 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7517 }
7518}
7519
7520////////////////////////////////////////////////////////////////////////////////
7521/// Return standard error of mean of this histogram along the X axis.
7522///
7523/// Note that the mean value/StdDev is computed using the bins in the currently
7524/// defined range (see TAxis::SetRange). By default the range includes
7525/// all bins from 1 to nbins included, excluding underflows and overflows.
7526/// To force the underflows and overflows in the computation, one must
7527/// call the static function TH1::StatOverflows(kTRUE) before filling
7528/// the histogram.
7529///
7530/// Also note, that although the definition of standard error doesn't include the
7531/// assumption of normality, many uses of this feature implicitly assume it.
7532///
7533/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7534/// are calculated. By default, if no range has been set, the returned value is
7535/// the (unbinned) one calculated at fill time. If a range has been set, however,
7536/// the value is calculated using the bins in range, as described above; THIS
7537/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7538/// the range. To ensure that the returned value (and all other statistics) is
7539/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7540/// See TH1::GetStats.
7541
7543{
7544 return GetMean(axis+10);
7545}
7546
7547////////////////////////////////////////////////////////////////////////////////
7548/// Returns the Standard Deviation (Sigma).
7549/// The Sigma estimate is computed as
7550/// \f[
7551/// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7552/// \f]
7553/// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7554/// X, Y or Z axis
7555/// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7556/// X, Y or Z axis for Normal distribution
7557///
7558/// Note that the mean value/sigma is computed using the bins in the currently
7559/// defined range (see TAxis::SetRange). By default the range includes
7560/// all bins from 1 to nbins included, excluding underflows and overflows.
7561/// To force the underflows and overflows in the computation, one must
7562/// call the static function TH1::StatOverflows(kTRUE) before filling
7563/// the histogram.
7564///
7565/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7566/// are calculated. By default, if no range has been set, the returned standard
7567/// deviation is the (unbinned) one calculated at fill time. If a range has been
7568/// set, however, the standard deviation is calculated using the bins in range,
7569/// as described above; THIS IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use
7570/// TAxis::SetRange(0, 0) to unset the range. To ensure that the returned standard
7571/// deviation (and all other statistics) is always that of the binned data stored
7572/// in the histogram, call TH1::ResetStats. See TH1::GetStats.
7573
7574Double_t TH1::GetStdDev(Int_t axis) const
7575{
7576 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7577
7578 Double_t x, stddev2, stats[kNstat];
7579 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7580 GetStats(stats);
7581 if (stats[0] == 0) return 0;
7582 Int_t ax[3] = {2,4,7};
7583 Int_t axm = ax[axis%10 - 1];
7584 x = stats[axm]/stats[0];
7585 // for negative stddev (e.g. when having negative weights) - return stdev=0
7586 stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7587 if (axis<10)
7588 return TMath::Sqrt(stddev2);
7589 else {
7590 // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7591 // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7593 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7594 }
7595}
7596
7597////////////////////////////////////////////////////////////////////////////////
7598/// Return error of standard deviation estimation for Normal distribution
7599///
7600/// Note that the mean value/StdDev is computed using the bins in the currently
7601/// defined range (see TAxis::SetRange). By default the range includes
7602/// all bins from 1 to nbins included, excluding underflows and overflows.
7603/// To force the underflows and overflows in the computation, one must
7604/// call the static function TH1::StatOverflows(kTRUE) before filling
7605/// the histogram.
7606///
7607/// Value returned is standard deviation of sample standard deviation.
7608/// Note that it is an approximated value which is valid only in the case that the
7609/// original data distribution is Normal. The correct one would require
7610/// the 4-th momentum value, which cannot be accurately estimated from a histogram since
7611/// the x-information for all entries is not kept.
7612///
7613/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7614/// are calculated. By default, if no range has been set, the returned value is
7615/// the (unbinned) one calculated at fill time. If a range has been set, however,
7616/// the value is calculated using the bins in range, as described above; THIS
7617/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7618/// the range. To ensure that the returned value (and all other statistics) is
7619/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7620/// See TH1::GetStats.
7621
7623{
7624 return GetStdDev(axis+10);
7625}
7626
7627////////////////////////////////////////////////////////////////////////////////
7628/// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7629/// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7630/// of the histogram along x, y or z axis
7631///
7632///Note, that since third and fourth moment are not calculated
7633///at the fill time, skewness and its standard error are computed bin by bin
7634///
7635/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7636/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7637
7639{
7640
7641 if (axis > 0 && axis <= 3){
7642
7643 Double_t mean = GetMean(axis);
7644 Double_t stddev = GetStdDev(axis);
7645 Double_t stddev3 = stddev*stddev*stddev;
7646
7647 Int_t firstBinX = fXaxis.GetFirst();
7648 Int_t lastBinX = fXaxis.GetLast();
7649 Int_t firstBinY = fYaxis.GetFirst();
7650 Int_t lastBinY = fYaxis.GetLast();
7651 Int_t firstBinZ = fZaxis.GetFirst();
7652 Int_t lastBinZ = fZaxis.GetLast();
7653 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7656 if (firstBinX == 1) firstBinX = 0;
7657 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7658 }
7660 if (firstBinY == 1) firstBinY = 0;
7661 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7662 }
7664 if (firstBinZ == 1) firstBinZ = 0;
7665 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7666 }
7667 }
7668
7669 Double_t x = 0;
7670 Double_t sum=0;
7671 Double_t np=0;
7672 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7673 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7674 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7675 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7676 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7677 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7678 Double_t w = GetBinContent(binx,biny,binz);
7679 np+=w;
7680 sum+=w*(x-mean)*(x-mean)*(x-mean);
7681 }
7682 }
7683 }
7684 sum/=np*stddev3;
7685 return sum;
7686 }
7687 else if (axis > 10 && axis <= 13) {
7688 //compute standard error of skewness
7689 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7691 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7692 }
7693 else {
7694 Error("GetSkewness", "illegal value of parameter");
7695 return 0;
7696 }
7697}
7698
7699////////////////////////////////////////////////////////////////////////////////
7700/// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7701/// Kurtosis(gaussian(0, 1)) = 0.
7702/// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7703/// of the histogram along x, y or z axis
7704////
7705/// Note, that since third and fourth moment are not calculated
7706/// at the fill time, kurtosis and its standard error are computed bin by bin
7707///
7708/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7709/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7710
7712{
7713 if (axis > 0 && axis <= 3){
7714
7715 Double_t mean = GetMean(axis);
7716 Double_t stddev = GetStdDev(axis);
7717 Double_t stddev4 = stddev*stddev*stddev*stddev;
7718
7719 Int_t firstBinX = fXaxis.GetFirst();
7720 Int_t lastBinX = fXaxis.GetLast();
7721 Int_t firstBinY = fYaxis.GetFirst();
7722 Int_t lastBinY = fYaxis.GetLast();
7723 Int_t firstBinZ = fZaxis.GetFirst();
7724 Int_t lastBinZ = fZaxis.GetLast();
7725 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7728 if (firstBinX == 1) firstBinX = 0;
7729 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7730 }
7732 if (firstBinY == 1) firstBinY = 0;
7733 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7734 }
7736 if (firstBinZ == 1) firstBinZ = 0;
7737 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7738 }
7739 }
7740
7741 Double_t x = 0;
7742 Double_t sum=0;
7743 Double_t np=0;
7744 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7745 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7746 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7747 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7748 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7749 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7750 Double_t w = GetBinContent(binx,biny,binz);
7751 np+=w;
7752 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7753 }
7754 }
7755 }
7756 sum/=(np*stddev4);
7757 return sum-3;
7758
7759 } else if (axis > 10 && axis <= 13) {
7760 //compute standard error of skewness
7761 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7763 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7764 }
7765 else {
7766 Error("GetKurtosis", "illegal value of parameter");
7767 return 0;
7768 }
7769}
7770
7771////////////////////////////////////////////////////////////////////////////////
7772/// fill the array stats from the contents of this histogram
7773/// The array stats must be correctly dimensioned in the calling program.
7774///
7775/// ~~~ {.cpp}
7776/// stats[0] = sumw
7777/// stats[1] = sumw2
7778/// stats[2] = sumwx
7779/// stats[3] = sumwx2
7780/// ~~~
7781///
7782/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7783/// is simply a copy of the statistics quantities computed at filling time.
7784/// If a sub-range is specified, the function recomputes these quantities
7785/// from the bin contents in the current axis range.
7786///
7787/// IMPORTANT NOTE: This means that the returned statistics are context-dependent.
7788/// If TAxis::kAxisRange, the returned statistics are dependent on the binning;
7789/// otherwise, they are a copy of the histogram statistics computed at fill time,
7790/// which are unbinned by default (calling TH1::ResetStats forces them to use
7791/// binned statistics). You can reset TAxis::kAxisRange using TAxis::SetRange(0, 0).
7792///
7793/// Note that the mean value/StdDev is computed using the bins in the currently
7794/// defined range (see TAxis::SetRange). By default the range includes
7795/// all bins from 1 to nbins included, excluding underflows and overflows.
7796/// To force the underflows and overflows in the computation, one must
7797/// call the static function TH1::StatOverflows(kTRUE) before filling
7798/// the histogram.
7799
7800void TH1::GetStats(Double_t *stats) const
7801{
7802 if (fBuffer) ((TH1*)this)->BufferEmpty();
7803
7804 // Loop on bins (possibly including underflows/overflows)
7805 Int_t bin, binx;
7806 Double_t w,err;
7807 Double_t x;
7808 // identify the case of labels with extension of axis range
7809 // in this case the statistics in x does not make any sense
7810 Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && fXaxis.CanExtend() );
7811 // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7812 if ( (fTsumw == 0 && fEntries > 0) || fXaxis.TestBit(TAxis::kAxisRange) ) {
7813 for (bin=0;bin<4;bin++) stats[bin] = 0;
7814
7815 Int_t firstBinX = fXaxis.GetFirst();
7816 Int_t lastBinX = fXaxis.GetLast();
7817 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7819 if (firstBinX == 1) firstBinX = 0;
7820 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7821 }
7822 for (binx = firstBinX; binx <= lastBinX; binx++) {
7823 x = fXaxis.GetBinCenter(binx);
7824 //w = TMath::Abs(RetrieveBinContent(binx));
7825 // not sure what to do here if w < 0
7826 w = RetrieveBinContent(binx);
7827 err = TMath::Abs(GetBinError(binx));
7828 stats[0] += w;
7829 stats[1] += err*err;
7830 // statistics in x makes sense only for not labels histograms
7831 if (!labelHist) {
7832 stats[2] += w*x;
7833 stats[3] += w*x*x;
7834 }
7835 }
7836 // if (stats[0] < 0) {
7837 // // in case total is negative do something ??
7838 // stats[0] = 0;
7839 // }
7840 } else {
7841 stats[0] = fTsumw;
7842 stats[1] = fTsumw2;
7843 stats[2] = fTsumwx;
7844 stats[3] = fTsumwx2;
7845 }
7846}
7847
7848////////////////////////////////////////////////////////////////////////////////
7849/// Replace current statistics with the values in array stats
7850
7851void TH1::PutStats(Double_t *stats)
7852{
7853 fTsumw = stats[0];
7854 fTsumw2 = stats[1];
7855 fTsumwx = stats[2];
7856 fTsumwx2 = stats[3];
7857}
7858
7859////////////////////////////////////////////////////////////////////////////////
7860/// Reset the statistics including the number of entries
7861/// and replace with values calculated from bin content
7862///
7863/// The number of entries is set to the total bin content or (in case of weighted histogram)
7864/// to number of effective entries
7865///
7866/// Note that, by default, before calling this function, statistics are those
7867/// computed at fill time, which are unbinned. See TH1::GetStats.
7868
7869void TH1::ResetStats()
7870{
7871 Double_t stats[kNstat] = {0};
7872 fTsumw = 0;
7873 fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
7874 GetStats(stats);
7875 PutStats(stats);
7877 // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
7878 if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
7879}
7880
7881////////////////////////////////////////////////////////////////////////////////
7882/// Return the sum of weights excluding under/overflows.
7883
7885{
7886 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7887
7888 Int_t bin,binx,biny,binz;
7889 Double_t sum =0;
7890 for(binz=1; binz<=fZaxis.GetNbins(); binz++) {
7891 for(biny=1; biny<=fYaxis.GetNbins(); biny++) {
7892 for(binx=1; binx<=fXaxis.GetNbins(); binx++) {
7893 bin = GetBin(binx,biny,binz);
7894 sum += RetrieveBinContent(bin);
7895 }
7896 }
7897 }
7898 return sum;
7899}
7900
7901////////////////////////////////////////////////////////////////////////////////
7902///Return integral of bin contents. Only bins in the bins range are considered.
7903///
7904/// By default the integral is computed as the sum of bin contents in the range.
7905/// if option "width" is specified, the integral is the sum of
7906/// the bin contents multiplied by the bin width in x.
7907
7909{
7911}
7912
7913////////////////////////////////////////////////////////////////////////////////
7914/// Return integral of bin contents in range [binx1,binx2].
7915///
7916/// By default the integral is computed as the sum of bin contents in the range.
7917/// if option "width" is specified, the integral is the sum of
7918/// the bin contents multiplied by the bin width in x.
7919
7920Double_t TH1::Integral(Int_t binx1, Int_t binx2, Option_t *option) const
7921{
7922 double err = 0;
7923 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
7924}
7925
7926////////////////////////////////////////////////////////////////////////////////
7927/// Return integral of bin contents in range [binx1,binx2] and its error.
7928///
7929/// By default the integral is computed as the sum of bin contents in the range.
7930/// if option "width" is specified, the integral is the sum of
7931/// the bin contents multiplied by the bin width in x.
7932/// the error is computed using error propagation from the bin errors assuming that
7933/// all the bins are uncorrelated
7934
7935Double_t TH1::IntegralAndError(Int_t binx1, Int_t binx2, Double_t & error, Option_t *option) const
7936{
7937 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
7938}
7939
7940////////////////////////////////////////////////////////////////////////////////
7941/// Internal function compute integral and optionally the error between the limits
7942/// specified by the bin number values working for all histograms (1D, 2D and 3D)
7943
7944Double_t TH1::DoIntegral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error ,
7945 Option_t *option, Bool_t doError) const
7946{
7947 if (fBuffer) ((TH1*)this)->BufferEmpty();
7948
7949 Int_t nx = GetNbinsX() + 2;
7950 if (binx1 < 0) binx1 = 0;
7951 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
7952
7953 if (GetDimension() > 1) {
7954 Int_t ny = GetNbinsY() + 2;
7955 if (biny1 < 0) biny1 = 0;
7956 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
7957 } else {
7958 biny1 = 0; biny2 = 0;
7959 }
7960
7961 if (GetDimension() > 2) {
7962 Int_t nz = GetNbinsZ() + 2;
7963 if (binz1 < 0) binz1 = 0;
7964 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
7965 } else {
7966 binz1 = 0; binz2 = 0;
7967 }
7968
7969 // - Loop on bins in specified range
7970 TString opt = option;
7971 opt.ToLower();
7973 if (opt.Contains("width")) width = kTRUE;
7974
7975
7976 Double_t dx = 1., dy = .1, dz =.1;
7977 Double_t integral = 0;
7978 Double_t igerr2 = 0;
7979 for (Int_t binx = binx1; binx <= binx2; ++binx) {
7980 if (width) dx = fXaxis.GetBinWidth(binx);
7981 for (Int_t biny = biny1; biny <= biny2; ++biny) {
7982 if (width) dy = fYaxis.GetBinWidth(biny);
7983 for (Int_t binz = binz1; binz <= binz2; ++binz) {
7984 Int_t bin = GetBin(binx, biny, binz);
7985 Double_t dv = 0.0;
7986 if (width) {
7987 dz = fZaxis.GetBinWidth(binz);
7988 dv = dx * dy * dz;
7989 integral += RetrieveBinContent(bin) * dv;
7990 } else {
7991 integral += RetrieveBinContent(bin);
7992 }
7993 if (doError) {
7994 if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
7995 else igerr2 += GetBinErrorSqUnchecked(bin);
7996 }
7997 }
7998 }
7999 }
8000
8001 if (doError) error = TMath::Sqrt(igerr2);
8002 return integral;
8003}
8004
8005////////////////////////////////////////////////////////////////////////////////
8006/// Statistical test of compatibility in shape between
8007/// this histogram and h2, using the Anderson-Darling 2 sample test.
8008///
8009/// The AD 2 sample test formula are derived from the paper
8010/// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
8011///
8012/// The test is implemented in root in the ROOT::Math::GoFTest class
8013/// It is the same formula ( (6) in the paper), and also shown in
8014/// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
8015///
8016/// Binned data are considered as un-binned data
8017/// with identical observation happening in the bin center.
8018///
8019/// \param[in] h2 Pointer to 1D histogram
8020/// \param[in] option is a character string to specify options
8021/// - "D" Put out a line of "Debug" printout
8022/// - "T" Return the normalized A-D test statistic
8023///
8024/// - Note1: Underflow and overflow are not considered in the test
8025/// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
8026/// - Note3: The histograms are not required to have the same X axis
8027/// - Note4: The test works only for 1-dimensional histograms
8028
8030{
8031 Double_t advalue = 0;
8032 Double_t pvalue = AndersonDarlingTest(h2, advalue);
8033
8034 TString opt = option;
8035 opt.ToUpper();
8036 if (opt.Contains("D") ) {
8037 printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
8038 }
8039 if (opt.Contains("T") ) return advalue;
8040
8041 return pvalue;
8042}
8043
8044////////////////////////////////////////////////////////////////////////////////
8045/// Same function as above but returning also the test statistic value
8046
8047Double_t TH1::AndersonDarlingTest(const TH1 *h2, Double_t & advalue) const
8048{
8049 if (GetDimension() != 1 || h2->GetDimension() != 1) {
8050 Error("AndersonDarlingTest","Histograms must be 1-D");
8051 return -1;
8052 }
8053
8054 // empty the buffer. Probably we could add as an unbinned test
8055 if (fBuffer) ((TH1*)this)->BufferEmpty();
8056
8057 // use the BinData class
8058 ROOT::Fit::BinData data1;
8059 ROOT::Fit::BinData data2;
8060
8061 ROOT::Fit::FillData(data1, this, nullptr);
8062 ROOT::Fit::FillData(data2, h2, nullptr);
8063
8064 double pvalue;
8065 ROOT::Math::GoFTest::AndersonDarling2SamplesTest(data1,data2, pvalue,advalue);
8066
8067 return pvalue;
8068}
8069
8070////////////////////////////////////////////////////////////////////////////////
8071/// Statistical test of compatibility in shape between
8072/// this histogram and h2, using Kolmogorov test.
8073/// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
8074/// and not for binned data as in the case of the histogram (see NOTE 3 below).
8075/// So, before using this method blindly, read the NOTE 3.
8076///
8077/// Default: Ignore under- and overflow bins in comparison
8078///
8079/// \param[in] h2 histogram
8080/// \param[in] option is a character string to specify options
8081/// - "U" include Underflows in test (also for 2-dim)
8082/// - "O" include Overflows (also valid for 2-dim)
8083/// - "N" include comparison of normalizations
8084/// - "D" Put out a line of "Debug" printout
8085/// - "M" Return the Maximum Kolmogorov distance instead of prob
8086/// - "X" Run the pseudo experiments post-processor with the following procedure:
8087/// make pseudoexperiments based on random values from the parent distribution,
8088/// compare the KS distance of the pseudoexperiment to the parent
8089/// distribution, and count all the KS values above the value
8090/// obtained from the original data to Monte Carlo distribution.
8091/// The number of pseudo-experiments nEXPT is by default 1000, and
8092/// it can be changed by specifying the option as "X=number",
8093/// for example "X=10000" for 10000 toys.
8094/// The function returns the probability.
8095/// (thanks to Ben Kilminster to submit this procedure). Note that
8096/// this option "X" is much slower.
8097///
8098/// The returned function value is the probability of test
8099/// (much less than one means NOT compatible)
8100///
8101/// Code adapted by Rene Brun from original HBOOK routine HDIFF
8102///
8103/// NOTE1
8104/// A good description of the Kolmogorov test can be seen at:
8105/// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
8106///
8107/// NOTE2
8108/// see also alternative function TH1::Chi2Test
8109/// The Kolmogorov test is assumed to give better results than Chi2Test
8110/// in case of histograms with low statistics.
8111///
8112/// NOTE3 (Jan Conrad, Fred James)
8113/// "The returned value PROB is calculated such that it will be
8114/// uniformly distributed between zero and one for compatible histograms,
8115/// provided the data are not binned (or the number of bins is very large
8116/// compared with the number of events). Users who have access to unbinned
8117/// data and wish exact confidence levels should therefore not put their data
8118/// into histograms, but should call directly TMath::KolmogorovTest. On
8119/// the other hand, since TH1 is a convenient way of collecting data and
8120/// saving space, this function has been provided. However, the values of
8121/// PROB for binned data will be shifted slightly higher than expected,
8122/// depending on the effects of the binning. For example, when comparing two
8123/// uniform distributions of 500 events in 100 bins, the values of PROB,
8124/// instead of being exactly uniformly distributed between zero and one, have
8125/// a mean value of about 0.56. We can apply a useful
8126/// rule: As long as the bin width is small compared with any significant
8127/// physical effect (for example the experimental resolution) then the binning
8128/// cannot have an important effect. Therefore, we believe that for all
8129/// practical purposes, the probability value PROB is calculated correctly
8130/// provided the user is aware that:
8131///
8132/// 1. The value of PROB should not be expected to have exactly the correct
8133/// distribution for binned data.
8134/// 2. The user is responsible for seeing to it that the bin widths are
8135/// small compared with any physical phenomena of interest.
8136/// 3. The effect of binning (if any) is always to make the value of PROB
8137/// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
8138/// will assure that at most 5% of truly compatible histograms are rejected,
8139/// and usually somewhat less."
8140///
8141/// Note also that for GoF test of unbinned data ROOT provides also the class
8142/// ROOT::Math::GoFTest. The class has also method for doing one sample tests
8143/// (i.e. comparing the data with a given distribution).
8144
8146{
8147 TString opt = option;
8148 opt.ToUpper();
8149
8150 Double_t prob = 0;
8151 TH1 *h1 = (TH1*)this;
8152 if (h2 == nullptr) return 0;
8153 const TAxis *axis1 = h1->GetXaxis();
8154 const TAxis *axis2 = h2->GetXaxis();
8155 Int_t ncx1 = axis1->GetNbins();
8156 Int_t ncx2 = axis2->GetNbins();
8157
8158 // Check consistency of dimensions
8159 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
8160 Error("KolmogorovTest","Histograms must be 1-D\n");
8161 return 0;
8162 }
8163
8164 // Check consistency in number of channels
8165 if (ncx1 != ncx2) {
8166 Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
8167 return 0;
8168 }
8169
8170 // empty the buffer. Probably we could add as an unbinned test
8171 if (fBuffer) ((TH1*)this)->BufferEmpty();
8172
8173 // Check consistency in bin edges
8174 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
8175 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
8176 Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
8177 return 0;
8178 }
8179 }
8180
8181 Bool_t afunc1 = kFALSE;
8182 Bool_t afunc2 = kFALSE;
8183 Double_t sum1 = 0, sum2 = 0;
8184 Double_t ew1, ew2, w1 = 0, w2 = 0;
8185 Int_t bin;
8186 Int_t ifirst = 1;
8187 Int_t ilast = ncx1;
8188 // integral of all bins (use underflow/overflow if option)
8189 if (opt.Contains("U")) ifirst = 0;
8190 if (opt.Contains("O")) ilast = ncx1 +1;
8191 for (bin = ifirst; bin <= ilast; bin++) {
8192 sum1 += h1->RetrieveBinContent(bin);
8193 sum2 += h2->RetrieveBinContent(bin);
8194 ew1 = h1->GetBinError(bin);
8195 ew2 = h2->GetBinError(bin);
8196 w1 += ew1*ew1;
8197 w2 += ew2*ew2;
8198 }
8199 if (sum1 == 0) {
8200 Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
8201 return 0;
8202 }
8203 if (sum2 == 0) {
8204 Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
8205 return 0;
8206 }
8207
8208 // calculate the effective entries.
8209 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
8210 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
8211 Double_t esum1 = 0, esum2 = 0;
8212 if (w1 > 0)
8213 esum1 = sum1 * sum1 / w1;
8214 else
8215 afunc1 = kTRUE; // use later for calculating z
8216
8217 if (w2 > 0)
8218 esum2 = sum2 * sum2 / w2;
8219 else
8220 afunc2 = kTRUE; // use later for calculating z
8221
8222 if (afunc2 && afunc1) {
8223 Error("KolmogorovTest","Errors are zero for both histograms\n");
8224 return 0;
8225 }
8226
8227
8228 Double_t s1 = 1/sum1;
8229 Double_t s2 = 1/sum2;
8230
8231 // Find largest difference for Kolmogorov Test
8232 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
8233
8234 for (bin=ifirst;bin<=ilast;bin++) {
8235 rsum1 += s1*h1->RetrieveBinContent(bin);
8236 rsum2 += s2*h2->RetrieveBinContent(bin);
8237 dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
8238 }
8239
8240 // Get Kolmogorov probability
8241 Double_t z, prb1=0, prb2=0, prb3=0;
8242
8243 // case h1 is exact (has zero errors)
8244 if (afunc1)
8245 z = dfmax*TMath::Sqrt(esum2);
8246 // case h2 has zero errors
8247 else if (afunc2)
8248 z = dfmax*TMath::Sqrt(esum1);
8249 else
8250 // for comparison between two data sets
8251 z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
8252
8253 prob = TMath::KolmogorovProb(z);
8254
8255 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
8256 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
8257 // Combine probabilities for shape and normalization,
8258 prb1 = prob;
8259 Double_t d12 = esum1-esum2;
8260 Double_t chi2 = d12*d12/(esum1+esum2);
8261 prb2 = TMath::Prob(chi2,1);
8262 // see Eadie et al., section 11.6.2
8263 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
8264 else prob = 0;
8265 }
8266 // X option. Run Pseudo-experiments to determine NULL distribution of the
8267 // KS distance. We can find the probability from the number of pseudo-experiment that have a
8268 // KS distance larger than the one opbserved in the data.
8269 // We use the histogram with the largest statistics as a parent distribution for the NULL.
8270 // Note if one histogram has zero errors is considered as a function. In that case we use it
8271 // as parent distribution for the toys.
8272 //
8273 Int_t nEXPT = 1000;
8274 if (opt.Contains("X")) {
8275 // get number of pseudo-experiment of specified
8276 if (opt.Contains("X=")) {
8277 int numpos = opt.Index("X=") + 2; // 2 is length of X=
8278 int numlen = 0;
8279 int len = opt.Length();
8280 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) )
8281 numlen++;
8282 TString snum = opt(numpos,numlen);
8283 int num = atoi(snum.Data());
8284 if (num <= 0)
8285 Warning("KolmogorovTest","invalid number of toys given: %d - use 1000",num);
8286 else
8287 nEXPT = num;
8288 }
8289
8290 Double_t dSEXPT;
8291 TH1D hparent;
8292 // we cannot have afunc1 and func2 both True
8293 if (afunc1 || esum1 > esum2 ) h1->Copy(hparent);
8294 else h2->Copy(hparent);
8295
8296 // copy h1Expt from h1 and h2. It is just needed to get the correct binning
8297
8298
8299 if (hparent.GetMinimum() < 0.0) {
8300 // we need to create a new histogram
8301 // With negative bins we can't draw random samples in a meaningful way.
8302 Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
8303 "skewed. Reduce number of bins for histogram?");
8304 while (hparent.GetMinimum() < 0.0) {
8305 Int_t idx = hparent.GetMinimumBin();
8306 hparent.SetBinContent(idx, 0.0);
8307 }
8308 }
8309
8310 // make nEXPT experiments (this should be a parameter)
8311 prb3 = 0;
8312 TH1D h1Expt;
8313 h1->Copy(h1Expt);
8314 TH1D h2Expt;
8315 h1->Copy(h2Expt);
8316 // loop on pseudoexperients and generate the two histograms h1Expt and h2Expt according to the
8317 // parent distribution. In case the parent distribution is not an histogram but a function randomize only one
8318 // histogram
8319 for (Int_t i=0; i < nEXPT; i++) {
8320 if (!afunc1) {
8321 h1Expt.Reset();
8322 h1Expt.FillRandom(&hparent, (Int_t)esum1);
8323 }
8324 if (!afunc2) {
8325 h2Expt.Reset();
8326 h2Expt.FillRandom(&hparent, (Int_t)esum2);
8327 }
8328 // note we cannot have both afunc1 and afunc2 to be true
8329 if (afunc1)
8330 dSEXPT = hparent.KolmogorovTest(&h2Expt,"M");
8331 else if (afunc2)
8332 dSEXPT = hparent.KolmogorovTest(&h1Expt,"M");
8333 else
8334 dSEXPT = h1Expt.KolmogorovTest(&h2Expt,"M");
8335 // count number of cases toy KS distance (TS) is larger than oberved one
8336 if (dSEXPT>dfmax) prb3 += 1.0;
8337 }
8338 // compute p-value
8339 prb3 /= (Double_t)nEXPT;
8340 }
8341
8342
8343 // debug printout
8344 if (opt.Contains("D")) {
8345 printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
8346 printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
8347 printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
8348 if (opt.Contains("N"))
8349 printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
8350 if (opt.Contains("X"))
8351 printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
8352 }
8353 // This numerical error condition should never occur:
8354 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
8355 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
8356
8357 if(opt.Contains("M")) return dfmax;
8358 else if(opt.Contains("X")) return prb3;
8359 else return prob;
8360}
8361
8362////////////////////////////////////////////////////////////////////////////////
8363/// Replace bin contents by the contents of array content
8364
8365void TH1::SetContent(const Double_t *content)
8366{
8367 fEntries = fNcells;
8368 fTsumw = 0;
8369 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
8370}
8371
8372////////////////////////////////////////////////////////////////////////////////
8373/// Return contour values into array levels if pointer levels is non zero.
8374///
8375/// The function returns the number of contour levels.
8376/// see GetContourLevel to return one contour only
8377
8379{
8380 Int_t nlevels = fContour.fN;
8381 if (levels) {
8382 if (nlevels == 0) {
8383 nlevels = 20;
8384 SetContour(nlevels);
8385 } else {
8386 if (TestBit(kUserContour) == 0) SetContour(nlevels);
8387 }
8388 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
8389 }
8390 return nlevels;
8391}
8392
8393////////////////////////////////////////////////////////////////////////////////
8394/// Return value of contour number level.
8395/// Use GetContour to return the array of all contour levels
8396
8398{
8399 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
8400}
8401
8402////////////////////////////////////////////////////////////////////////////////
8403/// Return the value of contour number "level" in Pad coordinates.
8404/// ie: if the Pad is in log scale along Z it returns le log of the contour level
8405/// value. See GetContour to return the array of all contour levels
8406
8408{
8409 if (level <0 || level >= fContour.fN) return 0;
8410 Double_t zlevel = fContour.fArray[level];
8411
8412 // In case of user defined contours and Pad in log scale along Z,
8413 // fContour.fArray doesn't contain the log of the contour whereas it does
8414 // in case of equidistant contours.
8415 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
8416 if (zlevel <= 0) return 0;
8417 zlevel = TMath::Log10(zlevel);
8418 }
8419 return zlevel;
8420}
8421
8422////////////////////////////////////////////////////////////////////////////////
8423/// Set the maximum number of entries to be kept in the buffer.
8424
8425void TH1::SetBuffer(Int_t buffersize, Option_t * /*option*/)
8426{
8427 if (fBuffer) {
8428 BufferEmpty();
8429 delete [] fBuffer;
8430 fBuffer = nullptr;
8431 }
8432 if (buffersize <= 0) {
8433 fBufferSize = 0;
8434 return;
8435 }
8436 if (buffersize < 100) buffersize = 100;
8437 fBufferSize = 1 + buffersize*(fDimension+1);
8439 memset(fBuffer, 0, sizeof(Double_t)*fBufferSize);
8440}
8441
8442////////////////////////////////////////////////////////////////////////////////
8443/// Set the number and values of contour levels.
8444///
8445/// By default the number of contour levels is set to 20. The contours values
8446/// in the array "levels" should be specified in increasing order.
8447///
8448/// if argument levels = 0 or missing, equidistant contours are computed
8449
8450void TH1::SetContour(Int_t nlevels, const Double_t *levels)
8451{
8452 Int_t level;
8454 if (nlevels <=0 ) {
8455 fContour.Set(0);
8456 return;
8457 }
8458 fContour.Set(nlevels);
8459
8460 // - Contour levels are specified
8461 if (levels) {
8463 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
8464 } else {
8465 // - contour levels are computed automatically as equidistant contours
8466 Double_t zmin = GetMinimum();
8467 Double_t zmax = GetMaximum();
8468 if ((zmin == zmax) && (zmin != 0)) {
8469 zmax += 0.01*TMath::Abs(zmax);
8470 zmin -= 0.01*TMath::Abs(zmin);
8471 }
8472 Double_t dz = (zmax-zmin)/Double_t(nlevels);
8473 if (gPad && gPad->GetLogz()) {
8474 if (zmax <= 0) return;
8475 if (zmin <= 0) zmin = 0.001*zmax;
8476 zmin = TMath::Log10(zmin);
8477 zmax = TMath::Log10(zmax);
8478 dz = (zmax-zmin)/Double_t(nlevels);
8479 }
8480 for (level=0; level<nlevels; level++) {
8481 fContour.fArray[level] = zmin + dz*Double_t(level);
8482 }
8483 }
8484}
8485
8486////////////////////////////////////////////////////////////////////////////////
8487/// Set value for one contour level.
8488
8490{
8491 if (level < 0 || level >= fContour.fN) return;
8493 fContour.fArray[level] = value;
8494}
8495
8496////////////////////////////////////////////////////////////////////////////////
8497/// Return maximum value smaller than maxval of bins in the range,
8498/// unless the value has been overridden by TH1::SetMaximum,
8499/// in which case it returns that value. This happens, for example,
8500/// when the histogram is drawn and the y or z axis limits are changed
8501///
8502/// To get the maximum value of bins in the histogram regardless of
8503/// whether the value has been overridden (using TH1::SetMaximum), use
8504///
8505/// ~~~ {.cpp}
8506/// h->GetBinContent(h->GetMaximumBin())
8507/// ~~~
8508///
8509/// TH1::GetMaximumBin can be used to get the location of the maximum
8510/// value.
8511
8512Double_t TH1::GetMaximum(Double_t maxval) const
8513{
8514 if (fMaximum != -1111) return fMaximum;
8515
8516 // empty the buffer
8517 if (fBuffer) ((TH1*)this)->BufferEmpty();
8518
8519 Int_t bin, binx, biny, binz;
8520 Int_t xfirst = fXaxis.GetFirst();
8521 Int_t xlast = fXaxis.GetLast();
8522 Int_t yfirst = fYaxis.GetFirst();
8523 Int_t ylast = fYaxis.GetLast();
8524 Int_t zfirst = fZaxis.GetFirst();
8525 Int_t zlast = fZaxis.GetLast();
8526 Double_t maximum = -FLT_MAX, value;
8527 for (binz=zfirst;binz<=zlast;binz++) {
8528 for (biny=yfirst;biny<=ylast;biny++) {
8529 for (binx=xfirst;binx<=xlast;binx++) {
8530 bin = GetBin(binx,biny,binz);
8532 if (value > maximum && value < maxval) maximum = value;
8533 }
8534 }
8535 }
8536 return maximum;
8537}
8538
8539////////////////////////////////////////////////////////////////////////////////
8540/// Return location of bin with maximum value in the range.
8541///
8542/// TH1::GetMaximum can be used to get the maximum value.
8543
8545{
8546 Int_t locmax, locmay, locmaz;
8547 return GetMaximumBin(locmax, locmay, locmaz);
8548}
8549
8550////////////////////////////////////////////////////////////////////////////////
8551/// Return location of bin with maximum value in the range.
8552
8553Int_t TH1::GetMaximumBin(Int_t &locmax, Int_t &locmay, Int_t &locmaz) const
8554{
8555 // empty the buffer
8556 if (fBuffer) ((TH1*)this)->BufferEmpty();
8557
8558 Int_t bin, binx, biny, binz;
8559 Int_t locm;
8560 Int_t xfirst = fXaxis.GetFirst();
8561 Int_t xlast = fXaxis.GetLast();
8562 Int_t yfirst = fYaxis.GetFirst();
8563 Int_t ylast = fYaxis.GetLast();
8564 Int_t zfirst = fZaxis.GetFirst();
8565 Int_t zlast = fZaxis.GetLast();
8566 Double_t maximum = -FLT_MAX, value;
8567 locm = locmax = locmay = locmaz = 0;
8568 for (binz=zfirst;binz<=zlast;binz++) {
8569 for (biny=yfirst;biny<=ylast;biny++) {
8570 for (binx=xfirst;binx<=xlast;binx++) {
8571 bin = GetBin(binx,biny,binz);
8573 if (value > maximum) {
8574 maximum = value;
8575 locm = bin;
8576 locmax = binx;
8577 locmay = biny;
8578 locmaz = binz;
8579 }
8580 }
8581 }
8582 }
8583 return locm;
8584}
8585
8586////////////////////////////////////////////////////////////////////////////////
8587/// Return minimum value larger than minval of bins in the range,
8588/// unless the value has been overridden by TH1::SetMinimum,
8589/// in which case it returns that value. This happens, for example,
8590/// when the histogram is drawn and the y or z axis limits are changed
8591///
8592/// To get the minimum value of bins in the histogram regardless of
8593/// whether the value has been overridden (using TH1::SetMinimum), use
8594///
8595/// ~~~ {.cpp}
8596/// h->GetBinContent(h->GetMinimumBin())
8597/// ~~~
8598///
8599/// TH1::GetMinimumBin can be used to get the location of the
8600/// minimum value.
8601
8602Double_t TH1::GetMinimum(Double_t minval) const
8603{
8604 if (fMinimum != -1111) return fMinimum;
8605
8606 // empty the buffer
8607 if (fBuffer) ((TH1*)this)->BufferEmpty();
8608
8609 Int_t bin, binx, biny, binz;
8610 Int_t xfirst = fXaxis.GetFirst();
8611 Int_t xlast = fXaxis.GetLast();
8612 Int_t yfirst = fYaxis.GetFirst();
8613 Int_t ylast = fYaxis.GetLast();
8614 Int_t zfirst = fZaxis.GetFirst();
8615 Int_t zlast = fZaxis.GetLast();
8616 Double_t minimum=FLT_MAX, value;
8617 for (binz=zfirst;binz<=zlast;binz++) {
8618 for (biny=yfirst;biny<=ylast;biny++) {
8619 for (binx=xfirst;binx<=xlast;binx++) {
8620 bin = GetBin(binx,biny,binz);
8622 if (value < minimum && value > minval) minimum = value;
8623 }
8624 }
8625 }
8626 return minimum;
8627}
8628
8629////////////////////////////////////////////////////////////////////////////////
8630/// Return location of bin with minimum value in the range.
8631
8633{
8634 Int_t locmix, locmiy, locmiz;
8635 return GetMinimumBin(locmix, locmiy, locmiz);
8636}
8637
8638////////////////////////////////////////////////////////////////////////////////
8639/// Return location of bin with minimum value in the range.
8640
8641Int_t TH1::GetMinimumBin(Int_t &locmix, Int_t &locmiy, Int_t &locmiz) const
8642{
8643 // empty the buffer
8644 if (fBuffer) ((TH1*)this)->BufferEmpty();
8645
8646 Int_t bin, binx, biny, binz;
8647 Int_t locm;
8648 Int_t xfirst = fXaxis.GetFirst();
8649 Int_t xlast = fXaxis.GetLast();
8650 Int_t yfirst = fYaxis.GetFirst();
8651 Int_t ylast = fYaxis.GetLast();
8652 Int_t zfirst = fZaxis.GetFirst();
8653 Int_t zlast = fZaxis.GetLast();
8654 Double_t minimum = FLT_MAX, value;
8655 locm = locmix = locmiy = locmiz = 0;
8656 for (binz=zfirst;binz<=zlast;binz++) {
8657 for (biny=yfirst;biny<=ylast;biny++) {
8658 for (binx=xfirst;binx<=xlast;binx++) {
8659 bin = GetBin(binx,biny,binz);
8661 if (value < minimum) {
8662 minimum = value;
8663 locm = bin;
8664 locmix = binx;
8665 locmiy = biny;
8666 locmiz = binz;
8667 }
8668 }
8669 }
8670 }
8671 return locm;
8672}
8673
8674///////////////////////////////////////////////////////////////////////////////
8675/// Retrieve the minimum and maximum values in the histogram
8676///
8677/// This will not return a cached value and will always search the
8678/// histogram for the min and max values. The user can condition whether
8679/// or not to call this with the GetMinimumStored() and GetMaximumStored()
8680/// methods. If the cache is empty, then the value will be -1111. Users
8681/// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8682/// For example, the following recipe will make efficient use of this method
8683/// and the cached minimum and maximum values.
8684//
8685/// \code{.cpp}
8686/// Double_t currentMin = pHist->GetMinimumStored();
8687/// Double_t currentMax = pHist->GetMaximumStored();
8688/// if ((currentMin == -1111) || (currentMax == -1111)) {
8689/// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8690/// pHist->SetMinimum(currentMin);
8691/// pHist->SetMaximum(currentMax);
8692/// }
8693/// \endcode
8694///
8695/// \param min reference to variable that will hold found minimum value
8696/// \param max reference to variable that will hold found maximum value
8697
8698void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8699{
8700 // empty the buffer
8701 if (fBuffer) ((TH1*)this)->BufferEmpty();
8702
8703 Int_t bin, binx, biny, binz;
8704 Int_t xfirst = fXaxis.GetFirst();
8705 Int_t xlast = fXaxis.GetLast();
8706 Int_t yfirst = fYaxis.GetFirst();
8707 Int_t ylast = fYaxis.GetLast();
8708 Int_t zfirst = fZaxis.GetFirst();
8709 Int_t zlast = fZaxis.GetLast();
8710 min=TMath::Infinity();
8711 max=-TMath::Infinity();
8713 for (binz=zfirst;binz<=zlast;binz++) {
8714 for (biny=yfirst;biny<=ylast;biny++) {
8715 for (binx=xfirst;binx<=xlast;binx++) {
8716 bin = GetBin(binx,biny,binz);
8718 if (value < min) min = value;
8719 if (value > max) max = value;
8720 }
8721 }
8722 }
8723}
8724
8725////////////////////////////////////////////////////////////////////////////////
8726/// Redefine x axis parameters.
8727///
8728/// The X axis parameters are modified.
8729/// The bins content array is resized
8730/// if errors (Sumw2) the errors array is resized
8731/// The previous bin contents are lost
8732/// To change only the axis limits, see TAxis::SetRange
8733
8735{
8736 if (GetDimension() != 1) {
8737 Error("SetBins","Operation only valid for 1-d histograms");
8738 return;
8739 }
8740 fXaxis.SetRange(0,0);
8741 fXaxis.Set(nx,xmin,xmax);
8742 fYaxis.Set(1,0,1);
8743 fZaxis.Set(1,0,1);
8744 fNcells = nx+2;
8746 if (fSumw2.fN) {
8748 }
8749}
8750
8751////////////////////////////////////////////////////////////////////////////////
8752/// Redefine x axis parameters with variable bin sizes.
8753///
8754/// The X axis parameters are modified.
8755/// The bins content array is resized
8756/// if errors (Sumw2) the errors array is resized
8757/// The previous bin contents are lost
8758/// To change only the axis limits, see TAxis::SetRange
8759/// xBins is supposed to be of length nx+1
8760
8761void TH1::SetBins(Int_t nx, const Double_t *xBins)
8762{
8763 if (GetDimension() != 1) {
8764 Error("SetBins","Operation only valid for 1-d histograms");
8765 return;
8766 }
8767 fXaxis.SetRange(0,0);
8768 fXaxis.Set(nx,xBins);
8769 fYaxis.Set(1,0,1);
8770 fZaxis.Set(1,0,1);
8771 fNcells = nx+2;
8773 if (fSumw2.fN) {
8775 }
8776}
8777
8778////////////////////////////////////////////////////////////////////////////////
8779/// Redefine x and y axis parameters.
8780///
8781/// The X and Y axis parameters are modified.
8782/// The bins content array is resized
8783/// if errors (Sumw2) the errors array is resized
8784/// The previous bin contents are lost
8785/// To change only the axis limits, see TAxis::SetRange
8786
8788{
8789 if (GetDimension() != 2) {
8790 Error("SetBins","Operation only valid for 2-D histograms");
8791 return;
8792 }
8793 fXaxis.SetRange(0,0);
8794 fYaxis.SetRange(0,0);
8795 fXaxis.Set(nx,xmin,xmax);
8796 fYaxis.Set(ny,ymin,ymax);
8797 fZaxis.Set(1,0,1);
8798 fNcells = (nx+2)*(ny+2);
8800 if (fSumw2.fN) {
8802 }
8803}
8804
8805////////////////////////////////////////////////////////////////////////////////
8806/// Redefine x and y axis parameters with variable bin sizes.
8807///
8808/// The X and Y axis parameters are modified.
8809/// The bins content array is resized
8810/// if errors (Sumw2) the errors array is resized
8811/// The previous bin contents are lost
8812/// To change only the axis limits, see TAxis::SetRange
8813/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
8814
8815void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
8816{
8817 if (GetDimension() != 2) {
8818 Error("SetBins","Operation only valid for 2-D histograms");
8819 return;
8820 }
8821 fXaxis.SetRange(0,0);
8822 fYaxis.SetRange(0,0);
8823 fXaxis.Set(nx,xBins);
8824 fYaxis.Set(ny,yBins);
8825 fZaxis.Set(1,0,1);
8826 fNcells = (nx+2)*(ny+2);
8828 if (fSumw2.fN) {
8830 }
8831}
8832
8833////////////////////////////////////////////////////////////////////////////////
8834/// Redefine x, y and z axis parameters.
8835///
8836/// The X, Y and Z axis parameters are modified.
8837/// The bins content array is resized
8838/// if errors (Sumw2) the errors array is resized
8839/// The previous bin contents are lost
8840/// To change only the axis limits, see TAxis::SetRange
8841
8843{
8844 if (GetDimension() != 3) {
8845 Error("SetBins","Operation only valid for 3-D histograms");
8846 return;
8847 }
8848 fXaxis.SetRange(0,0);
8849 fYaxis.SetRange(0,0);
8850 fZaxis.SetRange(0,0);
8851 fXaxis.Set(nx,xmin,xmax);
8852 fYaxis.Set(ny,ymin,ymax);
8853 fZaxis.Set(nz,zmin,zmax);
8854 fNcells = (nx+2)*(ny+2)*(nz+2);
8856 if (fSumw2.fN) {
8858 }
8859}
8860
8861////////////////////////////////////////////////////////////////////////////////
8862/// Redefine x, y and z axis parameters with variable bin sizes.
8863///
8864/// The X, Y and Z axis parameters are modified.
8865/// The bins content array is resized
8866/// if errors (Sumw2) the errors array is resized
8867/// The previous bin contents are lost
8868/// To change only the axis limits, see TAxis::SetRange
8869/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
8870/// zBins is supposed to be of length nz+1
8871
8872void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
8873{
8874 if (GetDimension() != 3) {
8875 Error("SetBins","Operation only valid for 3-D histograms");
8876 return;
8877 }
8878 fXaxis.SetRange(0,0);
8879 fYaxis.SetRange(0,0);
8880 fZaxis.SetRange(0,0);
8881 fXaxis.Set(nx,xBins);
8882 fYaxis.Set(ny,yBins);
8883 fZaxis.Set(nz,zBins);
8884 fNcells = (nx+2)*(ny+2)*(nz+2);
8886 if (fSumw2.fN) {
8888 }
8889}
8890
8891////////////////////////////////////////////////////////////////////////////////
8892/// By default, when a histogram is created, it is added to the list
8893/// of histogram objects in the current directory in memory.
8894/// Remove reference to this histogram from current directory and add
8895/// reference to new directory dir. dir can be 0 in which case the
8896/// histogram does not belong to any directory.
8897///
8898/// Note that the directory is not a real property of the histogram and
8899/// it will not be copied when the histogram is copied or cloned.
8900/// If the user wants to have the copied (cloned) histogram in the same
8901/// directory, he needs to set again the directory using SetDirectory to the
8902/// copied histograms
8903
8905{
8906 if (fDirectory == dir) return;
8907 if (fDirectory) fDirectory->Remove(this);
8908 fDirectory = dir;
8909 if (fDirectory) {
8911 fDirectory->Append(this);
8912 }
8913}
8914
8915////////////////////////////////////////////////////////////////////////////////
8916/// Replace bin errors by values in array error.
8917
8918void TH1::SetError(const Double_t *error)
8919{
8920 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
8921}
8922
8923////////////////////////////////////////////////////////////////////////////////
8924/// Change the name of this histogram
8926
8927void TH1::SetName(const char *name)
8928{
8929 // Histograms are named objects in a THashList.
8930 // We must update the hashlist if we change the name
8931 // We protect this operation
8933 if (fDirectory) fDirectory->Remove(this);
8934 fName = name;
8935 if (fDirectory) fDirectory->Append(this);
8936}
8937
8938////////////////////////////////////////////////////////////////////////////////
8939/// Change the name and title of this histogram
8940
8941void TH1::SetNameTitle(const char *name, const char *title)
8942{
8943 // Histograms are named objects in a THashList.
8944 // We must update the hashlist if we change the name
8945 SetName(name);
8946 SetTitle(title);
8947}
8948
8949////////////////////////////////////////////////////////////////////////////////
8950/// Set statistics option on/off.
8951///
8952/// By default, the statistics box is drawn.
8953/// The paint options can be selected via gStyle->SetOptStat.
8954/// This function sets/resets the kNoStats bit in the histogram object.
8955/// It has priority over the Style option.
8956
8957void TH1::SetStats(Bool_t stats)
8958{
8960 if (!stats) {
8962 //remove the "stats" object from the list of functions
8963 if (fFunctions) {
8964 TObject *obj = fFunctions->FindObject("stats");
8965 if (obj) {
8966 fFunctions->Remove(obj);
8967 delete obj;
8968 }
8969 }
8970 }
8971}
8972
8973////////////////////////////////////////////////////////////////////////////////
8974/// Create structure to store sum of squares of weights.
8975///
8976/// if histogram is already filled, the sum of squares of weights
8977/// is filled with the existing bin contents
8978///
8979/// The error per bin will be computed as sqrt(sum of squares of weight)
8980/// for each bin.
8981///
8982/// This function is automatically called when the histogram is created
8983/// if the static function TH1::SetDefaultSumw2 has been called before.
8984/// If flag = false the structure containing the sum of the square of weights
8985/// is rest and it will be empty, but it is not deleted (i.e. GetSumw2()->fN = 0)
8986
8987void TH1::Sumw2(Bool_t flag)
8988{
8989 if (!flag) {
8990 // clear the array if existing - do nothing otherwise
8991 if (fSumw2.fN > 0 ) fSumw2.Set(0);
8992 return;
8993 }
8994
8995 if (fSumw2.fN == fNcells) {
8996 if (!fgDefaultSumw2 )
8997 Warning("Sumw2","Sum of squares of weights structure already created");
8998 return;
8999 }
9000
9002
9003 // empty the buffer
9004 if (fBuffer) BufferEmpty();
9005
9006 if (fEntries > 0)
9007 for (Int_t i = 0; i < fNcells; ++i)
9009}
9010
9011////////////////////////////////////////////////////////////////////////////////
9012/// Return pointer to function with name.
9013///
9014///
9015/// Functions such as TH1::Fit store the fitted function in the list of
9016/// functions of this histogram.
9017
9018TF1 *TH1::GetFunction(const char *name) const
9019{
9020 return (TF1*)fFunctions->FindObject(name);
9021}
9022
9023////////////////////////////////////////////////////////////////////////////////
9024/// Return value of error associated to bin number bin.
9025///
9026/// if the sum of squares of weights has been defined (via Sumw2),
9027/// this function returns the sqrt(sum of w2).
9028/// otherwise it returns the sqrt(contents) for this bin.
9029
9031{
9032 if (bin < 0) bin = 0;
9033 if (bin >= fNcells) bin = fNcells-1;
9034 if (fBuffer) ((TH1*)this)->BufferEmpty();
9035 if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
9036
9038}
9039
9040////////////////////////////////////////////////////////////////////////////////
9041/// Return lower error associated to bin number bin.
9042///
9043/// The error will depend on the statistic option used will return
9044/// the binContent - lower interval value
9045
9047{
9048 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9049 // in case of weighted histogram check if it is really weighted
9050 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9051
9052 if (bin < 0) bin = 0;
9053 if (bin >= fNcells) bin = fNcells-1;
9054 if (fBuffer) ((TH1*)this)->BufferEmpty();
9055
9056 Double_t alpha = 1.- 0.682689492;
9057 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9058
9060 Int_t n = int(c);
9061 if (n < 0) {
9062 Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
9063 ((TH1*)this)->fBinStatErrOpt = kNormal;
9064 return GetBinError(bin);
9065 }
9066
9067 if (n == 0) return 0;
9068 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
9069}
9070
9071////////////////////////////////////////////////////////////////////////////////
9072/// Return upper error associated to bin number bin.
9073///
9074/// The error will depend on the statistic option used will return
9075/// the binContent - upper interval value
9076
9078{
9079 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9080 // in case of weighted histogram check if it is really weighted
9081 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9082 if (bin < 0) bin = 0;
9083 if (bin >= fNcells) bin = fNcells-1;
9084 if (fBuffer) ((TH1*)this)->BufferEmpty();
9085
9086 Double_t alpha = 1.- 0.682689492;
9087 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9088
9090 Int_t n = int(c);
9091 if (n < 0) {
9092 Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
9093 ((TH1*)this)->fBinStatErrOpt = kNormal;
9094 return GetBinError(bin);
9095 }
9096
9097 // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
9098 // decide to return always (1-alpha)/2 upper interval
9099 //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
9100 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
9101}
9102
9103//L.M. These following getters are useless and should be probably deprecated
9104////////////////////////////////////////////////////////////////////////////////
9105/// Return bin center for 1D histogram.
9106/// Better to use h1.GetXaxis()->GetBinCenter(bin)
9107
9109{
9110 if (fDimension == 1) return fXaxis.GetBinCenter(bin);
9111 Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
9112 return TMath::QuietNaN();
9113}
9114
9115////////////////////////////////////////////////////////////////////////////////
9116/// Return bin lower edge for 1D histogram.
9117/// Better to use h1.GetXaxis()->GetBinLowEdge(bin)
9118
9120{
9121 if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
9122 Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
9123 return TMath::QuietNaN();
9124}
9125
9126////////////////////////////////////////////////////////////////////////////////
9127/// Return bin width for 1D histogram.
9128/// Better to use h1.GetXaxis()->GetBinWidth(bin)
9129
9131{
9132 if (fDimension == 1) return fXaxis.GetBinWidth(bin);
9133 Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
9134 return TMath::QuietNaN();
9135}
9136
9137////////////////////////////////////////////////////////////////////////////////
9138/// Fill array with center of bins for 1D histogram
9139/// Better to use h1.GetXaxis()->GetCenter(center)
9140
9141void TH1::GetCenter(Double_t *center) const
9142{
9143 if (fDimension == 1) {
9144 fXaxis.GetCenter(center);
9145 return;
9146 }
9147 Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
9148}
9149
9150////////////////////////////////////////////////////////////////////////////////
9151/// Fill array with low edge of bins for 1D histogram
9152/// Better to use h1.GetXaxis()->GetLowEdge(edge)
9153
9154void TH1::GetLowEdge(Double_t *edge) const
9155{
9156 if (fDimension == 1) {
9157 fXaxis.GetLowEdge(edge);
9158 return;
9159 }
9160 Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
9161}
9162
9163////////////////////////////////////////////////////////////////////////////////
9164/// Set the bin Error
9165/// Note that this resets the bin eror option to be of Normal Type and for the
9166/// non-empty bin the bin error is set by default to the square root of their content.
9167/// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
9168/// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
9169/// will not be recalculated after setting the content and a default error = 0 will be used for those bins.
9170///
9171/// See convention for numbering bins in TH1::GetBin
9172
9173void TH1::SetBinError(Int_t bin, Double_t error)
9174{
9175 if (bin < 0 || bin>= fNcells) return;
9176 if (!fSumw2.fN) Sumw2();
9177 fSumw2.fArray[bin] = error * error;
9178 // reset the bin error option
9180}
9181
9182////////////////////////////////////////////////////////////////////////////////
9183/// Set bin content
9184/// see convention for numbering bins in TH1::GetBin
9185/// In case the bin number is greater than the number of bins and
9186/// the timedisplay option is set or CanExtendAllAxes(),
9187/// the number of bins is automatically doubled to accommodate the new bin
9188
9189void TH1::SetBinContent(Int_t bin, Double_t content)
9190{
9191 fEntries++;
9192 fTsumw = 0;
9193 if (bin < 0) return;
9194 if (bin >= fNcells-1) {
9196 while (bin >= fNcells-1) LabelsInflate();
9197 } else {
9198 if (bin == fNcells-1) UpdateBinContent(bin, content);
9199 return;
9200 }
9201 }
9202 UpdateBinContent(bin, content);
9203}
9204
9205////////////////////////////////////////////////////////////////////////////////
9206/// See convention for numbering bins in TH1::GetBin
9207
9208void TH1::SetBinError(Int_t binx, Int_t biny, Double_t error)
9209{
9210 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9211 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9212 SetBinError(GetBin(binx, biny), error);
9213}
9214
9215////////////////////////////////////////////////////////////////////////////////
9216/// See convention for numbering bins in TH1::GetBin
9217
9218void TH1::SetBinError(Int_t binx, Int_t biny, Int_t binz, Double_t error)
9219{
9220 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9221 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9222 if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
9223 SetBinError(GetBin(binx, biny, binz), error);
9224}
9225
9226////////////////////////////////////////////////////////////////////////////////
9227/// This function calculates the background spectrum in this histogram.
9228/// The background is returned as a histogram.
9229///
9230/// \param[in] niter number of iterations (default value = 2)
9231/// Increasing niter make the result smoother and lower.
9232/// \param[in] option may contain one of the following options
9233/// - to set the direction parameter
9234/// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
9235/// - filterOrder-order of clipping filter (default "BackOrder2")
9236/// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
9237/// - "nosmoothing" - if selected, the background is not smoothed
9238/// By default the background is smoothed.
9239/// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
9240/// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
9241/// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
9242/// - "nocompton" - if selected the estimation of Compton edge
9243/// will be not be included (by default the compton estimation is set)
9244/// - "same" if this option is specified, the resulting background
9245/// histogram is superimposed on the picture in the current pad.
9246/// This option is given by default.
9247///
9248/// NOTE that the background is only evaluated in the current range of this histogram.
9249/// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
9250/// the returned histogram will be created with the same number of bins
9251/// as this input histogram, but only bins from binmin to binmax will be filled
9252/// with the estimated background.
9253
9255{
9256 return (TH1*)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticBackground((TH1*)0x%zx,%d,\"%s\")",
9257 (size_t)this, niter, option).Data());
9258}
9259
9260////////////////////////////////////////////////////////////////////////////////
9261/// Interface to TSpectrum::Search.
9262/// The function finds peaks in this histogram where the width is > sigma
9263/// and the peak maximum greater than threshold*maximum bin content of this.
9264/// For more details see TSpectrum::Search.
9265/// Note the difference in the default value for option compared to TSpectrum::Search
9266/// option="" by default (instead of "goff").
9267
9269{
9270 return (Int_t)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticSearch((TH1*)0x%zx,%g,\"%s\",%g)",
9271 (size_t)this, sigma, option, threshold).Data());
9272}
9273
9274////////////////////////////////////////////////////////////////////////////////
9275/// For a given transform (first parameter), fills the histogram (second parameter)
9276/// with the transform output data, specified in the third parameter
9277/// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
9278/// and the user is responsible for deleting it.
9279///
9280/// Available options:
9281/// - "RE" - real part of the output
9282/// - "IM" - imaginary part of the output
9283/// - "MAG" - magnitude of the output
9284/// - "PH" - phase of the output
9285
9287{
9288 if (!fft || !fft->GetN() ) {
9289 ::Error("TransformHisto","Invalid FFT transform class");
9290 return nullptr;
9291 }
9292
9293 if (fft->GetNdim()>2){
9294 ::Error("TransformHisto","Only 1d and 2D transform are supported");
9295 return nullptr;
9296 }
9297 Int_t binx,biny;
9298 TString opt = option;
9299 opt.ToUpper();
9300 Int_t *n = fft->GetN();
9301 TH1 *hout=nullptr;
9302 if (h_output) {
9303 hout = h_output;
9304 }
9305 else {
9306 TString name = TString::Format("out_%s", opt.Data());
9307 if (fft->GetNdim()==1)
9308 hout = new TH1D(name, name,n[0], 0, n[0]);
9309 else if (fft->GetNdim()==2)
9310 hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
9311 }
9312 R__ASSERT(hout != nullptr);
9313 TString type=fft->GetType();
9314 Int_t ind[2];
9315 if (opt.Contains("RE")){
9316 if (type.Contains("2C") || type.Contains("2HC")) {
9317 Double_t re, im;
9318 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9319 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9320 ind[0] = binx-1; ind[1] = biny-1;
9321 fft->GetPointComplex(ind, re, im);
9322 hout->SetBinContent(binx, biny, re);
9323 }
9324 }
9325 } else {
9326 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9327 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9328 ind[0] = binx-1; ind[1] = biny-1;
9329 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
9330 }
9331 }
9332 }
9333 }
9334 if (opt.Contains("IM")) {
9335 if (type.Contains("2C") || type.Contains("2HC")) {
9336 Double_t re, im;
9337 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9338 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9339 ind[0] = binx-1; ind[1] = biny-1;
9340 fft->GetPointComplex(ind, re, im);
9341 hout->SetBinContent(binx, biny, im);
9342 }
9343 }
9344 } else {
9345 ::Error("TransformHisto","No complex numbers in the output");
9346 return nullptr;
9347 }
9348 }
9349 if (opt.Contains("MA")) {
9350 if (type.Contains("2C") || type.Contains("2HC")) {
9351 Double_t re, im;
9352 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9353 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9354 ind[0] = binx-1; ind[1] = biny-1;
9355 fft->GetPointComplex(ind, re, im);
9356 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
9357 }
9358 }
9359 } else {
9360 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9361 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9362 ind[0] = binx-1; ind[1] = biny-1;
9363 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
9364 }
9365 }
9366 }
9367 }
9368 if (opt.Contains("PH")) {
9369 if (type.Contains("2C") || type.Contains("2HC")){
9370 Double_t re, im, ph;
9371 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
9372 for (biny=1; biny<=hout->GetNbinsY(); biny++){
9373 ind[0] = binx-1; ind[1] = biny-1;
9374 fft->GetPointComplex(ind, re, im);
9375 if (TMath::Abs(re) > 1e-13){
9376 ph = TMath::ATan(im/re);
9377 //find the correct quadrant
9378 if (re<0 && im<0)
9379 ph -= TMath::Pi();
9380 if (re<0 && im>=0)
9381 ph += TMath::Pi();
9382 } else {
9383 if (TMath::Abs(im) < 1e-13)
9384 ph = 0;
9385 else if (im>0)
9386 ph = TMath::Pi()*0.5;
9387 else
9388 ph = -TMath::Pi()*0.5;
9389 }
9390 hout->SetBinContent(binx, biny, ph);
9391 }
9392 }
9393 } else {
9394 printf("Pure real output, no phase");
9395 return nullptr;
9396 }
9397 }
9398
9399 return hout;
9400}
9401
9402////////////////////////////////////////////////////////////////////////////////
9403/// Raw retrieval of bin content on internal data structure
9404/// see convention for numbering bins in TH1::GetBin
9405
9407{
9408 AbstractMethod("RetrieveBinContent");
9409 return 0;
9410}
9411
9412////////////////////////////////////////////////////////////////////////////////
9413/// Raw update of bin content on internal data structure
9414/// see convention for numbering bins in TH1::GetBin
9415
9417{
9418 AbstractMethod("UpdateBinContent");
9419}
9420
9421////////////////////////////////////////////////////////////////////////////////
9422/// Print value overload
9423
9424std::string cling::printValue(TH1 *val) {
9425 std::ostringstream strm;
9426 strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
9427 return strm.str();
9428}
9429
9430//______________________________________________________________________________
9431// TH1C methods
9432// TH1C : histograms with one byte per channel. Maximum bin content = 127
9433//______________________________________________________________________________
9434
9435ClassImp(TH1C);
9436
9437////////////////////////////////////////////////////////////////////////////////
9438/// Constructor.
9439
9440TH1C::TH1C(): TH1(), TArrayC()
9441{
9442 fDimension = 1;
9443 SetBinsLength(3);
9444 if (fgDefaultSumw2) Sumw2();
9445}
9446
9447////////////////////////////////////////////////////////////////////////////////
9448/// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
9449/// (see TH1::TH1 for explanation of parameters)
9450
9451TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9452: TH1(name,title,nbins,xlow,xup)
9453{
9454 fDimension = 1;
9456
9457 if (xlow >= xup) SetBuffer(fgBufferSize);
9458 if (fgDefaultSumw2) Sumw2();
9459}
9460
9461////////////////////////////////////////////////////////////////////////////////
9462/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9463/// (see TH1::TH1 for explanation of parameters)
9464
9465TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9466: TH1(name,title,nbins,xbins)
9467{
9468 fDimension = 1;
9470 if (fgDefaultSumw2) Sumw2();
9471}
9472
9473////////////////////////////////////////////////////////////////////////////////
9474/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9475/// (see TH1::TH1 for explanation of parameters)
9476
9477TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9478: TH1(name,title,nbins,xbins)
9479{
9480 fDimension = 1;
9482 if (fgDefaultSumw2) Sumw2();
9483}
9484
9485////////////////////////////////////////////////////////////////////////////////
9486/// Destructor.
9487
9489{
9490}
9491
9492////////////////////////////////////////////////////////////////////////////////
9493/// Copy constructor.
9494/// The list of functions is not copied. (Use Clone() if needed)
9495
9496TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
9497{
9498 h1c.TH1C::Copy(*this);
9499}
9500
9501////////////////////////////////////////////////////////////////////////////////
9502/// Increment bin content by 1.
9503/// Passing an out-of-range bin leads to undefined behavior
9504
9505void TH1C::AddBinContent(Int_t bin)
9506{
9507 if (fArray[bin] < 127) fArray[bin]++;
9508}
9509
9510////////////////////////////////////////////////////////////////////////////////
9511/// Increment bin content by w.
9512/// Passing an out-of-range bin leads to undefined behavior
9513
9515{
9516 Int_t newval = fArray[bin] + Int_t(w);
9517 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
9518 if (newval < -127) fArray[bin] = -127;
9519 if (newval > 127) fArray[bin] = 127;
9520}
9521
9522////////////////////////////////////////////////////////////////////////////////
9523/// Copy this to newth1
9524
9525void TH1C::Copy(TObject &newth1) const
9526{
9527 TH1::Copy(newth1);
9528}
9529
9530////////////////////////////////////////////////////////////////////////////////
9531/// Reset.
9532
9534{
9537}
9538
9539////////////////////////////////////////////////////////////////////////////////
9540/// Set total number of bins including under/overflow
9541/// Reallocate bin contents array
9542
9544{
9545 if (n < 0) n = fXaxis.GetNbins() + 2;
9546 fNcells = n;
9547 TArrayC::Set(n);
9548}
9549
9550////////////////////////////////////////////////////////////////////////////////
9551/// Operator =
9552
9553TH1C& TH1C::operator=(const TH1C &h1)
9554{
9555 if (this != &h1)
9556 h1.TH1C::Copy(*this);
9557 return *this;
9558}
9559
9560////////////////////////////////////////////////////////////////////////////////
9561/// Operator *
9562
9564{
9565 TH1C hnew = h1;
9566 hnew.Scale(c1);
9567 hnew.SetDirectory(nullptr);
9568 return hnew;
9569}
9570
9571////////////////////////////////////////////////////////////////////////////////
9572/// Operator +
9573
9574TH1C operator+(const TH1C &h1, const TH1C &h2)
9575{
9576 TH1C hnew = h1;
9577 hnew.Add(&h2,1);
9578 hnew.SetDirectory(nullptr);
9579 return hnew;
9580}
9581
9582////////////////////////////////////////////////////////////////////////////////
9583/// Operator -
9584
9585TH1C operator-(const TH1C &h1, const TH1C &h2)
9586{
9587 TH1C hnew = h1;
9588 hnew.Add(&h2,-1);
9589 hnew.SetDirectory(nullptr);
9590 return hnew;
9591}
9592
9593////////////////////////////////////////////////////////////////////////////////
9594/// Operator *
9595
9596TH1C operator*(const TH1C &h1, const TH1C &h2)
9597{
9598 TH1C hnew = h1;
9599 hnew.Multiply(&h2);
9600 hnew.SetDirectory(nullptr);
9601 return hnew;
9602}
9603
9604////////////////////////////////////////////////////////////////////////////////
9605/// Operator /
9606
9607TH1C operator/(const TH1C &h1, const TH1C &h2)
9608{
9609 TH1C hnew = h1;
9610 hnew.Divide(&h2);
9611 hnew.SetDirectory(nullptr);
9612 return hnew;
9613}
9614
9615//______________________________________________________________________________
9616// TH1S methods
9617// TH1S : histograms with one short per channel. Maximum bin content = 32767
9618//______________________________________________________________________________
9619
9620ClassImp(TH1S);
9621
9622////////////////////////////////////////////////////////////////////////////////
9623/// Constructor.
9624
9625TH1S::TH1S(): TH1(), TArrayS()
9626{
9627 fDimension = 1;
9628 SetBinsLength(3);
9629 if (fgDefaultSumw2) Sumw2();
9630}
9631
9632////////////////////////////////////////////////////////////////////////////////
9633/// Create a 1-Dim histogram with fix bins of type short
9634/// (see TH1::TH1 for explanation of parameters)
9635
9636TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9637: TH1(name,title,nbins,xlow,xup)
9638{
9639 fDimension = 1;
9641
9642 if (xlow >= xup) SetBuffer(fgBufferSize);
9643 if (fgDefaultSumw2) Sumw2();
9644}
9645
9646////////////////////////////////////////////////////////////////////////////////
9647/// Create a 1-Dim histogram with variable bins of type short
9648/// (see TH1::TH1 for explanation of parameters)
9649
9650TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9651: TH1(name,title,nbins,xbins)
9652{
9653 fDimension = 1;
9655 if (fgDefaultSumw2) Sumw2();
9656}
9657
9658////////////////////////////////////////////////////////////////////////////////
9659/// Create a 1-Dim histogram with variable bins of type short
9660/// (see TH1::TH1 for explanation of parameters)
9661
9662TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9663: TH1(name,title,nbins,xbins)
9664{
9665 fDimension = 1;
9667 if (fgDefaultSumw2) Sumw2();
9668}
9669
9670////////////////////////////////////////////////////////////////////////////////
9671/// Destructor.
9672
9674{
9675}
9676
9677////////////////////////////////////////////////////////////////////////////////
9678/// Copy constructor.
9679/// The list of functions is not copied. (Use Clone() if needed)
9680
9681TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9682{
9683 h1s.TH1S::Copy(*this);
9684}
9685
9686////////////////////////////////////////////////////////////////////////////////
9687/// Increment bin content by 1.
9688/// Passing an out-of-range bin leads to undefined behavior
9689
9690void TH1S::AddBinContent(Int_t bin)
9691{
9692 if (fArray[bin] < 32767) fArray[bin]++;
9693}
9694
9695////////////////////////////////////////////////////////////////////////////////
9696/// Increment bin content by w
9697/// Passing an out-of-range bin leads to undefined behavior
9698
9700{
9701 Int_t newval = fArray[bin] + Int_t(w);
9702 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9703 if (newval < -32767) fArray[bin] = -32767;
9704 if (newval > 32767) fArray[bin] = 32767;
9705}
9706
9707////////////////////////////////////////////////////////////////////////////////
9708/// Copy this to newth1
9709
9710void TH1S::Copy(TObject &newth1) const
9711{
9712 TH1::Copy(newth1);
9713}
9714
9715////////////////////////////////////////////////////////////////////////////////
9716/// Reset.
9717
9719{
9722}
9723
9724////////////////////////////////////////////////////////////////////////////////
9725/// Set total number of bins including under/overflow
9726/// Reallocate bin contents array
9727
9729{
9730 if (n < 0) n = fXaxis.GetNbins() + 2;
9731 fNcells = n;
9732 TArrayS::Set(n);
9733}
9734
9735////////////////////////////////////////////////////////////////////////////////
9736/// Operator =
9737
9738TH1S& TH1S::operator=(const TH1S &h1)
9739{
9740 if (this != &h1)
9741 h1.TH1S::Copy(*this);
9742 return *this;
9743}
9744
9745////////////////////////////////////////////////////////////////////////////////
9746/// Operator *
9747
9749{
9750 TH1S hnew = h1;
9751 hnew.Scale(c1);
9752 hnew.SetDirectory(nullptr);
9753 return hnew;
9754}
9755
9756////////////////////////////////////////////////////////////////////////////////
9757/// Operator +
9758
9759TH1S operator+(const TH1S &h1, const TH1S &h2)
9760{
9761 TH1S hnew = h1;
9762 hnew.Add(&h2,1);
9763 hnew.SetDirectory(nullptr);
9764 return hnew;
9765}
9766
9767////////////////////////////////////////////////////////////////////////////////
9768/// Operator -
9769
9770TH1S operator-(const TH1S &h1, const TH1S &h2)
9771{
9772 TH1S hnew = h1;
9773 hnew.Add(&h2,-1);
9774 hnew.SetDirectory(nullptr);
9775 return hnew;
9776}
9777
9778////////////////////////////////////////////////////////////////////////////////
9779/// Operator *
9780
9781TH1S operator*(const TH1S &h1, const TH1S &h2)
9782{
9783 TH1S hnew = h1;
9784 hnew.Multiply(&h2);
9785 hnew.SetDirectory(nullptr);
9786 return hnew;
9787}
9788
9789////////////////////////////////////////////////////////////////////////////////
9790/// Operator /
9791
9792TH1S operator/(const TH1S &h1, const TH1S &h2)
9793{
9794 TH1S hnew = h1;
9795 hnew.Divide(&h2);
9796 hnew.SetDirectory(nullptr);
9797 return hnew;
9798}
9799
9800//______________________________________________________________________________
9801// TH1I methods
9802// TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9803// 2147483647 = INT_MAX
9804//______________________________________________________________________________
9805
9806ClassImp(TH1I);
9807
9808////////////////////////////////////////////////////////////////////////////////
9809/// Constructor.
9810
9811TH1I::TH1I(): TH1(), TArrayI()
9812{
9813 fDimension = 1;
9814 SetBinsLength(3);
9815 if (fgDefaultSumw2) Sumw2();
9816}
9817
9818////////////////////////////////////////////////////////////////////////////////
9819/// Create a 1-Dim histogram with fix bins of type integer
9820/// (see TH1::TH1 for explanation of parameters)
9821
9822TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9823: TH1(name,title,nbins,xlow,xup)
9824{
9825 fDimension = 1;
9827
9828 if (xlow >= xup) SetBuffer(fgBufferSize);
9829 if (fgDefaultSumw2) Sumw2();
9830}
9831
9832////////////////////////////////////////////////////////////////////////////////
9833/// Create a 1-Dim histogram with variable bins of type integer
9834/// (see TH1::TH1 for explanation of parameters)
9835
9836TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9837: TH1(name,title,nbins,xbins)
9838{
9839 fDimension = 1;
9841 if (fgDefaultSumw2) Sumw2();
9842}
9843
9844////////////////////////////////////////////////////////////////////////////////
9845/// Create a 1-Dim histogram with variable bins of type integer
9846/// (see TH1::TH1 for explanation of parameters)
9847
9848TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9849: TH1(name,title,nbins,xbins)
9850{
9851 fDimension = 1;
9853 if (fgDefaultSumw2) Sumw2();
9854}
9855
9856////////////////////////////////////////////////////////////////////////////////
9857/// Destructor.
9858
9860{
9861}
9862
9863////////////////////////////////////////////////////////////////////////////////
9864/// Copy constructor.
9865/// The list of functions is not copied. (Use Clone() if needed)
9866
9867TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
9868{
9869 h1i.TH1I::Copy(*this);
9870}
9871
9872////////////////////////////////////////////////////////////////////////////////
9873/// Increment bin content by 1.
9874/// Passing an out-of-range bin leads to undefined behavior
9875
9876void TH1I::AddBinContent(Int_t bin)
9877{
9878 if (fArray[bin] < INT_MAX) fArray[bin]++;
9879}
9880
9881////////////////////////////////////////////////////////////////////////////////
9882/// Increment bin content by w
9883/// Passing an out-of-range bin leads to undefined behavior
9884
9886{
9887 Long64_t newval = fArray[bin] + Long64_t(w);
9888 if (newval > -INT_MAX && newval < INT_MAX) {fArray[bin] = Int_t(newval); return;}
9889 if (newval < -INT_MAX) fArray[bin] = -INT_MAX;
9890 if (newval > INT_MAX) fArray[bin] = INT_MAX;
9891}
9892
9893////////////////////////////////////////////////////////////////////////////////
9894/// Copy this to newth1
9895
9896void TH1I::Copy(TObject &newth1) const
9897{
9898 TH1::Copy(newth1);
9899}
9900
9901////////////////////////////////////////////////////////////////////////////////
9902/// Reset.
9903
9905{
9908}
9909
9910////////////////////////////////////////////////////////////////////////////////
9911/// Set total number of bins including under/overflow
9912/// Reallocate bin contents array
9913
9915{
9916 if (n < 0) n = fXaxis.GetNbins() + 2;
9917 fNcells = n;
9918 TArrayI::Set(n);
9919}
9920
9921////////////////////////////////////////////////////////////////////////////////
9922/// Operator =
9923
9924TH1I& TH1I::operator=(const TH1I &h1)
9925{
9926 if (this != &h1)
9927 h1.TH1I::Copy(*this);
9928 return *this;
9929}
9930
9931
9932////////////////////////////////////////////////////////////////////////////////
9933/// Operator *
9934
9936{
9937 TH1I hnew = h1;
9938 hnew.Scale(c1);
9939 hnew.SetDirectory(nullptr);
9940 return hnew;
9941}
9942
9943////////////////////////////////////////////////////////////////////////////////
9944/// Operator +
9945
9946TH1I operator+(const TH1I &h1, const TH1I &h2)
9947{
9948 TH1I hnew = h1;
9949 hnew.Add(&h2,1);
9950 hnew.SetDirectory(nullptr);
9951 return hnew;
9952}
9953
9954////////////////////////////////////////////////////////////////////////////////
9955/// Operator -
9956
9957TH1I operator-(const TH1I &h1, const TH1I &h2)
9958{
9959 TH1I hnew = h1;
9960 hnew.Add(&h2,-1);
9961 hnew.SetDirectory(nullptr);
9962 return hnew;
9963}
9964
9965////////////////////////////////////////////////////////////////////////////////
9966/// Operator *
9967
9968TH1I operator*(const TH1I &h1, const TH1I &h2)
9969{
9970 TH1I hnew = h1;
9971 hnew.Multiply(&h2);
9972 hnew.SetDirectory(nullptr);
9973 return hnew;
9974}
9975
9976////////////////////////////////////////////////////////////////////////////////
9977/// Operator /
9978
9979TH1I operator/(const TH1I &h1, const TH1I &h2)
9980{
9981 TH1I hnew = h1;
9982 hnew.Divide(&h2);
9983 hnew.SetDirectory(nullptr);
9984 return hnew;
9985}
9986
9987//______________________________________________________________________________
9988// TH1L methods
9989// TH1L : histograms with one long64 per channel. Maximum bin content = 9223372036854775807
9990// 9223372036854775807 = LLONG_MAX
9991//______________________________________________________________________________
9992
9993ClassImp(TH1L);
9994
9995////////////////////////////////////////////////////////////////////////////////
9996/// Constructor.
9997
9998TH1L::TH1L(): TH1(), TArrayL64()
9999{
10000 fDimension = 1;
10001 SetBinsLength(3);
10002 if (fgDefaultSumw2) Sumw2();
10003}
10004
10005////////////////////////////////////////////////////////////////////////////////
10006/// Create a 1-Dim histogram with fix bins of type long64
10007/// (see TH1::TH1 for explanation of parameters)
10008
10009TH1L::TH1L(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10010: TH1(name,title,nbins,xlow,xup)
10011{
10012 fDimension = 1;
10014
10015 if (xlow >= xup) SetBuffer(fgBufferSize);
10016 if (fgDefaultSumw2) Sumw2();
10017}
10018
10019////////////////////////////////////////////////////////////////////////////////
10020/// Create a 1-Dim histogram with variable bins of type long64
10021/// (see TH1::TH1 for explanation of parameters)
10022
10023TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10024: TH1(name,title,nbins,xbins)
10025{
10026 fDimension = 1;
10028 if (fgDefaultSumw2) Sumw2();
10029}
10030
10031////////////////////////////////////////////////////////////////////////////////
10032/// Create a 1-Dim histogram with variable bins of type long64
10033/// (see TH1::TH1 for explanation of parameters)
10034
10035TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10036: TH1(name,title,nbins,xbins)
10037{
10038 fDimension = 1;
10040 if (fgDefaultSumw2) Sumw2();
10041}
10042
10043////////////////////////////////////////////////////////////////////////////////
10044/// Destructor.
10045
10047{
10048}
10049
10050////////////////////////////////////////////////////////////////////////////////
10051/// Copy constructor.
10052/// The list of functions is not copied. (Use Clone() if needed)
10053
10054TH1L::TH1L(const TH1L &h1l) : TH1(), TArrayL64()
10055{
10056 h1l.TH1L::Copy(*this);
10057}
10058
10059////////////////////////////////////////////////////////////////////////////////
10060/// Increment bin content by 1.
10061/// Passing an out-of-range bin leads to undefined behavior
10062
10063void TH1L::AddBinContent(Int_t bin)
10064{
10065 if (fArray[bin] < LLONG_MAX) fArray[bin]++;
10066}
10067
10068////////////////////////////////////////////////////////////////////////////////
10069/// Increment bin content by w
10070/// Passing an out-of-range bin leads to undefined behavior
10071
10073{
10074 Long64_t newval = fArray[bin] + Long64_t(w);
10075 if (newval > -LLONG_MAX && newval < LLONG_MAX) {fArray[bin] = newval; return;}
10076 if (newval < -LLONG_MAX) fArray[bin] = -LLONG_MAX;
10077 if (newval > LLONG_MAX) fArray[bin] = LLONG_MAX;
10078}
10079
10080////////////////////////////////////////////////////////////////////////////////
10081/// Copy this to newth1
10082
10083void TH1L::Copy(TObject &newth1) const
10084{
10085 TH1::Copy(newth1);
10086}
10087
10088////////////////////////////////////////////////////////////////////////////////
10089/// Reset.
10090
10092{
10095}
10096
10097////////////////////////////////////////////////////////////////////////////////
10098/// Set total number of bins including under/overflow
10099/// Reallocate bin contents array
10100
10102{
10103 if (n < 0) n = fXaxis.GetNbins() + 2;
10104 fNcells = n;
10106}
10107
10108////////////////////////////////////////////////////////////////////////////////
10109/// Operator =
10110
10111TH1L& TH1L::operator=(const TH1L &h1)
10112{
10113 if (this != &h1)
10114 h1.TH1L::Copy(*this);
10115 return *this;
10116}
10117
10118
10119////////////////////////////////////////////////////////////////////////////////
10120/// Operator *
10121
10123{
10124 TH1L hnew = h1;
10125 hnew.Scale(c1);
10126 hnew.SetDirectory(nullptr);
10127 return hnew;
10128}
10129
10130////////////////////////////////////////////////////////////////////////////////
10131/// Operator +
10132
10133TH1L operator+(const TH1L &h1, const TH1L &h2)
10134{
10135 TH1L hnew = h1;
10136 hnew.Add(&h2,1);
10137 hnew.SetDirectory(nullptr);
10138 return hnew;
10139}
10140
10141////////////////////////////////////////////////////////////////////////////////
10142/// Operator -
10143
10144TH1L operator-(const TH1L &h1, const TH1L &h2)
10145{
10146 TH1L hnew = h1;
10147 hnew.Add(&h2,-1);
10148 hnew.SetDirectory(nullptr);
10149 return hnew;
10150}
10151
10152////////////////////////////////////////////////////////////////////////////////
10153/// Operator *
10154
10155TH1L operator*(const TH1L &h1, const TH1L &h2)
10156{
10157 TH1L hnew = h1;
10158 hnew.Multiply(&h2);
10159 hnew.SetDirectory(nullptr);
10160 return hnew;
10161}
10162
10163////////////////////////////////////////////////////////////////////////////////
10164/// Operator /
10165
10166TH1L operator/(const TH1L &h1, const TH1L &h2)
10167{
10168 TH1L hnew = h1;
10169 hnew.Divide(&h2);
10170 hnew.SetDirectory(nullptr);
10171 return hnew;
10172}
10173
10174//______________________________________________________________________________
10175// TH1F methods
10176// TH1F : histograms with one float per channel. Maximum precision 7 digits
10177//______________________________________________________________________________
10178
10179ClassImp(TH1F);
10180
10181////////////////////////////////////////////////////////////////////////////////
10182/// Constructor.
10183
10184TH1F::TH1F(): TH1(), TArrayF()
10185{
10186 fDimension = 1;
10187 SetBinsLength(3);
10188 if (fgDefaultSumw2) Sumw2();
10189}
10190
10191////////////////////////////////////////////////////////////////////////////////
10192/// Create a 1-Dim histogram with fix bins of type float
10193/// (see TH1::TH1 for explanation of parameters)
10194
10195TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10196: TH1(name,title,nbins,xlow,xup)
10197{
10198 fDimension = 1;
10200
10201 if (xlow >= xup) SetBuffer(fgBufferSize);
10202 if (fgDefaultSumw2) Sumw2();
10203}
10204
10205////////////////////////////////////////////////////////////////////////////////
10206/// Create a 1-Dim histogram with variable bins of type float
10207/// (see TH1::TH1 for explanation of parameters)
10208
10209TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10210: TH1(name,title,nbins,xbins)
10211{
10212 fDimension = 1;
10214 if (fgDefaultSumw2) Sumw2();
10215}
10216
10217////////////////////////////////////////////////////////////////////////////////
10218/// Create a 1-Dim histogram with variable bins of type float
10219/// (see TH1::TH1 for explanation of parameters)
10220
10221TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10222: TH1(name,title,nbins,xbins)
10223{
10224 fDimension = 1;
10226 if (fgDefaultSumw2) Sumw2();
10227}
10228
10229////////////////////////////////////////////////////////////////////////////////
10230/// Create a histogram from a TVectorF
10231/// by default the histogram name is "TVectorF" and title = ""
10232
10233TH1F::TH1F(const TVectorF &v)
10234: TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
10235{
10237 fDimension = 1;
10238 Int_t ivlow = v.GetLwb();
10239 for (Int_t i=0;i<fNcells-2;i++) {
10240 SetBinContent(i+1,v(i+ivlow));
10241 }
10243 if (fgDefaultSumw2) Sumw2();
10244}
10245
10246////////////////////////////////////////////////////////////////////////////////
10247/// Copy Constructor.
10248/// The list of functions is not copied. (Use Clone() if needed)
10249
10250TH1F::TH1F(const TH1F &h1f) : TH1(), TArrayF()
10251{
10252 h1f.TH1F::Copy(*this);
10253}
10254
10255////////////////////////////////////////////////////////////////////////////////
10256/// Destructor.
10257
10259{
10260}
10261
10262////////////////////////////////////////////////////////////////////////////////
10263/// Copy this to newth1.
10264
10265void TH1F::Copy(TObject &newth1) const
10266{
10267 TH1::Copy(newth1);
10268}
10269
10270////////////////////////////////////////////////////////////////////////////////
10271/// Reset.
10272
10274{
10277}
10278
10279////////////////////////////////////////////////////////////////////////////////
10280/// Set total number of bins including under/overflow
10281/// Reallocate bin contents array
10282
10284{
10285 if (n < 0) n = fXaxis.GetNbins() + 2;
10286 fNcells = n;
10287 TArrayF::Set(n);
10288}
10289
10290////////////////////////////////////////////////////////////////////////////////
10291/// Operator =
10292
10293TH1F& TH1F::operator=(const TH1F &h1f)
10294{
10295 if (this != &h1f)
10296 h1f.TH1F::Copy(*this);
10297 return *this;
10298}
10299
10300////////////////////////////////////////////////////////////////////////////////
10301/// Operator *
10302
10304{
10305 TH1F hnew = h1;
10306 hnew.Scale(c1);
10307 hnew.SetDirectory(nullptr);
10308 return hnew;
10309}
10310
10311////////////////////////////////////////////////////////////////////////////////
10312/// Operator +
10313
10314TH1F operator+(const TH1F &h1, const TH1F &h2)
10315{
10316 TH1F hnew = h1;
10317 hnew.Add(&h2,1);
10318 hnew.SetDirectory(nullptr);
10319 return hnew;
10320}
10321
10322////////////////////////////////////////////////////////////////////////////////
10323/// Operator -
10324
10325TH1F operator-(const TH1F &h1, const TH1F &h2)
10326{
10327 TH1F hnew = h1;
10328 hnew.Add(&h2,-1);
10329 hnew.SetDirectory(nullptr);
10330 return hnew;
10331}
10332
10333////////////////////////////////////////////////////////////////////////////////
10334/// Operator *
10335
10336TH1F operator*(const TH1F &h1, const TH1F &h2)
10337{
10338 TH1F hnew = h1;
10339 hnew.Multiply(&h2);
10340 hnew.SetDirectory(nullptr);
10341 return hnew;
10342}
10343
10344////////////////////////////////////////////////////////////////////////////////
10345/// Operator /
10346
10347TH1F operator/(const TH1F &h1, const TH1F &h2)
10348{
10349 TH1F hnew = h1;
10350 hnew.Divide(&h2);
10351 hnew.SetDirectory(nullptr);
10352 return hnew;
10353}
10354
10355//______________________________________________________________________________
10356// TH1D methods
10357// TH1D : histograms with one double per channel. Maximum precision 14 digits
10358//______________________________________________________________________________
10359
10360ClassImp(TH1D);
10361
10362////////////////////////////////////////////////////////////////////////////////
10363/// Constructor.
10364
10365TH1D::TH1D(): TH1(), TArrayD()
10366{
10367 fDimension = 1;
10368 SetBinsLength(3);
10369 if (fgDefaultSumw2) Sumw2();
10370}
10371
10372////////////////////////////////////////////////////////////////////////////////
10373/// Create a 1-Dim histogram with fix bins of type double
10374/// (see TH1::TH1 for explanation of parameters)
10375
10376TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10377: TH1(name,title,nbins,xlow,xup)
10378{
10379 fDimension = 1;
10381
10382 if (xlow >= xup) SetBuffer(fgBufferSize);
10383 if (fgDefaultSumw2) Sumw2();
10384}
10385
10386////////////////////////////////////////////////////////////////////////////////
10387/// Create a 1-Dim histogram with variable bins of type double
10388/// (see TH1::TH1 for explanation of parameters)
10389
10390TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10391: TH1(name,title,nbins,xbins)
10392{
10393 fDimension = 1;
10395 if (fgDefaultSumw2) Sumw2();
10396}
10397
10398////////////////////////////////////////////////////////////////////////////////
10399/// Create a 1-Dim histogram with variable bins of type double
10400/// (see TH1::TH1 for explanation of parameters)
10401
10402TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10403: TH1(name,title,nbins,xbins)
10404{
10405 fDimension = 1;
10407 if (fgDefaultSumw2) Sumw2();
10408}
10409
10410////////////////////////////////////////////////////////////////////////////////
10411/// Create a histogram from a TVectorD
10412/// by default the histogram name is "TVectorD" and title = ""
10413
10414TH1D::TH1D(const TVectorD &v)
10415: TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
10416{
10418 fDimension = 1;
10419 Int_t ivlow = v.GetLwb();
10420 for (Int_t i=0;i<fNcells-2;i++) {
10421 SetBinContent(i+1,v(i+ivlow));
10422 }
10424 if (fgDefaultSumw2) Sumw2();
10425}
10426
10427////////////////////////////////////////////////////////////////////////////////
10428/// Destructor.
10429
10431{
10432}
10433
10434////////////////////////////////////////////////////////////////////////////////
10435/// Constructor.
10436
10437TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
10438{
10439 // intentially call virtual method to warn if TProfile is copying
10440 h1d.Copy(*this);
10441}
10442
10443////////////////////////////////////////////////////////////////////////////////
10444/// Copy this to newth1
10445
10446void TH1D::Copy(TObject &newth1) const
10447{
10448 TH1::Copy(newth1);
10449}
10450
10451////////////////////////////////////////////////////////////////////////////////
10452/// Reset.
10453
10455{
10458}
10459
10460////////////////////////////////////////////////////////////////////////////////
10461/// Set total number of bins including under/overflow
10462/// Reallocate bin contents array
10463
10465{
10466 if (n < 0) n = fXaxis.GetNbins() + 2;
10467 fNcells = n;
10468 TArrayD::Set(n);
10469}
10470
10471////////////////////////////////////////////////////////////////////////////////
10472/// Operator =
10473
10474TH1D& TH1D::operator=(const TH1D &h1d)
10475{
10476 // intentially call virtual method to warn if TProfile is copying
10477 if (this != &h1d)
10478 h1d.Copy(*this);
10479 return *this;
10480}
10481
10482////////////////////////////////////////////////////////////////////////////////
10483/// Operator *
10484
10486{
10487 TH1D hnew = h1;
10488 hnew.Scale(c1);
10489 hnew.SetDirectory(nullptr);
10490 return hnew;
10491}
10492
10493////////////////////////////////////////////////////////////////////////////////
10494/// Operator +
10495
10496TH1D operator+(const TH1D &h1, const TH1D &h2)
10497{
10498 TH1D hnew = h1;
10499 hnew.Add(&h2,1);
10500 hnew.SetDirectory(nullptr);
10501 return hnew;
10502}
10503
10504////////////////////////////////////////////////////////////////////////////////
10505/// Operator -
10506
10507TH1D operator-(const TH1D &h1, const TH1D &h2)
10508{
10509 TH1D hnew = h1;
10510 hnew.Add(&h2,-1);
10511 hnew.SetDirectory(nullptr);
10512 return hnew;
10513}
10514
10515////////////////////////////////////////////////////////////////////////////////
10516/// Operator *
10517
10518TH1D operator*(const TH1D &h1, const TH1D &h2)
10519{
10520 TH1D hnew = h1;
10521 hnew.Multiply(&h2);
10522 hnew.SetDirectory(nullptr);
10523 return hnew;
10524}
10525
10526////////////////////////////////////////////////////////////////////////////////
10527/// Operator /
10528
10529TH1D operator/(const TH1D &h1, const TH1D &h2)
10530{
10531 TH1D hnew = h1;
10532 hnew.Divide(&h2);
10533 hnew.SetDirectory(nullptr);
10534 return hnew;
10535}
10536
10537////////////////////////////////////////////////////////////////////////////////
10538///return pointer to histogram with name
10539///hid if id >=0
10540///h_id if id <0
10541
10542TH1 *R__H(Int_t hid)
10543{
10544 TString hname;
10545 if(hid >= 0) hname.Form("h%d",hid);
10546 else hname.Form("h_%d",hid);
10547 return (TH1*)gDirectory->Get(hname);
10548}
10549
10550////////////////////////////////////////////////////////////////////////////////
10551///return pointer to histogram with name hname
10552
10553TH1 *R__H(const char * hname)
10554{
10555 return (TH1*)gDirectory->Get(hname);
10556}
10557
10558
10559/// \fn void TH1::SetBarOffset(Float_t offset)
10560/// Set the bar offset as fraction of the bin width for drawing mode "B".
10561/// This shifts bars to the right on the x axis, and helps to draw bars next to each other.
10562/// \see THistPainter, SetBarWidth()
10563
10564/// \fn void TH1::SetBarWidth(Float_t width)
10565/// Set the width of bars as fraction of the bin width for drawing mode "B".
10566/// This allows for making bars narrower than the bin width. With SetBarOffset(), this helps to draw multiple bars next to each other.
10567/// \see THistPainter, SetBarOffset()
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define s1(x)
Definition RSha256.hxx:91
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
short Style_t
Definition RtypesCore.h:89
bool Bool_t
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
short Color_t
Definition RtypesCore.h:92
short Version_t
Definition RtypesCore.h:65
char Char_t
Definition RtypesCore.h:37
float Float_t
Definition RtypesCore.h:57
short Short_t
Definition RtypesCore.h:39
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:80
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define BIT(n)
Definition Rtypes.h:85
#define ClassImp(name)
Definition Rtypes.h:377
#define gDirectory
Definition TDirectory.h:384
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
#define R__ASSERT(e)
Definition TError.h:118
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:5842
void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
Least square linear fit without weights.
Definition TH1.cxx:4790
void H1InitGaus()
Compute Initial values of parameters for a gaussian.
Definition TH1.cxx:4625
void H1InitExpo()
Compute Initial values of parameters for an exponential.
Definition TH1.cxx:4681
TH1C operator+(const TH1C &h1, const TH1C &h2)
Operator +.
Definition TH1.cxx:9572
TH1C operator-(const TH1C &h1, const TH1C &h2)
Operator -.
Definition TH1.cxx:9583
TH1C operator/(const TH1C &h1, const TH1C &h2)
Operator /.
Definition TH1.cxx:9605
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:4836
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:5825
static Bool_t AlmostInteger(Double_t a, Double_t epsilon=0.00000001)
Test if a double is almost an integer.
Definition TH1.cxx:5833
TF1 * gF1
Definition TH1.cxx:579
TH1 * R__H(Int_t hid)
return pointer to histogram with name hid if id >=0 h_id if id <0
Definition TH1.cxx:10540
TH1C operator*(Double_t c1, const TH1C &h1)
Operator *.
Definition TH1.cxx:9561
void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
Least squares lpolynomial fitting without weights.
Definition TH1.cxx:4731
void H1InitPolynom()
Compute Initial values of parameters for a polynom.
Definition TH1.cxx:4701
float xmin
int nentries
float * q
float ymin
float xmax
float ymax
#define gInterpreter
Int_t gDebug
Definition TROOT.cxx:595
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:406
R__EXTERN TRandom * gRandom
Definition TRandom.h:62
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2503
R__EXTERN TStyle * gStyle
Definition TStyle.h:433
#define R__LOCKGUARD(mutex)
#define gPad
#define R__WRITE_LOCKGUARD(mutex)
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition BinData.h:52
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition DataRange.h:35
void AndersonDarling2SamplesTest(Double_t &pvalue, Double_t &testStat) const
Performs the Anderson-Darling 2-Sample Test.
Definition GoFTest.cxx:646
Array of chars or bytes (8 bits per element).
Definition TArrayC.h:27
Char_t * fArray
Definition TArrayC.h:30
void Reset(Char_t val=0)
Definition TArrayC.h:47
void Set(Int_t n) override
Set size of this array to n chars.
Definition TArrayC.cxx:105
Array of doubles (64 bits per element).
Definition TArrayD.h:27
Double_t GetAt(Int_t i) const override
Definition TArrayD.h:45
Double_t * fArray
Definition TArrayD.h:30
void Streamer(TBuffer &) override
Stream a TArrayD object.
Definition TArrayD.cxx:149
void Copy(TArrayD &array) const
Definition TArrayD.h:42
void Set(Int_t n) override
Set size of this array to n doubles.
Definition TArrayD.cxx:106
const Double_t * GetArray() const
Definition TArrayD.h:43
void Reset()
Definition TArrayD.h:47
Array of floats (32 bits per element).
Definition TArrayF.h:27
void Reset()
Definition TArrayF.h:47
void Set(Int_t n) override
Set size of this array to n floats.
Definition TArrayF.cxx:105
Array of integers (32 bits per element).
Definition TArrayI.h:27
Int_t * fArray
Definition TArrayI.h:30
void Set(Int_t n) override
Set size of this array to n ints.
Definition TArrayI.cxx:105
void Reset()
Definition TArrayI.h:47
Array of long64s (64 bits per element).
Definition TArrayL64.h:27
Long64_t * fArray
Definition TArrayL64.h:30
void Set(Int_t n) override
Set size of this array to n long64s.
void Reset()
Definition TArrayL64.h:47
Array of shorts (16 bits per element).
Definition TArrayS.h:27
void Set(Int_t n) override
Set size of this array to n shorts.
Definition TArrayS.cxx:105
void Reset()
Definition TArrayS.h:47
Short_t * fArray
Definition TArrayS.h:30
Abstract array base class.
Definition TArray.h:31
Int_t fN
Definition TArray.h:38
virtual void Set(Int_t n)=0
Int_t GetSize() const
Definition TArray.h:47
virtual Color_t GetTitleColor() const
Definition TAttAxis.h:46
virtual Color_t GetLabelColor() const
Definition TAttAxis.h:38
virtual Int_t GetNdivisions() const
Definition TAttAxis.h:36
virtual Color_t GetAxisColor() const
Definition TAttAxis.h:37
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition TAttAxis.cxx:298
virtual Style_t GetTitleFont() const
Definition TAttAxis.h:47
virtual Float_t GetLabelOffset() const
Definition TAttAxis.h:40
virtual void SetAxisColor(Color_t color=1, Float_t alpha=1.)
Set color of the line axis and tick marks.
Definition TAttAxis.cxx:160
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
Definition TAttAxis.cxx:203
virtual Style_t GetLabelFont() const
Definition TAttAxis.h:39
virtual void SetTitleFont(Style_t font=62)
Set the title font.
Definition TAttAxis.cxx:327
virtual void SetLabelOffset(Float_t offset=0.005)
Set distance between the axis and the labels.
Definition TAttAxis.cxx:191
virtual void SetLabelFont(Style_t font=62)
Set labels' font.
Definition TAttAxis.cxx:180
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title.
Definition TAttAxis.cxx:309
virtual void SetTitleColor(Color_t color=1)
Set color of axis title.
Definition TAttAxis.cxx:318
virtual Float_t GetTitleSize() const
Definition TAttAxis.h:44
virtual Float_t GetLabelSize() const
Definition TAttAxis.h:41
virtual Float_t GetTickLength() const
Definition TAttAxis.h:45
virtual void ResetAttAxis(Option_t *option="")
Reset axis attributes.
Definition TAttAxis.cxx:79
virtual Float_t GetTitleOffset() const
Definition TAttAxis.h:43
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length.
Definition TAttAxis.cxx:284
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition TAttAxis.cxx:233
virtual void SetLabelColor(Color_t color=1, Float_t alpha=1.)
Set color of labels.
Definition TAttAxis.cxx:170
Fill Area Attributes class.
Definition TAttFill.h:19
virtual void Streamer(TBuffer &)
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:30
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition TAttFill.cxx:207
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:31
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
Save fill attributes as C++ statement(s) on output stream out.
Definition TAttFill.cxx:239
Line Attributes class.
Definition TAttLine.h:18
virtual void Streamer(TBuffer &)
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:33
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:42
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:35
virtual Style_t GetLineStyle() const
Return the line style.
Definition TAttLine.h:34
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition TAttLine.cxx:177
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition TAttLine.cxx:275
Marker Attributes class.
Definition TAttMarker.h:19
virtual void SaveMarkerAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t sizdef=1)
Save line attributes as C++ statement(s) on output stream out.
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition TAttMarker.h:32
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition TAttMarker.h:38
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:31
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition TAttMarker.h:33
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition TAttMarker.h:40
void Copy(TAttMarker &attmarker) const
Copy this marker attributes to a new TAttMarker.
virtual void Streamer(TBuffer &)
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition TAttMarker.h:45
Class to manage histogram axis.
Definition TAxis.h:31
virtual void GetCenter(Double_t *center) const
Return an array with the center of all bins.
Definition TAxis.cxx:553
virtual Bool_t GetTimeDisplay() const
Definition TAxis.h:131
Bool_t IsAlphanumeric() const
Definition TAxis.h:88
const char * GetTitle() const override
Returns title of object.
Definition TAxis.h:135
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:478
Bool_t CanExtend() const
Definition TAxis.h:86
virtual void SetParent(TObject *obj)
Definition TAxis.h:167
const TArrayD * GetXbins() const
Definition TAxis.h:136
void SetCanExtend(Bool_t canExtend)
Definition TAxis.h:90
void Copy(TObject &axis) const override
Copy axis structure to another axis.
Definition TAxis.cxx:216
Double_t GetXmax() const
Definition TAxis.h:140
@ kLabelsUp
Definition TAxis.h:74
@ kLabelsDown
Definition TAxis.h:73
@ kLabelsHori
Definition TAxis.h:71
@ kAxisRange
Definition TAxis.h:65
@ kLabelsVert
Definition TAxis.h:72
const char * GetBinLabel(Int_t bin) const
Return label for bin.
Definition TAxis.cxx:440
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:293
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:518
virtual void SetTimeDisplay(Int_t value)
Definition TAxis.h:171
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Definition TAxis.cxx:794
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:419
void SaveAttributes(std::ostream &out, const char *name, const char *subname) override
Save axis attributes as C++ statement(s) on output stream out.
Definition TAxis.cxx:710
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:469
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition TAxis.h:164
Double_t GetXmin() const
Definition TAxis.h:139
void Streamer(TBuffer &) override
Stream an object of class TAxis.
Definition TAxis.cxx:1216
Int_t GetNbins() const
Definition TAxis.h:125
virtual void GetLowEdge(Double_t *edge) const
Return an array with the low edge of all bins.
Definition TAxis.cxx:562
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis using bin numbers.
Definition TAxis.cxx:1052
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:540
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:528
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:458
THashList * GetLabels() const
Definition TAxis.h:121
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
Buffer base class used for serializing objects.
Definition TBuffer.h:43
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:4978
ROOT::NewFunc_t GetNew() const
Return the wrapper around new ThisClass().
Definition TClass.cxx:7447
Collection abstract base class.
Definition TCollection.h:65
virtual bool UseRWLock(Bool_t enable=true)
Set this collection to use a RW lock upon access, making it thread safe.
virtual void AddAll(const TCollection *col)
Add all objects from collection col to this collection.
virtual Bool_t IsEmpty() const
TObject * Clone(const char *newname="") const override
Make a clone of an collection using the Streamer facility.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Describe directory structure in memory.
Definition TDirectory.h:45
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:491
1-Dim function class
Definition TF1.h:233
static void RejectPoint(Bool_t reject=kTRUE)
Static function to set the global flag to reject points the fgRejectPoint global flag is tested by al...
Definition TF1.cxx:3683
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function Note that this histogram is managed ...
Definition TF1.cxx:1586
static TClass * Class()
virtual Int_t GetNpar() const
Definition TF1.h:507
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
IntegralOneDim or analytical integral.
Definition TF1.cxx:2531
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition TF1.cxx:2482
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2281
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=nullptr)
Evaluate function with given coordinates and parameters.
Definition TF1.cxx:1470
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set lower and upper limits for parameter ipar.
Definition TF1.cxx:3507
static Bool_t RejectedPoint()
See TF1::RejectPoint above.
Definition TF1.cxx:3692
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this function.
Definition TF1.cxx:1441
virtual void SetParameter(Int_t param, Double_t value)
Definition TF1.h:660
virtual Bool_t IsInside(const Double_t *x) const
return kTRUE if the point is inside the function range
Definition TF1.h:624
A 2-Dim function with parameters.
Definition TF2.h:29
A 3-Dim function with parameters.
Definition TF3.h:28
Provides an indirection to the TFitResult class and with a semantics identical to a TFitResult pointe...
1-D histogram with a byte per channel (see TH1 documentation)
Definition TH1.h:457
~TH1C() override
Destructor.
Definition TH1.cxx:9486
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9541
TH1C & operator=(const TH1C &h1)
Operator =.
Definition TH1.cxx:9551
TH1C()
Constructor.
Definition TH1.cxx:9438
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9523
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9503
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:9531
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:664
~TH1D() override
Destructor.
Definition TH1.cxx:10428
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10462
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10444
TH1D()
Constructor.
Definition TH1.cxx:10363
TH1D & operator=(const TH1D &h1)
Operator =.
Definition TH1.cxx:10472
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:10452
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:621
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:650
TH1F & operator=(const TH1F &h1)
Operator =.
Definition TH1.cxx:10291
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10263
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10281
~TH1F() override
Destructor.
Definition TH1.cxx:10256
TH1F()
Constructor.
Definition TH1.cxx:10182
1-D histogram with an int per channel (see TH1 documentation)
Definition TH1.h:539
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9912
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9874
~TH1I() override
Destructor.
Definition TH1.cxx:9857
TH1I()
Constructor.
Definition TH1.cxx:9809
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9894
TH1I & operator=(const TH1I &h1)
Operator =.
Definition TH1.cxx:9922
1-D histogram with a long64 per channel (see TH1 documentation)
Definition TH1.h:580
TH1L & operator=(const TH1L &h1)
Operator =.
Definition TH1.cxx:10109
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:10061
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10099
~TH1L() override
Destructor.
Definition TH1.cxx:10044
TH1L()
Constructor.
Definition TH1.cxx:9996
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10081
1-D histogram with a short per channel (see TH1 documentation)
Definition TH1.h:498
TH1S & operator=(const TH1S &h1)
Operator =.
Definition TH1.cxx:9736
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9708
TH1S()
Constructor.
Definition TH1.cxx:9623
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9726
~TH1S() override
Destructor.
Definition TH1.cxx:9671
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9688
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:59
~TH1() override
Histogram default destructor.
Definition TH1.cxx:641
virtual void SetError(const Double_t *error)
Replace bin errors by values in array error.
Definition TH1.cxx:8916
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:8902
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition TH1.cxx:4280
Double_t * fBuffer
[fBufferSize] entry buffer
Definition TH1.h:108
virtual Int_t AutoP2FindLimits(Double_t min, Double_t max)
Buffer-based estimate of the histogram range using the power of 2 algorithm.
Definition TH1.cxx:1341
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition TH1.cxx:4444
char * GetObjectInfo(Int_t px, Int_t py) const override
Redefines TObject::GetObjectInfo.
Definition TH1.cxx:4475
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition TH1.cxx:6843
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:9106
virtual void Rebuild(Option_t *option="")
Using the current bin info, recompute the arrays for contents and errors.
Definition TH1.cxx:7051
virtual void SetBarOffset(Float_t offset=0.25)
Set the bar offset as fraction of the bin width for drawing mode "B".
Definition TH1.h:364
static Bool_t fgStatOverflows
! Flag to use under/overflows in statistics
Definition TH1.h:117
virtual Int_t FindLastBinAbove(Double_t threshold=0, Int_t axis=1, Int_t firstBin=1, Int_t lastBin=-1) const
Find last bin with content > threshold for axis (1=x, 2=y, 3=z) if no bins with content > threshold i...
Definition TH1.cxx:3793
TAxis * GetZaxis()
Definition TH1.h:326
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a line.
Definition TH1.cxx:2819
virtual Bool_t Multiply(TF1 *f1, Double_t c1=1)
Performs the operation:
Definition TH1.cxx:6013
@ kXaxis
Definition TH1.h:73
@ kNoAxis
NOTE: Must always be 0 !!!
Definition TH1.h:72
@ kZaxis
Definition TH1.h:75
@ kYaxis
Definition TH1.h:74
Int_t fNcells
Number of bins(1D), cells (2D) +U/Overflows.
Definition TH1.h:89
virtual void GetStats(Double_t *stats) const
fill the array stats from the contents of this histogram The array stats must be correctly dimensione...
Definition TH1.cxx:7798
void Copy(TObject &hnew) const override
Copy this histogram structure to newth1.
Definition TH1.cxx:2667
void SetTitle(const char *title) override
Change/set the title.
Definition TH1.cxx:6682
Double_t fTsumw
Total Sum of weights.
Definition TH1.h:96
virtual Float_t GetBarWidth() const
Definition TH1.h:257
Double_t fTsumw2
Total Sum of squares of weights.
Definition TH1.h:97
static void StatOverflows(Bool_t flag=kTRUE)
if flag=kTRUE, underflows and overflows are used by the Fill functions in the computation of statisti...
Definition TH1.cxx:6889
virtual Float_t GetBarOffset() const
Definition TH1.h:256
TList * fFunctions
->Pointer to list of functions (fits and user)
Definition TH1.h:106
static Bool_t fgAddDirectory
! Flag to add histograms to the directory
Definition TH1.h:116
static int CheckConsistency(const TH1 *h1, const TH1 *h2)
Check histogram compatibility.
Definition TH1.cxx:1675
static TClass * Class()
static Int_t GetDefaultBufferSize()
Static function return the default buffer size for automatic histograms the parameter fgBufferSize ma...
Definition TH1.cxx:4402
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:7942
Double_t fTsumwx2
Total Sum of weight*X*X.
Definition TH1.h:99
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition TH1.cxx:7572
TH1()
Histogram default constructor.
Definition TH1.cxx:613
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:9284
void UseCurrentStyle() override
Copy current attributes from/to current style.
Definition TH1.cxx:7434
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:5346
virtual Int_t GetNbinsY() const
Definition TH1.h:298
Short_t fBarOffset
(1000*offset) for bar charts or legos
Definition TH1.h:93
virtual Double_t Chi2TestX(const TH1 *h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option="UU", Double_t *res=nullptr) const
The computation routine of the Chisquare test.
Definition TH1.cxx:2065
static bool CheckBinLimits(const TAxis *a1, const TAxis *a2)
Check bin limits.
Definition TH1.cxx:1539
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition TH1.cxx:1266
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:9028
static Int_t FitOptionsMake(Option_t *option, Foption_t &Foption)
Decode string choptin and fill fitOption structure.
Definition TH1.cxx:4616
virtual Int_t GetNbinsZ() const
Definition TH1.h:299
virtual Double_t GetNormFactor() const
Definition TH1.h:301
virtual Double_t GetMean(Int_t axis=1) const
For axis = 1,2 or 3 returns the mean value of the histogram along X,Y or Z axis.
Definition TH1.cxx:7500
virtual Double_t GetSkewness(Int_t axis=1) const
Definition TH1.cxx:7636
virtual void ClearUnderflowAndOverflow()
Remove all the content from the underflow and overflow bins, without changing the number of entries A...
Definition TH1.cxx:2515
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition TH1.cxx:8405
virtual TH1 * DrawNormalized(Option_t *option="", Double_t norm=1) const
Draw a normalized copy of this histogram.
Definition TH1.cxx:3140
@ kNeutral
Adapt to the global flag.
Definition TH1.h:83
virtual Int_t GetDimension() const
Definition TH1.h:283
void Streamer(TBuffer &) override
Stream a class object.
Definition TH1.cxx:6897
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1292
@ kIsAverage
Bin contents are average (used by Add)
Definition TH1.h:171
@ kUserContour
User specified contour levels.
Definition TH1.h:166
@ kNoStats
Don't draw stats box.
Definition TH1.h:165
@ kAutoBinPTwo
different than 1.
Definition TH1.h:174
@ kIsNotW
Histogram is forced to be not weighted even when the histogram is filled with weighted.
Definition TH1.h:172
@ kIsHighlight
bit set if histo is highlight
Definition TH1.h:175
virtual void SetContourLevel(Int_t level, Double_t value)
Set value for one contour level.
Definition TH1.cxx:8487
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition TH1.cxx:6600
TDirectory * fDirectory
! Pointer to directory holding this histogram
Definition TH1.h:109
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition TH1.cxx:7067
void SetNameTitle(const char *name, const char *title) override
Change the name and title of this histogram.
Definition TH1.cxx:8939
TAxis * GetXaxis()
Definition TH1.h:324
virtual void GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz) const
Return binx, biny, binz corresponding to the global bin number globalbin see TH1::GetBin function abo...
Definition TH1.cxx:4938
TH1 * GetCumulative(Bool_t forward=kTRUE, const char *suffix="_cumulative") const
Return a pointer to a histogram containing the cumulative content.
Definition TH1.cxx:2612
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:1306
virtual Int_t GetNcells() const
Definition TH1.h:300
virtual Int_t ShowPeaks(Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
Interface to TSpectrum::Search.
Definition TH1.cxx:9266
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition TH1.cxx:5872
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition TH1.cxx:7849
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition TH1.cxx:4484
TObject * FindObject(const char *name) const override
Search object named name in the list of functions.
Definition TH1.cxx:3853
virtual void FillRandom(const char *fname, Int_t ntimes=5000, TRandom *rng=nullptr)
Fill histogram following distribution in function fname.
Definition TH1.cxx:3515
void Print(Option_t *option="") const override
Print some global quantities for this histogram.
Definition TH1.cxx:6973
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
Definition TH1.cxx:4411
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:3730
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:3894
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:4925
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:8510
virtual Int_t GetNbinsX() const
Definition TH1.h:297
virtual void SetMaximum(Double_t maximum=-1111)
Definition TH1.h:403
virtual TH1 * FFT(TH1 *h_output, Option_t *option)
This function allows to do discrete Fourier transforms of TH1 and TH2.
Definition TH1.cxx:3280
virtual void LabelsInflate(Option_t *axis="X")
Double the number of bins for axis.
Definition TH1.cxx:5279
virtual TH1 * ShowBackground(Int_t niter=20, Option_t *option="same")
This function calculates the background spectrum in this histogram.
Definition TH1.cxx:9252
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
Definition TH1.cxx:5862
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:824
Double_t fMaximum
Maximum value for plotting.
Definition TH1.h:100
Int_t fBufferSize
fBuffer size
Definition TH1.h:107
virtual Double_t RetrieveBinContent(Int_t bin) const
Raw retrieval of bin content on internal data structure see convention for numbering bins in TH1::Get...
Definition TH1.cxx:9404
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:7933
Int_t fDimension
! Histogram dimension (1, 2 or 3 dim)
Definition TH1.h:110
virtual void SetBinError(Int_t bin, Double_t error)
Set the bin Error Note that this resets the bin eror option to be of Normal Type and for the non-empt...
Definition TH1.cxx:9171
EBinErrorOpt fBinStatErrOpt
Option for bin statistical errors.
Definition TH1.h:113
static Int_t fgBufferSize
! Default buffer size for automatic histograms
Definition TH1.h:115
virtual void SetBinsLength(Int_t=-1)
Definition TH1.h:380
Double_t fNormFactor
Normalization factor.
Definition TH1.h:102
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3340
TAxis * GetYaxis()
Definition TH1.h:325
TArrayD fContour
Array to display contour levels.
Definition TH1.h:103
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition TH1.cxx:9044
void Browse(TBrowser *b) override
Browse the Histogram object.
Definition TH1.cxx:760
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition TH1.cxx:8363
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx:3062
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:7344
Short_t fBarWidth
(1000*width) for bar charts or legos
Definition TH1.h:94
virtual Double_t GetBinErrorSqUnchecked(Int_t bin) const
Definition TH1.h:448
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:404
Bool_t IsBinUnderflow(Int_t bin, Int_t axis=0) const
Return true if the bin is underflow.
Definition TH1.cxx:5178
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TH1.cxx:7202
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check that axis have same labels.
Definition TH1.cxx:1566
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:5079
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:6667
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition TH1.cxx:5146
UInt_t GetAxisLabelStatus() const
Internal function used in TH1::Fill to see which axis is full alphanumeric, i.e.
Definition TH1.cxx:6639
Double_t * fIntegral
! Integral of bins used by GetRandom
Definition TH1.h:111
Double_t fMinimum
Minimum value for plotting.
Definition TH1.h:101
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition TH1.cxx:7906
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:9187
virtual void DirectoryAutoAdd(TDirectory *)
Perform the automatic addition of the histogram to the given directory.
Definition TH1.cxx:2797
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:9152
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:9117
void Build()
Creates histogram basic data structure.
Definition TH1.cxx:769
virtual Double_t GetEntries() const
Return the current number of entries.
Definition TH1.cxx:4419
virtual TF1 * GetFunction(const char *name) const
Return pointer to function with name.
Definition TH1.cxx:9016
virtual TH1 * Rebin(Int_t ngroup=2, const char *newname="", const Double_t *xbins=nullptr)
Rebin this histogram.
Definition TH1.cxx:6239
virtual Int_t BufferFill(Double_t x, Double_t w)
accumulate arguments in buffer.
Definition TH1.cxx:1504
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:5050
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:6613
TList * GetListOfFunctions() const
Definition TH1.h:244
void SetName(const char *name) override
Change the name of this histogram.
Definition TH1.cxx:8925
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition TH1.cxx:3109
Bool_t IsEmpty() const
Check if a histogram is empty (this is a protected method used mainly by TH1Merger )
Definition TH1.cxx:5128
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition TH1.cxx:7540
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6170
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:8027
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculated from bin cont...
Definition TH1.cxx:7867
static void SetDefaultBufferSize(Int_t buffersize=1000)
Static function to set the default buffer size for automatic histograms.
Definition TH1.cxx:6657
virtual void SetBinErrorOption(EBinErrorOpt type)
Definition TH1.h:381
virtual void SetBuffer(Int_t buffersize, Option_t *option="")
Set the maximum number of entries to be kept in the buffer.
Definition TH1.cxx:8423
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Definition TH1.cxx:3171
virtual Double_t GetRandom(TRandom *rng=nullptr) const
Return a random number distributed according the histogram bin contents.
Definition TH1.cxx:4974
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:2494
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:2006
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:3469
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition TH1.cxx:8696
@ kNstat
Size of statistics data (up to TProfile3D)
Definition TH1.h:184
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition TH1.cxx:8542
static Int_t AutoP2GetBins(Int_t n)
Auxiliary function to get the next power of 2 integer value larger then n.
Definition TH1.cxx:1319
Double_t fEntries
Number of entries.
Definition TH1.h:95
virtual Long64_t Merge(TCollection *list)
Definition TH1.h:345
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TH1.cxx:3236
virtual Double_t * GetIntegral()
Return a pointer to the array of bins integral.
Definition TH1.cxx:2582
TAxis fZaxis
Z axis descriptor.
Definition TH1.h:92
EStatOverflows fStatOverflows
Per object flag to use under/overflows in statistics.
Definition TH1.h:114
TClass * IsA() const override
Definition TH1.h:443
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:3443
virtual void UpdateBinContent(Int_t bin, Double_t content)
Raw update of bin content on internal data structure see convention for numbering bins in TH1::GetBin...
Definition TH1.cxx:9414
static bool CheckEqualAxes(const TAxis *a1, const TAxis *a2)
Check that the axis are the same.
Definition TH1.cxx:1609
@ kPoisson2
Errors from Poisson interval at 95% CL (~ 2 sigma)
Definition TH1.h:67
@ kNormal
Errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition TH1.h:65
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5025
virtual Int_t GetContour(Double_t *levels=nullptr)
Return contour values into array levels if pointer levels is non zero.
Definition TH1.cxx:8376
TAxis fXaxis
X axis descriptor.
Definition TH1.h:90
virtual Bool_t IsHighlight() const
Definition TH1.h:338
virtual void ExtendAxis(Double_t x, TAxis *axis)
Histogram is resized along axis such that x is in the axis range.
Definition TH1.cxx:6468
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:9128
TArrayD fSumw2
Array of sum of squares of weights.
Definition TH1.h:104
TH1 * GetAsymmetry(TH1 *h2, Double_t c2=1, Double_t dc2=0)
Return a histogram containing the asymmetry of this histogram with h2, where the asymmetry is defined...
Definition TH1.cxx:4335
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition TH1.cxx:8395
virtual void SetContour(Int_t nlevels, const Double_t *levels=nullptr)
Set the number and values of contour levels.
Definition TH1.cxx:8448
virtual void SetHighlight(Bool_t set=kTRUE)
Set highlight (enable/disable) mode for the histogram by default highlight mode is disable.
Definition TH1.cxx:4455
virtual Int_t GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum=nullptr)
Compute Quantiles for this histogram Quantile x_q of a probability distribution Function F is defined...
Definition TH1.cxx:4575
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition TH1.cxx:9075
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition TH1.cxx:6568
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition TH1.cxx:8630
virtual Int_t GetSumw2N() const
Definition TH1.h:315
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
Return Global bin number corresponding to x,y,z.
Definition TH1.cxx:3668
Bool_t GetStatOverflowsBehaviour() const
Definition TH1.h:152
void SaveAs(const char *filename, Option_t *option) const override
Save the histogram as .csv, .tsv or .txt.
Definition TH1.cxx:7145
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx:2748
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition TH1.cxx:7620
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:2836
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:8600
int LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge=false) const
Definition TH1.cxx:881
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:1638
void RecursiveRemove(TObject *obj) override
Recursively remove object from the list of functions.
Definition TH1.cxx:6540
TAxis fYaxis
Y axis descriptor.
Definition TH1.h:91
virtual Double_t KolmogorovTest(const TH1 *h2, Option_t *option="") const
Statistical test of compatibility in shape between this histogram and h2, using Kolmogorov test.
Definition TH1.cxx:8143
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition TH1.cxx:7882
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:6732
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:9139
TVirtualHistPainter * fPainter
! Pointer to histogram painter
Definition TH1.h:112
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition TH1.cxx:8732
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:3701
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:8985
virtual void SetEntries(Double_t n)
Definition TH1.h:390
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:6424
static bool CheckAxisLimits(const TAxis *a1, const TAxis *a2)
Check that the axis limits of the histograms are the same.
Definition TH1.cxx:1595
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition TH1.cxx:752
static Bool_t fgDefaultSumw2
! Flag to call TH1::Sumw2 automatically at histogram creation time
Definition TH1.h:118
Double_t fTsumwx
Total Sum of weight*X.
Definition TH1.h:98
virtual void LabelsDeflate(Option_t *axis="X")
Reduce the number of bins for the axis passed in the option to the number of bins having a label.
Definition TH1.cxx:5209
virtual Double_t ComputeIntegral(Bool_t onlyPositive=false)
Compute integral (cumulative sum of bins) The result stored in fIntegral is used by the GetRandom fun...
Definition TH1.cxx:2534
TString fOption
Histogram options.
Definition TH1.h:105
virtual void Eval(TF1 *f1, Option_t *option="")
Evaluate function f1 at the center of bins of this histogram.
Definition TH1.cxx:3188
virtual void SetBarWidth(Float_t width=0.5)
Set the width of bars as fraction of the bin width for drawing mode "B".
Definition TH1.h:365
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition TH1.cxx:1412
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition TH1.cxx:8955
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition TH1.cxx:7709
2-D histogram with a double per channel (see TH1 documentation)
Definition TH2.h:338
static THLimitsFinder * GetLimitsFinder()
Return pointer to the current finder.
virtual Int_t FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax)
Compute the best axis limits for the X axis.
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
void Clear(Option_t *option="") override
Remove all objects from the list.
A doubly linked list.
Definition TList.h:38
void Streamer(TBuffer &) override
Stream all objects in the collection to or from the I/O buffer.
Definition TList.cxx:1191
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:578
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition TList.cxx:764
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:822
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:659
virtual TObjLink * FirstLink() const
Definition TList.h:102
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:470
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:357
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
void Copy(TObject &named) const override
Copy this to obj.
Definition TNamed.cxx:94
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
void Streamer(TBuffer &) override
Stream an object of class TObject.
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
TString fTitle
Definition TNamed.h:33
TString fName
Definition TNamed.h:32
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
Mother of all ROOT objects.
Definition TObject.h:41
void AbstractMethod(const char *method) const
Use this method to implement an "abstract" method that you don't want to leave purely abstract.
Definition TObject.cxx:1018
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:439
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:457
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:207
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition TObject.cxx:801
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:962
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:184
virtual void SaveAs(const char *filename="", Option_t *option="") const
Save this object in the file specified by filename.
Definition TObject.cxx:686
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:780
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:525
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:976
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:791
void ResetBit(UInt_t f)
Definition TObject.h:200
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:64
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:950
Longptr_t ExecPlugin(int nargs)
Int_t LoadPlugin()
Load the plugin library for this handler.
static TClass * Class()
This is the base class for the ROOT Random number generators.
Definition TRandom.h:27
Double_t Rndm() override
Machine independent random number generator.
Definition TRandom.cxx:559
virtual Double_t PoissonD(Double_t mean)
Generates a random number according to a Poisson law.
Definition TRandom.cxx:461
virtual ULong64_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition TRandom.cxx:404
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:419
void ToLower()
Change string to lower-case.
Definition TString.cxx:1182
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2244
void Clear()
Clear string without changing its capacity.
Definition TString.cxx:1235
const char * Data() const
Definition TString.h:378
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:706
void ToUpper()
Change string to upper case.
Definition TString.cxx:1195
Bool_t IsNull() const
Definition TString.h:416
TString & Remove(Ssiz_t pos)
Definition TString.h:687
virtual void Streamer(TBuffer &)
Stream a string object.
Definition TString.cxx:1412
TString & Append(const char *cs)
Definition TString.h:574
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2378
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2356
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:634
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:653
Int_t GetOptStat() const
Definition TStyle.h:243
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:1636
void SetHistFillColor(Color_t color=1)
Definition TStyle.h:376
Color_t GetHistLineColor() const
Definition TStyle.h:231
Bool_t IsReading() const
Definition TStyle.h:294
Float_t GetBarOffset() const
Definition TStyle.h:181
void SetHistLineStyle(Style_t styl=0)
Definition TStyle.h:379
Style_t GetHistFillStyle() const
Definition TStyle.h:232
Color_t GetHistFillColor() const
Definition TStyle.h:230
Float_t GetBarWidth() const
Definition TStyle.h:182
Bool_t GetCanvasPreferGL() const
Definition TStyle.h:186
void SetHistLineColor(Color_t color=1)
Definition TStyle.h:377
void SetBarOffset(Float_t baroff=0.5)
Definition TStyle.h:333
Style_t GetHistLineStyle() const
Definition TStyle.h:233
void SetBarWidth(Float_t barwidth=0.5)
Definition TStyle.h:334
void SetHistFillStyle(Style_t styl=0)
Definition TStyle.h:378
Width_t GetHistLineWidth() const
Definition TStyle.h:234
Int_t GetOptFit() const
Definition TStyle.h:242
void SetHistLineWidth(Width_t width=1)
Definition TStyle.h:380
TVectorT.
Definition TVectorT.h:27
TVirtualFFT is an interface class for Fast Fourier Transforms.
Definition TVirtualFFT.h:88
static TVirtualFFT * FFT(Int_t ndim, Int_t *n, Option_t *option)
Returns a pointer to the FFT of requested size and type.
virtual Int_t GetNdim() const =0
static TVirtualFFT * SineCosine(Int_t ndim, Int_t *n, Int_t *r2rkind, Option_t *option)
Returns a pointer to a sine or cosine transform of requested size and kind.
virtual Option_t * GetType() const =0
virtual void Transform()=0
virtual void GetPointComplex(Int_t ipoint, Double_t &re, Double_t &im, Bool_t fromInput=kFALSE) const =0
virtual Int_t * GetN() const =0
virtual Double_t GetPointReal(Int_t ipoint, Bool_t fromInput=kFALSE) const =0
virtual void SetPoint(Int_t ipoint, Double_t re, Double_t im=0)=0
Abstract Base Class for Fitting.
virtual Int_t GetXlast() const
virtual TObject * GetObjectFit() const
virtual Int_t GetXfirst() const
static TVirtualFitter * GetFitter()
static: return the current Fitter
virtual TObject * GetUserFunc() const
Abstract interface to a histogram painter.
virtual void DrawPanel()=0
Int_t DistancetoPrimitive(Int_t px, Int_t py) override=0
Computes distance from point (px,py) to the object.
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override=0
Execute action corresponding to an event at (px,py).
virtual void SetHighlight()=0
static TVirtualHistPainter * HistPainter(TH1 *obj)
Static function returning a pointer to the current histogram painter.
void Paint(Option_t *option="") override=0
This method must be overridden if a class wants to paint itself.
virtual void SetParent(TObject *)=0
double gamma_quantile_c(double z, double alpha, double theta)
Inverse ( ) of the cumulative distribution function of the upper tail of the gamma distribution (gamm...
double gamma_quantile(double z, double alpha, double theta)
Inverse ( ) of the cumulative distribution function of the lower tail of the gamma distribution (gamm...
const Double_t sigma
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TH1F * h1
Definition legend1.C:5
TF1 * f1
Definition legend1.C:11
return c2
Definition legend2.C:14
R__ALWAYS_INLINE bool HasBeenDeleted(const TObject *obj)
Check if the TObject's memory has been deleted.
Definition TObject.h:404
TFitResultPtr FitObject(TH1 *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
fitting function for a TH1 (called from TH1::Fit)
Definition HFitImpl.cxx:972
double Chisquare(const TH1 &h1, TF1 &f1, bool useRange, EChisquareType type)
compute the chi2 value for an histogram given a function (see TH1::Chisquare for the documentation)
void FitOptionsMake(EFitObjectType type, const char *option, Foption_t &fitOption)
Decode list of options into fitOption.
Definition HFitImpl.cxx:685
void FillData(BinData &dv, const TH1 *hist, TF1 *func=nullptr)
fill the data vector from a TH1.
R__EXTERN TVirtualRWMutex * gCoreMutex
Bool_t IsNaN(Double_t x)
Definition TMath.h:892
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:693
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:250
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition TMath.cxx:637
Double_t Median(Long64_t n, const T *a, const Double_t *w=nullptr, Long64_t *work=nullptr)
Same as RMS.
Definition TMath.h:1272
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Definition TMath.h:902
Double_t Floor(Double_t x)
Rounds x downward, returning the largest integral value that is not greater than x.
Definition TMath.h:680
Double_t ATan(Double_t)
Returns the principal value of the arc tangent of x, expressed in radians.
Definition TMath.h:640
Double_t Ceil(Double_t x)
Rounds x upward, returning the smallest integral value that is not less than x.
Definition TMath.h:668
T MinElement(Long64_t n, const T *a)
Returns minimum of array a of length n.
Definition TMath.h:960
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:756
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:662
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:721
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
constexpr Double_t Pi()
Definition TMath.h:37
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Comparing floating points.
Definition TMath.h:426
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Comparing floating points.
Definition TMath.h:418
Double_t KolmogorovProb(Double_t z)
Calculates the Kolmogorov distribution function,.
Definition TMath.cxx:679
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Sort the n elements of the array a of generic templated type Element.
Definition TMathBase.h:431
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition TMathBase.h:347
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:762
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
Definition TMath.h:917
th1 Draw()
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345