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 <cstdlib>
13#include <cstring>
14#include <cstdio>
15#include <cctype>
16#include <climits>
17#include <sstream>
18#include <cmath>
19#include <iostream>
20
21#include "TROOT.h"
22#include "TBuffer.h"
23#include "TEnv.h"
24#include "TClass.h"
25#include "TMath.h"
26#include "THashList.h"
27#include "TH1.h"
28#include "TH2.h"
29#include "TH3.h"
30#include "TF2.h"
31#include "TF3.h"
32#include "TPluginManager.h"
33#include "TVirtualPad.h"
34#include "TRandom.h"
35#include "TVirtualFitter.h"
36#include "THLimitsFinder.h"
37#include "TProfile.h"
38#include "TStyle.h"
39#include "TVectorF.h"
40#include "TVectorD.h"
41#include "TBrowser.h"
42#include "TError.h"
43#include "TVirtualHistPainter.h"
44#include "TVirtualFFT.h"
45#include "TVirtualPaveStats.h"
46
47#include "HFitInterface.h"
48#include "Fit/DataRange.h"
49#include "Fit/BinData.h"
50#include "Math/GoFTest.h"
53
54#include "TH1Merger.h"
55
56/** \addtogroup Histograms
57@{
58\class TH1C
59\brief 1-D histogram with a byte per channel (see TH1 documentation)
60\class TH1S
61\brief 1-D histogram with a short per channel (see TH1 documentation)
62\class TH1I
63\brief 1-D histogram with an int per channel (see TH1 documentation)}
64\class TH1F
65\brief 1-D histogram with a float per channel (see TH1 documentation)}
66\class TH1D
67\brief 1-D histogram with a double per channel (see TH1 documentation)}
68@}
69*/
70
71/** \class TH1
72 \ingroup Histograms
73TH1 is the base class of all histogram classes in %ROOT.
74
75It provides the common interface for operations such as binning, filling, drawing, which
76will be detailed below.
77
78-# [Creating histograms](\ref creating-histograms)
79 - [Labelling axes](\ref labelling-axis)
80-# [Binning](\ref binning)
81 - [Fix or variable bin size](\ref fix-var)
82 - [Convention for numbering bins](\ref convention)
83 - [Alphanumeric Bin Labels](\ref alpha)
84 - [Histograms with automatic bins](\ref auto-bin)
85 - [Rebinning](\ref rebinning)
86-# [Filling histograms](\ref filling-histograms)
87 - [Associated errors](\ref associated-errors)
88 - [Associated functions](\ref associated-functions)
89 - [Projections of histograms](\ref prof-hist)
90 - [Random Numbers and histograms](\ref random-numbers)
91 - [Making a copy of a histogram](\ref making-a-copy)
92 - [Normalizing histograms](\ref normalizing)
93-# [Drawing histograms](\ref drawing-histograms)
94 - [Setting Drawing histogram contour levels (2-D hists only)](\ref cont-level)
95 - [Setting histogram graphics attributes](\ref graph-att)
96 - [Customising how axes are drawn](\ref axis-drawing)
97-# [Fitting histograms](\ref fitting-histograms)
98-# [Saving/reading histograms to/from a ROOT file](\ref saving-histograms)
99-# [Operations on histograms](\ref operations-on-histograms)
100-# [Miscellaneous operations](\ref misc)
101
102ROOT supports the following histogram types:
103
104 - 1-D histograms:
105 - TH1C : histograms with one byte per channel. Maximum bin content = 127
106 - TH1S : histograms with one short per channel. Maximum bin content = 32767
107 - TH1I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
108 - TH1F : histograms with one float per channel. Maximum precision 7 digits
109 - TH1D : histograms with one double per channel. Maximum precision 14 digits
110 - 2-D histograms:
111 - TH2C : histograms with one byte per channel. Maximum bin content = 127
112 - TH2S : histograms with one short per channel. Maximum bin content = 32767
113 - TH2I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
114 - TH2F : histograms with one float per channel. Maximum precision 7 digits
115 - TH2D : histograms with one double per channel. Maximum precision 14 digits
116 - 3-D histograms:
117 - TH3C : histograms with one byte per channel. Maximum bin content = 127
118 - TH3S : histograms with one short per channel. Maximum bin content = 32767
119 - TH3I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
120 - TH3F : histograms with one float per channel. Maximum precision 7 digits
121 - TH3D : histograms with one double per channel. Maximum precision 14 digits
122 - Profile histograms: See classes TProfile, TProfile2D and TProfile3D.
123 Profile histograms are used to display the mean value of Y and its standard deviation
124 for each bin in X. Profile histograms are in many cases an elegant
125 replacement of two-dimensional histograms : the inter-relation of two
126 measured quantities X and Y can always be visualized by a two-dimensional
127 histogram or scatter-plot; If Y is an unknown (but single-valued)
128 approximate function of X, this function is displayed by a profile
129 histogram with much better precision than by a scatter-plot.
130
131<sup>
132\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)
133</sup>
134
135The inheritance hierarchy looks as follows:
136
137\image html classTH1__inherit__graph_org.svg width=100%
138
139\anchor creating-histograms
140## Creating histograms
141
142Histograms are created by invoking one of the constructors, e.g.
143~~~ {.cpp}
144 TH1F *h1 = new TH1F("h1", "h1 title", 100, 0, 4.4);
145 TH2F *h2 = new TH2F("h2", "h2 title", 40, 0, 4, 30, -3, 3);
146~~~
147Histograms may also be created by:
148
149 - calling the Clone() function, see below
150 - making a projection from a 2-D or 3-D histogram, see below
151 - reading a histogram from a file
152
153 When a histogram is created, a reference to it is automatically added
154 to the list of in-memory objects for the current file or directory.
155 Then the pointer to this histogram in the current directory can be found
156 by its name, doing:
157~~~ {.cpp}
158 TH1F *h1 = (TH1F*)gDirectory->FindObject(name);
159~~~
160
161 This default behaviour can be changed by:
162~~~ {.cpp}
163 h->SetDirectory(nullptr); // for the current histogram h
164 TH1::AddDirectory(kFALSE); // sets a global switch disabling the referencing
165~~~
166 When the histogram is deleted, the reference to it is removed from
167 the list of objects in memory.
168 When a file is closed, all histograms in memory associated with this file
169 are automatically deleted.
170
171\anchor labelling-axis
172### Labelling axes
173
174 Axis titles can be specified in the title argument of the constructor.
175 They must be separated by ";":
176~~~ {.cpp}
177 TH1F* h=new TH1F("h", "Histogram title;X Axis;Y Axis", 100, 0, 1);
178~~~
179 The histogram title and the axis titles can be any TLatex string, and
180 are persisted if a histogram is written to a file.
181
182 Any title can be omitted:
183~~~ {.cpp}
184 TH1F* h=new TH1F("h", "Histogram title;;Y Axis", 100, 0, 1);
185 TH1F* h=new TH1F("h", ";;Y Axis", 100, 0, 1);
186~~~
187 The method SetTitle() has the same syntax:
188~~~ {.cpp}
189 h->SetTitle("Histogram title;Another X title Axis");
190~~~
191Alternatively, the title of each axis can be set directly:
192~~~ {.cpp}
193 h->GetXaxis()->SetTitle("X axis title");
194 h->GetYaxis()->SetTitle("Y axis title");
195~~~
196For bin labels see \ref binning.
197
198\anchor binning
199## Binning
200
201\anchor fix-var
202### Fix or variable bin size
203
204 All histogram types support either fix or variable bin sizes.
205 2-D histograms may have fix size bins along X and variable size bins
206 along Y or vice-versa. The functions to fill, manipulate, draw or access
207 histograms are identical in both cases.
208
209 Each histogram always contains 3 axis objects of type TAxis: fXaxis, fYaxis and fZaxis.
210 To access the axis parameters, use:
211~~~ {.cpp}
212 TAxis *xaxis = h->GetXaxis(); etc.
213 Double_t binCenter = xaxis->GetBinCenter(bin), etc.
214~~~
215 See class TAxis for a description of all the access functions.
216 The axis range is always stored internally in double precision.
217
218\anchor convention
219### Convention for numbering bins
220
221 For all histogram types: nbins, xlow, xup
222~~~ {.cpp}
223 bin = 0; underflow bin
224 bin = 1; first bin with low-edge xlow INCLUDED
225 bin = nbins; last bin with upper-edge xup EXCLUDED
226 bin = nbins+1; overflow bin
227~~~
228 In case of 2-D or 3-D histograms, a "global bin" number is defined.
229 For example, assuming a 3-D histogram with (binx, biny, binz), the function
230~~~ {.cpp}
231 Int_t gbin = h->GetBin(binx, biny, binz);
232~~~
233 returns a global/linearized gbin number. This global gbin is useful
234 to access the bin content/error information independently of the dimension.
235 Note that to access the information other than bin content and errors
236 one should use the TAxis object directly with e.g.:
237~~~ {.cpp}
238 Double_t xcenter = h3->GetZaxis()->GetBinCenter(27);
239~~~
240 returns the center along z of bin number 27 (not the global bin)
241 in the 3-D histogram h3.
242
243\anchor alpha
244### Alphanumeric Bin Labels
245
246 By default, a histogram axis is drawn with its numeric bin labels.
247 One can specify alphanumeric labels instead with:
248
249 - call TAxis::SetBinLabel(bin, label);
250 This can always be done before or after filling.
251 When the histogram is drawn, bin labels will be automatically drawn.
252 See examples labels1.C and labels2.C
253 - call to a Fill function with one of the arguments being a string, e.g.
254~~~ {.cpp}
255 hist1->Fill(somename, weight);
256 hist2->Fill(x, somename, weight);
257 hist2->Fill(somename, y, weight);
258 hist2->Fill(somenamex, somenamey, weight);
259~~~
260 See examples hlabels1.C and hlabels2.C
261 - via TTree::Draw. see for example cernstaff.C
262~~~ {.cpp}
263 tree.Draw("Nation::Division");
264~~~
265 where "Nation" and "Division" are two branches of a Tree.
266
267When using the options 2 or 3 above, the labels are automatically
268 added to the list (THashList) of labels for a given axis.
269 By default, an axis is drawn with the order of bins corresponding
270 to the filling sequence. It is possible to reorder the axis
271
272 - alphabetically
273 - by increasing or decreasing values
274
275 The reordering can be triggered via the TAxis context menu by selecting
276 the menu item "LabelsOption" or by calling directly
277 TH1::LabelsOption(option, axis) where
278
279 - axis may be "X", "Y" or "Z"
280 - option may be:
281 - "a" sort by alphabetic order
282 - ">" sort by decreasing values
283 - "<" sort by increasing values
284 - "h" draw labels horizontal
285 - "v" draw labels vertical
286 - "u" draw labels up (end of label right adjusted)
287 - "d" draw labels down (start of label left adjusted)
288
289 When using the option 2 above, new labels are added by doubling the current
290 number of bins in case one label does not exist yet.
291 When the Filling is terminated, it is possible to trim the number
292 of bins to match the number of active labels by calling
293~~~ {.cpp}
294 TH1::LabelsDeflate(axis) with axis = "X", "Y" or "Z"
295~~~
296 This operation is automatic when using TTree::Draw.
297 Once bin labels have been created, they become persistent if the histogram
298 is written to a file or when generating the C++ code via SavePrimitive.
299
300\anchor auto-bin
301### Histograms with automatic bins
302
303 When a histogram is created with an axis lower limit greater or equal
304 to its upper limit, the SetBuffer is automatically called with an
305 argument fBufferSize equal to fgBufferSize (default value=1000).
306 fgBufferSize may be reset via the static function TH1::SetDefaultBufferSize.
307 The axis limits will be automatically computed when the buffer will
308 be full or when the function BufferEmpty is called.
309
310\anchor rebinning
311### Rebinning
312
313 At any time, a histogram can be rebinned via TH1::Rebin. This function
314 returns a new histogram with the rebinned contents.
315 If bin errors were stored, they are recomputed during the rebinning.
316
317
318\anchor filling-histograms
319## Filling histograms
320
321 A histogram is typically filled with statements like:
322~~~ {.cpp}
323 h1->Fill(x);
324 h1->Fill(x, w); //fill with weight
325 h2->Fill(x, y)
326 h2->Fill(x, y, w)
327 h3->Fill(x, y, z)
328 h3->Fill(x, y, z, w)
329~~~
330 or via one of the Fill functions accepting names described above.
331 The Fill functions compute the bin number corresponding to the given
332 x, y or z argument and increment this bin by the given weight.
333 The Fill functions return the bin number for 1-D histograms or global
334 bin number for 2-D and 3-D histograms.
335 If TH1::Sumw2 has been called before filling, the sum of squares of
336 weights is also stored.
337 One can also increment directly a bin number via TH1::AddBinContent
338 or replace the existing content via TH1::SetBinContent.
339 To access the bin content of a given bin, do:
340~~~ {.cpp}
341 Double_t binContent = h->GetBinContent(bin);
342~~~
343
344 By default, the bin number is computed using the current axis ranges.
345 If the automatic binning option has been set via
346~~~ {.cpp}
347 h->SetCanExtend(TH1::kAllAxes);
348~~~
349 then, the Fill Function will automatically extend the axis range to
350 accomodate the new value specified in the Fill argument. The method
351 used is to double the bin size until the new value fits in the range,
352 merging bins two by two. This automatic binning options is extensively
353 used by the TTree::Draw function when histogramming Tree variables
354 with an unknown range.
355 This automatic binning option is supported for 1-D, 2-D and 3-D histograms.
356
357 During filling, some statistics parameters are incremented to compute
358 the mean value and Root Mean Square with the maximum precision.
359
360 In case of histograms of type TH1C, TH1S, TH2C, TH2S, TH3C, TH3S
361 a check is made that the bin contents do not exceed the maximum positive
362 capacity (127 or 32767). Histograms of all types may have positive
363 or/and negative bin contents.
364
365\anchor associated-errors
366### Associated errors
367 By default, for each bin, the sum of weights is computed at fill time.
368 One can also call TH1::Sumw2 to force the storage and computation
369 of the sum of the square of weights per bin.
370 If Sumw2 has been called, the error per bin is computed as the
371 sqrt(sum of squares of weights), otherwise the error is set equal
372 to the sqrt(bin content).
373 To return the error for a given bin number, do:
374~~~ {.cpp}
375 Double_t error = h->GetBinError(bin);
376~~~
377
378\anchor associated-functions
379### Associated functions
380 One or more object (typically a TF1*) can be added to the list
381 of functions (fFunctions) associated to each histogram.
382 When TH1::Fit is invoked, the fitted function is added to this list.
383 Given a histogram h, one can retrieve an associated function
384 with:
385~~~ {.cpp}
386 TF1 *myfunc = h->GetFunction("myfunc");
387~~~
388
389
390\anchor operations-on-histograms
391## Operations on histograms
392
393 Many types of operations are supported on histograms or between histograms
394
395 - Addition of a histogram to the current histogram.
396 - Additions of two histograms with coefficients and storage into the current
397 histogram.
398 - Multiplications and Divisions are supported in the same way as additions.
399 - The Add, Divide and Multiply functions also exist to add, divide or multiply
400 a histogram by a function.
401
402 If a histogram has associated error bars (TH1::Sumw2 has been called),
403 the resulting error bars are also computed assuming independent histograms.
404 In case of divisions, Binomial errors are also supported.
405 One can mark a histogram to be an "average" histogram by setting its bit kIsAverage via
406 myhist.SetBit(TH1::kIsAverage);
407 When adding (see TH1::Add) average histograms, the histograms are averaged and not summed.
408
409
410\anchor prof-hist
411### Projections of histograms
412
413 One can:
414
415 - make a 1-D projection of a 2-D histogram or Profile
416 see functions TH2::ProjectionX,Y, TH2::ProfileX,Y, TProfile::ProjectionX
417 - make a 1-D, 2-D or profile out of a 3-D histogram
418 see functions TH3::ProjectionZ, TH3::Project3D.
419
420 One can fit these projections via:
421~~~ {.cpp}
422 TH2::FitSlicesX,Y, TH3::FitSlicesZ.
423~~~
424
425\anchor random-numbers
426### Random Numbers and histograms
427
428 TH1::FillRandom can be used to randomly fill a histogram using
429 the contents of an existing TF1 function or another
430 TH1 histogram (for all dimensions).
431 For example, the following two statements create and fill a histogram
432 10000 times with a default gaussian distribution of mean 0 and sigma 1:
433~~~ {.cpp}
434 TH1F h1("h1", "histo from a gaussian", 100, -3, 3);
435 h1.FillRandom("gaus", 10000);
436~~~
437 TH1::GetRandom can be used to return a random number distributed
438 according to the contents of a histogram.
439
440\anchor making-a-copy
441### Making a copy of a histogram
442 Like for any other ROOT object derived from TObject, one can use
443 the Clone() function. This makes an identical copy of the original
444 histogram including all associated errors and functions, e.g.:
445~~~ {.cpp}
446 TH1F *hnew = (TH1F*)h->Clone("hnew");
447~~~
448
449\anchor normalizing
450### Normalizing histograms
451
452 One can scale a histogram such that the bins integral is equal to
453 the normalization parameter via TH1::Scale(Double_t norm), where norm
454 is the desired normalization divided by the integral of the histogram.
455
456
457\anchor drawing-histograms
458## Drawing histograms
459
460 Histograms are drawn via the THistPainter class. Each histogram has
461 a pointer to its own painter (to be usable in a multithreaded program).
462 Many drawing options are supported.
463 See THistPainter::Paint() for more details.
464
465 The same histogram can be drawn with different options in different pads.
466 When a histogram drawn in a pad is deleted, the histogram is
467 automatically removed from the pad or pads where it was drawn.
468 If a histogram is drawn in a pad, then filled again, the new status
469 of the histogram will be automatically shown in the pad next time
470 the pad is updated. One does not need to redraw the histogram.
471 To draw the current version of a histogram in a pad, one can use
472~~~ {.cpp}
473 h->DrawCopy();
474~~~
475 This makes a clone (see Clone below) of the histogram. Once the clone
476 is drawn, the original histogram may be modified or deleted without
477 affecting the aspect of the clone.
478
479 One can use TH1::SetMaximum() and TH1::SetMinimum() to force a particular
480 value for the maximum or the minimum scale on the plot. (For 1-D
481 histograms this means the y-axis, while for 2-D histograms these
482 functions affect the z-axis).
483
484 TH1::UseCurrentStyle() can be used to change all histogram graphics
485 attributes to correspond to the current selected style.
486 This function must be called for each histogram.
487 In case one reads and draws many histograms from a file, one can force
488 the histograms to inherit automatically the current graphics style
489 by calling before gROOT->ForceStyle().
490
491\anchor cont-level
492### Setting Drawing histogram contour levels (2-D hists only)
493
494 By default contours are automatically generated at equidistant
495 intervals. A default value of 20 levels is used. This can be modified
496 via TH1::SetContour() or TH1::SetContourLevel().
497 the contours level info is used by the drawing options "cont", "surf",
498 and "lego".
499
500\anchor graph-att
501### Setting histogram graphics attributes
502
503 The histogram classes inherit from the attribute classes:
504 TAttLine, TAttFill, and TAttMarker.
505 See the member functions of these classes for the list of options.
506
507\anchor axis-drawing
508### Customizing how axes are drawn
509
510 Use the functions of TAxis, such as
511~~~ {.cpp}
512 histogram.GetXaxis()->SetTicks("+");
513 histogram.GetYaxis()->SetRangeUser(1., 5.);
514~~~
515
516\anchor fitting-histograms
517## Fitting histograms
518
519 Histograms (1-D, 2-D, 3-D and Profiles) can be fitted with a user
520 specified function or a pre-defined function via TH1::Fit.
521 See TH1::Fit(TF1*, Option_t *, Option_t *, Double_t, Double_t) for the fitting documentation and the possible [fitting options](\ref HFitOpt)
522
523 The FitPanel can also be used for fitting an histogram. See the [FitPanel documentation](https://root.cern/manual/fitting/#using-the-fit-panel).
524
525\anchor saving-histograms
526## Saving/reading histograms to/from a ROOT file
527
528 The following statements create a ROOT file and store a histogram
529 on the file. Because TH1 derives from TNamed, the key identifier on
530 the file is the histogram name:
531~~~ {.cpp}
532 TFile f("histos.root", "new");
533 TH1F h1("hgaus", "histo from a gaussian", 100, -3, 3);
534 h1.FillRandom("gaus", 10000);
535 h1->Write();
536~~~
537 To read this histogram in another Root session, do:
538~~~ {.cpp}
539 TFile f("histos.root");
540 TH1F *h = (TH1F*)f.Get("hgaus");
541~~~
542 One can save all histograms in memory to the file by:
543~~~ {.cpp}
544 file->Write();
545~~~
546
547
548\anchor misc
549## Miscellaneous operations
550
551~~~ {.cpp}
552 TH1::KolmogorovTest(): statistical test of compatibility in shape
553 between two histograms
554 TH1::Smooth() smooths the bin contents of a 1-d histogram
555 TH1::Integral() returns the integral of bin contents in a given bin range
556 TH1::GetMean(int axis) returns the mean value along axis
557 TH1::GetStdDev(int axis) returns the sigma distribution along axis
558 TH1::GetEntries() returns the number of entries
559 TH1::Reset() resets the bin contents and errors of a histogram
560~~~
561 IMPORTANT NOTE: The returned values for GetMean and GetStdDev depend on how the
562 histogram statistics are calculated. By default, if no range has been set, the
563 returned values are the (unbinned) ones calculated at fill time. If a range has been
564 set, however, the values are calculated using the bins in range; THIS IS TRUE EVEN
565 IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset the range.
566 To ensure that the returned values are always those of the binned data stored in the
567 histogram, call TH1::ResetStats. See TH1::GetStats.
568*/
569
570TF1 *gF1=nullptr; //left for back compatibility (use TVirtualFitter::GetUserFunc instead)
571
576
577extern void H1InitGaus();
578extern void H1InitExpo();
579extern void H1InitPolynom();
580extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
581extern void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail);
582extern void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b);
583
584// Internal exceptions for the CheckConsistency method
585class DifferentDimension: public std::exception {};
586class DifferentNumberOfBins: public std::exception {};
587class DifferentAxisLimits: public std::exception {};
588class DifferentBinLimits: public std::exception {};
589class DifferentLabels: public std::exception {};
590
592
593////////////////////////////////////////////////////////////////////////////////
594/// Histogram default constructor.
595
597{
598 fDirectory = nullptr;
599 fFunctions = new TList;
600 fNcells = 0;
601 fIntegral = nullptr;
602 fPainter = nullptr;
603 fEntries = 0;
604 fNormFactor = 0;
606 fMaximum = -1111;
607 fMinimum = -1111;
608 fBufferSize = 0;
609 fBuffer = nullptr;
612 fXaxis.SetName("xaxis");
613 fYaxis.SetName("yaxis");
614 fZaxis.SetName("zaxis");
615 fXaxis.SetParent(this);
616 fYaxis.SetParent(this);
617 fZaxis.SetParent(this);
619}
620
621////////////////////////////////////////////////////////////////////////////////
622/// Histogram default destructor.
623
625{
627 return;
628 }
629 delete[] fIntegral;
630 fIntegral = nullptr;
631 delete[] fBuffer;
632 fBuffer = nullptr;
633 if (fFunctions) {
635
637 TObject* obj = nullptr;
638 //special logic to support the case where the same object is
639 //added multiple times in fFunctions.
640 //This case happens when the same object is added with different
641 //drawing modes
642 //In the loop below we must be careful with objects (eg TCutG) that may
643 // have been added to the list of functions of several histograms
644 //and may have been already deleted.
645 while ((obj = fFunctions->First())) {
646 while(fFunctions->Remove(obj)) { }
648 break;
649 }
650 delete obj;
651 obj = nullptr;
652 }
653 delete fFunctions;
654 fFunctions = nullptr;
655 }
656 if (fDirectory) {
657 fDirectory->Remove(this);
658 fDirectory = nullptr;
659 }
660 delete fPainter;
661 fPainter = nullptr;
662}
663
664////////////////////////////////////////////////////////////////////////////////
665/// Constructor for fix bin size histograms.
666/// Creates the main histogram structure.
667///
668/// \param[in] name name of histogram (avoid blanks)
669/// \param[in] title histogram title.
670/// If title is of the form `stringt;stringx;stringy;stringz`,
671/// the histogram title is set to `stringt`,
672/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
673/// \param[in] nbins number of bins
674/// \param[in] xlow low edge of first bin
675/// \param[in] xup upper edge of last bin (not included in last bin)
676
677
678TH1::TH1(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
679 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
680{
681 Build();
682 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
683 fXaxis.Set(nbins,xlow,xup);
684 fNcells = fXaxis.GetNbins()+2;
685}
686
687////////////////////////////////////////////////////////////////////////////////
688/// Constructor for variable bin size histograms using an input array of type float.
689/// Creates the main histogram structure.
690///
691/// \param[in] name name of histogram (avoid blanks)
692/// \param[in] title histogram title.
693/// If title is of the form `stringt;stringx;stringy;stringz`
694/// the histogram title is set to `stringt`,
695/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
696/// \param[in] nbins number of bins
697/// \param[in] xbins array of low-edges for each bin.
698/// This is an array of type float and size nbins+1
699
700TH1::TH1(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
701 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
702{
703 Build();
704 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
705 if (xbins) fXaxis.Set(nbins,xbins);
706 else fXaxis.Set(nbins,0,1);
707 fNcells = fXaxis.GetNbins()+2;
708}
709
710////////////////////////////////////////////////////////////////////////////////
711/// Constructor for variable bin size histograms using an input array of type double.
712///
713/// \param[in] name name of histogram (avoid blanks)
714/// \param[in] title histogram title.
715/// If title is of the form `stringt;stringx;stringy;stringz`
716/// the histogram title is set to `stringt`,
717/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
718/// \param[in] nbins number of bins
719/// \param[in] xbins array of low-edges for each bin.
720/// This is an array of type double and size nbins+1
721
722TH1::TH1(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
723 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
724{
725 Build();
726 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
727 if (xbins) fXaxis.Set(nbins,xbins);
728 else fXaxis.Set(nbins,0,1);
729 fNcells = fXaxis.GetNbins()+2;
730}
731
732////////////////////////////////////////////////////////////////////////////////
733/// Static function: cannot be inlined on Windows/NT.
734
736{
737 return fgAddDirectory;
738}
739
740////////////////////////////////////////////////////////////////////////////////
741/// Browse the Histogram object.
742
744{
745 Draw(b ? b->GetDrawOption() : "");
746 gPad->Update();
747}
748
749////////////////////////////////////////////////////////////////////////////////
750/// Creates histogram basic data structure.
751
753{
754 fDirectory = nullptr;
755 fPainter = nullptr;
756 fIntegral = nullptr;
757 fEntries = 0;
758 fNormFactor = 0;
760 fMaximum = -1111;
761 fMinimum = -1111;
762 fBufferSize = 0;
763 fBuffer = nullptr;
766 fXaxis.SetName("xaxis");
767 fYaxis.SetName("yaxis");
768 fZaxis.SetName("zaxis");
769 fYaxis.Set(1,0.,1.);
770 fZaxis.Set(1,0.,1.);
771 fXaxis.SetParent(this);
772 fYaxis.SetParent(this);
773 fZaxis.SetParent(this);
774
776
777 fFunctions = new TList;
778
780
783 if (fDirectory) {
785 fDirectory->Append(this,kTRUE);
786 }
787 }
788}
789
790////////////////////////////////////////////////////////////////////////////////
791/// Performs the operation: `this = this + c1*f1`
792/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
793///
794/// By default, the function is computed at the centre of the bin.
795/// if option "I" is specified (1-d histogram only), the integral of the
796/// function in each bin is used instead of the value of the function at
797/// the centre of the bin.
798///
799/// Only bins inside the function range are recomputed.
800///
801/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
802/// you should call Sumw2 before making this operation.
803/// This is particularly important if you fit the histogram after TH1::Add
804///
805/// The function return kFALSE if the Add operation failed
806
808{
809 if (!f1) {
810 Error("Add","Attempt to add a non-existing function");
811 return kFALSE;
812 }
813
814 TString opt = option;
815 opt.ToLower();
816 Bool_t integral = kFALSE;
817 if (opt.Contains("i") && fDimension == 1) integral = kTRUE;
818
819 Int_t ncellsx = GetNbinsX() + 2; // cells = normal bins + underflow bin + overflow bin
820 Int_t ncellsy = GetNbinsY() + 2;
821 Int_t ncellsz = GetNbinsZ() + 2;
822 if (fDimension < 2) ncellsy = 1;
823 if (fDimension < 3) ncellsz = 1;
824
825 // delete buffer if it is there since it will become invalid
826 if (fBuffer) BufferEmpty(1);
827
828 // - Add statistics
829 Double_t s1[10];
830 for (Int_t i = 0; i < 10; ++i) s1[i] = 0;
831 PutStats(s1);
832 SetMinimum();
833 SetMaximum();
834
835 // - Loop on bins (including underflows/overflows)
836 Int_t bin, binx, biny, binz;
837 Double_t cu=0;
838 Double_t xx[3];
839 Double_t *params = nullptr;
840 f1->InitArgs(xx,params);
841 for (binz = 0; binz < ncellsz; ++binz) {
842 xx[2] = fZaxis.GetBinCenter(binz);
843 for (biny = 0; biny < ncellsy; ++biny) {
844 xx[1] = fYaxis.GetBinCenter(biny);
845 for (binx = 0; binx < ncellsx; ++binx) {
846 xx[0] = fXaxis.GetBinCenter(binx);
847 if (!f1->IsInside(xx)) continue;
849 bin = binx + ncellsx * (biny + ncellsy * binz);
850 if (integral) {
851 cu = c1*f1->Integral(fXaxis.GetBinLowEdge(binx), fXaxis.GetBinUpEdge(binx), 0.) / fXaxis.GetBinWidth(binx);
852 } else {
853 cu = c1*f1->EvalPar(xx);
854 }
855 if (TF1::RejectedPoint()) continue;
856 AddBinContent(bin,cu);
857 }
858 }
859 }
860
861 return kTRUE;
862}
863
864////////////////////////////////////////////////////////////////////////////////
865/// Performs the operation: `this = this + c1*h1`
866/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
867///
868/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
869/// if not already set.
870///
871/// Note also that adding histogram with labels is not supported, histogram will be
872/// added merging them by bin number independently of the labels.
873/// For adding histogram with labels one should use TH1::Merge
874///
875/// SPECIAL CASE (Average/Efficiency histograms)
876/// For histograms representing averages or efficiencies, one should compute the average
877/// of the two histograms and not the sum. One can mark a histogram to be an average
878/// histogram by setting its bit kIsAverage with
879/// myhist.SetBit(TH1::kIsAverage);
880/// Note that the two histograms must have their kIsAverage bit set
881///
882/// IMPORTANT NOTE1: If you intend to use the errors of this histogram later
883/// you should call Sumw2 before making this operation.
884/// This is particularly important if you fit the histogram after TH1::Add
885///
886/// IMPORTANT NOTE2: if h1 has a normalisation factor, the normalisation factor
887/// is used , ie this = this + c1*factor*h1
888/// Use the other TH1::Add function if you do not want this feature
889///
890/// IMPORTANT NOTE3: You should be careful about the statistics of the
891/// returned histogram, whose statistics may be binned or unbinned,
892/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
893/// and whether TH1::ResetStats has been called on either this or h1.
894/// See TH1::GetStats.
895///
896/// The function return kFALSE if the Add operation failed
897
899{
900 if (!h1) {
901 Error("Add","Attempt to add a non-existing histogram");
902 return kFALSE;
903 }
904
905 // delete buffer if it is there since it will become invalid
906 if (fBuffer) BufferEmpty(1);
907
908 bool useMerge = (c1 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
909 try {
910 CheckConsistency(this,h1);
911 useMerge = kFALSE;
912 } catch(DifferentNumberOfBins&) {
913 if (useMerge)
914 Info("Add","Attempt to add histograms with different number of bins - trying to use TH1::Merge");
915 else {
916 Error("Add","Attempt to add histograms with different number of bins : nbins h1 = %d , nbins h2 = %d",GetNbinsX(), h1->GetNbinsX());
917 return kFALSE;
918 }
919 } catch(DifferentAxisLimits&) {
920 if (useMerge)
921 Info("Add","Attempt to add histograms with different axis limits - trying to use TH1::Merge");
922 else
923 Warning("Add","Attempt to add histograms with different axis limits");
924 } catch(DifferentBinLimits&) {
925 if (useMerge)
926 Info("Add","Attempt to add histograms with different bin limits - trying to use TH1::Merge");
927 else
928 Warning("Add","Attempt to add histograms with different bin limits");
929 } catch(DifferentLabels&) {
930 // in case of different labels -
931 if (useMerge)
932 Info("Add","Attempt to add histograms with different labels - trying to use TH1::Merge");
933 else
934 Info("Warning","Attempt to add histograms with different labels");
935 }
936
937 if (useMerge) {
938 TList l;
939 l.Add(const_cast<TH1*>(h1));
940 auto iret = Merge(&l);
941 return (iret >= 0);
942 }
943
944 // Create Sumw2 if h1 has Sumw2 set
945 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
946
947 // - Add statistics
948 Double_t entries = TMath::Abs( GetEntries() + c1 * h1->GetEntries() );
949
950 // statistics can be preserved only in case of positive coefficients
951 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
952 Bool_t resetStats = (c1 < 0);
953 Double_t s1[kNstat] = {0};
954 Double_t s2[kNstat] = {0};
955 if (!resetStats) {
956 // need to initialize to zero s1 and s2 since
957 // GetStats fills only used elements depending on dimension and type
958 GetStats(s1);
959 h1->GetStats(s2);
960 }
961
962 SetMinimum();
963 SetMaximum();
964
965 // - Loop on bins (including underflows/overflows)
966 Double_t factor = 1;
967 if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();;
968 Double_t c1sq = c1 * c1;
969 Double_t factsq = factor * factor;
970
971 for (Int_t bin = 0; bin < fNcells; ++bin) {
972 //special case where histograms have the kIsAverage bit set
973 if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
975 Double_t y2 = this->RetrieveBinContent(bin);
977 Double_t e2sq = this->GetBinErrorSqUnchecked(bin);
978 Double_t w1 = 1., w2 = 1.;
979
980 // consider all special cases when bin errors are zero
981 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
982 if (e1sq) w1 = 1. / e1sq;
983 else if (h1->fSumw2.fN) {
984 w1 = 1.E200; // use an arbitrary huge value
985 if (y1 == 0) {
986 // use an estimated error from the global histogram scale
987 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
988 w1 = 1./(sf*sf);
989 }
990 }
991 if (e2sq) w2 = 1. / e2sq;
992 else if (fSumw2.fN) {
993 w2 = 1.E200; // use an arbitrary huge value
994 if (y2 == 0) {
995 // use an estimated error from the global histogram scale
996 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
997 w2 = 1./(sf*sf);
998 }
999 }
1000
1001 double y = (w1*y1 + w2*y2)/(w1 + w2);
1002 UpdateBinContent(bin, y);
1003 if (fSumw2.fN) {
1004 double err2 = 1./(w1 + w2);
1005 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1006 fSumw2.fArray[bin] = err2;
1007 }
1008 } else { // normal case of addition between histograms
1009 AddBinContent(bin, c1 * factor * h1->RetrieveBinContent(bin));
1010 if (fSumw2.fN) fSumw2.fArray[bin] += c1sq * factsq * h1->GetBinErrorSqUnchecked(bin);
1011 }
1012 }
1013
1014 // update statistics (do here to avoid changes by SetBinContent)
1015 if (resetStats) {
1016 // statistics need to be reset in case coefficient are negative
1017 ResetStats();
1018 }
1019 else {
1020 for (Int_t i=0;i<kNstat;i++) {
1021 if (i == 1) s1[i] += c1*c1*s2[i];
1022 else s1[i] += c1*s2[i];
1023 }
1024 PutStats(s1);
1025 SetEntries(entries);
1026 }
1027 return kTRUE;
1028}
1029
1030////////////////////////////////////////////////////////////////////////////////
1031/// Replace contents of this histogram by the addition of h1 and h2.
1032///
1033/// `this = c1*h1 + c2*h2`
1034/// if errors are defined (see TH1::Sumw2), errors are also recalculated
1035///
1036/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
1037/// if not already set.
1038///
1039/// Note also that adding histogram with labels is not supported, histogram will be
1040/// added merging them by bin number independently of the labels.
1041/// For adding histogram ith labels one should use TH1::Merge
1042///
1043/// SPECIAL CASE (Average/Efficiency histograms)
1044/// For histograms representing averages or efficiencies, one should compute the average
1045/// of the two histograms and not the sum. One can mark a histogram to be an average
1046/// histogram by setting its bit kIsAverage with
1047/// myhist.SetBit(TH1::kIsAverage);
1048/// Note that the two histograms must have their kIsAverage bit set
1049///
1050/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
1051/// you should call Sumw2 before making this operation.
1052/// This is particularly important if you fit the histogram after TH1::Add
1053///
1054/// IMPORTANT NOTE2: You should be careful about the statistics of the
1055/// returned histogram, whose statistics may be binned or unbinned,
1056/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
1057/// and whether TH1::ResetStats has been called on either this or h1.
1058/// See TH1::GetStats.
1059///
1060/// ANOTHER SPECIAL CASE : h1 = h2 and c2 < 0
1061/// do a scaling this = c1 * h1 / (bin Volume)
1062///
1063/// The function returns kFALSE if the Add operation failed
1064
1066{
1067
1068 if (!h1 || !h2) {
1069 Error("Add","Attempt to add a non-existing histogram");
1070 return kFALSE;
1071 }
1072
1073 // delete buffer if it is there since it will become invalid
1074 if (fBuffer) BufferEmpty(1);
1075
1076 Bool_t normWidth = kFALSE;
1077 if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
1078
1079 if (h1 != h2) {
1080 bool useMerge = (c1 == 1. && c2 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
1081
1082 try {
1083 CheckConsistency(h1,h2);
1084 CheckConsistency(this,h1);
1085 useMerge = kFALSE;
1086 } catch(DifferentNumberOfBins&) {
1087 if (useMerge)
1088 Info("Add","Attempt to add histograms with different number of bins - trying to use TH1::Merge");
1089 else {
1090 Error("Add","Attempt to add histograms with different number of bins : nbins h1 = %d , nbins h2 = %d",GetNbinsX(), h1->GetNbinsX());
1091 return kFALSE;
1092 }
1093 } catch(DifferentAxisLimits&) {
1094 if (useMerge)
1095 Info("Add","Attempt to add histograms with different axis limits - trying to use TH1::Merge");
1096 else
1097 Warning("Add","Attempt to add histograms with different axis limits");
1098 } catch(DifferentBinLimits&) {
1099 if (useMerge)
1100 Info("Add","Attempt to add histograms with different bin limits - trying to use TH1::Merge");
1101 else
1102 Warning("Add","Attempt to add histograms with different bin limits");
1103 } catch(DifferentLabels&) {
1104 // in case of different labels -
1105 if (useMerge)
1106 Info("Add","Attempt to add histograms with different labels - trying to use TH1::Merge");
1107 else
1108 Info("Warning","Attempt to add histograms with different labels");
1109 }
1110
1111 if (useMerge) {
1112 TList l;
1113 // why TList takes non-const pointers ????
1114 l.Add(const_cast<TH1*>(h1));
1115 l.Add(const_cast<TH1*>(h2));
1116 Reset("ICE");
1117 auto iret = Merge(&l);
1118 return (iret >= 0);
1119 }
1120 }
1121
1122 // Create Sumw2 if h1 or h2 have Sumw2 set
1123 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
1124
1125 // - Add statistics
1126 Double_t nEntries = TMath::Abs( c1*h1->GetEntries() + c2*h2->GetEntries() );
1127
1128 // TODO remove
1129 // statistics can be preserved only in case of positive coefficients
1130 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1131 // also in case of scaling with the width we cannot preserve the statistics
1132 Double_t s1[kNstat] = {0};
1133 Double_t s2[kNstat] = {0};
1134 Double_t s3[kNstat];
1135
1136
1137 Bool_t resetStats = (c1*c2 < 0) || normWidth;
1138 if (!resetStats) {
1139 // need to initialize to zero s1 and s2 since
1140 // GetStats fills only used elements depending on dimension and type
1141 h1->GetStats(s1);
1142 h2->GetStats(s2);
1143 for (Int_t i=0;i<kNstat;i++) {
1144 if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
1145 //else s3[i] = TMath::Abs(c1)*s1[i] + TMath::Abs(c2)*s2[i];
1146 else s3[i] = c1*s1[i] + c2*s2[i];
1147 }
1148 }
1149
1150 SetMinimum();
1151 SetMaximum();
1152
1153 if (normWidth) { // DEPRECATED CASE: belongs to fitting / drawing modules
1154
1155 Int_t nbinsx = GetNbinsX() + 2; // normal bins + underflow, overflow
1156 Int_t nbinsy = GetNbinsY() + 2;
1157 Int_t nbinsz = GetNbinsZ() + 2;
1158
1159 if (fDimension < 2) nbinsy = 1;
1160 if (fDimension < 3) nbinsz = 1;
1161
1162 Int_t bin, binx, biny, binz;
1163 for (binz = 0; binz < nbinsz; ++binz) {
1164 Double_t wz = h1->GetZaxis()->GetBinWidth(binz);
1165 for (biny = 0; biny < nbinsy; ++biny) {
1166 Double_t wy = h1->GetYaxis()->GetBinWidth(biny);
1167 for (binx = 0; binx < nbinsx; ++binx) {
1168 Double_t wx = h1->GetXaxis()->GetBinWidth(binx);
1169 bin = GetBin(binx, biny, binz);
1170 Double_t w = wx*wy*wz;
1171 UpdateBinContent(bin, c1 * h1->RetrieveBinContent(bin) / w);
1172 if (fSumw2.fN) {
1173 Double_t e1 = h1->GetBinError(bin)/w;
1174 fSumw2.fArray[bin] = c1*c1*e1*e1;
1175 }
1176 }
1177 }
1178 }
1179 } else if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
1180 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
1181 // special case where histograms have the kIsAverage bit set
1185 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
1186 Double_t w1 = 1., w2 = 1.;
1187
1188 // consider all special cases when bin errors are zero
1189 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1190 if (e1sq) w1 = 1./ e1sq;
1191 else if (h1->fSumw2.fN) {
1192 w1 = 1.E200; // use an arbitrary huge value
1193 if (y1 == 0 ) { // use an estimated error from the global histogram scale
1194 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1195 w1 = 1./(sf*sf);
1196 }
1197 }
1198 if (e2sq) w2 = 1./ e2sq;
1199 else if (h2->fSumw2.fN) {
1200 w2 = 1.E200; // use an arbitrary huge value
1201 if (y2 == 0) { // use an estimated error from the global histogram scale
1202 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1203 w2 = 1./(sf*sf);
1204 }
1205 }
1206
1207 double y = (w1*y1 + w2*y2)/(w1 + w2);
1208 UpdateBinContent(i, y);
1209 if (fSumw2.fN) {
1210 double err2 = 1./(w1 + w2);
1211 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1212 fSumw2.fArray[i] = err2;
1213 }
1214 }
1215 } else { // case of simple histogram addition
1216 Double_t c1sq = c1 * c1;
1217 Double_t c2sq = c2 * c2;
1218 for (Int_t i = 0; i < fNcells; ++i) { // Loop on cells (bins including underflows/overflows)
1220 if (fSumw2.fN) {
1221 fSumw2.fArray[i] = c1sq * h1->GetBinErrorSqUnchecked(i) + c2sq * h2->GetBinErrorSqUnchecked(i);
1222 }
1223 }
1224 }
1225
1226 if (resetStats) {
1227 // statistics need to be reset in case coefficient are negative
1228 ResetStats();
1229 }
1230 else {
1231 // update statistics (do here to avoid changes by SetBinContent) FIXME remove???
1232 PutStats(s3);
1233 SetEntries(nEntries);
1234 }
1235
1236 return kTRUE;
1237}
1238
1239////////////////////////////////////////////////////////////////////////////////
1240/// Increment bin content by 1.
1241
1243{
1244 AbstractMethod("AddBinContent");
1245}
1246
1247////////////////////////////////////////////////////////////////////////////////
1248/// Increment bin content by a weight w.
1249
1251{
1252 AbstractMethod("AddBinContent");
1253}
1254
1255////////////////////////////////////////////////////////////////////////////////
1256/// Sets the flag controlling the automatic add of histograms in memory
1257///
1258/// By default (fAddDirectory = kTRUE), histograms are automatically added
1259/// to the list of objects in memory.
1260/// Note that one histogram can be removed from its support directory
1261/// by calling h->SetDirectory(nullptr) or h->SetDirectory(dir) to add it
1262/// to the list of objects in the directory dir.
1263///
1264/// NOTE that this is a static function. To call it, use;
1265/// TH1::AddDirectory
1266
1268{
1269 fgAddDirectory = add;
1270}
1271
1272////////////////////////////////////////////////////////////////////////////////
1273/// Auxiliary function to get the power of 2 next (larger) or previous (smaller)
1274/// a given x
1275///
1276/// next = kTRUE : next larger
1277/// next = kFALSE : previous smaller
1278///
1279/// Used by the autobin power of 2 algorithm
1280
1282{
1283 Int_t nn;
1284 Double_t f2 = std::frexp(x, &nn);
1285 return ((next && x > 0.) || (!next && x <= 0.)) ? std::ldexp(std::copysign(1., f2), nn)
1286 : std::ldexp(std::copysign(1., f2), --nn);
1287}
1288
1289////////////////////////////////////////////////////////////////////////////////
1290/// Auxiliary function to get the next power of 2 integer value larger then n
1291///
1292/// Used by the autobin power of 2 algorithm
1293
1295{
1296 Int_t nn;
1297 Double_t f2 = std::frexp(n, &nn);
1298 if (TMath::Abs(f2 - .5) > 0.001)
1299 return (Int_t)std::ldexp(1., nn);
1300 return n;
1301}
1302
1303////////////////////////////////////////////////////////////////////////////////
1304/// Buffer-based estimate of the histogram range using the power of 2 algorithm.
1305///
1306/// Used by the autobin power of 2 algorithm.
1307///
1308/// Works on arguments (min and max from fBuffer) and internal inputs: fXmin,
1309/// fXmax, NBinsX (from fXaxis), ...
1310/// Result save internally in fXaxis.
1311///
1312/// Overloaded by TH2 and TH3.
1313///
1314/// Return -1 if internal inputs are inconsistent, 0 otherwise.
1315
1317{
1318 // We need meaningful raw limits
1319 if (xmi >= xma)
1320 return -1;
1321
1323 Double_t xhmi = fXaxis.GetXmin();
1324 Double_t xhma = fXaxis.GetXmax();
1325
1326 // Now adjust
1327 if (TMath::Abs(xhma) > TMath::Abs(xhmi)) {
1328 // Start from the upper limit
1329 xhma = TH1::AutoP2GetPower2(xhma);
1330 xhmi = xhma - TH1::AutoP2GetPower2(xhma - xhmi);
1331 } else {
1332 // Start from the lower limit
1333 xhmi = TH1::AutoP2GetPower2(xhmi, kFALSE);
1334 xhma = xhmi + TH1::AutoP2GetPower2(xhma - xhmi);
1335 }
1336
1337 // Round the bins to the next power of 2; take into account the possible inflation
1338 // of the range
1339 Double_t rr = (xhma - xhmi) / (xma - xmi);
1340 Int_t nb = TH1::AutoP2GetBins((Int_t)(rr * GetNbinsX()));
1341
1342 // Adjust using the same bin width and offsets
1343 Double_t bw = (xhma - xhmi) / nb;
1344 // Bins to left free on each side
1345 Double_t autoside = gEnv->GetValue("Hist.Binning.Auto.Side", 0.05);
1346 Int_t nbside = (Int_t)(nb * autoside);
1347
1348 // Side up
1349 Int_t nbup = (xhma - xma) / bw;
1350 if (nbup % 2 != 0)
1351 nbup++; // Must be even
1352 if (nbup != nbside) {
1353 // Accounts also for both case: larger or smaller
1354 xhma -= bw * (nbup - nbside);
1355 nb -= (nbup - nbside);
1356 }
1357
1358 // Side low
1359 Int_t nblw = (xmi - xhmi) / bw;
1360 if (nblw % 2 != 0)
1361 nblw++; // Must be even
1362 if (nblw != nbside) {
1363 // Accounts also for both case: larger or smaller
1364 xhmi += bw * (nblw - nbside);
1365 nb -= (nblw - nbside);
1366 }
1367
1368 // Set everything and project
1369 SetBins(nb, xhmi, xhma);
1370
1371 // Done
1372 return 0;
1373}
1374
1375/// Fill histogram with all entries in the buffer.
1376///
1377/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
1378/// - action = 0 histogram is reset and filled from the buffer. When the histogram is filled from the
1379/// buffer the value fBuffer[0] is set to a negative number (= - number of entries)
1380/// When calling with action == 0 the histogram is NOT refilled when fBuffer[0] is < 0
1381/// While when calling with action = -1 the histogram is reset and ALWAYS refilled independently if
1382/// the histogram was filled before. This is needed when drawing the histogram
1383/// - action = 1 histogram is filled and buffer is deleted
1384/// The buffer is automatically deleted when filling the histogram and the entries is
1385/// larger than the buffer size
1386
1388{
1389 // do we need to compute the bin size?
1390 if (!fBuffer) return 0;
1391 Int_t nbentries = (Int_t)fBuffer[0];
1392
1393 // nbentries correspond to the number of entries of histogram
1394
1395 if (nbentries == 0) {
1396 // if action is 1 we delete the buffer
1397 // this will avoid infinite recursion
1398 if (action > 0) {
1399 delete [] fBuffer;
1400 fBuffer = nullptr;
1401 fBufferSize = 0;
1402 }
1403 return 0;
1404 }
1405 if (nbentries < 0 && action == 0) return 0; // case histogram has been already filled from the buffer
1406
1407 Double_t *buffer = fBuffer;
1408 if (nbentries < 0) {
1409 nbentries = -nbentries;
1410 // a reset might call BufferEmpty() giving an infinite recursion
1411 // Protect it by setting fBuffer = nullptr
1412 fBuffer = nullptr;
1413 //do not reset the list of functions
1414 Reset("ICES");
1415 fBuffer = buffer;
1416 }
1417 if (CanExtendAllAxes() || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
1418 //find min, max of entries in buffer
1421 for (Int_t i=0;i<nbentries;i++) {
1422 Double_t x = fBuffer[2*i+2];
1423 // skip infinity or NaN values
1424 if (!std::isfinite(x)) continue;
1425 if (x < xmin) xmin = x;
1426 if (x > xmax) xmax = x;
1427 }
1428 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
1429 Int_t rc = -1;
1431 if ((rc = AutoP2FindLimits(xmin, xmax)) < 0)
1432 Warning("BufferEmpty",
1433 "inconsistency found by power-of-2 autobin algorithm: fallback to standard method");
1434 }
1435 if (rc < 0)
1437 } else {
1438 fBuffer = nullptr;
1439 Int_t keep = fBufferSize; fBufferSize = 0;
1441 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax, &fXaxis);
1442 fBuffer = buffer;
1443 fBufferSize = keep;
1444 }
1445 }
1446
1447 // call DoFillN which will not put entries in the buffer as FillN does
1448 // set fBuffer to zero to avoid re-emptying the buffer from functions called
1449 // by DoFillN (e.g Sumw2)
1450 buffer = fBuffer; fBuffer = nullptr;
1451 DoFillN(nbentries,&buffer[2],&buffer[1],2);
1452 fBuffer = buffer;
1453
1454 // if action == 1 - delete the buffer
1455 if (action > 0) {
1456 delete [] fBuffer;
1457 fBuffer = nullptr;
1458 fBufferSize = 0;
1459 } else {
1460 // if number of entries is consistent with buffer - set it negative to avoid
1461 // refilling the histogram every time BufferEmpty(0) is called
1462 // In case it is not consistent, by setting fBuffer[0]=0 is like resetting the buffer
1463 // (it will not be used anymore the next time BufferEmpty is called)
1464 if (nbentries == (Int_t)fEntries)
1465 fBuffer[0] = -nbentries;
1466 else
1467 fBuffer[0] = 0;
1468 }
1469 return nbentries;
1470}
1471
1472////////////////////////////////////////////////////////////////////////////////
1473/// accumulate arguments in buffer. When buffer is full, empty the buffer
1474///
1475/// - `fBuffer[0]` = number of entries in buffer
1476/// - `fBuffer[1]` = w of first entry
1477/// - `fBuffer[2]` = x of first entry
1478
1480{
1481 if (!fBuffer) return -2;
1482 Int_t nbentries = (Int_t)fBuffer[0];
1483
1484
1485 if (nbentries < 0) {
1486 // reset nbentries to a positive value so next time BufferEmpty() is called
1487 // the histogram will be refilled
1488 nbentries = -nbentries;
1489 fBuffer[0] = nbentries;
1490 if (fEntries > 0) {
1491 // set fBuffer to zero to avoid calling BufferEmpty in Reset
1492 Double_t *buffer = fBuffer; fBuffer=nullptr;
1493 Reset("ICES"); // do not reset list of functions
1494 fBuffer = buffer;
1495 }
1496 }
1497 if (2*nbentries+2 >= fBufferSize) {
1498 BufferEmpty(1);
1499 if (!fBuffer)
1500 // to avoid infinite recursion Fill->BufferFill->Fill
1501 return Fill(x,w);
1502 // this cannot happen
1503 R__ASSERT(0);
1504 }
1505 fBuffer[2*nbentries+1] = w;
1506 fBuffer[2*nbentries+2] = x;
1507 fBuffer[0] += 1;
1508 return -2;
1509}
1510
1511////////////////////////////////////////////////////////////////////////////////
1512/// Check bin limits.
1513
1514bool TH1::CheckBinLimits(const TAxis* a1, const TAxis * a2)
1515{
1516 const TArrayD * h1Array = a1->GetXbins();
1517 const TArrayD * h2Array = a2->GetXbins();
1518 Int_t fN = h1Array->fN;
1519 if ( fN != 0 ) {
1520 if ( h2Array->fN != fN ) {
1521 throw DifferentBinLimits();
1522 return false;
1523 }
1524 else {
1525 for ( int i = 0; i < fN; ++i ) {
1526 // for i==fN (nbin+1) a->GetBinWidth() returns last bin width
1527 // we do not need to exclude that case
1528 double binWidth = a1->GetBinWidth(i);
1529 if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), binWidth*1E-10 ) ) {
1530 throw DifferentBinLimits();
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 throw DifferentLabels();
1552 return false;
1553 }
1554 // check now labels sizes are the same
1555 if (l1->GetSize() != l2->GetSize() ) {
1556 throw DifferentLabels();
1557 return false;
1558 }
1559 for (int i = 1; i <= a1->GetNbins(); ++i) {
1560 TString label1 = a1->GetBinLabel(i);
1561 TString label2 = a2->GetBinLabel(i);
1562 if (label1 != label2) {
1563 throw DifferentLabels();
1564 return false;
1565 }
1566 }
1567
1568 return true;
1569}
1570
1571////////////////////////////////////////////////////////////////////////////////
1572/// Check that the axis limits of the histograms are the same.
1573/// If a first and last bin is passed the axis is compared between the given range
1574
1575bool TH1::CheckAxisLimits(const TAxis *a1, const TAxis *a2 )
1576{
1577 double firstBin = a1->GetBinWidth(1);
1578 double lastBin = a1->GetBinWidth( a1->GetNbins() );
1579 if ( ! TMath::AreEqualAbs(a1->GetXmin(), a2->GetXmin(), firstBin* 1.E-10) ||
1580 ! TMath::AreEqualAbs(a1->GetXmax(), a2->GetXmax(), lastBin*1.E-10) ) {
1581 throw DifferentAxisLimits();
1582 return false;
1583 }
1584 return true;
1585}
1586
1587////////////////////////////////////////////////////////////////////////////////
1588/// Check that the axis are the same
1589
1590bool TH1::CheckEqualAxes(const TAxis *a1, const TAxis *a2 )
1591{
1592 if (a1->GetNbins() != a2->GetNbins() ) {
1593 //throw DifferentNumberOfBins();
1594 ::Info("CheckEqualAxes","Axes have different number of bins : nbin1 = %d nbin2 = %d",a1->GetNbins(),a2->GetNbins() );
1595 return false;
1596 }
1597 try {
1598 CheckAxisLimits(a1,a2);
1599 } catch (DifferentAxisLimits&) {
1600 ::Info("CheckEqualAxes","Axes have different limits");
1601 return false;
1602 }
1603 try {
1604 CheckBinLimits(a1,a2);
1605 } catch (DifferentBinLimits&) {
1606 ::Info("CheckEqualAxes","Axes have different bin limits");
1607 return false;
1608 }
1609
1610 // check labels
1611 try {
1612 CheckBinLabels(a1,a2);
1613 } catch (DifferentLabels&) {
1614 ::Info("CheckEqualAxes","Axes have different labels");
1615 return false;
1616 }
1617
1618 return true;
1619}
1620
1621////////////////////////////////////////////////////////////////////////////////
1622/// Check that two sub axis are the same.
1623/// The limits are defined by first bin and last bin
1624/// N.B. no check is done in this case for variable bins
1625
1626bool TH1::CheckConsistentSubAxes(const TAxis *a1, Int_t firstBin1, Int_t lastBin1, const TAxis * a2, Int_t firstBin2, Int_t lastBin2 )
1627{
1628 // By default is assumed that no bins are given for the second axis
1629 Int_t nbins1 = lastBin1-firstBin1 + 1;
1630 Double_t xmin1 = a1->GetBinLowEdge(firstBin1);
1631 Double_t xmax1 = a1->GetBinUpEdge(lastBin1);
1632
1633 Int_t nbins2 = a2->GetNbins();
1634 Double_t xmin2 = a2->GetXmin();
1635 Double_t xmax2 = a2->GetXmax();
1636
1637 if (firstBin2 < lastBin2) {
1638 // in this case assume no bins are given for the second axis
1639 nbins2 = lastBin1-firstBin1 + 1;
1640 xmin2 = a1->GetBinLowEdge(firstBin1);
1641 xmax2 = a1->GetBinUpEdge(lastBin1);
1642 }
1643
1644 if (nbins1 != nbins2 ) {
1645 ::Info("CheckConsistentSubAxes","Axes have different number of bins");
1646 return false;
1647 }
1648
1649 Double_t firstBin = a1->GetBinWidth(firstBin1);
1650 Double_t lastBin = a1->GetBinWidth(lastBin1);
1651 if ( ! TMath::AreEqualAbs(xmin1,xmin2,1.E-10 * firstBin) ||
1652 ! TMath::AreEqualAbs(xmax1,xmax2,1.E-10 * lastBin) ) {
1653 ::Info("CheckConsistentSubAxes","Axes have different limits");
1654 return false;
1655 }
1656
1657 return true;
1658}
1659
1660////////////////////////////////////////////////////////////////////////////////
1661/// Check histogram compatibility.
1662
1663bool TH1::CheckConsistency(const TH1* h1, const TH1* h2)
1664{
1665 if (h1 == h2) return true;
1666
1667 if (h1->GetDimension() != h2->GetDimension() ) {
1668 throw DifferentDimension();
1669 return false;
1670 }
1671 Int_t dim = h1->GetDimension();
1672
1673 // returns kTRUE if number of bins and bin limits are identical
1674 Int_t nbinsx = h1->GetNbinsX();
1675 Int_t nbinsy = h1->GetNbinsY();
1676 Int_t nbinsz = h1->GetNbinsZ();
1677
1678 // Check whether the histograms have the same number of bins.
1679 if (nbinsx != h2->GetNbinsX() ||
1680 (dim > 1 && nbinsy != h2->GetNbinsY()) ||
1681 (dim > 2 && nbinsz != h2->GetNbinsZ()) ) {
1682 throw DifferentNumberOfBins();
1683 return false;
1684 }
1685
1686 bool ret = true;
1687
1688 // check axis limits
1689 ret &= CheckAxisLimits(h1->GetXaxis(), h2->GetXaxis());
1690 if (dim > 1) ret &= CheckAxisLimits(h1->GetYaxis(), h2->GetYaxis());
1691 if (dim > 2) ret &= CheckAxisLimits(h1->GetZaxis(), h2->GetZaxis());
1692
1693 // check bin limits
1694 ret &= CheckBinLimits(h1->GetXaxis(), h2->GetXaxis());
1695 if (dim > 1) ret &= CheckBinLimits(h1->GetYaxis(), h2->GetYaxis());
1696 if (dim > 2) ret &= CheckBinLimits(h1->GetZaxis(), h2->GetZaxis());
1697
1698 // check labels if histograms are both not empty
1699 if ( !h1->IsEmpty() && !h2->IsEmpty() ) {
1700 ret &= CheckBinLabels(h1->GetXaxis(), h2->GetXaxis());
1701 if (dim > 1) ret &= CheckBinLabels(h1->GetYaxis(), h2->GetYaxis());
1702 if (dim > 2) ret &= CheckBinLabels(h1->GetZaxis(), h2->GetZaxis());
1703 }
1704
1705 return ret;
1706}
1707
1708////////////////////////////////////////////////////////////////////////////////
1709/// \f$ \chi^{2} \f$ test for comparing weighted and unweighted histograms
1710///
1711/// Function: Returns p-value. Other return values are specified by the 3rd parameter
1712///
1713/// \param[in] h2 the second histogram
1714/// \param[in] option
1715/// - "UU" = experiment experiment comparison (unweighted-unweighted)
1716/// - "UW" = experiment MC comparison (unweighted-weighted). Note that
1717/// the first histogram should be unweighted
1718/// - "WW" = MC MC comparison (weighted-weighted)
1719/// - "NORM" = to be used when one or both of the histograms is scaled
1720/// but the histogram originally was unweighted
1721/// - by default underflows and overflows are not included:
1722/// * "OF" = overflows included
1723/// * "UF" = underflows included
1724/// - "P" = print chi2, ndf, p_value, igood
1725/// - "CHI2" = returns chi2 instead of p-value
1726/// - "CHI2/NDF" = returns \f$ \chi^{2} \f$/ndf
1727/// \param[in] res not empty - computes normalized residuals and returns them in this array
1728///
1729/// The current implementation is based on the papers \f$ \chi^{2} \f$ test for comparison
1730/// of weighted and unweighted histograms" in Proceedings of PHYSTAT05 and
1731/// "Comparison weighted and unweighted histograms", arXiv:physics/0605123
1732/// by N.Gagunashvili. This function has been implemented by Daniel Haertl in August 2006.
1733///
1734/// #### Introduction:
1735///
1736/// A frequently used technique in data analysis is the comparison of
1737/// histograms. First suggested by Pearson [1] the \f$ \chi^{2} \f$ test of
1738/// homogeneity is used widely for comparing usual (unweighted) histograms.
1739/// This paper describes the implementation modified \f$ \chi^{2} \f$ tests
1740/// for comparison of weighted and unweighted histograms and two weighted
1741/// histograms [2] as well as usual Pearson's \f$ \chi^{2} \f$ test for
1742/// comparison two usual (unweighted) histograms.
1743///
1744/// #### Overview:
1745///
1746/// Comparison of two histograms expect hypotheses that two histograms
1747/// represent identical distributions. To make a decision p-value should
1748/// be calculated. The hypotheses of identity is rejected if the p-value is
1749/// lower then some significance level. Traditionally significance levels
1750/// 0.1, 0.05 and 0.01 are used. The comparison procedure should include an
1751/// analysis of the residuals which is often helpful in identifying the
1752/// bins of histograms responsible for a significant overall \f$ \chi^{2} \f$ value.
1753/// Residuals are the difference between bin contents and expected bin
1754/// contents. Most convenient for analysis are the normalized residuals. If
1755/// hypotheses of identity are valid then normalized residuals are
1756/// approximately independent and identically distributed random variables
1757/// having N(0,1) distribution. Analysis of residuals expect test of above
1758/// mentioned properties of residuals. Notice that indirectly the analysis
1759/// of residuals increase the power of \f$ \chi^{2} \f$ test.
1760///
1761/// #### Methods of comparison:
1762///
1763/// \f$ \chi^{2} \f$ test for comparison two (unweighted) histograms:
1764/// Let us consider two histograms with the same binning and the number
1765/// of bins equal to r. Let us denote the number of events in the ith bin
1766/// in the first histogram as ni and as mi in the second one. The total
1767/// number of events in the first histogram is equal to:
1768/// \f[
1769/// N = \sum_{i=1}^{r} n_{i}
1770/// \f]
1771/// and
1772/// \f[
1773/// M = \sum_{i=1}^{r} m_{i}
1774/// \f]
1775/// in the second histogram. The hypothesis of identity (homogeneity) [3]
1776/// is that the two histograms represent random values with identical
1777/// distributions. It is equivalent that there exist r constants p1,...,pr,
1778/// such that
1779/// \f[
1780///\sum_{i=1}^{r} p_{i}=1
1781/// \f]
1782/// and the probability of belonging to the ith bin for some measured value
1783/// in both experiments is equal to pi. The number of events in the ith
1784/// bin is a random variable with a distribution approximated by a Poisson
1785/// probability distribution
1786/// \f[
1787///\frac{e^{-Np_{i}}(Np_{i})^{n_{i}}}{n_{i}!}
1788/// \f]
1789///for the first histogram and with distribution
1790/// \f[
1791///\frac{e^{-Mp_{i}}(Mp_{i})^{m_{i}}}{m_{i}!}
1792/// \f]
1793/// for the second histogram. If the hypothesis of homogeneity is valid,
1794/// then the maximum likelihood estimator of pi, i=1,...,r, is
1795/// \f[
1796///\hat{p}_{i}= \frac{n_{i}+m_{i}}{N+M}
1797/// \f]
1798/// and then
1799/// \f[
1800/// 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}}
1801/// \f]
1802/// has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [3].
1803/// The comparison procedure can include an analysis of the residuals which
1804/// is often helpful in identifying the bins of histograms responsible for
1805/// a significant overall \f$ \chi^{2} \f$ value. Most convenient for
1806/// analysis are the adjusted (normalized) residuals [4]
1807/// \f[
1808/// 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))}}
1809/// \f]
1810/// If hypotheses of homogeneity are valid then residuals ri are
1811/// approximately independent and identically distributed random variables
1812/// having N(0,1) distribution. The application of the \f$ \chi^{2} \f$ test has
1813/// restrictions related to the value of the expected frequencies Npi,
1814/// Mpi, i=1,...,r. A conservative rule formulated in [5] is that all the
1815/// expectations must be 1 or greater for both histograms. In practical
1816/// cases when expected frequencies are not known the estimated expected
1817/// frequencies \f$ M\hat{p}_{i}, N\hat{p}_{i}, i=1,...,r \f$ can be used.
1818///
1819/// #### Unweighted and weighted histograms comparison:
1820///
1821/// A simple modification of the ideas described above can be used for the
1822/// comparison of the usual (unweighted) and weighted histograms. Let us
1823/// denote the number of events in the ith bin in the unweighted
1824/// histogram as ni and the common weight of events in the ith bin of the
1825/// weighted histogram as wi. The total number of events in the
1826/// unweighted histogram is equal to
1827///\f[
1828/// N = \sum_{i=1}^{r} n_{i}
1829///\f]
1830/// and the total weight of events in the weighted histogram is equal to
1831///\f[
1832/// W = \sum_{i=1}^{r} w_{i}
1833///\f]
1834/// Let us formulate the hypothesis of identity of an unweighted histogram
1835/// to a weighted histogram so that there exist r constants p1,...,pr, such
1836/// that
1837///\f[
1838/// \sum_{i=1}^{r} p_{i} = 1
1839///\f]
1840/// for the unweighted histogram. The weight wi is a random variable with a
1841/// distribution approximated by the normal probability distribution
1842/// \f$ N(Wp_{i},\sigma_{i}^{2}) \f$ where \f$ \sigma_{i}^{2} \f$ is the variance of the weight wi.
1843/// If we replace the variance \f$ \sigma_{i}^{2} \f$
1844/// with estimate \f$ s_{i}^{2} \f$ (sum of squares of weights of
1845/// events in the ith bin) and the hypothesis of identity is valid, then the
1846/// maximum likelihood estimator of pi,i=1,...,r, is
1847///\f[
1848/// \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}}
1849///\f]
1850/// We may then use the test statistic
1851///\f[
1852/// 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}}
1853///\f]
1854/// and it has approximately a \f$ \sigma^{2}_{(r-1)} \f$ distribution [2]. This test, as well
1855/// as the original one [3], has a restriction on the expected frequencies. The
1856/// expected frequencies recommended for the weighted histogram is more than 25.
1857/// The value of the minimal expected frequency can be decreased down to 10 for
1858/// the case when the weights of the events are close to constant. In the case
1859/// of a weighted histogram if the number of events is unknown, then we can
1860/// apply this recommendation for the equivalent number of events as
1861///\f[
1862/// n_{i}^{equiv} = \frac{ w_{i}^{2} }{ s_{i}^{2} }
1863///\f]
1864/// The minimal expected frequency for an unweighted histogram must be 1. Notice
1865/// that any usual (unweighted) histogram can be considered as a weighted
1866/// histogram with events that have constant weights equal to 1.
1867/// The variance \f$ z_{i}^{2} \f$ of the difference between the weight wi
1868/// and the estimated expectation value of the weight is approximately equal to:
1869///\f[
1870/// 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}
1871///\f]
1872/// The residuals
1873///\f[
1874/// r_{i} = \frac{w_{i}-W\hat{p}_{i}}{z_{i}}
1875///\f]
1876/// have approximately a normal distribution with mean equal to 0 and standard
1877/// deviation equal to 1.
1878///
1879/// #### Two weighted histograms comparison:
1880///
1881/// Let us denote the common weight of events of the ith bin in the first
1882/// histogram as w1i and as w2i in the second one. The total weight of events
1883/// in the first histogram is equal to
1884///\f[
1885/// W_{1} = \sum_{i=1}^{r} w_{1i}
1886///\f]
1887/// and
1888///\f[
1889/// W_{2} = \sum_{i=1}^{r} w_{2i}
1890///\f]
1891/// in the second histogram. Let us formulate the hypothesis of identity of
1892/// weighted histograms so that there exist r constants p1,...,pr, such that
1893///\f[
1894/// \sum_{i=1}^{r} p_{i} = 1
1895///\f]
1896/// and also expectation value of weight w1i equal to W1pi and expectation value
1897/// of weight w2i equal to W2pi. Weights in both the histograms are random
1898/// variables with distributions which can be approximated by a normal
1899/// probability distribution \f$ N(W_{1}p_{i},\sigma_{1i}^{2}) \f$ for the first histogram
1900/// and by a distribution \f$ N(W_{2}p_{i},\sigma_{2i}^{2}) \f$ for the second.
1901/// Here \f$ \sigma_{1i}^{2} \f$ and \f$ \sigma_{2i}^{2} \f$ are the variances
1902/// of w1i and w2i with estimators \f$ s_{1i}^{2} \f$ and \f$ s_{2i}^{2} \f$ respectively.
1903/// If the hypothesis of identity is valid, then the maximum likelihood and
1904/// Least Square Method estimator of pi,i=1,...,r, is
1905///\f[
1906/// \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}}
1907///\f]
1908/// We may then use the test statistic
1909///\f[
1910/// 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}}
1911///\f]
1912/// and it has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [2].
1913/// The normalized or studentised residuals [6]
1914///\f[
1915/// 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})}}}
1916///\f]
1917/// have approximately a normal distribution with mean equal to 0 and standard
1918/// deviation 1. A recommended minimal expected frequency is equal to 10 for
1919/// the proposed test.
1920///
1921/// #### Numerical examples:
1922///
1923/// The method described herein is now illustrated with an example.
1924/// We take a distribution
1925///\f[
1926/// \phi(x) = \frac{2}{(x-10)^{2}+1} + \frac{1}{(x-14)^{2}+1} (1)
1927///\f]
1928/// defined on the interval [4,16]. Events distributed according to the formula
1929/// (1) are simulated to create the unweighted histogram. Uniformly distributed
1930/// events are simulated for the weighted histogram with weights calculated by
1931/// formula (1). Each histogram has the same number of bins: 20. Fig.1 shows
1932/// the result of comparison of the unweighted histogram with 200 events
1933/// (minimal expected frequency equal to one) and the weighted histogram with
1934/// 500 events (minimal expected frequency equal to 25)
1935/// Begin_Macro
1936/// ../../../tutorials/math/chi2test.C
1937/// End_Macro
1938/// Fig 1. An example of comparison of the unweighted histogram with 200 events
1939/// and the weighted histogram with 500 events:
1940/// 1. unweighted histogram;
1941/// 2. weighted histogram;
1942/// 3. normalized residuals plot;
1943/// 4. normal Q-Q plot of residuals.
1944///
1945/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1946/// 21.09 with p-value equal to 0.33, therefore the hypothesis of identity of
1947/// the two histograms can be accepted for 0.05 significant level. The behavior
1948/// of the normalized residuals plot (see Fig. 1c) and the normal Q-Q plot
1949/// (see Fig. 1d) of residuals are regular and we cannot identify the outliers
1950/// or bins with a big influence on \f$ \chi^{2} \f$.
1951///
1952/// The second example presents the same two histograms but 17 events was added
1953/// to content of bin number 15 in unweighted histogram. Fig.2 shows the result
1954/// of comparison of the unweighted histogram with 217 events (minimal expected
1955/// frequency equal to one) and the weighted histogram with 500 events (minimal
1956/// expected frequency equal to 25)
1957/// Begin_Macro
1958/// ../../../tutorials/math/chi2test.C(17)
1959/// End_Macro
1960/// Fig 2. An example of comparison of the unweighted histogram with 217 events
1961/// and the weighted histogram with 500 events:
1962/// 1. unweighted histogram;
1963/// 2. weighted histogram;
1964/// 3. normalized residuals plot;
1965/// 4. normal Q-Q plot of residuals.
1966///
1967/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1968/// 32.33 with p-value equal to 0.029, therefore the hypothesis of identity of
1969/// the two histograms is rejected for 0.05 significant level. The behavior of
1970/// the normalized residuals plot (see Fig. 2c) and the normal Q-Q plot (see
1971/// Fig. 2d) of residuals are not regular and we can identify the outlier or
1972/// bin with a big influence on \f$ \chi^{2} \f$.
1973///
1974/// #### References:
1975///
1976/// - [1] Pearson, K., 1904. On the Theory of Contingency and Its Relation to
1977/// Association and Normal Correlation. Drapers' Co. Memoirs, Biometric
1978/// Series No. 1, London.
1979/// - [2] Gagunashvili, N., 2006. \f$ \sigma^{2} \f$ test for comparison
1980/// of weighted and unweighted histograms. Statistical Problems in Particle
1981/// Physics, Astrophysics and Cosmology, Proceedings of PHYSTAT05,
1982/// Oxford, UK, 12-15 September 2005, Imperial College Press, London, 43-44.
1983/// Gagunashvili,N., Comparison of weighted and unweighted histograms,
1984/// arXiv:physics/0605123, 2006.
1985/// - [3] Cramer, H., 1946. Mathematical methods of statistics.
1986/// Princeton University Press, Princeton.
1987/// - [4] Haberman, S.J., 1973. The analysis of residuals in cross-classified tables.
1988/// Biometrics 29, 205-220.
1989/// - [5] Lewontin, R.C. and Felsenstein, J., 1965. The robustness of homogeneity
1990/// test in 2xN tables. Biometrics 21, 19-33.
1991/// - [6] Seber, G.A.F., Lee, A.J., 2003, Linear Regression Analysis.
1992/// John Wiley & Sons Inc., New York.
1993
1994Double_t TH1::Chi2Test(const TH1* h2, Option_t *option, Double_t *res) const
1995{
1996 Double_t chi2 = 0;
1997 Int_t ndf = 0, igood = 0;
1998
1999 TString opt = option;
2000 opt.ToUpper();
2001
2002 Double_t prob = Chi2TestX(h2,chi2,ndf,igood,option,res);
2003
2004 if(opt.Contains("P")) {
2005 printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
2006 }
2007 if(opt.Contains("CHI2/NDF")) {
2008 if (ndf == 0) return 0;
2009 return chi2/ndf;
2010 }
2011 if(opt.Contains("CHI2")) {
2012 return chi2;
2013 }
2014
2015 return prob;
2016}
2017
2018////////////////////////////////////////////////////////////////////////////////
2019/// The computation routine of the Chisquare test. For the method description,
2020/// see Chi2Test() function.
2021///
2022/// \return p-value
2023/// \param[in] h2 the second histogram
2024/// \param[in] option
2025/// - "UU" = experiment experiment comparison (unweighted-unweighted)
2026/// - "UW" = experiment MC comparison (unweighted-weighted). Note that the first
2027/// histogram should be unweighted
2028/// - "WW" = MC MC comparison (weighted-weighted)
2029/// - "NORM" = if one or both histograms is scaled
2030/// - "OF" = overflows included
2031/// - "UF" = underflows included
2032/// by default underflows and overflows are not included
2033/// \param[out] igood test output
2034/// - igood=0 - no problems
2035/// - For unweighted unweighted comparison
2036/// - igood=1'There is a bin in the 1st histogram with less than 1 event'
2037/// - igood=2'There is a bin in the 2nd histogram with less than 1 event'
2038/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2039/// - For unweighted weighted comparison
2040/// - igood=1'There is a bin in the 1st histogram with less then 1 event'
2041/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective number of events'
2042/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2043/// - For weighted weighted comparison
2044/// - igood=1'There is a bin in the 1st histogram with less then 10 effective
2045/// number of events'
2046/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective
2047/// number of events'
2048/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2049/// \param[out] chi2 chisquare of the test
2050/// \param[out] ndf number of degrees of freedom (important, when both histograms have the same empty bins)
2051/// \param[out] res normalized residuals for further analysis
2052
2053Double_t TH1::Chi2TestX(const TH1* h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option, Double_t *res) const
2054{
2055
2056 Int_t i_start, i_end;
2057 Int_t j_start, j_end;
2058 Int_t k_start, k_end;
2059
2060 Double_t sum1 = 0.0, sumw1 = 0.0;
2061 Double_t sum2 = 0.0, sumw2 = 0.0;
2062
2063 chi2 = 0.0;
2064 ndf = 0;
2065
2066 TString opt = option;
2067 opt.ToUpper();
2068
2069 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
2070
2071 const TAxis *xaxis1 = GetXaxis();
2072 const TAxis *xaxis2 = h2->GetXaxis();
2073 const TAxis *yaxis1 = GetYaxis();
2074 const TAxis *yaxis2 = h2->GetYaxis();
2075 const TAxis *zaxis1 = GetZaxis();
2076 const TAxis *zaxis2 = h2->GetZaxis();
2077
2078 Int_t nbinx1 = xaxis1->GetNbins();
2079 Int_t nbinx2 = xaxis2->GetNbins();
2080 Int_t nbiny1 = yaxis1->GetNbins();
2081 Int_t nbiny2 = yaxis2->GetNbins();
2082 Int_t nbinz1 = zaxis1->GetNbins();
2083 Int_t nbinz2 = zaxis2->GetNbins();
2084
2085 //check dimensions
2086 if (this->GetDimension() != h2->GetDimension() ){
2087 Error("Chi2TestX","Histograms have different dimensions.");
2088 return 0.0;
2089 }
2090
2091 //check number of channels
2092 if (nbinx1 != nbinx2) {
2093 Error("Chi2TestX","different number of x channels");
2094 }
2095 if (nbiny1 != nbiny2) {
2096 Error("Chi2TestX","different number of y channels");
2097 }
2098 if (nbinz1 != nbinz2) {
2099 Error("Chi2TestX","different number of z channels");
2100 }
2101
2102 //check for ranges
2103 i_start = j_start = k_start = 1;
2104 i_end = nbinx1;
2105 j_end = nbiny1;
2106 k_end = nbinz1;
2107
2108 if (xaxis1->TestBit(TAxis::kAxisRange)) {
2109 i_start = xaxis1->GetFirst();
2110 i_end = xaxis1->GetLast();
2111 }
2112 if (yaxis1->TestBit(TAxis::kAxisRange)) {
2113 j_start = yaxis1->GetFirst();
2114 j_end = yaxis1->GetLast();
2115 }
2116 if (zaxis1->TestBit(TAxis::kAxisRange)) {
2117 k_start = zaxis1->GetFirst();
2118 k_end = zaxis1->GetLast();
2119 }
2120
2121
2122 if (opt.Contains("OF")) {
2123 if (GetDimension() == 3) k_end = ++nbinz1;
2124 if (GetDimension() >= 2) j_end = ++nbiny1;
2125 if (GetDimension() >= 1) i_end = ++nbinx1;
2126 }
2127
2128 if (opt.Contains("UF")) {
2129 if (GetDimension() == 3) k_start = 0;
2130 if (GetDimension() >= 2) j_start = 0;
2131 if (GetDimension() >= 1) i_start = 0;
2132 }
2133
2134 ndf = (i_end - i_start + 1) * (j_end - j_start + 1) * (k_end - k_start + 1) - 1;
2135
2136 Bool_t comparisonUU = opt.Contains("UU");
2137 Bool_t comparisonUW = opt.Contains("UW");
2138 Bool_t comparisonWW = opt.Contains("WW");
2139 Bool_t scaledHistogram = opt.Contains("NORM");
2140
2141 if (scaledHistogram && !comparisonUU) {
2142 Info("Chi2TestX", "NORM option should be used together with UU option. It is ignored");
2143 }
2144
2145 // look at histo global bin content and effective entries
2146 Stat_t s[kNstat];
2147 GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2148 Double_t sumBinContent1 = s[0];
2149 Double_t effEntries1 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2150
2151 h2->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2152 Double_t sumBinContent2 = s[0];
2153 Double_t effEntries2 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2154
2155 if (!comparisonUU && !comparisonUW && !comparisonWW ) {
2156 // deduce automatically from type of histogram
2157 if (TMath::Abs(sumBinContent1 - effEntries1) < 1) {
2158 if ( TMath::Abs(sumBinContent2 - effEntries2) < 1) comparisonUU = true;
2159 else comparisonUW = true;
2160 }
2161 else comparisonWW = true;
2162 }
2163 // check unweighted histogram
2164 if (comparisonUW) {
2165 if (TMath::Abs(sumBinContent1 - effEntries1) >= 1) {
2166 Warning("Chi2TestX","First histogram is not unweighted and option UW has been requested");
2167 }
2168 }
2169 if ( (!scaledHistogram && comparisonUU) ) {
2170 if ( ( TMath::Abs(sumBinContent1 - effEntries1) >= 1) || (TMath::Abs(sumBinContent2 - effEntries2) >= 1) ) {
2171 Warning("Chi2TestX","Both histograms are not unweighted and option UU has been requested");
2172 }
2173 }
2174
2175
2176 //get number of events in histogram
2177 if (comparisonUU && scaledHistogram) {
2178 for (Int_t i = i_start; i <= i_end; ++i) {
2179 for (Int_t j = j_start; j <= j_end; ++j) {
2180 for (Int_t k = k_start; k <= k_end; ++k) {
2181
2182 Int_t bin = GetBin(i, j, k);
2183
2184 Double_t cnt1 = RetrieveBinContent(bin);
2185 Double_t cnt2 = h2->RetrieveBinContent(bin);
2186 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2187 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2188
2189 if (e1sq > 0.0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2190 else cnt1 = 0.0;
2191
2192 if (e2sq > 0.0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2193 else cnt2 = 0.0;
2194
2195 // sum contents
2196 sum1 += cnt1;
2197 sum2 += cnt2;
2198 sumw1 += e1sq;
2199 sumw2 += e2sq;
2200 }
2201 }
2202 }
2203 if (sumw1 <= 0.0 || sumw2 <= 0.0) {
2204 Error("Chi2TestX", "Cannot use option NORM when one histogram has all zero errors");
2205 return 0.0;
2206 }
2207
2208 } else {
2209 for (Int_t i = i_start; i <= i_end; ++i) {
2210 for (Int_t j = j_start; j <= j_end; ++j) {
2211 for (Int_t k = k_start; k <= k_end; ++k) {
2212
2213 Int_t bin = GetBin(i, j, k);
2214
2215 sum1 += RetrieveBinContent(bin);
2216 sum2 += h2->RetrieveBinContent(bin);
2217
2218 if ( comparisonWW ) sumw1 += GetBinErrorSqUnchecked(bin);
2219 if ( comparisonUW || comparisonWW ) sumw2 += h2->GetBinErrorSqUnchecked(bin);
2220 }
2221 }
2222 }
2223 }
2224 //checks that the histograms are not empty
2225 if (sum1 == 0.0 || sum2 == 0.0) {
2226 Error("Chi2TestX","one histogram is empty");
2227 return 0.0;
2228 }
2229
2230 if ( comparisonWW && ( sumw1 <= 0.0 && sumw2 <= 0.0 ) ){
2231 Error("Chi2TestX","Hist1 and Hist2 have both all zero errors\n");
2232 return 0.0;
2233 }
2234
2235 //THE TEST
2236 Int_t m = 0, n = 0;
2237
2238 //Experiment - experiment comparison
2239 if (comparisonUU) {
2240 Double_t sum = sum1 + sum2;
2241 for (Int_t i = i_start; i <= i_end; ++i) {
2242 for (Int_t j = j_start; j <= j_end; ++j) {
2243 for (Int_t k = k_start; k <= k_end; ++k) {
2244
2245 Int_t bin = GetBin(i, j, k);
2246
2247 Double_t cnt1 = RetrieveBinContent(bin);
2248 Double_t cnt2 = h2->RetrieveBinContent(bin);
2249
2250 if (scaledHistogram) {
2251 // scale bin value to effective bin entries
2252 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2253 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2254
2255 if (e1sq > 0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2256 else cnt1 = 0;
2257
2258 if (e2sq > 0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2259 else cnt2 = 0;
2260 }
2261
2262 if (Int_t(cnt1) == 0 && Int_t(cnt2) == 0) --ndf; // no data means one degree of freedom less
2263 else {
2264
2265 Double_t cntsum = cnt1 + cnt2;
2266 Double_t nexp1 = cntsum * sum1 / sum;
2267 //Double_t nexp2 = binsum*sum2/sum;
2268
2269 if (res) res[i - i_start] = (cnt1 - nexp1) / TMath::Sqrt(nexp1);
2270
2271 if (cnt1 < 1) ++m;
2272 if (cnt2 < 1) ++n;
2273
2274 //Habermann correction for residuals
2275 Double_t correc = (1. - sum1 / sum) * (1. - cntsum / sum);
2276 if (res) res[i - i_start] /= TMath::Sqrt(correc);
2277
2278 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2279 chi2 += delta * delta / cntsum;
2280 }
2281 }
2282 }
2283 }
2284 chi2 /= sum1 * sum2;
2285
2286 // flag error only when of the two histogram is zero
2287 if (m) {
2288 igood += 1;
2289 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2290 }
2291 if (n) {
2292 igood += 2;
2293 Info("Chi2TestX","There is a bin in h2 with less than 1 event.\n");
2294 }
2295
2296 Double_t prob = TMath::Prob(chi2,ndf);
2297 return prob;
2298
2299 }
2300
2301 // unweighted - weighted comparison
2302 // case of error = 0 and content not zero is treated without problems by excluding second chi2 sum
2303 // and can be considered as a data-theory comparison
2304 if ( comparisonUW ) {
2305 for (Int_t i = i_start; i <= i_end; ++i) {
2306 for (Int_t j = j_start; j <= j_end; ++j) {
2307 for (Int_t k = k_start; k <= k_end; ++k) {
2308
2309 Int_t bin = GetBin(i, j, k);
2310
2311 Double_t cnt1 = RetrieveBinContent(bin);
2312 Double_t cnt2 = h2->RetrieveBinContent(bin);
2313 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2314
2315 // case both histogram have zero bin contents
2316 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2317 --ndf; //no data means one degree of freedom less
2318 continue;
2319 }
2320
2321 // case weighted histogram has zero bin content and error
2322 if (cnt2 * cnt2 == 0 && e2sq == 0) {
2323 if (sumw2 > 0) {
2324 // use as approximated error as 1 scaled by a scaling ratio
2325 // estimated from the total sum weight and sum weight squared
2326 e2sq = sumw2 / sum2;
2327 }
2328 else {
2329 // return error because infinite discrepancy here:
2330 // bin1 != 0 and bin2 =0 in a histogram with all errors zero
2331 Error("Chi2TestX","Hist2 has in bin (%d,%d,%d) zero content and zero errors\n", i, j, k);
2332 chi2 = 0; return 0;
2333 }
2334 }
2335
2336 if (cnt1 < 1) m++;
2337 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2338
2339 Double_t var1 = sum2 * cnt2 - sum1 * e2sq;
2340 Double_t var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2341
2342 // if cnt1 is zero and cnt2 = 1 and sum1 = sum2 var1 = 0 && var2 == 0
2343 // approximate by incrementing cnt1
2344 // LM (this need to be fixed for numerical errors)
2345 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2346 sum1++;
2347 cnt1++;
2348 var1 = sum2 * cnt2 - sum1 * e2sq;
2349 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2350 }
2351 var2 = TMath::Sqrt(var2);
2352
2353 while (var1 + var2 == 0) {
2354 sum1++;
2355 cnt1++;
2356 var1 = sum2 * cnt2 - sum1 * e2sq;
2357 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2358 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2359 sum1++;
2360 cnt1++;
2361 var1 = sum2 * cnt2 - sum1 * e2sq;
2362 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2363 }
2364 var2 = TMath::Sqrt(var2);
2365 }
2366
2367 Double_t probb = (var1 + var2) / (2. * sum2 * sum2);
2368
2369 Double_t nexp1 = probb * sum1;
2370 Double_t nexp2 = probb * sum2;
2371
2372 Double_t delta1 = cnt1 - nexp1;
2373 Double_t delta2 = cnt2 - nexp2;
2374
2375 chi2 += delta1 * delta1 / nexp1;
2376
2377 if (e2sq > 0) {
2378 chi2 += delta2 * delta2 / e2sq;
2379 }
2380
2381 if (res) {
2382 if (e2sq > 0) {
2383 Double_t temp1 = sum2 * e2sq / var2;
2384 Double_t temp2 = 1.0 + (sum1 * e2sq - sum2 * cnt2) / var2;
2385 temp2 = temp1 * temp1 * sum1 * probb * (1.0 - probb) + temp2 * temp2 * e2sq / 4.0;
2386 // invert sign here
2387 res[i - i_start] = - delta2 / TMath::Sqrt(temp2);
2388 }
2389 else
2390 res[i - i_start] = delta1 / TMath::Sqrt(nexp1);
2391 }
2392 }
2393 }
2394 }
2395
2396 if (m) {
2397 igood += 1;
2398 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2399 }
2400 if (n) {
2401 igood += 2;
2402 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2403 }
2404
2405 Double_t prob = TMath::Prob(chi2, ndf);
2406
2407 return prob;
2408 }
2409
2410 // weighted - weighted comparison
2411 if (comparisonWW) {
2412 for (Int_t i = i_start; i <= i_end; ++i) {
2413 for (Int_t j = j_start; j <= j_end; ++j) {
2414 for (Int_t k = k_start; k <= k_end; ++k) {
2415
2416 Int_t bin = GetBin(i, j, k);
2417 Double_t cnt1 = RetrieveBinContent(bin);
2418 Double_t cnt2 = h2->RetrieveBinContent(bin);
2419 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2420 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2421
2422 // case both histogram have zero bin contents
2423 // (use square of content to avoid numerical errors)
2424 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2425 --ndf; //no data means one degree of freedom less
2426 continue;
2427 }
2428
2429 if (e1sq == 0 && e2sq == 0) {
2430 // cannot treat case of booth histogram have zero zero errors
2431 Error("Chi2TestX","h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
2432 chi2 = 0; return 0;
2433 }
2434
2435 Double_t sigma = sum1 * sum1 * e2sq + sum2 * sum2 * e1sq;
2436 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2437 chi2 += delta * delta / sigma;
2438
2439 if (res) {
2440 Double_t temp = cnt1 * sum1 * e2sq + cnt2 * sum2 * e1sq;
2441 Double_t probb = temp / sigma;
2442 Double_t z = 0;
2443 if (e1sq > e2sq) {
2444 Double_t d1 = cnt1 - sum1 * probb;
2445 Double_t s1 = e1sq * ( 1. - e2sq * sum1 * sum1 / sigma );
2446 z = d1 / TMath::Sqrt(s1);
2447 }
2448 else {
2449 Double_t d2 = cnt2 - sum2 * probb;
2450 Double_t s2 = e2sq * ( 1. - e1sq * sum2 * sum2 / sigma );
2451 z = -d2 / TMath::Sqrt(s2);
2452 }
2453 res[i - i_start] = z;
2454 }
2455
2456 if (e1sq > 0 && cnt1 * cnt1 / e1sq < 10) m++;
2457 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2458 }
2459 }
2460 }
2461 if (m) {
2462 igood += 1;
2463 Info("Chi2TestX","There is a bin in h1 with less than 10 effective events.\n");
2464 }
2465 if (n) {
2466 igood += 2;
2467 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2468 }
2469 Double_t prob = TMath::Prob(chi2, ndf);
2470 return prob;
2471 }
2472 return 0;
2473}
2474////////////////////////////////////////////////////////////////////////////////
2475/// Compute and return the chisquare of this histogram with respect to a function
2476/// The chisquare is computed by weighting each histogram point by the bin error
2477/// By default the full range of the histogram is used.
2478/// Use option "R" for restricting the chisquare calculation to the given range of the function
2479/// Use option "L" for using the chisquare based on the poisson likelihood (Baker-Cousins Chisquare)
2480/// Use option "P" for using the Pearson chisquare based on the expected bin errors
2481
2483{
2484 if (!func) {
2485 Error("Chisquare","Function pointer is Null - return -1");
2486 return -1;
2487 }
2488
2489 TString opt(option); opt.ToUpper();
2490 bool useRange = opt.Contains("R");
2491 ROOT::Fit::EChisquareType type = ROOT::Fit::EChisquareType::kNeyman; // default chi2 with observed error
2494
2495 return ROOT::Fit::Chisquare(*this, *func, useRange, type);
2496}
2497
2498////////////////////////////////////////////////////////////////////////////////
2499/// Remove all the content from the underflow and overflow bins, without changing the number of entries
2500/// After calling this method, every undeflow and overflow bins will have content 0.0
2501/// The Sumw2 is also cleared, since there is no more content in the bins
2502
2504{
2505 for (Int_t bin = 0; bin < fNcells; ++bin)
2506 if (IsBinUnderflow(bin) || IsBinOverflow(bin)) {
2507 UpdateBinContent(bin, 0.0);
2508 if (fSumw2.fN) fSumw2.fArray[bin] = 0.0;
2509 }
2510}
2511
2512////////////////////////////////////////////////////////////////////////////////
2513/// Compute integral (cumulative sum of bins)
2514/// The result stored in fIntegral is used by the GetRandom functions.
2515/// This function is automatically called by GetRandom when the fIntegral
2516/// array does not exist or when the number of entries in the histogram
2517/// has changed since the previous call to GetRandom.
2518/// The resulting integral is normalized to 1
2519/// If the routine is called with the onlyPositive flag set an error will
2520/// be produced in case of negative bin content and a NaN value returned
2521
2523{
2524 if (fBuffer) BufferEmpty();
2525
2526 // delete previously computed integral (if any)
2527 if (fIntegral) delete [] fIntegral;
2528
2529 // - Allocate space to store the integral and compute integral
2530 Int_t nbinsx = GetNbinsX();
2531 Int_t nbinsy = GetNbinsY();
2532 Int_t nbinsz = GetNbinsZ();
2533 Int_t nbins = nbinsx * nbinsy * nbinsz;
2534
2535 fIntegral = new Double_t[nbins + 2];
2536 Int_t ibin = 0; fIntegral[ibin] = 0;
2537
2538 for (Int_t binz=1; binz <= nbinsz; ++binz) {
2539 for (Int_t biny=1; biny <= nbinsy; ++biny) {
2540 for (Int_t binx=1; binx <= nbinsx; ++binx) {
2541 ++ibin;
2542 Double_t y = RetrieveBinContent(GetBin(binx, biny, binz));
2543 if (onlyPositive && y < 0) {
2544 Error("ComputeIntegral","Bin content is negative - return a NaN value");
2545 fIntegral[nbins] = TMath::QuietNaN();
2546 break;
2547 }
2548 fIntegral[ibin] = fIntegral[ibin - 1] + y;
2549 }
2550 }
2551 }
2552
2553 // - Normalize integral to 1
2554 if (fIntegral[nbins] == 0 ) {
2555 Error("ComputeIntegral", "Integral = zero"); return 0;
2556 }
2557 for (Int_t bin=1; bin <= nbins; ++bin) fIntegral[bin] /= fIntegral[nbins];
2558 fIntegral[nbins+1] = fEntries;
2559 return fIntegral[nbins];
2560}
2561
2562////////////////////////////////////////////////////////////////////////////////
2563/// Return a pointer to the array of bins integral.
2564/// if the pointer fIntegral is null, TH1::ComputeIntegral is called
2565/// The array dimension is the number of bins in the histograms
2566/// including underflow and overflow (fNCells)
2567/// the last value integral[fNCells] is set to the number of entries of
2568/// the histogram
2569
2571{
2572 if (!fIntegral) ComputeIntegral();
2573 return fIntegral;
2574}
2575
2576////////////////////////////////////////////////////////////////////////////////
2577/// Return a pointer to a histogram containing the cumulative content.
2578/// The cumulative can be computed both in the forward (default) or backward
2579/// direction; the name of the new histogram is constructed from
2580/// the name of this histogram with the suffix "suffix" appended provided
2581/// by the user. If not provided a default suffix="_cumulative" is used.
2582///
2583/// The cumulative distribution is formed by filling each bin of the
2584/// resulting histogram with the sum of that bin and all previous
2585/// (forward == kTRUE) or following (forward = kFALSE) bins.
2586///
2587/// Note: while cumulative distributions make sense in one dimension, you
2588/// may not be getting what you expect in more than 1D because the concept
2589/// of a cumulative distribution is much trickier to define; make sure you
2590/// understand the order of summation before you use this method with
2591/// histograms of dimension >= 2.
2592///
2593/// Note 2: By default the cumulative is computed from bin 1 to Nbins
2594/// If an axis range is set, values between the minimum and maximum of the range
2595/// are set.
2596/// Setting an axis range can also be used for including underflow and overflow in
2597/// the cumulative (e.g. by setting h->GetXaxis()->SetRange(0, h->GetNbinsX()+1); )
2599
2600TH1 *TH1::GetCumulative(Bool_t forward, const char* suffix) const
2601{
2602 const Int_t firstX = fXaxis.GetFirst();
2603 const Int_t lastX = fXaxis.GetLast();
2604 const Int_t firstY = (fDimension > 1) ? fYaxis.GetFirst() : 1;
2605 const Int_t lastY = (fDimension > 1) ? fYaxis.GetLast() : 1;
2606 const Int_t firstZ = (fDimension > 1) ? fZaxis.GetFirst() : 1;
2607 const Int_t lastZ = (fDimension > 1) ? fZaxis.GetLast() : 1;
2608
2609 TH1* hintegrated = (TH1*) Clone(fName + suffix);
2610 hintegrated->Reset();
2611 Double_t sum = 0.;
2612 Double_t esum = 0;
2613 if (forward) { // Forward computation
2614 for (Int_t binz = firstZ; binz <= lastZ; ++binz) {
2615 for (Int_t biny = firstY; biny <= lastY; ++biny) {
2616 for (Int_t binx = firstX; binx <= lastX; ++binx) {
2617 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2618 sum += RetrieveBinContent(bin);
2619 hintegrated->AddBinContent(bin, sum);
2620 if (fSumw2.fN) {
2621 esum += GetBinErrorSqUnchecked(bin);
2622 hintegrated->fSumw2.fArray[bin] = esum;
2623 }
2624 }
2625 }
2626 }
2627 } else { // Backward computation
2628 for (Int_t binz = lastZ; binz >= firstZ; --binz) {
2629 for (Int_t biny = lastY; biny >= firstY; --biny) {
2630 for (Int_t binx = lastX; binx >= firstX; --binx) {
2631 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2632 sum += RetrieveBinContent(bin);
2633 hintegrated->AddBinContent(bin, sum);
2634 if (fSumw2.fN) {
2635 esum += GetBinErrorSqUnchecked(bin);
2636 hintegrated->fSumw2.fArray[bin] = esum;
2637 }
2638 }
2639 }
2640 }
2641 }
2642 return hintegrated;
2643}
2644
2645////////////////////////////////////////////////////////////////////////////////
2646/// Copy this histogram structure to newth1.
2647///
2648/// Note that this function does not copy the list of associated functions.
2649/// Use TObject::Clone to make a full copy of a histogram.
2650///
2651/// Note also that the histogram it will be created in gDirectory (if AddDirectoryStatus()=true)
2652/// or will not be added to any directory if AddDirectoryStatus()=false
2653/// independently of the current directory stored in the original histogram
2654
2655void TH1::Copy(TObject &obj) const
2656{
2657 if (((TH1&)obj).fDirectory) {
2658 // We are likely to change the hash value of this object
2659 // with TNamed::Copy, to keep things correct, we need to
2660 // clean up its existing entries.
2661 ((TH1&)obj).fDirectory->Remove(&obj);
2662 ((TH1&)obj).fDirectory = nullptr;
2663 }
2664 TNamed::Copy(obj);
2665 ((TH1&)obj).fDimension = fDimension;
2666 ((TH1&)obj).fNormFactor= fNormFactor;
2667 ((TH1&)obj).fNcells = fNcells;
2668 ((TH1&)obj).fBarOffset = fBarOffset;
2669 ((TH1&)obj).fBarWidth = fBarWidth;
2670 ((TH1&)obj).fOption = fOption;
2671 ((TH1&)obj).fBinStatErrOpt = fBinStatErrOpt;
2672 ((TH1&)obj).fBufferSize= fBufferSize;
2673 // copy the Buffer
2674 // delete first a previously existing buffer
2675 if (((TH1&)obj).fBuffer != nullptr) {
2676 delete [] ((TH1&)obj).fBuffer;
2677 ((TH1&)obj).fBuffer = nullptr;
2678 }
2679 if (fBuffer) {
2680 Double_t *buf = new Double_t[fBufferSize];
2681 for (Int_t i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
2682 // obj.fBuffer has been deleted before
2683 ((TH1&)obj).fBuffer = buf;
2684 }
2685
2686 // copy bin contents (this should be done by the derived classes, since TH1 does not store the bin content)
2687 // Do this in case derived from TArray
2688 TArray* a = dynamic_cast<TArray*>(&obj);
2689 if (a) {
2690 a->Set(fNcells);
2691 for (Int_t i = 0; i < fNcells; i++)
2693 }
2694
2695 ((TH1&)obj).fEntries = fEntries;
2696
2697 // which will call BufferEmpty(0) and set fBuffer[0] to a Maybe one should call
2698 // assignment operator on the TArrayD
2699
2700 ((TH1&)obj).fTsumw = fTsumw;
2701 ((TH1&)obj).fTsumw2 = fTsumw2;
2702 ((TH1&)obj).fTsumwx = fTsumwx;
2703 ((TH1&)obj).fTsumwx2 = fTsumwx2;
2704 ((TH1&)obj).fMaximum = fMaximum;
2705 ((TH1&)obj).fMinimum = fMinimum;
2706
2707 TAttLine::Copy(((TH1&)obj));
2708 TAttFill::Copy(((TH1&)obj));
2709 TAttMarker::Copy(((TH1&)obj));
2710 fXaxis.Copy(((TH1&)obj).fXaxis);
2711 fYaxis.Copy(((TH1&)obj).fYaxis);
2712 fZaxis.Copy(((TH1&)obj).fZaxis);
2713 ((TH1&)obj).fXaxis.SetParent(&obj);
2714 ((TH1&)obj).fYaxis.SetParent(&obj);
2715 ((TH1&)obj).fZaxis.SetParent(&obj);
2716 fContour.Copy(((TH1&)obj).fContour);
2717 fSumw2.Copy(((TH1&)obj).fSumw2);
2718 // fFunctions->Copy(((TH1&)obj).fFunctions);
2719 // when copying an histogram if the AddDirectoryStatus() is true it
2720 // will be added to gDirectory independently of the fDirectory stored.
2721 // and if the AddDirectoryStatus() is false it will not be added to
2722 // any directory (fDirectory = nullptr)
2723 if (fgAddDirectory && gDirectory) {
2724 gDirectory->Append(&obj);
2725 ((TH1&)obj).fFunctions->UseRWLock();
2726 ((TH1&)obj).fDirectory = gDirectory;
2727 } else
2728 ((TH1&)obj).fDirectory = nullptr;
2729
2730}
2731
2732////////////////////////////////////////////////////////////////////////////////
2733/// Make a complete copy of the underlying object. If 'newname' is set,
2734/// the copy's name will be set to that name.
2735
2736TObject* TH1::Clone(const char* newname) const
2737{
2738 TH1* obj = (TH1*)IsA()->GetNew()(nullptr);
2739 Copy(*obj);
2740
2741 // Now handle the parts that Copy doesn't do
2742 if(fFunctions) {
2743 // The Copy above might have published 'obj' to the ListOfCleanups.
2744 // Clone can call RecursiveRemove, for example via TCheckHashRecursiveRemoveConsistency
2745 // when dictionary information is initialized, so we need to
2746 // keep obj->fFunction valid during its execution and
2747 // protect the update with the write lock.
2748
2749 // Reset stats parent - else cloning the stats will clone this histogram, too.
2750 auto oldstats = dynamic_cast<TVirtualPaveStats*>(fFunctions->FindObject("stats"));
2751 TObject *oldparent = nullptr;
2752 if (oldstats) {
2753 oldparent = oldstats->GetParent();
2754 oldstats->SetParent(nullptr);
2755 }
2756
2757 auto newlist = (TList*)fFunctions->Clone();
2758
2759 if (oldstats)
2760 oldstats->SetParent(oldparent);
2761 auto newstats = dynamic_cast<TVirtualPaveStats*>(obj->fFunctions->FindObject("stats"));
2762 if (newstats)
2763 newstats->SetParent(obj);
2764
2765 auto oldlist = obj->fFunctions;
2766 {
2768 obj->fFunctions = newlist;
2769 }
2770 delete oldlist;
2771 }
2772 if(newname && strlen(newname) ) {
2773 obj->SetName(newname);
2774 }
2775 return obj;
2776}
2777
2778////////////////////////////////////////////////////////////////////////////////
2779/// Perform the automatic addition of the histogram to the given directory
2780///
2781/// Note this function is called in place when the semantic requires
2782/// this object to be added to a directory (I.e. when being read from
2783/// a TKey or being Cloned)
2784
2786{
2787 Bool_t addStatus = TH1::AddDirectoryStatus();
2788 if (addStatus) {
2789 SetDirectory(dir);
2790 if (dir) {
2792 }
2793 }
2794}
2795
2796////////////////////////////////////////////////////////////////////////////////
2797/// Compute distance from point px,py to a line.
2798///
2799/// Compute the closest distance of approach from point px,py to elements
2800/// of a histogram.
2801/// The distance is computed in pixels units.
2802///
2803/// #### Algorithm:
2804/// Currently, this simple model computes the distance from the mouse
2805/// to the histogram contour only.
2806
2808{
2809 if (!fPainter) return 9999;
2810 return fPainter->DistancetoPrimitive(px,py);
2811}
2812
2813////////////////////////////////////////////////////////////////////////////////
2814/// Performs the operation: `this = this/(c1*f1)`
2815/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2816///
2817/// Only bins inside the function range are recomputed.
2818/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2819/// you should call Sumw2 before making this operation.
2820/// This is particularly important if you fit the histogram after TH1::Divide
2821///
2822/// The function return kFALSE if the divide operation failed
2823
2825{
2826 if (!f1) {
2827 Error("Divide","Attempt to divide by a non-existing function");
2828 return kFALSE;
2829 }
2830
2831 // delete buffer if it is there since it will become invalid
2832 if (fBuffer) BufferEmpty(1);
2833
2834 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of
2835 Int_t ny = GetNbinsY() + 2;
2836 Int_t nz = GetNbinsZ() + 2;
2837 if (fDimension < 2) ny = 1;
2838 if (fDimension < 3) nz = 1;
2839
2840
2841 SetMinimum();
2842 SetMaximum();
2843
2844 // - Loop on bins (including underflows/overflows)
2845 Int_t bin, binx, biny, binz;
2846 Double_t cu, w;
2847 Double_t xx[3];
2848 Double_t *params = nullptr;
2849 f1->InitArgs(xx,params);
2850 for (binz = 0; binz < nz; ++binz) {
2851 xx[2] = fZaxis.GetBinCenter(binz);
2852 for (biny = 0; biny < ny; ++biny) {
2853 xx[1] = fYaxis.GetBinCenter(biny);
2854 for (binx = 0; binx < nx; ++binx) {
2855 xx[0] = fXaxis.GetBinCenter(binx);
2856 if (!f1->IsInside(xx)) continue;
2858 bin = binx + nx * (biny + ny * binz);
2859 cu = c1 * f1->EvalPar(xx);
2860 if (TF1::RejectedPoint()) continue;
2861 if (cu) w = RetrieveBinContent(bin) / cu;
2862 else w = 0;
2863 UpdateBinContent(bin, w);
2864 if (fSumw2.fN) {
2865 if (cu != 0) fSumw2.fArray[bin] = GetBinErrorSqUnchecked(bin) / (cu * cu);
2866 else fSumw2.fArray[bin] = 0;
2867 }
2868 }
2869 }
2870 }
2871 ResetStats();
2872 return kTRUE;
2873}
2874
2875////////////////////////////////////////////////////////////////////////////////
2876/// Divide this histogram by h1.
2877///
2878/// `this = this/h1`
2879/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2880/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
2881/// if not already set.
2882/// The resulting errors are calculated assuming uncorrelated histograms.
2883/// See the other TH1::Divide that gives the possibility to optionally
2884/// compute binomial errors.
2885///
2886/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2887/// you should call Sumw2 before making this operation.
2888/// This is particularly important if you fit the histogram after TH1::Scale
2889///
2890/// The function return kFALSE if the divide operation failed
2891
2892Bool_t TH1::Divide(const TH1 *h1)
2893{
2894 if (!h1) {
2895 Error("Divide", "Input histogram passed does not exist (NULL).");
2896 return kFALSE;
2897 }
2898
2899 // delete buffer if it is there since it will become invalid
2900 if (fBuffer) BufferEmpty(1);
2901
2902 try {
2903 CheckConsistency(this,h1);
2904 } catch(DifferentNumberOfBins&) {
2905 Error("Divide","Cannot divide histograms with different number of bins");
2906 return kFALSE;
2907 } catch(DifferentAxisLimits&) {
2908 Warning("Divide","Dividing histograms with different axis limits");
2909 } catch(DifferentBinLimits&) {
2910 Warning("Divide","Dividing histograms with different bin limits");
2911 } catch(DifferentLabels&) {
2912 Warning("Divide","Dividing histograms with different labels");
2913 }
2914
2915 // Create Sumw2 if h1 has Sumw2 set
2916 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
2917
2918 // - Loop on bins (including underflows/overflows)
2919 for (Int_t i = 0; i < fNcells; ++i) {
2922 if (c1) UpdateBinContent(i, c0 / c1);
2923 else UpdateBinContent(i, 0);
2924
2925 if(fSumw2.fN) {
2926 if (c1 == 0) { fSumw2.fArray[i] = 0; continue; }
2927 Double_t c1sq = c1 * c1;
2928 fSumw2.fArray[i] = (GetBinErrorSqUnchecked(i) * c1sq + h1->GetBinErrorSqUnchecked(i) * c0 * c0) / (c1sq * c1sq);
2929 }
2930 }
2931 ResetStats();
2932 return kTRUE;
2933}
2934
2935////////////////////////////////////////////////////////////////////////////////
2936/// Replace contents of this histogram by the division of h1 by h2.
2937///
2938/// `this = c1*h1/(c2*h2)`
2939///
2940/// If errors are defined (see TH1::Sumw2), errors are also recalculated
2941/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
2942/// if not already set.
2943/// The resulting errors are calculated assuming uncorrelated histograms.
2944/// However, if option ="B" is specified, Binomial errors are computed.
2945/// In this case c1 and c2 do not make real sense and they are ignored.
2946///
2947/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2948/// you should call Sumw2 before making this operation.
2949/// This is particularly important if you fit the histogram after TH1::Divide
2950///
2951/// Please note also that in the binomial case errors are calculated using standard
2952/// binomial statistics, which means when b1 = b2, the error is zero.
2953/// If you prefer to have efficiency errors not going to zero when the efficiency is 1, you must
2954/// use the function TGraphAsymmErrors::BayesDivide, which will return an asymmetric and non-zero lower
2955/// error for the case b1=b2.
2956///
2957/// The function return kFALSE if the divide operation failed
2958
2960{
2961
2962 TString opt = option;
2963 opt.ToLower();
2964 Bool_t binomial = kFALSE;
2965 if (opt.Contains("b")) binomial = kTRUE;
2966 if (!h1 || !h2) {
2967 Error("Divide", "At least one of the input histograms passed does not exist (NULL).");
2968 return kFALSE;
2969 }
2970
2971 // delete buffer if it is there since it will become invalid
2972 if (fBuffer) BufferEmpty(1);
2973
2974 try {
2975 CheckConsistency(h1,h2);
2976 CheckConsistency(this,h1);
2977 } catch(DifferentNumberOfBins&) {
2978 Error("Divide","Cannot divide histograms with different number of bins");
2979 return kFALSE;
2980 } catch(DifferentAxisLimits&) {
2981 Warning("Divide","Dividing histograms with different axis limits");
2982 } catch(DifferentBinLimits&) {
2983 Warning("Divide","Dividing histograms with different bin limits");
2984 } catch(DifferentLabels&) {
2985 Warning("Divide","Dividing histograms with different labels");
2986 }
2987
2988
2989 if (!c2) {
2990 Error("Divide","Coefficient of dividing histogram cannot be zero");
2991 return kFALSE;
2992 }
2993
2994 // Create Sumw2 if h1 or h2 have Sumw2 set, or if binomial errors are explicitly requested
2995 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0 || binomial)) Sumw2();
2996
2997 SetMinimum();
2998 SetMaximum();
2999
3000 // - Loop on bins (including underflows/overflows)
3001 for (Int_t i = 0; i < fNcells; ++i) {
3003 Double_t b2 = h2->RetrieveBinContent(i);
3004 if (b2) UpdateBinContent(i, c1 * b1 / (c2 * b2));
3005 else UpdateBinContent(i, 0);
3006
3007 if (fSumw2.fN) {
3008 if (b2 == 0) { fSumw2.fArray[i] = 0; continue; }
3009 Double_t b1sq = b1 * b1; Double_t b2sq = b2 * b2;
3010 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
3012 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
3013 if (binomial) {
3014 if (b1 != b2) {
3015 // in the case of binomial statistics c1 and c2 must be 1 otherwise it does not make sense
3016 // c1 and c2 are ignored
3017 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));//this is the formula in Hbook/Hoper1
3018 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2); // old formula from G. Flucke
3019 // formula which works also for weighted histogram (see http://root-forum.cern.ch/viewtopic.php?t=3753 )
3020 fSumw2.fArray[i] = TMath::Abs( ( (1. - 2.* b1 / b2) * e1sq + b1sq * e2sq / b2sq ) / b2sq );
3021 } else {
3022 //in case b1=b2 error is zero
3023 //use TGraphAsymmErrors::BayesDivide for getting the asymmetric error not equal to zero
3024 fSumw2.fArray[i] = 0;
3025 }
3026 } else {
3027 fSumw2.fArray[i] = c1sq * c2sq * (e1sq * b2sq + e2sq * b1sq) / (c2sq * c2sq * b2sq * b2sq);
3028 }
3029 }
3030 }
3031 ResetStats();
3032 if (binomial)
3033 // in case of binomial division use denominator for number of entries
3034 SetEntries ( h2->GetEntries() );
3035
3036 return kTRUE;
3037}
3038
3039////////////////////////////////////////////////////////////////////////////////
3040/// Draw this histogram with options.
3041///
3042/// Histograms are drawn via the THistPainter class. Each histogram has
3043/// a pointer to its own painter (to be usable in a multithreaded program).
3044/// The same histogram can be drawn with different options in different pads.
3045/// When a histogram drawn in a pad is deleted, the histogram is
3046/// automatically removed from the pad or pads where it was drawn.
3047/// If a histogram is drawn in a pad, then filled again, the new status
3048/// of the histogram will be automatically shown in the pad next time
3049/// the pad is updated. One does not need to redraw the histogram.
3050/// To draw the current version of a histogram in a pad, one can use
3051/// `h->DrawCopy();`
3052/// This makes a clone of the histogram. Once the clone is drawn, the original
3053/// histogram may be modified or deleted without affecting the aspect of the
3054/// clone.
3055/// By default, TH1::Draw clears the current pad.
3056///
3057/// One can use TH1::SetMaximum and TH1::SetMinimum to force a particular
3058/// value for the maximum or the minimum scale on the plot.
3059///
3060/// TH1::UseCurrentStyle can be used to change all histogram graphics
3061/// attributes to correspond to the current selected style.
3062/// This function must be called for each histogram.
3063/// In case one reads and draws many histograms from a file, one can force
3064/// the histograms to inherit automatically the current graphics style
3065/// by calling before gROOT->ForceStyle();
3066///
3067/// See the THistPainter class for a description of all the drawing options.
3068
3070{
3071 TString opt1 = option; opt1.ToLower();
3072 TString opt2 = option;
3073 Int_t index = opt1.Index("same");
3074
3075 // Check if the string "same" is part of a TCutg name.
3076 if (index>=0) {
3077 Int_t indb = opt1.Index("[");
3078 if (indb>=0) {
3079 Int_t indk = opt1.Index("]");
3080 if (index>indb && index<indk) index = -1;
3081 }
3082 }
3083
3084 // If there is no pad or an empty pad the "same" option is ignored.
3085 if (gPad) {
3086 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
3087 if (index>=0) {
3088 if (gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
3089 gPad->GetY1() == 0 && gPad->GetY2() == 1 &&
3090 gPad->GetListOfPrimitives()->GetSize()==0) opt2.Remove(index,4);
3091 } else {
3092 //the following statement is necessary in case one attempts to draw
3093 //a temporary histogram already in the current pad
3094 if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(this);
3095 gPad->Clear();
3096 }
3097 gPad->IncrementPaletteColor(1, opt1);
3098 } else {
3099 if (index>=0) opt2.Remove(index,4);
3100 }
3101
3102 AppendPad(opt2.Data());
3103}
3104
3105////////////////////////////////////////////////////////////////////////////////
3106/// Copy this histogram and Draw in the current pad.
3107///
3108/// Once the histogram is drawn into the pad, any further modification
3109/// using graphics input will be made on the copy of the histogram,
3110/// and not to the original object.
3111/// By default a postfix "_copy" is added to the histogram name. Pass an empty postfix in case
3112/// you want to draw a histogram with the same name
3113///
3114/// See Draw for the list of options
3115
3116TH1 *TH1::DrawCopy(Option_t *option, const char * name_postfix) const
3117{
3118 TString opt = option;
3119 opt.ToLower();
3120 if (gPad && !opt.Contains("same")) gPad->Clear();
3121 TString newName;
3122 if (name_postfix) newName.Form("%s%s", GetName(), name_postfix);
3123 TH1 *newth1 = (TH1 *)Clone(newName.Data());
3124 newth1->SetDirectory(nullptr);
3125 newth1->SetBit(kCanDelete);
3126 if (gPad) gPad->IncrementPaletteColor(1, opt);
3127
3128 newth1->AppendPad(option);
3129 return newth1;
3130}
3131
3132////////////////////////////////////////////////////////////////////////////////
3133/// Draw a normalized copy of this histogram.
3134///
3135/// A clone of this histogram is normalized to norm and drawn with option.
3136/// A pointer to the normalized histogram is returned.
3137/// The contents of the histogram copy are scaled such that the new
3138/// sum of weights (excluding under and overflow) is equal to norm.
3139/// Note that the returned normalized histogram is not added to the list
3140/// of histograms in the current directory in memory.
3141/// It is the user's responsibility to delete this histogram.
3142/// The kCanDelete bit is set for the returned object. If a pad containing
3143/// this copy is cleared, the histogram will be automatically deleted.
3144///
3145/// See Draw for the list of options
3146
3148{
3150 if (sum == 0) {
3151 Error("DrawNormalized","Sum of weights is null. Cannot normalize histogram: %s",GetName());
3152 return nullptr;
3153 }
3154 Bool_t addStatus = TH1::AddDirectoryStatus();
3156 TH1 *h = (TH1*)Clone();
3158 // in case of drawing with error options - scale correctly the error
3159 TString opt(option); opt.ToUpper();
3160 if (fSumw2.fN == 0) {
3161 h->Sumw2();
3162 // do not use in this case the "Error option " for drawing which is enabled by default since the normalized histogram has now errors
3163 if (opt.IsNull() || opt == "SAME") opt += "HIST";
3164 }
3165 h->Scale(norm/sum);
3166 if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
3167 if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
3168 h->Draw(opt);
3169 TH1::AddDirectory(addStatus);
3170 return h;
3171}
3172
3173////////////////////////////////////////////////////////////////////////////////
3174/// Display a panel with all histogram drawing options.
3175///
3176/// See class TDrawPanelHist for example
3177
3178void TH1::DrawPanel()
3179{
3180 if (!fPainter) {Draw(); if (gPad) gPad->Update();}
3181 if (fPainter) fPainter->DrawPanel();
3182}
3183
3184////////////////////////////////////////////////////////////////////////////////
3185/// Evaluate function f1 at the center of bins of this histogram.
3186///
3187/// - If option "R" is specified, the function is evaluated only
3188/// for the bins included in the function range.
3189/// - If option "A" is specified, the value of the function is added to the
3190/// existing bin contents
3191/// - If option "S" is specified, the value of the function is used to
3192/// generate a value, distributed according to the Poisson
3193/// distribution, with f1 as the mean.
3194
3196{
3197 Double_t x[3];
3198 Int_t range, stat, add;
3199 if (!f1) return;
3200
3201 TString opt = option;
3202 opt.ToLower();
3203 if (opt.Contains("a")) add = 1;
3204 else add = 0;
3205 if (opt.Contains("s")) stat = 1;
3206 else stat = 0;
3207 if (opt.Contains("r")) range = 1;
3208 else range = 0;
3209
3210 // delete buffer if it is there since it will become invalid
3211 if (fBuffer) BufferEmpty(1);
3212
3213 Int_t nbinsx = fXaxis.GetNbins();
3214 Int_t nbinsy = fYaxis.GetNbins();
3215 Int_t nbinsz = fZaxis.GetNbins();
3216 if (!add) Reset();
3217
3218 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
3219 x[2] = fZaxis.GetBinCenter(binz);
3220 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
3221 x[1] = fYaxis.GetBinCenter(biny);
3222 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
3223 Int_t bin = GetBin(binx,biny,binz);
3224 x[0] = fXaxis.GetBinCenter(binx);
3225 if (range && !f1->IsInside(x)) continue;
3226 Double_t fu = f1->Eval(x[0], x[1], x[2]);
3227 if (stat) fu = gRandom->PoissonD(fu);
3228 AddBinContent(bin, fu);
3229 if (fSumw2.fN) fSumw2.fArray[bin] += TMath::Abs(fu);
3230 }
3231 }
3232 }
3233}
3234
3235////////////////////////////////////////////////////////////////////////////////
3236/// Execute action corresponding to one event.
3237///
3238/// This member function is called when a histogram is clicked with the locator
3239///
3240/// If Left button clicked on the bin top value, then the content of this bin
3241/// is modified according to the new position of the mouse when it is released.
3242
3244{
3245 if (fPainter) fPainter->ExecuteEvent(event, px, py);
3246}
3247
3248////////////////////////////////////////////////////////////////////////////////
3249/// This function allows to do discrete Fourier transforms of TH1 and TH2.
3250/// Available transform types and flags are described below.
3251///
3252/// To extract more information about the transform, use the function
3253/// TVirtualFFT::GetCurrentTransform() to get a pointer to the current
3254/// transform object.
3255///
3256/// \param[out] h_output histogram for the output. If a null pointer is passed, a new histogram is created
3257/// and returned, otherwise, the provided histogram is used and should be big enough
3258/// \param[in] option option parameters consists of 3 parts:
3259/// - option on what to return
3260/// - "RE" - returns a histogram of the real part of the output
3261/// - "IM" - returns a histogram of the imaginary part of the output
3262/// - "MAG"- returns a histogram of the magnitude of the output
3263/// - "PH" - returns a histogram of the phase of the output
3264/// - option of transform type
3265/// - "R2C" - real to complex transforms - default
3266/// - "R2HC" - real to halfcomplex (special format of storing output data,
3267/// results the same as for R2C)
3268/// - "DHT" - discrete Hartley transform
3269/// real to real transforms (sine and cosine):
3270/// - "R2R_0", "R2R_1", "R2R_2", "R2R_3" - discrete cosine transforms of types I-IV
3271/// - "R2R_4", "R2R_5", "R2R_6", "R2R_7" - discrete sine transforms of types I-IV
3272/// To specify the type of each dimension of a 2-dimensional real to real
3273/// transform, use options of form "R2R_XX", for example, "R2R_02" for a transform,
3274/// which is of type "R2R_0" in 1st dimension and "R2R_2" in the 2nd.
3275/// - option of transform flag
3276/// - "ES" (from "estimate") - no time in preparing the transform, but probably sub-optimal
3277/// performance
3278/// - "M" (from "measure") - some time spend in finding the optimal way to do the transform
3279/// - "P" (from "patient") - more time spend in finding the optimal way to do the transform
3280/// - "EX" (from "exhaustive") - the most optimal way is found
3281/// This option should be chosen depending on how many transforms of the same size and
3282/// type are going to be done. Planning is only done once, for the first transform of this
3283/// size and type. Default is "ES".
3284///
3285/// Examples of valid options: "Mag R2C M" "Re R2R_11" "Im R2C ES" "PH R2HC EX"
3286
3287TH1* TH1::FFT(TH1* h_output, Option_t *option)
3288{
3289
3290 Int_t ndim[3];
3291 ndim[0] = this->GetNbinsX();
3292 ndim[1] = this->GetNbinsY();
3293 ndim[2] = this->GetNbinsZ();
3294
3295 TVirtualFFT *fft;
3296 TString opt = option;
3297 opt.ToUpper();
3298 if (!opt.Contains("2R")){
3299 if (!opt.Contains("2C") && !opt.Contains("2HC") && !opt.Contains("DHT")) {
3300 //no type specified, "R2C" by default
3301 opt.Append("R2C");
3302 }
3303 fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
3304 }
3305 else {
3306 //find the kind of transform
3307 Int_t ind = opt.Index("R2R", 3);
3308 Int_t *kind = new Int_t[2];
3309 char t;
3310 t = opt[ind+4];
3311 kind[0] = atoi(&t);
3312 if (h_output->GetDimension()>1) {
3313 t = opt[ind+5];
3314 kind[1] = atoi(&t);
3315 }
3316 fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
3317 delete [] kind;
3318 }
3319
3320 if (!fft) return nullptr;
3321 Int_t in=0;
3322 for (Int_t binx = 1; binx<=ndim[0]; binx++) {
3323 for (Int_t biny=1; biny<=ndim[1]; biny++) {
3324 for (Int_t binz=1; binz<=ndim[2]; binz++) {
3325 fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
3326 in++;
3327 }
3328 }
3329 }
3330 fft->Transform();
3331 h_output = TransformHisto(fft, h_output, option);
3332 return h_output;
3333}
3334
3335////////////////////////////////////////////////////////////////////////////////
3336/// Increment bin with abscissa X by 1.
3337///
3338/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3339/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3340///
3341/// If the storage of the sum of squares of weights has been triggered,
3342/// via the function Sumw2, then the sum of the squares of weights is incremented
3343/// by 1 in the bin corresponding to x.
3344///
3345/// The function returns the corresponding bin number which has its content incremented by 1
3346
3348{
3349 if (fBuffer) return BufferFill(x,1);
3350
3351 Int_t bin;
3352 fEntries++;
3353 bin =fXaxis.FindBin(x);
3354 if (bin <0) return -1;
3355 AddBinContent(bin);
3356 if (fSumw2.fN) ++fSumw2.fArray[bin];
3357 if (bin == 0 || bin > fXaxis.GetNbins()) {
3358 if (!GetStatOverflowsBehaviour()) return -1;
3359 }
3360 ++fTsumw;
3361 ++fTsumw2;
3362 fTsumwx += x;
3363 fTsumwx2 += x*x;
3364 return bin;
3365}
3366
3367////////////////////////////////////////////////////////////////////////////////
3368/// Increment bin with abscissa X with a weight w.
3369///
3370/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3371/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3372///
3373/// If the weight is not equal to 1, the storage of the sum of squares of
3374/// weights is automatically triggered and the sum of the squares of weights is incremented
3375/// by \f$ w^2 \f$ in the bin corresponding to x.
3376///
3377/// The function returns the corresponding bin number which has its content incremented by w
3378
3380{
3381
3382 if (fBuffer) return BufferFill(x,w);
3383
3384 Int_t bin;
3385 fEntries++;
3386 bin =fXaxis.FindBin(x);
3387 if (bin <0) return -1;
3388 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW) ) Sumw2(); // must be called before AddBinContent
3389 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3390 AddBinContent(bin, w);
3391 if (bin == 0 || bin > fXaxis.GetNbins()) {
3392 if (!GetStatOverflowsBehaviour()) return -1;
3393 }
3394 Double_t z= w;
3395 fTsumw += z;
3396 fTsumw2 += z*z;
3397 fTsumwx += z*x;
3398 fTsumwx2 += z*x*x;
3399 return bin;
3400}
3401
3402////////////////////////////////////////////////////////////////////////////////
3403/// Increment bin with namex with a weight w
3404///
3405/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3406/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3407///
3408/// If the weight is not equal to 1, the storage of the sum of squares of
3409/// weights is automatically triggered and the sum of the squares of weights is incremented
3410/// by \f$ w^2 \f$ in the bin corresponding to x.
3411///
3412/// The function returns the corresponding bin number which has its content
3413/// incremented by w.
3414
3415Int_t TH1::Fill(const char *namex, Double_t w)
3416{
3417 Int_t bin;
3418 fEntries++;
3419 bin =fXaxis.FindBin(namex);
3420 if (bin <0) return -1;
3421 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3422 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3423 AddBinContent(bin, w);
3424 if (bin == 0 || bin > fXaxis.GetNbins()) return -1;
3425 Double_t z= w;
3426 fTsumw += z;
3427 fTsumw2 += z*z;
3428 // this make sense if the histogram is not expanding (the x axis cannot be extended)
3429 if (!fXaxis.CanExtend() || !fXaxis.IsAlphanumeric()) {
3431 fTsumwx += z*x;
3432 fTsumwx2 += z*x*x;
3433 }
3434 return bin;
3435}
3436
3437////////////////////////////////////////////////////////////////////////////////
3438/// Fill this histogram with an array x and weights w.
3439///
3440/// \param[in] ntimes number of entries in arrays x and w (array size must be ntimes*stride)
3441/// \param[in] x array of values to be histogrammed
3442/// \param[in] w array of weighs
3443/// \param[in] stride step size through arrays x and w
3444///
3445/// If the weight is not equal to 1, the storage of the sum of squares of
3446/// weights is automatically triggered and the sum of the squares of weights is incremented
3447/// by \f$ w^2 \f$ in the bin corresponding to x.
3448/// if w is NULL each entry is assumed a weight=1
3449
3450void TH1::FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3451{
3452 //If a buffer is activated, fill buffer
3453 if (fBuffer) {
3454 ntimes *= stride;
3455 Int_t i = 0;
3456 for (i=0;i<ntimes;i+=stride) {
3457 if (!fBuffer) break; // buffer can be deleted in BufferFill when is empty
3458 if (w) BufferFill(x[i],w[i]);
3459 else BufferFill(x[i], 1.);
3460 }
3461 // fill the remaining entries if the buffer has been deleted
3462 if (i < ntimes && !fBuffer) {
3463 auto weights = w ? &w[i] : nullptr;
3464 DoFillN((ntimes-i)/stride,&x[i],weights,stride);
3465 }
3466 return;
3467 }
3468 // call internal method
3469 DoFillN(ntimes, x, w, stride);
3470}
3471
3472////////////////////////////////////////////////////////////////////////////////
3473/// Internal method to fill histogram content from a vector
3474/// called directly by TH1::BufferEmpty
3475
3476void TH1::DoFillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3477{
3478 Int_t bin,i;
3479
3480 fEntries += ntimes;
3481 Double_t ww = 1;
3482 Int_t nbins = fXaxis.GetNbins();
3483 ntimes *= stride;
3484 for (i=0;i<ntimes;i+=stride) {
3485 bin =fXaxis.FindBin(x[i]);
3486 if (bin <0) continue;
3487 if (w) ww = w[i];
3488 if (!fSumw2.fN && ww != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3489 if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
3490 AddBinContent(bin, ww);
3491 if (bin == 0 || bin > nbins) {
3492 if (!GetStatOverflowsBehaviour()) continue;
3493 }
3494 Double_t z= ww;
3495 fTsumw += z;
3496 fTsumw2 += z*z;
3497 fTsumwx += z*x[i];
3498 fTsumwx2 += z*x[i]*x[i];
3499 }
3500}
3501
3502////////////////////////////////////////////////////////////////////////////////
3503/// Fill histogram following distribution in function fname.
3504///
3505/// @param fname : Function name used for filling the histogram
3506/// @param ntimes : number of times the histogram is filled
3507/// @param rng : (optional) Random number generator used to sample
3508///
3509///
3510/// The distribution contained in the function fname (TF1) is integrated
3511/// over the channel contents for the bin range of this histogram.
3512/// It is normalized to 1.
3513///
3514/// Getting one random number implies:
3515/// - Generating a random number between 0 and 1 (say r1)
3516/// - Look in which bin in the normalized integral r1 corresponds to
3517/// - Fill histogram channel
3518/// ntimes random numbers are generated
3519///
3520/// One can also call TF1::GetRandom to get a random variate from a function.
3521
3522void TH1::FillRandom(const char *fname, Int_t ntimes, TRandom * rng)
3523{
3524 Int_t bin, binx, ibin, loop;
3525 Double_t r1, x;
3526 // - Search for fname in the list of ROOT defined functions
3527 TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
3528 if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
3529
3530 // - Allocate temporary space to store the integral and compute integral
3531
3532 TAxis * xAxis = &fXaxis;
3533
3534 // in case axis of histogram is not defined use the function axis
3535 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
3537 f1->GetRange(xmin,xmax);
3538 Info("FillRandom","Using function axis and range [%g,%g]",xmin, xmax);
3539 xAxis = f1->GetHistogram()->GetXaxis();
3540 }
3541
3542 Int_t first = xAxis->GetFirst();
3543 Int_t last = xAxis->GetLast();
3544 Int_t nbinsx = last-first+1;
3545
3546 Double_t *integral = new Double_t[nbinsx+1];
3547 integral[0] = 0;
3548 for (binx=1;binx<=nbinsx;binx++) {
3549 Double_t fint = f1->Integral(xAxis->GetBinLowEdge(binx+first-1),xAxis->GetBinUpEdge(binx+first-1), 0.);
3550 integral[binx] = integral[binx-1] + fint;
3551 }
3552
3553 // - Normalize integral to 1
3554 if (integral[nbinsx] == 0 ) {
3555 delete [] integral;
3556 Error("FillRandom", "Integral = zero"); return;
3557 }
3558 for (bin=1;bin<=nbinsx;bin++) integral[bin] /= integral[nbinsx];
3559
3560 // --------------Start main loop ntimes
3561 for (loop=0;loop<ntimes;loop++) {
3562 r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
3563 ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
3564 //binx = 1 + ibin;
3565 //x = xAxis->GetBinCenter(binx); //this is not OK when SetBuffer is used
3566 x = xAxis->GetBinLowEdge(ibin+first)
3567 +xAxis->GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
3568 Fill(x);
3569 }
3570 delete [] integral;
3571}
3572
3573////////////////////////////////////////////////////////////////////////////////
3574/// Fill histogram following distribution in histogram h.
3575///
3576/// @param h : Histogram pointer used for sampling random number
3577/// @param ntimes : number of times the histogram is filled
3578/// @param rng : (optional) Random number generator used for sampling
3579///
3580/// The distribution contained in the histogram h (TH1) is integrated
3581/// over the channel contents for the bin range of this histogram.
3582/// It is normalized to 1.
3583///
3584/// Getting one random number implies:
3585/// - Generating a random number between 0 and 1 (say r1)
3586/// - Look in which bin in the normalized integral r1 corresponds to
3587/// - Fill histogram channel ntimes random numbers are generated
3588///
3589/// SPECIAL CASE when the target histogram has the same binning as the source.
3590/// in this case we simply use a poisson distribution where
3591/// the mean value per bin = bincontent/integral.
3592
3593void TH1::FillRandom(TH1 *h, Int_t ntimes, TRandom * rng)
3594{
3595 if (!h) { Error("FillRandom", "Null histogram"); return; }
3596 if (fDimension != h->GetDimension()) {
3597 Error("FillRandom", "Histograms with different dimensions"); return;
3598 }
3599 if (std::isnan(h->ComputeIntegral(true))) {
3600 Error("FillRandom", "Histograms contains negative bins, does not represent probabilities");
3601 return;
3602 }
3603
3604 //in case the target histogram has the same binning and ntimes much greater
3605 //than the number of bins we can use a fast method
3607 Int_t last = fXaxis.GetLast();
3608 Int_t nbins = last-first+1;
3609 if (ntimes > 10*nbins) {
3610 try {
3611 CheckConsistency(this,h);
3612 Double_t sumw = h->Integral(first,last);
3613 if (sumw == 0) return;
3614 Double_t sumgen = 0;
3615 for (Int_t bin=first;bin<=last;bin++) {
3616 Double_t mean = h->RetrieveBinContent(bin)*ntimes/sumw;
3617 Double_t cont = (rng) ? rng->Poisson(mean) : gRandom->Poisson(mean);
3618 sumgen += cont;
3619 AddBinContent(bin,cont);
3620 if (fSumw2.fN) fSumw2.fArray[bin] += cont;
3621 }
3622
3623 // fix for the fluctuations in the total number n
3624 // since we use Poisson instead of multinomial
3625 // add a correction to have ntimes as generated entries
3626 Int_t i;
3627 if (sumgen < ntimes) {
3628 // add missing entries
3629 for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
3630 {
3631 Double_t x = h->GetRandom();
3632 Fill(x);
3633 }
3634 }
3635 else if (sumgen > ntimes) {
3636 // remove extra entries
3637 i = Int_t(sumgen+0.5);
3638 while( i > ntimes) {
3639 Double_t x = h->GetRandom(rng);
3640 Int_t ibin = fXaxis.FindBin(x);
3642 // skip in case bin is empty
3643 if (y > 0) {
3644 SetBinContent(ibin, y-1.);
3645 i--;
3646 }
3647 }
3648 }
3649
3650 ResetStats();
3651 return;
3652 }
3653 catch(std::exception&) {} // do nothing
3654 }
3655 // case of different axis and not too large ntimes
3656
3657 if (h->ComputeIntegral() ==0) return;
3658 Int_t loop;
3659 Double_t x;
3660 for (loop=0;loop<ntimes;loop++) {
3661 x = h->GetRandom();
3662 Fill(x);
3663 }
3664}
3665
3666////////////////////////////////////////////////////////////////////////////////
3667/// Return Global bin number corresponding to x,y,z
3668///
3669/// 2-D and 3-D histograms are represented with a one dimensional
3670/// structure. This has the advantage that all existing functions, such as
3671/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3672/// This function tries to extend the axis if the given point belongs to an
3673/// under-/overflow bin AND if CanExtendAllAxes() is true.
3674///
3675/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3676
3678{
3679 if (GetDimension() < 2) {
3680 return fXaxis.FindBin(x);
3681 }
3682 if (GetDimension() < 3) {
3683 Int_t nx = fXaxis.GetNbins()+2;
3684 Int_t binx = fXaxis.FindBin(x);
3685 Int_t biny = fYaxis.FindBin(y);
3686 return binx + nx*biny;
3687 }
3688 if (GetDimension() < 4) {
3689 Int_t nx = fXaxis.GetNbins()+2;
3690 Int_t ny = fYaxis.GetNbins()+2;
3691 Int_t binx = fXaxis.FindBin(x);
3692 Int_t biny = fYaxis.FindBin(y);
3693 Int_t binz = fZaxis.FindBin(z);
3694 return binx + nx*(biny +ny*binz);
3695 }
3696 return -1;
3697}
3698
3699////////////////////////////////////////////////////////////////////////////////
3700/// Return Global bin number corresponding to x,y,z.
3701///
3702/// 2-D and 3-D histograms are represented with a one dimensional
3703/// structure. This has the advantage that all existing functions, such as
3704/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3705/// This function DOES NOT try to extend the axis if the given point belongs
3706/// to an under-/overflow bin.
3707///
3708/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3709
3711{
3712 if (GetDimension() < 2) {
3713 return fXaxis.FindFixBin(x);
3714 }
3715 if (GetDimension() < 3) {
3716 Int_t nx = fXaxis.GetNbins()+2;
3717 Int_t binx = fXaxis.FindFixBin(x);
3718 Int_t biny = fYaxis.FindFixBin(y);
3719 return binx + nx*biny;
3720 }
3721 if (GetDimension() < 4) {
3722 Int_t nx = fXaxis.GetNbins()+2;
3723 Int_t ny = fYaxis.GetNbins()+2;
3724 Int_t binx = fXaxis.FindFixBin(x);
3725 Int_t biny = fYaxis.FindFixBin(y);
3726 Int_t binz = fZaxis.FindFixBin(z);
3727 return binx + nx*(biny +ny*binz);
3728 }
3729 return -1;
3730}
3731
3732////////////////////////////////////////////////////////////////////////////////
3733/// Find first bin with content > threshold for axis (1=x, 2=y, 3=z)
3734/// if no bins with content > threshold is found the function returns -1.
3735/// The search will occur between the specified first and last bin. Specifying
3736/// the value of the last bin to search to less than zero will search until the
3737/// last defined bin.
3738
3739Int_t TH1::FindFirstBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3740{
3741 if (fBuffer) ((TH1*)this)->BufferEmpty();
3742
3743 if (axis < 1 || (axis > 1 && GetDimension() == 1 ) ||
3744 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3 ) ) {
3745 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3746 axis = 1;
3747 }
3748 if (firstBin < 1) {
3749 firstBin = 1;
3750 }
3751 Int_t nbinsx = fXaxis.GetNbins();
3752 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3753 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3754
3755 if (axis == 1) {
3756 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3757 lastBin = fXaxis.GetNbins();
3758 }
3759 for (Int_t binx = firstBin; binx <= lastBin; binx++) {
3760 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3761 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3762 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binx;
3763 }
3764 }
3765 }
3766 }
3767 else if (axis == 2) {
3768 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3769 lastBin = fYaxis.GetNbins();
3770 }
3771 for (Int_t biny = firstBin; biny <= lastBin; biny++) {
3772 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3773 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3774 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return biny;
3775 }
3776 }
3777 }
3778 }
3779 else if (axis == 3) {
3780 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3781 lastBin = fZaxis.GetNbins();
3782 }
3783 for (Int_t binz = firstBin; binz <= lastBin; binz++) {
3784 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3785 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3786 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binz;
3787 }
3788 }
3789 }
3790 }
3791
3792 return -1;
3793}
3794
3795////////////////////////////////////////////////////////////////////////////////
3796/// Find last bin with content > threshold for axis (1=x, 2=y, 3=z)
3797/// if no bins with content > threshold is found the function returns -1.
3798/// The search will occur between the specified first and last bin. Specifying
3799/// the value of the last bin to search to less than zero will search until the
3800/// last defined bin.
3801
3802Int_t TH1::FindLastBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3803{
3804 if (fBuffer) ((TH1*)this)->BufferEmpty();
3805
3806
3807 if (axis < 1 || ( axis > 1 && GetDimension() == 1 ) ||
3808 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3) ) {
3809 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3810 axis = 1;
3811 }
3812 if (firstBin < 1) {
3813 firstBin = 1;
3814 }
3815 Int_t nbinsx = fXaxis.GetNbins();
3816 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3817 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3818
3819 if (axis == 1) {
3820 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3821 lastBin = fXaxis.GetNbins();
3822 }
3823 for (Int_t binx = lastBin; binx >= firstBin; binx--) {
3824 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3825 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3826 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binx;
3827 }
3828 }
3829 }
3830 }
3831 else if (axis == 2) {
3832 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3833 lastBin = fYaxis.GetNbins();
3834 }
3835 for (Int_t biny = lastBin; biny >= firstBin; biny--) {
3836 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3837 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3838 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return biny;
3839 }
3840 }
3841 }
3842 }
3843 else if (axis == 3) {
3844 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3845 lastBin = fZaxis.GetNbins();
3846 }
3847 for (Int_t binz = lastBin; binz >= firstBin; binz--) {
3848 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3849 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3850 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binz;
3851 }
3852 }
3853 }
3854 }
3855
3856 return -1;
3857}
3858
3859////////////////////////////////////////////////////////////////////////////////
3860/// Search object named name in the list of functions.
3861
3862TObject *TH1::FindObject(const char *name) const
3863{
3864 if (fFunctions) return fFunctions->FindObject(name);
3865 return nullptr;
3866}
3867
3868////////////////////////////////////////////////////////////////////////////////
3869/// Search object obj in the list of functions.
3870
3871TObject *TH1::FindObject(const TObject *obj) const
3872{
3873 if (fFunctions) return fFunctions->FindObject(obj);
3874 return nullptr;
3875}
3876
3877////////////////////////////////////////////////////////////////////////////////
3878/// Fit histogram with function fname.
3879///
3880///
3881/// fname is the name of a function available in the global ROOT list of functions
3882/// `gROOT->GetListOfFunctions`
3883/// The list include any TF1 object created by the user plus some pre-defined functions
3884/// which are automatically created by ROOT the first time a pre-defined function is requested from `gROOT`
3885/// (i.e. when calling `gROOT->GetFunction(const char *name)`).
3886/// These pre-defined functions are:
3887/// - `gaus, gausn` where gausn is the normalized Gaussian
3888/// - `landau, landaun`
3889/// - `expo`
3890/// - `pol1,...9, chebyshev1,...9`.
3891///
3892/// For printing the list of all available functions do:
3893///
3894/// TF1::InitStandardFunctions(); // not needed if `gROOT->GetFunction` is called before
3895/// gROOT->GetListOfFunctions()->ls()
3896///
3897/// `fname` can also be a formula that is accepted by the linear fitter containing the special operator `++`,
3898/// representing linear components separated by `++` sign, for example `x++sin(x)` for fitting `[0]*x+[1]*sin(x)`
3899///
3900/// This function finds a pointer to the TF1 object with name `fname` and calls TH1::Fit(TF1 *, Option_t *, Option_t *,
3901/// Double_t, Double_t). See there for the fitting options and the details about fitting histograms
3902
3903TFitResultPtr TH1::Fit(const char *fname ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
3904{
3905 char *linear;
3906 linear= (char*)strstr(fname, "++");
3907 Int_t ndim=GetDimension();
3908 if (linear){
3909 if (ndim<2){
3910 TF1 f1(fname, fname, xxmin, xxmax);
3911 return Fit(&f1,option,goption,xxmin,xxmax);
3912 }
3913 else if (ndim<3){
3914 TF2 f2(fname, fname);
3915 return Fit(&f2,option,goption,xxmin,xxmax);
3916 }
3917 else{
3918 TF3 f3(fname, fname);
3919 return Fit(&f3,option,goption,xxmin,xxmax);
3920 }
3921 }
3922 else{
3923 TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
3924 if (!f1) { Printf("Unknown function: %s",fname); return -1; }
3925 return Fit(f1,option,goption,xxmin,xxmax);
3926 }
3927}
3928
3929////////////////////////////////////////////////////////////////////////////////
3930/// Fit histogram with the function pointer f1.
3931///
3932/// \param[in] f1 pointer to the function object
3933/// \param[in] option string defining the fit options (see table below).
3934/// \param[in] goption specify a list of graphics options. See TH1::Draw for a complete list of these options.
3935/// \param[in] xxmin lower fitting range
3936/// \param[in] xxmax upper fitting range
3937/// \return A smart pointer to the TFitResult class
3938///
3939/// \anchor HFitOpt
3940/// ### Histogram Fitting Options
3941///
3942/// Here is the full list of fit options that can be given in the parameter `option`.
3943/// Several options can be used together by concatanating the strings without the need of any delimiters.
3944///
3945/// option | description
3946/// -------|------------
3947/// "L" | Uses a log likelihood method (default is chi-square method). To be used when the histogram represents counts.
3948/// "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.
3949/// "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.
3950/// "MULTI" | Uses Loglikelihood method based on multi-nomial distribution. In this case the function must be normalized and one fits only the function shape.
3951/// "W" | Fit using the chi-square method and ignoring the bin uncertainties and skip empty bins.
3952/// "WW" | Fit using the chi-square method and ignoring the bin uncertainties and include the empty bins.
3953/// "I" | Uses the integral of function in the bin instead of the default bin center value.
3954/// "F" | Uses the default minimizer (e.g. Minuit) when fitting a linear function (e.g. polN) instead of the linear fitter.
3955/// "U" | Uses a user specified objective function (e.g. user providedlikelihood function) defined using `TVirtualFitter::SetFCN`
3956/// "E" | Performs a better parameter errors estimation using the Minos technique for all fit parameters.
3957/// "M" | Uses the IMPROVE algorithm (available only in TMinuit). This algorithm attempts improve the found local minimum by searching for a better one.
3958/// "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`.
3959/// "Q" | Quiet mode (minimum printing)
3960/// "V" | Verbose mode (default is between Q and V)
3961/// "+" | 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.
3962/// "N" | Does not store the graphics function, does not draw the histogram with the function after fitting.
3963/// "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.
3964/// "R" | Fit using a fitting range specified in the function range with `TF1::SetRange`.
3965/// "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.
3966/// "C" | In case of linear fitting, do no calculate the chisquare (saves CPU time).
3967/// "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.
3968/// "WIDTH" | Scales the histogran bin content by the bin width (useful for variable bins histograms)
3969/// "SERIAL" | Runs in serial mode. By defult if ROOT is built with MT support and MT is enables, the fit is perfomed in multi-thread - "E" Perform better Errors estimation using Minos technique
3970/// "MULTITHREAD" | Forces usage of multi-thread execution whenever possible
3971///
3972/// The default fitting of an histogram (when no option is given) is perfomed as following:
3973/// - a chi-square fit (see below Chi-square Fits) computed using the bin histogram errors and excluding bins with zero errors (empty bins);
3974/// - the full range of the histogram is used;
3975/// - the default Minimizer with its default configuration is used (see below Minimizer Configuration) except for linear function;
3976/// - for linear functions (`polN`, `chenbyshev` or formula expressions combined using operator `++`) a linear minimization is used.
3977/// - only the status of the fit is returned;
3978/// - the fit is performed in Multithread whenever is enabled in ROOT;
3979/// - only the last fitted function is saved in the histogram;
3980/// - the histogram is drawn after fitting overalyed with the resulting fitting function
3981///
3982/// \anchor HFitMinimizer
3983/// ### Minimizer Configuration
3984///
3985/// The Fit is perfomed using the default Minimizer, defined in the `ROOT::Math::MinimizerOptions` class.
3986/// It is possible to change the default minimizer and its configuration parameters by calling these static functions before fitting (before calling `TH1::Fit`):
3987/// - `ROOT::Math::MinimizerOptions::SetDefaultMinimizer(minimizerName, minimizerAgorithm)` for changing the minmizer and/or the corresponding algorithm.
3988/// For example `ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");` will set the usage of the BFGS algorithm of the GSL multi-dimensional minimization
3989/// The current defaults are ("Minuit","Migrad").
3990/// See the documentation of the `ROOT::Math::MinimizerOptions` for the available minimizers in ROOT and their corresponding algorithms.
3991/// - `ROOT::Math::MinimizerOptions::SetDefaultTolerance` for setting a different tolerance value for the minimization.
3992/// - `ROOT::Math::MinimizerOptions::SetDefaultMaxFunctionCalls` for setting the maximum number of function calls.
3993/// - `ROOT::Math::MinimizerOptions::SetDefaultPrintLevel` for changing the minimizer print level from level=0 (minimal printing) to level=3 maximum printing
3994///
3995/// Other options are possible depending on the Minimizer used, see the corresponding documentation.
3996/// The default minimizer can be also set in the resource file in etc/system.rootrc. For example
3997///
3998/// ~~~ {.cpp}
3999/// Root.Fitter: Minuit2
4000/// ~~~
4001///
4002/// \anchor HFitChi2
4003/// ### Chi-square Fits
4004///
4005/// By default a chi-square (least-square) fit is performed on the histogram. The so-called modified least-square method
4006/// is used where the residual for each bin is computed using as error the observed value (the bin error) returned by `TH1::GetBinError`
4007///
4008/// \f[
4009/// Chi2 = \sum_{i}{ \left(\frac{y(i) - f(x(i) | p )}{e(i)} \right)^2 }
4010/// \f]
4011///
4012/// 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
4013/// an un-weighted histogram). Bins with zero errors are excluded from the fit. See also later the note on the treatment
4014/// of empty bins. When using option "I" the residual is computed not using the function value at the bin center, `f(x(i)|p)`,
4015/// but the integral of the function in the bin, Integral{ f(x|p)dx }, divided by the bin volume.
4016/// When using option `P` (Pearson chi2), the expected error computed as `e(i) = sqrt(f(x(i)|p))` is used.
4017/// In this case empty bins are considered in the fit.
4018/// Both chi-square methods should not be used when the bin content represent counts, especially in case of low bin statistics,
4019/// because they could return a biased result.
4020///
4021/// \anchor HFitNLL
4022/// ### Likelihood Fits
4023///
4024/// When using option "L" a likelihood fit is used instead of the default chi-square fit.
4025/// The likelihood is built assuming a Poisson probability density function for each bin.
4026/// The negative log-likelihood to be minimized is
4027///
4028/// \f[
4029/// NLL = - \sum_{i}{ \log {\mathrm P} ( y(i) | f(x(i) | p ) ) }
4030/// \f]
4031/// 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)`.
4032/// The exact likelihood used is the Poisson likelihood described in this paper:
4033/// S. Baker and R. D. Cousins, “Clarification of the use of chi-square and likelihood functions in fits to histograms,”
4034/// Nucl. Instrum. Meth. 221 (1984) 437.
4035///
4036/// \f[
4037/// NLL = \sum_{i}{( f(x(i) | p ) + y(i)\log(y(i)/ f(x(i) | p )) - y(i)) }
4038/// \f]
4039/// By using this formulation, `2*NLL` can be interpreted as the chi-square resulting from the fit.
4040///
4041/// This method should be always used when the bin content represents counts (i.e. errors are sqrt(N) ).
4042/// The likelihood method has the advantage of treating correctly bins with low statistics. In case of high
4043/// statistics/bin the distribution of the bin content becomes a normal distribution and the likelihood and the chi2 fit
4044/// give the same result.
4045///
4046/// The likelihood method, although a bit slower, it is therefore the recommended method,
4047/// when the histogram represent counts (Poisson statistics), where the chi-square methods may
4048/// give incorrect results, especially in case of low statistics.
4049/// In case of a weighted histogram, it is possible to perform also a likelihood fit by using the
4050/// option "WL". Note a weighted histogram is a histogram which has been filled with weights and it
4051/// has the information on the sum of the weight square for each bin ( TH1::Sumw2() has been called).
4052/// The bin error for a weighted histogram is the square root of the sum of the weight square.
4053///
4054/// \anchor HFitRes
4055/// ### Fit Result
4056///
4057/// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
4058/// By default the TFitResultPtr contains only the status of the fit which is return by an
4059/// automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
4060///
4061/// ~~~ {.cpp}
4062/// Int_t fitStatus = h->Fit(myFunc);
4063/// ~~~
4064///
4065/// If the option "S" is instead used, TFitResultPtr behaves as a smart
4066/// pointer to the TFitResult object. This is useful for retrieving the full result information from the fit, such as the covariance matrix,
4067/// as shown in this example code:
4068///
4069/// ~~~ {.cpp}
4070/// TFitResultPtr r = h->Fit(myFunc,"S");
4071/// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
4072/// Double_t chi2 = r->Chi2(); // to retrieve the fit chi2
4073/// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
4074/// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
4075/// r->Print("V"); // print full information of fit including covariance matrix
4076/// r->Write(); // store the result in a file
4077/// ~~~
4078///
4079/// The fit parameters, error and chi-square (but not covariance matrix) can be retrieved also
4080/// directly from the fitted function that is passed to this call.
4081/// Given a pointer to an associated fitted function `myfunc`, one can retrieve the function/fit
4082/// parameters with calls such as:
4083///
4084/// ~~~ {.cpp}
4085/// Double_t chi2 = myfunc->GetChisquare();
4086/// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
4087/// Double_t err0 = myfunc->GetParError(0); //error on first parameter
4088/// ~~~
4089///
4090/// ##### Associated functions
4091///
4092/// One or more object ( can be added to the list
4093/// of functions (fFunctions) associated to each histogram.
4094/// When TH1::Fit is invoked, the fitted function is added to the histogram list of functions (fFunctions).
4095/// If the histogram is made persistent, the list of associated functions is also persistent.
4096/// Given a histogram h, one can retrieve an associated function with:
4097///
4098/// ~~~ {.cpp}
4099/// TF1 *myfunc = h->GetFunction("myfunc");
4100/// ~~~
4101/// or by quering directly the list obtained by calling `TH1::GetListOfFunctions`.
4102///
4103/// \anchor HFitStatus
4104/// ### Fit status
4105///
4106/// The status of the fit is obtained converting the TFitResultPtr to an integer
4107/// independently if the fit option "S" is used or not:
4108///
4109/// ~~~ {.cpp}
4110/// TFitResultPtr r = h->Fit(myFunc,opt);
4111/// Int_t fitStatus = r;
4112/// ~~~
4113///
4114/// - `status = 0` : the fit has been performed successfully (i.e no error occurred).
4115/// - `status < 0` : there is an error not connected with the minimization procedure, for example when a wrong function is used.
4116/// - `status > 0` : return status from Minimizer, depends on used Minimizer. For example for TMinuit and Minuit2 we have:
4117/// - `status = migradStatus + 10*minosStatus + 100*hesseStatus + 1000*improveStatus`.
4118/// 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
4119/// only in Minos but not in Migrad a fitStatus of 40 will be returned.
4120/// Minuit2 returns 0 in case of success and different values in migrad,minos or
4121/// hesse depending on the error. See in this case the documentation of
4122/// Minuit2Minimizer::Minimize for the migrad return status, Minuit2Minimizer::GetMinosError for the
4123/// minos return status and Minuit2Minimizer::Hesse for the hesse return status.
4124/// If other minimizers are used see their specific documentation for the status code returned.
4125/// For example in the case of Fumili, see TFumili::Minimize.
4126///
4127/// \anchor HFitRange
4128/// ### Fitting in a range
4129///
4130/// In order to fit in a sub-range of the histogram you have two options:
4131/// - pass to this function the lower (`xxmin`) and upper (`xxmax`) values for the fitting range;
4132/// - define a specific range in the fitted function and use the fitting option "R".
4133/// For example, if your histogram has a defined range between -4 and 4 and you want to fit a gaussian
4134/// only in the interval 1 to 3, you can do:
4135///
4136/// ~~~ {.cpp}
4137/// TF1 *f1 = new TF1("f1", "gaus", 1, 3);
4138/// histo->Fit("f1", "R");
4139/// ~~~
4140///
4141/// The fitting range is also limited by the histogram range defined using TAxis::SetRange
4142/// or TAxis::SetRangeUser. Therefore the fitting range is the smallest range between the
4143/// histogram one and the one defined by one of the two previous options described above.
4144///
4145/// \anchor HFitInitial
4146/// ### Setting initial conditions
4147///
4148/// Parameters must be initialized before invoking the Fit function.
4149/// The setting of the parameter initial values is automatic for the
4150/// predefined functions such as poln, expo, gaus, landau. One can however disable
4151/// this automatic computation by using the option "B".
4152/// Note that if a predefined function is defined with an argument,
4153/// eg, gaus(0), expo(1), you must specify the initial values for
4154/// the parameters.
4155/// You can specify boundary limits for some or all parameters via
4156///
4157/// ~~~ {.cpp}
4158/// f1->SetParLimits(p_number, parmin, parmax);
4159/// ~~~
4160///
4161/// if `parmin >= parmax`, the parameter is fixed
4162/// Note that you are not forced to fix the limits for all parameters.
4163/// For example, if you fit a function with 6 parameters, you can do:
4164///
4165/// ~~~ {.cpp}
4166/// func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
4167/// func->SetParLimits(3, -10, -4);
4168/// func->FixParameter(4, 0);
4169/// func->SetParLimits(5, 1, 1);
4170/// ~~~
4171///
4172/// With this setup, parameters 0->2 can vary freely
4173/// Parameter 3 has boundaries [-10,-4] with initial value -8
4174/// Parameter 4 is fixed to 0
4175/// Parameter 5 is fixed to 100.
4176/// When the lower limit and upper limit are equal, the parameter is fixed.
4177/// However to fix a parameter to 0, one must call the FixParameter function.
4178///
4179/// \anchor HFitStatBox
4180/// ### Fit Statistics Box
4181///
4182/// The statistics box can display the result of the fit.
4183/// You can change the statistics box to display the fit parameters with
4184/// the TStyle::SetOptFit(mode) method. This mode has four digits.
4185/// mode = pcev (default = 0111)
4186///
4187/// v = 1; print name/values of parameters
4188/// e = 1; print errors (if e=1, v must be 1)
4189/// c = 1; print Chisquare/Number of degrees of freedom
4190/// p = 1; print Probability
4191///
4192/// For example: gStyle->SetOptFit(1011);
4193/// prints the fit probability, parameter names/values, and errors.
4194/// You can change the position of the statistics box with these lines
4195/// (where g is a pointer to the TGraph):
4196///
4197/// TPaveStats *st = (TPaveStats*)g->GetListOfFunctions()->FindObject("stats");
4198/// st->SetX1NDC(newx1); //new x start position
4199/// st->SetX2NDC(newx2); //new x end position
4200///
4201/// \anchor HFitExtra
4202/// ### Additional Notes on Fitting
4203///
4204/// #### Fitting a histogram of dimension N with a function of dimension N-1
4205///
4206/// It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
4207/// 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.
4208/// For correct error scaling, the obtained parameter error are corrected as in the case when the
4209/// option "W" is used.
4210///
4211/// #### User defined objective functions
4212///
4213/// By default when fitting a chi square function is used for fitting. When option "L" is used
4214/// a Poisson likelihood function is used. Using option "MULTI" a multinomial likelihood fit is used.
4215/// Thes functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
4216/// are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
4217/// the file math/mathcore/src/FitUtil.cxx.
4218/// It is possible to specify a user defined fitting function, using option "U" and
4219/// calling the following functions:
4220///
4221/// ~~~ {.cpp}
4222/// TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction);
4223/// ~~~
4224///
4225/// where MyFittingFunction is of type:
4226///
4227/// ~~~ {.cpp}
4228/// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
4229/// ~~~
4230///
4231/// #### Note on treatment of empty bins
4232///
4233/// Empty bins, which have the content equal to zero AND error equal to zero,
4234/// are excluded by default from the chi-square fit, but they are considered in the likelihood fit.
4235/// since they affect the likelihood if the function value in these bins is not negligible.
4236/// Note that if the histogram is having bins with zero content and non zero-errors they are considered as
4237/// any other bins in the fit. Instead bins with zero error and non-zero content are by default excluded in the chi-squared fit.
4238/// In general, one should not fit a histogram with non-empty bins and zero errors.
4239///
4240/// 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
4241/// fit). When using option "WW" the empty bins will be also considered in the chi-square fit with an error of 1.
4242/// Note that in this fitting case (option "W" or "WW") the resulting fitted parameter errors
4243/// are corrected by the obtained chi2 value using this scaling expression:
4244/// `errorp *= sqrt(chisquare/(ndf-1))` as it is done when fitting a TGraph with
4245/// no point errors.
4246///
4247/// #### Excluding points
4248///
4249/// You can use TF1::RejectPoint inside your fitting function to exclude some points
4250/// within a certain range from the fit. See the tutorial `fit/fitExclude.C`.
4251///
4252///
4253/// #### Warning when using the option "0"
4254///
4255/// When selecting the option "0", the fitted function is added to
4256/// the list of functions of the histogram, but it is not drawn when the histogram is drawn.
4257/// You can undo this behaviour resetting its corresponding bit in the TF1 object as following:
4258///
4259/// ~~~ {.cpp}
4260/// h.Fit("myFunction", "0"); // fit, store function but do not draw
4261/// h.Draw(); // function is not drawn
4262/// h.GetFunction("myFunction")->ResetBit(TF1::kNotDraw);
4263/// h.Draw(); // function is visible again
4264/// ~~~
4266
4268{
4269 // implementation of Fit method is in file hist/src/HFitImpl.cxx
4270 Foption_t fitOption;
4272
4273 // create range and minimizer options with default values
4274 ROOT::Fit::DataRange range(xxmin,xxmax);
4276
4277 // need to empty the buffer before
4278 // (t.b.d. do a ML unbinned fit with buffer data)
4279 if (fBuffer) BufferEmpty();
4280
4281 return ROOT::Fit::FitObject(this, f1 , fitOption , minOption, goption, range);
4282}
4283
4284////////////////////////////////////////////////////////////////////////////////
4285/// Display a panel with all histogram fit options.
4286///
4287/// See class TFitPanel for example
4288
4289void TH1::FitPanel()
4290{
4291 if (!gPad)
4292 gROOT->MakeDefCanvas();
4293
4294 if (!gPad) {
4295 Error("FitPanel", "Unable to create a default canvas");
4296 return;
4297 }
4298
4299
4300 // use plugin manager to create instance of TFitEditor
4301 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
4302 if (handler && handler->LoadPlugin() != -1) {
4303 if (handler->ExecPlugin(2, gPad, this) == 0)
4304 Error("FitPanel", "Unable to create the FitPanel");
4305 }
4306 else
4307 Error("FitPanel", "Unable to find the FitPanel plug-in");
4308}
4309
4310////////////////////////////////////////////////////////////////////////////////
4311/// Return a histogram containing the asymmetry of this histogram with h2,
4312/// where the asymmetry is defined as:
4313///
4314/// ~~~ {.cpp}
4315/// Asymmetry = (h1 - h2)/(h1 + h2) where h1 = this
4316/// ~~~
4317///
4318/// works for 1D, 2D, etc. histograms
4319/// c2 is an optional argument that gives a relative weight between the two
4320/// histograms, and dc2 is the error on this weight. This is useful, for example,
4321/// when forming an asymmetry between two histograms from 2 different data sets that
4322/// need to be normalized to each other in some way. The function calculates
4323/// the errors assuming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
4324///
4325/// example: assuming 'h1' and 'h2' are already filled
4326///
4327/// ~~~ {.cpp}
4328/// h3 = h1->GetAsymmetry(h2)
4329/// ~~~
4330///
4331/// then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
4332/// h1 and h2 are left intact.
4333///
4334/// Note that it is the user's responsibility to manage the created histogram.
4335/// The name of the returned histogram will be `Asymmetry_nameOfh1-nameOfh2`
4336///
4337/// code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
4338///
4339/// clone the histograms so top and bottom will have the
4340/// correct dimensions:
4341/// Sumw2 just makes sure the errors will be computed properly
4342/// when we form sums and ratios below.
4343
4345{
4346 TH1 *h1 = this;
4347 TString name = TString::Format("Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4348 TH1 *asym = (TH1*)Clone(name);
4349
4350 // set also the title
4351 TString title = TString::Format("(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4352 asym->SetTitle(title);
4353
4354 asym->Sumw2();
4355 Bool_t addStatus = TH1::AddDirectoryStatus();
4357 TH1 *top = (TH1*)asym->Clone();
4358 TH1 *bottom = (TH1*)asym->Clone();
4359 TH1::AddDirectory(addStatus);
4360
4361 // form the top and bottom of the asymmetry, and then divide:
4362 top->Add(h1,h2,1,-c2);
4363 bottom->Add(h1,h2,1,c2);
4364 asym->Divide(top,bottom);
4365
4366 Int_t xmax = asym->GetNbinsX();
4367 Int_t ymax = asym->GetNbinsY();
4368 Int_t zmax = asym->GetNbinsZ();
4369
4370 if (h1->fBuffer) h1->BufferEmpty(1);
4371 if (h2->fBuffer) h2->BufferEmpty(1);
4372 if (bottom->fBuffer) bottom->BufferEmpty(1);
4373
4374 // now loop over bins to calculate the correct errors
4375 // the reason this error calculation looks complex is because of c2
4376 for(Int_t i=1; i<= xmax; i++){
4377 for(Int_t j=1; j<= ymax; j++){
4378 for(Int_t k=1; k<= zmax; k++){
4379 Int_t bin = GetBin(i, j, k);
4380 // here some bin contents are written into variables to make the error
4381 // calculation a little more legible:
4383 Double_t b = h2->RetrieveBinContent(bin);
4384 Double_t bot = bottom->RetrieveBinContent(bin);
4385
4386 // make sure there are some events, if not, then the errors are set = 0
4387 // automatically.
4388 //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
4389 if(bot < 1e-6){}
4390 else{
4391 // computation of errors by Christos Leonidopoulos
4392 Double_t dasq = h1->GetBinErrorSqUnchecked(bin);
4393 Double_t dbsq = h2->GetBinErrorSqUnchecked(bin);
4394 Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4395 asym->SetBinError(i,j,k,error);
4396 }
4397 }
4398 }
4399 }
4400 delete top;
4401 delete bottom;
4402
4403 return asym;
4404}
4405
4406////////////////////////////////////////////////////////////////////////////////
4407/// Static function
4408/// return the default buffer size for automatic histograms
4409/// the parameter fgBufferSize may be changed via SetDefaultBufferSize
4410
4412{
4413 return fgBufferSize;
4414}
4415
4416////////////////////////////////////////////////////////////////////////////////
4417/// Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
4418/// see TH1::SetDefaultSumw2.
4419
4421{
4422 return fgDefaultSumw2;
4423}
4424
4425////////////////////////////////////////////////////////////////////////////////
4426/// Return the current number of entries.
4427
4429{
4430 if (fBuffer) {
4431 Int_t nentries = (Int_t) fBuffer[0];
4432 if (nentries > 0) return nentries;
4433 }
4434
4435 return fEntries;
4436}
4437
4438////////////////////////////////////////////////////////////////////////////////
4439/// Number of effective entries of the histogram.
4440///
4441/// \f[
4442/// neff = \frac{(\sum Weights )^2}{(\sum Weight^2 )}
4443/// \f]
4444///
4445/// In case of an unweighted histogram this number is equivalent to the
4446/// number of entries of the histogram.
4447/// For a weighted histogram, this number corresponds to the hypothetical number of unweighted entries
4448/// a histogram would need to have the same statistical power as this weighted histogram.
4449/// Note: The underflow/overflow are included if one has set the TH1::StatOverFlows flag
4450/// and if the statistics has been computed at filling time.
4451/// If a range is set in the histogram the number is computed from the given range.
4452
4454{
4455 Stat_t s[kNstat];
4456 this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
4457 return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4458}
4459
4460////////////////////////////////////////////////////////////////////////////////
4461/// Set highlight (enable/disable) mode for the histogram
4462/// by default highlight mode is disable
4463
4464void TH1::SetHighlight(Bool_t set)
4465{
4466 if (IsHighlight() == set)
4467 return;
4468 if (fDimension > 2) {
4469 Info("SetHighlight", "Supported only 1-D or 2-D histograms");
4470 return;
4471 }
4472
4473 SetBit(kIsHighlight, set);
4474
4475 if (fPainter)
4477}
4478
4479////////////////////////////////////////////////////////////////////////////////
4480/// Redefines TObject::GetObjectInfo.
4481/// Displays the histogram info (bin number, contents, integral up to bin
4482/// corresponding to cursor position px,py
4483
4484char *TH1::GetObjectInfo(Int_t px, Int_t py) const
4485{
4486 return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
4487}
4488
4489////////////////////////////////////////////////////////////////////////////////
4490/// Return pointer to painter.
4491/// If painter does not exist, it is created
4492
4494{
4495 if (!fPainter) {
4496 TString opt = option;
4497 opt.ToLower();
4498 if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
4499 //try to create TGLHistPainter
4500 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
4501
4502 if (handler && handler->LoadPlugin() != -1)
4503 fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
4504 }
4505 }
4506
4508
4509 return fPainter;
4510}
4511
4512////////////////////////////////////////////////////////////////////////////////
4513/// Compute Quantiles for this histogram
4514/// Quantile x_q of a probability distribution Function F is defined as
4515///
4516/// ~~~ {.cpp}
4517/// F(x_q) = q with 0 <= q <= 1.
4518/// ~~~
4519///
4520/// For instance the median x_0.5 of a distribution is defined as that value
4521/// of the random variable for which the distribution function equals 0.5:
4522///
4523/// ~~~ {.cpp}
4524/// F(x_0.5) = Probability(x < x_0.5) = 0.5
4525/// ~~~
4526///
4527/// code from Eddy Offermann, Renaissance
4528///
4529/// \param[in] nprobSum maximum size of array q and size of array probSum (if given)
4530/// \param[in] probSum array of positions where quantiles will be computed.
4531/// - if probSum is null, probSum will be computed internally and will
4532/// have a size = number of bins + 1 in h. it will correspond to the
4533/// quantiles calculated at the lowest edge of the histogram (quantile=0) and
4534/// all the upper edges of the bins.
4535/// - if probSum is not null, it is assumed to contain at least nprobSum values.
4536/// \param[out] q array q filled with nq quantiles
4537/// \return value nq (<=nprobSum) with the number of quantiles computed
4538///
4539/// Note that the Integral of the histogram is automatically recomputed
4540/// if the number of entries is different of the number of entries when
4541/// the integral was computed last time. In case you do not use the Fill
4542/// functions to fill your histogram, but SetBinContent, you must call
4543/// TH1::ComputeIntegral before calling this function.
4544///
4545/// Getting quantiles q from two histograms and storing results in a TGraph,
4546/// a so-called QQ-plot
4547///
4548/// ~~~ {.cpp}
4549/// TGraph *gr = new TGraph(nprob);
4550/// h1->GetQuantiles(nprob,gr->GetX());
4551/// h2->GetQuantiles(nprob,gr->GetY());
4552/// gr->Draw("alp");
4553/// ~~~
4554///
4555/// Example:
4556///
4557/// ~~~ {.cpp}
4558/// void quantiles() {
4559/// // demo for quantiles
4560/// const Int_t nq = 20;
4561/// TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
4562/// h->FillRandom("gaus",5000);
4563///
4564/// Double_t xq[nq]; // position where to compute the quantiles in [0,1]
4565/// Double_t yq[nq]; // array to contain the quantiles
4566/// for (Int_t i=0;i<nq;i++) xq[i] = Float_t(i+1)/nq;
4567/// h->GetQuantiles(nq,yq,xq);
4568///
4569/// //show the original histogram in the top pad
4570/// TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
4571/// c1->Divide(1,2);
4572/// c1->cd(1);
4573/// h->Draw();
4574///
4575/// // show the quantiles in the bottom pad
4576/// c1->cd(2);
4577/// gPad->SetGrid();
4578/// TGraph *gr = new TGraph(nq,xq,yq);
4579/// gr->SetMarkerStyle(21);
4580/// gr->Draw("alp");
4581/// }
4582/// ~~~
4583
4584Int_t TH1::GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
4585{
4586 if (GetDimension() > 1) {
4587 Error("GetQuantiles","Only available for 1-d histograms");
4588 return 0;
4589 }
4590
4591 const Int_t nbins = GetXaxis()->GetNbins();
4592 if (!fIntegral) ComputeIntegral();
4593 if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4594
4595 Int_t i, ibin;
4596 Double_t *prob = (Double_t*)probSum;
4597 Int_t nq = nprobSum;
4598 if (probSum == nullptr) {
4599 nq = nbins+1;
4600 prob = new Double_t[nq];
4601 prob[0] = 0;
4602 for (i=1;i<nq;i++) {
4603 prob[i] = fIntegral[i]/fIntegral[nbins];
4604 }
4605 }
4606
4607 for (i = 0; i < nq; i++) {
4608 ibin = TMath::BinarySearch(nbins,fIntegral,prob[i]);
4609 while (ibin < nbins-1 && fIntegral[ibin+1] == prob[i]) {
4610 if (fIntegral[ibin+2] == prob[i]) ibin++;
4611 else break;
4612 }
4613 q[i] = GetBinLowEdge(ibin+1);
4614 const Double_t dint = fIntegral[ibin+1]-fIntegral[ibin];
4615 if (dint > 0) q[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4616 }
4617
4618 if (!probSum) delete [] prob;
4619 return nq;
4620}
4621
4622////////////////////////////////////////////////////////////////////////////////
4623/// Decode string choptin and fill fitOption structure.
4624
4625Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
4626{
4628 return 1;
4629}
4630
4631////////////////////////////////////////////////////////////////////////////////
4632/// Compute Initial values of parameters for a gaussian.
4633
4634void H1InitGaus()
4635{
4636 Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4637 Int_t bin;
4638 const Double_t sqrtpi = 2.506628;
4639
4640 // - Compute mean value and StdDev of the histogram in the given range
4642 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4643 Int_t hxfirst = hFitter->GetXfirst();
4644 Int_t hxlast = hFitter->GetXlast();
4645 Double_t valmax = curHist->GetBinContent(hxfirst);
4646 Double_t binwidx = curHist->GetBinWidth(hxfirst);
4647 allcha = sumx = sumx2 = 0;
4648 for (bin=hxfirst;bin<=hxlast;bin++) {
4649 x = curHist->GetBinCenter(bin);
4650 val = TMath::Abs(curHist->GetBinContent(bin));
4651 if (val > valmax) valmax = val;
4652 sumx += val*x;
4653 sumx2 += val*x*x;
4654 allcha += val;
4655 }
4656 if (allcha == 0) return;
4657 mean = sumx/allcha;
4658 stddev = sumx2/allcha - mean*mean;
4659 if (stddev > 0) stddev = TMath::Sqrt(stddev);
4660 else stddev = 0;
4661 if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4662 //if the distribution is really gaussian, the best approximation
4663 //is binwidx*allcha/(sqrtpi*stddev)
4664 //However, in case of non-gaussian tails, this underestimates
4665 //the normalisation constant. In this case the maximum value
4666 //is a better approximation.
4667 //We take the average of both quantities
4668 Double_t constant = 0.5*(valmax+binwidx*allcha/(sqrtpi*stddev));
4669
4670 //In case the mean value is outside the histo limits and
4671 //the StdDev is bigger than the range, we take
4672 // mean = center of bins
4673 // stddev = half range
4674 Double_t xmin = curHist->GetXaxis()->GetXmin();
4675 Double_t xmax = curHist->GetXaxis()->GetXmax();
4676 if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4677 mean = 0.5*(xmax+xmin);
4678 stddev = 0.5*(xmax-xmin);
4679 }
4680 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4681 f1->SetParameter(0,constant);
4682 f1->SetParameter(1,mean);
4683 f1->SetParameter(2,stddev);
4684 f1->SetParLimits(2,0,10*stddev);
4685}
4686
4687////////////////////////////////////////////////////////////////////////////////
4688/// Compute Initial values of parameters for an exponential.
4689
4690void H1InitExpo()
4691{
4692 Double_t constant, slope;
4693 Int_t ifail;
4695 Int_t hxfirst = hFitter->GetXfirst();
4696 Int_t hxlast = hFitter->GetXlast();
4697 Int_t nchanx = hxlast - hxfirst + 1;
4698
4699 H1LeastSquareLinearFit(-nchanx, constant, slope, ifail);
4700
4701 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4702 f1->SetParameter(0,constant);
4703 f1->SetParameter(1,slope);
4704
4705}
4706
4707////////////////////////////////////////////////////////////////////////////////
4708/// Compute Initial values of parameters for a polynom.
4709
4710void H1InitPolynom()
4711{
4712 Double_t fitpar[25];
4713
4715 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4716 Int_t hxfirst = hFitter->GetXfirst();
4717 Int_t hxlast = hFitter->GetXlast();
4718 Int_t nchanx = hxlast - hxfirst + 1;
4719 Int_t npar = f1->GetNpar();
4720
4721 if (nchanx <=1 || npar == 1) {
4722 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4723 fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4724 } else {
4725 H1LeastSquareFit( nchanx, npar, fitpar);
4726 }
4727 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4728}
4729
4730////////////////////////////////////////////////////////////////////////////////
4731/// Least squares lpolynomial fitting without weights.
4732///
4733/// \param[in] n number of points to fit
4734/// \param[in] m number of parameters
4735/// \param[in] a array of parameters
4736///
4737/// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
4738/// (E.Keil. revised by B.Schorr, 23.10.1981.)
4739
4741{
4742 const Double_t zero = 0.;
4743 const Double_t one = 1.;
4744 const Int_t idim = 20;
4745
4746 Double_t b[400] /* was [20][20] */;
4747 Int_t i, k, l, ifail;
4748 Double_t power;
4749 Double_t da[20], xk, yk;
4750
4751 if (m <= 2) {
4752 H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4753 return;
4754 }
4755 if (m > idim || m > n) return;
4756 b[0] = Double_t(n);
4757 da[0] = zero;
4758 for (l = 2; l <= m; ++l) {
4759 b[l-1] = zero;
4760 b[m + l*20 - 21] = zero;
4761 da[l-1] = zero;
4762 }
4764 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4765 Int_t hxfirst = hFitter->GetXfirst();
4766 Int_t hxlast = hFitter->GetXlast();
4767 for (k = hxfirst; k <= hxlast; ++k) {
4768 xk = curHist->GetBinCenter(k);
4769 yk = curHist->GetBinContent(k);
4770 power = one;
4771 da[0] += yk;
4772 for (l = 2; l <= m; ++l) {
4773 power *= xk;
4774 b[l-1] += power;
4775 da[l-1] += power*yk;
4776 }
4777 for (l = 2; l <= m; ++l) {
4778 power *= xk;
4779 b[m + l*20 - 21] += power;
4780 }
4781 }
4782 for (i = 3; i <= m; ++i) {
4783 for (k = i; k <= m; ++k) {
4784 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4785 }
4786 }
4787 H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
4788
4789 for (i=0; i<m; ++i) a[i] = da[i];
4790
4791}
4792
4793////////////////////////////////////////////////////////////////////////////////
4794/// Least square linear fit without weights.
4795///
4796/// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
4797/// (added to LSQ by B. Schorr, 15.02.1982.)
4798
4799void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
4800{
4801 Double_t xbar, ybar, x2bar;
4802 Int_t i, n;
4803 Double_t xybar;
4804 Double_t fn, xk, yk;
4805 Double_t det;
4806
4807 n = TMath::Abs(ndata);
4808 ifail = -2;
4809 xbar = ybar = x2bar = xybar = 0;
4811 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4812 Int_t hxfirst = hFitter->GetXfirst();
4813 Int_t hxlast = hFitter->GetXlast();
4814 for (i = hxfirst; i <= hxlast; ++i) {
4815 xk = curHist->GetBinCenter(i);
4816 yk = curHist->GetBinContent(i);
4817 if (ndata < 0) {
4818 if (yk <= 0) yk = 1e-9;
4819 yk = TMath::Log(yk);
4820 }
4821 xbar += xk;
4822 ybar += yk;
4823 x2bar += xk*xk;
4824 xybar += xk*yk;
4825 }
4826 fn = Double_t(n);
4827 det = fn*x2bar - xbar*xbar;
4828 ifail = -1;
4829 if (det <= 0) {
4830 a0 = ybar/fn;
4831 a1 = 0;
4832 return;
4833 }
4834 ifail = 0;
4835 a0 = (x2bar*ybar - xbar*xybar) / det;
4836 a1 = (fn*xybar - xbar*ybar) / det;
4837
4838}
4839
4840////////////////////////////////////////////////////////////////////////////////
4841/// Extracted from CERN Program library routine DSEQN.
4842///
4843/// Translated to C++ by Rene Brun
4844
4845void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b)
4846{
4847 Int_t a_dim1, a_offset, b_dim1, b_offset;
4848 Int_t nmjp1, i, j, l;
4849 Int_t im1, jp1, nm1, nmi;
4850 Double_t s1, s21, s22;
4851 const Double_t one = 1.;
4852
4853 /* Parameter adjustments */
4854 b_dim1 = idim;
4855 b_offset = b_dim1 + 1;
4856 b -= b_offset;
4857 a_dim1 = idim;
4858 a_offset = a_dim1 + 1;
4859 a -= a_offset;
4860
4861 if (idim < n) return;
4862
4863 ifail = 0;
4864 for (j = 1; j <= n; ++j) {
4865 if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
4866 a[j + j*a_dim1] = one / a[j + j*a_dim1];
4867 if (j == n) continue;
4868 jp1 = j + 1;
4869 for (l = jp1; l <= n; ++l) {
4870 a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4871 s1 = -a[l + (j+1)*a_dim1];
4872 for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4873 a[l + (j+1)*a_dim1] = -s1;
4874 }
4875 }
4876 if (k <= 0) return;
4877
4878 for (l = 1; l <= k; ++l) {
4879 b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
4880 }
4881 if (n == 1) return;
4882 for (l = 1; l <= k; ++l) {
4883 for (i = 2; i <= n; ++i) {
4884 im1 = i - 1;
4885 s21 = -b[i + l*b_dim1];
4886 for (j = 1; j <= im1; ++j) {
4887 s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
4888 }
4889 b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
4890 }
4891 nm1 = n - 1;
4892 for (i = 1; i <= nm1; ++i) {
4893 nmi = n - i;
4894 s22 = -b[nmi + l*b_dim1];
4895 for (j = 1; j <= i; ++j) {
4896 nmjp1 = n - j + 1;
4897 s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
4898 }
4899 b[nmi + l*b_dim1] = -s22;
4900 }
4901 }
4902}
4903
4904////////////////////////////////////////////////////////////////////////////////
4905/// Return Global bin number corresponding to binx,y,z.
4906///
4907/// 2-D and 3-D histograms are represented with a one dimensional
4908/// structure.
4909/// This has the advantage that all existing functions, such as
4910/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
4911///
4912/// In case of a TH1x, returns binx directly.
4913/// see TH1::GetBinXYZ for the inverse transformation.
4914///
4915/// Convention for numbering bins
4916///
4917/// For all histogram types: nbins, xlow, xup
4918///
4919/// - bin = 0; underflow bin
4920/// - bin = 1; first bin with low-edge xlow INCLUDED
4921/// - bin = nbins; last bin with upper-edge xup EXCLUDED
4922/// - bin = nbins+1; overflow bin
4923///
4924/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4925/// For example, assuming a 3-D histogram with binx,biny,binz, the function
4926///
4927/// ~~~ {.cpp}
4928/// Int_t bin = h->GetBin(binx,biny,binz);
4929/// ~~~
4930///
4931/// returns a global/linearized bin number. This global bin is useful
4932/// to access the bin information independently of the dimension.
4933
4934Int_t TH1::GetBin(Int_t binx, Int_t, Int_t) const
4935{
4936 Int_t ofx = fXaxis.GetNbins() + 1; // overflow bin
4937 if (binx < 0) binx = 0;
4938 if (binx > ofx) binx = ofx;
4939
4940 return binx;
4941}
4942
4943////////////////////////////////////////////////////////////////////////////////
4944/// Return binx, biny, binz corresponding to the global bin number globalbin
4945/// see TH1::GetBin function above
4946
4947void TH1::GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz) const
4948{
4949 Int_t nx = fXaxis.GetNbins()+2;
4950 Int_t ny = fYaxis.GetNbins()+2;
4951
4952 if (GetDimension() == 1) {
4953 binx = binglobal%nx;
4954 biny = 0;
4955 binz = 0;
4956 return;
4957 }
4958 if (GetDimension() == 2) {
4959 binx = binglobal%nx;
4960 biny = ((binglobal-binx)/nx)%ny;
4961 binz = 0;
4962 return;
4963 }
4964 if (GetDimension() == 3) {
4965 binx = binglobal%nx;
4966 biny = ((binglobal-binx)/nx)%ny;
4967 binz = ((binglobal-binx)/nx -biny)/ny;
4968 }
4969}
4970
4971////////////////////////////////////////////////////////////////////////////////
4972/// Return a random number distributed according the histogram bin contents.
4973/// This function checks if the bins integral exists. If not, the integral
4974/// is evaluated, normalized to one.
4975///
4976/// @param rng (optional) Random number generator pointer used (default is gRandom)
4977///
4978/// The integral is automatically recomputed if the number of entries
4979/// is not the same then when the integral was computed.
4980/// NB Only valid for 1-d histograms. Use GetRandom2 or 3 otherwise.
4981/// If the histogram has a bin with negative content a NaN is returned
4982
4983Double_t TH1::GetRandom(TRandom * rng) const
4984{
4985 if (fDimension > 1) {
4986 Error("GetRandom","Function only valid for 1-d histograms");
4987 return 0;
4988 }
4989 Int_t nbinsx = GetNbinsX();
4990 Double_t integral = 0;
4991 // compute integral checking that all bins have positive content (see ROOT-5894)
4992 if (fIntegral) {
4993 if (fIntegral[nbinsx+1] != fEntries) integral = ((TH1*)this)->ComputeIntegral(true);
4994 else integral = fIntegral[nbinsx];
4995 } else {
4996 integral = ((TH1*)this)->ComputeIntegral(true);
4997 }
4998 if (integral == 0) return 0;
4999 // return a NaN in case some bins have negative content
5000 if (integral == TMath::QuietNaN() ) return TMath::QuietNaN();
5001
5002 Double_t r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
5003 Int_t ibin = TMath::BinarySearch(nbinsx,fIntegral,r1);
5004 Double_t x = GetBinLowEdge(ibin+1);
5005 if (r1 > fIntegral[ibin]) x +=
5006 GetBinWidth(ibin+1)*(r1-fIntegral[ibin])/(fIntegral[ibin+1] - fIntegral[ibin]);
5007 return x;
5008}
5009
5010////////////////////////////////////////////////////////////////////////////////
5011/// Return content of bin number bin.
5012///
5013/// Implemented in TH1C,S,F,D
5014///
5015/// Convention for numbering bins
5016///
5017/// For all histogram types: nbins, xlow, xup
5018///
5019/// - bin = 0; underflow bin
5020/// - bin = 1; first bin with low-edge xlow INCLUDED
5021/// - bin = nbins; last bin with upper-edge xup EXCLUDED
5022/// - bin = nbins+1; overflow bin
5023///
5024/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
5025/// For example, assuming a 3-D histogram with binx,biny,binz, the function
5026///
5027/// ~~~ {.cpp}
5028/// Int_t bin = h->GetBin(binx,biny,binz);
5029/// ~~~
5030///
5031/// returns a global/linearized bin number. This global bin is useful
5032/// to access the bin information independently of the dimension.
5033
5035{
5036 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
5037 if (bin < 0) bin = 0;
5038 if (bin >= fNcells) bin = fNcells-1;
5039
5040 return RetrieveBinContent(bin);
5041}
5042
5043////////////////////////////////////////////////////////////////////////////////
5044/// Compute first binx in the range [firstx,lastx] for which
5045/// diff = abs(bin_content-c) <= maxdiff
5046///
5047/// In case several bins in the specified range with diff=0 are found
5048/// the first bin found is returned in binx.
5049/// In case several bins in the specified range satisfy diff <=maxdiff
5050/// the bin with the smallest difference is returned in binx.
5051/// In all cases the function returns the smallest difference.
5052///
5053/// NOTE1: if firstx <= 0, firstx is set to bin 1
5054/// if (lastx < firstx then firstx is set to the number of bins
5055/// ie if firstx=0 and lastx=0 (default) the search is on all bins.
5056///
5057/// NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
5058
5059Double_t TH1::GetBinWithContent(Double_t c, Int_t &binx, Int_t firstx, Int_t lastx,Double_t maxdiff) const
5060{
5061 if (fDimension > 1) {
5062 binx = 0;
5063 Error("GetBinWithContent","function is only valid for 1-D histograms");
5064 return 0;
5065 }
5066
5067 if (fBuffer) ((TH1*)this)->BufferEmpty();
5068
5069 if (firstx <= 0) firstx = 1;
5070 if (lastx < firstx) lastx = fXaxis.GetNbins();
5071 Int_t binminx = 0;
5072 Double_t diff, curmax = 1.e240;
5073 for (Int_t i=firstx;i<=lastx;i++) {
5074 diff = TMath::Abs(RetrieveBinContent(i)-c);
5075 if (diff <= 0) {binx = i; return diff;}
5076 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
5077 }
5078 binx = binminx;
5079 return curmax;
5080}
5081
5082////////////////////////////////////////////////////////////////////////////////
5083/// Given a point x, approximates the value via linear interpolation
5084/// based on the two nearest bin centers
5085///
5086/// Andy Mastbaum 10/21/08
5087
5089{
5090 if (fBuffer) ((TH1*)this)->BufferEmpty();
5091
5092 Int_t xbin = fXaxis.FindFixBin(x);
5093 Double_t x0,x1,y0,y1;
5094
5095 if(x<=GetBinCenter(1)) {
5096 return RetrieveBinContent(1);
5097 } else if(x>=GetBinCenter(GetNbinsX())) {
5098 return RetrieveBinContent(GetNbinsX());
5099 } else {
5100 if(x<=GetBinCenter(xbin)) {
5101 y0 = RetrieveBinContent(xbin-1);
5102 x0 = GetBinCenter(xbin-1);
5103 y1 = RetrieveBinContent(xbin);
5104 x1 = GetBinCenter(xbin);
5105 } else {
5106 y0 = RetrieveBinContent(xbin);
5107 x0 = GetBinCenter(xbin);
5108 y1 = RetrieveBinContent(xbin+1);
5109 x1 = GetBinCenter(xbin+1);
5110 }
5111 return y0 + (x-x0)*((y1-y0)/(x1-x0));
5112 }
5113}
5114
5115////////////////////////////////////////////////////////////////////////////////
5116/// 2d Interpolation. Not yet implemented.
5117
5119{
5120 Error("Interpolate","This function must be called with 1 argument for a TH1");
5121 return 0;
5122}
5123
5124////////////////////////////////////////////////////////////////////////////////
5125/// 3d Interpolation. Not yet implemented.
5126
5128{
5129 Error("Interpolate","This function must be called with 1 argument for a TH1");
5130 return 0;
5131}
5132
5133///////////////////////////////////////////////////////////////////////////////
5134/// Check if a histogram is empty
5135/// (this is a protected method used mainly by TH1Merger )
5136
5137Bool_t TH1::IsEmpty() const
5138{
5139 // if fTsumw or fentries are not zero histogram is not empty
5140 // need to use GetEntries() instead of fEntries in case of bugger histograms
5141 // so we will flash the buffer
5142 if (fTsumw != 0) return kFALSE;
5143 if (GetEntries() != 0) return kFALSE;
5144 // case fTSumw == 0 amd entries are also zero
5145 // this should not really happening, but if one sets content by hand
5146 // it can happen. a call to ResetStats() should be done in such cases
5147 double sumw = 0;
5148 for (int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
5149 return (sumw != 0) ? kFALSE : kTRUE;
5150}
5151
5152////////////////////////////////////////////////////////////////////////////////
5153/// Return true if the bin is overflow.
5154
5155Bool_t TH1::IsBinOverflow(Int_t bin, Int_t iaxis) const
5156{
5157 Int_t binx, biny, binz;
5158 GetBinXYZ(bin, binx, biny, binz);
5159
5160 if (iaxis == 0) {
5161 if ( fDimension == 1 )
5162 return binx >= GetNbinsX() + 1;
5163 if ( fDimension == 2 )
5164 return (binx >= GetNbinsX() + 1) ||
5165 (biny >= GetNbinsY() + 1);
5166 if ( fDimension == 3 )
5167 return (binx >= GetNbinsX() + 1) ||
5168 (biny >= GetNbinsY() + 1) ||
5169 (binz >= GetNbinsZ() + 1);
5170 return kFALSE;
5171 }
5172 if (iaxis == 1)
5173 return binx >= GetNbinsX() + 1;
5174 if (iaxis == 2)
5175 return biny >= GetNbinsY() + 1;
5176 if (iaxis == 3)
5177 return binz >= GetNbinsZ() + 1;
5178
5179 Error("IsBinOverflow","Invalid axis value");
5180 return kFALSE;
5181}
5182
5183////////////////////////////////////////////////////////////////////////////////
5184/// Return true if the bin is underflow.
5185/// If iaxis = 0 make OR with all axes otherwise check only for the given axis
5186
5187Bool_t TH1::IsBinUnderflow(Int_t bin, Int_t iaxis) const
5188{
5189 Int_t binx, biny, binz;
5190 GetBinXYZ(bin, binx, biny, binz);
5191
5192 if (iaxis == 0) {
5193 if ( fDimension == 1 )
5194 return (binx <= 0);
5195 else if ( fDimension == 2 )
5196 return (binx <= 0 || biny <= 0);
5197 else if ( fDimension == 3 )
5198 return (binx <= 0 || biny <= 0 || binz <= 0);
5199 else
5200 return kFALSE;
5201 }
5202 if (iaxis == 1)
5203 return (binx <= 0);
5204 if (iaxis == 2)
5205 return (biny <= 0);
5206 if (iaxis == 3)
5207 return (binz <= 0);
5208
5209 Error("IsBinUnderflow","Invalid axis value");
5210 return kFALSE;
5211}
5212
5213////////////////////////////////////////////////////////////////////////////////
5214/// Reduce the number of bins for the axis passed in the option to the number of bins having a label.
5215/// The method will remove only the extra bins existing after the last "labeled" bin.
5216/// Note that if there are "un-labeled" bins present between "labeled" bins they will not be removed
5217
5219{
5220 Int_t iaxis = AxisChoice(ax);
5221 TAxis *axis = nullptr;
5222 if (iaxis == 1) axis = GetXaxis();
5223 if (iaxis == 2) axis = GetYaxis();
5224 if (iaxis == 3) axis = GetZaxis();
5225 if (!axis) {
5226 Error("LabelsDeflate","Invalid axis option %s",ax);
5227 return;
5228 }
5229 if (!axis->GetLabels()) return;
5230
5231 // find bin with last labels
5232 // bin number is object ID in list of labels
5233 // therefore max bin number is number of bins of the deflated histograms
5234 TIter next(axis->GetLabels());
5235 TObject *obj;
5236 Int_t nbins = 0;
5237 while ((obj = next())) {
5238 Int_t ibin = obj->GetUniqueID();
5239 if (ibin > nbins) nbins = ibin;
5240 }
5241 if (nbins < 1) nbins = 1;
5242
5243 // Do nothing in case it was the last bin
5244 if (nbins==axis->GetNbins()) return;
5245
5246 TH1 *hold = (TH1*)IsA()->New();
5247 R__ASSERT(hold);
5248 hold->SetDirectory(nullptr);
5249 Copy(*hold);
5250
5251 Bool_t timedisp = axis->GetTimeDisplay();
5252 Double_t xmin = axis->GetXmin();
5253 Double_t xmax = axis->GetBinUpEdge(nbins);
5254 if (xmax <= xmin) xmax = xmin +nbins;
5255 axis->SetRange(0,0);
5256 axis->Set(nbins,xmin,xmax);
5257 SetBinsLength(-1); // reset the number of cells
5258 Int_t errors = fSumw2.fN;
5259 if (errors) fSumw2.Set(fNcells);
5260 axis->SetTimeDisplay(timedisp);
5261 // reset histogram content
5262 Reset("ICE");
5263
5264 //now loop on all bins and refill
5265 // NOTE that if the bins without labels have content
5266 // it will be put in the underflow/overflow.
5267 // For this reason we use AddBinContent method
5268 Double_t oldEntries = fEntries;
5269 Int_t bin,binx,biny,binz;
5270 for (bin=0; bin < hold->fNcells; ++bin) {
5271 hold->GetBinXYZ(bin,binx,biny,binz);
5272 Int_t ibin = GetBin(binx,biny,binz);
5273 Double_t cu = hold->RetrieveBinContent(bin);
5274 AddBinContent(ibin,cu);
5275 if (errors) {
5276 fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5277 }
5278 }
5279 fEntries = oldEntries;
5280 delete hold;
5281}
5282
5283////////////////////////////////////////////////////////////////////////////////
5284/// Double the number of bins for axis.
5285/// Refill histogram.
5286/// This function is called by TAxis::FindBin(const char *label)
5287
5289{
5290 Int_t iaxis = AxisChoice(ax);
5291 TAxis *axis = nullptr;
5292 if (iaxis == 1) axis = GetXaxis();
5293 if (iaxis == 2) axis = GetYaxis();
5294 if (iaxis == 3) axis = GetZaxis();
5295 if (!axis) return;
5296
5297 TH1 *hold = (TH1*)IsA()->New();
5298 hold->SetDirectory(nullptr);
5299 Copy(*hold);
5300 hold->ResetBit(kMustCleanup);
5301
5302 Bool_t timedisp = axis->GetTimeDisplay();
5303 Int_t nbins = axis->GetNbins();
5304 Double_t xmin = axis->GetXmin();
5305 Double_t xmax = axis->GetXmax();
5306 xmax = xmin + 2*(xmax-xmin);
5307 axis->SetRange(0,0);
5308 // double the bins and recompute ncells
5309 axis->Set(2*nbins,xmin,xmax);
5310 SetBinsLength(-1);
5311 Int_t errors = fSumw2.fN;
5312 if (errors) fSumw2.Set(fNcells);
5313 axis->SetTimeDisplay(timedisp);
5314
5315 Reset("ICE"); // reset content and error
5316
5317 //now loop on all bins and refill
5318 Double_t oldEntries = fEntries;
5319 Int_t bin,ibin,binx,biny,binz;
5320 for (ibin =0; ibin < hold->fNcells; ibin++) {
5321 // get the binx,y,z values . The x-y-z (axis) bin values will stay the same between new-old after the expanding
5322 hold->GetBinXYZ(ibin,binx,biny,binz);
5323 bin = GetBin(binx,biny,binz);
5324
5325 // underflow and overflow will be cleaned up because their meaning has been altered
5326 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5327 continue;
5328 }
5329 else {
5330 AddBinContent(bin, hold->RetrieveBinContent(ibin));
5331 if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5332 }
5333 }
5334 fEntries = oldEntries;
5335 delete hold;
5336}
5337
5338////////////////////////////////////////////////////////////////////////////////
5339/// Sort bins with labels or set option(s) to draw axis with labels
5340/// \param[in] option
5341/// - "a" sort by alphabetic order
5342/// - ">" sort by decreasing values
5343/// - "<" sort by increasing values
5344/// - "h" draw labels horizontal
5345/// - "v" draw labels vertical
5346/// - "u" draw labels up (end of label right adjusted)
5347/// - "d" draw labels down (start of label left adjusted)
5348///
5349/// In case not all bins have labels sorting will work only in the case
5350/// the first `n` consecutive bins have all labels and sorting will be performed on
5351/// those label bins.
5352///
5353/// \param[in] ax axis
5354
5356{
5357 Int_t iaxis = AxisChoice(ax);
5358 TAxis *axis = nullptr;
5359 if (iaxis == 1)
5360 axis = GetXaxis();
5361 if (iaxis == 2)
5362 axis = GetYaxis();
5363 if (iaxis == 3)
5364 axis = GetZaxis();
5365 if (!axis)
5366 return;
5367 THashList *labels = axis->GetLabels();
5368 if (!labels) {
5369 Warning("LabelsOption", "Axis %s has no labels!",axis->GetName());
5370 return;
5371 }
5372 TString opt = option;
5373 opt.ToLower();
5374 Int_t iopt = -1;
5375 if (opt.Contains("h")) {
5380 iopt = 0;
5381 }
5382 if (opt.Contains("v")) {
5387 iopt = 1;
5388 }
5389 if (opt.Contains("u")) {
5390 axis->SetBit(TAxis::kLabelsUp);
5394 iopt = 2;
5395 }
5396 if (opt.Contains("d")) {
5401 iopt = 3;
5402 }
5403 Int_t sort = -1;
5404 if (opt.Contains("a"))
5405 sort = 0;
5406 if (opt.Contains(">"))
5407 sort = 1;
5408 if (opt.Contains("<"))
5409 sort = 2;
5410 if (sort < 0) {
5411 if (iopt < 0)
5412 Error("LabelsOption", "%s is an invalid label placement option!",opt.Data());
5413 return;
5414 }
5415
5416 // Code works only if first n bins have labels if we uncomment following line
5417 // but we don't want to support this special case
5418 // Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5419
5420 // support only cases where each bin has a labels (should be when axis is alphanumeric)
5421 Int_t n = labels->GetSize();
5422 if (n != axis->GetNbins()) {
5423 // check if labels are all consecutive and starts from the first bin
5424 // in that case the current code will work fine
5425 Int_t firstLabelBin = axis->GetNbins()+1;
5426 Int_t lastLabelBin = -1;
5427 for (Int_t i = 0; i < n; ++i) {
5428 Int_t bin = labels->At(i)->GetUniqueID();
5429 if (bin < firstLabelBin) firstLabelBin = bin;
5430 if (bin > lastLabelBin) lastLabelBin = bin;
5431 }
5432 if (firstLabelBin != 1 || lastLabelBin-firstLabelBin +1 != n) {
5433 Error("LabelsOption", "%s of Histogram %s contains bins without labels. Sorting will not work correctly - return",
5434 axis->GetName(), GetName());
5435 return;
5436 }
5437 // case where label bins are consecutive starting from first bin will work
5438 // calling before a TH1::LabelsDeflate() will avoid this error message
5439 Warning("LabelsOption", "axis %s of Histogram %s has extra following bins without labels. Sorting will work only for first label bins",
5440 axis->GetName(), GetName());
5441 }
5442 std::vector<Int_t> a(n);
5443 std::vector<Int_t> b(n);
5444
5445
5446 Int_t i, j, k;
5447 std::vector<Double_t> cont;
5448 std::vector<Double_t> errors2;
5449 THashList *labold = new THashList(labels->GetSize(), 1);
5450 TIter nextold(labels);
5451 TObject *obj = nullptr;
5452 labold->AddAll(labels);
5453 labels->Clear();
5454
5455 // delete buffer if it is there since bins will be reordered.
5456 if (fBuffer)
5457 BufferEmpty(1);
5458
5459 if (sort > 0) {
5460 //---sort by values of bins
5461 if (GetDimension() == 1) {
5462 cont.resize(n);
5463 if (fSumw2.fN)
5464 errors2.resize(n);
5465 for (i = 0; i < n; i++) {
5466 cont[i] = RetrieveBinContent(i + 1);
5467 if (!errors2.empty())
5468 errors2[i] = GetBinErrorSqUnchecked(i + 1);
5469 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5470 a[i] = i;
5471 }
5472 if (sort == 1)
5473 TMath::Sort(n, cont.data(), a.data(), kTRUE); // sort by decreasing values
5474 else
5475 TMath::Sort(n, cont.data(), a.data(), kFALSE); // sort by increasing values
5476 for (i = 0; i < n; i++) {
5477 // use UpdateBinCOntent to not screw up histogram entries
5478 UpdateBinContent(i + 1, cont[b[a[i]] - 1]); // b[a[i]] returns bin number. .we need to subtract 1
5479 if (gDebug)
5480 Info("LabelsOption","setting bin %d value %f from bin %d label %s at pos %d ",
5481 i+1,cont[b[a[i]] - 1],b[a[i]],labold->At(a[i])->GetName(),a[i]);
5482 if (!errors2.empty())
5483 fSumw2.fArray[i + 1] = errors2[b[a[i]] - 1];
5484 }
5485 for (i = 0; i < n; i++) {
5486 obj = labold->At(a[i]);
5487 labels->Add(obj);
5488 obj->SetUniqueID(i + 1);
5489 }
5490 } else if (GetDimension() == 2) {
5491 std::vector<Double_t> pcont(n + 2);
5492 Int_t nx = fXaxis.GetNbins() + 2;
5493 Int_t ny = fYaxis.GetNbins() + 2;
5494 cont.resize((nx + 2) * (ny + 2));
5495 if (fSumw2.fN)
5496 errors2.resize((nx + 2) * (ny + 2));
5497 for (i = 0; i < nx; i++) {
5498 for (j = 0; j < ny; j++) {
5499 Int_t bin = GetBin(i,j);
5500 cont[i + nx * j] = RetrieveBinContent(bin);
5501 if (!errors2.empty())
5502 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5503 if (axis == GetXaxis())
5504 k = i - 1;
5505 else
5506 k = j - 1;
5507 if (k >= 0 && k < n) { // we consider underflow/overflows in y for ordering the bins
5508 pcont[k] += cont[i + nx * j];
5509 a[k] = k;
5510 }
5511 }
5512 }
5513 if (sort == 1)
5514 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5515 else
5516 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5517 for (i = 0; i < n; i++) {
5518 // iterate on old label list to find corresponding bin match
5519 TIter next(labold);
5520 UInt_t bin = a[i] + 1;
5521 while ((obj = next())) {
5522 if (obj->GetUniqueID() == (UInt_t)bin)
5523 break;
5524 else
5525 obj = nullptr;
5526 }
5527 if (!obj) {
5528 // this should not really happen
5529 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5530 return;
5531 }
5532
5533 labels->Add(obj);
5534 if (gDebug)
5535 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from order " << a[i] << " bin "
5536 << b[a[i]] << "content " << pcont[a[i]] << std::endl;
5537 }
5538 // need to set here new ordered labels - otherwise loop before does not work since labold and labels list
5539 // contain same objects
5540 for (i = 0; i < n; i++) {
5541 labels->At(i)->SetUniqueID(i + 1);
5542 }
5543 // set now the bin contents
5544 if (axis == GetXaxis()) {
5545 for (i = 0; i < n; i++) {
5546 Int_t ix = a[i] + 1;
5547 for (j = 0; j < ny; j++) {
5548 Int_t bin = GetBin(i + 1, j);
5549 UpdateBinContent(bin, cont[ix + nx * j]);
5550 if (!errors2.empty())
5551 fSumw2.fArray[bin] = errors2[ix + nx * j];
5552 }
5553 }
5554 } else {
5555 // using y axis
5556 for (i = 0; i < nx; i++) {
5557 for (j = 0; j < n; j++) {
5558 Int_t iy = a[j] + 1;
5559 Int_t bin = GetBin(i, j + 1);
5560 UpdateBinContent(bin, cont[i + nx * iy]);
5561 if (!errors2.empty())
5562 fSumw2.fArray[bin] = errors2[i + nx * iy];
5563 }
5564 }
5565 }
5566 } else {
5567 // sorting histograms: 3D case
5568 std::vector<Double_t> pcont(n + 2);
5569 Int_t nx = fXaxis.GetNbins() + 2;
5570 Int_t ny = fYaxis.GetNbins() + 2;
5571 Int_t nz = fZaxis.GetNbins() + 2;
5572 Int_t l = 0;
5573 cont.resize((nx + 2) * (ny + 2) * (nz + 2));
5574 if (fSumw2.fN)
5575 errors2.resize((nx + 2) * (ny + 2) * (nz + 2));
5576 for (i = 0; i < nx; i++) {
5577 for (j = 0; j < ny; j++) {
5578 for (k = 0; k < nz; k++) {
5579 Int_t bin = GetBin(i,j,k);
5581 if (axis == GetXaxis())
5582 l = i - 1;
5583 else if (axis == GetYaxis())
5584 l = j - 1;
5585 else
5586 l = k - 1;
5587 if (l >= 0 && l < n) { // we consider underflow/overflows in y for ordering the bins
5588 pcont[l] += c;
5589 a[l] = l;
5590 }
5591 cont[i + nx * (j + ny * k)] = c;
5592 if (!errors2.empty())
5593 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5594 }
5595 }
5596 }
5597 if (sort == 1)
5598 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5599 else
5600 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5601 for (i = 0; i < n; i++) {
5602 // iterate on the old label list to find corresponding bin match
5603 TIter next(labold);
5604 UInt_t bin = a[i] + 1;
5605 obj = nullptr;
5606 while ((obj = next())) {
5607 if (obj->GetUniqueID() == (UInt_t)bin) {
5608 break;
5609 }
5610 else
5611 obj = nullptr;
5612 }
5613 if (!obj) {
5614 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5615 return;
5616 }
5617 labels->Add(obj);
5618 if (gDebug)
5619 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from bin " << a[i] << "content "
5620 << pcont[a[i]] << std::endl;
5621 }
5622
5623 // need to set here new ordered labels - otherwise loop before does not work since labold and llabels list
5624 // contain same objects
5625 for (i = 0; i < n; i++) {
5626 labels->At(i)->SetUniqueID(i + 1);
5627 }
5628 // set now the bin contents
5629 if (axis == GetXaxis()) {
5630 for (i = 0; i < n; i++) {
5631 Int_t ix = a[i] + 1;
5632 for (j = 0; j < ny; j++) {
5633 for (k = 0; k < nz; k++) {
5634 Int_t bin = GetBin(i + 1, j, k);
5635 UpdateBinContent(bin, cont[ix + nx * (j + ny * k)]);
5636 if (!errors2.empty())
5637 fSumw2.fArray[bin] = errors2[ix + nx * (j + ny * k)];
5638 }
5639 }
5640 }
5641 } else if (axis == GetYaxis()) {
5642 // using y axis
5643 for (i = 0; i < nx; i++) {
5644 for (j = 0; j < n; j++) {
5645 Int_t iy = a[j] + 1;
5646 for (k = 0; k < nz; k++) {
5647 Int_t bin = GetBin(i, j + 1, k);
5648 UpdateBinContent(bin, cont[i + nx * (iy + ny * k)]);
5649 if (!errors2.empty())
5650 fSumw2.fArray[bin] = errors2[i + nx * (iy + ny * k)];
5651 }
5652 }
5653 }
5654 } else {
5655 // using z axis
5656 for (i = 0; i < nx; i++) {
5657 for (j = 0; j < ny; j++) {
5658 for (k = 0; k < n; k++) {
5659 Int_t iz = a[k] + 1;
5660 Int_t bin = GetBin(i, j , k +1);
5661 UpdateBinContent(bin, cont[i + nx * (j + ny * iz)]);
5662 if (!errors2.empty())
5663 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * iz)];
5664 }
5665 }
5666 }
5667 }
5668 }
5669 } else {
5670 //---alphabetic sort
5671 // sort labels using vector of strings and TMath::Sort
5672 // I need to array because labels order in list is not necessary that of the bins
5673 std::vector<std::string> vecLabels(n);
5674 for (i = 0; i < n; i++) {
5675 vecLabels[i] = labold->At(i)->GetName();
5676 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5677 a[i] = i;
5678 }
5679 // sort in ascending order for strings
5680 TMath::Sort(n, vecLabels.data(), a.data(), kFALSE);
5681 // set the new labels
5682 for (i = 0; i < n; i++) {
5683 TObject *labelObj = labold->At(a[i]);
5684 labels->Add(labold->At(a[i]));
5685 // set the corresponding bin. NB bin starts from 1
5686 labelObj->SetUniqueID(i + 1);
5687 if (gDebug)
5688 std::cout << "bin " << i + 1 << " setting new labels for axis " << labold->At(a[i])->GetName() << " from "
5689 << b[a[i]] << std::endl;
5690 }
5691
5692 if (GetDimension() == 1) {
5693 cont.resize(n + 2);
5694 if (fSumw2.fN)
5695 errors2.resize(n + 2);
5696 for (i = 0; i < n; i++) {
5697 cont[i] = RetrieveBinContent(b[a[i]]);
5698 if (!errors2.empty())
5699 errors2[i] = GetBinErrorSqUnchecked(b[a[i]]);
5700 }
5701 for (i = 0; i < n; i++) {
5702 UpdateBinContent(i + 1, cont[i]);
5703 if (!errors2.empty())
5704 fSumw2.fArray[i+1] = errors2[i];
5705 }
5706 } else if (GetDimension() == 2) {
5707 Int_t nx = fXaxis.GetNbins() + 2;
5708 Int_t ny = fYaxis.GetNbins() + 2;
5709 cont.resize(nx * ny);
5710 if (fSumw2.fN)
5711 errors2.resize(nx * ny);
5712 // copy old bin contents and then set to new ordered bins
5713 // N.B. bin in histograms starts from 1, but in y we consider under/overflows
5714 for (i = 0; i < nx; i++) {
5715 for (j = 0; j < ny; j++) { // ny is nbins+2
5716 Int_t bin = GetBin(i, j);
5717 cont[i + nx * j] = RetrieveBinContent(bin);
5718 if (!errors2.empty())
5719 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5720 }
5721 }
5722 if (axis == GetXaxis()) {
5723 for (i = 0; i < n; i++) {
5724 for (j = 0; j < ny; j++) {
5725 Int_t bin = GetBin(i + 1 , j);
5726 UpdateBinContent(bin, cont[b[a[i]] + nx * j]);
5727 if (!errors2.empty())
5728 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * j];
5729 }
5730 }
5731 } else {
5732 for (i = 0; i < nx; i++) {
5733 for (j = 0; j < n; j++) {
5734 Int_t bin = GetBin(i, j + 1);
5735 UpdateBinContent(bin, cont[i + nx * b[a[j]]]);
5736 if (!errors2.empty())
5737 fSumw2.fArray[bin] = errors2[i + nx * b[a[j]]];
5738 }
5739 }
5740 }
5741 } else {
5742 // case of 3D (needs to be tested)
5743 Int_t nx = fXaxis.GetNbins() + 2;
5744 Int_t ny = fYaxis.GetNbins() + 2;
5745 Int_t nz = fZaxis.GetNbins() + 2;
5746 cont.resize(nx * ny * nz);
5747 if (fSumw2.fN)
5748 errors2.resize(nx * ny * nz);
5749 for (i = 0; i < nx; i++) {
5750 for (j = 0; j < ny; j++) {
5751 for (k = 0; k < nz; k++) {
5752 Int_t bin = GetBin(i, j, k);
5753 cont[i + nx * (j + ny * k)] = RetrieveBinContent(bin);
5754 if (!errors2.empty())
5755 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5756 }
5757 }
5758 }
5759 if (axis == GetXaxis()) {
5760 // labels on x axis
5761 for (i = 0; i < n; i++) { // for x we loop only on bins with the labels
5762 for (j = 0; j < ny; j++) {
5763 for (k = 0; k < nz; k++) {
5764 Int_t bin = GetBin(i + 1, j, k);
5765 UpdateBinContent(bin, cont[b[a[i]] + nx * (j + ny * k)]);
5766 if (!errors2.empty())
5767 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * (j + ny * k)];
5768 }
5769 }
5770 }
5771 } else if (axis == GetYaxis()) {
5772 // labels on y axis
5773 for (i = 0; i < nx; i++) {
5774 for (j = 0; j < n; j++) {
5775 for (k = 0; k < nz; k++) {
5776 Int_t bin = GetBin(i, j+1, k);
5777 UpdateBinContent(bin, cont[i + nx * (b[a[j]] + ny * k)]);
5778 if (!errors2.empty())
5779 fSumw2.fArray[bin] = errors2[i + nx * (b[a[j]] + ny * k)];
5780 }
5781 }
5782 }
5783 } else {
5784 // labels on z axis
5785 for (i = 0; i < nx; i++) {
5786 for (j = 0; j < ny; j++) {
5787 for (k = 0; k < n; k++) {
5788 Int_t bin = GetBin(i, j, k+1);
5789 UpdateBinContent(bin, cont[i + nx * (j + ny * b[a[k]])]);
5790 if (!errors2.empty())
5791 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * b[a[k]])];
5792 }
5793 }
5794 }
5795 }
5796 }
5797 }
5798 // need to set to zero the statistics if axis has been sorted
5799 // see for example TH3::PutStats for definition of s vector
5800 bool labelsAreSorted = kFALSE;
5801 for (i = 0; i < n; ++i) {
5802 if (a[i] != i) {
5803 labelsAreSorted = kTRUE;
5804 break;
5805 }
5806 }
5807 if (labelsAreSorted) {
5808 double s[TH1::kNstat];
5809 GetStats(s);
5810 if (iaxis == 1) {
5811 s[2] = 0; // fTsumwx
5812 s[3] = 0; // fTsumwx2
5813 s[6] = 0; // fTsumwxy
5814 s[9] = 0; // fTsumwxz
5815 } else if (iaxis == 2) {
5816 s[4] = 0; // fTsumwy
5817 s[5] = 0; // fTsumwy2
5818 s[6] = 0; // fTsumwxy
5819 s[10] = 0; // fTsumwyz
5820 } else if (iaxis == 3) {
5821 s[7] = 0; // fTsumwz
5822 s[8] = 0; // fTsumwz2
5823 s[9] = 0; // fTsumwxz
5824 s[10] = 0; // fTsumwyz
5825 }
5826 PutStats(s);
5827 }
5828 delete labold;
5829}
5830
5831////////////////////////////////////////////////////////////////////////////////
5832/// Test if two double are almost equal.
5833
5834static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5835{
5836 return TMath::Abs(a - b) < epsilon;
5837}
5838
5839////////////////////////////////////////////////////////////////////////////////
5840/// Test if a double is almost an integer.
5841
5842static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5843{
5844 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5846}
5847
5848////////////////////////////////////////////////////////////////////////////////
5849/// Test if the binning is equidistant.
5850
5851static inline bool IsEquidistantBinning(const TAxis& axis)
5852{
5853 // check if axis bin are equals
5854 if (!axis.GetXbins()->fN) return true; //
5855 // not able to check if there is only one axis entry
5856 bool isEquidistant = true;
5857 const Double_t firstBinWidth = axis.GetBinWidth(1);
5858 for (int i = 1; i < axis.GetNbins(); ++i) {
5859 const Double_t binWidth = axis.GetBinWidth(i);
5860 const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5861 isEquidistant &= match;
5862 if (!match)
5863 break;
5864 }
5865 return isEquidistant;
5866}
5867
5868////////////////////////////////////////////////////////////////////////////////
5869/// Same limits and bins.
5870
5871Bool_t TH1::SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2){
5872 return axis1.GetNbins() == axis2.GetNbins() &&
5873 TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
5874 TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
5875}
5876
5877////////////////////////////////////////////////////////////////////////////////
5878/// Finds new limits for the axis for the Merge function.
5879/// returns false if the limits are incompatible
5880
5881Bool_t TH1::RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
5882{
5883 if (SameLimitsAndNBins(destAxis, anAxis))
5884 return kTRUE;
5885
5886 if (!IsEquidistantBinning(destAxis) || !IsEquidistantBinning(anAxis))
5887 return kFALSE; // not equidistant user binning not supported
5888
5889 Double_t width1 = destAxis.GetBinWidth(0);
5890 Double_t width2 = anAxis.GetBinWidth(0);
5891 if (width1 == 0 || width2 == 0)
5892 return kFALSE; // no binning not supported
5893
5894 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
5895 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
5896 Double_t width = TMath::Max(width1, width2);
5897
5898 // check the bin size
5899 if (!AlmostInteger(width/width1) || !AlmostInteger(width/width2))
5900 return kFALSE;
5901
5902 // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
5903 // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
5904
5905
5906 // check the limits
5907 Double_t delta;
5908 delta = (destAxis.GetXmin() - xmin)/width1;
5909 if (!AlmostInteger(delta))
5910 xmin -= (TMath::Ceil(delta) - delta)*width1;
5911
5912 delta = (anAxis.GetXmin() - xmin)/width2;
5913 if (!AlmostInteger(delta))
5914 xmin -= (TMath::Ceil(delta) - delta)*width2;
5915
5916
5917 delta = (destAxis.GetXmin() - xmin)/width1;
5918 if (!AlmostInteger(delta))
5919 return kFALSE;
5920
5921
5922 delta = (xmax - destAxis.GetXmax())/width1;
5923 if (!AlmostInteger(delta))
5924 xmax += (TMath::Ceil(delta) - delta)*width1;
5925
5926
5927 delta = (xmax - anAxis.GetXmax())/width2;
5928 if (!AlmostInteger(delta))
5929 xmax += (TMath::Ceil(delta) - delta)*width2;
5930
5931
5932 delta = (xmax - destAxis.GetXmax())/width1;
5933 if (!AlmostInteger(delta))
5934 return kFALSE;
5935#ifdef DEBUG
5936 if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
5937 printf("TH1::RecomputeAxisLimits - Impossible\n");
5938 return kFALSE;
5939 }
5940#endif
5941
5942
5943 destAxis.Set(TMath::Nint((xmax - xmin)/width), xmin, xmax);
5944
5945 //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
5946
5947 return kTRUE;
5948}
5949
5950////////////////////////////////////////////////////////////////////////////////
5951/// Add all histograms in the collection to this histogram.
5952/// This function computes the min/max for the x axis,
5953/// compute a new number of bins, if necessary,
5954/// add bin contents, errors and statistics.
5955/// If all histograms have bin labels, bins with identical labels
5956/// will be merged, no matter what their order is.
5957/// If overflows are present and limits are different the function will fail.
5958/// The function returns the total number of entries in the result histogram
5959/// if the merge is successful, -1 otherwise.
5960///
5961/// Possible option:
5962/// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
5963/// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
5964/// (enabled by default) slows down the merging
5965///
5966/// IMPORTANT remark. The axis x may have different number
5967/// of bins and different limits, BUT the largest bin width must be
5968/// a multiple of the smallest bin width and the upper limit must also
5969/// be a multiple of the bin width.
5970/// Example:
5971///
5972/// ~~~ {.cpp}
5973/// void atest() {
5974/// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
5975/// TH1F *h2 = new TH1F("h2","h2",220,0,110);
5976/// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
5977/// TRandom r;
5978/// for (Int_t i=0;i<10000;i++) {
5979/// h1->Fill(r.Gaus(-55,10));
5980/// h2->Fill(r.Gaus(55,10));
5981/// h3->Fill(r.Gaus(0,10));
5982/// }
5983///
5984/// TList *list = new TList;
5985/// list->Add(h1);
5986/// list->Add(h2);
5987/// list->Add(h3);
5988/// TH1F *h = (TH1F*)h1->Clone("h");
5989/// h->Reset();
5990/// h->Merge(list);
5991/// h->Draw();
5992/// }
5993/// ~~~
5994
5996{
5997 if (!li) return 0;
5998 if (li->IsEmpty()) return (Long64_t) GetEntries();
5999
6000 // use TH1Merger class
6001 TH1Merger merger(*this,*li,opt);
6002 Bool_t ret = merger();
6003
6004 return (ret) ? GetEntries() : -1;
6005}
6006
6007
6008////////////////////////////////////////////////////////////////////////////////
6009/// Performs the operation:
6010///
6011/// `this = this*c1*f1`
6012///
6013/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
6014///
6015/// Only bins inside the function range are recomputed.
6016/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6017/// you should call Sumw2 before making this operation.
6018/// This is particularly important if you fit the histogram after TH1::Multiply
6019///
6020/// The function return kFALSE if the Multiply operation failed
6021
6023{
6024 if (!f1) {
6025 Error("Multiply","Attempt to multiply by a non-existing function");
6026 return kFALSE;
6027 }
6028
6029 // delete buffer if it is there since it will become invalid
6030 if (fBuffer) BufferEmpty(1);
6031
6032 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
6033 Int_t ny = GetNbinsY() + 2;
6034 Int_t nz = GetNbinsZ() + 2;
6035 if (fDimension < 2) ny = 1;
6036 if (fDimension < 3) nz = 1;
6037
6038 // reset min-maximum
6039 SetMinimum();
6040 SetMaximum();
6041
6042 // - Loop on bins (including underflows/overflows)
6043 Double_t xx[3];
6044 Double_t *params = nullptr;
6045 f1->InitArgs(xx,params);
6046
6047 for (Int_t binz = 0; binz < nz; ++binz) {
6048 xx[2] = fZaxis.GetBinCenter(binz);
6049 for (Int_t biny = 0; biny < ny; ++biny) {
6050 xx[1] = fYaxis.GetBinCenter(biny);
6051 for (Int_t binx = 0; binx < nx; ++binx) {
6052 xx[0] = fXaxis.GetBinCenter(binx);
6053 if (!f1->IsInside(xx)) continue;
6055 Int_t bin = binx + nx * (biny + ny *binz);
6056 Double_t cu = c1*f1->EvalPar(xx);
6057 if (TF1::RejectedPoint()) continue;
6058 UpdateBinContent(bin, RetrieveBinContent(bin) * cu);
6059 if (fSumw2.fN) {
6060 fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
6061 }
6062 }
6063 }
6064 }
6065 ResetStats();
6066 return kTRUE;
6067}
6068
6069////////////////////////////////////////////////////////////////////////////////
6070/// Multiply this histogram by h1.
6071///
6072/// `this = this*h1`
6073///
6074/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6075/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
6076/// if not already set.
6077///
6078/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6079/// you should call Sumw2 before making this operation.
6080/// This is particularly important if you fit the histogram after TH1::Multiply
6081///
6082/// The function return kFALSE if the Multiply operation failed
6083
6084Bool_t TH1::Multiply(const TH1 *h1)
6085{
6086 if (!h1) {
6087 Error("Multiply","Attempt to multiply by a non-existing histogram");
6088 return kFALSE;
6089 }
6090
6091 // delete buffer if it is there since it will become invalid
6092 if (fBuffer) BufferEmpty(1);
6093
6094 try {
6095 CheckConsistency(this,h1);
6096 } catch(DifferentNumberOfBins&) {
6097 Error("Multiply","Attempt to multiply histograms with different number of bins");
6098 return kFALSE;
6099 } catch(DifferentAxisLimits&) {
6100 Warning("Multiply","Attempt to multiply histograms with different axis limits");
6101 } catch(DifferentBinLimits&) {
6102 Warning("Multiply","Attempt to multiply histograms with different bin limits");
6103 } catch(DifferentLabels&) {
6104 Warning("Multiply","Attempt to multiply histograms with different labels");
6105 }
6106
6107 // Create Sumw2 if h1 has Sumw2 set
6108 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
6109
6110 // - Reset min- maximum
6111 SetMinimum();
6112 SetMaximum();
6113
6114 // - Loop on bins (including underflows/overflows)
6115 for (Int_t i = 0; i < fNcells; ++i) {
6118 UpdateBinContent(i, c0 * c1);
6119 if (fSumw2.fN) {
6121 }
6122 }
6123 ResetStats();
6124 return kTRUE;
6125}
6126
6127////////////////////////////////////////////////////////////////////////////////
6128/// Replace contents of this histogram by multiplication of h1 by h2.
6129///
6130/// `this = (c1*h1)*(c2*h2)`
6131///
6132/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6133/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
6134/// if not already set.
6135///
6136/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6137/// you should call Sumw2 before making this operation.
6138/// This is particularly important if you fit the histogram after TH1::Multiply
6139///
6140/// The function return kFALSE if the Multiply operation failed
6141
6143{
6144 TString opt = option;
6145 opt.ToLower();
6146 // Bool_t binomial = kFALSE;
6147 // if (opt.Contains("b")) binomial = kTRUE;
6148 if (!h1 || !h2) {
6149 Error("Multiply","Attempt to multiply by a non-existing histogram");
6150 return kFALSE;
6151 }
6152
6153 // delete buffer if it is there since it will become invalid
6154 if (fBuffer) BufferEmpty(1);
6155
6156 try {
6157 CheckConsistency(h1,h2);
6158 CheckConsistency(this,h1);
6159 } catch(DifferentNumberOfBins&) {
6160 Error("Multiply","Attempt to multiply histograms with different number of bins");
6161 return kFALSE;
6162 } catch(DifferentAxisLimits&) {
6163 Warning("Multiply","Attempt to multiply histograms with different axis limits");
6164 } catch(DifferentBinLimits&) {
6165 Warning("Multiply","Attempt to multiply histograms with different bin limits");
6166 } catch(DifferentLabels&) {
6167 Warning("Multiply","Attempt to multiply histograms with different labels");
6168 }
6169
6170 // Create Sumw2 if h1 or h2 have Sumw2 set
6171 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
6172
6173 // - Reset min - maximum
6174 SetMinimum();
6175 SetMaximum();
6176
6177 // - Loop on bins (including underflows/overflows)
6178 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
6179 for (Int_t i = 0; i < fNcells; ++i) {
6181 Double_t b2 = h2->RetrieveBinContent(i);
6182 UpdateBinContent(i, c1 * b1 * c2 * b2);
6183 if (fSumw2.fN) {
6184 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
6185 }
6186 }
6187 ResetStats();
6188 return kTRUE;
6189}
6190
6191////////////////////////////////////////////////////////////////////////////////
6192/// Control routine to paint any kind of histograms.
6193///
6194/// This function is automatically called by TCanvas::Update.
6195/// (see TH1::Draw for the list of options)
6196
6198{
6200
6201 if (fPainter) {
6202 if (option && strlen(option) > 0)
6204 else
6206 }
6207}
6208
6209////////////////////////////////////////////////////////////////////////////////
6210/// Rebin this histogram
6211///
6212/// #### case 1 xbins=0
6213///
6214/// If newname is blank (default), the current histogram is modified and
6215/// a pointer to it is returned.
6216///
6217/// If newname is not blank, the current histogram is not modified, and a
6218/// new histogram is returned which is a Clone of the current histogram
6219/// with its name set to newname.
6220///
6221/// The parameter ngroup indicates how many bins of this have to be merged
6222/// into one bin of the result.
6223///
6224/// If the original histogram has errors stored (via Sumw2), the resulting
6225/// histograms has new errors correctly calculated.
6226///
6227/// examples: if h1 is an existing TH1F histogram with 100 bins
6228///
6229/// ~~~ {.cpp}
6230/// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
6231/// h1->Rebin(5); //merges five bins in one in h1
6232/// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
6233/// // merging 5 bins of h1 in one bin
6234/// ~~~
6235///
6236/// NOTE: If ngroup is not an exact divider of the number of bins,
6237/// the top limit of the rebinned histogram is reduced
6238/// to the upper edge of the last bin that can make a complete
6239/// group. The remaining bins are added to the overflow bin.
6240/// Statistics will be recomputed from the new bin contents.
6241///
6242/// #### case 2 xbins!=0
6243///
6244/// A new histogram is created (you should specify newname).
6245/// The parameter ngroup is the number of variable size bins in the created histogram.
6246/// The array xbins must contain ngroup+1 elements that represent the low-edges
6247/// of the bins.
6248/// If the original histogram has errors stored (via Sumw2), the resulting
6249/// histograms has new errors correctly calculated.
6250///
6251/// NOTE: The bin edges specified in xbins should correspond to bin edges
6252/// in the original histogram. If a bin edge in the new histogram is
6253/// in the middle of a bin in the original histogram, all entries in
6254/// the split bin in the original histogram will be transfered to the
6255/// lower of the two possible bins in the new histogram. This is
6256/// probably not what you want. A warning message is emitted in this
6257/// case
6258///
6259/// examples: if h1 is an existing TH1F histogram with 100 bins
6260///
6261/// ~~~ {.cpp}
6262/// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
6263/// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
6264/// ~~~
6265
6266TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
6267{
6268 Int_t nbins = fXaxis.GetNbins();
6271 if ((ngroup <= 0) || (ngroup > nbins)) {
6272 Error("Rebin", "Illegal value of ngroup=%d",ngroup);
6273 return nullptr;
6274 }
6275
6276 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
6277 Error("Rebin", "Operation valid on 1-D histograms only");
6278 return nullptr;
6279 }
6280 if (!newname && xbins) {
6281 Error("Rebin","if xbins is specified, newname must be given");
6282 return nullptr;
6283 }
6284
6285 Int_t newbins = nbins/ngroup;
6286 if (!xbins) {
6287 Int_t nbg = nbins/ngroup;
6288 if (nbg*ngroup != nbins) {
6289 Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
6290 }
6291 }
6292 else {
6293 // in the case that xbins is given (rebinning in variable bins), ngroup is
6294 // the new number of bins and number of grouped bins is not constant.
6295 // when looping for setting the contents for the new histogram we
6296 // need to loop on all bins of original histogram. Then set ngroup=nbins
6297 newbins = ngroup;
6298 ngroup = nbins;
6299 }
6300
6301 // Save old bin contents into a new array
6302 Double_t entries = fEntries;
6303 Double_t *oldBins = new Double_t[nbins+2];
6304 Int_t bin, i;
6305 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
6306 Double_t *oldErrors = nullptr;
6307 if (fSumw2.fN != 0) {
6308 oldErrors = new Double_t[nbins+2];
6309 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
6310 }
6311 // rebin will not include underflow/overflow if new axis range is larger than old axis range
6312 if (xbins) {
6313 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
6314 Warning("Rebin","underflow entries will not be used when rebinning");
6315 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
6316 Warning("Rebin","overflow entries will not be used when rebinning");
6317 }
6318
6319
6320 // create a clone of the old histogram if newname is specified
6321 TH1 *hnew = this;
6322 if ((newname && strlen(newname) > 0) || xbins) {
6323 hnew = (TH1*)Clone(newname);
6324 }
6325
6326 //reset can extend bit to avoid an axis extension in SetBinContent
6327 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
6328
6329 // save original statistics
6330 Double_t stat[kNstat];
6331 GetStats(stat);
6332 bool resetStat = false;
6333 // change axis specs and rebuild bin contents array::RebinAx
6334 if(!xbins && (newbins*ngroup != nbins)) {
6335 xmax = fXaxis.GetBinUpEdge(newbins*ngroup);
6336 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
6337 }
6338 // save the TAttAxis members (reset by SetBins)
6339 Int_t nDivisions = fXaxis.GetNdivisions();
6340 Color_t axisColor = fXaxis.GetAxisColor();
6341 Color_t labelColor = fXaxis.GetLabelColor();
6342 Style_t labelFont = fXaxis.GetLabelFont();
6343 Float_t labelOffset = fXaxis.GetLabelOffset();
6344 Float_t labelSize = fXaxis.GetLabelSize();
6345 Float_t tickLength = fXaxis.GetTickLength();
6346 Float_t titleOffset = fXaxis.GetTitleOffset();
6347 Float_t titleSize = fXaxis.GetTitleSize();
6348 Color_t titleColor = fXaxis.GetTitleColor();
6349 Style_t titleFont = fXaxis.GetTitleFont();
6350
6351 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
6352 Double_t *bins = new Double_t[newbins+1];
6353 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
6354 hnew->SetBins(newbins,bins); //this also changes errors array (if any)
6355 delete [] bins;
6356 } else if (xbins) {
6357 hnew->SetBins(newbins,xbins);
6358 } else {
6359 hnew->SetBins(newbins,xmin,xmax);
6360 }
6361
6362 // Restore axis attributes
6363 fXaxis.SetNdivisions(nDivisions);
6364 fXaxis.SetAxisColor(axisColor);
6365 fXaxis.SetLabelColor(labelColor);
6366 fXaxis.SetLabelFont(labelFont);
6367 fXaxis.SetLabelOffset(labelOffset);
6368 fXaxis.SetLabelSize(labelSize);
6369 fXaxis.SetTickLength(tickLength);
6370 fXaxis.SetTitleOffset(titleOffset);
6371 fXaxis.SetTitleSize(titleSize);
6372 fXaxis.SetTitleColor(titleColor);
6373 fXaxis.SetTitleFont(titleFont);
6374
6375 // copy merged bin contents (ignore under/overflows)
6376 // Start merging only once the new lowest edge is reached
6377 Int_t startbin = 1;
6378 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
6379 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
6380 startbin++;
6381 }
6382 Int_t oldbin = startbin;
6383 Double_t binContent, binError;
6384 for (bin = 1;bin<=newbins;bin++) {
6385 binContent = 0;
6386 binError = 0;
6387 Int_t imax = ngroup;
6388 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6389 // check bin edges for the cases when we provide an array of bins
6390 // be careful in case bins can have zero width
6391 if (xbins && !TMath::AreEqualAbs(fXaxis.GetBinLowEdge(oldbin),
6392 hnew->GetXaxis()->GetBinLowEdge(bin),
6393 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6394 {
6395 Warning("Rebin","Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6396 }
6397 for (i=0;i<ngroup;i++) {
6398 if( (oldbin+i > nbins) ||
6399 ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6400 imax = i;
6401 break;
6402 }
6403 binContent += oldBins[oldbin+i];
6404 if (oldErrors) binError += oldErrors[oldbin+i]*oldErrors[oldbin+i];
6405 }
6406 hnew->SetBinContent(bin,binContent);
6407 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6408 oldbin += imax;
6409 }
6410
6411 // sum underflow and overflow contents until startbin
6412 binContent = 0;
6413 binError = 0;
6414 for (i = 0; i < startbin; ++i) {
6415 binContent += oldBins[i];
6416 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6417 }
6418 hnew->SetBinContent(0,binContent);
6419 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6420 // sum overflow
6421 binContent = 0;
6422 binError = 0;
6423 for (i = oldbin; i <= nbins+1; ++i) {
6424 binContent += oldBins[i];
6425 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6426 }
6427 hnew->SetBinContent(newbins+1,binContent);
6428 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6429
6430 hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6431
6432 // restore statistics and entries modified by SetBinContent
6433 hnew->SetEntries(entries);
6434 if (!resetStat) hnew->PutStats(stat);
6435 delete [] oldBins;
6436 if (oldErrors) delete [] oldErrors;
6437 return hnew;
6438}
6439
6440////////////////////////////////////////////////////////////////////////////////
6441/// finds new limits for the axis so that *point* is within the range and
6442/// the limits are compatible with the previous ones (see TH1::Merge).
6443/// new limits are put into *newMin* and *newMax* variables.
6444/// axis - axis whose limits are to be recomputed
6445/// point - point that should fit within the new axis limits
6446/// newMin - new minimum will be stored here
6447/// newMax - new maximum will be stored here.
6448/// false if failed (e.g. if the initial axis limits are wrong
6449/// or the new range is more than \f$ 2^{64} \f$ times the old one).
6450
6451Bool_t TH1::FindNewAxisLimits(const TAxis* axis, const Double_t point, Double_t& newMin, Double_t &newMax)
6452{
6453 Double_t xmin = axis->GetXmin();
6454 Double_t xmax = axis->GetXmax();
6455 if (xmin >= xmax) return kFALSE;
6456 Double_t range = xmax-xmin;
6457
6458 //recompute new axis limits by doubling the current range
6459 Int_t ntimes = 0;
6460 while (point < xmin) {
6461 if (ntimes++ > 64)
6462 return kFALSE;
6463 xmin = xmin - range;
6464 range *= 2;
6465 }
6466 while (point >= xmax) {
6467 if (ntimes++ > 64)
6468 return kFALSE;
6469 xmax = xmax + range;
6470 range *= 2;
6471 }
6472 newMin = xmin;
6473 newMax = xmax;
6474 // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6475 // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6476
6477 return kTRUE;
6478}
6479
6480////////////////////////////////////////////////////////////////////////////////
6481/// Histogram is resized along axis such that x is in the axis range.
6482/// The new axis limits are recomputed by doubling iteratively
6483/// the current axis range until the specified value x is within the limits.
6484/// The algorithm makes a copy of the histogram, then loops on all bins
6485/// of the old histogram to fill the extended histogram.
6486/// Takes into account errors (Sumw2) if any.
6487/// The algorithm works for 1-d, 2-D and 3-D histograms.
6488/// The axis must be extendable before invoking this function.
6489/// Ex:
6490///
6491/// ~~~ {.cpp}
6492/// h->GetXaxis()->SetCanExtend(kTRUE);
6493/// ~~~
6494
6495void TH1::ExtendAxis(Double_t x, TAxis *axis)
6496{
6497 if (!axis->CanExtend()) return;
6498 if (TMath::IsNaN(x)) { // x may be a NaN
6500 return;
6501 }
6502
6503 if (axis->GetXmin() >= axis->GetXmax()) return;
6504 if (axis->GetNbins() <= 0) return;
6505
6507 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6508 return;
6509
6510 //save a copy of this histogram
6511 TH1 *hold = (TH1*)IsA()->New();
6512 hold->SetDirectory(nullptr);
6513 Copy(*hold);
6514 //set new axis limits
6515 axis->SetLimits(xmin,xmax);
6516
6517
6518 //now loop on all bins and refill
6519 Int_t errors = GetSumw2N();
6520
6521 Reset("ICE"); //reset only Integral, contents and Errors
6522
6523 int iaxis = 0;
6524 if (axis == &fXaxis) iaxis = 1;
6525 if (axis == &fYaxis) iaxis = 2;
6526 if (axis == &fZaxis) iaxis = 3;
6527 bool firstw = kTRUE;
6528 Int_t binx,biny, binz = 0;
6529 Int_t ix = 0,iy = 0,iz = 0;
6530 Double_t bx,by,bz;
6531 Int_t ncells = hold->GetNcells();
6532 for (Int_t bin = 0; bin < ncells; ++bin) {
6533 hold->GetBinXYZ(bin,binx,biny,binz);
6534 bx = hold->GetXaxis()->GetBinCenter(binx);
6535 ix = fXaxis.FindFixBin(bx);
6536 if (fDimension > 1) {
6537 by = hold->GetYaxis()->GetBinCenter(biny);
6538 iy = fYaxis.FindFixBin(by);
6539 if (fDimension > 2) {
6540 bz = hold->GetZaxis()->GetBinCenter(binz);
6541 iz = fZaxis.FindFixBin(bz);
6542 }
6543 }
6544 // exclude underflow/overflow
6545 double content = hold->RetrieveBinContent(bin);
6546 if (content == 0) continue;
6547 if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6548 if (firstw) {
6549 Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6550 " their content will be lost",GetName() );
6551 firstw= kFALSE;
6552 }
6553 continue;
6554 }
6555 Int_t ibin= GetBin(ix,iy,iz);
6556 AddBinContent(ibin, content);
6557 if (errors) {
6558 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6559 }
6560 }
6561 delete hold;
6562}
6563
6564////////////////////////////////////////////////////////////////////////////////
6565/// Recursively remove object from the list of functions
6566
6568{
6569 // Rely on TROOT::RecursiveRemove to take the readlock.
6570
6571 if (fFunctions) {
6573 }
6574}
6575
6576////////////////////////////////////////////////////////////////////////////////
6577/// Multiply this histogram by a constant c1.
6578///
6579/// `this = c1*this`
6580///
6581/// Note that both contents and errors (if any) are scaled.
6582/// This function uses the services of TH1::Add
6583///
6584/// IMPORTANT NOTE: Sumw2() is called automatically when scaling.
6585/// If you are not interested in the histogram statistics you can call
6586/// Sumw2(kFALSE) or use the option "nosw2"
6587///
6588/// One can scale a histogram such that the bins integral is equal to
6589/// the normalization parameter via TH1::Scale(Double_t norm), where norm
6590/// is the desired normalization divided by the integral of the histogram.
6591///
6592/// If option contains "width" the bin contents and errors are divided
6593/// by the bin width.
6594
6596{
6597
6598 TString opt = option; opt.ToLower();
6599 // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6600 if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6601 if (opt.Contains("width")) Add(this, this, c1, -1);
6602 else {
6603 if (fBuffer) BufferEmpty(1);
6604 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6605 if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6606 // update global histograms statistics
6607 Double_t s[kNstat] = {0};
6608 GetStats(s);
6609 for (Int_t i=0 ; i < kNstat; i++) {
6610 if (i == 1) s[i] = c1*c1*s[i];
6611 else s[i] = c1*s[i];
6612 }
6613 PutStats(s);
6614 SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6615 }
6616
6617 // if contours set, must also scale contours
6618 Int_t ncontours = GetContour();
6619 if (ncontours == 0) return;
6620 Double_t* levels = fContour.GetArray();
6621 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6622}
6623
6624////////////////////////////////////////////////////////////////////////////////
6625/// Returns true if all axes are extendable.
6626
6628{
6629 Bool_t canExtend = fXaxis.CanExtend();
6630 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6631 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6632
6633 return canExtend;
6634}
6635
6636////////////////////////////////////////////////////////////////////////////////
6637/// Make the histogram axes extendable / not extendable according to the bit mask
6638/// returns the previous bit mask specifying which axes are extendable
6639
6640UInt_t TH1::SetCanExtend(UInt_t extendBitMask)
6641{
6642 UInt_t oldExtendBitMask = kNoAxis;
6643
6644 if (fXaxis.CanExtend()) oldExtendBitMask |= kXaxis;
6645 if (extendBitMask & kXaxis) fXaxis.SetCanExtend(kTRUE);
6647
6648 if (GetDimension() > 1) {
6649 if (fYaxis.CanExtend()) oldExtendBitMask |= kYaxis;
6650 if (extendBitMask & kYaxis) fYaxis.SetCanExtend(kTRUE);
6652 }
6653
6654 if (GetDimension() > 2) {
6655 if (fZaxis.CanExtend()) oldExtendBitMask |= kZaxis;
6656 if (extendBitMask & kZaxis) fZaxis.SetCanExtend(kTRUE);
6658 }
6659
6660 return oldExtendBitMask;
6661}
6662
6663///////////////////////////////////////////////////////////////////////////////
6664/// Internal function used in TH1::Fill to see which axis is full alphanumeric,
6665/// i.e. can be extended and is alphanumeric
6667{
6668 UInt_t bitMask = kNoAxis;
6669 if (fXaxis.CanExtend() && fXaxis.IsAlphanumeric() ) bitMask |= kXaxis;
6671 bitMask |= kYaxis;
6673 bitMask |= kZaxis;
6674
6675 return bitMask;
6676}
6677
6678////////////////////////////////////////////////////////////////////////////////
6679/// Static function to set the default buffer size for automatic histograms.
6680/// When a histogram is created with one of its axis lower limit greater
6681/// or equal to its upper limit, the function SetBuffer is automatically
6682/// called with the default buffer size.
6683
6684void TH1::SetDefaultBufferSize(Int_t buffersize)
6685{
6686 fgBufferSize = buffersize > 0 ? buffersize : 0;
6687}
6688
6689////////////////////////////////////////////////////////////////////////////////
6690/// When this static function is called with `sumw2=kTRUE`, all new
6691/// histograms will automatically activate the storage
6692/// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6693
6694void TH1::SetDefaultSumw2(Bool_t sumw2)
6695{
6696 fgDefaultSumw2 = sumw2;
6697}
6698
6699////////////////////////////////////////////////////////////////////////////////
6700/// Change/set the title.
6701///
6702/// If title is in the form `stringt;stringx;stringy;stringz`
6703/// the histogram title is set to `stringt`, the x axis title to `stringx`,
6704/// the y axis title to `stringy`, and the z axis title to `stringz`.
6705///
6706/// To insert the character `;` in one of the titles, one should use `#;`
6707/// or `#semicolon`.
6708
6709void TH1::SetTitle(const char *title)
6710{
6711 fTitle = title;
6712 fTitle.ReplaceAll("#;",2,"#semicolon",10);
6713
6714 // Decode fTitle. It may contain X, Y and Z titles
6715 TString str1 = fTitle, str2;
6716 Int_t isc = str1.Index(";");
6717 Int_t lns = str1.Length();
6718
6719 if (isc >=0 ) {
6720 fTitle = str1(0,isc);
6721 str1 = str1(isc+1, lns);
6722 isc = str1.Index(";");
6723 if (isc >=0 ) {
6724 str2 = str1(0,isc);
6725 str2.ReplaceAll("#semicolon",10,";",1);
6726 fXaxis.SetTitle(str2.Data());
6727 lns = str1.Length();
6728 str1 = str1(isc+1, lns);
6729 isc = str1.Index(";");
6730 if (isc >=0 ) {
6731 str2 = str1(0,isc);
6732 str2.ReplaceAll("#semicolon",10,";",1);
6733 fYaxis.SetTitle(str2.Data());
6734 lns = str1.Length();
6735 str1 = str1(isc+1, lns);
6736 str1.ReplaceAll("#semicolon",10,";",1);
6737 fZaxis.SetTitle(str1.Data());
6738 } else {
6739 str1.ReplaceAll("#semicolon",10,";",1);
6740 fYaxis.SetTitle(str1.Data());
6741 }
6742 } else {
6743 str1.ReplaceAll("#semicolon",10,";",1);
6744 fXaxis.SetTitle(str1.Data());
6745 }
6746 }
6747
6748 fTitle.ReplaceAll("#semicolon",10,";",1);
6749
6750 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6751}
6752
6753////////////////////////////////////////////////////////////////////////////////
6754/// Smooth array xx, translation of Hbook routine `hsmoof.F`.
6755/// Based on algorithm 353QH twice presented by J. Friedman
6756/// in Proc.of the 1974 CERN School of Computing, Norway, 11-24 August, 1974.
6757
6758void TH1::SmoothArray(Int_t nn, Double_t *xx, Int_t ntimes)
6759{
6760 if (nn < 3 ) {
6761 ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6762 return;
6763 }
6764
6765 Int_t ii;
6766 Double_t hh[6] = {0,0,0,0,0,0};
6767
6768 std::vector<double> yy(nn);
6769 std::vector<double> zz(nn);
6770 std::vector<double> rr(nn);
6771
6772 for (Int_t pass=0;pass<ntimes;pass++) {
6773 // first copy original data into temp array
6774 std::copy(xx, xx+nn, zz.begin() );
6775
6776 for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6777
6778 // do 353 i.e. running median 3, 5, and 3 in a single loop
6779 for (int kk = 0; kk < 3; kk++) {
6780 std::copy(zz.begin(), zz.end(), yy.begin());
6781 int medianType = (kk != 1) ? 3 : 5;
6782 int ifirst = (kk != 1 ) ? 1 : 2;
6783 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6784 //nn2 = nn - ik - 1;
6785 // do all elements beside the first and last point for median 3
6786 // and first two and last 2 for median 5
6787 for ( ii = ifirst; ii < ilast; ii++) {
6788 assert(ii - ifirst >= 0);
6789 for (int jj = 0; jj < medianType; jj++) {
6790 hh[jj] = yy[ii - ifirst + jj ];
6791 }
6792 zz[ii] = TMath::Median(medianType, hh);
6793 }
6794
6795 if (kk == 0) { // first median 3
6796 // first point
6797 hh[0] = zz[1];
6798 hh[1] = zz[0];
6799 hh[2] = 3*zz[1] - 2*zz[2];
6800 zz[0] = TMath::Median(3, hh);
6801 // last point
6802 hh[0] = zz[nn - 2];
6803 hh[1] = zz[nn - 1];
6804 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6805 zz[nn - 1] = TMath::Median(3, hh);
6806 }
6807
6808 if (kk == 1) { // median 5
6809 for (ii = 0; ii < 3; ii++) {
6810 hh[ii] = yy[ii];
6811 }
6812 zz[1] = TMath::Median(3, hh);
6813 // last two points
6814 for (ii = 0; ii < 3; ii++) {
6815 hh[ii] = yy[nn - 3 + ii];
6816 }
6817 zz[nn - 2] = TMath::Median(3, hh);
6818 }
6819
6820 }
6821
6822 std::copy ( zz.begin(), zz.end(), yy.begin() );
6823
6824 // quadratic interpolation for flat segments
6825 for (ii = 2; ii < (nn - 2); ii++) {
6826 if (zz[ii - 1] != zz[ii]) continue;
6827 if (zz[ii] != zz[ii + 1]) continue;
6828 hh[0] = zz[ii - 2] - zz[ii];
6829 hh[1] = zz[ii + 2] - zz[ii];
6830 if (hh[0] * hh[1] <= 0) continue;
6831 int jk = 1;
6832 if ( TMath::Abs(hh[1]) > TMath::Abs(hh[0]) ) jk = -1;
6833 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6834 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6835 }
6836
6837 // running means
6838 //std::copy(zz.begin(), zz.end(), yy.begin());
6839 for (ii = 1; ii < nn - 1; ii++) {
6840 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6841 }
6842 zz[0] = yy[0];
6843 zz[nn - 1] = yy[nn - 1];
6844
6845 if (noent == 0) {
6846
6847 // save computed values
6848 std::copy(zz.begin(), zz.end(), rr.begin());
6849
6850 // COMPUTE residuals
6851 for (ii = 0; ii < nn; ii++) {
6852 zz[ii] = xx[ii] - zz[ii];
6853 }
6854 }
6855
6856 } // end loop on noent
6857
6858
6859 double xmin = TMath::MinElement(nn,xx);
6860 for (ii = 0; ii < nn; ii++) {
6861 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6862 // make smoothing defined positive - not better using 0 ?
6863 else xx[ii] = TMath::Max((rr[ii] + zz[ii]),0.0 );
6864 }
6865 }
6866}
6867
6868////////////////////////////////////////////////////////////////////////////////
6869/// Smooth bin contents of this histogram.
6870/// if option contains "R" smoothing is applied only to the bins
6871/// defined in the X axis range (default is to smooth all bins)
6872/// Bin contents are replaced by their smooth values.
6873/// Errors (if any) are not modified.
6874/// the smoothing procedure is repeated ntimes (default=1)
6875
6876void TH1::Smooth(Int_t ntimes, Option_t *option)
6877{
6878 if (fDimension != 1) {
6879 Error("Smooth","Smooth only supported for 1-d histograms");
6880 return;
6881 }
6882 Int_t nbins = fXaxis.GetNbins();
6883 if (nbins < 3) {
6884 Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
6885 return;
6886 }
6887
6888 // delete buffer if it is there since it will become invalid
6889 if (fBuffer) BufferEmpty(1);
6890
6891 Int_t firstbin = 1, lastbin = nbins;
6892 TString opt = option;
6893 opt.ToLower();
6894 if (opt.Contains("r")) {
6895 firstbin= fXaxis.GetFirst();
6896 lastbin = fXaxis.GetLast();
6897 }
6898 nbins = lastbin - firstbin + 1;
6899 Double_t *xx = new Double_t[nbins];
6900 Double_t nent = fEntries;
6901 Int_t i;
6902 for (i=0;i<nbins;i++) {
6903 xx[i] = RetrieveBinContent(i+firstbin);
6904 }
6905
6906 TH1::SmoothArray(nbins,xx,ntimes);
6907
6908 for (i=0;i<nbins;i++) {
6909 UpdateBinContent(i+firstbin,xx[i]);
6910 }
6911 fEntries = nent;
6912 delete [] xx;
6913
6914 if (gPad) gPad->Modified();
6915}
6916
6917////////////////////////////////////////////////////////////////////////////////
6918/// if flag=kTRUE, underflows and overflows are used by the Fill functions
6919/// in the computation of statistics (mean value, StdDev).
6920/// By default, underflows or overflows are not used.
6921
6922void TH1::StatOverflows(Bool_t flag)
6923{
6924 fgStatOverflows = flag;
6925}
6926
6927////////////////////////////////////////////////////////////////////////////////
6928/// Stream a class object.
6929
6930void TH1::Streamer(TBuffer &b)
6931{
6932 if (b.IsReading()) {
6933 UInt_t R__s, R__c;
6934 Version_t R__v = b.ReadVersion(&R__s, &R__c);
6935 if (fDirectory) fDirectory->Remove(this);
6936 fDirectory = nullptr;
6937 if (R__v > 2) {
6938 b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
6939
6941 fXaxis.SetParent(this);
6942 fYaxis.SetParent(this);
6943 fZaxis.SetParent(this);
6944 TIter next(fFunctions);
6945 TObject *obj;
6946 while ((obj=next())) {
6947 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
6948 }
6949 return;
6950 }
6951 //process old versions before automatic schema evolution
6956 b >> fNcells;
6957 fXaxis.Streamer(b);
6958 fYaxis.Streamer(b);
6959 fZaxis.Streamer(b);
6960 fXaxis.SetParent(this);
6961 fYaxis.SetParent(this);
6962 fZaxis.SetParent(this);
6963 b >> fBarOffset;
6964 b >> fBarWidth;
6965 b >> fEntries;
6966 b >> fTsumw;
6967 b >> fTsumw2;
6968 b >> fTsumwx;
6969 b >> fTsumwx2;
6970 if (R__v < 2) {
6971 Float_t maximum, minimum, norm;
6972 Float_t *contour=nullptr;
6973 b >> maximum; fMaximum = maximum;
6974 b >> minimum; fMinimum = minimum;
6975 b >> norm; fNormFactor = norm;
6976 Int_t n = b.ReadArray(contour);
6977 fContour.Set(n);
6978 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
6979 delete [] contour;
6980 } else {
6981 b >> fMaximum;
6982 b >> fMinimum;
6983 b >> fNormFactor;
6985 }
6986 fSumw2.Streamer(b);
6988 fFunctions->Delete();
6990 b.CheckByteCount(R__s, R__c, TH1::IsA());
6991
6992 } else {
6993 b.WriteClassBuffer(TH1::Class(),this);
6994 }
6995}
6996
6997////////////////////////////////////////////////////////////////////////////////
6998/// Print some global quantities for this histogram.
6999/// \param[in] option
7000/// - "base" is given, number of bins and ranges are also printed
7001/// - "range" is given, bin contents and errors are also printed
7002/// for all bins in the current range (default 1-->nbins)
7003/// - "all" is given, bin contents and errors are also printed
7004/// for all bins including under and overflows.
7005
7006void TH1::Print(Option_t *option) const
7007{
7008 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7009 printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
7010 TString opt = option;
7011 opt.ToLower();
7012 Int_t all;
7013 if (opt.Contains("all")) all = 0;
7014 else if (opt.Contains("range")) all = 1;
7015 else if (opt.Contains("base")) all = 2;
7016 else return;
7017
7018 Int_t bin, binx, biny, binz;
7019 Int_t firstx=0,lastx=0,firsty=0,lasty=0,firstz=0,lastz=0;
7020 if (all == 0) {
7021 lastx = fXaxis.GetNbins()+1;
7022 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
7023 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
7024 } else {
7025 firstx = fXaxis.GetFirst(); lastx = fXaxis.GetLast();
7026 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
7027 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
7028 }
7029
7030 if (all== 2) {
7031 printf(" Title = %s\n", GetTitle());
7032 printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
7033 if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
7034 if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
7035 printf("\n");
7036 return;
7037 }
7038
7039 Double_t w,e;
7040 Double_t x,y,z;
7041 if (fDimension == 1) {
7042 for (binx=firstx;binx<=lastx;binx++) {
7043 x = fXaxis.GetBinCenter(binx);
7044 w = RetrieveBinContent(binx);
7045 e = GetBinError(binx);
7046 if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
7047 else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
7048 }
7049 }
7050 if (fDimension == 2) {
7051 for (biny=firsty;biny<=lasty;biny++) {
7052 y = fYaxis.GetBinCenter(biny);
7053 for (binx=firstx;binx<=lastx;binx++) {
7054 bin = GetBin(binx,biny);
7055 x = fXaxis.GetBinCenter(binx);
7056 w = RetrieveBinContent(bin);
7057 e = GetBinError(bin);
7058 if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
7059 else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
7060 }
7061 }
7062 }
7063 if (fDimension == 3) {
7064 for (binz=firstz;binz<=lastz;binz++) {
7065 z = fZaxis.GetBinCenter(binz);
7066 for (biny=firsty;biny<=lasty;biny++) {
7067 y = fYaxis.GetBinCenter(biny);
7068 for (binx=firstx;binx<=lastx;binx++) {
7069 bin = GetBin(binx,biny,binz);
7070 x = fXaxis.GetBinCenter(binx);
7071 w = RetrieveBinContent(bin);
7072 e = GetBinError(bin);
7073 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);
7074 else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
7075 }
7076 }
7077 }
7078 }
7079}
7080
7081////////////////////////////////////////////////////////////////////////////////
7082/// Using the current bin info, recompute the arrays for contents and errors
7083
7084void TH1::Rebuild(Option_t *)
7085{
7086 SetBinsLength();
7087 if (fSumw2.fN) {
7089 }
7090}
7091
7092////////////////////////////////////////////////////////////////////////////////
7093/// Reset this histogram: contents, errors, etc.
7094/// \param[in] option
7095/// - if "ICE" is specified, resets only Integral, Contents and Errors.
7096/// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
7097/// This option is used
7098/// - if "M" is specified, resets also Minimum and Maximum
7099
7101{
7102 // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
7103 // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
7104
7105 TString opt = option;
7106 opt.ToUpper();
7107 fSumw2.Reset();
7108 if (fIntegral) {
7109 delete [] fIntegral;
7110 fIntegral = nullptr;
7111 }
7112
7113 if (opt.Contains("M")) {
7114 SetMinimum();
7115 SetMaximum();
7116 }
7117
7118 if (opt.Contains("ICE") && !opt.Contains("S")) return;
7119
7120 // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
7121 // But what is the sense of calling BufferEmpty() ? For making the axes ?
7122 // BufferEmpty will update contents that later will be
7123 // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
7124 // It may be needed for computing the axis limits....
7125 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
7126
7127 // need to reset also the statistics
7128 // (needs to be done after calling BufferEmpty() )
7129 fTsumw = 0;
7130 fTsumw2 = 0;
7131 fTsumwx = 0;
7132 fTsumwx2 = 0;
7133 fEntries = 0;
7134
7135 if (opt == "ICES") return;
7136
7137
7138 TObject *stats = fFunctions->FindObject("stats");
7139 fFunctions->Remove(stats);
7140 //special logic to support the case where the same object is
7141 //added multiple times in fFunctions.
7142 //This case happens when the same object is added with different
7143 //drawing modes
7144 TObject *obj;
7145 while ((obj = fFunctions->First())) {
7146 while(fFunctions->Remove(obj)) { }
7147 delete obj;
7148 }
7149 if(stats) fFunctions->Add(stats);
7150 fContour.Set(0);
7151}
7152
7153////////////////////////////////////////////////////////////////////////////////
7154/// Save primitive as a C++ statement(s) on output stream out
7155
7156void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
7157{
7158 // empty the buffer before if it exists
7159 if (fBuffer) BufferEmpty();
7160
7161 Bool_t nonEqiX = kFALSE;
7162 Bool_t nonEqiY = kFALSE;
7163 Bool_t nonEqiZ = kFALSE;
7164 Int_t i;
7165 static Int_t nxaxis = 0;
7166 static Int_t nyaxis = 0;
7167 static Int_t nzaxis = 0;
7168 TString sxaxis="xAxis",syaxis="yAxis",szaxis="zAxis";
7169
7170 // Check if the histogram has equidistant X bins or not. If not, we
7171 // create an array holding the bins.
7172 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
7173 nonEqiX = kTRUE;
7174 nxaxis++;
7175 sxaxis += nxaxis;
7176 out << " Double_t "<<sxaxis<<"[" << GetXaxis()->GetXbins()->fN
7177 << "] = {";
7178 for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
7179 if (i != 0) out << ", ";
7180 out << GetXaxis()->GetXbins()->fArray[i];
7181 }
7182 out << "}; " << std::endl;
7183 }
7184 // If the histogram is 2 or 3 dimensional, check if the histogram
7185 // has equidistant Y bins or not. If not, we create an array
7186 // holding the bins.
7187 if (fDimension > 1 && GetYaxis()->GetXbins()->fN &&
7188 GetYaxis()->GetXbins()->fArray) {
7189 nonEqiY = kTRUE;
7190 nyaxis++;
7191 syaxis += nyaxis;
7192 out << " Double_t "<<syaxis<<"[" << GetYaxis()->GetXbins()->fN
7193 << "] = {";
7194 for (i = 0; i < GetYaxis()->GetXbins()->fN; i++) {
7195 if (i != 0) out << ", ";
7196 out << GetYaxis()->GetXbins()->fArray[i];
7197 }
7198 out << "}; " << std::endl;
7199 }
7200 // IF the histogram is 3 dimensional, check if the histogram
7201 // has equidistant Z bins or not. If not, we create an array
7202 // holding the bins.
7203 if (fDimension > 2 && GetZaxis()->GetXbins()->fN &&
7204 GetZaxis()->GetXbins()->fArray) {
7205 nonEqiZ = kTRUE;
7206 nzaxis++;
7207 szaxis += nzaxis;
7208 out << " Double_t "<<szaxis<<"[" << GetZaxis()->GetXbins()->fN
7209 << "] = {";
7210 for (i = 0; i < GetZaxis()->GetXbins()->fN; i++) {
7211 if (i != 0) out << ", ";
7212 out << GetZaxis()->GetXbins()->fArray[i];
7213 }
7214 out << "}; " << std::endl;
7215 }
7216
7217 char quote = '"';
7218 out <<" "<<std::endl;
7219 out <<" "<< ClassName() <<" *";
7220
7221 // Histogram pointer has by default the histogram name with an incremental suffix.
7222 // If the histogram belongs to a graph or a stack the suffix is not added because
7223 // the graph and stack objects are not aware of this new name. Same thing if
7224 // the histogram is drawn with the option COLZ because the TPaletteAxis drawn
7225 // when this option is selected, does not know this new name either.
7226 TString opt = option;
7227 opt.ToLower();
7228 static Int_t hcounter = 0;
7229 TString histName = GetName();
7230 if ( !histName.Contains("Graph")
7231 && !histName.Contains("_stack_")
7232 && !opt.Contains("colz")) {
7233 hcounter++;
7234 histName += "__";
7235 histName += hcounter;
7236 }
7237 histName = gInterpreter-> MapCppName(histName);
7238 const char *hname = histName.Data();
7239 if (!strlen(hname)) hname = "unnamed";
7240 TString savedName = GetName();
7241 this->SetName(hname);
7242 TString t(GetTitle());
7243 t.ReplaceAll("\\","\\\\");
7244 t.ReplaceAll("\"","\\\"");
7245 out << hname << " = new " << ClassName() << "(" << quote
7246 << hname << quote << "," << quote<< t.Data() << quote
7247 << "," << GetXaxis()->GetNbins();
7248 if (nonEqiX)
7249 out << ", "<<sxaxis;
7250 else
7251 out << "," << GetXaxis()->GetXmin()
7252 << "," << GetXaxis()->GetXmax();
7253 if (fDimension > 1) {
7254 out << "," << GetYaxis()->GetNbins();
7255 if (nonEqiY)
7256 out << ", "<<syaxis;
7257 else
7258 out << "," << GetYaxis()->GetXmin()
7259 << "," << GetYaxis()->GetXmax();
7260 }
7261 if (fDimension > 2) {
7262 out << "," << GetZaxis()->GetNbins();
7263 if (nonEqiZ)
7264 out << ", "<<szaxis;
7265 else
7266 out << "," << GetZaxis()->GetXmin()
7267 << "," << GetZaxis()->GetXmax();
7268 }
7269 out << ");" << std::endl;
7270
7271 // save bin contents
7272 Int_t bin;
7273 for (bin=0;bin<fNcells;bin++) {
7274 Double_t bc = RetrieveBinContent(bin);
7275 if (bc) {
7276 out<<" "<<hname<<"->SetBinContent("<<bin<<","<<bc<<");"<<std::endl;
7277 }
7278 }
7279
7280 // save bin errors
7281 if (fSumw2.fN) {
7282 for (bin=0;bin<fNcells;bin++) {
7283 Double_t be = GetBinError(bin);
7284 if (be) {
7285 out<<" "<<hname<<"->SetBinError("<<bin<<","<<be<<");"<<std::endl;
7286 }
7287 }
7288 }
7289
7290 TH1::SavePrimitiveHelp(out, hname, option);
7291 this->SetName(savedName.Data());
7292}
7293
7294////////////////////////////////////////////////////////////////////////////////
7295/// Helper function for the SavePrimitive functions from TH1
7296/// or classes derived from TH1, eg TProfile, TProfile2D.
7297
7298void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
7299{
7300 char quote = '"';
7301 if (TMath::Abs(GetBarOffset()) > 1e-5) {
7302 out<<" "<<hname<<"->SetBarOffset("<<GetBarOffset()<<");"<<std::endl;
7303 }
7304 if (TMath::Abs(GetBarWidth()-1) > 1e-5) {
7305 out<<" "<<hname<<"->SetBarWidth("<<GetBarWidth()<<");"<<std::endl;
7306 }
7307 if (fMinimum != -1111) {
7308 out<<" "<<hname<<"->SetMinimum("<<fMinimum<<");"<<std::endl;
7309 }
7310 if (fMaximum != -1111) {
7311 out<<" "<<hname<<"->SetMaximum("<<fMaximum<<");"<<std::endl;
7312 }
7313 if (fNormFactor != 0) {
7314 out<<" "<<hname<<"->SetNormFactor("<<fNormFactor<<");"<<std::endl;
7315 }
7316 if (fEntries != 0) {
7317 out<<" "<<hname<<"->SetEntries("<<fEntries<<");"<<std::endl;
7318 }
7319 if (!fDirectory) {
7320 out<<" "<<hname<<"->SetDirectory(nullptr);"<<std::endl;
7321 }
7322 if (TestBit(kNoStats)) {
7323 out<<" "<<hname<<"->SetStats(0);"<<std::endl;
7324 }
7325 if (fOption.Length() != 0) {
7326 out<<" "<<hname<<"->SetOption("<<quote<<fOption.Data()<<quote<<");"<<std::endl;
7327 }
7328
7329 // save contour levels
7330 Int_t ncontours = GetContour();
7331 if (ncontours > 0) {
7332 out<<" "<<hname<<"->SetContour("<<ncontours<<");"<<std::endl;
7333 Double_t zlevel;
7334 for (Int_t bin=0;bin<ncontours;bin++) {
7335 if (gPad->GetLogz()) {
7336 zlevel = TMath::Power(10,GetContourLevel(bin));
7337 } else {
7338 zlevel = GetContourLevel(bin);
7339 }
7340 out<<" "<<hname<<"->SetContourLevel("<<bin<<","<<zlevel<<");"<<std::endl;
7341 }
7342 }
7343
7344 // save list of functions
7345 auto lnk = fFunctions->FirstLink();
7346 static Int_t funcNumber = 0;
7347 while (lnk) {
7348 auto obj = lnk->GetObject();
7349 obj->SavePrimitive(out, TString::Format("nodraw #%d\n",++funcNumber).Data());
7350 if (obj->InheritsFrom(TF1::Class())) {
7351 TString fname;
7352 fname.Form("%s%d",obj->GetName(),funcNumber);
7353 out << " " << fname << "->SetParent(" << hname << ");\n";
7354 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7355 << fname <<");"<<std::endl;
7356 } else if (obj->InheritsFrom("TPaveStats")) {
7357 out<<" "<<hname<<"->GetListOfFunctions()->Add(ptstats);"<<std::endl;
7358 out<<" ptstats->SetParent("<<hname<<");"<<std::endl;
7359 } else if (obj->InheritsFrom("TPolyMarker")) {
7360 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7361 <<"pmarker ,"<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
7362 } else {
7363 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7364 <<obj->GetName()
7365 <<","<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
7366 }
7367 lnk = lnk->Next();
7368 }
7369
7370 // save attributes
7371 SaveFillAttributes(out,hname,0,1001);
7372 SaveLineAttributes(out,hname,1,1,1);
7373 SaveMarkerAttributes(out,hname,1,1,1);
7374 fXaxis.SaveAttributes(out,hname,"->GetXaxis()");
7375 fYaxis.SaveAttributes(out,hname,"->GetYaxis()");
7376 fZaxis.SaveAttributes(out,hname,"->GetZaxis()");
7377 TString opt = option;
7378 opt.ToLower();
7379 if (!opt.Contains("nodraw")) {
7380 out<<" "<<hname<<"->Draw("
7381 <<quote<<option<<quote<<");"<<std::endl;
7382 }
7383}
7384
7385////////////////////////////////////////////////////////////////////////////////
7386/// Copy current attributes from/to current style
7387
7389{
7390 if (!gStyle) return;
7391 if (gStyle->IsReading()) {
7392 fXaxis.ResetAttAxis("X");
7393 fYaxis.ResetAttAxis("Y");
7394 fZaxis.ResetAttAxis("Z");
7405 Int_t dostat = gStyle->GetOptStat();
7406 if (gStyle->GetOptFit() && !dostat) dostat = 1000000001;
7407 SetStats(dostat);
7408 } else {
7420 }
7421 TIter next(GetListOfFunctions());
7422 TObject *obj;
7423
7424 while ((obj = next())) {
7425 obj->UseCurrentStyle();
7426 }
7427}
7428
7429////////////////////////////////////////////////////////////////////////////////
7430/// For axis = 1,2 or 3 returns the mean value of the histogram along
7431/// X,Y or Z axis.
7432///
7433/// For axis = 11, 12, 13 returns the standard error of the mean value
7434/// of the histogram along X, Y or Z axis
7435///
7436/// Note that the mean value/StdDev is computed using the bins in the currently
7437/// defined range (see TAxis::SetRange). By default the range includes
7438/// all bins from 1 to nbins included, excluding underflows and overflows.
7439/// To force the underflows and overflows in the computation, one must
7440/// call the static function TH1::StatOverflows(kTRUE) before filling
7441/// the histogram.
7442///
7443/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7444/// are calculated. By default, if no range has been set, the returned mean is
7445/// the (unbinned) one calculated at fill time. If a range has been set, however,
7446/// the mean is calculated using the bins in range, as described above; THIS
7447/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7448/// the range. To ensure that the returned mean (and all other statistics) is
7449/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7450/// See TH1::GetStats.
7451///
7452/// Return mean value of this histogram along the X axis.
7453
7454Double_t TH1::GetMean(Int_t axis) const
7455{
7456 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7457 Double_t stats[kNstat];
7458 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7459 GetStats(stats);
7460 if (stats[0] == 0) return 0;
7461 if (axis<4){
7462 Int_t ax[3] = {2,4,7};
7463 return stats[ax[axis-1]]/stats[0];
7464 } else {
7465 // mean error = StdDev / sqrt( Neff )
7466 Double_t stddev = GetStdDev(axis-10);
7468 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7469 }
7470}
7471
7472////////////////////////////////////////////////////////////////////////////////
7473/// Return standard error of mean of this histogram along the X axis.
7474///
7475/// Note that the mean value/StdDev is computed using the bins in the currently
7476/// defined range (see TAxis::SetRange). By default the range includes
7477/// all bins from 1 to nbins included, excluding underflows and overflows.
7478/// To force the underflows and overflows in the computation, one must
7479/// call the static function TH1::StatOverflows(kTRUE) before filling
7480/// the histogram.
7481///
7482/// Also note, that although the definition of standard error doesn't include the
7483/// assumption of normality, many uses of this feature implicitly assume it.
7484///
7485/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7486/// are calculated. By default, if no range has been set, the returned value is
7487/// the (unbinned) one calculated at fill time. If a range has been set, however,
7488/// the value is calculated using the bins in range, as described above; THIS
7489/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7490/// the range. To ensure that the returned value (and all other statistics) is
7491/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7492/// See TH1::GetStats.
7493
7495{
7496 return GetMean(axis+10);
7497}
7498
7499////////////////////////////////////////////////////////////////////////////////
7500/// Returns the Standard Deviation (Sigma).
7501/// The Sigma estimate is computed as
7502/// \f[
7503/// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7504/// \f]
7505/// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7506/// X, Y or Z axis
7507/// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7508/// X, Y or Z axis for Normal distribution
7509///
7510/// Note that the mean value/sigma is computed using the bins in the currently
7511/// defined range (see TAxis::SetRange). By default the range includes
7512/// all bins from 1 to nbins included, excluding underflows and overflows.
7513/// To force the underflows and overflows in the computation, one must
7514/// call the static function TH1::StatOverflows(kTRUE) before filling
7515/// the histogram.
7516///
7517/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7518/// are calculated. By default, if no range has been set, the returned standard
7519/// deviation is the (unbinned) one calculated at fill time. If a range has been
7520/// set, however, the standard deviation is calculated using the bins in range,
7521/// as described above; THIS IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use
7522/// TAxis::SetRange(0, 0) to unset the range. To ensure that the returned standard
7523/// deviation (and all other statistics) is always that of the binned data stored
7524/// in the histogram, call TH1::ResetStats. See TH1::GetStats.
7525
7526Double_t TH1::GetStdDev(Int_t axis) const
7527{
7528 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7529
7530 Double_t x, stddev2, stats[kNstat];
7531 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7532 GetStats(stats);
7533 if (stats[0] == 0) return 0;
7534 Int_t ax[3] = {2,4,7};
7535 Int_t axm = ax[axis%10 - 1];
7536 x = stats[axm]/stats[0];
7537 // for negative stddev (e.g. when having negative weights) - return stdev=0
7538 stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7539 if (axis<10)
7540 return TMath::Sqrt(stddev2);
7541 else {
7542 // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7543 // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7545 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7546 }
7547}
7548
7549////////////////////////////////////////////////////////////////////////////////
7550/// Return error of standard deviation estimation for Normal distribution
7551///
7552/// Note that the mean value/StdDev is computed using the bins in the currently
7553/// defined range (see TAxis::SetRange). By default the range includes
7554/// all bins from 1 to nbins included, excluding underflows and overflows.
7555/// To force the underflows and overflows in the computation, one must
7556/// call the static function TH1::StatOverflows(kTRUE) before filling
7557/// the histogram.
7558///
7559/// Value returned is standard deviation of sample standard deviation.
7560/// Note that it is an approximated value which is valid only in the case that the
7561/// original data distribution is Normal. The correct one would require
7562/// the 4-th momentum value, which cannot be accurately estimated from a histogram since
7563/// the x-information for all entries is not kept.
7564///
7565/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7566/// are calculated. By default, if no range has been set, the returned value is
7567/// the (unbinned) one calculated at fill time. If a range has been set, however,
7568/// the value is calculated using the bins in range, as described above; THIS
7569/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7570/// the range. To ensure that the returned value (and all other statistics) is
7571/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7572/// See TH1::GetStats.
7573
7575{
7576 return GetStdDev(axis+10);
7577}
7578
7579////////////////////////////////////////////////////////////////////////////////
7580/// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7581/// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7582/// of the histogram along x, y or z axis
7583///
7584///Note, that since third and fourth moment are not calculated
7585///at the fill time, skewness and its standard error are computed bin by bin
7586///
7587/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7588/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7589
7591{
7592
7593 if (axis > 0 && axis <= 3){
7594
7595 Double_t mean = GetMean(axis);
7596 Double_t stddev = GetStdDev(axis);
7597 Double_t stddev3 = stddev*stddev*stddev;
7598
7599 Int_t firstBinX = fXaxis.GetFirst();
7600 Int_t lastBinX = fXaxis.GetLast();
7601 Int_t firstBinY = fYaxis.GetFirst();
7602 Int_t lastBinY = fYaxis.GetLast();
7603 Int_t firstBinZ = fZaxis.GetFirst();
7604 Int_t lastBinZ = fZaxis.GetLast();
7605 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7608 if (firstBinX == 1) firstBinX = 0;
7609 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7610 }
7612 if (firstBinY == 1) firstBinY = 0;
7613 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7614 }
7616 if (firstBinZ == 1) firstBinZ = 0;
7617 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7618 }
7619 }
7620
7621 Double_t x = 0;
7622 Double_t sum=0;
7623 Double_t np=0;
7624 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7625 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7626 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7627 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7628 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7629 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7630 Double_t w = GetBinContent(binx,biny,binz);
7631 np+=w;
7632 sum+=w*(x-mean)*(x-mean)*(x-mean);
7633 }
7634 }
7635 }
7636 sum/=np*stddev3;
7637 return sum;
7638 }
7639 else if (axis > 10 && axis <= 13) {
7640 //compute standard error of skewness
7641 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7643 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7644 }
7645 else {
7646 Error("GetSkewness", "illegal value of parameter");
7647 return 0;
7648 }
7649}
7650
7651////////////////////////////////////////////////////////////////////////////////
7652/// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7653/// Kurtosis(gaussian(0, 1)) = 0.
7654/// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7655/// of the histogram along x, y or z axis
7656////
7657/// Note, that since third and fourth moment are not calculated
7658/// at the fill time, kurtosis and its standard error are computed bin by bin
7659///
7660/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7661/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7662
7664{
7665 if (axis > 0 && axis <= 3){
7666
7667 Double_t mean = GetMean(axis);
7668 Double_t stddev = GetStdDev(axis);
7669 Double_t stddev4 = stddev*stddev*stddev*stddev;
7670
7671 Int_t firstBinX = fXaxis.GetFirst();
7672 Int_t lastBinX = fXaxis.GetLast();
7673 Int_t firstBinY = fYaxis.GetFirst();
7674 Int_t lastBinY = fYaxis.GetLast();
7675 Int_t firstBinZ = fZaxis.GetFirst();
7676 Int_t lastBinZ = fZaxis.GetLast();
7677 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7680 if (firstBinX == 1) firstBinX = 0;
7681 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7682 }
7684 if (firstBinY == 1) firstBinY = 0;
7685 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7686 }
7688 if (firstBinZ == 1) firstBinZ = 0;
7689 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7690 }
7691 }
7692
7693 Double_t x = 0;
7694 Double_t sum=0;
7695 Double_t np=0;
7696 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7697 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7698 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7699 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7700 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7701 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7702 Double_t w = GetBinContent(binx,biny,binz);
7703 np+=w;
7704 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7705 }
7706 }
7707 }
7708 sum/=(np*stddev4);
7709 return sum-3;
7710
7711 } else if (axis > 10 && axis <= 13) {
7712 //compute standard error of skewness
7713 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7715 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7716 }
7717 else {
7718 Error("GetKurtosis", "illegal value of parameter");
7719 return 0;
7720 }
7721}
7722
7723////////////////////////////////////////////////////////////////////////////////
7724/// fill the array stats from the contents of this histogram
7725/// The array stats must be correctly dimensioned in the calling program.
7726///
7727/// ~~~ {.cpp}
7728/// stats[0] = sumw
7729/// stats[1] = sumw2
7730/// stats[2] = sumwx
7731/// stats[3] = sumwx2
7732/// ~~~
7733///
7734/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7735/// is simply a copy of the statistics quantities computed at filling time.
7736/// If a sub-range is specified, the function recomputes these quantities
7737/// from the bin contents in the current axis range.
7738///
7739/// IMPORTANT NOTE: This means that the returned statistics are context-dependent.
7740/// If TAxis::kAxisRange, the returned statistics are dependent on the binning;
7741/// otherwise, they are a copy of the histogram statistics computed at fill time,
7742/// which are unbinned by default (calling TH1::ResetStats forces them to use
7743/// binned statistics). You can reset TAxis::kAxisRange using TAxis::SetRange(0, 0).
7744///
7745/// Note that the mean value/StdDev is computed using the bins in the currently
7746/// defined range (see TAxis::SetRange). By default the range includes
7747/// all bins from 1 to nbins included, excluding underflows and overflows.
7748/// To force the underflows and overflows in the computation, one must
7749/// call the static function TH1::StatOverflows(kTRUE) before filling
7750/// the histogram.
7751
7752void TH1::GetStats(Double_t *stats) const
7753{
7754 if (fBuffer) ((TH1*)this)->BufferEmpty();
7755
7756 // Loop on bins (possibly including underflows/overflows)
7757 Int_t bin, binx;
7758 Double_t w,err;
7759 Double_t x;
7760 // identify the case of labels with extension of axis range
7761 // in this case the statistics in x does not make any sense
7762 Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && fXaxis.CanExtend() );
7763 // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7764 if ( (fTsumw == 0 && fEntries > 0) || fXaxis.TestBit(TAxis::kAxisRange) ) {
7765 for (bin=0;bin<4;bin++) stats[bin] = 0;
7766
7767 Int_t firstBinX = fXaxis.GetFirst();
7768 Int_t lastBinX = fXaxis.GetLast();
7769 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7771 if (firstBinX == 1) firstBinX = 0;
7772 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7773 }
7774 for (binx = firstBinX; binx <= lastBinX; binx++) {
7775 x = fXaxis.GetBinCenter(binx);
7776 //w = TMath::Abs(RetrieveBinContent(binx));
7777 // not sure what to do here if w < 0
7778 w = RetrieveBinContent(binx);
7779 err = TMath::Abs(GetBinError(binx));
7780 stats[0] += w;
7781 stats[1] += err*err;
7782 // statistics in x makes sense only for not labels histograms
7783 if (!labelHist) {
7784 stats[2] += w*x;
7785 stats[3] += w*x*x;
7786 }
7787 }
7788 // if (stats[0] < 0) {
7789 // // in case total is negative do something ??
7790 // stats[0] = 0;
7791 // }
7792 } else {
7793 stats[0] = fTsumw;
7794 stats[1] = fTsumw2;
7795 stats[2] = fTsumwx;
7796 stats[3] = fTsumwx2;
7797 }
7798}
7799
7800////////////////////////////////////////////////////////////////////////////////
7801/// Replace current statistics with the values in array stats
7802
7803void TH1::PutStats(Double_t *stats)
7804{
7805 fTsumw = stats[0];
7806 fTsumw2 = stats[1];
7807 fTsumwx = stats[2];
7808 fTsumwx2 = stats[3];
7809}
7810
7811////////////////////////////////////////////////////////////////////////////////
7812/// Reset the statistics including the number of entries
7813/// and replace with values calculated from bin content
7814///
7815/// The number of entries is set to the total bin content or (in case of weighted histogram)
7816/// to number of effective entries
7817///
7818/// Note that, by default, before calling this function, statistics are those
7819/// computed at fill time, which are unbinned. See TH1::GetStats.
7820
7821void TH1::ResetStats()
7822{
7823 Double_t stats[kNstat] = {0};
7824 fTsumw = 0;
7825 fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
7826 GetStats(stats);
7827 PutStats(stats);
7829 // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
7830 if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
7831}
7832
7833////////////////////////////////////////////////////////////////////////////////
7834/// Return the sum of weights excluding under/overflows.
7835
7837{
7838 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7839
7840 Int_t bin,binx,biny,binz;
7841 Double_t sum =0;
7842 for(binz=1; binz<=fZaxis.GetNbins(); binz++) {
7843 for(biny=1; biny<=fYaxis.GetNbins(); biny++) {
7844 for(binx=1; binx<=fXaxis.GetNbins(); binx++) {
7845 bin = GetBin(binx,biny,binz);
7846 sum += RetrieveBinContent(bin);
7847 }
7848 }
7849 }
7850 return sum;
7851}
7852
7853////////////////////////////////////////////////////////////////////////////////
7854///Return integral of bin contents. Only bins in the bins range are considered.
7855///
7856/// By default the integral is computed as the sum of bin contents in the range.
7857/// if option "width" is specified, the integral is the sum of
7858/// the bin contents multiplied by the bin width in x.
7859
7861{
7863}
7864
7865////////////////////////////////////////////////////////////////////////////////
7866/// Return integral of bin contents in range [binx1,binx2].
7867///
7868/// By default the integral is computed as the sum of bin contents in the range.
7869/// if option "width" is specified, the integral is the sum of
7870/// the bin contents multiplied by the bin width in x.
7871
7872Double_t TH1::Integral(Int_t binx1, Int_t binx2, Option_t *option) const
7873{
7874 double err = 0;
7875 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
7876}
7877
7878////////////////////////////////////////////////////////////////////////////////
7879/// Return integral of bin contents in range [binx1,binx2] and its error.
7880///
7881/// By default the integral is computed as the sum of bin contents in the range.
7882/// if option "width" is specified, the integral is the sum of
7883/// the bin contents multiplied by the bin width in x.
7884/// the error is computed using error propagation from the bin errors assuming that
7885/// all the bins are uncorrelated
7886
7887Double_t TH1::IntegralAndError(Int_t binx1, Int_t binx2, Double_t & error, Option_t *option) const
7888{
7889 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
7890}
7891
7892////////////////////////////////////////////////////////////////////////////////
7893/// Internal function compute integral and optionally the error between the limits
7894/// specified by the bin number values working for all histograms (1D, 2D and 3D)
7895
7896Double_t TH1::DoIntegral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error ,
7897 Option_t *option, Bool_t doError) const
7898{
7899 if (fBuffer) ((TH1*)this)->BufferEmpty();
7900
7901 Int_t nx = GetNbinsX() + 2;
7902 if (binx1 < 0) binx1 = 0;
7903 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
7904
7905 if (GetDimension() > 1) {
7906 Int_t ny = GetNbinsY() + 2;
7907 if (biny1 < 0) biny1 = 0;
7908 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
7909 } else {
7910 biny1 = 0; biny2 = 0;
7911 }
7912
7913 if (GetDimension() > 2) {
7914 Int_t nz = GetNbinsZ() + 2;
7915 if (binz1 < 0) binz1 = 0;
7916 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
7917 } else {
7918 binz1 = 0; binz2 = 0;
7919 }
7920
7921 // - Loop on bins in specified range
7922 TString opt = option;
7923 opt.ToLower();
7925 if (opt.Contains("width")) width = kTRUE;
7926
7927
7928 Double_t dx = 1., dy = .1, dz =.1;
7929 Double_t integral = 0;
7930 Double_t igerr2 = 0;
7931 for (Int_t binx = binx1; binx <= binx2; ++binx) {
7932 if (width) dx = fXaxis.GetBinWidth(binx);
7933 for (Int_t biny = biny1; biny <= biny2; ++biny) {
7934 if (width) dy = fYaxis.GetBinWidth(biny);
7935 for (Int_t binz = binz1; binz <= binz2; ++binz) {
7936 Int_t bin = GetBin(binx, biny, binz);
7937 Double_t dv = 0.0;
7938 if (width) {
7939 dz = fZaxis.GetBinWidth(binz);
7940 dv = dx * dy * dz;
7941 integral += RetrieveBinContent(bin) * dv;
7942 } else {
7943 integral += RetrieveBinContent(bin);
7944 }
7945 if (doError) {
7946 if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
7947 else igerr2 += GetBinErrorSqUnchecked(bin);
7948 }
7949 }
7950 }
7951 }
7952
7953 if (doError) error = TMath::Sqrt(igerr2);
7954 return integral;
7955}
7956
7957////////////////////////////////////////////////////////////////////////////////
7958/// Statistical test of compatibility in shape between
7959/// this histogram and h2, using the Anderson-Darling 2 sample test.
7960///
7961/// The AD 2 sample test formula are derived from the paper
7962/// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
7963///
7964/// The test is implemented in root in the ROOT::Math::GoFTest class
7965/// It is the same formula ( (6) in the paper), and also shown in
7966/// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
7967///
7968/// Binned data are considered as un-binned data
7969/// with identical observation happening in the bin center.
7970///
7971/// \param[in] h2 Pointer to 1D histogram
7972/// \param[in] option is a character string to specify options
7973/// - "D" Put out a line of "Debug" printout
7974/// - "T" Return the normalized A-D test statistic
7975///
7976/// - Note1: Underflow and overflow are not considered in the test
7977/// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
7978/// - Note3: The histograms are not required to have the same X axis
7979/// - Note4: The test works only for 1-dimensional histograms
7980
7982{
7983 Double_t advalue = 0;
7984 Double_t pvalue = AndersonDarlingTest(h2, advalue);
7985
7986 TString opt = option;
7987 opt.ToUpper();
7988 if (opt.Contains("D") ) {
7989 printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
7990 }
7991 if (opt.Contains("T") ) return advalue;
7992
7993 return pvalue;
7994}
7995
7996////////////////////////////////////////////////////////////////////////////////
7997/// Same function as above but returning also the test statistic value
7998
7999Double_t TH1::AndersonDarlingTest(const TH1 *h2, Double_t & advalue) const
8000{
8001 if (GetDimension() != 1 || h2->GetDimension() != 1) {
8002 Error("AndersonDarlingTest","Histograms must be 1-D");
8003 return -1;
8004 }
8005
8006 // empty the buffer. Probably we could add as an unbinned test
8007 if (fBuffer) ((TH1*)this)->BufferEmpty();
8008
8009 // use the BinData class
8010 ROOT::Fit::BinData data1;
8011 ROOT::Fit::BinData data2;
8012
8013 ROOT::Fit::FillData(data1, this, nullptr);
8014 ROOT::Fit::FillData(data2, h2, nullptr);
8015
8016 double pvalue;
8017 ROOT::Math::GoFTest::AndersonDarling2SamplesTest(data1,data2, pvalue,advalue);
8018
8019 return pvalue;
8020}
8021
8022////////////////////////////////////////////////////////////////////////////////
8023/// Statistical test of compatibility in shape between
8024/// this histogram and h2, using Kolmogorov test.
8025/// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
8026/// and not for binned data as in the case of the histogram (see NOTE 3 below).
8027/// So, before using this method blindly, read the NOTE 3.
8028///
8029/// Default: Ignore under- and overflow bins in comparison
8030///
8031/// \param[in] h2 histogram
8032/// \param[in] option is a character string to specify options
8033/// - "U" include Underflows in test (also for 2-dim)
8034/// - "O" include Overflows (also valid for 2-dim)
8035/// - "N" include comparison of normalizations
8036/// - "D" Put out a line of "Debug" printout
8037/// - "M" Return the Maximum Kolmogorov distance instead of prob
8038/// - "X" Run the pseudo experiments post-processor with the following procedure:
8039/// make pseudoexperiments based on random values from the parent distribution,
8040/// compare the KS distance of the pseudoexperiment to the parent
8041/// distribution, and count all the KS values above the value
8042/// obtained from the original data to Monte Carlo distribution.
8043/// The number of pseudo-experiments nEXPT is by default 1000, and
8044/// it can be changed by specifying the option as "X=number",
8045/// for example "X=10000" for 10000 toys.
8046/// The function returns the probability.
8047/// (thanks to Ben Kilminster to submit this procedure). Note that
8048/// this option "X" is much slower.
8049///
8050/// The returned function value is the probability of test
8051/// (much less than one means NOT compatible)
8052///
8053/// Code adapted by Rene Brun from original HBOOK routine HDIFF
8054///
8055/// NOTE1
8056/// A good description of the Kolmogorov test can be seen at:
8057/// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
8058///
8059/// NOTE2
8060/// see also alternative function TH1::Chi2Test
8061/// The Kolmogorov test is assumed to give better results than Chi2Test
8062/// in case of histograms with low statistics.
8063///
8064/// NOTE3 (Jan Conrad, Fred James)
8065/// "The returned value PROB is calculated such that it will be
8066/// uniformly distributed between zero and one for compatible histograms,
8067/// provided the data are not binned (or the number of bins is very large
8068/// compared with the number of events). Users who have access to unbinned
8069/// data and wish exact confidence levels should therefore not put their data
8070/// into histograms, but should call directly TMath::KolmogorovTest. On
8071/// the other hand, since TH1 is a convenient way of collecting data and
8072/// saving space, this function has been provided. However, the values of
8073/// PROB for binned data will be shifted slightly higher than expected,
8074/// depending on the effects of the binning. For example, when comparing two
8075/// uniform distributions of 500 events in 100 bins, the values of PROB,
8076/// instead of being exactly uniformly distributed between zero and one, have
8077/// a mean value of about 0.56. We can apply a useful
8078/// rule: As long as the bin width is small compared with any significant
8079/// physical effect (for example the experimental resolution) then the binning
8080/// cannot have an important effect. Therefore, we believe that for all
8081/// practical purposes, the probability value PROB is calculated correctly
8082/// provided the user is aware that:
8083///
8084/// 1. The value of PROB should not be expected to have exactly the correct
8085/// distribution for binned data.
8086/// 2. The user is responsible for seeing to it that the bin widths are
8087/// small compared with any physical phenomena of interest.
8088/// 3. The effect of binning (if any) is always to make the value of PROB
8089/// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
8090/// will assure that at most 5% of truly compatible histograms are rejected,
8091/// and usually somewhat less."
8092///
8093/// Note also that for GoF test of unbinned data ROOT provides also the class
8094/// ROOT::Math::GoFTest. The class has also method for doing one sample tests
8095/// (i.e. comparing the data with a given distribution).
8096
8098{
8099 TString opt = option;
8100 opt.ToUpper();
8101
8102 Double_t prob = 0;
8103 TH1 *h1 = (TH1*)this;
8104 if (h2 == nullptr) return 0;
8105 const TAxis *axis1 = h1->GetXaxis();
8106 const TAxis *axis2 = h2->GetXaxis();
8107 Int_t ncx1 = axis1->GetNbins();
8108 Int_t ncx2 = axis2->GetNbins();
8109
8110 // Check consistency of dimensions
8111 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
8112 Error("KolmogorovTest","Histograms must be 1-D\n");
8113 return 0;
8114 }
8115
8116 // Check consistency in number of channels
8117 if (ncx1 != ncx2) {
8118 Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
8119 return 0;
8120 }
8121
8122 // empty the buffer. Probably we could add as an unbinned test
8123 if (fBuffer) ((TH1*)this)->BufferEmpty();
8124
8125 // Check consistency in bin edges
8126 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
8127 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
8128 Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
8129 return 0;
8130 }
8131 }
8132
8133 Bool_t afunc1 = kFALSE;
8134 Bool_t afunc2 = kFALSE;
8135 Double_t sum1 = 0, sum2 = 0;
8136 Double_t ew1, ew2, w1 = 0, w2 = 0;
8137 Int_t bin;
8138 Int_t ifirst = 1;
8139 Int_t ilast = ncx1;
8140 // integral of all bins (use underflow/overflow if option)
8141 if (opt.Contains("U")) ifirst = 0;
8142 if (opt.Contains("O")) ilast = ncx1 +1;
8143 for (bin = ifirst; bin <= ilast; bin++) {
8144 sum1 += h1->RetrieveBinContent(bin);
8145 sum2 += h2->RetrieveBinContent(bin);
8146 ew1 = h1->GetBinError(bin);
8147 ew2 = h2->GetBinError(bin);
8148 w1 += ew1*ew1;
8149 w2 += ew2*ew2;
8150 }
8151 if (sum1 == 0) {
8152 Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
8153 return 0;
8154 }
8155 if (sum2 == 0) {
8156 Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
8157 return 0;
8158 }
8159
8160 // calculate the effective entries.
8161 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
8162 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
8163 Double_t esum1 = 0, esum2 = 0;
8164 if (w1 > 0)
8165 esum1 = sum1 * sum1 / w1;
8166 else
8167 afunc1 = kTRUE; // use later for calculating z
8168
8169 if (w2 > 0)
8170 esum2 = sum2 * sum2 / w2;
8171 else
8172 afunc2 = kTRUE; // use later for calculating z
8173
8174 if (afunc2 && afunc1) {
8175 Error("KolmogorovTest","Errors are zero for both histograms\n");
8176 return 0;
8177 }
8178
8179
8180 Double_t s1 = 1/sum1;
8181 Double_t s2 = 1/sum2;
8182
8183 // Find largest difference for Kolmogorov Test
8184 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
8185
8186 for (bin=ifirst;bin<=ilast;bin++) {
8187 rsum1 += s1*h1->RetrieveBinContent(bin);
8188 rsum2 += s2*h2->RetrieveBinContent(bin);
8189 dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
8190 }
8191
8192 // Get Kolmogorov probability
8193 Double_t z, prb1=0, prb2=0, prb3=0;
8194
8195 // case h1 is exact (has zero errors)
8196 if (afunc1)
8197 z = dfmax*TMath::Sqrt(esum2);
8198 // case h2 has zero errors
8199 else if (afunc2)
8200 z = dfmax*TMath::Sqrt(esum1);
8201 else
8202 // for comparison between two data sets
8203 z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
8204
8205 prob = TMath::KolmogorovProb(z);
8206
8207 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
8208 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
8209 // Combine probabilities for shape and normalization,
8210 prb1 = prob;
8211 Double_t d12 = esum1-esum2;
8212 Double_t chi2 = d12*d12/(esum1+esum2);
8213 prb2 = TMath::Prob(chi2,1);
8214 // see Eadie et al., section 11.6.2
8215 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
8216 else prob = 0;
8217 }
8218 // X option. Run Pseudo-experiments to determine NULL distribution of the
8219 // KS distance. We can find the probability from the number of pseudo-experiment that have a
8220 // KS distance larger than the one opbserved in the data.
8221 // We use the histogram with the largest statistics as a parent distribution for the NULL.
8222 // Note if one histogram has zero errors is considered as a function. In that case we use it
8223 // as parent distribution for the toys.
8224 //
8225 Int_t nEXPT = 1000;
8226 if (opt.Contains("X")) {
8227 // get number of pseudo-experiment of specified
8228 if (opt.Contains("X=")) {
8229 int numpos = opt.Index("X=") + 2; // 2 is length of X=
8230 int numlen = 0;
8231 int len = opt.Length();
8232 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) )
8233 numlen++;
8234 TString snum = opt(numpos,numlen);
8235 int num = atoi(snum.Data());
8236 if (num <= 0)
8237 Warning("KolmogorovTest","invalid number of toys given: %d - use 1000",num);
8238 else
8239 nEXPT = num;
8240 }
8241
8242 Double_t dSEXPT;
8243 TH1D hparent;
8244 // we cannot have afunc1 and func2 both True
8245 if (afunc1 || esum1 > esum2 ) h1->Copy(hparent);
8246 else h2->Copy(hparent);
8247
8248 // copy h1Expt from h1 and h2. It is just needed to get the correct binning
8249
8250
8251 if (hparent.GetMinimum() < 0.0) {
8252 // we need to create a new histogram
8253 // With negative bins we can't draw random samples in a meaningful way.
8254 Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
8255 "skewed. Reduce number of bins for histogram?");
8256 while (hparent.GetMinimum() < 0.0) {
8257 Int_t idx = hparent.GetMinimumBin();
8258 hparent.SetBinContent(idx, 0.0);
8259 }
8260 }
8261
8262 // make nEXPT experiments (this should be a parameter)
8263 prb3 = 0;
8264 TH1D h1Expt;
8265 h1->Copy(h1Expt);
8266 TH1D h2Expt;
8267 h1->Copy(h2Expt);
8268 // loop on pseudoexperients and generate the two histograms h1Expt and h2Expt according to the
8269 // parent distribution. In case the parent distribution is not an histogram but a function randomize only one
8270 // histogram
8271 for (Int_t i=0; i < nEXPT; i++) {
8272 if (!afunc1) {
8273 h1Expt.Reset();
8274 h1Expt.FillRandom(&hparent, (Int_t)esum1);
8275 }
8276 if (!afunc2) {
8277 h2Expt.Reset();
8278 h2Expt.FillRandom(&hparent, (Int_t)esum2);
8279 }
8280 // note we cannot have both afunc1 and afunc2 to be true
8281 if (afunc1)
8282 dSEXPT = hparent.KolmogorovTest(&h2Expt,"M");
8283 else if (afunc2)
8284 dSEXPT = hparent.KolmogorovTest(&h1Expt,"M");
8285 else
8286 dSEXPT = h1Expt.KolmogorovTest(&h2Expt,"M");
8287 // count number of cases toy KS distance (TS) is larger than oberved one
8288 if (dSEXPT>dfmax) prb3 += 1.0;
8289 }
8290 // compute p-value
8291 prb3 /= (Double_t)nEXPT;
8292 }
8293
8294
8295 // debug printout
8296 if (opt.Contains("D")) {
8297 printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
8298 printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
8299 printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
8300 if (opt.Contains("N"))
8301 printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
8302 if (opt.Contains("X"))
8303 printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
8304 }
8305 // This numerical error condition should never occur:
8306 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
8307 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
8308
8309 if(opt.Contains("M")) return dfmax;
8310 else if(opt.Contains("X")) return prb3;
8311 else return prob;
8312}
8313
8314////////////////////////////////////////////////////////////////////////////////
8315/// Replace bin contents by the contents of array content
8316
8317void TH1::SetContent(const Double_t *content)
8318{
8319 fEntries = fNcells;
8320 fTsumw = 0;
8321 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
8322}
8323
8324////////////////////////////////////////////////////////////////////////////////
8325/// Return contour values into array levels if pointer levels is non zero.
8326///
8327/// The function returns the number of contour levels.
8328/// see GetContourLevel to return one contour only
8329
8331{
8332 Int_t nlevels = fContour.fN;
8333 if (levels) {
8334 if (nlevels == 0) {
8335 nlevels = 20;
8336 SetContour(nlevels);
8337 } else {
8338 if (TestBit(kUserContour) == 0) SetContour(nlevels);
8339 }
8340 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
8341 }
8342 return nlevels;
8343}
8344
8345////////////////////////////////////////////////////////////////////////////////
8346/// Return value of contour number level.
8347/// Use GetContour to return the array of all contour levels
8348
8350{
8351 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
8352}
8353
8354////////////////////////////////////////////////////////////////////////////////
8355/// Return the value of contour number "level" in Pad coordinates.
8356/// ie: if the Pad is in log scale along Z it returns le log of the contour level
8357/// value. See GetContour to return the array of all contour levels
8358
8360{
8361 if (level <0 || level >= fContour.fN) return 0;
8362 Double_t zlevel = fContour.fArray[level];
8363
8364 // In case of user defined contours and Pad in log scale along Z,
8365 // fContour.fArray doesn't contain the log of the contour whereas it does
8366 // in case of equidistant contours.
8367 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
8368 if (zlevel <= 0) return 0;
8369 zlevel = TMath::Log10(zlevel);
8370 }
8371 return zlevel;
8372}
8373
8374////////////////////////////////////////////////////////////////////////////////
8375/// Set the maximum number of entries to be kept in the buffer.
8376
8377void TH1::SetBuffer(Int_t buffersize, Option_t * /*option*/)
8378{
8379 if (fBuffer) {
8380 BufferEmpty();
8381 delete [] fBuffer;
8382 fBuffer = nullptr;
8383 }
8384 if (buffersize <= 0) {
8385 fBufferSize = 0;
8386 return;
8387 }
8388 if (buffersize < 100) buffersize = 100;
8389 fBufferSize = 1 + buffersize*(fDimension+1);
8391 memset(fBuffer, 0, sizeof(Double_t)*fBufferSize);
8392}
8393
8394////////////////////////////////////////////////////////////////////////////////
8395/// Set the number and values of contour levels.
8396///
8397/// By default the number of contour levels is set to 20. The contours values
8398/// in the array "levels" should be specified in increasing order.
8399///
8400/// if argument levels = 0 or missing, equidistant contours are computed
8401
8402void TH1::SetContour(Int_t nlevels, const Double_t *levels)
8403{
8404 Int_t level;
8406 if (nlevels <=0 ) {
8407 fContour.Set(0);
8408 return;
8409 }
8410 fContour.Set(nlevels);
8411
8412 // - Contour levels are specified
8413 if (levels) {
8415 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
8416 } else {
8417 // - contour levels are computed automatically as equidistant contours
8418 Double_t zmin = GetMinimum();
8419 Double_t zmax = GetMaximum();
8420 if ((zmin == zmax) && (zmin != 0)) {
8421 zmax += 0.01*TMath::Abs(zmax);
8422 zmin -= 0.01*TMath::Abs(zmin);
8423 }
8424 Double_t dz = (zmax-zmin)/Double_t(nlevels);
8425 if (gPad && gPad->GetLogz()) {
8426 if (zmax <= 0) return;
8427 if (zmin <= 0) zmin = 0.001*zmax;
8428 zmin = TMath::Log10(zmin);
8429 zmax = TMath::Log10(zmax);
8430 dz = (zmax-zmin)/Double_t(nlevels);
8431 }
8432 for (level=0; level<nlevels; level++) {
8433 fContour.fArray[level] = zmin + dz*Double_t(level);
8434 }
8435 }
8436}
8437
8438////////////////////////////////////////////////////////////////////////////////
8439/// Set value for one contour level.
8440
8442{
8443 if (level < 0 || level >= fContour.fN) return;
8445 fContour.fArray[level] = value;
8446}
8447
8448////////////////////////////////////////////////////////////////////////////////
8449/// Return maximum value smaller than maxval of bins in the range,
8450/// unless the value has been overridden by TH1::SetMaximum,
8451/// in which case it returns that value. This happens, for example,
8452/// when the histogram is drawn and the y or z axis limits are changed
8453///
8454/// To get the maximum value of bins in the histogram regardless of
8455/// whether the value has been overridden (using TH1::SetMaximum), use
8456///
8457/// ~~~ {.cpp}
8458/// h->GetBinContent(h->GetMaximumBin())
8459/// ~~~
8460///
8461/// TH1::GetMaximumBin can be used to get the location of the maximum
8462/// value.
8463
8464Double_t TH1::GetMaximum(Double_t maxval) const
8465{
8466 if (fMaximum != -1111) return fMaximum;
8467
8468 // empty the buffer
8469 if (fBuffer) ((TH1*)this)->BufferEmpty();
8470
8471 Int_t bin, binx, biny, binz;
8472 Int_t xfirst = fXaxis.GetFirst();
8473 Int_t xlast = fXaxis.GetLast();
8474 Int_t yfirst = fYaxis.GetFirst();
8475 Int_t ylast = fYaxis.GetLast();
8476 Int_t zfirst = fZaxis.GetFirst();
8477 Int_t zlast = fZaxis.GetLast();
8478 Double_t maximum = -FLT_MAX, value;
8479 for (binz=zfirst;binz<=zlast;binz++) {
8480 for (biny=yfirst;biny<=ylast;biny++) {
8481 for (binx=xfirst;binx<=xlast;binx++) {
8482 bin = GetBin(binx,biny,binz);
8484 if (value > maximum && value < maxval) maximum = value;
8485 }
8486 }
8487 }
8488 return maximum;
8489}
8490
8491////////////////////////////////////////////////////////////////////////////////
8492/// Return location of bin with maximum value in the range.
8493///
8494/// TH1::GetMaximum can be used to get the maximum value.
8495
8497{
8498 Int_t locmax, locmay, locmaz;
8499 return GetMaximumBin(locmax, locmay, locmaz);
8500}
8501
8502////////////////////////////////////////////////////////////////////////////////
8503/// Return location of bin with maximum value in the range.
8504
8505Int_t TH1::GetMaximumBin(Int_t &locmax, Int_t &locmay, Int_t &locmaz) const
8506{
8507 // empty the buffer
8508 if (fBuffer) ((TH1*)this)->BufferEmpty();
8509
8510 Int_t bin, binx, biny, binz;
8511 Int_t locm;
8512 Int_t xfirst = fXaxis.GetFirst();
8513 Int_t xlast = fXaxis.GetLast();
8514 Int_t yfirst = fYaxis.GetFirst();
8515 Int_t ylast = fYaxis.GetLast();
8516 Int_t zfirst = fZaxis.GetFirst();
8517 Int_t zlast = fZaxis.GetLast();
8518 Double_t maximum = -FLT_MAX, value;
8519 locm = locmax = locmay = locmaz = 0;
8520 for (binz=zfirst;binz<=zlast;binz++) {
8521 for (biny=yfirst;biny<=ylast;biny++) {
8522 for (binx=xfirst;binx<=xlast;binx++) {
8523 bin = GetBin(binx,biny,binz);
8525 if (value > maximum) {
8526 maximum = value;
8527 locm = bin;
8528 locmax = binx;
8529 locmay = biny;
8530 locmaz = binz;
8531 }
8532 }
8533 }
8534 }
8535 return locm;
8536}
8537
8538////////////////////////////////////////////////////////////////////////////////
8539/// Return minimum value larger than minval of bins in the range,
8540/// unless the value has been overridden by TH1::SetMinimum,
8541/// in which case it returns that value. This happens, for example,
8542/// when the histogram is drawn and the y or z axis limits are changed
8543///
8544/// To get the minimum value of bins in the histogram regardless of
8545/// whether the value has been overridden (using TH1::SetMinimum), use
8546///
8547/// ~~~ {.cpp}
8548/// h->GetBinContent(h->GetMinimumBin())
8549/// ~~~
8550///
8551/// TH1::GetMinimumBin can be used to get the location of the
8552/// minimum value.
8553
8554Double_t TH1::GetMinimum(Double_t minval) const
8555{
8556 if (fMinimum != -1111) return fMinimum;
8557
8558 // empty the buffer
8559 if (fBuffer) ((TH1*)this)->BufferEmpty();
8560
8561 Int_t bin, binx, biny, binz;
8562 Int_t xfirst = fXaxis.GetFirst();
8563 Int_t xlast = fXaxis.GetLast();
8564 Int_t yfirst = fYaxis.GetFirst();
8565 Int_t ylast = fYaxis.GetLast();
8566 Int_t zfirst = fZaxis.GetFirst();
8567 Int_t zlast = fZaxis.GetLast();
8568 Double_t minimum=FLT_MAX, value;
8569 for (binz=zfirst;binz<=zlast;binz++) {
8570 for (biny=yfirst;biny<=ylast;biny++) {
8571 for (binx=xfirst;binx<=xlast;binx++) {
8572 bin = GetBin(binx,biny,binz);
8574 if (value < minimum && value > minval) minimum = value;
8575 }
8576 }
8577 }
8578 return minimum;
8579}
8580
8581////////////////////////////////////////////////////////////////////////////////
8582/// Return location of bin with minimum value in the range.
8583
8585{
8586 Int_t locmix, locmiy, locmiz;
8587 return GetMinimumBin(locmix, locmiy, locmiz);
8588}
8589
8590////////////////////////////////////////////////////////////////////////////////
8591/// Return location of bin with minimum value in the range.
8592
8593Int_t TH1::GetMinimumBin(Int_t &locmix, Int_t &locmiy, Int_t &locmiz) const
8594{
8595 // empty the buffer
8596 if (fBuffer) ((TH1*)this)->BufferEmpty();
8597
8598 Int_t bin, binx, biny, binz;
8599 Int_t locm;
8600 Int_t xfirst = fXaxis.GetFirst();
8601 Int_t xlast = fXaxis.GetLast();
8602 Int_t yfirst = fYaxis.GetFirst();
8603 Int_t ylast = fYaxis.GetLast();
8604 Int_t zfirst = fZaxis.GetFirst();
8605 Int_t zlast = fZaxis.GetLast();
8606 Double_t minimum = FLT_MAX, value;
8607 locm = locmix = locmiy = locmiz = 0;
8608 for (binz=zfirst;binz<=zlast;binz++) {
8609 for (biny=yfirst;biny<=ylast;biny++) {
8610 for (binx=xfirst;binx<=xlast;binx++) {
8611 bin = GetBin(binx,biny,binz);
8613 if (value < minimum) {
8614 minimum = value;
8615 locm = bin;
8616 locmix = binx;
8617 locmiy = biny;
8618 locmiz = binz;
8619 }
8620 }
8621 }
8622 }
8623 return locm;
8624}
8625
8626///////////////////////////////////////////////////////////////////////////////
8627/// Retrieve the minimum and maximum values in the histogram
8628///
8629/// This will not return a cached value and will always search the
8630/// histogram for the min and max values. The user can condition whether
8631/// or not to call this with the GetMinimumStored() and GetMaximumStored()
8632/// methods. If the cache is empty, then the value will be -1111. Users
8633/// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8634/// For example, the following recipe will make efficient use of this method
8635/// and the cached minimum and maximum values.
8636//
8637/// \code{.cpp}
8638/// Double_t currentMin = pHist->GetMinimumStored();
8639/// Double_t currentMax = pHist->GetMaximumStored();
8640/// if ((currentMin == -1111) || (currentMax == -1111)) {
8641/// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8642/// pHist->SetMinimum(currentMin);
8643/// pHist->SetMaximum(currentMax);
8644/// }
8645/// \endcode
8646///
8647/// \param min reference to variable that will hold found minimum value
8648/// \param max reference to variable that will hold found maximum value
8649
8650void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8651{
8652 // empty the buffer
8653 if (fBuffer) ((TH1*)this)->BufferEmpty();
8654
8655 Int_t bin, binx, biny, binz;
8656 Int_t xfirst = fXaxis.GetFirst();
8657 Int_t xlast = fXaxis.GetLast();
8658 Int_t yfirst = fYaxis.GetFirst();
8659 Int_t ylast = fYaxis.GetLast();
8660 Int_t zfirst = fZaxis.GetFirst();
8661 Int_t zlast = fZaxis.GetLast();
8662 min=TMath::Infinity();
8663 max=-TMath::Infinity();
8665 for (binz=zfirst;binz<=zlast;binz++) {
8666 for (biny=yfirst;biny<=ylast;biny++) {
8667 for (binx=xfirst;binx<=xlast;binx++) {
8668 bin = GetBin(binx,biny,binz);
8670 if (value < min) min = value;
8671 if (value > max) max = value;
8672 }
8673 }
8674 }
8675}
8676
8677////////////////////////////////////////////////////////////////////////////////
8678/// Redefine x axis parameters.
8679///
8680/// The X axis parameters are modified.
8681/// The bins content array is resized
8682/// if errors (Sumw2) the errors array is resized
8683/// The previous bin contents are lost
8684/// To change only the axis limits, see TAxis::SetRange
8685
8687{
8688 if (GetDimension() != 1) {
8689 Error("SetBins","Operation only valid for 1-d histograms");
8690 return;
8691 }
8692 fXaxis.SetRange(0,0);
8693 fXaxis.Set(nx,xmin,xmax);
8694 fYaxis.Set(1,0,1);
8695 fZaxis.Set(1,0,1);
8696 fNcells = nx+2;
8698 if (fSumw2.fN) {
8700 }
8701}
8702
8703////////////////////////////////////////////////////////////////////////////////
8704/// Redefine x axis parameters with variable bin sizes.
8705///
8706/// The X axis parameters are modified.
8707/// The bins content array is resized
8708/// if errors (Sumw2) the errors array is resized
8709/// The previous bin contents are lost
8710/// To change only the axis limits, see TAxis::SetRange
8711/// xBins is supposed to be of length nx+1
8712
8713void TH1::SetBins(Int_t nx, const Double_t *xBins)
8714{
8715 if (GetDimension() != 1) {
8716 Error("SetBins","Operation only valid for 1-d histograms");
8717 return;
8718 }
8719 fXaxis.SetRange(0,0);
8720 fXaxis.Set(nx,xBins);
8721 fYaxis.Set(1,0,1);
8722 fZaxis.Set(1,0,1);
8723 fNcells = nx+2;
8725 if (fSumw2.fN) {
8727 }
8728}
8729
8730////////////////////////////////////////////////////////////////////////////////
8731/// Redefine x and y axis parameters.
8732///
8733/// The X and Y axis parameters are modified.
8734/// The bins content array is resized
8735/// if errors (Sumw2) the errors array is resized
8736/// The previous bin contents are lost
8737/// To change only the axis limits, see TAxis::SetRange
8738
8740{
8741 if (GetDimension() != 2) {
8742 Error("SetBins","Operation only valid for 2-D histograms");
8743 return;
8744 }
8745 fXaxis.SetRange(0,0);
8746 fYaxis.SetRange(0,0);
8747 fXaxis.Set(nx,xmin,xmax);
8748 fYaxis.Set(ny,ymin,ymax);
8749 fZaxis.Set(1,0,1);
8750 fNcells = (nx+2)*(ny+2);
8752 if (fSumw2.fN) {
8754 }
8755}
8756
8757////////////////////////////////////////////////////////////////////////////////
8758/// Redefine x and y axis parameters with variable bin sizes.
8759///
8760/// The X and Y axis parameters are modified.
8761/// The bins content array is resized
8762/// if errors (Sumw2) the errors array is resized
8763/// The previous bin contents are lost
8764/// To change only the axis limits, see TAxis::SetRange
8765/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
8766
8767void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
8768{
8769 if (GetDimension() != 2) {
8770 Error("SetBins","Operation only valid for 2-D histograms");
8771 return;
8772 }
8773 fXaxis.SetRange(0,0);
8774 fYaxis.SetRange(0,0);
8775 fXaxis.Set(nx,xBins);
8776 fYaxis.Set(ny,yBins);
8777 fZaxis.Set(1,0,1);
8778 fNcells = (nx+2)*(ny+2);
8780 if (fSumw2.fN) {
8782 }
8783}
8784
8785////////////////////////////////////////////////////////////////////////////////
8786/// Redefine x, y and z axis parameters.
8787///
8788/// The X, Y and Z axis parameters are modified.
8789/// The bins content array is resized
8790/// if errors (Sumw2) the errors array is resized
8791/// The previous bin contents are lost
8792/// To change only the axis limits, see TAxis::SetRange
8793
8795{
8796 if (GetDimension() != 3) {
8797 Error("SetBins","Operation only valid for 3-D histograms");
8798 return;
8799 }
8800 fXaxis.SetRange(0,0);
8801 fYaxis.SetRange(0,0);
8802 fZaxis.SetRange(0,0);
8803 fXaxis.Set(nx,xmin,xmax);
8804 fYaxis.Set(ny,ymin,ymax);
8805 fZaxis.Set(nz,zmin,zmax);
8806 fNcells = (nx+2)*(ny+2)*(nz+2);
8808 if (fSumw2.fN) {
8810 }
8811}
8812
8813////////////////////////////////////////////////////////////////////////////////
8814/// Redefine x, y and z axis parameters with variable bin sizes.
8815///
8816/// The X, Y and Z axis parameters are modified.
8817/// The bins content array is resized
8818/// if errors (Sumw2) the errors array is resized
8819/// The previous bin contents are lost
8820/// To change only the axis limits, see TAxis::SetRange
8821/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
8822/// zBins is supposed to be of length nz+1
8823
8824void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
8825{
8826 if (GetDimension() != 3) {
8827 Error("SetBins","Operation only valid for 3-D histograms");
8828 return;
8829 }
8830 fXaxis.SetRange(0,0);
8831 fYaxis.SetRange(0,0);
8832 fZaxis.SetRange(0,0);
8833 fXaxis.Set(nx,xBins);
8834 fYaxis.Set(ny,yBins);
8835 fZaxis.Set(nz,zBins);
8836 fNcells = (nx+2)*(ny+2)*(nz+2);
8838 if (fSumw2.fN) {
8840 }
8841}
8842
8843////////////////////////////////////////////////////////////////////////////////
8844/// By default, when a histogram is created, it is added to the list
8845/// of histogram objects in the current directory in memory.
8846/// Remove reference to this histogram from current directory and add
8847/// reference to new directory dir. dir can be 0 in which case the
8848/// histogram does not belong to any directory.
8849///
8850/// Note that the directory is not a real property of the histogram and
8851/// it will not be copied when the histogram is copied or cloned.
8852/// If the user wants to have the copied (cloned) histogram in the same
8853/// directory, he needs to set again the directory using SetDirectory to the
8854/// copied histograms
8855
8857{
8858 if (fDirectory == dir) return;
8859 if (fDirectory) fDirectory->Remove(this);
8860 fDirectory = dir;
8861 if (fDirectory) {
8863 fDirectory->Append(this);
8864 }
8865}
8866
8867////////////////////////////////////////////////////////////////////////////////
8868/// Replace bin errors by values in array error.
8869
8870void TH1::SetError(const Double_t *error)
8871{
8872 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
8873}
8874
8875////////////////////////////////////////////////////////////////////////////////
8876/// Change the name of this histogram
8878
8879void TH1::SetName(const char *name)
8880{
8881 // Histograms are named objects in a THashList.
8882 // We must update the hashlist if we change the name
8883 // We protect this operation
8885 if (fDirectory) fDirectory->Remove(this);
8886 fName = name;
8887 if (fDirectory) fDirectory->Append(this);
8888}
8889
8890////////////////////////////////////////////////////////////////////////////////
8891/// Change the name and title of this histogram
8892
8893void TH1::SetNameTitle(const char *name, const char *title)
8894{
8895 // Histograms are named objects in a THashList.
8896 // We must update the hashlist if we change the name
8897 SetName(name);
8898 SetTitle(title);
8899}
8900
8901////////////////////////////////////////////////////////////////////////////////
8902/// Set statistics option on/off.
8903///
8904/// By default, the statistics box is drawn.
8905/// The paint options can be selected via gStyle->SetOptStat.
8906/// This function sets/resets the kNoStats bit in the histogram object.
8907/// It has priority over the Style option.
8908
8909void TH1::SetStats(Bool_t stats)
8910{
8912 if (!stats) {
8914 //remove the "stats" object from the list of functions
8915 if (fFunctions) {
8916 TObject *obj = fFunctions->FindObject("stats");
8917 if (obj) {
8918 fFunctions->Remove(obj);
8919 delete obj;
8920 }
8921 }
8922 }
8923}
8924
8925////////////////////////////////////////////////////////////////////////////////
8926/// Create structure to store sum of squares of weights.
8927///
8928/// if histogram is already filled, the sum of squares of weights
8929/// is filled with the existing bin contents
8930///
8931/// The error per bin will be computed as sqrt(sum of squares of weight)
8932/// for each bin.
8933///
8934/// This function is automatically called when the histogram is created
8935/// if the static function TH1::SetDefaultSumw2 has been called before.
8936/// If flag = false the structure containing the sum of the square of weights
8937/// is rest and it will be empty, but it is not deleted (i.e. GetSumw2()->fN = 0)
8938
8939void TH1::Sumw2(Bool_t flag)
8940{
8941 if (!flag) {
8942 // clear the array if existing - do nothing otherwise
8943 if (fSumw2.fN > 0 ) fSumw2.Set(0);
8944 return;
8945 }
8946
8947 if (fSumw2.fN == fNcells) {
8948 if (!fgDefaultSumw2 )
8949 Warning("Sumw2","Sum of squares of weights structure already created");
8950 return;
8951 }
8952
8954
8955 // empty the buffer
8956 if (fBuffer) BufferEmpty();
8957
8958 if (fEntries > 0)
8959 for (Int_t i = 0; i < fNcells; ++i)
8961}
8962
8963////////////////////////////////////////////////////////////////////////////////
8964/// Return pointer to function with name.
8965///
8966///
8967/// Functions such as TH1::Fit store the fitted function in the list of
8968/// functions of this histogram.
8969
8970TF1 *TH1::GetFunction(const char *name) const
8971{
8972 return (TF1*)fFunctions->FindObject(name);
8973}
8974
8975////////////////////////////////////////////////////////////////////////////////
8976/// Return value of error associated to bin number bin.
8977///
8978/// if the sum of squares of weights has been defined (via Sumw2),
8979/// this function returns the sqrt(sum of w2).
8980/// otherwise it returns the sqrt(contents) for this bin.
8981
8983{
8984 if (bin < 0) bin = 0;
8985 if (bin >= fNcells) bin = fNcells-1;
8986 if (fBuffer) ((TH1*)this)->BufferEmpty();
8987 if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
8988
8990}
8991
8992////////////////////////////////////////////////////////////////////////////////
8993/// Return lower error associated to bin number bin.
8994///
8995/// The error will depend on the statistic option used will return
8996/// the binContent - lower interval value
8997
8999{
9000 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9001 // in case of weighted histogram check if it is really weighted
9002 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9003
9004 if (bin < 0) bin = 0;
9005 if (bin >= fNcells) bin = fNcells-1;
9006 if (fBuffer) ((TH1*)this)->BufferEmpty();
9007
9008 Double_t alpha = 1.- 0.682689492;
9009 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9010
9012 Int_t n = int(c);
9013 if (n < 0) {
9014 Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
9015 ((TH1*)this)->fBinStatErrOpt = kNormal;
9016 return GetBinError(bin);
9017 }
9018
9019 if (n == 0) return 0;
9020 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
9021}
9022
9023////////////////////////////////////////////////////////////////////////////////
9024/// Return upper error associated to bin number bin.
9025///
9026/// The error will depend on the statistic option used will return
9027/// the binContent - upper interval value
9028
9030{
9031 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
9032 // in case of weighted histogram check if it is really weighted
9033 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
9034 if (bin < 0) bin = 0;
9035 if (bin >= fNcells) bin = fNcells-1;
9036 if (fBuffer) ((TH1*)this)->BufferEmpty();
9037
9038 Double_t alpha = 1.- 0.682689492;
9039 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
9040
9042 Int_t n = int(c);
9043 if (n < 0) {
9044 Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
9045 ((TH1*)this)->fBinStatErrOpt = kNormal;
9046 return GetBinError(bin);
9047 }
9048
9049 // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
9050 // decide to return always (1-alpha)/2 upper interval
9051 //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
9052 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
9053}
9054
9055//L.M. These following getters are useless and should be probably deprecated
9056////////////////////////////////////////////////////////////////////////////////
9057/// Return bin center for 1D histogram.
9058/// Better to use h1.GetXaxis()->GetBinCenter(bin)
9059
9061{
9062 if (fDimension == 1) return fXaxis.GetBinCenter(bin);
9063 Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
9064 return TMath::QuietNaN();
9065}
9066
9067////////////////////////////////////////////////////////////////////////////////
9068/// Return bin lower edge for 1D histogram.
9069/// Better to use h1.GetXaxis()->GetBinLowEdge(bin)
9070
9072{
9073 if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
9074 Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
9075 return TMath::QuietNaN();
9076}
9077
9078////////////////////////////////////////////////////////////////////////////////
9079/// Return bin width for 1D histogram.
9080/// Better to use h1.GetXaxis()->GetBinWidth(bin)
9081
9083{
9084 if (fDimension == 1) return fXaxis.GetBinWidth(bin);
9085 Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
9086 return TMath::QuietNaN();
9087}
9088
9089////////////////////////////////////////////////////////////////////////////////
9090/// Fill array with center of bins for 1D histogram
9091/// Better to use h1.GetXaxis()->GetCenter(center)
9092
9093void TH1::GetCenter(Double_t *center) const
9094{
9095 if (fDimension == 1) {
9096 fXaxis.GetCenter(center);
9097 return;
9098 }
9099 Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
9100}
9101
9102////////////////////////////////////////////////////////////////////////////////
9103/// Fill array with low edge of bins for 1D histogram
9104/// Better to use h1.GetXaxis()->GetLowEdge(edge)
9105
9106void TH1::GetLowEdge(Double_t *edge) const
9107{
9108 if (fDimension == 1) {
9109 fXaxis.GetLowEdge(edge);
9110 return;
9111 }
9112 Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
9113}
9114
9115////////////////////////////////////////////////////////////////////////////////
9116/// Set the bin Error
9117/// Note that this resets the bin eror option to be of Normal Type and for the
9118/// non-empty bin the bin error is set by default to the square root of their content.
9119/// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
9120/// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
9121/// will not be recalculated after setting the content and a default error = 0 will be used for those bins.
9122///
9123/// See convention for numbering bins in TH1::GetBin
9124
9125void TH1::SetBinError(Int_t bin, Double_t error)
9126{
9127 if (bin < 0 || bin>= fNcells) return;
9128 if (!fSumw2.fN) Sumw2();
9129 fSumw2.fArray[bin] = error * error;
9130 // reset the bin error option
9132}
9133
9134////////////////////////////////////////////////////////////////////////////////
9135/// Set bin content
9136/// see convention for numbering bins in TH1::GetBin
9137/// In case the bin number is greater than the number of bins and
9138/// the timedisplay option is set or CanExtendAllAxes(),
9139/// the number of bins is automatically doubled to accommodate the new bin
9140
9141void TH1::SetBinContent(Int_t bin, Double_t content)
9142{
9143 fEntries++;
9144 fTsumw = 0;
9145 if (bin < 0) return;
9146 if (bin >= fNcells-1) {
9148 while (bin >= fNcells-1) LabelsInflate();
9149 } else {
9150 if (bin == fNcells-1) UpdateBinContent(bin, content);
9151 return;
9152 }
9153 }
9154 UpdateBinContent(bin, content);
9155}
9156
9157////////////////////////////////////////////////////////////////////////////////
9158/// See convention for numbering bins in TH1::GetBin
9159
9160void TH1::SetBinError(Int_t binx, Int_t biny, Double_t error)
9161{
9162 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9163 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9164 SetBinError(GetBin(binx, biny), error);
9165}
9166
9167////////////////////////////////////////////////////////////////////////////////
9168/// See convention for numbering bins in TH1::GetBin
9169
9170void TH1::SetBinError(Int_t binx, Int_t biny, Int_t binz, Double_t error)
9171{
9172 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9173 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9174 if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
9175 SetBinError(GetBin(binx, biny, binz), error);
9176}
9177
9178////////////////////////////////////////////////////////////////////////////////
9179/// This function calculates the background spectrum in this histogram.
9180/// The background is returned as a histogram.
9181///
9182/// \param[in] niter number of iterations (default value = 2)
9183/// Increasing niter make the result smoother and lower.
9184/// \param[in] option may contain one of the following options
9185/// - to set the direction parameter
9186/// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
9187/// - filterOrder-order of clipping filter (default "BackOrder2")
9188/// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
9189/// - "nosmoothing" - if selected, the background is not smoothed
9190/// By default the background is smoothed.
9191/// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
9192/// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
9193/// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
9194/// - "nocompton" - if selected the estimation of Compton edge
9195/// will be not be included (by default the compton estimation is set)
9196/// - "same" if this option is specified, the resulting background
9197/// histogram is superimposed on the picture in the current pad.
9198/// This option is given by default.
9199///
9200/// NOTE that the background is only evaluated in the current range of this histogram.
9201/// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
9202/// the returned histogram will be created with the same number of bins
9203/// as this input histogram, but only bins from binmin to binmax will be filled
9204/// with the estimated background.
9205
9207{
9208 return (TH1*)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticBackground((TH1*)0x%zx,%d,\"%s\")",
9209 (size_t)this, niter, option).Data());
9210}
9211
9212////////////////////////////////////////////////////////////////////////////////
9213/// Interface to TSpectrum::Search.
9214/// The function finds peaks in this histogram where the width is > sigma
9215/// and the peak maximum greater than threshold*maximum bin content of this.
9216/// For more details see TSpectrum::Search.
9217/// Note the difference in the default value for option compared to TSpectrum::Search
9218/// option="" by default (instead of "goff").
9219
9221{
9222 return (Int_t)gROOT->ProcessLineFast(TString::Format("TSpectrum::StaticSearch((TH1*)0x%zx,%g,\"%s\",%g)",
9223 (size_t)this, sigma, option, threshold).Data());
9224}
9225
9226////////////////////////////////////////////////////////////////////////////////
9227/// For a given transform (first parameter), fills the histogram (second parameter)
9228/// with the transform output data, specified in the third parameter
9229/// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
9230/// and the user is responsible for deleting it.
9231///
9232/// Available options:
9233/// - "RE" - real part of the output
9234/// - "IM" - imaginary part of the output
9235/// - "MAG" - magnitude of the output
9236/// - "PH" - phase of the output
9237
9239{
9240 if (!fft || !fft->GetN() ) {
9241 ::Error("TransformHisto","Invalid FFT transform class");
9242 return nullptr;
9243 }
9244
9245 if (fft->GetNdim()>2){
9246 ::Error("TransformHisto","Only 1d and 2D transform are supported");
9247 return nullptr;
9248 }
9249 Int_t binx,biny;
9250 TString opt = option;
9251 opt.ToUpper();
9252 Int_t *n = fft->GetN();
9253 TH1 *hout=nullptr;
9254 if (h_output) {
9255 hout = h_output;
9256 }
9257 else {
9258 TString name = TString::Format("out_%s", opt.Data());
9259 if (fft->GetNdim()==1)
9260 hout = new TH1D(name, name,n[0], 0, n[0]);
9261 else if (fft->GetNdim()==2)
9262 hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
9263 }
9264 R__ASSERT(hout != nullptr);
9265 TString type=fft->GetType();
9266 Int_t ind[2];
9267 if (opt.Contains("RE")){
9268 if (type.Contains("2C") || type.Contains("2HC")) {
9269 Double_t re, im;
9270 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9271 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9272 ind[0] = binx-1; ind[1] = biny-1;
9273 fft->GetPointComplex(ind, re, im);
9274 hout->SetBinContent(binx, biny, re);
9275 }
9276 }
9277 } else {
9278 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9279 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9280 ind[0] = binx-1; ind[1] = biny-1;
9281 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
9282 }
9283 }
9284 }
9285 }
9286 if (opt.Contains("IM")) {
9287 if (type.Contains("2C") || type.Contains("2HC")) {
9288 Double_t re, im;
9289 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9290 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9291 ind[0] = binx-1; ind[1] = biny-1;
9292 fft->GetPointComplex(ind, re, im);
9293 hout->SetBinContent(binx, biny, im);
9294 }
9295 }
9296 } else {
9297 ::Error("TransformHisto","No complex numbers in the output");
9298 return nullptr;
9299 }
9300 }
9301 if (opt.Contains("MA")) {
9302 if (type.Contains("2C") || type.Contains("2HC")) {
9303 Double_t re, im;
9304 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9305 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9306 ind[0] = binx-1; ind[1] = biny-1;
9307 fft->GetPointComplex(ind, re, im);
9308 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
9309 }
9310 }
9311 } else {
9312 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9313 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9314 ind[0] = binx-1; ind[1] = biny-1;
9315 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
9316 }
9317 }
9318 }
9319 }
9320 if (opt.Contains("PH")) {
9321 if (type.Contains("2C") || type.Contains("2HC")){
9322 Double_t re, im, ph;
9323 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
9324 for (biny=1; biny<=hout->GetNbinsY(); biny++){
9325 ind[0] = binx-1; ind[1] = biny-1;
9326 fft->GetPointComplex(ind, re, im);
9327 if (TMath::Abs(re) > 1e-13){
9328 ph = TMath::ATan(im/re);
9329 //find the correct quadrant
9330 if (re<0 && im<0)
9331 ph -= TMath::Pi();
9332 if (re<0 && im>=0)
9333 ph += TMath::Pi();
9334 } else {
9335 if (TMath::Abs(im) < 1e-13)
9336 ph = 0;
9337 else if (im>0)
9338 ph = TMath::Pi()*0.5;
9339 else
9340 ph = -TMath::Pi()*0.5;
9341 }
9342 hout->SetBinContent(binx, biny, ph);
9343 }
9344 }
9345 } else {
9346 printf("Pure real output, no phase");
9347 return nullptr;
9348 }
9349 }
9350
9351 return hout;
9352}
9353
9354////////////////////////////////////////////////////////////////////////////////
9355/// Raw retrieval of bin content on internal data structure
9356/// see convention for numbering bins in TH1::GetBin
9357
9359{
9360 AbstractMethod("RetrieveBinContent");
9361 return 0;
9362}
9363
9364////////////////////////////////////////////////////////////////////////////////
9365/// Raw update of bin content on internal data structure
9366/// see convention for numbering bins in TH1::GetBin
9367
9369{
9370 AbstractMethod("UpdateBinContent");
9371}
9372
9373////////////////////////////////////////////////////////////////////////////////
9374/// Print value overload
9375
9376std::string cling::printValue(TH1 *val) {
9377 std::ostringstream strm;
9378 strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
9379 return strm.str();
9380}
9381
9382//______________________________________________________________________________
9383// TH1C methods
9384// TH1C : histograms with one byte per channel. Maximum bin content = 127
9385//______________________________________________________________________________
9386
9387ClassImp(TH1C);
9388
9389////////////////////////////////////////////////////////////////////////////////
9390/// Constructor.
9391
9392TH1C::TH1C(): TH1(), TArrayC()
9393{
9394 fDimension = 1;
9395 SetBinsLength(3);
9396 if (fgDefaultSumw2) Sumw2();
9397}
9398
9399////////////////////////////////////////////////////////////////////////////////
9400/// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
9401/// (see TH1::TH1 for explanation of parameters)
9402
9403TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9404: TH1(name,title,nbins,xlow,xup)
9405{
9406 fDimension = 1;
9408
9409 if (xlow >= xup) SetBuffer(fgBufferSize);
9410 if (fgDefaultSumw2) Sumw2();
9411}
9412
9413////////////////////////////////////////////////////////////////////////////////
9414/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9415/// (see TH1::TH1 for explanation of parameters)
9416
9417TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9418: TH1(name,title,nbins,xbins)
9419{
9420 fDimension = 1;
9422 if (fgDefaultSumw2) Sumw2();
9423}
9424
9425////////////////////////////////////////////////////////////////////////////////
9426/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9427/// (see TH1::TH1 for explanation of parameters)
9428
9429TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9430: TH1(name,title,nbins,xbins)
9431{
9432 fDimension = 1;
9434 if (fgDefaultSumw2) Sumw2();
9435}
9436
9437////////////////////////////////////////////////////////////////////////////////
9438/// Destructor.
9439
9441{
9442}
9443
9444////////////////////////////////////////////////////////////////////////////////
9445/// Copy constructor.
9446/// The list of functions is not copied. (Use Clone() if needed)
9447
9448TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
9449{
9450 h1c.TH1C::Copy(*this);
9451}
9452
9453////////////////////////////////////////////////////////////////////////////////
9454/// Increment bin content by 1.
9455
9456void TH1C::AddBinContent(Int_t bin)
9457{
9458 if (fArray[bin] < 127) fArray[bin]++;
9459}
9460
9461////////////////////////////////////////////////////////////////////////////////
9462/// Increment bin content by w.
9463
9465{
9466 Int_t newval = fArray[bin] + Int_t(w);
9467 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
9468 if (newval < -127) fArray[bin] = -127;
9469 if (newval > 127) fArray[bin] = 127;
9470}
9471
9472////////////////////////////////////////////////////////////////////////////////
9473/// Copy this to newth1
9474
9475void TH1C::Copy(TObject &newth1) const
9476{
9477 TH1::Copy(newth1);
9478}
9479
9480////////////////////////////////////////////////////////////////////////////////
9481/// Reset.
9482
9484{
9487}
9488
9489////////////////////////////////////////////////////////////////////////////////
9490/// Set total number of bins including under/overflow
9491/// Reallocate bin contents array
9492
9494{
9495 if (n < 0) n = fXaxis.GetNbins() + 2;
9496 fNcells = n;
9497 TArrayC::Set(n);
9498}
9499
9500////////////////////////////////////////////////////////////////////////////////
9501/// Operator =
9502
9503TH1C& TH1C::operator=(const TH1C &h1)
9504{
9505 if (this != &h1)
9506 h1.TH1C::Copy(*this);
9507 return *this;
9508}
9509
9510////////////////////////////////////////////////////////////////////////////////
9511/// Operator *
9512
9514{
9515 TH1C hnew = h1;
9516 hnew.Scale(c1);
9517 hnew.SetDirectory(nullptr);
9518 return hnew;
9519}
9520
9521////////////////////////////////////////////////////////////////////////////////
9522/// Operator +
9523
9524TH1C operator+(const TH1C &h1, const TH1C &h2)
9525{
9526 TH1C hnew = h1;
9527 hnew.Add(&h2,1);
9528 hnew.SetDirectory(nullptr);
9529 return hnew;
9530}
9531
9532////////////////////////////////////////////////////////////////////////////////
9533/// Operator -
9534
9535TH1C operator-(const TH1C &h1, const TH1C &h2)
9536{
9537 TH1C hnew = h1;
9538 hnew.Add(&h2,-1);
9539 hnew.SetDirectory(nullptr);
9540 return hnew;
9541}
9542
9543////////////////////////////////////////////////////////////////////////////////
9544/// Operator *
9545
9546TH1C operator*(const TH1C &h1, const TH1C &h2)
9547{
9548 TH1C hnew = h1;
9549 hnew.Multiply(&h2);
9550 hnew.SetDirectory(nullptr);
9551 return hnew;
9552}
9553
9554////////////////////////////////////////////////////////////////////////////////
9555/// Operator /
9556
9557TH1C operator/(const TH1C &h1, const TH1C &h2)
9558{
9559 TH1C hnew = h1;
9560 hnew.Divide(&h2);
9561 hnew.SetDirectory(nullptr);
9562 return hnew;
9563}
9564
9565//______________________________________________________________________________
9566// TH1S methods
9567// TH1S : histograms with one short per channel. Maximum bin content = 32767
9568//______________________________________________________________________________
9569
9570ClassImp(TH1S);
9571
9572////////////////////////////////////////////////////////////////////////////////
9573/// Constructor.
9574
9575TH1S::TH1S(): TH1(), TArrayS()
9576{
9577 fDimension = 1;
9578 SetBinsLength(3);
9579 if (fgDefaultSumw2) Sumw2();
9580}
9581
9582////////////////////////////////////////////////////////////////////////////////
9583/// Create a 1-Dim histogram with fix bins of type short
9584/// (see TH1::TH1 for explanation of parameters)
9585
9586TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9587: TH1(name,title,nbins,xlow,xup)
9588{
9589 fDimension = 1;
9591
9592 if (xlow >= xup) SetBuffer(fgBufferSize);
9593 if (fgDefaultSumw2) Sumw2();
9594}
9595
9596////////////////////////////////////////////////////////////////////////////////
9597/// Create a 1-Dim histogram with variable bins of type short
9598/// (see TH1::TH1 for explanation of parameters)
9599
9600TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9601: TH1(name,title,nbins,xbins)
9602{
9603 fDimension = 1;
9605 if (fgDefaultSumw2) Sumw2();
9606}
9607
9608////////////////////////////////////////////////////////////////////////////////
9609/// Create a 1-Dim histogram with variable bins of type short
9610/// (see TH1::TH1 for explanation of parameters)
9611
9612TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9613: TH1(name,title,nbins,xbins)
9614{
9615 fDimension = 1;
9617 if (fgDefaultSumw2) Sumw2();
9618}
9619
9620////////////////////////////////////////////////////////////////////////////////
9621/// Destructor.
9622
9624{
9625}
9626
9627////////////////////////////////////////////////////////////////////////////////
9628/// Copy constructor.
9629/// The list of functions is not copied. (Use Clone() if needed)
9630
9631TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9632{
9633 h1s.TH1S::Copy(*this);
9634}
9635
9636////////////////////////////////////////////////////////////////////////////////
9637/// Increment bin content by 1.
9638
9639void TH1S::AddBinContent(Int_t bin)
9640{
9641 if (fArray[bin] < 32767) fArray[bin]++;
9642}
9643
9644////////////////////////////////////////////////////////////////////////////////
9645/// Increment bin content by w
9646
9648{
9649 Int_t newval = fArray[bin] + Int_t(w);
9650 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9651 if (newval < -32767) fArray[bin] = -32767;
9652 if (newval > 32767) fArray[bin] = 32767;
9653}
9654
9655////////////////////////////////////////////////////////////////////////////////
9656/// Copy this to newth1
9657
9658void TH1S::Copy(TObject &newth1) const
9659{
9660 TH1::Copy(newth1);
9661}
9662
9663////////////////////////////////////////////////////////////////////////////////
9664/// Reset.
9665
9667{
9670}
9671
9672////////////////////////////////////////////////////////////////////////////////
9673/// Set total number of bins including under/overflow
9674/// Reallocate bin contents array
9675
9677{
9678 if (n < 0) n = fXaxis.GetNbins() + 2;
9679 fNcells = n;
9680 TArrayS::Set(n);
9681}
9682
9683////////////////////////////////////////////////////////////////////////////////
9684/// Operator =
9685
9686TH1S& TH1S::operator=(const TH1S &h1)
9687{
9688 if (this != &h1)
9689 h1.TH1S::Copy(*this);
9690 return *this;
9691}
9692
9693////////////////////////////////////////////////////////////////////////////////
9694/// Operator *
9695
9697{
9698 TH1S hnew = h1;
9699 hnew.Scale(c1);
9700 hnew.SetDirectory(nullptr);
9701 return hnew;
9702}
9703
9704////////////////////////////////////////////////////////////////////////////////
9705/// Operator +
9706
9707TH1S operator+(const TH1S &h1, const TH1S &h2)
9708{
9709 TH1S hnew = h1;
9710 hnew.Add(&h2,1);
9711 hnew.SetDirectory(nullptr);
9712 return hnew;
9713}
9714
9715////////////////////////////////////////////////////////////////////////////////
9716/// Operator -
9717
9718TH1S operator-(const TH1S &h1, const TH1S &h2)
9719{
9720 TH1S hnew = h1;
9721 hnew.Add(&h2,-1);
9722 hnew.SetDirectory(nullptr);
9723 return hnew;
9724}
9725
9726////////////////////////////////////////////////////////////////////////////////
9727/// Operator *
9728
9729TH1S operator*(const TH1S &h1, const TH1S &h2)
9730{
9731 TH1S hnew = h1;
9732 hnew.Multiply(&h2);
9733 hnew.SetDirectory(nullptr);
9734 return hnew;
9735}
9736
9737////////////////////////////////////////////////////////////////////////////////
9738/// Operator /
9739
9740TH1S operator/(const TH1S &h1, const TH1S &h2)
9741{
9742 TH1S hnew = h1;
9743 hnew.Divide(&h2);
9744 hnew.SetDirectory(nullptr);
9745 return hnew;
9746}
9747
9748//______________________________________________________________________________
9749// TH1I methods
9750// TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9751// 2147483647 = INT_MAX
9752//______________________________________________________________________________
9753
9754ClassImp(TH1I);
9755
9756////////////////////////////////////////////////////////////////////////////////
9757/// Constructor.
9758
9759TH1I::TH1I(): TH1(), TArrayI()
9760{
9761 fDimension = 1;
9762 SetBinsLength(3);
9763 if (fgDefaultSumw2) Sumw2();
9764}
9765
9766////////////////////////////////////////////////////////////////////////////////
9767/// Create a 1-Dim histogram with fix bins of type integer
9768/// (see TH1::TH1 for explanation of parameters)
9769
9770TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9771: TH1(name,title,nbins,xlow,xup)
9772{
9773 fDimension = 1;
9775
9776 if (xlow >= xup) SetBuffer(fgBufferSize);
9777 if (fgDefaultSumw2) Sumw2();
9778}
9779
9780////////////////////////////////////////////////////////////////////////////////
9781/// Create a 1-Dim histogram with variable bins of type integer
9782/// (see TH1::TH1 for explanation of parameters)
9783
9784TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9785: TH1(name,title,nbins,xbins)
9786{
9787 fDimension = 1;
9789 if (fgDefaultSumw2) Sumw2();
9790}
9791
9792////////////////////////////////////////////////////////////////////////////////
9793/// Create a 1-Dim histogram with variable bins of type integer
9794/// (see TH1::TH1 for explanation of parameters)
9795
9796TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9797: TH1(name,title,nbins,xbins)
9798{
9799 fDimension = 1;
9801 if (fgDefaultSumw2) Sumw2();
9802}
9803
9804////////////////////////////////////////////////////////////////////////////////
9805/// Destructor.
9806
9808{
9809}
9810
9811////////////////////////////////////////////////////////////////////////////////
9812/// Copy constructor.
9813/// The list of functions is not copied. (Use Clone() if needed)
9814
9815TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
9816{
9817 h1i.TH1I::Copy(*this);
9818}
9819
9820////////////////////////////////////////////////////////////////////////////////
9821/// Increment bin content by 1.
9822
9823void TH1I::AddBinContent(Int_t bin)
9824{
9825 if (fArray[bin] < INT_MAX) fArray[bin]++;
9826}
9827
9828////////////////////////////////////////////////////////////////////////////////
9829/// Increment bin content by w
9830
9832{
9833 Long64_t newval = fArray[bin] + Long64_t(w);
9834 if (newval > -INT_MAX && newval < INT_MAX) {fArray[bin] = Int_t(newval); return;}
9835 if (newval < -INT_MAX) fArray[bin] = -INT_MAX;
9836 if (newval > INT_MAX) fArray[bin] = INT_MAX;
9837}
9838
9839////////////////////////////////////////////////////////////////////////////////
9840/// Copy this to newth1
9841
9842void TH1I::Copy(TObject &newth1) const
9843{
9844 TH1::Copy(newth1);
9845}
9846
9847////////////////////////////////////////////////////////////////////////////////
9848/// Reset.
9849
9851{
9854}
9855
9856////////////////////////////////////////////////////////////////////////////////
9857/// Set total number of bins including under/overflow
9858/// Reallocate bin contents array
9859
9861{
9862 if (n < 0) n = fXaxis.GetNbins() + 2;
9863 fNcells = n;
9864 TArrayI::Set(n);
9865}
9866
9867////////////////////////////////////////////////////////////////////////////////
9868/// Operator =
9869
9870TH1I& TH1I::operator=(const TH1I &h1)
9871{
9872 if (this != &h1)
9873 h1.TH1I::Copy(*this);
9874 return *this;
9875}
9876
9877
9878////////////////////////////////////////////////////////////////////////////////
9879/// Operator *
9880
9882{
9883 TH1I hnew = h1;
9884 hnew.Scale(c1);
9885 hnew.SetDirectory(nullptr);
9886 return hnew;
9887}
9888
9889////////////////////////////////////////////////////////////////////////////////
9890/// Operator +
9891
9892TH1I operator+(const TH1I &h1, const TH1I &h2)
9893{
9894 TH1I hnew = h1;
9895 hnew.Add(&h2,1);
9896 hnew.SetDirectory(nullptr);
9897 return hnew;
9898}
9899
9900////////////////////////////////////////////////////////////////////////////////
9901/// Operator -
9902
9903TH1I operator-(const TH1I &h1, const TH1I &h2)
9904{
9905 TH1I hnew = h1;
9906 hnew.Add(&h2,-1);
9907 hnew.SetDirectory(nullptr);
9908 return hnew;
9909}
9910
9911////////////////////////////////////////////////////////////////////////////////
9912/// Operator *
9913
9914TH1I operator*(const TH1I &h1, const TH1I &h2)
9915{
9916 TH1I hnew = h1;
9917 hnew.Multiply(&h2);
9918 hnew.SetDirectory(nullptr);
9919 return hnew;
9920}
9921
9922////////////////////////////////////////////////////////////////////////////////
9923/// Operator /
9924
9925TH1I operator/(const TH1I &h1, const TH1I &h2)
9926{
9927 TH1I hnew = h1;
9928 hnew.Divide(&h2);
9929 hnew.SetDirectory(nullptr);
9930 return hnew;
9931}
9932
9933//______________________________________________________________________________
9934// TH1F methods
9935// TH1F : histograms with one float per channel. Maximum precision 7 digits
9936//______________________________________________________________________________
9937
9938ClassImp(TH1F);
9939
9940////////////////////////////////////////////////////////////////////////////////
9941/// Constructor.
9942
9943TH1F::TH1F(): TH1(), TArrayF()
9944{
9945 fDimension = 1;
9946 SetBinsLength(3);
9947 if (fgDefaultSumw2) Sumw2();
9948}
9949
9950////////////////////////////////////////////////////////////////////////////////
9951/// Create a 1-Dim histogram with fix bins of type float
9952/// (see TH1::TH1 for explanation of parameters)
9953
9954TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9955: TH1(name,title,nbins,xlow,xup)
9956{
9957 fDimension = 1;
9959
9960 if (xlow >= xup) SetBuffer(fgBufferSize);
9961 if (fgDefaultSumw2) Sumw2();
9962}
9963
9964////////////////////////////////////////////////////////////////////////////////
9965/// Create a 1-Dim histogram with variable bins of type float
9966/// (see TH1::TH1 for explanation of parameters)
9967
9968TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9969: TH1(name,title,nbins,xbins)
9970{
9971 fDimension = 1;
9973 if (fgDefaultSumw2) Sumw2();
9974}
9975
9976////////////////////////////////////////////////////////////////////////////////
9977/// Create a 1-Dim histogram with variable bins of type float
9978/// (see TH1::TH1 for explanation of parameters)
9979
9980TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9981: TH1(name,title,nbins,xbins)
9982{
9983 fDimension = 1;
9985 if (fgDefaultSumw2) Sumw2();
9986}
9987
9988////////////////////////////////////////////////////////////////////////////////
9989/// Create a histogram from a TVectorF
9990/// by default the histogram name is "TVectorF" and title = ""
9991
9992TH1F::TH1F(const TVectorF &v)
9993: TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
9994{
9996 fDimension = 1;
9997 Int_t ivlow = v.GetLwb();
9998 for (Int_t i=0;i<fNcells-2;i++) {
9999 SetBinContent(i+1,v(i+ivlow));
10000 }
10002 if (fgDefaultSumw2) Sumw2();
10003}
10004
10005////////////////////////////////////////////////////////////////////////////////
10006/// Copy Constructor.
10007/// The list of functions is not copied. (Use Clone() if needed)
10008
10009TH1F::TH1F(const TH1F &h1f) : TH1(), TArrayF()
10010{
10011 h1f.TH1F::Copy(*this);
10012}
10013
10014////////////////////////////////////////////////////////////////////////////////
10015/// Destructor.
10016
10018{
10019}
10020
10021////////////////////////////////////////////////////////////////////////////////
10022/// Copy this to newth1.
10023
10024void TH1F::Copy(TObject &newth1) const
10025{
10026 TH1::Copy(newth1);
10027}
10028
10029////////////////////////////////////////////////////////////////////////////////
10030/// Reset.
10031
10033{
10036}
10037
10038////////////////////////////////////////////////////////////////////////////////
10039/// Set total number of bins including under/overflow
10040/// Reallocate bin contents array
10041
10043{
10044 if (n < 0) n = fXaxis.GetNbins() + 2;
10045 fNcells = n;
10046 TArrayF::Set(n);
10047}
10048
10049////////////////////////////////////////////////////////////////////////////////
10050/// Operator =
10051
10052TH1F& TH1F::operator=(const TH1F &h1f)
10053{
10054 if (this != &h1f)
10055 h1f.TH1F::Copy(*this);
10056 return *this;
10057}
10058
10059////////////////////////////////////////////////////////////////////////////////
10060/// Operator *
10061
10063{
10064 TH1F hnew = h1;
10065 hnew.Scale(c1);
10066 hnew.SetDirectory(nullptr);
10067 return hnew;
10068}
10069
10070////////////////////////////////////////////////////////////////////////////////
10071/// Operator +
10072
10073TH1F operator+(const TH1F &h1, const TH1F &h2)
10074{
10075 TH1F hnew = h1;
10076 hnew.Add(&h2,1);
10077 hnew.SetDirectory(nullptr);
10078 return hnew;
10079}
10080
10081////////////////////////////////////////////////////////////////////////////////
10082/// Operator -
10083
10084TH1F operator-(const TH1F &h1, const TH1F &h2)
10085{
10086 TH1F hnew = h1;
10087 hnew.Add(&h2,-1);
10088 hnew.SetDirectory(nullptr);
10089 return hnew;
10090}
10091
10092////////////////////////////////////////////////////////////////////////////////
10093/// Operator *
10094
10095TH1F operator*(const TH1F &h1, const TH1F &h2)
10096{
10097 TH1F hnew = h1;
10098 hnew.Multiply(&h2);
10099 hnew.SetDirectory(nullptr);
10100 return hnew;
10101}
10102
10103////////////////////////////////////////////////////////////////////////////////
10104/// Operator /
10105
10106TH1F operator/(const TH1F &h1, const TH1F &h2)
10107{
10108 TH1F hnew = h1;
10109 hnew.Divide(&h2);
10110 hnew.SetDirectory(nullptr);
10111 return hnew;
10112}
10113
10114//______________________________________________________________________________
10115// TH1D methods
10116// TH1D : histograms with one double per channel. Maximum precision 14 digits
10117//______________________________________________________________________________
10118
10119ClassImp(TH1D);
10120
10121////////////////////////////////////////////////////////////////////////////////
10122/// Constructor.
10123
10124TH1D::TH1D(): TH1(), TArrayD()
10125{
10126 fDimension = 1;
10127 SetBinsLength(3);
10128 if (fgDefaultSumw2) Sumw2();
10129}
10130
10131////////////////////////////////////////////////////////////////////////////////
10132/// Create a 1-Dim histogram with fix bins of type double
10133/// (see TH1::TH1 for explanation of parameters)
10134
10135TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10136: TH1(name,title,nbins,xlow,xup)
10137{
10138 fDimension = 1;
10140
10141 if (xlow >= xup) SetBuffer(fgBufferSize);
10142 if (fgDefaultSumw2) Sumw2();
10143}
10144
10145////////////////////////////////////////////////////////////////////////////////
10146/// Create a 1-Dim histogram with variable bins of type double
10147/// (see TH1::TH1 for explanation of parameters)
10148
10149TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10150: TH1(name,title,nbins,xbins)
10151{
10152 fDimension = 1;
10154 if (fgDefaultSumw2) Sumw2();
10155}
10156
10157////////////////////////////////////////////////////////////////////////////////
10158/// Create a 1-Dim histogram with variable bins of type double
10159/// (see TH1::TH1 for explanation of parameters)
10160
10161TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10162: TH1(name,title,nbins,xbins)
10163{
10164 fDimension = 1;
10166 if (fgDefaultSumw2) Sumw2();
10167}
10168
10169////////////////////////////////////////////////////////////////////////////////
10170/// Create a histogram from a TVectorD
10171/// by default the histogram name is "TVectorD" and title = ""
10172
10173TH1D::TH1D(const TVectorD &v)
10174: TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
10175{
10177 fDimension = 1;
10178 Int_t ivlow = v.GetLwb();
10179 for (Int_t i=0;i<fNcells-2;i++) {
10180 SetBinContent(i+1,v(i+ivlow));
10181 }
10183 if (fgDefaultSumw2) Sumw2();
10184}
10185
10186////////////////////////////////////////////////////////////////////////////////
10187/// Destructor.
10188
10190{
10191}
10192
10193////////////////////////////////////////////////////////////////////////////////
10194/// Constructor.
10195
10196TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
10197{
10198 // intentially call virtual method to warn if TProfile is copying
10199 h1d.Copy(*this);
10200}
10201
10202////////////////////////////////////////////////////////////////////////////////
10203/// Copy this to newth1
10204
10205void TH1D::Copy(TObject &newth1) const
10206{
10207 TH1::Copy(newth1);
10208}
10209
10210////////////////////////////////////////////////////////////////////////////////
10211/// Reset.
10212
10214{
10217}
10218
10219////////////////////////////////////////////////////////////////////////////////
10220/// Set total number of bins including under/overflow
10221/// Reallocate bin contents array
10222
10224{
10225 if (n < 0) n = fXaxis.GetNbins() + 2;
10226 fNcells = n;
10227 TArrayD::Set(n);
10228}
10229
10230////////////////////////////////////////////////////////////////////////////////
10231/// Operator =
10232
10233TH1D& TH1D::operator=(const TH1D &h1d)
10234{
10235 // intentially call virtual method to warn if TProfile is copying
10236 if (this != &h1d)
10237 h1d.Copy(*this);
10238 return *this;
10239}
10240
10241////////////////////////////////////////////////////////////////////////////////
10242/// Operator *
10243
10245{
10246 TH1D hnew = h1;
10247 hnew.Scale(c1);
10248 hnew.SetDirectory(nullptr);
10249 return hnew;
10250}
10251
10252////////////////////////////////////////////////////////////////////////////////
10253/// Operator +
10254
10255TH1D operator+(const TH1D &h1, const TH1D &h2)
10256{
10257 TH1D hnew = h1;
10258 hnew.Add(&h2,1);
10259 hnew.SetDirectory(nullptr);
10260 return hnew;
10261}
10262
10263////////////////////////////////////////////////////////////////////////////////
10264/// Operator -
10265
10266TH1D operator-(const TH1D &h1, const TH1D &h2)
10267{
10268 TH1D hnew = h1;
10269 hnew.Add(&h2,-1);
10270 hnew.SetDirectory(nullptr);
10271 return hnew;
10272}
10273
10274////////////////////////////////////////////////////////////////////////////////
10275/// Operator *
10276
10277TH1D operator*(const TH1D &h1, const TH1D &h2)
10278{
10279 TH1D hnew = h1;
10280 hnew.Multiply(&h2);
10281 hnew.SetDirectory(nullptr);
10282 return hnew;
10283}
10284
10285////////////////////////////////////////////////////////////////////////////////
10286/// Operator /
10287
10288TH1D operator/(const TH1D &h1, const TH1D &h2)
10289{
10290 TH1D hnew = h1;
10291 hnew.Divide(&h2);
10292 hnew.SetDirectory(nullptr);
10293 return hnew;
10294}
10295
10296////////////////////////////////////////////////////////////////////////////////
10297///return pointer to histogram with name
10298///hid if id >=0
10299///h_id if id <0
10300
10301TH1 *R__H(Int_t hid)
10302{
10303 TString hname;
10304 if(hid >= 0) hname.Form("h%d",hid);
10305 else hname.Form("h_%d",hid);
10306 return (TH1*)gDirectory->Get(hname);
10307}
10308
10309////////////////////////////////////////////////////////////////////////////////
10310///return pointer to histogram with name hname
10311
10312TH1 *R__H(const char * hname)
10313{
10314 return (TH1*)gDirectory->Get(hname);
10315}
10316
10317
10318/// \fn void TH1::SetBarOffset(Float_t offset)
10319/// Set the bar offset as fraction of the bin width for drawing mode "B".
10320/// This shifts bars to the right on the x axis, and helps to draw bars next to each other.
10321/// \see THistPainter, SetBarWidth()
10322
10323/// \fn void TH1::SetBarWidth(Float_t width)
10324/// Set the width of bars as fraction of the bin width for drawing mode "B".
10325/// This allows for making bars narrower than the bin width. With SetBarOffset(), this helps to draw multiple bars next to each other.
10326/// \see THistPainter, SetBarOffset()
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define s1(x)
Definition RSha256.hxx:91
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
short Style_t
Definition RtypesCore.h:89
bool Bool_t
Definition RtypesCore.h:63
int Int_t
Definition RtypesCore.h:45
short Color_t
Definition RtypesCore.h:92
short Version_t
Definition RtypesCore.h:65
char Char_t
Definition RtypesCore.h:37
float Float_t
Definition RtypesCore.h:57
short Short_t
Definition RtypesCore.h:39
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:80
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:377
#define gDirectory
Definition TDirectory.h:384
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
#define R__ASSERT(e)
Definition TError.h:118
Option_t Option_t option
Option_t Option_t SetLineWidth
Option_t Option_t 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 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:5849
void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
Least square linear fit without weights.
Definition TH1.cxx:4797
void H1InitGaus()
Compute Initial values of parameters for a gaussian.
Definition TH1.cxx:4632
void H1InitExpo()
Compute Initial values of parameters for an exponential.
Definition TH1.cxx:4688
TH1C operator+(const TH1C &h1, const TH1C &h2)
Operator +.
Definition TH1.cxx:9522
TH1C operator-(const TH1C &h1, const TH1C &h2)
Operator -.
Definition TH1.cxx:9533
TH1C operator/(const TH1C &h1, const TH1C &h2)
Operator /.
Definition TH1.cxx:9555
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:4843
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:5832
static Bool_t AlmostInteger(Double_t a, Double_t epsilon=0.00000001)
Test if a double is almost an integer.
Definition TH1.cxx:5840
TF1 * gF1
Definition TH1.cxx:570
TH1 * R__H(Int_t hid)
return pointer to histogram with name hid if id >=0 h_id if id <0
Definition TH1.cxx:10299
TH1C operator*(Double_t c1, const TH1C &h1)
Operator *.
Definition TH1.cxx:9511
void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
Least squares lpolynomial fitting without weights.
Definition TH1.cxx:4738
void H1InitPolynom()
Compute Initial values of parameters for a polynom.
Definition TH1.cxx:4708
float xmin
int nentries
float * q
float ymin
float xmax
float ymax
#define gInterpreter
Int_t gDebug
Definition TROOT.cxx:597
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:407
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:2481
R__EXTERN TStyle * gStyle
Definition TStyle.h:433
#define R__LOCKGUARD(mutex)
#define gPad
#define R__WRITE_LOCKGUARD(mutex)
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition BinData.h:52
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition DataRange.h:35
void AndersonDarling2SamplesTest(Double_t &pvalue, Double_t &testStat) const
Performs the Anderson-Darling 2-Sample Test.
Definition GoFTest.cxx:645
Array of chars or bytes (8 bits per element).
Definition TArrayC.h:27
Char_t * fArray
Definition TArrayC.h:30
void Reset(Char_t val=0)
Definition TArrayC.h:47
void Set(Int_t n) override
Set size of this array to n chars.
Definition TArrayC.cxx:105
Array of doubles (64 bits per element).
Definition TArrayD.h:27
Double_t GetAt(Int_t i) const override
Definition TArrayD.h:45
Double_t * fArray
Definition TArrayD.h:30
void Streamer(TBuffer &) override
Stream a TArrayD object.
Definition TArrayD.cxx:149
void Copy(TArrayD &array) const
Definition TArrayD.h:42
void Set(Int_t n) override
Set size of this array to n doubles.
Definition TArrayD.cxx:106
const Double_t * GetArray() const
Definition TArrayD.h:43
void Reset()
Definition TArrayD.h:47
Array of floats (32 bits per element).
Definition TArrayF.h:27
void Reset()
Definition TArrayF.h:47
void Set(Int_t n) override
Set size of this array to n floats.
Definition TArrayF.cxx:105
Array of integers (32 bits per element).
Definition TArrayI.h:27
Int_t * fArray
Definition TArrayI.h:30
void Set(Int_t n) override
Set size of this array to n ints.
Definition TArrayI.cxx:105
void Reset()
Definition TArrayI.h:47
Array of shorts (16 bits per element).
Definition TArrayS.h:27
void Set(Int_t n) override
Set size of this array to n shorts.
Definition TArrayS.cxx:105
void Reset()
Definition TArrayS.h:47
Short_t * fArray
Definition TArrayS.h:30
Abstract array base class.
Definition TArray.h:31
Int_t fN
Definition TArray.h:38
virtual void Set(Int_t n)=0
Int_t GetSize() const
Definition TArray.h:47
virtual Color_t GetTitleColor() const
Definition TAttAxis.h:46
virtual Color_t GetLabelColor() const
Definition TAttAxis.h:38
virtual Int_t GetNdivisions() const
Definition TAttAxis.h:36
virtual Color_t GetAxisColor() const
Definition TAttAxis.h:37
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition TAttAxis.cxx:298
virtual Style_t GetTitleFont() const
Definition TAttAxis.h:47
virtual Float_t GetLabelOffset() const
Definition TAttAxis.h:40
virtual void SetAxisColor(Color_t color=1, Float_t alpha=1.)
Set color of the line axis and tick marks.
Definition TAttAxis.cxx:160
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
Definition TAttAxis.cxx:203
virtual Style_t GetLabelFont() const
Definition TAttAxis.h:39
virtual void SetTitleFont(Style_t font=62)
Set the title font.
Definition TAttAxis.cxx:327
virtual void SetLabelOffset(Float_t offset=0.005)
Set distance between the axis and the labels.
Definition TAttAxis.cxx:191
virtual void SetLabelFont(Style_t font=62)
Set labels' font.
Definition TAttAxis.cxx:180
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title.
Definition TAttAxis.cxx:309
virtual void SetTitleColor(Color_t color=1)
Set color of axis title.
Definition TAttAxis.cxx:318
virtual Float_t GetTitleSize() const
Definition TAttAxis.h:44
virtual Float_t GetLabelSize() const
Definition TAttAxis.h:41
virtual Float_t GetTickLength() const
Definition TAttAxis.h:45
virtual void ResetAttAxis(Option_t *option="")
Reset axis attributes.
Definition TAttAxis.cxx:79
virtual Float_t GetTitleOffset() const
Definition TAttAxis.h:43
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length.
Definition TAttAxis.cxx:284
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition TAttAxis.cxx:233
virtual void SetLabelColor(Color_t color=1, Float_t alpha=1.)
Set color of labels.
Definition TAttAxis.cxx:170
Fill Area Attributes class.
Definition TAttFill.h:19
virtual void Streamer(TBuffer &)
virtual Color_t GetFillColor() const
Return the fill area color.
Definition TAttFill.h:30
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition TAttFill.cxx:204
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition TAttFill.h:31
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
Save fill attributes as C++ statement(s) on output stream out.
Definition TAttFill.cxx:236
Line Attributes class.
Definition TAttLine.h:18
virtual void Streamer(TBuffer &)
virtual Color_t GetLineColor() const
Return the line color.
Definition TAttLine.h:33
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:42
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:35
virtual Style_t GetLineStyle() const
Return the line style.
Definition TAttLine.h:34
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition TAttLine.cxx:175
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:273
Marker Attributes class.
Definition TAttMarker.h:19
virtual void SaveMarkerAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t sizdef=1)
Save line attributes as C++ statement(s) on output stream out.
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition TAttMarker.h:32
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition TAttMarker.h:38
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:31
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition TAttMarker.h:33
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition TAttMarker.h:40
void Copy(TAttMarker &attmarker) const
Copy this marker attributes to a new TAttMarker.
virtual void Streamer(TBuffer &)
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition TAttMarker.h:45
Class to manage histogram axis.
Definition TAxis.h:31
virtual void GetCenter(Double_t *center) const
Return an array with the center of all bins.
Definition TAxis.cxx:553
virtual Bool_t GetTimeDisplay() const
Definition TAxis.h:131
Bool_t IsAlphanumeric() const
Definition TAxis.h:88
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:478
Bool_t CanExtend() const
Definition TAxis.h:86
virtual void SetParent(TObject *obj)
Definition TAxis.h:167
const TArrayD * GetXbins() const
Definition TAxis.h:136
void SetCanExtend(Bool_t canExtend)
Definition TAxis.h:90
void Copy(TObject &axis) const override
Copy axis structure to another axis.
Definition TAxis.cxx:216
Double_t GetXmax() const
Definition TAxis.h:140
@ kLabelsUp
Definition TAxis.h:74
@ kLabelsDown
Definition TAxis.h:73
@ kLabelsHori
Definition TAxis.h:71
@ kAxisRange
Definition TAxis.h:65
@ kLabelsVert
Definition TAxis.h:72
const char * GetBinLabel(Int_t bin) const
Return label for bin.
Definition TAxis.cxx:440
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:293
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:518
virtual void SetTimeDisplay(Int_t value)
Definition TAxis.h:171
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Definition TAxis.cxx:794
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:419
void SaveAttributes(std::ostream &out, const char *name, const char *subname) override
Save axis attributes as C++ statement(s) on output stream out.
Definition TAxis.cxx:710
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:469
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition TAxis.h:164
Double_t GetXmin() const
Definition TAxis.h:139
void Streamer(TBuffer &) override
Stream an object of class TAxis.
Definition TAxis.cxx:1212
Int_t GetNbins() const
Definition TAxis.h:125
virtual void GetLowEdge(Double_t *edge) const
Return an array with the low edge of all bins.
Definition TAxis.cxx:562
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis using bin numbers.
Definition TAxis.cxx:1052
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:540
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:528
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:458
THashList * GetLabels() const
Definition TAxis.h:121
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
Buffer base class used for serializing objects.
Definition TBuffer.h:43
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:4978
ROOT::NewFunc_t GetNew() const
Return the wrapper around new ThisClass().
Definition TClass.cxx:7447
Collection abstract base class.
Definition TCollection.h:65
virtual bool UseRWLock(Bool_t enable=true)
Set this collection to use a RW lock upon access, making it thread safe.
virtual void AddAll(const TCollection *col)
Add all objects from collection col to this collection.
virtual Bool_t IsEmpty() const
TObject * Clone(const char *newname="") const override
Make a clone of an collection using the Streamer facility.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Describe directory structure in memory.
Definition TDirectory.h:45
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:491
1-Dim function class
Definition TF1.h:214
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:3648
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function Note that this histogram is managed ...
Definition TF1.cxx:1586
static TClass * Class()
virtual Int_t GetNpar() const
Definition TF1.h:487
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
IntegralOneDim or analytical integral.
Definition TF1.cxx:2531
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition TF1.cxx:2482
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2281
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=nullptr)
Evaluate function with given coordinates and parameters.
Definition TF1.cxx:1470
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set lower and upper limits for parameter ipar.
Definition TF1.cxx:3501
static Bool_t RejectedPoint()
See TF1::RejectPoint above.
Definition TF1.cxx:3657
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this function.
Definition TF1.cxx:1441
virtual void SetParameter(Int_t param, Double_t value)
Definition TF1.h:640
virtual Bool_t IsInside(const Double_t *x) const
return kTRUE if the point is inside the function range
Definition TF1.h:604
A 2-Dim function with parameters.
Definition TF2.h:29
A 3-Dim function with parameters.
Definition TF3.h:28
Provides an indirection to the TFitResult class and with a semantics identical to a TFitResult pointe...
1-D histogram with a byte per channel (see TH1 documentation)
Definition TH1.h:454
~TH1C() override
Destructor.
Definition TH1.cxx:9438
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9491
TH1C & operator=(const TH1C &h1)
Operator =.
Definition TH1.cxx:9501
TH1C()
Constructor.
Definition TH1.cxx:9390
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9473
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9454
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:9481
1-D histogram with a double per channel (see TH1 documentation)}
Definition TH1.h:620
~TH1D() override
Destructor.
Definition TH1.cxx:10187
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10221
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10203
TH1D()
Constructor.
Definition TH1.cxx:10122
TH1D & operator=(const TH1D &h1)
Operator =.
Definition TH1.cxx:10231
void Reset(Option_t *option="") override
Reset.
Definition TH1.cxx:10211
1-D histogram with a float per channel (see TH1 documentation)}
Definition TH1.h:577
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:606
TH1F & operator=(const TH1F &h1)
Operator =.
Definition TH1.cxx:10050
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:10022
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10040
~TH1F() override
Destructor.
Definition TH1.cxx:10015
TH1F()
Constructor.
Definition TH1.cxx:9941
1-D histogram with an int per channel (see TH1 documentation)}
Definition TH1.h:536
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9858
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9821
~TH1I() override
Destructor.
Definition TH1.cxx:9805
TH1I()
Constructor.
Definition TH1.cxx:9757
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9840
TH1I & operator=(const TH1I &h1)
Operator =.
Definition TH1.cxx:9868
1-D histogram with a short per channel (see TH1 documentation)
Definition TH1.h:495
TH1S & operator=(const TH1S &h1)
Operator =.
Definition TH1.cxx:9684
void Copy(TObject &hnew) const override
Copy this to newth1.
Definition TH1.cxx:9656
TH1S()
Constructor.
Definition TH1.cxx:9573
void SetBinsLength(Int_t n=-1) override
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9674
~TH1S() override
Destructor.
Definition TH1.cxx:9621
void AddBinContent(Int_t bin) override
Increment bin content by 1.
Definition TH1.cxx:9637
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:58
~TH1() override
Histogram default destructor.
Definition TH1.cxx:624
virtual void SetError(const Double_t *error)
Replace bin errors by values in array error.
Definition TH1.cxx:8868
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:8854
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition TH1.cxx:4287
Double_t * fBuffer
[fBufferSize] entry buffer
Definition TH1.h:107
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:1316
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition TH1.cxx:4451
char * GetObjectInfo(Int_t px, Int_t py) const override
Redefines TObject::GetObjectInfo.
Definition TH1.cxx:4482
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition TH1.cxx:6874
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:9058
virtual void Rebuild(Option_t *option="")
Using the current bin info, recompute the arrays for contents and errors.
Definition TH1.cxx:7082
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:361
static Bool_t fgStatOverflows
! Flag to use under/overflows in statistics
Definition TH1.h:116
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:3800
TAxis * GetZaxis()
Definition TH1.h:324
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a line.
Definition TH1.cxx:2805
virtual Bool_t Multiply(TF1 *f1, Double_t c1=1)
Performs the operation:
Definition TH1.cxx:6020
@ kXaxis
Definition TH1.h:72
@ kNoAxis
NOTE: Must always be 0 !!!
Definition TH1.h:71
@ kZaxis
Definition TH1.h:74
@ kYaxis
Definition TH1.h:73
Int_t fNcells
Number of bins(1D), cells (2D) +U/Overflows.
Definition TH1.h:88
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:7750
void Copy(TObject &hnew) const override
Copy this histogram structure to newth1.
Definition TH1.cxx:2653
void SetTitle(const char *title) override
Change/set the title.
Definition TH1.cxx:6707
Double_t fTsumw
Total Sum of weights.
Definition TH1.h:95
virtual Float_t GetBarWidth() const
Definition TH1.h:255
Double_t fTsumw2
Total Sum of squares of weights.
Definition TH1.h:96
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:6920
virtual Float_t GetBarOffset() const
Definition TH1.h:254
TList * fFunctions
->Pointer to list of functions (fits and user)
Definition TH1.h:105
static Bool_t fgAddDirectory
! Flag to add histograms to the directory
Definition TH1.h:115
static TClass * Class()
static Int_t GetDefaultBufferSize()
Static function return the default buffer size for automatic histograms the parameter fgBufferSize ma...
Definition TH1.cxx:4409
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:7894
Double_t fTsumwx2
Total Sum of weight*X*X.
Definition TH1.h:98
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition TH1.cxx:7524
TH1()
Histogram default constructor.
Definition TH1.cxx:596
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:9236
void UseCurrentStyle() override
Copy current attributes from/to current style.
Definition TH1.cxx:7386
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:5353
virtual Int_t GetNbinsY() const
Definition TH1.h:296
Short_t fBarOffset
(1000*offset) for bar charts or legos
Definition TH1.h:92
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:2051
static bool CheckBinLimits(const TAxis *a1, const TAxis *a2)
Check bin limits.
Definition TH1.cxx:1514
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition TH1.cxx:1242
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:8980
static Int_t FitOptionsMake(Option_t *option, Foption_t &Foption)
Decode string choptin and fill fitOption structure.
Definition TH1.cxx:4623
virtual Int_t GetNbinsZ() const
Definition TH1.h:297
virtual Double_t GetNormFactor() const
Definition TH1.h:299
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:7452
virtual Double_t GetSkewness(Int_t axis=1) const
Definition TH1.cxx:7588
virtual void ClearUnderflowAndOverflow()
Remove all the content from the underflow and overflow bins, without changing the number of entries A...
Definition TH1.cxx:2501
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition TH1.cxx:8357
virtual TH1 * DrawNormalized(Option_t *option="", Double_t norm=1) const
Draw a normalized copy of this histogram.
Definition TH1.cxx:3145
@ kNeutral
Adapt to the global flag.
Definition TH1.h:82
virtual Int_t GetDimension() const
Definition TH1.h:281
void Streamer(TBuffer &) override
Stream a class object.
Definition TH1.cxx:6928
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1267
@ kIsAverage
Bin contents are average (used by Add)
Definition TH1.h:169
@ kUserContour
User specified contour levels.
Definition TH1.h:164
@ kNoStats
Don't draw stats box.
Definition TH1.h:163
@ kAutoBinPTwo
different than 1.
Definition TH1.h:172
@ kIsNotW
Histogram is forced to be not weighted even when the histogram is filled with weighted.
Definition TH1.h:170
@ kIsHighlight
bit set if histo is highlight
Definition TH1.h:173
virtual void SetContourLevel(Int_t level, Double_t value)
Set value for one contour level.
Definition TH1.cxx:8439
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition TH1.cxx:6625
TDirectory * fDirectory
! Pointer to directory holding this histogram
Definition TH1.h:108
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition TH1.cxx:7098
void SetNameTitle(const char *name, const char *title) override
Change the name and title of this histogram.
Definition TH1.cxx:8891
TAxis * GetXaxis()
Definition TH1.h:322
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:4945
TH1 * GetCumulative(Bool_t forward=kTRUE, const char *suffix="_cumulative") const
Return a pointer to a histogram containing the cumulative content.
Definition TH1.cxx:2598
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:1281
virtual Int_t GetNcells() const
Definition TH1.h:298
virtual Int_t ShowPeaks(Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
Interface to TSpectrum::Search.
Definition TH1.cxx:9218
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition TH1.cxx:5879
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition TH1.cxx:7801
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition TH1.cxx:4491
TObject * FindObject(const char *name) const override
Search object named name in the list of functions.
Definition TH1.cxx:3860
virtual void FillRandom(const char *fname, Int_t ntimes=5000, TRandom *rng=nullptr)
Fill histogram following distribution in function fname.
Definition TH1.cxx:3520
void Print(Option_t *option="") const override
Print some global quantities for this histogram.
Definition TH1.cxx:7004
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
Definition TH1.cxx:4418
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:3737
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:3901
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:4932
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:8462
virtual Int_t GetNbinsX() const
Definition TH1.h:295
virtual void SetMaximum(Double_t maximum=-1111)
Definition TH1.h:400
virtual TH1 * FFT(TH1 *h_output, Option_t *option)
This function allows to do discrete Fourier transforms of TH1 and TH2.
Definition TH1.cxx:3285
virtual void LabelsInflate(Option_t *axis="X")
Double the number of bins for axis.
Definition TH1.cxx:5286
virtual TH1 * ShowBackground(Int_t niter=20, Option_t *option="same")
This function calculates the background spectrum in this histogram.
Definition TH1.cxx:9204
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
Definition TH1.cxx:5869
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:807
Double_t fMaximum
Maximum value for plotting.
Definition TH1.h:99
Int_t fBufferSize
fBuffer size
Definition TH1.h:106
virtual Double_t RetrieveBinContent(Int_t bin) const
Raw retrieval of bin content on internal data structure see convention for numbering bins in TH1::Get...
Definition TH1.cxx:9356
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:7885
Int_t fDimension
! Histogram dimension (1, 2 or 3 dim)
Definition TH1.h:109
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:9123
EBinErrorOpt fBinStatErrOpt
Option for bin statistical errors.
Definition TH1.h:112
static Int_t fgBufferSize
! Default buffer size for automatic histograms
Definition TH1.h:114
virtual void SetBinsLength(Int_t=-1)
Definition TH1.h:377
Double_t fNormFactor
Normalization factor.
Definition TH1.h:101
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3345
TAxis * GetYaxis()
Definition TH1.h:323
TArrayD fContour
Array to display contour levels.
Definition TH1.h:102
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition TH1.cxx:8996
void Browse(TBrowser *b) override
Browse the Histogram object.
Definition TH1.cxx:743
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition TH1.cxx:8315
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx:3067
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:7296
Short_t fBarWidth
(1000*width) for bar charts or legos
Definition TH1.h:93
virtual Double_t GetBinErrorSqUnchecked(Int_t bin) const
Definition TH1.h:445
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:401
Bool_t IsBinUnderflow(Int_t bin, Int_t axis=0) const
Return true if the bin is underflow.
Definition TH1.cxx:5185
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
Definition TH1.cxx:7154
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:5086
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:6692
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition TH1.cxx:5153
UInt_t GetAxisLabelStatus() const
Internal function used in TH1::Fill to see which axis is full alphanumeric, i.e.
Definition TH1.cxx:6664
Double_t * fIntegral
! Integral of bins used by GetRandom
Definition TH1.h:110
Double_t fMinimum
Minimum value for plotting.
Definition TH1.h:100
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition TH1.cxx:7858
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:9139
virtual void DirectoryAutoAdd(TDirectory *)
Perform the automatic addition of the histogram to the given directory.
Definition TH1.cxx:2783
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:9104
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:9069
void Build()
Creates histogram basic data structure.
Definition TH1.cxx:752
virtual Double_t GetEntries() const
Return the current number of entries.
Definition TH1.cxx:4426
virtual TF1 * GetFunction(const char *name) const
Return pointer to function with name.
Definition TH1.cxx:8968
virtual TH1 * Rebin(Int_t ngroup=2, const char *newname="", const Double_t *xbins=nullptr)
Rebin this histogram.
Definition TH1.cxx:6264
virtual Int_t BufferFill(Double_t x, Double_t w)
accumulate arguments in buffer.
Definition TH1.cxx:1479
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:5057
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:6638
TList * GetListOfFunctions() const
Definition TH1.h:242
void SetName(const char *name) override
Change the name of this histogram.
Definition TH1.cxx:8877
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition TH1.cxx:3114
Bool_t IsEmpty() const
Check if a histogram is empty (this is a protected method used mainly by TH1Merger )
Definition TH1.cxx:5135
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition TH1.cxx:7492
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6195
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:7979
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculated from bin cont...
Definition TH1.cxx:7819
static void SetDefaultBufferSize(Int_t buffersize=1000)
Static function to set the default buffer size for automatic histograms.
Definition TH1.cxx:6682
virtual void SetBinErrorOption(EBinErrorOpt type)
Definition TH1.h:378
virtual void SetBuffer(Int_t buffersize, Option_t *option="")
Set the maximum number of entries to be kept in the buffer.
Definition TH1.cxx:8375
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Definition TH1.cxx:3176
virtual Double_t GetRandom(TRandom *rng=nullptr) const
Return a random number distributed according the histogram bin contents.
Definition TH1.cxx:4981
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:2480
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:1992
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:3474
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition TH1.cxx:8648
@ kNstat
Size of statistics data (up to TProfile3D)
Definition TH1.h:182
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition TH1.cxx:8494
static Int_t AutoP2GetBins(Int_t n)
Auxiliary function to get the next power of 2 integer value larger then n.
Definition TH1.cxx:1294
Double_t fEntries
Number of entries.
Definition TH1.h:94
virtual Long64_t Merge(TCollection *list)
Definition TH1.h:343
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TH1.cxx:3241
virtual Double_t * GetIntegral()
Return a pointer to the array of bins integral.
Definition TH1.cxx:2568
TAxis fZaxis
Z axis descriptor.
Definition TH1.h:91
EStatOverflows fStatOverflows
Per object flag to use under/overflows in statistics.
Definition TH1.h:113
TClass * IsA() const override
Definition TH1.h:440
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:3448
virtual void UpdateBinContent(Int_t bin, Double_t content)
Raw update of bin content on internal data structure see convention for numbering bins in TH1::GetBin...
Definition TH1.cxx:9366
static bool CheckEqualAxes(const TAxis *a1, const TAxis *a2)
Check that the axis are the same.
Definition TH1.cxx:1590
@ kPoisson2
Errors from Poisson interval at 95% CL (~ 2 sigma)
Definition TH1.h:66
@ kNormal
Errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition TH1.h:64
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5032
virtual Int_t GetContour(Double_t *levels=nullptr)
Return contour values into array levels if pointer levels is non zero.
Definition TH1.cxx:8328
TAxis fXaxis
X axis descriptor.
Definition TH1.h:89
virtual Bool_t IsHighlight() const
Definition TH1.h:336
virtual void ExtendAxis(Double_t x, TAxis *axis)
Histogram is resized along axis such that x is in the axis range.
Definition TH1.cxx:6493
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:9080
static bool CheckConsistency(const TH1 *h1, const TH1 *h2)
Check histogram compatibility.
Definition TH1.cxx:1663
TArrayD fSumw2
Array of sum of squares of weights.
Definition TH1.h:103
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:4342
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition TH1.cxx:8347
virtual void SetContour(Int_t nlevels, const Double_t *levels=nullptr)
Set the number and values of contour levels.
Definition TH1.cxx:8400
virtual void SetHighlight(Bool_t set=kTRUE)
Set highlight (enable/disable) mode for the histogram by default highlight mode is disable.
Definition TH1.cxx:4462
virtual Int_t GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum=nullptr)
Compute Quantiles for this histogram Quantile x_q of a probability distribution Function F is defined...
Definition TH1.cxx:4582
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition TH1.cxx:9027
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition TH1.cxx:6593
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition TH1.cxx:8582
virtual Int_t GetSumw2N() const
Definition TH1.h:313
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:3675
Bool_t GetStatOverflowsBehaviour() const
Definition TH1.h:151
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx:2734
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition TH1.cxx:7572
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:2822
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:8552
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:1626
void RecursiveRemove(TObject *obj) override
Recursively remove object from the list of functions.
Definition TH1.cxx:6565
TAxis fYaxis
Y axis descriptor.
Definition TH1.h:90
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:8095
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition TH1.cxx:7834
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:6756
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:9091
TVirtualHistPainter * fPainter
! Pointer to histogram painter
Definition TH1.h:111
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition TH1.cxx:8684
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:3708
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:8937
virtual void SetEntries(Double_t n)
Definition TH1.h:387
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:6449
static bool CheckAxisLimits(const TAxis *a1, const TAxis *a2)
Check that the axis limits of the histograms are the same.
Definition TH1.cxx:1575
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition TH1.cxx:735
static Bool_t fgDefaultSumw2
! Flag to call TH1::Sumw2 automatically at histogram creation time
Definition TH1.h:117
Double_t fTsumwx
Total Sum of weight*X.
Definition TH1.h:97
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:5216
virtual Double_t ComputeIntegral(Bool_t onlyPositive=false)
Compute integral (cumulative sum of bins) The result stored in fIntegral is used by the GetRandom fun...
Definition TH1.cxx:2520
TString fOption
Histogram options.
Definition TH1.h:104
virtual void Eval(TF1 *f1, Option_t *option="")
Evaluate function f1 at the center of bins of this histogram.
Definition TH1.cxx:3193
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:362
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition TH1.cxx:1387
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition TH1.cxx:8907
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition TH1.cxx:7661
2-D histogram with a double per channel (see TH1 documentation)}
Definition TH2.h:301
static THLimitsFinder * GetLimitsFinder()
Return pointer to the current finder.
virtual Int_t FindGoodLimits(TH1 *h, Double_t xmin, Double_t xmax)
Compute the best axis limits for the X axis.
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
void Clear(Option_t *option="") override
Remove all objects from the list.
A doubly linked list.
Definition TList.h:38
void Streamer(TBuffer &) override
Stream all objects in the collection to or from the I/O buffer.
Definition TList.cxx:1191
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:578
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition TList.cxx:764
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:822
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:659
virtual TObjLink * FirstLink() const
Definition TList.h:102
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:470
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:357
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
void Copy(TObject &named) const override
Copy this to obj.
Definition TNamed.cxx:94
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
void Streamer(TBuffer &) override
Stream an object of class TObject.
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
TString fTitle
Definition TNamed.h:33
TString fName
Definition TNamed.h:32
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
Mother of all ROOT objects.
Definition TObject.h:41
void AbstractMethod(const char *method) const
Use this method to implement an "abstract" method that you don't want to leave purely abstract.
Definition TObject.cxx:1029
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:439
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:199
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:457
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:207
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition TObject.cxx:801
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:973
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:184
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:780
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:525
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:791
void ResetBit(UInt_t f)
Definition TObject.h:198
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:64
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:961
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
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition TRandom.cxx:402
Double_t Rndm() override
Machine independent random number generator.
Definition TRandom.cxx:552
virtual Double_t PoissonD(Double_t mean)
Generates a random number according to a Poisson law.
Definition TRandom.cxx:454
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:421
void ToLower()
Change string to lower-case.
Definition TString.cxx:1170
void Clear()
Clear string without changing its capacity.
Definition TString.cxx:1221
const char * Data() const
Definition TString.h:380
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
void ToUpper()
Change string to upper case.
Definition TString.cxx:1183
Bool_t IsNull() const
Definition TString.h:418
TString & Remove(Ssiz_t pos)
Definition TString.h:685
virtual void Streamer(TBuffer &)
Stream a string object.
Definition TString.cxx:1390
TString & Append(const char *cs)
Definition TString.h:576
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:2356
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2334
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:636
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
Int_t GetOptStat() const
Definition TStyle.h:243
void SetOptStat(Int_t stat=1)
The type of information printed in the histogram statistics box can be selected via the parameter mod...
Definition TStyle.cxx:1636
void SetHistFillColor(Color_t color=1)
Definition TStyle.h:376
Color_t GetHistLineColor() const
Definition TStyle.h:231
Bool_t IsReading() const
Definition TStyle.h:294
Float_t GetBarOffset() const
Definition TStyle.h:181
void SetHistLineStyle(Style_t styl=0)
Definition TStyle.h:379
Style_t GetHistFillStyle() const
Definition TStyle.h:232
Color_t GetHistFillColor() const
Definition TStyle.h:230
Float_t GetBarWidth() const
Definition TStyle.h:182
Bool_t GetCanvasPreferGL() const
Definition TStyle.h:186
void SetHistLineColor(Color_t color=1)
Definition TStyle.h:377
void SetBarOffset(Float_t baroff=0.5)
Definition TStyle.h:333
Style_t GetHistLineStyle() const
Definition TStyle.h:233
void SetBarWidth(Float_t barwidth=0.5)
Definition TStyle.h:334
void SetHistFillStyle(Style_t styl=0)
Definition TStyle.h:378
Width_t GetHistLineWidth() const
Definition TStyle.h:234
Int_t GetOptFit() const
Definition TStyle.h:242
void SetHistLineWidth(Width_t width=1)
Definition TStyle.h:380
TVectorT.
Definition TVectorT.h:27
TVirtualFFT is an interface class for Fast Fourier Transforms.
Definition TVirtualFFT.h:88
static TVirtualFFT * FFT(Int_t ndim, Int_t *n, Option_t *option)
Returns a pointer to the FFT of requested size and type.
virtual Int_t GetNdim() const =0
static TVirtualFFT * SineCosine(Int_t ndim, Int_t *n, Int_t *r2rkind, Option_t *option)
Returns a pointer to a sine or cosine transform of requested size and kind.
virtual Option_t * GetType() const =0
virtual void Transform()=0
virtual void GetPointComplex(Int_t ipoint, Double_t &re, Double_t &im, Bool_t fromInput=kFALSE) const =0
virtual Int_t * GetN() const =0
virtual Double_t GetPointReal(Int_t ipoint, Bool_t fromInput=kFALSE) const =0
virtual void SetPoint(Int_t ipoint, Double_t re, Double_t im=0)=0
Abstract Base Class for Fitting.
virtual Int_t GetXlast() const
virtual TObject * GetObjectFit() const
virtual Int_t GetXfirst() const
static TVirtualFitter * GetFitter()
static: return the current Fitter
virtual TObject * GetUserFunc() const
Abstract interface to a histogram painter.
virtual void DrawPanel()=0
Int_t DistancetoPrimitive(Int_t px, Int_t py) override=0
Computes distance from point (px,py) to the object.
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override=0
Execute action corresponding to an event at (px,py).
virtual void SetHighlight()=0
static TVirtualHistPainter * HistPainter(TH1 *obj)
Static function returning a pointer to the current histogram painter.
void Paint(Option_t *option="") override=0
This method must be overridden if a class wants to paint itself.
virtual void SetParent(TObject *)=0
double gamma_quantile_c(double z, double alpha, double theta)
Inverse ( ) of the cumulative distribution function of the upper tail of the gamma distribution (gamm...
double gamma_quantile(double z, double alpha, double theta)
Inverse ( ) of the cumulative distribution function of the lower tail of the gamma distribution (gamm...
const Double_t sigma
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TH1F * h1
Definition legend1.C:5
TF1 * f1
Definition legend1.C:11
return c2
Definition legend2.C:14
R__ALWAYS_INLINE bool HasBeenDeleted(const TObject *obj)
Check if the TObject's memory has been deleted.
Definition TObject.h:402
TFitResultPtr FitObject(TH1 *h1, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption, const char *goption, ROOT::Fit::DataRange &range)
fitting function for a TH1 (called from TH1::Fit)
Definition HFitImpl.cxx:972
double Chisquare(const TH1 &h1, TF1 &f1, bool useRange, EChisquareType type)
compute the chi2 value for an histogram given a function (see TH1::Chisquare for the documentation)
void FitOptionsMake(EFitObjectType type, const char *option, Foption_t &fitOption)
Decode list of options into fitOption.
Definition HFitImpl.cxx:689
void FillData(BinData &dv, const TH1 *hist, TF1 *func=nullptr)
fill the data vector from a TH1.
R__EXTERN TVirtualRWMutex * gCoreMutex
Bool_t IsNaN(Double_t x)
Definition TMath.h:892
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:693
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:250
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition TMath.cxx:637
Double_t Median(Long64_t n, const T *a, const Double_t *w=nullptr, Long64_t *work=nullptr)
Same as RMS.
Definition TMath.h:1272
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754.
Definition TMath.h:902
Double_t Floor(Double_t x)
Rounds x downward, returning the largest integral value that is not greater than x.
Definition TMath.h:680
Double_t ATan(Double_t)
Returns the principal value of the arc tangent of x, expressed in radians.
Definition TMath.h:640
Double_t Ceil(Double_t x)
Rounds x upward, returning the smallest integral value that is not less than x.
Definition TMath.h:668
T MinElement(Long64_t n, const T *a)
Returns minimum of array a of length n.
Definition TMath.h:960
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:756
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:662
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:721
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
constexpr Double_t Pi()
Definition TMath.h:37
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Comparing floating points.
Definition TMath.h:426
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Comparing floating points.
Definition TMath.h:418
Double_t KolmogorovProb(Double_t z)
Calculates the Kolmogorov distribution function,.
Definition TMath.cxx:679
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Sort the n elements of the array a of generic templated type Element.
Definition TMathBase.h:431
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Binary search in an array of n values to locate value.
Definition TMathBase.h:347
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:762
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
Definition TMath.h:917
Definition first.py:1
th1 Draw()
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345
double epsilon
Definition triangle.c:618