Logo ROOT  
Reference Guide
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 <stdlib.h>
13#include <string.h>
14#include <stdio.h>
15#include <ctype.h>
16#include <sstream>
17#include <cmath>
18
19#include "Riostream.h"
20#include "TROOT.h"
21#include "TEnv.h"
22#include "TClass.h"
23#include "TMath.h"
24#include "THashList.h"
25#include "TH1.h"
26#include "TH2.h"
27#include "TH3.h"
28#include "TF2.h"
29#include "TF3.h"
30#include "TPluginManager.h"
31#include "TVirtualPad.h"
32#include "TRandom.h"
33#include "TVirtualFitter.h"
34#include "THLimitsFinder.h"
35#include "TProfile.h"
36#include "TStyle.h"
37#include "TVectorF.h"
38#include "TVectorD.h"
39#include "TBrowser.h"
40#include "TObjString.h"
41#include "TError.h"
42#include "TVirtualHistPainter.h"
43#include "TVirtualFFT.h"
44#include "TVirtualPaveStats.h"
45#include "TSystem.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 Hist
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
72The TH1 histogram class.
73
74### The Histogram classes
75ROOT supports the following histogram types:
76
77 - 1-D histograms:
78 - TH1C : histograms with one byte per channel. Maximum bin content = 127
79 - TH1S : histograms with one short per channel. Maximum bin content = 32767
80 - TH1I : histograms with one int per channel. Maximum bin content = 2147483647
81 - TH1F : histograms with one float per channel. Maximum precision 7 digits
82 - TH1D : histograms with one double per channel. Maximum precision 14 digits
83 - 2-D histograms:
84 - TH2C : histograms with one byte per channel. Maximum bin content = 127
85 - TH2S : histograms with one short per channel. Maximum bin content = 32767
86 - TH2I : histograms with one int per channel. Maximum bin content = 2147483647
87 - TH2F : histograms with one float per channel. Maximum precision 7 digits
88 - TH2D : histograms with one double per channel. Maximum precision 14 digits
89 - 3-D histograms:
90 - TH3C : histograms with one byte per channel. Maximum bin content = 127
91 - TH3S : histograms with one short per channel. Maximum bin content = 32767
92 - TH3I : histograms with one int per channel. Maximum bin content = 2147483647
93 - TH3F : histograms with one float per channel. Maximum precision 7 digits
94 - TH3D : histograms with one double per channel. Maximum precision 14 digits
95 - Profile histograms: See classes TProfile, TProfile2D and TProfile3D.
96 Profile histograms are used to display the mean value of Y and its standard deviation
97 for each bin in X. Profile histograms are in many cases an elegant
98 replacement of two-dimensional histograms : the inter-relation of two
99 measured quantities X and Y can always be visualized by a two-dimensional
100 histogram or scatter-plot; If Y is an unknown (but single-valued)
101 approximate function of X, this function is displayed by a profile
102 histogram with much better precision than by a scatter-plot.
103
104
105All histogram classes are derived from the base class TH1
106~~~ {.cpp}
107 TH1
108 ^
109 |
110 |
111 |
112 +----------------+-------+------+------+-----+-----+
113 | | | | | | |
114 | | TH1C TH1S TH1I TH1F TH1D
115 | | |
116 | | |
117 | TH2 TProfile
118 | |
119 | |
120 | +-------+------+------+-----+-----+
121 | | | | | |
122 | TH2C TH2S TH2I TH2F TH2D
123 | |
124 TH3 |
125 | TProfile2D
126 |
127 +-------+------+------+------+------+
128 | | | | |
129 TH3C TH3S TH3I TH3F TH3D
130 |
131 |
132 TProfile3D
133
134 The TH*C classes also inherit from the array class TArrayC.
135 The TH*S classes also inherit from the array class TArrayS.
136 The TH*I classes also inherit from the array class TArrayI.
137 The TH*F classes also inherit from the array class TArrayF.
138 The TH*D classes also inherit from the array class TArrayD.
139~~~
140
141#### Creating histograms
142
143Histograms are created by invoking one of the constructors, e.g.
144~~~ {.cpp}
145 TH1F *h1 = new TH1F("h1", "h1 title", 100, 0, 4.4);
146 TH2F *h2 = new TH2F("h2", "h2 title", 40, 0, 4, 30, -3, 3);
147~~~
148Histograms may also be created by:
149
150 - calling the Clone function, see below
151 - making a projection from a 2-D or 3-D histogram, see below
152 - reading an histogram from a file
153
154 When an histogram is created, a reference to it is automatically added
155 to the list of in-memory objects for the current file or directory.
156 This default behaviour can be changed by:
157~~~ {.cpp}
158 h->SetDirectory(0); for the current histogram h
159 TH1::AddDirectory(kFALSE); sets a global switch disabling the reference
160~~~
161 When the histogram is deleted, the reference to it is removed from
162 the list of objects in memory.
163 When a file is closed, all histograms in memory associated with this file
164 are automatically deleted.
165
166#### Fix or variable bin size
167
168 All histogram types support either fix or variable bin sizes.
169 2-D histograms may have fix size bins along X and variable size bins
170 along Y or vice-versa. The functions to fill, manipulate, draw or access
171 histograms are identical in both cases.
172
173 Each histogram always contains 3 objects TAxis: fXaxis, fYaxis and fZaxis
174 o access the axis parameters, do:
175~~~ {.cpp}
176 TAxis *xaxis = h->GetXaxis(); etc.
177 Double_t binCenter = xaxis->GetBinCenter(bin), etc.
178~~~
179 See class TAxis for a description of all the access functions.
180 The axis range is always stored internally in double precision.
181
182#### Convention for numbering bins
183
184 For all histogram types: nbins, xlow, xup
185~~~ {.cpp}
186 bin = 0; underflow bin
187 bin = 1; first bin with low-edge xlow INCLUDED
188 bin = nbins; last bin with upper-edge xup EXCLUDED
189 bin = nbins+1; overflow bin
190~~~
191 In case of 2-D or 3-D histograms, a "global bin" number is defined.
192 For example, assuming a 3-D histogram with (binx, biny, binz), the function
193~~~ {.cpp}
194 Int_t gbin = h->GetBin(binx, biny, binz);
195~~~
196 returns a global/linearized gbin number. This global gbin is useful
197 to access the bin content/error information independently of the dimension.
198 Note that to access the information other than bin content and errors
199 one should use the TAxis object directly with e.g.:
200~~~ {.cpp}
201 Double_t xcenter = h3->GetZaxis()->GetBinCenter(27);
202~~~
203 returns the center along z of bin number 27 (not the global bin)
204 in the 3-D histogram h3.
205
206#### Alphanumeric Bin Labels
207
208 By default, an histogram axis is drawn with its numeric bin labels.
209 One can specify alphanumeric labels instead with:
210
211 - call TAxis::SetBinLabel(bin, label);
212 This can always be done before or after filling.
213 When the histogram is drawn, bin labels will be automatically drawn.
214 See examples labels1.C and labels2.C
215 - call to a Fill function with one of the arguments being a string, e.g.
216~~~ {.cpp}
217 hist1->Fill(somename, weight);
218 hist2->Fill(x, somename, weight);
219 hist2->Fill(somename, y, weight);
220 hist2->Fill(somenamex, somenamey, weight);
221~~~
222 See examples hlabels1.C and hlabels2.C
223 - via TTree::Draw. see for example cernstaff.C
224~~~ {.cpp}
225 tree.Draw("Nation::Division");
226~~~
227 where "Nation" and "Division" are two branches of a Tree.
228
229When using the options 2 or 3 above, the labels are automatically
230 added to the list (THashList) of labels for a given axis.
231 By default, an axis is drawn with the order of bins corresponding
232 to the filling sequence. It is possible to reorder the axis
233
234 - alphabetically
235 - by increasing or decreasing values
236
237 The reordering can be triggered via the TAxis context menu by selecting
238 the menu item "LabelsOption" or by calling directly
239 TH1::LabelsOption(option, axis) where
240
241 - axis may be "X", "Y" or "Z"
242 - option may be:
243 - "a" sort by alphabetic order
244 - ">" sort by decreasing values
245 - "<" sort by increasing values
246 - "h" draw labels horizontal
247 - "v" draw labels vertical
248 - "u" draw labels up (end of label right adjusted)
249 - "d" draw labels down (start of label left adjusted)
250
251 When using the option 2 above, new labels are added by doubling the current
252 number of bins in case one label does not exist yet.
253 When the Filling is terminated, it is possible to trim the number
254 of bins to match the number of active labels by calling
255~~~ {.cpp}
256 TH1::LabelsDeflate(axis) with axis = "X", "Y" or "Z"
257~~~
258 This operation is automatic when using TTree::Draw.
259 Once bin labels have been created, they become persistent if the histogram
260 is written to a file or when generating the C++ code via SavePrimitive.
261
262#### Histograms with automatic bins
263
264 When an histogram is created with an axis lower limit greater or equal
265 to its upper limit, the SetBuffer is automatically called with an
266 argument fBufferSize equal to fgBufferSize (default value=1000).
267 fgBufferSize may be reset via the static function TH1::SetDefaultBufferSize.
268 The axis limits will be automatically computed when the buffer will
269 be full or when the function BufferEmpty is called.
270
271#### Filling histograms
272
273 An histogram is typically filled with statements like:
274~~~ {.cpp}
275 h1->Fill(x);
276 h1->Fill(x, w); //fill with weight
277 h2->Fill(x, y)
278 h2->Fill(x, y, w)
279 h3->Fill(x, y, z)
280 h3->Fill(x, y, z, w)
281~~~
282 or via one of the Fill functions accepting names described above.
283 The Fill functions compute the bin number corresponding to the given
284 x, y or z argument and increment this bin by the given weight.
285 The Fill functions return the bin number for 1-D histograms or global
286 bin number for 2-D and 3-D histograms.
287 If TH1::Sumw2 has been called before filling, the sum of squares of
288 weights is also stored.
289 One can also increment directly a bin number via TH1::AddBinContent
290 or replace the existing content via TH1::SetBinContent.
291 To access the bin content of a given bin, do:
292~~~ {.cpp}
293 Double_t binContent = h->GetBinContent(bin);
294~~~
295
296 By default, the bin number is computed using the current axis ranges.
297 If the automatic binning option has been set via
298~~~ {.cpp}
299 h->SetCanExtend(TH1::kAllAxes);
300~~~
301 then, the Fill Function will automatically extend the axis range to
302 accomodate the new value specified in the Fill argument. The method
303 used is to double the bin size until the new value fits in the range,
304 merging bins two by two. This automatic binning options is extensively
305 used by the TTree::Draw function when histogramming Tree variables
306 with an unknown range.
307 This automatic binning option is supported for 1-D, 2-D and 3-D histograms.
308
309 During filling, some statistics parameters are incremented to compute
310 the mean value and Root Mean Square with the maximum precision.
311
312 In case of histograms of type TH1C, TH1S, TH2C, TH2S, TH3C, TH3S
313 a check is made that the bin contents do not exceed the maximum positive
314 capacity (127 or 32767). Histograms of all types may have positive
315 or/and negative bin contents.
316
317#### Rebinning
318 At any time, an histogram can be rebinned via TH1::Rebin. This function
319 returns a new histogram with the rebinned contents.
320 If bin errors were stored, they are recomputed during the rebinning.
321
322#### Associated errors
323 By default, for each bin, the sum of weights is computed at fill time.
324 One can also call TH1::Sumw2 to force the storage and computation
325 of the sum of the square of weights per bin.
326 If Sumw2 has been called, the error per bin is computed as the
327 sqrt(sum of squares of weights), otherwise the error is set equal
328 to the sqrt(bin content).
329 To return the error for a given bin number, do:
330~~~ {.cpp}
331 Double_t error = h->GetBinError(bin);
332~~~
333
334#### Associated functions
335 One or more object (typically a TF1*) can be added to the list
336 of functions (fFunctions) associated to each histogram.
337 When TH1::Fit is invoked, the fitted function is added to this list.
338 Given an histogram h, one can retrieve an associated function
339 with:
340~~~ {.cpp}
341 TF1 *myfunc = h->GetFunction("myfunc");
342~~~
343
344#### Operations on histograms
345
346 Many types of operations are supported on histograms or between histograms
347
348 - Addition of an histogram to the current histogram.
349 - Additions of two histograms with coefficients and storage into the current
350 histogram.
351 - Multiplications and Divisions are supported in the same way as additions.
352 - The Add, Divide and Multiply functions also exist to add, divide or multiply
353 an histogram by a function.
354
355 If an histogram has associated error bars (TH1::Sumw2 has been called),
356 the resulting error bars are also computed assuming independent histograms.
357 In case of divisions, Binomial errors are also supported.
358 One can mark a histogram to be an "average" histogram by setting its bit kIsAverage via
359 myhist.SetBit(TH1::kIsAverage);
360 When adding (see TH1::Add) average histograms, the histograms are averaged and not summed.
361
362#### Fitting histograms
363
364 Histograms (1-D, 2-D, 3-D and Profiles) can be fitted with a user
365 specified function via TH1::Fit. When an histogram is fitted, the
366 resulting function with its parameters is added to the list of functions
367 of this histogram. If the histogram is made persistent, the list of
368 associated functions is also persistent. Given a pointer (see above)
369 to an associated function myfunc, one can retrieve the function/fit
370 parameters with calls such as:
371~~~ {.cpp}
372 Double_t chi2 = myfunc->GetChisquare();
373 Double_t par0 = myfunc->GetParameter(0); value of 1st parameter
374 Double_t err0 = myfunc->GetParError(0); error on first parameter
375~~~
376
377#### Projections of histograms
378
379 One can:
380
381 - make a 1-D projection of a 2-D histogram or Profile
382 see functions TH2::ProjectionX,Y, TH2::ProfileX,Y, TProfile::ProjectionX
383 - make a 1-D, 2-D or profile out of a 3-D histogram
384 see functions TH3::ProjectionZ, TH3::Project3D.
385
386 One can fit these projections via:
387~~~ {.cpp}
388 TH2::FitSlicesX,Y, TH3::FitSlicesZ.
389~~~
390
391#### Random Numbers and histograms
392
393 TH1::FillRandom can be used to randomly fill an histogram using
394 the contents of an existing TF1 function or another
395 TH1 histogram (for all dimensions).
396 For example the following two statements create and fill an histogram
397 10000 times with a default gaussian distribution of mean 0 and sigma 1:
398~~~ {.cpp}
399 TH1F h1("h1", "histo from a gaussian", 100, -3, 3);
400 h1.FillRandom("gaus", 10000);
401~~~
402 TH1::GetRandom can be used to return a random number distributed
403 according the contents of an histogram.
404
405#### Making a copy of an histogram
406 Like for any other ROOT object derived from TObject, one can use
407 the Clone() function. This makes an identical copy of the original
408 histogram including all associated errors and functions, e.g.:
409~~~ {.cpp}
410 TH1F *hnew = (TH1F*)h->Clone("hnew");
411~~~
412
413#### Normalizing histograms
414
415 One can scale an histogram such that the bins integral is equal to
416 the normalization parameter via TH1::Scale(Double_t norm), where norm
417 is the desired normalization divided by the integral of the histogram.
418
419#### Drawing histograms
420
421 Histograms are drawn via the THistPainter class. Each histogram has
422 a pointer to its own painter (to be usable in a multithreaded program).
423 Many drawing options are supported.
424 See THistPainter::Paint() for more details.
425
426 The same histogram can be drawn with different options in different pads.
427 When an histogram drawn in a pad is deleted, the histogram is
428 automatically removed from the pad or pads where it was drawn.
429 If an histogram is drawn in a pad, then filled again, the new status
430 of the histogram will be automatically shown in the pad next time
431 the pad is updated. One does not need to redraw the histogram.
432 To draw the current version of an histogram in a pad, one can use
433~~~ {.cpp}
434 h->DrawCopy();
435~~~
436 This makes a clone (see Clone below) of the histogram. Once the clone
437 is drawn, the original histogram may be modified or deleted without
438 affecting the aspect of the clone.
439
440 One can use TH1::SetMaximum() and TH1::SetMinimum() to force a particular
441 value for the maximum or the minimum scale on the plot. (For 1-D
442 histograms this means the y-axis, while for 2-D histograms these
443 functions affect the z-axis).
444
445 TH1::UseCurrentStyle() can be used to change all histogram graphics
446 attributes to correspond to the current selected style.
447 This function must be called for each histogram.
448 In case one reads and draws many histograms from a file, one can force
449 the histograms to inherit automatically the current graphics style
450 by calling before gROOT->ForceStyle().
451
452#### Setting Drawing histogram contour levels (2-D hists only)
453
454 By default contours are automatically generated at equidistant
455 intervals. A default value of 20 levels is used. This can be modified
456 via TH1::SetContour() or TH1::SetContourLevel().
457 the contours level info is used by the drawing options "cont", "surf",
458 and "lego".
459
460#### Setting histogram graphics attributes
461
462 The histogram classes inherit from the attribute classes:
463 TAttLine, TAttFill, and TAttMarker.
464 See the member functions of these classes for the list of options.
465
466#### Giving titles to the X, Y and Z axis
467
468~~~ {.cpp}
469 h->GetXaxis()->SetTitle("X axis title");
470 h->GetYaxis()->SetTitle("Y axis title");
471~~~
472 The histogram title and the axis titles can be any TLatex string.
473 The titles are part of the persistent histogram.
474 It is also possible to specify the histogram title and the axis
475 titles at creation time. These titles can be given in the "title"
476 parameter. They must be separated by ";":
477~~~ {.cpp}
478 TH1F* h=new TH1F("h", "Histogram title;X Axis;Y Axis;Z Axis", 100, 0, 1);
479~~~
480 Any title can be omitted:
481~~~ {.cpp}
482 TH1F* h=new TH1F("h", "Histogram title;;Y Axis", 100, 0, 1);
483 TH1F* h=new TH1F("h", ";;Y Axis", 100, 0, 1);
484~~~
485 The method SetTitle has the same syntax:
486~~~ {.cpp}
487 h->SetTitle("Histogram title;Another X title Axis");
488~~~
489
490#### Saving/Reading histograms to/from a ROOT file
491
492 The following statements create a ROOT file and store an histogram
493 on the file. Because TH1 derives from TNamed, the key identifier on
494 the file is the histogram name:
495~~~ {.cpp}
496 TFile f("histos.root", "new");
497 TH1F h1("hgaus", "histo from a gaussian", 100, -3, 3);
498 h1.FillRandom("gaus", 10000);
499 h1->Write();
500~~~
501 To read this histogram in another Root session, do:
502~~~ {.cpp}
503 TFile f("histos.root");
504 TH1F *h = (TH1F*)f.Get("hgaus");
505~~~
506 One can save all histograms in memory to the file by:
507~~~ {.cpp}
508 file->Write();
509~~~
510
511#### Miscellaneous operations
512
513~~~ {.cpp}
514 TH1::KolmogorovTest(): statistical test of compatibility in shape
515 between two histograms
516 TH1::Smooth() smooths the bin contents of a 1-d histogram
517 TH1::Integral() returns the integral of bin contents in a given bin range
518 TH1::GetMean(int axis) returns the mean value along axis
519 TH1::GetStdDev(int axis) returns the sigma distribution along axis
520 TH1::GetEntries() returns the number of entries
521 TH1::Reset() resets the bin contents and errors of an histogram
522~~~
523*/
524
525TF1 *gF1=0; //left for back compatibility (use TVirtualFitter::GetUserFunc instead)
526
531
532extern void H1InitGaus();
533extern void H1InitExpo();
534extern void H1InitPolynom();
535extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
536extern void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail);
537extern void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b);
538
539// Internal exceptions for the CheckConsistency method
540class DifferentDimension: public std::exception {};
541class DifferentNumberOfBins: public std::exception {};
542class DifferentAxisLimits: public std::exception {};
543class DifferentBinLimits: public std::exception {};
544class DifferentLabels: public std::exception {};
545
547
548////////////////////////////////////////////////////////////////////////////////
549/// Histogram default constructor.
550
552{
553 fDirectory = 0;
554 fFunctions = new TList;
555 fNcells = 0;
556 fIntegral = 0;
557 fPainter = 0;
558 fEntries = 0;
559 fNormFactor = 0;
561 fMaximum = -1111;
562 fMinimum = -1111;
563 fBufferSize = 0;
564 fBuffer = 0;
566 fStatOverflows = EStatOverflows::kNeutral;
567 fXaxis.SetName("xaxis");
568 fYaxis.SetName("yaxis");
569 fZaxis.SetName("zaxis");
570 fXaxis.SetParent(this);
571 fYaxis.SetParent(this);
572 fZaxis.SetParent(this);
574}
575
576////////////////////////////////////////////////////////////////////////////////
577/// Histogram default destructor.
578
580{
581 if (!TestBit(kNotDeleted)) {
582 return;
583 }
584 delete[] fIntegral;
585 fIntegral = 0;
586 delete[] fBuffer;
587 fBuffer = 0;
588 if (fFunctions) {
590
592 TObject* obj = 0;
593 //special logic to support the case where the same object is
594 //added multiple times in fFunctions.
595 //This case happens when the same object is added with different
596 //drawing modes
597 //In the loop below we must be careful with objects (eg TCutG) that may
598 // have been added to the list of functions of several histograms
599 //and may have been already deleted.
600 while ((obj = fFunctions->First())) {
601 while(fFunctions->Remove(obj)) { }
602 if (!obj->TestBit(kNotDeleted)) {
603 break;
604 }
605 delete obj;
606 obj = 0;
607 }
608 delete fFunctions;
609 fFunctions = 0;
610 }
611 if (fDirectory) {
612 fDirectory->Remove(this);
613 fDirectory = 0;
614 }
615 delete fPainter;
616 fPainter = 0;
617}
618
619////////////////////////////////////////////////////////////////////////////////
620/// Normal constructor for fix bin size histograms.
621/// Creates the main histogram structure.
622///
623/// \param[in] name name of histogram (avoid blanks)
624/// \param[in] title histogram title.
625/// If title is of the form stringt;stringx;stringy;stringz`
626/// the histogram title is set to `stringt`,
627/// the x axis title to `stringy`, the y axis title to `stringy`, etc.
628/// \param[in] nbins number of bins
629/// \param[in] xlow low edge of first bin
630/// \param[in] xup upper edge of last bin (not included in last bin)
631///
632/// When an histogram is created, it is automatically added to the list
633/// of special objects in the current directory.
634/// To find the pointer to this histogram in the current directory
635/// by its name, do:
636/// ~~~ {.cpp}
637/// TH1F *h1 = (TH1F*)gDirectory->FindObject(name);
638/// ~~~
639
640TH1::TH1(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
641 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
642{
643 Build();
644 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
645 fXaxis.Set(nbins,xlow,xup);
646 fNcells = fXaxis.GetNbins()+2;
647}
648
649////////////////////////////////////////////////////////////////////////////////
650/// Normal constructor for variable bin size histograms.
651/// Creates the main histogram structure.
652///
653/// \param[in] name name of histogram (avoid blanks)
654/// \param[in] title histogram title.
655/// If title is of the form `stringt;stringx;stringy;stringz`
656/// the histogram title is set to `stringt`,
657/// the x axis title to `stringy`, the y axis title to `stringy`, etc.
658/// \param[in] nbins number of bins
659/// \param[in] xbins array of low-edges for each bin.
660/// This is an array of size nbins+1
661
662TH1::TH1(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
663 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
664{
665 Build();
666 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
667 if (xbins) fXaxis.Set(nbins,xbins);
668 else fXaxis.Set(nbins,0,1);
669 fNcells = fXaxis.GetNbins()+2;
670}
671
672////////////////////////////////////////////////////////////////////////////////
673/// Normal constructor for variable bin size histograms.
674///
675/// \param[in] name name of histogram (avoid blanks)
676/// \param[in] title histogram title.
677/// If title is of the form `stringt;stringx;stringy;stringz`
678/// the histogram title is set to `stringt`,
679/// the x axis title to `stringy`, the y axis title to `stringy`, etc.
680/// \param[in] nbins number of bins
681/// \param[in] xbins array of low-edges for each bin.
682/// This is an array of size nbins+1
683
684TH1::TH1(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
685 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
686{
687 Build();
688 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
689 if (xbins) fXaxis.Set(nbins,xbins);
690 else fXaxis.Set(nbins,0,1);
691 fNcells = fXaxis.GetNbins()+2;
692}
693
694////////////////////////////////////////////////////////////////////////////////
695/// Copy constructor.
696/// The list of functions is not copied. (Use Clone if needed)
697
699{
700 ((TH1&)h).Copy(*this);
701}
702
703////////////////////////////////////////////////////////////////////////////////
704/// Static function: cannot be inlined on Windows/NT.
705
707{
708 return fgAddDirectory;
709}
710
711////////////////////////////////////////////////////////////////////////////////
712/// Browse the Histogram object.
713
715{
716 Draw(b ? b->GetDrawOption() : "");
717 gPad->Update();
718}
719
720////////////////////////////////////////////////////////////////////////////////
721/// Creates histogram basic data structure.
722
724{
725 fDirectory = 0;
726 fPainter = 0;
727 fIntegral = 0;
728 fEntries = 0;
729 fNormFactor = 0;
731 fMaximum = -1111;
732 fMinimum = -1111;
733 fBufferSize = 0;
734 fBuffer = 0;
736 fStatOverflows = EStatOverflows::kNeutral;
737 fXaxis.SetName("xaxis");
738 fYaxis.SetName("yaxis");
739 fZaxis.SetName("zaxis");
740 fYaxis.Set(1,0.,1.);
741 fZaxis.Set(1,0.,1.);
742 fXaxis.SetParent(this);
743 fYaxis.SetParent(this);
744 fZaxis.SetParent(this);
745
747
748 fFunctions = new TList;
749
751
754 if (fDirectory) {
756 fDirectory->Append(this,kTRUE);
757 }
758 }
759}
760
761////////////////////////////////////////////////////////////////////////////////
762/// Performs the operation: `this = this + c1*f1`
763/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
764///
765/// By default, the function is computed at the centre of the bin.
766/// if option "I" is specified (1-d histogram only), the integral of the
767/// function in each bin is used instead of the value of the function at
768/// the centre of the bin.
769///
770/// Only bins inside the function range are recomputed.
771///
772/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
773/// you should call Sumw2 before making this operation.
774/// This is particularly important if you fit the histogram after TH1::Add
775///
776/// The function return kFALSE if the Add operation failed
777
779{
780 if (!f1) {
781 Error("Add","Attempt to add a non-existing function");
782 return kFALSE;
783 }
784
785 TString opt = option;
786 opt.ToLower();
787 Bool_t integral = kFALSE;
788 if (opt.Contains("i") && fDimension == 1) integral = kTRUE;
789
790 Int_t ncellsx = GetNbinsX() + 2; // cells = normal bins + underflow bin + overflow bin
791 Int_t ncellsy = GetNbinsY() + 2;
792 Int_t ncellsz = GetNbinsZ() + 2;
793 if (fDimension < 2) ncellsy = 1;
794 if (fDimension < 3) ncellsz = 1;
795
796 // delete buffer if it is there since it will become invalid
797 if (fBuffer) BufferEmpty(1);
798
799 // - Add statistics
800 Double_t s1[10];
801 for (Int_t i = 0; i < 10; ++i) s1[i] = 0;
802 PutStats(s1);
803 SetMinimum();
804 SetMaximum();
805
806 // - Loop on bins (including underflows/overflows)
807 Int_t bin, binx, biny, binz;
808 Double_t cu=0;
809 Double_t xx[3];
810 Double_t *params = 0;
811 f1->InitArgs(xx,params);
812 for (binz = 0; binz < ncellsz; ++binz) {
813 xx[2] = fZaxis.GetBinCenter(binz);
814 for (biny = 0; biny < ncellsy; ++biny) {
815 xx[1] = fYaxis.GetBinCenter(biny);
816 for (binx = 0; binx < ncellsx; ++binx) {
817 xx[0] = fXaxis.GetBinCenter(binx);
818 if (!f1->IsInside(xx)) continue;
820 bin = binx + ncellsx * (biny + ncellsy * binz);
821 if (integral) {
822 cu = c1*f1->Integral(fXaxis.GetBinLowEdge(binx), fXaxis.GetBinUpEdge(binx), 0.) / fXaxis.GetBinWidth(binx);
823 } else {
824 cu = c1*f1->EvalPar(xx);
825 }
826 if (TF1::RejectedPoint()) continue;
827 AddBinContent(bin,cu);
828 }
829 }
830 }
831
832 return kTRUE;
833}
834
835////////////////////////////////////////////////////////////////////////////////
836/// Performs the operation: `this = this + c1*h1`
837/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
838///
839/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
840/// if not already set.
841///
842/// Note also that adding histogram with labels is not supported, histogram will be
843/// added merging them by bin number independently of the labels.
844/// For adding histogram with labels one should use TH1::Merge
845///
846/// SPECIAL CASE (Average/Efficiency histograms)
847/// For histograms representing averages or efficiencies, one should compute the average
848/// of the two histograms and not the sum. One can mark a histogram to be an average
849/// histogram by setting its bit kIsAverage with
850/// myhist.SetBit(TH1::kIsAverage);
851/// Note that the two histograms must have their kIsAverage bit set
852///
853/// IMPORTANT NOTE1: If you intend to use the errors of this histogram later
854/// you should call Sumw2 before making this operation.
855/// This is particularly important if you fit the histogram after TH1::Add
856///
857/// IMPORTANT NOTE2: if h1 has a normalisation factor, the normalisation factor
858/// is used , ie this = this + c1*factor*h1
859/// Use the other TH1::Add function if you do not want this feature
860///
861/// The function return kFALSE if the Add operation failed
862
864{
865 if (!h1) {
866 Error("Add","Attempt to add a non-existing histogram");
867 return kFALSE;
868 }
869
870 // delete buffer if it is there since it will become invalid
871 if (fBuffer) BufferEmpty(1);
872
873 bool useMerge = (c1 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
874 try {
875 CheckConsistency(this,h1);
876 useMerge = kFALSE;
877 } catch(DifferentNumberOfBins&) {
878 if (useMerge)
879 Info("Add","Attempt to add histograms with different number of bins - trying to use TH1::Merge");
880 else {
881 Error("Add","Attempt to add histograms with different number of bins : nbins h1 = %d , nbins h2 = %d",GetNbinsX(), h1->GetNbinsX());
882 return kFALSE;
883 }
884 } catch(DifferentAxisLimits&) {
885 if (useMerge)
886 Info("Add","Attempt to add histograms with different axis limits - trying to use TH1::Merge");
887 else
888 Warning("Add","Attempt to add histograms with different axis limits");
889 } catch(DifferentBinLimits&) {
890 if (useMerge)
891 Info("Add","Attempt to add histograms with different bin limits - trying to use TH1::Merge");
892 else
893 Warning("Add","Attempt to add histograms with different bin limits");
894 } catch(DifferentLabels&) {
895 // in case of different labels -
896 if (useMerge)
897 Info("Add","Attempt to add histograms with different labels - trying to use TH1::Merge");
898 else
899 Info("Warning","Attempt to add histograms with different labels");
900 }
901
902 if (useMerge) {
903 TList l;
904 l.Add(const_cast<TH1*>(h1));
905 auto iret = Merge(&l);
906 return (iret >= 0);
907 }
908
909 // Create Sumw2 if h1 has Sumw2 set
910 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
911
912 // - Add statistics
913 Double_t entries = TMath::Abs( GetEntries() + c1 * h1->GetEntries() );
914
915 // statistics can be preserved only in case of positive coefficients
916 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
917 Bool_t resetStats = (c1 < 0);
918 Double_t s1[kNstat] = {0};
919 Double_t s2[kNstat] = {0};
920 if (!resetStats) {
921 // need to initialize to zero s1 and s2 since
922 // GetStats fills only used elements depending on dimension and type
923 GetStats(s1);
924 h1->GetStats(s2);
925 }
926
927 SetMinimum();
928 SetMaximum();
929
930 // - Loop on bins (including underflows/overflows)
931 Double_t factor = 1;
932 if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();;
933 Double_t c1sq = c1 * c1;
934 Double_t factsq = factor * factor;
935
936 for (Int_t bin = 0; bin < fNcells; ++bin) {
937 //special case where histograms have the kIsAverage bit set
938 if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
939 Double_t y1 = h1->RetrieveBinContent(bin);
940 Double_t y2 = this->RetrieveBinContent(bin);
942 Double_t e2sq = this->GetBinErrorSqUnchecked(bin);
943 Double_t w1 = 1., w2 = 1.;
944
945 // consider all special cases when bin errors are zero
946 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
947 if (e1sq) w1 = 1. / e1sq;
948 else if (h1->fSumw2.fN) {
949 w1 = 1.E200; // use an arbitrary huge value
950 if (y1 == 0) {
951 // use an estimated error from the global histogram scale
952 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
953 w1 = 1./(sf*sf);
954 }
955 }
956 if (e2sq) w2 = 1. / e2sq;
957 else if (fSumw2.fN) {
958 w2 = 1.E200; // use an arbitrary huge value
959 if (y2 == 0) {
960 // use an estimated error from the global histogram scale
961 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
962 w2 = 1./(sf*sf);
963 }
964 }
965
966 double y = (w1*y1 + w2*y2)/(w1 + w2);
967 UpdateBinContent(bin, y);
968 if (fSumw2.fN) {
969 double err2 = 1./(w1 + w2);
970 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
971 fSumw2.fArray[bin] = err2;
972 }
973 } else { // normal case of addition between histograms
974 AddBinContent(bin, c1 * factor * h1->RetrieveBinContent(bin));
975 if (fSumw2.fN) fSumw2.fArray[bin] += c1sq * factsq * h1->GetBinErrorSqUnchecked(bin);
976 }
977 }
978
979 // update statistics (do here to avoid changes by SetBinContent)
980 if (resetStats) {
981 // statistics need to be reset in case coefficient are negative
982 ResetStats();
983 }
984 else {
985 for (Int_t i=0;i<kNstat;i++) {
986 if (i == 1) s1[i] += c1*c1*s2[i];
987 else s1[i] += c1*s2[i];
988 }
989 PutStats(s1);
990 SetEntries(entries);
991 }
992 return kTRUE;
993}
994
995////////////////////////////////////////////////////////////////////////////////
996/// Replace contents of this histogram by the addition of h1 and h2.
997///
998/// `this = c1*h1 + c2*h2`
999/// if errors are defined (see TH1::Sumw2), errors are also recalculated
1000///
1001/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
1002/// if not already set.
1003///
1004/// Note also that adding histogram with labels is not supported, histogram will be
1005/// added merging them by bin number independently of the labels.
1006/// For adding histogram ith labels one should use TH1::Merge
1007///
1008/// SPECIAL CASE (Average/Efficiency histograms)
1009/// For histograms representing averages or efficiencies, one should compute the average
1010/// of the two histograms and not the sum. One can mark a histogram to be an average
1011/// histogram by setting its bit kIsAverage with
1012/// myhist.SetBit(TH1::kIsAverage);
1013/// Note that the two histograms must have their kIsAverage bit set
1014///
1015/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
1016/// you should call Sumw2 before making this operation.
1017/// This is particularly important if you fit the histogram after TH1::Add
1018///
1019/// ANOTHER SPECIAL CASE : h1 = h2 and c2 < 0
1020/// do a scaling this = c1 * h1 / (bin Volume)
1021///
1022/// The function returns kFALSE if the Add operation failed
1023
1025{
1026
1027 if (!h1 || !h2) {
1028 Error("Add","Attempt to add a non-existing histogram");
1029 return kFALSE;
1030 }
1031
1032 // delete buffer if it is there since it will become invalid
1033 if (fBuffer) BufferEmpty(1);
1034
1035 Bool_t normWidth = kFALSE;
1036 if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
1037
1038 if (h1 != h2) {
1039 bool useMerge = (c1 == 1. && c2 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
1040
1041 try {
1042 CheckConsistency(h1,h2);
1043 CheckConsistency(this,h1);
1044 useMerge = kFALSE;
1045 } catch(DifferentNumberOfBins&) {
1046 if (useMerge)
1047 Info("Add","Attempt to add histograms with different number of bins - trying to use TH1::Merge");
1048 else {
1049 Error("Add","Attempt to add histograms with different number of bins : nbins h1 = %d , nbins h2 = %d",GetNbinsX(), h1->GetNbinsX());
1050 return kFALSE;
1051 }
1052 } catch(DifferentAxisLimits&) {
1053 if (useMerge)
1054 Info("Add","Attempt to add histograms with different axis limits - trying to use TH1::Merge");
1055 else
1056 Warning("Add","Attempt to add histograms with different axis limits");
1057 } catch(DifferentBinLimits&) {
1058 if (useMerge)
1059 Info("Add","Attempt to add histograms with different bin limits - trying to use TH1::Merge");
1060 else
1061 Warning("Add","Attempt to add histograms with different bin limits");
1062 } catch(DifferentLabels&) {
1063 // in case of different labels -
1064 if (useMerge)
1065 Info("Add","Attempt to add histograms with different labels - trying to use TH1::Merge");
1066 else
1067 Info("Warning","Attempt to add histograms with different labels");
1068 }
1069
1070 if (useMerge) {
1071 TList l;
1072 // why TList takes non-const pointers ????
1073 l.Add(const_cast<TH1*>(h1));
1074 l.Add(const_cast<TH1*>(h2));
1075 Reset("ICE");
1076 auto iret = Merge(&l);
1077 return (iret >= 0);
1078 }
1079 }
1080
1081 // Create Sumw2 if h1 or h2 have Sumw2 set
1082 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
1083
1084 // - Add statistics
1085 Double_t nEntries = TMath::Abs( c1*h1->GetEntries() + c2*h2->GetEntries() );
1086
1087 // TODO remove
1088 // statistics can be preserved only in case of positive coefficients
1089 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1090 // also in case of scaling with the width we cannot preserve the statistics
1091 Double_t s1[kNstat] = {0};
1092 Double_t s2[kNstat] = {0};
1093 Double_t s3[kNstat];
1094
1095
1096 Bool_t resetStats = (c1*c2 < 0) || normWidth;
1097 if (!resetStats) {
1098 // need to initialize to zero s1 and s2 since
1099 // GetStats fills only used elements depending on dimension and type
1100 h1->GetStats(s1);
1101 h2->GetStats(s2);
1102 for (Int_t i=0;i<kNstat;i++) {
1103 if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
1104 //else s3[i] = TMath::Abs(c1)*s1[i] + TMath::Abs(c2)*s2[i];
1105 else s3[i] = c1*s1[i] + c2*s2[i];
1106 }
1107 }
1108
1109 SetMinimum();
1110 SetMaximum();
1111
1112 if (normWidth) { // DEPRECATED CASE: belongs to fitting / drawing modules
1113
1114 Int_t nbinsx = GetNbinsX() + 2; // normal bins + underflow, overflow
1115 Int_t nbinsy = GetNbinsY() + 2;
1116 Int_t nbinsz = GetNbinsZ() + 2;
1117
1118 if (fDimension < 2) nbinsy = 1;
1119 if (fDimension < 3) nbinsz = 1;
1120
1121 Int_t bin, binx, biny, binz;
1122 for (binz = 0; binz < nbinsz; ++binz) {
1123 Double_t wz = h1->GetZaxis()->GetBinWidth(binz);
1124 for (biny = 0; biny < nbinsy; ++biny) {
1125 Double_t wy = h1->GetYaxis()->GetBinWidth(biny);
1126 for (binx = 0; binx < nbinsx; ++binx) {
1127 Double_t wx = h1->GetXaxis()->GetBinWidth(binx);
1128 bin = GetBin(binx, biny, binz);
1129 Double_t w = wx*wy*wz;
1130 UpdateBinContent(bin, c1 * h1->RetrieveBinContent(bin) / w);
1131 if (fSumw2.fN) {
1132 Double_t e1 = h1->GetBinError(bin)/w;
1133 fSumw2.fArray[bin] = c1*c1*e1*e1;
1134 }
1135 }
1136 }
1137 }
1138 } else if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
1139 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
1140 // special case where histograms have the kIsAverage bit set
1142 Double_t y2 = h2->RetrieveBinContent(i);
1144 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
1145 Double_t w1 = 1., w2 = 1.;
1146
1147 // consider all special cases when bin errors are zero
1148 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1149 if (e1sq) w1 = 1./ e1sq;
1150 else if (h1->fSumw2.fN) {
1151 w1 = 1.E200; // use an arbitrary huge value
1152 if (y1 == 0 ) { // use an estimated error from the global histogram scale
1153 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1154 w1 = 1./(sf*sf);
1155 }
1156 }
1157 if (e2sq) w2 = 1./ e2sq;
1158 else if (h2->fSumw2.fN) {
1159 w2 = 1.E200; // use an arbitrary huge value
1160 if (y2 == 0) { // use an estimated error from the global histogram scale
1161 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1162 w2 = 1./(sf*sf);
1163 }
1164 }
1165
1166 double y = (w1*y1 + w2*y2)/(w1 + w2);
1167 UpdateBinContent(i, y);
1168 if (fSumw2.fN) {
1169 double err2 = 1./(w1 + w2);
1170 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1171 fSumw2.fArray[i] = err2;
1172 }
1173 }
1174 } else { // case of simple histogram addition
1175 Double_t c1sq = c1 * c1;
1176 Double_t c2sq = c2 * c2;
1177 for (Int_t i = 0; i < fNcells; ++i) { // Loop on cells (bins including underflows/overflows)
1179 if (fSumw2.fN) {
1180 fSumw2.fArray[i] = c1sq * h1->GetBinErrorSqUnchecked(i) + c2sq * h2->GetBinErrorSqUnchecked(i);
1181 }
1182 }
1183 }
1184
1185 if (resetStats) {
1186 // statistics need to be reset in case coefficient are negative
1187 ResetStats();
1188 }
1189 else {
1190 // update statistics (do here to avoid changes by SetBinContent) FIXME remove???
1191 PutStats(s3);
1192 SetEntries(nEntries);
1193 }
1194
1195 return kTRUE;
1196}
1197
1198////////////////////////////////////////////////////////////////////////////////
1199/// Increment bin content by 1.
1200
1202{
1203 AbstractMethod("AddBinContent");
1204}
1205
1206////////////////////////////////////////////////////////////////////////////////
1207/// Increment bin content by a weight w.
1208
1210{
1211 AbstractMethod("AddBinContent");
1212}
1213
1214////////////////////////////////////////////////////////////////////////////////
1215/// Sets the flag controlling the automatic add of histograms in memory
1216///
1217/// By default (fAddDirectory = kTRUE), histograms are automatically added
1218/// to the list of objects in memory.
1219/// Note that one histogram can be removed from its support directory
1220/// by calling h->SetDirectory(0) or h->SetDirectory(dir) to add it
1221/// to the list of objects in the directory dir.
1222///
1223/// NOTE that this is a static function. To call it, use;
1224/// TH1::AddDirectory
1225
1227{
1228 fgAddDirectory = add;
1229}
1230
1231////////////////////////////////////////////////////////////////////////////////
1232/// Auxilliary function to get the power of 2 next (larger) or previous (smaller)
1233/// a given x
1234///
1235/// next = kTRUE : next larger
1236/// next = kFALSE : previous smaller
1237///
1238/// Used by the autobin power of 2 algorithm
1239
1241{
1242 Int_t nn;
1243 Double_t f2 = std::frexp(x, &nn);
1244 return ((next && x > 0.) || (!next && x <= 0.)) ? std::ldexp(std::copysign(1., f2), nn)
1245 : std::ldexp(std::copysign(1., f2), --nn);
1246}
1247
1248////////////////////////////////////////////////////////////////////////////////
1249/// Auxilliary function to get the next power of 2 integer value larger then n
1250///
1251/// Used by the autobin power of 2 algorithm
1252
1254{
1255 Int_t nn;
1256 Double_t f2 = std::frexp(n, &nn);
1257 if (TMath::Abs(f2 - .5) > 0.001)
1258 return (Int_t)std::ldexp(1., nn);
1259 return n;
1260}
1261
1262////////////////////////////////////////////////////////////////////////////////
1263/// Buffer-based estimate of the histogram range using the power of 2 algorithm.
1264///
1265/// Used by the autobin power of 2 algorithm.
1266///
1267/// Works on arguments (min and max from fBuffer) and internal inputs: fXmin,
1268/// fXmax, NBinsX (from fXaxis), ...
1269/// Result save internally in fXaxis.
1270///
1271/// Overloaded by TH2 and TH3.
1272///
1273/// Return -1 if internal inputs are incosistent, 0 otherwise.
1274///
1275
1277{
1278 // We need meaningful raw limits
1279 if (xmi >= xma)
1280 return -1;
1281
1283 Double_t xhmi = fXaxis.GetXmin();
1284 Double_t xhma = fXaxis.GetXmax();
1285
1286 // Now adjust
1287 if (TMath::Abs(xhma) > TMath::Abs(xhmi)) {
1288 // Start from the upper limit
1289 xhma = TH1::AutoP2GetPower2(xhma);
1290 xhmi = xhma - TH1::AutoP2GetPower2(xhma - xhmi);
1291 } else {
1292 // Start from the lower limit
1293 xhmi = TH1::AutoP2GetPower2(xhmi, kFALSE);
1294 xhma = xhmi + TH1::AutoP2GetPower2(xhma - xhmi);
1295 }
1296
1297 // Round the bins to the next power of 2; take into account the possible inflation
1298 // of the range
1299 Double_t rr = (xhma - xhmi) / (xma - xmi);
1300 Int_t nb = TH1::AutoP2GetBins((Int_t)(rr * GetNbinsX()));
1301
1302 // Adjust using the same bin width and offsets
1303 Double_t bw = (xhma - xhmi) / nb;
1304 // Bins to left free on each side
1305 Double_t autoside = gEnv->GetValue("Hist.Binning.Auto.Side", 0.05);
1306 Int_t nbside = (Int_t)(nb * autoside);
1307
1308 // Side up
1309 Int_t nbup = (xhma - xma) / bw;
1310 if (nbup % 2 != 0)
1311 nbup++; // Must be even
1312 if (nbup != nbside) {
1313 // Accounts also for both case: larger or smaller
1314 xhma -= bw * (nbup - nbside);
1315 nb -= (nbup - nbside);
1316 }
1317
1318 // Side low
1319 Int_t nblw = (xmi - xhmi) / bw;
1320 if (nblw % 2 != 0)
1321 nblw++; // Must be even
1322 if (nblw != nbside) {
1323 // Accounts also for both case: larger or smaller
1324 xhmi += bw * (nblw - nbside);
1325 nb -= (nblw - nbside);
1326 }
1327
1328 // Set everything and project
1329 SetBins(nb, xhmi, xhma);
1330
1331 // Done
1332 return 0;
1333}
1334
1335/// Fill histogram with all entries in the buffer.
1336///
1337/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
1338/// - action = 0 histogram is reset and filled from the buffer. When the histogram is filled from the
1339/// buffer the value fBuffer[0] is set to a negative number (= - number of entries)
1340/// When calling with action == 0 the histogram is NOT refilled when fBuffer[0] is < 0
1341/// While when calling with action = -1 the histogram is reset and ALWAYS refilled independently if
1342/// the histogram was filled before. This is needed when drawing the histogram
1343/// - action = 1 histogram is filled and buffer is deleted
1344/// The buffer is automatically deleted when filling the histogram and the entries is
1345/// larger than the buffer size
1346
1348{
1349 // do we need to compute the bin size?
1350 if (!fBuffer) return 0;
1351 Int_t nbentries = (Int_t)fBuffer[0];
1352
1353 // nbentries correspond to the number of entries of histogram
1354
1355 if (nbentries == 0) {
1356 // if action is 1 we delete the buffer
1357 // this will avoid infinite recursion
1358 if (action > 0) {
1359 delete [] fBuffer;
1360 fBuffer = 0;
1361 fBufferSize = 0;
1362 }
1363 return 0;
1364 }
1365 if (nbentries < 0 && action == 0) return 0; // case histogram has been already filled from the buffer
1366
1367 Double_t *buffer = fBuffer;
1368 if (nbentries < 0) {
1369 nbentries = -nbentries;
1370 // a reset might call BufferEmpty() giving an infinite recursion
1371 // Protect it by setting fBuffer = 0
1372 fBuffer=0;
1373 //do not reset the list of functions
1374 Reset("ICES");
1375 fBuffer = buffer;
1376 }
1377 if (CanExtendAllAxes() || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
1378 //find min, max of entries in buffer
1379 Double_t xmin = fBuffer[2];
1380 Double_t xmax = xmin;
1381 for (Int_t i=1;i<nbentries;i++) {
1382 Double_t x = fBuffer[2*i+2];
1383 if (x < xmin) xmin = x;
1384 if (x > xmax) xmax = x;
1385 }
1386 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
1387 Int_t rc = -1;
1389 if ((rc = AutoP2FindLimits(xmin, xmax)) < 0)
1390 Warning("BufferEmpty",
1391 "incosistency found by power-of-2 autobin algorithm: fallback to standard method");
1392 }
1393 if (rc < 0)
1395 } else {
1396 fBuffer = 0;
1397 Int_t keep = fBufferSize; fBufferSize = 0;
1399 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax, &fXaxis);
1400 fBuffer = buffer;
1401 fBufferSize = keep;
1402 }
1403 }
1404
1405 // call DoFillN which will not put entries in the buffer as FillN does
1406 // set fBuffer to zero to avoid re-emptying the buffer from functions called
1407 // by DoFillN (e.g Sumw2)
1408 buffer = fBuffer; fBuffer = 0;
1409 DoFillN(nbentries,&buffer[2],&buffer[1],2);
1410 fBuffer = buffer;
1411
1412 // if action == 1 - delete the buffer
1413 if (action > 0) {
1414 delete [] fBuffer;
1415 fBuffer = 0;
1416 fBufferSize = 0;
1417 } else {
1418 // if number of entries is consistent with buffer - set it negative to avoid
1419 // refilling the histogram every time BufferEmpty(0) is called
1420 // In case it is not consistent, by setting fBuffer[0]=0 is like resetting the buffer
1421 // (it will not be used anymore the next time BufferEmpty is called)
1422 if (nbentries == (Int_t)fEntries)
1423 fBuffer[0] = -nbentries;
1424 else
1425 fBuffer[0] = 0;
1426 }
1427 return nbentries;
1428}
1429
1430////////////////////////////////////////////////////////////////////////////////
1431/// accumulate arguments in buffer. When buffer is full, empty the buffer
1432///
1433/// - `fBuffer[0]` = number of entries in buffer
1434/// - `fBuffer[1]` = w of first entry
1435/// - `fBuffer[2]` = x of first entry
1436
1438{
1439 if (!fBuffer) return -2;
1440 Int_t nbentries = (Int_t)fBuffer[0];
1441
1442
1443 if (nbentries < 0) {
1444 // reset nbentries to a positive value so next time BufferEmpty() is called
1445 // the histogram will be refilled
1446 nbentries = -nbentries;
1447 fBuffer[0] = nbentries;
1448 if (fEntries > 0) {
1449 // set fBuffer to zero to avoid calling BufferEmpty in Reset
1450 Double_t *buffer = fBuffer; fBuffer=0;
1451 Reset("ICES"); // do not reset list of functions
1452 fBuffer = buffer;
1453 }
1454 }
1455 if (2*nbentries+2 >= fBufferSize) {
1456 BufferEmpty(1);
1457 if (!fBuffer)
1458 // to avoid infinite recursion Fill->BufferFill->Fill
1459 return Fill(x,w);
1460 // this cannot happen
1461 R__ASSERT(0);
1462 }
1463 fBuffer[2*nbentries+1] = w;
1464 fBuffer[2*nbentries+2] = x;
1465 fBuffer[0] += 1;
1466 return -2;
1467}
1468
1469////////////////////////////////////////////////////////////////////////////////
1470/// Check bin limits.
1471
1472bool TH1::CheckBinLimits(const TAxis* a1, const TAxis * a2)
1473{
1474 const TArrayD * h1Array = a1->GetXbins();
1475 const TArrayD * h2Array = a2->GetXbins();
1476 Int_t fN = h1Array->fN;
1477 if ( fN != 0 ) {
1478 if ( h2Array->fN != fN ) {
1479 throw DifferentBinLimits();
1480 return false;
1481 }
1482 else {
1483 for ( int i = 0; i < fN; ++i ) {
1484 // for i==fN (nbin+1) a->GetBinWidth() returns last bin width
1485 // we do not need to exclude that case
1486 double binWidth = a1->GetBinWidth(i);
1487 if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), binWidth*1E-10 ) ) {
1488 throw DifferentBinLimits();
1489 return false;
1490 }
1491 }
1492 }
1493 }
1494
1495 return true;
1496}
1497
1498////////////////////////////////////////////////////////////////////////////////
1499/// Check that axis have same labels.
1500
1501bool TH1::CheckBinLabels(const TAxis* a1, const TAxis * a2)
1502{
1503 THashList *l1 = a1->GetLabels();
1504 THashList *l2 = a2->GetLabels();
1505
1506 if (!l1 && !l2 )
1507 return true;
1508 if (!l1 || !l2 ) {
1509 throw DifferentLabels();
1510 return false;
1511 }
1512 // check now labels sizes are the same
1513 if (l1->GetSize() != l2->GetSize() ) {
1514 throw DifferentLabels();
1515 return false;
1516 }
1517 for (int i = 1; i <= a1->GetNbins(); ++i) {
1518 TString label1 = a1->GetBinLabel(i);
1519 TString label2 = a2->GetBinLabel(i);
1520 if (label1 != label2) {
1521 throw DifferentLabels();
1522 return false;
1523 }
1524 }
1525
1526 return true;
1527}
1528
1529////////////////////////////////////////////////////////////////////////////////
1530/// Check that the axis limits of the histograms are the same.
1531/// If a first and last bin is passed the axis is compared between the given range
1532
1533bool TH1::CheckAxisLimits(const TAxis *a1, const TAxis *a2 )
1534{
1535 double firstBin = a1->GetBinWidth(1);
1536 double lastBin = a1->GetBinWidth( a1->GetNbins() );
1537 if ( ! TMath::AreEqualAbs(a1->GetXmin(), a2->GetXmin(), firstBin* 1.E-10) ||
1538 ! TMath::AreEqualAbs(a1->GetXmax(), a2->GetXmax(), lastBin*1.E-10) ) {
1539 throw DifferentAxisLimits();
1540 return false;
1541 }
1542 return true;
1543}
1544
1545////////////////////////////////////////////////////////////////////////////////
1546/// Check that the axis are the same
1547
1548bool TH1::CheckEqualAxes(const TAxis *a1, const TAxis *a2 )
1549{
1550 if (a1->GetNbins() != a2->GetNbins() ) {
1551 //throw DifferentNumberOfBins();
1552 ::Info("CheckEqualAxes","Axes have different number of bins : nbin1 = %d nbin2 = %d",a1->GetNbins(),a2->GetNbins() );
1553 return false;
1554 }
1555 try {
1556 CheckAxisLimits(a1,a2);
1557 } catch (DifferentAxisLimits&) {
1558 ::Info("CheckEqualAxes","Axes have different limits");
1559 return false;
1560 }
1561 try {
1562 CheckBinLimits(a1,a2);
1563 } catch (DifferentBinLimits&) {
1564 ::Info("CheckEqualAxes","Axes have different bin limits");
1565 return false;
1566 }
1567
1568 // check labels
1569 try {
1570 CheckBinLabels(a1,a2);
1571 } catch (DifferentLabels&) {
1572 ::Info("CheckEqualAxes","Axes have different labels");
1573 return false;
1574 }
1575
1576 return true;
1577}
1578
1579////////////////////////////////////////////////////////////////////////////////
1580/// Check that two sub axis are the same.
1581/// The limits are defined by first bin and last bin
1582/// N.B. no check is done in this case for variable bins
1583
1584bool TH1::CheckConsistentSubAxes(const TAxis *a1, Int_t firstBin1, Int_t lastBin1, const TAxis * a2, Int_t firstBin2, Int_t lastBin2 )
1585{
1586 // By default is assumed that no bins are given for the second axis
1587 Int_t nbins1 = lastBin1-firstBin1 + 1;
1588 Double_t xmin1 = a1->GetBinLowEdge(firstBin1);
1589 Double_t xmax1 = a1->GetBinUpEdge(lastBin1);
1590
1591 Int_t nbins2 = a2->GetNbins();
1592 Double_t xmin2 = a2->GetXmin();
1593 Double_t xmax2 = a2->GetXmax();
1594
1595 if (firstBin2 < lastBin2) {
1596 // in this case assume no bins are given for the second axis
1597 nbins2 = lastBin1-firstBin1 + 1;
1598 xmin2 = a1->GetBinLowEdge(firstBin1);
1599 xmax2 = a1->GetBinUpEdge(lastBin1);
1600 }
1601
1602 if (nbins1 != nbins2 ) {
1603 ::Info("CheckConsistentSubAxes","Axes have different number of bins");
1604 return false;
1605 }
1606
1607 Double_t firstBin = a1->GetBinWidth(firstBin1);
1608 Double_t lastBin = a1->GetBinWidth(lastBin1);
1609 if ( ! TMath::AreEqualAbs(xmin1,xmin2,1.E-10 * firstBin) ||
1610 ! TMath::AreEqualAbs(xmax1,xmax2,1.E-10 * lastBin) ) {
1611 ::Info("CheckConsistentSubAxes","Axes have different limits");
1612 return false;
1613 }
1614
1615 return true;
1616}
1617
1618////////////////////////////////////////////////////////////////////////////////
1619/// Check histogram compatibility.
1620
1621bool TH1::CheckConsistency(const TH1* h1, const TH1* h2)
1622{
1623 if (h1 == h2) return true;
1624
1625 if (h1->GetDimension() != h2->GetDimension() ) {
1626 throw DifferentDimension();
1627 return false;
1628 }
1629 Int_t dim = h1->GetDimension();
1630
1631 // returns kTRUE if number of bins and bin limits are identical
1632 Int_t nbinsx = h1->GetNbinsX();
1633 Int_t nbinsy = h1->GetNbinsY();
1634 Int_t nbinsz = h1->GetNbinsZ();
1635
1636 // Check whether the histograms have the same number of bins.
1637 if (nbinsx != h2->GetNbinsX() ||
1638 (dim > 1 && nbinsy != h2->GetNbinsY()) ||
1639 (dim > 2 && nbinsz != h2->GetNbinsZ()) ) {
1640 throw DifferentNumberOfBins();
1641 return false;
1642 }
1643
1644 bool ret = true;
1645
1646 // check axis limits
1647 ret &= CheckAxisLimits(h1->GetXaxis(), h2->GetXaxis());
1648 if (dim > 1) ret &= CheckAxisLimits(h1->GetYaxis(), h2->GetYaxis());
1649 if (dim > 2) ret &= CheckAxisLimits(h1->GetZaxis(), h2->GetZaxis());
1650
1651 // check bin limits
1652 ret &= CheckBinLimits(h1->GetXaxis(), h2->GetXaxis());
1653 if (dim > 1) ret &= CheckBinLimits(h1->GetYaxis(), h2->GetYaxis());
1654 if (dim > 2) ret &= CheckBinLimits(h1->GetZaxis(), h2->GetZaxis());
1655
1656 // check labels if histograms are both not empty
1657 if ( !h1->IsEmpty() && !h2->IsEmpty() ) {
1658 ret &= CheckBinLabels(h1->GetXaxis(), h2->GetXaxis());
1659 if (dim > 1) ret &= CheckBinLabels(h1->GetYaxis(), h2->GetYaxis());
1660 if (dim > 2) ret &= CheckBinLabels(h1->GetZaxis(), h2->GetZaxis());
1661 }
1662
1663 return ret;
1664}
1665
1666////////////////////////////////////////////////////////////////////////////////
1667/// \f$ \chi^{2} \f$ test for comparing weighted and unweighted histograms
1668///
1669/// Function: Returns p-value. Other return values are specified by the 3rd parameter
1670///
1671/// \param[in] h2 the second histogram
1672/// \param[in] option
1673/// - "UU" = experiment experiment comparison (unweighted-unweighted)
1674/// - "UW" = experiment MC comparison (unweighted-weighted). Note that
1675/// the first histogram should be unweighted
1676/// - "WW" = MC MC comparison (weighted-weighted)
1677/// - "NORM" = to be used when one or both of the histograms is scaled
1678/// but the histogram originally was unweighted
1679/// - by default underflows and overflows are not included:
1680/// * "OF" = overflows included
1681/// * "UF" = underflows included
1682/// - "P" = print chi2, ndf, p_value, igood
1683/// - "CHI2" = returns chi2 instead of p-value
1684/// - "CHI2/NDF" = returns \f$ \chi^{2} \f$/ndf
1685/// \param[in] res not empty - computes normalized residuals and returns them in this array
1686///
1687/// The current implementation is based on the papers \f$ \chi^{2} \f$ test for comparison
1688/// of weighted and unweighted histograms" in Proceedings of PHYSTAT05 and
1689/// "Comparison weighted and unweighted histograms", arXiv:physics/0605123
1690/// by N.Gagunashvili. This function has been implemented by Daniel Haertl in August 2006.
1691///
1692/// #### Introduction:
1693///
1694/// A frequently used technique in data analysis is the comparison of
1695/// histograms. First suggested by Pearson [1] the \f$ \chi^{2} \f$ test of
1696/// homogeneity is used widely for comparing usual (unweighted) histograms.
1697/// This paper describes the implementation modified \f$ \chi^{2} \f$ tests
1698/// for comparison of weighted and unweighted histograms and two weighted
1699/// histograms [2] as well as usual Pearson's \f$ \chi^{2} \f$ test for
1700/// comparison two usual (unweighted) histograms.
1701///
1702/// #### Overview:
1703///
1704/// Comparison of two histograms expect hypotheses that two histograms
1705/// represent identical distributions. To make a decision p-value should
1706/// be calculated. The hypotheses of identity is rejected if the p-value is
1707/// lower then some significance level. Traditionally significance levels
1708/// 0.1, 0.05 and 0.01 are used. The comparison procedure should include an
1709/// analysis of the residuals which is often helpful in identifying the
1710/// bins of histograms responsible for a significant overall \f$ \chi^{2} \f$ value.
1711/// Residuals are the difference between bin contents and expected bin
1712/// contents. Most convenient for analysis are the normalized residuals. If
1713/// hypotheses of identity are valid then normalized residuals are
1714/// approximately independent and identically distributed random variables
1715/// having N(0,1) distribution. Analysis of residuals expect test of above
1716/// mentioned properties of residuals. Notice that indirectly the analysis
1717/// of residuals increase the power of \f$ \chi^{2} \f$ test.
1718///
1719/// #### Methods of comparison:
1720///
1721/// \f$ \chi^{2} \f$ test for comparison two (unweighted) histograms:
1722/// Let us consider two histograms with the same binning and the number
1723/// of bins equal to r. Let us denote the number of events in the ith bin
1724/// in the first histogram as ni and as mi in the second one. The total
1725/// number of events in the first histogram is equal to:
1726/// \f[
1727/// N = \sum_{i=1}^{r} n_{i}
1728/// \f]
1729/// and
1730/// \f[
1731/// M = \sum_{i=1}^{r} m_{i}
1732/// \f]
1733/// in the second histogram. The hypothesis of identity (homogeneity) [3]
1734/// is that the two histograms represent random values with identical
1735/// distributions. It is equivalent that there exist r constants p1,...,pr,
1736/// such that
1737/// \f[
1738///\sum_{i=1}^{r} p_{i}=1
1739/// \f]
1740/// and the probability of belonging to the ith bin for some measured value
1741/// in both experiments is equal to pi. The number of events in the ith
1742/// bin is a random variable with a distribution approximated by a Poisson
1743/// probability distribution
1744/// \f[
1745///\frac{e^{-Np_{i}}(Np_{i})^{n_{i}}}{n_{i}!}
1746/// \f]
1747///for the first histogram and with distribution
1748/// \f[
1749///\frac{e^{-Mp_{i}}(Mp_{i})^{m_{i}}}{m_{i}!}
1750/// \f]
1751/// for the second histogram. If the hypothesis of homogeneity is valid,
1752/// then the maximum likelihood estimator of pi, i=1,...,r, is
1753/// \f[
1754///\hat{p}_{i}= \frac{n_{i}+m_{i}}{N+M}
1755/// \f]
1756/// and then
1757/// \f[
1758/// 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}}
1759/// \f]
1760/// has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [3].
1761/// The comparison procedure can include an analysis of the residuals which
1762/// is often helpful in identifying the bins of histograms responsible for
1763/// a significant overall \f$ \chi^{2} \f$ value. Most convenient for
1764/// analysis are the adjusted (normalized) residuals [4]
1765/// \f[
1766/// 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))}}
1767/// \f]
1768/// If hypotheses of homogeneity are valid then residuals ri are
1769/// approximately independent and identically distributed random variables
1770/// having N(0,1) distribution. The application of the \f$ \chi^{2} \f$ test has
1771/// restrictions related to the value of the expected frequencies Npi,
1772/// Mpi, i=1,...,r. A conservative rule formulated in [5] is that all the
1773/// expectations must be 1 or greater for both histograms. In practical
1774/// cases when expected frequencies are not known the estimated expected
1775/// frequencies \f$ M\hat{p}_{i}, N\hat{p}_{i}, i=1,...,r \f$ can be used.
1776///
1777/// #### Unweighted and weighted histograms comparison:
1778///
1779/// A simple modification of the ideas described above can be used for the
1780/// comparison of the usual (unweighted) and weighted histograms. Let us
1781/// denote the number of events in the ith bin in the unweighted
1782/// histogram as ni and the common weight of events in the ith bin of the
1783/// weighted histogram as wi. The total number of events in the
1784/// unweighted histogram is equal to
1785///\f[
1786/// N = \sum_{i=1}^{r} n_{i}
1787///\f]
1788/// and the total weight of events in the weighted histogram is equal to
1789///\f[
1790/// W = \sum_{i=1}^{r} w_{i}
1791///\f]
1792/// Let us formulate the hypothesis of identity of an unweighted histogram
1793/// to a weighted histogram so that there exist r constants p1,...,pr, such
1794/// that
1795///\f[
1796/// \sum_{i=1}^{r} p_{i} = 1
1797///\f]
1798/// for the unweighted histogram. The weight wi is a random variable with a
1799/// distribution approximated by the normal probability distribution
1800/// \f$ N(Wp_{i},\sigma_{i}^{2}) \f$ where \f$ \sigma_{i}^{2} \f$ is the variance of the weight wi.
1801/// If we replace the variance \f$ \sigma_{i}^{2} \f$
1802/// with estimate \f$ s_{i}^{2} \f$ (sum of squares of weights of
1803/// events in the ith bin) and the hypothesis of identity is valid, then the
1804/// maximum likelihood estimator of pi,i=1,...,r, is
1805///\f[
1806/// \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}}
1807///\f]
1808/// We may then use the test statistic
1809///\f[
1810/// 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}}
1811///\f]
1812/// and it has approximately a \f$ \sigma^{2}_{(r-1)} \f$ distribution [2]. This test, as well
1813/// as the original one [3], has a restriction on the expected frequencies. The
1814/// expected frequencies recommended for the weighted histogram is more than 25.
1815/// The value of the minimal expected frequency can be decreased down to 10 for
1816/// the case when the weights of the events are close to constant. In the case
1817/// of a weighted histogram if the number of events is unknown, then we can
1818/// apply this recommendation for the equivalent number of events as
1819///\f[
1820/// n_{i}^{equiv} = \frac{ w_{i}^{2} }{ s_{i}^{2} }
1821///\f]
1822/// The minimal expected frequency for an unweighted histogram must be 1. Notice
1823/// that any usual (unweighted) histogram can be considered as a weighted
1824/// histogram with events that have constant weights equal to 1.
1825/// The variance \f$ z_{i}^{2} \f$ of the difference between the weight wi
1826/// and the estimated expectation value of the weight is approximately equal to:
1827///\f[
1828/// 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}
1829///\f]
1830/// The residuals
1831///\f[
1832/// r_{i} = \frac{w_{i}-W\hat{p}_{i}}{z_{i}}
1833///\f]
1834/// have approximately a normal distribution with mean equal to 0 and standard
1835/// deviation equal to 1.
1836///
1837/// #### Two weighted histograms comparison:
1838///
1839/// Let us denote the common weight of events of the ith bin in the first
1840/// histogram as w1i and as w2i in the second one. The total weight of events
1841/// in the first histogram is equal to
1842///\f[
1843/// W_{1} = \sum_{i=1}^{r} w_{1i}
1844///\f]
1845/// and
1846///\f[
1847/// W_{2} = \sum_{i=1}^{r} w_{2i}
1848///\f]
1849/// in the second histogram. Let us formulate the hypothesis of identity of
1850/// weighted histograms so that there exist r constants p1,...,pr, such that
1851///\f[
1852/// \sum_{i=1}^{r} p_{i} = 1
1853///\f]
1854/// and also expectation value of weight w1i equal to W1pi and expectation value
1855/// of weight w2i equal to W2pi. Weights in both the histograms are random
1856/// variables with distributions which can be approximated by a normal
1857/// probability distribution \f$ N(W_{1}p_{i},\sigma_{1i}^{2}) \f$ for the first histogram
1858/// and by a distribution \f$ N(W_{2}p_{i},\sigma_{2i}^{2}) \f$ for the second.
1859/// Here \f$ \sigma_{1i}^{2} \f$ and \f$ \sigma_{2i}^{2} \f$ are the variances
1860/// of w1i and w2i with estimators \f$ s_{1i}^{2} \f$ and \f$ s_{2i}^{2} \f$ respectively.
1861/// If the hypothesis of identity is valid, then the maximum likelihood and
1862/// Least Square Method estimator of pi,i=1,...,r, is
1863///\f[
1864/// \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}}
1865///\f]
1866/// We may then use the test statistic
1867///\f[
1868/// 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}}
1869///\f]
1870/// and it has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [2].
1871/// The normalized or studentised residuals [6]
1872///\f[
1873/// 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})}}}
1874///\f]
1875/// have approximately a normal distribution with mean equal to 0 and standard
1876/// deviation 1. A recommended minimal expected frequency is equal to 10 for
1877/// the proposed test.
1878///
1879/// #### Numerical examples:
1880///
1881/// The method described herein is now illustrated with an example.
1882/// We take a distribution
1883///\f[
1884/// \phi(x) = \frac{2}{(x-10)^{2}+1} + \frac{1}{(x-14)^{2}+1} (1)
1885///\f]
1886/// defined on the interval [4,16]. Events distributed according to the formula
1887/// (1) are simulated to create the unweighted histogram. Uniformly distributed
1888/// events are simulated for the weighted histogram with weights calculated by
1889/// formula (1). Each histogram has the same number of bins: 20. Fig.1 shows
1890/// the result of comparison of the unweighted histogram with 200 events
1891/// (minimal expected frequency equal to one) and the weighted histogram with
1892/// 500 events (minimal expected frequency equal to 25)
1893/// Begin_Macro
1894/// ../../../tutorials/math/chi2test.C
1895/// End_Macro
1896/// Fig 1. An example of comparison of the unweighted histogram with 200 events
1897/// and the weighted histogram with 500 events:
1898/// 1. unweighted histogram;
1899/// 2. weighted histogram;
1900/// 3. normalized residuals plot;
1901/// 4. normal Q-Q plot of residuals.
1902///
1903/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1904/// 21.09 with p-value equal to 0.33, therefore the hypothesis of identity of
1905/// the two histograms can be accepted for 0.05 significant level. The behavior
1906/// of the normalized residuals plot (see Fig. 1c) and the normal Q-Q plot
1907/// (see Fig. 1d) of residuals are regular and we cannot identify the outliers
1908/// or bins with a big influence on \f$ \chi^{2} \f$.
1909///
1910/// The second example presents the same two histograms but 17 events was added
1911/// to content of bin number 15 in unweighted histogram. Fig.2 shows the result
1912/// of comparison of the unweighted histogram with 217 events (minimal expected
1913/// frequency equal to one) and the weighted histogram with 500 events (minimal
1914/// expected frequency equal to 25)
1915/// Begin_Macro
1916/// ../../../tutorials/math/chi2test.C(17)
1917/// End_Macro
1918/// Fig 2. An example of comparison of the unweighted histogram with 217 events
1919/// and the weighted histogram with 500 events:
1920/// 1. unweighted histogram;
1921/// 2. weighted histogram;
1922/// 3. normalized residuals plot;
1923/// 4. normal Q-Q plot of residuals.
1924///
1925/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1926/// 32.33 with p-value equal to 0.029, therefore the hypothesis of identity of
1927/// the two histograms is rejected for 0.05 significant level. The behavior of
1928/// the normalized residuals plot (see Fig. 2c) and the normal Q-Q plot (see
1929/// Fig. 2d) of residuals are not regular and we can identify the outlier or
1930/// bin with a big influence on \f$ \chi^{2} \f$.
1931///
1932/// #### References:
1933///
1934/// - [1] Pearson, K., 1904. On the Theory of Contingency and Its Relation to
1935/// Association and Normal Correlation. Drapers' Co. Memoirs, Biometric
1936/// Series No. 1, London.
1937/// - [2] Gagunashvili, N., 2006. \f$ \sigma^{2} \f$ test for comparison
1938/// of weighted and unweighted histograms. Statistical Problems in Particle
1939/// Physics, Astrophysics and Cosmology, Proceedings of PHYSTAT05,
1940/// Oxford, UK, 12-15 September 2005, Imperial College Press, London, 43-44.
1941/// Gagunashvili,N., Comparison of weighted and unweighted histograms,
1942/// arXiv:physics/0605123, 2006.
1943/// - [3] Cramer, H., 1946. Mathematical methods of statistics.
1944/// Princeton University Press, Princeton.
1945/// - [4] Haberman, S.J., 1973. The analysis of residuals in cross-classified tables.
1946/// Biometrics 29, 205-220.
1947/// - [5] Lewontin, R.C. and Felsenstein, J., 1965. The robustness of homogeneity
1948/// test in 2xN tables. Biometrics 21, 19-33.
1949/// - [6] Seber, G.A.F., Lee, A.J., 2003, Linear Regression Analysis.
1950/// John Wiley & Sons Inc., New York.
1951
1952Double_t TH1::Chi2Test(const TH1* h2, Option_t *option, Double_t *res) const
1953{
1954 Double_t chi2 = 0;
1955 Int_t ndf = 0, igood = 0;
1956
1957 TString opt = option;
1958 opt.ToUpper();
1959
1960 Double_t prob = Chi2TestX(h2,chi2,ndf,igood,option,res);
1961
1962 if(opt.Contains("P")) {
1963 printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
1964 }
1965 if(opt.Contains("CHI2/NDF")) {
1966 if (ndf == 0) return 0;
1967 return chi2/ndf;
1968 }
1969 if(opt.Contains("CHI2")) {
1970 return chi2;
1971 }
1972
1973 return prob;
1974}
1975
1976////////////////////////////////////////////////////////////////////////////////
1977/// The computation routine of the Chisquare test. For the method description,
1978/// see Chi2Test() function.
1979///
1980/// \return p-value
1981/// \param[in] h2 the second histogram
1982/// \param[in] option
1983/// - "UU" = experiment experiment comparison (unweighted-unweighted)
1984/// - "UW" = experiment MC comparison (unweighted-weighted). Note that the first
1985/// histogram should be unweighted
1986/// - "WW" = MC MC comparison (weighted-weighted)
1987/// - "NORM" = if one or both histograms is scaled
1988/// - "OF" = overflows included
1989/// - "UF" = underflows included
1990/// by default underflows and overflows are not included
1991/// \param[out] igood test output
1992/// - igood=0 - no problems
1993/// - For unweighted unweighted comparison
1994/// - igood=1'There is a bin in the 1st histogram with less than 1 event'
1995/// - igood=2'There is a bin in the 2nd histogram with less than 1 event'
1996/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
1997/// - For unweighted weighted comparison
1998/// - igood=1'There is a bin in the 1st histogram with less then 1 event'
1999/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective number of events'
2000/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2001/// - For weighted weighted comparison
2002/// - igood=1'There is a bin in the 1st histogram with less then 10 effective
2003/// number of events'
2004/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective
2005/// number of events'
2006/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2007/// \param[out] chi2 chisquare of the test
2008/// \param[out] ndf number of degrees of freedom (important, when both histograms have the same empty bins)
2009/// \param[out] res normalized residuals for further analysis
2010
2011Double_t TH1::Chi2TestX(const TH1* h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option, Double_t *res) const
2012{
2013
2014 Int_t i_start, i_end;
2015 Int_t j_start, j_end;
2016 Int_t k_start, k_end;
2017
2018 Double_t sum1 = 0.0, sumw1 = 0.0;
2019 Double_t sum2 = 0.0, sumw2 = 0.0;
2020
2021 chi2 = 0.0;
2022 ndf = 0;
2023
2024 TString opt = option;
2025 opt.ToUpper();
2026
2027 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
2028
2029 const TAxis *xaxis1 = GetXaxis();
2030 const TAxis *xaxis2 = h2->GetXaxis();
2031 const TAxis *yaxis1 = GetYaxis();
2032 const TAxis *yaxis2 = h2->GetYaxis();
2033 const TAxis *zaxis1 = GetZaxis();
2034 const TAxis *zaxis2 = h2->GetZaxis();
2035
2036 Int_t nbinx1 = xaxis1->GetNbins();
2037 Int_t nbinx2 = xaxis2->GetNbins();
2038 Int_t nbiny1 = yaxis1->GetNbins();
2039 Int_t nbiny2 = yaxis2->GetNbins();
2040 Int_t nbinz1 = zaxis1->GetNbins();
2041 Int_t nbinz2 = zaxis2->GetNbins();
2042
2043 //check dimensions
2044 if (this->GetDimension() != h2->GetDimension() ){
2045 Error("Chi2TestX","Histograms have different dimensions.");
2046 return 0.0;
2047 }
2048
2049 //check number of channels
2050 if (nbinx1 != nbinx2) {
2051 Error("Chi2TestX","different number of x channels");
2052 }
2053 if (nbiny1 != nbiny2) {
2054 Error("Chi2TestX","different number of y channels");
2055 }
2056 if (nbinz1 != nbinz2) {
2057 Error("Chi2TestX","different number of z channels");
2058 }
2059
2060 //check for ranges
2061 i_start = j_start = k_start = 1;
2062 i_end = nbinx1;
2063 j_end = nbiny1;
2064 k_end = nbinz1;
2065
2066 if (xaxis1->TestBit(TAxis::kAxisRange)) {
2067 i_start = xaxis1->GetFirst();
2068 i_end = xaxis1->GetLast();
2069 }
2070 if (yaxis1->TestBit(TAxis::kAxisRange)) {
2071 j_start = yaxis1->GetFirst();
2072 j_end = yaxis1->GetLast();
2073 }
2074 if (zaxis1->TestBit(TAxis::kAxisRange)) {
2075 k_start = zaxis1->GetFirst();
2076 k_end = zaxis1->GetLast();
2077 }
2078
2079
2080 if (opt.Contains("OF")) {
2081 if (GetDimension() == 3) k_end = ++nbinz1;
2082 if (GetDimension() >= 2) j_end = ++nbiny1;
2083 if (GetDimension() >= 1) i_end = ++nbinx1;
2084 }
2085
2086 if (opt.Contains("UF")) {
2087 if (GetDimension() == 3) k_start = 0;
2088 if (GetDimension() >= 2) j_start = 0;
2089 if (GetDimension() >= 1) i_start = 0;
2090 }
2091
2092 ndf = (i_end - i_start + 1) * (j_end - j_start + 1) * (k_end - k_start + 1) - 1;
2093
2094 Bool_t comparisonUU = opt.Contains("UU");
2095 Bool_t comparisonUW = opt.Contains("UW");
2096 Bool_t comparisonWW = opt.Contains("WW");
2097 Bool_t scaledHistogram = opt.Contains("NORM");
2098
2099 if (scaledHistogram && !comparisonUU) {
2100 Info("Chi2TestX", "NORM option should be used together with UU option. It is ignored");
2101 }
2102
2103 // look at histo global bin content and effective entries
2104 Stat_t s[kNstat];
2105 GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2106 Double_t sumBinContent1 = s[0];
2107 Double_t effEntries1 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2108
2109 h2->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2110 Double_t sumBinContent2 = s[0];
2111 Double_t effEntries2 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2112
2113 if (!comparisonUU && !comparisonUW && !comparisonWW ) {
2114 // deduce automatically from type of histogram
2115 if (TMath::Abs(sumBinContent1 - effEntries1) < 1) {
2116 if ( TMath::Abs(sumBinContent2 - effEntries2) < 1) comparisonUU = true;
2117 else comparisonUW = true;
2118 }
2119 else comparisonWW = true;
2120 }
2121 // check unweighted histogram
2122 if (comparisonUW) {
2123 if (TMath::Abs(sumBinContent1 - effEntries1) >= 1) {
2124 Warning("Chi2TestX","First histogram is not unweighted and option UW has been requested");
2125 }
2126 }
2127 if ( (!scaledHistogram && comparisonUU) ) {
2128 if ( ( TMath::Abs(sumBinContent1 - effEntries1) >= 1) || (TMath::Abs(sumBinContent2 - effEntries2) >= 1) ) {
2129 Warning("Chi2TestX","Both histograms are not unweighted and option UU has been requested");
2130 }
2131 }
2132
2133
2134 //get number of events in histogram
2135 if (comparisonUU && scaledHistogram) {
2136 for (Int_t i = i_start; i <= i_end; ++i) {
2137 for (Int_t j = j_start; j <= j_end; ++j) {
2138 for (Int_t k = k_start; k <= k_end; ++k) {
2139
2140 Int_t bin = GetBin(i, j, k);
2141
2142 Double_t cnt1 = RetrieveBinContent(bin);
2143 Double_t cnt2 = h2->RetrieveBinContent(bin);
2144 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2145 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2146
2147 if (e1sq > 0.0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2148 else cnt1 = 0.0;
2149
2150 if (e2sq > 0.0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2151 else cnt2 = 0.0;
2152
2153 // sum contents
2154 sum1 += cnt1;
2155 sum2 += cnt2;
2156 sumw1 += e1sq;
2157 sumw2 += e2sq;
2158 }
2159 }
2160 }
2161 if (sumw1 <= 0.0 || sumw2 <= 0.0) {
2162 Error("Chi2TestX", "Cannot use option NORM when one histogram has all zero errors");
2163 return 0.0;
2164 }
2165
2166 } else {
2167 for (Int_t i = i_start; i <= i_end; ++i) {
2168 for (Int_t j = j_start; j <= j_end; ++j) {
2169 for (Int_t k = k_start; k <= k_end; ++k) {
2170
2171 Int_t bin = GetBin(i, j, k);
2172
2173 sum1 += RetrieveBinContent(bin);
2174 sum2 += h2->RetrieveBinContent(bin);
2175
2176 if ( comparisonWW ) sumw1 += GetBinErrorSqUnchecked(bin);
2177 if ( comparisonUW || comparisonWW ) sumw2 += h2->GetBinErrorSqUnchecked(bin);
2178 }
2179 }
2180 }
2181 }
2182 //checks that the histograms are not empty
2183 if (sum1 == 0.0 || sum2 == 0.0) {
2184 Error("Chi2TestX","one histogram is empty");
2185 return 0.0;
2186 }
2187
2188 if ( comparisonWW && ( sumw1 <= 0.0 && sumw2 <= 0.0 ) ){
2189 Error("Chi2TestX","Hist1 and Hist2 have both all zero errors\n");
2190 return 0.0;
2191 }
2192
2193 //THE TEST
2194 Int_t m = 0, n = 0;
2195
2196 //Experiment - experiment comparison
2197 if (comparisonUU) {
2198 Double_t sum = sum1 + sum2;
2199 for (Int_t i = i_start; i <= i_end; ++i) {
2200 for (Int_t j = j_start; j <= j_end; ++j) {
2201 for (Int_t k = k_start; k <= k_end; ++k) {
2202
2203 Int_t bin = GetBin(i, j, k);
2204
2205 Double_t cnt1 = RetrieveBinContent(bin);
2206 Double_t cnt2 = h2->RetrieveBinContent(bin);
2207
2208 if (scaledHistogram) {
2209 // scale bin value to effective bin entries
2210 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2211 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2212
2213 if (e1sq > 0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2214 else cnt1 = 0;
2215
2216 if (e2sq > 0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2217 else cnt2 = 0;
2218 }
2219
2220 if (Int_t(cnt1) == 0 && Int_t(cnt2) == 0) --ndf; // no data means one degree of freedom less
2221 else {
2222
2223 Double_t cntsum = cnt1 + cnt2;
2224 Double_t nexp1 = cntsum * sum1 / sum;
2225 //Double_t nexp2 = binsum*sum2/sum;
2226
2227 if (res) res[i - i_start] = (cnt1 - nexp1) / TMath::Sqrt(nexp1);
2228
2229 if (cnt1 < 1) ++m;
2230 if (cnt2 < 1) ++n;
2231
2232 //Habermann correction for residuals
2233 Double_t correc = (1. - sum1 / sum) * (1. - cntsum / sum);
2234 if (res) res[i - i_start] /= TMath::Sqrt(correc);
2235
2236 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2237 chi2 += delta * delta / cntsum;
2238 }
2239 }
2240 }
2241 }
2242 chi2 /= sum1 * sum2;
2243
2244 // flag error only when of the two histogram is zero
2245 if (m) {
2246 igood += 1;
2247 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2248 }
2249 if (n) {
2250 igood += 2;
2251 Info("Chi2TestX","There is a bin in h2 with less than 1 event.\n");
2252 }
2253
2254 Double_t prob = TMath::Prob(chi2,ndf);
2255 return prob;
2256
2257 }
2258
2259 // unweighted - weighted comparison
2260 // case of error = 0 and content not zero is treated without problems by excluding second chi2 sum
2261 // and can be considered as a data-theory comparison
2262 if ( comparisonUW ) {
2263 for (Int_t i = i_start; i <= i_end; ++i) {
2264 for (Int_t j = j_start; j <= j_end; ++j) {
2265 for (Int_t k = k_start; k <= k_end; ++k) {
2266
2267 Int_t bin = GetBin(i, j, k);
2268
2269 Double_t cnt1 = RetrieveBinContent(bin);
2270 Double_t cnt2 = h2->RetrieveBinContent(bin);
2271 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2272
2273 // case both histogram have zero bin contents
2274 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2275 --ndf; //no data means one degree of freedom less
2276 continue;
2277 }
2278
2279 // case weighted histogram has zero bin content and error
2280 if (cnt2 * cnt2 == 0 && e2sq == 0) {
2281 if (sumw2 > 0) {
2282 // use as approximated error as 1 scaled by a scaling ratio
2283 // estimated from the total sum weight and sum weight squared
2284 e2sq = sumw2 / sum2;
2285 }
2286 else {
2287 // return error because infinite discrepancy here:
2288 // bin1 != 0 and bin2 =0 in a histogram with all errors zero
2289 Error("Chi2TestX","Hist2 has in bin (%d,%d,%d) zero content and zero errors\n", i, j, k);
2290 chi2 = 0; return 0;
2291 }
2292 }
2293
2294 if (cnt1 < 1) m++;
2295 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2296
2297 Double_t var1 = sum2 * cnt2 - sum1 * e2sq;
2298 Double_t var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2299
2300 // if cnt1 is zero and cnt2 = 1 and sum1 = sum2 var1 = 0 && var2 == 0
2301 // approximate by incrementing cnt1
2302 // LM (this need to be fixed for numerical errors)
2303 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2304 sum1++;
2305 cnt1++;
2306 var1 = sum2 * cnt2 - sum1 * e2sq;
2307 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2308 }
2309 var2 = TMath::Sqrt(var2);
2310
2311 while (var1 + var2 == 0) {
2312 sum1++;
2313 cnt1++;
2314 var1 = sum2 * cnt2 - sum1 * e2sq;
2315 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2316 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2317 sum1++;
2318 cnt1++;
2319 var1 = sum2 * cnt2 - sum1 * e2sq;
2320 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2321 }
2322 var2 = TMath::Sqrt(var2);
2323 }
2324
2325 Double_t probb = (var1 + var2) / (2. * sum2 * sum2);
2326
2327 Double_t nexp1 = probb * sum1;
2328 Double_t nexp2 = probb * sum2;
2329
2330 Double_t delta1 = cnt1 - nexp1;
2331 Double_t delta2 = cnt2 - nexp2;
2332
2333 chi2 += delta1 * delta1 / nexp1;
2334
2335 if (e2sq > 0) {
2336 chi2 += delta2 * delta2 / e2sq;
2337 }
2338
2339 if (res) {
2340 if (e2sq > 0) {
2341 Double_t temp1 = sum2 * e2sq / var2;
2342 Double_t temp2 = 1.0 + (sum1 * e2sq - sum2 * cnt2) / var2;
2343 temp2 = temp1 * temp1 * sum1 * probb * (1.0 - probb) + temp2 * temp2 * e2sq / 4.0;
2344 // invert sign here
2345 res[i - i_start] = - delta2 / TMath::Sqrt(temp2);
2346 }
2347 else
2348 res[i - i_start] = delta1 / TMath::Sqrt(nexp1);
2349 }
2350 }
2351 }
2352 }
2353
2354 if (m) {
2355 igood += 1;
2356 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2357 }
2358 if (n) {
2359 igood += 2;
2360 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2361 }
2362
2363 Double_t prob = TMath::Prob(chi2, ndf);
2364
2365 return prob;
2366 }
2367
2368 // weighted - weighted comparison
2369 if (comparisonWW) {
2370 for (Int_t i = i_start; i <= i_end; ++i) {
2371 for (Int_t j = j_start; j <= j_end; ++j) {
2372 for (Int_t k = k_start; k <= k_end; ++k) {
2373
2374 Int_t bin = GetBin(i, j, k);
2375 Double_t cnt1 = RetrieveBinContent(bin);
2376 Double_t cnt2 = h2->RetrieveBinContent(bin);
2377 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2378 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2379
2380 // case both histogram have zero bin contents
2381 // (use square of content to avoid numerical errors)
2382 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2383 --ndf; //no data means one degree of freedom less
2384 continue;
2385 }
2386
2387 if (e1sq == 0 && e2sq == 0) {
2388 // cannot treat case of booth histogram have zero zero errors
2389 Error("Chi2TestX","h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
2390 chi2 = 0; return 0;
2391 }
2392
2393 Double_t sigma = sum1 * sum1 * e2sq + sum2 * sum2 * e1sq;
2394 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2395 chi2 += delta * delta / sigma;
2396
2397 if (res) {
2398 Double_t temp = cnt1 * sum1 * e2sq + cnt2 * sum2 * e1sq;
2399 Double_t probb = temp / sigma;
2400 Double_t z = 0;
2401 if (e1sq > e2sq) {
2402 Double_t d1 = cnt1 - sum1 * probb;
2403 Double_t s1 = e1sq * ( 1. - e2sq * sum1 * sum1 / sigma );
2404 z = d1 / TMath::Sqrt(s1);
2405 }
2406 else {
2407 Double_t d2 = cnt2 - sum2 * probb;
2408 Double_t s2 = e2sq * ( 1. - e1sq * sum2 * sum2 / sigma );
2409 z = -d2 / TMath::Sqrt(s2);
2410 }
2411 res[i - i_start] = z;
2412 }
2413
2414 if (e1sq > 0 && cnt1 * cnt1 / e1sq < 10) m++;
2415 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2416 }
2417 }
2418 }
2419 if (m) {
2420 igood += 1;
2421 Info("Chi2TestX","There is a bin in h1 with less than 10 effective events.\n");
2422 }
2423 if (n) {
2424 igood += 2;
2425 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2426 }
2427 Double_t prob = TMath::Prob(chi2, ndf);
2428 return prob;
2429 }
2430 return 0;
2431}
2432////////////////////////////////////////////////////////////////////////////////
2433/// Compute and return the chisquare of this histogram with respect to a function
2434/// The chisquare is computed by weighting each histogram point by the bin error
2435/// By default the full range of the histogram is used.
2436/// Use option "R" for restricting the chisquare calculation to the given range of the function
2437/// Use option "L" for using the chisquare based on the poisson likelihood (Baker-Cousins Chisquare)
2438
2439Double_t TH1::Chisquare(TF1 * func, Option_t *option) const
2440{
2441 if (!func) {
2442 Error("Chisquare","Function pointer is Null - return -1");
2443 return -1;
2444 }
2445
2446 TString opt(option); opt.ToUpper();
2447 bool useRange = opt.Contains("R");
2448 bool usePL = opt.Contains("L");
2449
2450 return ROOT::Fit::Chisquare(*this, *func, useRange, usePL);
2451}
2452
2453////////////////////////////////////////////////////////////////////////////////
2454/// Remove all the content from the underflow and overflow bins, without changing the number of entries
2455/// After calling this method, every undeflow and overflow bins will have content 0.0
2456/// The Sumw2 is also cleared, since there is no more content in the bins
2457
2459{
2460 for (Int_t bin = 0; bin < fNcells; ++bin)
2461 if (IsBinUnderflow(bin) || IsBinOverflow(bin)) {
2462 UpdateBinContent(bin, 0.0);
2463 if (fSumw2.fN) fSumw2.fArray[bin] = 0.0;
2464 }
2465}
2466
2467////////////////////////////////////////////////////////////////////////////////
2468/// Compute integral (cumulative sum of bins)
2469/// The result stored in fIntegral is used by the GetRandom functions.
2470/// This function is automatically called by GetRandom when the fIntegral
2471/// array does not exist or when the number of entries in the histogram
2472/// has changed since the previous call to GetRandom.
2473/// The resulting integral is normalized to 1
2474/// If the routine is called with the onlyPositive flag set an error will
2475/// be produced in case of negative bin content and a NaN value returned
2476
2478{
2479 if (fBuffer) BufferEmpty();
2480
2481 // delete previously computed integral (if any)
2482 if (fIntegral) delete [] fIntegral;
2483
2484 // - Allocate space to store the integral and compute integral
2485 Int_t nbinsx = GetNbinsX();
2486 Int_t nbinsy = GetNbinsY();
2487 Int_t nbinsz = GetNbinsZ();
2488 Int_t nbins = nbinsx * nbinsy * nbinsz;
2489
2490 fIntegral = new Double_t[nbins + 2];
2491 Int_t ibin = 0; fIntegral[ibin] = 0;
2492
2493 for (Int_t binz=1; binz <= nbinsz; ++binz) {
2494 for (Int_t biny=1; biny <= nbinsy; ++biny) {
2495 for (Int_t binx=1; binx <= nbinsx; ++binx) {
2496 ++ibin;
2497 Double_t y = RetrieveBinContent(GetBin(binx, biny, binz));
2498 if (onlyPositive && y < 0) {
2499 Error("ComputeIntegral","Bin content is negative - return a NaN value");
2500 fIntegral[nbins] = TMath::QuietNaN();
2501 break;
2502 }
2503 fIntegral[ibin] = fIntegral[ibin - 1] + y;
2504 }
2505 }
2506 }
2507
2508 // - Normalize integral to 1
2509 if (fIntegral[nbins] == 0 ) {
2510 Error("ComputeIntegral", "Integral = zero"); return 0;
2511 }
2512 for (Int_t bin=1; bin <= nbins; ++bin) fIntegral[bin] /= fIntegral[nbins];
2513 fIntegral[nbins+1] = fEntries;
2514 return fIntegral[nbins];
2515}
2516
2517////////////////////////////////////////////////////////////////////////////////
2518/// Return a pointer to the array of bins integral.
2519/// if the pointer fIntegral is null, TH1::ComputeIntegral is called
2520/// The array dimension is the number of bins in the histograms
2521/// including underflow and overflow (fNCells)
2522/// the last value integral[fNCells] is set to the number of entries of
2523/// the histogram
2524
2526{
2527 if (!fIntegral) ComputeIntegral();
2528 return fIntegral;
2529}
2530
2531////////////////////////////////////////////////////////////////////////////////
2532/// Return a pointer to an histogram containing the cumulative The
2533/// cumulative can be computed both in the forward (default) or backward
2534/// direction; the name of the new histogram is constructed from
2535/// the name of this histogram with the suffix suffix appended.
2536///
2537/// The cumulative distribution is formed by filling each bin of the
2538/// resulting histogram with the sum of that bin and all previous
2539/// (forward == kTRUE) or following (forward = kFALSE) bins.
2540///
2541/// note: while cumulative distributions make sense in one dimension, you
2542/// may not be getting what you expect in more than 1D because the concept
2543/// of a cumulative distribution is much trickier to define; make sure you
2544/// understand the order of summation before you use this method with
2545/// histograms of dimension >= 2.
2546
2547TH1 *TH1::GetCumulative(Bool_t forward, const char* suffix) const
2548{
2549 const Int_t nbinsx = GetNbinsX();
2550 const Int_t nbinsy = GetNbinsY();
2551 const Int_t nbinsz = GetNbinsZ();
2552 TH1* hintegrated = (TH1*) Clone(fName + suffix);
2553 hintegrated->Reset();
2554 if (forward) { // Forward computation
2555 Double_t sum = 0.;
2556 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
2557 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
2558 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
2559 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2560 sum += GetBinContent(bin);
2561 hintegrated->SetBinContent(bin, sum);
2562 }
2563 }
2564 }
2565 } else { // Backward computation
2566 Double_t sum = 0.;
2567 for (Int_t binz = nbinsz; binz >= 1; --binz) {
2568 for (Int_t biny = nbinsy; biny >= 1; --biny) {
2569 for (Int_t binx = nbinsx; binx >= 1; --binx) {
2570 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2571 sum += GetBinContent(bin);
2572 hintegrated->SetBinContent(bin, sum);
2573 }
2574 }
2575 }
2576 }
2577 return hintegrated;
2578}
2579
2580////////////////////////////////////////////////////////////////////////////////
2581/// Copy this histogram structure to newth1.
2582///
2583/// Note that this function does not copy the list of associated functions.
2584/// Use TObject::Clone to make a full copy of an histogram.
2585///
2586/// Note also that the histogram it will be created in gDirectory (if AddDirectoryStatus()=true)
2587/// or will not be added to any directory if AddDirectoryStatus()=false
2588/// independently of the current directory stored in the original histogram
2589
2590void TH1::Copy(TObject &obj) const
2591{
2592 if (((TH1&)obj).fDirectory) {
2593 // We are likely to change the hash value of this object
2594 // with TNamed::Copy, to keep things correct, we need to
2595 // clean up its existing entries.
2596 ((TH1&)obj).fDirectory->Remove(&obj);
2597 ((TH1&)obj).fDirectory = 0;
2598 }
2599 TNamed::Copy(obj);
2600 ((TH1&)obj).fDimension = fDimension;
2601 ((TH1&)obj).fNormFactor= fNormFactor;
2602 ((TH1&)obj).fNcells = fNcells;
2603 ((TH1&)obj).fBarOffset = fBarOffset;
2604 ((TH1&)obj).fBarWidth = fBarWidth;
2605 ((TH1&)obj).fOption = fOption;
2606 ((TH1&)obj).fBinStatErrOpt = fBinStatErrOpt;
2607 ((TH1&)obj).fBufferSize= fBufferSize;
2608 // copy the Buffer
2609 // delete first a previously existing buffer
2610 if (((TH1&)obj).fBuffer != 0) {
2611 delete [] ((TH1&)obj).fBuffer;
2612 ((TH1&)obj).fBuffer = 0;
2613 }
2614 if (fBuffer) {
2615 Double_t *buf = new Double_t[fBufferSize];
2616 for (Int_t i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
2617 // obj.fBuffer has been deleted before
2618 ((TH1&)obj).fBuffer = buf;
2619 }
2620
2621
2622 TArray* a = dynamic_cast<TArray*>(&obj);
2623 if (a) a->Set(fNcells);
2624 for (Int_t i = 0; i < fNcells; i++) ((TH1&)obj).UpdateBinContent(i, RetrieveBinContent(i));
2625
2626 ((TH1&)obj).fEntries = fEntries;
2627
2628 // which will call BufferEmpty(0) and set fBuffer[0] to a Maybe one should call
2629 // assignment operator on the TArrayD
2630
2631 ((TH1&)obj).fTsumw = fTsumw;
2632 ((TH1&)obj).fTsumw2 = fTsumw2;
2633 ((TH1&)obj).fTsumwx = fTsumwx;
2634 ((TH1&)obj).fTsumwx2 = fTsumwx2;
2635 ((TH1&)obj).fMaximum = fMaximum;
2636 ((TH1&)obj).fMinimum = fMinimum;
2637
2638 TAttLine::Copy(((TH1&)obj));
2639 TAttFill::Copy(((TH1&)obj));
2640 TAttMarker::Copy(((TH1&)obj));
2641 fXaxis.Copy(((TH1&)obj).fXaxis);
2642 fYaxis.Copy(((TH1&)obj).fYaxis);
2643 fZaxis.Copy(((TH1&)obj).fZaxis);
2644 ((TH1&)obj).fXaxis.SetParent(&obj);
2645 ((TH1&)obj).fYaxis.SetParent(&obj);
2646 ((TH1&)obj).fZaxis.SetParent(&obj);
2647 fContour.Copy(((TH1&)obj).fContour);
2648 fSumw2.Copy(((TH1&)obj).fSumw2);
2649 // fFunctions->Copy(((TH1&)obj).fFunctions);
2650 // when copying an histogram if the AddDirectoryStatus() is true it
2651 // will be added to gDirectory independently of the fDirectory stored.
2652 // and if the AddDirectoryStatus() is false it will not be added to
2653 // any directory (fDirectory = 0)
2654 if (fgAddDirectory && gDirectory) {
2655 gDirectory->Append(&obj);
2656 ((TH1&)obj).fFunctions->UseRWLock();
2657 ((TH1&)obj).fDirectory = gDirectory;
2658 } else
2659 ((TH1&)obj).fDirectory = 0;
2660
2661}
2662
2663////////////////////////////////////////////////////////////////////////////////
2664/// Make a complete copy of the underlying object. If 'newname' is set,
2665/// the copy's name will be set to that name.
2666
2667TObject* TH1::Clone(const char* newname) const
2668{
2669 TH1* obj = (TH1*)IsA()->GetNew()(0);
2670 Copy(*obj);
2671
2672 // Now handle the parts that Copy doesn't do
2673 if(fFunctions) {
2674 // The Copy above might have published 'obj' to the ListOfCleanups.
2675 // Clone can call RecursiveRemove, for example via TCheckHashRecursiveRemoveConsistency
2676 // when dictionary information is initialized, so we need to
2677 // keep obj->fFunction valid during its execution and
2678 // protect the update with the write lock.
2679
2680 // Reset stats parent - else cloning the stats will clone this histogram, too.
2681 auto oldstats = dynamic_cast<TVirtualPaveStats*>(fFunctions->FindObject("stats"));
2682 TObject *oldparent = nullptr;
2683 if (oldstats) {
2684 oldparent = oldstats->GetParent();
2685 oldstats->SetParent(nullptr);
2686 }
2687
2688 auto newlist = (TList*)fFunctions->Clone();
2689
2690 if (oldstats)
2691 oldstats->SetParent(oldparent);
2692 auto newstats = dynamic_cast<TVirtualPaveStats*>(obj->fFunctions->FindObject("stats"));
2693 if (newstats)
2694 newstats->SetParent(obj);
2695
2696 auto oldlist = obj->fFunctions;
2697 {
2699 obj->fFunctions = newlist;
2700 }
2701 delete oldlist;
2702 }
2703 if(newname && strlen(newname) ) {
2704 obj->SetName(newname);
2705 }
2706 return obj;
2707}
2708
2709////////////////////////////////////////////////////////////////////////////////
2710/// Perform the automatic addition of the histogram to the given directory
2711///
2712/// Note this function is called in place when the semantic requires
2713/// this object to be added to a directory (I.e. when being read from
2714/// a TKey or being Cloned)
2715
2717{
2718 Bool_t addStatus = TH1::AddDirectoryStatus();
2719 if (addStatus) {
2720 SetDirectory(dir);
2721 if (dir) {
2723 }
2724 }
2725}
2726
2727////////////////////////////////////////////////////////////////////////////////
2728/// Compute distance from point px,py to a line.
2729///
2730/// Compute the closest distance of approach from point px,py to elements
2731/// of an histogram.
2732/// The distance is computed in pixels units.
2733///
2734/// #### Algorithm:
2735/// Currently, this simple model computes the distance from the mouse
2736/// to the histogram contour only.
2737
2739{
2740 if (!fPainter) return 9999;
2741 return fPainter->DistancetoPrimitive(px,py);
2742}
2743
2744////////////////////////////////////////////////////////////////////////////////
2745/// Performs the operation: `this = this/(c1*f1)`
2746/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2747///
2748/// Only bins inside the function range are recomputed.
2749/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2750/// you should call Sumw2 before making this operation.
2751/// This is particularly important if you fit the histogram after TH1::Divide
2752///
2753/// The function return kFALSE if the divide operation failed
2754
2756{
2757 if (!f1) {
2758 Error("Divide","Attempt to divide by a non-existing function");
2759 return kFALSE;
2760 }
2761
2762 // delete buffer if it is there since it will become invalid
2763 if (fBuffer) BufferEmpty(1);
2764
2765 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of
2766 Int_t ny = GetNbinsY() + 2;
2767 Int_t nz = GetNbinsZ() + 2;
2768 if (fDimension < 2) ny = 1;
2769 if (fDimension < 3) nz = 1;
2770
2771
2772 SetMinimum();
2773 SetMaximum();
2774
2775 // - Loop on bins (including underflows/overflows)
2776 Int_t bin, binx, biny, binz;
2777 Double_t cu, w;
2778 Double_t xx[3];
2779 Double_t *params = 0;
2780 f1->InitArgs(xx,params);
2781 for (binz = 0; binz < nz; ++binz) {
2782 xx[2] = fZaxis.GetBinCenter(binz);
2783 for (biny = 0; biny < ny; ++biny) {
2784 xx[1] = fYaxis.GetBinCenter(biny);
2785 for (binx = 0; binx < nx; ++binx) {
2786 xx[0] = fXaxis.GetBinCenter(binx);
2787 if (!f1->IsInside(xx)) continue;
2789 bin = binx + nx * (biny + ny * binz);
2790 cu = c1 * f1->EvalPar(xx);
2791 if (TF1::RejectedPoint()) continue;
2792 if (cu) w = RetrieveBinContent(bin) / cu;
2793 else w = 0;
2794 UpdateBinContent(bin, w);
2795 if (fSumw2.fN) {
2796 if (cu != 0) fSumw2.fArray[bin] = GetBinErrorSqUnchecked(bin) / (cu * cu);
2797 else fSumw2.fArray[bin] = 0;
2798 }
2799 }
2800 }
2801 }
2802 ResetStats();
2803 return kTRUE;
2804}
2805
2806////////////////////////////////////////////////////////////////////////////////
2807/// Divide this histogram by h1.
2808///
2809/// `this = this/h1`
2810/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2811/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
2812/// if not already set.
2813/// The resulting errors are calculated assuming uncorrelated histograms.
2814/// See the other TH1::Divide that gives the possibility to optionally
2815/// compute binomial errors.
2816///
2817/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2818/// you should call Sumw2 before making this operation.
2819/// This is particularly important if you fit the histogram after TH1::Scale
2820///
2821/// The function return kFALSE if the divide operation failed
2822
2823Bool_t TH1::Divide(const TH1 *h1)
2824{
2825 if (!h1) {
2826 Error("Divide", "Input histogram passed does not exist (NULL).");
2827 return kFALSE;
2828 }
2829
2830 // delete buffer if it is there since it will become invalid
2831 if (fBuffer) BufferEmpty(1);
2832
2833 try {
2834 CheckConsistency(this,h1);
2835 } catch(DifferentNumberOfBins&) {
2836 Error("Divide","Cannot divide histograms with different number of bins");
2837 return kFALSE;
2838 } catch(DifferentAxisLimits&) {
2839 Warning("Divide","Dividing histograms with different axis limits");
2840 } catch(DifferentBinLimits&) {
2841 Warning("Divide","Dividing histograms with different bin limits");
2842 } catch(DifferentLabels&) {
2843 Warning("Divide","Dividing histograms with different labels");
2844 }
2845
2846 // Create Sumw2 if h1 has Sumw2 set
2847 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
2848
2849 // - Loop on bins (including underflows/overflows)
2850 for (Int_t i = 0; i < fNcells; ++i) {
2853 if (c1) UpdateBinContent(i, c0 / c1);
2854 else UpdateBinContent(i, 0);
2855
2856 if(fSumw2.fN) {
2857 if (c1 == 0) { fSumw2.fArray[i] = 0; continue; }
2858 Double_t c1sq = c1 * c1;
2859 fSumw2.fArray[i] = (GetBinErrorSqUnchecked(i) * c1sq + h1->GetBinErrorSqUnchecked(i) * c0 * c0) / (c1sq * c1sq);
2860 }
2861 }
2862 ResetStats();
2863 return kTRUE;
2864}
2865
2866////////////////////////////////////////////////////////////////////////////////
2867/// Replace contents of this histogram by the division of h1 by h2.
2868///
2869/// `this = c1*h1/(c2*h2)`
2870///
2871/// If errors are defined (see TH1::Sumw2), errors are also recalculated
2872/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
2873/// if not already set.
2874/// The resulting errors are calculated assuming uncorrelated histograms.
2875/// However, if option ="B" is specified, Binomial errors are computed.
2876/// In this case c1 and c2 do not make real sense and they are ignored.
2877///
2878/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2879/// you should call Sumw2 before making this operation.
2880/// This is particularly important if you fit the histogram after TH1::Divide
2881///
2882/// Please note also that in the binomial case errors are calculated using standard
2883/// binomial statistics, which means when b1 = b2, the error is zero.
2884/// If you prefer to have efficiency errors not going to zero when the efficiency is 1, you must
2885/// use the function TGraphAsymmErrors::BayesDivide, which will return an asymmetric and non-zero lower
2886/// error for the case b1=b2.
2887///
2888/// The function return kFALSE if the divide operation failed
2889
2890Bool_t TH1::Divide(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
2891{
2892
2893 TString opt = option;
2894 opt.ToLower();
2895 Bool_t binomial = kFALSE;
2896 if (opt.Contains("b")) binomial = kTRUE;
2897 if (!h1 || !h2) {
2898 Error("Divide", "At least one of the input histograms passed does not exist (NULL).");
2899 return kFALSE;
2900 }
2901
2902 // delete buffer if it is there since it will become invalid
2903 if (fBuffer) BufferEmpty(1);
2904
2905 try {
2906 CheckConsistency(h1,h2);
2907 CheckConsistency(this,h1);
2908 } catch(DifferentNumberOfBins&) {
2909 Error("Divide","Cannot divide histograms with different number of bins");
2910 return kFALSE;
2911 } catch(DifferentAxisLimits&) {
2912 Warning("Divide","Dividing histograms with different axis limits");
2913 } catch(DifferentBinLimits&) {
2914 Warning("Divide","Dividing histograms with different bin limits");
2915 } catch(DifferentLabels&) {
2916 Warning("Divide","Dividing histograms with different labels");
2917 }
2918
2919
2920 if (!c2) {
2921 Error("Divide","Coefficient of dividing histogram cannot be zero");
2922 return kFALSE;
2923 }
2924
2925 // Create Sumw2 if h1 or h2 have Sumw2 set, or if binomial errors are explicitly requested
2926 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0 || binomial)) Sumw2();
2927
2928 SetMinimum();
2929 SetMaximum();
2930
2931 // - Loop on bins (including underflows/overflows)
2932 for (Int_t i = 0; i < fNcells; ++i) {
2934 Double_t b2 = h2->RetrieveBinContent(i);
2935 if (b2) UpdateBinContent(i, c1 * b1 / (c2 * b2));
2936 else UpdateBinContent(i, 0);
2937
2938 if (fSumw2.fN) {
2939 if (b2 == 0) { fSumw2.fArray[i] = 0; continue; }
2940 Double_t b1sq = b1 * b1; Double_t b2sq = b2 * b2;
2941 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
2943 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
2944 if (binomial) {
2945 if (b1 != b2) {
2946 // in the case of binomial statistics c1 and c2 must be 1 otherwise it does not make sense
2947 // c1 and c2 are ignored
2948 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));//this is the formula in Hbook/Hoper1
2949 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2); // old formula from G. Flucke
2950 // formula which works also for weighted histogram (see http://root-forum.cern.ch/viewtopic.php?t=3753 )
2951 fSumw2.fArray[i] = TMath::Abs( ( (1. - 2.* b1 / b2) * e1sq + b1sq * e2sq / b2sq ) / b2sq );
2952 } else {
2953 //in case b1=b2 error is zero
2954 //use TGraphAsymmErrors::BayesDivide for getting the asymmetric error not equal to zero
2955 fSumw2.fArray[i] = 0;
2956 }
2957 } else {
2958 fSumw2.fArray[i] = c1sq * c2sq * (e1sq * b2sq + e2sq * b1sq) / (c2sq * c2sq * b2sq * b2sq);
2959 }
2960 }
2961 }
2962 ResetStats();
2963 if (binomial)
2964 // in case of binomial division use denominator for number of entries
2965 SetEntries ( h2->GetEntries() );
2966
2967 return kTRUE;
2968}
2969
2970////////////////////////////////////////////////////////////////////////////////
2971/// Draw this histogram with options.
2972///
2973/// Histograms are drawn via the THistPainter class. Each histogram has
2974/// a pointer to its own painter (to be usable in a multithreaded program).
2975/// The same histogram can be drawn with different options in different pads.
2976/// When an histogram drawn in a pad is deleted, the histogram is
2977/// automatically removed from the pad or pads where it was drawn.
2978/// If an histogram is drawn in a pad, then filled again, the new status
2979/// of the histogram will be automatically shown in the pad next time
2980/// the pad is updated. One does not need to redraw the histogram.
2981/// To draw the current version of an histogram in a pad, one can use
2982/// `h->DrawCopy();`
2983/// This makes a clone of the histogram. Once the clone is drawn, the original
2984/// histogram may be modified or deleted without affecting the aspect of the
2985/// clone.
2986/// By default, TH1::Draw clears the current pad.
2987///
2988/// One can use TH1::SetMaximum and TH1::SetMinimum to force a particular
2989/// value for the maximum or the minimum scale on the plot.
2990///
2991/// TH1::UseCurrentStyle can be used to change all histogram graphics
2992/// attributes to correspond to the current selected style.
2993/// This function must be called for each histogram.
2994/// In case one reads and draws many histograms from a file, one can force
2995/// the histograms to inherit automatically the current graphics style
2996/// by calling before gROOT->ForceStyle();
2997///
2998/// See the THistPainter class for a description of all the drawing options.
2999
3000void TH1::Draw(Option_t *option)
3001{
3002 TString opt1 = option; opt1.ToLower();
3003 TString opt2 = option;
3004 Int_t index = opt1.Index("same");
3005
3006 // Check if the string "same" is part of a TCutg name.
3007 if (index>=0) {
3008 Int_t indb = opt1.Index("[");
3009 if (indb>=0) {
3010 Int_t indk = opt1.Index("]");
3011 if (index>indb && index<indk) index = -1;
3012 }
3013 }
3014
3015 // If there is no pad or an empty pad the "same" option is ignored.
3016 if (gPad) {
3017 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
3018 if (index>=0) {
3019 if (gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
3020 gPad->GetY1() == 0 && gPad->GetY2() == 1 &&
3021 gPad->GetListOfPrimitives()->GetSize()==0) opt2.Remove(index,4);
3022 } else {
3023 //the following statement is necessary in case one attempts to draw
3024 //a temporary histogram already in the current pad
3025 if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(this);
3026 gPad->Clear();
3027 }
3028 gPad->IncrementPaletteColor(1, opt1);
3029 } else {
3030 if (index>=0) opt2.Remove(index,4);
3031 }
3032
3033 AppendPad(opt2.Data());
3034}
3035
3036////////////////////////////////////////////////////////////////////////////////
3037/// Copy this histogram and Draw in the current pad.
3038///
3039/// Once the histogram is drawn into the pad, any further modification
3040/// using graphics input will be made on the copy of the histogram,
3041/// and not to the original object.
3042/// By default a postfix "_copy" is added to the histogram name. Pass an empty postfix in case
3043/// you want to draw an histogram with the same name
3044///
3045/// See Draw for the list of options
3046
3047TH1 *TH1::DrawCopy(Option_t *option, const char * name_postfix) const
3048{
3049 TString opt = option;
3050 opt.ToLower();
3051 if (gPad && !opt.Contains("same")) gPad->Clear();
3052 TString newName = (name_postfix) ? TString::Format("%s%s",GetName(),name_postfix) : "";
3053 TH1 *newth1 = (TH1 *)Clone(newName);
3054 newth1->SetDirectory(0);
3055 newth1->SetBit(kCanDelete);
3056 if (gPad) gPad->IncrementPaletteColor(1, opt);
3057
3058 newth1->AppendPad(option);
3059 return newth1;
3060}
3061
3062////////////////////////////////////////////////////////////////////////////////
3063/// Draw a normalized copy of this histogram.
3064///
3065/// A clone of this histogram is normalized to norm and drawn with option.
3066/// A pointer to the normalized histogram is returned.
3067/// The contents of the histogram copy are scaled such that the new
3068/// sum of weights (excluding under and overflow) is equal to norm.
3069/// Note that the returned normalized histogram is not added to the list
3070/// of histograms in the current directory in memory.
3071/// It is the user's responsibility to delete this histogram.
3072/// The kCanDelete bit is set for the returned object. If a pad containing
3073/// this copy is cleared, the histogram will be automatically deleted.
3074///
3075/// See Draw for the list of options
3076
3077TH1 *TH1::DrawNormalized(Option_t *option, Double_t norm) const
3078{
3080 if (sum == 0) {
3081 Error("DrawNormalized","Sum of weights is null. Cannot normalize histogram: %s",GetName());
3082 return 0;
3083 }
3084 Bool_t addStatus = TH1::AddDirectoryStatus();
3086 TH1 *h = (TH1*)Clone();
3087 h->SetBit(kCanDelete);
3088 // in case of drawing with error options - scale correctly the error
3089 TString opt(option); opt.ToUpper();
3090 if (fSumw2.fN == 0) {
3091 h->Sumw2();
3092 // do not use in this case the "Error option " for drawing which is enabled by default since the normalized histogram has now errors
3093 if (opt.IsNull() || opt == "SAME") opt += "HIST";
3094 }
3095 h->Scale(norm/sum);
3096 if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
3097 if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
3098 h->Draw(opt);
3099 TH1::AddDirectory(addStatus);
3100 return h;
3101}
3102
3103////////////////////////////////////////////////////////////////////////////////
3104/// Display a panel with all histogram drawing options.
3105///
3106/// See class TDrawPanelHist for example
3107
3108void TH1::DrawPanel()
3109{
3110 if (!fPainter) {Draw(); if (gPad) gPad->Update();}
3111 if (fPainter) fPainter->DrawPanel();
3112}
3113
3114////////////////////////////////////////////////////////////////////////////////
3115/// Evaluate function f1 at the center of bins of this histogram.
3116///
3117/// - If option "R" is specified, the function is evaluated only
3118/// for the bins included in the function range.
3119/// - If option "A" is specified, the value of the function is added to the
3120/// existing bin contents
3121/// - If option "S" is specified, the value of the function is used to
3122/// generate a value, distributed according to the Poisson
3123/// distribution, with f1 as the mean.
3124
3125void TH1::Eval(TF1 *f1, Option_t *option)
3126{
3127 Double_t x[3];
3128 Int_t range, stat, add;
3129 if (!f1) return;
3130
3131 TString opt = option;
3132 opt.ToLower();
3133 if (opt.Contains("a")) add = 1;
3134 else add = 0;
3135 if (opt.Contains("s")) stat = 1;
3136 else stat = 0;
3137 if (opt.Contains("r")) range = 1;
3138 else range = 0;
3139
3140 // delete buffer if it is there since it will become invalid
3141 if (fBuffer) BufferEmpty(1);
3142
3143 Int_t nbinsx = fXaxis.GetNbins();
3144 Int_t nbinsy = fYaxis.GetNbins();
3145 Int_t nbinsz = fZaxis.GetNbins();
3146 if (!add) Reset();
3147
3148 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
3149 x[2] = fZaxis.GetBinCenter(binz);
3150 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
3151 x[1] = fYaxis.GetBinCenter(biny);
3152 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
3153 Int_t bin = GetBin(binx,biny,binz);
3154 x[0] = fXaxis.GetBinCenter(binx);
3155 if (range && !f1->IsInside(x)) continue;
3156 Double_t fu = f1->Eval(x[0], x[1], x[2]);
3157 if (stat) fu = gRandom->PoissonD(fu);
3158 AddBinContent(bin, fu);
3159 if (fSumw2.fN) fSumw2.fArray[bin] += TMath::Abs(fu);
3160 }
3161 }
3162 }
3163}
3164
3165////////////////////////////////////////////////////////////////////////////////
3166/// Execute action corresponding to one event.
3167///
3168/// This member function is called when a histogram is clicked with the locator
3169///
3170/// If Left button clicked on the bin top value, then the content of this bin
3171/// is modified according to the new position of the mouse when it is released.
3172
3173void TH1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3174{
3175 if (fPainter) fPainter->ExecuteEvent(event, px, py);
3176}
3177
3178////////////////////////////////////////////////////////////////////////////////
3179/// This function allows to do discrete Fourier transforms of TH1 and TH2.
3180/// Available transform types and flags are described below.
3181///
3182/// To extract more information about the transform, use the function
3183/// TVirtualFFT::GetCurrentTransform() to get a pointer to the current
3184/// transform object.
3185///
3186/// \param[out] h_output histogram for the output. If a null pointer is passed, a new histogram is created
3187/// and returned, otherwise, the provided histogram is used and should be big enough
3188/// \param[in] option option parameters consists of 3 parts:
3189/// - option on what to return
3190/// - "RE" - returns a histogram of the real part of the output
3191/// - "IM" - returns a histogram of the imaginary part of the output
3192/// - "MAG"- returns a histogram of the magnitude of the output
3193/// - "PH" - returns a histogram of the phase of the output
3194/// - option of transform type
3195/// - "R2C" - real to complex transforms - default
3196/// - "R2HC" - real to halfcomplex (special format of storing output data,
3197/// results the same as for R2C)
3198/// - "DHT" - discrete Hartley transform
3199/// real to real transforms (sine and cosine):
3200/// - "R2R_0", "R2R_1", "R2R_2", "R2R_3" - discrete cosine transforms of types I-IV
3201/// - "R2R_4", "R2R_5", "R2R_6", "R2R_7" - discrete sine transforms of types I-IV
3202/// To specify the type of each dimension of a 2-dimensional real to real
3203/// transform, use options of form "R2R_XX", for example, "R2R_02" for a transform,
3204/// which is of type "R2R_0" in 1st dimension and "R2R_2" in the 2nd.
3205/// - option of transform flag
3206/// - "ES" (from "estimate") - no time in preparing the transform, but probably sub-optimal
3207/// performance
3208/// - "M" (from "measure") - some time spend in finding the optimal way to do the transform
3209/// - "P" (from "patient") - more time spend in finding the optimal way to do the transform
3210/// - "EX" (from "exhaustive") - the most optimal way is found
3211/// This option should be chosen depending on how many transforms of the same size and
3212/// type are going to be done. Planning is only done once, for the first transform of this
3213/// size and type. Default is "ES".
3214///
3215/// Examples of valid options: "Mag R2C M" "Re R2R_11" "Im R2C ES" "PH R2HC EX"
3216
3217TH1* TH1::FFT(TH1* h_output, Option_t *option)
3218{
3219
3220 Int_t ndim[3];
3221 ndim[0] = this->GetNbinsX();
3222 ndim[1] = this->GetNbinsY();
3223 ndim[2] = this->GetNbinsZ();
3224
3225 TVirtualFFT *fft;
3226 TString opt = option;
3227 opt.ToUpper();
3228 if (!opt.Contains("2R")){
3229 if (!opt.Contains("2C") && !opt.Contains("2HC") && !opt.Contains("DHT")) {
3230 //no type specified, "R2C" by default
3231 opt.Append("R2C");
3232 }
3233 fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
3234 }
3235 else {
3236 //find the kind of transform
3237 Int_t ind = opt.Index("R2R", 3);
3238 Int_t *kind = new Int_t[2];
3239 char t;
3240 t = opt[ind+4];
3241 kind[0] = atoi(&t);
3242 if (h_output->GetDimension()>1) {
3243 t = opt[ind+5];
3244 kind[1] = atoi(&t);
3245 }
3246 fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
3247 delete [] kind;
3248 }
3249
3250 if (!fft) return 0;
3251 Int_t in=0;
3252 for (Int_t binx = 1; binx<=ndim[0]; binx++) {
3253 for (Int_t biny=1; biny<=ndim[1]; biny++) {
3254 for (Int_t binz=1; binz<=ndim[2]; binz++) {
3255 fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
3256 in++;
3257 }
3258 }
3259 }
3260 fft->Transform();
3261 h_output = TransformHisto(fft, h_output, option);
3262 return h_output;
3263}
3264
3265////////////////////////////////////////////////////////////////////////////////
3266/// Increment bin with abscissa X by 1.
3267///
3268/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3269/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3270///
3271/// If the storage of the sum of squares of weights has been triggered,
3272/// via the function Sumw2, then the sum of the squares of weights is incremented
3273/// by 1 in the bin corresponding to x.
3274///
3275/// The function returns the corresponding bin number which has its content incremented by 1
3276
3278{
3279 if (fBuffer) return BufferFill(x,1);
3280
3281 Int_t bin;
3282 fEntries++;
3283 bin =fXaxis.FindBin(x);
3284 if (bin <0) return -1;
3285 AddBinContent(bin);
3286 if (fSumw2.fN) ++fSumw2.fArray[bin];
3287 if (bin == 0 || bin > fXaxis.GetNbins()) {
3288 if (!GetStatOverflowsBehaviour()) return -1;
3289 }
3290 ++fTsumw;
3291 ++fTsumw2;
3292 fTsumwx += x;
3293 fTsumwx2 += x*x;
3294 return bin;
3295}
3296
3297////////////////////////////////////////////////////////////////////////////////
3298/// Increment bin with abscissa X with a weight w.
3299///
3300/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3301/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3302///
3303/// If the weight is not equal to 1, the storage of the sum of squares of
3304/// weights is automatically triggered and the sum of the squares of weights is incremented
3305/// by \f$ w^2 \f$ in the bin corresponding to x.
3306///
3307/// The function returns the corresponding bin number which has its content incremented by w
3308
3310{
3311
3312 if (fBuffer) return BufferFill(x,w);
3313
3314 Int_t bin;
3315 fEntries++;
3316 bin =fXaxis.FindBin(x);
3317 if (bin <0) return -1;
3318 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW) ) Sumw2(); // must be called before AddBinContent
3319 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3320 AddBinContent(bin, w);
3321 if (bin == 0 || bin > fXaxis.GetNbins()) {
3322 if (!GetStatOverflowsBehaviour()) return -1;
3323 }
3324 Double_t z= w;
3325 fTsumw += z;
3326 fTsumw2 += z*z;
3327 fTsumwx += z*x;
3328 fTsumwx2 += z*x*x;
3329 return bin;
3330}
3331
3332////////////////////////////////////////////////////////////////////////////////
3333/// Increment bin with namex with a weight w
3334///
3335/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3336/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3337///
3338/// If the weight is not equal to 1, the storage of the sum of squares of
3339/// weights is automatically triggered and the sum of the squares of weights is incremented
3340/// by \f$ w^2 \f$ in the bin corresponding to x.
3341///
3342/// The function returns the corresponding bin number which has its content
3343/// incremented by w.
3344
3345Int_t TH1::Fill(const char *namex, Double_t w)
3346{
3347 Int_t bin;
3348 fEntries++;
3349 bin =fXaxis.FindBin(namex);
3350 if (bin <0) return -1;
3351 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3352 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3353 AddBinContent(bin, w);
3354 if (bin == 0 || bin > fXaxis.GetNbins()) return -1;
3355 Double_t z= w;
3356 fTsumw += z;
3357 fTsumw2 += z*z;
3358 // this make sense if the histogram is not expanding (no axis can be extended)
3359 if (!CanExtendAllAxes()) {
3361 fTsumwx += z*x;
3362 fTsumwx2 += z*x*x;
3363 }
3364 return bin;
3365}
3366
3367////////////////////////////////////////////////////////////////////////////////
3368/// Fill this histogram with an array x and weights w.
3369///
3370/// \param[in] ntimes number of entries in arrays x and w (array size must be ntimes*stride)
3371/// \param[in] x array of values to be histogrammed
3372/// \param[in] w array of weighs
3373/// \param[in] stride step size through arrays x and w
3374///
3375/// If the weight is not equal to 1, the storage of the sum of squares of
3376/// weights is automatically triggered and the sum of the squares of weights is incremented
3377/// by \f$ w^2 \f$ in the bin corresponding to x.
3378/// if w is NULL each entry is assumed a weight=1
3379
3380void TH1::FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3381{
3382 //If a buffer is activated, fill buffer
3383 if (fBuffer) {
3384 ntimes *= stride;
3385 Int_t i = 0;
3386 for (i=0;i<ntimes;i+=stride) {
3387 if (!fBuffer) break; // buffer can be deleted in BufferFill when is empty
3388 if (w) BufferFill(x[i],w[i]);
3389 else BufferFill(x[i], 1.);
3390 }
3391 // fill the remaining entries if the buffer has been deleted
3392 if (i < ntimes && fBuffer==0) {
3393 auto weights = w ? &w[i] : nullptr;
3394 DoFillN((ntimes-i)/stride,&x[i],weights,stride);
3395 }
3396 return;
3397 }
3398 // call internal method
3399 DoFillN(ntimes, x, w, stride);
3400}
3401
3402////////////////////////////////////////////////////////////////////////////////
3403/// Internal method to fill histogram content from a vector
3404/// called directly by TH1::BufferEmpty
3405
3406void TH1::DoFillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3407{
3408 Int_t bin,i;
3409
3410 fEntries += ntimes;
3411 Double_t ww = 1;
3412 Int_t nbins = fXaxis.GetNbins();
3413 ntimes *= stride;
3414 for (i=0;i<ntimes;i+=stride) {
3415 bin =fXaxis.FindBin(x[i]);
3416 if (bin <0) continue;
3417 if (w) ww = w[i];
3418 if (!fSumw2.fN && ww != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3419 if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
3420 AddBinContent(bin, ww);
3421 if (bin == 0 || bin > nbins) {
3422 if (!GetStatOverflowsBehaviour()) continue;
3423 }
3424 Double_t z= ww;
3425 fTsumw += z;
3426 fTsumw2 += z*z;
3427 fTsumwx += z*x[i];
3428 fTsumwx2 += z*x[i]*x[i];
3429 }
3430}
3431
3432////////////////////////////////////////////////////////////////////////////////
3433/// Fill histogram following distribution in function fname.
3434///
3435/// The distribution contained in the function fname (TF1) is integrated
3436/// over the channel contents for the bin range of this histogram.
3437/// It is normalized to 1.
3438///
3439/// Getting one random number implies:
3440/// - Generating a random number between 0 and 1 (say r1)
3441/// - Look in which bin in the normalized integral r1 corresponds to
3442/// - Fill histogram channel
3443/// ntimes random numbers are generated
3444///
3445/// One can also call TF1::GetRandom to get a random variate from a function.
3446
3447void TH1::FillRandom(const char *fname, Int_t ntimes)
3448{
3449 Int_t bin, binx, ibin, loop;
3450 Double_t r1, x;
3451 // - Search for fname in the list of ROOT defined functions
3452 TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
3453 if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
3454
3455 // - Allocate temporary space to store the integral and compute integral
3456
3457 TAxis * xAxis = &fXaxis;
3458
3459 // in case axis of histogram is not defined use the function axis
3460 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
3462 f1->GetRange(xmin,xmax);
3463 Info("FillRandom","Using function axis and range [%g,%g]",xmin, xmax);
3464 xAxis = f1->GetHistogram()->GetXaxis();
3465 }
3466
3467 Int_t first = xAxis->GetFirst();
3468 Int_t last = xAxis->GetLast();
3469 Int_t nbinsx = last-first+1;
3470
3471 Double_t *integral = new Double_t[nbinsx+1];
3472 integral[0] = 0;
3473 for (binx=1;binx<=nbinsx;binx++) {
3474 Double_t fint = f1->Integral(xAxis->GetBinLowEdge(binx+first-1),xAxis->GetBinUpEdge(binx+first-1), 0.);
3475 integral[binx] = integral[binx-1] + fint;
3476 }
3477
3478 // - Normalize integral to 1
3479 if (integral[nbinsx] == 0 ) {
3480 delete [] integral;
3481 Error("FillRandom", "Integral = zero"); return;
3482 }
3483 for (bin=1;bin<=nbinsx;bin++) integral[bin] /= integral[nbinsx];
3484
3485 // --------------Start main loop ntimes
3486 for (loop=0;loop<ntimes;loop++) {
3487 r1 = gRandom->Rndm();
3488 ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
3489 //binx = 1 + ibin;
3490 //x = xAxis->GetBinCenter(binx); //this is not OK when SetBuffer is used
3491 x = xAxis->GetBinLowEdge(ibin+first)
3492 +xAxis->GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
3493 Fill(x);
3494 }
3495 delete [] integral;
3496}
3497
3498////////////////////////////////////////////////////////////////////////////////
3499/// Fill histogram following distribution in histogram h.
3500///
3501/// The distribution contained in the histogram h (TH1) is integrated
3502/// over the channel contents for the bin range of this histogram.
3503/// It is normalized to 1.
3504///
3505/// Getting one random number implies:
3506/// - Generating a random number between 0 and 1 (say r1)
3507/// - Look in which bin in the normalized integral r1 corresponds to
3508/// - Fill histogram channel ntimes random numbers are generated
3509///
3510/// SPECIAL CASE when the target histogram has the same binning as the source.
3511/// in this case we simply use a poisson distribution where
3512/// the mean value per bin = bincontent/integral.
3513
3514void TH1::FillRandom(TH1 *h, Int_t ntimes)
3515{
3516 if (!h) { Error("FillRandom", "Null histogram"); return; }
3517 if (fDimension != h->GetDimension()) {
3518 Error("FillRandom", "Histograms with different dimensions"); return;
3519 }
3520 if (std::isnan(h->ComputeIntegral(true))) {
3521 Error("FillRandom", "Histograms contains negative bins, does not represent probabilities");
3522 return;
3523 }
3524
3525 //in case the target histogram has the same binning and ntimes much greater
3526 //than the number of bins we can use a fast method
3528 Int_t last = fXaxis.GetLast();
3529 Int_t nbins = last-first+1;
3530 if (ntimes > 10*nbins) {
3531 try {
3532 CheckConsistency(this,h);
3533 Double_t sumw = h->Integral(first,last);
3534 if (sumw == 0) return;
3535 Double_t sumgen = 0;
3536 for (Int_t bin=first;bin<=last;bin++) {
3537 Double_t mean = h->RetrieveBinContent(bin)*ntimes/sumw;
3538 Double_t cont = (Double_t)gRandom->Poisson(mean);
3539 sumgen += cont;
3540 AddBinContent(bin,cont);
3541 if (fSumw2.fN) fSumw2.fArray[bin] += cont;
3542 }
3543
3544 // fix for the fluctuations in the total number n
3545 // since we use Poisson instead of multinomial
3546 // add a correction to have ntimes as generated entries
3547 Int_t i;
3548 if (sumgen < ntimes) {
3549 // add missing entries
3550 for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
3551 {
3552 Double_t x = h->GetRandom();
3553 Fill(x);
3554 }
3555 }
3556 else if (sumgen > ntimes) {
3557 // remove extra entries
3558 i = Int_t(sumgen+0.5);
3559 while( i > ntimes) {
3560 Double_t x = h->GetRandom();
3561 Int_t ibin = fXaxis.FindBin(x);
3563 // skip in case bin is empty
3564 if (y > 0) {
3565 SetBinContent(ibin, y-1.);
3566 i--;
3567 }
3568 }
3569 }
3570
3571 ResetStats();
3572 return;
3573 }
3574 catch(std::exception&) {} // do nothing
3575 }
3576 // case of different axis and not too large ntimes
3577
3578 if (h->ComputeIntegral() ==0) return;
3579 Int_t loop;
3580 Double_t x;
3581 for (loop=0;loop<ntimes;loop++) {
3582 x = h->GetRandom();
3583 Fill(x);
3584 }
3585}
3586
3587////////////////////////////////////////////////////////////////////////////////
3588/// Return Global bin number corresponding to x,y,z
3589///
3590/// 2-D and 3-D histograms are represented with a one dimensional
3591/// structure. This has the advantage that all existing functions, such as
3592/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3593/// This function tries to extend the axis if the given point belongs to an
3594/// under-/overflow bin AND if CanExtendAllAxes() is true.
3595///
3596/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3597
3599{
3600 if (GetDimension() < 2) {
3601 return fXaxis.FindBin(x);
3602 }
3603 if (GetDimension() < 3) {
3604 Int_t nx = fXaxis.GetNbins()+2;
3605 Int_t binx = fXaxis.FindBin(x);
3606 Int_t biny = fYaxis.FindBin(y);
3607 return binx + nx*biny;
3608 }
3609 if (GetDimension() < 4) {
3610 Int_t nx = fXaxis.GetNbins()+2;
3611 Int_t ny = fYaxis.GetNbins()+2;
3612 Int_t binx = fXaxis.FindBin(x);
3613 Int_t biny = fYaxis.FindBin(y);
3614 Int_t binz = fZaxis.FindBin(z);
3615 return binx + nx*(biny +ny*binz);
3616 }
3617 return -1;
3618}
3619
3620////////////////////////////////////////////////////////////////////////////////
3621/// Return Global bin number corresponding to x,y,z.
3622///
3623/// 2-D and 3-D histograms are represented with a one dimensional
3624/// structure. This has the advantage that all existing functions, such as
3625/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3626/// This function DOES NOT try to extend the axis if the given point belongs
3627/// to an under-/overflow bin.
3628///
3629/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3630
3632{
3633 if (GetDimension() < 2) {
3634 return fXaxis.FindFixBin(x);
3635 }
3636 if (GetDimension() < 3) {
3637 Int_t nx = fXaxis.GetNbins()+2;
3638 Int_t binx = fXaxis.FindFixBin(x);
3639 Int_t biny = fYaxis.FindFixBin(y);
3640 return binx + nx*biny;
3641 }
3642 if (GetDimension() < 4) {
3643 Int_t nx = fXaxis.GetNbins()+2;
3644 Int_t ny = fYaxis.GetNbins()+2;
3645 Int_t binx = fXaxis.FindFixBin(x);
3646 Int_t biny = fYaxis.FindFixBin(y);
3647 Int_t binz = fZaxis.FindFixBin(z);
3648 return binx + nx*(biny +ny*binz);
3649 }
3650 return -1;
3651}
3652
3653////////////////////////////////////////////////////////////////////////////////
3654/// Find first bin with content > threshold for axis (1=x, 2=y, 3=z)
3655/// if no bins with content > threshold is found the function returns -1.
3656/// The search will occur between the specified first and last bin. Specifying
3657/// the value of the last bin to search to less than zero will search until the
3658/// last defined bin.
3659
3660Int_t TH1::FindFirstBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3661{
3662 if (fBuffer) ((TH1*)this)->BufferEmpty();
3663
3664 if (axis < 1 || (axis > 1 && GetDimension() == 1 ) ||
3665 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3 ) ) {
3666 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3667 axis = 1;
3668 }
3669 if (firstBin < 1) {
3670 firstBin = 1;
3671 }
3672 Int_t nbinsx = fXaxis.GetNbins();
3673 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3674 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3675
3676 if (axis == 1) {
3677 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3678 lastBin = fXaxis.GetNbins();
3679 }
3680 for (Int_t binx = firstBin; binx <= lastBin; binx++) {
3681 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3682 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3683 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binx;
3684 }
3685 }
3686 }
3687 }
3688 else if (axis == 2) {
3689 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3690 lastBin = fYaxis.GetNbins();
3691 }
3692 for (Int_t biny = firstBin; biny <= lastBin; biny++) {
3693 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3694 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3695 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return biny;
3696 }
3697 }
3698 }
3699 }
3700 else if (axis == 3) {
3701 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3702 lastBin = fZaxis.GetNbins();
3703 }
3704 for (Int_t binz = firstBin; binz <= lastBin; binz++) {
3705 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3706 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3707 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binz;
3708 }
3709 }
3710 }
3711 }
3712
3713 return -1;
3714}
3715
3716////////////////////////////////////////////////////////////////////////////////
3717/// Find last bin with content > threshold for axis (1=x, 2=y, 3=z)
3718/// if no bins with content > threshold is found the function returns -1.
3719/// The search will occur between the specified first and last bin. Specifying
3720/// the value of the last bin to search to less than zero will search until the
3721/// last defined bin.
3722
3723Int_t TH1::FindLastBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3724{
3725 if (fBuffer) ((TH1*)this)->BufferEmpty();
3726
3727
3728 if (axis < 1 || ( axis > 1 && GetDimension() == 1 ) ||
3729 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3) ) {
3730 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3731 axis = 1;
3732 }
3733 if (firstBin < 1) {
3734 firstBin = 1;
3735 }
3736 Int_t nbinsx = fXaxis.GetNbins();
3737 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3738 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3739
3740 if (axis == 1) {
3741 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3742 lastBin = fXaxis.GetNbins();
3743 }
3744 for (Int_t binx = lastBin; binx >= firstBin; binx--) {
3745 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3746 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3747 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binx;
3748 }
3749 }
3750 }
3751 }
3752 else if (axis == 2) {
3753 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3754 lastBin = fYaxis.GetNbins();
3755 }
3756 for (Int_t biny = lastBin; biny >= firstBin; biny--) {
3757 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3758 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3759 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return biny;
3760 }
3761 }
3762 }
3763 }
3764 else if (axis == 3) {
3765 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3766 lastBin = fZaxis.GetNbins();
3767 }
3768 for (Int_t binz = lastBin; binz >= firstBin; binz--) {
3769 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3770 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3771 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binz;
3772 }
3773 }
3774 }
3775 }
3776
3777 return -1;
3778}
3779
3780////////////////////////////////////////////////////////////////////////////////
3781/// Search object named name in the list of functions.
3782
3783TObject *TH1::FindObject(const char *name) const
3784{
3785 if (fFunctions) return fFunctions->FindObject(name);
3786 return 0;
3787}
3788
3789////////////////////////////////////////////////////////////////////////////////
3790/// Search object obj in the list of functions.
3791
3792TObject *TH1::FindObject(const TObject *obj) const
3793{
3794 if (fFunctions) return fFunctions->FindObject(obj);
3795 return 0;
3796}
3797
3798////////////////////////////////////////////////////////////////////////////////
3799/// Fit histogram with function fname.
3800///
3801/// fname is the name of an already predefined function created by TF1 or TF2
3802/// Predefined functions such as gaus, expo and poln are automatically
3803/// created by ROOT.
3804/// fname can also be a formula, accepted by the linear fitter (linear parts divided
3805/// by "++" sign), for example "x++sin(x)" for fitting "[0]*x+[1]*sin(x)"
3806///
3807/// This function finds a pointer to the TF1 object with name fname
3808/// and calls TH1::Fit(TF1 *f1,...)
3809
3810TFitResultPtr TH1::Fit(const char *fname ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
3811{
3812 char *linear;
3813 linear= (char*)strstr(fname, "++");
3814 Int_t ndim=GetDimension();
3815 if (linear){
3816 if (ndim<2){
3817 TF1 f1(fname, fname, xxmin, xxmax);
3818 return Fit(&f1,option,goption,xxmin,xxmax);
3819 }
3820 else if (ndim<3){
3821 TF2 f2(fname, fname);
3822 return Fit(&f2,option,goption,xxmin,xxmax);
3823 }
3824 else{
3825 TF3 f3(fname, fname);
3826 return Fit(&f3,option,goption,xxmin,xxmax);
3827 }
3828 }
3829 else{
3830 TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
3831 if (!f1) { Printf("Unknown function: %s",fname); return -1; }
3832 return Fit(f1,option,goption,xxmin,xxmax);
3833 }
3834}
3835
3836////////////////////////////////////////////////////////////////////////////////
3837/// Fit histogram with function f1.
3838///
3839/// \param[in] option fit options is given in parameter option.
3840/// - "W" Set all weights to 1 for non empty bins; ignore error bars
3841/// - "WW" Set all weights to 1 including empty bins; ignore error bars
3842/// - "I" Use integral of function in bin, normalized by the bin volume,
3843/// instead of value at bin center
3844/// - "L" Use Loglikelihood method (default is chisquare method)
3845/// - "WL" Use Loglikelihood method and bin contents are not integer,
3846/// i.e. histogram is weighted (must have Sumw2() set)
3847/// - "P" Use Pearson chi2 (using expected errors instead of observed errors)
3848/// - "U" Use a User specified fitting algorithm (via SetFCN)
3849/// - "Q" Quiet mode (minimum printing)
3850/// - "V" Verbose mode (default is between Q and V)
3851/// - "E" Perform better Errors estimation using Minos technique
3852/// - "B" User defined parameter settings are used for predefined functions
3853/// like "gaus", "expo", "poln", "landau".
3854/// Use this option when you want to fix one or more parameters for these functions.
3855/// - "M" More. Improve fit results.
3856/// It uses the IMPROVE command of TMinuit (see TMinuit::mnimpr).
3857/// This algorithm attempts to improve the found local minimum by searching for a
3858/// better one.
3859/// - "R" Use the Range specified in the function range
3860/// - "N" Do not store the graphics function, do not draw
3861/// - "0" Do not plot the result of the fit. By default the fitted function
3862/// is drawn unless the option"N" above is specified.
3863/// - "+" Add this new fitted function to the list of fitted functions
3864/// (by default, any previous function is deleted)
3865/// - "C" In case of linear fitting, don't calculate the chisquare
3866/// (saves time)
3867/// - "F" If fitting a polN, switch to minuit fitter
3868/// - "S" The result of the fit is returned in the TFitResultPtr
3869/// (see below Access to the Fit Result)
3870/// \param[in] goption specify a list of graphics options. See TH1::Draw for a complete list of these options.
3871/// \param[in] xxmin range
3872/// \param[in] xxmax range
3873///
3874/// In order to use the Range option, one must first create a function
3875/// with the expression to be fitted. For example, if your histogram
3876/// has a defined range between -4 and 4 and you want to fit a gaussian
3877/// only in the interval 1 to 3, you can do:
3878///
3879/// ~~~ {.cpp}
3880/// TF1 *f1 = new TF1("f1", "gaus", 1, 3);
3881/// histo->Fit("f1", "R");
3882/// ~~~
3883///
3884/// ## Setting initial conditions
3885/// Parameters must be initialized before invoking the Fit function.
3886/// The setting of the parameter initial values is automatic for the
3887/// predefined functions : poln, expo, gaus, landau. One can however disable
3888/// this automatic computation by specifying the option "B".
3889/// Note that if a predefined function is defined with an argument,
3890/// eg, gaus(0), expo(1), you must specify the initial values for
3891/// the parameters.
3892/// You can specify boundary limits for some or all parameters via
3893///
3894/// ~~~ {.cpp}
3895/// f1->SetParLimits(p_number, parmin, parmax);
3896/// ~~~
3897///
3898/// if parmin>=parmax, the parameter is fixed
3899/// Note that you are not forced to fix the limits for all parameters.
3900/// For example, if you fit a function with 6 parameters, you can do:
3901///
3902/// ~~~ {.cpp}
3903/// func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
3904/// func->SetParLimits(3, -10, -4);
3905/// func->FixParameter(4, 0);
3906/// func->SetParLimits(5, 1, 1);
3907/// ~~~
3908///
3909/// With this setup, parameters 0->2 can vary freely
3910/// Parameter 3 has boundaries [-10,-4] with initial value -8
3911/// Parameter 4 is fixed to 0
3912/// Parameter 5 is fixed to 100.
3913/// When the lower limit and upper limit are equal, the parameter is fixed.
3914/// However to fix a parameter to 0, one must call the FixParameter function.
3915///
3916/// Note that option "I" gives better results but is slower.
3917///
3918/// #### Changing the fitting objective function
3919///
3920/// By default a chi square function is used for fitting. When option "L" (or "LL") is used
3921/// a Poisson likelihood function (see note below) is used.
3922/// The functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
3923/// are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
3924/// the file math/mathcore/src/FitUtil.cxx.
3925/// To specify a User defined fitting function, specify option "U" and
3926/// call the following functions:
3927///
3928/// ~~~ {.cpp}
3929/// TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction)
3930/// ~~~
3931///
3932/// where MyFittingFunction is of type:
3933///
3934/// ~~~ {.cpp}
3935/// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
3936/// ~~~
3937///
3938/// #### Chi2 Fits
3939///
3940/// By default a chi2 (least-square) fit is performed on the histogram. The so-called modified least-square method
3941/// is used where the residual for each bin is computed using as error the observed value (the bin error)
3942///
3943/// \f[
3944/// Chi2 = \sum{ \left(\frac{y(i) - f(x(i) | p )}{e(i)} \right)^2 }
3945/// \f]
3946///
3947/// 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
3948/// an un-weighted histogram. Bins with zero errors are excluded from the fit. See also later the note on the treatment of empty bins.
3949/// When using option "I" the residual is computed not using the function value at the bin center, f (x(i) | p), but the integral
3950/// of the function in the bin, Integral{ f(x|p)dx } divided by the bin volume
3951///
3952/// #### Likelihood Fits
3953///
3954/// When using option "L" a likelihood fit is used instead of the default chi2 square fit.
3955/// The likelihood is built assuming a Poisson probability density function for each bin.
3956/// The negative log-likelihood to be minimized is
3957///
3958/// \f[
3959/// NLL = \sum{ log Poisson ( y(i) | f(x(i) | p ) ) }
3960/// \f]
3961///
3962/// The exact likelihood used is the Poisson likelihood described in this paper:
3963/// S. Baker and R. D. Cousins, “Clarification of the use of chi-square and likelihood functions in fits to histograms,”
3964/// Nucl. Instrum. Meth. 221 (1984) 437.
3965///
3966/// This method can then be used only when the bin content represents counts (i.e. errors are sqrt(N) ).
3967/// The likelihood method has the advantage of treating correctly bins with low statistics. In case of high
3968/// statistics/bin the distribution of the bin content becomes a normal distribution and the likelihood and chi2 fit
3969/// give the same result.
3970///
3971/// The likelihood method, although a bit slower, it is therefore the recommended method in case of low
3972/// bin statistics, where the chi2 method may give incorrect results, in particular when there are
3973/// several empty bins (see also below).
3974/// In case of a weighted histogram, it is possible to perform a likelihood fit by using the
3975/// option "WL". Note a weighted histogram is an histogram which has been filled with weights and it
3976/// contains the sum of the weight square ( TH1::Sumw2() has been called). The bin error for a weighted
3977/// histogram is the square root of the sum of the weight square.
3978///
3979/// #### Treatment of Empty Bins
3980///
3981/// Empty bins, which have the content equal to zero AND error equal to zero,
3982/// are excluded by default from the chisquare fit, but they are considered in the likelihood fit.
3983/// since they affect the likelihood if the function value in these bins is not negligible.
3984/// When using option "WW" these bins will be considered in the chi2 fit with an error of 1.
3985/// Note that if the histogram is having bins with zero content and non zero-errors they are considered as
3986/// any other bins in the fit. Instead bins with zero error and non-zero content are excluded in the chi2 fit.
3987/// A likelihood fit should also not be performed on such an histogram, since we are assuming a wrong pdf for each bin.
3988/// In general, one should not fit an histogram with non-empty bins and zero errors, apart if all the bins have zero errors.
3989/// In this case one could use the option "w", which gives a weight=1 for each bin (unweighted least-square fit).
3990///
3991/// #### Fitting a histogram of dimension N with a function of dimension N-1
3992///
3993/// It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
3994/// In this case the option "Integral" is not allowed and each cell has
3995/// equal weight.
3996///
3997/// #### Associated functions
3998///
3999/// One or more object (typically a TF1*) can be added to the list
4000/// of functions (fFunctions) associated to each histogram.
4001/// When TH1::Fit is invoked, the fitted function is added to this list.
4002/// Given an histogram h, one can retrieve an associated function
4003/// with:
4004///
4005/// ~~~ {.cpp}
4006/// TF1 *myfunc = h->GetFunction("myfunc");
4007/// ~~~
4008///
4009/// #### Access to the fit result
4010///
4011/// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
4012/// By default the TFitResultPtr contains only the status of the fit which is return by an
4013/// automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
4014///
4015/// ~~~ {.cpp}
4016/// Int_t fitStatus = h->Fit(myFunc)
4017/// ~~~
4018///
4019/// If the option "S" is instead used, TFitResultPtr contains the TFitResult and behaves as a smart
4020/// pointer to it. For example one can do:
4021///
4022/// ~~~ {.cpp}
4023/// TFitResultPtr r = h->Fit(myFunc,"S");
4024/// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
4025/// Double_t chi2 = r->Chi2(); // to retrieve the fit chi2
4026/// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
4027/// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
4028/// r->Print("V"); // print full information of fit including covariance matrix
4029/// r->Write(); // store the result in a file
4030/// ~~~
4031///
4032/// The fit parameters, error and chi2 (but not covariance matrix) can be retrieved also
4033/// from the fitted function.
4034/// If the histogram is made persistent, the list of
4035/// associated functions is also persistent. Given a pointer (see above)
4036/// to an associated function myfunc, one can retrieve the function/fit
4037/// parameters with calls such as:
4038///
4039/// ~~~ {.cpp}
4040/// Double_t chi2 = myfunc->GetChisquare();
4041/// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
4042/// Double_t err0 = myfunc->GetParError(0); //error on first parameter
4043/// ~~~
4044///
4045/// #### Access to the fit status
4046///
4047/// The status of the fit can be obtained converting the TFitResultPtr to an integer
4048/// independently if the fit option "S" is used or not:
4049///
4050/// ~~~ {.cpp}
4051/// TFitResultPtr r = h->Fit(myFunc,opt);
4052/// Int_t fitStatus = r;
4053/// ~~~
4054///
4055/// The fitStatus is 0 if the fit is OK (i.e no error occurred).
4056/// The value of the fit status code is negative in case of an error not connected with the
4057/// minimization procedure, for example when a wrong function is used.
4058/// Otherwise the return value is the one returned from the minimization procedure.
4059/// When TMinuit (default case) or Minuit2 are used as minimizer the status returned is :
4060/// `fitStatus = migradResult + 10*minosResult + 100*hesseResult + 1000*improveResult`.
4061/// TMinuit will return 0 (for migrad, minos, hesse or improve) in case of success and 4 in
4062/// case of error (see the documentation of TMinuit::mnexcm). So for example, for an error
4063/// only in Minos but not in Migrad a fitStatus of 40 will be returned.
4064/// Minuit2 will return also 0 in case of success and different values in migrad minos or
4065/// hesse depending on the error. See in this case the documentation of
4066/// Minuit2Minimizer::Minimize for the migradResult, Minuit2Minimizer::GetMinosError for the
4067/// minosResult and Minuit2Minimizer::Hesse for the hesseResult.
4068/// If other minimizers are used see their specific documentation for the status code returned.
4069/// For example in the case of Fumili, for the status returned see TFumili::Minimize.
4070///
4071/// #### Excluding points
4072///
4073/// Use TF1::RejectPoint inside your fitting function to exclude points
4074/// within a certain range from the fit. Example:
4075///
4076/// ~~~ {.cpp}
4077/// Double_t fline(Double_t *x, Double_t *par)
4078/// {
4079/// if (x[0] > 2.5 && x[0] < 3.5) {
4080/// TF1::RejectPoint();
4081/// return 0;
4082/// }
4083/// return par[0] + par[1]*x[0];
4084/// }
4085///
4086/// void exclude() {
4087/// TF1 *f1 = new TF1("f1", "[0] +[1]*x +gaus(2)", 0, 5);
4088/// f1->SetParameters(6, -1,5, 3, 0.2);
4089/// TH1F *h = new TH1F("h", "background + signal", 100, 0, 5);
4090/// h->FillRandom("f1", 2000);
4091/// TF1 *fline = new TF1("fline", fline, 0, 5, 2);
4092/// fline->SetParameters(2, -1);
4093/// h->Fit("fline", "l");
4094/// }
4095/// ~~~
4096///
4097/// #### Warning when using the option "0"
4098///
4099/// When selecting the option "0", the fitted function is added to
4100/// the list of functions of the histogram, but it is not drawn.
4101/// You can undo what you disabled in the following way:
4102///
4103/// ~~~ {.cpp}
4104/// h.Fit("myFunction", "0"); // fit, store function but do not draw
4105/// h.Draw(); function is not drawn
4106/// const Int_t kNotDraw = 1<<9;
4107/// h.GetFunction("myFunction")->ResetBit(kNotDraw);
4108/// h.Draw(); // function is visible again
4109/// ~~~
4110///
4111/// #### Access to the Minimizer information during fitting
4112///
4113/// This function calls, the ROOT::Fit::FitObject function implemented in HFitImpl.cxx
4114/// which uses the ROOT::Fit::Fitter class. The Fitter class creates the objective function
4115/// (e.g. chi2 or likelihood) and uses an implementation of the Minimizer interface for minimizing
4116/// the function.
4117/// The default minimizer is Minuit (class TMinuitMinimizer which calls TMinuit).
4118/// The default can be set in the resource file in etc/system.rootrc. For example
4119///
4120/// ~~~ {.cpp}
4121/// Root.Fitter: Minuit2
4122/// ~~~
4123///
4124/// A different fitter can also be set via ROOT::Math::MinimizerOptions::SetDefaultMinimizer
4125/// (or TVirtualFitter::SetDefaultFitter).
4126/// For example ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");
4127/// will set the usage of the BFGS algorithm of the GSL multi-dimensional minimization
4128/// (implemented in libMathMore). ROOT::Math::MinimizerOptions can be used also to set other
4129/// default options, like maximum number of function calls, minimization tolerance or print
4130/// level. See the documentation of this class.
4131///
4132/// For fitting linear functions (containing the "++" sign" and polN functions,
4133/// the linear fitter is automatically initialized.
4134
4135TFitResultPtr TH1::Fit(TF1 *f1 ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
4136{
4137 // implementation of Fit method is in file hist/src/HFitImpl.cxx
4138 Foption_t fitOption;
4140
4141 // create range and minimizer options with default values
4142 ROOT::Fit::DataRange range(xxmin,xxmax);
4144
4145 // need to empty the buffer before
4146 // (t.b.d. do a ML unbinned fit with buffer data)
4147 if (fBuffer) BufferEmpty();
4148
4149 return ROOT::Fit::FitObject(this, f1 , fitOption , minOption, goption, range);
4150}
4151
4152////////////////////////////////////////////////////////////////////////////////
4153/// Display a panel with all histogram fit options.
4154///
4155/// See class TFitPanel for example
4156
4157void TH1::FitPanel()
4158{
4159 if (!gPad)
4160 gROOT->MakeDefCanvas();
4161
4162 if (!gPad) {
4163 Error("FitPanel", "Unable to create a default canvas");
4164 return;
4165 }
4166
4167
4168 // use plugin manager to create instance of TFitEditor
4169 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
4170 if (handler && handler->LoadPlugin() != -1) {
4171 if (handler->ExecPlugin(2, gPad, this) == 0)
4172 Error("FitPanel", "Unable to create the FitPanel");
4173 }
4174 else
4175 Error("FitPanel", "Unable to find the FitPanel plug-in");
4176}
4177
4178////////////////////////////////////////////////////////////////////////////////
4179/// Return an histogram containing the asymmetry of this histogram with h2,
4180/// where the asymmetry is defined as:
4181///
4182/// ~~~ {.cpp}
4183/// Asymmetry = (h1 - h2)/(h1 + h2) where h1 = this
4184/// ~~~
4185///
4186/// works for 1D, 2D, etc. histograms
4187/// c2 is an optional argument that gives a relative weight between the two
4188/// histograms, and dc2 is the error on this weight. This is useful, for example,
4189/// when forming an asymmetry between two histograms from 2 different data sets that
4190/// need to be normalized to each other in some way. The function calculates
4191/// the errors assuming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
4192///
4193/// example: assuming 'h1' and 'h2' are already filled
4194///
4195/// ~~~ {.cpp}
4196/// h3 = h1->GetAsymmetry(h2)
4197/// ~~~
4198///
4199/// then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
4200/// h1 and h2 are left intact.
4201///
4202/// Note that it is the user's responsibility to manage the created histogram.
4203/// The name of the returned histogram will be `Asymmetry_nameOfh1-nameOfh2`
4204///
4205/// code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
4206///
4207/// clone the histograms so top and bottom will have the
4208/// correct dimensions:
4209/// Sumw2 just makes sure the errors will be computed properly
4210/// when we form sums and ratios below.
4211
4213{
4214 TH1 *h1 = this;
4215 TString name = TString::Format("Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4216 TH1 *asym = (TH1*)Clone(name);
4217
4218 // set also the title
4219 TString title = TString::Format("(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4220 asym->SetTitle(title);
4221
4222 asym->Sumw2();
4223 Bool_t addStatus = TH1::AddDirectoryStatus();
4225 TH1 *top = (TH1*)asym->Clone();
4226 TH1 *bottom = (TH1*)asym->Clone();
4227 TH1::AddDirectory(addStatus);
4228
4229 // form the top and bottom of the asymmetry, and then divide:
4230 top->Add(h1,h2,1,-c2);
4231 bottom->Add(h1,h2,1,c2);
4232 asym->Divide(top,bottom);
4233
4234 Int_t xmax = asym->GetNbinsX();
4235 Int_t ymax = asym->GetNbinsY();
4236 Int_t zmax = asym->GetNbinsZ();
4237
4238 if (h1->fBuffer) h1->BufferEmpty(1);
4239 if (h2->fBuffer) h2->BufferEmpty(1);
4240 if (bottom->fBuffer) bottom->BufferEmpty(1);
4241
4242 // now loop over bins to calculate the correct errors
4243 // the reason this error calculation looks complex is because of c2
4244 for(Int_t i=1; i<= xmax; i++){
4245 for(Int_t j=1; j<= ymax; j++){
4246 for(Int_t k=1; k<= zmax; k++){
4247 Int_t bin = GetBin(i, j, k);
4248 // here some bin contents are written into variables to make the error
4249 // calculation a little more legible:
4251 Double_t b = h2->RetrieveBinContent(bin);
4252 Double_t bot = bottom->RetrieveBinContent(bin);
4253
4254 // make sure there are some events, if not, then the errors are set = 0
4255 // automatically.
4256 //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
4257 if(bot < 1e-6){}
4258 else{
4259 // computation of errors by Christos Leonidopoulos
4260 Double_t dasq = h1->GetBinErrorSqUnchecked(bin);
4261 Double_t dbsq = h2->GetBinErrorSqUnchecked(bin);
4262 Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4263 asym->SetBinError(i,j,k,error);
4264 }
4265 }
4266 }
4267 }
4268 delete top;
4269 delete bottom;
4270
4271 return asym;
4272}
4273
4274////////////////////////////////////////////////////////////////////////////////
4275/// Static function
4276/// return the default buffer size for automatic histograms
4277/// the parameter fgBufferSize may be changed via SetDefaultBufferSize
4278
4280{
4281 return fgBufferSize;
4282}
4283
4284////////////////////////////////////////////////////////////////////////////////
4285/// Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
4286/// see TH1::SetDefaultSumw2.
4287
4289{
4290 return fgDefaultSumw2;
4291}
4292
4293////////////////////////////////////////////////////////////////////////////////
4294/// Return the current number of entries.
4295
4297{
4298 if (fBuffer) {
4299 Int_t nentries = (Int_t) fBuffer[0];
4300 if (nentries > 0) return nentries;
4301 }
4302
4303 return fEntries;
4304}
4305
4306////////////////////////////////////////////////////////////////////////////////
4307/// Number of effective entries of the histogram.
4308///
4309/// \f[
4310/// neff = \frac{(\sum Weights )^2}{(\sum Weight^2 )}
4311/// \f]
4312///
4313/// In case of an unweighted histogram this number is equivalent to the
4314/// number of entries of the histogram.
4315/// For a weighted histogram, this number corresponds to the hypothetical number of unweighted entries
4316/// a histogram would need to have the same statistical power as this weighted histogram.
4317/// Note: The underflow/overflow are included if one has set the TH1::StatOverFlows flag
4318/// and if the statistics has been computed at filling time.
4319/// If a range is set in the histogram the number is computed from the given range.
4320
4322{
4323 Stat_t s[kNstat];
4324 this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
4325 return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4326}
4327
4328////////////////////////////////////////////////////////////////////////////////
4329/// Set highlight (enable/disable) mode for the histogram
4330/// by default highlight mode is disable
4331
4332void TH1::SetHighlight(Bool_t set)
4333{
4334 if (IsHighlight() == set) return;
4335 if (fDimension > 2) {
4336 Info("SetHighlight", "Supported only 1-D or 2-D histograms");
4337 return;
4338 }
4339
4340 if (!fPainter) {
4341 Info("SetHighlight", "Need to draw histogram first");
4342 return;
4343 }
4344 SetBit(kIsHighlight, set);
4346}
4347
4348////////////////////////////////////////////////////////////////////////////////
4349/// Redefines TObject::GetObjectInfo.
4350/// Displays the histogram info (bin number, contents, integral up to bin
4351/// corresponding to cursor position px,py
4352
4353char *TH1::GetObjectInfo(Int_t px, Int_t py) const
4354{
4355 return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
4356}
4357
4358////////////////////////////////////////////////////////////////////////////////
4359/// Return pointer to painter.
4360/// If painter does not exist, it is created
4361
4363{
4364 if (!fPainter) {
4365 TString opt = option;
4366 opt.ToLower();
4367 if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
4368 //try to create TGLHistPainter
4369 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
4370
4371 if (handler && handler->LoadPlugin() != -1)
4372 fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
4373 }
4374 }
4375
4377
4378 return fPainter;
4379}
4380
4381////////////////////////////////////////////////////////////////////////////////
4382/// Compute Quantiles for this histogram
4383/// Quantile x_q of a probability distribution Function F is defined as
4384///
4385/// ~~~ {.cpp}
4386/// F(x_q) = q with 0 <= q <= 1.
4387/// ~~~
4388///
4389/// For instance the median x_0.5 of a distribution is defined as that value
4390/// of the random variable for which the distribution function equals 0.5:
4391///
4392/// ~~~ {.cpp}
4393/// F(x_0.5) = Probability(x < x_0.5) = 0.5
4394/// ~~~
4395///
4396/// code from Eddy Offermann, Renaissance
4397///
4398/// \param[in] nprobSum maximum size of array q and size of array probSum (if given)
4399/// \param[in] probSum array of positions where quantiles will be computed.
4400/// - if probSum is null, probSum will be computed internally and will
4401/// have a size = number of bins + 1 in h. it will correspond to the
4402/// quantiles calculated at the lowest edge of the histogram (quantile=0) and
4403/// all the upper edges of the bins.
4404/// - if probSum is not null, it is assumed to contain at least nprobSum values.
4405/// \param[out] q array q filled with nq quantiles
4406/// \return value nq (<=nprobSum) with the number of quantiles computed
4407///
4408/// Note that the Integral of the histogram is automatically recomputed
4409/// if the number of entries is different of the number of entries when
4410/// the integral was computed last time. In case you do not use the Fill
4411/// functions to fill your histogram, but SetBinContent, you must call
4412/// TH1::ComputeIntegral before calling this function.
4413///
4414/// Getting quantiles q from two histograms and storing results in a TGraph,
4415/// a so-called QQ-plot
4416///
4417/// ~~~ {.cpp}
4418/// TGraph *gr = new TGraph(nprob);
4419/// h1->GetQuantiles(nprob,gr->GetX());
4420/// h2->GetQuantiles(nprob,gr->GetY());
4421/// gr->Draw("alp");
4422/// ~~~
4423///
4424/// Example:
4425///
4426/// ~~~ {.cpp}
4427/// void quantiles() {
4428/// // demo for quantiles
4429/// const Int_t nq = 20;
4430/// TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
4431/// h->FillRandom("gaus",5000);
4432///
4433/// Double_t xq[nq]; // position where to compute the quantiles in [0,1]
4434/// Double_t yq[nq]; // array to contain the quantiles
4435/// for (Int_t i=0;i<nq;i++) xq[i] = Float_t(i+1)/nq;
4436/// h->GetQuantiles(nq,yq,xq);
4437///
4438/// //show the original histogram in the top pad
4439/// TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
4440/// c1->Divide(1,2);
4441/// c1->cd(1);
4442/// h->Draw();
4443///
4444/// // show the quantiles in the bottom pad
4445/// c1->cd(2);
4446/// gPad->SetGrid();
4447/// TGraph *gr = new TGraph(nq,xq,yq);
4448/// gr->SetMarkerStyle(21);
4449/// gr->Draw("alp");
4450/// }
4451/// ~~~
4452
4453Int_t TH1::GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
4454{
4455 if (GetDimension() > 1) {
4456 Error("GetQuantiles","Only available for 1-d histograms");
4457 return 0;
4458 }
4459
4460 const Int_t nbins = GetXaxis()->GetNbins();
4461 if (!fIntegral) ComputeIntegral();
4462 if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4463
4464 Int_t i, ibin;
4465 Double_t *prob = (Double_t*)probSum;
4466 Int_t nq = nprobSum;
4467 if (probSum == 0) {
4468 nq = nbins+1;
4469 prob = new Double_t[nq];
4470 prob[0] = 0;
4471 for (i=1;i<nq;i++) {
4472 prob[i] = fIntegral[i]/fIntegral[nbins];
4473 }
4474 }
4475
4476 for (i = 0; i < nq; i++) {
4477 ibin = TMath::BinarySearch(nbins,fIntegral,prob[i]);
4478 while (ibin < nbins-1 && fIntegral[ibin+1] == prob[i]) {
4479 if (fIntegral[ibin+2] == prob[i]) ibin++;
4480 else break;
4481 }
4482 q[i] = GetBinLowEdge(ibin+1);
4483 const Double_t dint = fIntegral[ibin+1]-fIntegral[ibin];
4484 if (dint > 0) q[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4485 }
4486
4487 if (!probSum) delete [] prob;
4488 return nq;
4489}
4490
4491////////////////////////////////////////////////////////////////////////////////
4492/// Decode string choptin and fill fitOption structure.
4493
4494Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
4495{
4497 return 1;
4498}
4499
4500////////////////////////////////////////////////////////////////////////////////
4501/// Compute Initial values of parameters for a gaussian.
4502
4503void H1InitGaus()
4504{
4505 Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4506 Int_t bin;
4507 const Double_t sqrtpi = 2.506628;
4508
4509 // - Compute mean value and StdDev of the histogram in the given range
4511 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4512 Int_t hxfirst = hFitter->GetXfirst();
4513 Int_t hxlast = hFitter->GetXlast();
4514 Double_t valmax = curHist->GetBinContent(hxfirst);
4515 Double_t binwidx = curHist->GetBinWidth(hxfirst);
4516 allcha = sumx = sumx2 = 0;
4517 for (bin=hxfirst;bin<=hxlast;bin++) {
4518 x = curHist->GetBinCenter(bin);
4519 val = TMath::Abs(curHist->GetBinContent(bin));
4520 if (val > valmax) valmax = val;
4521 sumx += val*x;
4522 sumx2 += val*x*x;
4523 allcha += val;
4524 }
4525 if (allcha == 0) return;
4526 mean = sumx/allcha;
4527 stddev = sumx2/allcha - mean*mean;
4528 if (stddev > 0) stddev = TMath::Sqrt(stddev);
4529 else stddev = 0;
4530 if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4531 //if the distribution is really gaussian, the best approximation
4532 //is binwidx*allcha/(sqrtpi*stddev)
4533 //However, in case of non-gaussian tails, this underestimates
4534 //the normalisation constant. In this case the maximum value
4535 //is a better approximation.
4536 //We take the average of both quantities
4537 Double_t constant = 0.5*(valmax+binwidx*allcha/(sqrtpi*stddev));
4538
4539 //In case the mean value is outside the histo limits and
4540 //the StdDev is bigger than the range, we take
4541 // mean = center of bins
4542 // stddev = half range
4543 Double_t xmin = curHist->GetXaxis()->GetXmin();
4544 Double_t xmax = curHist->GetXaxis()->GetXmax();
4545 if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4546 mean = 0.5*(xmax+xmin);
4547 stddev = 0.5*(xmax-xmin);
4548 }
4549 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4550 f1->SetParameter(0,constant);
4551 f1->SetParameter(1,mean);
4552 f1->SetParameter(2,stddev);
4553 f1->SetParLimits(2,0,10*stddev);
4554}
4555
4556////////////////////////////////////////////////////////////////////////////////
4557/// Compute Initial values of parameters for an exponential.
4558
4559void H1InitExpo()
4560{
4561 Double_t constant, slope;
4562 Int_t ifail;
4564 Int_t hxfirst = hFitter->GetXfirst();
4565 Int_t hxlast = hFitter->GetXlast();
4566 Int_t nchanx = hxlast - hxfirst + 1;
4567
4568 H1LeastSquareLinearFit(-nchanx, constant, slope, ifail);
4569
4570 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4571 f1->SetParameter(0,constant);
4572 f1->SetParameter(1,slope);
4573
4574}
4575
4576////////////////////////////////////////////////////////////////////////////////
4577/// Compute Initial values of parameters for a polynom.
4578
4579void H1InitPolynom()
4580{
4581 Double_t fitpar[25];
4582
4584 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4585 Int_t hxfirst = hFitter->GetXfirst();
4586 Int_t hxlast = hFitter->GetXlast();
4587 Int_t nchanx = hxlast - hxfirst + 1;
4588 Int_t npar = f1->GetNpar();
4589
4590 if (nchanx <=1 || npar == 1) {
4591 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4592 fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4593 } else {
4594 H1LeastSquareFit( nchanx, npar, fitpar);
4595 }
4596 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4597}
4598
4599////////////////////////////////////////////////////////////////////////////////
4600/// Least squares lpolynomial fitting without weights.
4601///
4602/// \param[in] n number of points to fit
4603/// \param[in] m number of parameters
4604/// \param[in] a array of parameters
4605///
4606/// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
4607/// (E.Keil. revised by B.Schorr, 23.10.1981.)
4608
4610{
4611 const Double_t zero = 0.;
4612 const Double_t one = 1.;
4613 const Int_t idim = 20;
4614
4615 Double_t b[400] /* was [20][20] */;
4616 Int_t i, k, l, ifail;
4617 Double_t power;
4618 Double_t da[20], xk, yk;
4619
4620 if (m <= 2) {
4621 H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4622 return;
4623 }
4624 if (m > idim || m > n) return;
4625 b[0] = Double_t(n);
4626 da[0] = zero;
4627 for (l = 2; l <= m; ++l) {
4628 b[l-1] = zero;
4629 b[m + l*20 - 21] = zero;
4630 da[l-1] = zero;
4631 }
4633 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4634 Int_t hxfirst = hFitter->GetXfirst();
4635 Int_t hxlast = hFitter->GetXlast();
4636 for (k = hxfirst; k <= hxlast; ++k) {
4637 xk = curHist->GetBinCenter(k);
4638 yk = curHist->GetBinContent(k);
4639 power = one;
4640 da[0] += yk;
4641 for (l = 2; l <= m; ++l) {
4642 power *= xk;
4643 b[l-1] += power;
4644 da[l-1] += power*yk;
4645 }
4646 for (l = 2; l <= m; ++l) {
4647 power *= xk;
4648 b[m + l*20 - 21] += power;
4649 }
4650 }
4651 for (i = 3; i <= m; ++i) {
4652 for (k = i; k <= m; ++k) {
4653 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4654 }
4655 }
4656 H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
4657
4658 for (i=0; i<m; ++i) a[i] = da[i];
4659
4660}
4661
4662////////////////////////////////////////////////////////////////////////////////
4663/// Least square linear fit without weights.
4664///
4665/// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
4666/// (added to LSQ by B. Schorr, 15.02.1982.)
4667
4668void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
4669{
4670 Double_t xbar, ybar, x2bar;
4671 Int_t i, n;
4672 Double_t xybar;
4673 Double_t fn, xk, yk;
4674 Double_t det;
4675
4676 n = TMath::Abs(ndata);
4677 ifail = -2;
4678 xbar = ybar = x2bar = xybar = 0;
4680 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4681 Int_t hxfirst = hFitter->GetXfirst();
4682 Int_t hxlast = hFitter->GetXlast();
4683 for (i = hxfirst; i <= hxlast; ++i) {
4684 xk = curHist->GetBinCenter(i);
4685 yk = curHist->GetBinContent(i);
4686 if (ndata < 0) {
4687 if (yk <= 0) yk = 1e-9;
4688 yk = TMath::Log(yk);
4689 }
4690 xbar += xk;
4691 ybar += yk;
4692 x2bar += xk*xk;
4693 xybar += xk*yk;
4694 }
4695 fn = Double_t(n);
4696 det = fn*x2bar - xbar*xbar;
4697 ifail = -1;
4698 if (det <= 0) {
4699 a0 = ybar/fn;
4700 a1 = 0;
4701 return;
4702 }
4703 ifail = 0;
4704 a0 = (x2bar*ybar - xbar*xybar) / det;
4705 a1 = (fn*xybar - xbar*ybar) / det;
4706
4707}
4708
4709////////////////////////////////////////////////////////////////////////////////
4710/// Extracted from CERN Program library routine DSEQN.
4711///
4712/// Translated to C++ by Rene Brun
4713
4714void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b)
4715{
4716 Int_t a_dim1, a_offset, b_dim1, b_offset;
4717 Int_t nmjp1, i, j, l;
4718 Int_t im1, jp1, nm1, nmi;
4719 Double_t s1, s21, s22;
4720 const Double_t one = 1.;
4721
4722 /* Parameter adjustments */
4723 b_dim1 = idim;
4724 b_offset = b_dim1 + 1;
4725 b -= b_offset;
4726 a_dim1 = idim;
4727 a_offset = a_dim1 + 1;
4728 a -= a_offset;
4729
4730 if (idim < n) return;
4731
4732 ifail = 0;
4733 for (j = 1; j <= n; ++j) {
4734 if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
4735 a[j + j*a_dim1] = one / a[j + j*a_dim1];
4736 if (j == n) continue;
4737 jp1 = j + 1;
4738 for (l = jp1; l <= n; ++l) {
4739 a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4740 s1 = -a[l + (j+1)*a_dim1];
4741 for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4742 a[l + (j+1)*a_dim1] = -s1;
4743 }
4744 }
4745 if (k <= 0) return;
4746
4747 for (l = 1; l <= k; ++l) {
4748 b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
4749 }
4750 if (n == 1) return;
4751 for (l = 1; l <= k; ++l) {
4752 for (i = 2; i <= n; ++i) {
4753 im1 = i - 1;
4754 s21 = -b[i + l*b_dim1];
4755 for (j = 1; j <= im1; ++j) {
4756 s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
4757 }
4758 b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
4759 }
4760 nm1 = n - 1;
4761 for (i = 1; i <= nm1; ++i) {
4762 nmi = n - i;
4763 s22 = -b[nmi + l*b_dim1];
4764 for (j = 1; j <= i; ++j) {
4765 nmjp1 = n - j + 1;
4766 s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
4767 }
4768 b[nmi + l*b_dim1] = -s22;
4769 }
4770 }
4771}
4772
4773////////////////////////////////////////////////////////////////////////////////
4774/// Return Global bin number corresponding to binx,y,z.
4775///
4776/// 2-D and 3-D histograms are represented with a one dimensional
4777/// structure.
4778/// This has the advantage that all existing functions, such as
4779/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
4780///
4781/// In case of a TH1x, returns binx directly.
4782/// see TH1::GetBinXYZ for the inverse transformation.
4783///
4784/// Convention for numbering bins
4785///
4786/// For all histogram types: nbins, xlow, xup
4787///
4788/// - bin = 0; underflow bin
4789/// - bin = 1; first bin with low-edge xlow INCLUDED
4790/// - bin = nbins; last bin with upper-edge xup EXCLUDED
4791/// - bin = nbins+1; overflow bin
4792///
4793/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4794/// For example, assuming a 3-D histogram with binx,biny,binz, the function
4795///
4796/// ~~~ {.cpp}
4797/// Int_t bin = h->GetBin(binx,biny,binz);
4798/// ~~~
4799///
4800/// returns a global/linearized bin number. This global bin is useful
4801/// to access the bin information independently of the dimension.
4802
4803Int_t TH1::GetBin(Int_t binx, Int_t, Int_t) const
4804{
4805 Int_t ofx = fXaxis.GetNbins() + 1; // overflow bin
4806 if (binx < 0) binx = 0;
4807 if (binx > ofx) binx = ofx;
4808
4809 return binx;
4810}
4811
4812////////////////////////////////////////////////////////////////////////////////
4813/// Return binx, biny, binz corresponding to the global bin number globalbin
4814/// see TH1::GetBin function above
4815
4816void TH1::GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz) const
4817{
4818 Int_t nx = fXaxis.GetNbins()+2;
4819 Int_t ny = fYaxis.GetNbins()+2;
4820
4821 if (GetDimension() == 1) {
4822 binx = binglobal%nx;
4823 biny = 0;
4824 binz = 0;
4825 return;
4826 }
4827 if (GetDimension() == 2) {
4828 binx = binglobal%nx;
4829 biny = ((binglobal-binx)/nx)%ny;
4830 binz = 0;
4831 return;
4832 }
4833 if (GetDimension() == 3) {
4834 binx = binglobal%nx;
4835 biny = ((binglobal-binx)/nx)%ny;
4836 binz = ((binglobal-binx)/nx -biny)/ny;
4837 }
4838}
4839
4840////////////////////////////////////////////////////////////////////////////////
4841/// Return a random number distributed according the histogram bin contents.
4842/// This function checks if the bins integral exists. If not, the integral
4843/// is evaluated, normalized to one.
4844///
4845/// The integral is automatically recomputed if the number of entries
4846/// is not the same then when the integral was computed.
4847/// NB Only valid for 1-d histograms. Use GetRandom2 or 3 otherwise.
4848/// If the histogram has a bin with negative content a NaN is returned
4849
4851{
4852 if (fDimension > 1) {
4853 Error("GetRandom","Function only valid for 1-d histograms");
4854 return 0;
4855 }
4856 Int_t nbinsx = GetNbinsX();
4857 Double_t integral = 0;
4858 // compute integral checking that all bins have positive content (see ROOT-5894)
4859 if (fIntegral) {
4860 if (fIntegral[nbinsx+1] != fEntries) integral = ((TH1*)this)->ComputeIntegral(true);
4861 else integral = fIntegral[nbinsx];
4862 } else {
4863 integral = ((TH1*)this)->ComputeIntegral(true);
4864 }
4865 if (integral == 0) return 0;
4866 // return a NaN in case some bins have negative content
4867 if (integral == TMath::QuietNaN() ) return TMath::QuietNaN();
4868
4869 Double_t r1 = gRandom->Rndm();
4870 Int_t ibin = TMath::BinarySearch(nbinsx,fIntegral,r1);
4871 Double_t x = GetBinLowEdge(ibin+1);
4872 if (r1 > fIntegral[ibin]) x +=
4873 GetBinWidth(ibin+1)*(r1-fIntegral[ibin])/(fIntegral[ibin+1] - fIntegral[ibin]);
4874 return x;
4875}
4876
4877////////////////////////////////////////////////////////////////////////////////
4878/// Return content of bin number bin.
4879///
4880/// Implemented in TH1C,S,F,D
4881///
4882/// Convention for numbering bins
4883///
4884/// For all histogram types: nbins, xlow, xup
4885///
4886/// - bin = 0; underflow bin
4887/// - bin = 1; first bin with low-edge xlow INCLUDED
4888/// - bin = nbins; last bin with upper-edge xup EXCLUDED
4889/// - bin = nbins+1; overflow bin
4890///
4891/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4892/// For example, assuming a 3-D histogram with binx,biny,binz, the function
4893///
4894/// ~~~ {.cpp}
4895/// Int_t bin = h->GetBin(binx,biny,binz);
4896/// ~~~
4897///
4898/// returns a global/linearized bin number. This global bin is useful
4899/// to access the bin information independently of the dimension.
4900
4902{
4903 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
4904 if (bin < 0) bin = 0;
4905 if (bin >= fNcells) bin = fNcells-1;
4906
4907 return RetrieveBinContent(bin);
4908}
4909
4910////////////////////////////////////////////////////////////////////////////////
4911/// Compute first binx in the range [firstx,lastx] for which
4912/// diff = abs(bin_content-c) <= maxdiff
4913///
4914/// In case several bins in the specified range with diff=0 are found
4915/// the first bin found is returned in binx.
4916/// In case several bins in the specified range satisfy diff <=maxdiff
4917/// the bin with the smallest difference is returned in binx.
4918/// In all cases the function returns the smallest difference.
4919///
4920/// NOTE1: if firstx <= 0, firstx is set to bin 1
4921/// if (lastx < firstx then firstx is set to the number of bins
4922/// ie if firstx=0 and lastx=0 (default) the search is on all bins.
4923///
4924/// NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
4925
4926Double_t TH1::GetBinWithContent(Double_t c, Int_t &binx, Int_t firstx, Int_t lastx,Double_t maxdiff) const
4927{
4928 if (fDimension > 1) {
4929 binx = 0;
4930 Error("GetBinWithContent","function is only valid for 1-D histograms");
4931 return 0;
4932 }
4933
4934 if (fBuffer) ((TH1*)this)->BufferEmpty();
4935
4936 if (firstx <= 0) firstx = 1;
4937 if (lastx < firstx) lastx = fXaxis.GetNbins();
4938 Int_t binminx = 0;
4939 Double_t diff, curmax = 1.e240;
4940 for (Int_t i=firstx;i<=lastx;i++) {
4941 diff = TMath::Abs(RetrieveBinContent(i)-c);
4942 if (diff <= 0) {binx = i; return diff;}
4943 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
4944 }
4945 binx = binminx;
4946 return curmax;
4947}
4948
4949////////////////////////////////////////////////////////////////////////////////
4950/// Given a point x, approximates the value via linear interpolation
4951/// based on the two nearest bin centers
4952///
4953/// Andy Mastbaum 10/21/08
4954
4956{
4957 if (fBuffer) ((TH1*)this)->BufferEmpty();
4958
4959 Int_t xbin = fXaxis.FindFixBin(x);
4960 Double_t x0,x1,y0,y1;
4961
4962 if(x<=GetBinCenter(1)) {
4963 return RetrieveBinContent(1);
4964 } else if(x>=GetBinCenter(GetNbinsX())) {
4965 return RetrieveBinContent(GetNbinsX());
4966 } else {
4967 if(x<=GetBinCenter(xbin)) {
4968 y0 = RetrieveBinContent(xbin-1);
4969 x0 = GetBinCenter(xbin-1);
4970 y1 = RetrieveBinContent(xbin);
4971 x1 = GetBinCenter(xbin);
4972 } else {
4973 y0 = RetrieveBinContent(xbin);
4974 x0 = GetBinCenter(xbin);
4975 y1 = RetrieveBinContent(xbin+1);
4976 x1 = GetBinCenter(xbin+1);
4977 }
4978 return y0 + (x-x0)*((y1-y0)/(x1-x0));
4979 }
4980}
4981
4982////////////////////////////////////////////////////////////////////////////////
4983/// 2d Interpolation. Not yet implemented.
4984
4986{
4987 Error("Interpolate","This function must be called with 1 argument for a TH1");
4988 return 0;
4989}
4990
4991////////////////////////////////////////////////////////////////////////////////
4992/// 3d Interpolation. Not yet implemented.
4993
4995{
4996 Error("Interpolate","This function must be called with 1 argument for a TH1");
4997 return 0;
4998}
4999
5000///////////////////////////////////////////////////////////////////////////////
5001/// Check if an histogram is empty
5002/// (this a protected method used mainly by TH1Merger )
5003
5004Bool_t TH1::IsEmpty() const
5005{
5006 // if fTsumw or fentries are not zero histogram is not empty
5007 // need to use GetEntries() instead of fEntries in case of bugger histograms
5008 // so we will flash the buffer
5009 if (fTsumw != 0) return kFALSE;
5010 if (GetEntries() != 0) return kFALSE;
5011 // case fTSumw == 0 amd entries are also zero
5012 // this should not really happening, but if one sets content by hand
5013 // it can happen. a call to ResetStats() should be done in such cases
5014 double sumw = 0;
5015 for (int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
5016 return (sumw != 0) ? kFALSE : kTRUE;
5017}
5018
5019////////////////////////////////////////////////////////////////////////////////
5020/// Return true if the bin is overflow.
5021
5022Bool_t TH1::IsBinOverflow(Int_t bin, Int_t iaxis) const
5023{
5024 Int_t binx, biny, binz;
5025 GetBinXYZ(bin, binx, biny, binz);
5026
5027 if (iaxis == 0) {
5028 if ( fDimension == 1 )
5029 return binx >= GetNbinsX() + 1;
5030 if ( fDimension == 2 )
5031 return (binx >= GetNbinsX() + 1) ||
5032 (biny >= GetNbinsY() + 1);
5033 if ( fDimension == 3 )
5034 return (binx >= GetNbinsX() + 1) ||
5035 (biny >= GetNbinsY() + 1) ||
5036 (binz >= GetNbinsZ() + 1);
5037 return kFALSE;
5038 }
5039 if (iaxis == 1)
5040 return binx >= GetNbinsX() + 1;
5041 if (iaxis == 2)
5042 return biny >= GetNbinsY() + 1;
5043 if (iaxis == 3)
5044 return binz >= GetNbinsZ() + 1;
5045
5046 Error("IsBinOverflow","Invalid axis value");
5047 return kFALSE;
5048}
5049
5050////////////////////////////////////////////////////////////////////////////////
5051/// Return true if the bin is underflow.
5052/// If iaxis = 0 make OR with all axes otherwise check only for the given axis
5053
5054Bool_t TH1::IsBinUnderflow(Int_t bin, Int_t iaxis) const
5055{
5056 Int_t binx, biny, binz;
5057 GetBinXYZ(bin, binx, biny, binz);
5058
5059 if (iaxis == 0) {
5060 if ( fDimension == 1 )
5061 return (binx <= 0);
5062 else if ( fDimension == 2 )
5063 return (binx <= 0 || biny <= 0);
5064 else if ( fDimension == 3 )
5065 return (binx <= 0 || biny <= 0 || binz <= 0);
5066 else
5067 return kFALSE;
5068 }
5069 if (iaxis == 1)
5070 return (binx <= 0);
5071 if (iaxis == 2)
5072 return (biny <= 0);
5073 if (iaxis == 3)
5074 return (binz <= 0);
5075
5076 Error("IsBinUnderflow","Invalid axis value");
5077 return kFALSE;
5078}
5079
5080////////////////////////////////////////////////////////////////////////////////
5081/// Reduce the number of bins for the axis passed in the option to the number of bins having a label.
5082/// The method will remove only the extra bins existing after the last "labeled" bin.
5083/// Note that if there are "un-labeled" bins present between "labeled" bins they will not be removed
5084
5086{
5087 Int_t iaxis = AxisChoice(ax);
5088 TAxis *axis = 0;
5089 if (iaxis == 1) axis = GetXaxis();
5090 if (iaxis == 2) axis = GetYaxis();
5091 if (iaxis == 3) axis = GetZaxis();
5092 if (!axis) {
5093 Error("LabelsDeflate","Invalid axis option %s",ax);
5094 return;
5095 }
5096 if (!axis->GetLabels()) return;
5097
5098 // find bin with last labels
5099 // bin number is object ID in list of labels
5100 // therefore max bin number is number of bins of the deflated histograms
5101 TIter next(axis->GetLabels());
5102 TObject *obj;
5103 Int_t nbins = 0;
5104 while ((obj = next())) {
5105 Int_t ibin = obj->GetUniqueID();
5106 if (ibin > nbins) nbins = ibin;
5107 }
5108 if (nbins < 1) nbins = 1;
5109
5110 // Do nothing in case it was the last bin
5111 if (nbins==axis->GetNbins()) return;
5112
5113 TH1 *hold = (TH1*)IsA()->New();
5114 R__ASSERT(hold);
5115 hold->SetDirectory(0);
5116 Copy(*hold);
5117
5118 Bool_t timedisp = axis->GetTimeDisplay();
5119 Double_t xmin = axis->GetXmin();
5120 Double_t xmax = axis->GetBinUpEdge(nbins);
5121 if (xmax <= xmin) xmax = xmin +nbins;
5122 axis->SetRange(0,0);
5123 axis->Set(nbins,xmin,xmax);
5124 SetBinsLength(-1); // reset the number of cells
5125 Int_t errors = fSumw2.fN;
5126 if (errors) fSumw2.Set(fNcells);
5127 axis->SetTimeDisplay(timedisp);
5128 // reset histogram content
5129 Reset("ICE");
5130
5131 //now loop on all bins and refill
5132 // NOTE that if the bins without labels have content
5133 // it will be put in the underflow/overflow.
5134 // For this reason we use AddBinContent method
5135 Double_t oldEntries = fEntries;
5136 Int_t bin,binx,biny,binz;
5137 for (bin=0; bin < hold->fNcells; ++bin) {
5138 hold->GetBinXYZ(bin,binx,biny,binz);
5139 Int_t ibin = GetBin(binx,biny,binz);
5140 Double_t cu = hold->RetrieveBinContent(bin);
5141 AddBinContent(ibin,cu);
5142 if (errors) {
5143 fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5144 }
5145 }
5146 fEntries = oldEntries;
5147 delete hold;
5148}
5149
5150////////////////////////////////////////////////////////////////////////////////
5151/// Double the number of bins for axis.
5152/// Refill histogram
5153/// This function is called by TAxis::FindBin(const char *label)
5154
5156{
5157 Int_t iaxis = AxisChoice(ax);
5158 TAxis *axis = 0;
5159 if (iaxis == 1) axis = GetXaxis();
5160 if (iaxis == 2) axis = GetYaxis();
5161 if (iaxis == 3) axis = GetZaxis();
5162 if (!axis) return;
5163
5164 TH1 *hold = (TH1*)IsA()->New();;
5165 hold->SetDirectory(0);
5166 Copy(*hold);
5167
5168 Bool_t timedisp = axis->GetTimeDisplay();
5169 Int_t nbins = axis->GetNbins();
5170 Double_t xmin = axis->GetXmin();
5171 Double_t xmax = axis->GetXmax();
5172 xmax = xmin + 2*(xmax-xmin);
5173 axis->SetRange(0,0);
5174 // double the bins and recompute ncells
5175 axis->Set(2*nbins,xmin,xmax);
5176 SetBinsLength(-1);
5177 Int_t errors = fSumw2.fN;
5178 if (errors) fSumw2.Set(fNcells);
5179 axis->SetTimeDisplay(timedisp);
5180
5181 Reset("ICE"); // reset content and error
5182
5183 //now loop on all bins and refill
5184 Double_t oldEntries = fEntries;
5185 Int_t bin,ibin,binx,biny,binz;
5186 for (ibin =0; ibin < hold->fNcells; ibin++) {
5187 // get the binx,y,z values . The x-y-z (axis) bin values will stay the same between new-old after the expanding
5188 hold->GetBinXYZ(ibin,binx,biny,binz);
5189 bin = GetBin(binx,biny,binz);
5190
5191 // underflow and overflow will be cleaned up because their meaning has been altered
5192 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5193 continue;
5194 }
5195 else {
5196 AddBinContent(bin, hold->RetrieveBinContent(ibin));
5197 if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5198 }
5199 }
5200 fEntries = oldEntries;
5201 delete hold;
5202}
5203
5204////////////////////////////////////////////////////////////////////////////////
5205/// Set option(s) to draw axis with labels
5206/// \param[in] option
5207/// - "a" sort by alphabetic order
5208/// - ">" sort by decreasing values
5209/// - "<" sort by increasing values
5210/// - "h" draw labels horizontal
5211/// - "v" draw labels vertical
5212/// - "u" draw labels up (end of label right adjusted)
5213/// - "d" draw labels down (start of label left adjusted)
5214/// \param[in] ax axis
5215
5216void TH1::LabelsOption(Option_t *option, Option_t *ax)
5217{
5218 Int_t iaxis = AxisChoice(ax);
5219 TAxis *axis = 0;
5220 if (iaxis == 1) axis = GetXaxis();
5221 if (iaxis == 2) axis = GetYaxis();
5222 if (iaxis == 3) axis = GetZaxis();
5223 if (!axis) return;
5224 THashList *labels = axis->GetLabels();
5225 if (!labels) {
5226 Warning("LabelsOption","Cannot sort. No labels");
5227 return;
5228 }
5229 TString opt = option;
5230 opt.ToLower();
5231 if (opt.Contains("h")) {
5236 }
5237 if (opt.Contains("v")) {
5242 }
5243 if (opt.Contains("u")) {
5244 axis->SetBit(TAxis::kLabelsUp);
5248 }
5249 if (opt.Contains("d")) {
5254 }
5255 Int_t sort = -1;
5256 if (opt.Contains("a")) sort = 0;
5257 if (opt.Contains(">")) sort = 1;
5258 if (opt.Contains("<")) sort = 2;
5259 if (sort < 0) return;
5260 if (sort > 0 && GetDimension() > 2) {
5261 Error("LabelsOption","Sorting by value not implemented for 3-D histograms");
5262 return;
5263 }
5264
5265 Double_t entries = fEntries;
5266 Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5267 std::vector<Int_t> a(n+2);
5268
5269 Int_t i,j,k;
5270 std::vector<Double_t> cont;
5271 std::vector<Double_t> errors;
5272 THashList *labold = new THashList(labels->GetSize(),1);
5273 TIter nextold(labels);
5274 TObject *obj;
5275 while ((obj=nextold())) {
5276 labold->Add(obj);
5277 }
5278 labels->Clear();
5279 if (sort > 0) {
5280 //---sort by values of bins
5281 if (GetDimension() == 1) {
5282 cont.resize(n);
5283 if (fSumw2.fN) errors.resize(n);
5284 for (i=1;i<=n;i++) {
5285 cont[i-1] = GetBinContent(i);
5286 if (!errors.empty()) errors[i-1] = GetBinError(i);
5287 }
5288 if (sort ==1) TMath::Sort(n,cont.data(),a.data(),kTRUE); //sort by decreasing values
5289 else TMath::Sort(n,cont.data(),a.data(),kFALSE); //sort by increasing values
5290 for (i=1;i<=n;i++) {
5291 SetBinContent(i,cont[a[i-1]]);
5292 if (!errors.empty()) SetBinError(i,errors[a[i-1]]);
5293 }
5294 for (i=1;i<=n;i++) {
5295 obj = labold->At(a[i-1]);
5296 labels->Add(obj);
5297 obj->SetUniqueID(i);
5298 }
5299 } else if (GetDimension()== 2) {
5300 std::vector<Double_t> pcont(n+2);
5301 Int_t nx = fXaxis.GetNbins();
5302 Int_t ny = fYaxis.GetNbins();
5303 cont.resize( (nx+2)*(ny+2));
5304 if (fSumw2.fN) errors.resize( (nx+2)*(ny+2));
5305 for (i=1;i<=nx;i++) {
5306 for (j=1;j<=ny;j++) {
5307 cont[i+nx*j] = GetBinContent(i,j);
5308 if (!errors.empty()) errors[i+nx*j] = GetBinError(i,j);
5309 if (axis == GetXaxis()) k = i;
5310 else k = j;
5311 pcont[k-1] += cont[i+nx*j];
5312 }
5313 }
5314 if (sort ==1) TMath::Sort(n,pcont.data(),a.data(),kTRUE); //sort by decreasing values
5315 else TMath::Sort(n,pcont.data(),a.data(),kFALSE); //sort by increasing values
5316 for (i=0;i<n;i++) {
5317 obj = labold->At(a[i]);
5318 labels->Add(obj);
5319 obj->SetUniqueID(i+1);
5320 }
5321 if (axis == GetXaxis()) {
5322 for (i=1;i<=n;i++) {
5323 for (j=1;j<=ny;j++) {
5324 SetBinContent(i,j,cont[a[i-1]+1+nx*j]);
5325 if (!errors.empty()) SetBinError(i,j,errors[a[i-1]+1+nx*j]);
5326 }
5327 }
5328 }
5329 else {
5330 // using y axis
5331 for (i=1;i<=nx;i++) {
5332 for (j=1;j<=n;j++) {
5333 SetBinContent(i,j,cont[i+nx*(a[j-1]+1)]);
5334 if (!errors.empty()) SetBinError(i,j,errors[i+nx*(a[j-1]+1)]);
5335 }
5336 }
5337 }
5338 } else {
5339 //to be implemented for 3d
5340 }
5341 } else {
5342 //---alphabetic sort
5343 const UInt_t kUsed = 1<<18;
5344 TObject *objk=0;
5345 a[0] = 0;
5346 a[n+1] = n+1;
5347 for (i=1;i<=n;i++) {
5348 const char *label = "zzzzzzzzzzzz";
5349 for (j=1;j<=n;j++) {
5350 obj = labold->At(j-1);
5351 if (!obj) continue;
5352 if (obj->TestBit(kUsed)) continue;
5353 //use strcasecmp for case non-sensitive sort (may be an option)
5354 if (strcmp(label,obj->GetName()) < 0) continue;
5355 objk = obj;
5356 a[i] = j;
5357 label = obj->GetName();
5358 }
5359 if (objk) {
5360 objk->SetUniqueID(i);
5361 labels->Add(objk);
5362 objk->SetBit(kUsed);
5363 }
5364 }
5365 for (i=1;i<=n;i++) {
5366 obj = labels->At(i-1);
5367 if (!obj) continue;
5368 obj->ResetBit(kUsed);
5369 }
5370
5371 if (GetDimension() == 1) {
5372 cont.resize(n+2);
5373 if (fSumw2.fN) errors.resize(n+2);
5374 for (i=1;i<=n;i++) {
5375 cont[i] = GetBinContent(a[i]);
5376 if (!errors.empty()) errors[i] = GetBinError(a[i]);
5377 }
5378 for (i=1;i<=n;i++) {
5379 SetBinContent(i,cont[i]);
5380 if (!errors.empty()) SetBinError(i,errors[i]);
5381 }
5382 } else if (GetDimension()== 2) {
5383 Int_t nx = fXaxis.GetNbins()+2;
5384 Int_t ny = fYaxis.GetNbins()+2;
5385 cont.resize(nx*ny);
5386 if (fSumw2.fN) errors.resize(nx*ny);
5387 for (i=0;i<nx;i++) {
5388 for (j=0;j<ny;j++) {
5389 cont[i+nx*j] = GetBinContent(i,j);
5390 if (!errors.empty()) errors[i+nx*j] = GetBinError(i,j);
5391 }
5392 }
5393 if (axis == GetXaxis()) {
5394 for (i=1;i<=n;i++) {
5395 for (j=0;j<ny;j++) {
5396 SetBinContent(i,j,cont[a[i]+nx*j]);
5397 if (!errors.empty()) SetBinError(i,j,errors[a[i]+nx*j]);
5398 }
5399 }
5400 } else {
5401 for (i=0;i<nx;i++) {
5402 for (j=1;j<=n;j++) {
5403 SetBinContent(i,j,cont[i+nx*a[j]]);
5404 if (!errors.empty()) SetBinError(i,j,errors[i+nx*a[j]]);
5405 }
5406 }
5407 }
5408 } else {
5409 Int_t nx = fXaxis.GetNbins()+2;
5410 Int_t ny = fYaxis.GetNbins()+2;
5411 Int_t nz = fZaxis.GetNbins()+2;
5412 cont.resize(nx*ny*nz);
5413 if (fSumw2.fN) errors.resize(nx*ny*nz);
5414 for (i=0;i<nx;i++) {
5415 for (j=0;j<ny;j++) {
5416 for (k=0;k<nz;k++) {
5417 cont[i+nx*(j+ny*k)] = GetBinContent(i,j,k);
5418 if (!errors.empty()) errors[i+nx*(j+ny*k)] = GetBinError(i,j,k);
5419 }
5420 }
5421 }
5422 if (axis == GetXaxis()) {
5423 // labels on x axis
5424 for (i=1;i<=n;i++) {
5425 for (j=0;j<ny;j++) {
5426 for (k=0;k<nz;k++) {
5427 SetBinContent(i,j,k,cont[a[i]+nx*(j+ny*k)]);
5428 if (!errors.empty()) SetBinError(i,j,k,errors[a[i]+nx*(j+ny*k)]);
5429 }
5430 }
5431 }
5432 }
5433 else if (axis == GetYaxis()) {
5434 // labels on y axis
5435 for (i=0;i<nx;i++) {
5436 for (j=1;j<=n;j++) {
5437 for (k=0;k<nz;k++) {
5438 SetBinContent(i,j,k,cont[i+nx*(a[j]+ny*k)]);
5439 if (!errors.empty()) SetBinError(i,j,k,errors[i+nx*(a[j]+ny*k)]);
5440 }
5441 }
5442 }
5443 }
5444 else {
5445 // labels on z axis
5446 for (i=0;i<nx;i++) {
5447 for (j=0;j<ny;j++) {
5448 for (k=1;k<=n;k++) {
5449 SetBinContent(i,j,k,cont[i+nx*(j+ny*a[k])]);
5450 if (!errors.empty()) SetBinError(i,j,k,errors[i+nx*(j+ny*a[k])]);
5451 }
5452 }
5453 }
5454 }
5455 }
5456 }
5457 fEntries = entries;
5458 delete labold;
5459}
5460
5461////////////////////////////////////////////////////////////////////////////////
5462/// Test if two double are almost equal.
5463
5464static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5465{
5466 return TMath::Abs(a - b) < epsilon;
5467}
5468
5469////////////////////////////////////////////////////////////////////////////////
5470/// Test if a double is almost an integer.
5471
5472static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5473{
5474 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5476}
5477
5478////////////////////////////////////////////////////////////////////////////////
5479/// Test if the binning is equidistant.
5480
5481static inline bool IsEquidistantBinning(const TAxis& axis)
5482{
5483 // check if axis bin are equals
5484 if (!axis.GetXbins()->fN) return true; //
5485 // not able to check if there is only one axis entry
5486 bool isEquidistant = true;
5487 const Double_t firstBinWidth = axis.GetBinWidth(1);
5488 for (int i = 1; i < axis.GetNbins(); ++i) {
5489 const Double_t binWidth = axis.GetBinWidth(i);
5490 const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5491 isEquidistant &= match;
5492 if (!match)
5493 break;
5494 }
5495 return isEquidistant;
5496}
5497
5498////////////////////////////////////////////////////////////////////////////////
5499/// Same limits and bins.
5500
5501Bool_t TH1::SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2){
5502 return axis1.GetNbins() == axis2.GetNbins() &&
5503 TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
5504 TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
5505}
5506
5507////////////////////////////////////////////////////////////////////////////////
5508/// Finds new limits for the axis for the Merge function.
5509/// returns false if the limits are incompatible
5510
5511Bool_t TH1::RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
5512{
5513 if (SameLimitsAndNBins(destAxis, anAxis))
5514 return kTRUE;
5515
5516 if (!IsEquidistantBinning(destAxis) || !IsEquidistantBinning(anAxis))
5517 return kFALSE; // not equidistant user binning not supported
5518
5519 Double_t width1 = destAxis.GetBinWidth(0);
5520 Double_t width2 = anAxis.GetBinWidth(0);
5521 if (width1 == 0 || width2 == 0)
5522 return kFALSE; // no binning not supported
5523
5524 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
5525 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
5526 Double_t width = TMath::Max(width1, width2);
5527
5528 // check the bin size
5529 if (!AlmostInteger(width/width1) || !AlmostInteger(width/width2))
5530 return kFALSE;
5531
5532 // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
5533 // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
5534
5535
5536 // check the limits
5537 Double_t delta;
5538 delta = (destAxis.GetXmin() - xmin)/width1;
5539 if (!AlmostInteger(delta))
5540 xmin -= (TMath::Ceil(delta) - delta)*width1;
5541
5542 delta = (anAxis.GetXmin() - xmin)/width2;
5543 if (!AlmostInteger(delta))
5544 xmin -= (TMath::Ceil(delta) - delta)*width2;
5545
5546
5547 delta = (destAxis.GetXmin() - xmin)/width1;
5548 if (!AlmostInteger(delta))
5549 return kFALSE;
5550
5551
5552 delta = (xmax - destAxis.GetXmax())/width1;
5553 if (!AlmostInteger(delta))
5554 xmax += (TMath::Ceil(delta) - delta)*width1;
5555
5556
5557 delta = (xmax - anAxis.GetXmax())/width2;
5558 if (!AlmostInteger(delta))
5559 xmax += (TMath::Ceil(delta) - delta)*width2;
5560
5561
5562 delta = (xmax - destAxis.GetXmax())/width1;
5563 if (!AlmostInteger(delta))
5564 return kFALSE;
5565#ifdef DEBUG
5566 if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
5567 printf("TH1::RecomputeAxisLimits - Impossible\n");
5568 return kFALSE;
5569 }
5570#endif
5571
5572
5573 destAxis.Set(TMath::Nint((xmax - xmin)/width), xmin, xmax);
5574
5575 //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
5576
5577 return kTRUE;
5578}
5579
5580////////////////////////////////////////////////////////////////////////////////
5581/// Add all histograms in the collection to this histogram.
5582/// This function computes the min/max for the x axis,
5583/// compute a new number of bins, if necessary,
5584/// add bin contents, errors and statistics.
5585/// If all histograms have bin labels, bins with identical labels
5586/// will be merged, no matter what their order is.
5587/// If overflows are present and limits are different the function will fail.
5588/// The function returns the total number of entries in the result histogram
5589/// if the merge is successful, -1 otherwise.
5590///
5591/// Possible option:
5592/// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
5593/// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
5594/// (enabled by default) slows down the merging
5595///
5596/// IMPORTANT remark. The axis x may have different number
5597/// of bins and different limits, BUT the largest bin width must be
5598/// a multiple of the smallest bin width and the upper limit must also
5599/// be a multiple of the bin width.
5600/// Example:
5601///
5602/// ~~~ {.cpp}
5603/// void atest() {
5604/// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
5605/// TH1F *h2 = new TH1F("h2","h2",220,0,110);
5606/// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
5607/// TRandom r;
5608/// for (Int_t i=0;i<10000;i++) {
5609/// h1->Fill(r.Gaus(-55,10));
5610/// h2->Fill(r.Gaus(55,10));
5611/// h3->Fill(r.Gaus(0,10));
5612/// }
5613///
5614/// TList *list = new TList;
5615/// list->Add(h1);
5616/// list->Add(h2);
5617/// list->Add(h3);
5618/// TH1F *h = (TH1F*)h1->Clone("h");
5619/// h->Reset();
5620/// h->Merge(list);
5621/// h->Draw();
5622/// }
5623/// ~~~
5624
5626{
5627 if (!li) return 0;
5628 if (li->IsEmpty()) return (Long64_t) GetEntries();
5629
5630 // use TH1Merger class
5631 TH1Merger merger(*this,*li,opt);
5632 Bool_t ret = merger();
5633
5634 return (ret) ? GetEntries() : -1;
5635}
5636
5637
5638////////////////////////////////////////////////////////////////////////////////
5639/// Performs the operation:
5640///
5641/// `this = this*c1*f1`
5642///
5643/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
5644///
5645/// Only bins inside the function range are recomputed.
5646/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5647/// you should call Sumw2 before making this operation.
5648/// This is particularly important if you fit the histogram after TH1::Multiply
5649///
5650/// The function return kFALSE if the Multiply operation failed
5651
5653{
5654 if (!f1) {
5655 Error("Multiply","Attempt to multiply by a non-existing function");
5656 return kFALSE;
5657 }
5658
5659 // delete buffer if it is there since it will become invalid
5660 if (fBuffer) BufferEmpty(1);
5661
5662 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
5663 Int_t ny = GetNbinsY() + 2;
5664 Int_t nz = GetNbinsZ() + 2;
5665 if (fDimension < 2) ny = 1;
5666 if (fDimension < 3) nz = 1;
5667
5668 // reset min-maximum
5669 SetMinimum();
5670 SetMaximum();
5671
5672 // - Loop on bins (including underflows/overflows)
5673 Double_t xx[3];
5674 Double_t *params = 0;
5675 f1->InitArgs(xx,params);
5676
5677 for (Int_t binz = 0; binz < nz; ++binz) {
5678 xx[2] = fZaxis.GetBinCenter(binz);
5679 for (Int_t biny = 0; biny < ny; ++biny) {
5680 xx[1] = fYaxis.GetBinCenter(biny);
5681 for (Int_t binx = 0; binx < nx; ++binx) {
5682 xx[0] = fXaxis.GetBinCenter(binx);
5683 if (!f1->IsInside(xx)) continue;
5685 Int_t bin = binx + nx * (biny + ny *binz);
5686 Double_t cu = c1*f1->EvalPar(xx);
5687 if (TF1::RejectedPoint()) continue;
5688 UpdateBinContent(bin, RetrieveBinContent(bin) * cu);
5689 if (fSumw2.fN) {
5690 fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
5691 }
5692 }
5693 }
5694 }
5695 ResetStats();
5696 return kTRUE;
5697}
5698
5699////////////////////////////////////////////////////////////////////////////////
5700/// Multiply this histogram by h1.
5701///
5702/// `this = this*h1`
5703///
5704/// If errors of this are available (TH1::Sumw2), errors are recalculated.
5705/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
5706/// if not already set.
5707///
5708/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5709/// you should call Sumw2 before making this operation.
5710/// This is particularly important if you fit the histogram after TH1::Multiply
5711///
5712/// The function return kFALSE if the Multiply operation failed
5713
5714Bool_t TH1::Multiply(const TH1 *h1)
5715{
5716 if (!h1) {
5717 Error("Multiply","Attempt to multiply by a non-existing histogram");
5718 return kFALSE;
5719 }
5720
5721 // delete buffer if it is there since it will become invalid
5722 if (fBuffer) BufferEmpty(1);
5723
5724 try {
5725 CheckConsistency(this,h1);
5726 } catch(DifferentNumberOfBins&) {
5727 Error("Multiply","Attempt to multiply histograms with different number of bins");
5728 return kFALSE;
5729 } catch(DifferentAxisLimits&) {
5730 Warning("Multiply","Attempt to multiply histograms with different axis limits");
5731 } catch(DifferentBinLimits&) {
5732 Warning("Multiply","Attempt to multiply histograms with different bin limits");
5733 } catch(DifferentLabels&) {
5734 Warning("Multiply","Attempt to multiply histograms with different labels");
5735 }
5736
5737 // Create Sumw2 if h1 has Sumw2 set
5738 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
5739
5740 // - Reset min- maximum
5741 SetMinimum();
5742 SetMaximum();
5743
5744 // - Loop on bins (including underflows/overflows)
5745 for (Int_t i = 0; i < fNcells; ++i) {
5748 UpdateBinContent(i, c0 * c1);
5749 if (fSumw2.fN) {
5751 }
5752 }
5753 ResetStats();
5754 return kTRUE;
5755}
5756
5757////////////////////////////////////////////////////////////////////////////////
5758/// Replace contents of this histogram by multiplication of h1 by h2.
5759///
5760/// `this = (c1*h1)*(c2*h2)`
5761///
5762/// If errors of this are available (TH1::Sumw2), errors are recalculated.
5763/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
5764/// if not already set.
5765///
5766/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5767/// you should call Sumw2 before making this operation.
5768/// This is particularly important if you fit the histogram after TH1::Multiply
5769///
5770/// The function return kFALSE if the Multiply operation failed
5771
5772Bool_t TH1::Multiply(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
5773{
5774 TString opt = option;
5775 opt.ToLower();
5776 // Bool_t binomial = kFALSE;
5777 // if (opt.Contains("b")) binomial = kTRUE;
5778 if (!h1 || !h2) {
5779 Error("Multiply","Attempt to multiply by a non-existing histogram");
5780 return kFALSE;
5781 }
5782
5783 // delete buffer if it is there since it will become invalid
5784 if (fBuffer) BufferEmpty(1);
5785
5786 try {
5787 CheckConsistency(h1,h2);
5788 CheckConsistency(this,h1);
5789 } catch(DifferentNumberOfBins&) {
5790 Error("Multiply","Attempt to multiply histograms with different number of bins");
5791 return kFALSE;
5792 } catch(DifferentAxisLimits&) {
5793 Warning("Multiply","Attempt to multiply histograms with different axis limits");
5794 } catch(DifferentBinLimits&) {
5795 Warning("Multiply","Attempt to multiply histograms with different bin limits");
5796 } catch(DifferentLabels&) {
5797 Warning("Multiply","Attempt to multiply histograms with different labels");
5798 }
5799
5800 // Create Sumw2 if h1 or h2 have Sumw2 set
5801 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
5802
5803 // - Reset min - maximum
5804 SetMinimum();
5805 SetMaximum();
5806
5807 // - Loop on bins (including underflows/overflows)
5808 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
5809 for (Int_t i = 0; i < fNcells; ++i) {
5811 Double_t b2 = h2->RetrieveBinContent(i);
5812 UpdateBinContent(i, c1 * b1 * c2 * b2);
5813 if (fSumw2.fN) {
5814 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
5815 }
5816 }
5817 ResetStats();
5818 return kTRUE;
5819}
5820
5821////////////////////////////////////////////////////////////////////////////////
5822/// Control routine to paint any kind of histograms.
5823///
5824/// This function is automatically called by TCanvas::Update.
5825/// (see TH1::Draw for the list of options)
5826
5827void TH1::Paint(Option_t *option)
5828{
5829 GetPainter(option);
5830
5831 if (fPainter) {
5832 if (strlen(option) > 0) fPainter->Paint(option);
5833 else fPainter->Paint(fOption.Data());
5834 }
5835}
5836
5837////////////////////////////////////////////////////////////////////////////////
5838/// Rebin this histogram
5839///
5840/// #### case 1 xbins=0
5841///
5842/// If newname is blank (default), the current histogram is modified and
5843/// a pointer to it is returned.
5844///
5845/// If newname is not blank, the current histogram is not modified, and a
5846/// new histogram is returned which is a Clone of the current histogram
5847/// with its name set to newname.
5848///
5849/// The parameter ngroup indicates how many bins of this have to be merged
5850/// into one bin of the result.
5851///
5852/// If the original histogram has errors stored (via Sumw2), the resulting
5853/// histograms has new errors correctly calculated.
5854///
5855/// examples: if h1 is an existing TH1F histogram with 100 bins
5856///
5857/// ~~~ {.cpp}
5858/// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
5859/// h1->Rebin(5); //merges five bins in one in h1
5860/// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
5861/// // merging 5 bins of h1 in one bin
5862/// ~~~
5863///
5864/// NOTE: If ngroup is not an exact divider of the number of bins,
5865/// the top limit of the rebinned histogram is reduced
5866/// to the upper edge of the last bin that can make a complete
5867/// group. The remaining bins are added to the overflow bin.
5868/// Statistics will be recomputed from the new bin contents.
5869///
5870/// #### case 2 xbins!=0
5871///
5872/// A new histogram is created (you should specify newname).
5873/// The parameter ngroup is the number of variable size bins in the created histogram.
5874/// The array xbins must contain ngroup+1 elements that represent the low-edges
5875/// of the bins.
5876/// If the original histogram has errors stored (via Sumw2), the resulting
5877/// histograms has new errors correctly calculated.
5878///
5879/// NOTE: The bin edges specified in xbins should correspond to bin edges
5880/// in the original histogram. If a bin edge in the new histogram is
5881/// in the middle of a bin in the original histogram, all entries in
5882/// the split bin in the original histogram will be transfered to the
5883/// lower of the two possible bins in the new histogram. This is
5884/// probably not what you want. A warning message is emitted in this
5885/// case
5886///
5887/// examples: if h1 is an existing TH1F histogram with 100 bins
5888///
5889/// ~~~ {.cpp}
5890/// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
5891/// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
5892/// ~~~
5893
5894TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
5895{
5896 Int_t nbins = fXaxis.GetNbins();
5899 if ((ngroup <= 0) || (ngroup > nbins)) {
5900 Error("Rebin", "Illegal value of ngroup=%d",ngroup);
5901 return 0;
5902 }
5903
5904 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
5905 Error("Rebin", "Operation valid on 1-D histograms only");
5906 return 0;
5907 }
5908 if (!newname && xbins) {
5909 Error("Rebin","if xbins is specified, newname must be given");
5910 return 0;
5911 }
5912
5913 Int_t newbins = nbins/ngroup;
5914 if (!xbins) {
5915 Int_t nbg = nbins/ngroup;
5916 if (nbg*ngroup != nbins) {
5917 Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
5918 }
5919 }
5920 else {
5921 // in the case that xbins is given (rebinning in variable bins), ngroup is
5922 // the new number of bins and number of grouped bins is not constant.
5923 // when looping for setting the contents for the new histogram we
5924 // need to loop on all bins of original histogram. Then set ngroup=nbins
5925 newbins = ngroup;
5926 ngroup = nbins;
5927 }
5928
5929 // Save old bin contents into a new array
5930 Double_t entries = fEntries;
5931 Double_t *oldBins = new Double_t[nbins+2];
5932 Int_t bin, i;
5933 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
5934 Double_t *oldErrors = 0;
5935 if (fSumw2.fN != 0) {
5936 oldErrors = new Double_t[nbins+2];
5937 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
5938 }
5939 // rebin will not include underflow/overflow if new axis range is larger than old axis range
5940 if (xbins) {
5941 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
5942 Warning("Rebin","underflow entries will not be used when rebinning");
5943 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
5944 Warning("Rebin","overflow entries will not be used when rebinning");
5945 }
5946
5947
5948 // create a clone of the old histogram if newname is specified
5949 TH1 *hnew = this;
5950 if ((newname && strlen(newname) > 0) || xbins) {
5951 hnew = (TH1*)Clone(newname);
5952 }
5953
5954 //reset can extend bit to avoid an axis extension in SetBinContent
5955 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
5956
5957 // save original statistics
5958 Double_t stat[kNstat];
5959 GetStats(stat);
5960 bool resetStat = false;
5961 // change axis specs and rebuild bin contents array::RebinAx
5962 if(!xbins && (newbins*ngroup != nbins)) {
5963 xmax = fXaxis.GetBinUpEdge(newbins*ngroup);
5964 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
5965 }
5966 // save the TAttAxis members (reset by SetBins)
5967 Int_t nDivisions = fXaxis.GetNdivisions();
5968 Color_t axisColor = fXaxis.GetAxisColor();
5969 Color_t labelColor = fXaxis.GetLabelColor();
5970 Style_t labelFont = fXaxis.GetLabelFont();
5971 Float_t labelOffset = fXaxis.GetLabelOffset();
5972 Float_t labelSize = fXaxis.GetLabelSize();
5973 Float_t tickLength = fXaxis.GetTickLength();
5974 Float_t titleOffset = fXaxis.GetTitleOffset();
5975 Float_t titleSize = fXaxis.GetTitleSize();
5976 Color_t titleColor = fXaxis.GetTitleColor();
5977 Style_t titleFont = fXaxis.GetTitleFont();
5978
5979 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
5980 Double_t *bins = new Double_t[newbins+1];
5981 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
5982 hnew->SetBins(newbins,bins); //this also changes errors array (if any)
5983 delete [] bins;
5984 } else if (xbins) {
5985 hnew->SetBins(newbins,xbins);
5986 } else {
5987 hnew->SetBins(newbins,xmin,xmax);
5988 }
5989
5990 // Restore axis attributes
5991 fXaxis.SetNdivisions(nDivisions);
5992 fXaxis.SetAxisColor(axisColor);
5993 fXaxis.SetLabelColor(labelColor);
5994 fXaxis.SetLabelFont(labelFont);
5995 fXaxis.SetLabelOffset(labelOffset);
5996 fXaxis.SetLabelSize(labelSize);
5997 fXaxis.SetTickLength(tickLength);
5998 fXaxis.SetTitleOffset(titleOffset);
5999 fXaxis.SetTitleSize(titleSize);
6000 fXaxis.SetTitleColor(titleColor);
6001 fXaxis.SetTitleFont(titleFont);
6002
6003 // copy merged bin contents (ignore under/overflows)
6004 // Start merging only once the new lowest edge is reached
6005 Int_t startbin = 1;
6006 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
6007 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
6008 startbin++;
6009 }
6010 Int_t oldbin = startbin;
6011 Double_t binContent, binError;
6012 for (bin = 1;bin<=newbins;bin++) {
6013 binContent = 0;
6014 binError = 0;
6015 Int_t imax = ngroup;
6016 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6017 // check bin edges for the cases when we provide an array of bins
6018 // be careful in case bins can have zero width
6019 if (xbins && !TMath::AreEqualAbs(fXaxis.GetBinLowEdge(oldbin),
6020 hnew->GetXaxis()->GetBinLowEdge(bin),
6021 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6022 {
6023 Warning("Rebin","Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6024 }
6025 for (i=0;i<ngroup;i++) {
6026 if( (oldbin+i > nbins) ||
6027 ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6028 imax = i;
6029 break;
6030 }
6031 binContent += oldBins[oldbin+i];
6032 if (oldErrors) binError += oldErrors[oldbin+i]*oldErrors[oldbin+i];
6033 }
6034 hnew->SetBinContent(bin,binContent);
6035 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6036 oldbin += imax;
6037 }
6038
6039 // sum underflow and overflow contents until startbin
6040 binContent = 0;
6041 binError = 0;
6042 for (i = 0; i < startbin; ++i) {
6043 binContent += oldBins[i];
6044 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6045 }
6046 hnew->SetBinContent(0,binContent);
6047 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6048 // sum overflow
6049 binContent = 0;
6050 binError = 0;
6051 for (i = oldbin; i <= nbins+1; ++i) {
6052 binContent += oldBins[i];
6053 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6054 }
6055 hnew->SetBinContent(newbins+1,binContent);
6056 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6057
6058 hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6059
6060 // restore statistics and entries modified by SetBinContent
6061 hnew->SetEntries(entries);
6062 if (!resetStat) hnew->PutStats(stat);
6063 delete [] oldBins;
6064 if (oldErrors) delete [] oldErrors;
6065 return hnew;
6066}
6067
6068////////////////////////////////////////////////////////////////////////////////
6069/// finds new limits for the axis so that *point* is within the range and
6070/// the limits are compatible with the previous ones (see TH1::Merge).
6071/// new limits are put into *newMin* and *newMax* variables.
6072/// axis - axis whose limits are to be recomputed
6073/// point - point that should fit within the new axis limits
6074/// newMin - new minimum will be stored here
6075/// newMax - new maximum will be stored here.
6076/// false if failed (e.g. if the initial axis limits are wrong
6077/// or the new range is more than \f$ 2^{64} \f$ times the old one).
6078
6079Bool_t TH1::FindNewAxisLimits(const TAxis* axis, const Double_t point, Double_t& newMin, Double_t &newMax)
6080{
6081 Double_t xmin = axis->GetXmin();
6082 Double_t xmax = axis->GetXmax();
6083 if (xmin >= xmax) return kFALSE;
6084 Double_t range = xmax-xmin;
6085 Double_t binsize = range / axis->GetNbins();
6086
6087 //recompute new axis limits by doubling the current range
6088 Int_t ntimes = 0;
6089 while (point < xmin) {
6090 if (ntimes++ > 64)
6091 return kFALSE;
6092 xmin = xmin - range;
6093 range *= 2;
6094 binsize *= 2;
6095 // // make sure that the merging will be correct
6096 // if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
6097 // xmin += 0.5 * binsize;
6098 // xmax += 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
6099 // }
6100 }
6101 while (point >= xmax) {
6102 if (ntimes++ > 64)
6103 return kFALSE;
6104 xmax = xmax + range;
6105 range *= 2;
6106 binsize *= 2;
6107 // // make sure that the merging will be correct
6108 // if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
6109 // xmin -= 0.5 * binsize;
6110 // xmax -= 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
6111 // }
6112 }
6113 newMin = xmin;
6114 newMax = xmax;
6115 // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6116 // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6117
6118 return kTRUE;
6119}
6120
6121////////////////////////////////////////////////////////////////////////////////
6122/// Histogram is resized along axis such that x is in the axis range.
6123/// The new axis limits are recomputed by doubling iteratively
6124/// the current axis range until the specified value x is within the limits.
6125/// The algorithm makes a copy of the histogram, then loops on all bins
6126/// of the old histogram to fill the extended histogram.
6127/// Takes into account errors (Sumw2) if any.
6128/// The algorithm works for 1-d, 2-D and 3-D histograms.
6129/// The axis must be extendable before invoking this function.
6130/// Ex:
6131///
6132/// ~~~ {.cpp}
6133/// h->GetXaxis()->SetCanExtend(kTRUE);
6134/// ~~~
6135
6136void TH1::ExtendAxis(Double_t x, TAxis *axis)
6137{
6138 if (!axis->CanExtend()) return;
6139 if (TMath::IsNaN(x)) { // x may be a NaN
6141 return;
6142 }
6143
6144 if (axis->GetXmin() >= axis->GetXmax()) return;
6145 if (axis->GetNbins() <= 0) return;
6146
6148 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6149 return;
6150
6151 //save a copy of this histogram
6152 TH1 *hold = (TH1*)IsA()->New();
6153 hold->SetDirectory(0);
6154 Copy(*hold);
6155 //set new axis limits
6156 axis->SetLimits(xmin,xmax);
6157
6158
6159 //now loop on all bins and refill
6160 Int_t errors = GetSumw2N();
6161
6162 Reset("ICE"); //reset only Integral, contents and Errors
6163
6164 int iaxis = 0;
6165 if (axis == &fXaxis) iaxis = 1;
6166 if (axis == &fYaxis) iaxis = 2;
6167 if (axis == &fZaxis) iaxis = 3;
6168 bool firstw = kTRUE;
6169 Int_t binx,biny, binz = 0;
6170 Int_t ix = 0,iy = 0,iz = 0;
6171 Double_t bx,by,bz;
6172 Int_t ncells = hold->GetNcells();
6173 for (Int_t bin = 0; bin < ncells; ++bin) {
6174 hold->GetBinXYZ(bin,binx,biny,binz);
6175 bx = hold->GetXaxis()->GetBinCenter(binx);
6176 ix = fXaxis.FindFixBin(bx);
6177 if (fDimension > 1) {
6178 by = hold->GetYaxis()->GetBinCenter(biny);
6179 iy = fYaxis.FindFixBin(by);
6180 if (fDimension > 2) {
6181 bz = hold->GetZaxis()->GetBinCenter(binz);
6182 iz = fZaxis.FindFixBin(bz);
6183 }
6184 }
6185 // exclude underflow/overflow
6186 double content = hold->RetrieveBinContent(bin);
6187 if (content == 0) continue;
6188 if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6189 if (firstw) {
6190 Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6191 " their content will be lost",GetName() );
6192 firstw= kFALSE;
6193 }
6194 continue;
6195 }
6196 Int_t ibin= GetBin(ix,iy,iz);
6197 AddBinContent(ibin, content);
6198 if (errors) {
6199 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6200 }
6201 }
6202 delete hold;
6203}
6204
6205////////////////////////////////////////////////////////////////////////////////
6206/// Recursively remove object from the list of functions
6207
6209{
6210 // Rely on TROOT::RecursiveRemove to take the readlock.
6211
6212 if (fFunctions) {
6214 }
6215}
6216
6217////////////////////////////////////////////////////////////////////////////////
6218/// Multiply this histogram by a constant c1.
6219///
6220/// `this = c1*this`
6221///
6222/// Note that both contents and errors(if any) are scaled.
6223/// This function uses the services of TH1::Add
6224///
6225/// IMPORTANT NOTE: Sumw2() is called automatically when scaling
6226/// If you are not interested in the histogram statistics you can call
6227/// Sumw2(off) or use the option "nosw2"
6228///
6229/// One can scale an histogram such that the bins integral is equal to
6230/// the normalization parameter via TH1::Scale(Double_t norm), where norm
6231/// is the desired normalization divided by the integral of the histogram.
6232///
6233/// If option contains "width" the bin contents and errors are divided
6234/// by the bin width.
6235
6236void TH1::Scale(Double_t c1, Option_t *option)
6237{
6238
6239 TString opt = option; opt.ToLower();
6240 // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6241 if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6242 if (opt.Contains("width")) Add(this, this, c1, -1);
6243 else {
6244 if (fBuffer) BufferEmpty(1);
6245 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6246 if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6247 // update global histograms statistics
6248 Double_t s[kNstat] = {0};
6249 GetStats(s);
6250 for (Int_t i=0 ; i < kNstat; i++) {
6251 if (i == 1) s[i] = c1*c1*s[i];
6252 else s[i] = c1*s[i];
6253 }
6254 PutStats(s);
6255 SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6256 }
6257
6258 // if contours set, must also scale contours
6259 Int_t ncontours = GetContour();
6260 if (ncontours == 0) return;
6261 Double_t* levels = fContour.GetArray();
6262 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6263}
6264
6265////////////////////////////////////////////////////////////////////////////////
6266/// Returns true if all axes are extendable.
6267
6269{
6270 Bool_t canExtend = fXaxis.CanExtend();
6271 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6272 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6273
6274 return canExtend;
6275}
6276
6277////////////////////////////////////////////////////////////////////////////////
6278/// Make the histogram axes extendable / not extendable according to the bit mask
6279/// returns the previous bit mask specifying which axes are extendable
6280
6281UInt_t TH1::SetCanExtend(UInt_t extendBitMask)
6282{
6283 UInt_t oldExtendBitMask = kNoAxis;
6284
6285 if (fXaxis.CanExtend()) oldExtendBitMask |= kXaxis;
6286 if (extendBitMask & kXaxis) fXaxis.SetCanExtend(kTRUE);
6288
6289 if (GetDimension() > 1) {
6290 if (fYaxis.CanExtend()) oldExtendBitMask |= kYaxis;
6291 if (extendBitMask & kYaxis) fYaxis.SetCanExtend(kTRUE);
6293 }
6294
6295 if (GetDimension() > 2) {
6296 if (fZaxis.CanExtend()) oldExtendBitMask |= kZaxis;
6297 if (extendBitMask & kZaxis) fZaxis.SetCanExtend(kTRUE);
6299 }
6300
6301 return oldExtendBitMask;
6302}
6303
6304////////////////////////////////////////////////////////////////////////////////
6305/// Static function to set the default buffer size for automatic histograms.
6306/// When an histogram is created with one of its axis lower limit greater
6307/// or equal to its upper limit, the function SetBuffer is automatically
6308/// called with the default buffer size.
6309
6310void TH1::SetDefaultBufferSize(Int_t buffersize)
6311{
6312 fgBufferSize = buffersize > 0 ? buffersize : 0;
6313}
6314
6315////////////////////////////////////////////////////////////////////////////////
6316/// When this static function is called with `sumw2=kTRUE`, all new
6317/// histograms will automatically activate the storage
6318/// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6319
6320void TH1::SetDefaultSumw2(Bool_t sumw2)
6321{
6322 fgDefaultSumw2 = sumw2;
6323}
6324
6325////////////////////////////////////////////////////////////////////////////////
6326/// Change (i.e. set) the title
6327///
6328/// if title is in the form `stringt;stringx;stringy;stringz`
6329/// the histogram title is set to `stringt`, the x axis title to `stringx`,
6330/// the y axis title to `stringy`, and the z axis title to `stringz`.
6331///
6332/// To insert the character `;` in one of the titles, one should use `#;`
6333/// or `#semicolon`.
6334
6335void TH1::SetTitle(const char *title)
6336{
6337 fTitle = title;
6338 fTitle.ReplaceAll("#;",2,"#semicolon",10);
6339
6340 // Decode fTitle. It may contain X, Y and Z titles
6341 TString str1 = fTitle, str2;
6342 Int_t isc = str1.Index(";");
6343 Int_t lns = str1.Length();
6344
6345 if (isc >=0 ) {
6346 fTitle = str1(0,isc);
6347 str1 = str1(isc+1, lns);
6348 isc = str1.Index(";");
6349 if (isc >=0 ) {
6350 str2 = str1(0,isc);
6351 str2.ReplaceAll("#semicolon",10,";",1);
6352 fXaxis.SetTitle(str2.Data());
6353 lns = str1.Length();
6354 str1 = str1(isc+1, lns);
6355 isc = str1.Index(";");
6356 if (isc >=0 ) {
6357 str2 = str1(0,isc);
6358 str2.ReplaceAll("#semicolon",10,";",1);
6359 fYaxis.SetTitle(str2.Data());
6360 lns = str1.Length();
6361 str1 = str1(isc+1, lns);
6362 str1.ReplaceAll("#semicolon",10,";",1);
6363 fZaxis.SetTitle(str1.Data());
6364 } else {
6365 str1.ReplaceAll("#semicolon",10,";",1);
6366 fYaxis.SetTitle(str1.Data());
6367 }
6368 } else {
6369 str1.ReplaceAll("#semicolon",10,";",1);
6370 fXaxis.SetTitle(str1.Data());
6371 }
6372 }
6373
6374 fTitle.ReplaceAll("#semicolon",10,";",1);
6375
6376 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6377}
6378
6379////////////////////////////////////////////////////////////////////////////////
6380/// Smooth array xx, translation of Hbook routine hsmoof.F
6381/// based on algorithm 353QH twice presented by J. Friedman
6382/// in Proc.of the 1974 CERN School of Computing, Norway, 11-24 August, 1974.
6383
6384void TH1::SmoothArray(Int_t nn, Double_t *xx, Int_t ntimes)
6385{
6386 if (nn < 3 ) {
6387 ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6388 return;
6389 }
6390
6391 Int_t ii;
6392 Double_t hh[6] = {0,0,0,0,0,0};
6393
6394 std::vector<double> yy(nn);
6395 std::vector<double> zz(nn);
6396 std::vector<double> rr(nn);
6397
6398 for (Int_t pass=0;pass<ntimes;pass++) {
6399 // first copy original data into temp array
6400 std::copy(xx, xx+nn, zz.begin() );
6401
6402 for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6403
6404 // do 353 i.e. running median 3, 5, and 3 in a single loop
6405 for (int kk = 0; kk < 3; kk++) {
6406 std::copy(zz.begin(), zz.end(), yy.begin());
6407 int medianType = (kk != 1) ? 3 : 5;
6408 int ifirst = (kk != 1 ) ? 1 : 2;
6409 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6410 //nn2 = nn - ik - 1;
6411 // do all elements beside the first and last point for median 3
6412 // and first two and last 2 for median 5
6413 for ( ii = ifirst; ii < ilast; ii++) {
6414 assert(ii - ifirst >= 0);
6415 for (int jj = 0; jj < medianType; jj++) {
6416 hh[jj] = yy[ii - ifirst + jj ];
6417 }
6418 zz[ii] = TMath::Median(medianType, hh);
6419 }
6420
6421 if (kk == 0) { // first median 3
6422 // first point
6423 hh[0] = zz[1];
6424 hh[1] = zz[0];
6425 hh[2] = 3*zz[1] - 2*zz[2];
6426 zz[0] = TMath::Median(3, hh);
6427 // last point
6428 hh[0] = zz[nn - 2];
6429 hh[1] = zz[nn - 1];
6430 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6431 zz[nn - 1] = TMath::Median(3, hh);
6432 }
6433
6434 if (kk == 1) { // median 5
6435 for (ii = 0; ii < 3; ii++) {
6436 hh[ii] = yy[ii];
6437 }
6438 zz[1] = TMath::Median(3, hh);
6439 // last two points
6440 for (ii = 0; ii < 3; ii++) {
6441 hh[ii] = yy[nn - 3 + ii];
6442 }
6443 zz[nn - 2] = TMath::Median(3, hh);
6444 }
6445
6446 }
6447
6448 std::copy ( zz.begin(), zz.end(), yy.begin() );
6449
6450 // quadratic interpolation for flat segments
6451 for (ii = 2; ii < (nn - 2); ii++) {
6452 if (zz[ii - 1] != zz[ii]) continue;
6453 if (zz[ii] != zz[ii + 1]) continue;
6454 hh[0] = zz[ii - 2] - zz[ii];
6455 hh[1] = zz[ii + 2] - zz[ii];
6456 if (hh[0] * hh[1] <= 0) continue;
6457 int jk = 1;
6458 if ( TMath::Abs(hh[1]) > TMath::Abs(hh[0]) ) jk = -1;
6459 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6460 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6461 }
6462
6463 // running means
6464 //std::copy(zz.begin(), zz.end(), yy.begin());
6465 for (ii = 1; ii < nn - 1; ii++) {
6466 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6467 }
6468 zz[0] = yy[0];
6469 zz[nn - 1] = yy[nn - 1];
6470
6471 if (noent == 0) {
6472
6473 // save computed values
6474 std::copy(zz.begin(), zz.end(), rr.begin());
6475
6476 // COMPUTE residuals
6477 for (ii = 0; ii < nn; ii++) {
6478 zz[ii] = xx[ii] - zz[ii];
6479 }
6480 }
6481
6482 } // end loop on noent
6483
6484
6485 double xmin = TMath::MinElement(nn,xx);
6486 for (ii = 0; ii < nn; ii++) {
6487 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6488 // make smoothing defined positive - not better using 0 ?
6489 else xx[ii] = TMath::Max((rr[ii] + zz[ii]),0.0 );
6490 }
6491 }
6492}
6493
6494////////////////////////////////////////////////////////////////////////////////
6495/// Smooth bin contents of this histogram.
6496/// if option contains "R" smoothing is applied only to the bins
6497/// defined in the X axis range (default is to smooth all bins)
6498/// Bin contents are replaced by their smooth values.
6499/// Errors (if any) are not modified.
6500/// the smoothing procedure is repeated ntimes (default=1)
6501
6502void TH1::Smooth(Int_t ntimes, Option_t *option)
6503{
6504 if (fDimension != 1) {
6505 Error("Smooth","Smooth only supported for 1-d histograms");
6506 return;
6507 }
6508 Int_t nbins = fXaxis.GetNbins();
6509 if (nbins < 3) {
6510 Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
6511 return;
6512 }
6513
6514 // delete buffer if it is there since it will become invalid
6515 if (fBuffer) BufferEmpty(1);
6516
6517 Int_t firstbin = 1, lastbin = nbins;
6518 TString opt = option;
6519 opt.ToLower();
6520 if (opt.Contains("r")) {
6521 firstbin= fXaxis.GetFirst();
6522 lastbin = fXaxis.GetLast();
6523 }
6524 nbins = lastbin - firstbin + 1;
6525 Double_t *xx = new Double_t[nbins];
6526 Double_t nent = fEntries;
6527 Int_t i;
6528 for (i=0;i<nbins;i++) {
6529 xx[i] = RetrieveBinContent(i+firstbin);
6530 }
6531
6532 TH1::SmoothArray(nbins,xx,ntimes);
6533
6534 for (i=0;i<nbins;i++) {
6535 UpdateBinContent(i+firstbin,xx[i]);
6536 }
6537 fEntries = nent;
6538 delete [] xx;
6539
6540 if (gPad) gPad->Modified();
6541}
6542
6543////////////////////////////////////////////////////////////////////////////////
6544/// if flag=kTRUE, underflows and overflows are used by the Fill functions
6545/// in the computation of statistics (mean value, StdDev).
6546/// By default, underflows or overflows are not used.
6547
6548void TH1::StatOverflows(Bool_t flag)
6549{
6550 fgStatOverflows = flag;
6551}
6552
6553////////////////////////////////////////////////////////////////////////////////
6554/// Stream a class object.
6555
6556void TH1::Streamer(TBuffer &b)
6557{
6558 if (b.IsReading()) {
6559 UInt_t R__s, R__c;
6560 Version_t R__v = b.ReadVersion(&R__s, &R__c);
6561 if (fDirectory) fDirectory->Remove(this);
6562 fDirectory = 0;
6563 if (R__v > 2) {
6564 b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
6565
6567 fXaxis.SetParent(this);
6568 fYaxis.SetParent(this);
6569 fZaxis.SetParent(this);
6570 TIter next(fFunctions);
6571 TObject *obj;
6572 while ((obj=next())) {
6573 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
6574 }
6575 return;
6576 }
6577 //process old versions before automatic schema evolution
6578 TNamed::Streamer(b);
6579 TAttLine::Streamer(b);
6580 TAttFill::Streamer(b);
6581 TAttMarker::Streamer(b);
6582 b >> fNcells;
6583 fXaxis.Streamer(b);
6584 fYaxis.Streamer(b);
6585 fZaxis.Streamer(b);
6586 fXaxis.SetParent(this);
6587 fYaxis.SetParent(this);
6588 fZaxis.SetParent(this);
6589 b >> fBarOffset;
6590 b >> fBarWidth;
6591 b >> fEntries;
6592 b >> fTsumw;
6593 b >> fTsumw2;
6594 b >> fTsumwx;
6595 b >> fTsumwx2;
6596 if (R__v < 2) {
6597 Float_t maximum, minimum, norm;
6598 Float_t *contour=0;
6599 b >> maximum; fMaximum = maximum;
6600 b >> minimum; fMinimum = minimum;
6601 b >> norm; fNormFactor = norm;
6602 Int_t n = b.ReadArray(contour);
6603 fContour.Set(n);
6604 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
6605 delete [] contour;
6606 } else {
6607 b >> fMaximum;
6608 b >> fMinimum;
6609 b >> fNormFactor;
6610 fContour.Streamer(b);
6611 }
6612 fSumw2.Streamer(b);
6613 fOption.Streamer(b);
6614 fFunctions->Delete();
6615 fFunctions->Streamer(b);
6616 b.CheckByteCount(R__s, R__c, TH1::IsA());
6617
6618 } else {
6619 b.WriteClassBuffer(TH1::Class(),this);
6620 }
6621}
6622
6623////////////////////////////////////////////////////////////////////////////////
6624/// Print some global quantities for this histogram.
6625/// \param[in] option
6626/// - "base" is given, number of bins and ranges are also printed
6627/// - "range" is given, bin contents and errors are also printed
6628/// for all bins in the current range (default 1-->nbins)
6629/// - "all" is given, bin contents and errors are also printed
6630/// for all bins including under and overflows.
6631
6632void TH1::Print(Option_t *option) const
6633{
6634 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
6635 printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
6636 TString opt = option;
6637 opt.ToLower();
6638 Int_t all;
6639 if (opt.Contains("all")) all = 0;
6640 else if (opt.Contains("range")) all = 1;
6641 else if (opt.Contains("base")) all = 2;
6642 else return;
6643
6644 Int_t bin, binx, biny, binz;
6645 Int_t firstx=0,lastx=0,firsty=0,lasty=0,firstz=0,lastz=0;
6646 if (all == 0) {
6647 lastx = fXaxis.GetNbins()+1;
6648 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
6649 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
6650 } else {
6651 firstx = fXaxis.GetFirst(); lastx = fXaxis.GetLast();
6652 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
6653 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
6654 }
6655
6656 if (all== 2) {
6657 printf(" Title = %s\n", GetTitle());
6658 printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
6659 if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
6660 if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
6661 printf("\n");
6662 return;
6663 }
6664
6665 Double_t w,e;
6666 Double_t x,y,z;
6667 if (fDimension == 1) {
6668 for (binx=firstx;binx<=lastx;binx++) {
6669 x = fXaxis.GetBinCenter(binx);
6670 w = RetrieveBinContent(binx);
6671 e = GetBinError(binx);
6672 if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
6673 else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
6674 }
6675 }
6676 if (fDimension == 2) {
6677 for (biny=firsty;biny<=lasty;biny++) {
6678 y = fYaxis.GetBinCenter(biny);
6679 for (binx=firstx;binx<=lastx;binx++) {
6680 bin = GetBin(binx,biny);
6681 x = fXaxis.GetBinCenter(binx);
6682 w = RetrieveBinContent(bin);
6683 e = GetBinError(bin);
6684 if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
6685 else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
6686 }
6687 }
6688 }
6689 if (fDimension == 3) {
6690 for (binz=firstz;binz<=lastz;binz++) {
6691 z = fZaxis.GetBinCenter(binz);
6692 for (biny=firsty;biny<=lasty;biny++) {
6693 y = fYaxis.GetBinCenter(biny);
6694 for (binx=firstx;binx<=lastx;binx++) {
6695 bin = GetBin(binx,biny,binz);
6696 x = fXaxis.GetBinCenter(binx);
6697 w = RetrieveBinContent(bin);
6698 e = GetBinError(bin);
6699 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);
6700 else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
6701 }
6702 }
6703 }
6704 }
6705}
6706
6707////////////////////////////////////////////////////////////////////////////////
6708/// Using the current bin info, recompute the arrays for contents and errors
6709
6710void TH1::Rebuild(Option_t *)
6711{
6712 SetBinsLength();
6713 if (fSumw2.fN) {
6715 }
6716}
6717
6718////////////////////////////////////////////////////////////////////////////////
6719/// Reset this histogram: contents, errors, etc.
6720/// \param[in] option
6721/// - if "ICE" is specified, resets only Integral, Contents and Errors.
6722/// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
6723/// This option is used
6724/// - if "M" is specified, resets also Minimum and Maximum
6725
6726void TH1::Reset(Option_t *option)
6727{
6728 // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
6729 // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
6730
6731 TString opt = option;
6732 opt.ToUpper();
6733 fSumw2.Reset();
6734 if (fIntegral) {delete [] fIntegral; fIntegral = 0;}
6735
6736 if (opt.Contains("M")) {
6737 SetMinimum();
6738 SetMaximum();
6739 }
6740
6741 if (opt.Contains("ICE") && !opt.Contains("S")) return;
6742
6743 // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
6744 // But what is the sense of calling BufferEmpty() ? For making the axes ?
6745 // BufferEmpty will update contents that later will be
6746 // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
6747 // It may be needed for computing the axis limits....
6748 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
6749
6750 // need to reset also the statistics
6751 // (needs to be done after calling BufferEmpty() )
6752 fTsumw = 0;
6753 fTsumw2 = 0;
6754 fTsumwx = 0;
6755 fTsumwx2 = 0;
6756 fEntries = 0;
6757
6758 if (opt == "ICES") return;
6759
6760
6761 TObject *stats = fFunctions->FindObject("stats");
6762 fFunctions->Remove(stats);
6763 //special logic to support the case where the same object is
6764 //added multiple times in fFunctions.
6765 //This case happens when the same object is added with different
6766 //drawing modes
6767 TObject *obj;
6768 while ((obj = fFunctions->First())) {
6769 while(fFunctions->Remove(obj)) { }
6770 delete obj;
6771 }
6772 if(stats) fFunctions->Add(stats);
6773 fContour.Set(0);
6774}
6775
6776////////////////////////////////////////////////////////////////////////////////
6777/// Save primitive as a C++ statement(s) on output stream out
6778
6779void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
6780{
6781 // empty the buffer before if it exists
6782 if (fBuffer) BufferEmpty();
6783
6784 Bool_t nonEqiX = kFALSE;
6785 Bool_t nonEqiY = kFALSE;
6786 Bool_t nonEqiZ = kFALSE;
6787 Int_t i;
6788 static Int_t nxaxis = 0;
6789 static Int_t nyaxis = 0;
6790 static Int_t nzaxis = 0;
6791 TString sxaxis="xAxis",syaxis="yAxis",szaxis="zAxis";
6792
6793 // Check if the histogram has equidistant X bins or not. If not, we
6794 // create an array holding the bins.
6795 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
6796 nonEqiX = kTRUE;
6797 nxaxis++;
6798 sxaxis += nxaxis;
6799 out << " Double_t "<<sxaxis<<"[" << GetXaxis()->GetXbins()->fN
6800 << "] = {";
6801 for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
6802 if (i != 0) out << ", ";
6803 out << GetXaxis()->GetXbins()->fArray[i];
6804 }
6805 out << "}; " << std::endl;
6806 }
6807 // If the histogram is 2 or 3 dimensional, check if the histogram
6808 // has equidistant Y bins or not. If not, we create an array
6809 // holding the bins.
6810 if (fDimension > 1 && GetYaxis()->GetXbins()->fN &&
6811 GetYaxis()->GetXbins()->fArray) {
6812 nonEqiY = kTRUE;
6813 nyaxis++;
6814 syaxis += nyaxis;
6815 out << " Double_t "<<syaxis<<"[" << GetYaxis()->GetXbins()->fN
6816 << "] = {";
6817 for (i = 0; i < GetYaxis()->GetXbins()->fN; i++) {
6818 if (i != 0) out << ", ";
6819 out << GetYaxis()->GetXbins()->fArray[i];
6820 }
6821 out << "}; " << std::endl;
6822 }
6823 // IF the histogram is 3 dimensional, check if the histogram
6824 // has equidistant Z bins or not. If not, we create an array
6825 // holding the bins.
6826 if (fDimension > 2 && GetZaxis()->GetXbins()->fN &&
6827 GetZaxis()->GetXbins()->fArray) {
6828 nonEqiZ = kTRUE;
6829 nzaxis++;
6830 szaxis += nzaxis;
6831 out << " Double_t "<<szaxis<<"[" << GetZaxis()->GetXbins()->fN
6832 << "] = {";
6833 for (i = 0; i < GetZaxis()->GetXbins()->fN; i++) {
6834 if (i != 0) out << ", ";
6835 out << GetZaxis()->GetXbins()->fArray[i];
6836 }
6837 out << "}; " << std::endl;
6838 }
6839
6840 char quote = '"';
6841 out <<" "<<std::endl;
6842 out <<" "<< ClassName() <<" *";
6843
6844 // Histogram pointer has by default the histogram name with an incremental suffix.
6845 // If the histogram belongs to a graph or a stack the suffix is not added because
6846 // the graph and stack objects are not aware of this new name. Same thing if
6847 // the histogram is drawn with the option COLZ because the TPaletteAxis drawn
6848 // when this option is selected, does not know this new name either.
6849 TString opt = option;
6850 opt.ToLower();
6851 static Int_t hcounter = 0;
6852 TString histName = GetName();
6853 if ( !histName.Contains("Graph")
6854 && !histName.Contains("_stack_")
6855 && !opt.Contains("colz")) {
6856 hcounter++;
6857 histName += "__";
6858 histName += hcounter;
6859 }
6860 histName = gInterpreter-> MapCppName(histName);
6861 const char *hname = histName.Data();
6862 if (!strlen(hname)) hname = "unnamed";
6863 TString savedName = GetName();
6864 this->SetName(hname);
6865 TString t(GetTitle());
6866 t.ReplaceAll("\\","\\\\");
6867 t.ReplaceAll("\"","\\\"");
6868 out << hname << " = new " << ClassName() << "(" << quote
6869 << hname << quote << "," << quote<< t.Data() << quote
6870 << "," << GetXaxis()->GetNbins();
6871 if (nonEqiX)
6872 out << ", "<<sxaxis;
6873 else
6874 out << "," << GetXaxis()->GetXmin()
6875 << "," << GetXaxis()->GetXmax();
6876 if (fDimension > 1) {
6877 out << "," << GetYaxis()->GetNbins();
6878 if (nonEqiY)
6879 out << ", "<<syaxis;
6880 else
6881 out << "," << GetYaxis()->GetXmin()
6882 << "," << GetYaxis()->GetXmax();
6883 }
6884 if (fDimension > 2) {
6885 out << "," << GetZaxis()->GetNbins();
6886 if (nonEqiZ)
6887 out << ", "<<szaxis;
6888 else
6889 out << "," << GetZaxis()->GetXmin()
6890 << "," << GetZaxis()->GetXmax();
6891 }
6892 out << ");" << std::endl;
6893
6894 // save bin contents
6895 Int_t bin;
6896 for (bin=0;bin<fNcells;bin++) {
6897 Double_t bc = RetrieveBinContent(bin);
6898 if (bc) {
6899 out<<" "<<hname<<"->SetBinContent("<<bin<<","<<bc<<");"<<std::endl;
6900 }
6901 }
6902
6903 // save bin errors
6904 if (fSumw2.fN) {
6905 for (bin=0;bin<fNcells;bin++) {
6906 Double_t be = GetBinError(bin);
6907 if (be) {
6908 out<<" "<<hname<<"->SetBinError("<<bin<<","<<be<<");"<<std::endl;
6909 }
6910 }
6911 }
6912
6913 TH1::SavePrimitiveHelp(out, hname, option);
6914 this->SetName(savedName.Data());
6915}
6916
6917////////////////////////////////////////////////////////////////////////////////
6918/// Helper function for the SavePrimitive functions from TH1
6919/// or classes derived from TH1, eg TProfile, TProfile2D.
6920
6921void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
6922{
6923 char quote = '"';
6924 if (TMath::Abs(GetBarOffset()) > 1e-5) {
6925 out<<" "<<hname<<"->SetBarOffset("<<GetBarOffset()<<");"<<std::endl;
6926 }
6927 if (TMath::Abs(GetBarWidth()-1) > 1e-5) {
6928 out<<" "<<hname<<"->SetBarWidth("<<GetBarWidth()<<");"<<std::endl;
6929 }
6930 if (fMinimum != -1111) {
6931 out<<" "<<hname<<"->SetMinimum("<<fMinimum<<");"<<std::endl;
6932 }
6933 if (fMaximum != -1111) {
6934 out<<" "<<hname<<"->SetMaximum("<<fMaximum<<");"<<std::endl;
6935 }
6936 if (fNormFactor != 0) {
6937 out<<" "<<hname<<"->SetNormFactor("<<fNormFactor<<");"<<std::endl;
6938 }
6939 if (fEntries != 0) {
6940 out<<" "<<hname<<"->SetEntries("<<fEntries<<");"<<std::endl;
6941 }
6942 if (fDirectory == 0) {
6943 out<<" "<<hname<<"->SetDirectory(0);"<<std::endl;
6944 }
6945 if (TestBit(kNoStats)) {
6946 out<<" "<<hname<<"->SetStats(0);"<<std::endl;
6947 }
6948 if (fOption.Length() != 0) {
6949 out<<" "<<hname<<"->SetOption("<<quote<<fOption.Data()<<quote<<");"<<std::endl;
6950 }
6951
6952 // save contour levels
6953 Int_t ncontours = GetContour();
6954 if (ncontours > 0) {
6955 out<<" "<<hname<<"->SetContour("<<ncontours<<");"<<std::endl;
6956 Double_t zlevel;
6957 for (Int_t bin=0;bin<ncontours;bin++) {
6958 if (gPad->GetLogz()) {
6959 zlevel = TMath::Power(10,GetContourLevel(bin));
6960 } else {
6961 zlevel = GetContourLevel(bin);
6962 }
6963 out<<" "<<hname<<"->SetContourLevel("<<bin<<","<<zlevel<<");"<<std::endl;
6964 }
6965 }
6966
6967 // save list of functions
6969 TObject *obj;
6970 static Int_t funcNumber = 0;
6971 while (lnk) {
6972 obj = lnk->GetObject();
6973 obj->SavePrimitive(out,Form("nodraw #%d\n",++funcNumber));
6974 if (obj->InheritsFrom(TF1::Class())) {
6975 TString fname;
6976 fname.Form("%s%d",obj->GetName(),funcNumber);
6977 out << " " << fname << "->SetParent(" << hname << ");\n";
6978 out<<" "<<hname<<"->GetListOfFunctions()->Add("
6979 << fname <<");"<<std::endl;
6980 } else if (obj->InheritsFrom("TPaveStats")) {
6981 out<<" "<<hname<<"->GetListOfFunctions()->Add(ptstats);"<<std::endl;
6982 out<<" ptstats->SetParent("<<hname<<");"<<std::endl;
6983 } else if (obj->InheritsFrom("TPolyMarker")) {
6984 out<<" "<<hname<<"->GetListOfFunctions()->Add("
6985 <<"pmarker ,"<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
6986 } else {
6987 out<<" "<<hname<<"->GetListOfFunctions()->Add("
6988 <<obj->GetName()
6989 <<","<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
6990 }
6991 lnk = (TObjOptLink*)lnk->Next();
6992 }
6993
6994 // save attributes
6995 SaveFillAttributes(out,hname,0,1001);
6996 SaveLineAttributes(out,hname,1,1,1);
6997 SaveMarkerAttributes(out,hname,1,1,1);
6998 fXaxis.SaveAttributes(out,hname,"->GetXaxis()");
6999 fYaxis.SaveAttributes(out,hname,"->GetYaxis()");
7000 fZaxis.SaveAttributes(out,hname,"->GetZaxis()");
7001 TString opt = option;
7002 opt.ToLower();
7003 if (!opt.Contains("nodraw")) {
7004 out<<" "<<hname<<"->Draw("
7005 <<quote<<option<<quote<<");"<<std::endl;
7006 }
7007}
7008
7009////////////////////////////////////////////////////////////////////////////////
7010/// Copy current attributes from/to current style
7011
7013{
7014 if (!gStyle) return;
7015 if (gStyle->IsReading()) {
7016 fXaxis.ResetAttAxis("X");
7017 fYaxis.ResetAttAxis("Y");
7018 fZaxis.ResetAttAxis("Z");
7029 Int_t dostat = gStyle->GetOptStat();
7030 if (gStyle->GetOptFit() && !dostat) dostat = 1000000001;
7031 SetStats(dostat);
7032 } else {
7044 }
7045 TIter next(GetListOfFunctions());
7046 TObject *obj;
7047
7048 while ((obj = next())) {
7049 obj->UseCurrentStyle();
7050 }
7051}
7052
7053////////////////////////////////////////////////////////////////////////////////
7054/// For axis = 1,2 or 3 returns the mean value of the histogram along
7055/// X,Y or Z axis.
7056///
7057/// For axis = 11, 12, 13 returns the standard error of the mean value
7058/// of the histogram along X, Y or Z axis
7059///
7060/// Note that the mean value/StdDev is computed using the bins in the currently
7061/// defined range (see TAxis::SetRange). By default the range includes
7062/// all bins from 1 to nbins included, excluding underflows and overflows.
7063/// To force the underflows and overflows in the computation, one must
7064/// call the static function TH1::StatOverflows(kTRUE) before filling
7065/// the histogram.
7066///
7067/// Return mean value of this histogram along the X axis.
7068///
7069/// Note that the mean value/StdDev is computed using the bins in the currently
7070/// defined range (see TAxis::SetRange). By default the range includes
7071/// all bins from 1 to nbins included, excluding underflows and overflows.
7072/// To force the underflows and overflows in the computation, one must
7073/// call the static function TH1::StatOverflows(kTRUE) before filling
7074/// the histogram.
7075
7076Double_t TH1::GetMean(Int_t axis) const
7077{
7078 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7079 Double_t stats[kNstat];
7080 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7081 GetStats(stats);
7082 if (stats[0] == 0) return 0;
7083 if (axis<4){
7084 Int_t ax[3] = {2,4,7};
7085 return stats[ax[axis-1]]/stats[0];
7086 } else {
7087 // mean error = StdDev / sqrt( Neff )
7088 Double_t stddev = GetStdDev(axis-10);
7090 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7091 }
7092}
7093
7094////////////////////////////////////////////////////////////////////////////////
7095/// Return standard error of mean of this histogram along the X axis.
7096///
7097/// Note that the mean value/StdDev is computed using the bins in the currently
7098/// defined range (see TAxis::SetRange). By default the range includes
7099/// all bins from 1 to nbins included, excluding underflows and overflows.
7100/// To force the underflows and overflows in the computation, one must
7101/// call the static function TH1::StatOverflows(kTRUE) before filling
7102/// the histogram.
7103///
7104/// Also note, that although the definition of standard error doesn't include the
7105/// assumption of normality, many uses of this feature implicitly assume it.
7106
7108{
7109 return GetMean(axis+10);
7110}
7111
7112////////////////////////////////////////////////////////////////////////////////
7113/// Returns the Standard Deviation (Sigma).
7114/// The Sigma estimate is computed as
7115/// \f[
7116/// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7117/// \f]
7118/// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7119/// X, Y or Z axis
7120/// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7121/// X, Y or Z axis for Normal distribution
7122///
7123/// Note that the mean value/sigma is computed using the bins in the currently
7124/// defined range (see TAxis::SetRange). By default the range includes
7125/// all bins from 1 to nbins included, excluding underflows and overflows.
7126/// To force the underflows and overflows in the computation, one must
7127/// call the static function TH1::StatOverflows(kTRUE) before filling
7128/// the histogram.
7129
7130Double_t TH1::GetStdDev(Int_t axis) const
7131{
7132 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7133
7134 Double_t x, stddev2, stats[kNstat];
7135 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7136 GetStats(stats);
7137 if (stats[0] == 0) return 0;
7138 Int_t ax[3] = {2,4,7};
7139 Int_t axm = ax[axis%10 - 1];
7140 x = stats[axm]/stats[0];
7141 // for negative stddev (e.g. when having negative weights) - return stdev=0
7142 stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7143 if (axis<10)
7144 return TMath::Sqrt(stddev2);
7145 else {
7146 // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7147 // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7149 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7150 }
7151}
7152
7153////////////////////////////////////////////////////////////////////////////////
7154/// Return error of standard deviation estimation for Normal distribution
7155///
7156/// Note that the mean value/StdDev is computed using the bins in the currently
7157/// defined range (see TAxis::SetRange). By default the range includes
7158/// all bins from 1 to nbins included, excluding underflows and overflows.
7159/// To force the underflows and overflows in the computation, one must
7160/// call the static function TH1::StatOverflows(kTRUE) before filling
7161/// the histogram.
7162///
7163/// Value returned is standard deviation of sample standard deviation.
7164/// Note that it is an approximated value which is valid only in the case that the
7165/// original data distribution is Normal. The correct one would require
7166/// the 4-th momentum value, which cannot be accurately estimated from an histogram since
7167/// the x-information for all entries is not kept.
7168
7170{
7171 return GetStdDev(axis+10);
7172}
7173
7174////////////////////////////////////////////////////////////////////////////////
7175/// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7176/// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7177/// of the histogram along x, y or z axis
7178///
7179///Note, that since third and fourth moment are not calculated
7180///at the fill time, skewness and its standard error are computed bin by bin
7181
7183{
7184
7185 if (axis > 0 && axis <= 3){
7186
7187 Double_t mean = GetMean(axis);
7188 Double_t stddev = GetStdDev(axis);
7189 Double_t stddev3 = stddev*stddev*stddev;
7190
7191 Int_t firstBinX = fXaxis.GetFirst();
7192 Int_t lastBinX = fXaxis.GetLast();
7193 Int_t firstBinY = fYaxis.GetFirst();
7194 Int_t lastBinY = fYaxis.GetLast();
7195 Int_t firstBinZ = fZaxis.GetFirst();
7196 Int_t lastBinZ = fZaxis.GetLast();
7197 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7200 if (firstBinX == 1) firstBinX = 0;
7201 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7202 }
7204 if (firstBinY == 1) firstBinY = 0;
7205 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7206 }
7208 if (firstBinZ == 1) firstBinZ = 0;
7209 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7210 }
7211 }
7212
7213 Double_t x = 0;
7214 Double_t sum=0;
7215 Double_t np=0;
7216 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7217 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7218 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7219 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7220 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7221 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7222 Double_t w = GetBinContent(binx,biny,binz);
7223 np+=w;
7224 sum+=w*(x-mean)*(x-mean)*(x-mean);
7225 }
7226 }
7227 }
7228 sum/=np*stddev3;
7229 return sum;
7230 }
7231 else if (axis > 10 && axis <= 13) {
7232 //compute standard error of skewness
7233 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7235 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7236 }
7237 else {
7238 Error("GetSkewness", "illegal value of parameter");
7239 return 0;
7240 }
7241}
7242
7243////////////////////////////////////////////////////////////////////////////////
7244/// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7245/// Kurtosis(gaussian(0, 1)) = 0.
7246/// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7247/// of the histogram along x, y or z axis
7248////
7249/// Note, that since third and fourth moment are not calculated
7250/// at the fill time, kurtosis and its standard error are computed bin by bin
7251
7253{
7254 if (axis > 0 && axis <= 3){
7255
7256 Double_t mean = GetMean(axis);
7257 Double_t stddev = GetStdDev(axis);
7258 Double_t stddev4 = stddev*stddev*stddev*stddev;
7259
7260 Int_t firstBinX = fXaxis.GetFirst();
7261 Int_t lastBinX = fXaxis.GetLast();
7262 Int_t firstBinY = fYaxis.GetFirst();
7263 Int_t lastBinY = fYaxis.GetLast();
7264 Int_t firstBinZ = fZaxis.GetFirst();
7265 Int_t lastBinZ = fZaxis.GetLast();
7266 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7269 if (firstBinX == 1) firstBinX = 0;
7270 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7271 }
7273 if (firstBinY == 1) firstBinY = 0;
7274 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7275 }
7277 if (firstBinZ == 1) firstBinZ = 0;
7278 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7279 }
7280 }
7281
7282 Double_t x = 0;
7283 Double_t sum=0;
7284 Double_t np=0;
7285 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7286 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7287 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7288 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7289 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7290 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7291 Double_t w = GetBinContent(binx,biny,binz);
7292 np+=w;
7293 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7294 }
7295 }
7296 }
7297 sum/=(np*stddev4);
7298 return sum-3;
7299
7300 } else if (axis > 10 && axis <= 13) {
7301 //compute standard error of skewness
7302 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7304 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7305 }
7306 else {
7307 Error("GetKurtosis", "illegal value of parameter");
7308 return 0;
7309 }
7310}
7311
7312////////////////////////////////////////////////////////////////////////////////
7313/// fill the array stats from the contents of this histogram
7314/// The array stats must be correctly dimensioned in the calling program.
7315///
7316/// ~~~ {.cpp}
7317/// stats[0] = sumw
7318/// stats[1] = sumw2
7319/// stats[2] = sumwx
7320/// stats[3] = sumwx2
7321/// ~~~
7322///
7323/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7324/// is simply a copy of the statistics quantities computed at filling time.
7325/// If a sub-range is specified, the function recomputes these quantities
7326/// from the bin contents in the current axis range.
7327///
7328/// Note that the mean value/StdDev is computed using the bins in the currently
7329/// defined range (see TAxis::SetRange). By default the range includes
7330/// all bins from 1 to nbins included, excluding underflows and overflows.
7331/// To force the underflows and overflows in the computation, one must
7332/// call the static function TH1::StatOverflows(kTRUE) before filling
7333/// the histogram.
7334
7335void TH1::GetStats(Double_t *stats) const
7336{
7337 if (fBuffer) ((TH1*)this)->BufferEmpty();
7338
7339 // Loop on bins (possibly including underflows/overflows)
7340 Int_t bin, binx;
7341 Double_t w,err;
7342 Double_t x;
7343 // identify the case of labels with extension of axis range
7344 // in this case the statistics in x does not make any sense
7345 Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && CanExtendAllAxes() );
7346 // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7347 if ((fTsumw == 0 && fEntries > 0) || ( fXaxis.TestBit(TAxis::kAxisRange) && !labelHist) ) {
7348 for (bin=0;bin<4;bin++) stats[bin] = 0;
7349
7350 Int_t firstBinX = fXaxis.GetFirst();
7351 Int_t lastBinX = fXaxis.GetLast();
7352 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7354 if (firstBinX == 1) firstBinX = 0;
7355 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7356 }
7357 for (binx = firstBinX; binx <= lastBinX; binx++) {
7358 x = fXaxis.GetBinCenter(binx);
7359 //w = TMath::Abs(RetrieveBinContent(binx));
7360 // not sure what to do here if w < 0
7361 w = RetrieveBinContent(binx);
7362 err = TMath::Abs(GetBinError(binx));
7363 stats[0] += w;
7364 stats[1] += err*err;
7365 // statistics in x makes sense only for not labels histograms
7366 if (!labelHist) {
7367 stats[2] += w*x;
7368 stats[3] += w*x*x;
7369 }
7370 }
7371 // if (stats[0] < 0) {
7372 // // in case total is negative do something ??
7373 // stats[0] = 0;
7374 // }
7375 } else {
7376 stats[0] = fTsumw;
7377 stats[1] = fTsumw2;
7378 stats[2] = fTsumwx;
7379 stats[3] = fTsumwx2;
7380 }
7381}
7382
7383////////////////////////////////////////////////////////////////////////////////
7384/// Replace current statistics with the values in array stats
7385
7386void TH1::PutStats(Double_t *stats)
7387{
7388 fTsumw = stats[0];
7389 fTsumw2 = stats[1];
7390 fTsumwx = stats[2];
7391 fTsumwx2 = stats[3];
7392}
7393
7394////////////////////////////////////////////////////////////////////////////////
7395/// Reset the statistics including the number of entries
7396/// and replace with values calculates from bin content
7397///
7398/// The number of entries is set to the total bin content or (in case of weighted histogram)
7399/// to number of effective entries
7400
7401void TH1::ResetStats()
7402{
7403 Double_t stats[kNstat] = {0};
7404 fTsumw = 0;
7405 fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
7406 GetStats(stats);
7407 PutStats(stats);
7409 // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
7410 if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
7411}
7412
7413////////////////////////////////////////////////////////////////////////////////
7414/// Return the sum of weights excluding under/overflows.
7415
7417{
7418 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7419
7420 Int_t bin,binx,biny,binz;
7421 Double_t sum =0;
7422 for(binz=1; binz<=fZaxis.GetNbins(); binz++) {
7423 for(biny=1; biny<=fYaxis.GetNbins(); biny++) {
7424 for(binx=1; binx<=fXaxis.GetNbins(); binx++) {
7425 bin = GetBin(binx,biny,binz);
7426 sum += RetrieveBinContent(bin);
7427 }
7428 }
7429 }
7430 return sum;
7431}
7432
7433////////////////////////////////////////////////////////////////////////////////
7434///Return integral of bin contents. Only bins in the bins range are considered.
7435///
7436/// By default the integral is computed as the sum of bin contents in the range.
7437/// if option "width" is specified, the integral is the sum of
7438/// the bin contents multiplied by the bin width in x.
7439
7440Double_t TH1::Integral(Option_t *option) const
7441{
7442 return Integral(fXaxis.GetFirst(),fXaxis.GetLast(),option);
7443}
7444
7445////////////////////////////////////////////////////////////////////////////////
7446/// Return integral of bin contents in range [binx1,binx2].
7447///
7448/// By default the integral is computed as the sum of bin contents in the range.
7449/// if option "width" is specified, the integral is the sum of
7450/// the bin contents multiplied by the bin width in x.
7451
7452Double_t TH1::Integral(Int_t binx1, Int_t binx2, Option_t *option) const
7453{
7454 double err = 0;
7455 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
7456}
7457
7458////////////////////////////////////////////////////////////////////////////////
7459/// Return integral of bin contents in range [binx1,binx2] and its error.
7460///
7461/// By default the integral is computed as the sum of bin contents in the range.
7462/// if option "width" is specified, the integral is the sum of
7463/// the bin contents multiplied by the bin width in x.
7464/// the error is computed using error propagation from the bin errors assuming that
7465/// all the bins are uncorrelated
7466
7467Double_t TH1::IntegralAndError(Int_t binx1, Int_t binx2, Double_t & error, Option_t *option) const
7468{
7469 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
7470}
7471
7472////////////////////////////////////////////////////////////////////////////////
7473/// Internal function compute integral and optionally the error between the limits
7474/// specified by the bin number values working for all histograms (1D, 2D and 3D)
7475
7476Double_t TH1::DoIntegral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error ,
7477 Option_t *option, Bool_t doError) const
7478{
7479 if (fBuffer) ((TH1*)this)->BufferEmpty();
7480
7481 Int_t nx = GetNbinsX() + 2;
7482 if (binx1 < 0) binx1 = 0;
7483 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
7484
7485 if (GetDimension() > 1) {
7486 Int_t ny = GetNbinsY() + 2;
7487 if (biny1 < 0) biny1 = 0;
7488 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
7489 } else {
7490 biny1 = 0; biny2 = 0;
7491 }
7492
7493 if (GetDimension() > 2) {
7494 Int_t nz = GetNbinsZ() + 2;
7495 if (binz1 < 0) binz1 = 0;
7496 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
7497 } else {
7498 binz1 = 0; binz2 = 0;
7499 }
7500
7501 // - Loop on bins in specified range
7502 TString opt = option;
7503 opt.ToLower();
7505 if (opt.Contains("width")) width = kTRUE;
7506
7507
7508 Double_t dx = 1., dy = .1, dz =.1;
7509 Double_t integral = 0;
7510 Double_t igerr2 = 0;
7511 for (Int_t binx = binx1; binx <= binx2; ++binx) {
7512 if (width) dx = fXaxis.GetBinWidth(binx);
7513 for (Int_t biny = biny1; biny <= biny2; ++biny) {
7514 if (width) dy = fYaxis.GetBinWidth(biny);
7515 for (Int_t binz = binz1; binz <= binz2; ++binz) {
7516 Int_t bin = GetBin(binx, biny, binz);
7517 Double_t dv = 0.0;
7518 if (width) {
7519 dz = fZaxis.GetBinWidth(binz);
7520 dv = dx * dy * dz;
7521 integral += RetrieveBinContent(bin) * dv;
7522 } else {
7523 integral += RetrieveBinContent(bin);
7524 }
7525 if (doError) {
7526 if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
7527 else igerr2 += GetBinErrorSqUnchecked(bin);
7528 }
7529 }
7530 }
7531 }
7532
7533 if (doError) error = TMath::Sqrt(igerr2);
7534 return integral;
7535}
7536
7537////////////////////////////////////////////////////////////////////////////////
7538/// Statistical test of compatibility in shape between
7539/// this histogram and h2, using the Anderson-Darling 2 sample test.
7540///
7541/// The AD 2 sample test formula are derived from the paper
7542/// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
7543///
7544/// The test is implemented in root in the ROOT::Math::GoFTest class
7545/// It is the same formula ( (6) in the paper), and also shown in
7546/// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
7547///
7548/// Binned data are considered as un-binned data
7549/// with identical observation happening in the bin center.
7550///
7551/// \param[in] option is a character string to specify options
7552/// - "D" Put out a line of "Debug" printout
7553/// - "T" Return the normalized A-D test statistic
7554///
7555/// - Note1: Underflow and overflow are not considered in the test
7556/// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
7557/// - Note3: The histograms are not required to have the same X axis
7558/// - Note4: The test works only for 1-dimensional histograms
7559
7560Double_t TH1::AndersonDarlingTest(const TH1 *h2, Option_t *option) const
7561{
7562 Double_t advalue = 0;
7563 Double_t pvalue = AndersonDarlingTest(h2, advalue);
7564
7565 TString opt = option;
7566 opt.ToUpper();
7567 if (opt.Contains("D") ) {
7568 printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
7569 }
7570 if (opt.Contains("T") ) return advalue;
7571
7572 return pvalue;
7573}
7574
7575////////////////////////////////////////////////////////////////////////////////
7576/// Same function as above but returning also the test statistic value
7577
7578Double_t TH1::AndersonDarlingTest(const TH1 *h2, Double_t & advalue) const
7579{
7580 if (GetDimension() != 1 || h2->GetDimension() != 1) {
7581 Error("AndersonDarlingTest","Histograms must be 1-D");
7582 return -1;
7583 }
7584
7585 // empty the buffer. Probably we could add as an unbinned test
7586 if (fBuffer) ((TH1*)this)->BufferEmpty();
7587
7588 // use the BinData class
7589 ROOT::Fit::BinData data1;
7590 ROOT::Fit::BinData data2;
7591
7592 ROOT::Fit::FillData(data1, this, 0);
7593 ROOT::Fit::FillData(data2, h2, 0);
7594
7595 double pvalue;
7596 ROOT::Math::GoFTest::AndersonDarling2SamplesTest(data1,data2, pvalue,advalue);
7597
7598 return pvalue;
7599}
7600
7601////////////////////////////////////////////////////////////////////////////////
7602/// Statistical test of compatibility in shape between
7603/// this histogram and h2, using Kolmogorov test.
7604/// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
7605/// and not for binned data as in the case of the histogram (see NOTE 3 below).
7606/// So, before using this method blindly, read the NOTE 3.
7607///
7608/// Default: Ignore under- and overflow bins in comparison
7609///
7610/// \param[in] h2 histogram
7611/// \param[in] option is a character string to specify options
7612/// - "U" include Underflows in test (also for 2-dim)
7613/// - "O" include Overflows (also valid for 2-dim)
7614/// - "N" include comparison of normalizations
7615/// - "D" Put out a line of "Debug" printout
7616/// - "M" Return the Maximum Kolmogorov distance instead of prob
7617/// - "X" Run the pseudo experiments post-processor with the following procedure:
7618/// make pseudoexperiments based on random values from the parent distribution,
7619/// compare the KS distance of the pseudoexperiment to the parent
7620/// distribution, and count all the KS values above the value
7621/// obtained from the original data to Monte Carlo distribution.
7622/// The number of pseudo-experiments nEXPT is currently fixed at 1000.
7623/// The function returns the probability.
7624/// (thanks to Ben Kilminster to submit this procedure). Note that
7625/// this option "X" is much slower.
7626///
7627/// The returned function value is the probability of test
7628/// (much less than one means NOT compatible)
7629///
7630/// Code adapted by Rene Brun from original HBOOK routine HDIFF
7631///
7632/// NOTE1
7633/// A good description of the Kolmogorov test can be seen at:
7634/// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
7635///
7636/// NOTE2
7637/// see also alternative function TH1::Chi2Test
7638/// The Kolmogorov test is assumed to give better results than Chi2Test
7639/// in case of histograms with low statistics.
7640///
7641/// NOTE3 (Jan Conrad, Fred James)
7642/// "The returned value PROB is calculated such that it will be
7643/// uniformly distributed between zero and one for compatible histograms,
7644/// provided the data are not binned (or the number of bins is very large
7645/// compared with the number of events). Users who have access to unbinned
7646/// data and wish exact confidence levels should therefore not put their data
7647/// into histograms, but should call directly TMath::KolmogorovTest. On
7648/// the other hand, since TH1 is a convenient way of collecting data and
7649/// saving space, this function has been provided. However, the values of
7650/// PROB for binned data will be shifted slightly higher than expected,
7651/// depending on the effects of the binning. For example, when comparing two
7652/// uniform distributions of 500 events in 100 bins, the values of PROB,
7653/// instead of being exactly uniformly distributed between zero and one, have
7654/// a mean value of about 0.56. We can apply a useful
7655/// rule: As long as the bin width is small compared with any significant
7656/// physical effect (for example the experimental resolution) then the binning
7657/// cannot have an important effect. Therefore, we believe that for all
7658/// practical purposes, the probability value PROB is calculated correctly
7659/// provided the user is aware that:
7660///
7661/// 1. The value of PROB should not be expected to have exactly the correct
7662/// distribution for binned data.
7663/// 2. The user is responsible for seeing to it that the bin widths are
7664/// small compared with any physical phenomena of interest.
7665/// 3. The effect of binning (if any) is always to make the value of PROB
7666/// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
7667/// will assure that at most 5% of truly compatible histograms are rejected,
7668/// and usually somewhat less."
7669///
7670/// Note also that for GoF test of unbinned data ROOT provides also the class
7671/// ROOT::Math::GoFTest. The class has also method for doing one sample tests
7672/// (i.e. comparing the data with a given distribution).
7673
7674Double_t TH1::KolmogorovTest(const TH1 *h2, Option_t *option) const
7675{
7676 TString opt = option;
7677 opt.ToUpper();
7678
7679 Double_t prob = 0;
7680 TH1 *h1 = (TH1*)this;
7681 if (h2 == 0) return 0;
7682 const TAxis *axis1 = h1->GetXaxis();
7683 const TAxis *axis2 = h2->GetXaxis();
7684 Int_t ncx1 = axis1->GetNbins();
7685 Int_t ncx2 = axis2->GetNbins();
7686
7687 // Check consistency of dimensions
7688 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
7689 Error("KolmogorovTest","Histograms must be 1-D\n");
7690 return 0;
7691 }
7692
7693 // Check consistency in number of channels
7694 if (ncx1 != ncx2) {
7695 Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
7696 return 0;
7697 }
7698
7699 // empty the buffer. Probably we could add as an unbinned test
7700 if (fBuffer) ((TH1*)this)->BufferEmpty();
7701
7702 // Check consistency in bin edges
7703 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
7704 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
7705 Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
7706 return 0;
7707 }
7708 }
7709
7710 Bool_t afunc1 = kFALSE;
7711 Bool_t afunc2 = kFALSE;
7712 Double_t sum1 = 0, sum2 = 0;
7713 Double_t ew1, ew2, w1 = 0, w2 = 0;
7714 Int_t bin;
7715 Int_t ifirst = 1;
7716 Int_t ilast = ncx1;
7717 // integral of all bins (use underflow/overflow if option)
7718 if (opt.Contains("U")) ifirst = 0;
7719 if (opt.Contains("O")) ilast = ncx1 +1;
7720 for (bin = ifirst; bin <= ilast; bin++) {
7721 sum1 += h1->RetrieveBinContent(bin);
7722 sum2 += h2->RetrieveBinContent(bin);
7723 ew1 = h1->GetBinError(bin);
7724 ew2 = h2->GetBinError(bin);
7725 w1 += ew1*ew1;
7726 w2 += ew2*ew2;
7727 }
7728 if (sum1 == 0) {
7729 Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
7730 return 0;
7731 }
7732 if (sum2 == 0) {
7733 Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
7734 return 0;
7735 }
7736
7737 // calculate the effective entries.
7738 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
7739 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
7740 Double_t esum1 = 0, esum2 = 0;
7741 if (w1 > 0)
7742 esum1 = sum1 * sum1 / w1;
7743 else
7744 afunc1 = kTRUE; // use later for calculating z
7745
7746 if (w2 > 0)
7747 esum2 = sum2 * sum2 / w2;
7748 else
7749 afunc2 = kTRUE; // use later for calculating z
7750
7751 if (afunc2 && afunc1) {
7752 Error("KolmogorovTest","Errors are zero for both histograms\n");
7753 return 0;
7754 }
7755
7756
7757 Double_t s1 = 1/sum1;
7758 Double_t s2 = 1/sum2;
7759
7760 // Find largest difference for Kolmogorov Test
7761 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
7762
7763 for (bin=ifirst;bin<=ilast;bin++) {
7764 rsum1 += s1*h1->RetrieveBinContent(bin);
7765 rsum2 += s2*h2->RetrieveBinContent(bin);
7766 dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
7767 }
7768
7769 // Get Kolmogorov probability
7770 Double_t z, prb1=0, prb2=0, prb3=0;
7771
7772 // case h1 is exact (has zero errors)
7773 if (afunc1)
7774 z = dfmax*TMath::Sqrt(esum2);
7775 // case h2 has zero errors
7776 else if (afunc2)
7777 z = dfmax*TMath::Sqrt(esum1);
7778 else
7779 // for comparison between two data sets
7780 z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
7781
7782 prob = TMath::KolmogorovProb(z);
7783
7784 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
7785 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
7786 // Combine probabilities for shape and normalization,
7787 prb1 = prob;
7788 Double_t d12 = esum1-esum2;
7789 Double_t chi2 = d12*d12/(esum1+esum2);
7790 prb2 = TMath::Prob(chi2,1);
7791 // see Eadie et al., section 11.6.2
7792 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
7793 else prob = 0;
7794 }
7795 // X option. Pseudo-experiments post-processor to determine KS probability
7796 const Int_t nEXPT = 1000;
7797 if (opt.Contains("X") && !(afunc1 || afunc2 ) ) {
7798 Double_t dSEXPT;
7799 TH1 *h1_cpy = (TH1 *)(gDirectory ? gDirectory->CloneObject(this, kFALSE) : gROOT->CloneObject(this, kFALSE));
7800 TH1 *h1Expt = (TH1*)(gDirectory ? gDirectory->CloneObject(this,kFALSE) : gROOT->CloneObject(this,kFALSE));
7801 TH1 *h2Expt = (TH1*)(gDirectory ? gDirectory->CloneObject(this,kFALSE) : gROOT->CloneObject(this,kFALSE));
7802
7803 if (GetMinimum() < 0.0) {
7804 // we need to create a new histogram
7805 // With negative bins we can't draw random samples in a meaningful way.
7806 Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
7807 "skewed. Reduce number of bins for histogram?");
7808 while (h1_cpy->GetMinimum() < 0.0) {
7809 Int_t idx = h1_cpy->GetMinimumBin();
7810 h1_cpy->SetBinContent(idx, 0.0);
7811 }
7812 }
7813
7814 // make nEXPT experiments (this should be a parameter)
7815 prb3 = 0;
7816 for (Int_t i=0; i < nEXPT; i++) {
7817 h1Expt->Reset();
7818 h2Expt->Reset();
7819 h1Expt->FillRandom(h1_cpy, (Int_t)esum1);
7820 h2Expt->FillRandom(h1_cpy, (Int_t)esum2);
7821 dSEXPT = h1Expt->KolmogorovTest(h2Expt,"M");
7822 if (dSEXPT>dfmax) prb3 += 1.0;
7823 }
7824 prb3 /= (Double_t)nEXPT;
7825 delete h1_cpy;
7826 delete h1Expt;
7827 delete h2Expt;
7828 }
7829
7830 // debug printout
7831 if (opt.Contains("D")) {
7832 printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
7833 printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
7834 printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
7835 if (opt.Contains("N"))
7836 printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
7837 if (opt.Contains("X"))
7838 printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
7839 }
7840 // This numerical error condition should never occur:
7841 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
7842 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
7843
7844 if(opt.Contains("M")) return dfmax;
7845 else if(opt.Contains("X")) return prb3;
7846 else return prob;
7847}
7848
7849////////////////////////////////////////////////////////////////////////////////
7850/// Replace bin contents by the contents of array content
7851
7852void TH1::SetContent(const Double_t *content)
7853{
7854 fEntries = fNcells;
7855 fTsumw = 0;
7856 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
7857}
7858
7859////////////////////////////////////////////////////////////////////////////////
7860/// Return contour values into array levels if pointer levels is non zero.
7861///
7862/// The function returns the number of contour levels.
7863/// see GetContourLevel to return one contour only
7864
7866{
7867 Int_t nlevels = fContour.fN;
7868 if (levels) {
7869 if (nlevels == 0) {
7870 nlevels = 20;
7871 SetContour(nlevels);
7872 } else {
7873 if (TestBit(kUserContour) == 0) SetContour(nlevels);
7874 }
7875 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
7876 }
7877 return nlevels;
7878}
7879
7880////////////////////////////////////////////////////////////////////////////////
7881/// Return value of contour number level.
7882/// Use GetContour to return the array of all contour levels
7883
7885{
7886 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
7887}
7888
7889////////////////////////////////////////////////////////////////////////////////
7890/// Return the value of contour number "level" in Pad coordinates.
7891/// ie: if the Pad is in log scale along Z it returns le log of the contour level
7892/// value. See GetContour to return the array of all contour levels
7893
7895{
7896 if (level <0 || level >= fContour.fN) return 0;
7897 Double_t zlevel = fContour.fArray[level];
7898
7899 // In case of user defined contours and Pad in log scale along Z,
7900 // fContour.fArray doesn't contain the log of the contour whereas it does
7901 // in case of equidistant contours.
7902 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
7903 if (zlevel <= 0) return 0;
7904 zlevel = TMath::Log10(zlevel);
7905 }
7906 return zlevel;
7907}
7908
7909////////////////////////////////////////////////////////////////////////////////
7910/// Set the maximum number of entries to be kept in the buffer.
7911
7912void TH1::SetBuffer(Int_t buffersize, Option_t * /*option*/)
7913{
7914 if (fBuffer) {
7915 BufferEmpty();
7916 delete [] fBuffer;
7917 fBuffer = 0;
7918 }
7919 if (buffersize <= 0) {
7920 fBufferSize = 0;
7921 return;
7922 }
7923 if (buffersize < 100) buffersize = 100;
7924 fBufferSize = 1 + buffersize*(fDimension+1);
7926 memset(fBuffer,0,sizeof(Double_t)*fBufferSize);
7927}
7928
7929////////////////////////////////////////////////////////////////////////////////
7930/// Set the number and values of contour levels.
7931///
7932/// By default the number of contour levels is set to 20. The contours values
7933/// in the array "levels" should be specified in increasing order.
7934///
7935/// if argument levels = 0 or missing, equidistant contours are computed
7936
7937void TH1::SetContour(Int_t nlevels, const Double_t *levels)
7938{
7939 Int_t level;
7941 if (nlevels <=0 ) {
7942 fContour.Set(0);
7943 return;
7944 }
7945 fContour.Set(nlevels);
7946
7947 // - Contour levels are specified
7948 if (levels) {
7950 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
7951 } else {
7952 // - contour levels are computed automatically as equidistant contours
7953 Double_t zmin = GetMinimum();
7954 Double_t zmax = GetMaximum();
7955 if ((zmin == zmax) && (zmin != 0)) {
7956 zmax += 0.01*TMath::Abs(zmax);
7957 zmin -= 0.01*TMath::Abs(zmin);
7958 }
7959 Double_t dz = (zmax-zmin)/Double_t(nlevels);
7960 if (gPad && gPad->GetLogz()) {
7961 if (zmax <= 0) return;
7962 if (zmin <= 0) zmin = 0.001*zmax;
7963 zmin = TMath::Log10(zmin);
7964 zmax = TMath::Log10(zmax);
7965 dz = (zmax-zmin)/Double_t(nlevels);
7966 }
7967 for (level=0; level<nlevels; level++) {
7968 fContour.fArray[level] = zmin + dz*Double_t(level);
7969 }
7970 }
7971}
7972
7973////////////////////////////////////////////////////////////////////////////////
7974/// Set value for one contour level.
7975
7976void TH1::SetContourLevel(Int_t level, Double_t value)
7977{
7978 if (level < 0 || level >= fContour.fN) return;
7980 fContour.fArray[level] = value;
7981}
7982
7983////////////////////////////////////////////////////////////////////////////////
7984/// Return maximum value smaller than maxval of bins in the range,
7985/// unless the value has been overridden by TH1::SetMaximum,
7986/// in which case it returns that value. (This happens, for example,
7987/// when the histogram is drawn and the y or z axis limits are changed
7988///
7989/// To get the maximum value of bins in the histogram regardless of
7990/// whether the value has been overridden, use
7991///
7992/// ~~~ {.cpp}
7993/// h->GetBinContent(h->GetMaximumBin())
7994/// ~~~
7995
7996Double_t TH1::GetMaximum(Double_t maxval) const
7997{
7998 if (fMaximum != -1111) return fMaximum;
7999
8000 // empty the buffer
8001 if (fBuffer) ((TH1*)this)->BufferEmpty();
8002
8003 Int_t bin, binx, biny, binz;
8004 Int_t xfirst = fXaxis.GetFirst();
8005 Int_t xlast = fXaxis.GetLast();
8006 Int_t yfirst = fYaxis.GetFirst();
8007 Int_t ylast = fYaxis.GetLast();
8008 Int_t zfirst = fZaxis.GetFirst();
8009 Int_t zlast = fZaxis.GetLast();
8010 Double_t maximum = -FLT_MAX, value;
8011 for (binz=zfirst;binz<=zlast;binz++) {
8012 for (biny=yfirst;biny<=ylast;biny++) {
8013 for (binx=xfirst;binx<=xlast;binx++) {
8014 bin = GetBin(binx,biny,binz);
8015 value = RetrieveBinContent(bin);
8016 if (value > maximum && value < maxval) maximum = value;
8017 }
8018 }
8019 }
8020 return maximum;
8021}
8022
8023////////////////////////////////////////////////////////////////////////////////
8024/// Return location of bin with maximum value in the range.
8025
8027{
8028 Int_t locmax, locmay, locmaz;
8029 return GetMaximumBin(locmax, locmay, locmaz);
8030}
8031
8032////////////////////////////////////////////////////////////////////////////////
8033/// Return location of bin with maximum value in the range.
8034
8035Int_t TH1::GetMaximumBin(Int_t &locmax, Int_t &locmay, Int_t &locmaz) const
8036{
8037 // empty the buffer
8038 if (fBuffer) ((TH1*)this)->BufferEmpty();
8039
8040 Int_t bin, binx, biny, binz;
8041 Int_t locm;
8042 Int_t xfirst = fXaxis.GetFirst();
8043 Int_t xlast = fXaxis.GetLast();
8044 Int_t yfirst = fYaxis.GetFirst();
8045 Int_t ylast = fYaxis.GetLast();
8046 Int_t zfirst = fZaxis.GetFirst();
8047 Int_t zlast = fZaxis.GetLast();
8048 Double_t maximum = -FLT_MAX, value;
8049 locm = locmax = locmay = locmaz = 0;
8050 for (binz=zfirst;binz<=zlast;binz++) {
8051 for (biny=yfirst;biny<=ylast;biny++) {
8052 for (binx=xfirst;binx<=xlast;binx++) {
8053 bin = GetBin(binx,biny,binz);
8054 value = RetrieveBinContent(bin);
8055 if (value > maximum) {
8056 maximum = value;
8057 locm = bin;
8058 locmax = binx;
8059 locmay = biny;
8060 locmaz = binz;
8061 }
8062 }
8063 }
8064 }
8065 return locm;
8066}
8067
8068////////////////////////////////////////////////////////////////////////////////
8069/// Return minimum value larger than minval of bins in the range,
8070/// unless the value has been overridden by TH1::SetMinimum,
8071/// in which case it returns that value. (This happens, for example,
8072/// when the histogram is drawn and the y or z axis limits are changed
8073///
8074/// To get the minimum value of bins in the histogram regardless of
8075/// whether the value has been overridden, use
8076///
8077/// ~~~ {.cpp}
8078/// h->GetBinContent(h->GetMinimumBin())
8079/// ~~~
8080
8081Double_t TH1::GetMinimum(Double_t minval) const
8082{
8083 if (fMinimum != -1111) return fMinimum;
8084
8085 // empty the buffer
8086 if (fBuffer) ((TH1*)this)->BufferEmpty();
8087
8088 Int_t bin, binx, biny, binz;
8089 Int_t xfirst = fXaxis.GetFirst();
8090 Int_t xlast = fXaxis.GetLast();
8091 Int_t yfirst = fYaxis.GetFirst();
8092 Int_t ylast = fYaxis.GetLast();
8093 Int_t zfirst = fZaxis.GetFirst();
8094 Int_t zlast = fZaxis.GetLast();
8095 Double_t minimum=FLT_MAX, value;
8096 for (binz=zfirst;binz<=zlast;binz++) {
8097 for (biny=yfirst;biny<=ylast;biny++) {
8098 for (binx=xfirst;binx<=xlast;binx++) {
8099 bin = GetBin(binx,biny,binz);
8100 value = RetrieveBinContent(bin);
8101 if (value < minimum && value > minval) minimum = value;
8102 }
8103 }
8104 }
8105 return minimum;
8106}
8107
8108////////////////////////////////////////////////////////////////////////////////
8109/// Return location of bin with minimum value in the range.
8110
8112{
8113 Int_t locmix, locmiy, locmiz;
8114 return GetMinimumBin(locmix, locmiy, locmiz);
8115}
8116
8117////////////////////////////////////////////////////////////////////////////////
8118/// Return location of bin with minimum value in the range.
8119
8120Int_t TH1::GetMinimumBin(Int_t &locmix, Int_t &locmiy, Int_t &locmiz) const
8121{
8122 // empty the buffer
8123 if (fBuffer) ((TH1*)this)->BufferEmpty();
8124
8125 Int_t bin, binx, biny, binz;
8126 Int_t locm;
8127 Int_t xfirst = fXaxis.GetFirst();
8128 Int_t xlast = fXaxis.GetLast();
8129 Int_t yfirst = fYaxis.GetFirst();
8130 Int_t ylast = fYaxis.GetLast();
8131 Int_t zfirst = fZaxis.GetFirst();
8132 Int_t zlast = fZaxis.GetLast();
8133 Double_t minimum = FLT_MAX, value;
8134 locm = locmix = locmiy = locmiz = 0;
8135 for (binz=zfirst;binz<=zlast;binz++) {
8136 for (biny=yfirst;biny<=ylast;biny++) {
8137 for (binx=xfirst;binx<=xlast;binx++) {
8138 bin = GetBin(binx,biny,binz);
8139 value = RetrieveBinContent(bin);
8140 if (value < minimum) {
8141 minimum = value;
8142 locm = bin;
8143 locmix = binx;
8144 locmiy = biny;
8145 locmiz = binz;
8146 }
8147 }
8148 }
8149 }
8150 return locm;
8151}
8152
8153///////////////////////////////////////////////////////////////////////////////
8154/// Retrieve the minimum and maximum values in the histogram
8155///
8156/// This will not return a cached value and will always search the
8157/// histogram for the min and max values. The user can condition whether
8158/// or not to call this with the GetMinimumStored() and GetMaximumStored()
8159/// methods. If the cache is empty, then the value will be -1111. Users
8160/// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8161/// For example, the following recipe will make efficient use of this method
8162/// and the cached minimum and maximum values.
8163//
8164/// \code{.cpp}
8165/// Double_t currentMin = pHist->GetMinimumStored();
8166/// Double_t currentMax = pHist->GetMaximumStored();
8167/// if ((currentMin == -1111) || (currentMax == -1111)) {
8168/// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8169/// pHist->SetMinimum(currentMin);
8170/// pHist->SetMaximum(currentMax);
8171/// }
8172/// \endcode
8173///
8174/// \param min reference to variable that will hold found minimum value
8175/// \param max reference to variable that will hold found maximum value
8176
8177void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8178{
8179 // empty the buffer
8180 if (fBuffer) ((TH1*)this)->BufferEmpty();
8181
8182 Int_t bin, binx, biny, binz;
8183 Int_t xfirst = fXaxis.GetFirst();
8184 Int_t xlast = fXaxis.GetLast();
8185 Int_t yfirst = fYaxis.GetFirst();
8186 Int_t ylast = fYaxis.GetLast();
8187 Int_t zfirst = fZaxis.GetFirst();
8188 Int_t zlast = fZaxis.GetLast();
8189 min=TMath::Infinity();
8190 max=-TMath::Infinity();
8191 Double_t value;
8192 for (binz=zfirst;binz<=zlast;binz++) {
8193 for (biny=yfirst;biny<=ylast;biny++) {
8194 for (binx=xfirst;binx<=xlast;binx++) {
8195 bin = GetBin(binx,biny,binz);
8196 value = RetrieveBinContent(bin);
8197 if (value < min) min = value;
8198 if (value > max) max = value;
8199 }
8200 }
8201 }
8202}
8203
8204////////////////////////////////////////////////////////////////////////////////
8205/// Redefine x axis parameters.
8206///
8207/// The X axis parameters are modified.
8208/// The bins content array is resized
8209/// if errors (Sumw2) the errors array is resized
8210/// The previous bin contents are lost
8211/// To change only the axis limits, see TAxis::SetRange
8212
8214{
8215 if (GetDimension() != 1) {
8216 Error("SetBins","Operation only valid for 1-d histograms");
8217 return;
8218 }
8219 fXaxis.SetRange(0,0);
8220 fXaxis.Set(nx,xmin,xmax);
8221 fYaxis.Set(1,0,1);
8222 fZaxis.Set(1,0,1);
8223 fNcells = nx+2;
8225 if (fSumw2.fN) {
8227 }
8228}
8229
8230////////////////////////////////////////////////////////////////////////////////
8231/// Redefine x axis parameters with variable bin sizes.
8232///
8233/// The X axis parameters are modified.
8234/// The bins content array is resized
8235/// if errors (Sumw2) the errors array is resized
8236/// The previous bin contents are lost
8237/// To change only the axis limits, see TAxis::SetRange
8238/// xBins is supposed to be of length nx+1
8239
8240void TH1::SetBins(Int_t nx, const Double_t *xBins)
8241{
8242 if (GetDimension() != 1) {
8243 Error("SetBins","Operation only valid for 1-d histograms");
8244 return;
8245 }
8246 fXaxis.SetRange(0,0);
8247 fXaxis.Set(nx,xBins);
8248 fYaxis.Set(1,0,1);
8249 fZaxis.Set(1,0,1);
8250 fNcells = nx+2;
8252 if (fSumw2.fN) {
8254 }
8255}
8256
8257////////////////////////////////////////////////////////////////////////////////
8258/// Redefine x and y axis parameters.
8259///
8260/// The X and Y axis parameters are modified.
8261/// The bins content array is resized
8262/// if errors (Sumw2) the errors array is resized
8263/// The previous bin contents are lost
8264/// To change only the axis limits, see TAxis::SetRange
8265
8267{
8268 if (GetDimension() != 2) {
8269 Error("SetBins","Operation only valid for 2-D histograms");
8270 return;
8271 }
8272 fXaxis.SetRange(0,0);
8273 fYaxis.SetRange(0,0);
8274 fXaxis.Set(nx,xmin,xmax);
8275 fYaxis.Set(ny,ymin,ymax);
8276 fZaxis.Set(1,0,1);
8277 fNcells = (nx+2)*(ny+2);
8279 if (fSumw2.fN) {
8281 }
8282}
8283
8284////////////////////////////////////////////////////////////////////////////////
8285/// Redefine x and y axis parameters with variable bin sizes.
8286///
8287/// The X and Y axis parameters are modified.
8288/// The bins content array is resized
8289/// if errors (Sumw2) the errors array is resized
8290/// The previous bin contents are lost
8291/// To change only the axis limits, see TAxis::SetRange
8292/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
8293
8294void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
8295{
8296 if (GetDimension() != 2) {
8297 Error("SetBins","Operation only valid for 2-D histograms");
8298 return;
8299 }
8300 fXaxis.SetRange(0,0);
8301 fYaxis.SetRange(0,0);
8302 fXaxis.Set(nx,xBins);
8303 fYaxis.Set(ny,yBins);
8304 fZaxis.Set(1,0,1);
8305 fNcells = (nx+2)*(ny+2);
8307 if (fSumw2.fN) {
8309 }
8310}
8311
8312////////////////////////////////////////////////////////////////////////////////
8313/// Redefine x, y and z axis parameters.
8314///
8315/// The X, Y and Z axis parameters are modified.
8316/// The bins content array is resized
8317/// if errors (Sumw2) the errors array is resized
8318/// The previous bin contents are lost
8319/// To change only the axis limits, see TAxis::SetRange
8320
8322{
8323 if (GetDimension() != 3) {
8324 Error("SetBins","Operation only valid for 3-D histograms");
8325 return;
8326 }
8327 fXaxis.SetRange(0,0);
8328 fYaxis.SetRange(0,0);
8329 fZaxis.SetRange(0,0);
8330 fXaxis.Set(nx,xmin,xmax);
8331 fYaxis.Set(ny,ymin,ymax);
8332 fZaxis.Set(nz,zmin,zmax);
8333 fNcells = (nx+2)*(ny+2)*(nz+2);
8335 if (fSumw2.fN) {
8337 }
8338}
8339
8340////////////////////////////////////////////////////////////////////////////////
8341/// Redefine x, y and z axis parameters with variable bin sizes.
8342///
8343/// The X, Y and Z axis parameters are modified.
8344/// The bins content array is resized
8345/// if errors (Sumw2) the errors array is resized
8346/// The previous bin contents are lost
8347/// To change only the axis limits, see TAxis::SetRange
8348/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
8349/// zBins is supposed to be of length nz+1
8350
8351void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
8352{
8353 if (GetDimension() != 3) {
8354 Error("SetBins","Operation only valid for 3-D histograms");
8355 return;
8356 }
8357 fXaxis.SetRange(0,0);
8358 fYaxis.SetRange(0,0);
8359 fZaxis.SetRange(0,0);
8360 fXaxis.Set(nx,xBins);
8361 fYaxis.Set(ny,yBins);
8362 fZaxis.Set(nz,zBins);
8363 fNcells = (nx+2)*(ny+2)*(nz+2);
8365 if (fSumw2.fN) {
8367 }
8368}
8369
8370////////////////////////////////////////////////////////////////////////////////
8371/// By default when an histogram is created, it is added to the list
8372/// of histogram objects in the current directory in memory.
8373/// Remove reference to this histogram from current directory and add
8374/// reference to new directory dir. dir can be 0 in which case the
8375/// histogram does not belong to any directory.
8376///
8377/// Note that the directory is not a real property of the histogram and
8378/// it will not be copied when the histogram is copied or cloned.
8379/// If the user wants to have the copied (cloned) histogram in the same
8380/// directory, he needs to set again the directory using SetDirectory to the
8381/// copied histograms
8382
8384{
8385 if (fDirectory == dir) return;
8386 if (fDirectory) fDirectory->Remove(this);
8387 fDirectory = dir;
8388 if (fDirectory) {
8390 fDirectory->Append(this);
8391 }
8392}
8393
8394////////////////////////////////////////////////////////////////////////////////
8395/// Replace bin errors by values in array error.
8396
8397void TH1::SetError(const Double_t *error)
8398{
8399 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
8400}
8401
8402////////////////////////////////////////////////////////////////////////////////
8403/// Change the name of this histogram
8405
8406void TH1::SetName(const char *name)
8407{
8408 // Histograms are named objects in a THashList.
8409 // We must update the hashlist if we change the name
8410 // We protect this operation
8412 if (fDirectory) fDirectory->Remove(this);
8413 fName = name;
8414 if (fDirectory) fDirectory->Append(this);
8415}
8416
8417////////////////////////////////////////////////////////////////////////////////
8418/// Change the name and title of this histogram
8419
8420void TH1::SetNameTitle(const char *name, const char *title)
8421{
8422 // Histograms are named objects in a THashList.
8423 // We must update the hashlist if we change the name
8424 SetName(name);
8425 SetTitle(title);
8426}
8427
8428////////////////////////////////////////////////////////////////////////////////
8429/// Set statistics option on/off
8430///
8431/// By default, the statistics box is drawn.
8432/// The paint options can be selected via gStyle->SetOptStats.
8433/// This function sets/resets the kNoStats bin in the histogram object.
8434/// It has priority over the Style option.
8435
8436void TH1::SetStats(Bool_t stats)
8437{
8439 if (!stats) {
8441 //remove the "stats" object from the list of functions
8442 if (fFunctions) {
8443 TObject *obj = fFunctions->FindObject("stats");
8444 if (obj) {
8445 fFunctions->Remove(obj);
8446 delete obj;
8447 }
8448 }
8449 }
8450}
8451
8452////////////////////////////////////////////////////////////////////////////////
8453/// Create structure to store sum of squares of weights.
8454///
8455/// if histogram is already filled, the sum of squares of weights
8456/// is filled with the existing bin contents
8457///
8458/// The error per bin will be computed as sqrt(sum of squares of weight)
8459/// for each bin.
8460///
8461/// This function is automatically called when the histogram is created
8462/// if the static function TH1::SetDefaultSumw2 has been called before.
8463/// If flag = false the structure containing the sum of the square of weights
8464/// is rest and it will be empty, but it is not deleted (i.e. GetSumw2()->fN = 0)
8465
8466void TH1::Sumw2(Bool_t flag)
8467{
8468 if (!flag) {
8469 // clear the array if existing - do nothing otherwise
8470 if (fSumw2.fN > 0 ) fSumw2.Set(0);
8471 return;
8472 }
8473
8474 if (fSumw2.fN == fNcells) {
8475 if (!fgDefaultSumw2 )
8476 Warning("Sumw2","Sum of squares of weights structure already created");
8477 return;
8478 }
8479
8481
8482 // empty the buffer
8483 if (fBuffer) BufferEmpty();
8484
8485 if (fEntries > 0)
8486 for (Int_t i = 0; i < fNcells; ++i)
8488}
8489
8490////////////////////////////////////////////////////////////////////////////////
8491/// Return pointer to function with name.
8492///
8493///
8494/// Functions such as TH1::Fit store the fitted function in the list of
8495/// functions of this histogram.
8496
8497TF1 *TH1::GetFunction(const char *name) const
8498{
8499 return (TF1*)fFunctions->FindObject(name);
8500}
8501
8502////////////////////////////////////////////////////////////////////////////////
8503/// Return value of error associated to bin number bin.
8504///
8505/// if the sum of squares of weights has been defined (via Sumw2),
8506/// this function returns the sqrt(sum of w2).
8507/// otherwise it returns the sqrt(contents) for this bin.
8508
8510{
8511 if (bin < 0) bin = 0;
8512 if (bin >= fNcells) bin = fNcells-1;
8513 if (fBuffer) ((TH1*)this)->BufferEmpty();
8514 if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
8515
8517}
8518
8519////////////////////////////////////////////////////////////////////////////////
8520/// Return lower error associated to bin number bin.
8521///
8522/// The error will depend on the statistic option used will return
8523/// the binContent - lower interval value
8524
8526{
8527 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
8528 // in case of weighted histogram check if it is really weighted
8529 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
8530
8531 if (bin < 0) bin = 0;
8532 if (bin >= fNcells) bin = fNcells-1;
8533 if (fBuffer) ((TH1*)this)->BufferEmpty();
8534
8535 Double_t alpha = 1.- 0.682689492;
8536 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
8537
8539 Int_t n = int(c);
8540 if (n < 0) {
8541 Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
8542 ((TH1*)this)->fBinStatErrOpt = kNormal;
8543 return GetBinError(bin);
8544 }
8545
8546 if (n == 0) return 0;
8547 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
8548}
8549
8550////////////////////////////////////////////////////////////////////////////////
8551/// Return upper error associated to bin number bin.
8552///
8553/// The error will depend on the statistic option used will return
8554/// the binContent - upper interval value
8555
8557{
8558 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
8559 // in case of weighted histogram check if it is really weighted
8560 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
8561 if (bin < 0) bin = 0;
8562 if (bin >= fNcells) bin = fNcells-1;
8563 if (fBuffer) ((TH1*)this)->BufferEmpty();
8564
8565 Double_t alpha = 1.- 0.682689492;
8566 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
8567
8569 Int_t n = int(c);
8570 if (n < 0) {
8571 Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
8572 ((TH1*)this)->fBinStatErrOpt = kNormal;
8573 return GetBinError(bin);
8574 }
8575
8576 // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
8577 // decide to return always (1-alpha)/2 upper interval
8578 //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
8579 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
8580}
8581
8582//L.M. These following getters are useless and should be probably deprecated
8583////////////////////////////////////////////////////////////////////////////////
8584/// Return bin center for 1D histogram.
8585/// Better to use h1.GetXaxis().GetBinCenter(bin)
8586
8588{
8589 if (fDimension == 1) return fXaxis.GetBinCenter(bin);
8590 Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
8591 return TMath::QuietNaN();
8592}
8593
8594////////////////////////////////////////////////////////////////////////////////
8595/// Return bin lower edge for 1D histogram.
8596/// Better to use h1.GetXaxis().GetBinLowEdge(bin)
8597
8599{
8600 if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
8601 Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
8602 return TMath::QuietNaN();
8603}
8604
8605////////////////////////////////////////////////////////////////////////////////
8606/// Return bin width for 1D histogram.
8607/// Better to use h1.GetXaxis().GetBinWidth(bin)
8608
8610{
8611 if (fDimension == 1) return fXaxis.GetBinWidth(bin);
8612 Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
8613 return TMath::QuietNaN();
8614}
8615
8616////////////////////////////////////////////////////////////////////////////////
8617/// Fill array with center of bins for 1D histogram
8618/// Better to use h1.GetXaxis().GetCenter(center)
8619
8620void TH1::GetCenter(Double_t *center) const
8621{
8622 if (fDimension == 1) {
8623 fXaxis.GetCenter(center);
8624 return;
8625 }
8626 Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
8627}
8628
8629////////////////////////////////////////////////////////////////////////////////
8630/// Fill array with low edge of bins for 1D histogram
8631/// Better to use h1.GetXaxis().GetLowEdge(edge)
8632
8633void TH1::GetLowEdge(Double_t *edge) const
8634{
8635 if (fDimension == 1) {
8636 fXaxis.GetLowEdge(edge);
8637 return;
8638 }
8639 Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
8640}
8641
8642////////////////////////////////////////////////////////////////////////////////
8643/// Set the bin Error
8644/// Note that this resets the bin eror option to be of Normal Type and for the
8645/// non-empty bin the bin error is set by default to the square root of their content.
8646/// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
8647/// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
8648/// will not recalcualated after setting the content and a default error = 0 will be used for those bins.
8649///
8650/// See convention for numbering bins in TH1::GetBin
8651
8652void TH1::SetBinError(Int_t bin, Double_t error)
8653{
8654 if (bin < 0 || bin>= fNcells) return;
8655 if (!fSumw2.fN) Sumw2();
8656 fSumw2.fArray[bin] = error * error;
8657 // reset the bin error option
8659}
8660
8661////////////////////////////////////////////////////////////////////////////////
8662/// Set bin content
8663/// see convention for numbering bins in TH1::GetBin
8664/// In case the bin number is greater than the number of bins and
8665/// the timedisplay option is set or CanExtendAllAxes(),
8666/// the number of bins is automatically doubled to accommodate the new bin
8667
8668void TH1::SetBinContent(Int_t bin, Double_t content)
8669{
8670 fEntries++;
8671 fTsumw = 0;
8672 if (bin < 0) return;
8673 if (bin >= fNcells-1) {
8675 while (bin >= fNcells-1) LabelsInflate();
8676 } else {
8677 if (bin == fNcells-1) UpdateBinContent(bin, content);
8678 return;
8679 }
8680 }
8681 UpdateBinContent(bin, content);
8682}
8683
8684////////////////////////////////////////////////////////////////////////////////
8685/// See convention for numbering bins in TH1::GetBin
8686
8687void TH1::SetBinError(Int_t binx, Int_t biny, Double_t error)
8688{
8689 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
8690 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
8691 SetBinError(GetBin(binx, biny), error);
8692}
8693
8694////////////////////////////////////////////////////////////////////////////////
8695/// See convention for numbering bins in TH1::GetBin
8696
8697void TH1::SetBinError(Int_t binx, Int_t biny, Int_t binz, Double_t error)
8698{
8699 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
8700 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
8701 if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
8702 SetBinError(GetBin(binx, biny, binz), error);
8703}
8704
8705////////////////////////////////////////////////////////////////////////////////
8706/// This function calculates the background spectrum in this histogram.
8707/// The background is returned as a histogram.
8708///
8709/// \param[in] niter number of iterations (default value = 2)
8710/// Increasing niter make the result smoother and lower.
8711/// \param[in] option may contain one of the following options
8712/// - to set the direction parameter
8713/// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
8714/// - filterOrder-order of clipping filter (default "BackOrder2")
8715/// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
8716/// - "nosmoothing" - if selected, the background is not smoothed
8717/// By default the background is smoothed.
8718/// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
8719/// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
8720/// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
8721/// - "nocompton" - if selected the estimation of Compton edge
8722/// will be not be included (by default the compton estimation is set)
8723/// - "same" if this option is specified, the resulting background
8724/// histogram is superimposed on the picture in the current pad.
8725/// This option is given by default.
8726///
8727/// NOTE that the background is only evaluated in the current range of this histogram.
8728/// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
8729/// the returned histogram will be created with the same number of bins
8730/// as this input histogram, but only bins from binmin to binmax will be filled
8731/// with the estimated background.
8732
8733TH1 *TH1::ShowBackground(Int_t niter, Option_t *option)
8734{
8735
8736 return (TH1*)gROOT->ProcessLineFast(Form("TSpectrum::StaticBackground((TH1*)0x%lx,%d,\"%s\")",
8737 (ULong_t)this, niter, option));
8738}
8739
8740////////////////////////////////////////////////////////////////////////////////
8741/// Interface to TSpectrum::Search.
8742/// The function finds peaks in this histogram where the width is > sigma
8743/// and the peak maximum greater than threshold*maximum bin content of this.
8744/// For more details see TSpectrum::Search.
8745/// Note the difference in the default value for option compared to TSpectrum::Search
8746/// option="" by default (instead of "goff").
8747
8749{
8750 return (Int_t)gROOT->ProcessLineFast(Form("TSpectrum::StaticSearch((TH1*)0x%lx,%g,\"%s\",%g)",
8751 (ULong_t)this, sigma, option, threshold));
8752}
8753
8754////////////////////////////////////////////////////////////////////////////////
8755/// For a given transform (first parameter), fills the histogram (second parameter)
8756/// with the transform output data, specified in the third parameter
8757/// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
8758/// and the user is responsible for deleting it.
8759///
8760/// Available options:
8761/// - "RE" - real part of the output
8762/// - "IM" - imaginary part of the output
8763/// - "MAG" - magnitude of the output
8764/// - "PH" - phase of the output
8765
8766TH1* TH1::TransformHisto(TVirtualFFT *fft, TH1* h_output, Option_t *option)
8767{
8768 if (!fft || !fft->GetN() ) {
8769 ::Error("TransformHisto","Invalid FFT transform class");
8770 return 0;
8771 }
8772
8773 if (fft->GetNdim()>2){
8774 ::Error("TransformHisto","Only 1d and 2D transform are supported");
8775 return 0;
8776 }
8777 Int_t binx,biny;
8778 TString opt = option;
8779 opt.ToUpper();
8780 Int_t *n = fft->GetN();
8781 TH1 *hout=0;
8782 if (h_output) {
8783 hout = h_output;
8784 }
8785 else {
8786 TString name = TString::Format("out_%s", opt.Data());
8787 if (fft->GetNdim()==1)
8788 hout = new TH1D(name, name,n[0], 0, n[0]);
8789 else if (fft->GetNdim()==2)
8790 hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
8791 }
8792 R__ASSERT(hout != 0);
8793 TString type=fft->GetType();
8794 Int_t ind[2];
8795 if (opt.Contains("RE")){
8796 if (type.Contains("2C") || type.Contains("2HC")) {
8797 Double_t re, im;
8798 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8799 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8800 ind[0] = binx-1; ind[1] = biny-1;
8801 fft->GetPointComplex(ind, re, im);
8802 hout->SetBinContent(binx, biny, re);
8803 }
8804 }
8805 } else {
8806 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8807 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8808 ind[0] = binx-1; ind[1] = biny-1;
8809 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
8810 }
8811 }
8812 }
8813 }
8814 if (opt.Contains("IM")) {
8815 if (type.Contains("2C") || type.Contains("2HC")) {
8816 Double_t re, im;
8817 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8818 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8819 ind[0] = binx-1; ind[1] = biny-1;
8820 fft->GetPointComplex(ind, re, im);
8821 hout->SetBinContent(binx, biny, im);
8822 }
8823 }
8824 } else {
8825 ::Error("TransformHisto","No complex numbers in the output");
8826 return 0;
8827 }
8828 }
8829 if (opt.Contains("MA")) {
8830 if (type.Contains("2C") || type.Contains("2HC")) {
8831 Double_t re, im;
8832 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8833 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8834 ind[0] = binx-1; ind[1] = biny-1;
8835 fft->GetPointComplex(ind, re, im);
8836 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
8837 }
8838 }
8839 } else {
8840 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8841 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8842 ind[0] = binx-1; ind[1] = biny-1;
8843 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
8844 }
8845 }
8846 }
8847 }
8848 if (opt.Contains("PH")) {
8849 if (type.Contains("2C") || type.Contains("2HC")){
8850 Double_t re, im, ph;
8851 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
8852 for (biny=1; biny<=hout->GetNbinsY(); biny++){
8853 ind[0] = binx-1; ind[1] = biny-1;
8854 fft->GetPointComplex(ind, re, im);
8855 if (TMath::Abs(re) > 1e-13){
8856 ph = TMath::ATan(im/re);
8857 //find the correct quadrant
8858 if (re<0 && im<0)
8859 ph -= TMath::Pi();
8860 if (re<0 && im>=0)
8861 ph += TMath::Pi();
8862 } else {
8863 if (TMath::Abs(im) < 1e-13)
8864 ph = 0;
8865 else if (im>0)
8866 ph = TMath::Pi()*0.5;
8867 else
8868 ph = -TMath::Pi()*0.5;
8869 }
8870 hout->SetBinContent(binx, biny, ph);
8871 }
8872 }
8873 } else {
8874 printf("Pure real output, no phase");
8875 return 0;
8876 }
8877 }
8878
8879 return hout;
8880}
8881
8882////////////////////////////////////////////////////////////////////////////////
8883/// Raw retrieval of bin content on internal data structure
8884/// see convention for numbering bins in TH1::GetBin
8885
8887{
8888 AbstractMethod("RetrieveBinContent");
8889 return 0;
8890}
8891
8892////////////////////////////////////////////////////////////////////////////////
8893/// Raw update of bin content on internal data structure
8894/// see convention for numbering bins in TH1::GetBin
8895
8897{
8898 AbstractMethod("UpdateBinContent");
8899}
8900
8901////////////////////////////////////////////////////////////////////////////////
8902/// Print value overload
8903
8904std::string cling::printValue(TH1 *val) {
8905 std::ostringstream strm;
8906 strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
8907 return strm.str();
8908}
8909
8910//______________________________________________________________________________
8911// TH1C methods
8912// TH1C : histograms with one byte per channel. Maximum bin content = 127
8913//______________________________________________________________________________
8914
8915ClassImp(TH1C);
8916
8917////////////////////////////////////////////////////////////////////////////////
8918/// Constructor.
8919
8920TH1C::TH1C(): TH1(), TArrayC()
8921{
8922 fDimension = 1;
8923 SetBinsLength(3);
8924 if (fgDefaultSumw2) Sumw2();
8925}
8926
8927////////////////////////////////////////////////////////////////////////////////
8928/// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
8929/// (see TH1::TH1 for explanation of parameters)
8930
8931TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
8932: TH1(name,title,nbins,xlow,xup)
8933{
8934 fDimension = 1;
8936
8937 if (xlow >= xup) SetBuffer(fgBufferSize);
8938 if (fgDefaultSumw2) Sumw2();
8939}
8940
8941////////////////////////////////////////////////////////////////////////////////
8942/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
8943/// (see TH1::TH1 for explanation of parameters)
8944
8945TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
8946: TH1(name,title,nbins,xbins)
8947{
8948 fDimension = 1;
8950 if (fgDefaultSumw2) Sumw2();
8951}
8952
8953////////////////////////////////////////////////////////////////////////////////
8954/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
8955/// (see TH1::TH1 for explanation of parameters)
8956
8957TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
8958: TH1(name,title,nbins,xbins)
8959{
8960 fDimension = 1;
8962 if (fgDefaultSumw2) Sumw2();
8963}
8964
8965////////////////////////////////////////////////////////////////////////////////
8966/// Destructor.
8967
8969{
8970}
8971
8972////////////////////////////////////////////////////////////////////////////////
8973/// Copy constructor.
8974
8975TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
8976{
8977 ((TH1C&)h1c).Copy(*this);
8978}
8979
8980////////////////////////////////////////////////////////////////////////////////
8981/// Increment bin content by 1.
8982
8983void TH1C::AddBinContent(Int_t bin)
8984{
8985 if (fArray[bin] < 127) fArray[bin]++;
8986}
8987
8988////////////////////////////////////////////////////////////////////////////////
8989/// Increment bin content by w.
8990
8992{
8993 Int_t newval = fArray[bin] + Int_t(w);
8994 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
8995 if (newval < -127) fArray[bin] = -127;
8996 if (newval > 127) fArray[bin] = 127;
8997}
8998
8999////////////////////////////////////////////////////////////////////////////////
9000/// Copy this to newth1
9001
9002void TH1C::Copy(TObject &newth1) const
9003{
9004 TH1::Copy(newth1);
9005}
9006
9007////////////////////////////////////////////////////////////////////////////////
9008/// Reset.
9009
9010void TH1C::Reset(Option_t *option)
9011{
9012 TH1::Reset(option);
9014}
9015
9016////////////////////////////////////////////////////////////////////////////////
9017/// Set total number of bins including under/overflow
9018/// Reallocate bin contents array
9019
9021{
9022 if (n < 0) n = fXaxis.GetNbins() + 2;
9023 fNcells = n;
9024 TArrayC::Set(n);
9025}
9026
9027////////////////////////////////////////////////////////////////////////////////
9028/// Operator =
9029
9030TH1C& TH1C::operator=(const TH1C &h1)
9031{
9032 if (this != &h1) ((TH1C&)h1).Copy(*this);
9033 return *this;
9034}
9035
9036////////////////////////////////////////////////////////////////////////////////
9037/// Operator *
9038
9040{
9041 TH1C hnew = h1;
9042 hnew.Scale(c1);
9043 hnew.SetDirectory(0);
9044 return hnew;
9045}
9046
9047////////////////////////////////////////////////////////////////////////////////
9048/// Operator +
9049
9050TH1C operator+(const TH1C &h1, const TH1C &h2)
9051{
9052 TH1C hnew = h1;
9053 hnew.Add(&h2,1);
9054 hnew.SetDirectory(0);
9055 return hnew;
9056}
9057
9058////////////////////////////////////////////////////////////////////////////////
9059/// Operator -
9060
9061TH1C operator-(const TH1C &h1, const TH1C &h2)
9062{
9063 TH1C hnew = h1;
9064 hnew.Add(&h2,-1);
9065 hnew.SetDirectory(0);
9066 return hnew;
9067}
9068
9069////////////////////////////////////////////////////////////////////////////////
9070/// Operator *
9071
9072TH1C operator*(const TH1C &h1, const TH1C &h2)
9073{
9074 TH1C hnew = h1;
9075 hnew.Multiply(&h2);
9076 hnew.SetDirectory(0);
9077 return hnew;
9078}
9079
9080////////////////////////////////////////////////////////////////////////////////
9081/// Operator /
9082
9083TH1C operator/(const TH1C &h1, const TH1C &h2)
9084{
9085 TH1C hnew = h1;
9086 hnew.Divide(&h2);
9087 hnew.SetDirectory(0);
9088 return hnew;
9089}
9090
9091//______________________________________________________________________________
9092// TH1S methods
9093// TH1S : histograms with one short per channel. Maximum bin content = 32767
9094//______________________________________________________________________________
9095
9096ClassImp(TH1S);
9097
9098////////////////////////////////////////////////////////////////////////////////
9099/// Constructor.
9100
9101TH1S::TH1S(): TH1(), TArrayS()
9102{
9103 fDimension = 1;
9104 SetBinsLength(3);
9105 if (fgDefaultSumw2) Sumw2();
9106}
9107
9108////////////////////////////////////////////////////////////////////////////////
9109/// Create a 1-Dim histogram with fix bins of type short
9110/// (see TH1::TH1 for explanation of parameters)
9111
9112TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9113: TH1(name,title,nbins,xlow,xup)
9114{
9115 fDimension = 1;
9117
9118 if (xlow >= xup) SetBuffer(fgBufferSize);
9119 if (fgDefaultSumw2) Sumw2();
9120}
9121
9122////////////////////////////////////////////////////////////////////////////////
9123/// Create a 1-Dim histogram with variable bins of type short
9124/// (see TH1::TH1 for explanation of parameters)
9125
9126TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9127: TH1(name,title,nbins,xbins)
9128{
9129 fDimension = 1;
9131 if (fgDefaultSumw2) Sumw2();
9132}
9133
9134////////////////////////////////////////////////////////////////////////////////
9135/// Create a 1-Dim histogram with variable bins of type short
9136/// (see TH1::TH1 for explanation of parameters)
9137
9138TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9139: TH1(name,title,nbins,xbins)
9140{
9141 fDimension = 1;
9143 if (fgDefaultSumw2) Sumw2();
9144}
9145
9146////////////////////////////////////////////////////////////////////////////////
9147/// Destructor.
9148
9150{
9151}
9152
9153////////////////////////////////////////////////////////////////////////////////
9154/// Copy constructor.
9155
9156TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9157{
9158 ((TH1S&)h1s).Copy(*this);
9159}
9160
9161////////////////////////////////////////////////////////////////////////////////
9162/// Increment bin content by 1.
9163
9164void TH1S::AddBinContent(Int_t bin)
9165{
9166 if (fArray[bin] < 32767) fArray[bin]++;
9167}
9168
9169////////////////////////////////////////////////////////////////////////////////
9170/// Increment bin content by w
9171
9173{
9174 Int_t newval = fArray[bin] + Int_t(w);
9175 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9176 if (newval < -32767) fArray[bin] = -32767;
9177 if (newval > 32767) fArray[bin] = 32767;
9178}
9179
9180////////////////////////////////////////////////////////////////////////////////
9181/// Copy this to newth1
9182
9183void TH1S::Copy(TObject &newth1) const
9184{
9185 TH1::Copy(newth1);
9186}
9187
9188////////////////////////////////////////////////////////////////////////////////
9189/// Reset.
9190
9191void TH1S::Reset(Option_t *option)
9192{
9193 TH1::Reset(option);
9195}
9196
9197////////////////////////////////////////////////////////////////////////////////
9198/// Set total number of bins including under/overflow
9199/// Reallocate bin contents array
9200
9202{
9203 if (n < 0) n = fXaxis.GetNbins() + 2;
9204 fNcells = n;
9205 TArrayS::Set(n);
9206}
9207
9208////////////////////////////////////////////////////////////////////////////////
9209/// Operator =
9210
9211TH1S& TH1S::operator=(const TH1S &h1)
9212{
9213 if (this != &h1) ((TH1S&)h1).Copy(*this);
9214 return *this;
9215}
9216
9217////////////////////////////////////////////////////////////////////////////////
9218/// Operator *
9219
9221{
9222 TH1S hnew = h1;
9223 hnew.Scale(c1);
9224 hnew.SetDirectory(0);
9225 return hnew;
9226}
9227
9228////////////////////////////////////////////////////////////////////////////////
9229/// Operator +
9230
9231TH1S operator+(const TH1S &h1, const TH1S &h2)
9232{
9233 TH1S hnew = h1;
9234 hnew.Add(&h2,1);
9235 hnew.SetDirectory(0);
9236 return hnew;
9237}
9238
9239////////////////////////////////////////////////////////////////////////////////
9240/// Operator -
9241
9242TH1S operator-(const TH1S &h1, const TH1S &h2)
9243{
9244 TH1S hnew = h1;
9245 hnew.Add(&h2,-1);
9246 hnew.SetDirectory(0);
9247 return hnew;
9248}
9249
9250////////////////////////////////////////////////////////////////////////////////
9251/// Operator *
9252
9253TH1S operator*(const TH1S &h1, const TH1S &h2)
9254{
9255 TH1S hnew = h1;
9256 hnew.Multiply(&h2);
9257 hnew.SetDirectory(0);
9258 return hnew;
9259}
9260
9261////////////////////////////////////////////////////////////////////////////////
9262/// Operator /
9263
9264TH1S operator/(const TH1S &h1, const TH1S &h2)
9265{
9266 TH1S hnew = h1;
9267 hnew.Divide(&h2);
9268 hnew.SetDirectory(0);
9269 return hnew;
9270}
9271
9272//______________________________________________________________________________
9273// TH1I methods
9274// TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9275//______________________________________________________________________________
9276
9277ClassImp(TH1I);
9278
9279////////////////////////////////////////////////////////////////////////////////
9280/// Constructor.
9281
9282TH1I::TH1I(): TH1(), TArrayI()
9283{
9284 fDimension = 1;
9285 SetBinsLength(3);
9286 if (fgDefaultSumw2) Sumw2();
9287}
9288
9289////////////////////////////////////////////////////////////////////////////////
9290/// Create a 1-Dim histogram with fix bins of type integer
9291/// (see TH1::TH1 for explanation of parameters)
9292
9293TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9294: TH1(name,title,nbins,xlow,xup)
9295{
9296 fDimension = 1;
9298
9299 if (xlow >= xup) SetBuffer(fgBufferSize);
9300 if (fgDefaultSumw2) Sumw2();
9301}
9302
9303////////////////////////////////////////////////////////////////////////////////
9304/// Create a 1-Dim histogram with variable bins of type integer
9305/// (see TH1::TH1 for explanation of parameters)
9306
9307TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9308: TH1(name,title,nbins,xbins)
9309{
9310 fDimension = 1;
9312 if (fgDefaultSumw2) Sumw2();
9313}
9314
9315////////////////////////////////////////////////////////////////////////////////
9316/// Create a 1-Dim histogram with variable bins of type integer
9317/// (see TH1::TH1 for explanation of parameters)
9318
9319TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9320: TH1(name,title,nbins,xbins)
9321{
9322 fDimension = 1;
9324 if (fgDefaultSumw2) Sumw2();
9325}
9326
9327////////////////////////////////////////////////////////////////////////////////
9328/// Destructor.
9329
9331{
9332}
9333
9334////////////////////////////////////////////////////////////////////////////////
9335/// Copy constructor.
9336
9337TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
9338{
9339 ((TH1I&)h1i).Copy(*this);
9340}
9341
9342////////////////////////////////////////////////////////////////////////////////
9343/// Increment bin content by 1.
9344
9345void TH1I::AddBinContent(Int_t bin)
9346{
9347 if (fArray[bin] < 2147483647) fArray[bin]++;
9348}
9349
9350////////////////////////////////////////////////////////////////////////////////
9351/// Increment bin content by w
9352
9354{
9355 Long64_t newval = fArray[bin] + Long64_t(w);
9356 if (newval > -2147483647 && newval < 2147483647) {fArray[bin] = Int_t(newval); return;}
9357 if (newval < -2147483647) fArray[bin] = -2147483647;
9358 if (newval > 2147483647) fArray[bin] = 2147483647;
9359}
9360
9361////////////////////////////////////////////////////////////////////////////////
9362/// Copy this to newth1
9363
9364void TH1I::Copy(TObject &newth1) const
9365{
9366 TH1::Copy(newth1);
9367}
9368
9369////////////////////////////////////////////////////////////////////////////////
9370/// Reset.
9371
9372void TH1I::Reset(Option_t *option)
9373{
9374 TH1::Reset(option);
9376}
9377
9378////////////////////////////////////////////////////////////////////////////////
9379/// Set total number of bins including under/overflow
9380/// Reallocate bin contents array
9381
9383{
9384 if (n < 0) n = fXaxis.GetNbins() + 2;
9385 fNcells = n;
9386 TArrayI::Set(n);
9387}
9388
9389////////////////////////////////////////////////////////////////////////////////
9390/// Operator =
9391
9392TH1I& TH1I::operator=(const TH1I &h1)
9393{
9394 if (this != &h1) ((TH1I&)h1).Copy(*this);
9395 return *this;
9396}
9397
9398
9399////////////////////////////////////////////////////////////////////////////////
9400/// Operator *
9401
9403{
9404 TH1I hnew = h1;
9405 hnew.Scale(c1);
9406 hnew.SetDirectory(0);
9407 return hnew;
9408}
9409
9410////////////////////////////////////////////////////////////////////////////////
9411/// Operator +
9412
9413TH1I operator+(const TH1I &h1, const TH1I &h2)
9414{
9415 TH1I hnew = h1;
9416 hnew.Add(&h2,1);
9417 hnew.SetDirectory(0);
9418 return hnew;
9419}
9420
9421////////////////////////////////////////////////////////////////////////////////
9422/// Operator -
9423
9424TH1I operator-(const TH1I &h1, const TH1I &h2)
9425{
9426 TH1I hnew = h1;
9427 hnew.Add(&h2,-1);
9428 hnew.SetDirectory(0);
9429 return hnew;
9430}
9431
9432////////////////////////////////////////////////////////////////////////////////
9433/// Operator *
9434
9435TH1I operator*(const TH1I &h1, const TH1I &h2)
9436{
9437 TH1I hnew = h1;
9438 hnew.Multiply(&h2);
9439 hnew.SetDirectory(0);
9440 return hnew;
9441}
9442
9443////////////////////////////////////////////////////////////////////////////////
9444/// Operator /
9445
9446TH1I operator/(const TH1I &h1, const TH1I &h2)
9447{
9448 TH1I hnew = h1;
9449 hnew.Divide(&h2);
9450 hnew.SetDirectory(0);
9451 return hnew;
9452}
9453
9454//______________________________________________________________________________
9455// TH1F methods
9456// TH1F : histograms with one float per channel. Maximum precision 7 digits
9457//______________________________________________________________________________
9458
9459ClassImp(TH1F);
9460
9461////////////////////////////////////////////////////////////////////////////////
9462/// Constructor.
9463
9464TH1F::TH1F(): TH1(), TArrayF()
9465{
9466 fDimension = 1;
9467 SetBinsLength(3);
9468 if (fgDefaultSumw2) Sumw2();
9469}
9470
9471////////////////////////////////////////////////////////////////////////////////
9472/// Create a 1-Dim histogram with fix bins of type float
9473/// (see TH1::TH1 for explanation of parameters)
9474
9475TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9476: TH1(name,title,nbins,xlow,xup)
9477{
9478 fDimension = 1;
9480
9481 if (xlow >= xup) SetBuffer(fgBufferSize);
9482 if (fgDefaultSumw2) Sumw2();
9483}
9484
9485////////////////////////////////////////////////////////////////////////////////
9486/// Create a 1-Dim histogram with variable bins of type float
9487/// (see TH1::TH1 for explanation of parameters)
9488
9489TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9490: TH1(name,title,nbins,xbins)
9491{
9492 fDimension = 1;
9494 if (fgDefaultSumw2) Sumw2();
9495}
9496
9497////////////////////////////////////////////////////////////////////////////////
9498/// Create a 1-Dim histogram with variable bins of type float
9499/// (see TH1::TH1 for explanation of parameters)
9500
9501TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9502: TH1(name,title,nbins,xbins)
9503{
9504 fDimension = 1;
9506 if (fgDefaultSumw2) Sumw2();
9507}
9508
9509////////////////////////////////////////////////////////////////////////////////
9510/// Create a histogram from a TVectorF
9511/// by default the histogram name is "TVectorF" and title = ""
9512
9513TH1F::TH1F(const TVectorF &v)
9514: TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
9515{
9517 fDimension = 1;
9518 Int_t ivlow = v.GetLwb();
9519 for (Int_t i=0;i<fNcells-2;i++) {
9520 SetBinContent(i+1,v(i+ivlow));
9521 }
9523 if (fgDefaultSumw2) Sumw2();
9524}
9525
9526////////////////////////////////////////////////////////////////////////////////
9527/// Copy Constructor.
9528
9529TH1F::TH1F(const TH1F &h) : TH1(), TArrayF()
9530{
9531 ((TH1F&)h).Copy(*this);
9532}
9533
9534////////////////////////////////////////////////////////////////////////////////
9535/// Destructor.
9536
9538{
9539}
9540
9541////////////////////////////////////////////////////////////////////////////////
9542/// Copy this to newth1.
9543
9544void TH1F::Copy(TObject &newth1) const
9545{
9546 TH1::Copy(newth1);
9547}
9548
9549////////////////////////////////////////////////////////////////////////////////
9550/// Reset.
9551
9552void TH1F::Reset(Option_t *option)
9553{
9554 TH1::Reset(option);
9556}
9557
9558////////////////////////////////////////////////////////////////////////////////
9559/// Set total number of bins including under/overflow
9560/// Reallocate bin contents array
9561
9563{
9564 if (n < 0) n = fXaxis.GetNbins() + 2;
9565 fNcells = n;
9566 TArrayF::Set(n);
9567}
9568
9569////////////////////////////////////////////////////////////////////////////////
9570/// Operator =
9571
9572TH1F& TH1F::operator=(const TH1F &h1)
9573{
9574 if (this != &h1) ((TH1F&)h1).Copy(*this);
9575 return *this;
9576}
9577
9578////////////////////////////////////////////////////////////////////////////////
9579/// Operator *
9580
9582{
9583 TH1F hnew = h1;
9584 hnew.Scale(c1);
9585 hnew.SetDirectory(0);
9586 return hnew;
9587}
9588
9589////////////////////////////////////////////////////////////////////////////////
9590/// Operator +
9591
9592TH1F operator+(const TH1F &h1, const TH1F &h2)
9593{
9594 TH1F hnew = h1;
9595 hnew.Add(&h2,1);
9596 hnew.SetDirectory(0);
9597 return hnew;
9598}
9599
9600////////////////////////////////////////////////////////////////////////////////
9601/// Operator -
9602
9603TH1F operator-(const TH1F &h1, const TH1F &h2)
9604{
9605 TH1F hnew = h1;
9606 hnew.Add(&h2,-1);
9607 hnew.SetDirectory(0);
9608 return hnew;
9609}
9610
9611////////////////////////////////////////////////////////////////////////////////
9612/// Operator *
9613
9614TH1F operator*(const TH1F &h1, const TH1F &h2)
9615{
9616 TH1F hnew = h1;
9617 hnew.Multiply(&h2);
9618 hnew.SetDirectory(0);
9619 return hnew;
9620}
9621
9622////////////////////////////////////////////////////////////////////////////////
9623/// Operator /
9624
9625TH1F operator/(const TH1F &h1, const TH1F &h2)
9626{
9627 TH1F hnew = h1;
9628 hnew.Divide(&h2);
9629 hnew.SetDirectory(0);
9630 return hnew;
9631}
9632
9633//______________________________________________________________________________
9634// TH1D methods
9635// TH1D : histograms with one double per channel. Maximum precision 14 digits
9636//______________________________________________________________________________
9637
9638ClassImp(TH1D);
9639
9640////////////////////////////////////////////////////////////////////////////////
9641/// Constructor.
9642
9643TH1D::TH1D(): TH1(), TArrayD()
9644{
9645 fDimension = 1;
9646 SetBinsLength(3);
9647 if (fgDefaultSumw2) Sumw2();
9648}
9649
9650////////////////////////////////////////////////////////////////////////////////
9651/// Create a 1-Dim histogram with fix bins of type double
9652/// (see TH1::TH1 for explanation of parameters)
9653
9654TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9655: TH1(name,title,nbins,xlow,xup)
9656{
9657 fDimension = 1;
9659
9660 if (xlow >= xup) SetBuffer(fgBufferSize);
9661 if (fgDefaultSumw2) Sumw2();
9662}
9663
9664////////////////////////////////////////////////////////////////////////////////
9665/// Create a 1-Dim histogram with variable bins of type double
9666/// (see TH1::TH1 for explanation of parameters)
9667
9668TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9669: TH1(name,title,nbins,xbins)
9670{
9671 fDimension = 1;
9673 if (fgDefaultSumw2) Sumw2();
9674}
9675
9676////////////////////////////////////////////////////////////////////////////////
9677/// Create a 1-Dim histogram with variable bins of type double
9678/// (see TH1::TH1 for explanation of parameters)
9679
9680TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9681: TH1(name,title,nbins,xbins)
9682{
9683 fDimension = 1;
9685 if (fgDefaultSumw2) Sumw2();
9686}
9687
9688////////////////////////////////////////////////////////////////////////////////
9689/// Create a histogram from a TVectorD
9690/// by default the histogram name is "TVectorD" and title = ""
9691
9692TH1D::TH1D(const TVectorD &v)
9693: TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
9694{
9696 fDimension = 1;
9697 Int_t ivlow = v.GetLwb();
9698 for (Int_t i=0;i<fNcells-2;i++) {
9699 SetBinContent(i+1,v(i+ivlow));
9700 }
9702 if (fgDefaultSumw2) Sumw2();
9703}
9704
9705////////////////////////////////////////////////////////////////////////////////
9706/// Destructor.
9707
9709{
9710}
9711
9712////////////////////////////////////////////////////////////////////////////////
9713/// Constructor.
9714
9715TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
9716{
9717 ((TH1D&)h1d).Copy(*this);
9718}
9719
9720////////////////////////////////////////////////////////////////////////////////
9721/// Copy this to newth1
9722
9723void TH1D::Copy(TObject &newth1) const
9724{
9725 TH1::Copy(newth1);
9726}
9727
9728////////////////////////////////////////////////////////////////////////////////
9729/// Reset.
9730
9731void TH1D::Reset(Option_t *option)
9732{
9733 TH1::Reset(option);
9735}
9736
9737////////////////////////////////////////////////////////////////////////////////
9738/// Set total number of bins including under/overflow
9739/// Reallocate bin contents array
9740
9742{
9743 if (n < 0) n = fXaxis.GetNbins() + 2;
9744 fNcells = n;
9745 TArrayD::Set(n);
9746}
9747
9748////////////////////////////////////////////////////////////////////////////////
9749/// Operator =
9750
9751TH1D& TH1D::operator=(const TH1D &h1)
9752{
9753 if (this != &h1) ((TH1D&)h1).Copy(*this);
9754 return *this;
9755}
9756
9757////////////////////////////////////////////////////////////////////////////////
9758/// Operator *
9759
9761{
9762 TH1D hnew = h1;
9763 hnew.Scale(c1);
9764 hnew.SetDirectory(0);
9765 return hnew;
9766}
9767
9768////////////////////////////////////////////////////////////////////////////////
9769/// Operator +
9770
9771TH1D operator+(const TH1D &h1, const TH1D &h2)
9772{
9773 TH1D hnew = h1;
9774 hnew.Add(&h2,1);
9775 hnew.SetDirectory(0);
9776 return hnew;
9777}
9778
9779////////////////////////////////////////////////////////////////////////////////
9780/// Operator -
9781
9782TH1D operator-(const TH1D &h1, const TH1D &h2)
9783{
9784 TH1D hnew = h1;
9785 hnew.Add(&h2,-1);
9786 hnew.SetDirectory(0);
9787 return hnew;
9788}
9789
9790////////////////////////////////////////////////////////////////////////////////
9791/// Operator *
9792
9793TH1D operator*(const TH1D &h1, const TH1D &h2)
9794{
9795 TH1D hnew = h1;
9796 hnew.Multiply(&h2);
9797 hnew.SetDirectory(0);
9798 return hnew;
9799}
9800
9801////////////////////////////////////////////////////////////////////////////////
9802/// Operator /
9803
9804TH1D operator/(const TH1D &h1, const TH1D &h2)
9805{
9806 TH1D hnew = h1;
9807 hnew.Divide(&h2);
9808 hnew.SetDirectory(0);
9809 return hnew;
9810}
9811
9812////////////////////////////////////////////////////////////////////////////////
9813///return pointer to histogram with name
9814///hid if id >=0
9815///h_id if id <0
9816
9817TH1 *R__H(Int_t hid)
9818{
9819 TString hname;
9820 if(hid >= 0) hname.Form("h%d",hid);
9821 else hname.Form("h_%d",hid);
9822 return (TH1*)gDirectory->Get(hname);
9823}
9824
9825////////////////////////////////////////////////////////////////////////////////
9826///return pointer to histogram with name hname
9827
9828TH1 *R__H(const char * hname)
9829{
9830 return (TH1*)gDirectory->Get(hname);
9831}
void Class()
Definition: Class.C:29
#define b(i)
Definition: RSha256.hxx:100
#define c(i)
Definition: RSha256.hxx:101
#define s1(x)
Definition: RSha256.hxx:91
#define h(i)
Definition: RSha256.hxx:106
#define e(i)
Definition: RSha256.hxx:103
static const double x1[5]
int Int_t
Definition: RtypesCore.h:41
short Version_t
Definition: RtypesCore.h:61
char Char_t
Definition: RtypesCore.h:29
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
bool Bool_t
Definition: RtypesCore.h:59
short Short_t
Definition: RtypesCore.h:35
double Double_t
Definition: RtypesCore.h:55
double Stat_t
Definition: RtypesCore.h:73
short Color_t
Definition: RtypesCore.h:79
long long Long64_t
Definition: RtypesCore.h:69
short Style_t
Definition: RtypesCore.h:76
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
#define ClassImp(name)
Definition: Rtypes.h:365
#define gDirectory
Definition: TDirectory.h:223
include TDocParser_001 C image html pict1_TDocParser_001 png width
Definition: TDocParser.cxx:121
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
#define R__ASSERT(e)
Definition: TError.h:96
char name[80]
Definition: TGX11.cxx:109
int type
Definition: TGX11.cxx:120
static bool IsEquidistantBinning(const TAxis &axis)
Test if the binning is equidistant.
Definition: TH1.cxx:5479
void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
Least square linear fit without weights.
Definition: TH1.cxx:4666
void H1InitGaus()
Compute Initial values of parameters for a gaussian.
Definition: TH1.cxx:4501
void H1InitExpo()
Compute Initial values of parameters for an exponential.
Definition: TH1.cxx:4557
TH1C operator+(const TH1C &h1, const TH1C &h2)
Operator +.
Definition: TH1.cxx:9048
TH1C operator-(const TH1C &h1, const TH1C &h2)
Operator -.
Definition: TH1.cxx:9059
TH1C operator/(const TH1C &h1, const TH1C &h2)
Operator /.
Definition: TH1.cxx:9081
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:4712
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:5462
static Bool_t AlmostInteger(Double_t a, Double_t epsilon=0.00000001)
Test if a double is almost an integer.
Definition: TH1.cxx:5470
TF1 * gF1
Definition: TH1.cxx:525
TH1 * R__H(Int_t hid)
return pointer to histogram with name hid if id >=0 h_id if id <0
Definition: TH1.cxx:9815
TH1C operator*(Double_t c1, const TH1C &h1)
Operator *.
Definition: TH1.cxx:9037
void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
Least squares lpolynomial fitting without weights.
Definition: TH1.cxx:4607
void H1InitPolynom()
Compute Initial values of parameters for a polynom.
Definition: TH1.cxx:4577
float xmin
Definition: THbookFile.cxx:93
int nentries
Definition: THbookFile.cxx:89
float * q
Definition: THbookFile.cxx:87
float ymin
Definition: THbookFile.cxx:93
float xmax
Definition: THbookFile.cxx:93
float ymax
Definition: THbookFile.cxx:93
#define gInterpreter
Definition: TInterpreter.h:555
int isnan(double)
double ldexp(double, int)
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:59
#define gROOT
Definition: TROOT.h:415
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
char * Form(const char *fmt,...)
void Printf(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:407
#define R__LOCKGUARD(mutex)
#define gPad
Definition: TVirtualPad.h:286
#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:53
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition: DataRange.h:34
void AndersonDarling2SamplesTest(Double_t &pvalue, Double_t &testStat) const
Definition: GoFTest.cxx:646
Array of chars or bytes (8 bits per element).
Definition: TArrayC.h:27
void Set(Int_t n)
Set size of this array to n chars.
Definition: TArrayC.cxx:105
Char_t * fArray
Definition: TArrayC.h:30
void Copy(TArrayC &array) const
Definition: TArrayC.h:42
void Reset(Char_t val=0)
Definition: TArrayC.h:47
Array of doubles (64 bits per element).
Definition: TArrayD.h:27
Double_t GetAt(Int_t i) const
Definition: TArrayD.h:45
Double_t * fArray
Definition: TArrayD.h:30
void Copy(TArrayD &array) const
Definition: TArrayD.h:42
void Set(Int_t n)
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 Copy(TArrayF &array) const
Definition: TArrayF.h:42
void Reset()
Definition: TArrayF.h:47
void Set(Int_t n)
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)
Set size of this array to n ints.
Definition: TArrayI.cxx:105
void Reset()
Definition: TArrayI.h:47
void Copy(TArrayI &array) const
Definition: TArrayI.h:42
Array of shorts (16 bits per element).
Definition: TArrayS.h:27
void Set(Int_t n)
Set size of this array to n shorts.
Definition: TArrayS.cxx:105
void Reset()
Definition: TArrayS.h:47
void Copy(TArrayS &array) const
Definition: TArrayS.h:42
Short_t * fArray
Definition: TArrayS.h:30
Abstract array base class.
Definition: TArray.h:31
Int_t fN
Definition: TArray.h:38
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:294
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:163
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
Definition: TAttAxis.cxx:204
virtual Style_t GetLabelFont() const
Definition: TAttAxis.h:39
virtual void SetTitleFont(Style_t font=62)
Set the title font.
Definition: TAttAxis.cxx:322
virtual void SetLabelOffset(Float_t offset=0.005)
Set distance between the axis and the labels.
Definition: TAttAxis.cxx:193
virtual void SetLabelFont(Style_t font=62)
Set labels' font.
Definition: TAttAxis.cxx:183
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title.
Definition: TAttAxis.cxx:304
virtual void SetTitleColor(Color_t color=1)
Set color of axis title.
Definition: TAttAxis.cxx:313
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:280
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition: TAttAxis.cxx:229
virtual void SetLabelColor(Color_t color=1, Float_t alpha=1.)
Set color of labels.
Definition: TAttAxis.cxx:173
Fill Area Attributes class.
Definition: TAttFill.h:19
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:202
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition: TAttFill.h:37
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
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:234
Line Attributes class.
Definition: TAttLine.h:18
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 void SetLineWidth(Width_t lwidth)
Set the line width.
Definition: TAttLine.h:43
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
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:172
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:270
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.
Definition: TAttMarker.cxx:245
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.
Definition: TAttMarker.cxx:210
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition: TAttMarker.h:41
Class to manage histogram axis.
Definition: TAxis.h:30
virtual void GetCenter(Double_t *center) const
Return an array with the center of all bins.
Definition: TAxis.cxx:539
virtual Bool_t GetTimeDisplay() const
Definition: TAxis.h:126
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:464
Bool_t CanExtend() const
Definition: TAxis.h:82
virtual void SetParent(TObject *obj)
Definition: TAxis.h:157
const TArrayD * GetXbins() const
Definition: TAxis.h:130
void SetCanExtend(Bool_t canExtend)
Definition: TAxis.h:86
Double_t GetXmax() const
Definition: TAxis.h:134
virtual void SaveAttributes(std::ostream &out, const char *name, const char *subname)
Save axis attributes as C++ statement(s) on output stream out.
Definition: TAxis.cxx:647
@ kLabelsUp
Definition: TAxis.h:70
@ kLabelsDown
Definition: TAxis.h:69
@ kLabelsHori
Definition: TAxis.h:67
@ kAxisRange
Definition: TAxis.h:61
@ kLabelsVert
Definition: TAxis.h:68
const char * GetBinLabel(Int_t bin) const
Return label for bin.
Definition: TAxis.cxx:426
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:279
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:504
virtual void SetTimeDisplay(Int_t value)
Definition: TAxis.h:161
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Definition: TAxis.cxx:717
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:405
virtual void Copy(TObject &axis) const
Copy axis structure to another axis.
Definition: TAxis.cxx:208
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:455
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition: TAxis.h:154
Double_t GetXmin() const
Definition: TAxis.h:133
Int_t GetNbins() const
Definition: TAxis.h:121
virtual void GetLowEdge(Double_t *edge) const
Return an array with the low edge of all bins.
Definition: TAxis.cxx:548
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis from bin first to last.
Definition: TAxis.cxx:903
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:526
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:514
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:444
THashList * GetLabels() const
Definition: TAxis.h:117
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
Collection abstract base class.
Definition: TCollection.h:63
virtual bool UseRWLock()
Set this collection to use a RW lock upon access, making it thread safe.
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
virtual Bool_t IsEmpty() const
Definition: TCollection.h:186
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
Describe directory structure in memory.
Definition: TDirectory.h:34
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
Definition: TDirectory.cxx:190
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:211
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:3650
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function.
Definition: TF1.cxx:1564
virtual Int_t GetNpar() const
Definition: TF1.h:475
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
IntegralOneDim or analytical integral.
Definition: TF1.cxx:2502
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=0)
Evaluate function with given coordinates and parameters.
Definition: TF1.cxx:1458
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition: TF1.cxx:2454
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition: TF1.cxx:2263
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set limits for parameter ipar.
Definition: TF1.cxx:3497
static Bool_t RejectedPoint()
See TF1::RejectPoint above.
Definition: TF1.cxx:3659
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:1429
virtual void SetParameter(Int_t param, Double_t value)
Definition: TF1.h:628
virtual Bool_t IsInside(const Double_t *x) const
return kTRUE if the point is inside the function range
Definition: TF1.h:592
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...
Definition: TFitResultPtr.h:31
1-D histogram with a byte per channel (see TH1 documentation)
Definition: TH1.h:448
TH1C & operator=(const TH1C &h1)
Operator =.
Definition: TH1.cxx:9028
TH1C()
Constructor.
Definition: TH1.cxx:8918
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:9000
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9018
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH1.cxx:8981
virtual ~TH1C()
Destructor.
Definition: TH1.cxx:8966
virtual void Reset(Option_t *option="")
Reset.
Definition: TH1.cxx:9008
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:614
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:9721
virtual ~TH1D()
Destructor.
Definition: TH1.cxx:9706
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9739
TH1D()
Constructor.
Definition: TH1.cxx:9641
TH1D & operator=(const TH1D &h1)
Operator =.
Definition: TH1.cxx:9749
1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:571
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.h:600
virtual ~TH1F()
Destructor.
Definition: TH1.cxx:9535
TH1F & operator=(const TH1F &h1)
Operator =.
Definition: TH1.cxx:9570
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9560
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:9542
TH1F()
Constructor.
Definition: TH1.cxx:9462
1-D histogram with an int per channel (see TH1 documentation)}
Definition: TH1.h:530
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:9362
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH1.cxx:9343
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9380
virtual ~TH1I()
Destructor.
Definition: TH1.cxx:9328
TH1I()
Constructor.
Definition: TH1.cxx:9280
TH1I & operator=(const TH1I &h1)
Operator =.
Definition: TH1.cxx:9390
1-D histogram with a short per channel (see TH1 documentation)
Definition: TH1.h:489
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH1.cxx:9162
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9199
virtual ~TH1S()
Destructor.
Definition: TH1.cxx:9147
TH1S & operator=(const TH1S &h1)
Operator =.
Definition: TH1.cxx:9209
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:9181
TH1S()
Constructor.
Definition: TH1.cxx:9099
The TH1 histogram class.
Definition: TH1.h:56
virtual void SetError(const Double_t *error)
Replace bin errors by values in array error.
Definition: TH1.cxx:8395
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8381
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition: TH1.cxx:4155
Double_t * fBuffer
[fBufferSize] entry buffer
Definition: TH1.h:105
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:1276
@ kXaxis
Definition: TH1.h:70
@ kNoAxis
NOTE: Must always be 0 !!!
Definition: TH1.h:69
@ kZaxis
Definition: TH1.h:72
@ kYaxis
Definition: TH1.h:71
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition: TH1.cxx:4319
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TH1.cxx:6777
virtual void SetTitle(const char *title)
See GetStatOverflows for more information.
Definition: TH1.cxx:6333
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition: TH1.cxx:6500
virtual void Print(Option_t *option="") const
Print some global quantities for this histogram.
Definition: TH1.cxx:6630
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition: TH1.cxx:8585
virtual void Rebuild(Option_t *option="")
Using the current bin info, recompute the arrays for contents and errors.
Definition: TH1.cxx:6708
static Bool_t fgStatOverflows
!flag to use under/overflows in statistics
Definition: TH1.h:114
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:3721
TAxis * GetZaxis()
Definition: TH1.h:318
virtual Bool_t Multiply(TF1 *f1, Double_t c1=1)
Performs the operation:
Definition: TH1.cxx:5650
virtual void Browse(TBrowser *b)
Browse the Histogram object.
Definition: TH1.cxx:714
Int_t fNcells
number of bins(1D), cells (2D) +U/Overflows
Definition: TH1.h:86
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:7333
virtual void FillRandom(const char *fname, Int_t ntimes=5000)
Fill histogram following distribution in function fname.
Definition: TH1.cxx:3445
Double_t fTsumw
Total Sum of weights.
Definition: TH1.h:93
virtual Float_t GetBarWidth() const
Definition: TH1.h:252
Double_t fTsumw2
Total Sum of squares of weights.
Definition: TH1.h:94
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:6546
virtual Float_t GetBarOffset() const
Definition: TH1.h:251
virtual ~TH1()
Histogram default destructor.
Definition: TH1.cxx:579
TList * fFunctions
->Pointer to list of functions (fits and user)
Definition: TH1.h:103
static Bool_t fgAddDirectory
!flag to add histograms to the directory
Definition: TH1.h:113
virtual Int_t GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum=0)
Compute Quantiles for this histogram Quantile x_q of a probability distribution Function F is defined...
Definition: TH1.cxx:4451
static Int_t GetDefaultBufferSize()
Static function return the default buffer size for automatic histograms the parameter fgBufferSize ma...
Definition: TH1.cxx:4277
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:7474
Double_t fTsumwx2
Total Sum of weight*X*X.
Definition: TH1.h:96
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition: TH1.cxx:7128
TH1()
Histogram default constructor.
Definition: TH1.cxx:551
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:8764
virtual void LabelsOption(Option_t *option="h", Option_t *axis="X")
Set option(s) to draw axis with labels.
Definition: TH1.cxx:5214
virtual Int_t GetNbinsY() const
Definition: TH1.h:293
Short_t fBarOffset
(1000*offset) for bar charts or legos
Definition: TH1.h:90
static bool CheckBinLimits(const TAxis *a1, const TAxis *a2)
Check bin limits.
Definition: TH1.cxx:1472
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH1.cxx:1201
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8507
static Int_t FitOptionsMake(Option_t *option, Foption_t &Foption)
Decode string choptin and fill fitOption structure.
Definition: TH1.cxx:4492
virtual Int_t GetNbinsZ() const
Definition: TH1.h:294
virtual Double_t GetNormFactor() const
Definition: TH1.h:296
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:7074
virtual Double_t GetSkewness(Int_t axis=1) const
Definition: TH1.cxx:7180
virtual void ClearUnderflowAndOverflow()
Remove all the content from the underflow and overflow bins, without changing the number of entries A...
Definition: TH1.cxx:2456
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition: TH1.cxx:7892
virtual TH1 * DrawNormalized(Option_t *option="", Double_t norm=1) const
Draw a normalized copy of this histogram.
Definition: TH1.cxx:3075
virtual Double_t Chi2TestX(const TH1 *h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option="UU", Double_t *res=0) const
The computation routine of the Chisquare test.
Definition: TH1.cxx:2009
virtual Int_t GetDimension() const
Definition: TH1.h:278
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition: TH1.cxx:1226
@ kIsAverage
Bin contents are average (used by Add)
Definition: TH1.h:166
@ kUserContour
user specified contour levels
Definition: TH1.h:161
@ kNoStats
don't draw stats box
Definition: TH1.h:160
@ kAutoBinPTwo
Use Power(2)-based algorithm for autobinning.
Definition: TH1.h:169
@ kIsNotW
Histogram is forced to be not weighted even when the histogram is filled with weighted different than...
Definition: TH1.h:167
@ kIsHighlight
bit set if histo is highlight
Definition: TH1.h:170
virtual Double_t GetRandom() const
Return a random number distributed according the histogram bin contents.
Definition: TH1.cxx:4848
virtual void SetContourLevel(Int_t level, Double_t value)
Set value for one contour level.
Definition: TH1.cxx:7974
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition: TH1.cxx:6266
TDirectory * fDirectory
!Pointer to directory holding this histogram
Definition: TH1.h:106
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition: TH1.cxx:6724
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition: TH1.h:316
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:4814
TH1 * GetCumulative(Bool_t forward=kTRUE, const char *suffix="_cumulative") const
Return a pointer to an histogram containing the cumulative The cumulative can be computed both in the...
Definition: TH1.cxx:2545
void UseCurrentStyle()
Copy current attributes from/to current style.
Definition: TH1.cxx:7010
static Double_t AutoP2GetPower2(Double_t x, Bool_t next=kTRUE)
Auxilliary function to get the power of 2 next (larger) or previous (smaller) a given x.
Definition: TH1.cxx:1240
virtual Int_t GetNcells() const
Definition: TH1.h:295
virtual Int_t ShowPeaks(Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
Interface to TSpectrum::Search.
Definition: TH1.cxx:8746
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition: TH1.cxx:5509
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition: TH1.cxx:7384
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition: TH1.cxx:4360
TObject * Clone(const char *newname=0) const
Make a complete copy of the underlying object.
Definition: TH1.cxx:2665
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
Definition: TH1.cxx:4286
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:3658
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:3808
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:4801
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:7994
virtual Int_t GetNbinsX() const
Definition: TH1.h:292
virtual void SetMaximum(Double_t maximum=-1111)
Definition: TH1.h:394
virtual TH1 * FFT(TH1 *h_output, Option_t *option)
This function allows to do discrete Fourier transforms of TH1 and TH2.
Definition: TH1.cxx:3215
virtual void LabelsInflate(Option_t *axis="X")
Double the number of bins for axis.
Definition: TH1.cxx:5153
virtual TH1 * ShowBackground(Int_t niter=20, Option_t *option="same")
This function calculates the background spectrum in this histogram.
Definition: TH1.cxx:8731
virtual Double_t Chi2Test(const TH1 *h2, Option_t *option="UU", Double_t *res=0) const
test for comparing weighted and unweighted histograms
Definition: TH1.cxx:1950
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
Definition: TH1.cxx:5499
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:778
Double_t fMaximum
Maximum value for plotting.
Definition: TH1.h:97
Int_t fBufferSize
fBuffer size
Definition: TH1.h:104
virtual void RecursiveRemove(TObject *obj)
Recursively remove object from the list of functions.
Definition: TH1.cxx:6206
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:8884
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:7465
Int_t fDimension
!Histogram dimension (1, 2 or 3 dim)
Definition: TH1.h:107
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:8650
EBinErrorOpt fBinStatErrOpt
option for bin statistical errors
Definition: TH1.h:110
static Int_t fgBufferSize
!default buffer size for automatic histograms
Definition: TH1.h:112
virtual void SetBinsLength(Int_t=-1)
Definition: TH1.h:371
Double_t fNormFactor
Normalization factor.
Definition: TH1.h:99
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3275
virtual TObject * FindObject(const char *name) const
Search object named name in the list of functions.
Definition: TH1.cxx:3781
TAxis * GetYaxis()
Definition: TH1.h:317
TArrayD fContour
Array to display contour levels.
Definition: TH1.h:100
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition: TH1.cxx:8523
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition: TH1.cxx:7850
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:6919
Short_t fBarWidth
(1000*width) for bar charts or legos
Definition: TH1.h:91
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition: TH1.cxx:7935
virtual Double_t GetBinErrorSqUnchecked(Int_t bin) const
Definition: TH1.h:439
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:395
Bool_t IsBinUnderflow(Int_t bin, Int_t axis=0) const
Return true if the bin is underflow.
Definition: TH1.cxx:5052
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check that axis have same labels.
Definition: TH1.cxx:1501
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:4953
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:6318
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition: TH1.cxx:5020
Double_t * fIntegral
!Integral of bins used by GetRandom
Definition: TH1.h:108
Double_t fMinimum
Minimum value for plotting.
Definition: TH1.h:98
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition: TH1.cxx:7438
virtual void SetBarWidth(Float_t width=0.5)
Definition: TH1.h:356
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:8666
virtual void DirectoryAutoAdd(TDirectory *)
Perform the automatic addition of the histogram to the given directory.
Definition: TH1.cxx:2714
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:8631
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8596
void Build()
Creates histogram basic data structure.
Definition: TH1.cxx:723
virtual Double_t GetEntries() const
Return the current number of entries.
Definition: TH1.cxx:4294
virtual TF1 * GetFunction(const char *name) const
Return pointer to function with name.
Definition: TH1.cxx:8495
virtual Int_t BufferFill(Double_t x, Double_t w)
accumulate arguments in buffer.
Definition: TH1.cxx:1437
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:4924
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:6279
TList * GetListOfFunctions() const
Definition: TH1.h:239
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition: TH1.cxx:3045
virtual void Copy(TObject &hnew) const
Copy this histogram structure to newth1.
Definition: TH1.cxx:2588
Bool_t IsEmpty() const
Check if an histogram is empty (this a protected method used mainly by TH1Merger )
Definition: TH1.cxx:5002
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition: TH1.cxx:7105
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2998
virtual void SetBarOffset(Float_t offset=0.25)
Definition: TH1.h:355
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:7558
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculates from bin cont...
Definition: TH1.cxx:7399
static void SetDefaultBufferSize(Int_t buffersize=1000)
Static function to set the default buffer size for automatic histograms.
Definition: TH1.cxx:6308
virtual void SetBinErrorOption(EBinErrorOpt type)
Definition: TH1.h:372
virtual void SetBuffer(Int_t buffersize, Option_t *option="")
Set the maximum number of entries to be kept in the buffer.
Definition: TH1.cxx:7910
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Definition: TH1.cxx:3106
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:2437
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:3404
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition: TH1.cxx:8175
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition: TH1.cxx:8024
static Int_t AutoP2GetBins(Int_t n)
Auxilliary function to get the next power of 2 integer value larger then n.
Definition: TH1.cxx:1253
Double_t fEntries
Number of entries.
Definition: TH1.h:92
virtual Long64_t Merge(TCollection *list)
Definition: TH1.h:337
virtual void SetName(const char *name)
Change the name of this histogram.
Definition: TH1.cxx:8404
virtual Double_t * GetIntegral()
Return a pointer to the array of bins integral.
Definition: TH1.cxx:2523
TAxis fZaxis
Z axis descriptor.
Definition: TH1.h:89
EStatOverflows fStatOverflows
per object flag to use under/overflows in statistics
Definition: TH1.h:111
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:3378
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:8894
static bool CheckEqualAxes(const TAxis *a1, const TAxis *a2)
Check that the axis are the same.
Definition: TH1.cxx:1548
@ kPoisson2
errors from Poisson interval at 95% CL (~ 2 sigma)
Definition: TH1.h:64
@ kNormal
errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition: TH1.h:62
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4899
TAxis fXaxis
X axis descriptor.
Definition: TH1.h:87
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition: TH1.cxx:3171
virtual Bool_t IsHighlight() const
Definition: TH1.h:330
virtual void ExtendAxis(Double_t x, TAxis *axis)
Histogram is resized along axis such that x is in the axis range.
Definition: TH1.cxx:6134
virtual void SetNameTitle(const char *name, const char *title)
Change the name and title of this histogram.
Definition: TH1.cxx:8418
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8607
static bool CheckConsistency(const TH1 *h1, const TH1 *h2)
Check histogram compatibility.
Definition: TH1.cxx:1621
TArrayD fSumw2
Array of sum of squares of weights.
Definition: TH1.h:101
TH1 * GetAsymmetry(TH1 *h2, Double_t c2=1, Double_t dc2=0)
Return an histogram containing the asymmetry of this histogram with h2, where the asymmetry is define...
Definition: TH1.cxx:4210
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition: TH1.cxx:7882
virtual void SetHighlight(Bool_t set=kTRUE)
Set highlight (enable/disable) mode for the histogram by default highlight mode is disable.
Definition: TH1.cxx:4330
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition: TH1.cxx:8554
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition: TH1.cxx:6234
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms.
Definition: TH1.cxx:5825
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition: TH1.cxx:8109
virtual Int_t GetSumw2N() const
Definition: TH1.h:310
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:3596
Bool_t GetStatOverflowsBehaviour() const
Definition: TH1.h:148
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition: TH1.cxx:7167
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:2753
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:8079
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:1584
TAxis fYaxis
Y axis descriptor.
Definition: TH1.h:88
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:7672
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7414
static void SmoothArray(Int_t NN, Double_t *XX, Int_t ntimes=1)
Smooth array xx, translation of Hbook routine hsmoof.F based on algorithm 353QH twice presented by J.
Definition: TH1.cxx:6382
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:8618
TVirtualHistPainter * fPainter
!pointer to histogram painter
Definition: TH1.h:109
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition: TH1.cxx:8211
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:3629
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Redefines TObject::GetObjectInfo.
Definition: TH1.cxx:4351
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition: TH1.cxx:8464
virtual void SetEntries(Double_t n)
Definition: TH1.h:381
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:6077
static bool CheckAxisLimits(const TAxis *a1, const TAxis *a2)
Check that the axis limits of the histograms are the same.
Definition: TH1.cxx:1533
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition: TH1.cxx:706
static Bool_t fgDefaultSumw2
!flag to call TH1::Sumw2 automatically at histogram creation time
Definition: TH1.h:115
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a line.
Definition: TH1.cxx:2736
Double_t fTsumwx
Total Sum of weight*X.
Definition: TH1.h:95
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:5083
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:2475
TString fOption
histogram options
Definition: TH1.h:102
virtual Int_t GetContour(Double_t *levels=0)
Return contour values into array levels if pointer levels is non zero.
Definition: TH1.cxx:7863
virtual void Eval(TF1 *f1, Option_t *option="")
Evaluate function f1 at the center of bins of this histogram.
Definition: TH1.cxx:3123
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition: TH1.cxx:1347
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition: TH1.cxx:8434
@ kNstat
Definition: TH1.h:179
virtual TH1 * Rebin(Int_t ngroup=2, const char *newname="", const Double_t *xbins=0)
Rebin this histogram.
Definition: TH1.cxx:5892
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition: TH1.cxx:7250
2-D histogram with a double per channel (see TH1 documentation)}
Definition: TH2.h:292
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="")
Remove all objects from the list.
Definition: THashList.cxx:189
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:819
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:575
virtual TObjLink * FirstLink() const
Definition: TList.h:108
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: TList.cxx:761
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:656
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual void Copy(TObject &named) const
Copy this to obj.
Definition: TNamed.cxx:94
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
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
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Mother of all ROOT objects.
Definition: TObject.h:37
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:922
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition: TObject.cxx:375
@ kNotDeleted
object has not been deleted
Definition: TObject.h:78
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:128
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition: TObject.cxx:715
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition: TObject.cxx:105
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TObject.cxx:664
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:705
void ResetBit(UInt_t f)
Definition: TObject.h:171
@ kCanDelete
if object in a list can be deleted
Definition: TObject.h:58
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition: TObject.h:68
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Long_t ExecPlugin(int nargs, const T &... params)
Int_t LoadPlugin()
Load the plugin library for this handler.
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition: TRandom.cxx:391
virtual Double_t PoissonD(Double_t mean)
Generates a random number according to a Poisson law.
Definition: TRandom.cxx:443
virtual Double_t Rndm()
Machine independent random number generator.
Definition: TRandom.cxx:541
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1138
Bool_t IsNull() const
Definition: TString.h:402
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
TString & Append(const char *cs)
Definition: TString.h:559
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:2311
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
Int_t GetOptStat() const
Definition: TStyle.h:233
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:1450
void SetHistFillColor(Color_t color=1)
Definition: TStyle.h:357
Color_t GetHistLineColor() const
Definition: TStyle.h:221
Bool_t IsReading() const
Definition: TStyle.h:278
Float_t GetBarOffset() const
Definition: TStyle.h:171
void SetHistLineStyle(Style_t styl=0)
Definition: TStyle.h:360
Style_t GetHistFillStyle() const
Definition: TStyle.h:222
Color_t GetHistFillColor() const
Definition: TStyle.h:220
Float_t GetBarWidth() const
Definition: TStyle.h:172
Bool_t GetCanvasPreferGL() const
Definition: TStyle.h:176
void SetHistLineColor(Color_t color=1)
Definition: TStyle.h:358
void SetBarOffset(Float_t baroff=0.5)
Definition: TStyle.h:314
Style_t GetHistLineStyle() const
Definition: TStyle.h:223
void SetBarWidth(Float_t barwidth=0.5)
Definition: TStyle.h:315
void SetHistFillStyle(Style_t styl=0)
Definition: TStyle.h:359
Width_t GetHistLineWidth() const
Definition: TStyle.h:224
Int_t GetOptFit() const
Definition: TStyle.h:232
void SetHistLineWidth(Width_t width=1)
Definition: TStyle.h:361
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
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)=0
Execute action corresponding to an event at (px,py).
virtual void Paint(Option_t *option="")=0
This method must be overridden if a class wants to paint itself.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)=0
Computes distance from point (px,py) to the object.
virtual void SetHighlight()=0
static TVirtualHistPainter * HistPainter(TH1 *obj)
Static function returning a pointer to the current histogram painter.
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
return c1
Definition: legend1.C:41
Double_t y[n]
Definition: legend1.C:17
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
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:966
void FitOptionsMake(EFitObjectType type, const char *option, Foption_t &fitOption)
Decode list of options into fitOption.
Definition: HFitImpl.cxx:683
void FillData(BinData &dv, const TH1 *hist, TF1 *func=0)
fill the data vector from a TH1.
double Chisquare(const TH1 &h1, TF1 &f1, bool useRange, bool usePL=false)
compute the chi2 value for an histogram given a function (see TH1::Chisquare for the documentation)
Definition: HFitImpl.cxx:1020
R__EXTERN TVirtualRWMutex * gCoreMutex
static constexpr double s
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN
Definition: NeuralNet.icc:546
Bool_t IsNaN(Double_t x)
Definition: TMath.h:882
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:703
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:212
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:621
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754
Definition: TMath.h:891
Double_t Floor(Double_t x)
Definition: TMath.h:693
Double_t ATan(Double_t)
Definition: TMath.h:665
Double_t Ceil(Double_t x)
Definition: TMath.h:685
T MinElement(Long64_t n, const T *a)
Return minimum of array a of length n.
Definition: TMath.h:942
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:97
Double_t Log(Double_t x)
Definition: TMath.h:750
Double_t Sqrt(Double_t x)
Definition: TMath.h:681
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:725
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
constexpr Double_t Pi()
Definition: TMath.h:38
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition: TMath.h:418
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Definition: TMath.h:412
Double_t KolmogorovProb(Double_t z)
Calculates the Kolmogorov distribution function,.
Definition: TMath.cxx:663
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Definition: TMathBase.h:362
Double_t Median(Long64_t n, const T *a, const Double_t *w=0, Long64_t *work=0)
Return the median of the array a where each entry i has weight w[i] .
Definition: TMath.h:1237
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMathBase.h:278
Double_t Log10(Double_t x)
Definition: TMath.h:754
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
Double_t Infinity()
Returns an infinity as defined by the IEEE standard.
Definition: TMath.h:904
Definition: first.py:1
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12
static long int sum(long int i)
Definition: Factory.cxx:2276
REAL epsilon
Definition: triangle.c:617