Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TH1.cxx
Go to the documentation of this file.
1// @(#)root/hist:$Id$
2// Author: Rene Brun 26/12/94
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <array>
13#include <cctype>
14#include <climits>
15#include <cmath>
16#include <cstdio>
17#include <cstdlib>
18#include <cstring>
19#include <iostream>
20#include <memory>
21#include <sstream>
22#include <fstream>
23#include <limits>
24#include <iomanip>
25
26#include "TROOT.h"
27#include "TBuffer.h"
28#include "TEnv.h"
29#include "TClass.h"
30#include "TMath.h"
31#include "THashList.h"
32#include "TH1.h"
33#include "TH2.h"
34#include "TH3.h"
35#include "TF2.h"
36#include "TF3.h"
37#include "TPluginManager.h"
38#include "TVirtualPad.h"
39#include "TRandom.h"
40#include "TVirtualFitter.h"
41#include "THLimitsFinder.h"
42#include "TProfile.h"
43#include "TStyle.h"
44#include "TVectorF.h"
45#include "TVectorD.h"
46#include "TBrowser.h"
47#include "TError.h"
48#include "TVirtualHistPainter.h"
49#include "TVirtualFFT.h"
50#include "TVirtualPaveStats.h"
51
52#include "HFitInterface.h"
53#include "Fit/DataRange.h"
54#include "Fit/BinData.h"
55#include "Math/GoFTest.h"
58
59#include "TH1Merger.h"
60
61/** \addtogroup Histograms
62@{
63\class TH1C
64\brief 1-D histogram with a byte per channel (see TH1 documentation)
65\class TH1S
66\brief 1-D histogram with a short per channel (see TH1 documentation)
67\class TH1I
68\brief 1-D histogram with an int per channel (see TH1 documentation)
69\class TH1L
70\brief 1-D histogram with a long64 per channel (see TH1 documentation)
71\class TH1F
72\brief 1-D histogram with a float per channel (see TH1 documentation)
73\class TH1D
74\brief 1-D histogram with a double per channel (see TH1 documentation)
75@}
76*/
77
78/** \class TH1
79 \ingroup Histograms
80TH1 is the base class of all histogram classes in %ROOT.
81
82It provides the common interface for operations such as binning, filling, drawing, which
83will be detailed below.
84
85-# [Creating histograms](\ref creating-histograms)
86 - [Labelling axes](\ref labelling-axis)
87-# [Binning](\ref binning)
88 - [Fix or variable bin size](\ref fix-var)
89 - [Convention for numbering bins](\ref convention)
90 - [Alphanumeric Bin Labels](\ref alpha)
91 - [Histograms with automatic bins](\ref auto-bin)
92 - [Rebinning](\ref rebinning)
93-# [Filling histograms](\ref filling-histograms)
94 - [Associated errors](\ref associated-errors)
95 - [Associated functions](\ref associated-functions)
96 - [Projections of histograms](\ref prof-hist)
97 - [Random Numbers and histograms](\ref random-numbers)
98 - [Making a copy of a histogram](\ref making-a-copy)
99 - [Normalizing histograms](\ref normalizing)
100-# [Drawing histograms](\ref drawing-histograms)
101 - [Setting Drawing histogram contour levels (2-D hists only)](\ref cont-level)
102 - [Setting histogram graphics attributes](\ref graph-att)
103 - [Customising how axes are drawn](\ref axis-drawing)
104-# [Fitting histograms](\ref fitting-histograms)
105-# [Saving/reading histograms to/from a ROOT file](\ref saving-histograms)
106-# [Operations on histograms](\ref operations-on-histograms)
107-# [Miscellaneous operations](\ref misc)
108
109ROOT supports the following histogram types:
110
111 - 1-D histograms:
112 - TH1C : histograms with one byte per channel. Maximum bin content = 127
113 - TH1S : histograms with one short per channel. Maximum bin content = 32767
114 - TH1I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
115 - TH1L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
116 - TH1F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax "***")
117 - TH1D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax "****")
118 - 2-D histograms:
119 - TH2C : histograms with one byte per channel. Maximum bin content = 127
120 - TH2S : histograms with one short per channel. Maximum bin content = 32767
121 - TH2I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
122 - TH2L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
123 - TH2F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax "***")
124 - TH2D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax "****")
125 - 3-D histograms:
126 - TH3C : histograms with one byte per channel. Maximum bin content = 127
127 - TH3S : histograms with one short per channel. Maximum bin content = 32767
128 - TH3I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
129 - TH3L : histograms with one long64 per channel. Maximum bin content = LLONG_MAX (\ref llongmax "**")
130 - TH3F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216 (\ref floatmax "***")
131 - TH3D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992 (\ref doublemax "****")
132 - Profile histograms: See classes TProfile, TProfile2D and TProfile3D.
133 Profile histograms are used to display the mean value of Y and its standard deviation
134 for each bin in X. Profile histograms are in many cases an elegant
135 replacement of two-dimensional histograms : the inter-relation of two
136 measured quantities X and Y can always be visualized by a two-dimensional
137 histogram or scatter-plot; If Y is an unknown (but single-valued)
138 approximate function of X, this function is displayed by a profile
139 histogram with much better precision than by a scatter-plot.
140
141<sup>
142\anchor intmax (*) INT_MAX = 2147483647 is the [maximum value for a variable of type int.](https://docs.microsoft.com/en-us/cpp/c-language/cpp-integer-limits)<br>
143\anchor llongmax (**) LLONG_MAX = 9223372036854775807 is the [maximum value for a variable of type long64.](https://docs.microsoft.com/en-us/cpp/c-language/cpp-integer-limits)<br>
144\anchor floatmax (***) 2^24 = 16777216 is the [maximum integer that can be properly represented by a float32 with 23-bit mantissa.](https://stackoverflow.com/a/3793950/7471760)<br>
145\anchor doublemax (****) 2^53 = 9007199254740992 is the [maximum integer that can be properly represented by a double64 with 52-bit mantissa.](https://stackoverflow.com/a/3793950/7471760)
146</sup>
147
148The inheritance hierarchy looks as follows:
149
150\image html classTH1__inherit__graph_org.svg width=100%
151
152\anchor creating-histograms
153## Creating histograms
154
155Histograms are created by invoking one of the constructors, e.g.
156~~~ {.cpp}
157 TH1F *h1 = new TH1F("h1", "h1 title", 100, 0, 4.4);
158 TH2F *h2 = new TH2F("h2", "h2 title", 40, 0, 4, 30, -3, 3);
159~~~
160Histograms may also be created by:
161
162 - calling the Clone() function, see below
163 - making a projection from a 2-D or 3-D histogram, see below
164 - reading a histogram from a file
165
166 When a histogram is created, a reference to it is automatically added
167 to the list of in-memory objects for the current file or directory.
168 Then the pointer to this histogram in the current directory can be found
169 by its name, doing:
170~~~ {.cpp}
171 TH1F *h1 = (TH1F*)gDirectory->FindObject(name);
172~~~
173
174 This default behaviour can be changed by:
175~~~ {.cpp}
176 h->SetDirectory(nullptr); // for the current histogram h
177 TH1::AddDirectory(kFALSE); // sets a global switch disabling the referencing
178~~~
179 When the histogram is deleted, the reference to it is removed from
180 the list of objects in memory.
181 When a file is closed, all histograms in memory associated with this file
182 are automatically deleted.
183
184\anchor labelling-axis
185### Labelling axes
186
187 Axis titles can be specified in the title argument of the constructor.
188 They must be separated by ";":
189~~~ {.cpp}
190 TH1F* h=new TH1F("h", "Histogram title;X Axis;Y Axis", 100, 0, 1);
191~~~
192 The histogram title and the axis titles can be any TLatex string, and
193 are persisted if a histogram is written to a file.
194
195 Any title can be omitted:
196~~~ {.cpp}
197 TH1F* h=new TH1F("h", "Histogram title;;Y Axis", 100, 0, 1);
198 TH1F* h=new TH1F("h", ";;Y Axis", 100, 0, 1);
199~~~
200 The method SetTitle() has the same syntax:
201~~~ {.cpp}
202 h->SetTitle("Histogram title;Another X title Axis");
203~~~
204Alternatively, the title of each axis can be set directly:
205~~~ {.cpp}
206 h->GetXaxis()->SetTitle("X axis title");
207 h->GetYaxis()->SetTitle("Y axis title");
208~~~
209For bin labels see \ref binning.
210
211\anchor binning
212## Binning
213
214\anchor fix-var
215### Fix or variable bin size
216
217 All histogram types support either fix or variable bin sizes.
218 2-D histograms may have fix size bins along X and variable size bins
219 along Y or vice-versa. The functions to fill, manipulate, draw or access
220 histograms are identical in both cases.
221
222 Each histogram always contains 3 axis objects of type TAxis: fXaxis, fYaxis and fZaxis.
223 To access the axis parameters, use:
224~~~ {.cpp}
225 TAxis *xaxis = h->GetXaxis(); etc.
226 Double_t binCenter = xaxis->GetBinCenter(bin), etc.
227~~~
228 See class TAxis for a description of all the access functions.
229 The axis range is always stored internally in double precision.
230
231\anchor convention
232### Convention for numbering bins
233
234 For all histogram types: nbins, xlow, xup
235~~~ {.cpp}
236 bin = 0; underflow bin
237 bin = 1; first bin with low-edge xlow INCLUDED
238 bin = nbins; last bin with upper-edge xup EXCLUDED
239 bin = nbins+1; overflow bin
240~~~
241 In case of 2-D or 3-D histograms, a "global bin" number is defined.
242 For example, assuming a 3-D histogram with (binx, biny, binz), the function
243~~~ {.cpp}
244 Int_t gbin = h->GetBin(binx, biny, binz);
245~~~
246 returns a global/linearized gbin number. This global gbin is useful
247 to access the bin content/error information independently of the dimension.
248 Note that to access the information other than bin content and errors
249 one should use the TAxis object directly with e.g.:
250~~~ {.cpp}
251 Double_t xcenter = h3->GetZaxis()->GetBinCenter(27);
252~~~
253 returns the center along z of bin number 27 (not the global bin)
254 in the 3-D histogram h3.
255
256\anchor alpha
257### Alphanumeric Bin Labels
258
259 By default, a histogram axis is drawn with its numeric bin labels.
260 One can specify alphanumeric labels instead with:
261
262 - call TAxis::SetBinLabel(bin, label);
263 This can always be done before or after filling.
264 When the histogram is drawn, bin labels will be automatically drawn.
265 See examples labels1.C and labels2.C
266 - call to a Fill function with one of the arguments being a string, e.g.
267~~~ {.cpp}
268 hist1->Fill(somename, weight);
269 hist2->Fill(x, somename, weight);
270 hist2->Fill(somename, y, weight);
271 hist2->Fill(somenamex, somenamey, weight);
272~~~
273 See examples hlabels1.C and hlabels2.C
274 - via TTree::Draw. see for example cernstaff.C
275~~~ {.cpp}
276 tree.Draw("Nation::Division");
277~~~
278 where "Nation" and "Division" are two branches of a Tree.
279
280When using the options 2 or 3 above, the labels are automatically
281 added to the list (THashList) of labels for a given axis.
282 By default, an axis is drawn with the order of bins corresponding
283 to the filling sequence. It is possible to reorder the axis
284
285 - alphabetically
286 - by increasing or decreasing values
287
288 The reordering can be triggered via the TAxis context menu by selecting
289 the menu item "LabelsOption" or by calling directly
290 TH1::LabelsOption(option, axis) where
291
292 - axis may be "X", "Y" or "Z"
293 - option may be:
294 - "a" sort by alphabetic order
295 - ">" sort by decreasing values
296 - "<" sort by increasing values
297 - "h" draw labels horizontal
298 - "v" draw labels vertical
299 - "u" draw labels up (end of label right adjusted)
300 - "d" draw labels down (start of label left adjusted)
301
302 When using the option 2 above, new labels are added by doubling the current
303 number of bins in case one label does not exist yet.
304 When the Filling is terminated, it is possible to trim the number
305 of bins to match the number of active labels by calling
306~~~ {.cpp}
307 TH1::LabelsDeflate(axis) with axis = "X", "Y" or "Z"
308~~~
309 This operation is automatic when using TTree::Draw.
310 Once bin labels have been created, they become persistent if the histogram
311 is written to a file or when generating the C++ code via SavePrimitive.
312
313\anchor auto-bin
314### Histograms with automatic bins
315
316 When a histogram is created with an axis lower limit greater or equal
317 to its upper limit, the SetBuffer is automatically called with an
318 argument fBufferSize equal to fgBufferSize (default value=1000).
319 fgBufferSize may be reset via the static function TH1::SetDefaultBufferSize.
320 The axis limits will be automatically computed when the buffer will
321 be full or when the function BufferEmpty is called.
322
323\anchor rebinning
324### Rebinning
325
326 At any time, a histogram can be rebinned via TH1::Rebin. This function
327 returns a new histogram with the rebinned contents.
328 If bin errors were stored, they are recomputed during the rebinning.
329
330
331\anchor filling-histograms
332## Filling histograms
333
334 A histogram is typically filled with statements like:
335~~~ {.cpp}
336 h1->Fill(x);
337 h1->Fill(x, w); //fill with weight
338 h2->Fill(x, y)
339 h2->Fill(x, y, w)
340 h3->Fill(x, y, z)
341 h3->Fill(x, y, z, w)
342~~~
343 or via one of the Fill functions accepting names described above.
344 The Fill functions compute the bin number corresponding to the given
345 x, y or z argument and increment this bin by the given weight.
346 The Fill functions return the bin number for 1-D histograms or global
347 bin number for 2-D and 3-D histograms.
348 If TH1::Sumw2 has been called before filling, the sum of squares of
349 weights is also stored.
350 One can also increment directly a bin number via TH1::AddBinContent
351 or replace the existing content via TH1::SetBinContent. Passing an
352 out-of-range bin to TH1::AddBinContent leads to undefined behavior.
353 To access the bin content of a given bin, do:
354~~~ {.cpp}
355 Double_t binContent = h->GetBinContent(bin);
356~~~
357
358 By default, the bin number is computed using the current axis ranges.
359 If the automatic binning option has been set via
360~~~ {.cpp}
361 h->SetCanExtend(TH1::kAllAxes);
362~~~
363 then, the Fill Function will automatically extend the axis range to
364 accommodate the new value specified in the Fill argument. The method
365 used is to double the bin size until the new value fits in the range,
366 merging bins two by two. This automatic binning options is extensively
367 used by the TTree::Draw function when histogramming Tree variables
368 with an unknown range.
369 This automatic binning option is supported for 1-D, 2-D and 3-D histograms.
370
371 During filling, some statistics parameters are incremented to compute
372 the mean value and Root Mean Square with the maximum precision.
373
374 In case of histograms of type TH1C, TH1S, TH2C, TH2S, TH3C, TH3S
375 a check is made that the bin contents do not exceed the maximum positive
376 capacity (127 or 32767). Histograms of all types may have positive
377 or/and negative bin contents.
378
379\anchor associated-errors
380### Associated errors
381 By default, for each bin, the sum of weights is computed at fill time.
382 One can also call TH1::Sumw2 to force the storage and computation
383 of the sum of the square of weights per bin.
384 If Sumw2 has been called, the error per bin is computed as the
385 sqrt(sum of squares of weights), otherwise the error is set equal
386 to the sqrt(bin content).
387 To return the error for a given bin number, do:
388~~~ {.cpp}
389 Double_t error = h->GetBinError(bin);
390~~~
391
392\anchor associated-functions
393### Associated functions
394 One or more objects (typically a TF1*) can be added to the list
395 of functions (fFunctions) associated to each histogram.
396 When TH1::Fit is invoked, the fitted function is added to this list.
397 Given a histogram (or TGraph) `h`, one can retrieve an associated function
398 with:
399~~~ {.cpp}
400 TF1 *myfunc = h->GetFunction("myfunc");
401~~~
402
403
404\anchor operations-on-histograms
405## Operations on histograms
406
407 Many types of operations are supported on histograms or between histograms
408
409 - Addition of a histogram to the current histogram.
410 - Additions of two histograms with coefficients and storage into the current
411 histogram.
412 - Multiplications and Divisions are supported in the same way as additions.
413 - The Add, Divide and Multiply functions also exist to add, divide or multiply
414 a histogram by a function.
415
416 If a histogram has associated error bars (TH1::Sumw2 has been called),
417 the resulting error bars are also computed assuming independent histograms.
418 In case of divisions, Binomial errors are also supported.
419 One can mark a histogram to be an "average" histogram by setting its bit kIsAverage via
420 myhist.SetBit(TH1::kIsAverage);
421 When adding (see TH1::Add) average histograms, the histograms are averaged and not summed.
422
423
424\anchor prof-hist
425### Projections of histograms
426
427 One can:
428
429 - make a 1-D projection of a 2-D histogram or Profile
430 see functions TH2::ProjectionX,Y, TH2::ProfileX,Y, TProfile::ProjectionX
431 - make a 1-D, 2-D or profile out of a 3-D histogram
432 see functions TH3::ProjectionZ, TH3::Project3D.
433
434 One can fit these projections via:
435~~~ {.cpp}
436 TH2::FitSlicesX,Y, TH3::FitSlicesZ.
437~~~
438
439\anchor random-numbers
440### Random Numbers and histograms
441
442 TH1::FillRandom can be used to randomly fill a histogram using
443 the contents of an existing TF1 function or another
444 TH1 histogram (for all dimensions).
445 For example, the following two statements create and fill a histogram
446 10000 times with a default gaussian distribution of mean 0 and sigma 1:
447~~~ {.cpp}
448 TH1F h1("h1", "histo from a gaussian", 100, -3, 3);
449 h1.FillRandom("gaus", 10000);
450~~~
451 TH1::GetRandom can be used to return a random number distributed
452 according to the contents of a histogram.
453
454\anchor making-a-copy
455### Making a copy of a histogram
456 Like for any other ROOT object derived from TObject, one can use
457 the Clone() function. This makes an identical copy of the original
458 histogram including all associated errors and functions, e.g.:
459~~~ {.cpp}
460 TH1F *hnew = (TH1F*)h->Clone("hnew");
461~~~
462
463\anchor normalizing
464### Normalizing histograms
465
466 One can scale a histogram such that the bins integral is equal to
467 the normalization parameter via TH1::Scale(Double_t norm), where norm
468 is the desired normalization divided by the integral of the histogram.
471\anchor drawing-histograms
472## Drawing histograms
473
474 Histograms are drawn via the THistPainter class. Each histogram has
475 a pointer to its own painter (to be usable in a multithreaded program).
476 Many drawing options are supported.
477 See THistPainter::Paint() for more details.
478
479 The same histogram can be drawn with different options in different pads.
480 When a histogram drawn in a pad is deleted, the histogram is
481 automatically removed from all pads where it was drawn.
482 If a histogram is drawn in a pad, then modified, the new status
483 of the histogram will be automatically shown in the pad next time
484 the pad is updated. One does not need to redraw the histogram.
485 To draw the current version of a histogram in a pad, one can use
486~~~ {.cpp}
487 h->DrawCopy();
488~~~
489 DrawCopy() is also useful when a temporary histogram should be drawn, for
490 example in
491~~~ {.cpp}
492 void drawHisto() {
493 TH1D histo("histo", "An example histogram", 10, 0, 10);
494 // ...
495 histo.DrawCopy();
496 } // histo goes out of scope here, but the copy stays visible
497~~~
498
499 One can use TH1::SetMaximum() and TH1::SetMinimum() to force a particular
500 value for the maximum or the minimum scale on the plot. (For 1-D
501 histograms this means the y-axis, while for 2-D histograms these
502 functions affect the z-axis).
503
504 TH1::UseCurrentStyle() can be used to change all histogram graphics
505 attributes to correspond to the current selected style.
506 This function must be called for each histogram.
507 In case one reads and draws many histograms from a file, one can force
508 the histograms to inherit automatically the current graphics style
509 by calling before gROOT->ForceStyle().
510
511\anchor cont-level
512### Setting Drawing histogram contour levels (2-D hists only)
513
514 By default contours are automatically generated at equidistant
515 intervals. A default value of 20 levels is used. This can be modified
516 via TH1::SetContour() or TH1::SetContourLevel().
517 the contours level info is used by the drawing options "cont", "surf",
518 and "lego".
519
520\anchor graph-att
521### Setting histogram graphics attributes
522
523 The histogram classes inherit from the attribute classes:
524 TAttLine, TAttFill, and TAttMarker.
525 See the member functions of these classes for the list of options.
526
527\anchor axis-drawing
528### Customizing how axes are drawn
529
530 Use the functions of TAxis, such as
531~~~ {.cpp}
532 histogram.GetXaxis()->SetTicks("+");
533 histogram.GetYaxis()->SetRangeUser(1., 5.);
534~~~
535
536\anchor fitting-histograms
537## Fitting histograms
538
539 Histograms (1-D, 2-D, 3-D and Profiles) can be fitted with a user
540 specified function or a pre-defined function via TH1::Fit.
541 See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for the fitting documentation and the possible [fitting options](\ref HFitOpt)
542
543 The FitPanel can also be used for fitting an histogram. See the [FitPanel documentation](https://root.cern/manual/fitting/#using-the-fit-panel).
544
545\anchor saving-histograms
546## Saving/reading histograms to/from a ROOT file
547
548 The following statements create a ROOT file and store a histogram
549 on the file. Because TH1 derives from TNamed, the key identifier on
550 the file is the histogram name:
551~~~ {.cpp}
552 TFile f("histos.root", "new");
553 TH1F h1("hgaus", "histo from a gaussian", 100, -3, 3);
554 h1.FillRandom("gaus", 10000);
555 h1->Write();
556~~~
557 To read this histogram in another Root session, do:
558~~~ {.cpp}
559 TFile f("histos.root");
560 TH1F *h = (TH1F*)f.Get("hgaus");
561~~~
562 One can save all histograms in memory to the file by:
563~~~ {.cpp}
564 file->Write();
565~~~
566
567
568\anchor misc
569## Miscellaneous operations
570
571~~~ {.cpp}
572 TH1::KolmogorovTest(): statistical test of compatibility in shape
573 between two histograms
574 TH1::Smooth() smooths the bin contents of a 1-d histogram
575 TH1::Integral() returns the integral of bin contents in a given bin range
576 TH1::GetMean(int axis) returns the mean value along axis
577 TH1::GetStdDev(int axis) returns the sigma distribution along axis
578 TH1::GetEntries() returns the number of entries
579 TH1::Reset() resets the bin contents and errors of a histogram
580~~~
581 IMPORTANT NOTE: The returned values for GetMean and GetStdDev depend on how the
582 histogram statistics are calculated. By default, if no range has been set, the
583 returned values are the (unbinned) ones calculated at fill time. If a range has been
584 set, however, the values are calculated using the bins in range; THIS IS TRUE EVEN
585 IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset the range.
586 To ensure that the returned values are always those of the binned data stored in the
587 histogram, call TH1::ResetStats. See TH1::GetStats.
588*/
589
590TF1 *gF1=nullptr; //left for back compatibility (use TVirtualFitter::GetUserFunc instead)
591
596
597extern void H1InitGaus();
598extern void H1InitExpo();
599extern void H1InitPolynom();
600extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
603
604
605////////////////////////////////////////////////////////////////////////////////
606/// Histogram default constructor.
607
609{
610 fDirectory = nullptr;
611 fFunctions = new TList;
612 fNcells = 0;
613 fIntegral = nullptr;
614 fPainter = nullptr;
615 fEntries = 0;
616 fNormFactor = 0;
618 fMaximum = -1111;
619 fMinimum = -1111;
620 fBufferSize = 0;
621 fBuffer = nullptr;
624 fXaxis.SetName("xaxis");
625 fYaxis.SetName("yaxis");
626 fZaxis.SetName("zaxis");
627 fXaxis.SetParent(this);
628 fYaxis.SetParent(this);
629 fZaxis.SetParent(this);
631}
632
633////////////////////////////////////////////////////////////////////////////////
634/// Histogram default destructor.
635
637{
639 return;
640 }
641 delete[] fIntegral;
642 fIntegral = nullptr;
643 delete[] fBuffer;
644 fBuffer = nullptr;
645 if (fFunctions) {
647
649 TObject* obj = nullptr;
650 //special logic to support the case where the same object is
651 //added multiple times in fFunctions.
652 //This case happens when the same object is added with different
653 //drawing modes
654 //In the loop below we must be careful with objects (eg TCutG) that may
655 // have been added to the list of functions of several histograms
656 //and may have been already deleted.
657 while ((obj = fFunctions->First())) {
658 while(fFunctions->Remove(obj)) { }
660 break;
661 }
662 delete obj;
663 obj = nullptr;
664 }
665 delete fFunctions;
666 fFunctions = nullptr;
667 }
668 if (fDirectory) {
669 fDirectory->Remove(this);
670 fDirectory = nullptr;
671 }
672 delete fPainter;
673 fPainter = nullptr;
674}
675
676////////////////////////////////////////////////////////////////////////////////
677/// Constructor for fix bin size histograms.
678/// Creates the main histogram structure.
679///
680/// \param[in] name name of histogram (avoid blanks)
681/// \param[in] title histogram title.
682/// If title is of the form `stringt;stringx;stringy;stringz`,
683/// the histogram title is set to `stringt`,
684/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
685/// \param[in] nbins number of bins
686/// \param[in] xlow low edge of first bin
687/// \param[in] xup upper edge of last bin (not included in last bin)
688
689
690TH1::TH1(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
691 :TNamed(name,title)
692{
693 Build();
694 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
695 fXaxis.Set(nbins,xlow,xup);
696 fNcells = fXaxis.GetNbins()+2;
697}
698
699////////////////////////////////////////////////////////////////////////////////
700/// Constructor for variable bin size histograms using an input array of type float.
701/// Creates the main histogram structure.
702///
703/// \param[in] name name of histogram (avoid blanks)
704/// \param[in] title histogram title.
705/// If title is of the form `stringt;stringx;stringy;stringz`
706/// the histogram title is set to `stringt`,
707/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
708/// \param[in] nbins number of bins
709/// \param[in] xbins array of low-edges for each bin.
710/// This is an array of type float and size nbins+1
711
712TH1::TH1(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
713 :TNamed(name,title)
714{
715 Build();
716 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
717 if (xbins) fXaxis.Set(nbins,xbins);
718 else fXaxis.Set(nbins,0,1);
719 fNcells = fXaxis.GetNbins()+2;
720}
721
722////////////////////////////////////////////////////////////////////////////////
723/// Constructor for variable bin size histograms using an input array of type double.
724///
725/// \param[in] name name of histogram (avoid blanks)
726/// \param[in] title histogram title.
727/// If title is of the form `stringt;stringx;stringy;stringz`
728/// the histogram title is set to `stringt`,
729/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
730/// \param[in] nbins number of bins
731/// \param[in] xbins array of low-edges for each bin.
732/// This is an array of type double and size nbins+1
733
734TH1::TH1(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
735 :TNamed(name,title)
736{
737 Build();
738 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
739 if (xbins) fXaxis.Set(nbins,xbins);
740 else fXaxis.Set(nbins,0,1);
741 fNcells = fXaxis.GetNbins()+2;
742}
743
744////////////////////////////////////////////////////////////////////////////////
745/// Static function: cannot be inlined on Windows/NT.
746
751
752////////////////////////////////////////////////////////////////////////////////
753/// Browse the Histogram object.
754
756{
757 Draw(b ? b->GetDrawOption() : "");
758 gPad->Update();
759}
760
761////////////////////////////////////////////////////////////////////////////////
762/// Creates histogram basic data structure.
763
765{
766 fDirectory = nullptr;
767 fPainter = nullptr;
768 fIntegral = nullptr;
769 fEntries = 0;
770 fNormFactor = 0;
772 fMaximum = -1111;
773 fMinimum = -1111;
774 fBufferSize = 0;
775 fBuffer = nullptr;
778 fXaxis.SetName("xaxis");
779 fYaxis.SetName("yaxis");
780 fZaxis.SetName("zaxis");
781 fYaxis.Set(1,0.,1.);
782 fZaxis.Set(1,0.,1.);
783 fXaxis.SetParent(this);
784 fYaxis.SetParent(this);
785 fZaxis.SetParent(this);
786
788
789 fFunctions = new TList;
790
792
795 if (fDirectory) {
797 fDirectory->Append(this,kTRUE);
798 }
799 }
800}
801
802////////////////////////////////////////////////////////////////////////////////
803/// Performs the operation: `this = this + c1*f1`
804/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
805///
806/// By default, the function is computed at the centre of the bin.
807/// if option "I" is specified (1-d histogram only), the integral of the
808/// function in each bin is used instead of the value of the function at
809/// the centre of the bin.
810///
811/// Only bins inside the function range are recomputed.
812///
813/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
814/// you should call Sumw2 before making this operation.
815/// This is particularly important if you fit the histogram after TH1::Add
816///
817/// The function return kFALSE if the Add operation failed
818
820{
821 if (!f1) {
822 Error("Add","Attempt to add a non-existing function");
823 return kFALSE;
824 }
825
826 TString opt = option;
827 opt.ToLower();
828 Bool_t integral = kFALSE;
829 if (opt.Contains("i") && fDimension == 1) integral = kTRUE;
830
831 Int_t ncellsx = GetNbinsX() + 2; // cells = normal bins + underflow bin + overflow bin
832 Int_t ncellsy = GetNbinsY() + 2;
833 Int_t ncellsz = GetNbinsZ() + 2;
834 if (fDimension < 2) ncellsy = 1;
835 if (fDimension < 3) ncellsz = 1;
836
837 // delete buffer if it is there since it will become invalid
838 if (fBuffer) BufferEmpty(1);
839
840 // - Add statistics
841 Double_t s1[10];
842 for (Int_t i = 0; i < 10; ++i) s1[i] = 0;
843 PutStats(s1);
844 SetMinimum();
845 SetMaximum();
846
847 // - Loop on bins (including underflows/overflows)
848 Int_t bin, binx, biny, binz;
849 Double_t cu=0;
850 Double_t xx[3];
851 Double_t *params = nullptr;
852 f1->InitArgs(xx,params);
853 for (binz = 0; binz < ncellsz; ++binz) {
855 for (biny = 0; biny < ncellsy; ++biny) {
857 for (binx = 0; binx < ncellsx; ++binx) {
859 if (!f1->IsInside(xx)) continue;
861 bin = binx + ncellsx * (biny + ncellsy * binz);
862 if (integral) {
864 } else {
865 cu = c1*f1->EvalPar(xx);
866 }
867 if (TF1::RejectedPoint()) continue;
868 AddBinContent(bin,cu);
869 }
870 }
871 }
872
873 return kTRUE;
874}
875
876int TH1::LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge) const
877{
878 const auto inconsistency = CheckConsistency(h1, h2);
879
881 if (useMerge)
882 Info(name, "Histograms have different dimensions - trying to use TH1::Merge");
883 else {
884 Error(name, "Histograms have different dimensions");
885 }
887 if (useMerge)
888 Info(name, "Histograms have different number of bins - trying to use TH1::Merge");
889 else {
890 Error(name, "Histograms have different number of bins");
891 }
892 } else if (inconsistency & kDifferentAxisLimits) {
893 if (useMerge)
894 Info(name, "Histograms have different axis limits - trying to use TH1::Merge");
895 else
896 Warning(name, "Histograms have different axis limits");
897 } else if (inconsistency & kDifferentBinLimits) {
898 if (useMerge)
899 Info(name, "Histograms have different bin limits - trying to use TH1::Merge");
900 else
901 Warning(name, "Histograms have different bin limits");
902 } else if (inconsistency & kDifferentLabels) {
903 // in case of different labels -
904 if (useMerge)
905 Info(name, "Histograms have different labels - trying to use TH1::Merge");
906 else
907 Info(name, "Histograms have different labels");
908 }
909
910 return inconsistency;
911}
912
913////////////////////////////////////////////////////////////////////////////////
914/// Performs the operation: `this = this + c1*h1`
915/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
916///
917/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
918/// if not already set.
919///
920/// Note also that adding histogram with labels is not supported, histogram will be
921/// added merging them by bin number independently of the labels.
922/// For adding histogram with labels one should use TH1::Merge
923///
924/// SPECIAL CASE (Average/Efficiency histograms)
925/// For histograms representing averages or efficiencies, one should compute the average
926/// of the two histograms and not the sum. One can mark a histogram to be an average
927/// histogram by setting its bit kIsAverage with
928/// myhist.SetBit(TH1::kIsAverage);
929/// Note that the two histograms must have their kIsAverage bit set
930///
931/// IMPORTANT NOTE1: If you intend to use the errors of this histogram later
932/// you should call Sumw2 before making this operation.
933/// This is particularly important if you fit the histogram after TH1::Add
934///
935/// IMPORTANT NOTE2: if h1 has a normalisation factor, the normalisation factor
936/// is used , ie this = this + c1*factor*h1
937/// Use the other TH1::Add function if you do not want this feature
938///
939/// IMPORTANT NOTE3: You should be careful about the statistics of the
940/// returned histogram, whose statistics may be binned or unbinned,
941/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
942/// and whether TH1::ResetStats has been called on either this or h1.
943/// See TH1::GetStats.
944///
945/// The function return kFALSE if the Add operation failed
946
948{
949 if (!h1) {
950 Error("Add","Attempt to add a non-existing histogram");
951 return kFALSE;
952 }
953
954 // delete buffer if it is there since it will become invalid
955 if (fBuffer) BufferEmpty(1);
956
957 bool useMerge = false;
958 const bool considerMerge = (c1 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
959 const auto inconsistency = LoggedInconsistency("Add", this, h1, considerMerge);
960 // If there is a bad inconsistency and we can't even consider merging, just give up
962 return false;
963 }
964 // If there is an inconsistency, we try to use merging
967 }
968
969 if (useMerge) {
970 TList l;
971 l.Add(const_cast<TH1*>(h1));
972 auto iret = Merge(&l);
973 return (iret >= 0);
974 }
975
976 // Create Sumw2 if h1 has Sumw2 set
977 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
978
979 // - Add statistics
980 Double_t entries = TMath::Abs( GetEntries() + c1 * h1->GetEntries() );
981
982 // statistics can be preserved only in case of positive coefficients
983 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
984 Bool_t resetStats = (c1 < 0);
985 Double_t s1[kNstat] = {0};
986 Double_t s2[kNstat] = {0};
987 if (!resetStats) {
988 // need to initialize to zero s1 and s2 since
989 // GetStats fills only used elements depending on dimension and type
990 GetStats(s1);
991 h1->GetStats(s2);
992 }
993
994 SetMinimum();
995 SetMaximum();
996
997 // - Loop on bins (including underflows/overflows)
998 Double_t factor = 1;
999 if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();
1000 Double_t c1sq = c1 * c1;
1001 Double_t factsq = factor * factor;
1002
1003 for (Int_t bin = 0; bin < fNcells; ++bin) {
1004 //special case where histograms have the kIsAverage bit set
1005 if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
1007 Double_t y2 = this->RetrieveBinContent(bin);
1010 Double_t w1 = 1., w2 = 1.;
1011
1012 // consider all special cases when bin errors are zero
1013 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1014 if (e1sq) w1 = 1. / e1sq;
1015 else if (h1->fSumw2.fN) {
1016 w1 = 1.E200; // use an arbitrary huge value
1017 if (y1 == 0) {
1018 // use an estimated error from the global histogram scale
1019 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1020 w1 = 1./(sf*sf);
1021 }
1022 }
1023 if (e2sq) w2 = 1. / e2sq;
1024 else if (fSumw2.fN) {
1025 w2 = 1.E200; // use an arbitrary huge value
1026 if (y2 == 0) {
1027 // use an estimated error from the global histogram scale
1028 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1029 w2 = 1./(sf*sf);
1030 }
1031 }
1032
1033 double y = (w1*y1 + w2*y2)/(w1 + w2);
1034 UpdateBinContent(bin, y);
1035 if (fSumw2.fN) {
1036 double err2 = 1./(w1 + w2);
1037 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1038 fSumw2.fArray[bin] = err2;
1039 }
1040 } else { // normal case of addition between histograms
1041 AddBinContent(bin, c1 * factor * h1->RetrieveBinContent(bin));
1042 if (fSumw2.fN) fSumw2.fArray[bin] += c1sq * factsq * h1->GetBinErrorSqUnchecked(bin);
1043 }
1044 }
1045
1046 // update statistics (do here to avoid changes by SetBinContent)
1047 if (resetStats) {
1048 // statistics need to be reset in case coefficient are negative
1049 ResetStats();
1050 }
1051 else {
1052 for (Int_t i=0;i<kNstat;i++) {
1053 if (i == 1) s1[i] += c1*c1*s2[i];
1054 else s1[i] += c1*s2[i];
1055 }
1056 PutStats(s1);
1057 SetEntries(entries);
1058 }
1059 return kTRUE;
1060}
1061
1062////////////////////////////////////////////////////////////////////////////////
1063/// Replace contents of this histogram by the addition of h1 and h2.
1064///
1065/// `this = c1*h1 + c2*h2`
1066/// if errors are defined (see TH1::Sumw2), errors are also recalculated
1067///
1068/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
1069/// if not already set.
1070///
1071/// Note also that adding histogram with labels is not supported, histogram will be
1072/// added merging them by bin number independently of the labels.
1073/// For adding histogram ith labels one should use TH1::Merge
1074///
1075/// SPECIAL CASE (Average/Efficiency histograms)
1076/// For histograms representing averages or efficiencies, one should compute the average
1077/// of the two histograms and not the sum. One can mark a histogram to be an average
1078/// histogram by setting its bit kIsAverage with
1079/// myhist.SetBit(TH1::kIsAverage);
1080/// Note that the two histograms must have their kIsAverage bit set
1081///
1082/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
1083/// you should call Sumw2 before making this operation.
1084/// This is particularly important if you fit the histogram after TH1::Add
1085///
1086/// IMPORTANT NOTE2: You should be careful about the statistics of the
1087/// returned histogram, whose statistics may be binned or unbinned,
1088/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
1089/// and whether TH1::ResetStats has been called on either this or h1.
1090/// See TH1::GetStats.
1091///
1092/// ANOTHER SPECIAL CASE : h1 = h2 and c2 < 0
1093/// do a scaling this = c1 * h1 / (bin Volume)
1094///
1095/// The function returns kFALSE if the Add operation failed
1096
1098{
1099
1100 if (!h1 || !h2) {
1101 Error("Add","Attempt to add a non-existing histogram");
1102 return kFALSE;
1103 }
1104
1105 // delete buffer if it is there since it will become invalid
1106 if (fBuffer) BufferEmpty(1);
1107
1109 if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
1110
1111 if (h1 != h2) {
1112 bool useMerge = false;
1113 const bool considerMerge = (c1 == 1. && c2 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
1114
1115 // We can combine inconsistencies like this, since they are ordered and a
1116 // higher inconsistency is worse
1117 auto const inconsistency = std::max(LoggedInconsistency("Add", this, h1, considerMerge),
1118 LoggedInconsistency("Add", h1, h2, considerMerge));
1119
1120 // If there is a bad inconsistency and we can't even consider merging, just give up
1122 return false;
1123 }
1124 // If there is an inconsistency, we try to use merging
1127 }
1128
1129 if (useMerge) {
1130 TList l;
1131 // why TList takes non-const pointers ????
1132 l.Add(const_cast<TH1*>(h1));
1133 l.Add(const_cast<TH1*>(h2));
1134 Reset("ICE");
1135 auto iret = Merge(&l);
1136 return (iret >= 0);
1137 }
1138 }
1139
1140 // Create Sumw2 if h1 or h2 have Sumw2 set
1141 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
1142
1143 // - Add statistics
1144 Double_t nEntries = TMath::Abs( c1*h1->GetEntries() + c2*h2->GetEntries() );
1145
1146 // TODO remove
1147 // statistics can be preserved only in case of positive coefficients
1148 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1149 // also in case of scaling with the width we cannot preserve the statistics
1150 Double_t s1[kNstat] = {0};
1151 Double_t s2[kNstat] = {0};
1153
1154
1155 Bool_t resetStats = (c1*c2 < 0) || normWidth;
1156 if (!resetStats) {
1157 // need to initialize to zero s1 and s2 since
1158 // GetStats fills only used elements depending on dimension and type
1159 h1->GetStats(s1);
1160 h2->GetStats(s2);
1161 for (Int_t i=0;i<kNstat;i++) {
1162 if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
1163 //else s3[i] = TMath::Abs(c1)*s1[i] + TMath::Abs(c2)*s2[i];
1164 else s3[i] = c1*s1[i] + c2*s2[i];
1165 }
1166 }
1167
1168 SetMinimum();
1169 SetMaximum();
1170
1171 if (normWidth) { // DEPRECATED CASE: belongs to fitting / drawing modules
1172
1173 Int_t nbinsx = GetNbinsX() + 2; // normal bins + underflow, overflow
1174 Int_t nbinsy = GetNbinsY() + 2;
1175 Int_t nbinsz = GetNbinsZ() + 2;
1176
1177 if (fDimension < 2) nbinsy = 1;
1178 if (fDimension < 3) nbinsz = 1;
1179
1180 Int_t bin, binx, biny, binz;
1181 for (binz = 0; binz < nbinsz; ++binz) {
1183 for (biny = 0; biny < nbinsy; ++biny) {
1185 for (binx = 0; binx < nbinsx; ++binx) {
1187 bin = GetBin(binx, biny, binz);
1188 Double_t w = wx*wy*wz;
1189 UpdateBinContent(bin, c1 * h1->RetrieveBinContent(bin) / w);
1190 if (fSumw2.fN) {
1191 Double_t e1 = h1->GetBinError(bin)/w;
1192 fSumw2.fArray[bin] = c1*c1*e1*e1;
1193 }
1194 }
1195 }
1196 }
1197 } else if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
1198 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
1199 // special case where histograms have the kIsAverage bit set
1201 Double_t y2 = h2->RetrieveBinContent(i);
1203 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
1204 Double_t w1 = 1., w2 = 1.;
1205
1206 // consider all special cases when bin errors are zero
1207 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1208 if (e1sq) w1 = 1./ e1sq;
1209 else if (h1->fSumw2.fN) {
1210 w1 = 1.E200; // use an arbitrary huge value
1211 if (y1 == 0 ) { // use an estimated error from the global histogram scale
1212 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1213 w1 = 1./(sf*sf);
1214 }
1215 }
1216 if (e2sq) w2 = 1./ e2sq;
1217 else if (h2->fSumw2.fN) {
1218 w2 = 1.E200; // use an arbitrary huge value
1219 if (y2 == 0) { // use an estimated error from the global histogram scale
1220 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1221 w2 = 1./(sf*sf);
1222 }
1223 }
1224
1225 double y = (w1*y1 + w2*y2)/(w1 + w2);
1226 UpdateBinContent(i, y);
1227 if (fSumw2.fN) {
1228 double err2 = 1./(w1 + w2);
1229 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1230 fSumw2.fArray[i] = err2;
1231 }
1232 }
1233 } else { // case of simple histogram addition
1234 Double_t c1sq = c1 * c1;
1235 Double_t c2sq = c2 * c2;
1236 for (Int_t i = 0; i < fNcells; ++i) { // Loop on cells (bins including underflows/overflows)
1237 UpdateBinContent(i, c1 * h1->RetrieveBinContent(i) + c2 * h2->RetrieveBinContent(i));
1238 if (fSumw2.fN) {
1239 fSumw2.fArray[i] = c1sq * h1->GetBinErrorSqUnchecked(i) + c2sq * h2->GetBinErrorSqUnchecked(i);
1240 }
1241 }
1242 }
1243
1244 if (resetStats) {
1245 // statistics need to be reset in case coefficient are negative
1246 ResetStats();
1247 }
1248 else {
1249 // update statistics (do here to avoid changes by SetBinContent) FIXME remove???
1250 PutStats(s3);
1252 }
1253
1254 return kTRUE;
1255}
1256
1257////////////////////////////////////////////////////////////////////////////////
1258/// Sets the flag controlling the automatic add of histograms in memory
1259///
1260/// By default (fAddDirectory = kTRUE), histograms are automatically added
1261/// to the list of objects in memory.
1262/// Note that one histogram can be removed from its support directory
1263/// by calling h->SetDirectory(nullptr) or h->SetDirectory(dir) to add it
1264/// to the list of objects in the directory dir.
1265///
1266/// NOTE that this is a static function. To call it, use;
1267/// TH1::AddDirectory
1268
1270{
1271 fgAddDirectory = add;
1272}
1273
1274////////////////////////////////////////////////////////////////////////////////
1275/// Auxiliary function to get the power of 2 next (larger) or previous (smaller)
1276/// a given x
1277///
1278/// next = kTRUE : next larger
1279/// next = kFALSE : previous smaller
1280///
1281/// Used by the autobin power of 2 algorithm
1282
1284{
1285 Int_t nn;
1286 Double_t f2 = std::frexp(x, &nn);
1287 return ((next && x > 0.) || (!next && x <= 0.)) ? std::ldexp(std::copysign(1., f2), nn)
1288 : std::ldexp(std::copysign(1., f2), --nn);
1289}
1290
1291////////////////////////////////////////////////////////////////////////////////
1292/// Auxiliary function to get the next power of 2 integer value larger then n
1293///
1294/// Used by the autobin power of 2 algorithm
1295
1297{
1298 Int_t nn;
1299 Double_t f2 = std::frexp(n, &nn);
1300 if (TMath::Abs(f2 - .5) > 0.001)
1301 return (Int_t)std::ldexp(1., nn);
1302 return n;
1303}
1304
1305////////////////////////////////////////////////////////////////////////////////
1306/// Buffer-based estimate of the histogram range using the power of 2 algorithm.
1307///
1308/// Used by the autobin power of 2 algorithm.
1309///
1310/// Works on arguments (min and max from fBuffer) and internal inputs: fXmin,
1311/// fXmax, NBinsX (from fXaxis), ...
1312/// Result save internally in fXaxis.
1313///
1314/// Overloaded by TH2 and TH3.
1315///
1316/// Return -1 if internal inputs are inconsistent, 0 otherwise.
1317
1319{
1320 // We need meaningful raw limits
1321 if (xmi >= xma)
1322 return -1;
1323
1324 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this, xmi, xma);
1327
1328 // Now adjust
1329 if (TMath::Abs(xhma) > TMath::Abs(xhmi)) {
1330 // Start from the upper limit
1333 } else {
1334 // Start from the lower limit
1337 }
1338
1339 // Round the bins to the next power of 2; take into account the possible inflation
1340 // of the range
1341 Double_t rr = (xhma - xhmi) / (xma - xmi);
1343
1344 // Adjust using the same bin width and offsets
1345 Double_t bw = (xhma - xhmi) / nb;
1346 // Bins to left free on each side
1347 Double_t autoside = gEnv->GetValue("Hist.Binning.Auto.Side", 0.05);
1348 Int_t nbside = (Int_t)(nb * autoside);
1349
1350 // Side up
1351 Int_t nbup = (xhma - xma) / bw;
1352 if (nbup % 2 != 0)
1353 nbup++; // Must be even
1354 if (nbup != nbside) {
1355 // Accounts also for both case: larger or smaller
1356 xhma -= bw * (nbup - nbside);
1357 nb -= (nbup - nbside);
1358 }
1359
1360 // Side low
1361 Int_t nblw = (xmi - xhmi) / bw;
1362 if (nblw % 2 != 0)
1363 nblw++; // Must be even
1364 if (nblw != nbside) {
1365 // Accounts also for both case: larger or smaller
1366 xhmi += bw * (nblw - nbside);
1367 nb -= (nblw - nbside);
1368 }
1369
1370 // Set everything and project
1371 SetBins(nb, xhmi, xhma);
1372
1373 // Done
1374 return 0;
1375}
1376
1377/// Fill histogram with all entries in the buffer.
1378///
1379/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
1380/// - action = 0 histogram is reset and filled from the buffer. When the histogram is filled from the
1381/// buffer the value fBuffer[0] is set to a negative number (= - number of entries)
1382/// When calling with action == 0 the histogram is NOT refilled when fBuffer[0] is < 0
1383/// While when calling with action = -1 the histogram is reset and ALWAYS refilled independently if
1384/// the histogram was filled before. This is needed when drawing the histogram
1385/// - action = 1 histogram is filled and buffer is deleted
1386/// The buffer is automatically deleted when filling the histogram and the entries is
1387/// larger than the buffer size
1388
1390{
1391 // do we need to compute the bin size?
1392 if (!fBuffer) return 0;
1394
1395 // nbentries correspond to the number of entries of histogram
1396
1397 if (nbentries == 0) {
1398 // if action is 1 we delete the buffer
1399 // this will avoid infinite recursion
1400 if (action > 0) {
1401 delete [] fBuffer;
1402 fBuffer = nullptr;
1403 fBufferSize = 0;
1404 }
1405 return 0;
1406 }
1407 if (nbentries < 0 && action == 0) return 0; // case histogram has been already filled from the buffer
1408
1409 Double_t *buffer = fBuffer;
1410 if (nbentries < 0) {
1412 // a reset might call BufferEmpty() giving an infinite recursion
1413 // Protect it by setting fBuffer = nullptr
1414 fBuffer = nullptr;
1415 //do not reset the list of functions
1416 Reset("ICES");
1417 fBuffer = buffer;
1418 }
1419 if (CanExtendAllAxes() || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
1420 //find min, max of entries in buffer
1423 for (Int_t i=0;i<nbentries;i++) {
1424 Double_t x = fBuffer[2*i+2];
1425 // skip infinity or NaN values
1426 if (!std::isfinite(x)) continue;
1427 if (x < xmin) xmin = x;
1428 if (x > xmax) xmax = x;
1429 }
1430 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
1431 Int_t rc = -1;
1433 if ((rc = AutoP2FindLimits(xmin, xmax)) < 0)
1434 Warning("BufferEmpty",
1435 "inconsistency found by power-of-2 autobin algorithm: fallback to standard method");
1436 }
1437 if (rc < 0)
1438 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this, xmin, xmax);
1439 } else {
1440 fBuffer = nullptr;
1443 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax, &fXaxis);
1444 fBuffer = buffer;
1445 fBufferSize = keep;
1446 }
1447 }
1448
1449 // call DoFillN which will not put entries in the buffer as FillN does
1450 // set fBuffer to zero to avoid re-emptying the buffer from functions called
1451 // by DoFillN (e.g Sumw2)
1452 buffer = fBuffer; fBuffer = nullptr;
1453 DoFillN(nbentries,&buffer[2],&buffer[1],2);
1454 fBuffer = buffer;
1455
1456 // if action == 1 - delete the buffer
1457 if (action > 0) {
1458 delete [] fBuffer;
1459 fBuffer = nullptr;
1460 fBufferSize = 0;
1461 } else {
1462 // if number of entries is consistent with buffer - set it negative to avoid
1463 // refilling the histogram every time BufferEmpty(0) is called
1464 // In case it is not consistent, by setting fBuffer[0]=0 is like resetting the buffer
1465 // (it will not be used anymore the next time BufferEmpty is called)
1466 if (nbentries == (Int_t)fEntries)
1467 fBuffer[0] = -nbentries;
1468 else
1469 fBuffer[0] = 0;
1470 }
1471 return nbentries;
1472}
1473
1474////////////////////////////////////////////////////////////////////////////////
1475/// accumulate arguments in buffer. When buffer is full, empty the buffer
1476///
1477/// - `fBuffer[0]` = number of entries in buffer
1478/// - `fBuffer[1]` = w of first entry
1479/// - `fBuffer[2]` = x of first entry
1480
1482{
1483 if (!fBuffer) return -2;
1485
1486
1487 if (nbentries < 0) {
1488 // reset nbentries to a positive value so next time BufferEmpty() is called
1489 // the histogram will be refilled
1491 fBuffer[0] = nbentries;
1492 if (fEntries > 0) {
1493 // set fBuffer to zero to avoid calling BufferEmpty in Reset
1494 Double_t *buffer = fBuffer; fBuffer=nullptr;
1495 Reset("ICES"); // do not reset list of functions
1496 fBuffer = buffer;
1497 }
1498 }
1499 if (2*nbentries+2 >= fBufferSize) {
1500 BufferEmpty(1);
1501 if (!fBuffer)
1502 // to avoid infinite recursion Fill->BufferFill->Fill
1503 return Fill(x,w);
1504 // this cannot happen
1505 R__ASSERT(0);
1506 }
1507 fBuffer[2*nbentries+1] = w;
1508 fBuffer[2*nbentries+2] = x;
1509 fBuffer[0] += 1;
1510 return -2;
1511}
1512
1513////////////////////////////////////////////////////////////////////////////////
1514/// Check bin limits.
1515
1516bool TH1::CheckBinLimits(const TAxis* a1, const TAxis * a2)
1517{
1518 const TArrayD * h1Array = a1->GetXbins();
1519 const TArrayD * h2Array = a2->GetXbins();
1520 Int_t fN = h1Array->fN;
1521 if ( fN != 0 ) {
1522 if ( h2Array->fN != fN ) {
1523 return false;
1524 }
1525 else {
1526 for ( int i = 0; i < fN; ++i ) {
1527 // for i==fN (nbin+1) a->GetBinWidth() returns last bin width
1528 // we do not need to exclude that case
1529 double binWidth = a1->GetBinWidth(i);
1530 if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), binWidth*1E-10 ) ) {
1531 return false;
1532 }
1533 }
1534 }
1535 }
1536
1537 return true;
1538}
1539
1540////////////////////////////////////////////////////////////////////////////////
1541/// Check that axis have same labels.
1542
1543bool TH1::CheckBinLabels(const TAxis* a1, const TAxis * a2)
1544{
1545 THashList *l1 = a1->GetLabels();
1546 THashList *l2 = a2->GetLabels();
1547
1548 if (!l1 && !l2 )
1549 return true;
1550 if (!l1 || !l2 ) {
1551 return false;
1552 }
1553 // check now labels sizes are the same
1554 if (l1->GetSize() != l2->GetSize() ) {
1555 return false;
1556 }
1557 for (int i = 1; i <= a1->GetNbins(); ++i) {
1558 TString label1 = a1->GetBinLabel(i);
1559 TString label2 = a2->GetBinLabel(i);
1560 if (label1 != label2) {
1561 return false;
1562 }
1563 }
1564
1565 return true;
1566}
1567
1568////////////////////////////////////////////////////////////////////////////////
1569/// Check that the axis limits of the histograms are the same.
1570/// If a first and last bin is passed the axis is compared between the given range
1571
1572bool TH1::CheckAxisLimits(const TAxis *a1, const TAxis *a2 )
1573{
1574 double firstBin = a1->GetBinWidth(1);
1575 double lastBin = a1->GetBinWidth( a1->GetNbins() );
1576 if ( ! TMath::AreEqualAbs(a1->GetXmin(), a2->GetXmin(), firstBin* 1.E-10) ||
1577 ! TMath::AreEqualAbs(a1->GetXmax(), a2->GetXmax(), lastBin*1.E-10) ) {
1578 return false;
1579 }
1580 return true;
1581}
1582
1583////////////////////////////////////////////////////////////////////////////////
1584/// Check that the axis are the same
1585
1586bool TH1::CheckEqualAxes(const TAxis *a1, const TAxis *a2 )
1587{
1588 if (a1->GetNbins() != a2->GetNbins() ) {
1589 ::Info("CheckEqualAxes","Axes have different number of bins : nbin1 = %d nbin2 = %d",a1->GetNbins(),a2->GetNbins() );
1590 return false;
1591 }
1592 if(!CheckAxisLimits(a1,a2)) {
1593 ::Info("CheckEqualAxes","Axes have different limits");
1594 return false;
1595 }
1596 if(!CheckBinLimits(a1,a2)) {
1597 ::Info("CheckEqualAxes","Axes have different bin limits");
1598 return false;
1599 }
1600
1601 // check labels
1602 if(!CheckBinLabels(a1,a2)) {
1603 ::Info("CheckEqualAxes","Axes have different labels");
1604 return false;
1605 }
1606
1607 return true;
1608}
1609
1610////////////////////////////////////////////////////////////////////////////////
1611/// Check that two sub axis are the same.
1612/// The limits are defined by first bin and last bin
1613/// N.B. no check is done in this case for variable bins
1614
1616{
1617 // By default is assumed that no bins are given for the second axis
1619 Double_t xmin1 = a1->GetBinLowEdge(firstBin1);
1620 Double_t xmax1 = a1->GetBinUpEdge(lastBin1);
1621
1622 Int_t nbins2 = a2->GetNbins();
1623 Double_t xmin2 = a2->GetXmin();
1624 Double_t xmax2 = a2->GetXmax();
1625
1626 if (firstBin2 < lastBin2) {
1627 // in this case assume no bins are given for the second axis
1629 xmin2 = a1->GetBinLowEdge(firstBin1);
1630 xmax2 = a1->GetBinUpEdge(lastBin1);
1631 }
1632
1633 if (nbins1 != nbins2 ) {
1634 ::Info("CheckConsistentSubAxes","Axes have different number of bins");
1635 return false;
1636 }
1637
1638 Double_t firstBin = a1->GetBinWidth(firstBin1);
1639 Double_t lastBin = a1->GetBinWidth(lastBin1);
1640 if ( ! TMath::AreEqualAbs(xmin1,xmin2,1.E-10 * firstBin) ||
1641 ! TMath::AreEqualAbs(xmax1,xmax2,1.E-10 * lastBin) ) {
1642 ::Info("CheckConsistentSubAxes","Axes have different limits");
1643 return false;
1644 }
1645
1646 return true;
1647}
1648
1649////////////////////////////////////////////////////////////////////////////////
1650/// Check histogram compatibility.
1651/// The returned integer is part of EInconsistencyBits
1652/// The value 0 means that the histograms are compatible
1653
1655{
1656 if (h1 == h2) return kFullyConsistent;
1657
1658 if (h1->GetDimension() != h2->GetDimension() ) {
1659 return kDifferentDimensions;
1660 }
1661 Int_t dim = h1->GetDimension();
1662
1663 // returns kTRUE if number of bins and bin limits are identical
1664 Int_t nbinsx = h1->GetNbinsX();
1665 Int_t nbinsy = h1->GetNbinsY();
1666 Int_t nbinsz = h1->GetNbinsZ();
1667
1668 // Check whether the histograms have the same number of bins.
1669 if (nbinsx != h2->GetNbinsX() ||
1670 (dim > 1 && nbinsy != h2->GetNbinsY()) ||
1671 (dim > 2 && nbinsz != h2->GetNbinsZ()) ) {
1673 }
1674
1675 bool ret = true;
1676
1677 // check axis limits
1678 ret &= CheckAxisLimits(h1->GetXaxis(), h2->GetXaxis());
1679 if (dim > 1) ret &= CheckAxisLimits(h1->GetYaxis(), h2->GetYaxis());
1680 if (dim > 2) ret &= CheckAxisLimits(h1->GetZaxis(), h2->GetZaxis());
1681 if (!ret) return kDifferentAxisLimits;
1682
1683 // check bin limits
1684 ret &= CheckBinLimits(h1->GetXaxis(), h2->GetXaxis());
1685 if (dim > 1) ret &= CheckBinLimits(h1->GetYaxis(), h2->GetYaxis());
1686 if (dim > 2) ret &= CheckBinLimits(h1->GetZaxis(), h2->GetZaxis());
1687 if (!ret) return kDifferentBinLimits;
1688
1689 // check labels if histograms are both not empty
1690 if ( !h1->IsEmpty() && !h2->IsEmpty() ) {
1691 ret &= CheckBinLabels(h1->GetXaxis(), h2->GetXaxis());
1692 if (dim > 1) ret &= CheckBinLabels(h1->GetYaxis(), h2->GetYaxis());
1693 if (dim > 2) ret &= CheckBinLabels(h1->GetZaxis(), h2->GetZaxis());
1694 if (!ret) return kDifferentLabels;
1695 }
1696
1697 return kFullyConsistent;
1698}
1699
1700////////////////////////////////////////////////////////////////////////////////
1701/// \f$ \chi^{2} \f$ test for comparing weighted and unweighted histograms.
1702///
1703/// Compares the histograms' adjusted (normalized) residuals.
1704/// Function: Returns p-value. Other return values are specified by the 3rd parameter
1705///
1706/// \param[in] h2 the second histogram
1707/// \param[in] option
1708/// - "UU" = experiment experiment comparison (unweighted-unweighted)
1709/// - "UW" = experiment MC comparison (unweighted-weighted). Note that
1710/// the first histogram should be unweighted
1711/// - "WW" = MC MC comparison (weighted-weighted)
1712/// - "NORM" = to be used when one or both of the histograms is scaled
1713/// but the histogram originally was unweighted
1714/// - by default underflows and overflows are not included:
1715/// * "OF" = overflows included
1716/// * "UF" = underflows included
1717/// - "P" = print chi2, ndf, p_value, igood
1718/// - "CHI2" = returns chi2 instead of p-value
1719/// - "CHI2/NDF" = returns \f$ \chi^{2} \f$/ndf
1720/// \param[in] res not empty - computes normalized residuals and returns them in this array
1721///
1722/// The current implementation is based on the papers \f$ \chi^{2} \f$ test for comparison
1723/// of weighted and unweighted histograms" in Proceedings of PHYSTAT05 and
1724/// "Comparison weighted and unweighted histograms", arXiv:physics/0605123
1725/// by N.Gagunashvili. This function has been implemented by Daniel Haertl in August 2006.
1726///
1727/// #### Introduction:
1728///
1729/// A frequently used technique in data analysis is the comparison of
1730/// histograms. First suggested by Pearson [1] the \f$ \chi^{2} \f$ test of
1731/// homogeneity is used widely for comparing usual (unweighted) histograms.
1732/// This paper describes the implementation modified \f$ \chi^{2} \f$ tests
1733/// for comparison of weighted and unweighted histograms and two weighted
1734/// histograms [2] as well as usual Pearson's \f$ \chi^{2} \f$ test for
1735/// comparison two usual (unweighted) histograms.
1736///
1737/// #### Overview:
1738///
1739/// Comparison of two histograms expect hypotheses that two histograms
1740/// represent identical distributions. To make a decision p-value should
1741/// be calculated. The hypotheses of identity is rejected if the p-value is
1742/// lower then some significance level. Traditionally significance levels
1743/// 0.1, 0.05 and 0.01 are used. The comparison procedure should include an
1744/// analysis of the residuals which is often helpful in identifying the
1745/// bins of histograms responsible for a significant overall \f$ \chi^{2} \f$ value.
1746/// Residuals are the difference between bin contents and expected bin
1747/// contents. Most convenient for analysis are the normalized residuals. If
1748/// hypotheses of identity are valid then normalized residuals are
1749/// approximately independent and identically distributed random variables
1750/// having N(0,1) distribution. Analysis of residuals expect test of above
1751/// mentioned properties of residuals. Notice that indirectly the analysis
1752/// of residuals increase the power of \f$ \chi^{2} \f$ test.
1753///
1754/// #### Methods of comparison:
1755///
1756/// \f$ \chi^{2} \f$ test for comparison two (unweighted) histograms:
1757/// Let us consider two histograms with the same binning and the number
1758/// of bins equal to r. Let us denote the number of events in the ith bin
1759/// in the first histogram as ni and as mi in the second one. The total
1760/// number of events in the first histogram is equal to:
1761/// \f[
1762/// N = \sum_{i=1}^{r} n_{i}
1763/// \f]
1764/// and
1765/// \f[
1766/// M = \sum_{i=1}^{r} m_{i}
1767/// \f]
1768/// in the second histogram. The hypothesis of identity (homogeneity) [3]
1769/// is that the two histograms represent random values with identical
1770/// distributions. It is equivalent that there exist r constants p1,...,pr,
1771/// such that
1772/// \f[
1773///\sum_{i=1}^{r} p_{i}=1
1774/// \f]
1775/// and the probability of belonging to the ith bin for some measured value
1776/// in both experiments is equal to pi. The number of events in the ith
1777/// bin is a random variable with a distribution approximated by a Poisson
1778/// probability distribution
1779/// \f[
1780///\frac{e^{-Np_{i}}(Np_{i})^{n_{i}}}{n_{i}!}
1781/// \f]
1782///for the first histogram and with distribution
1783/// \f[
1784///\frac{e^{-Mp_{i}}(Mp_{i})^{m_{i}}}{m_{i}!}
1785/// \f]
1786/// for the second histogram. If the hypothesis of homogeneity is valid,
1787/// then the maximum likelihood estimator of pi, i=1,...,r, is
1788/// \f[
1789///\hat{p}_{i}= \frac{n_{i}+m_{i}}{N+M}
1790/// \f]
1791/// and then
1792/// \f[
1793/// 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}}
1794/// \f]
1795/// has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [3].
1796/// The comparison procedure can include an analysis of the residuals which
1797/// is often helpful in identifying the bins of histograms responsible for
1798/// a significant overall \f$ \chi^{2} \f$ value. Most convenient for
1799/// analysis are the adjusted (normalized) residuals [4]
1800/// \f[
1801/// 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))}}
1802/// \f]
1803/// If hypotheses of homogeneity are valid then residuals ri are
1804/// approximately independent and identically distributed random variables
1805/// having N(0,1) distribution. The application of the \f$ \chi^{2} \f$ test has
1806/// restrictions related to the value of the expected frequencies Npi,
1807/// Mpi, i=1,...,r. A conservative rule formulated in [5] is that all the
1808/// expectations must be 1 or greater for both histograms. In practical
1809/// cases when expected frequencies are not known the estimated expected
1810/// frequencies \f$ M\hat{p}_{i}, N\hat{p}_{i}, i=1,...,r \f$ can be used.
1811///
1812/// #### Unweighted and weighted histograms comparison:
1813///
1814/// A simple modification of the ideas described above can be used for the
1815/// comparison of the usual (unweighted) and weighted histograms. Let us
1816/// denote the number of events in the ith bin in the unweighted
1817/// histogram as ni and the common weight of events in the ith bin of the
1818/// weighted histogram as wi. The total number of events in the
1819/// unweighted histogram is equal to
1820///\f[
1821/// N = \sum_{i=1}^{r} n_{i}
1822///\f]
1823/// and the total weight of events in the weighted histogram is equal to
1824///\f[
1825/// W = \sum_{i=1}^{r} w_{i}
1826///\f]
1827/// Let us formulate the hypothesis of identity of an unweighted histogram
1828/// to a weighted histogram so that there exist r constants p1,...,pr, such
1829/// that
1830///\f[
1831/// \sum_{i=1}^{r} p_{i} = 1
1832///\f]
1833/// for the unweighted histogram. The weight wi is a random variable with a
1834/// distribution approximated by the normal probability distribution
1835/// \f$ N(Wp_{i},\sigma_{i}^{2}) \f$ where \f$ \sigma_{i}^{2} \f$ is the variance of the weight wi.
1836/// If we replace the variance \f$ \sigma_{i}^{2} \f$
1837/// with estimate \f$ s_{i}^{2} \f$ (sum of squares of weights of
1838/// events in the ith bin) and the hypothesis of identity is valid, then the
1839/// maximum likelihood estimator of pi,i=1,...,r, is
1840///\f[
1841/// \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}}
1842///\f]
1843/// We may then use the test statistic
1844///\f[
1845/// 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}}
1846///\f]
1847/// and it has approximately a \f$ \sigma^{2}_{(r-1)} \f$ distribution [2]. This test, as well
1848/// as the original one [3], has a restriction on the expected frequencies. The
1849/// expected frequencies recommended for the weighted histogram is more than 25.
1850/// The value of the minimal expected frequency can be decreased down to 10 for
1851/// the case when the weights of the events are close to constant. In the case
1852/// of a weighted histogram if the number of events is unknown, then we can
1853/// apply this recommendation for the equivalent number of events as
1854///\f[
1855/// n_{i}^{equiv} = \frac{ w_{i}^{2} }{ s_{i}^{2} }
1856///\f]
1857/// The minimal expected frequency for an unweighted histogram must be 1. Notice
1858/// that any usual (unweighted) histogram can be considered as a weighted
1859/// histogram with events that have constant weights equal to 1.
1860/// The variance \f$ z_{i}^{2} \f$ of the difference between the weight wi
1861/// and the estimated expectation value of the weight is approximately equal to:
1862///\f[
1863/// 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}
1864///\f]
1865/// The residuals
1866///\f[
1867/// r_{i} = \frac{w_{i}-W\hat{p}_{i}}{z_{i}}
1868///\f]
1869/// have approximately a normal distribution with mean equal to 0 and standard
1870/// deviation equal to 1.
1871///
1872/// #### Two weighted histograms comparison:
1873///
1874/// Let us denote the common weight of events of the ith bin in the first
1875/// histogram as w1i and as w2i in the second one. The total weight of events
1876/// in the first histogram is equal to
1877///\f[
1878/// W_{1} = \sum_{i=1}^{r} w_{1i}
1879///\f]
1880/// and
1881///\f[
1882/// W_{2} = \sum_{i=1}^{r} w_{2i}
1883///\f]
1884/// in the second histogram. Let us formulate the hypothesis of identity of
1885/// weighted histograms so that there exist r constants p1,...,pr, such that
1886///\f[
1887/// \sum_{i=1}^{r} p_{i} = 1
1888///\f]
1889/// and also expectation value of weight w1i equal to W1pi and expectation value
1890/// of weight w2i equal to W2pi. Weights in both the histograms are random
1891/// variables with distributions which can be approximated by a normal
1892/// probability distribution \f$ N(W_{1}p_{i},\sigma_{1i}^{2}) \f$ for the first histogram
1893/// and by a distribution \f$ N(W_{2}p_{i},\sigma_{2i}^{2}) \f$ for the second.
1894/// Here \f$ \sigma_{1i}^{2} \f$ and \f$ \sigma_{2i}^{2} \f$ are the variances
1895/// of w1i and w2i with estimators \f$ s_{1i}^{2} \f$ and \f$ s_{2i}^{2} \f$ respectively.
1896/// If the hypothesis of identity is valid, then the maximum likelihood and
1897/// Least Square Method estimator of pi,i=1,...,r, is
1898///\f[
1899/// \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}}
1900///\f]
1901/// We may then use the test statistic
1902///\f[
1903/// 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}}
1904///\f]
1905/// and it has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [2].
1906/// The normalized or studentised residuals [6]
1907///\f[
1908/// 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})}}}
1909///\f]
1910/// have approximately a normal distribution with mean equal to 0 and standard
1911/// deviation 1. A recommended minimal expected frequency is equal to 10 for
1912/// the proposed test.
1913///
1914/// #### Numerical examples:
1915///
1916/// The method described herein is now illustrated with an example.
1917/// We take a distribution
1918///\f[
1919/// \phi(x) = \frac{2}{(x-10)^{2}+1} + \frac{1}{(x-14)^{2}+1} (1)
1920///\f]
1921/// defined on the interval [4,16]. Events distributed according to the formula
1922/// (1) are simulated to create the unweighted histogram. Uniformly distributed
1923/// events are simulated for the weighted histogram with weights calculated by
1924/// formula (1). Each histogram has the same number of bins: 20. Fig.1 shows
1925/// the result of comparison of the unweighted histogram with 200 events
1926/// (minimal expected frequency equal to one) and the weighted histogram with
1927/// 500 events (minimal expected frequency equal to 25)
1928/// Begin_Macro
1929/// ../../../tutorials/math/chi2test.C
1930/// End_Macro
1931/// Fig 1. An example of comparison of the unweighted histogram with 200 events
1932/// and the weighted histogram with 500 events:
1933/// 1. unweighted histogram;
1934/// 2. weighted histogram;
1935/// 3. normalized residuals plot;
1936/// 4. normal Q-Q plot of residuals.
1937///
1938/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1939/// 21.09 with p-value equal to 0.33, therefore the hypothesis of identity of
1940/// the two histograms can be accepted for 0.05 significant level. The behavior
1941/// of the normalized residuals plot (see Fig. 1c) and the normal Q-Q plot
1942/// (see Fig. 1d) of residuals are regular and we cannot identify the outliers
1943/// or bins with a big influence on \f$ \chi^{2} \f$.
1944///
1945/// The second example presents the same two histograms but 17 events was added
1946/// to content of bin number 15 in unweighted histogram. Fig.2 shows the result
1947/// of comparison of the unweighted histogram with 217 events (minimal expected
1948/// frequency equal to one) and the weighted histogram with 500 events (minimal
1949/// expected frequency equal to 25)
1950/// Begin_Macro
1951/// ../../../tutorials/math/chi2test.C(17)
1952/// End_Macro
1953/// Fig 2. An example of comparison of the unweighted histogram with 217 events
1954/// and the weighted histogram with 500 events:
1955/// 1. unweighted histogram;
1956/// 2. weighted histogram;
1957/// 3. normalized residuals plot;
1958/// 4. normal Q-Q plot of residuals.
1959///
1960/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1961/// 32.33 with p-value equal to 0.029, therefore the hypothesis of identity of
1962/// the two histograms is rejected for 0.05 significant level. The behavior of
1963/// the normalized residuals plot (see Fig. 2c) and the normal Q-Q plot (see
1964/// Fig. 2d) of residuals are not regular and we can identify the outlier or
1965/// bin with a big influence on \f$ \chi^{2} \f$.
1966///
1967/// #### References:
1968///
1969/// - [1] Pearson, K., 1904. On the Theory of Contingency and Its Relation to
1970/// Association and Normal Correlation. Drapers' Co. Memoirs, Biometric
1971/// Series No. 1, London.
1972/// - [2] Gagunashvili, N., 2006. \f$ \sigma^{2} \f$ test for comparison
1973/// of weighted and unweighted histograms. Statistical Problems in Particle
1974/// Physics, Astrophysics and Cosmology, Proceedings of PHYSTAT05,
1975/// Oxford, UK, 12-15 September 2005, Imperial College Press, London, 43-44.
1976/// Gagunashvili,N., Comparison of weighted and unweighted histograms,
1977/// arXiv:physics/0605123, 2006.
1978/// - [3] Cramer, H., 1946. Mathematical methods of statistics.
1979/// Princeton University Press, Princeton.
1980/// - [4] Haberman, S.J., 1973. The analysis of residuals in cross-classified tables.
1981/// Biometrics 29, 205-220.
1982/// - [5] Lewontin, R.C. and Felsenstein, J., 1965. The robustness of homogeneity
1983/// test in 2xN tables. Biometrics 21, 19-33.
1984/// - [6] Seber, G.A.F., Lee, A.J., 2003, Linear Regression Analysis.
1985/// John Wiley & Sons Inc., New York.
1986
1987Double_t TH1::Chi2Test(const TH1* h2, Option_t *option, Double_t *res) const
1988{
1989 Double_t chi2 = 0;
1990 Int_t ndf = 0, igood = 0;
1991
1992 TString opt = option;
1993 opt.ToUpper();
1994
1995 Double_t prob = Chi2TestX(h2,chi2,ndf,igood,option,res);
1996
1997 if(opt.Contains("P")) {
1998 printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
1999 }
2000 if(opt.Contains("CHI2/NDF")) {
2001 if (ndf == 0) return 0;
2002 return chi2/ndf;
2003 }
2004 if(opt.Contains("CHI2")) {
2005 return chi2;
2006 }
2007
2008 return prob;
2009}
2010
2011////////////////////////////////////////////////////////////////////////////////
2012/// The computation routine of the Chisquare test. For the method description,
2013/// see Chi2Test() function.
2014///
2015/// \return p-value
2016/// \param[in] h2 the second histogram
2017/// \param[in] option
2018/// - "UU" = experiment experiment comparison (unweighted-unweighted)
2019/// - "UW" = experiment MC comparison (unweighted-weighted). Note that the first
2020/// histogram should be unweighted
2021/// - "WW" = MC MC comparison (weighted-weighted)
2022/// - "NORM" = if one or both histograms is scaled
2023/// - "OF" = overflows included
2024/// - "UF" = underflows included
2025/// by default underflows and overflows are not included
2026/// \param[out] igood test output
2027/// - igood=0 - no problems
2028/// - For unweighted unweighted comparison
2029/// - igood=1'There is a bin in the 1st histogram with less than 1 event'
2030/// - igood=2'There is a bin in the 2nd histogram with less than 1 event'
2031/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2032/// - For unweighted weighted comparison
2033/// - igood=1'There is a bin in the 1st histogram with less then 1 event'
2034/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective number of events'
2035/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2036/// - For weighted weighted comparison
2037/// - igood=1'There is a bin in the 1st histogram with less then 10 effective
2038/// number of events'
2039/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective
2040/// number of events'
2041/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2042/// \param[out] chi2 chisquare of the test
2043/// \param[out] ndf number of degrees of freedom (important, when both histograms have the same empty bins)
2044/// \param[out] res normalized residuals for further analysis
2045
2046Double_t TH1::Chi2TestX(const TH1* h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option, Double_t *res) const
2047{
2048
2052
2053 Double_t sum1 = 0.0, sumw1 = 0.0;
2054 Double_t sum2 = 0.0, sumw2 = 0.0;
2055
2056 chi2 = 0.0;
2057 ndf = 0;
2058
2059 TString opt = option;
2060 opt.ToUpper();
2061
2062 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
2063
2064 const TAxis *xaxis1 = GetXaxis();
2065 const TAxis *xaxis2 = h2->GetXaxis();
2066 const TAxis *yaxis1 = GetYaxis();
2067 const TAxis *yaxis2 = h2->GetYaxis();
2068 const TAxis *zaxis1 = GetZaxis();
2069 const TAxis *zaxis2 = h2->GetZaxis();
2070
2071 Int_t nbinx1 = xaxis1->GetNbins();
2072 Int_t nbinx2 = xaxis2->GetNbins();
2073 Int_t nbiny1 = yaxis1->GetNbins();
2074 Int_t nbiny2 = yaxis2->GetNbins();
2075 Int_t nbinz1 = zaxis1->GetNbins();
2076 Int_t nbinz2 = zaxis2->GetNbins();
2077
2078 //check dimensions
2079 if (this->GetDimension() != h2->GetDimension() ){
2080 Error("Chi2TestX","Histograms have different dimensions.");
2081 return 0.0;
2082 }
2083
2084 //check number of channels
2085 if (nbinx1 != nbinx2) {
2086 Error("Chi2TestX","different number of x channels");
2087 }
2088 if (nbiny1 != nbiny2) {
2089 Error("Chi2TestX","different number of y channels");
2090 }
2091 if (nbinz1 != nbinz2) {
2092 Error("Chi2TestX","different number of z channels");
2093 }
2094
2095 //check for ranges
2096 i_start = j_start = k_start = 1;
2097 i_end = nbinx1;
2098 j_end = nbiny1;
2099 k_end = nbinz1;
2100
2101 if (xaxis1->TestBit(TAxis::kAxisRange)) {
2102 i_start = xaxis1->GetFirst();
2103 i_end = xaxis1->GetLast();
2104 }
2105 if (yaxis1->TestBit(TAxis::kAxisRange)) {
2106 j_start = yaxis1->GetFirst();
2107 j_end = yaxis1->GetLast();
2108 }
2109 if (zaxis1->TestBit(TAxis::kAxisRange)) {
2110 k_start = zaxis1->GetFirst();
2111 k_end = zaxis1->GetLast();
2112 }
2113
2114
2115 if (opt.Contains("OF")) {
2116 if (GetDimension() == 3) k_end = ++nbinz1;
2117 if (GetDimension() >= 2) j_end = ++nbiny1;
2118 if (GetDimension() >= 1) i_end = ++nbinx1;
2119 }
2120
2121 if (opt.Contains("UF")) {
2122 if (GetDimension() == 3) k_start = 0;
2123 if (GetDimension() >= 2) j_start = 0;
2124 if (GetDimension() >= 1) i_start = 0;
2125 }
2126
2127 ndf = (i_end - i_start + 1) * (j_end - j_start + 1) * (k_end - k_start + 1) - 1;
2128
2129 Bool_t comparisonUU = opt.Contains("UU");
2130 Bool_t comparisonUW = opt.Contains("UW");
2131 Bool_t comparisonWW = opt.Contains("WW");
2132 Bool_t scaledHistogram = opt.Contains("NORM");
2133
2134 if (scaledHistogram && !comparisonUU) {
2135 Info("Chi2TestX", "NORM option should be used together with UU option. It is ignored");
2136 }
2137
2138 // look at histo global bin content and effective entries
2139 Stat_t s[kNstat];
2140 GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2141 Double_t sumBinContent1 = s[0];
2142 Double_t effEntries1 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2143
2144 h2->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2145 Double_t sumBinContent2 = s[0];
2146 Double_t effEntries2 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2147
2148 if (!comparisonUU && !comparisonUW && !comparisonWW ) {
2149 // deduce automatically from type of histogram
2152 else comparisonUW = true;
2153 }
2154 else comparisonWW = true;
2155 }
2156 // check unweighted histogram
2157 if (comparisonUW) {
2159 Warning("Chi2TestX","First histogram is not unweighted and option UW has been requested");
2160 }
2161 }
2162 if ( (!scaledHistogram && comparisonUU) ) {
2164 Warning("Chi2TestX","Both histograms are not unweighted and option UU has been requested");
2165 }
2166 }
2167
2168
2169 //get number of events in histogram
2171 for (Int_t i = i_start; i <= i_end; ++i) {
2172 for (Int_t j = j_start; j <= j_end; ++j) {
2173 for (Int_t k = k_start; k <= k_end; ++k) {
2174
2175 Int_t bin = GetBin(i, j, k);
2176
2178 Double_t cnt2 = h2->RetrieveBinContent(bin);
2180 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2181
2182 if (e1sq > 0.0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2183 else cnt1 = 0.0;
2184
2185 if (e2sq > 0.0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2186 else cnt2 = 0.0;
2187
2188 // sum contents
2189 sum1 += cnt1;
2190 sum2 += cnt2;
2191 sumw1 += e1sq;
2192 sumw2 += e2sq;
2193 }
2194 }
2195 }
2196 if (sumw1 <= 0.0 || sumw2 <= 0.0) {
2197 Error("Chi2TestX", "Cannot use option NORM when one histogram has all zero errors");
2198 return 0.0;
2199 }
2200
2201 } else {
2202 for (Int_t i = i_start; i <= i_end; ++i) {
2203 for (Int_t j = j_start; j <= j_end; ++j) {
2204 for (Int_t k = k_start; k <= k_end; ++k) {
2205
2206 Int_t bin = GetBin(i, j, k);
2207
2208 sum1 += RetrieveBinContent(bin);
2209 sum2 += h2->RetrieveBinContent(bin);
2210
2212 if ( comparisonUW || comparisonWW ) sumw2 += h2->GetBinErrorSqUnchecked(bin);
2213 }
2214 }
2215 }
2216 }
2217 //checks that the histograms are not empty
2218 if (sum1 == 0.0 || sum2 == 0.0) {
2219 Error("Chi2TestX","one histogram is empty");
2220 return 0.0;
2221 }
2222
2223 if ( comparisonWW && ( sumw1 <= 0.0 && sumw2 <= 0.0 ) ){
2224 Error("Chi2TestX","Hist1 and Hist2 have both all zero errors\n");
2225 return 0.0;
2226 }
2227
2228 //THE TEST
2229 Int_t m = 0, n = 0;
2230 //Experiment - experiment comparison
2231 if (comparisonUU) {
2232 Int_t resIndex = 0;
2233 Double_t sum = sum1 + sum2;
2234 for (Int_t i = i_start; i <= i_end; ++i) {
2235 for (Int_t j = j_start; j <= j_end; ++j) {
2236 for (Int_t k = k_start; k <= k_end; ++k) {
2237
2238 Int_t bin = GetBin(i, j, k);
2239
2241 Double_t cnt2 = h2->RetrieveBinContent(bin);
2242
2243 if (scaledHistogram) {
2244 // scale bin value to effective bin entries
2246 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2247
2248 if (e1sq > 0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2249 else cnt1 = 0;
2250
2251 if (e2sq > 0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2252 else cnt2 = 0;
2253 }
2254
2255 if (Int_t(cnt1) == 0 && Int_t(cnt2) == 0) --ndf; // no data means one degree of freedom less
2256 else {
2257
2260 //Double_t nexp2 = binsum*sum2/sum;
2261
2262 if (res) res[resIndex] = (cnt1 - nexp1) / TMath::Sqrt(nexp1);
2263
2264 if (cnt1 < 1) ++m;
2265 if (cnt2 < 1) ++n;
2266
2267 //Habermann correction for residuals
2268 Double_t correc = (1. - sum1 / sum) * (1. - cntsum / sum);
2269 if (res) res[resIndex] /= TMath::Sqrt(correc);
2270 if (res) resIndex++;
2271 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2272 chi2 += delta * delta / cntsum;
2273 }
2274 }
2275 }
2276 }
2277 chi2 /= sum1 * sum2;
2278
2279 // flag error only when of the two histogram is zero
2280 if (m) {
2281 igood += 1;
2282 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2283 }
2284 if (n) {
2285 igood += 2;
2286 Info("Chi2TestX","There is a bin in h2 with less than 1 event.\n");
2287 }
2288
2290 return prob;
2291
2292 }
2293
2294 // unweighted - weighted comparison
2295 // case of error = 0 and content not zero is treated without problems by excluding second chi2 sum
2296 // and can be considered as a data-theory comparison
2297 if ( comparisonUW ) {
2298 Int_t resIndex = 0;
2299 for (Int_t i = i_start; i <= i_end; ++i) {
2300 for (Int_t j = j_start; j <= j_end; ++j) {
2301 for (Int_t k = k_start; k <= k_end; ++k) {
2302
2303 Int_t bin = GetBin(i, j, k);
2304
2306 Double_t cnt2 = h2->RetrieveBinContent(bin);
2307 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2308
2309 // case both histogram have zero bin contents
2310 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2311 --ndf; //no data means one degree of freedom less
2312 continue;
2313 }
2314
2315 // case weighted histogram has zero bin content and error
2316 if (cnt2 * cnt2 == 0 && e2sq == 0) {
2317 if (sumw2 > 0) {
2318 // use as approximated error as 1 scaled by a scaling ratio
2319 // estimated from the total sum weight and sum weight squared
2320 e2sq = sumw2 / sum2;
2321 }
2322 else {
2323 // return error because infinite discrepancy here:
2324 // bin1 != 0 and bin2 =0 in a histogram with all errors zero
2325 Error("Chi2TestX","Hist2 has in bin (%d,%d,%d) zero content and zero errors\n", i, j, k);
2326 chi2 = 0; return 0;
2327 }
2328 }
2329
2330 if (cnt1 < 1) m++;
2331 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2332
2333 Double_t var1 = sum2 * cnt2 - sum1 * e2sq;
2334 Double_t var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2335
2336 // if cnt1 is zero and cnt2 = 1 and sum1 = sum2 var1 = 0 && var2 == 0
2337 // approximate by incrementing cnt1
2338 // LM (this need to be fixed for numerical errors)
2339 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2340 sum1++;
2341 cnt1++;
2342 var1 = sum2 * cnt2 - sum1 * e2sq;
2343 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2344 }
2346
2347 while (var1 + var2 == 0) {
2348 sum1++;
2349 cnt1++;
2350 var1 = sum2 * cnt2 - sum1 * e2sq;
2351 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2352 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2353 sum1++;
2354 cnt1++;
2355 var1 = sum2 * cnt2 - sum1 * e2sq;
2356 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2357 }
2359 }
2360
2361 Double_t probb = (var1 + var2) / (2. * sum2 * sum2);
2362
2365
2368
2369 chi2 += delta1 * delta1 / nexp1;
2370
2371 if (e2sq > 0) {
2372 chi2 += delta2 * delta2 / e2sq;
2373 }
2374
2375 if (res) {
2376 if (e2sq > 0) {
2377 Double_t temp1 = sum2 * e2sq / var2;
2378 Double_t temp2 = 1.0 + (sum1 * e2sq - sum2 * cnt2) / var2;
2379 temp2 = temp1 * temp1 * sum1 * probb * (1.0 - probb) + temp2 * temp2 * e2sq / 4.0;
2380 // invert sign here
2381 res[resIndex] = - delta2 / TMath::Sqrt(temp2);
2382 }
2383 else
2384 res[resIndex] = delta1 / TMath::Sqrt(nexp1);
2385 resIndex++;
2386 }
2387 }
2388 }
2389 }
2390
2391 if (m) {
2392 igood += 1;
2393 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2394 }
2395 if (n) {
2396 igood += 2;
2397 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2398 }
2399
2400 Double_t prob = TMath::Prob(chi2, ndf);
2401
2402 return prob;
2403 }
2404
2405 // weighted - weighted comparison
2406 if (comparisonWW) {
2407 Int_t resIndex = 0;
2408 for (Int_t i = i_start; i <= i_end; ++i) {
2409 for (Int_t j = j_start; j <= j_end; ++j) {
2410 for (Int_t k = k_start; k <= k_end; ++k) {
2411
2412 Int_t bin = GetBin(i, j, k);
2414 Double_t cnt2 = h2->RetrieveBinContent(bin);
2416 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2417
2418 // case both histogram have zero bin contents
2419 // (use square of content to avoid numerical errors)
2420 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2421 --ndf; //no data means one degree of freedom less
2422 continue;
2423 }
2424
2425 if (e1sq == 0 && e2sq == 0) {
2426 // cannot treat case of booth histogram have zero zero errors
2427 Error("Chi2TestX","h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
2428 chi2 = 0; return 0;
2429 }
2430
2431 Double_t sigma = sum1 * sum1 * e2sq + sum2 * sum2 * e1sq;
2432 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2433 chi2 += delta * delta / sigma;
2434
2435 if (res) {
2436 Double_t temp = cnt1 * sum1 * e2sq + cnt2 * sum2 * e1sq;
2437 Double_t probb = temp / sigma;
2438 Double_t z = 0;
2439 if (e1sq > e2sq) {
2440 Double_t d1 = cnt1 - sum1 * probb;
2441 Double_t s1 = e1sq * ( 1. - e2sq * sum1 * sum1 / sigma );
2442 z = d1 / TMath::Sqrt(s1);
2443 }
2444 else {
2445 Double_t d2 = cnt2 - sum2 * probb;
2446 Double_t s2 = e2sq * ( 1. - e1sq * sum2 * sum2 / sigma );
2447 z = -d2 / TMath::Sqrt(s2);
2448 }
2449 res[resIndex] = z;
2450 resIndex++;
2451 }
2452
2453 if (e1sq > 0 && cnt1 * cnt1 / e1sq < 10) m++;
2454 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2455 }
2456 }
2457 }
2458 if (m) {
2459 igood += 1;
2460 Info("Chi2TestX","There is a bin in h1 with less than 10 effective events.\n");
2461 }
2462 if (n) {
2463 igood += 2;
2464 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2465 }
2466 Double_t prob = TMath::Prob(chi2, ndf);
2467 return prob;
2468 }
2469 return 0;
2470}
2471////////////////////////////////////////////////////////////////////////////////
2472/// Compute and return the chisquare of this histogram with respect to a function
2473/// The chisquare is computed by weighting each histogram point by the bin error
2474/// By default the full range of the histogram is used, unless TAxis::SetRange or TAxis::SetRangeUser was called before.
2475/// Use option "R" for restricting the chisquare calculation to the given range of the function
2476/// Use option "L" for using the chisquare based on the poisson likelihood (Baker-Cousins Chisquare)
2477/// Use option "P" for using the Pearson chisquare based on the expected bin errors
2478
2480{
2481 if (!func) {
2482 Error("Chisquare","Function pointer is Null - return -1");
2483 return -1;
2484 }
2485
2486 TString opt(option); opt.ToUpper();
2487 bool useRange = opt.Contains("R");
2488 ROOT::Fit::EChisquareType type = ROOT::Fit::EChisquareType::kNeyman; // default chi2 with observed error
2491
2492 return ROOT::Fit::Chisquare(*this, *func, useRange, type);
2493}
2494
2495////////////////////////////////////////////////////////////////////////////////
2496/// Remove all the content from the underflow and overflow bins, without changing the number of entries
2497/// After calling this method, every undeflow and overflow bins will have content 0.0
2498/// The Sumw2 is also cleared, since there is no more content in the bins
2499
2501{
2502 for (Int_t bin = 0; bin < fNcells; ++bin)
2503 if (IsBinUnderflow(bin) || IsBinOverflow(bin)) {
2504 UpdateBinContent(bin, 0.0);
2505 if (fSumw2.fN) fSumw2.fArray[bin] = 0.0;
2506 }
2507}
2508
2509////////////////////////////////////////////////////////////////////////////////
2510/// Compute integral (normalized cumulative sum of bins) w/o under/overflows
2511/// The result is stored in fIntegral and used by the GetRandom functions.
2512/// This function is automatically called by GetRandom when the fIntegral
2513/// array does not exist or when the number of entries in the histogram
2514/// has changed since the previous call to GetRandom.
2515/// The resulting integral is normalized to 1.
2516/// If the routine is called with the onlyPositive flag set an error will
2517/// be produced in case of negative bin content and a NaN value returned
2518/// \param onlyPositive If set to true, an error will be produced and NaN will be returned
2519/// when a bin with negative number of entries is encountered.
2520/// \param option
2521/// - `""` (default) Compute the cumulative density function assuming current bin contents represent counts.
2522/// - `"width"` Computes the cumulative density function assuming current bin contents represent densities.
2523/// \return 1 if success, 0 if integral is zero, NAN if onlyPositive-test fails
2524
2526{
2527 if (fBuffer) BufferEmpty();
2529 // delete previously computed integral (if any)
2530 if (fIntegral) delete [] fIntegral;
2531
2532 // - Allocate space to store the integral and compute integral
2536 Int_t nbins = nbinsx * nbinsy * nbinsz;
2537
2538 fIntegral = new Double_t[nbins + 2];
2539 Int_t ibin = 0; fIntegral[ibin] = 0;
2540
2541 for (Int_t binz=1; binz <= nbinsz; ++binz) {
2543 for (Int_t biny=1; biny <= nbinsy; ++biny) {
2545 for (Int_t binx=1; binx <= nbinsx; ++binx) {
2547 ++ibin;
2549 if (useArea)
2550 y *= xWidth * yWidth * zWidth;
2551
2552 if (onlyPositive && y < 0) {
2553 Error("ComputeIntegral","Bin content is negative - return a NaN value");
2554 fIntegral[nbins] = TMath::QuietNaN();
2555 break;
2556 }
2557 fIntegral[ibin] = fIntegral[ibin - 1] + y;
2558 }
2559 }
2560 }
2561
2562 // - Normalize integral to 1
2563 if (fIntegral[nbins] == 0 ) {
2564 Error("ComputeIntegral", "Integral = 0, no hits in histogram bins (excluding over/underflow).");
2565 return 0;
2566 }
2567 for (Int_t bin=1; bin <= nbins; ++bin) fIntegral[bin] /= fIntegral[nbins];
2568 fIntegral[nbins+1] = fEntries;
2569 return fIntegral[nbins];
2570}
2571
2572////////////////////////////////////////////////////////////////////////////////
2573/// Return a pointer to the array of bins integral.
2574/// if the pointer fIntegral is null, TH1::ComputeIntegral is called
2575/// The array dimension is the number of bins in the histograms
2576/// including underflow and overflow (fNCells)
2577/// the last value integral[fNCells] is set to the number of entries of
2578/// the histogram
2579
2581{
2582 if (!fIntegral) ComputeIntegral();
2583 return fIntegral;
2584}
2585
2586////////////////////////////////////////////////////////////////////////////////
2587/// Return a pointer to a histogram containing the cumulative content.
2588/// The cumulative can be computed both in the forward (default) or backward
2589/// direction; the name of the new histogram is constructed from
2590/// the name of this histogram with the suffix "suffix" appended provided
2591/// by the user. If not provided a default suffix="_cumulative" is used.
2592///
2593/// The cumulative distribution is formed by filling each bin of the
2594/// resulting histogram with the sum of that bin and all previous
2595/// (forward == kTRUE) or following (forward = kFALSE) bins.
2596///
2597/// Note: while cumulative distributions make sense in one dimension, you
2598/// may not be getting what you expect in more than 1D because the concept
2599/// of a cumulative distribution is much trickier to define; make sure you
2600/// understand the order of summation before you use this method with
2601/// histograms of dimension >= 2.
2602///
2603/// Note 2: By default the cumulative is computed from bin 1 to Nbins
2604/// If an axis range is set, values between the minimum and maximum of the range
2605/// are set.
2606/// Setting an axis range can also be used for including underflow and overflow in
2607/// the cumulative (e.g. by setting h->GetXaxis()->SetRange(0, h->GetNbinsX()+1); )
2609
2610TH1 *TH1::GetCumulative(Bool_t forward, const char* suffix) const
2611{
2612 const Int_t firstX = fXaxis.GetFirst();
2613 const Int_t lastX = fXaxis.GetLast();
2614 const Int_t firstY = (fDimension > 1) ? fYaxis.GetFirst() : 1;
2615 const Int_t lastY = (fDimension > 1) ? fYaxis.GetLast() : 1;
2616 const Int_t firstZ = (fDimension > 1) ? fZaxis.GetFirst() : 1;
2617 const Int_t lastZ = (fDimension > 1) ? fZaxis.GetLast() : 1;
2618
2620 hintegrated->Reset();
2621 Double_t sum = 0.;
2622 Double_t esum = 0;
2623 if (forward) { // Forward computation
2624 for (Int_t binz = firstZ; binz <= lastZ; ++binz) {
2625 for (Int_t biny = firstY; biny <= lastY; ++biny) {
2626 for (Int_t binx = firstX; binx <= lastX; ++binx) {
2627 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2628 sum += RetrieveBinContent(bin);
2629 hintegrated->AddBinContent(bin, sum);
2630 if (fSumw2.fN) {
2632 hintegrated->fSumw2.fArray[bin] = esum;
2633 }
2634 }
2635 }
2636 }
2637 } else { // Backward computation
2638 for (Int_t binz = lastZ; binz >= firstZ; --binz) {
2639 for (Int_t biny = lastY; biny >= firstY; --biny) {
2640 for (Int_t binx = lastX; binx >= firstX; --binx) {
2641 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2642 sum += RetrieveBinContent(bin);
2643 hintegrated->AddBinContent(bin, sum);
2644 if (fSumw2.fN) {
2646 hintegrated->fSumw2.fArray[bin] = esum;
2647 }
2648 }
2649 }
2650 }
2651 }
2652 return hintegrated;
2653}
2654
2655////////////////////////////////////////////////////////////////////////////////
2656/// Copy this histogram structure to newth1.
2657///
2658/// Note that this function does not copy the list of associated functions.
2659/// Use TObject::Clone to make a full copy of a histogram.
2660///
2661/// Note also that the histogram it will be created in gDirectory (if AddDirectoryStatus()=true)
2662/// or will not be added to any directory if AddDirectoryStatus()=false
2663/// independently of the current directory stored in the original histogram
2664
2665void TH1::Copy(TObject &obj) const
2666{
2667 if (((TH1&)obj).fDirectory) {
2668 // We are likely to change the hash value of this object
2669 // with TNamed::Copy, to keep things correct, we need to
2670 // clean up its existing entries.
2671 ((TH1&)obj).fDirectory->Remove(&obj);
2672 ((TH1&)obj).fDirectory = nullptr;
2673 }
2674 TNamed::Copy(obj);
2675 ((TH1&)obj).fDimension = fDimension;
2676 ((TH1&)obj).fNormFactor= fNormFactor;
2677 ((TH1&)obj).fNcells = fNcells;
2678 ((TH1&)obj).fBarOffset = fBarOffset;
2679 ((TH1&)obj).fBarWidth = fBarWidth;
2680 ((TH1&)obj).fOption = fOption;
2681 ((TH1&)obj).fBinStatErrOpt = fBinStatErrOpt;
2682 ((TH1&)obj).fBufferSize= fBufferSize;
2683 // copy the Buffer
2684 // delete first a previously existing buffer
2685 if (((TH1&)obj).fBuffer != nullptr) {
2686 delete [] ((TH1&)obj).fBuffer;
2687 ((TH1&)obj).fBuffer = nullptr;
2688 }
2689 if (fBuffer) {
2690 Double_t *buf = new Double_t[fBufferSize];
2691 for (Int_t i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
2692 // obj.fBuffer has been deleted before
2693 ((TH1&)obj).fBuffer = buf;
2694 }
2695
2696 // copy bin contents (this should be done by the derived classes, since TH1 does not store the bin content)
2697 // Do this in case derived from TArray
2698 TArray* a = dynamic_cast<TArray*>(&obj);
2699 if (a) {
2700 a->Set(fNcells);
2701 for (Int_t i = 0; i < fNcells; i++)
2703 }
2704
2705 ((TH1&)obj).fEntries = fEntries;
2706
2707 // which will call BufferEmpty(0) and set fBuffer[0] to a Maybe one should call
2708 // assignment operator on the TArrayD
2709
2710 ((TH1&)obj).fTsumw = fTsumw;
2711 ((TH1&)obj).fTsumw2 = fTsumw2;
2712 ((TH1&)obj).fTsumwx = fTsumwx;
2713 ((TH1&)obj).fTsumwx2 = fTsumwx2;
2714 ((TH1&)obj).fMaximum = fMaximum;
2715 ((TH1&)obj).fMinimum = fMinimum;
2716
2717 TAttLine::Copy(((TH1&)obj));
2718 TAttFill::Copy(((TH1&)obj));
2719 TAttMarker::Copy(((TH1&)obj));
2720 fXaxis.Copy(((TH1&)obj).fXaxis);
2721 fYaxis.Copy(((TH1&)obj).fYaxis);
2722 fZaxis.Copy(((TH1&)obj).fZaxis);
2723 ((TH1&)obj).fXaxis.SetParent(&obj);
2724 ((TH1&)obj).fYaxis.SetParent(&obj);
2725 ((TH1&)obj).fZaxis.SetParent(&obj);
2726 fContour.Copy(((TH1&)obj).fContour);
2727 fSumw2.Copy(((TH1&)obj).fSumw2);
2728 // fFunctions->Copy(((TH1&)obj).fFunctions);
2729 // when copying an histogram if the AddDirectoryStatus() is true it
2730 // will be added to gDirectory independently of the fDirectory stored.
2731 // and if the AddDirectoryStatus() is false it will not be added to
2732 // any directory (fDirectory = nullptr)
2733 if (fgAddDirectory && gDirectory) {
2734 gDirectory->Append(&obj);
2735 ((TH1&)obj).fFunctions->UseRWLock();
2736 ((TH1&)obj).fDirectory = gDirectory;
2737 } else
2738 ((TH1&)obj).fDirectory = nullptr;
2739
2740}
2741
2742////////////////////////////////////////////////////////////////////////////////
2743/// Make a complete copy of the underlying object. If 'newname' is set,
2744/// the copy's name will be set to that name.
2745
2746TObject* TH1::Clone(const char* newname) const
2747{
2748 TH1* obj = (TH1*)IsA()->GetNew()(nullptr);
2749 Copy(*obj);
2750
2751 // Now handle the parts that Copy doesn't do
2752 if(fFunctions) {
2753 // The Copy above might have published 'obj' to the ListOfCleanups.
2754 // Clone can call RecursiveRemove, for example via TCheckHashRecursiveRemoveConsistency
2755 // when dictionary information is initialized, so we need to
2756 // keep obj->fFunction valid during its execution and
2757 // protect the update with the write lock.
2758
2759 // Reset stats parent - else cloning the stats will clone this histogram, too.
2760 auto oldstats = dynamic_cast<TVirtualPaveStats*>(fFunctions->FindObject("stats"));
2761 TObject *oldparent = nullptr;
2762 if (oldstats) {
2763 oldparent = oldstats->GetParent();
2764 oldstats->SetParent(nullptr);
2765 }
2766
2767 auto newlist = (TList*)fFunctions->Clone();
2768
2769 if (oldstats)
2770 oldstats->SetParent(oldparent);
2771 auto newstats = dynamic_cast<TVirtualPaveStats*>(obj->fFunctions->FindObject("stats"));
2772 if (newstats)
2773 newstats->SetParent(obj);
2774
2775 auto oldlist = obj->fFunctions;
2776 {
2778 obj->fFunctions = newlist;
2779 }
2780 delete oldlist;
2781 }
2782 if(newname && strlen(newname) ) {
2783 obj->SetName(newname);
2784 }
2785 return obj;
2786}
2787
2788////////////////////////////////////////////////////////////////////////////////
2789/// Perform the automatic addition of the histogram to the given directory
2790///
2791/// Note this function is called in place when the semantic requires
2792/// this object to be added to a directory (I.e. when being read from
2793/// a TKey or being Cloned)
2794
2796{
2798 if (addStatus) {
2799 SetDirectory(dir);
2800 if (dir) {
2802 }
2803 }
2804}
2805
2806////////////////////////////////////////////////////////////////////////////////
2807/// Compute distance from point px,py to a line.
2808///
2809/// Compute the closest distance of approach from point px,py to elements
2810/// of a histogram.
2811/// The distance is computed in pixels units.
2812///
2813/// #### Algorithm:
2814/// Currently, this simple model computes the distance from the mouse
2815/// to the histogram contour only.
2816
2818{
2819 if (!fPainter) return 9999;
2820 return fPainter->DistancetoPrimitive(px,py);
2821}
2822
2823////////////////////////////////////////////////////////////////////////////////
2824/// Performs the operation: `this = this/(c1*f1)`
2825/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2826///
2827/// Only bins inside the function range are recomputed.
2828/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2829/// you should call Sumw2 before making this operation.
2830/// This is particularly important if you fit the histogram after TH1::Divide
2831///
2832/// The function return kFALSE if the divide operation failed
2833
2835{
2836 if (!f1) {
2837 Error("Divide","Attempt to divide by a non-existing function");
2838 return kFALSE;
2839 }
2840
2841 // delete buffer if it is there since it will become invalid
2842 if (fBuffer) BufferEmpty(1);
2843
2844 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of
2845 Int_t ny = GetNbinsY() + 2;
2846 Int_t nz = GetNbinsZ() + 2;
2847 if (fDimension < 2) ny = 1;
2848 if (fDimension < 3) nz = 1;
2849
2850
2851 SetMinimum();
2852 SetMaximum();
2853
2854 // - Loop on bins (including underflows/overflows)
2855 Int_t bin, binx, biny, binz;
2856 Double_t cu, w;
2857 Double_t xx[3];
2858 Double_t *params = nullptr;
2859 f1->InitArgs(xx,params);
2860 for (binz = 0; binz < nz; ++binz) {
2861 xx[2] = fZaxis.GetBinCenter(binz);
2862 for (biny = 0; biny < ny; ++biny) {
2863 xx[1] = fYaxis.GetBinCenter(biny);
2864 for (binx = 0; binx < nx; ++binx) {
2865 xx[0] = fXaxis.GetBinCenter(binx);
2866 if (!f1->IsInside(xx)) continue;
2868 bin = binx + nx * (biny + ny * binz);
2869 cu = c1 * f1->EvalPar(xx);
2870 if (TF1::RejectedPoint()) continue;
2871 if (cu) w = RetrieveBinContent(bin) / cu;
2872 else w = 0;
2873 UpdateBinContent(bin, w);
2874 if (fSumw2.fN) {
2875 if (cu != 0) fSumw2.fArray[bin] = GetBinErrorSqUnchecked(bin) / (cu * cu);
2876 else fSumw2.fArray[bin] = 0;
2877 }
2878 }
2879 }
2880 }
2881 ResetStats();
2882 return kTRUE;
2883}
2884
2885////////////////////////////////////////////////////////////////////////////////
2886/// Divide this histogram by h1.
2887///
2888/// `this = this/h1`
2889/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2890/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
2891/// if not already set.
2892/// The resulting errors are calculated assuming uncorrelated histograms.
2893/// See the other TH1::Divide that gives the possibility to optionally
2894/// compute binomial errors.
2895///
2896/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2897/// you should call Sumw2 before making this operation.
2898/// This is particularly important if you fit the histogram after TH1::Scale
2899///
2900/// The function return kFALSE if the divide operation failed
2901
2902Bool_t TH1::Divide(const TH1 *h1)
2903{
2904 if (!h1) {
2905 Error("Divide", "Input histogram passed does not exist (NULL).");
2906 return kFALSE;
2907 }
2908
2909 // delete buffer if it is there since it will become invalid
2910 if (fBuffer) BufferEmpty(1);
2911
2912 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins) {
2913 return false;
2914 }
2915
2916 // Create Sumw2 if h1 has Sumw2 set
2917 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
2918
2919 // - Loop on bins (including underflows/overflows)
2920 for (Int_t i = 0; i < fNcells; ++i) {
2923 if (c1) UpdateBinContent(i, c0 / c1);
2924 else UpdateBinContent(i, 0);
2925
2926 if(fSumw2.fN) {
2927 if (c1 == 0) { fSumw2.fArray[i] = 0; continue; }
2928 Double_t c1sq = c1 * c1;
2929 fSumw2.fArray[i] = (GetBinErrorSqUnchecked(i) * c1sq + h1->GetBinErrorSqUnchecked(i) * c0 * c0) / (c1sq * c1sq);
2930 }
2931 }
2932 ResetStats();
2933 return kTRUE;
2934}
2935
2936////////////////////////////////////////////////////////////////////////////////
2937/// Replace contents of this histogram by the division of h1 by h2.
2938///
2939/// `this = c1*h1/(c2*h2)`
2940///
2941/// If errors are defined (see TH1::Sumw2), errors are also recalculated
2942/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
2943/// if not already set.
2944/// The resulting errors are calculated assuming uncorrelated histograms.
2945/// However, if option ="B" is specified, Binomial errors are computed.
2946/// In this case c1 and c2 do not make real sense and they are ignored.
2947///
2948/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2949/// you should call Sumw2 before making this operation.
2950/// This is particularly important if you fit the histogram after TH1::Divide
2951///
2952/// Please note also that in the binomial case errors are calculated using standard
2953/// binomial statistics, which means when b1 = b2, the error is zero.
2954/// If you prefer to have efficiency errors not going to zero when the efficiency is 1, you must
2955/// use the function TGraphAsymmErrors::BayesDivide, which will return an asymmetric and non-zero lower
2956/// error for the case b1=b2.
2957///
2958/// The function return kFALSE if the divide operation failed
2959
2961{
2962
2963 TString opt = option;
2964 opt.ToLower();
2965 Bool_t binomial = kFALSE;
2966 if (opt.Contains("b")) binomial = kTRUE;
2967 if (!h1 || !h2) {
2968 Error("Divide", "At least one of the input histograms passed does not exist (NULL).");
2969 return kFALSE;
2970 }
2971
2972 // delete buffer if it is there since it will become invalid
2973 if (fBuffer) BufferEmpty(1);
2974
2975 if (LoggedInconsistency("Divide", this, h1) >= kDifferentNumberOfBins ||
2976 LoggedInconsistency("Divide", h1, h2) >= kDifferentNumberOfBins) {
2977 return false;
2978 }
2979
2980 if (!c2) {
2981 Error("Divide","Coefficient of dividing histogram cannot be zero");
2982 return kFALSE;
2983 }
2984
2985 // Create Sumw2 if h1 or h2 have Sumw2 set, or if binomial errors are explicitly requested
2986 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0 || binomial)) Sumw2();
2987
2988 SetMinimum();
2989 SetMaximum();
2990
2991 // - Loop on bins (including underflows/overflows)
2992 for (Int_t i = 0; i < fNcells; ++i) {
2994 Double_t b2 = h2->RetrieveBinContent(i);
2995 if (b2) UpdateBinContent(i, c1 * b1 / (c2 * b2));
2996 else UpdateBinContent(i, 0);
2997
2998 if (fSumw2.fN) {
2999 if (b2 == 0) { fSumw2.fArray[i] = 0; continue; }
3000 Double_t b1sq = b1 * b1; Double_t b2sq = b2 * b2;
3001 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
3003 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
3004 if (binomial) {
3005 if (b1 != b2) {
3006 // in the case of binomial statistics c1 and c2 must be 1 otherwise it does not make sense
3007 // c1 and c2 are ignored
3008 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));//this is the formula in Hbook/Hoper1
3009 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2); // old formula from G. Flucke
3010 // formula which works also for weighted histogram (see http://root-forum.cern.ch/viewtopic.php?t=3753 )
3011 fSumw2.fArray[i] = TMath::Abs( ( (1. - 2.* b1 / b2) * e1sq + b1sq * e2sq / b2sq ) / b2sq );
3012 } else {
3013 //in case b1=b2 error is zero
3014 //use TGraphAsymmErrors::BayesDivide for getting the asymmetric error not equal to zero
3015 fSumw2.fArray[i] = 0;
3016 }
3017 } else {
3018 fSumw2.fArray[i] = c1sq * c2sq * (e1sq * b2sq + e2sq * b1sq) / (c2sq * c2sq * b2sq * b2sq);
3019 }
3020 }
3021 }
3022 ResetStats();
3023 if (binomial)
3024 // in case of binomial division use denominator for number of entries
3025 SetEntries ( h2->GetEntries() );
3026
3027 return kTRUE;
3028}
3029
3030////////////////////////////////////////////////////////////////////////////////
3031/// Draw this histogram with options.
3032///
3033/// Histograms are drawn via the THistPainter class. Each histogram has
3034/// a pointer to its own painter (to be usable in a multithreaded program).
3035/// The same histogram can be drawn with different options in different pads.
3036/// If a histogram is updated after it has been drawn, the updated data will
3037/// be shown the next time the pad is updated. One does not need to
3038/// redraw the histogram.
3039///
3040/// When a histogram is deleted, the histogram is **automatically removed from
3041/// all pads where it was drawn**. If a histogram should be modified or deleted
3042/// without affecting what is drawn, it should be drawn using DrawCopy().
3043///
3044/// By default, TH1::Draw clears the current pad. Passing the option "SAME", the
3045/// histogram will be drawn on top of what's in the pad.
3046/// One can use TH1::SetMaximum and TH1::SetMinimum to force a particular
3047/// value for the maximum or the minimum scale on the plot.
3048///
3049/// TH1::UseCurrentStyle can be used to change all histogram graphics
3050/// attributes to correspond to the current selected style.
3051/// This function must be called for each histogram.
3052/// In case one reads and draws many histograms from a file, one can force
3053/// the histograms to inherit automatically the current graphics style
3054/// by calling before gROOT->ForceStyle();
3055///
3056/// See the THistPainter class for a description of all the drawing options.
3057
3059{
3060 TString opt1 = option; opt1.ToLower();
3062 Int_t index = opt1.Index("same");
3063
3064 // Check if the string "same" is part of a TCutg name.
3065 if (index>=0) {
3066 Int_t indb = opt1.Index("[");
3067 if (indb>=0) {
3068 Int_t indk = opt1.Index("]");
3069 if (index>indb && index<indk) index = -1;
3070 }
3071 }
3072
3073 // If there is no pad or an empty pad the "same" option is ignored.
3074 if (gPad) {
3075 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
3076 if (index>=0) {
3077 if (gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
3078 gPad->GetY1() == 0 && gPad->GetY2() == 1 &&
3079 gPad->GetListOfPrimitives()->GetSize()==0) opt2.Remove(index,4);
3080 } else {
3081 //the following statement is necessary in case one attempts to draw
3082 //a temporary histogram already in the current pad
3083 if (TestBit(kCanDelete)) gPad->Remove(this);
3084 gPad->Clear();
3085 }
3086 gPad->IncrementPaletteColor(1, opt1);
3087 } else {
3088 if (index>=0) opt2.Remove(index,4);
3089 }
3090
3091 AppendPad(opt2.Data());
3092}
3093
3094////////////////////////////////////////////////////////////////////////////////
3095/// Copy this histogram and Draw in the current pad.
3096///
3097/// Once the histogram is drawn into the pad, the original and its drawn copy can be modified or deleted without
3098/// affecting each other. The copied histogram will be owned by the pad, and is deleted when the pad is cleared.
3099///
3100/// DrawCopy() is useful if the original histogram is a temporary, e.g. from code such as
3101/// ~~~ {.cpp}
3102/// void someFunction(...) {
3103/// TH1D histogram(...);
3104/// histogram.DrawCopy();
3105///
3106/// // or equivalently
3107/// std::unique_ptr<TH1F> histogram(...);
3108/// histogram->DrawCopy();
3109/// }
3110/// ~~~
3111/// If Draw() has been used, the histograms would disappear from the canvas at the end of this function.
3112///
3113/// By default a postfix "_copy" is added to the histogram name. Pass an empty postfix in case
3114/// you want to draw a histogram with the same name.
3115///
3116/// See Draw() for the list of options.
3117///
3118/// In contrast to TObject::DrawClone(), DrawCopy
3119/// - Ignores `gROOT->SetSelectedPad()`.
3120/// - Does not register the histogram to any directory.
3121/// - And can cycle through a colour palette when multiple objects are drawn with auto colouring.
3122
3123TH1 *TH1::DrawCopy(Option_t *option, const char * name_postfix) const
3124{
3125 TString opt = option;
3126 opt.ToLower();
3127 if (gPad && !opt.Contains("same")) gPad->Clear();
3129 if (name_postfix) newName.Form("%s%s", GetName(), name_postfix);
3130 TH1 *newth1 = (TH1 *)Clone(newName.Data());
3131 newth1->SetDirectory(nullptr);
3132 newth1->SetBit(kCanDelete);
3133 if (gPad) gPad->IncrementPaletteColor(1, opt);
3134
3135 newth1->AppendPad(option);
3136 return newth1;
3137}
3138
3139////////////////////////////////////////////////////////////////////////////////
3140/// Draw a normalized copy of this histogram.
3141///
3142/// A clone of this histogram is normalized to norm and drawn with option.
3143/// A pointer to the normalized histogram is returned.
3144/// The contents of the histogram copy are scaled such that the new
3145/// sum of weights (excluding under and overflow) is equal to norm.
3146/// Note that the returned normalized histogram is not added to the list
3147/// of histograms in the current directory in memory.
3148/// It is the user's responsibility to delete this histogram.
3149/// The kCanDelete bit is set for the returned object. If a pad containing
3150/// this copy is cleared, the histogram will be automatically deleted.
3151///
3152/// See Draw for the list of options
3153
3155{
3157 if (sum == 0) {
3158 Error("DrawNormalized","Sum of weights is null. Cannot normalize histogram: %s",GetName());
3159 return nullptr;
3160 }
3163 TH1 *h = (TH1*)Clone();
3165 // in case of drawing with error options - scale correctly the error
3166 TString opt(option); opt.ToUpper();
3167 if (fSumw2.fN == 0) {
3168 h->Sumw2();
3169 // do not use in this case the "Error option " for drawing which is enabled by default since the normalized histogram has now errors
3170 if (opt.IsNull() || opt == "SAME") opt += "HIST";
3171 }
3172 h->Scale(norm/sum);
3173 if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
3174 if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
3175 h->Draw(opt);
3177 return h;
3178}
3179
3180////////////////////////////////////////////////////////////////////////////////
3181/// Display a panel with all histogram drawing options.
3182///
3183/// See class TDrawPanelHist for example
3184
3185void TH1::DrawPanel()
3186{
3187 if (!fPainter) {Draw(); if (gPad) gPad->Update();}
3188 if (fPainter) fPainter->DrawPanel();
3189}
3190
3191////////////////////////////////////////////////////////////////////////////////
3192/// Evaluate function f1 at the center of bins of this histogram.
3193///
3194/// - If option "R" is specified, the function is evaluated only
3195/// for the bins included in the function range.
3196/// - If option "A" is specified, the value of the function is added to the
3197/// existing bin contents
3198/// - If option "S" is specified, the value of the function is used to
3199/// generate a value, distributed according to the Poisson
3200/// distribution, with f1 as the mean.
3201
3203{
3204 Double_t x[3];
3205 Int_t range, stat, add;
3206 if (!f1) return;
3207
3208 TString opt = option;
3209 opt.ToLower();
3210 if (opt.Contains("a")) add = 1;
3211 else add = 0;
3212 if (opt.Contains("s")) stat = 1;
3213 else stat = 0;
3214 if (opt.Contains("r")) range = 1;
3215 else range = 0;
3216
3217 // delete buffer if it is there since it will become invalid
3218 if (fBuffer) BufferEmpty(1);
3219
3223 if (!add) Reset();
3224
3225 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
3226 x[2] = fZaxis.GetBinCenter(binz);
3227 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
3228 x[1] = fYaxis.GetBinCenter(biny);
3229 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
3230 Int_t bin = GetBin(binx,biny,binz);
3231 x[0] = fXaxis.GetBinCenter(binx);
3232 if (range && !f1->IsInside(x)) continue;
3233 Double_t fu = f1->Eval(x[0], x[1], x[2]);
3234 if (stat) fu = gRandom->PoissonD(fu);
3235 AddBinContent(bin, fu);
3236 if (fSumw2.fN) fSumw2.fArray[bin] += TMath::Abs(fu);
3237 }
3238 }
3239 }
3240}
3241
3242////////////////////////////////////////////////////////////////////////////////
3243/// Execute action corresponding to one event.
3244///
3245/// This member function is called when a histogram is clicked with the locator
3246///
3247/// If Left button clicked on the bin top value, then the content of this bin
3248/// is modified according to the new position of the mouse when it is released.
3249
3250void TH1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3251{
3252 if (fPainter) fPainter->ExecuteEvent(event, px, py);
3253}
3254
3255////////////////////////////////////////////////////////////////////////////////
3256/// This function allows to do discrete Fourier transforms of TH1 and TH2.
3257/// Available transform types and flags are described below.
3258///
3259/// To extract more information about the transform, use the function
3260/// TVirtualFFT::GetCurrentTransform() to get a pointer to the current
3261/// transform object.
3262///
3263/// \param[out] h_output histogram for the output. If a null pointer is passed, a new histogram is created
3264/// and returned, otherwise, the provided histogram is used and should be big enough
3265/// \param[in] option option parameters consists of 3 parts:
3266/// - option on what to return
3267/// - "RE" - returns a histogram of the real part of the output
3268/// - "IM" - returns a histogram of the imaginary part of the output
3269/// - "MAG"- returns a histogram of the magnitude of the output
3270/// - "PH" - returns a histogram of the phase of the output
3271/// - option of transform type
3272/// - "R2C" - real to complex transforms - default
3273/// - "R2HC" - real to halfcomplex (special format of storing output data,
3274/// results the same as for R2C)
3275/// - "DHT" - discrete Hartley transform
3276/// real to real transforms (sine and cosine):
3277/// - "R2R_0", "R2R_1", "R2R_2", "R2R_3" - discrete cosine transforms of types I-IV
3278/// - "R2R_4", "R2R_5", "R2R_6", "R2R_7" - discrete sine transforms of types I-IV
3279/// To specify the type of each dimension of a 2-dimensional real to real
3280/// transform, use options of form "R2R_XX", for example, "R2R_02" for a transform,
3281/// which is of type "R2R_0" in 1st dimension and "R2R_2" in the 2nd.
3282/// - option of transform flag
3283/// - "ES" (from "estimate") - no time in preparing the transform, but probably sub-optimal
3284/// performance
3285/// - "M" (from "measure") - some time spend in finding the optimal way to do the transform
3286/// - "P" (from "patient") - more time spend in finding the optimal way to do the transform
3287/// - "EX" (from "exhaustive") - the most optimal way is found
3288/// This option should be chosen depending on how many transforms of the same size and
3289/// type are going to be done. Planning is only done once, for the first transform of this
3290/// size and type. Default is "ES".
3291///
3292/// Examples of valid options: "Mag R2C M" "Re R2R_11" "Im R2C ES" "PH R2HC EX"
3293
3295{
3296
3297 Int_t ndim[3];
3298 ndim[0] = this->GetNbinsX();
3299 ndim[1] = this->GetNbinsY();
3300 ndim[2] = this->GetNbinsZ();
3301
3303 TString opt = option;
3304 opt.ToUpper();
3305 if (!opt.Contains("2R")){
3306 if (!opt.Contains("2C") && !opt.Contains("2HC") && !opt.Contains("DHT")) {
3307 //no type specified, "R2C" by default
3308 opt.Append("R2C");
3309 }
3310 fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
3311 }
3312 else {
3313 //find the kind of transform
3314 Int_t ind = opt.Index("R2R", 3);
3315 Int_t *kind = new Int_t[2];
3316 char t;
3317 t = opt[ind+4];
3318 kind[0] = atoi(&t);
3319 if (h_output->GetDimension()>1) {
3320 t = opt[ind+5];
3321 kind[1] = atoi(&t);
3322 }
3323 fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
3324 delete [] kind;
3325 }
3326
3327 if (!fft) return nullptr;
3328 Int_t in=0;
3329 for (Int_t binx = 1; binx<=ndim[0]; binx++) {
3330 for (Int_t biny=1; biny<=ndim[1]; biny++) {
3331 for (Int_t binz=1; binz<=ndim[2]; binz++) {
3332 fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
3333 in++;
3334 }
3335 }
3336 }
3337 fft->Transform();
3339 return h_output;
3340}
3341
3342////////////////////////////////////////////////////////////////////////////////
3343/// Increment bin with abscissa X by 1.
3344///
3345/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3346/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3347///
3348/// If the storage of the sum of squares of weights has been triggered,
3349/// via the function Sumw2, then the sum of the squares of weights is incremented
3350/// by 1 in the bin corresponding to x.
3351///
3352/// The function returns the corresponding bin number which has its content incremented by 1
3353
3355{
3356 if (fBuffer) return BufferFill(x,1);
3357
3358 Int_t bin;
3359 fEntries++;
3360 bin =fXaxis.FindBin(x);
3361 if (bin <0) return -1;
3362 AddBinContent(bin);
3363 if (fSumw2.fN) ++fSumw2.fArray[bin];
3364 if (bin == 0 || bin > fXaxis.GetNbins()) {
3365 if (!GetStatOverflowsBehaviour()) return -1;
3366 }
3367 ++fTsumw;
3368 ++fTsumw2;
3369 fTsumwx += x;
3370 fTsumwx2 += x*x;
3371 return bin;
3372}
3373
3374////////////////////////////////////////////////////////////////////////////////
3375/// Increment bin with abscissa X with a weight w.
3376///
3377/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3378/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3379///
3380/// If the weight is not equal to 1, the storage of the sum of squares of
3381/// weights is automatically triggered and the sum of the squares of weights is incremented
3382/// by \f$ w^2 \f$ in the bin corresponding to x.
3383///
3384/// The function returns the corresponding bin number which has its content incremented by w
3385
3387{
3388
3389 if (fBuffer) return BufferFill(x,w);
3390
3391 Int_t bin;
3392 fEntries++;
3393 bin =fXaxis.FindBin(x);
3394 if (bin <0) return -1;
3395 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW) ) Sumw2(); // must be called before AddBinContent
3396 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3397 AddBinContent(bin, w);
3398 if (bin == 0 || bin > fXaxis.GetNbins()) {
3399 if (!GetStatOverflowsBehaviour()) return -1;
3400 }
3401 Double_t z= w;
3402 fTsumw += z;
3403 fTsumw2 += z*z;
3404 fTsumwx += z*x;
3405 fTsumwx2 += z*x*x;
3406 return bin;
3407}
3408
3409////////////////////////////////////////////////////////////////////////////////
3410/// Increment bin with namex with a weight w
3411///
3412/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3413/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3414///
3415/// If the weight is not equal to 1, the storage of the sum of squares of
3416/// weights is automatically triggered and the sum of the squares of weights is incremented
3417/// by \f$ w^2 \f$ in the bin corresponding to x.
3418///
3419/// The function returns the corresponding bin number which has its content
3420/// incremented by w.
3421
3422Int_t TH1::Fill(const char *namex, Double_t w)
3423{
3424 Int_t bin;
3425 fEntries++;
3426 bin =fXaxis.FindBin(namex);
3427 if (bin <0) return -1;
3428 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3429 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3430 AddBinContent(bin, w);
3431 if (bin == 0 || bin > fXaxis.GetNbins()) return -1;
3432 Double_t z= w;
3433 fTsumw += z;
3434 fTsumw2 += z*z;
3435 // this make sense if the histogram is not expanding (the x axis cannot be extended)
3436 if (!fXaxis.CanExtend() || !fXaxis.IsAlphanumeric()) {
3438 fTsumwx += z*x;
3439 fTsumwx2 += z*x*x;
3440 }
3441 return bin;
3442}
3443
3444////////////////////////////////////////////////////////////////////////////////
3445/// Fill this histogram with an array x and weights w.
3446///
3447/// \param[in] ntimes number of entries in arrays x and w (array size must be ntimes*stride)
3448/// \param[in] x array of values to be histogrammed
3449/// \param[in] w array of weighs
3450/// \param[in] stride step size through arrays x and w
3451///
3452/// If the weight is not equal to 1, the storage of the sum of squares of
3453/// weights is automatically triggered and the sum of the squares of weights is incremented
3454/// by \f$ w^2 \f$ in the bin corresponding to x.
3455/// if w is NULL each entry is assumed a weight=1
3456
3457void TH1::FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3458{
3459 //If a buffer is activated, fill buffer
3460 if (fBuffer) {
3461 ntimes *= stride;
3462 Int_t i = 0;
3463 for (i=0;i<ntimes;i+=stride) {
3464 if (!fBuffer) break; // buffer can be deleted in BufferFill when is empty
3465 if (w) BufferFill(x[i],w[i]);
3466 else BufferFill(x[i], 1.);
3467 }
3468 // fill the remaining entries if the buffer has been deleted
3469 if (i < ntimes && !fBuffer) {
3470 auto weights = w ? &w[i] : nullptr;
3471 DoFillN((ntimes-i)/stride,&x[i],weights,stride);
3472 }
3473 return;
3474 }
3475 // call internal method
3476 DoFillN(ntimes, x, w, stride);
3477}
3478
3479////////////////////////////////////////////////////////////////////////////////
3480/// Internal method to fill histogram content from a vector
3481/// called directly by TH1::BufferEmpty
3482
3483void TH1::DoFillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3484{
3485 Int_t bin,i;
3486
3487 fEntries += ntimes;
3488 Double_t ww = 1;
3489 Int_t nbins = fXaxis.GetNbins();
3490 ntimes *= stride;
3491 for (i=0;i<ntimes;i+=stride) {
3492 bin =fXaxis.FindBin(x[i]);
3493 if (bin <0) continue;
3494 if (w) ww = w[i];
3495 if (!fSumw2.fN && ww != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3496 if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
3497 AddBinContent(bin, ww);
3498 if (bin == 0 || bin > nbins) {
3499 if (!GetStatOverflowsBehaviour()) continue;
3500 }
3501 Double_t z= ww;
3502 fTsumw += z;
3503 fTsumw2 += z*z;
3504 fTsumwx += z*x[i];
3505 fTsumwx2 += z*x[i]*x[i];
3506 }
3507}
3508
3509////////////////////////////////////////////////////////////////////////////////
3510/// Fill histogram following distribution in function fname.
3511///
3512/// @param fname : Function name used for filling the histogram
3513/// @param ntimes : number of times the histogram is filled
3514/// @param rng : (optional) Random number generator used to sample
3515///
3516///
3517/// The distribution contained in the function fname (TF1) is integrated
3518/// over the channel contents for the bin range of this histogram.
3519/// It is normalized to 1.
3520///
3521/// Getting one random number implies:
3522/// - Generating a random number between 0 and 1 (say r1)
3523/// - Look in which bin in the normalized integral r1 corresponds to
3524/// - Fill histogram channel
3525/// ntimes random numbers are generated
3526///
3527/// One can also call TF1::GetRandom to get a random variate from a function.
3528
3529void TH1::FillRandom(const char *fname, Int_t ntimes, TRandom * rng)
3530{
3531 // - Search for fname in the list of ROOT defined functions
3532 TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
3533 if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
3534
3537
3539{
3540 Int_t bin, binx, ibin, loop;
3541 Double_t r1, x;
3542
3543 // - Allocate temporary space to store the integral and compute integral
3544
3545 TAxis * xAxis = &fXaxis;
3546
3547 // in case axis of histogram is not defined use the function axis
3548 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
3550 f1->GetRange(xmin,xmax);
3551 Info("FillRandom","Using function axis and range [%g,%g]",xmin, xmax);
3552 xAxis = f1->GetHistogram()->GetXaxis();
3553 }
3554
3555 Int_t first = xAxis->GetFirst();
3556 Int_t last = xAxis->GetLast();
3557 Int_t nbinsx = last-first+1;
3558
3559 Double_t *integral = new Double_t[nbinsx+1];
3560 integral[0] = 0;
3561 for (binx=1;binx<=nbinsx;binx++) {
3562 Double_t fint = f1->Integral(xAxis->GetBinLowEdge(binx+first-1),xAxis->GetBinUpEdge(binx+first-1), 0.);
3563 integral[binx] = integral[binx-1] + fint;
3564 }
3565
3566 // - Normalize integral to 1
3567 if (integral[nbinsx] == 0 ) {
3568 delete [] integral;
3569 Error("FillRandom", "Integral = zero"); return;
3570 }
3571 for (bin=1;bin<=nbinsx;bin++) integral[bin] /= integral[nbinsx];
3572
3573 // --------------Start main loop ntimes
3574 for (loop=0;loop<ntimes;loop++) {
3575 r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
3576 ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
3577 //binx = 1 + ibin;
3578 //x = xAxis->GetBinCenter(binx); //this is not OK when SetBuffer is used
3579 x = xAxis->GetBinLowEdge(ibin+first)
3580 +xAxis->GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
3581 Fill(x);
3582 }
3583 delete [] integral;
3584}
3585
3586////////////////////////////////////////////////////////////////////////////////
3587/// Fill histogram following distribution in histogram h.
3588///
3589/// @param h : Histogram pointer used for sampling random number
3590/// @param ntimes : number of times the histogram is filled
3591/// @param rng : (optional) Random number generator used for sampling
3592///
3593/// The distribution contained in the histogram h (TH1) is integrated
3594/// over the channel contents for the bin range of this histogram.
3595/// It is normalized to 1.
3596///
3597/// Getting one random number implies:
3598/// - Generating a random number between 0 and 1 (say r1)
3599/// - Look in which bin in the normalized integral r1 corresponds to
3600/// - Fill histogram channel ntimes random numbers are generated
3601///
3602/// SPECIAL CASE when the target histogram has the same binning as the source.
3603/// in this case we simply use a poisson distribution where
3604/// the mean value per bin = bincontent/integral.
3605
3607{
3608 if (!h) { Error("FillRandom", "Null histogram"); return; }
3609 if (fDimension != h->GetDimension()) {
3610 Error("FillRandom", "Histograms with different dimensions"); return;
3611 }
3612 if (std::isnan(h->ComputeIntegral(true))) {
3613 Error("FillRandom", "Histograms contains negative bins, does not represent probabilities");
3614 return;
3615 }
3616
3617 //in case the target histogram has the same binning and ntimes much greater
3618 //than the number of bins we can use a fast method
3619 Int_t first = fXaxis.GetFirst();
3620 Int_t last = fXaxis.GetLast();
3621 Int_t nbins = last-first+1;
3622 if (ntimes > 10*nbins) {
3623 auto inconsistency = CheckConsistency(this,h);
3624 if (inconsistency != kFullyConsistent) return; // do nothing
3625 Double_t sumw = h->Integral(first,last);
3626 if (sumw == 0) return;
3627 Double_t sumgen = 0;
3628 for (Int_t bin=first;bin<=last;bin++) {
3629 Double_t mean = h->RetrieveBinContent(bin)*ntimes/sumw;
3630 Double_t cont = (rng) ? rng->Poisson(mean) : gRandom->Poisson(mean);
3631 sumgen += cont;
3632 AddBinContent(bin,cont);
3633 if (fSumw2.fN) fSumw2.fArray[bin] += cont;
3634 }
3635
3636 // fix for the fluctuations in the total number n
3637 // since we use Poisson instead of multinomial
3638 // add a correction to have ntimes as generated entries
3639 Int_t i;
3640 if (sumgen < ntimes) {
3641 // add missing entries
3642 for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
3643 {
3644 Double_t x = h->GetRandom();
3645 Fill(x);
3646 }
3647 }
3648 else if (sumgen > ntimes) {
3649 // remove extra entries
3650 i = Int_t(sumgen+0.5);
3651 while( i > ntimes) {
3652 Double_t x = h->GetRandom(rng);
3655 // skip in case bin is empty
3656 if (y > 0) {
3657 SetBinContent(ibin, y-1.);
3658 i--;
3659 }
3660 }
3661 }
3662
3663 ResetStats();
3664 return;
3665 }
3666 // case of different axis and not too large ntimes
3667
3668 if (h->ComputeIntegral() ==0) return;
3669 Int_t loop;
3670 Double_t x;
3671 for (loop=0;loop<ntimes;loop++) {
3672 x = h->GetRandom();
3673 Fill(x);
3674 }
3675}
3676
3677////////////////////////////////////////////////////////////////////////////////
3678/// Return Global bin number corresponding to x,y,z
3679///
3680/// 2-D and 3-D histograms are represented with a one dimensional
3681/// structure. This has the advantage that all existing functions, such as
3682/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3683/// This function tries to extend the axis if the given point belongs to an
3684/// under-/overflow bin AND if CanExtendAllAxes() is true.
3685///
3686/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3687
3689{
3690 if (GetDimension() < 2) {
3691 return fXaxis.FindBin(x);
3692 }
3693 if (GetDimension() < 3) {
3694 Int_t nx = fXaxis.GetNbins()+2;
3697 return binx + nx*biny;
3698 }
3699 if (GetDimension() < 4) {
3700 Int_t nx = fXaxis.GetNbins()+2;
3701 Int_t ny = fYaxis.GetNbins()+2;
3704 Int_t binz = fZaxis.FindBin(z);
3705 return binx + nx*(biny +ny*binz);
3706 }
3707 return -1;
3708}
3709
3710////////////////////////////////////////////////////////////////////////////////
3711/// Return Global bin number corresponding to x,y,z.
3712///
3713/// 2-D and 3-D histograms are represented with a one dimensional
3714/// structure. This has the advantage that all existing functions, such as
3715/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3716/// This function DOES NOT try to extend the axis if the given point belongs
3717/// to an under-/overflow bin.
3718///
3719/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3720
3722{
3723 if (GetDimension() < 2) {
3724 return fXaxis.FindFixBin(x);
3725 }
3726 if (GetDimension() < 3) {
3727 Int_t nx = fXaxis.GetNbins()+2;
3730 return binx + nx*biny;
3731 }
3732 if (GetDimension() < 4) {
3733 Int_t nx = fXaxis.GetNbins()+2;
3734 Int_t ny = fYaxis.GetNbins()+2;
3738 return binx + nx*(biny +ny*binz);
3739 }
3740 return -1;
3741}
3742
3743////////////////////////////////////////////////////////////////////////////////
3744/// Find first bin with content > threshold for axis (1=x, 2=y, 3=z)
3745/// if no bins with content > threshold is found the function returns -1.
3746/// The search will occur between the specified first and last bin. Specifying
3747/// the value of the last bin to search to less than zero will search until the
3748/// last defined bin.
3749
3751{
3752 if (fBuffer) ((TH1*)this)->BufferEmpty();
3753
3754 if (axis < 1 || (axis > 1 && GetDimension() == 1 ) ||
3755 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3 ) ) {
3756 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3757 axis = 1;
3758 }
3759 if (firstBin < 1) {
3760 firstBin = 1;
3761 }
3763 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3764 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3765
3766 if (axis == 1) {
3769 }
3770 for (Int_t binx = firstBin; binx <= lastBin; binx++) {
3771 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3772 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3774 }
3775 }
3776 }
3777 }
3778 else if (axis == 2) {
3781 }
3782 for (Int_t biny = firstBin; biny <= lastBin; biny++) {
3783 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3784 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3786 }
3787 }
3788 }
3789 }
3790 else if (axis == 3) {
3793 }
3794 for (Int_t binz = firstBin; binz <= lastBin; binz++) {
3795 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3796 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3798 }
3799 }
3800 }
3801 }
3802
3803 return -1;
3804}
3805
3806////////////////////////////////////////////////////////////////////////////////
3807/// Find last bin with content > threshold for axis (1=x, 2=y, 3=z)
3808/// if no bins with content > threshold is found the function returns -1.
3809/// The search will occur between the specified first and last bin. Specifying
3810/// the value of the last bin to search to less than zero will search until the
3811/// last defined bin.
3812
3814{
3815 if (fBuffer) ((TH1*)this)->BufferEmpty();
3816
3817
3818 if (axis < 1 || ( axis > 1 && GetDimension() == 1 ) ||
3819 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3) ) {
3820 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3821 axis = 1;
3822 }
3823 if (firstBin < 1) {
3824 firstBin = 1;
3825 }
3827 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3828 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3829
3830 if (axis == 1) {
3833 }
3834 for (Int_t binx = lastBin; binx >= firstBin; binx--) {
3835 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3836 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3838 }
3839 }
3840 }
3841 }
3842 else if (axis == 2) {
3845 }
3846 for (Int_t biny = lastBin; biny >= firstBin; biny--) {
3847 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3848 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3850 }
3851 }
3852 }
3853 }
3854 else if (axis == 3) {
3857 }
3858 for (Int_t binz = lastBin; binz >= firstBin; binz--) {
3859 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3860 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3862 }
3863 }
3864 }
3865 }
3866
3867 return -1;
3868}
3869
3870////////////////////////////////////////////////////////////////////////////////
3871/// Search object named name in the list of functions.
3872
3873TObject *TH1::FindObject(const char *name) const
3874{
3875 if (fFunctions) return fFunctions->FindObject(name);
3876 return nullptr;
3877}
3878
3879////////////////////////////////////////////////////////////////////////////////
3880/// Search object obj in the list of functions.
3881
3882TObject *TH1::FindObject(const TObject *obj) const
3883{
3884 if (fFunctions) return fFunctions->FindObject(obj);
3885 return nullptr;
3886}
3887
3888////////////////////////////////////////////////////////////////////////////////
3889/// Fit histogram with function fname.
3890///
3891///
3892/// fname is the name of a function available in the global ROOT list of functions
3893/// `gROOT->GetListOfFunctions`. Note that this is not thread safe.
3894/// The list include any TF1 object created by the user plus some pre-defined functions
3895/// which are automatically created by ROOT the first time a pre-defined function is requested from `gROOT`
3896/// (i.e. when calling `gROOT->GetFunction(const char *name)`).
3897/// These pre-defined functions are:
3898/// - `gaus, gausn` where gausn is the normalized Gaussian
3899/// - `landau, landaun`
3900/// - `expo`
3901/// - `pol1,...9, chebyshev1,...9`.
3902///
3903/// For printing the list of all available functions do:
3904///
3905/// TF1::InitStandardFunctions(); // not needed if `gROOT->GetFunction` is called before
3906/// TF2::InitStandardFunctions(); TF3::InitStandardFunctions(); // For 2D or 3D
3907/// gROOT->GetListOfFunctions()->ls()
3908///
3909/// `fname` can also be a formula that is accepted by the linear fitter containing the special operator `++`,
3910/// representing linear components separated by `++` sign, for example `x++sin(x)` for fitting `[0]*x+[1]*sin(x)`
3911///
3912/// This function finds a pointer to the TF1 object with name `fname` and calls TH1::Fit(TF1 *, Option_t *, Option_t *,
3913/// Double_t, Double_t). See there for the fitting options and the details about fitting histograms
3914
3916{
3917 char *linear;
3918 linear= (char*)strstr(fname, "++");
3919 Int_t ndim=GetDimension();
3920 if (linear){
3921 if (ndim<2){
3923 return Fit(&f1,option,goption,xxmin,xxmax);
3924 }
3925 else if (ndim<3){
3926 TF2 f2(fname, fname);
3927 return Fit(&f2,option,goption,xxmin,xxmax);
3928 }
3929 else{
3930 TF3 f3(fname, fname);
3931 return Fit(&f3,option,goption,xxmin,xxmax);
3932 }
3933 }
3934 else{
3935 TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
3936 if (!f1) { Printf("Unknown function: %s",fname); return -1; }
3937 return Fit(f1,option,goption,xxmin,xxmax);
3938 }
3939}
3940
3941////////////////////////////////////////////////////////////////////////////////
3942/// Fit histogram with the function pointer f1.
3943///
3944/// \param[in] f1 pointer to the function object
3945/// \param[in] option string defining the fit options (see table below).
3946/// \param[in] goption specify a list of graphics options. See TH1::Draw for a complete list of these options.
3947/// \param[in] xxmin lower fitting range
3948/// \param[in] xxmax upper fitting range
3949/// \return A smart pointer to the TFitResult class
3950///
3951/// \anchor HFitOpt
3952/// ### Histogram Fitting Options
3953///
3954/// Here is the full list of fit options that can be given in the parameter `option`.
3955/// Several options can be used together by concatanating the strings without the need of any delimiters.
3956///
3957/// option | description
3958/// -------|------------
3959/// "L" | Uses a log likelihood method (default is chi-square method). To be used when the histogram represents counts.
3960/// "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.
3961/// "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.
3962/// "MULTI" | Uses Loglikelihood method based on multi-nomial distribution. In this case the function must be normalized and one fits only the function shape.
3963/// "W" | Fit using the chi-square method and ignoring the bin uncertainties and skip empty bins.
3964/// "WW" | Fit using the chi-square method and ignoring the bin uncertainties and include the empty bins.
3965/// "I" | Uses the integral of function in the bin instead of the default bin center value.
3966/// "F" | Uses the default minimizer (e.g. Minuit) when fitting a linear function (e.g. polN) instead of the linear fitter.
3967/// "U" | Uses a user specified objective function (e.g. user providedlikelihood function) defined using `TVirtualFitter::SetFCN`
3968/// "E" | Performs a better parameter errors estimation using the Minos technique for all fit parameters.
3969/// "M" | Uses the IMPROVE algorithm (available only in TMinuit). This algorithm attempts improve the found local minimum by searching for a better one.
3970/// "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`.
3971/// "Q" | Quiet mode (minimum printing)
3972/// "V" | Verbose mode (default is between Q and V)
3973/// "+" | 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.
3974/// "N" | Does not store the graphics function, does not draw the histogram with the function after fitting.
3975/// "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.
3976/// "R" | Fit using a fitting range specified in the function range with `TF1::SetRange`.
3977/// "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.
3978/// "C" | In case of linear fitting, do no calculate the chisquare (saves CPU time).
3979/// "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.
3980/// "WIDTH" | Scales the histogran bin content by the bin width (useful for variable bins histograms)
3981/// "SERIAL" | Runs in serial mode. By default if ROOT is built with MT support and MT is enables, the fit is perfomed in multi-thread - "E" Perform better Errors estimation using Minos technique
3982/// "MULTITHREAD" | Forces usage of multi-thread execution whenever possible
3983///
3984/// The default fitting of an histogram (when no option is given) is perfomed as following:
3985/// - a chi-square fit (see below Chi-square Fits) computed using the bin histogram errors and excluding bins with zero errors (empty bins);
3986/// - the full range of the histogram is used, unless TAxis::SetRange or TAxis::SetRangeUser was called before;
3987/// - the default Minimizer with its default configuration is used (see below Minimizer Configuration) except for linear function;
3988/// - for linear functions (`polN`, `chenbyshev` or formula expressions combined using operator `++`) a linear minimization is used.
3989/// - only the status of the fit is returned;
3990/// - the fit is performed in Multithread whenever is enabled in ROOT;
3991/// - only the last fitted function is saved in the histogram;
3992/// - the histogram is drawn after fitting overalyed with the resulting fitting function
3993///
3994/// \anchor HFitMinimizer
3995/// ### Minimizer Configuration
3996///
3997/// The Fit is perfomed using the default Minimizer, defined in the `ROOT::Math::MinimizerOptions` class.
3998/// It is possible to change the default minimizer and its configuration parameters by calling these static functions before fitting (before calling `TH1::Fit`):
3999/// - `ROOT::Math::MinimizerOptions::SetDefaultMinimizer(minimizerName, minimizerAgorithm)` for changing the minmizer and/or the corresponding algorithm.
4000/// For example `ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");` will set the usage of the BFGS algorithm of the GSL multi-dimensional minimization
4001/// The current defaults are ("Minuit","Migrad").
4002/// See the documentation of the `ROOT::Math::MinimizerOptions` for the available minimizers in ROOT and their corresponding algorithms.
4003/// - `ROOT::Math::MinimizerOptions::SetDefaultTolerance` for setting a different tolerance value for the minimization.
4004/// - `ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls` for setting the maximum number of function calls.
4005/// - `ROOT::Math::MinimizerOptions::SetDefaultPrintLevel` for changing the minimizer print level from level=0 (minimal printing) to level=3 maximum printing
4006///
4007/// Other options are possible depending on the Minimizer used, see the corresponding documentation.
4008/// The default minimizer can be also set in the resource file in etc/system.rootrc. For example
4009///
4010/// ~~~ {.cpp}
4011/// Root.Fitter: Minuit2
4012/// ~~~
4013///
4014/// \anchor HFitChi2
4015/// ### Chi-square Fits
4016///
4017/// By default a chi-square (least-square) fit is performed on the histogram. The so-called modified least-square method
4018/// is used where the residual for each bin is computed using as error the observed value (the bin error) returned by `TH1::GetBinError`
4019///
4020/// \f[
4021/// Chi2 = \sum_{i}{ \left(\frac{y(i) - f(x(i) | p )}{e(i)} \right)^2 }
4022/// \f]
4023///
4024/// 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
4025/// an un-weighted histogram). Bins with zero errors are excluded from the fit. See also later the note on the treatment
4026/// of empty bins. When using option "I" the residual is computed not using the function value at the bin center, `f(x(i)|p)`,
4027/// but the integral of the function in the bin, Integral{ f(x|p)dx }, divided by the bin volume.
4028/// When using option `P` (Pearson chi2), the expected error computed as `e(i) = sqrt(f(x(i)|p))` is used.
4029/// In this case empty bins are considered in the fit.
4030/// Both chi-square methods should not be used when the bin content represent counts, especially in case of low bin statistics,
4031/// because they could return a biased result.
4032///
4033/// \anchor HFitNLL
4034/// ### Likelihood Fits
4035///
4036/// When using option "L" a likelihood fit is used instead of the default chi-square fit.
4037/// The likelihood is built assuming a Poisson probability density function for each bin.
4038/// The negative log-likelihood to be minimized is
4039///
4040/// \f[
4041/// NLL = - \sum_{i}{ \log {\mathrm P} ( y(i) | f(x(i) | p ) ) }
4042/// \f]
4043/// 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)`.
4044/// The exact likelihood used is the Poisson likelihood described in this paper:
4045/// S. Baker and R. D. Cousins, “Clarification of the use of chi-square and likelihood functions in fits to histograms,”
4046/// Nucl. Instrum. Meth. 221 (1984) 437.
4047///
4048/// \f[
4049/// NLL = \sum_{i}{( f(x(i) | p ) + y(i)\log(y(i)/ f(x(i) | p )) - y(i)) }
4050/// \f]
4051/// By using this formulation, `2*NLL` can be interpreted as the chi-square resulting from the fit.
4052///
4053/// This method should be always used when the bin content represents counts (i.e. errors are sqrt(N) ).
4054/// The likelihood method has the advantage of treating correctly bins with low statistics. In case of high
4055/// statistics/bin the distribution of the bin content becomes a normal distribution and the likelihood and the chi2 fit
4056/// give the same result.
4057///
4058/// The likelihood method, although a bit slower, it is therefore the recommended method,
4059/// when the histogram represent counts (Poisson statistics), where the chi-square methods may
4060/// give incorrect results, especially in case of low statistics.
4061/// In case of a weighted histogram, it is possible to perform also a likelihood fit by using the
4062/// option "WL". Note a weighted histogram is a histogram which has been filled with weights and it
4063/// has the information on the sum of the weight square for each bin ( TH1::Sumw2() has been called).
4064/// The bin error for a weighted histogram is the square root of the sum of the weight square.
4065///
4066/// \anchor HFitRes
4067/// ### Fit Result
4068///
4069/// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
4070/// By default the TFitResultPtr contains only the status of the fit which is return by an
4071/// automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
4072///
4073/// ~~~ {.cpp}
4074/// Int_t fitStatus = h->Fit(myFunc);
4075/// ~~~
4076///
4077/// If the option "S" is instead used, TFitResultPtr behaves as a smart
4078/// pointer to the TFitResult object. This is useful for retrieving the full result information from the fit, such as the covariance matrix,
4079/// as shown in this example code:
4080///
4081/// ~~~ {.cpp}
4082/// TFitResultPtr r = h->Fit(myFunc,"S");
4083/// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
4084/// Double_t chi2 = r->Chi2(); // to retrieve the fit chi2
4085/// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
4086/// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
4087/// r->Print("V"); // print full information of fit including covariance matrix
4088/// r->Write(); // store the result in a file
4089/// ~~~
4090///
4091/// The fit parameters, error and chi-square (but not covariance matrix) can be retrieved also
4092/// directly from the fitted function that is passed to this call.
4093/// Given a pointer to an associated fitted function `myfunc`, one can retrieve the function/fit
4094/// parameters with calls such as:
4095///
4096/// ~~~ {.cpp}
4097/// Double_t chi2 = myfunc->GetChisquare();
4098/// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
4099/// Double_t err0 = myfunc->GetParError(0); //error on first parameter
4100/// ~~~
4101///
4102/// ##### Associated functions
4103///
4104/// One or more objects (typically a TF1*) can be added to the list
4105/// of functions (fFunctions) associated to each histogram.
4106/// When TH1::Fit is invoked, the fitted function is added to the histogram list of functions (fFunctions).
4107/// If the histogram is made persistent, the list of associated functions is also persistent.
4108/// Given a histogram h, one can retrieve an associated function with:
4109///
4110/// ~~~ {.cpp}
4111/// TF1 *myfunc = h->GetFunction("myfunc");
4112/// ~~~
4113/// or by quering directly the list obtained by calling `TH1::GetListOfFunctions`.
4114///
4115/// \anchor HFitStatus
4116/// ### Fit status
4117///
4118/// The status of the fit is obtained converting the TFitResultPtr to an integer
4119/// independently if the fit option "S" is used or not:
4120///
4121/// ~~~ {.cpp}
4122/// TFitResultPtr r = h->Fit(myFunc,opt);
4123/// Int_t fitStatus = r;
4124/// ~~~
4125///
4126/// - `status = 0` : the fit has been performed successfully (i.e no error occurred).
4127/// - `status < 0` : there is an error not connected with the minimization procedure, for example when a wrong function is used.
4128/// - `status > 0` : return status from Minimizer, depends on used Minimizer. For example for TMinuit and Minuit2 we have:
4129/// - `status = migradStatus + 10*minosStatus + 100*hesseStatus + 1000*improveStatus`.
4130/// 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
4131/// only in Minos but not in Migrad a fitStatus of 40 will be returned.
4132/// Minuit2 returns 0 in case of success and different values in migrad,minos or
4133/// hesse depending on the error. See in this case the documentation of
4134/// Minuit2Minimizer::Minimize for the migrad return status, Minuit2Minimizer::GetMinosError for the
4135/// minos return status and Minuit2Minimizer::Hesse for the hesse return status.
4136/// If other minimizers are used see their specific documentation for the status code returned.
4137/// For example in the case of Fumili, see TFumili::Minimize.
4138///
4139/// \anchor HFitRange
4140/// ### Fitting in a range
4141///
4142/// In order to fit in a sub-range of the histogram you have two options:
4143/// - pass to this function the lower (`xxmin`) and upper (`xxmax`) values for the fitting range;
4144/// - define a specific range in the fitted function and use the fitting option "R".
4145/// For example, if your histogram has a defined range between -4 and 4 and you want to fit a gaussian
4146/// only in the interval 1 to 3, you can do:
4147///
4148/// ~~~ {.cpp}
4149/// TF1 *f1 = new TF1("f1", "gaus", 1, 3);
4150/// histo->Fit("f1", "R");
4151/// ~~~
4152///
4153/// The fitting range is also limited by the histogram range defined using TAxis::SetRange
4154/// or TAxis::SetRangeUser. Therefore the fitting range is the smallest range between the
4155/// histogram one and the one defined by one of the two previous options described above.
4156///
4157/// \anchor HFitInitial
4158/// ### Setting initial conditions
4159///
4160/// Parameters must be initialized before invoking the Fit function.
4161/// The setting of the parameter initial values is automatic for the
4162/// predefined functions such as poln, expo, gaus, landau. One can however disable
4163/// this automatic computation by using the option "B".
4164/// Note that if a predefined function is defined with an argument,
4165/// eg, gaus(0), expo(1), you must specify the initial values for
4166/// the parameters.
4167/// You can specify boundary limits for some or all parameters via
4168///
4169/// ~~~ {.cpp}
4170/// f1->SetParLimits(p_number, parmin, parmax);
4171/// ~~~
4172///
4173/// if `parmin >= parmax`, the parameter is fixed
4174/// Note that you are not forced to fix the limits for all parameters.
4175/// For example, if you fit a function with 6 parameters, you can do:
4176///
4177/// ~~~ {.cpp}
4178/// func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
4179/// func->SetParLimits(3, -10, -4);
4180/// func->FixParameter(4, 0);
4181/// func->SetParLimits(5, 1, 1);
4182/// ~~~
4183///
4184/// With this setup, parameters 0->2 can vary freely
4185/// Parameter 3 has boundaries [-10,-4] with initial value -8
4186/// Parameter 4 is fixed to 0
4187/// Parameter 5 is fixed to 100.
4188/// When the lower limit and upper limit are equal, the parameter is fixed.
4189/// However to fix a parameter to 0, one must call the FixParameter function.
4190///
4191/// \anchor HFitStatBox
4192/// ### Fit Statistics Box
4193///
4194/// The statistics box can display the result of the fit.
4195/// You can change the statistics box to display the fit parameters with
4196/// the TStyle::SetOptFit(mode) method. This mode has four digits.
4197/// mode = pcev (default = 0111)
4198///
4199/// v = 1; print name/values of parameters
4200/// e = 1; print errors (if e=1, v must be 1)
4201/// c = 1; print Chisquare/Number of degrees of freedom
4202/// p = 1; print Probability
4203///
4204/// For example: gStyle->SetOptFit(1011);
4205/// prints the fit probability, parameter names/values, and errors.
4206/// You can change the position of the statistics box with these lines
4207/// (where g is a pointer to the TGraph):
4208///
4209/// TPaveStats *st = (TPaveStats*)g->GetListOfFunctions()->FindObject("stats");
4210/// st->SetX1NDC(newx1); //new x start position
4211/// st->SetX2NDC(newx2); //new x end position
4212///
4213/// \anchor HFitExtra
4214/// ### Additional Notes on Fitting
4215///
4216/// #### Fitting a histogram of dimension N with a function of dimension N-1
4217///
4218/// It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
4219/// 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.
4220/// For correct error scaling, the obtained parameter error are corrected as in the case when the
4221/// option "W" is used.
4222///
4223/// #### User defined objective functions
4224///
4225/// By default when fitting a chi square function is used for fitting. When option "L" is used
4226/// a Poisson likelihood function is used. Using option "MULTI" a multinomial likelihood fit is used.
4227/// Thes functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
4228/// are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
4229/// the file math/mathcore/src/FitUtil.cxx.
4230/// It is possible to specify a user defined fitting function, using option "U" and
4231/// calling the following functions:
4232///
4233/// ~~~ {.cpp}
4234/// TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction);
4235/// ~~~
4236///
4237/// where MyFittingFunction is of type:
4238///
4239/// ~~~ {.cpp}
4240/// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
4241/// ~~~
4242///
4243/// #### Note on treatment of empty bins
4244///
4245/// Empty bins, which have the content equal to zero AND error equal to zero,
4246/// are excluded by default from the chi-square fit, but they are considered in the likelihood fit.
4247/// since they affect the likelihood if the function value in these bins is not negligible.
4248/// Note that if the histogram is having bins with zero content and non zero-errors they are considered as
4249/// any other bins in the fit. Instead bins with zero error and non-zero content are by default excluded in the chi-squared fit.
4250/// In general, one should not fit a histogram with non-empty bins and zero errors.
4251///
4252/// 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
4253/// fit). When using option "WW" the empty bins will be also considered in the chi-square fit with an error of 1.
4254/// Note that in this fitting case (option "W" or "WW") the resulting fitted parameter errors
4255/// are corrected by the obtained chi2 value using this scaling expression:
4256/// `errorp *= sqrt(chisquare/(ndf-1))` as it is done when fitting a TGraph with
4257/// no point errors.
4258///
4259/// #### Excluding points
4260///
4261/// You can use TF1::RejectPoint inside your fitting function to exclude some points
4262/// within a certain range from the fit. See the tutorial `fit/fitExclude.C`.
4263///
4264///
4265/// #### Warning when using the option "0"
4266///
4267/// When selecting the option "0", the fitted function is added to
4268/// the list of functions of the histogram, but it is not drawn when the histogram is drawn.
4269/// You can undo this behaviour resetting its corresponding bit in the TF1 object as following:
4270///
4271/// ~~~ {.cpp}
4272/// h.Fit("myFunction", "0"); // fit, store function but do not draw
4273/// h.Draw(); // function is not drawn
4274/// h.GetFunction("myFunction")->ResetBit(TF1::kNotDraw);
4275/// h.Draw(); // function is visible again
4276/// ~~~
4278
4280{
4281 // implementation of Fit method is in file hist/src/HFitImpl.cxx
4284
4285 // create range and minimizer options with default values
4288
4289 // need to empty the buffer before
4290 // (t.b.d. do a ML unbinned fit with buffer data)
4291 if (fBuffer) BufferEmpty();
4292
4294}
4295
4296////////////////////////////////////////////////////////////////////////////////
4297/// Display a panel with all histogram fit options.
4298///
4299/// See class TFitPanel for example
4300
4301void TH1::FitPanel()
4302{
4303 if (!gPad)
4304 gROOT->MakeDefCanvas();
4305
4306 if (!gPad) {
4307 Error("FitPanel", "Unable to create a default canvas");
4308 return;
4309 }
4310
4311
4312 // use plugin manager to create instance of TFitEditor
4313 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
4314 if (handler && handler->LoadPlugin() != -1) {
4315 if (handler->ExecPlugin(2, gPad, this) == 0)
4316 Error("FitPanel", "Unable to create the FitPanel");
4317 }
4318 else
4319 Error("FitPanel", "Unable to find the FitPanel plug-in");
4320}
4321
4322////////////////////////////////////////////////////////////////////////////////
4323/// Return a histogram containing the asymmetry of this histogram with h2,
4324/// where the asymmetry is defined as:
4325///
4326/// ~~~ {.cpp}
4327/// Asymmetry = (h1 - h2)/(h1 + h2) where h1 = this
4328/// ~~~
4329///
4330/// works for 1D, 2D, etc. histograms
4331/// c2 is an optional argument that gives a relative weight between the two
4332/// histograms, and dc2 is the error on this weight. This is useful, for example,
4333/// when forming an asymmetry between two histograms from 2 different data sets that
4334/// need to be normalized to each other in some way. The function calculates
4335/// the errors assuming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
4336///
4337/// example: assuming 'h1' and 'h2' are already filled
4338///
4339/// ~~~ {.cpp}
4340/// h3 = h1->GetAsymmetry(h2)
4341/// ~~~
4342///
4343/// then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
4344/// h1 and h2 are left intact.
4345///
4346/// Note that it is the user's responsibility to manage the created histogram.
4347/// The name of the returned histogram will be `Asymmetry_nameOfh1-nameOfh2`
4348///
4349/// code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
4350///
4351/// clone the histograms so top and bottom will have the
4352/// correct dimensions:
4353/// Sumw2 just makes sure the errors will be computed properly
4354/// when we form sums and ratios below.
4355
4357{
4358 TH1 *h1 = this;
4359 TString name = TString::Format("Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4360 TH1 *asym = (TH1*)Clone(name);
4361
4362 // set also the title
4363 TString title = TString::Format("(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4364 asym->SetTitle(title);
4365
4366 asym->Sumw2();
4369 TH1 *top = (TH1*)asym->Clone();
4370 TH1 *bottom = (TH1*)asym->Clone();
4372
4373 // form the top and bottom of the asymmetry, and then divide:
4374 top->Add(h1,h2,1,-c2);
4375 bottom->Add(h1,h2,1,c2);
4376 asym->Divide(top,bottom);
4377
4378 Int_t xmax = asym->GetNbinsX();
4379 Int_t ymax = asym->GetNbinsY();
4380 Int_t zmax = asym->GetNbinsZ();
4381
4382 if (h1->fBuffer) h1->BufferEmpty(1);
4383 if (h2->fBuffer) h2->BufferEmpty(1);
4384 if (bottom->fBuffer) bottom->BufferEmpty(1);
4385
4386 // now loop over bins to calculate the correct errors
4387 // the reason this error calculation looks complex is because of c2
4388 for(Int_t i=1; i<= xmax; i++){
4389 for(Int_t j=1; j<= ymax; j++){
4390 for(Int_t k=1; k<= zmax; k++){
4391 Int_t bin = GetBin(i, j, k);
4392 // here some bin contents are written into variables to make the error
4393 // calculation a little more legible:
4395 Double_t b = h2->RetrieveBinContent(bin);
4396 Double_t bot = bottom->RetrieveBinContent(bin);
4397
4398 // make sure there are some events, if not, then the errors are set = 0
4399 // automatically.
4400 //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
4401 if(bot < 1e-6){}
4402 else{
4403 // computation of errors by Christos Leonidopoulos
4405 Double_t dbsq = h2->GetBinErrorSqUnchecked(bin);
4406 Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4407 asym->SetBinError(i,j,k,error);
4408 }
4409 }
4410 }
4411 }
4412 delete top;
4413 delete bottom;
4414
4415 return asym;
4416}
4417
4418////////////////////////////////////////////////////////////////////////////////
4419/// Static function
4420/// return the default buffer size for automatic histograms
4421/// the parameter fgBufferSize may be changed via SetDefaultBufferSize
4422
4424{
4425 return fgBufferSize;
4426}
4427
4428////////////////////////////////////////////////////////////////////////////////
4429/// Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
4430/// see TH1::SetDefaultSumw2.
4431
4433{
4434 return fgDefaultSumw2;
4435}
4436
4437////////////////////////////////////////////////////////////////////////////////
4438/// Return the current number of entries.
4439
4441{
4442 if (fBuffer) {
4443 Int_t nentries = (Int_t) fBuffer[0];
4444 if (nentries > 0) return nentries;
4445 }
4446
4447 return fEntries;
4448}
4449
4450////////////////////////////////////////////////////////////////////////////////
4451/// Number of effective entries of the histogram.
4452///
4453/// \f[
4454/// neff = \frac{(\sum Weights )^2}{(\sum Weight^2 )}
4455/// \f]
4456///
4457/// In case of an unweighted histogram this number is equivalent to the
4458/// number of entries of the histogram.
4459/// For a weighted histogram, this number corresponds to the hypothetical number of unweighted entries
4460/// a histogram would need to have the same statistical power as this weighted histogram.
4461/// Note: The underflow/overflow are included if one has set the TH1::StatOverFlows flag
4462/// and if the statistics has been computed at filling time.
4463/// If a range is set in the histogram the number is computed from the given range.
4464
4466{
4467 Stat_t s[kNstat];
4468 this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
4469 return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4470}
4471
4472////////////////////////////////////////////////////////////////////////////////
4473/// Shortcut to set the three histogram colors with a single call.
4474///
4475/// By default: linecolor = markercolor = fillcolor = -1
4476/// If a color is < 0 this method does not change the corresponding color if positive or null it set the color.
4477///
4478/// For instance:
4479/// ~~~ {.cpp}
4480/// h->SetColors(kRed, kRed);
4481/// ~~~
4482/// will set the line color and the marker color to red.
4483
4485{
4486 if (linecolor >= 0)
4488 if (markercolor >= 0)
4490 if (fillcolor >= 0)
4492}
4493
4494
4495////////////////////////////////////////////////////////////////////////////////
4496/// Set highlight (enable/disable) mode for the histogram
4497/// by default highlight mode is disable
4498
4499void TH1::SetHighlight(Bool_t set)
4500{
4501 if (IsHighlight() == set)
4502 return;
4503 if (fDimension > 2) {
4504 Info("SetHighlight", "Supported only 1-D or 2-D histograms");
4505 return;
4506 }
4507
4508 SetBit(kIsHighlight, set);
4509
4510 if (fPainter)
4512}
4513
4514////////////////////////////////////////////////////////////////////////////////
4515/// Redefines TObject::GetObjectInfo.
4516/// Displays the histogram info (bin number, contents, integral up to bin
4517/// corresponding to cursor position px,py
4518
4519char *TH1::GetObjectInfo(Int_t px, Int_t py) const
4520{
4521 return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
4522}
4523
4524////////////////////////////////////////////////////////////////////////////////
4525/// Return pointer to painter.
4526/// If painter does not exist, it is created
4527
4529{
4530 if (!fPainter) {
4531 TString opt = option;
4532 opt.ToLower();
4533 if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
4534 //try to create TGLHistPainter
4535 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
4536
4537 if (handler && handler->LoadPlugin() != -1)
4538 fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
4539 }
4540 }
4541
4543
4544 return fPainter;
4545}
4546
4547////////////////////////////////////////////////////////////////////////////////
4548/// Compute Quantiles for this histogram.
4549/// A quantile x_p := Q(p) is defined as the value x_p such that the cumulative
4550/// probability distribution Function F of variable X yields:
4551///
4552/// ~~~ {.cpp}
4553/// F(x_p) = Pr(X <= x_p) = p with 0 <= p <= 1.
4554/// x_p = Q(p) = F_inv(p)
4555/// ~~~
4556///
4557/// For instance the median x_0.5 of a distribution is defined as that value
4558/// of the random variable X for which the distribution function equals 0.5:
4559///
4560/// ~~~ {.cpp}
4561/// F(x_0.5) = Probability(X < x_0.5) = 0.5
4562/// x_0.5 = Q(0.5)
4563/// ~~~
4564///
4565/// \author Eddy Offermann
4566/// code from Eddy Offermann, Renaissance
4567///
4568/// \param[in] n maximum size of the arrays xp and p (if given)
4569/// \param[out] xp array to be filled with nq quantiles evaluated at (p). Memory has to be preallocated by caller.
4570/// - If `p == nullptr`, the quantiles are computed at the (first `n`) probabilities p given by the CDF of the histogram;
4571/// `n` must thus be smaller or equal Nbins+1, otherwise the extra values of `xp` will not be filled and `nq` will be smaller than `n`.
4572/// If all bins have non-zero entries, the quantiles happen to be the bin centres.
4573/// Empty bins will, however, be skipped in the quantiles.
4574/// If the CDF is e.g. [0., 0., 0.1, ...], the quantiles would be, [3., 3., 3., ...], with the third bin starting
4575/// at 3.
4576/// \param[in] p array of cumulative probabilities where quantiles should be evaluated.
4577/// - if `p == nullptr`, the CDF of the histogram will be used to compute the quantiles, and will
4578/// have a size of n.
4579/// - Otherwise, it is assumed to contain at least n values.
4580/// \return number of quantiles computed
4581/// \note Unlike in TF1::GetQuantiles, `p` is here an optional argument
4582///
4583/// Note that the Integral of the histogram is automatically recomputed
4584/// if the number of entries is different of the number of entries when
4585/// the integral was computed last time. In case you do not use the Fill
4586/// functions to fill your histogram, but SetBinContent, you must call
4587/// TH1::ComputeIntegral before calling this function.
4588///
4589/// Getting quantiles xp from two histograms and storing results in a TGraph,
4590/// a so-called QQ-plot
4591///
4592/// ~~~ {.cpp}
4593/// TGraph *gr = new TGraph(nprob);
4594/// h1->GetQuantiles(nprob,gr->GetX());
4595/// h2->GetQuantiles(nprob,gr->GetY());
4596/// gr->Draw("alp");
4597/// ~~~
4598///
4599/// Example:
4600///
4601/// ~~~ {.cpp}
4602/// void quantiles() {
4603/// // demo for quantiles
4604/// const Int_t nq = 20;
4605/// TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
4606/// h->FillRandom("gaus",5000);
4607/// h->GetXaxis()->SetTitle("x");
4608/// h->GetYaxis()->SetTitle("Counts");
4609///
4610/// Double_t p[nq]; // probabilities where to evaluate the quantiles in [0,1]
4611/// Double_t xp[nq]; // array of positions X to store the resulting quantiles
4612/// for (Int_t i=0;i<nq;i++) p[i] = Float_t(i+1)/nq;
4613/// h->GetQuantiles(nq,xp,p);
4614///
4615/// //show the original histogram in the top pad
4616/// TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
4617/// c1->Divide(1,2);
4618/// c1->cd(1);
4619/// h->Draw();
4620///
4621/// // show the quantiles in the bottom pad
4622/// c1->cd(2);
4623/// gPad->SetGrid();
4624/// TGraph *gr = new TGraph(nq,p,xp);
4625/// gr->SetMarkerStyle(21);
4626/// gr->GetXaxis()->SetTitle("p");
4627/// gr->GetYaxis()->SetTitle("x");
4628/// gr->Draw("alp");
4629/// }
4630/// ~~~
4631
4633{
4634 if (GetDimension() > 1) {
4635 Error("GetQuantiles","Only available for 1-d histograms");
4636 return 0;
4637 }
4638
4639 const Int_t nbins = GetXaxis()->GetNbins();
4640 if (!fIntegral) ComputeIntegral();
4641 if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4642
4643 Int_t i, ibin;
4644 Int_t nq = n;
4645 std::unique_ptr<Double_t[]> localProb;
4646 if (p == nullptr) {
4647 nq = nbins+1;
4648 localProb.reset(new Double_t[nq]);
4649 localProb[0] = 0;
4650 for (i=1;i<nq;i++) {
4651 localProb[i] = fIntegral[i] / fIntegral[nbins];
4652 }
4653 }
4654 Double_t const *const prob = p ? p : localProb.get();
4655
4656 for (i = 0; i < nq; i++) {
4658 if (fIntegral[ibin] == prob[i]) {
4659 if (prob[i] == 0.) {
4660 for (; ibin+1 <= nbins && fIntegral[ibin+1] == 0.; ++ibin) {
4661
4662 }
4663 xp[i] = fXaxis.GetBinUpEdge(ibin);
4664 }
4665 else if (prob[i] == 1.) {
4666 xp[i] = fXaxis.GetBinUpEdge(ibin);
4667 }
4668 else {
4669 // Find equal integral in later bins (ie their entries are zero)
4670 Double_t width = 0;
4671 for (Int_t j = ibin+1; j <= nbins; ++j) {
4672 if (prob[i] == fIntegral[j]) {
4674 }
4675 else
4676 break;
4677 }
4679 }
4680 }
4681 else {
4682 xp[i] = GetBinLowEdge(ibin+1);
4684 if (dint > 0) xp[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4685 }
4686 }
4687
4688 return nq;
4689}
4690
4691////////////////////////////////////////////////////////////////////////////////
4697 return 1;
4698}
4699
4700////////////////////////////////////////////////////////////////////////////////
4701/// Compute Initial values of parameters for a gaussian.
4702
4703void H1InitGaus()
4704{
4705 Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4706 Int_t bin;
4707 const Double_t sqrtpi = 2.506628;
4708
4709 // - Compute mean value and StdDev of the histogram in the given range
4711 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4712 Int_t hxfirst = hFitter->GetXfirst();
4713 Int_t hxlast = hFitter->GetXlast();
4714 Double_t valmax = curHist->GetBinContent(hxfirst);
4715 Double_t binwidx = curHist->GetBinWidth(hxfirst);
4716 allcha = sumx = sumx2 = 0;
4717 for (bin=hxfirst;bin<=hxlast;bin++) {
4718 x = curHist->GetBinCenter(bin);
4719 val = TMath::Abs(curHist->GetBinContent(bin));
4720 if (val > valmax) valmax = val;
4721 sumx += val*x;
4722 sumx2 += val*x*x;
4723 allcha += val;
4724 }
4725 if (allcha == 0) return;
4726 mean = sumx/allcha;
4727 stddev = sumx2/allcha - mean*mean;
4728 if (stddev > 0) stddev = TMath::Sqrt(stddev);
4729 else stddev = 0;
4730 if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4731 //if the distribution is really gaussian, the best approximation
4732 //is binwidx*allcha/(sqrtpi*stddev)
4733 //However, in case of non-gaussian tails, this underestimates
4734 //the normalisation constant. In this case the maximum value
4735 //is a better approximation.
4736 //We take the average of both quantities
4738
4739 //In case the mean value is outside the histo limits and
4740 //the StdDev is bigger than the range, we take
4741 // mean = center of bins
4742 // stddev = half range
4743 Double_t xmin = curHist->GetXaxis()->GetXmin();
4744 Double_t xmax = curHist->GetXaxis()->GetXmax();
4745 if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4746 mean = 0.5*(xmax+xmin);
4747 stddev = 0.5*(xmax-xmin);
4748 }
4749 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4751 f1->SetParameter(1,mean);
4753 f1->SetParLimits(2,0,10*stddev);
4754}
4755
4756////////////////////////////////////////////////////////////////////////////////
4757/// Compute Initial values of parameters for an exponential.
4758
4759void H1InitExpo()
4760{
4762 Int_t ifail;
4764 Int_t hxfirst = hFitter->GetXfirst();
4765 Int_t hxlast = hFitter->GetXlast();
4766 Int_t nchanx = hxlast - hxfirst + 1;
4767
4769
4770 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4772 f1->SetParameter(1,slope);
4773
4774}
4775
4776////////////////////////////////////////////////////////////////////////////////
4777/// Compute Initial values of parameters for a polynom.
4778
4779void H1InitPolynom()
4780{
4781 Double_t fitpar[25];
4782
4784 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4785 Int_t hxfirst = hFitter->GetXfirst();
4786 Int_t hxlast = hFitter->GetXlast();
4787 Int_t nchanx = hxlast - hxfirst + 1;
4788 Int_t npar = f1->GetNpar();
4789
4790 if (nchanx <=1 || npar == 1) {
4791 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4792 fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4793 } else {
4795 }
4796 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4797}
4798
4799////////////////////////////////////////////////////////////////////////////////
4800/// Least squares lpolynomial fitting without weights.
4801///
4802/// \param[in] n number of points to fit
4803/// \param[in] m number of parameters
4804/// \param[in] a array of parameters
4805///
4806/// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
4807/// (E.Keil. revised by B.Schorr, 23.10.1981.)
4808
4810{
4811 const Double_t zero = 0.;
4812 const Double_t one = 1.;
4813 const Int_t idim = 20;
4814
4815 Double_t b[400] /* was [20][20] */;
4816 Int_t i, k, l, ifail;
4818 Double_t da[20], xk, yk;
4819
4820 if (m <= 2) {
4821 H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4822 return;
4823 }
4824 if (m > idim || m > n) return;
4825 b[0] = Double_t(n);
4826 da[0] = zero;
4827 for (l = 2; l <= m; ++l) {
4828 b[l-1] = zero;
4829 b[m + l*20 - 21] = zero;
4830 da[l-1] = zero;
4831 }
4833 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4834 Int_t hxfirst = hFitter->GetXfirst();
4835 Int_t hxlast = hFitter->GetXlast();
4836 for (k = hxfirst; k <= hxlast; ++k) {
4837 xk = curHist->GetBinCenter(k);
4838 yk = curHist->GetBinContent(k);
4839 power = one;
4840 da[0] += yk;
4841 for (l = 2; l <= m; ++l) {
4842 power *= xk;
4843 b[l-1] += power;
4844 da[l-1] += power*yk;
4845 }
4846 for (l = 2; l <= m; ++l) {
4847 power *= xk;
4848 b[m + l*20 - 21] += power;
4849 }
4850 }
4851 for (i = 3; i <= m; ++i) {
4852 for (k = i; k <= m; ++k) {
4853 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4854 }
4855 }
4857
4858 for (i=0; i<m; ++i) a[i] = da[i];
4859
4860}
4861
4862////////////////////////////////////////////////////////////////////////////////
4863/// Least square linear fit without weights.
4864///
4865/// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
4866/// (added to LSQ by B. Schorr, 15.02.1982.)
4867
4869{
4871 Int_t i, n;
4873 Double_t fn, xk, yk;
4874 Double_t det;
4875
4876 n = TMath::Abs(ndata);
4877 ifail = -2;
4878 xbar = ybar = x2bar = xybar = 0;
4880 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4881 Int_t hxfirst = hFitter->GetXfirst();
4882 Int_t hxlast = hFitter->GetXlast();
4883 for (i = hxfirst; i <= hxlast; ++i) {
4884 xk = curHist->GetBinCenter(i);
4885 yk = curHist->GetBinContent(i);
4886 if (ndata < 0) {
4887 if (yk <= 0) yk = 1e-9;
4888 yk = TMath::Log(yk);
4889 }
4890 xbar += xk;
4891 ybar += yk;
4892 x2bar += xk*xk;
4893 xybar += xk*yk;
4894 }
4895 fn = Double_t(n);
4896 det = fn*x2bar - xbar*xbar;
4897 ifail = -1;
4898 if (det <= 0) {
4899 a0 = ybar/fn;
4900 a1 = 0;
4901 return;
4902 }
4903 ifail = 0;
4904 a0 = (x2bar*ybar - xbar*xybar) / det;
4905 a1 = (fn*xybar - xbar*ybar) / det;
4906
4907}
4908
4909////////////////////////////////////////////////////////////////////////////////
4910/// Extracted from CERN Program library routine DSEQN.
4911///
4912/// Translated to C++ by Rene Brun
4913
4915{
4917 Int_t nmjp1, i, j, l;
4918 Int_t im1, jp1, nm1, nmi;
4919 Double_t s1, s21, s22;
4920 const Double_t one = 1.;
4921
4922 /* Parameter adjustments */
4923 b_dim1 = idim;
4924 b_offset = b_dim1 + 1;
4925 b -= b_offset;
4926 a_dim1 = idim;
4927 a_offset = a_dim1 + 1;
4928 a -= a_offset;
4929
4930 if (idim < n) return;
4931
4932 ifail = 0;
4933 for (j = 1; j <= n; ++j) {
4934 if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
4935 a[j + j*a_dim1] = one / a[j + j*a_dim1];
4936 if (j == n) continue;
4937 jp1 = j + 1;
4938 for (l = jp1; l <= n; ++l) {
4939 a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4940 s1 = -a[l + (j+1)*a_dim1];
4941 for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4942 a[l + (j+1)*a_dim1] = -s1;
4943 }
4944 }
4945 if (k <= 0) return;
4946
4947 for (l = 1; l <= k; ++l) {
4948 b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
4949 }
4950 if (n == 1) return;
4951 for (l = 1; l <= k; ++l) {
4952 for (i = 2; i <= n; ++i) {
4953 im1 = i - 1;
4954 s21 = -b[i + l*b_dim1];
4955 for (j = 1; j <= im1; ++j) {
4956 s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
4957 }
4958 b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
4959 }
4960 nm1 = n - 1;
4961 for (i = 1; i <= nm1; ++i) {
4962 nmi = n - i;
4963 s22 = -b[nmi + l*b_dim1];
4964 for (j = 1; j <= i; ++j) {
4965 nmjp1 = n - j + 1;
4966 s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
4967 }
4968 b[nmi + l*b_dim1] = -s22;
4969 }
4970 }
4971}
4972
4973////////////////////////////////////////////////////////////////////////////////
4974/// Return Global bin number corresponding to binx,y,z.
4975///
4976/// 2-D and 3-D histograms are represented with a one dimensional
4977/// structure.
4978/// This has the advantage that all existing functions, such as
4979/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
4980///
4981/// In case of a TH1x, returns binx directly.
4982/// see TH1::GetBinXYZ for the inverse transformation.
4983///
4984/// Convention for numbering bins
4985///
4986/// For all histogram types: nbins, xlow, xup
4987///
4988/// - bin = 0; underflow bin
4989/// - bin = 1; first bin with low-edge xlow INCLUDED
4990/// - bin = nbins; last bin with upper-edge xup EXCLUDED
4991/// - bin = nbins+1; overflow bin
4992///
4993/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4994/// For example, assuming a 3-D histogram with binx,biny,binz, the function
4995///
4996/// ~~~ {.cpp}
4997/// Int_t bin = h->GetBin(binx,biny,binz);
4998/// ~~~
4999///
5000/// returns a global/linearized bin number. This global bin is useful
5001/// to access the bin information independently of the dimension.
5002
5004{
5005 Int_t ofx = fXaxis.GetNbins() + 1; // overflow bin
5006 if (binx < 0) binx = 0;
5007 if (binx > ofx) binx = ofx;
5008
5009 return binx;
5010}
5011
5012////////////////////////////////////////////////////////////////////////////////
5013/// Return binx, biny, binz corresponding to the global bin number globalbin
5014/// see TH1::GetBin function above
5015
5017{
5018 Int_t nx = fXaxis.GetNbins()+2;
5019 Int_t ny = fYaxis.GetNbins()+2;
5020
5021 if (GetDimension() == 1) {
5022 binx = binglobal%nx;
5023 biny = 0;
5024 binz = 0;
5025 return;
5026 }
5027 if (GetDimension() == 2) {
5028 binx = binglobal%nx;
5029 biny = ((binglobal-binx)/nx)%ny;
5030 binz = 0;
5031 return;
5032 }
5033 if (GetDimension() == 3) {
5034 binx = binglobal%nx;
5035 biny = ((binglobal-binx)/nx)%ny;
5036 binz = ((binglobal-binx)/nx -biny)/ny;
5037 }
5038}
5039
5040////////////////////////////////////////////////////////////////////////////////
5041/// Return a random number distributed according the histogram bin contents.
5042/// This function checks if the bins integral exists. If not, the integral
5043/// is evaluated, normalized to one.
5044///
5045/// @param rng (optional) Random number generator pointer used (default is gRandom)
5046/// @param option (optional) Set it to "width" if your non-uniform bin contents represent a density rather than counts
5047///
5048/// The integral is automatically recomputed if the number of entries
5049/// is not the same then when the integral was computed.
5050/// @note Only valid for 1-d histograms. Use GetRandom2 or GetRandom3 otherwise.
5051/// If the histogram has a bin with negative content, a NaN is returned.
5052
5054{
5055 if (fDimension > 1) {
5056 Error("GetRandom","Function only valid for 1-d histograms");
5057 return 0;
5058 }
5060 Double_t integral = 0;
5061 // compute integral checking that all bins have positive content (see ROOT-5894)
5062 if (fIntegral) {
5063 if (fIntegral[nbinsx + 1] != fEntries)
5064 integral = const_cast<TH1 *>(this)->ComputeIntegral(true, option);
5065 else integral = fIntegral[nbinsx];
5066 } else {
5067 integral = const_cast<TH1 *>(this)->ComputeIntegral(true, option);
5068 }
5069 if (integral == 0) return 0;
5070 // return a NaN in case some bins have negative content
5071 if (integral == TMath::QuietNaN() ) return TMath::QuietNaN();
5072
5073 Double_t r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
5076 if (r1 > fIntegral[ibin]) x +=
5078 return x;
5079}
5080
5081////////////////////////////////////////////////////////////////////////////////
5082/// Return content of bin number bin.
5083///
5084/// Implemented in TH1C,S,F,D
5085///
5086/// Convention for numbering bins
5087///
5088/// For all histogram types: nbins, xlow, xup
5089///
5090/// - bin = 0; underflow bin
5091/// - bin = 1; first bin with low-edge xlow INCLUDED
5092/// - bin = nbins; last bin with upper-edge xup EXCLUDED
5093/// - bin = nbins+1; overflow bin
5094///
5095/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
5096/// For example, assuming a 3-D histogram with binx,biny,binz, the function
5097///
5098/// ~~~ {.cpp}
5099/// Int_t bin = h->GetBin(binx,biny,binz);
5100/// ~~~
5101///
5102/// returns a global/linearized bin number. This global bin is useful
5103/// to access the bin information independently of the dimension.
5104
5106{
5107 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
5108 if (bin < 0) bin = 0;
5109 if (bin >= fNcells) bin = fNcells-1;
5110
5111 return RetrieveBinContent(bin);
5112}
5113
5114////////////////////////////////////////////////////////////////////////////////
5115/// Compute first binx in the range [firstx,lastx] for which
5116/// diff = abs(bin_content-c) <= maxdiff
5117///
5118/// In case several bins in the specified range with diff=0 are found
5119/// the first bin found is returned in binx.
5120/// In case several bins in the specified range satisfy diff <=maxdiff
5121/// the bin with the smallest difference is returned in binx.
5122/// In all cases the function returns the smallest difference.
5123///
5124/// NOTE1: if firstx <= 0, firstx is set to bin 1
5125/// if (lastx < firstx then firstx is set to the number of bins
5126/// ie if firstx=0 and lastx=0 (default) the search is on all bins.
5127///
5128/// NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
5129
5131{
5132 if (fDimension > 1) {
5133 binx = 0;
5134 Error("GetBinWithContent","function is only valid for 1-D histograms");
5135 return 0;
5136 }
5137
5138 if (fBuffer) ((TH1*)this)->BufferEmpty();
5139
5140 if (firstx <= 0) firstx = 1;
5141 if (lastx < firstx) lastx = fXaxis.GetNbins();
5142 Int_t binminx = 0;
5143 Double_t diff, curmax = 1.e240;
5144 for (Int_t i=firstx;i<=lastx;i++) {
5146 if (diff <= 0) {binx = i; return diff;}
5147 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
5148 }
5149 binx = binminx;
5150 return curmax;
5151}
5152
5153////////////////////////////////////////////////////////////////////////////////
5154/// Given a point x, approximates the value via linear interpolation
5155/// based on the two nearest bin centers
5156///
5157/// Andy Mastbaum 10/21/08
5158
5160{
5161 if (fBuffer) ((TH1*)this)->BufferEmpty();
5162
5164 Double_t x0,x1,y0,y1;
5165
5166 if(x<=GetBinCenter(1)) {
5167 return RetrieveBinContent(1);
5168 } else if(x>=GetBinCenter(GetNbinsX())) {
5169 return RetrieveBinContent(GetNbinsX());
5170 } else {
5171 if(x<=GetBinCenter(xbin)) {
5173 x0 = GetBinCenter(xbin-1);
5175 x1 = GetBinCenter(xbin);
5176 } else {
5178 x0 = GetBinCenter(xbin);
5180 x1 = GetBinCenter(xbin+1);
5181 }
5182 return y0 + (x-x0)*((y1-y0)/(x1-x0));
5183 }
5184}
5185
5186////////////////////////////////////////////////////////////////////////////////
5187/// 2d Interpolation. Not yet implemented.
5188
5190{
5191 Error("Interpolate","This function must be called with 1 argument for a TH1");
5192 return 0;
5193}
5194
5195////////////////////////////////////////////////////////////////////////////////
5196/// 3d Interpolation. Not yet implemented.
5197
5199{
5200 Error("Interpolate","This function must be called with 1 argument for a TH1");
5201 return 0;
5202}
5203
5204///////////////////////////////////////////////////////////////////////////////
5205/// Check if a histogram is empty
5206/// (this is a protected method used mainly by TH1Merger )
5207
5208Bool_t TH1::IsEmpty() const
5209{
5210 // if fTsumw or fentries are not zero histogram is not empty
5211 // need to use GetEntries() instead of fEntries in case of bugger histograms
5212 // so we will flash the buffer
5213 if (fTsumw != 0) return kFALSE;
5214 if (GetEntries() != 0) return kFALSE;
5215 // case fTSumw == 0 amd entries are also zero
5216 // this should not really happening, but if one sets content by hand
5217 // it can happen. a call to ResetStats() should be done in such cases
5218 double sumw = 0;
5219 for (int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
5220 return (sumw != 0) ? kFALSE : kTRUE;
5221}
5222
5223////////////////////////////////////////////////////////////////////////////////
5224/// Return true if the bin is overflow.
5225
5227{
5228 Int_t binx, biny, binz;
5229 GetBinXYZ(bin, binx, biny, binz);
5230
5231 if (iaxis == 0) {
5232 if ( fDimension == 1 )
5233 return binx >= GetNbinsX() + 1;
5234 if ( fDimension == 2 )
5235 return (binx >= GetNbinsX() + 1) ||
5236 (biny >= GetNbinsY() + 1);
5237 if ( fDimension == 3 )
5238 return (binx >= GetNbinsX() + 1) ||
5239 (biny >= GetNbinsY() + 1) ||
5240 (binz >= GetNbinsZ() + 1);
5241 return kFALSE;
5242 }
5243 if (iaxis == 1)
5244 return binx >= GetNbinsX() + 1;
5245 if (iaxis == 2)
5246 return biny >= GetNbinsY() + 1;
5247 if (iaxis == 3)
5248 return binz >= GetNbinsZ() + 1;
5249
5250 Error("IsBinOverflow","Invalid axis value");
5251 return kFALSE;
5252}
5253
5254////////////////////////////////////////////////////////////////////////////////
5255/// Return true if the bin is underflow.
5256/// If iaxis = 0 make OR with all axes otherwise check only for the given axis
5257
5259{
5260 Int_t binx, biny, binz;
5261 GetBinXYZ(bin, binx, biny, binz);
5262
5263 if (iaxis == 0) {
5264 if ( fDimension == 1 )
5265 return (binx <= 0);
5266 else if ( fDimension == 2 )
5267 return (binx <= 0 || biny <= 0);
5268 else if ( fDimension == 3 )
5269 return (binx <= 0 || biny <= 0 || binz <= 0);
5270 else
5271 return kFALSE;
5272 }
5273 if (iaxis == 1)
5274 return (binx <= 0);
5275 if (iaxis == 2)
5276 return (biny <= 0);
5277 if (iaxis == 3)
5278 return (binz <= 0);
5279
5280 Error("IsBinUnderflow","Invalid axis value");
5281 return kFALSE;
5282}
5283
5284////////////////////////////////////////////////////////////////////////////////
5285/// Reduce the number of bins for the axis passed in the option to the number of bins having a label.
5286/// The method will remove only the extra bins existing after the last "labeled" bin.
5287/// Note that if there are "un-labeled" bins present between "labeled" bins they will not be removed
5288
5290{
5292 TAxis *axis = nullptr;
5293 if (iaxis == 1) axis = GetXaxis();
5294 if (iaxis == 2) axis = GetYaxis();
5295 if (iaxis == 3) axis = GetZaxis();
5296 if (!axis) {
5297 Error("LabelsDeflate","Invalid axis option %s",ax);
5298 return;
5299 }
5300 if (!axis->GetLabels()) return;
5301
5302 // find bin with last labels
5303 // bin number is object ID in list of labels
5304 // therefore max bin number is number of bins of the deflated histograms
5305 TIter next(axis->GetLabels());
5306 TObject *obj;
5307 Int_t nbins = 0;
5308 while ((obj = next())) {
5309 Int_t ibin = obj->GetUniqueID();
5310 if (ibin > nbins) nbins = ibin;
5311 }
5312 if (nbins < 1) nbins = 1;
5313
5314 // Do nothing in case it was the last bin
5315 if (nbins==axis->GetNbins()) return;
5316
5317 TH1 *hold = (TH1*)IsA()->New();
5318 R__ASSERT(hold);
5319 hold->SetDirectory(nullptr);
5320 Copy(*hold);
5321
5322 Bool_t timedisp = axis->GetTimeDisplay();
5323 Double_t xmin = axis->GetXmin();
5324 Double_t xmax = axis->GetBinUpEdge(nbins);
5325 if (xmax <= xmin) xmax = xmin +nbins;
5326 axis->SetRange(0,0);
5327 axis->Set(nbins,xmin,xmax);
5328 SetBinsLength(-1); // reset the number of cells
5330 if (errors) fSumw2.Set(fNcells);
5331 axis->SetTimeDisplay(timedisp);
5332 // reset histogram content
5333 Reset("ICE");
5334
5335 //now loop on all bins and refill
5336 // NOTE that if the bins without labels have content
5337 // it will be put in the underflow/overflow.
5338 // For this reason we use AddBinContent method
5340 Int_t bin,binx,biny,binz;
5341 for (bin=0; bin < hold->fNcells; ++bin) {
5342 hold->GetBinXYZ(bin,binx,biny,binz);
5344 Double_t cu = hold->RetrieveBinContent(bin);
5346 if (errors) {
5347 fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5348 }
5349 }
5351 delete hold;
5352}
5353
5354////////////////////////////////////////////////////////////////////////////////
5355/// Double the number of bins for axis.
5356/// Refill histogram.
5357/// This function is called by TAxis::FindBin(const char *label)
5358
5360{
5362 TAxis *axis = nullptr;
5363 if (iaxis == 1) axis = GetXaxis();
5364 if (iaxis == 2) axis = GetYaxis();
5365 if (iaxis == 3) axis = GetZaxis();
5366 if (!axis) return;
5367
5368 TH1 *hold = (TH1*)IsA()->New();
5369 hold->SetDirectory(nullptr);
5370 Copy(*hold);
5371 hold->ResetBit(kMustCleanup);
5372
5373 Bool_t timedisp = axis->GetTimeDisplay();
5374 Int_t nbins = axis->GetNbins();
5375 Double_t xmin = axis->GetXmin();
5376 Double_t xmax = axis->GetXmax();
5377 xmax = xmin + 2*(xmax-xmin);
5378 axis->SetRange(0,0);
5379 // double the bins and recompute ncells
5380 axis->Set(2*nbins,xmin,xmax);
5381 SetBinsLength(-1);
5383 if (errors) fSumw2.Set(fNcells);
5384 axis->SetTimeDisplay(timedisp);
5385
5386 Reset("ICE"); // reset content and error
5387
5388 //now loop on all bins and refill
5390 Int_t bin,ibin,binx,biny,binz;
5391 for (ibin =0; ibin < hold->fNcells; ibin++) {
5392 // get the binx,y,z values . The x-y-z (axis) bin values will stay the same between new-old after the expanding
5393 hold->GetBinXYZ(ibin,binx,biny,binz);
5394 bin = GetBin(binx,biny,binz);
5395
5396 // underflow and overflow will be cleaned up because their meaning has been altered
5397 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5398 continue;
5399 }
5400 else {
5401 AddBinContent(bin, hold->RetrieveBinContent(ibin));
5402 if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5403 }
5404 }
5406 delete hold;
5407}
5408
5409////////////////////////////////////////////////////////////////////////////////
5410/// Sort bins with labels or set option(s) to draw axis with labels
5411/// \param[in] option
5412/// - "a" sort by alphabetic order
5413/// - ">" sort by decreasing values
5414/// - "<" sort by increasing values
5415/// - "h" draw labels horizontal
5416/// - "v" draw labels vertical
5417/// - "u" draw labels up (end of label right adjusted)
5418/// - "d" draw labels down (start of label left adjusted)
5419///
5420/// In case not all bins have labels sorting will work only in the case
5421/// the first `n` consecutive bins have all labels and sorting will be performed on
5422/// those label bins.
5423///
5424/// \param[in] ax axis
5425
5427{
5429 TAxis *axis = nullptr;
5430 if (iaxis == 1)
5431 axis = GetXaxis();
5432 if (iaxis == 2)
5433 axis = GetYaxis();
5434 if (iaxis == 3)
5435 axis = GetZaxis();
5436 if (!axis)
5437 return;
5438 THashList *labels = axis->GetLabels();
5439 if (!labels) {
5440 Warning("LabelsOption", "Axis %s has no labels!",axis->GetName());
5441 return;
5442 }
5443 TString opt = option;
5444 opt.ToLower();
5445 Int_t iopt = -1;
5446 if (opt.Contains("h")) {
5451 iopt = 0;
5452 }
5453 if (opt.Contains("v")) {
5458 iopt = 1;
5459 }
5460 if (opt.Contains("u")) {
5461 axis->SetBit(TAxis::kLabelsUp);
5465 iopt = 2;
5466 }
5467 if (opt.Contains("d")) {
5472 iopt = 3;
5473 }
5474 Int_t sort = -1;
5475 if (opt.Contains("a"))
5476 sort = 0;
5477 if (opt.Contains(">"))
5478 sort = 1;
5479 if (opt.Contains("<"))
5480 sort = 2;
5481 if (sort < 0) {
5482 if (iopt < 0)
5483 Error("LabelsOption", "%s is an invalid label placement option!",opt.Data());
5484 return;
5485 }
5486
5487 // Code works only if first n bins have labels if we uncomment following line
5488 // but we don't want to support this special case
5489 // Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5490
5491 // support only cases where each bin has a labels (should be when axis is alphanumeric)
5492 Int_t n = labels->GetSize();
5493 if (n != axis->GetNbins()) {
5494 // check if labels are all consecutive and starts from the first bin
5495 // in that case the current code will work fine
5496 Int_t firstLabelBin = axis->GetNbins()+1;
5497 Int_t lastLabelBin = -1;
5498 for (Int_t i = 0; i < n; ++i) {
5499 Int_t bin = labels->At(i)->GetUniqueID();
5500 if (bin < firstLabelBin) firstLabelBin = bin;
5501 if (bin > lastLabelBin) lastLabelBin = bin;
5502 }
5503 if (firstLabelBin != 1 || lastLabelBin-firstLabelBin +1 != n) {
5504 Error("LabelsOption", "%s of Histogram %s contains bins without labels. Sorting will not work correctly - return",
5505 axis->GetName(), GetName());
5506 return;
5507 }
5508 // case where label bins are consecutive starting from first bin will work
5509 // calling before a TH1::LabelsDeflate() will avoid this error message
5510 Warning("LabelsOption", "axis %s of Histogram %s has extra following bins without labels. Sorting will work only for first label bins",
5511 axis->GetName(), GetName());
5512 }
5513 std::vector<Int_t> a(n);
5514 std::vector<Int_t> b(n);
5515
5516
5517 Int_t i, j, k;
5518 std::vector<Double_t> cont;
5519 std::vector<Double_t> errors2;
5520 THashList *labold = new THashList(labels->GetSize(), 1);
5521 TIter nextold(labels);
5522 TObject *obj = nullptr;
5523 labold->AddAll(labels);
5524 labels->Clear();
5525
5526 // delete buffer if it is there since bins will be reordered.
5527 if (fBuffer)
5528 BufferEmpty(1);
5529
5530 if (sort > 0) {
5531 //---sort by values of bins
5532 if (GetDimension() == 1) {
5533 cont.resize(n);
5534 if (fSumw2.fN)
5535 errors2.resize(n);
5536 for (i = 0; i < n; i++) {
5537 cont[i] = RetrieveBinContent(i + 1);
5538 if (!errors2.empty())
5539 errors2[i] = GetBinErrorSqUnchecked(i + 1);
5540 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5541 a[i] = i;
5542 }
5543 if (sort == 1)
5544 TMath::Sort(n, cont.data(), a.data(), kTRUE); // sort by decreasing values
5545 else
5546 TMath::Sort(n, cont.data(), a.data(), kFALSE); // sort by increasing values
5547 for (i = 0; i < n; i++) {
5548 // use UpdateBinCOntent to not screw up histogram entries
5549 UpdateBinContent(i + 1, cont[b[a[i]] - 1]); // b[a[i]] returns bin number. .we need to subtract 1
5550 if (gDebug)
5551 Info("LabelsOption","setting bin %d value %f from bin %d label %s at pos %d ",
5552 i+1,cont[b[a[i]] - 1],b[a[i]],labold->At(a[i])->GetName(),a[i]);
5553 if (!errors2.empty())
5554 fSumw2.fArray[i + 1] = errors2[b[a[i]] - 1];
5555 }
5556 for (i = 0; i < n; i++) {
5557 obj = labold->At(a[i]);
5558 labels->Add(obj);
5559 obj->SetUniqueID(i + 1);
5560 }
5561 } else if (GetDimension() == 2) {
5562 std::vector<Double_t> pcont(n + 2);
5563 Int_t nx = fXaxis.GetNbins() + 2;
5564 Int_t ny = fYaxis.GetNbins() + 2;
5565 cont.resize((nx + 2) * (ny + 2));
5566 if (fSumw2.fN)
5567 errors2.resize((nx + 2) * (ny + 2));
5568 for (i = 0; i < nx; i++) {
5569 for (j = 0; j < ny; j++) {
5570 Int_t bin = GetBin(i,j);
5571 cont[i + nx * j] = RetrieveBinContent(bin);
5572 if (!errors2.empty())
5573 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5574 if (axis == GetXaxis())
5575 k = i - 1;
5576 else
5577 k = j - 1;
5578 if (k >= 0 && k < n) { // we consider underflow/overflows in y for ordering the bins
5579 pcont[k] += cont[i + nx * j];
5580 a[k] = k;
5581 }
5582 }
5583 }
5584 if (sort == 1)
5585 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5586 else
5587 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5588 for (i = 0; i < n; i++) {
5589 // iterate on old label list to find corresponding bin match
5590 TIter next(labold);
5591 UInt_t bin = a[i] + 1;
5592 while ((obj = next())) {
5593 if (obj->GetUniqueID() == (UInt_t)bin)
5594 break;
5595 else
5596 obj = nullptr;
5597 }
5598 if (!obj) {
5599 // this should not really happen
5600 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5601 return;
5602 }
5603
5604 labels->Add(obj);
5605 if (gDebug)
5606 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from order " << a[i] << " bin "
5607 << b[a[i]] << "content " << pcont[a[i]] << std::endl;
5608 }
5609 // need to set here new ordered labels - otherwise loop before does not work since labold and labels list
5610 // contain same objects
5611 for (i = 0; i < n; i++) {
5612 labels->At(i)->SetUniqueID(i + 1);
5613 }
5614 // set now the bin contents
5615 if (axis == GetXaxis()) {
5616 for (i = 0; i < n; i++) {
5617 Int_t ix = a[i] + 1;
5618 for (j = 0; j < ny; j++) {
5619 Int_t bin = GetBin(i + 1, j);
5620 UpdateBinContent(bin, cont[ix + nx * j]);
5621 if (!errors2.empty())
5622 fSumw2.fArray[bin] = errors2[ix + nx * j];
5623 }
5624 }
5625 } else {
5626 // using y axis
5627 for (i = 0; i < nx; i++) {
5628 for (j = 0; j < n; j++) {
5629 Int_t iy = a[j] + 1;
5630 Int_t bin = GetBin(i, j + 1);
5631 UpdateBinContent(bin, cont[i + nx * iy]);
5632 if (!errors2.empty())
5633 fSumw2.fArray[bin] = errors2[i + nx * iy];
5634 }
5635 }
5636 }
5637 } else {
5638 // sorting histograms: 3D case
5639 std::vector<Double_t> pcont(n + 2);
5640 Int_t nx = fXaxis.GetNbins() + 2;
5641 Int_t ny = fYaxis.GetNbins() + 2;
5642 Int_t nz = fZaxis.GetNbins() + 2;
5643 Int_t l = 0;
5644 cont.resize((nx + 2) * (ny + 2) * (nz + 2));
5645 if (fSumw2.fN)
5646 errors2.resize((nx + 2) * (ny + 2) * (nz + 2));
5647 for (i = 0; i < nx; i++) {
5648 for (j = 0; j < ny; j++) {
5649 for (k = 0; k < nz; k++) {
5650 Int_t bin = GetBin(i,j,k);
5652 if (axis == GetXaxis())
5653 l = i - 1;
5654 else if (axis == GetYaxis())
5655 l = j - 1;
5656 else
5657 l = k - 1;
5658 if (l >= 0 && l < n) { // we consider underflow/overflows in y for ordering the bins
5659 pcont[l] += c;
5660 a[l] = l;
5661 }
5662 cont[i + nx * (j + ny * k)] = c;
5663 if (!errors2.empty())
5664 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5665 }
5666 }
5667 }
5668 if (sort == 1)
5669 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5670 else
5671 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5672 for (i = 0; i < n; i++) {
5673 // iterate on the old label list to find corresponding bin match
5674 TIter next(labold);
5675 UInt_t bin = a[i] + 1;
5676 obj = nullptr;
5677 while ((obj = next())) {
5678 if (obj->GetUniqueID() == (UInt_t)bin) {
5679 break;
5680 }
5681 else
5682 obj = nullptr;
5683 }
5684 if (!obj) {
5685 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5686 return;
5687 }
5688 labels->Add(obj);
5689 if (gDebug)
5690 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from bin " << a[i] << "content "
5691 << pcont[a[i]] << std::endl;
5692 }
5693
5694 // need to set here new ordered labels - otherwise loop before does not work since labold and llabels list
5695 // contain same objects
5696 for (i = 0; i < n; i++) {
5697 labels->At(i)->SetUniqueID(i + 1);
5698 }
5699 // set now the bin contents
5700 if (axis == GetXaxis()) {
5701 for (i = 0; i < n; i++) {
5702 Int_t ix = a[i] + 1;
5703 for (j = 0; j < ny; j++) {
5704 for (k = 0; k < nz; k++) {
5705 Int_t bin = GetBin(i + 1, j, k);
5706 UpdateBinContent(bin, cont[ix + nx * (j + ny * k)]);
5707 if (!errors2.empty())
5708 fSumw2.fArray[bin] = errors2[ix + nx * (j + ny * k)];
5709 }
5710 }
5711 }
5712 } else if (axis == GetYaxis()) {
5713 // using y axis
5714 for (i = 0; i < nx; i++) {
5715 for (j = 0; j < n; j++) {
5716 Int_t iy = a[j] + 1;
5717 for (k = 0; k < nz; k++) {
5718 Int_t bin = GetBin(i, j + 1, k);
5719 UpdateBinContent(bin, cont[i + nx * (iy + ny * k)]);
5720 if (!errors2.empty())
5721 fSumw2.fArray[bin] = errors2[i + nx * (iy + ny * k)];
5722 }
5723 }
5724 }
5725 } else {
5726 // using z axis
5727 for (i = 0; i < nx; i++) {
5728 for (j = 0; j < ny; j++) {
5729 for (k = 0; k < n; k++) {
5730 Int_t iz = a[k] + 1;
5731 Int_t bin = GetBin(i, j , k +1);
5732 UpdateBinContent(bin, cont[i + nx * (j + ny * iz)]);
5733 if (!errors2.empty())
5734 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * iz)];
5735 }
5736 }
5737 }
5738 }
5739 }
5740 } else {
5741 //---alphabetic sort
5742 // sort labels using vector of strings and TMath::Sort
5743 // I need to array because labels order in list is not necessary that of the bins
5744 std::vector<std::string> vecLabels(n);
5745 for (i = 0; i < n; i++) {
5746 vecLabels[i] = labold->At(i)->GetName();
5747 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5748 a[i] = i;
5749 }
5750 // sort in ascending order for strings
5751 TMath::Sort(n, vecLabels.data(), a.data(), kFALSE);
5752 // set the new labels
5753 for (i = 0; i < n; i++) {
5754 TObject *labelObj = labold->At(a[i]);
5755 labels->Add(labold->At(a[i]));
5756 // set the corresponding bin. NB bin starts from 1
5757 labelObj->SetUniqueID(i + 1);
5758 if (gDebug)
5759 std::cout << "bin " << i + 1 << " setting new labels for axis " << labold->At(a[i])->GetName() << " from "
5760 << b[a[i]] << std::endl;
5761 }
5762
5763 if (GetDimension() == 1) {
5764 cont.resize(n + 2);
5765 if (fSumw2.fN)
5766 errors2.resize(n + 2);
5767 for (i = 0; i < n; i++) {
5768 cont[i] = RetrieveBinContent(b[a[i]]);
5769 if (!errors2.empty())
5771 }
5772 for (i = 0; i < n; i++) {
5773 UpdateBinContent(i + 1, cont[i]);
5774 if (!errors2.empty())
5775 fSumw2.fArray[i+1] = errors2[i];
5776 }
5777 } else if (GetDimension() == 2) {
5778 Int_t nx = fXaxis.GetNbins() + 2;
5779 Int_t ny = fYaxis.GetNbins() + 2;
5780 cont.resize(nx * ny);
5781 if (fSumw2.fN)
5782 errors2.resize(nx * ny);
5783 // copy old bin contents and then set to new ordered bins
5784 // N.B. bin in histograms starts from 1, but in y we consider under/overflows
5785 for (i = 0; i < nx; i++) {
5786 for (j = 0; j < ny; j++) { // ny is nbins+2
5787 Int_t bin = GetBin(i, j);
5788 cont[i + nx * j] = RetrieveBinContent(bin);
5789 if (!errors2.empty())
5790 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5791 }
5792 }
5793 if (axis == GetXaxis()) {
5794 for (i = 0; i < n; i++) {
5795 for (j = 0; j < ny; j++) {
5796 Int_t bin = GetBin(i + 1 , j);
5797 UpdateBinContent(bin, cont[b[a[i]] + nx * j]);
5798 if (!errors2.empty())
5799 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * j];
5800 }
5801 }
5802 } else {
5803 for (i = 0; i < nx; i++) {
5804 for (j = 0; j < n; j++) {
5805 Int_t bin = GetBin(i, j + 1);
5806 UpdateBinContent(bin, cont[i + nx * b[a[j]]]);
5807 if (!errors2.empty())
5808 fSumw2.fArray[bin] = errors2[i + nx * b[a[j]]];
5809 }
5810 }
5811 }
5812 } else {
5813 // case of 3D (needs to be tested)
5814 Int_t nx = fXaxis.GetNbins() + 2;
5815 Int_t ny = fYaxis.GetNbins() + 2;
5816 Int_t nz = fZaxis.GetNbins() + 2;
5817 cont.resize(nx * ny * nz);
5818 if (fSumw2.fN)
5819 errors2.resize(nx * ny * nz);
5820 for (i = 0; i < nx; i++) {
5821 for (j = 0; j < ny; j++) {
5822 for (k = 0; k < nz; k++) {
5823 Int_t bin = GetBin(i, j, k);
5824 cont[i + nx * (j + ny * k)] = RetrieveBinContent(bin);
5825 if (!errors2.empty())
5826 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5827 }
5828 }
5829 }
5830 if (axis == GetXaxis()) {
5831 // labels on x axis
5832 for (i = 0; i < n; i++) { // for x we loop only on bins with the labels
5833 for (j = 0; j < ny; j++) {
5834 for (k = 0; k < nz; k++) {
5835 Int_t bin = GetBin(i + 1, j, k);
5836 UpdateBinContent(bin, cont[b[a[i]] + nx * (j + ny * k)]);
5837 if (!errors2.empty())
5838 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * (j + ny * k)];
5839 }
5840 }
5841 }
5842 } else if (axis == GetYaxis()) {
5843 // labels on y axis
5844 for (i = 0; i < nx; i++) {
5845 for (j = 0; j < n; j++) {
5846 for (k = 0; k < nz; k++) {
5847 Int_t bin = GetBin(i, j+1, k);
5848 UpdateBinContent(bin, cont[i + nx * (b[a[j]] + ny * k)]);
5849 if (!errors2.empty())
5850 fSumw2.fArray[bin] = errors2[i + nx * (b[a[j]] + ny * k)];
5851 }
5852 }
5853 }
5854 } else {
5855 // labels on z axis
5856 for (i = 0; i < nx; i++) {
5857 for (j = 0; j < ny; j++) {
5858 for (k = 0; k < n; k++) {
5859 Int_t bin = GetBin(i, j, k+1);
5860 UpdateBinContent(bin, cont[i + nx * (j + ny * b[a[k]])]);
5861 if (!errors2.empty())
5862 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * b[a[k]])];
5863 }
5864 }
5865 }
5866 }
5867 }
5868 }
5869 // need to set to zero the statistics if axis has been sorted
5870 // see for example TH3::PutStats for definition of s vector
5871 bool labelsAreSorted = kFALSE;
5872 for (i = 0; i < n; ++i) {
5873 if (a[i] != i) {
5875 break;
5876 }
5877 }
5878 if (labelsAreSorted) {
5879 double s[TH1::kNstat];
5880 GetStats(s);
5881 if (iaxis == 1) {
5882 s[2] = 0; // fTsumwx
5883 s[3] = 0; // fTsumwx2
5884 s[6] = 0; // fTsumwxy
5885 s[9] = 0; // fTsumwxz
5886 } else if (iaxis == 2) {
5887 s[4] = 0; // fTsumwy
5888 s[5] = 0; // fTsumwy2
5889 s[6] = 0; // fTsumwxy
5890 s[10] = 0; // fTsumwyz
5891 } else if (iaxis == 3) {
5892 s[7] = 0; // fTsumwz
5893 s[8] = 0; // fTsumwz2
5894 s[9] = 0; // fTsumwxz
5895 s[10] = 0; // fTsumwyz
5896 }
5897 PutStats(s);
5898 }
5899 delete labold;
5900}
5901
5902////////////////////////////////////////////////////////////////////////////////
5903/// Test if two double are almost equal.
5904
5905static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5906{
5907 return TMath::Abs(a - b) < epsilon;
5908}
5909
5910////////////////////////////////////////////////////////////////////////////////
5911/// Test if a double is almost an integer.
5912
5913static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5914{
5915 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5916 AlmostEqual(a - TMath::Floor(a), 1, epsilon);
5917}
5918
5919////////////////////////////////////////////////////////////////////////////////
5920/// Test if the binning is equidistant.
5921
5922static inline bool IsEquidistantBinning(const TAxis& axis)
5923{
5924 // check if axis bin are equals
5925 if (!axis.GetXbins()->fN) return true; //
5926 // not able to check if there is only one axis entry
5927 bool isEquidistant = true;
5928 const Double_t firstBinWidth = axis.GetBinWidth(1);
5929 for (int i = 1; i < axis.GetNbins(); ++i) {
5930 const Double_t binWidth = axis.GetBinWidth(i);
5931 const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5932 isEquidistant &= match;
5933 if (!match)
5934 break;
5935 }
5936 return isEquidistant;
5937}
5938
5939////////////////////////////////////////////////////////////////////////////////
5940/// Same limits and bins.
5941
5943 return axis1.GetNbins() == axis2.GetNbins() &&
5944 TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
5945 TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
5946}
5947
5948////////////////////////////////////////////////////////////////////////////////
5949/// Finds new limits for the axis for the Merge function.
5950/// returns false if the limits are incompatible
5951
5953{
5955 return kTRUE;
5956
5958 return kFALSE; // not equidistant user binning not supported
5959
5960 Double_t width1 = destAxis.GetBinWidth(0);
5961 Double_t width2 = anAxis.GetBinWidth(0);
5962 if (width1 == 0 || width2 == 0)
5963 return kFALSE; // no binning not supported
5964
5965 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
5966 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
5968
5969 // check the bin size
5971 return kFALSE;
5972
5973 // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
5974 // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
5975
5976
5977 // check the limits
5978 Double_t delta;
5979 delta = (destAxis.GetXmin() - xmin)/width1;
5980 if (!AlmostInteger(delta))
5981 xmin -= (TMath::Ceil(delta) - delta)*width1;
5982
5983 delta = (anAxis.GetXmin() - xmin)/width2;
5984 if (!AlmostInteger(delta))
5985 xmin -= (TMath::Ceil(delta) - delta)*width2;
5986
5987
5988 delta = (destAxis.GetXmin() - xmin)/width1;
5989 if (!AlmostInteger(delta))
5990 return kFALSE;
5991
5992
5993 delta = (xmax - destAxis.GetXmax())/width1;
5994 if (!AlmostInteger(delta))
5995 xmax += (TMath::Ceil(delta) - delta)*width1;
5996
5997
5998 delta = (xmax - anAxis.GetXmax())/width2;
5999 if (!AlmostInteger(delta))
6000 xmax += (TMath::Ceil(delta) - delta)*width2;
6001
6002
6003 delta = (xmax - destAxis.GetXmax())/width1;
6004 if (!AlmostInteger(delta))
6005 return kFALSE;
6006#ifdef DEBUG
6007 if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
6008 printf("TH1::RecomputeAxisLimits - Impossible\n");
6009 return kFALSE;
6010 }
6011#endif
6012
6013
6015
6016 //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
6017
6018 return kTRUE;
6019}
6020
6021////////////////////////////////////////////////////////////////////////////////
6022/// Add all histograms in the collection to this histogram.
6023/// This function computes the min/max for the x axis,
6024/// compute a new number of bins, if necessary,
6025/// add bin contents, errors and statistics.
6026/// If all histograms have bin labels, bins with identical labels
6027/// will be merged, no matter what their order is.
6028/// If overflows are present and limits are different the function will fail.
6029/// The function returns the total number of entries in the result histogram
6030/// if the merge is successful, -1 otherwise.
6031///
6032/// Possible option:
6033/// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
6034/// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
6035/// (enabled by default) slows down the merging
6036///
6037/// IMPORTANT remark. The axis x may have different number
6038/// of bins and different limits, BUT the largest bin width must be
6039/// a multiple of the smallest bin width and the upper limit must also
6040/// be a multiple of the bin width.
6041/// Example:
6042///
6043/// ~~~ {.cpp}
6044/// void atest() {
6045/// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
6046/// TH1F *h2 = new TH1F("h2","h2",220,0,110);
6047/// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
6048/// TRandom r;
6049/// for (Int_t i=0;i<10000;i++) {
6050/// h1->Fill(r.Gaus(-55,10));
6051/// h2->Fill(r.Gaus(55,10));
6052/// h3->Fill(r.Gaus(0,10));
6053/// }
6054///
6055/// TList *list = new TList;
6056/// list->Add(h1);
6057/// list->Add(h2);
6058/// list->Add(h3);
6059/// TH1F *h = (TH1F*)h1->Clone("h");
6060/// h->Reset();
6061/// h->Merge(list);
6062/// h->Draw();
6063/// }
6064/// ~~~
6065
6067{
6068 if (!li) return 0;
6069 if (li->IsEmpty()) return (Long64_t) GetEntries();
6070
6071 // use TH1Merger class
6072 TH1Merger merger(*this,*li,opt);
6073 Bool_t ret = merger();
6074
6075 return (ret) ? GetEntries() : -1;
6076}
6077
6078
6079////////////////////////////////////////////////////////////////////////////////
6080/// Performs the operation:
6081///
6082/// `this = this*c1*f1`
6083///
6084/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
6085///
6086/// Only bins inside the function range are recomputed.
6087/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6088/// you should call Sumw2 before making this operation.
6089/// This is particularly important if you fit the histogram after TH1::Multiply
6090///
6091/// The function return kFALSE if the Multiply operation failed
6092
6094{
6095 if (!f1) {
6096 Error("Multiply","Attempt to multiply by a non-existing function");
6097 return kFALSE;
6098 }
6099
6100 // delete buffer if it is there since it will become invalid
6101 if (fBuffer) BufferEmpty(1);
6102
6103 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
6104 Int_t ny = GetNbinsY() + 2;
6105 Int_t nz = GetNbinsZ() + 2;
6106 if (fDimension < 2) ny = 1;
6107 if (fDimension < 3) nz = 1;
6108
6109 // reset min-maximum
6110 SetMinimum();
6111 SetMaximum();
6112
6113 // - Loop on bins (including underflows/overflows)
6114 Double_t xx[3];
6115 Double_t *params = nullptr;
6116 f1->InitArgs(xx,params);
6117
6118 for (Int_t binz = 0; binz < nz; ++binz) {
6119 xx[2] = fZaxis.GetBinCenter(binz);
6120 for (Int_t biny = 0; biny < ny; ++biny) {
6121 xx[1] = fYaxis.GetBinCenter(biny);
6122 for (Int_t binx = 0; binx < nx; ++binx) {
6123 xx[0] = fXaxis.GetBinCenter(binx);
6124 if (!f1->IsInside(xx)) continue;
6126 Int_t bin = binx + nx * (biny + ny *binz);
6127 Double_t cu = c1*f1->EvalPar(xx);
6128 if (TF1::RejectedPoint()) continue;
6130 if (fSumw2.fN) {
6131 fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
6132 }
6133 }
6134 }
6135 }
6136 ResetStats();
6137 return kTRUE;
6138}
6139
6140////////////////////////////////////////////////////////////////////////////////
6141/// Multiply this histogram by h1.
6142///
6143/// `this = this*h1`
6144///
6145/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6146/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
6147/// if not already set.
6148///
6149/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6150/// you should call Sumw2 before making this operation.
6151/// This is particularly important if you fit the histogram after TH1::Multiply
6152///
6153/// The function return kFALSE if the Multiply operation failed
6154
6155Bool_t TH1::Multiply(const TH1 *h1)
6156{
6157 if (!h1) {
6158 Error("Multiply","Attempt to multiply by a non-existing histogram");
6159 return kFALSE;
6160 }
6161
6162 // delete buffer if it is there since it will become invalid
6163 if (fBuffer) BufferEmpty(1);
6164
6165 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins) {
6166 return false;
6167 }
6168
6169 // Create Sumw2 if h1 has Sumw2 set
6170 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
6171
6172 // - Reset min- maximum
6173 SetMinimum();
6174 SetMaximum();
6175
6176 // - Loop on bins (including underflows/overflows)
6177 for (Int_t i = 0; i < fNcells; ++i) {
6180 UpdateBinContent(i, c0 * c1);
6181 if (fSumw2.fN) {
6183 }
6184 }
6185 ResetStats();
6186 return kTRUE;
6187}
6188
6189////////////////////////////////////////////////////////////////////////////////
6190/// Replace contents of this histogram by multiplication of h1 by h2.
6191///
6192/// `this = (c1*h1)*(c2*h2)`
6193///
6194/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6195/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
6196/// if not already set.
6197///
6198/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6199/// you should call Sumw2 before making this operation.
6200/// This is particularly important if you fit the histogram after TH1::Multiply
6201///
6202/// The function return kFALSE if the Multiply operation failed
6203
6205{
6206 TString opt = option;
6207 opt.ToLower();
6208 // Bool_t binomial = kFALSE;
6209 // if (opt.Contains("b")) binomial = kTRUE;
6210 if (!h1 || !h2) {
6211 Error("Multiply","Attempt to multiply by a non-existing histogram");
6212 return kFALSE;
6213 }
6214
6215 // delete buffer if it is there since it will become invalid
6216 if (fBuffer) BufferEmpty(1);
6217
6218 if (LoggedInconsistency("Multiply", this, h1) >= kDifferentNumberOfBins ||
6219 LoggedInconsistency("Multiply", h1, h2) >= kDifferentNumberOfBins) {
6220 return false;
6221 }
6222
6223 // Create Sumw2 if h1 or h2 have Sumw2 set
6224 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
6225
6226 // - Reset min - maximum
6227 SetMinimum();
6228 SetMaximum();
6229
6230 // - Loop on bins (including underflows/overflows)
6231 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
6232 for (Int_t i = 0; i < fNcells; ++i) {
6234 Double_t b2 = h2->RetrieveBinContent(i);
6235 UpdateBinContent(i, c1 * b1 * c2 * b2);
6236 if (fSumw2.fN) {
6237 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
6238 }
6239 }
6240 ResetStats();
6241 return kTRUE;
6242}
6243
6244////////////////////////////////////////////////////////////////////////////////
6245/// @brief Normalize a histogram to its integral or to its maximum.
6246/// @note Works for TH1, TH2, TH3, ...
6247/// @param option: normalization strategy ("", "max" or "sum")
6248/// - "": Scale to `1/(sum*bin_width)`.
6249/// - max: Scale to `1/GetMaximum()`
6250/// - sum: Scale to `1/sum`.
6251///
6252/// In case the norm is zero, it raises an error.
6253/// @sa https://root-forum.cern.ch/t/different-ways-of-normalizing-histograms/15582/
6254
6256{
6257 TString opt = option;
6258 opt.ToLower();
6259 if (!opt.IsNull() && (opt != "max") && (opt != "sum")) {
6260 Error("Normalize", "Unrecognized option %s", option);
6261 return;
6262 }
6263
6264 const Double_t norm = (opt == "max") ? GetMaximum() : Integral(opt.IsNull() ? "width" : "");
6265
6266 if (norm == 0) {
6267 Error("Normalize", "Attempt to normalize histogram with zero integral");
6268 } else {
6269 Scale(1.0 / norm, "");
6270 // An alternative could have been to call Integral("") and Scale(1/norm, "width"), but this
6271 // will lead to a different value of GetEntries.
6272 // Instead, doing simultaneously Integral("width") and Scale(1/norm, "width") leads to an error since you are
6273 // dividing twice by bin width.
6274 }
6275}
6276
6277////////////////////////////////////////////////////////////////////////////////
6278/// Control routine to paint any kind of histograms.
6279///
6280/// This function is automatically called by TCanvas::Update.
6281/// (see TH1::Draw for the list of options)
6282
6284{
6286
6287 if (fPainter) {
6288 if (option && strlen(option) > 0)
6290 else
6292 }
6293}
6294
6295////////////////////////////////////////////////////////////////////////////////
6296/// Rebin this histogram
6297///
6298/// #### case 1 xbins=0
6299///
6300/// If newname is blank (default), the current histogram is modified and
6301/// a pointer to it is returned.
6302///
6303/// If newname is not blank, the current histogram is not modified, and a
6304/// new histogram is returned which is a Clone of the current histogram
6305/// with its name set to newname.
6306///
6307/// The parameter ngroup indicates how many bins of this have to be merged
6308/// into one bin of the result.
6309///
6310/// If the original histogram has errors stored (via Sumw2), the resulting
6311/// histograms has new errors correctly calculated.
6312///
6313/// examples: if h1 is an existing TH1F histogram with 100 bins
6314///
6315/// ~~~ {.cpp}
6316/// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
6317/// h1->Rebin(5); //merges five bins in one in h1
6318/// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
6319/// // merging 5 bins of h1 in one bin
6320/// ~~~
6321///
6322/// NOTE: If ngroup is not an exact divider of the number of bins,
6323/// the top limit of the rebinned histogram is reduced
6324/// to the upper edge of the last bin that can make a complete
6325/// group. The remaining bins are added to the overflow bin.
6326/// Statistics will be recomputed from the new bin contents.
6327///
6328/// #### case 2 xbins!=0
6329///
6330/// A new histogram is created (you should specify newname).
6331/// The parameter ngroup is the number of variable size bins in the created histogram.
6332/// The array xbins must contain ngroup+1 elements that represent the low-edges
6333/// of the bins.
6334/// If the original histogram has errors stored (via Sumw2), the resulting
6335/// histograms has new errors correctly calculated.
6336///
6337/// NOTE: The bin edges specified in xbins should correspond to bin edges
6338/// in the original histogram. If a bin edge in the new histogram is
6339/// in the middle of a bin in the original histogram, all entries in
6340/// the split bin in the original histogram will be transferred to the
6341/// lower of the two possible bins in the new histogram. This is
6342/// probably not what you want. A warning message is emitted in this
6343/// case
6344///
6345/// examples: if h1 is an existing TH1F histogram with 100 bins
6346///
6347/// ~~~ {.cpp}
6348/// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
6349/// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
6350/// ~~~
6351
6352TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
6353{
6354 Int_t nbins = fXaxis.GetNbins();
6357 if ((ngroup <= 0) || (ngroup > nbins)) {
6358 Error("Rebin", "Illegal value of ngroup=%d",ngroup);
6359 return nullptr;
6360 }
6361
6362 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
6363 Error("Rebin", "Operation valid on 1-D histograms only");
6364 return nullptr;
6365 }
6366 if (!newname && xbins) {
6367 Error("Rebin","if xbins is specified, newname must be given");
6368 return nullptr;
6369 }
6370
6371 Int_t newbins = nbins/ngroup;
6372 if (!xbins) {
6373 Int_t nbg = nbins/ngroup;
6374 if (nbg*ngroup != nbins) {
6375 Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
6376 }
6377 }
6378 else {
6379 // in the case that xbins is given (rebinning in variable bins), ngroup is
6380 // the new number of bins and number of grouped bins is not constant.
6381 // when looping for setting the contents for the new histogram we
6382 // need to loop on all bins of original histogram. Then set ngroup=nbins
6383 newbins = ngroup;
6384 ngroup = nbins;
6385 }
6386
6387 // Save old bin contents into a new array
6388 Double_t entries = fEntries;
6389 Double_t *oldBins = new Double_t[nbins+2];
6390 Int_t bin, i;
6391 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
6392 Double_t *oldErrors = nullptr;
6393 if (fSumw2.fN != 0) {
6394 oldErrors = new Double_t[nbins+2];
6395 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
6396 }
6397 // rebin will not include underflow/overflow if new axis range is larger than old axis range
6398 if (xbins) {
6399 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
6400 Warning("Rebin","underflow entries will not be used when rebinning");
6401 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
6402 Warning("Rebin","overflow entries will not be used when rebinning");
6403 }
6404
6405
6406 // create a clone of the old histogram if newname is specified
6407 TH1 *hnew = this;
6408 if ((newname && strlen(newname) > 0) || xbins) {
6409 hnew = (TH1*)Clone(newname);
6410 }
6411
6412 //reset can extend bit to avoid an axis extension in SetBinContent
6413 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
6414
6415 // save original statistics
6416 Double_t stat[kNstat];
6417 GetStats(stat);
6418 bool resetStat = false;
6419 // change axis specs and rebuild bin contents array::RebinAx
6420 if(!xbins && (newbins*ngroup != nbins)) {
6422 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
6423 }
6424 // save the TAttAxis members (reset by SetBins)
6436
6437 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
6438 Double_t *bins = new Double_t[newbins+1];
6439 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
6440 hnew->SetBins(newbins,bins); //this also changes errors array (if any)
6441 delete [] bins;
6442 } else if (xbins) {
6443 hnew->SetBins(newbins,xbins);
6444 } else {
6445 hnew->SetBins(newbins,xmin,xmax);
6446 }
6447
6448 // Restore axis attributes
6460
6461 // copy merged bin contents (ignore under/overflows)
6462 // Start merging only once the new lowest edge is reached
6463 Int_t startbin = 1;
6464 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
6465 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
6466 startbin++;
6467 }
6470 for (bin = 1;bin<=newbins;bin++) {
6471 binContent = 0;
6472 binError = 0;
6473 Int_t imax = ngroup;
6474 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6475 // check bin edges for the cases when we provide an array of bins
6476 // be careful in case bins can have zero width
6478 hnew->GetXaxis()->GetBinLowEdge(bin),
6479 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6480 {
6481 Warning("Rebin","Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6482 }
6483 for (i=0;i<ngroup;i++) {
6484 if( (oldbin+i > nbins) ||
6485 ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6486 imax = i;
6487 break;
6488 }
6491 }
6492 hnew->SetBinContent(bin,binContent);
6493 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6494 oldbin += imax;
6495 }
6496
6497 // sum underflow and overflow contents until startbin
6498 binContent = 0;
6499 binError = 0;
6500 for (i = 0; i < startbin; ++i) {
6501 binContent += oldBins[i];
6502 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6503 }
6504 hnew->SetBinContent(0,binContent);
6505 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6506 // sum overflow
6507 binContent = 0;
6508 binError = 0;
6509 for (i = oldbin; i <= nbins+1; ++i) {
6510 binContent += oldBins[i];
6511 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6512 }
6513 hnew->SetBinContent(newbins+1,binContent);
6514 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6515
6516 hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6517
6518 // restore statistics and entries modified by SetBinContent
6519 hnew->SetEntries(entries);
6520 if (!resetStat) hnew->PutStats(stat);
6521 delete [] oldBins;
6522 if (oldErrors) delete [] oldErrors;
6523 return hnew;
6524}
6525
6526////////////////////////////////////////////////////////////////////////////////
6527/// finds new limits for the axis so that *point* is within the range and
6528/// the limits are compatible with the previous ones (see TH1::Merge).
6529/// new limits are put into *newMin* and *newMax* variables.
6530/// axis - axis whose limits are to be recomputed
6531/// point - point that should fit within the new axis limits
6532/// newMin - new minimum will be stored here
6533/// newMax - new maximum will be stored here.
6534/// false if failed (e.g. if the initial axis limits are wrong
6535/// or the new range is more than \f$ 2^{64} \f$ times the old one).
6536
6538{
6539 Double_t xmin = axis->GetXmin();
6540 Double_t xmax = axis->GetXmax();
6541 if (xmin >= xmax) return kFALSE;
6543
6544 //recompute new axis limits by doubling the current range
6545 Int_t ntimes = 0;
6546 while (point < xmin) {
6547 if (ntimes++ > 64)
6548 return kFALSE;
6549 xmin = xmin - range;
6550 range *= 2;
6551 }
6552 while (point >= xmax) {
6553 if (ntimes++ > 64)
6554 return kFALSE;
6555 xmax = xmax + range;
6556 range *= 2;
6557 }
6558 newMin = xmin;
6559 newMax = xmax;
6560 // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6561 // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6562
6563 return kTRUE;
6564}
6565
6566////////////////////////////////////////////////////////////////////////////////
6567/// Histogram is resized along axis such that x is in the axis range.
6568/// The new axis limits are recomputed by doubling iteratively
6569/// the current axis range until the specified value x is within the limits.
6570/// The algorithm makes a copy of the histogram, then loops on all bins
6571/// of the old histogram to fill the extended histogram.
6572/// Takes into account errors (Sumw2) if any.
6573/// The algorithm works for 1-d, 2-D and 3-D histograms.
6574/// The axis must be extendable before invoking this function.
6575/// Ex:
6576///
6577/// ~~~ {.cpp}
6578/// h->GetXaxis()->SetCanExtend(kTRUE);
6579/// ~~~
6580
6581void TH1::ExtendAxis(Double_t x, TAxis *axis)
6582{
6583 if (!axis->CanExtend()) return;
6584 if (TMath::IsNaN(x)) { // x may be a NaN
6586 return;
6587 }
6588
6589 if (axis->GetXmin() >= axis->GetXmax()) return;
6590 if (axis->GetNbins() <= 0) return;
6591
6593 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6594 return;
6595
6596 //save a copy of this histogram
6597 TH1 *hold = (TH1*)IsA()->New();
6598 hold->SetDirectory(nullptr);
6599 Copy(*hold);
6600 //set new axis limits
6601 axis->SetLimits(xmin,xmax);
6602
6603
6604 //now loop on all bins and refill
6606
6607 Reset("ICE"); //reset only Integral, contents and Errors
6608
6609 int iaxis = 0;
6610 if (axis == &fXaxis) iaxis = 1;
6611 if (axis == &fYaxis) iaxis = 2;
6612 if (axis == &fZaxis) iaxis = 3;
6613 bool firstw = kTRUE;
6614 Int_t binx,biny, binz = 0;
6615 Int_t ix = 0,iy = 0,iz = 0;
6616 Double_t bx,by,bz;
6617 Int_t ncells = hold->GetNcells();
6618 for (Int_t bin = 0; bin < ncells; ++bin) {
6619 hold->GetBinXYZ(bin,binx,biny,binz);
6620 bx = hold->GetXaxis()->GetBinCenter(binx);
6621 ix = fXaxis.FindFixBin(bx);
6622 if (fDimension > 1) {
6623 by = hold->GetYaxis()->GetBinCenter(biny);
6624 iy = fYaxis.FindFixBin(by);
6625 if (fDimension > 2) {
6626 bz = hold->GetZaxis()->GetBinCenter(binz);
6627 iz = fZaxis.FindFixBin(bz);
6628 }
6629 }
6630 // exclude underflow/overflow
6631 double content = hold->RetrieveBinContent(bin);
6632 if (content == 0) continue;
6633 if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6634 if (firstw) {
6635 Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6636 " their content will be lost",GetName() );
6637 firstw= kFALSE;
6638 }
6639 continue;
6640 }
6641 Int_t ibin= GetBin(ix,iy,iz);
6643 if (errors) {
6644 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6645 }
6646 }
6647 delete hold;
6648}
6649
6650////////////////////////////////////////////////////////////////////////////////
6651/// Recursively remove object from the list of functions
6652
6654{
6655 // Rely on TROOT::RecursiveRemove to take the readlock.
6656
6657 if (fFunctions) {
6659 }
6660}
6661
6662////////////////////////////////////////////////////////////////////////////////
6663/// Multiply this histogram by a constant c1.
6664///
6665/// `this = c1*this`
6666///
6667/// Note that both contents and errors (if any) are scaled.
6668/// This function uses the services of TH1::Add
6669///
6670/// IMPORTANT NOTE: Sumw2() is called automatically when scaling.
6671/// If you are not interested in the histogram statistics you can call
6672/// Sumw2(kFALSE) or use the option "nosw2"
6673///
6674/// One can scale a histogram such that the bins integral is equal to
6675/// the normalization parameter via TH1::Scale(Double_t norm), where norm
6676/// is the desired normalization divided by the integral of the histogram.
6677///
6678/// If option contains "width" the bin contents and errors are divided
6679/// by the bin width.
6680
6682{
6683
6684 TString opt = option; opt.ToLower();
6685 // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6686 if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6687 if (opt.Contains("width")) Add(this, this, c1, -1);
6688 else {
6689 if (fBuffer) BufferEmpty(1);
6690 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6691 if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6692 // update global histograms statistics
6693 Double_t s[kNstat] = {0};
6694 GetStats(s);
6695 for (Int_t i=0 ; i < kNstat; i++) {
6696 if (i == 1) s[i] = c1*c1*s[i];
6697 else s[i] = c1*s[i];
6698 }
6699 PutStats(s);
6700 SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6701 }
6702
6703 // if contours set, must also scale contours
6705 if (ncontours == 0) return;
6707 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6708}
6709
6710////////////////////////////////////////////////////////////////////////////////
6711/// Returns true if all axes are extendable.
6712
6714{
6716 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6717 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6718
6719 return canExtend;
6720}
6721
6722////////////////////////////////////////////////////////////////////////////////
6723/// Make the histogram axes extendable / not extendable according to the bit mask
6724/// returns the previous bit mask specifying which axes are extendable
6725
6727{
6729
6733
6734 if (GetDimension() > 1) {
6738 }
6739
6740 if (GetDimension() > 2) {
6744 }
6745
6746 return oldExtendBitMask;
6747}
6748
6749///////////////////////////////////////////////////////////////////////////////
6750/// Internal function used in TH1::Fill to see which axis is full alphanumeric,
6751/// i.e. can be extended and is alphanumeric
6753{
6757 bitMask |= kYaxis;
6759 bitMask |= kZaxis;
6760
6761 return bitMask;
6762}
6763
6764////////////////////////////////////////////////////////////////////////////////
6765/// Static function to set the default buffer size for automatic histograms.
6766/// When a histogram is created with one of its axis lower limit greater
6767/// or equal to its upper limit, the function SetBuffer is automatically
6768/// called with the default buffer size.
6769
6771{
6772 fgBufferSize = bufsize > 0 ? bufsize : 0;
6773}
6774
6775////////////////////////////////////////////////////////////////////////////////
6776/// When this static function is called with `sumw2=kTRUE`, all new
6777/// histograms will automatically activate the storage
6778/// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6779
6781{
6783}
6784
6785////////////////////////////////////////////////////////////////////////////////
6786/// Change/set the title.
6787///
6788/// If title is in the form `stringt;stringx;stringy;stringz;stringc`
6789/// the histogram title is set to `stringt`, the x axis title to `stringx`,
6790/// the y axis title to `stringy`, the z axis title to `stringz`, and the c
6791/// axis title for the palette is ignored at this stage.
6792/// Note that you can use e.g. `stringt;stringx` if you only want to specify
6793/// title and x axis title.
6794///
6795/// To insert the character `;` in one of the titles, one should use `#;`
6796/// or `#semicolon`.
6797
6798void TH1::SetTitle(const char *title)
6799{
6800 fTitle = title;
6801 fTitle.ReplaceAll("#;",2,"#semicolon",10);
6802
6803 // Decode fTitle. It may contain X, Y and Z titles
6805 Int_t isc = str1.Index(";");
6806 Int_t lns = str1.Length();
6807
6808 if (isc >=0 ) {
6809 fTitle = str1(0,isc);
6810 str1 = str1(isc+1, lns);
6811 isc = str1.Index(";");
6812 if (isc >=0 ) {
6813 str2 = str1(0,isc);
6814 str2.ReplaceAll("#semicolon",10,";",1);
6815 fXaxis.SetTitle(str2.Data());
6816 lns = str1.Length();
6817 str1 = str1(isc+1, lns);
6818 isc = str1.Index(";");
6819 if (isc >=0 ) {
6820 str2 = str1(0,isc);
6821 str2.ReplaceAll("#semicolon",10,";",1);
6822 fYaxis.SetTitle(str2.Data());
6823 lns = str1.Length();
6824 str1 = str1(isc+1, lns);
6825 isc = str1.Index(";");
6826 if (isc >=0 ) {
6827 str2 = str1(0,isc);
6828 str2.ReplaceAll("#semicolon",10,";",1);
6829 fZaxis.SetTitle(str2.Data());
6830 } else {
6831 str1.ReplaceAll("#semicolon",10,";",1);
6832 fZaxis.SetTitle(str1.Data());
6833 }
6834 } else {
6835 str1.ReplaceAll("#semicolon",10,";",1);
6836 fYaxis.SetTitle(str1.Data());
6837 }
6838 } else {
6839 str1.ReplaceAll("#semicolon",10,";",1);
6840 fXaxis.SetTitle(str1.Data());
6841 }
6842 }
6843
6844 fTitle.ReplaceAll("#semicolon",10,";",1);
6845
6846 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6847}
6848
6849////////////////////////////////////////////////////////////////////////////////
6850/// Smooth array xx, translation of Hbook routine `hsmoof.F`.
6851/// Based on algorithm 353QH twice presented by J. Friedman
6852/// in [Proc. of the 1974 CERN School of Computing, Norway, 11-24 August, 1974](https://cds.cern.ch/record/186223).
6853/// 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).
6854
6856{
6857 if (nn < 3 ) {
6858 ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6859 return;
6860 }
6861
6862 Int_t ii;
6863 std::array<double, 3> hh{};
6864
6865 std::vector<double> yy(nn);
6866 std::vector<double> zz(nn);
6867 std::vector<double> rr(nn);
6868
6869 for (Int_t pass=0;pass<ntimes;pass++) {
6870 // first copy original data into temp array
6871 std::copy(xx, xx+nn, zz.begin() );
6872
6873 for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6874
6875 // do 353 i.e. running median 3, 5, and 3 in a single loop
6876 for (int kk = 0; kk < 3; kk++) {
6877 std::copy(zz.begin(), zz.end(), yy.begin());
6878 int medianType = (kk != 1) ? 3 : 5;
6879 int ifirst = (kk != 1 ) ? 1 : 2;
6880 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6881 //nn2 = nn - ik - 1;
6882 // do all elements beside the first and last point for median 3
6883 // and first two and last 2 for median 5
6884 for ( ii = ifirst; ii < ilast; ii++) {
6885 zz[ii] = TMath::Median(medianType, yy.data() + ii - ifirst);
6886 }
6887
6888 if (kk == 0) { // first median 3
6889 // first point
6890 hh[0] = zz[1];
6891 hh[1] = zz[0];
6892 hh[2] = 3*zz[1] - 2*zz[2];
6893 zz[0] = TMath::Median(3, hh.data());
6894 // last point
6895 hh[0] = zz[nn - 2];
6896 hh[1] = zz[nn - 1];
6897 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6898 zz[nn - 1] = TMath::Median(3, hh.data());
6899 }
6900
6901 if (kk == 1) { // median 5
6902 // second point with window length 3
6903 zz[1] = TMath::Median(3, yy.data());
6904 // second-to-last point with window length 3
6905 zz[nn - 2] = TMath::Median(3, yy.data() + nn - 3);
6906 }
6907
6908 // In the third iteration (kk == 2), the first and last point stay
6909 // the same (see paper linked in the documentation).
6910 }
6911
6912 std::copy ( zz.begin(), zz.end(), yy.begin() );
6913
6914 // quadratic interpolation for flat segments
6915 for (ii = 2; ii < (nn - 2); ii++) {
6916 if (zz[ii - 1] != zz[ii]) continue;
6917 if (zz[ii] != zz[ii + 1]) continue;
6918 const double tmp0 = zz[ii - 2] - zz[ii];
6919 const double tmp1 = zz[ii + 2] - zz[ii];
6920 if (tmp0 * tmp1 <= 0) continue;
6921 int jk = 1;
6922 if ( std::abs(tmp1) > std::abs(tmp0) ) jk = -1;
6923 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6924 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6925 }
6926
6927 // running means
6928 //std::copy(zz.begin(), zz.end(), yy.begin());
6929 for (ii = 1; ii < nn - 1; ii++) {
6930 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6931 }
6932 zz[0] = yy[0];
6933 zz[nn - 1] = yy[nn - 1];
6934
6935 if (noent == 0) {
6936
6937 // save computed values
6938 std::copy(zz.begin(), zz.end(), rr.begin());
6939
6940 // COMPUTE residuals
6941 for (ii = 0; ii < nn; ii++) {
6942 zz[ii] = xx[ii] - zz[ii];
6943 }
6944 }
6945
6946 } // end loop on noent
6947
6948
6949 double xmin = TMath::MinElement(nn,xx);
6950 for (ii = 0; ii < nn; ii++) {
6951 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6952 // make smoothing defined positive - not better using 0 ?
6953 else xx[ii] = std::max((rr[ii] + zz[ii]),0.0 );
6954 }
6955 }
6956}
6957
6958////////////////////////////////////////////////////////////////////////////////
6959/// Smooth bin contents of this histogram.
6960/// if option contains "R" smoothing is applied only to the bins
6961/// defined in the X axis range (default is to smooth all bins)
6962/// Bin contents are replaced by their smooth values.
6963/// Errors (if any) are not modified.
6964/// the smoothing procedure is repeated ntimes (default=1)
6965
6967{
6968 if (fDimension != 1) {
6969 Error("Smooth","Smooth only supported for 1-d histograms");
6970 return;
6971 }
6972 Int_t nbins = fXaxis.GetNbins();
6973 if (nbins < 3) {
6974 Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
6975 return;
6976 }
6977
6978 // delete buffer if it is there since it will become invalid
6979 if (fBuffer) BufferEmpty(1);
6980
6981 Int_t firstbin = 1, lastbin = nbins;
6982 TString opt = option;
6983 opt.ToLower();
6984 if (opt.Contains("r")) {
6987 }
6988 nbins = lastbin - firstbin + 1;
6989 Double_t *xx = new Double_t[nbins];
6991 Int_t i;
6992 for (i=0;i<nbins;i++) {
6994 }
6995
6996 TH1::SmoothArray(nbins,xx,ntimes);
6997
6998 for (i=0;i<nbins;i++) {
7000 }
7001 fEntries = nent;
7002 delete [] xx;
7003
7004 if (gPad) gPad->Modified();
7005}
7006
7007////////////////////////////////////////////////////////////////////////////////
7008/// if flag=kTRUE, underflows and overflows are used by the Fill functions
7009/// in the computation of statistics (mean value, StdDev).
7010/// By default, underflows or overflows are not used.
7011
7013{
7015}
7016
7017////////////////////////////////////////////////////////////////////////////////
7018/// Stream a class object.
7019
7020void TH1::Streamer(TBuffer &b)
7021{
7022 if (b.IsReading()) {
7023 UInt_t R__s, R__c;
7024 Version_t R__v = b.ReadVersion(&R__s, &R__c);
7025 if (fDirectory) fDirectory->Remove(this);
7026 fDirectory = nullptr;
7027 if (R__v > 2) {
7028 b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
7029
7031 fXaxis.SetParent(this);
7032 fYaxis.SetParent(this);
7033 fZaxis.SetParent(this);
7034 TIter next(fFunctions);
7035 TObject *obj;
7036 while ((obj=next())) {
7037 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
7038 }
7039 return;
7040 }
7041 //process old versions before automatic schema evolution
7046 b >> fNcells;
7047 fXaxis.Streamer(b);
7048 fYaxis.Streamer(b);
7049 fZaxis.Streamer(b);
7050 fXaxis.SetParent(this);
7051 fYaxis.SetParent(this);
7052 fZaxis.SetParent(this);
7053 b >> fBarOffset;
7054 b >> fBarWidth;
7055 b >> fEntries;
7056 b >> fTsumw;
7057 b >> fTsumw2;
7058 b >> fTsumwx;
7059 b >> fTsumwx2;
7060 if (R__v < 2) {
7062 Float_t *contour=nullptr;
7063 b >> maximum; fMaximum = maximum;
7064 b >> minimum; fMinimum = minimum;
7065 b >> norm; fNormFactor = norm;
7066 Int_t n = b.ReadArray(contour);
7067 fContour.Set(n);
7068 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
7069 delete [] contour;
7070 } else {
7071 b >> fMaximum;
7072 b >> fMinimum;
7073 b >> fNormFactor;
7075 }
7076 fSumw2.Streamer(b);
7078 fFunctions->Delete();
7080 b.CheckByteCount(R__s, R__c, TH1::IsA());
7081
7082 } else {
7083 b.WriteClassBuffer(TH1::Class(),this);
7084 }
7085}
7086
7087////////////////////////////////////////////////////////////////////////////////
7088/// Print some global quantities for this histogram.
7089/// \param[in] option
7090/// - "base" is given, number of bins and ranges are also printed
7091/// - "range" is given, bin contents and errors are also printed
7092/// for all bins in the current range (default 1-->nbins)
7093/// - "all" is given, bin contents and errors are also printed
7094/// for all bins including under and overflows.
7095
7096void TH1::Print(Option_t *option) const
7097{
7098 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7099 printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
7100 TString opt = option;
7101 opt.ToLower();
7102 Int_t all;
7103 if (opt.Contains("all")) all = 0;
7104 else if (opt.Contains("range")) all = 1;
7105 else if (opt.Contains("base")) all = 2;
7106 else return;
7107
7108 Int_t bin, binx, biny, binz;
7110 if (all == 0) {
7111 lastx = fXaxis.GetNbins()+1;
7112 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
7113 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
7114 } else {
7116 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
7117 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
7118 }
7119
7120 if (all== 2) {
7121 printf(" Title = %s\n", GetTitle());
7122 printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
7123 if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
7124 if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
7125 printf("\n");
7126 return;
7127 }
7128
7129 Double_t w,e;
7130 Double_t x,y,z;
7131 if (fDimension == 1) {
7132 for (binx=firstx;binx<=lastx;binx++) {
7135 e = GetBinError(binx);
7136 if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
7137 else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
7138 }
7139 }
7140 if (fDimension == 2) {
7141 for (biny=firsty;biny<=lasty;biny++) {
7143 for (binx=firstx;binx<=lastx;binx++) {
7144 bin = GetBin(binx,biny);
7146 w = RetrieveBinContent(bin);
7147 e = GetBinError(bin);
7148 if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
7149 else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
7150 }
7151 }
7152 }
7153 if (fDimension == 3) {
7154 for (binz=firstz;binz<=lastz;binz++) {
7156 for (biny=firsty;biny<=lasty;biny++) {
7158 for (binx=firstx;binx<=lastx;binx++) {
7159 bin = GetBin(binx,biny,binz);
7161 w = RetrieveBinContent(bin);
7162 e = GetBinError(bin);
7163 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);
7164 else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
7165 }
7166 }
7167 }
7168 }
7169}
7170
7171////////////////////////////////////////////////////////////////////////////////
7172/// Using the current bin info, recompute the arrays for contents and errors
7173
7174void TH1::Rebuild(Option_t *)
7175{
7176 SetBinsLength();
7177 if (fSumw2.fN) {
7179 }
7180}
7181
7182////////////////////////////////////////////////////////////////////////////////
7183/// Reset this histogram: contents, errors, etc.
7184/// \param[in] option
7185/// - if "ICE" is specified, resets only Integral, Contents and Errors.
7186/// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
7187/// This option is used
7188/// - if "M" is specified, resets also Minimum and Maximum
7189
7191{
7192 // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
7193 // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
7194
7195 TString opt = option;
7196 opt.ToUpper();
7197 fSumw2.Reset();
7198 if (fIntegral) {
7199 delete [] fIntegral;
7200 fIntegral = nullptr;
7201 }
7202
7203 if (opt.Contains("M")) {
7204 SetMinimum();
7205 SetMaximum();
7206 }
7207
7208 if (opt.Contains("ICE") && !opt.Contains("S")) return;
7209
7210 // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
7211 // But what is the sense of calling BufferEmpty() ? For making the axes ?
7212 // BufferEmpty will update contents that later will be
7213 // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
7214 // It may be needed for computing the axis limits....
7215 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
7216
7217 // need to reset also the statistics
7218 // (needs to be done after calling BufferEmpty() )
7219 fTsumw = 0;
7220 fTsumw2 = 0;
7221 fTsumwx = 0;
7222 fTsumwx2 = 0;
7223 fEntries = 0;
7224
7225 if (opt == "ICES") return;
7226
7227
7228 TObject *stats = fFunctions->FindObject("stats");
7229 fFunctions->Remove(stats);
7230 //special logic to support the case where the same object is
7231 //added multiple times in fFunctions.
7232 //This case happens when the same object is added with different
7233 //drawing modes
7234 TObject *obj;
7235 while ((obj = fFunctions->First())) {
7236 while(fFunctions->Remove(obj)) { }
7237 delete obj;
7238 }
7239 if(stats) fFunctions->Add(stats);
7240 fContour.Set(0);
7241}
7242
7243////////////////////////////////////////////////////////////////////////////////
7244/// Save the histogram as .csv, .tsv or .txt. In case of any other extension, fall
7245/// back to TObject::SaveAs, which saves as a .C macro (but with the file name
7246/// extension specified by the user)
7247///
7248/// The Under/Overflow bins are also exported (as first and last lines)
7249/// The fist 2 columns are the lower and upper edges of the bins
7250/// Column 3 contains the bin contents
7251/// The last column contains the error in y. If errors are not present, the column
7252/// is left empty
7253///
7254/// The result can be immediately imported into Excel, gnuplot, Python or whatever,
7255/// without the needing to install pyroot, etc.
7256///
7257/// \param filename the name of the file where to store the histogram
7258/// \param option some tuning options
7259///
7260/// The file extension defines the delimiter used:
7261/// - `.csv` : comma
7262/// - `.tsv` : tab
7263/// - `.txt` : space
7264///
7265/// If option = "title" a title line is generated. If the y-axis has a title,
7266/// this title is displayed as column 3 name, otherwise, it shows "BinContent"
7267
7268void TH1::SaveAs(const char *filename, Option_t *option) const
7269{
7270 char del = '\0';
7271 TString ext = "";
7273 TString opt = option;
7274
7275 if (filename) {
7276 if (fname.EndsWith(".csv")) {
7277 del = ',';
7278 ext = "csv";
7279 } else if (fname.EndsWith(".tsv")) {
7280 del = '\t';
7281 ext = "tsv";
7282 } else if (fname.EndsWith(".txt")) {
7283 del = ' ';
7284 ext = "txt";
7285 }
7286 }
7287 if (!del) {
7289 return;
7290 }
7291 std::ofstream out;
7292 out.open(filename, std::ios::out);
7293 if (!out.good()) {
7294 Error("SaveAs", "cannot open file: %s", filename);
7295 return;
7296 }
7297 if (opt.Contains("title")) {
7298 if (std::strcmp(GetYaxis()->GetTitle(), "") == 0) {
7299 out << "# " << "BinLowEdge" << del << "BinUpEdge" << del
7300 << "BinContent"
7301 << del << "ey" << std::endl;
7302 } else {
7303 out << "# " << "BinLowEdge" << del << "BinUpEdge" << del << GetYaxis()->GetTitle() << del << "ey" << std::endl;
7304 }
7305 }
7306 if (fSumw2.fN) {
7307 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7308 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7309 << GetBinError(i) << std::endl;
7310 }
7311 } else {
7312 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
7313 out << GetXaxis()->GetBinLowEdge(i) << del << GetXaxis()->GetBinUpEdge(i) << del << GetBinContent(i) << del
7314 << std::endl;
7315 }
7316 }
7317 out.close();
7318 Info("SaveAs", "%s file: %s has been generated", ext.Data(), filename);
7319}
7320
7321////////////////////////////////////////////////////////////////////////////////
7322/// Provide variable name for histogram for saving as primitive
7323/// Histogram pointer has by default the histogram name with an incremental suffix.
7324/// If the histogram belongs to a graph or a stack the suffix is not added because
7325/// the graph and stack objects are not aware of this new name. Same thing if
7326/// the histogram is drawn with the option COLZ because the TPaletteAxis drawn
7327/// when this option is selected, does not know this new name either.
7328
7330{
7331 thread_local Int_t storeNumber = 0;
7332
7333 TString opt = option;
7334 opt.ToLower();
7335 TString histName = GetName();
7336 // for TProfile and TH2Poly also fDirectory should be tested
7337 if (!histName.Contains("Graph") && !histName.Contains("_stack_") && !opt.Contains("colz") &&
7338 (!testfdir || !fDirectory)) {
7339 storeNumber++;
7340 histName += "__";
7341 histName += storeNumber;
7342 }
7343 if (histName.IsNull())
7344 histName = "unnamed";
7345 return gInterpreter->MapCppName(histName);
7346}
7347
7348////////////////////////////////////////////////////////////////////////////////
7349/// Save primitive as a C++ statement(s) on output stream out
7350
7351void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
7352{
7353 // empty the buffer before if it exists
7354 if (fBuffer)
7355 BufferEmpty();
7356
7358
7361 SetName(hname);
7362
7363 out <<" \n";
7364
7365 // Check if the histogram has equidistant X bins or not. If not, we
7366 // create an array holding the bins.
7367 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray)
7368 sxaxis = SavePrimitiveVector(out, hname + "_x", GetXaxis()->GetXbins()->fN, GetXaxis()->GetXbins()->fArray);
7369 // If the histogram is 2 or 3 dimensional, check if the histogram
7370 // has equidistant Y bins or not. If not, we create an array
7371 // holding the bins.
7372 if (fDimension > 1 && GetYaxis()->GetXbins()->fN && GetYaxis()->GetXbins()->fArray)
7373 syaxis = SavePrimitiveVector(out, hname + "_y", GetYaxis()->GetXbins()->fN, GetYaxis()->GetXbins()->fArray);
7374 // IF the histogram is 3 dimensional, check if the histogram
7375 // has equidistant Z bins or not. If not, we create an array
7376 // holding the bins.
7377 if (fDimension > 2 && GetZaxis()->GetXbins()->fN && GetZaxis()->GetXbins()->fArray)
7378 szaxis = SavePrimitiveVector(out, hname + "_z", GetZaxis()->GetXbins()->fN, GetZaxis()->GetXbins()->fArray);
7379
7380 const auto old_precision{out.precision()};
7381 constexpr auto max_precision{std::numeric_limits<double>::digits10 + 1};
7382 out << std::setprecision(max_precision);
7383
7384 out << " " << ClassName() << " *" << hname << " = new " << ClassName() << "(\"" << TString(savedName).ReplaceSpecialCppChars() << "\", \""
7385 << TString(GetTitle()).ReplaceSpecialCppChars() << "\", " << GetXaxis()->GetNbins();
7386 if (!sxaxis.IsNull())
7387 out << ", " << sxaxis << ".data()";
7388 else
7389 out << ", " << GetXaxis()->GetXmin() << ", " << GetXaxis()->GetXmax();
7390 if (fDimension > 1) {
7391 out << ", " << GetYaxis()->GetNbins();
7392 if (!syaxis.IsNull())
7393 out << ", " << syaxis << ".data()";
7394 else
7395 out << ", " << GetYaxis()->GetXmin() << ", " << GetYaxis()->GetXmax();
7396 }
7397 if (fDimension > 2) {
7398 out << ", " << GetZaxis()->GetNbins();
7399 if (!szaxis.IsNull())
7400 out << ", " << szaxis << ".data()";
7401 else
7402 out << ", " << GetZaxis()->GetXmin() << ", " << GetZaxis()->GetXmax();
7403 }
7404 out << ");\n";
7405
7407 Int_t numbins = 0, numerrors = 0;
7408
7409 std::vector<Double_t> content(fNcells), errors(save_errors ? fNcells : 0);
7410 for (Int_t bin = 0; bin < fNcells; bin++) {
7411 content[bin] = RetrieveBinContent(bin);
7412 if (content[bin])
7413 numbins++;
7414 if (save_errors) {
7415 errors[bin] = GetBinError(bin);
7416 if (errors[bin])
7417 numerrors++;
7418 }
7419 }
7420
7421 if ((numbins < 100) && (numerrors < 100)) {
7422 // in case of few non-empty bins store them as before
7423 for (Int_t bin = 0; bin < fNcells; bin++) {
7424 if (content[bin])
7425 out << " " << hname << "->SetBinContent(" << bin << "," << content[bin] << ");\n";
7426 }
7427 if (save_errors)
7428 for (Int_t bin = 0; bin < fNcells; bin++) {
7429 if (errors[bin])
7430 out << " " << hname << "->SetBinError(" << bin << "," << errors[bin] << ");\n";
7431 }
7432 } else {
7433 if (numbins > 0) {
7435 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
7436 out << " if (" << vectname << "[bin])\n";
7437 out << " " << hname << "->SetBinContent(bin, " << vectname << "[bin]);\n";
7438 }
7439 if (numerrors > 0) {
7441 out << " for (Int_t bin = 0; bin < " << fNcells << "; bin++)\n";
7442 out << " if (" << vectname << "[bin])\n";
7443 out << " " << hname << "->SetBinError(bin, " << vectname << "[bin]);\n";
7444 }
7445 }
7446
7448 out << std::setprecision(old_precision);
7449 SetName(savedName.Data());
7450}
7451
7452////////////////////////////////////////////////////////////////////////////////
7453/// Helper function for the SavePrimitive functions from TH1
7454/// or classes derived from TH1, eg TProfile, TProfile2D.
7455
7456void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
7457{
7458 if (TMath::Abs(GetBarOffset()) > 1e-5)
7459 out << " " << hname << "->SetBarOffset(" << GetBarOffset() << ");\n";
7460 if (TMath::Abs(GetBarWidth() - 1) > 1e-5)
7461 out << " " << hname << "->SetBarWidth(" << GetBarWidth() << ");\n";
7462 if (fMinimum != -1111)
7463 out << " " << hname << "->SetMinimum(" << fMinimum << ");\n";
7464 if (fMaximum != -1111)
7465 out << " " << hname << "->SetMaximum(" << fMaximum << ");\n";
7466 if (fNormFactor != 0)
7467 out << " " << hname << "->SetNormFactor(" << fNormFactor << ");\n";
7468 if (fEntries != 0)
7469 out << " " << hname << "->SetEntries(" << fEntries << ");\n";
7470 if (!fDirectory)
7471 out << " " << hname << "->SetDirectory(nullptr);\n";
7472 if (TestBit(kNoStats))
7473 out << " " << hname << "->SetStats(0);\n";
7474 if (fOption.Length() != 0)
7475 out << " " << hname << "->SetOption(\n" << TString(fOption).ReplaceSpecialCppChars() << "\");\n";
7476
7477 // save contour levels
7479 if (ncontours > 0) {
7481 if (TestBit(kUserContour)) {
7482 std::vector<Double_t> levels(ncontours);
7483 for (Int_t bin = 0; bin < ncontours; bin++)
7484 levels[bin] = GetContourLevel(bin);
7486 }
7487 out << " " << hname << "->SetContour(" << ncontours;
7488 if (!vectname.IsNull())
7489 out << ", " << vectname << ".data()";
7490 out << ");\n";
7491 }
7492
7494
7495 // save attributes
7496 SaveFillAttributes(out, hname, -1, -1);
7497 SaveLineAttributes(out, hname, 1, 1, 1);
7498 SaveMarkerAttributes(out, hname, 1, 1, 1);
7499 fXaxis.SaveAttributes(out, hname, "->GetXaxis()");
7500 fYaxis.SaveAttributes(out, hname, "->GetYaxis()");
7501 fZaxis.SaveAttributes(out, hname, "->GetZaxis()");
7502
7504}
7505
7506////////////////////////////////////////////////////////////////////////////////
7507/// Save list of functions
7508/// Also can be used by TGraph classes
7509
7510void TH1::SavePrimitiveFunctions(std::ostream &out, const char *varname, TList *lst)
7511{
7512 thread_local Int_t funcNumber = 0;
7513
7514 TObjLink *lnk = lst ? lst->FirstLink() : nullptr;
7515 while (lnk) {
7516 auto obj = lnk->GetObject();
7517 obj->SavePrimitive(out, TString::Format("nodraw #%d\n", ++funcNumber).Data());
7518 TString objvarname = obj->GetName();
7520 if (obj->InheritsFrom(TF1::Class())) {
7522 objvarname = gInterpreter->MapCppName(objvarname);
7523 out << " " << objvarname << "->SetParent(" << varname << ");\n";
7524 } else if (obj->InheritsFrom("TPaveStats")) {
7525 objvarname = "ptstats";
7526 withopt = kFALSE; // pave stats preserve own draw options
7527 out << " " << objvarname << "->SetParent(" << varname << ");\n";
7528 } else if (obj->InheritsFrom("TPolyMarker")) {
7529 objvarname = "pmarker";
7530 }
7531
7532 out << " " << varname << "->GetListOfFunctions()->Add(" << objvarname;
7533 if (withopt)
7534 out << ",\"" << TString(lnk->GetOption()).ReplaceSpecialCppChars() << "\"";
7535 out << ");\n";
7536
7537 lnk = lnk->Next();
7538 }
7539}
7540
7541////////////////////////////////////////////////////////////////////////////////
7582 }
7583}
7584
7585////////////////////////////////////////////////////////////////////////////////
7586/// For axis = 1,2 or 3 returns the mean value of the histogram along
7587/// X,Y or Z axis.
7588///
7589/// For axis = 11, 12, 13 returns the standard error of the mean value
7590/// of the histogram along X, Y or Z axis
7591///
7592/// Note that the mean value/StdDev is computed using the bins in the currently
7593/// defined range (see TAxis::SetRange). By default the range includes
7594/// all bins from 1 to nbins included, excluding underflows and overflows.
7595/// To force the underflows and overflows in the computation, one must
7596/// call the static function TH1::StatOverflows(kTRUE) before filling
7597/// the histogram.
7598///
7599/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7600/// are calculated. By default, if no range has been set, the returned mean is
7601/// the (unbinned) one calculated at fill time. If a range has been set, however,
7602/// the mean is calculated using the bins in range, as described above; THIS
7603/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7604/// the range. To ensure that the returned mean (and all other statistics) is
7605/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7606/// See TH1::GetStats.
7607///
7608/// Return mean value of this histogram along the X axis.
7609
7610Double_t TH1::GetMean(Int_t axis) const
7611{
7612 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7613 Double_t stats[kNstat];
7614 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7615 GetStats(stats);
7616 if (stats[0] == 0) return 0;
7617 if (axis<4){
7618 Int_t ax[3] = {2,4,7};
7619 return stats[ax[axis-1]]/stats[0];
7620 } else {
7621 // mean error = StdDev / sqrt( Neff )
7622 Double_t stddev = GetStdDev(axis-10);
7624 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7625 }
7626}
7627
7628////////////////////////////////////////////////////////////////////////////////
7629/// Return standard error of mean of this histogram along the X axis.
7630///
7631/// Note that the mean value/StdDev is computed using the bins in the currently
7632/// defined range (see TAxis::SetRange). By default the range includes
7633/// all bins from 1 to nbins included, excluding underflows and overflows.
7634/// To force the underflows and overflows in the computation, one must
7635/// call the static function TH1::StatOverflows(kTRUE) before filling
7636/// the histogram.
7637///
7638/// Also note, that although the definition of standard error doesn't include the
7639/// assumption of normality, many uses of this feature implicitly assume it.
7640///
7641/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7642/// are calculated. By default, if no range has been set, the returned value is
7643/// the (unbinned) one calculated at fill time. If a range has been set, however,
7644/// the value is calculated using the bins in range, as described above; THIS
7645/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7646/// the range. To ensure that the returned value (and all other statistics) is
7647/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7648/// See TH1::GetStats.
7649
7651{
7652 return GetMean(axis+10);
7653}
7654
7655////////////////////////////////////////////////////////////////////////////////
7656/// Returns the Standard Deviation (Sigma).
7657/// The Sigma estimate is computed as
7658/// \f[
7659/// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7660/// \f]
7661/// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7662/// X, Y or Z axis
7663/// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7664/// X, Y or Z axis for Normal distribution
7665///
7666/// Note that the mean value/sigma is computed using the bins in the currently
7667/// defined range (see TAxis::SetRange). By default the range includes
7668/// all bins from 1 to nbins included, excluding underflows and overflows.
7669/// To force the underflows and overflows in the computation, one must
7670/// call the static function TH1::StatOverflows(kTRUE) before filling
7671/// the histogram.
7672///
7673/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7674/// are calculated. By default, if no range has been set, the returned standard
7675/// deviation is the (unbinned) one calculated at fill time. If a range has been
7676/// set, however, the standard deviation is calculated using the bins in range,
7677/// as described above; THIS IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use
7678/// TAxis::SetRange(0, 0) to unset the range. To ensure that the returned standard
7679/// deviation (and all other statistics) is always that of the binned data stored
7680/// in the histogram, call TH1::ResetStats. See TH1::GetStats.
7681
7682Double_t TH1::GetStdDev(Int_t axis) const
7683{
7684 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7685
7686 Double_t x, stddev2, stats[kNstat];
7687 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7688 GetStats(stats);
7689 if (stats[0] == 0) return 0;
7690 Int_t ax[3] = {2,4,7};
7691 Int_t axm = ax[axis%10 - 1];
7692 x = stats[axm]/stats[0];
7693 // for negative stddev (e.g. when having negative weights) - return stdev=0
7694 stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7695 if (axis<10)
7696 return TMath::Sqrt(stddev2);
7697 else {
7698 // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7699 // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7701 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7702 }
7703}
7704
7705////////////////////////////////////////////////////////////////////////////////
7706/// Return error of standard deviation estimation for Normal distribution
7707///
7708/// Note that the mean value/StdDev is computed using the bins in the currently
7709/// defined range (see TAxis::SetRange). By default the range includes
7710/// all bins from 1 to nbins included, excluding underflows and overflows.
7711/// To force the underflows and overflows in the computation, one must
7712/// call the static function TH1::StatOverflows(kTRUE) before filling
7713/// the histogram.
7714///
7715/// Value returned is standard deviation of sample standard deviation.
7716/// Note that it is an approximated value which is valid only in the case that the
7717/// original data distribution is Normal. The correct one would require
7718/// the 4-th momentum value, which cannot be accurately estimated from a histogram since
7719/// the x-information for all entries is not kept.
7720///
7721/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7722/// are calculated. By default, if no range has been set, the returned value is
7723/// the (unbinned) one calculated at fill time. If a range has been set, however,
7724/// the value is calculated using the bins in range, as described above; THIS
7725/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7726/// the range. To ensure that the returned value (and all other statistics) is
7727/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7728/// See TH1::GetStats.
7729
7731{
7732 return GetStdDev(axis+10);
7733}
7734
7735////////////////////////////////////////////////////////////////////////////////
7736/// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7737/// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7738/// of the histogram along x, y or z axis
7739///
7740///Note, that since third and fourth moment are not calculated
7741///at the fill time, skewness and its standard error are computed bin by bin
7742///
7743/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7744/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7745
7747{
7748
7749 if (axis > 0 && axis <= 3){
7750
7751 Double_t mean = GetMean(axis);
7752 Double_t stddev = GetStdDev(axis);
7754
7761 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7764 if (firstBinX == 1) firstBinX = 0;
7765 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7766 }
7768 if (firstBinY == 1) firstBinY = 0;
7769 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7770 }
7772 if (firstBinZ == 1) firstBinZ = 0;
7773 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7774 }
7775 }
7776
7777 Double_t x = 0;
7778 Double_t sum=0;
7779 Double_t np=0;
7780 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7781 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7782 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7783 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7784 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7785 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7787 np+=w;
7788 sum+=w*(x-mean)*(x-mean)*(x-mean);
7789 }
7790 }
7791 }
7792 sum/=np*stddev3;
7793 return sum;
7794 }
7795 else if (axis > 10 && axis <= 13) {
7796 //compute standard error of skewness
7797 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7799 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7800 }
7801 else {
7802 Error("GetSkewness", "illegal value of parameter");
7803 return 0;
7804 }
7805}
7806
7807////////////////////////////////////////////////////////////////////////////////
7808/// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7809/// Kurtosis(gaussian(0, 1)) = 0.
7810/// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7811/// of the histogram along x, y or z axis
7812////
7813/// Note, that since third and fourth moment are not calculated
7814/// at the fill time, kurtosis and its standard error are computed bin by bin
7815///
7816/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7817/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7818
7820{
7821 if (axis > 0 && axis <= 3){
7822
7823 Double_t mean = GetMean(axis);
7824 Double_t stddev = GetStdDev(axis);
7826
7833 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7836 if (firstBinX == 1) firstBinX = 0;
7837 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7838 }
7840 if (firstBinY == 1) firstBinY = 0;
7841 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7842 }
7844 if (firstBinZ == 1) firstBinZ = 0;
7845 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7846 }
7847 }
7848
7849 Double_t x = 0;
7850 Double_t sum=0;
7851 Double_t np=0;
7852 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7853 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7854 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7855 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7856 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7857 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7859 np+=w;
7860 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7861 }
7862 }
7863 }
7864 sum/=(np*stddev4);
7865 return sum-3;
7866
7867 } else if (axis > 10 && axis <= 13) {
7868 //compute standard error of skewness
7869 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7871 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7872 }
7873 else {
7874 Error("GetKurtosis", "illegal value of parameter");
7875 return 0;
7876 }
7877}
7878
7879////////////////////////////////////////////////////////////////////////////////
7880/// fill the array stats from the contents of this histogram
7881/// The array stats must be correctly dimensioned in the calling program.
7882///
7883/// ~~~ {.cpp}
7884/// stats[0] = sumw
7885/// stats[1] = sumw2
7886/// stats[2] = sumwx
7887/// stats[3] = sumwx2
7888/// ~~~
7889///
7890/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7891/// is simply a copy of the statistics quantities computed at filling time.
7892/// If a sub-range is specified, the function recomputes these quantities
7893/// from the bin contents in the current axis range.
7894///
7895/// IMPORTANT NOTE: This means that the returned statistics are context-dependent.
7896/// If TAxis::kAxisRange, the returned statistics are dependent on the binning;
7897/// otherwise, they are a copy of the histogram statistics computed at fill time,
7898/// which are unbinned by default (calling TH1::ResetStats forces them to use
7899/// binned statistics). You can reset TAxis::kAxisRange using TAxis::SetRange(0, 0).
7900///
7901/// Note that the mean value/StdDev is computed using the bins in the currently
7902/// defined range (see TAxis::SetRange). By default the range includes
7903/// all bins from 1 to nbins included, excluding underflows and overflows.
7904/// To force the underflows and overflows in the computation, one must
7905/// call the static function TH1::StatOverflows(kTRUE) before filling
7906/// the histogram.
7907
7908void TH1::GetStats(Double_t *stats) const
7909{
7910 if (fBuffer) ((TH1*)this)->BufferEmpty();
7911
7912 // Loop on bins (possibly including underflows/overflows)
7913 Int_t bin, binx;
7914 Double_t w,err;
7915 Double_t x;
7916 // identify the case of labels with extension of axis range
7917 // in this case the statistics in x does not make any sense
7918 Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && fXaxis.CanExtend() );
7919 // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7920 if ( (fTsumw == 0 && fEntries > 0) || fXaxis.TestBit(TAxis::kAxisRange) ) {
7921 for (bin=0;bin<4;bin++) stats[bin] = 0;
7922
7925 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7927 if (firstBinX == 1) firstBinX = 0;
7928 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7929 }
7930 for (binx = firstBinX; binx <= lastBinX; binx++) {
7932 //w = TMath::Abs(RetrieveBinContent(binx));
7933 // not sure what to do here if w < 0
7935 err = TMath::Abs(GetBinError(binx));
7936 stats[0] += w;
7937 stats[1] += err*err;
7938 // statistics in x makes sense only for not labels histograms
7939 if (!labelHist) {
7940 stats[2] += w*x;
7941 stats[3] += w*x*x;
7942 }
7943 }
7944 // if (stats[0] < 0) {
7945 // // in case total is negative do something ??
7946 // stats[0] = 0;
7947 // }
7948 } else {
7949 stats[0] = fTsumw;
7950 stats[1] = fTsumw2;
7951 stats[2] = fTsumwx;
7952 stats[3] = fTsumwx2;
7953 }
7954}
7955
7956////////////////////////////////////////////////////////////////////////////////
7957/// Replace current statistics with the values in array stats
7958
7959void TH1::PutStats(Double_t *stats)
7960{
7961 fTsumw = stats[0];
7962 fTsumw2 = stats[1];
7963 fTsumwx = stats[2];
7964 fTsumwx2 = stats[3];
7965}
7966
7967////////////////////////////////////////////////////////////////////////////////
7968/// Reset the statistics including the number of entries
7969/// and replace with values calculated from bin content
7970///
7971/// The number of entries is set to the total bin content or (in case of weighted histogram)
7972/// to number of effective entries
7973///
7974/// \note By default, before calling this function, statistics are those
7975/// computed at fill time, which are unbinned. See TH1::GetStats.
7976
7977void TH1::ResetStats()
7978{
7979 Double_t stats[kNstat] = {0};
7980 fTsumw = 0;
7981 fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
7982 GetStats(stats);
7983 PutStats(stats);
7985 // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
7986 if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
7987}
7988
7989////////////////////////////////////////////////////////////////////////////////
7990/// Return the sum of all weights
7991/// \param includeOverflow true to include under/overflows bins, false to exclude those.
7992/// \note Different from TH1::GetSumOfWeights, that always excludes those
7993
7995{
7996 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7997
7998 const Int_t start = (includeOverflow ? 0 : 1);
7999 const Int_t lastX = fXaxis.GetNbins() + (includeOverflow ? 1 : 0);
8000 const Int_t lastY = fYaxis.GetNbins() + (includeOverflow ? 1 : 0);
8001 const Int_t lastZ = fZaxis.GetNbins() + (includeOverflow ? 1 : 0);
8002 Double_t sum =0;
8003 for(auto binz = start; binz <= lastZ; binz++) {
8004 for(auto biny = start; biny <= lastY; biny++) {
8005 for(auto binx = start; binx <= lastX; binx++) {
8006 const auto bin = GetBin(binx, biny, binz);
8007 sum += RetrieveBinContent(bin);
8008 }
8009 }
8010 }
8011 return sum;
8012}
8013
8014////////////////////////////////////////////////////////////////////////////////
8015///Return integral of bin contents. Only bins in the bins range are considered.
8016///
8017/// By default the integral is computed as the sum of bin contents in the range.
8018/// if option "width" is specified, the integral is the sum of
8019/// the bin contents multiplied by the bin width in x.
8020
8022{
8024}
8025
8026////////////////////////////////////////////////////////////////////////////////
8027/// Return integral of bin contents in range [binx1,binx2].
8028///
8029/// By default the integral is computed as the sum of bin contents in the range.
8030/// if option "width" is specified, the integral is the sum of
8031/// the bin contents multiplied by the bin width in x.
8032
8034{
8035 double err = 0;
8036 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
8037}
8038
8039////////////////////////////////////////////////////////////////////////////////
8040/// Return integral of bin contents in range [binx1,binx2] and its error.
8041///
8042/// By default the integral is computed as the sum of bin contents in the range.
8043/// if option "width" is specified, the integral is the sum of
8044/// the bin contents multiplied by the bin width in x.
8045/// the error is computed using error propagation from the bin errors assuming that
8046/// all the bins are uncorrelated
8047
8049{
8050 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
8051}
8052
8053////////////////////////////////////////////////////////////////////////////////
8054/// Internal function compute integral and optionally the error between the limits
8055/// specified by the bin number values working for all histograms (1D, 2D and 3D)
8056
8058 Option_t *option, Bool_t doError) const
8059{
8060 if (fBuffer) ((TH1*)this)->BufferEmpty();
8061
8062 Int_t nx = GetNbinsX() + 2;
8063 if (binx1 < 0) binx1 = 0;
8064 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
8065
8066 if (GetDimension() > 1) {
8067 Int_t ny = GetNbinsY() + 2;
8068 if (biny1 < 0) biny1 = 0;
8069 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
8070 } else {
8071 biny1 = 0; biny2 = 0;
8072 }
8073
8074 if (GetDimension() > 2) {
8075 Int_t nz = GetNbinsZ() + 2;
8076 if (binz1 < 0) binz1 = 0;
8077 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
8078 } else {
8079 binz1 = 0; binz2 = 0;
8080 }
8081
8082 // - Loop on bins in specified range
8083 TString opt = option;
8084 opt.ToLower();
8086 if (opt.Contains("width")) width = kTRUE;
8087
8088
8089 Double_t dx = 1., dy = .1, dz =.1;
8090 Double_t integral = 0;
8091 Double_t igerr2 = 0;
8092 for (Int_t binx = binx1; binx <= binx2; ++binx) {
8093 if (width) dx = fXaxis.GetBinWidth(binx);
8094 for (Int_t biny = biny1; biny <= biny2; ++biny) {
8095 if (width) dy = fYaxis.GetBinWidth(biny);
8096 for (Int_t binz = binz1; binz <= binz2; ++binz) {
8097 Int_t bin = GetBin(binx, biny, binz);
8098 Double_t dv = 0.0;
8099 if (width) {
8101 dv = dx * dy * dz;
8102 integral += RetrieveBinContent(bin) * dv;
8103 } else {
8104 integral += RetrieveBinContent(bin);
8105 }
8106 if (doError) {
8107 if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
8108 else igerr2 += GetBinErrorSqUnchecked(bin);
8109 }
8110 }
8111 }
8112 }
8113
8114 if (doError) error = TMath::Sqrt(igerr2);
8115 return integral;
8116}
8117
8118////////////////////////////////////////////////////////////////////////////////
8119/// Statistical test of compatibility in shape between
8120/// this histogram and h2, using the Anderson-Darling 2 sample test.
8121///
8122/// The AD 2 sample test formula are derived from the paper
8123/// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
8124///
8125/// The test is implemented in root in the ROOT::Math::GoFTest class
8126/// It is the same formula ( (6) in the paper), and also shown in
8127/// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
8128///
8129/// Binned data are considered as un-binned data
8130/// with identical observation happening in the bin center.
8131///
8132/// \param[in] h2 Pointer to 1D histogram
8133/// \param[in] option is a character string to specify options
8134/// - "D" Put out a line of "Debug" printout
8135/// - "T" Return the normalized A-D test statistic
8136///
8137/// - Note1: Underflow and overflow are not considered in the test
8138/// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
8139/// - Note3: The histograms are not required to have the same X axis
8140/// - Note4: The test works only for 1-dimensional histograms
8141
8143{
8144 Double_t advalue = 0;
8146
8147 TString opt = option;
8148 opt.ToUpper();
8149 if (opt.Contains("D") ) {
8150 printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
8151 }
8152 if (opt.Contains("T") ) return advalue;
8153
8154 return pvalue;
8155}
8156
8157////////////////////////////////////////////////////////////////////////////////
8158/// Same function as above but returning also the test statistic value
8159
8161{
8162 if (GetDimension() != 1 || h2->GetDimension() != 1) {
8163 Error("AndersonDarlingTest","Histograms must be 1-D");
8164 return -1;
8165 }
8166
8167 // empty the buffer. Probably we could add as an unbinned test
8168 if (fBuffer) ((TH1*)this)->BufferEmpty();
8169
8170 // use the BinData class
8173
8174 ROOT::Fit::FillData(data1, this, nullptr);
8175 ROOT::Fit::FillData(data2, h2, nullptr);
8176
8177 double pvalue;
8179
8180 return pvalue;
8181}
8182
8183////////////////////////////////////////////////////////////////////////////////
8184/// Statistical test of compatibility in shape between
8185/// this histogram and h2, using Kolmogorov test.
8186/// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
8187/// and not for binned data as in the case of the histogram (see NOTE 3 below).
8188/// So, before using this method blindly, read the NOTE 3.
8189///
8190/// Default: Ignore under- and overflow bins in comparison
8191///
8192/// \param[in] h2 histogram
8193/// \param[in] option is a character string to specify options
8194/// - "U" include Underflows in test (also for 2-dim)
8195/// - "O" include Overflows (also valid for 2-dim)
8196/// - "N" include comparison of normalizations
8197/// - "D" Put out a line of "Debug" printout
8198/// - "M" Return the Maximum Kolmogorov distance instead of prob
8199/// - "X" Run the pseudo experiments post-processor with the following procedure:
8200/// make pseudoexperiments based on random values from the parent distribution,
8201/// compare the KS distance of the pseudoexperiment to the parent
8202/// distribution, and count all the KS values above the value
8203/// obtained from the original data to Monte Carlo distribution.
8204/// The number of pseudo-experiments nEXPT is by default 1000, and
8205/// it can be changed by specifying the option as "X=number",
8206/// for example "X=10000" for 10000 toys.
8207/// The function returns the probability.
8208/// (thanks to Ben Kilminster to submit this procedure). Note that
8209/// this option "X" is much slower.
8210///
8211/// The returned function value is the probability of test
8212/// (much less than one means NOT compatible)
8213///
8214/// Code adapted by Rene Brun from original HBOOK routine HDIFF
8215///
8216/// NOTE1
8217/// A good description of the Kolmogorov test can be seen at:
8218/// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
8219///
8220/// NOTE2
8221/// see also alternative function TH1::Chi2Test
8222/// The Kolmogorov test is assumed to give better results than Chi2Test
8223/// in case of histograms with low statistics.
8224///
8225/// NOTE3 (Jan Conrad, Fred James)
8226/// "The returned value PROB is calculated such that it will be
8227/// uniformly distributed between zero and one for compatible histograms,
8228/// provided the data are not binned (or the number of bins is very large
8229/// compared with the number of events). Users who have access to unbinned
8230/// data and wish exact confidence levels should therefore not put their data
8231/// into histograms, but should call directly TMath::KolmogorovTest. On
8232/// the other hand, since TH1 is a convenient way of collecting data and
8233/// saving space, this function has been provided. However, the values of
8234/// PROB for binned data will be shifted slightly higher than expected,
8235/// depending on the effects of the binning. For example, when comparing two
8236/// uniform distributions of 500 events in 100 bins, the values of PROB,
8237/// instead of being exactly uniformly distributed between zero and one, have
8238/// a mean value of about 0.56. We can apply a useful
8239/// rule: As long as the bin width is small compared with any significant
8240/// physical effect (for example the experimental resolution) then the binning
8241/// cannot have an important effect. Therefore, we believe that for all
8242/// practical purposes, the probability value PROB is calculated correctly
8243/// provided the user is aware that:
8244///
8245/// 1. The value of PROB should not be expected to have exactly the correct
8246/// distribution for binned data.
8247/// 2. The user is responsible for seeing to it that the bin widths are
8248/// small compared with any physical phenomena of interest.
8249/// 3. The effect of binning (if any) is always to make the value of PROB
8250/// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
8251/// will assure that at most 5% of truly compatible histograms are rejected,
8252/// and usually somewhat less."
8253///
8254/// Note also that for GoF test of unbinned data ROOT provides also the class
8255/// ROOT::Math::GoFTest. The class has also method for doing one sample tests
8256/// (i.e. comparing the data with a given distribution).
8257
8259{
8260 TString opt = option;
8261 opt.ToUpper();
8262
8263 Double_t prob = 0;
8264 TH1 *h1 = (TH1*)this;
8265 if (h2 == nullptr) return 0;
8266 const TAxis *axis1 = h1->GetXaxis();
8267 const TAxis *axis2 = h2->GetXaxis();
8268 Int_t ncx1 = axis1->GetNbins();
8269 Int_t ncx2 = axis2->GetNbins();
8270
8271 // Check consistency of dimensions
8272 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
8273 Error("KolmogorovTest","Histograms must be 1-D\n");
8274 return 0;
8275 }
8276
8277 // Check consistency in number of channels
8278 if (ncx1 != ncx2) {
8279 Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
8280 return 0;
8281 }
8282
8283 // empty the buffer. Probably we could add as an unbinned test
8284 if (fBuffer) ((TH1*)this)->BufferEmpty();
8285
8286 // Check consistency in bin edges
8287 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
8288 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
8289 Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
8290 return 0;
8291 }
8292 }
8293
8296 Double_t sum1 = 0, sum2 = 0;
8297 Double_t ew1, ew2, w1 = 0, w2 = 0;
8298 Int_t bin;
8299 Int_t ifirst = 1;
8300 Int_t ilast = ncx1;
8301 // integral of all bins (use underflow/overflow if option)
8302 if (opt.Contains("U")) ifirst = 0;
8303 if (opt.Contains("O")) ilast = ncx1 +1;
8304 for (bin = ifirst; bin <= ilast; bin++) {
8305 sum1 += h1->RetrieveBinContent(bin);
8306 sum2 += h2->RetrieveBinContent(bin);
8307 ew1 = h1->GetBinError(bin);
8308 ew2 = h2->GetBinError(bin);
8309 w1 += ew1*ew1;
8310 w2 += ew2*ew2;
8311 }
8312 if (sum1 == 0) {
8313 Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
8314 return 0;
8315 }
8316 if (sum2 == 0) {
8317 Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
8318 return 0;
8319 }
8320
8321 // calculate the effective entries.
8322 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
8323 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
8324 Double_t esum1 = 0, esum2 = 0;
8325 if (w1 > 0)
8326 esum1 = sum1 * sum1 / w1;
8327 else
8328 afunc1 = kTRUE; // use later for calculating z
8329
8330 if (w2 > 0)
8331 esum2 = sum2 * sum2 / w2;
8332 else
8333 afunc2 = kTRUE; // use later for calculating z
8334
8335 if (afunc2 && afunc1) {
8336 Error("KolmogorovTest","Errors are zero for both histograms\n");
8337 return 0;
8338 }
8339
8340
8341 Double_t s1 = 1/sum1;
8342 Double_t s2 = 1/sum2;
8343
8344 // Find largest difference for Kolmogorov Test
8345 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
8346
8347 for (bin=ifirst;bin<=ilast;bin++) {
8348 rsum1 += s1*h1->RetrieveBinContent(bin);
8349 rsum2 += s2*h2->RetrieveBinContent(bin);
8351 }
8352
8353 // Get Kolmogorov probability
8354 Double_t z, prb1=0, prb2=0, prb3=0;
8355
8356 // case h1 is exact (has zero errors)
8357 if (afunc1)
8358 z = dfmax*TMath::Sqrt(esum2);
8359 // case h2 has zero errors
8360 else if (afunc2)
8361 z = dfmax*TMath::Sqrt(esum1);
8362 else
8363 // for comparison between two data sets
8365
8367
8368 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
8369 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
8370 // Combine probabilities for shape and normalization,
8371 prb1 = prob;
8374 prb2 = TMath::Prob(chi2,1);
8375 // see Eadie et al., section 11.6.2
8376 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
8377 else prob = 0;
8378 }
8379 // X option. Run Pseudo-experiments to determine NULL distribution of the
8380 // KS distance. We can find the probability from the number of pseudo-experiment that have a
8381 // KS distance larger than the one opbserved in the data.
8382 // We use the histogram with the largest statistics as a parent distribution for the NULL.
8383 // Note if one histogram has zero errors is considered as a function. In that case we use it
8384 // as parent distribution for the toys.
8385 //
8386 Int_t nEXPT = 1000;
8387 if (opt.Contains("X")) {
8388 // get number of pseudo-experiment of specified
8389 if (opt.Contains("X=")) {
8390 int numpos = opt.Index("X=") + 2; // 2 is length of X=
8391 int numlen = 0;
8392 int len = opt.Length();
8393 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) )
8394 numlen++;
8395 TString snum = opt(numpos,numlen);
8396 int num = atoi(snum.Data());
8397 if (num <= 0)
8398 Warning("KolmogorovTest","invalid number of toys given: %d - use 1000",num);
8399 else
8400 nEXPT = num;
8401 }
8402
8404 TH1D hparent;
8405 // we cannot have afunc1 and func2 both True
8406 if (afunc1 || esum1 > esum2 ) h1->Copy(hparent);
8407 else h2->Copy(hparent);
8408
8409 // copy h1Expt from h1 and h2. It is just needed to get the correct binning
8410
8411
8412 if (hparent.GetMinimum() < 0.0) {
8413 // we need to create a new histogram
8414 // With negative bins we can't draw random samples in a meaningful way.
8415 Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
8416 "skewed. Reduce number of bins for histogram?");
8417 while (hparent.GetMinimum() < 0.0) {
8418 Int_t idx = hparent.GetMinimumBin();
8419 hparent.SetBinContent(idx, 0.0);
8420 }
8421 }
8422
8423 // make nEXPT experiments (this should be a parameter)
8424 prb3 = 0;
8425 TH1D h1Expt;
8426 h1->Copy(h1Expt);
8427 TH1D h2Expt;
8428 h1->Copy(h2Expt);
8429 // loop on pseudoexperients and generate the two histograms h1Expt and h2Expt according to the
8430 // parent distribution. In case the parent distribution is not an histogram but a function randomize only one
8431 // histogram
8432 for (Int_t i=0; i < nEXPT; i++) {
8433 if (!afunc1) {
8434 h1Expt.Reset();
8435 h1Expt.FillRandom(&hparent, (Int_t)esum1);
8436 }
8437 if (!afunc2) {
8438 h2Expt.Reset();
8439 h2Expt.FillRandom(&hparent, (Int_t)esum2);
8440 }
8441 // note we cannot have both afunc1 and afunc2 to be true
8442 if (afunc1)
8443 dSEXPT = hparent.KolmogorovTest(&h2Expt,"M");
8444 else if (afunc2)
8445 dSEXPT = hparent.KolmogorovTest(&h1Expt,"M");
8446 else
8447 dSEXPT = h1Expt.KolmogorovTest(&h2Expt,"M");
8448 // count number of cases toy KS distance (TS) is larger than oberved one
8449 if (dSEXPT>dfmax) prb3 += 1.0;
8450 }
8451 // compute p-value
8452 prb3 /= (Double_t)nEXPT;
8453 }
8454
8455
8456 // debug printout
8457 if (opt.Contains("D")) {
8458 printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
8459 printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
8460 printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
8461 if (opt.Contains("N"))
8462 printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
8463 if (opt.Contains("X"))
8464 printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
8465 }
8466 // This numerical error condition should never occur:
8467 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
8468 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
8469
8470 if(opt.Contains("M")) return dfmax;
8471 else if(opt.Contains("X")) return prb3;
8472 else return prob;
8473}
8474
8475////////////////////////////////////////////////////////////////////////////////
8476/// Replace bin contents by the contents of array content
8477
8478void TH1::SetContent(const Double_t *content)
8479{
8480 fEntries = fNcells;
8481 fTsumw = 0;
8482 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
8483}
8484
8485////////////////////////////////////////////////////////////////////////////////
8486/// Return contour values into array levels if pointer levels is non zero.
8487///
8488/// The function returns the number of contour levels.
8489/// see GetContourLevel to return one contour only
8490
8492{
8494 if (levels) {
8495 if (nlevels == 0) {
8496 nlevels = 20;
8498 } else {
8500 }
8501 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
8502 }
8503 return nlevels;
8504}
8505
8506////////////////////////////////////////////////////////////////////////////////
8507/// Return value of contour number level.
8508/// Use GetContour to return the array of all contour levels
8509
8511{
8512 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
8513}
8514
8515////////////////////////////////////////////////////////////////////////////////
8516/// Return the value of contour number "level" in Pad coordinates.
8517/// ie: if the Pad is in log scale along Z it returns le log of the contour level
8518/// value. See GetContour to return the array of all contour levels
8519
8521{
8522 if (level <0 || level >= fContour.fN) return 0;
8523 Double_t zlevel = fContour.fArray[level];
8524
8525 // In case of user defined contours and Pad in log scale along Z,
8526 // fContour.fArray doesn't contain the log of the contour whereas it does
8527 // in case of equidistant contours.
8528 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
8529 if (zlevel <= 0) return 0;
8531 }
8532 return zlevel;
8533}
8534
8535////////////////////////////////////////////////////////////////////////////////
8536/// Set the maximum number of entries to be kept in the buffer.
8537
8538void TH1::SetBuffer(Int_t bufsize, Option_t * /*option*/)
8539{
8540 if (fBuffer) {
8541 BufferEmpty();
8542 delete [] fBuffer;
8543 fBuffer = nullptr;
8544 }
8545 if (bufsize <= 0) {
8546 fBufferSize = 0;
8547 return;
8548 }
8549 if (bufsize < 100) bufsize = 100;
8550 fBufferSize = 1 + bufsize*(fDimension+1);
8552 memset(fBuffer, 0, sizeof(Double_t)*fBufferSize);
8553}
8554
8555////////////////////////////////////////////////////////////////////////////////
8556/// Set the number and values of contour levels.
8557///
8558/// By default the number of contour levels is set to 20. The contours values
8559/// in the array "levels" should be specified in increasing order.
8560///
8561/// if argument levels = 0 or missing, `nlevels` equidistant contours are computed
8562/// between `zmin` and `zmax - dz`, both included, with step
8563/// `dz = (zmax - zmin)/nlevels`. Note that contour lines are not centered, but
8564/// contour surfaces (when drawing with `COLZ`) will be, since contour color `i` covers
8565/// the region of values between contour line `i` and `i+1`.
8566
8568{
8569 Int_t level;
8571 if (nlevels <=0 ) {
8572 fContour.Set(0);
8573 return;
8574 }
8576
8577 // - Contour levels are specified
8578 if (levels) {
8580 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
8581 } else {
8582 // - contour levels are computed automatically as equidistant contours
8583 Double_t zmin = GetMinimum();
8584 Double_t zmax = GetMaximum();
8585 if ((zmin == zmax) && (zmin != 0)) {
8586 zmax += 0.01*TMath::Abs(zmax);
8587 zmin -= 0.01*TMath::Abs(zmin);
8588 }
8589 Double_t dz = (zmax-zmin)/Double_t(nlevels);
8590 if (gPad && gPad->GetLogz()) {
8591 if (zmax <= 0) return;
8592 if (zmin <= 0) zmin = 0.001*zmax;
8593 zmin = TMath::Log10(zmin);
8594 zmax = TMath::Log10(zmax);
8595 dz = (zmax-zmin)/Double_t(nlevels);
8596 }
8597 for (level=0; level<nlevels; level++) {
8598 fContour.fArray[level] = zmin + dz*Double_t(level);
8599 }
8600 }
8601}
8602
8603////////////////////////////////////////////////////////////////////////////////
8604/// Set value for one contour level.
8605
8607{
8608 if (level < 0 || level >= fContour.fN) return;
8610 fContour.fArray[level] = value;
8611}
8612
8613////////////////////////////////////////////////////////////////////////////////
8614/// Return maximum value smaller than maxval of bins in the range,
8615/// unless the value has been overridden by TH1::SetMaximum,
8616/// in which case it returns that value. This happens, for example,
8617/// when the histogram is drawn and the y or z axis limits are changed
8618///
8619/// To get the maximum value of bins in the histogram regardless of
8620/// whether the value has been overridden (using TH1::SetMaximum), use
8621///
8622/// ~~~ {.cpp}
8623/// h->GetBinContent(h->GetMaximumBin())
8624/// ~~~
8625///
8626/// TH1::GetMaximumBin can be used to get the location of the maximum
8627/// value.
8628
8630{
8631 if (fMaximum != -1111) return fMaximum;
8632
8633 // empty the buffer
8634 if (fBuffer) ((TH1*)this)->BufferEmpty();
8635
8636 Int_t bin, binx, biny, binz;
8637 Int_t xfirst = fXaxis.GetFirst();
8638 Int_t xlast = fXaxis.GetLast();
8639 Int_t yfirst = fYaxis.GetFirst();
8640 Int_t ylast = fYaxis.GetLast();
8641 Int_t zfirst = fZaxis.GetFirst();
8642 Int_t zlast = fZaxis.GetLast();
8644 for (binz=zfirst;binz<=zlast;binz++) {
8645 for (biny=yfirst;biny<=ylast;biny++) {
8646 for (binx=xfirst;binx<=xlast;binx++) {
8647 bin = GetBin(binx,biny,binz);
8649 if (value > maximum && value < maxval) maximum = value;
8650 }
8651 }
8652 }
8653 return maximum;
8654}
8655
8656////////////////////////////////////////////////////////////////////////////////
8657/// Return location of bin with maximum value in the range.
8658///
8659/// TH1::GetMaximum can be used to get the maximum value.
8660
8662{
8665}
8666
8667////////////////////////////////////////////////////////////////////////////////
8668/// Return location of bin with maximum value in the range.
8669
8671{
8672 // empty the buffer
8673 if (fBuffer) ((TH1*)this)->BufferEmpty();
8674
8675 Int_t bin, binx, biny, binz;
8676 Int_t locm;
8677 Int_t xfirst = fXaxis.GetFirst();
8678 Int_t xlast = fXaxis.GetLast();
8679 Int_t yfirst = fYaxis.GetFirst();
8680 Int_t ylast = fYaxis.GetLast();
8681 Int_t zfirst = fZaxis.GetFirst();
8682 Int_t zlast = fZaxis.GetLast();
8684 locm = locmax = locmay = locmaz = 0;
8685 for (binz=zfirst;binz<=zlast;binz++) {
8686 for (biny=yfirst;biny<=ylast;biny++) {
8687 for (binx=xfirst;binx<=xlast;binx++) {
8688 bin = GetBin(binx,biny,binz);
8690 if (value > maximum) {
8691 maximum = value;
8692 locm = bin;
8693 locmax = binx;
8694 locmay = biny;
8695 locmaz = binz;
8696 }
8697 }
8698 }
8699 }
8700 return locm;
8701}
8702
8703////////////////////////////////////////////////////////////////////////////////
8704/// Return minimum value larger than minval of bins in the range,
8705/// unless the value has been overridden by TH1::SetMinimum,
8706/// in which case it returns that value. This happens, for example,
8707/// when the histogram is drawn and the y or z axis limits are changed
8708///
8709/// To get the minimum value of bins in the histogram regardless of
8710/// whether the value has been overridden (using TH1::SetMinimum), use
8711///
8712/// ~~~ {.cpp}
8713/// h->GetBinContent(h->GetMinimumBin())
8714/// ~~~
8715///
8716/// TH1::GetMinimumBin can be used to get the location of the
8717/// minimum value.
8718
8720{
8721 if (fMinimum != -1111) return fMinimum;
8722
8723 // empty the buffer
8724 if (fBuffer) ((TH1*)this)->BufferEmpty();
8725
8726 Int_t bin, binx, biny, binz;
8727 Int_t xfirst = fXaxis.GetFirst();
8728 Int_t xlast = fXaxis.GetLast();
8729 Int_t yfirst = fYaxis.GetFirst();
8730 Int_t ylast = fYaxis.GetLast();
8731 Int_t zfirst = fZaxis.GetFirst();
8732 Int_t zlast = fZaxis.GetLast();
8734 for (binz=zfirst;binz<=zlast;binz++) {
8735 for (biny=yfirst;biny<=ylast;biny++) {
8736 for (binx=xfirst;binx<=xlast;binx++) {
8737 bin = GetBin(binx,biny,binz);
8740 }
8741 }
8742 }
8743 return minimum;
8744}
8745
8746////////////////////////////////////////////////////////////////////////////////
8747/// Return location of bin with minimum value in the range.
8748
8750{
8753}
8754
8755////////////////////////////////////////////////////////////////////////////////
8756/// Return location of bin with minimum value in the range.
8757
8759{
8760 // empty the buffer
8761 if (fBuffer) ((TH1*)this)->BufferEmpty();
8762
8763 Int_t bin, binx, biny, binz;
8764 Int_t locm;
8765 Int_t xfirst = fXaxis.GetFirst();
8766 Int_t xlast = fXaxis.GetLast();
8767 Int_t yfirst = fYaxis.GetFirst();
8768 Int_t ylast = fYaxis.GetLast();
8769 Int_t zfirst = fZaxis.GetFirst();
8770 Int_t zlast = fZaxis.GetLast();
8772 locm = locmix = locmiy = locmiz = 0;
8773 for (binz=zfirst;binz<=zlast;binz++) {
8774 for (biny=yfirst;biny<=ylast;biny++) {
8775 for (binx=xfirst;binx<=xlast;binx++) {
8776 bin = GetBin(binx,biny,binz);
8778 if (value < minimum) {
8779 minimum = value;
8780 locm = bin;
8781 locmix = binx;
8782 locmiy = biny;
8783 locmiz = binz;
8784 }
8785 }
8786 }
8787 }
8788 return locm;
8789}
8790
8791///////////////////////////////////////////////////////////////////////////////
8792/// Retrieve the minimum and maximum values in the histogram
8793///
8794/// This will not return a cached value and will always search the
8795/// histogram for the min and max values. The user can condition whether
8796/// or not to call this with the GetMinimumStored() and GetMaximumStored()
8797/// methods. If the cache is empty, then the value will be -1111. Users
8798/// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8799/// For example, the following recipe will make efficient use of this method
8800/// and the cached minimum and maximum values.
8801//
8802/// \code{.cpp}
8803/// Double_t currentMin = pHist->GetMinimumStored();
8804/// Double_t currentMax = pHist->GetMaximumStored();
8805/// if ((currentMin == -1111) || (currentMax == -1111)) {
8806/// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8807/// pHist->SetMinimum(currentMin);
8808/// pHist->SetMaximum(currentMax);
8809/// }
8810/// \endcode
8811///
8812/// \param min reference to variable that will hold found minimum value
8813/// \param max reference to variable that will hold found maximum value
8814
8815void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8816{
8817 // empty the buffer
8818 if (fBuffer) ((TH1*)this)->BufferEmpty();
8819
8820 Int_t bin, binx, biny, binz;
8821 Int_t xfirst = fXaxis.GetFirst();
8822 Int_t xlast = fXaxis.GetLast();
8823 Int_t yfirst = fYaxis.GetFirst();
8824 Int_t ylast = fYaxis.GetLast();
8825 Int_t zfirst = fZaxis.GetFirst();
8826 Int_t zlast = fZaxis.GetLast();
8827 min=TMath::Infinity();
8828 max=-TMath::Infinity();
8830 for (binz=zfirst;binz<=zlast;binz++) {
8831 for (biny=yfirst;biny<=ylast;biny++) {
8832 for (binx=xfirst;binx<=xlast;binx++) {
8833 bin = GetBin(binx,biny,binz);
8835 if (value < min) min = value;
8836 if (value > max) max = value;
8837 }
8838 }
8839 }
8840}
8841
8842////////////////////////////////////////////////////////////////////////////////
8843/// Redefine x axis parameters.
8844///
8845/// The X axis parameters are modified.
8846/// The bins content array is resized
8847/// if errors (Sumw2) the errors array is resized
8848/// The previous bin contents are lost
8849/// To change only the axis limits, see TAxis::SetRange
8850
8852{
8853 if (GetDimension() != 1) {
8854 Error("SetBins","Operation only valid for 1-d histograms");
8855 return;
8856 }
8857 fXaxis.SetRange(0,0);
8859 fYaxis.Set(1,0,1);
8860 fZaxis.Set(1,0,1);
8861 fNcells = nx+2;
8863 if (fSumw2.fN) {
8865 }
8866}
8867
8868////////////////////////////////////////////////////////////////////////////////
8869/// Redefine x axis parameters with variable bin sizes.
8870///
8871/// The X axis parameters are modified.
8872/// The bins content array is resized
8873/// if errors (Sumw2) the errors array is resized
8874/// The previous bin contents are lost
8875/// To change only the axis limits, see TAxis::SetRange
8876/// xBins is supposed to be of length nx+1
8877
8878void TH1::SetBins(Int_t nx, const Double_t *xBins)
8879{
8880 if (GetDimension() != 1) {
8881 Error("SetBins","Operation only valid for 1-d histograms");
8882 return;
8883 }
8884 fXaxis.SetRange(0,0);
8885 fXaxis.Set(nx,xBins);
8886 fYaxis.Set(1,0,1);
8887 fZaxis.Set(1,0,1);
8888 fNcells = nx+2;
8890 if (fSumw2.fN) {
8892 }
8893}
8894
8895////////////////////////////////////////////////////////////////////////////////
8896/// Redefine x and y axis parameters.
8897///
8898/// The X and Y axis parameters are modified.
8899/// The bins content array is resized
8900/// if errors (Sumw2) the errors array is resized
8901/// The previous bin contents are lost
8902/// To change only the axis limits, see TAxis::SetRange
8903
8905{
8906 if (GetDimension() != 2) {
8907 Error("SetBins","Operation only valid for 2-D histograms");
8908 return;
8909 }
8910 fXaxis.SetRange(0,0);
8911 fYaxis.SetRange(0,0);
8914 fZaxis.Set(1,0,1);
8915 fNcells = (nx+2)*(ny+2);
8917 if (fSumw2.fN) {
8919 }
8920}
8921
8922////////////////////////////////////////////////////////////////////////////////
8923/// Redefine x and y axis parameters with variable bin sizes.
8924///
8925/// The X and Y axis parameters are modified.
8926/// The bins content array is resized
8927/// if errors (Sumw2) the errors array is resized
8928/// The previous bin contents are lost
8929/// To change only the axis limits, see TAxis::SetRange
8930/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
8931
8932void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
8933{
8934 if (GetDimension() != 2) {
8935 Error("SetBins","Operation only valid for 2-D histograms");
8936 return;
8937 }
8938 fXaxis.SetRange(0,0);
8939 fYaxis.SetRange(0,0);
8940 fXaxis.Set(nx,xBins);
8941 fYaxis.Set(ny,yBins);
8942 fZaxis.Set(1,0,1);
8943 fNcells = (nx+2)*(ny+2);
8945 if (fSumw2.fN) {
8947 }
8948}
8949
8950////////////////////////////////////////////////////////////////////////////////
8951/// Redefine x, y and z axis parameters.
8952///
8953/// The X, Y and Z axis parameters are modified.
8954/// The bins content array is resized
8955/// if errors (Sumw2) the errors array is resized
8956/// The previous bin contents are lost
8957/// To change only the axis limits, see TAxis::SetRange
8958
8960{
8961 if (GetDimension() != 3) {
8962 Error("SetBins","Operation only valid for 3-D histograms");
8963 return;
8964 }
8965 fXaxis.SetRange(0,0);
8966 fYaxis.SetRange(0,0);
8967 fZaxis.SetRange(0,0);
8970 fZaxis.Set(nz,zmin,zmax);
8971 fNcells = (nx+2)*(ny+2)*(nz+2);
8973 if (fSumw2.fN) {
8975 }
8976}
8977
8978////////////////////////////////////////////////////////////////////////////////
8979/// Redefine x, y and z axis parameters with variable bin sizes.
8980///
8981/// The X, Y and Z axis parameters are modified.
8982/// The bins content array is resized
8983/// if errors (Sumw2) the errors array is resized
8984/// The previous bin contents are lost
8985/// To change only the axis limits, see TAxis::SetRange
8986/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
8987/// zBins is supposed to be of length nz+1
8988
8989void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
8990{
8991 if (GetDimension() != 3) {
8992 Error("SetBins","Operation only valid for 3-D histograms");
8993 return;
8994 }
8995 fXaxis.SetRange(0,0);
8996 fYaxis.SetRange(0,0);
8997 fZaxis.SetRange(0,0);
8998 fXaxis.Set(nx,xBins);
8999 fYaxis.Set(ny,yBins);
9000 fZaxis.Set(nz,zBins);
9001 fNcells = (nx+2)*(ny+2)*(nz+2);
9003 if (fSumw2.fN) {
9005 }
9006}
9007
9008////////////////////////////////////////////////////////////////////////////////
9009/// By default, when a histogram is created, it is added to the list
9010/// of histogram objects in the current directory in memory.
9011/// Remove reference to this histogram from current directory and add
9012/// reference to new directory dir. dir can be 0 in which case the
9013/// histogram does not belong to any directory.
9014///
9015/// Note that the directory is not a real property of the histogram and
9016/// it will not be copied when the histogram is copied or cloned.
9017/// If the user wants to have the copied (cloned) histogram in the same
9018/// directory, he needs to set again the directory using SetDirectory to the
9019/// copied histograms
9020
9022{
9023 if (fDirectory == dir) return;
9024 if (fDirectory) fDirectory->Remove(this);
9025 fDirectory = dir;
9026 if (fDirectory) {
9028 fDirectory->Append(this);
9029 }
9030}
9031
9032////////////////////////////////////////////////////////////////////////////////
9033/// Replace bin errors by values in array error.
9034
9035void TH1::SetError(const Double_t *error)
9036{
9037 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
9038}
9039
9040////////////////////////////////////////////////////////////////////////////////
9041/// Change the name of this histogram
9043
9044void TH1::SetName(const char *name)
9045{
9046 // Histograms are named objects in a THashList.
9047 // We must update the hashlist if we change the name
9048 // We protect this operation
9050 if (fDirectory) fDirectory->Remove(this);
9051 fName = name;
9052 if (fDirectory) fDirectory->Append(this);
9053}
9054
9055////////////////////////////////////////////////////////////////////////////////
9056/// Change the name and title of this histogram
9057
9058void TH1::SetNameTitle(const char *name, const char *title)
9059{
9060 // Histograms are named objects in a THashList.
9061 // We must update the hashlist if we change the name
9062 SetName(name);
9063 SetTitle(title);
9064}
9065
9066////////////////////////////////////////////////////////////////////////////////
9067/// Set statistics option on/off.
9068///
9069/// By default, the statistics box is drawn.
9070/// The paint options can be selected via gStyle->SetOptStat.
9071/// This function sets/resets the kNoStats bit in the histogram object.
9072/// It has priority over the Style option.
9073
9074void TH1::SetStats(Bool_t stats)
9075{
9077 if (!stats) {
9079 //remove the "stats" object from the list of functions
9080 if (fFunctions) {
9081 TObject *obj = fFunctions->FindObject("stats");
9082 if (obj) {
9083 fFunctions->Remove(obj);
9084 delete obj;
9085 }
9086 }
9087 }
9088}
9089
9090////////////////////////////////////////////////////////////////////////////////
9091/// Create structure to store sum of squares of weights.
9092///
9093/// if histogram is already filled, the sum of squares of weights
9094/// is filled with the existing bin contents
9095///
9096/// The error per bin will be computed as sqrt(sum of squares of weight)
9097/// for each bin.
9098///
9099/// This function is automatically called when the histogram is created
9100/// if the static function TH1::SetDefaultSumw2 has been called before.
9101/// If flag = false the structure containing the sum of the square of weights
9102/// is rest and it will be empty, but it is not deleted (i.e. GetSumw2()->fN = 0)
9103
9105{
9106 if (!flag) {
9107 // clear the array if existing - do nothing otherwise
9108 if (fSumw2.fN > 0 ) fSumw2.Set(0);
9109 return;
9110 }
9111
9112 if (fSumw2.fN == fNcells) {
9113 if (!fgDefaultSumw2 )
9114 Warning("Sumw2","Sum of squares of weights structure already created");
9115 return;
9116 }
9117
9119
9120 if (fEntries > 0)
9121 for (Int_t i = 0; i < fNcells; ++i)
9123}
9124
9125////////////////////////////////////////////////////////////////////////////////
9126/// Return pointer to function with name.
9127///
9128///
9129/// Functions such as TH1::Fit store the fitted function in the list of
9130/// functions of this histogram.
9131
9132TF1 *TH1::GetFunction(const char *name) const
9133{
9134 return (TF1*)fFunctions->FindObject(name);
9135}
9136
9137////////////////////////////////////////////////////////////////////////////////
9138/// Return value of error associated to bin number bin.
9139///
9140/// if the sum of squares of weights has been defined (via Sumw2),
9141/// this function returns the sqrt(sum of w2).
9142/// otherwise it returns the sqrt(contents) for this bin.
9143
9145{
9146 if (bin < 0) bin = 0;
9147 if (bin >= fNcells) bin = fNcells-1;
9148 if (fBuffer) ((TH1*)this)->BufferEmpty();
9149 if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
9150
9152}
9153
9154////////////////////////////////////////////////////////////////////////////////
9155/// Return lower error associated to bin number bin.
9156///
9157/// The error will depend on the statistic option used will return
9158/// the binContent - lower interval value
9159
9161{
9162 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9163 // in case of weighted histogram check if it is really weighted
9164 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9165
9166 if (bin < 0) bin = 0;
9167 if (bin >= fNcells) bin = fNcells-1;
9168 if (fBuffer) ((TH1*)this)->BufferEmpty();
9169
9170 Double_t alpha = 1.- 0.682689492;
9171 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9172
9174 Int_t n = int(c);
9175 if (n < 0) {
9176 Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
9177 ((TH1*)this)->fBinStatErrOpt = kNormal;
9178 return GetBinError(bin);
9179 }
9180
9181 if (n == 0) return 0;
9182 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
9183}
9184
9185////////////////////////////////////////////////////////////////////////////////
9186/// Return upper error associated to bin number bin.
9187///
9188/// The error will depend on the statistic option used will return
9189/// the binContent - upper interval value
9190
9192{
9193 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9194 // in case of weighted histogram check if it is really weighted
9195 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9196 if (bin < 0) bin = 0;
9197 if (bin >= fNcells) bin = fNcells-1;
9198 if (fBuffer) ((TH1*)this)->BufferEmpty();
9199
9200 Double_t alpha = 1.- 0.682689492;
9201 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9202
9204 Int_t n = int(c);
9205 if (n < 0) {
9206 Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
9207 ((TH1*)this)->fBinStatErrOpt = kNormal;
9208 return GetBinError(bin);
9209 }
9210
9211 // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
9212 // decide to return always (1-alpha)/2 upper interval
9213 //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
9214 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
9215}
9216
9217//L.M. These following getters are useless and should be probably deprecated
9218////////////////////////////////////////////////////////////////////////////////
9219/// Return bin center for 1D histogram.
9220/// Better to use h1.GetXaxis()->GetBinCenter(bin)
9221
9223{
9224 if (fDimension == 1) return fXaxis.GetBinCenter(bin);
9225 Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
9226 return TMath::QuietNaN();
9227}
9228
9229////////////////////////////////////////////////////////////////////////////////
9230/// Return bin lower edge for 1D histogram.
9231/// Better to use h1.GetXaxis()->GetBinLowEdge(bin)
9232
9234{
9235 if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
9236 Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
9237 return TMath::QuietNaN();
9238}
9239
9240////////////////////////////////////////////////////////////////////////////////
9241/// Return bin width for 1D histogram.
9242/// Better to use h1.GetXaxis()->GetBinWidth(bin)
9243
9245{
9246 if (fDimension == 1) return fXaxis.GetBinWidth(bin);
9247 Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
9248 return TMath::QuietNaN();
9249}
9250
9251////////////////////////////////////////////////////////////////////////////////
9252/// Fill array with center of bins for 1D histogram
9253/// Better to use h1.GetXaxis()->GetCenter(center)
9254
9255void TH1::GetCenter(Double_t *center) const
9256{
9257 if (fDimension == 1) {
9258 fXaxis.GetCenter(center);
9259 return;
9260 }
9261 Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
9262}
9263
9264////////////////////////////////////////////////////////////////////////////////
9265/// Fill array with low edge of bins for 1D histogram
9266/// Better to use h1.GetXaxis()->GetLowEdge(edge)
9267
9268void TH1::GetLowEdge(Double_t *edge) const
9269{
9270 if (fDimension == 1) {
9272 return;
9273 }
9274 Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
9275}
9276
9277////////////////////////////////////////////////////////////////////////////////
9278/// Set the bin Error
9279/// Note that this resets the bin eror option to be of Normal Type and for the
9280/// non-empty bin the bin error is set by default to the square root of their content.
9281/// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
9282/// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
9283/// will not be recalculated after setting the content and a default error = 0 will be used for those bins.
9284///
9285/// See convention for numbering bins in TH1::GetBin
9286
9287void TH1::SetBinError(Int_t bin, Double_t error)
9288{
9289 if (bin < 0 || bin>= fNcells) return;
9290 if (!fSumw2.fN) Sumw2();
9291 fSumw2.fArray[bin] = error * error;
9292 // reset the bin error option
9294}
9295
9296////////////////////////////////////////////////////////////////////////////////
9297/// Set bin content
9298/// see convention for numbering bins in TH1::GetBin
9299/// In case the bin number is greater than the number of bins and
9300/// the timedisplay option is set or CanExtendAllAxes(),
9301/// the number of bins is automatically doubled to accommodate the new bin
9302
9304{
9305 fEntries++;
9306 fTsumw = 0;
9307 if (bin < 0) return;
9308 if (bin >= fNcells-1) {
9310 while (bin >= fNcells-1) LabelsInflate();
9311 } else {
9312 if (bin == fNcells-1) UpdateBinContent(bin, content);
9313 return;
9314 }
9315 }
9317}
9318
9319////////////////////////////////////////////////////////////////////////////////
9320/// See convention for numbering bins in TH1::GetBin
9321
9323{
9324 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9325 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9326 SetBinError(GetBin(binx, biny), error);
9327}
9328
9329////////////////////////////////////////////////////////////////////////////////
9330/// See convention for numbering bins in TH1::GetBin
9331
9333{
9334 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9335 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9336 if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
9337 SetBinError(GetBin(binx, biny, binz), error);
9338}
9339
9340////////////////////////////////////////////////////////////////////////////////
9341/// This function calculates the background spectrum in this histogram.
9342/// The background is returned as a histogram.
9343///
9344/// \param[in] niter number of iterations (default value = 2)
9345/// Increasing niter make the result smoother and lower.
9346/// \param[in] option may contain one of the following options
9347/// - to set the direction parameter
9348/// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
9349/// - filterOrder-order of clipping filter (default "BackOrder2")
9350/// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
9351/// - "nosmoothing" - if selected, the background is not smoothed
9352/// By default the background is smoothed.
9353/// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
9354/// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
9355/// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
9356/// - "nocompton" - if selected the estimation of Compton edge
9357/// will be not be included (by default the compton estimation is set)
9358/// - "same" if this option is specified, the resulting background
9359/// histogram is superimposed on the picture in the current pad.
9360/// This option is given by default.
9361///
9362/// NOTE that the background is only evaluated in the current range of this histogram.
9363/// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
9364/// the returned histogram will be created with the same number of bins
9365/// as this input histogram, but only bins from binmin to binmax will be filled
9366/// with the estimated background.
9367
9369{
9370 return (TH1*)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticBackground((TH1*)0x%zx,%d,\"%s\")",
9371 (size_t)this, niter, option).Data());
9372}
9373
9374////////////////////////////////////////////////////////////////////////////////
9375/// Interface to TSpectrum::Search.
9376/// The function finds peaks in this histogram where the width is > sigma
9377/// and the peak maximum greater than threshold*maximum bin content of this.
9378/// For more details see TSpectrum::Search.
9379/// Note the difference in the default value for option compared to TSpectrum::Search
9380/// option="" by default (instead of "goff").
9381
9383{
9384 return (Int_t)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticSearch((TH1*)0x%zx,%g,\"%s\",%g)",
9385 (size_t)this, sigma, option, threshold).Data());
9386}
9387
9388////////////////////////////////////////////////////////////////////////////////
9389/// For a given transform (first parameter), fills the histogram (second parameter)
9390/// with the transform output data, specified in the third parameter
9391/// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
9392/// and the user is responsible for deleting it.
9393///
9394/// Available options:
9395/// - "RE" - real part of the output
9396/// - "IM" - imaginary part of the output
9397/// - "MAG" - magnitude of the output
9398/// - "PH" - phase of the output
9399
9401{
9402 if (!fft || !fft->GetN() ) {
9403 ::Error("TransformHisto","Invalid FFT transform class");
9404 return nullptr;
9405 }
9406
9407 if (fft->GetNdim()>2){
9408 ::Error("TransformHisto","Only 1d and 2D transform are supported");
9409 return nullptr;
9410 }
9411 Int_t binx,biny;
9412 TString opt = option;
9413 opt.ToUpper();
9414 Int_t *n = fft->GetN();
9415 TH1 *hout=nullptr;
9416 if (h_output) {
9417 hout = h_output;
9418 }
9419 else {
9420 TString name = TString::Format("out_%s", opt.Data());
9421 if (fft->GetNdim()==1)
9422 hout = new TH1D(name, name,n[0], 0, n[0]);
9423 else if (fft->GetNdim()==2)
9424 hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
9425 }
9426 R__ASSERT(hout != nullptr);
9427 TString type=fft->GetType();
9428 Int_t ind[2];
9429 if (opt.Contains("RE")){
9430 if (type.Contains("2C") || type.Contains("2HC")) {
9431 Double_t re, im;
9432 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9433 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9434 ind[0] = binx-1; ind[1] = biny-1;
9435 fft->GetPointComplex(ind, re, im);
9436 hout->SetBinContent(binx, biny, re);
9437 }
9438 }
9439 } else {
9440 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9441 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9442 ind[0] = binx-1; ind[1] = biny-1;
9443 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
9444 }
9445 }
9446 }
9447 }
9448 if (opt.Contains("IM")) {
9449 if (type.Contains("2C") || type.Contains("2HC")) {
9450 Double_t re, im;
9451 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9452 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9453 ind[0] = binx-1; ind[1] = biny-1;
9454 fft->GetPointComplex(ind, re, im);
9455 hout->SetBinContent(binx, biny, im);
9456 }
9457 }
9458 } else {
9459 ::Error("TransformHisto","No complex numbers in the output");
9460 return nullptr;
9461 }
9462 }
9463 if (opt.Contains("MA")) {
9464 if (type.Contains("2C") || type.Contains("2HC")) {
9465 Double_t re, im;
9466 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9467 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9468 ind[0] = binx-1; ind[1] = biny-1;
9469 fft->GetPointComplex(ind, re, im);
9470 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
9471 }
9472 }
9473 } else {
9474 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9475 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9476 ind[0] = binx-1; ind[1] = biny-1;
9477 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
9478 }
9479 }
9480 }
9481 }
9482 if (opt.Contains("PH")) {
9483 if (type.Contains("2C") || type.Contains("2HC")){
9484 Double_t re, im, ph;
9485 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
9486 for (biny=1; biny<=hout->GetNbinsY(); biny++){
9487 ind[0] = binx-1; ind[1] = biny-1;
9488 fft->GetPointComplex(ind, re, im);
9489 if (TMath::Abs(re) > 1e-13){
9490 ph = TMath::ATan(im/re);
9491 //find the correct quadrant
9492 if (re<0 && im<0)
9493 ph -= TMath::Pi();
9494 if (re<0 && im>=0)
9495 ph += TMath::Pi();
9496 } else {
9497 if (TMath::Abs(im) < 1e-13)
9498 ph = 0;
9499 else if (im>0)
9500 ph = TMath::Pi()*0.5;
9501 else
9502 ph = -TMath::Pi()*0.5;
9503 }
9504 hout->SetBinContent(binx, biny, ph);
9505 }
9506 }
9507 } else {
9508 printf("Pure real output, no phase");
9509 return nullptr;
9510 }
9511 }
9512
9513 return hout;
9514}
9515
9516////////////////////////////////////////////////////////////////////////////////
9517/// Print value overload
9518
9519std::string cling::printValue(TH1 *val) {
9520 std::ostringstream strm;
9521 strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
9522 return strm.str();
9523}
9524
9525//______________________________________________________________________________
9526// TH1C methods
9527// TH1C : histograms with one byte per channel. Maximum bin content = 127
9528//______________________________________________________________________________
9529
9530
9531////////////////////////////////////////////////////////////////////////////////
9532/// Constructor.
9533
9534TH1C::TH1C()
9535{
9536 fDimension = 1;
9537 SetBinsLength(3);
9538 if (fgDefaultSumw2) Sumw2();
9539}
9540
9541////////////////////////////////////////////////////////////////////////////////
9542/// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
9543/// (see TH1::TH1 for explanation of parameters)
9544
9545TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9546: TH1(name,title,nbins,xlow,xup)
9547{
9548 fDimension = 1;
9550
9551 if (xlow >= xup) SetBuffer(fgBufferSize);
9552 if (fgDefaultSumw2) Sumw2();
9553}
9554
9555////////////////////////////////////////////////////////////////////////////////
9556/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9557/// (see TH1::TH1 for explanation of parameters)
9558
9559TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9560: TH1(name,title,nbins,xbins)
9561{
9562 fDimension = 1;
9564 if (fgDefaultSumw2) Sumw2();
9565}
9566
9567////////////////////////////////////////////////////////////////////////////////
9568/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9569/// (see TH1::TH1 for explanation of parameters)
9570
9571TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9572: TH1(name,title,nbins,xbins)
9573{
9574 fDimension = 1;
9576 if (fgDefaultSumw2) Sumw2();
9577}
9578
9579////////////////////////////////////////////////////////////////////////////////
9580/// Destructor.
9581
9583{
9584}
9585
9586////////////////////////////////////////////////////////////////////////////////
9587/// Copy constructor.
9588/// The list of functions is not copied. (Use Clone() if needed)
9589
9590TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
9591{
9592 h1c.TH1C::Copy(*this);
9593}
9594
9595////////////////////////////////////////////////////////////////////////////////
9596/// Increment bin content by 1.
9597/// Passing an out-of-range bin leads to undefined behavior
9598
9599void TH1C::AddBinContent(Int_t bin)
9600{
9601 if (fArray[bin] < 127) fArray[bin]++;
9602}
9603
9604////////////////////////////////////////////////////////////////////////////////
9605/// Increment bin content by w.
9606/// \warning The value of w is cast to `Int_t` before being added.
9607/// Passing an out-of-range bin leads to undefined behavior
9608
9610{
9611 Int_t newval = fArray[bin] + Int_t(w);
9612 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
9613 if (newval < -127) fArray[bin] = -127;
9614 if (newval > 127) fArray[bin] = 127;
9615}
9616
9617////////////////////////////////////////////////////////////////////////////////
9618/// Copy this to newth1
9619
9620void TH1C::Copy(TObject &newth1) const
9621{
9623}
9624
9625////////////////////////////////////////////////////////////////////////////////
9626/// Reset.
9627
9629{
9632}
9633
9634////////////////////////////////////////////////////////////////////////////////
9635/// Set total number of bins including under/overflow
9636/// Reallocate bin contents array
9637
9639{
9640 if (n < 0) n = fXaxis.GetNbins() + 2;
9641 fNcells = n;
9642 TArrayC::Set(n);
9643}
9644
9645////////////////////////////////////////////////////////////////////////////////
9646/// Operator =
9647
9648TH1C& TH1C::operator=(const TH1C &h1)
9649{
9650 if (this != &h1)
9651 h1.TH1C::Copy(*this);
9652 return *this;
9653}
9654
9655////////////////////////////////////////////////////////////////////////////////
9656/// Operator *
9657
9659{
9660 TH1C hnew = h1;
9661 hnew.Scale(c1);
9662 hnew.SetDirectory(nullptr);
9663 return hnew;
9664}
9665
9666////////////////////////////////////////////////////////////////////////////////
9667/// Operator +
9668
9669TH1C operator+(const TH1C &h1, const TH1C &h2)
9670{
9671 TH1C hnew = h1;
9672 hnew.Add(&h2,1);
9673 hnew.SetDirectory(nullptr);
9674 return hnew;
9675}
9676
9677////////////////////////////////////////////////////////////////////////////////
9678/// Operator -
9679
9680TH1C operator-(const TH1C &h1, const TH1C &h2)
9681{
9682 TH1C hnew = h1;
9683 hnew.Add(&h2,-1);
9684 hnew.SetDirectory(nullptr);
9685 return hnew;
9686}
9687
9688////////////////////////////////////////////////////////////////////////////////
9689/// Operator *
9690
9691TH1C operator*(const TH1C &h1, const TH1C &h2)
9692{
9693 TH1C hnew = h1;
9694 hnew.Multiply(&h2);
9695 hnew.SetDirectory(nullptr);
9696 return hnew;
9697}
9698
9699////////////////////////////////////////////////////////////////////////////////
9700/// Operator /
9701
9702TH1C operator/(const TH1C &h1, const TH1C &h2)
9703{
9704 TH1C hnew = h1;
9705 hnew.Divide(&h2);
9706 hnew.SetDirectory(nullptr);
9707 return hnew;
9708}
9709
9710//______________________________________________________________________________
9711// TH1S methods
9712// TH1S : histograms with one short per channel. Maximum bin content = 32767
9713//______________________________________________________________________________
9714
9715
9716////////////////////////////////////////////////////////////////////////////////
9717/// Constructor.
9718
9719TH1S::TH1S()
9720{
9721 fDimension = 1;
9722 SetBinsLength(3);
9723 if (fgDefaultSumw2) Sumw2();
9724}
9725
9726////////////////////////////////////////////////////////////////////////////////
9727/// Create a 1-Dim histogram with fix bins of type short
9728/// (see TH1::TH1 for explanation of parameters)
9729
9730TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9731: TH1(name,title,nbins,xlow,xup)
9732{
9733 fDimension = 1;
9735
9736 if (xlow >= xup) SetBuffer(fgBufferSize);
9737 if (fgDefaultSumw2) Sumw2();
9738}
9739
9740////////////////////////////////////////////////////////////////////////////////
9741/// Create a 1-Dim histogram with variable bins of type short
9742/// (see TH1::TH1 for explanation of parameters)
9743
9744TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9745: TH1(name,title,nbins,xbins)
9746{
9747 fDimension = 1;
9749 if (fgDefaultSumw2) Sumw2();
9750}
9751
9752////////////////////////////////////////////////////////////////////////////////
9753/// Create a 1-Dim histogram with variable bins of type short
9754/// (see TH1::TH1 for explanation of parameters)
9755
9756TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9757: TH1(name,title,nbins,xbins)
9758{
9759 fDimension = 1;
9761 if (fgDefaultSumw2) Sumw2();
9762}
9763
9764////////////////////////////////////////////////////////////////////////////////
9765/// Destructor.
9766
9768{
9769}
9770
9771////////////////////////////////////////////////////////////////////////////////
9772/// Copy constructor.
9773/// The list of functions is not copied. (Use Clone() if needed)
9774
9775TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9776{
9777 h1s.TH1S::Copy(*this);
9778}
9779
9780////////////////////////////////////////////////////////////////////////////////
9781/// Increment bin content by 1.
9782/// Passing an out-of-range bin leads to undefined behavior
9783
9784void TH1S::AddBinContent(Int_t bin)
9785{
9786 if (fArray[bin] < 32767) fArray[bin]++;
9787}
9788
9789////////////////////////////////////////////////////////////////////////////////
9790/// Increment bin content by w.
9791/// \warning The value of w is cast to `Int_t` before being added.
9792/// Passing an out-of-range bin leads to undefined behavior
9793
9795{
9796 Int_t newval = fArray[bin] + Int_t(w);
9797 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9798 if (newval < -32767) fArray[bin] = -32767;
9799 if (newval > 32767) fArray[bin] = 32767;
9800}
9801
9802////////////////////////////////////////////////////////////////////////////////
9803/// Copy this to newth1
9804
9805void TH1S::Copy(TObject &newth1) const
9806{
9808}
9809
9810////////////////////////////////////////////////////////////////////////////////
9811/// Reset.
9812
9814{
9817}
9818
9819////////////////////////////////////////////////////////////////////////////////
9820/// Set total number of bins including under/overflow
9821/// Reallocate bin contents array
9822
9824{
9825 if (n < 0) n = fXaxis.GetNbins() + 2;
9826 fNcells = n;
9827 TArrayS::Set(n);
9828}
9829
9830////////////////////////////////////////////////////////////////////////////////
9831/// Operator =
9832
9833TH1S& TH1S::operator=(const TH1S &h1)
9834{
9835 if (this != &h1)
9836 h1.TH1S::Copy(*this);
9837 return *this;
9838}
9839
9840////////////////////////////////////////////////////////////////////////////////
9841/// Operator *
9842
9844{
9845 TH1S hnew = h1;
9846 hnew.Scale(c1);
9847 hnew.SetDirectory(nullptr);
9848 return hnew;
9849}
9850
9851////////////////////////////////////////////////////////////////////////////////
9852/// Operator +
9853
9854TH1S operator+(const TH1S &h1, const TH1S &h2)
9855{
9856 TH1S hnew = h1;
9857 hnew.Add(&h2,1);
9858 hnew.SetDirectory(nullptr);
9859 return hnew;
9860}
9861
9862////////////////////////////////////////////////////////////////////////////////
9863/// Operator -
9864
9865TH1S operator-(const TH1S &h1, const TH1S &h2)
9866{
9867 TH1S hnew = h1;
9868 hnew.Add(&h2,-1);
9869 hnew.SetDirectory(nullptr);
9870 return hnew;
9871}
9872
9873////////////////////////////////////////////////////////////////////////////////
9874/// Operator *
9875
9876TH1S operator*(const TH1S &h1, const TH1S &h2)
9877{
9878 TH1S hnew = h1;
9879 hnew.Multiply(&h2);
9880 hnew.SetDirectory(nullptr);
9881 return hnew;
9882}
9883
9884////////////////////////////////////////////////////////////////////////////////
9885/// Operator /
9886
9887TH1S operator/(const TH1S &h1, const TH1S &h2)
9888{
9889 TH1S hnew = h1;
9890 hnew.Divide(&h2);
9891 hnew.SetDirectory(nullptr);
9892 return hnew;
9893}
9894
9895//______________________________________________________________________________
9896// TH1I methods
9897// TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9898// 2147483647 = INT_MAX
9899//______________________________________________________________________________
9900
9901
9902////////////////////////////////////////////////////////////////////////////////
9903/// Constructor.
9904
9905TH1I::TH1I()
9906{
9907 fDimension = 1;
9908 SetBinsLength(3);
9909 if (fgDefaultSumw2) Sumw2();
9910}
9911
9912////////////////////////////////////////////////////////////////////////////////
9913/// Create a 1-Dim histogram with fix bins of type integer
9914/// (see TH1::TH1 for explanation of parameters)
9915
9916TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9917: TH1(name,title,nbins,xlow,xup)
9918{
9919 fDimension = 1;
9921
9922 if (xlow >= xup) SetBuffer(fgBufferSize);
9923 if (fgDefaultSumw2) Sumw2();
9924}
9925
9926////////////////////////////////////////////////////////////////////////////////
9927/// Create a 1-Dim histogram with variable bins of type integer
9928/// (see TH1::TH1 for explanation of parameters)
9929
9930TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9931: TH1(name,title,nbins,xbins)
9932{
9933 fDimension = 1;
9935 if (fgDefaultSumw2) Sumw2();
9936}
9937
9938////////////////////////////////////////////////////////////////////////////////
9939/// Create a 1-Dim histogram with variable bins of type integer
9940/// (see TH1::TH1 for explanation of parameters)
9941
9942TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9943: TH1(name,title,nbins,xbins)
9944{
9945 fDimension = 1;
9947 if (fgDefaultSumw2) Sumw2();
9948}
9949
9950////////////////////////////////////////////////////////////////////////////////
9951/// Destructor.
9952
9954{
9955}
9956
9957////////////////////////////////////////////////////////////////////////////////
9958/// Copy constructor.
9959/// The list of functions is not copied. (Use Clone() if needed)
9960
9961TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
9962{
9963 h1i.TH1I::Copy(*this);
9964}
9965
9966////////////////////////////////////////////////////////////////////////////////
9967/// Increment bin content by 1.
9968/// Passing an out-of-range bin leads to undefined behavior
9969
9970void TH1I::AddBinContent(Int_t bin)
9971{
9972 if (fArray[bin] < INT_MAX) fArray[bin]++;
9973}
9974
9975////////////////////////////////////////////////////////////////////////////////
9976/// Increment bin content by w
9977/// \warning The value of w is cast to `Long64_t` before being added.
9978/// Passing an out-of-range bin leads to undefined behavior
9979
9981{
9982 Long64_t newval = fArray[bin] + Long64_t(w);
9983 if (newval > -INT_MAX && newval < INT_MAX) {fArray[bin] = Int_t(newval); return;}
9984 if (newval < -INT_MAX) fArray[bin] = -INT_MAX;
9985 if (newval > INT_MAX) fArray[bin] = INT_MAX;
9986}
9987
9988////////////////////////////////////////////////////////////////////////////////
9989/// Copy this to newth1
9990
9991void TH1I::Copy(TObject &newth1) const
9992{
9994}
9995
9996////////////////////////////////////////////////////////////////////////////////
9997/// Reset.
9998
10000{
10003}
10004
10005////////////////////////////////////////////////////////////////////////////////
10006/// Set total number of bins including under/overflow
10007/// Reallocate bin contents array
10008
10010{
10011 if (n < 0) n = fXaxis.GetNbins() + 2;
10012 fNcells = n;
10013 TArrayI::Set(n);
10014}
10015
10016////////////////////////////////////////////////////////////////////////////////
10017/// Operator =
10018
10019TH1I& TH1I::operator=(const TH1I &h1)
10020{
10021 if (this != &h1)
10022 h1.TH1I::Copy(*this);
10023 return *this;
10024}
10025
10026
10027////////////////////////////////////////////////////////////////////////////////
10028/// Operator *
10029
10031{
10032 TH1I hnew = h1;
10033 hnew.Scale(c1);
10034 hnew.SetDirectory(nullptr);
10035 return hnew;
10036}
10037
10038////////////////////////////////////////////////////////////////////////////////
10039/// Operator +
10040
10041TH1I operator+(const TH1I &h1, const TH1I &h2)
10042{
10043 TH1I hnew = h1;
10044 hnew.Add(&h2,1);
10045 hnew.SetDirectory(nullptr);
10046 return hnew;
10047}
10048
10049////////////////////////////////////////////////////////////////////////////////
10050/// Operator -
10051
10052TH1I operator-(const TH1I &h1, const TH1I &h2)
10053{
10054 TH1I hnew = h1;
10055 hnew.Add(&h2,-1);
10056 hnew.SetDirectory(nullptr);
10057 return hnew;
10058}
10059
10060////////////////////////////////////////////////////////////////////////////////
10061/// Operator *
10062
10063TH1I operator*(const TH1I &h1, const TH1I &h2)
10064{
10065 TH1I hnew = h1;
10066 hnew.Multiply(&h2);
10067 hnew.SetDirectory(nullptr);
10068 return hnew;
10069}
10070
10071////////////////////////////////////////////////////////////////////////////////
10072/// Operator /
10073
10074TH1I operator/(const TH1I &h1, const TH1I &h2)
10075{
10076 TH1I hnew = h1;
10077 hnew.Divide(&h2);
10078 hnew.SetDirectory(nullptr);
10079 return hnew;
10080}
10081
10082//______________________________________________________________________________
10083// TH1L methods
10084// TH1L : histograms with one long64 per channel. Maximum bin content = 9223372036854775807
10085// 9223372036854775807 = LLONG_MAX
10086//______________________________________________________________________________
10087
10088
10089////////////////////////////////////////////////////////////////////////////////
10090/// Constructor.
10091
10092TH1L::TH1L()
10093{
10094 fDimension = 1;
10095 SetBinsLength(3);
10096 if (fgDefaultSumw2) Sumw2();
10097}
10098
10099////////////////////////////////////////////////////////////////////////////////
10100/// Create a 1-Dim histogram with fix bins of type long64
10101/// (see TH1::TH1 for explanation of parameters)
10102
10103TH1L::TH1L(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10104: TH1(name,title,nbins,xlow,xup)
10105{
10106 fDimension = 1;
10108
10109 if (xlow >= xup) SetBuffer(fgBufferSize);
10110 if (fgDefaultSumw2) Sumw2();
10111}
10112
10113////////////////////////////////////////////////////////////////////////////////
10114/// Create a 1-Dim histogram with variable bins of type long64
10115/// (see TH1::TH1 for explanation of parameters)
10116
10117TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10118: TH1(name,title,nbins,xbins)
10119{
10120 fDimension = 1;
10122 if (fgDefaultSumw2) Sumw2();
10123}
10124
10125////////////////////////////////////////////////////////////////////////////////
10126/// Create a 1-Dim histogram with variable bins of type long64
10127/// (see TH1::TH1 for explanation of parameters)
10128
10129TH1L::TH1L(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10130: TH1(name,title,nbins,xbins)
10131{
10132 fDimension = 1;
10134 if (fgDefaultSumw2) Sumw2();
10135}
10136
10137////////////////////////////////////////////////////////////////////////////////
10138/// Destructor.
10139
10141{
10142}
10143
10144////////////////////////////////////////////////////////////////////////////////
10145/// Copy constructor.
10146/// The list of functions is not copied. (Use Clone() if needed)
10147
10148TH1L::TH1L(const TH1L &h1l) : TH1(), TArrayL64()
10149{
10150 h1l.TH1L::Copy(*this);
10151}
10152
10153////////////////////////////////////////////////////////////////////////////////
10154/// Increment bin content by 1.
10155/// Passing an out-of-range bin leads to undefined behavior
10156
10157void TH1L::AddBinContent(Int_t bin)
10158{
10159 if (fArray[bin] < LLONG_MAX) fArray[bin]++;
10160}
10161
10162////////////////////////////////////////////////////////////////////////////////
10163/// Increment bin content by w.
10164/// \warning The value of w is cast to `Long64_t` before being added.
10165/// Passing an out-of-range bin leads to undefined behavior
10166
10168{
10169 Long64_t newval = fArray[bin] + Long64_t(w);
10170 if (newval > -LLONG_MAX && newval < LLONG_MAX) {fArray[bin] = newval; return;}
10171 if (newval < -LLONG_MAX) fArray[bin] = -LLONG_MAX;
10172 if (newval > LLONG_MAX) fArray[bin] = LLONG_MAX;
10173}
10174
10175////////////////////////////////////////////////////////////////////////////////
10176/// Copy this to newth1
10177
10178void TH1L::Copy(TObject &newth1) const
10179{
10181}
10182
10183////////////////////////////////////////////////////////////////////////////////
10184/// Reset.
10185
10187{
10190}
10191
10192////////////////////////////////////////////////////////////////////////////////
10193/// Set total number of bins including under/overflow
10194/// Reallocate bin contents array
10195
10197{
10198 if (n < 0) n = fXaxis.GetNbins() + 2;
10199 fNcells = n;
10201}
10202
10203////////////////////////////////////////////////////////////////////////////////
10204/// Operator =
10205
10206TH1L& TH1L::operator=(const TH1L &h1)
10207{
10208 if (this != &h1)
10209 h1.TH1L::Copy(*this);
10210 return *this;
10211}
10212
10213
10214////////////////////////////////////////////////////////////////////////////////
10215/// Operator *
10216
10218{
10219 TH1L hnew = h1;
10220 hnew.Scale(c1);
10221 hnew.SetDirectory(nullptr);
10222 return hnew;
10223}
10224
10225////////////////////////////////////////////////////////////////////////////////
10226/// Operator +
10227
10228TH1L operator+(const TH1L &h1, const TH1L &h2)
10229{
10230 TH1L hnew = h1;
10231 hnew.Add(&h2,1);
10232 hnew.SetDirectory(nullptr);
10233 return hnew;
10234}
10235
10236////////////////////////////////////////////////////////////////////////////////
10237/// Operator -
10238
10239TH1L operator-(const TH1L &h1, const TH1L &h2)
10240{
10241 TH1L hnew = h1;
10242 hnew.Add(&h2,-1);
10243 hnew.SetDirectory(nullptr);
10244 return hnew;
10245}
10246
10247////////////////////////////////////////////////////////////////////////////////
10248/// Operator *
10249
10250TH1L operator*(const TH1L &h1, const TH1L &h2)
10251{
10252 TH1L hnew = h1;
10253 hnew.Multiply(&h2);
10254 hnew.SetDirectory(nullptr);
10255 return hnew;
10256}
10257
10258////////////////////////////////////////////////////////////////////////////////
10259/// Operator /
10260
10261TH1L operator/(const TH1L &h1, const TH1L &h2)
10262{
10263 TH1L hnew = h1;
10264 hnew.Divide(&h2);
10265 hnew.SetDirectory(nullptr);
10266 return hnew;
10267}
10268
10269//______________________________________________________________________________
10270// TH1F methods
10271// TH1F : histograms with one float per channel. Maximum precision 7 digits, maximum integer bin content = +/-16777216
10272//______________________________________________________________________________
10273
10274
10275////////////////////////////////////////////////////////////////////////////////
10276/// Constructor.
10277
10278TH1F::TH1F()
10279{
10280 fDimension = 1;
10281 SetBinsLength(3);
10282 if (fgDefaultSumw2) Sumw2();
10283}
10284
10285////////////////////////////////////////////////////////////////////////////////
10286/// Create a 1-Dim histogram with fix bins of type float
10287/// (see TH1::TH1 for explanation of parameters)
10288
10289TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10290: TH1(name,title,nbins,xlow,xup)
10291{
10292 fDimension = 1;
10294
10295 if (xlow >= xup) SetBuffer(fgBufferSize);
10296 if (fgDefaultSumw2) Sumw2();
10297}
10298
10299////////////////////////////////////////////////////////////////////////////////
10300/// Create a 1-Dim histogram with variable bins of type float
10301/// (see TH1::TH1 for explanation of parameters)
10302
10303TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10304: TH1(name,title,nbins,xbins)
10305{
10306 fDimension = 1;
10308 if (fgDefaultSumw2) Sumw2();
10309}
10310
10311////////////////////////////////////////////////////////////////////////////////
10312/// Create a 1-Dim histogram with variable bins of type float
10313/// (see TH1::TH1 for explanation of parameters)
10314
10315TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10316: TH1(name,title,nbins,xbins)
10317{
10318 fDimension = 1;
10320 if (fgDefaultSumw2) Sumw2();
10321}
10322
10323////////////////////////////////////////////////////////////////////////////////
10324/// Create a histogram from a TVectorF
10325/// by default the histogram name is "TVectorF" and title = ""
10326
10327TH1F::TH1F(const TVectorF &v)
10328: TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
10329{
10331 fDimension = 1;
10332 Int_t ivlow = v.GetLwb();
10333 for (Int_t i=0;i<fNcells-2;i++) {
10334 SetBinContent(i+1,v(i+ivlow));
10335 }
10337 if (fgDefaultSumw2) Sumw2();
10338}
10339
10340////////////////////////////////////////////////////////////////////////////////
10341/// Copy Constructor.
10342/// The list of functions is not copied. (Use Clone() if needed)
10343
10344TH1F::TH1F(const TH1F &h1f) : TH1(), TArrayF()
10345{
10346 h1f.TH1F::Copy(*this);
10347}
10348
10349////////////////////////////////////////////////////////////////////////////////
10350/// Destructor.
10351
10353{
10354}
10355
10356////////////////////////////////////////////////////////////////////////////////
10357/// Copy this to newth1.
10358
10359void TH1F::Copy(TObject &newth1) const
10360{
10362}
10363
10364////////////////////////////////////////////////////////////////////////////////
10365/// Reset.
10366
10368{
10371}
10372
10373////////////////////////////////////////////////////////////////////////////////
10374/// Set total number of bins including under/overflow
10375/// Reallocate bin contents array
10376
10378{
10379 if (n < 0) n = fXaxis.GetNbins() + 2;
10380 fNcells = n;
10381 TArrayF::Set(n);
10382}
10383
10384////////////////////////////////////////////////////////////////////////////////
10385/// Operator =
10386
10388{
10389 if (this != &h1f)
10390 h1f.TH1F::Copy(*this);
10391 return *this;
10392}
10393
10394////////////////////////////////////////////////////////////////////////////////
10395/// Operator *
10396
10398{
10399 TH1F hnew = h1;
10400 hnew.Scale(c1);
10401 hnew.SetDirectory(nullptr);
10402 return hnew;
10403}
10404
10405////////////////////////////////////////////////////////////////////////////////
10406/// Operator +
10407
10408TH1F operator+(const TH1F &h1, const TH1F &h2)
10409{
10410 TH1F hnew = h1;
10411 hnew.Add(&h2,1);
10412 hnew.SetDirectory(nullptr);
10413 return hnew;
10414}
10415
10416////////////////////////////////////////////////////////////////////////////////
10417/// Operator -
10418
10419TH1F operator-(const TH1F &h1, const TH1F &h2)
10420{
10421 TH1F hnew = h1;
10422 hnew.Add(&h2,-1);
10423 hnew.SetDirectory(nullptr);
10424 return hnew;
10425}
10426
10427////////////////////////////////////////////////////////////////////////////////
10428/// Operator *
10429
10430TH1F operator*(const TH1F &h1, const TH1F &h2)
10431{
10432 TH1F hnew = h1;
10433 hnew.Multiply(&h2);
10434 hnew.SetDirectory(nullptr);
10435 return hnew;
10436}
10437
10438////////////////////////////////////////////////////////////////////////////////
10439/// Operator /
10440
10441TH1F operator/(const TH1F &h1, const TH1F &h2)
10442{
10443 TH1F hnew = h1;
10444 hnew.Divide(&h2);
10445 hnew.SetDirectory(nullptr);
10446 return hnew;
10447}
10448
10449//______________________________________________________________________________
10450// TH1D methods
10451// TH1D : histograms with one double per channel. Maximum precision 14 digits, maximum integer bin content = +/-9007199254740992
10452//______________________________________________________________________________
10453
10454
10455////////////////////////////////////////////////////////////////////////////////
10456/// Constructor.
10457
10458TH1D::TH1D()
10459{
10460 fDimension = 1;
10461 SetBinsLength(3);
10462 if (fgDefaultSumw2) Sumw2();
10463}
10464
10465////////////////////////////////////////////////////////////////////////////////
10466/// Create a 1-Dim histogram with fix bins of type double
10467/// (see TH1::TH1 for explanation of parameters)
10468
10469TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10470: TH1(name,title,nbins,xlow,xup)
10471{
10472 fDimension = 1;
10474
10475 if (xlow >= xup) SetBuffer(fgBufferSize);
10476 if (fgDefaultSumw2) Sumw2();
10477}
10478
10479////////////////////////////////////////////////////////////////////////////////
10480/// Create a 1-Dim histogram with variable bins of type double
10481/// (see TH1::TH1 for explanation of parameters)
10482
10483TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10484: TH1(name,title,nbins,xbins)
10485{
10486 fDimension = 1;
10488 if (fgDefaultSumw2) Sumw2();
10489}
10490
10491////////////////////////////////////////////////////////////////////////////////
10492/// Create a 1-Dim histogram with variable bins of type double
10493/// (see TH1::TH1 for explanation of parameters)
10494
10495TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10496: TH1(name,title,nbins,xbins)
10497{
10498 fDimension = 1;
10500 if (fgDefaultSumw2) Sumw2();
10501}
10502
10503////////////////////////////////////////////////////////////////////////////////
10504/// Create a histogram from a TVectorD
10505/// by default the histogram name is "TVectorD" and title = ""
10506
10507TH1D::TH1D(const TVectorD &v)
10508: TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
10509{
10511 fDimension = 1;
10512 Int_t ivlow = v.GetLwb();
10513 for (Int_t i=0;i<fNcells-2;i++) {
10514 SetBinContent(i+1,v(i+ivlow));
10515 }
10517 if (fgDefaultSumw2) Sumw2();
10518}
10519
10520////////////////////////////////////////////////////////////////////////////////
10521/// Destructor.
10522
10524{
10525}
10526
10527////////////////////////////////////////////////////////////////////////////////
10528/// Constructor.
10529
10530TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
10531{
10532 // intentially call virtual method to warn if TProfile is copying
10533 h1d.Copy(*this);
10534}
10535
10536////////////////////////////////////////////////////////////////////////////////
10537/// Copy this to newth1
10538
10539void TH1D::Copy(TObject &newth1) const
10540{
10542}
10543
10544////////////////////////////////////////////////////////////////////////////////
10545/// Reset.
10546
10548{
10551}
10552
10553////////////////////////////////////////////////////////////////////////////////
10554/// Set total number of bins including under/overflow
10555/// Reallocate bin contents array
10556
10558{
10559 if (n < 0) n = fXaxis.GetNbins() + 2;
10560 fNcells = n;
10561 TArrayD::Set(n);
10562}
10563
10564////////////////////////////////////////////////////////////////////////////////
10565/// Operator =
10566
10568{
10569 // intentially call virtual method to warn if TProfile is copying
10570 if (this != &h1d)
10571 h1d.Copy(*this);
10572 return *this;
10573}
10574
10575////////////////////////////////////////////////////////////////////////////////
10576/// Operator *
10577
10579{
10580 TH1D hnew = h1;
10581 hnew.Scale(c1);
10582 hnew.SetDirectory(nullptr);
10583 return hnew;
10584}
10585
10586////////////////////////////////////////////////////////////////////////////////
10587/// Operator +
10588
10589TH1D operator+(const TH1D &h1, const TH1D &h2)
10590{
10591 TH1D hnew = h1;
10592 hnew.Add(&h2,1);
10593 hnew.SetDirectory(nullptr);
10594 return hnew;
10595}
10596
10597////////////////////////////////////////////////////////////////////////////////
10598/// Operator -
10599
10600TH1D operator-(const TH1D &h1, const TH1D &h2)
10601{
10602 TH1D hnew = h1;
10603 hnew.Add(&h2,-1);
10604 hnew.SetDirectory(nullptr);
10605 return hnew;
10606}
10607
10608////////////////////////////////////////////////////////////////////////////////
10609/// Operator *
10610
10611TH1D operator*(const TH1D &h1, const TH1D &h2)
10612{
10613 TH1D hnew = h1;
10614 hnew.Multiply(&h2);
10615 hnew.SetDirectory(nullptr);
10616 return hnew;
10617}
10618
10619////////////////////////////////////////////////////////////////////////////////
10620/// Operator /
10621
10622TH1D operator/(const TH1D &h1, const TH1D &h2)
10623{
10624 TH1D hnew = h1;
10625 hnew.Divide(&h2);
10626 hnew.SetDirectory(nullptr);
10627 return hnew;
10628}
10629
10630////////////////////////////////////////////////////////////////////////////////
10631///return pointer to histogram with name
10632///hid if id >=0
10633///h_id if id <0
10634
10635TH1 *R__H(Int_t hid)
10636{
10637 TString hname;
10638 if(hid >= 0) hname.Form("h%d",hid);
10639 else hname.Form("h_%d",hid);
10640 return (TH1*)gDirectory->Get(hname);
10641}
10642
10643////////////////////////////////////////////////////////////////////////////////
10644///return pointer to histogram with name hname
10645
10646TH1 *R__H(const char * hname)
10647{
10648 return (TH1*)gDirectory->Get(hname);
10649}
10650
10651
10652/// \fn void TH1::SetBarOffset(Float_t offset)
10653/// Set the bar offset as fraction of the bin width for drawing mode "B".
10654/// This shifts bars to the right on the x axis, and helps to draw bars next to each other.
10655/// \see THistPainter, SetBarWidth()
10656
10657/// \fn void TH1::SetBarWidth(Float_t width)
10658/// Set the width of bars as fraction of the bin width for drawing mode "B".
10659/// This allows for making bars narrower than the bin width. With SetBarOffset(), this helps to draw multiple bars next to each other.
10660/// \see THistPainter, SetBarOffset()
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define s1(x)
Definition RSha256.hxx:91
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
short Style_t
Style number (short)
Definition RtypesCore.h:96
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:77
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Color_t
Color number (short)
Definition RtypesCore.h:99
short Version_t
Class version identifier (short)
Definition RtypesCore.h:79
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
short Short_t
Signed Short integer 2 bytes (short)
Definition RtypesCore.h:53
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:385
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t SetLineWidth
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t SetFillStyle
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t del
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t SetLineColor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t SetFillColor
Option_t Option_t SetMarkerStyle
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Option_t Option_t TPoint TPoint const char y1
char name[80]
Definition TGX11.cxx:110
static bool IsEquidistantBinning(const TAxis &axis)
Test if the binning is equidistant.
Definition TH1.cxx:5920
void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
Least square linear fit without weights.
Definition TH1.cxx:4866
void H1InitGaus()
Compute Initial values of parameters for a gaussian.
Definition TH1.cxx:4701
void H1InitExpo()
Compute Initial values of parameters for an exponential.
Definition TH1.cxx:4757
TH1C operator+(const TH1C &h1, const TH1C &h2)
Operator +.
Definition TH1.cxx:9667
TH1C operator-(const TH1C &h1, const TH1C &h2)
Operator -.
Definition TH1.cxx:9678
TH1C operator/(const TH1C &h1, const TH1C &h2)
Operator /.
Definition TH1.cxx:9700
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:4912
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:5903
static Bool_t AlmostInteger(Double_t a, Double_t epsilon=0.00000001)
Test if a double is almost an integer.
Definition TH1.cxx:5911
TF1 * gF1
Definition TH1.cxx:590
TH1 * R__H(Int_t hid)
return pointer to histogram with name hid if id >=0 h_id if id <0
Definition TH1.cxx:10633
TH1C operator*(Double_t c1, const TH1C &h1)
Operator *.
Definition TH1.cxx:9656
void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
Least squares lpolynomial fitting without weights.
Definition TH1.cxx:4807
void H1InitPolynom()
Compute Initial values of parameters for a polynom.
Definition TH1.cxx:4777
float xmin
int nentries
float ymin
float xmax
float ymax
#define gInterpreter
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:627
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:414
R__EXTERN TRandom * gRandom
Definition TRandom.h:62
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2509
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
#define R__LOCKGUARD(mutex)
#define gPad
#define R__WRITE_LOCKGUARD(mutex)
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition BinData.h:52
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition DataRange.h:35
void AndersonDarling2SamplesTest(Double_t &pvalue, Double_t &testStat) const
Performs the Anderson-Darling 2-Sample Test.
Definition GoFTest.cxx:646
const_iterator begin() const
const_iterator end() const
Array of chars or bytes (8 bits per element).
Definition TArrayC.h:27
Char_t * fArray
Definition TArrayC.h:30
void Reset(Char_t val=0)
Definition TArrayC.h:47
void Set(Int_t n) override
Set size of this array to n chars.
Definition TArrayC.cxx:104
Array of doubles (64 bits per element).
Definition TArrayD.h:27
Double_t * fArray
Definition TArrayD.h:30
void Streamer(TBuffer &) override
Stream a TArrayD object.
Definition TArrayD.cxx:148
void Copy(TArrayD &array) const
Definition TArrayD.h:42
void Set(Int_t n) override
Set size of this array to n doubles.
Definition TArrayD.cxx:105
const Double_t * GetArray() const
Definition TArrayD.h:43
void Reset()
Definition TArrayD.h:47
Array of floats (32 bits per element).
Definition TArrayF.h:27
void Reset()
Definition TArrayF.h:47
void Set(Int_t n) override
Set size of this array to n floats.
Definition TArrayF.cxx:104
Array of integers (32 bits per element).
Definition TArrayI.h:27
Int_t * fArray
Definition TArrayI.h:30
void Set(Int_t n) override
Set size of this array to n ints.
Definition TArrayI.cxx:104
void Reset()
Definition TArrayI.h:47
Array of long64s (64 bits per element).
Definition TArrayL64.h:27
Long64_t * fArray
Definition TArrayL64.h:30
void Set(Int_t n) override
Set size of this array to n long64s.
void Reset()
Definition TArrayL64.h:47
Array of shorts (16 bits per element).
Definition TArrayS.h:27
void Set(Int_t n) override
Set size of this array to n shorts.
Definition TArrayS.cxx:104
void Reset()
Definition TArrayS.h:47
Short_t * fArray
Definition TArrayS.h:30
Abstract array base class.
Definition TArray.h:31
Int_t fN
Definition TArray.h:38
virtual void Set(Int_t n)=0
virtual Color_t GetTitleColor() const
Definition TAttAxis.h:47
virtual Color_t GetLabelColor() const
Definition TAttAxis.h:39
virtual Int_t GetNdivisions() const
Definition TAttAxis.h:37
virtual Color_t GetAxisColor() const
Definition TAttAxis.h:38
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition TAttAxis.cxx:279
virtual Style_t GetTitleFont() const
Definition TAttAxis.h:48
virtual Float_t GetLabelOffset() const
Definition TAttAxis.h:41
virtual void SetAxisColor(Color_t color=1, Float_t alpha=1.)
Set color of the line axis and tick marks.
Definition TAttAxis.cxx:141
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
Definition TAttAxis.cxx:184
virtual Style_t GetLabelFont() const
Definition TAttAxis.h:40
virtual void SetTitleFont(Style_t font=62)
Set the title font.
Definition TAttAxis.cxx:308
virtual void SetLabelOffset(Float_t offset=0.005)
Set distance between the axis and the labels.
Definition TAttAxis.cxx:172
virtual void SetLabelFont(Style_t font=62)
Set labels' font.
Definition TAttAxis.cxx:161
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title.
Definition TAttAxis.cxx:290
virtual void SetTitleColor(Color_t color=1)
Set color of axis title.
Definition TAttAxis.cxx:299
virtual Float_t GetTitleSize() const
Definition TAttAxis.h:45
virtual Float_t GetLabelSize() const
Definition TAttAxis.h:42
virtual Float_t GetTickLength() const
Definition TAttAxis.h:46
virtual void ResetAttAxis(Option_t *option="")
Reset axis attributes.
Definition TAttAxis.cxx:78
virtual Float_t GetTitleOffset() const
Definition TAttAxis.h:44
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length.
Definition TAttAxis.cxx:265
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition TAttAxis.cxx:214
virtual void SetLabelColor(Color_t color=1, Float_t alpha=1.)
Set color of labels.
Definition TAttAxis.cxx:151
virtual void Streamer(TBuffer &)
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:31
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition TAttFill.cxx:206
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:32
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
Save fill attributes as C++ statement(s) on output stream out.
Definition TAttFill.cxx:238
virtual void Streamer(TBuffer &)
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:35
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:44
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:37
virtual Style_t GetLineStyle() const
Return the line style.
Definition TAttLine.h:36
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition TAttLine.cxx:176
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition TAttLine.cxx:274
virtual void SaveMarkerAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t sizdef=1)
Save line attributes as C++ statement(s) on output stream out.
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition TAttMarker.h:33
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition TAttMarker.h:39
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:32
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition TAttMarker.h:34
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition TAttMarker.h:41
void Copy(TAttMarker &attmarker) const
Copy this marker attributes to a new TAttMarker.
virtual void Streamer(TBuffer &)
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition TAttMarker.h:46
Class to manage histogram axis.
Definition TAxis.h:32
virtual void GetCenter(Double_t *center) const
Return an array with the center of all bins.
Definition TAxis.cxx:558
virtual Bool_t GetTimeDisplay() const
Definition TAxis.h:133
Bool_t IsAlphanumeric() const
Definition TAxis.h:90
const char * GetTitle() const override
Returns title of object.
Definition TAxis.h:137
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:482
Bool_t CanExtend() const
Definition TAxis.h:88
virtual void SetParent(TObject *obj)
Definition TAxis.h:169
const TArrayD * GetXbins() const
Definition TAxis.h:138
void SetCanExtend(Bool_t canExtend)
Definition TAxis.h:92
void Copy(TObject &axis) const override
Copy axis structure to another axis.
Definition TAxis.cxx:211
Double_t GetXmax() const
Definition TAxis.h:142
@ kLabelsUp
Definition TAxis.h:75
@ kLabelsDown
Definition TAxis.h:74
@ kLabelsHori
Definition TAxis.h:72
@ kAxisRange
Definition TAxis.h:66
@ kLabelsVert
Definition TAxis.h:73
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:293
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:522
virtual void SetTimeDisplay(Int_t value)
Definition TAxis.h:173
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Definition TAxis.cxx:790
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x
Definition TAxis.cxx:422
void SaveAttributes(std::ostream &out, const char *name, const char *subname) override
Save axis attributes as C++ statement(s) on output stream out.
Definition TAxis.cxx:715
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:473
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition TAxis.h:166
Double_t GetXmin() const
Definition TAxis.h:141
void Streamer(TBuffer &) override
Stream an object of class TAxis.
Definition TAxis.cxx:1224
Int_t GetNbins() const
Definition TAxis.h:127
virtual void GetLowEdge(Double_t *edge) const
Return an array with the low edge of all bins.
Definition TAxis.cxx:567
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis using bin numbers.
Definition TAxis.cxx:1061
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:546
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:532
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:462
THashList * GetLabels() const
Definition TAxis.h:123
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
Buffer base class used for serializing objects.
Definition TBuffer.h:43
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:5017
ROOT::NewFunc_t GetNew() const
Return the wrapper around new ThisClass().
Definition TClass.cxx:7549
Collection abstract base class.
Definition TCollection.h:65
virtual bool UseRWLock(Bool_t enable=true)
Set this collection to use a RW lock upon access, making it thread safe.
TObject * Clone(const char *newname="") const override
Make a clone of an collection using the Streamer facility.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Describe directory structure in memory.
Definition TDirectory.h:45
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:503
1-Dim function class
Definition TF1.h:182
static void RejectPoint(Bool_t reject=kTRUE)
Static function to set the global flag to reject points the fgRejectPoint global flag is tested by al...
Definition TF1.cxx:3723
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function Note that this histogram is managed ...
Definition TF1.cxx:1634
static TClass * Class()
virtual Int_t GetNpar() const
Definition TF1.h:446
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
IntegralOneDim or analytical integral.
Definition TF1.cxx:2580
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition TF1.cxx:2530
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2329
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=nullptr)
Evaluate function with given coordinates and parameters.
Definition TF1.cxx:1498
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set lower and upper limits for parameter ipar.
Definition TF1.cxx:3562
static Bool_t RejectedPoint()
See TF1::RejectPoint above.
Definition TF1.cxx:3732
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this function.
Definition TF1.cxx:1446
virtual void SetParameter(Int_t param, Double_t value)
Definition TF1.h:608
virtual Bool_t IsInside(const Double_t *x) const
return kTRUE if the point is inside the function range
Definition TF1.h:567
A 2-Dim function with parameters.
Definition TF2.h:29
TF3 defines a 3D Function with Parameters.
Definition TF3.h:28
Provides an indirection to the TFitResult class and with a semantics identical to a TFitResult pointe...
1-D histogram with a byte per channel (see TH1 documentation)
Definition TH1.h:714
~TH1C() override
Destructor.
Definition TH1.cxx:9580
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9636
TH1C & operator=(const TH1C &h1)
Operator =.
Definition TH1.cxx:9646
TH1C()
Constructor.
Definition TH1.cxx:9532
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9618
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9597
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:9626
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:926
~TH1D() override
Destructor.
Definition TH1.cxx:10521
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10555
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10537
TH1D()
Constructor.
Definition TH1.cxx:10456
TH1D & operator=(const TH1D &h1)
Operator =.
Definition TH1.cxx:10565
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:878
Double_t RetrieveBinContent(Int_t bin) const override
Raw retrieval of bin content on internal data structure see convention for numbering bins in TH1::Get...
Definition TH1.h:912
TH1F & operator=(const TH1F &h1)
Operator =.
Definition TH1.cxx:10385
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10357
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10375
~TH1F() override
Destructor.
Definition TH1.cxx:10350
TH1F()
Constructor.
Definition TH1.cxx:10276
1-D histogram with an int per channel (see TH1 documentation)
Definition TH1.h:796
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10007
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9968
~TH1I() override
Destructor.
Definition TH1.cxx:9951
TH1I()
Constructor.
Definition TH1.cxx:9903
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9989
TH1I & operator=(const TH1I &h1)
Operator =.
Definition TH1.cxx:10017
1-D histogram with a long64 per channel (see TH1 documentation)
Definition TH1.h:837
TH1L & operator=(const TH1L &h1)
Operator =.
Definition TH1.cxx:10204
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:10155
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10194
~TH1L() override
Destructor.
Definition TH1.cxx:10138
TH1L()
Constructor.
Definition TH1.cxx:10090
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10176
1-D histogram with a short per channel (see TH1 documentation)
Definition TH1.h:755
TH1S & operator=(const TH1S &h1)
Operator =.
Definition TH1.cxx:9831
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9803
TH1S()
Constructor.
Definition TH1.cxx:9717
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9821
~TH1S() override
Destructor.
Definition TH1.cxx:9765
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9782
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
~TH1() override
Histogram default destructor.
Definition TH1.cxx:636
virtual void SetError(const Double_t *error)
Replace bin errors by values in array error.
Definition TH1.cxx:9033
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:9019
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition TH1.cxx:4299
Double_t * fBuffer
[fBufferSize] entry buffer
Definition TH1.h:169
virtual Int_t AutoP2FindLimits(Double_t min, Double_t max)
Buffer-based estimate of the histogram range using the power of 2 algorithm.
Definition TH1.cxx:1318
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition TH1.cxx:4463
char * GetObjectInfo(Int_t px, Int_t py) const override
Redefines TObject::GetObjectInfo.
Definition TH1.cxx:4517
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition TH1.cxx:6964
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:9220
virtual void Rebuild(Option_t *option="")
Using the current bin info, recompute the arrays for contents and errors.
Definition TH1.cxx:7172
virtual void SetBarOffset(Float_t offset=0.25)
Set the bar offset as fraction of the bin width for drawing mode "B".
Definition TH1.h:612
static Bool_t fgStatOverflows
! Flag to use under/overflows in statistics
Definition TH1.h:178
virtual Int_t FindLastBinAbove(Double_t threshold=0, Int_t axis=1, Int_t firstBin=1, Int_t lastBin=-1) const
Find last bin with content > threshold for axis (1=x, 2=y, 3=z) if no bins with content > threshold i...
Definition TH1.cxx:3811
TAxis * GetZaxis()
Definition TH1.h:573
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a line.
Definition TH1.cxx:2815
virtual Bool_t Multiply(TF1 *f1, Double_t c1=1)
Performs the operation:
Definition TH1.cxx:6091
@ kXaxis
Definition TH1.h:123
@ kNoAxis
NOTE: Must always be 0 !!!
Definition TH1.h:122
@ kZaxis
Definition TH1.h:125
@ kYaxis
Definition TH1.h:124
Int_t fNcells
Number of bins(1D), cells (2D) +U/Overflows.
Definition TH1.h:150
virtual void GetStats(Double_t *stats) const
fill the array stats from the contents of this histogram The array stats must be correctly dimensione...
Definition TH1.cxx:7906
virtual void Normalize(Option_t *option="")
Normalize a histogram to its integral or to its maximum.
Definition TH1.cxx:6253
void Copy(TObject &hnew) const override
Copy this histogram structure to newth1.
Definition TH1.cxx:2663
void SetTitle(const char *title) override
Change/set the title.
Definition TH1.cxx:6796
Double_t fTsumw
Total Sum of weights.
Definition TH1.h:157
virtual Float_t GetBarWidth() const
Definition TH1.h:501
Double_t fTsumw2
Total Sum of squares of weights.
Definition TH1.h:158
static void StatOverflows(Bool_t flag=kTRUE)
if flag=kTRUE, underflows and overflows are used by the Fill functions in the computation of statisti...
Definition TH1.cxx:7010
virtual Float_t GetBarOffset() const
Definition TH1.h:500
TList * fFunctions
->Pointer to list of functions (fits and user)
Definition TH1.h:167
static Bool_t fgAddDirectory
! Flag to add histograms to the directory
Definition TH1.h:177
static TClass * Class()
static Int_t GetDefaultBufferSize()
Static function return the default buffer size for automatic histograms the parameter fgBufferSize ma...
Definition TH1.cxx:4421
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:8055
Double_t fTsumwx2
Total Sum of weight*X*X.
Definition TH1.h:160
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition TH1.cxx:7680
TH1()
Histogram default constructor.
Definition TH1.cxx:608
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:9398
void UseCurrentStyle() override
Copy current attributes from/to current style.
Definition TH1.cxx:7542
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:5424
virtual Int_t GetNbinsY() const
Definition TH1.h:542
Short_t fBarOffset
(1000*offset) for bar charts or legos
Definition TH1.h:154
virtual Double_t Chi2TestX(const TH1 *h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option="UU", Double_t *res=nullptr) const
The computation routine of the Chisquare test.
Definition TH1.cxx:2044
static bool CheckBinLimits(const TAxis *a1, const TAxis *a2)
Check bin limits.
Definition TH1.cxx:1516
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:9142
static Int_t FitOptionsMake(Option_t *option, Foption_t &Foption)
Decode string choptin and fill fitOption structure.
Definition TH1.cxx:4692
virtual Int_t GetNbinsZ() const
Definition TH1.h:543
virtual Double_t GetNormFactor() const
Definition TH1.h:545
virtual Double_t GetMean(Int_t axis=1) const
For axis = 1,2 or 3 returns the mean value of the histogram along X,Y or Z axis.
Definition TH1.cxx:7608
virtual Double_t GetSkewness(Int_t axis=1) const
Definition TH1.cxx:7744
virtual void ClearUnderflowAndOverflow()
Remove all the content from the underflow and overflow bins, without changing the number of entries A...
Definition TH1.cxx:2498
virtual void FillRandom(TF1 *f1, Int_t ntimes=5000, TRandom *rng=nullptr)
Definition TH1.cxx:3536
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition TH1.cxx:8518
virtual TH1 * DrawNormalized(Option_t *option="", Double_t norm=1) const
Draw a normalized copy of this histogram.
Definition TH1.cxx:3152
@ kNeutral
Adapt to the global flag.
Definition TH1.h:133
virtual Int_t GetDimension() const
Definition TH1.h:527
void Streamer(TBuffer &) override
Stream a class object.
Definition TH1.cxx:7018
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1269
Double_t GetSumOfAllWeights(const bool includeOverflow) const
Return the sum of all weights.
Definition TH1.cxx:7992
@ kIsAverage
Bin contents are average (used by Add)
Definition TH1.h:409
@ kUserContour
User specified contour levels.
Definition TH1.h:404
@ kNoStats
Don't draw stats box.
Definition TH1.h:403
@ kAutoBinPTwo
different than 1.
Definition TH1.h:412
@ kIsNotW
Histogram is forced to be not weighted even when the histogram is filled with weighted.
Definition TH1.h:410
@ kIsHighlight
bit set if histo is highlight
Definition TH1.h:413
virtual void SetContourLevel(Int_t level, Double_t value)
Set value for one contour level.
Definition TH1.cxx:8604
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition TH1.cxx:6711
TDirectory * fDirectory
! Pointer to directory holding this histogram
Definition TH1.h:170
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition TH1.cxx:7188
void SetNameTitle(const char *name, const char *title) override
Change the name and title of this histogram.
Definition TH1.cxx:9056
TAxis * GetXaxis()
Definition TH1.h:571
virtual void GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz) const
Return binx, biny, binz corresponding to the global bin number globalbin see TH1::GetBin function abo...
Definition TH1.cxx:5014
TH1 * GetCumulative(Bool_t forward=kTRUE, const char *suffix="_cumulative") const
Return a pointer to a histogram containing the cumulative content.
Definition TH1.cxx:2608
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:1283
virtual Int_t GetNcells() const
Definition TH1.h:544
virtual Int_t ShowPeaks(Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
Interface to TSpectrum::Search.
Definition TH1.cxx:9380
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition TH1.cxx:5950
virtual Double_t GetSumOfWeights() const
Return the sum of weights across all bins excluding under/overflows.
Definition TH1.h:559
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition TH1.cxx:7957
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition TH1.cxx:4526
TObject * FindObject(const char *name) const override
Search object named name in the list of functions.
Definition TH1.cxx:3871
void Print(Option_t *option="") const override
Print some global quantities for this histogram.
Definition TH1.cxx:7094
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
Definition TH1.cxx:4430
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:3748
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:3913
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:5001
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:8627
virtual Int_t GetNbinsX() const
Definition TH1.h:541
virtual void SetMaximum(Double_t maximum=-1111)
Definition TH1.h:652
virtual TH1 * FFT(TH1 *h_output, Option_t *option)
This function allows to do discrete Fourier transforms of TH1 and TH2.
Definition TH1.cxx:3292
virtual void LabelsInflate(Option_t *axis="X")
Double the number of bins for axis.
Definition TH1.cxx:5357
virtual TH1 * ShowBackground(Int_t niter=20, Option_t *option="same")
This function calculates the background spectrum in this histogram.
Definition TH1.cxx:9366
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
Definition TH1.cxx:5940
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:819
Double_t fMaximum
Maximum value for plotting.
Definition TH1.h:161
Int_t fBufferSize
fBuffer size
Definition TH1.h:168
TString ProvideSaveName(Option_t *option, Bool_t testfdir=kFALSE)
Provide variable name for histogram for saving as primitive Histogram pointer has by default the hist...
Definition TH1.cxx:7327
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:8046
Int_t fDimension
! Histogram dimension (1, 2 or 3 dim)
Definition TH1.h:171
virtual void SetBinError(Int_t bin, Double_t error)
Set the bin Error Note that this resets the bin eror option to be of Normal Type and for the non-empt...
Definition TH1.cxx:9285
EBinErrorOpt fBinStatErrOpt
Option for bin statistical errors.
Definition TH1.h:174
static Int_t fgBufferSize
! Default buffer size for automatic histograms
Definition TH1.h:176
virtual void SetBinsLength(Int_t=-1)
Definition TH1.h:628
Double_t fNormFactor
Normalization factor.
Definition TH1.h:163
@ kFullyConsistent
Definition TH1.h:139
@ kDifferentNumberOfBins
Definition TH1.h:143
@ kDifferentDimensions
Definition TH1.h:144
@ kDifferentBinLimits
Definition TH1.h:141
@ kDifferentAxisLimits
Definition TH1.h:142
@ kDifferentLabels
Definition TH1.h:140
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3352
TAxis * GetYaxis()
Definition TH1.h:572
TArrayD fContour
Array to display contour levels.
Definition TH1.h:164
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition TH1.cxx:9158
void Browse(TBrowser *b) override
Browse the Histogram object.
Definition TH1.cxx:755
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition TH1.cxx:8476
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx:3056
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:7454
Short_t fBarWidth
(1000*width) for bar charts or legos
Definition TH1.h:155
virtual Double_t GetBinErrorSqUnchecked(Int_t bin) const
Definition TH1.h:705
Int_t AxisChoice(Option_t *axis) const
Choose an axis according to "axis".
Definition Haxis.cxx:14
virtual void SetMinimum(Double_t minimum=-1111)
Definition TH1.h:653
Bool_t IsBinUnderflow(Int_t bin, Int_t axis=0) const
Return true if the bin is underflow.
Definition TH1.cxx:5256
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TH1.cxx:7349
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check that axis have same labels.
Definition TH1.cxx:1543
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:5157
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:6778
virtual void SetBuffer(Int_t bufsize, Option_t *option="")
Set the maximum number of entries to be kept in the buffer.
Definition TH1.cxx:8536
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition TH1.cxx:5224
UInt_t GetAxisLabelStatus() const
Internal function used in TH1::Fill to see which axis is full alphanumeric, i.e.
Definition TH1.cxx:6750
Double_t * fIntegral
! Integral of bins used by GetRandom
Definition TH1.h:172
Double_t fMinimum
Minimum value for plotting.
Definition TH1.h:162
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition TH1.cxx:8019
static void SetDefaultBufferSize(Int_t bufsize=1000)
Static function to set the default buffer size for automatic histograms.
Definition TH1.cxx:6768
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:9301
virtual void DirectoryAutoAdd(TDirectory *)
Perform the automatic addition of the histogram to the given directory.
Definition TH1.cxx:2793
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:9266
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:9231
void Build()
Creates histogram basic data structure.
Definition TH1.cxx:764
virtual Double_t GetEntries() const
Return the current number of entries.
Definition TH1.cxx:4438
virtual Double_t RetrieveBinContent(Int_t bin) const =0
Raw retrieval of bin content on internal data structure see convention for numbering bins in TH1::Get...
virtual TF1 * GetFunction(const char *name) const
Return pointer to function with name.
Definition TH1.cxx:9130
virtual TH1 * Rebin(Int_t ngroup=2, const char *newname="", const Double_t *xbins=nullptr)
Rebin this histogram.
Definition TH1.cxx:6350
virtual Int_t BufferFill(Double_t x, Double_t w)
accumulate arguments in buffer.
Definition TH1.cxx:1481
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:5128
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:6724
TList * GetListOfFunctions() const
Definition TH1.h:488
void SetName(const char *name) override
Change the name of this histogram.
Definition TH1.cxx:9042
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition TH1.cxx:3121
virtual Double_t GetRandom(TRandom *rng=nullptr, Option_t *option="") const
Return a random number distributed according the histogram bin contents.
Definition TH1.cxx:5051
Bool_t IsEmpty() const
Check if a histogram is empty (this is a protected method used mainly by TH1Merger )
Definition TH1.cxx:5206
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition TH1.cxx:7648
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6281
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:8140
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculated from bin cont...
Definition TH1.cxx:7975
virtual void SetBinErrorOption(EBinErrorOpt type)
Definition TH1.h:629
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Definition TH1.cxx:3183
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:2477
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:1985
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:3481
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition TH1.cxx:8813
@ kNstat
Size of statistics data (up to TProfile3D)
Definition TH1.h:422
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition TH1.cxx:8659
static Int_t AutoP2GetBins(Int_t n)
Auxiliary function to get the next power of 2 integer value larger then n.
Definition TH1.cxx:1296
Double_t fEntries
Number of entries.
Definition TH1.h:156
virtual Long64_t Merge(TCollection *list)
Definition TH1.h:592
virtual void SetColors(Color_t linecolor=-1, Color_t markercolor=-1, Color_t fillcolor=-1)
Shortcut to set the three histogram colors with a single call.
Definition TH1.cxx:4482
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TH1.cxx:3248
virtual Double_t * GetIntegral()
Return a pointer to the array of bins integral.
Definition TH1.cxx:2578
TAxis fZaxis
Z axis descriptor.
Definition TH1.h:153
EStatOverflows fStatOverflows
Per object flag to use under/overflows in statistics.
Definition TH1.h:175
TClass * IsA() const override
Definition TH1.h:693
virtual void FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride=1)
Fill this histogram with an array x and weights w.
Definition TH1.cxx:3455
static bool CheckEqualAxes(const TAxis *a1, const TAxis *a2)
Check that the axis are the same.
Definition TH1.cxx:1586
@ kPoisson2
Errors from Poisson interval at 95% CL (~ 2 sigma)
Definition TH1.h:117
@ kNormal
Errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition TH1.h:115
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5103
virtual Int_t GetContour(Double_t *levels=nullptr)
Return contour values into array levels if pointer levels is non zero.
Definition TH1.cxx:8489
TAxis fXaxis
X axis descriptor.
Definition TH1.h:151
virtual Bool_t IsHighlight() const
Definition TH1.h:585
virtual void ExtendAxis(Double_t x, TAxis *axis)
Histogram is resized along axis such that x is in the axis range.
Definition TH1.cxx:6579
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:9242
TArrayD fSumw2
Array of sum of squares of weights.
Definition TH1.h:165
TH1 * GetAsymmetry(TH1 *h2, Double_t c2=1, Double_t dc2=0)
Return a histogram containing the asymmetry of this histogram with h2, where the asymmetry is defined...
Definition TH1.cxx:4354
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition TH1.cxx:8508
virtual void SetContour(Int_t nlevels, const Double_t *levels=nullptr)
Set the number and values of contour levels.
Definition TH1.cxx:8565
virtual void SetHighlight(Bool_t set=kTRUE)
Set highlight (enable/disable) mode for the histogram by default highlight mode is disable.
Definition TH1.cxx:4497
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition TH1.cxx:9189
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition TH1.cxx:6679
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition TH1.cxx:8747
virtual Double_t ComputeIntegral(Bool_t onlyPositive=false, Option_t *option="")
Compute integral (normalized cumulative sum of bins) w/o under/overflows The result is stored in fInt...
Definition TH1.cxx:2523
virtual Int_t GetSumw2N() const
Definition TH1.h:562
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
Return Global bin number corresponding to x,y,z.
Definition TH1.cxx:3686
Bool_t GetStatOverflowsBehaviour() const
Definition TH1.h:391
void SaveAs(const char *filename="hist", Option_t *option="") const override
Save the histogram as .csv, .tsv or .txt.
Definition TH1.cxx:7266
virtual Int_t GetQuantiles(Int_t n, Double_t *xp, const Double_t *p=nullptr)
Compute Quantiles for this histogram.
Definition TH1.cxx:4630
virtual void AddBinContent(Int_t bin)=0
Increment bin content by 1.
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx:2744
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition TH1.cxx:7728
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:2832
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:8717
int LoggedInconsistency(const char *name, const TH1 *h1, const TH1 *h2, bool useMerge=false) const
Definition TH1.cxx:876
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:1615
static Int_t CheckConsistency(const TH1 *h1, const TH1 *h2)
Check histogram compatibility.
Definition TH1.cxx:1654
void RecursiveRemove(TObject *obj) override
Recursively remove object from the list of functions.
Definition TH1.cxx:6651
TAxis fYaxis
Y axis descriptor.
Definition TH1.h:152
virtual Double_t KolmogorovTest(const TH1 *h2, Option_t *option="") const
Statistical test of compatibility in shape between this histogram and h2, using Kolmogorov test.
Definition TH1.cxx:8256
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:6853
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:9253
TVirtualHistPainter * fPainter
! Pointer to histogram painter
Definition TH1.h:173
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition TH1.cxx:8849
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:3719
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:9102
virtual void SetEntries(Double_t n)
Definition TH1.h:639
virtual Bool_t FindNewAxisLimits(const TAxis *axis, const Double_t point, Double_t &newMin, Double_t &newMax)
finds new limits for the axis so that point is within the range and the limits are compatible with th...
Definition TH1.cxx:6535
static bool CheckAxisLimits(const TAxis *a1, const TAxis *a2)
Check that the axis limits of the histograms are the same.
Definition TH1.cxx:1572
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition TH1.cxx:747
static Bool_t fgDefaultSumw2
! Flag to call TH1::Sumw2 automatically at histogram creation time
Definition TH1.h:179
static void SavePrimitiveFunctions(std::ostream &out, const char *varname, TList *lst)
Save list of functions Also can be used by TGraph classes.
Definition TH1.cxx:7508
virtual void UpdateBinContent(Int_t bin, Double_t content)=0
Raw update of bin content on internal data structure see convention for numbering bins in TH1::GetBin...
Double_t fTsumwx
Total Sum of weight*X.
Definition TH1.h:159
virtual void LabelsDeflate(Option_t *axis="X")
Reduce the number of bins for the axis passed in the option to the number of bins having a label.
Definition TH1.cxx:5287
TString fOption
Histogram options.
Definition TH1.h:166
virtual void Eval(TF1 *f1, Option_t *option="")
Evaluate function f1 at the center of bins of this histogram.
Definition TH1.cxx:3200
virtual void SetBarWidth(Float_t width=0.5)
Set the width of bars as fraction of the bin width for drawing mode "B".
Definition TH1.h:613
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition TH1.cxx:1389
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition TH1.cxx:9072
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition TH1.cxx:7817
2-D histogram with a double per channel (see TH1 documentation)
Definition TH2.h:400
static THLimitsFinder * GetLimitsFinder()
Return pointer to the current finder.
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
void Clear(Option_t *option="") override
Remove all objects from the list.
A doubly linked list.
Definition TList.h:38
void Streamer(TBuffer &) override
Stream all objects in the collection to or from the I/O buffer.
Definition TList.cxx:1323
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:708
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition TList.cxx:894
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:952
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:789
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:600
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:487
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
void Copy(TObject &named) const override
Copy this to obj.
Definition TNamed.cxx:93
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:173
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
void Streamer(TBuffer &) override
Stream an object of class TObject.
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
TString fTitle
Definition TNamed.h:33
TString fName
Definition TNamed.h:32
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:149
Mother of all ROOT objects.
Definition TObject.h:42
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:458
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:476
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition TObject.cxx:903
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1075
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:203
virtual void SaveAs(const char *filename="", Option_t *option="") const
Save this object in the file specified by filename.
Definition TObject.cxx:706
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:882
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:544
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1089
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:893
static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option=nullptr)
Save invocation of primitive Draw() method Skipped if option contains "nodraw" string.
Definition TObject.cxx:840
static TString SavePrimitiveVector(std::ostream &out, const char *prefix, Int_t len, Double_t *arr, Int_t flag=0)
Save array in the output stream "out" as vector.
Definition TObject.cxx:791
void ResetBit(UInt_t f)
Definition TObject.h:203
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:70
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:80
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:72
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1063
Longptr_t ExecPlugin(int nargs)
Int_t LoadPlugin()
Load the plugin library for this handler.
static TClass * Class()
This is the base class for the ROOT Random number generators.
Definition TRandom.h:27
Double_t Rndm() override
Machine independent random number generator.
Definition TRandom.cxx:558
virtual Double_t PoissonD(Double_t mean)
Generates a random number according to a Poisson law.
Definition TRandom.cxx:460
virtual ULong64_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition TRandom.cxx:403
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
void ToLower()
Change string to lower-case.
Definition TString.cxx:1189
TString & ReplaceSpecialCppChars()
Find special characters which are typically used in printf() calls and replace them by appropriate es...
Definition TString.cxx:1121
const char * Data() const
Definition TString.h:384
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:713
@ kIgnoreCase
Definition TString.h:285
void ToUpper()
Change string to upper case.
Definition TString.cxx:1202
Bool_t IsNull() const
Definition TString.h:422
virtual void Streamer(TBuffer &)
Stream a string object.
Definition TString.cxx:1418
TString & Append(const char *cs)
Definition TString.h:581
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:641
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:660
Int_t GetOptStat() const
Definition TStyle.h:247
void SetOptStat(Int_t stat=1)
The type of information printed in the histogram statistics box can be selected via the parameter mod...
Definition TStyle.cxx:1641
void SetHistFillColor(Color_t color=1)
Definition TStyle.h:383
Color_t GetHistLineColor() const
Definition TStyle.h:235
Bool_t IsReading() const
Definition TStyle.h:300
Float_t GetBarOffset() const
Definition TStyle.h:184
void SetHistLineStyle(Style_t styl=0)
Definition TStyle.h:386
Style_t GetHistFillStyle() const
Definition TStyle.h:236
Color_t GetHistFillColor() const
Definition TStyle.h:234
Float_t GetBarWidth() const
Definition TStyle.h:185
Bool_t GetCanvasPreferGL() const
Definition TStyle.h:189
void SetHistLineColor(Color_t color=1)
Definition TStyle.h:384
void SetBarOffset(Float_t baroff=0.5)
Definition TStyle.h:339
Style_t GetHistLineStyle() const
Definition TStyle.h:237
void SetBarWidth(Float_t barwidth=0.5)
Definition TStyle.h:340
void SetHistFillStyle(Style_t styl=0)
Definition TStyle.h:385
Width_t GetHistLineWidth() const
Definition TStyle.h:238
Int_t GetOptFit() const
Definition TStyle.h:246
void SetHistLineWidth(Width_t width=1)
Definition TStyle.h:387
TVectorT.
Definition TVectorT.h:29
TVirtualFFT is an interface class for Fast Fourier Transforms.
Definition TVirtualFFT.h:88
static TVirtualFFT * FFT(Int_t ndim, Int_t *n, Option_t *option)
Returns a pointer to the FFT of requested size and type.
static TVirtualFFT * SineCosine(Int_t ndim, Int_t *n, Int_t *r2rkind, Option_t *option)
Returns a pointer to a sine or cosine transform of requested size and kind.
Abstract Base Class for Fitting.
static TVirtualFitter * GetFitter()
static: return the current Fitter
Abstract interface to a histogram painter.
virtual void DrawPanel()=0
Int_t DistancetoPrimitive(Int_t px, Int_t py) override=0
Computes distance from point (px,py) to the object.
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override=0
Execute action corresponding to an event at (px,py).
virtual void SetHighlight()=0
static TVirtualHistPainter * HistPainter(TH1 *obj)
Static function returning a pointer to the current histogram painter.
void Paint(Option_t *option="") override=0
This method must be overridden if a class wants to paint itself.
double gamma_quantile_c(double z, double alpha, double theta)
Inverse ( ) of the cumulative distribution function of the upper tail of the gamma distribution (gamm...
double gamma_quantile(double z, double alpha, double theta)
Inverse ( ) of the cumulative distribution function of the lower tail of the gamma distribution (gamm...
const Double_t sigma
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TH1F * h1
Definition legend1.C:5
TF1 * f1
Definition legend1.C:11
return c2
Definition legend2.C:14
R__ALWAYS_INLINE bool HasBeenDeleted(const TObject *obj)
Check if the TObject's memory has been deleted.
Definition TObject.h:407
TFitResultPtr FitObject(TH1 *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
fitting function for a TH1 (called from TH1::Fit)
Definition HFitImpl.cxx:977
double Chisquare(const TH1 &h1, TF1 &f1, bool useRange, EChisquareType type)
compute the chi2 value for an histogram given a function (see TH1::Chisquare for the documentation)
void FitOptionsMake(EFitObjectType type, const char *option, Foption_t &fitOption)
Decode list of options into fitOption.
Definition HFitImpl.cxx:685
void FillData(BinData &dv, const TH1 *hist, TF1 *func=nullptr)
fill the data vector from a TH1.
R__EXTERN TVirtualRWMutex * gCoreMutex
Bool_t IsNaN(Double_t x)
Definition TMath.h:903
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:704
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition TMath.cxx:637
Double_t Median(Long64_t n, const T *a, const Double_t *w=nullptr, Long64_t *work=nullptr)
Same as RMS.
Definition TMath.h:1359
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Definition TMath.h:913
Double_t Floor(Double_t x)
Rounds x downward, returning the largest integral value that is not greater than x.
Definition TMath.h:691
Double_t ATan(Double_t)
Returns the principal value of the arc tangent of x, expressed in radians.
Definition TMath.h:651
Double_t Ceil(Double_t x)
Rounds x upward, returning the smallest integral value that is not less than x.
Definition TMath.h:679
T MinElement(Long64_t n, const T *a)
Returns minimum of array a of length n.
Definition TMath.h:971
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:767
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
constexpr Double_t Pi()
Definition TMath.h:40
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Comparing floating points.
Definition TMath.h:429
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Comparing floating points.
Definition TMath.h:421
Double_t KolmogorovProb(Double_t z)
Calculates the Kolmogorov distribution function,.
Definition TMath.cxx:679
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Sort the n elements of the array a of generic templated type Element.
Definition TMathBase.h:413
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition TMathBase.h:329
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:773
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:122
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
Definition TMath.h:928
th1 Draw()
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2338