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 "TBuffer.h"
22#include "TEnv.h"
23#include "TClass.h"
24#include "TMath.h"
25#include "THashList.h"
26#include "TH1.h"
27#include "TH2.h"
28#include "TH3.h"
29#include "TF2.h"
30#include "TF3.h"
31#include "TPluginManager.h"
32#include "TVirtualPad.h"
33#include "TRandom.h"
34#include "TVirtualFitter.h"
35#include "THLimitsFinder.h"
36#include "TProfile.h"
37#include "TStyle.h"
38#include "TVectorF.h"
39#include "TVectorD.h"
40#include "TBrowser.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" Ignore the bin uncertainties when fitting using the default least square (chi2) method but skip empty bins
3841/// - "WW" Ignore the bin uncertainties when fitting using the default least square (chi2) method and include also the empty bins
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/// -"MULTI" Use Loglikelihood method based on multi-nomial distribution.
3848/// In this case function must be normalized and one fits only the function shape (a not extended binned
3849/// likelihood fit)
3850/// - "P" Use Pearson chi2 (using expected errors instead of observed errors)
3851/// - "U" Use a User specified fitting algorithm (via SetFCN)
3852/// - "Q" Quiet mode (minimum printing)
3853/// - "V" Verbose mode (default is between Q and V)
3854/// - "E" Perform better Errors estimation using Minos technique
3855/// - "B" User defined parameter settings are used for predefined functions
3856/// like "gaus", "expo", "poln", "landau".
3857/// Use this option when you want to fix one or more parameters for these functions.
3858/// - "M" More. Improve fit results.
3859/// It uses the IMPROVE command of TMinuit (see TMinuit::mnimpr).
3860/// This algorithm attempts to improve the found local minimum by searching for a
3861/// better one.
3862/// - "R" Use the Range specified in the function range
3863/// - "N" Do not store the graphics function, do not draw
3864/// - "0" Do not plot the result of the fit. By default the fitted function
3865/// is drawn unless the option"N" above is specified.
3866/// - "+" Add this new fitted function to the list of fitted functions
3867/// (by default, any previous function is deleted)
3868/// - "C" In case of linear fitting, don't calculate the chisquare
3869/// (saves time)
3870/// - "F" If fitting a polN, switch to minuit fitter
3871/// - "S" The result of the fit is returned in the TFitResultPtr
3872/// (see below Access to the Fit Result)
3873/// \param[in] goption specify a list of graphics options. See TH1::Draw for a complete list of these options.
3874/// \param[in] xxmin range
3875/// \param[in] xxmax range
3876///
3877/// In order to use the Range option, one must first create a function
3878/// with the expression to be fitted. For example, if your histogram
3879/// has a defined range between -4 and 4 and you want to fit a gaussian
3880/// only in the interval 1 to 3, you can do:
3881///
3882/// ~~~ {.cpp}
3883/// TF1 *f1 = new TF1("f1", "gaus", 1, 3);
3884/// histo->Fit("f1", "R");
3885/// ~~~
3886///
3887/// ## Setting initial conditions
3888/// Parameters must be initialized before invoking the Fit function.
3889/// The setting of the parameter initial values is automatic for the
3890/// predefined functions : poln, expo, gaus, landau. One can however disable
3891/// this automatic computation by specifying the option "B".
3892/// Note that if a predefined function is defined with an argument,
3893/// eg, gaus(0), expo(1), you must specify the initial values for
3894/// the parameters.
3895/// You can specify boundary limits for some or all parameters via
3896///
3897/// ~~~ {.cpp}
3898/// f1->SetParLimits(p_number, parmin, parmax);
3899/// ~~~
3900///
3901/// if parmin>=parmax, the parameter is fixed
3902/// Note that you are not forced to fix the limits for all parameters.
3903/// For example, if you fit a function with 6 parameters, you can do:
3904///
3905/// ~~~ {.cpp}
3906/// func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
3907/// func->SetParLimits(3, -10, -4);
3908/// func->FixParameter(4, 0);
3909/// func->SetParLimits(5, 1, 1);
3910/// ~~~
3911///
3912/// With this setup, parameters 0->2 can vary freely
3913/// Parameter 3 has boundaries [-10,-4] with initial value -8
3914/// Parameter 4 is fixed to 0
3915/// Parameter 5 is fixed to 100.
3916/// When the lower limit and upper limit are equal, the parameter is fixed.
3917/// However to fix a parameter to 0, one must call the FixParameter function.
3918///
3919///
3920/// #### Changing the fitting objective function
3921///
3922/// By default a chi square function is used for fitting. When option "L" (or "LL") is used
3923/// a Poisson likelihood function (see note below) is used.
3924/// Using option "MULTI" a multinomial likelihood fit is used. In this case the function normalization is not fitted
3925/// but only the function shape. Therefore the provided function must be normalized.
3926/// The functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
3927/// are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
3928/// the file math/mathcore/src/FitUtil.cxx.
3929/// To specify a User defined fitting function, specify option "U" and
3930/// call the following functions:
3931///
3932/// ~~~ {.cpp}
3933/// TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction)
3934/// ~~~
3935///
3936/// where MyFittingFunction is of type:
3937///
3938/// ~~~ {.cpp}
3939/// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
3940/// ~~~
3941///
3942/// #### Chi2 Fits
3943///
3944/// By default a chi2 (least-square) fit is performed on the histogram. The so-called modified least-square method
3945/// is used where the residual for each bin is computed using as error the observed value (the bin error)
3946///
3947/// \f[
3948/// Chi2 = \sum{ \left(\frac{y(i) - f(x(i) | p )}{e(i)} \right)^2 }
3949/// \f]
3950///
3951/// 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
3952/// an un-weighted histogram. Bins with zero errors are excluded from the fit. See also later the note on the treatment
3953/// of empty bins. When using option "I" the residual is computed not using the function value at the bin center, f
3954/// (x(i) | p), but the integral of the function in the bin, Integral{ f(x|p)dx } divided by the bin volume
3955///
3956/// #### Likelihood Fits
3957///
3958/// When using option "L" a likelihood fit is used instead of the default chi2 square fit.
3959/// The likelihood is built assuming a Poisson probability density function for each bin.
3960/// The negative log-likelihood to be minimized is
3961///
3962/// \f[
3963/// NLL = \sum{ log Poisson ( y(i) | f(x(i) | p ) ) }
3964/// \f]
3965///
3966/// The exact likelihood used is the Poisson likelihood described in this paper:
3967/// S. Baker and R. D. Cousins, “Clarification of the use of chi-square and likelihood functions in fits to histograms,”
3968/// Nucl. Instrum. Meth. 221 (1984) 437.
3969///
3970/// This method can then be used only when the bin content represents counts (i.e. errors are sqrt(N) ).
3971/// The likelihood method has the advantage of treating correctly bins with low statistics. In case of high
3972/// statistics/bin the distribution of the bin content becomes a normal distribution and the likelihood and chi2 fit
3973/// give the same result.
3974///
3975/// The likelihood method, although a bit slower, it is therefore the recommended method in case of low
3976/// bin statistics, where the chi2 method may give incorrect results, in particular when there are
3977/// several empty bins (see also below).
3978/// In case of a weighted histogram, it is possible to perform a likelihood fit by using the
3979/// option "WL". Note a weighted histogram is an histogram which has been filled with weights and it
3980/// contains the sum of the weight square ( TH1::Sumw2() has been called). The bin error for a weighted
3981/// histogram is the square root of the sum of the weight square.
3982///
3983/// #### Treatment of Empty Bins
3984///
3985/// Empty bins, which have the content equal to zero AND error equal to zero,
3986/// are excluded by default from the chisquare fit, but they are considered in the likelihood fit.
3987/// since they affect the likelihood if the function value in these bins is not negligible.
3988/// When using option "WW" these bins will be considered in the chi2 fit with an error of 1.
3989/// Note that if the histogram is having bins with zero content and non zero-errors they are considered as
3990/// any other bins in the fit. Instead bins with zero error and non-zero content are excluded in the chi2 fit.
3991/// A likelihood fit should also not be performed on such an histogram, since we are assuming a wrong pdf for each bin.
3992/// In general, one should not fit an histogram with non-empty bins and zero errors, apart if all the bins have zero
3993/// errors. In this case one could use the option "w", which gives a weight=1 for each bin (unweighted least-square
3994/// fit).
3995/// Note that in case of histogram with no errors (chi2 fit with option W or W1) the resulting fitted parameter errors
3996/// are corrected by the obtained chi2 value using this expression: errorp *= sqrt(chisquare/(ndf-1))
3997///
3998/// #### Fitting a histogram of dimension N with a function of dimension N-1
3999///
4000/// It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
4001/// In this case the option "Integral" is not allowed and each cell has
4002/// equal weight. Also in this case th eobtained parameter error are corrected as in the case when the
4003/// option "W" is used (see above)
4004///
4005/// #### Associated functions
4006///
4007/// One or more object (typically a TF1*) can be added to the list
4008/// of functions (fFunctions) associated to each histogram.
4009/// When TH1::Fit is invoked, the fitted function is added to this list.
4010/// Given an histogram h, one can retrieve an associated function
4011/// with:
4012///
4013/// ~~~ {.cpp}
4014/// TF1 *myfunc = h->GetFunction("myfunc");
4015/// ~~~
4016///
4017/// #### Access to the fit result
4018///
4019/// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
4020/// By default the TFitResultPtr contains only the status of the fit which is return by an
4021/// automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
4022///
4023/// ~~~ {.cpp}
4024/// Int_t fitStatus = h->Fit(myFunc)
4025/// ~~~
4026///
4027/// If the option "S" is instead used, TFitResultPtr contains the TFitResult and behaves as a smart
4028/// pointer to it. For example one can do:
4029///
4030/// ~~~ {.cpp}
4031/// TFitResultPtr r = h->Fit(myFunc,"S");
4032/// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
4033/// Double_t chi2 = r->Chi2(); // to retrieve the fit chi2
4034/// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
4035/// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
4036/// r->Print("V"); // print full information of fit including covariance matrix
4037/// r->Write(); // store the result in a file
4038/// ~~~
4039///
4040/// The fit parameters, error and chi2 (but not covariance matrix) can be retrieved also
4041/// from the fitted function.
4042/// If the histogram is made persistent, the list of
4043/// associated functions is also persistent. Given a pointer (see above)
4044/// to an associated function myfunc, one can retrieve the function/fit
4045/// parameters with calls such as:
4046///
4047/// ~~~ {.cpp}
4048/// Double_t chi2 = myfunc->GetChisquare();
4049/// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
4050/// Double_t err0 = myfunc->GetParError(0); //error on first parameter
4051/// ~~~
4052///
4053/// #### Access to the fit status
4054///
4055/// The status of the fit can be obtained converting the TFitResultPtr to an integer
4056/// independently if the fit option "S" is used or not:
4057///
4058/// ~~~ {.cpp}
4059/// TFitResultPtr r = h->Fit(myFunc,opt);
4060/// Int_t fitStatus = r;
4061/// ~~~
4062///
4063/// The fitStatus is 0 if the fit is OK (i.e no error occurred).
4064/// The value of the fit status code is negative in case of an error not connected with the
4065/// minimization procedure, for example when a wrong function is used.
4066/// Otherwise the return value is the one returned from the minimization procedure.
4067/// When TMinuit (default case) or Minuit2 are used as minimizer the status returned is :
4068/// `fitStatus = migradResult + 10*minosResult + 100*hesseResult + 1000*improveResult`.
4069/// TMinuit will return 0 (for migrad, minos, hesse or improve) in case of success and 4 in
4070/// case of error (see the documentation of TMinuit::mnexcm). So for example, for an error
4071/// only in Minos but not in Migrad a fitStatus of 40 will be returned.
4072/// Minuit2 will return also 0 in case of success and different values in migrad minos or
4073/// hesse depending on the error. See in this case the documentation of
4074/// Minuit2Minimizer::Minimize for the migradResult, Minuit2Minimizer::GetMinosError for the
4075/// minosResult and Minuit2Minimizer::Hesse for the hesseResult.
4076/// If other minimizers are used see their specific documentation for the status code returned.
4077/// For example in the case of Fumili, for the status returned see TFumili::Minimize.
4078///
4079/// #### Excluding points
4080///
4081/// Use TF1::RejectPoint inside your fitting function to exclude points
4082/// within a certain range from the fit. Example:
4083///
4084/// ~~~ {.cpp}
4085/// Double_t fline(Double_t *x, Double_t *par)
4086/// {
4087/// if (x[0] > 2.5 && x[0] < 3.5) {
4088/// TF1::RejectPoint();
4089/// return 0;
4090/// }
4091/// return par[0] + par[1]*x[0];
4092/// }
4093///
4094/// void exclude() {
4095/// TF1 *f1 = new TF1("f1", "[0] +[1]*x +gaus(2)", 0, 5);
4096/// f1->SetParameters(6, -1,5, 3, 0.2);
4097/// TH1F *h = new TH1F("h", "background + signal", 100, 0, 5);
4098/// h->FillRandom("f1", 2000);
4099/// TF1 *fline = new TF1("fline", fline, 0, 5, 2);
4100/// fline->SetParameters(2, -1);
4101/// h->Fit("fline", "l");
4102/// }
4103/// ~~~
4104///
4105/// #### Warning when using the option "0"
4106///
4107/// When selecting the option "0", the fitted function is added to
4108/// the list of functions of the histogram, but it is not drawn.
4109/// You can undo what you disabled in the following way:
4110///
4111/// ~~~ {.cpp}
4112/// h.Fit("myFunction", "0"); // fit, store function but do not draw
4113/// h.Draw(); function is not drawn
4114/// const Int_t kNotDraw = 1<<9;
4115/// h.GetFunction("myFunction")->ResetBit(kNotDraw);
4116/// h.Draw(); // function is visible again
4117/// ~~~
4118///
4119/// #### Access to the Minimizer information during fitting
4120///
4121/// This function calls, the ROOT::Fit::FitObject function implemented in HFitImpl.cxx
4122/// which uses the ROOT::Fit::Fitter class. The Fitter class creates the objective function
4123/// (e.g. chi2 or likelihood) and uses an implementation of the Minimizer interface for minimizing
4124/// the function.
4125/// The default minimizer is Minuit (class TMinuitMinimizer which calls TMinuit).
4126/// The default can be set in the resource file in etc/system.rootrc. For example
4127///
4128/// ~~~ {.cpp}
4129/// Root.Fitter: Minuit2
4130/// ~~~
4131///
4132/// A different fitter can also be set via ROOT::Math::MinimizerOptions::SetDefaultMinimizer
4133/// (or TVirtualFitter::SetDefaultFitter).
4134/// For example ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");
4135/// will set the usage of the BFGS algorithm of the GSL multi-dimensional minimization
4136/// (implemented in libMathMore). ROOT::Math::MinimizerOptions can be used also to set other
4137/// default options, like maximum number of function calls, minimization tolerance or print
4138/// level. See the documentation of this class.
4139///
4140/// For fitting linear functions (containing the "++" sign" and polN functions,
4141/// the linear fitter is automatically initialized.
4142
4143TFitResultPtr TH1::Fit(TF1 *f1 ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
4144{
4145 // implementation of Fit method is in file hist/src/HFitImpl.cxx
4146 Foption_t fitOption;
4148
4149 // create range and minimizer options with default values
4150 ROOT::Fit::DataRange range(xxmin,xxmax);
4152
4153 // need to empty the buffer before
4154 // (t.b.d. do a ML unbinned fit with buffer data)
4155 if (fBuffer) BufferEmpty();
4156
4157 return ROOT::Fit::FitObject(this, f1 , fitOption , minOption, goption, range);
4158}
4159
4160////////////////////////////////////////////////////////////////////////////////
4161/// Display a panel with all histogram fit options.
4162///
4163/// See class TFitPanel for example
4164
4165void TH1::FitPanel()
4166{
4167 if (!gPad)
4168 gROOT->MakeDefCanvas();
4169
4170 if (!gPad) {
4171 Error("FitPanel", "Unable to create a default canvas");
4172 return;
4173 }
4174
4175
4176 // use plugin manager to create instance of TFitEditor
4177 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
4178 if (handler && handler->LoadPlugin() != -1) {
4179 if (handler->ExecPlugin(2, gPad, this) == 0)
4180 Error("FitPanel", "Unable to create the FitPanel");
4181 }
4182 else
4183 Error("FitPanel", "Unable to find the FitPanel plug-in");
4184}
4185
4186////////////////////////////////////////////////////////////////////////////////
4187/// Return an histogram containing the asymmetry of this histogram with h2,
4188/// where the asymmetry is defined as:
4189///
4190/// ~~~ {.cpp}
4191/// Asymmetry = (h1 - h2)/(h1 + h2) where h1 = this
4192/// ~~~
4193///
4194/// works for 1D, 2D, etc. histograms
4195/// c2 is an optional argument that gives a relative weight between the two
4196/// histograms, and dc2 is the error on this weight. This is useful, for example,
4197/// when forming an asymmetry between two histograms from 2 different data sets that
4198/// need to be normalized to each other in some way. The function calculates
4199/// the errors assuming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
4200///
4201/// example: assuming 'h1' and 'h2' are already filled
4202///
4203/// ~~~ {.cpp}
4204/// h3 = h1->GetAsymmetry(h2)
4205/// ~~~
4206///
4207/// then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
4208/// h1 and h2 are left intact.
4209///
4210/// Note that it is the user's responsibility to manage the created histogram.
4211/// The name of the returned histogram will be `Asymmetry_nameOfh1-nameOfh2`
4212///
4213/// code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
4214///
4215/// clone the histograms so top and bottom will have the
4216/// correct dimensions:
4217/// Sumw2 just makes sure the errors will be computed properly
4218/// when we form sums and ratios below.
4219
4221{
4222 TH1 *h1 = this;
4223 TString name = TString::Format("Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4224 TH1 *asym = (TH1*)Clone(name);
4225
4226 // set also the title
4227 TString title = TString::Format("(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4228 asym->SetTitle(title);
4229
4230 asym->Sumw2();
4231 Bool_t addStatus = TH1::AddDirectoryStatus();
4233 TH1 *top = (TH1*)asym->Clone();
4234 TH1 *bottom = (TH1*)asym->Clone();
4235 TH1::AddDirectory(addStatus);
4236
4237 // form the top and bottom of the asymmetry, and then divide:
4238 top->Add(h1,h2,1,-c2);
4239 bottom->Add(h1,h2,1,c2);
4240 asym->Divide(top,bottom);
4241
4242 Int_t xmax = asym->GetNbinsX();
4243 Int_t ymax = asym->GetNbinsY();
4244 Int_t zmax = asym->GetNbinsZ();
4245
4246 if (h1->fBuffer) h1->BufferEmpty(1);
4247 if (h2->fBuffer) h2->BufferEmpty(1);
4248 if (bottom->fBuffer) bottom->BufferEmpty(1);
4249
4250 // now loop over bins to calculate the correct errors
4251 // the reason this error calculation looks complex is because of c2
4252 for(Int_t i=1; i<= xmax; i++){
4253 for(Int_t j=1; j<= ymax; j++){
4254 for(Int_t k=1; k<= zmax; k++){
4255 Int_t bin = GetBin(i, j, k);
4256 // here some bin contents are written into variables to make the error
4257 // calculation a little more legible:
4259 Double_t b = h2->RetrieveBinContent(bin);
4260 Double_t bot = bottom->RetrieveBinContent(bin);
4261
4262 // make sure there are some events, if not, then the errors are set = 0
4263 // automatically.
4264 //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
4265 if(bot < 1e-6){}
4266 else{
4267 // computation of errors by Christos Leonidopoulos
4268 Double_t dasq = h1->GetBinErrorSqUnchecked(bin);
4269 Double_t dbsq = h2->GetBinErrorSqUnchecked(bin);
4270 Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4271 asym->SetBinError(i,j,k,error);
4272 }
4273 }
4274 }
4275 }
4276 delete top;
4277 delete bottom;
4278
4279 return asym;
4280}
4281
4282////////////////////////////////////////////////////////////////////////////////
4283/// Static function
4284/// return the default buffer size for automatic histograms
4285/// the parameter fgBufferSize may be changed via SetDefaultBufferSize
4286
4288{
4289 return fgBufferSize;
4290}
4291
4292////////////////////////////////////////////////////////////////////////////////
4293/// Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
4294/// see TH1::SetDefaultSumw2.
4295
4297{
4298 return fgDefaultSumw2;
4299}
4300
4301////////////////////////////////////////////////////////////////////////////////
4302/// Return the current number of entries.
4303
4305{
4306 if (fBuffer) {
4307 Int_t nentries = (Int_t) fBuffer[0];
4308 if (nentries > 0) return nentries;
4309 }
4310
4311 return fEntries;
4312}
4313
4314////////////////////////////////////////////////////////////////////////////////
4315/// Number of effective entries of the histogram.
4316///
4317/// \f[
4318/// neff = \frac{(\sum Weights )^2}{(\sum Weight^2 )}
4319/// \f]
4320///
4321/// In case of an unweighted histogram this number is equivalent to the
4322/// number of entries of the histogram.
4323/// For a weighted histogram, this number corresponds to the hypothetical number of unweighted entries
4324/// a histogram would need to have the same statistical power as this weighted histogram.
4325/// Note: The underflow/overflow are included if one has set the TH1::StatOverFlows flag
4326/// and if the statistics has been computed at filling time.
4327/// If a range is set in the histogram the number is computed from the given range.
4328
4330{
4331 Stat_t s[kNstat];
4332 this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
4333 return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4334}
4335
4336////////////////////////////////////////////////////////////////////////////////
4337/// Set highlight (enable/disable) mode for the histogram
4338/// by default highlight mode is disable
4339
4340void TH1::SetHighlight(Bool_t set)
4341{
4342 if (IsHighlight() == set) return;
4343 if (fDimension > 2) {
4344 Info("SetHighlight", "Supported only 1-D or 2-D histograms");
4345 return;
4346 }
4347
4348 if (!fPainter) {
4349 Info("SetHighlight", "Need to draw histogram first");
4350 return;
4351 }
4352 SetBit(kIsHighlight, set);
4354}
4355
4356////////////////////////////////////////////////////////////////////////////////
4357/// Redefines TObject::GetObjectInfo.
4358/// Displays the histogram info (bin number, contents, integral up to bin
4359/// corresponding to cursor position px,py
4360
4361char *TH1::GetObjectInfo(Int_t px, Int_t py) const
4362{
4363 return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
4364}
4365
4366////////////////////////////////////////////////////////////////////////////////
4367/// Return pointer to painter.
4368/// If painter does not exist, it is created
4369
4371{
4372 if (!fPainter) {
4373 TString opt = option;
4374 opt.ToLower();
4375 if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
4376 //try to create TGLHistPainter
4377 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
4378
4379 if (handler && handler->LoadPlugin() != -1)
4380 fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
4381 }
4382 }
4383
4385
4386 return fPainter;
4387}
4388
4389////////////////////////////////////////////////////////////////////////////////
4390/// Compute Quantiles for this histogram
4391/// Quantile x_q of a probability distribution Function F is defined as
4392///
4393/// ~~~ {.cpp}
4394/// F(x_q) = q with 0 <= q <= 1.
4395/// ~~~
4396///
4397/// For instance the median x_0.5 of a distribution is defined as that value
4398/// of the random variable for which the distribution function equals 0.5:
4399///
4400/// ~~~ {.cpp}
4401/// F(x_0.5) = Probability(x < x_0.5) = 0.5
4402/// ~~~
4403///
4404/// code from Eddy Offermann, Renaissance
4405///
4406/// \param[in] nprobSum maximum size of array q and size of array probSum (if given)
4407/// \param[in] probSum array of positions where quantiles will be computed.
4408/// - if probSum is null, probSum will be computed internally and will
4409/// have a size = number of bins + 1 in h. it will correspond to the
4410/// quantiles calculated at the lowest edge of the histogram (quantile=0) and
4411/// all the upper edges of the bins.
4412/// - if probSum is not null, it is assumed to contain at least nprobSum values.
4413/// \param[out] q array q filled with nq quantiles
4414/// \return value nq (<=nprobSum) with the number of quantiles computed
4415///
4416/// Note that the Integral of the histogram is automatically recomputed
4417/// if the number of entries is different of the number of entries when
4418/// the integral was computed last time. In case you do not use the Fill
4419/// functions to fill your histogram, but SetBinContent, you must call
4420/// TH1::ComputeIntegral before calling this function.
4421///
4422/// Getting quantiles q from two histograms and storing results in a TGraph,
4423/// a so-called QQ-plot
4424///
4425/// ~~~ {.cpp}
4426/// TGraph *gr = new TGraph(nprob);
4427/// h1->GetQuantiles(nprob,gr->GetX());
4428/// h2->GetQuantiles(nprob,gr->GetY());
4429/// gr->Draw("alp");
4430/// ~~~
4431///
4432/// Example:
4433///
4434/// ~~~ {.cpp}
4435/// void quantiles() {
4436/// // demo for quantiles
4437/// const Int_t nq = 20;
4438/// TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
4439/// h->FillRandom("gaus",5000);
4440///
4441/// Double_t xq[nq]; // position where to compute the quantiles in [0,1]
4442/// Double_t yq[nq]; // array to contain the quantiles
4443/// for (Int_t i=0;i<nq;i++) xq[i] = Float_t(i+1)/nq;
4444/// h->GetQuantiles(nq,yq,xq);
4445///
4446/// //show the original histogram in the top pad
4447/// TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
4448/// c1->Divide(1,2);
4449/// c1->cd(1);
4450/// h->Draw();
4451///
4452/// // show the quantiles in the bottom pad
4453/// c1->cd(2);
4454/// gPad->SetGrid();
4455/// TGraph *gr = new TGraph(nq,xq,yq);
4456/// gr->SetMarkerStyle(21);
4457/// gr->Draw("alp");
4458/// }
4459/// ~~~
4460
4461Int_t TH1::GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
4462{
4463 if (GetDimension() > 1) {
4464 Error("GetQuantiles","Only available for 1-d histograms");
4465 return 0;
4466 }
4467
4468 const Int_t nbins = GetXaxis()->GetNbins();
4469 if (!fIntegral) ComputeIntegral();
4470 if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4471
4472 Int_t i, ibin;
4473 Double_t *prob = (Double_t*)probSum;
4474 Int_t nq = nprobSum;
4475 if (probSum == 0) {
4476 nq = nbins+1;
4477 prob = new Double_t[nq];
4478 prob[0] = 0;
4479 for (i=1;i<nq;i++) {
4480 prob[i] = fIntegral[i]/fIntegral[nbins];
4481 }
4482 }
4483
4484 for (i = 0; i < nq; i++) {
4485 ibin = TMath::BinarySearch(nbins,fIntegral,prob[i]);
4486 while (ibin < nbins-1 && fIntegral[ibin+1] == prob[i]) {
4487 if (fIntegral[ibin+2] == prob[i]) ibin++;
4488 else break;
4489 }
4490 q[i] = GetBinLowEdge(ibin+1);
4491 const Double_t dint = fIntegral[ibin+1]-fIntegral[ibin];
4492 if (dint > 0) q[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4493 }
4494
4495 if (!probSum) delete [] prob;
4496 return nq;
4497}
4498
4499////////////////////////////////////////////////////////////////////////////////
4500/// Decode string choptin and fill fitOption structure.
4501
4502Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
4503{
4505 return 1;
4506}
4507
4508////////////////////////////////////////////////////////////////////////////////
4509/// Compute Initial values of parameters for a gaussian.
4510
4511void H1InitGaus()
4512{
4513 Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4514 Int_t bin;
4515 const Double_t sqrtpi = 2.506628;
4516
4517 // - Compute mean value and StdDev of the histogram in the given range
4519 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4520 Int_t hxfirst = hFitter->GetXfirst();
4521 Int_t hxlast = hFitter->GetXlast();
4522 Double_t valmax = curHist->GetBinContent(hxfirst);
4523 Double_t binwidx = curHist->GetBinWidth(hxfirst);
4524 allcha = sumx = sumx2 = 0;
4525 for (bin=hxfirst;bin<=hxlast;bin++) {
4526 x = curHist->GetBinCenter(bin);
4527 val = TMath::Abs(curHist->GetBinContent(bin));
4528 if (val > valmax) valmax = val;
4529 sumx += val*x;
4530 sumx2 += val*x*x;
4531 allcha += val;
4532 }
4533 if (allcha == 0) return;
4534 mean = sumx/allcha;
4535 stddev = sumx2/allcha - mean*mean;
4536 if (stddev > 0) stddev = TMath::Sqrt(stddev);
4537 else stddev = 0;
4538 if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4539 //if the distribution is really gaussian, the best approximation
4540 //is binwidx*allcha/(sqrtpi*stddev)
4541 //However, in case of non-gaussian tails, this underestimates
4542 //the normalisation constant. In this case the maximum value
4543 //is a better approximation.
4544 //We take the average of both quantities
4545 Double_t constant = 0.5*(valmax+binwidx*allcha/(sqrtpi*stddev));
4546
4547 //In case the mean value is outside the histo limits and
4548 //the StdDev is bigger than the range, we take
4549 // mean = center of bins
4550 // stddev = half range
4551 Double_t xmin = curHist->GetXaxis()->GetXmin();
4552 Double_t xmax = curHist->GetXaxis()->GetXmax();
4553 if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4554 mean = 0.5*(xmax+xmin);
4555 stddev = 0.5*(xmax-xmin);
4556 }
4557 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4558 f1->SetParameter(0,constant);
4559 f1->SetParameter(1,mean);
4560 f1->SetParameter(2,stddev);
4561 f1->SetParLimits(2,0,10*stddev);
4562}
4563
4564////////////////////////////////////////////////////////////////////////////////
4565/// Compute Initial values of parameters for an exponential.
4566
4567void H1InitExpo()
4568{
4569 Double_t constant, slope;
4570 Int_t ifail;
4572 Int_t hxfirst = hFitter->GetXfirst();
4573 Int_t hxlast = hFitter->GetXlast();
4574 Int_t nchanx = hxlast - hxfirst + 1;
4575
4576 H1LeastSquareLinearFit(-nchanx, constant, slope, ifail);
4577
4578 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4579 f1->SetParameter(0,constant);
4580 f1->SetParameter(1,slope);
4581
4582}
4583
4584////////////////////////////////////////////////////////////////////////////////
4585/// Compute Initial values of parameters for a polynom.
4586
4587void H1InitPolynom()
4588{
4589 Double_t fitpar[25];
4590
4592 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4593 Int_t hxfirst = hFitter->GetXfirst();
4594 Int_t hxlast = hFitter->GetXlast();
4595 Int_t nchanx = hxlast - hxfirst + 1;
4596 Int_t npar = f1->GetNpar();
4597
4598 if (nchanx <=1 || npar == 1) {
4599 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4600 fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4601 } else {
4602 H1LeastSquareFit( nchanx, npar, fitpar);
4603 }
4604 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4605}
4606
4607////////////////////////////////////////////////////////////////////////////////
4608/// Least squares lpolynomial fitting without weights.
4609///
4610/// \param[in] n number of points to fit
4611/// \param[in] m number of parameters
4612/// \param[in] a array of parameters
4613///
4614/// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
4615/// (E.Keil. revised by B.Schorr, 23.10.1981.)
4616
4618{
4619 const Double_t zero = 0.;
4620 const Double_t one = 1.;
4621 const Int_t idim = 20;
4622
4623 Double_t b[400] /* was [20][20] */;
4624 Int_t i, k, l, ifail;
4625 Double_t power;
4626 Double_t da[20], xk, yk;
4627
4628 if (m <= 2) {
4629 H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4630 return;
4631 }
4632 if (m > idim || m > n) return;
4633 b[0] = Double_t(n);
4634 da[0] = zero;
4635 for (l = 2; l <= m; ++l) {
4636 b[l-1] = zero;
4637 b[m + l*20 - 21] = zero;
4638 da[l-1] = zero;
4639 }
4641 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4642 Int_t hxfirst = hFitter->GetXfirst();
4643 Int_t hxlast = hFitter->GetXlast();
4644 for (k = hxfirst; k <= hxlast; ++k) {
4645 xk = curHist->GetBinCenter(k);
4646 yk = curHist->GetBinContent(k);
4647 power = one;
4648 da[0] += yk;
4649 for (l = 2; l <= m; ++l) {
4650 power *= xk;
4651 b[l-1] += power;
4652 da[l-1] += power*yk;
4653 }
4654 for (l = 2; l <= m; ++l) {
4655 power *= xk;
4656 b[m + l*20 - 21] += power;
4657 }
4658 }
4659 for (i = 3; i <= m; ++i) {
4660 for (k = i; k <= m; ++k) {
4661 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4662 }
4663 }
4664 H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
4665
4666 for (i=0; i<m; ++i) a[i] = da[i];
4667
4668}
4669
4670////////////////////////////////////////////////////////////////////////////////
4671/// Least square linear fit without weights.
4672///
4673/// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
4674/// (added to LSQ by B. Schorr, 15.02.1982.)
4675
4676void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
4677{
4678 Double_t xbar, ybar, x2bar;
4679 Int_t i, n;
4680 Double_t xybar;
4681 Double_t fn, xk, yk;
4682 Double_t det;
4683
4684 n = TMath::Abs(ndata);
4685 ifail = -2;
4686 xbar = ybar = x2bar = xybar = 0;
4688 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4689 Int_t hxfirst = hFitter->GetXfirst();
4690 Int_t hxlast = hFitter->GetXlast();
4691 for (i = hxfirst; i <= hxlast; ++i) {
4692 xk = curHist->GetBinCenter(i);
4693 yk = curHist->GetBinContent(i);
4694 if (ndata < 0) {
4695 if (yk <= 0) yk = 1e-9;
4696 yk = TMath::Log(yk);
4697 }
4698 xbar += xk;
4699 ybar += yk;
4700 x2bar += xk*xk;
4701 xybar += xk*yk;
4702 }
4703 fn = Double_t(n);
4704 det = fn*x2bar - xbar*xbar;
4705 ifail = -1;
4706 if (det <= 0) {
4707 a0 = ybar/fn;
4708 a1 = 0;
4709 return;
4710 }
4711 ifail = 0;
4712 a0 = (x2bar*ybar - xbar*xybar) / det;
4713 a1 = (fn*xybar - xbar*ybar) / det;
4714
4715}
4716
4717////////////////////////////////////////////////////////////////////////////////
4718/// Extracted from CERN Program library routine DSEQN.
4719///
4720/// Translated to C++ by Rene Brun
4721
4722void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b)
4723{
4724 Int_t a_dim1, a_offset, b_dim1, b_offset;
4725 Int_t nmjp1, i, j, l;
4726 Int_t im1, jp1, nm1, nmi;
4727 Double_t s1, s21, s22;
4728 const Double_t one = 1.;
4729
4730 /* Parameter adjustments */
4731 b_dim1 = idim;
4732 b_offset = b_dim1 + 1;
4733 b -= b_offset;
4734 a_dim1 = idim;
4735 a_offset = a_dim1 + 1;
4736 a -= a_offset;
4737
4738 if (idim < n) return;
4739
4740 ifail = 0;
4741 for (j = 1; j <= n; ++j) {
4742 if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
4743 a[j + j*a_dim1] = one / a[j + j*a_dim1];
4744 if (j == n) continue;
4745 jp1 = j + 1;
4746 for (l = jp1; l <= n; ++l) {
4747 a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4748 s1 = -a[l + (j+1)*a_dim1];
4749 for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4750 a[l + (j+1)*a_dim1] = -s1;
4751 }
4752 }
4753 if (k <= 0) return;
4754
4755 for (l = 1; l <= k; ++l) {
4756 b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
4757 }
4758 if (n == 1) return;
4759 for (l = 1; l <= k; ++l) {
4760 for (i = 2; i <= n; ++i) {
4761 im1 = i - 1;
4762 s21 = -b[i + l*b_dim1];
4763 for (j = 1; j <= im1; ++j) {
4764 s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
4765 }
4766 b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
4767 }
4768 nm1 = n - 1;
4769 for (i = 1; i <= nm1; ++i) {
4770 nmi = n - i;
4771 s22 = -b[nmi + l*b_dim1];
4772 for (j = 1; j <= i; ++j) {
4773 nmjp1 = n - j + 1;
4774 s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
4775 }
4776 b[nmi + l*b_dim1] = -s22;
4777 }
4778 }
4779}
4780
4781////////////////////////////////////////////////////////////////////////////////
4782/// Return Global bin number corresponding to binx,y,z.
4783///
4784/// 2-D and 3-D histograms are represented with a one dimensional
4785/// structure.
4786/// This has the advantage that all existing functions, such as
4787/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
4788///
4789/// In case of a TH1x, returns binx directly.
4790/// see TH1::GetBinXYZ for the inverse transformation.
4791///
4792/// Convention for numbering bins
4793///
4794/// For all histogram types: nbins, xlow, xup
4795///
4796/// - bin = 0; underflow bin
4797/// - bin = 1; first bin with low-edge xlow INCLUDED
4798/// - bin = nbins; last bin with upper-edge xup EXCLUDED
4799/// - bin = nbins+1; overflow bin
4800///
4801/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4802/// For example, assuming a 3-D histogram with binx,biny,binz, the function
4803///
4804/// ~~~ {.cpp}
4805/// Int_t bin = h->GetBin(binx,biny,binz);
4806/// ~~~
4807///
4808/// returns a global/linearized bin number. This global bin is useful
4809/// to access the bin information independently of the dimension.
4810
4811Int_t TH1::GetBin(Int_t binx, Int_t, Int_t) const
4812{
4813 Int_t ofx = fXaxis.GetNbins() + 1; // overflow bin
4814 if (binx < 0) binx = 0;
4815 if (binx > ofx) binx = ofx;
4816
4817 return binx;
4818}
4819
4820////////////////////////////////////////////////////////////////////////////////
4821/// Return binx, biny, binz corresponding to the global bin number globalbin
4822/// see TH1::GetBin function above
4823
4824void TH1::GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz) const
4825{
4826 Int_t nx = fXaxis.GetNbins()+2;
4827 Int_t ny = fYaxis.GetNbins()+2;
4828
4829 if (GetDimension() == 1) {
4830 binx = binglobal%nx;
4831 biny = 0;
4832 binz = 0;
4833 return;
4834 }
4835 if (GetDimension() == 2) {
4836 binx = binglobal%nx;
4837 biny = ((binglobal-binx)/nx)%ny;
4838 binz = 0;
4839 return;
4840 }
4841 if (GetDimension() == 3) {
4842 binx = binglobal%nx;
4843 biny = ((binglobal-binx)/nx)%ny;
4844 binz = ((binglobal-binx)/nx -biny)/ny;
4845 }
4846}
4847
4848////////////////////////////////////////////////////////////////////////////////
4849/// Return a random number distributed according the histogram bin contents.
4850/// This function checks if the bins integral exists. If not, the integral
4851/// is evaluated, normalized to one.
4852///
4853/// The integral is automatically recomputed if the number of entries
4854/// is not the same then when the integral was computed.
4855/// NB Only valid for 1-d histograms. Use GetRandom2 or 3 otherwise.
4856/// If the histogram has a bin with negative content a NaN is returned
4857
4859{
4860 if (fDimension > 1) {
4861 Error("GetRandom","Function only valid for 1-d histograms");
4862 return 0;
4863 }
4864 Int_t nbinsx = GetNbinsX();
4865 Double_t integral = 0;
4866 // compute integral checking that all bins have positive content (see ROOT-5894)
4867 if (fIntegral) {
4868 if (fIntegral[nbinsx+1] != fEntries) integral = ((TH1*)this)->ComputeIntegral(true);
4869 else integral = fIntegral[nbinsx];
4870 } else {
4871 integral = ((TH1*)this)->ComputeIntegral(true);
4872 }
4873 if (integral == 0) return 0;
4874 // return a NaN in case some bins have negative content
4875 if (integral == TMath::QuietNaN() ) return TMath::QuietNaN();
4876
4877 Double_t r1 = gRandom->Rndm();
4878 Int_t ibin = TMath::BinarySearch(nbinsx,fIntegral,r1);
4879 Double_t x = GetBinLowEdge(ibin+1);
4880 if (r1 > fIntegral[ibin]) x +=
4881 GetBinWidth(ibin+1)*(r1-fIntegral[ibin])/(fIntegral[ibin+1] - fIntegral[ibin]);
4882 return x;
4883}
4884
4885////////////////////////////////////////////////////////////////////////////////
4886/// Return content of bin number bin.
4887///
4888/// Implemented in TH1C,S,F,D
4889///
4890/// Convention for numbering bins
4891///
4892/// For all histogram types: nbins, xlow, xup
4893///
4894/// - bin = 0; underflow bin
4895/// - bin = 1; first bin with low-edge xlow INCLUDED
4896/// - bin = nbins; last bin with upper-edge xup EXCLUDED
4897/// - bin = nbins+1; overflow bin
4898///
4899/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4900/// For example, assuming a 3-D histogram with binx,biny,binz, the function
4901///
4902/// ~~~ {.cpp}
4903/// Int_t bin = h->GetBin(binx,biny,binz);
4904/// ~~~
4905///
4906/// returns a global/linearized bin number. This global bin is useful
4907/// to access the bin information independently of the dimension.
4908
4910{
4911 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
4912 if (bin < 0) bin = 0;
4913 if (bin >= fNcells) bin = fNcells-1;
4914
4915 return RetrieveBinContent(bin);
4916}
4917
4918////////////////////////////////////////////////////////////////////////////////
4919/// Compute first binx in the range [firstx,lastx] for which
4920/// diff = abs(bin_content-c) <= maxdiff
4921///
4922/// In case several bins in the specified range with diff=0 are found
4923/// the first bin found is returned in binx.
4924/// In case several bins in the specified range satisfy diff <=maxdiff
4925/// the bin with the smallest difference is returned in binx.
4926/// In all cases the function returns the smallest difference.
4927///
4928/// NOTE1: if firstx <= 0, firstx is set to bin 1
4929/// if (lastx < firstx then firstx is set to the number of bins
4930/// ie if firstx=0 and lastx=0 (default) the search is on all bins.
4931///
4932/// NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
4933
4934Double_t TH1::GetBinWithContent(Double_t c, Int_t &binx, Int_t firstx, Int_t lastx,Double_t maxdiff) const
4935{
4936 if (fDimension > 1) {
4937 binx = 0;
4938 Error("GetBinWithContent","function is only valid for 1-D histograms");
4939 return 0;
4940 }
4941
4942 if (fBuffer) ((TH1*)this)->BufferEmpty();
4943
4944 if (firstx <= 0) firstx = 1;
4945 if (lastx < firstx) lastx = fXaxis.GetNbins();
4946 Int_t binminx = 0;
4947 Double_t diff, curmax = 1.e240;
4948 for (Int_t i=firstx;i<=lastx;i++) {
4949 diff = TMath::Abs(RetrieveBinContent(i)-c);
4950 if (diff <= 0) {binx = i; return diff;}
4951 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
4952 }
4953 binx = binminx;
4954 return curmax;
4955}
4956
4957////////////////////////////////////////////////////////////////////////////////
4958/// Given a point x, approximates the value via linear interpolation
4959/// based on the two nearest bin centers
4960///
4961/// Andy Mastbaum 10/21/08
4962
4964{
4965 if (fBuffer) ((TH1*)this)->BufferEmpty();
4966
4967 Int_t xbin = fXaxis.FindFixBin(x);
4968 Double_t x0,x1,y0,y1;
4969
4970 if(x<=GetBinCenter(1)) {
4971 return RetrieveBinContent(1);
4972 } else if(x>=GetBinCenter(GetNbinsX())) {
4973 return RetrieveBinContent(GetNbinsX());
4974 } else {
4975 if(x<=GetBinCenter(xbin)) {
4976 y0 = RetrieveBinContent(xbin-1);
4977 x0 = GetBinCenter(xbin-1);
4978 y1 = RetrieveBinContent(xbin);
4979 x1 = GetBinCenter(xbin);
4980 } else {
4981 y0 = RetrieveBinContent(xbin);
4982 x0 = GetBinCenter(xbin);
4983 y1 = RetrieveBinContent(xbin+1);
4984 x1 = GetBinCenter(xbin+1);
4985 }
4986 return y0 + (x-x0)*((y1-y0)/(x1-x0));
4987 }
4988}
4989
4990////////////////////////////////////////////////////////////////////////////////
4991/// 2d Interpolation. Not yet implemented.
4992
4994{
4995 Error("Interpolate","This function must be called with 1 argument for a TH1");
4996 return 0;
4997}
4998
4999////////////////////////////////////////////////////////////////////////////////
5000/// 3d Interpolation. Not yet implemented.
5001
5003{
5004 Error("Interpolate","This function must be called with 1 argument for a TH1");
5005 return 0;
5006}
5007
5008///////////////////////////////////////////////////////////////////////////////
5009/// Check if an histogram is empty
5010/// (this a protected method used mainly by TH1Merger )
5011
5012Bool_t TH1::IsEmpty() const
5013{
5014 // if fTsumw or fentries are not zero histogram is not empty
5015 // need to use GetEntries() instead of fEntries in case of bugger histograms
5016 // so we will flash the buffer
5017 if (fTsumw != 0) return kFALSE;
5018 if (GetEntries() != 0) return kFALSE;
5019 // case fTSumw == 0 amd entries are also zero
5020 // this should not really happening, but if one sets content by hand
5021 // it can happen. a call to ResetStats() should be done in such cases
5022 double sumw = 0;
5023 for (int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
5024 return (sumw != 0) ? kFALSE : kTRUE;
5025}
5026
5027////////////////////////////////////////////////////////////////////////////////
5028/// Return true if the bin is overflow.
5029
5030Bool_t TH1::IsBinOverflow(Int_t bin, Int_t iaxis) const
5031{
5032 Int_t binx, biny, binz;
5033 GetBinXYZ(bin, binx, biny, binz);
5034
5035 if (iaxis == 0) {
5036 if ( fDimension == 1 )
5037 return binx >= GetNbinsX() + 1;
5038 if ( fDimension == 2 )
5039 return (binx >= GetNbinsX() + 1) ||
5040 (biny >= GetNbinsY() + 1);
5041 if ( fDimension == 3 )
5042 return (binx >= GetNbinsX() + 1) ||
5043 (biny >= GetNbinsY() + 1) ||
5044 (binz >= GetNbinsZ() + 1);
5045 return kFALSE;
5046 }
5047 if (iaxis == 1)
5048 return binx >= GetNbinsX() + 1;
5049 if (iaxis == 2)
5050 return biny >= GetNbinsY() + 1;
5051 if (iaxis == 3)
5052 return binz >= GetNbinsZ() + 1;
5053
5054 Error("IsBinOverflow","Invalid axis value");
5055 return kFALSE;
5056}
5057
5058////////////////////////////////////////////////////////////////////////////////
5059/// Return true if the bin is underflow.
5060/// If iaxis = 0 make OR with all axes otherwise check only for the given axis
5061
5062Bool_t TH1::IsBinUnderflow(Int_t bin, Int_t iaxis) const
5063{
5064 Int_t binx, biny, binz;
5065 GetBinXYZ(bin, binx, biny, binz);
5066
5067 if (iaxis == 0) {
5068 if ( fDimension == 1 )
5069 return (binx <= 0);
5070 else if ( fDimension == 2 )
5071 return (binx <= 0 || biny <= 0);
5072 else if ( fDimension == 3 )
5073 return (binx <= 0 || biny <= 0 || binz <= 0);
5074 else
5075 return kFALSE;
5076 }
5077 if (iaxis == 1)
5078 return (binx <= 0);
5079 if (iaxis == 2)
5080 return (biny <= 0);
5081 if (iaxis == 3)
5082 return (binz <= 0);
5083
5084 Error("IsBinUnderflow","Invalid axis value");
5085 return kFALSE;
5086}
5087
5088////////////////////////////////////////////////////////////////////////////////
5089/// Reduce the number of bins for the axis passed in the option to the number of bins having a label.
5090/// The method will remove only the extra bins existing after the last "labeled" bin.
5091/// Note that if there are "un-labeled" bins present between "labeled" bins they will not be removed
5092
5094{
5095 Int_t iaxis = AxisChoice(ax);
5096 TAxis *axis = 0;
5097 if (iaxis == 1) axis = GetXaxis();
5098 if (iaxis == 2) axis = GetYaxis();
5099 if (iaxis == 3) axis = GetZaxis();
5100 if (!axis) {
5101 Error("LabelsDeflate","Invalid axis option %s",ax);
5102 return;
5103 }
5104 if (!axis->GetLabels()) return;
5105
5106 // find bin with last labels
5107 // bin number is object ID in list of labels
5108 // therefore max bin number is number of bins of the deflated histograms
5109 TIter next(axis->GetLabels());
5110 TObject *obj;
5111 Int_t nbins = 0;
5112 while ((obj = next())) {
5113 Int_t ibin = obj->GetUniqueID();
5114 if (ibin > nbins) nbins = ibin;
5115 }
5116 if (nbins < 1) nbins = 1;
5117
5118 // Do nothing in case it was the last bin
5119 if (nbins==axis->GetNbins()) return;
5120
5121 TH1 *hold = (TH1*)IsA()->New();
5122 R__ASSERT(hold);
5123 hold->SetDirectory(0);
5124 Copy(*hold);
5125
5126 Bool_t timedisp = axis->GetTimeDisplay();
5127 Double_t xmin = axis->GetXmin();
5128 Double_t xmax = axis->GetBinUpEdge(nbins);
5129 if (xmax <= xmin) xmax = xmin +nbins;
5130 axis->SetRange(0,0);
5131 axis->Set(nbins,xmin,xmax);
5132 SetBinsLength(-1); // reset the number of cells
5133 Int_t errors = fSumw2.fN;
5134 if (errors) fSumw2.Set(fNcells);
5135 axis->SetTimeDisplay(timedisp);
5136 // reset histogram content
5137 Reset("ICE");
5138
5139 //now loop on all bins and refill
5140 // NOTE that if the bins without labels have content
5141 // it will be put in the underflow/overflow.
5142 // For this reason we use AddBinContent method
5143 Double_t oldEntries = fEntries;
5144 Int_t bin,binx,biny,binz;
5145 for (bin=0; bin < hold->fNcells; ++bin) {
5146 hold->GetBinXYZ(bin,binx,biny,binz);
5147 Int_t ibin = GetBin(binx,biny,binz);
5148 Double_t cu = hold->RetrieveBinContent(bin);
5149 AddBinContent(ibin,cu);
5150 if (errors) {
5151 fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5152 }
5153 }
5154 fEntries = oldEntries;
5155 delete hold;
5156}
5157
5158////////////////////////////////////////////////////////////////////////////////
5159/// Double the number of bins for axis.
5160/// Refill histogram
5161/// This function is called by TAxis::FindBin(const char *label)
5162
5164{
5165 Int_t iaxis = AxisChoice(ax);
5166 TAxis *axis = 0;
5167 if (iaxis == 1) axis = GetXaxis();
5168 if (iaxis == 2) axis = GetYaxis();
5169 if (iaxis == 3) axis = GetZaxis();
5170 if (!axis) return;
5171
5172 TH1 *hold = (TH1*)IsA()->New();;
5173 hold->SetDirectory(0);
5174 Copy(*hold);
5175
5176 Bool_t timedisp = axis->GetTimeDisplay();
5177 Int_t nbins = axis->GetNbins();
5178 Double_t xmin = axis->GetXmin();
5179 Double_t xmax = axis->GetXmax();
5180 xmax = xmin + 2*(xmax-xmin);
5181 axis->SetRange(0,0);
5182 // double the bins and recompute ncells
5183 axis->Set(2*nbins,xmin,xmax);
5184 SetBinsLength(-1);
5185 Int_t errors = fSumw2.fN;
5186 if (errors) fSumw2.Set(fNcells);
5187 axis->SetTimeDisplay(timedisp);
5188
5189 Reset("ICE"); // reset content and error
5190
5191 //now loop on all bins and refill
5192 Double_t oldEntries = fEntries;
5193 Int_t bin,ibin,binx,biny,binz;
5194 for (ibin =0; ibin < hold->fNcells; ibin++) {
5195 // get the binx,y,z values . The x-y-z (axis) bin values will stay the same between new-old after the expanding
5196 hold->GetBinXYZ(ibin,binx,biny,binz);
5197 bin = GetBin(binx,biny,binz);
5198
5199 // underflow and overflow will be cleaned up because their meaning has been altered
5200 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5201 continue;
5202 }
5203 else {
5204 AddBinContent(bin, hold->RetrieveBinContent(ibin));
5205 if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5206 }
5207 }
5208 fEntries = oldEntries;
5209 delete hold;
5210}
5211
5212////////////////////////////////////////////////////////////////////////////////
5213/// Set option(s) to draw axis with labels
5214/// \param[in] option
5215/// - "a" sort by alphabetic order
5216/// - ">" sort by decreasing values
5217/// - "<" sort by increasing values
5218/// - "h" draw labels horizontal
5219/// - "v" draw labels vertical
5220/// - "u" draw labels up (end of label right adjusted)
5221/// - "d" draw labels down (start of label left adjusted)
5222/// \param[in] ax axis
5223
5224void TH1::LabelsOption(Option_t *option, Option_t *ax)
5225{
5226 Int_t iaxis = AxisChoice(ax);
5227 TAxis *axis = 0;
5228 if (iaxis == 1) axis = GetXaxis();
5229 if (iaxis == 2) axis = GetYaxis();
5230 if (iaxis == 3) axis = GetZaxis();
5231 if (!axis) return;
5232 THashList *labels = axis->GetLabels();
5233 if (!labels) {
5234 Warning("LabelsOption","Cannot sort. No labels");
5235 return;
5236 }
5237 TString opt = option;
5238 opt.ToLower();
5239 if (opt.Contains("h")) {
5244 }
5245 if (opt.Contains("v")) {
5250 }
5251 if (opt.Contains("u")) {
5252 axis->SetBit(TAxis::kLabelsUp);
5256 }
5257 if (opt.Contains("d")) {
5262 }
5263 Int_t sort = -1;
5264 if (opt.Contains("a")) sort = 0;
5265 if (opt.Contains(">")) sort = 1;
5266 if (opt.Contains("<")) sort = 2;
5267 if (sort < 0) return;
5268 if (sort > 0 && GetDimension() > 2) {
5269 Error("LabelsOption","Sorting by value not implemented for 3-D histograms");
5270 return;
5271 }
5272
5273 Double_t entries = fEntries;
5274 Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5275 std::vector<Int_t> a(n+2);
5276
5277 Int_t i,j,k;
5278 std::vector<Double_t> cont;
5279 std::vector<Double_t> errors;
5280 THashList *labold = new THashList(labels->GetSize(),1);
5281 TIter nextold(labels);
5282 TObject *obj;
5283 while ((obj=nextold())) {
5284 labold->Add(obj);
5285 }
5286 labels->Clear();
5287
5288 // delete buffer if it is there since bins will be reordered.
5289 if (fBuffer) BufferEmpty(1);
5290
5291 if (sort > 0) {
5292 //---sort by values of bins
5293 if (GetDimension() == 1) {
5294 cont.resize(n);
5295 if (fSumw2.fN) errors.resize(n);
5296 for (i=1;i<=n;i++) {
5297 cont[i-1] = GetBinContent(i);
5298 if (!errors.empty()) errors[i-1] = GetBinError(i);
5299 }
5300 if (sort ==1) TMath::Sort(n,cont.data(),a.data(),kTRUE); //sort by decreasing values
5301 else TMath::Sort(n,cont.data(),a.data(),kFALSE); //sort by increasing values
5302 for (i=1;i<=n;i++) {
5303 SetBinContent(i,cont[a[i-1]]);
5304 if (!errors.empty()) SetBinError(i,errors[a[i-1]]);
5305 }
5306 for (i=1;i<=n;i++) {
5307 obj = labold->At(a[i-1]);
5308 labels->Add(obj);
5309 obj->SetUniqueID(i);
5310 }
5311 } else if (GetDimension()== 2) {
5312 std::vector<Double_t> pcont(n+2);
5313 Int_t nx = fXaxis.GetNbins();
5314 Int_t ny = fYaxis.GetNbins();
5315 cont.resize( (nx+2)*(ny+2));
5316 if (fSumw2.fN) errors.resize( (nx+2)*(ny+2));
5317 for (i=1;i<=nx;i++) {
5318 for (j=1;j<=ny;j++) {
5319 cont[i+nx*j] = GetBinContent(i,j);
5320 if (!errors.empty()) errors[i+nx*j] = GetBinError(i,j);
5321 if (axis == GetXaxis()) k = i;
5322 else k = j;
5323 pcont[k-1] += cont[i+nx*j];
5324 }
5325 }
5326 if (sort ==1) TMath::Sort(n,pcont.data(),a.data(),kTRUE); //sort by decreasing values
5327 else TMath::Sort(n,pcont.data(),a.data(),kFALSE); //sort by increasing values
5328 for (i=0;i<n;i++) {
5329 obj = labold->At(a[i]);
5330 labels->Add(obj);
5331 obj->SetUniqueID(i+1);
5332 }
5333 if (axis == GetXaxis()) {
5334 for (i=1;i<=n;i++) {
5335 for (j=1;j<=ny;j++) {
5336 SetBinContent(i,j,cont[a[i-1]+1+nx*j]);
5337 if (!errors.empty()) SetBinError(i,j,errors[a[i-1]+1+nx*j]);
5338 }
5339 }
5340 }
5341 else {
5342 // using y axis
5343 for (i=1;i<=nx;i++) {
5344 for (j=1;j<=n;j++) {
5345 SetBinContent(i,j,cont[i+nx*(a[j-1]+1)]);
5346 if (!errors.empty()) SetBinError(i,j,errors[i+nx*(a[j-1]+1)]);
5347 }
5348 }
5349 }
5350 } else {
5351 //to be implemented for 3d
5352 }
5353 } else {
5354 //---alphabetic sort
5355 const UInt_t kUsed = 1<<18;
5356 TObject *objk=0;
5357 a[0] = 0;
5358 a[n+1] = n+1;
5359 for (i=1;i<=n;i++) {
5360 const char *label = "zzzzzzzzzzzz";
5361 for (j=1;j<=n;j++) {
5362 obj = labold->At(j-1);
5363 if (!obj) continue;
5364 if (obj->TestBit(kUsed)) continue;
5365 //use strcasecmp for case non-sensitive sort (may be an option)
5366 if (strcmp(label,obj->GetName()) < 0) continue;
5367 objk = obj;
5368 a[i] = j;
5369 label = obj->GetName();
5370 }
5371 if (objk) {
5372 objk->SetUniqueID(i);
5373 labels->Add(objk);
5374 objk->SetBit(kUsed);
5375 }
5376 }
5377 for (i=1;i<=n;i++) {
5378 obj = labels->At(i-1);
5379 if (!obj) continue;
5380 obj->ResetBit(kUsed);
5381 }
5382
5383 if (GetDimension() == 1) {
5384 cont.resize(n+2);
5385 if (fSumw2.fN) errors.resize(n+2);
5386 for (i=1;i<=n;i++) {
5387 cont[i] = GetBinContent(a[i]);
5388 if (!errors.empty()) errors[i] = GetBinError(a[i]);
5389 }
5390 for (i=1;i<=n;i++) {
5391 SetBinContent(i,cont[i]);
5392 if (!errors.empty()) SetBinError(i,errors[i]);
5393 }
5394 } else if (GetDimension()== 2) {
5395 Int_t nx = fXaxis.GetNbins()+2;
5396 Int_t ny = fYaxis.GetNbins()+2;
5397 cont.resize(nx*ny);
5398 if (fSumw2.fN) errors.resize(nx*ny);
5399 for (i=0;i<nx;i++) {
5400 for (j=0;j<ny;j++) {
5401 cont[i+nx*j] = GetBinContent(i,j);
5402 if (!errors.empty()) errors[i+nx*j] = GetBinError(i,j);
5403 }
5404 }
5405 if (axis == GetXaxis()) {
5406 for (i=1;i<=n;i++) {
5407 for (j=0;j<ny;j++) {
5408 SetBinContent(i,j,cont[a[i]+nx*j]);
5409 if (!errors.empty()) SetBinError(i,j,errors[a[i]+nx*j]);
5410 }
5411 }
5412 } else {
5413 for (i=0;i<nx;i++) {
5414 for (j=1;j<=n;j++) {
5415 SetBinContent(i,j,cont[i+nx*a[j]]);
5416 if (!errors.empty()) SetBinError(i,j,errors[i+nx*a[j]]);
5417 }
5418 }
5419 }
5420 } else {
5421 Int_t nx = fXaxis.GetNbins()+2;
5422 Int_t ny = fYaxis.GetNbins()+2;
5423 Int_t nz = fZaxis.GetNbins()+2;
5424 cont.resize(nx*ny*nz);
5425 if (fSumw2.fN) errors.resize(nx*ny*nz);
5426 for (i=0;i<nx;i++) {
5427 for (j=0;j<ny;j++) {
5428 for (k=0;k<nz;k++) {
5429 cont[i+nx*(j+ny*k)] = GetBinContent(i,j,k);
5430 if (!errors.empty()) errors[i+nx*(j+ny*k)] = GetBinError(i,j,k);
5431 }
5432 }
5433 }
5434 if (axis == GetXaxis()) {
5435 // labels on x axis
5436 for (i=1;i<=n;i++) {
5437 for (j=0;j<ny;j++) {
5438 for (k=0;k<nz;k++) {
5439 SetBinContent(i,j,k,cont[a[i]+nx*(j+ny*k)]);
5440 if (!errors.empty()) SetBinError(i,j,k,errors[a[i]+nx*(j+ny*k)]);
5441 }
5442 }
5443 }
5444 }
5445 else if (axis == GetYaxis()) {
5446 // labels on y axis
5447 for (i=0;i<nx;i++) {
5448 for (j=1;j<=n;j++) {
5449 for (k=0;k<nz;k++) {
5450 SetBinContent(i,j,k,cont[i+nx*(a[j]+ny*k)]);
5451 if (!errors.empty()) SetBinError(i,j,k,errors[i+nx*(a[j]+ny*k)]);
5452 }
5453 }
5454 }
5455 }
5456 else {
5457 // labels on z axis
5458 for (i=0;i<nx;i++) {
5459 for (j=0;j<ny;j++) {
5460 for (k=1;k<=n;k++) {
5461 SetBinContent(i,j,k,cont[i+nx*(j+ny*a[k])]);
5462 if (!errors.empty()) SetBinError(i,j,k,errors[i+nx*(j+ny*a[k])]);
5463 }
5464 }
5465 }
5466 }
5467 }
5468 }
5469 fEntries = entries;
5470 delete labold;
5471}
5472
5473////////////////////////////////////////////////////////////////////////////////
5474/// Test if two double are almost equal.
5475
5476static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5477{
5478 return TMath::Abs(a - b) < epsilon;
5479}
5480
5481////////////////////////////////////////////////////////////////////////////////
5482/// Test if a double is almost an integer.
5483
5484static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5485{
5486 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5488}
5489
5490////////////////////////////////////////////////////////////////////////////////
5491/// Test if the binning is equidistant.
5492
5493static inline bool IsEquidistantBinning(const TAxis& axis)
5494{
5495 // check if axis bin are equals
5496 if (!axis.GetXbins()->fN) return true; //
5497 // not able to check if there is only one axis entry
5498 bool isEquidistant = true;
5499 const Double_t firstBinWidth = axis.GetBinWidth(1);
5500 for (int i = 1; i < axis.GetNbins(); ++i) {
5501 const Double_t binWidth = axis.GetBinWidth(i);
5502 const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5503 isEquidistant &= match;
5504 if (!match)
5505 break;
5506 }
5507 return isEquidistant;
5508}
5509
5510////////////////////////////////////////////////////////////////////////////////
5511/// Same limits and bins.
5512
5513Bool_t TH1::SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2){
5514 return axis1.GetNbins() == axis2.GetNbins() &&
5515 TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
5516 TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
5517}
5518
5519////////////////////////////////////////////////////////////////////////////////
5520/// Finds new limits for the axis for the Merge function.
5521/// returns false if the limits are incompatible
5522
5523Bool_t TH1::RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
5524{
5525 if (SameLimitsAndNBins(destAxis, anAxis))
5526 return kTRUE;
5527
5528 if (!IsEquidistantBinning(destAxis) || !IsEquidistantBinning(anAxis))
5529 return kFALSE; // not equidistant user binning not supported
5530
5531 Double_t width1 = destAxis.GetBinWidth(0);
5532 Double_t width2 = anAxis.GetBinWidth(0);
5533 if (width1 == 0 || width2 == 0)
5534 return kFALSE; // no binning not supported
5535
5536 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
5537 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
5538 Double_t width = TMath::Max(width1, width2);
5539
5540 // check the bin size
5541 if (!AlmostInteger(width/width1) || !AlmostInteger(width/width2))
5542 return kFALSE;
5543
5544 // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
5545 // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
5546
5547
5548 // check the limits
5549 Double_t delta;
5550 delta = (destAxis.GetXmin() - xmin)/width1;
5551 if (!AlmostInteger(delta))
5552 xmin -= (TMath::Ceil(delta) - delta)*width1;
5553
5554 delta = (anAxis.GetXmin() - xmin)/width2;
5555 if (!AlmostInteger(delta))
5556 xmin -= (TMath::Ceil(delta) - delta)*width2;
5557
5558
5559 delta = (destAxis.GetXmin() - xmin)/width1;
5560 if (!AlmostInteger(delta))
5561 return kFALSE;
5562
5563
5564 delta = (xmax - destAxis.GetXmax())/width1;
5565 if (!AlmostInteger(delta))
5566 xmax += (TMath::Ceil(delta) - delta)*width1;
5567
5568
5569 delta = (xmax - anAxis.GetXmax())/width2;
5570 if (!AlmostInteger(delta))
5571 xmax += (TMath::Ceil(delta) - delta)*width2;
5572
5573
5574 delta = (xmax - destAxis.GetXmax())/width1;
5575 if (!AlmostInteger(delta))
5576 return kFALSE;
5577#ifdef DEBUG
5578 if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
5579 printf("TH1::RecomputeAxisLimits - Impossible\n");
5580 return kFALSE;
5581 }
5582#endif
5583
5584
5585 destAxis.Set(TMath::Nint((xmax - xmin)/width), xmin, xmax);
5586
5587 //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
5588
5589 return kTRUE;
5590}
5591
5592////////////////////////////////////////////////////////////////////////////////
5593/// Add all histograms in the collection to this histogram.
5594/// This function computes the min/max for the x axis,
5595/// compute a new number of bins, if necessary,
5596/// add bin contents, errors and statistics.
5597/// If all histograms have bin labels, bins with identical labels
5598/// will be merged, no matter what their order is.
5599/// If overflows are present and limits are different the function will fail.
5600/// The function returns the total number of entries in the result histogram
5601/// if the merge is successful, -1 otherwise.
5602///
5603/// Possible option:
5604/// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
5605/// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
5606/// (enabled by default) slows down the merging
5607///
5608/// IMPORTANT remark. The axis x may have different number
5609/// of bins and different limits, BUT the largest bin width must be
5610/// a multiple of the smallest bin width and the upper limit must also
5611/// be a multiple of the bin width.
5612/// Example:
5613///
5614/// ~~~ {.cpp}
5615/// void atest() {
5616/// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
5617/// TH1F *h2 = new TH1F("h2","h2",220,0,110);
5618/// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
5619/// TRandom r;
5620/// for (Int_t i=0;i<10000;i++) {
5621/// h1->Fill(r.Gaus(-55,10));
5622/// h2->Fill(r.Gaus(55,10));
5623/// h3->Fill(r.Gaus(0,10));
5624/// }
5625///
5626/// TList *list = new TList;
5627/// list->Add(h1);
5628/// list->Add(h2);
5629/// list->Add(h3);
5630/// TH1F *h = (TH1F*)h1->Clone("h");
5631/// h->Reset();
5632/// h->Merge(list);
5633/// h->Draw();
5634/// }
5635/// ~~~
5636
5638{
5639 if (!li) return 0;
5640 if (li->IsEmpty()) return (Long64_t) GetEntries();
5641
5642 // use TH1Merger class
5643 TH1Merger merger(*this,*li,opt);
5644 Bool_t ret = merger();
5645
5646 return (ret) ? GetEntries() : -1;
5647}
5648
5649
5650////////////////////////////////////////////////////////////////////////////////
5651/// Performs the operation:
5652///
5653/// `this = this*c1*f1`
5654///
5655/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
5656///
5657/// Only bins inside the function range are recomputed.
5658/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5659/// you should call Sumw2 before making this operation.
5660/// This is particularly important if you fit the histogram after TH1::Multiply
5661///
5662/// The function return kFALSE if the Multiply operation failed
5663
5665{
5666 if (!f1) {
5667 Error("Multiply","Attempt to multiply by a non-existing function");
5668 return kFALSE;
5669 }
5670
5671 // delete buffer if it is there since it will become invalid
5672 if (fBuffer) BufferEmpty(1);
5673
5674 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
5675 Int_t ny = GetNbinsY() + 2;
5676 Int_t nz = GetNbinsZ() + 2;
5677 if (fDimension < 2) ny = 1;
5678 if (fDimension < 3) nz = 1;
5679
5680 // reset min-maximum
5681 SetMinimum();
5682 SetMaximum();
5683
5684 // - Loop on bins (including underflows/overflows)
5685 Double_t xx[3];
5686 Double_t *params = 0;
5687 f1->InitArgs(xx,params);
5688
5689 for (Int_t binz = 0; binz < nz; ++binz) {
5690 xx[2] = fZaxis.GetBinCenter(binz);
5691 for (Int_t biny = 0; biny < ny; ++biny) {
5692 xx[1] = fYaxis.GetBinCenter(biny);
5693 for (Int_t binx = 0; binx < nx; ++binx) {
5694 xx[0] = fXaxis.GetBinCenter(binx);
5695 if (!f1->IsInside(xx)) continue;
5697 Int_t bin = binx + nx * (biny + ny *binz);
5698 Double_t cu = c1*f1->EvalPar(xx);
5699 if (TF1::RejectedPoint()) continue;
5700 UpdateBinContent(bin, RetrieveBinContent(bin) * cu);
5701 if (fSumw2.fN) {
5702 fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
5703 }
5704 }
5705 }
5706 }
5707 ResetStats();
5708 return kTRUE;
5709}
5710
5711////////////////////////////////////////////////////////////////////////////////
5712/// Multiply this histogram by h1.
5713///
5714/// `this = this*h1`
5715///
5716/// If errors of this are available (TH1::Sumw2), errors are recalculated.
5717/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
5718/// if not already set.
5719///
5720/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5721/// you should call Sumw2 before making this operation.
5722/// This is particularly important if you fit the histogram after TH1::Multiply
5723///
5724/// The function return kFALSE if the Multiply operation failed
5725
5726Bool_t TH1::Multiply(const TH1 *h1)
5727{
5728 if (!h1) {
5729 Error("Multiply","Attempt to multiply by a non-existing histogram");
5730 return kFALSE;
5731 }
5732
5733 // delete buffer if it is there since it will become invalid
5734 if (fBuffer) BufferEmpty(1);
5735
5736 try {
5737 CheckConsistency(this,h1);
5738 } catch(DifferentNumberOfBins&) {
5739 Error("Multiply","Attempt to multiply histograms with different number of bins");
5740 return kFALSE;
5741 } catch(DifferentAxisLimits&) {
5742 Warning("Multiply","Attempt to multiply histograms with different axis limits");
5743 } catch(DifferentBinLimits&) {
5744 Warning("Multiply","Attempt to multiply histograms with different bin limits");
5745 } catch(DifferentLabels&) {
5746 Warning("Multiply","Attempt to multiply histograms with different labels");
5747 }
5748
5749 // Create Sumw2 if h1 has Sumw2 set
5750 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
5751
5752 // - Reset min- maximum
5753 SetMinimum();
5754 SetMaximum();
5755
5756 // - Loop on bins (including underflows/overflows)
5757 for (Int_t i = 0; i < fNcells; ++i) {
5760 UpdateBinContent(i, c0 * c1);
5761 if (fSumw2.fN) {
5763 }
5764 }
5765 ResetStats();
5766 return kTRUE;
5767}
5768
5769////////////////////////////////////////////////////////////////////////////////
5770/// Replace contents of this histogram by multiplication of h1 by h2.
5771///
5772/// `this = (c1*h1)*(c2*h2)`
5773///
5774/// If errors of this are available (TH1::Sumw2), errors are recalculated.
5775/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
5776/// if not already set.
5777///
5778/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5779/// you should call Sumw2 before making this operation.
5780/// This is particularly important if you fit the histogram after TH1::Multiply
5781///
5782/// The function return kFALSE if the Multiply operation failed
5783
5784Bool_t TH1::Multiply(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
5785{
5786 TString opt = option;
5787 opt.ToLower();
5788 // Bool_t binomial = kFALSE;
5789 // if (opt.Contains("b")) binomial = kTRUE;
5790 if (!h1 || !h2) {
5791 Error("Multiply","Attempt to multiply by a non-existing histogram");
5792 return kFALSE;
5793 }
5794
5795 // delete buffer if it is there since it will become invalid
5796 if (fBuffer) BufferEmpty(1);
5797
5798 try {
5799 CheckConsistency(h1,h2);
5800 CheckConsistency(this,h1);
5801 } catch(DifferentNumberOfBins&) {
5802 Error("Multiply","Attempt to multiply histograms with different number of bins");
5803 return kFALSE;
5804 } catch(DifferentAxisLimits&) {
5805 Warning("Multiply","Attempt to multiply histograms with different axis limits");
5806 } catch(DifferentBinLimits&) {
5807 Warning("Multiply","Attempt to multiply histograms with different bin limits");
5808 } catch(DifferentLabels&) {
5809 Warning("Multiply","Attempt to multiply histograms with different labels");
5810 }
5811
5812 // Create Sumw2 if h1 or h2 have Sumw2 set
5813 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
5814
5815 // - Reset min - maximum
5816 SetMinimum();
5817 SetMaximum();
5818
5819 // - Loop on bins (including underflows/overflows)
5820 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
5821 for (Int_t i = 0; i < fNcells; ++i) {
5823 Double_t b2 = h2->RetrieveBinContent(i);
5824 UpdateBinContent(i, c1 * b1 * c2 * b2);
5825 if (fSumw2.fN) {
5826 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
5827 }
5828 }
5829 ResetStats();
5830 return kTRUE;
5831}
5832
5833////////////////////////////////////////////////////////////////////////////////
5834/// Control routine to paint any kind of histograms.
5835///
5836/// This function is automatically called by TCanvas::Update.
5837/// (see TH1::Draw for the list of options)
5838
5839void TH1::Paint(Option_t *option)
5840{
5841 GetPainter(option);
5842
5843 if (fPainter) {
5844 if (strlen(option) > 0) fPainter->Paint(option);
5845 else fPainter->Paint(fOption.Data());
5846 }
5847}
5848
5849////////////////////////////////////////////////////////////////////////////////
5850/// Rebin this histogram
5851///
5852/// #### case 1 xbins=0
5853///
5854/// If newname is blank (default), the current histogram is modified and
5855/// a pointer to it is returned.
5856///
5857/// If newname is not blank, the current histogram is not modified, and a
5858/// new histogram is returned which is a Clone of the current histogram
5859/// with its name set to newname.
5860///
5861/// The parameter ngroup indicates how many bins of this have to be merged
5862/// into one bin of the result.
5863///
5864/// If the original histogram has errors stored (via Sumw2), the resulting
5865/// histograms has new errors correctly calculated.
5866///
5867/// examples: if h1 is an existing TH1F histogram with 100 bins
5868///
5869/// ~~~ {.cpp}
5870/// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
5871/// h1->Rebin(5); //merges five bins in one in h1
5872/// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
5873/// // merging 5 bins of h1 in one bin
5874/// ~~~
5875///
5876/// NOTE: If ngroup is not an exact divider of the number of bins,
5877/// the top limit of the rebinned histogram is reduced
5878/// to the upper edge of the last bin that can make a complete
5879/// group. The remaining bins are added to the overflow bin.
5880/// Statistics will be recomputed from the new bin contents.
5881///
5882/// #### case 2 xbins!=0
5883///
5884/// A new histogram is created (you should specify newname).
5885/// The parameter ngroup is the number of variable size bins in the created histogram.
5886/// The array xbins must contain ngroup+1 elements that represent the low-edges
5887/// of the bins.
5888/// If the original histogram has errors stored (via Sumw2), the resulting
5889/// histograms has new errors correctly calculated.
5890///
5891/// NOTE: The bin edges specified in xbins should correspond to bin edges
5892/// in the original histogram. If a bin edge in the new histogram is
5893/// in the middle of a bin in the original histogram, all entries in
5894/// the split bin in the original histogram will be transfered to the
5895/// lower of the two possible bins in the new histogram. This is
5896/// probably not what you want. A warning message is emitted in this
5897/// case
5898///
5899/// examples: if h1 is an existing TH1F histogram with 100 bins
5900///
5901/// ~~~ {.cpp}
5902/// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
5903/// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
5904/// ~~~
5905
5906TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
5907{
5908 Int_t nbins = fXaxis.GetNbins();
5911 if ((ngroup <= 0) || (ngroup > nbins)) {
5912 Error("Rebin", "Illegal value of ngroup=%d",ngroup);
5913 return 0;
5914 }
5915
5916 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
5917 Error("Rebin", "Operation valid on 1-D histograms only");
5918 return 0;
5919 }
5920 if (!newname && xbins) {
5921 Error("Rebin","if xbins is specified, newname must be given");
5922 return 0;
5923 }
5924
5925 Int_t newbins = nbins/ngroup;
5926 if (!xbins) {
5927 Int_t nbg = nbins/ngroup;
5928 if (nbg*ngroup != nbins) {
5929 Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
5930 }
5931 }
5932 else {
5933 // in the case that xbins is given (rebinning in variable bins), ngroup is
5934 // the new number of bins and number of grouped bins is not constant.
5935 // when looping for setting the contents for the new histogram we
5936 // need to loop on all bins of original histogram. Then set ngroup=nbins
5937 newbins = ngroup;
5938 ngroup = nbins;
5939 }
5940
5941 // Save old bin contents into a new array
5942 Double_t entries = fEntries;
5943 Double_t *oldBins = new Double_t[nbins+2];
5944 Int_t bin, i;
5945 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
5946 Double_t *oldErrors = 0;
5947 if (fSumw2.fN != 0) {
5948 oldErrors = new Double_t[nbins+2];
5949 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
5950 }
5951 // rebin will not include underflow/overflow if new axis range is larger than old axis range
5952 if (xbins) {
5953 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
5954 Warning("Rebin","underflow entries will not be used when rebinning");
5955 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
5956 Warning("Rebin","overflow entries will not be used when rebinning");
5957 }
5958
5959
5960 // create a clone of the old histogram if newname is specified
5961 TH1 *hnew = this;
5962 if ((newname && strlen(newname) > 0) || xbins) {
5963 hnew = (TH1*)Clone(newname);
5964 }
5965
5966 //reset can extend bit to avoid an axis extension in SetBinContent
5967 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
5968
5969 // save original statistics
5970 Double_t stat[kNstat];
5971 GetStats(stat);
5972 bool resetStat = false;
5973 // change axis specs and rebuild bin contents array::RebinAx
5974 if(!xbins && (newbins*ngroup != nbins)) {
5975 xmax = fXaxis.GetBinUpEdge(newbins*ngroup);
5976 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
5977 }
5978 // save the TAttAxis members (reset by SetBins)
5979 Int_t nDivisions = fXaxis.GetNdivisions();
5980 Color_t axisColor = fXaxis.GetAxisColor();
5981 Color_t labelColor = fXaxis.GetLabelColor();
5982 Style_t labelFont = fXaxis.GetLabelFont();
5983 Float_t labelOffset = fXaxis.GetLabelOffset();
5984 Float_t labelSize = fXaxis.GetLabelSize();
5985 Float_t tickLength = fXaxis.GetTickLength();
5986 Float_t titleOffset = fXaxis.GetTitleOffset();
5987 Float_t titleSize = fXaxis.GetTitleSize();
5988 Color_t titleColor = fXaxis.GetTitleColor();
5989 Style_t titleFont = fXaxis.GetTitleFont();
5990
5991 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
5992 Double_t *bins = new Double_t[newbins+1];
5993 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
5994 hnew->SetBins(newbins,bins); //this also changes errors array (if any)
5995 delete [] bins;
5996 } else if (xbins) {
5997 hnew->SetBins(newbins,xbins);
5998 } else {
5999 hnew->SetBins(newbins,xmin,xmax);
6000 }
6001
6002 // Restore axis attributes
6003 fXaxis.SetNdivisions(nDivisions);
6004 fXaxis.SetAxisColor(axisColor);
6005 fXaxis.SetLabelColor(labelColor);
6006 fXaxis.SetLabelFont(labelFont);
6007 fXaxis.SetLabelOffset(labelOffset);
6008 fXaxis.SetLabelSize(labelSize);
6009 fXaxis.SetTickLength(tickLength);
6010 fXaxis.SetTitleOffset(titleOffset);
6011 fXaxis.SetTitleSize(titleSize);
6012 fXaxis.SetTitleColor(titleColor);
6013 fXaxis.SetTitleFont(titleFont);
6014
6015 // copy merged bin contents (ignore under/overflows)
6016 // Start merging only once the new lowest edge is reached
6017 Int_t startbin = 1;
6018 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
6019 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
6020 startbin++;
6021 }
6022 Int_t oldbin = startbin;
6023 Double_t binContent, binError;
6024 for (bin = 1;bin<=newbins;bin++) {
6025 binContent = 0;
6026 binError = 0;
6027 Int_t imax = ngroup;
6028 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6029 // check bin edges for the cases when we provide an array of bins
6030 // be careful in case bins can have zero width
6031 if (xbins && !TMath::AreEqualAbs(fXaxis.GetBinLowEdge(oldbin),
6032 hnew->GetXaxis()->GetBinLowEdge(bin),
6033 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6034 {
6035 Warning("Rebin","Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6036 }
6037 for (i=0;i<ngroup;i++) {
6038 if( (oldbin+i > nbins) ||
6039 ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6040 imax = i;
6041 break;
6042 }
6043 binContent += oldBins[oldbin+i];
6044 if (oldErrors) binError += oldErrors[oldbin+i]*oldErrors[oldbin+i];
6045 }
6046 hnew->SetBinContent(bin,binContent);
6047 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6048 oldbin += imax;
6049 }
6050
6051 // sum underflow and overflow contents until startbin
6052 binContent = 0;
6053 binError = 0;
6054 for (i = 0; i < startbin; ++i) {
6055 binContent += oldBins[i];
6056 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6057 }
6058 hnew->SetBinContent(0,binContent);
6059 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6060 // sum overflow
6061 binContent = 0;
6062 binError = 0;
6063 for (i = oldbin; i <= nbins+1; ++i) {
6064 binContent += oldBins[i];
6065 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6066 }
6067 hnew->SetBinContent(newbins+1,binContent);
6068 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6069
6070 hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6071
6072 // restore statistics and entries modified by SetBinContent
6073 hnew->SetEntries(entries);
6074 if (!resetStat) hnew->PutStats(stat);
6075 delete [] oldBins;
6076 if (oldErrors) delete [] oldErrors;
6077 return hnew;
6078}
6079
6080////////////////////////////////////////////////////////////////////////////////
6081/// finds new limits for the axis so that *point* is within the range and
6082/// the limits are compatible with the previous ones (see TH1::Merge).
6083/// new limits are put into *newMin* and *newMax* variables.
6084/// axis - axis whose limits are to be recomputed
6085/// point - point that should fit within the new axis limits
6086/// newMin - new minimum will be stored here
6087/// newMax - new maximum will be stored here.
6088/// false if failed (e.g. if the initial axis limits are wrong
6089/// or the new range is more than \f$ 2^{64} \f$ times the old one).
6090
6091Bool_t TH1::FindNewAxisLimits(const TAxis* axis, const Double_t point, Double_t& newMin, Double_t &newMax)
6092{
6093 Double_t xmin = axis->GetXmin();
6094 Double_t xmax = axis->GetXmax();
6095 if (xmin >= xmax) return kFALSE;
6096 Double_t range = xmax-xmin;
6097 Double_t binsize = range / axis->GetNbins();
6098
6099 //recompute new axis limits by doubling the current range
6100 Int_t ntimes = 0;
6101 while (point < xmin) {
6102 if (ntimes++ > 64)
6103 return kFALSE;
6104 xmin = xmin - 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 while (point >= xmax) {
6114 if (ntimes++ > 64)
6115 return kFALSE;
6116 xmax = xmax + range;
6117 range *= 2;
6118 binsize *= 2;
6119 // // make sure that the merging will be correct
6120 // if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
6121 // xmin -= 0.5 * binsize;
6122 // xmax -= 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
6123 // }
6124 }
6125 newMin = xmin;
6126 newMax = xmax;
6127 // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6128 // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6129
6130 return kTRUE;
6131}
6132
6133////////////////////////////////////////////////////////////////////////////////
6134/// Histogram is resized along axis such that x is in the axis range.
6135/// The new axis limits are recomputed by doubling iteratively
6136/// the current axis range until the specified value x is within the limits.
6137/// The algorithm makes a copy of the histogram, then loops on all bins
6138/// of the old histogram to fill the extended histogram.
6139/// Takes into account errors (Sumw2) if any.
6140/// The algorithm works for 1-d, 2-D and 3-D histograms.
6141/// The axis must be extendable before invoking this function.
6142/// Ex:
6143///
6144/// ~~~ {.cpp}
6145/// h->GetXaxis()->SetCanExtend(kTRUE);
6146/// ~~~
6147
6148void TH1::ExtendAxis(Double_t x, TAxis *axis)
6149{
6150 if (!axis->CanExtend()) return;
6151 if (TMath::IsNaN(x)) { // x may be a NaN
6153 return;
6154 }
6155
6156 if (axis->GetXmin() >= axis->GetXmax()) return;
6157 if (axis->GetNbins() <= 0) return;
6158
6160 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6161 return;
6162
6163 //save a copy of this histogram
6164 TH1 *hold = (TH1*)IsA()->New();
6165 hold->SetDirectory(0);
6166 Copy(*hold);
6167 //set new axis limits
6168 axis->SetLimits(xmin,xmax);
6169
6170
6171 //now loop on all bins and refill
6172 Int_t errors = GetSumw2N();
6173
6174 Reset("ICE"); //reset only Integral, contents and Errors
6175
6176 int iaxis = 0;
6177 if (axis == &fXaxis) iaxis = 1;
6178 if (axis == &fYaxis) iaxis = 2;
6179 if (axis == &fZaxis) iaxis = 3;
6180 bool firstw = kTRUE;
6181 Int_t binx,biny, binz = 0;
6182 Int_t ix = 0,iy = 0,iz = 0;
6183 Double_t bx,by,bz;
6184 Int_t ncells = hold->GetNcells();
6185 for (Int_t bin = 0; bin < ncells; ++bin) {
6186 hold->GetBinXYZ(bin,binx,biny,binz);
6187 bx = hold->GetXaxis()->GetBinCenter(binx);
6188 ix = fXaxis.FindFixBin(bx);
6189 if (fDimension > 1) {
6190 by = hold->GetYaxis()->GetBinCenter(biny);
6191 iy = fYaxis.FindFixBin(by);
6192 if (fDimension > 2) {
6193 bz = hold->GetZaxis()->GetBinCenter(binz);
6194 iz = fZaxis.FindFixBin(bz);
6195 }
6196 }
6197 // exclude underflow/overflow
6198 double content = hold->RetrieveBinContent(bin);
6199 if (content == 0) continue;
6200 if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6201 if (firstw) {
6202 Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6203 " their content will be lost",GetName() );
6204 firstw= kFALSE;
6205 }
6206 continue;
6207 }
6208 Int_t ibin= GetBin(ix,iy,iz);
6209 AddBinContent(ibin, content);
6210 if (errors) {
6211 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6212 }
6213 }
6214 delete hold;
6215}
6216
6217////////////////////////////////////////////////////////////////////////////////
6218/// Recursively remove object from the list of functions
6219
6221{
6222 // Rely on TROOT::RecursiveRemove to take the readlock.
6223
6224 if (fFunctions) {
6226 }
6227}
6228
6229////////////////////////////////////////////////////////////////////////////////
6230/// Multiply this histogram by a constant c1.
6231///
6232/// `this = c1*this`
6233///
6234/// Note that both contents and errors(if any) are scaled.
6235/// This function uses the services of TH1::Add
6236///
6237/// IMPORTANT NOTE: Sumw2() is called automatically when scaling
6238/// If you are not interested in the histogram statistics you can call
6239/// Sumw2(off) or use the option "nosw2"
6240///
6241/// One can scale an histogram such that the bins integral is equal to
6242/// the normalization parameter via TH1::Scale(Double_t norm), where norm
6243/// is the desired normalization divided by the integral of the histogram.
6244///
6245/// If option contains "width" the bin contents and errors are divided
6246/// by the bin width.
6247
6248void TH1::Scale(Double_t c1, Option_t *option)
6249{
6250
6251 TString opt = option; opt.ToLower();
6252 // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6253 if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6254 if (opt.Contains("width")) Add(this, this, c1, -1);
6255 else {
6256 if (fBuffer) BufferEmpty(1);
6257 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6258 if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6259 // update global histograms statistics
6260 Double_t s[kNstat] = {0};
6261 GetStats(s);
6262 for (Int_t i=0 ; i < kNstat; i++) {
6263 if (i == 1) s[i] = c1*c1*s[i];
6264 else s[i] = c1*s[i];
6265 }
6266 PutStats(s);
6267 SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6268 }
6269
6270 // if contours set, must also scale contours
6271 Int_t ncontours = GetContour();
6272 if (ncontours == 0) return;
6273 Double_t* levels = fContour.GetArray();
6274 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6275}
6276
6277////////////////////////////////////////////////////////////////////////////////
6278/// Returns true if all axes are extendable.
6279
6281{
6282 Bool_t canExtend = fXaxis.CanExtend();
6283 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6284 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6285
6286 return canExtend;
6287}
6288
6289////////////////////////////////////////////////////////////////////////////////
6290/// Make the histogram axes extendable / not extendable according to the bit mask
6291/// returns the previous bit mask specifying which axes are extendable
6292
6293UInt_t TH1::SetCanExtend(UInt_t extendBitMask)
6294{
6295 UInt_t oldExtendBitMask = kNoAxis;
6296
6297 if (fXaxis.CanExtend()) oldExtendBitMask |= kXaxis;
6298 if (extendBitMask & kXaxis) fXaxis.SetCanExtend(kTRUE);
6300
6301 if (GetDimension() > 1) {
6302 if (fYaxis.CanExtend()) oldExtendBitMask |= kYaxis;
6303 if (extendBitMask & kYaxis) fYaxis.SetCanExtend(kTRUE);
6305 }
6306
6307 if (GetDimension() > 2) {
6308 if (fZaxis.CanExtend()) oldExtendBitMask |= kZaxis;
6309 if (extendBitMask & kZaxis) fZaxis.SetCanExtend(kTRUE);
6311 }
6312
6313 return oldExtendBitMask;
6314}
6315
6316////////////////////////////////////////////////////////////////////////////////
6317/// Static function to set the default buffer size for automatic histograms.
6318/// When an histogram is created with one of its axis lower limit greater
6319/// or equal to its upper limit, the function SetBuffer is automatically
6320/// called with the default buffer size.
6321
6322void TH1::SetDefaultBufferSize(Int_t buffersize)
6323{
6324 fgBufferSize = buffersize > 0 ? buffersize : 0;
6325}
6326
6327////////////////////////////////////////////////////////////////////////////////
6328/// When this static function is called with `sumw2=kTRUE`, all new
6329/// histograms will automatically activate the storage
6330/// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6331
6332void TH1::SetDefaultSumw2(Bool_t sumw2)
6333{
6334 fgDefaultSumw2 = sumw2;
6335}
6336
6337////////////////////////////////////////////////////////////////////////////////
6338/// Change (i.e. set) the title
6339///
6340/// if title is in the form `stringt;stringx;stringy;stringz`
6341/// the histogram title is set to `stringt`, the x axis title to `stringx`,
6342/// the y axis title to `stringy`, and the z axis title to `stringz`.
6343///
6344/// To insert the character `;` in one of the titles, one should use `#;`
6345/// or `#semicolon`.
6346
6347void TH1::SetTitle(const char *title)
6348{
6349 fTitle = title;
6350 fTitle.ReplaceAll("#;",2,"#semicolon",10);
6351
6352 // Decode fTitle. It may contain X, Y and Z titles
6353 TString str1 = fTitle, str2;
6354 Int_t isc = str1.Index(";");
6355 Int_t lns = str1.Length();
6356
6357 if (isc >=0 ) {
6358 fTitle = str1(0,isc);
6359 str1 = str1(isc+1, lns);
6360 isc = str1.Index(";");
6361 if (isc >=0 ) {
6362 str2 = str1(0,isc);
6363 str2.ReplaceAll("#semicolon",10,";",1);
6364 fXaxis.SetTitle(str2.Data());
6365 lns = str1.Length();
6366 str1 = str1(isc+1, lns);
6367 isc = str1.Index(";");
6368 if (isc >=0 ) {
6369 str2 = str1(0,isc);
6370 str2.ReplaceAll("#semicolon",10,";",1);
6371 fYaxis.SetTitle(str2.Data());
6372 lns = str1.Length();
6373 str1 = str1(isc+1, lns);
6374 str1.ReplaceAll("#semicolon",10,";",1);
6375 fZaxis.SetTitle(str1.Data());
6376 } else {
6377 str1.ReplaceAll("#semicolon",10,";",1);
6378 fYaxis.SetTitle(str1.Data());
6379 }
6380 } else {
6381 str1.ReplaceAll("#semicolon",10,";",1);
6382 fXaxis.SetTitle(str1.Data());
6383 }
6384 }
6385
6386 fTitle.ReplaceAll("#semicolon",10,";",1);
6387
6388 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6389}
6390
6391////////////////////////////////////////////////////////////////////////////////
6392/// Smooth array xx, translation of Hbook routine hsmoof.F
6393/// based on algorithm 353QH twice presented by J. Friedman
6394/// in Proc.of the 1974 CERN School of Computing, Norway, 11-24 August, 1974.
6395
6396void TH1::SmoothArray(Int_t nn, Double_t *xx, Int_t ntimes)
6397{
6398 if (nn < 3 ) {
6399 ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6400 return;
6401 }
6402
6403 Int_t ii;
6404 Double_t hh[6] = {0,0,0,0,0,0};
6405
6406 std::vector<double> yy(nn);
6407 std::vector<double> zz(nn);
6408 std::vector<double> rr(nn);
6409
6410 for (Int_t pass=0;pass<ntimes;pass++) {
6411 // first copy original data into temp array
6412 std::copy(xx, xx+nn, zz.begin() );
6413
6414 for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6415
6416 // do 353 i.e. running median 3, 5, and 3 in a single loop
6417 for (int kk = 0; kk < 3; kk++) {
6418 std::copy(zz.begin(), zz.end(), yy.begin());
6419 int medianType = (kk != 1) ? 3 : 5;
6420 int ifirst = (kk != 1 ) ? 1 : 2;
6421 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6422 //nn2 = nn - ik - 1;
6423 // do all elements beside the first and last point for median 3
6424 // and first two and last 2 for median 5
6425 for ( ii = ifirst; ii < ilast; ii++) {
6426 assert(ii - ifirst >= 0);
6427 for (int jj = 0; jj < medianType; jj++) {
6428 hh[jj] = yy[ii - ifirst + jj ];
6429 }
6430 zz[ii] = TMath::Median(medianType, hh);
6431 }
6432
6433 if (kk == 0) { // first median 3
6434 // first point
6435 hh[0] = zz[1];
6436 hh[1] = zz[0];
6437 hh[2] = 3*zz[1] - 2*zz[2];
6438 zz[0] = TMath::Median(3, hh);
6439 // last point
6440 hh[0] = zz[nn - 2];
6441 hh[1] = zz[nn - 1];
6442 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6443 zz[nn - 1] = TMath::Median(3, hh);
6444 }
6445
6446 if (kk == 1) { // median 5
6447 for (ii = 0; ii < 3; ii++) {
6448 hh[ii] = yy[ii];
6449 }
6450 zz[1] = TMath::Median(3, hh);
6451 // last two points
6452 for (ii = 0; ii < 3; ii++) {
6453 hh[ii] = yy[nn - 3 + ii];
6454 }
6455 zz[nn - 2] = TMath::Median(3, hh);
6456 }
6457
6458 }
6459
6460 std::copy ( zz.begin(), zz.end(), yy.begin() );
6461
6462 // quadratic interpolation for flat segments
6463 for (ii = 2; ii < (nn - 2); ii++) {
6464 if (zz[ii - 1] != zz[ii]) continue;
6465 if (zz[ii] != zz[ii + 1]) continue;
6466 hh[0] = zz[ii - 2] - zz[ii];
6467 hh[1] = zz[ii + 2] - zz[ii];
6468 if (hh[0] * hh[1] <= 0) continue;
6469 int jk = 1;
6470 if ( TMath::Abs(hh[1]) > TMath::Abs(hh[0]) ) jk = -1;
6471 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6472 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6473 }
6474
6475 // running means
6476 //std::copy(zz.begin(), zz.end(), yy.begin());
6477 for (ii = 1; ii < nn - 1; ii++) {
6478 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6479 }
6480 zz[0] = yy[0];
6481 zz[nn - 1] = yy[nn - 1];
6482
6483 if (noent == 0) {
6484
6485 // save computed values
6486 std::copy(zz.begin(), zz.end(), rr.begin());
6487
6488 // COMPUTE residuals
6489 for (ii = 0; ii < nn; ii++) {
6490 zz[ii] = xx[ii] - zz[ii];
6491 }
6492 }
6493
6494 } // end loop on noent
6495
6496
6497 double xmin = TMath::MinElement(nn,xx);
6498 for (ii = 0; ii < nn; ii++) {
6499 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6500 // make smoothing defined positive - not better using 0 ?
6501 else xx[ii] = TMath::Max((rr[ii] + zz[ii]),0.0 );
6502 }
6503 }
6504}
6505
6506////////////////////////////////////////////////////////////////////////////////
6507/// Smooth bin contents of this histogram.
6508/// if option contains "R" smoothing is applied only to the bins
6509/// defined in the X axis range (default is to smooth all bins)
6510/// Bin contents are replaced by their smooth values.
6511/// Errors (if any) are not modified.
6512/// the smoothing procedure is repeated ntimes (default=1)
6513
6514void TH1::Smooth(Int_t ntimes, Option_t *option)
6515{
6516 if (fDimension != 1) {
6517 Error("Smooth","Smooth only supported for 1-d histograms");
6518 return;
6519 }
6520 Int_t nbins = fXaxis.GetNbins();
6521 if (nbins < 3) {
6522 Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
6523 return;
6524 }
6525
6526 // delete buffer if it is there since it will become invalid
6527 if (fBuffer) BufferEmpty(1);
6528
6529 Int_t firstbin = 1, lastbin = nbins;
6530 TString opt = option;
6531 opt.ToLower();
6532 if (opt.Contains("r")) {
6533 firstbin= fXaxis.GetFirst();
6534 lastbin = fXaxis.GetLast();
6535 }
6536 nbins = lastbin - firstbin + 1;
6537 Double_t *xx = new Double_t[nbins];
6538 Double_t nent = fEntries;
6539 Int_t i;
6540 for (i=0;i<nbins;i++) {
6541 xx[i] = RetrieveBinContent(i+firstbin);
6542 }
6543
6544 TH1::SmoothArray(nbins,xx,ntimes);
6545
6546 for (i=0;i<nbins;i++) {
6547 UpdateBinContent(i+firstbin,xx[i]);
6548 }
6549 fEntries = nent;
6550 delete [] xx;
6551
6552 if (gPad) gPad->Modified();
6553}
6554
6555////////////////////////////////////////////////////////////////////////////////
6556/// if flag=kTRUE, underflows and overflows are used by the Fill functions
6557/// in the computation of statistics (mean value, StdDev).
6558/// By default, underflows or overflows are not used.
6559
6560void TH1::StatOverflows(Bool_t flag)
6561{
6562 fgStatOverflows = flag;
6563}
6564
6565////////////////////////////////////////////////////////////////////////////////
6566/// Stream a class object.
6567
6568void TH1::Streamer(TBuffer &b)
6569{
6570 if (b.IsReading()) {
6571 UInt_t R__s, R__c;
6572 Version_t R__v = b.ReadVersion(&R__s, &R__c);
6573 if (fDirectory) fDirectory->Remove(this);
6574 fDirectory = 0;
6575 if (R__v > 2) {
6576 b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
6577
6579 fXaxis.SetParent(this);
6580 fYaxis.SetParent(this);
6581 fZaxis.SetParent(this);
6582 TIter next(fFunctions);
6583 TObject *obj;
6584 while ((obj=next())) {
6585 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
6586 }
6587 return;
6588 }
6589 //process old versions before automatic schema evolution
6590 TNamed::Streamer(b);
6591 TAttLine::Streamer(b);
6592 TAttFill::Streamer(b);
6593 TAttMarker::Streamer(b);
6594 b >> fNcells;
6595 fXaxis.Streamer(b);
6596 fYaxis.Streamer(b);
6597 fZaxis.Streamer(b);
6598 fXaxis.SetParent(this);
6599 fYaxis.SetParent(this);
6600 fZaxis.SetParent(this);
6601 b >> fBarOffset;
6602 b >> fBarWidth;
6603 b >> fEntries;
6604 b >> fTsumw;
6605 b >> fTsumw2;
6606 b >> fTsumwx;
6607 b >> fTsumwx2;
6608 if (R__v < 2) {
6609 Float_t maximum, minimum, norm;
6610 Float_t *contour=0;
6611 b >> maximum; fMaximum = maximum;
6612 b >> minimum; fMinimum = minimum;
6613 b >> norm; fNormFactor = norm;
6614 Int_t n = b.ReadArray(contour);
6615 fContour.Set(n);
6616 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
6617 delete [] contour;
6618 } else {
6619 b >> fMaximum;
6620 b >> fMinimum;
6621 b >> fNormFactor;
6622 fContour.Streamer(b);
6623 }
6624 fSumw2.Streamer(b);
6625 fOption.Streamer(b);
6626 fFunctions->Delete();
6627 fFunctions->Streamer(b);
6628 b.CheckByteCount(R__s, R__c, TH1::IsA());
6629
6630 } else {
6631 b.WriteClassBuffer(TH1::Class(),this);
6632 }
6633}
6634
6635////////////////////////////////////////////////////////////////////////////////
6636/// Print some global quantities for this histogram.
6637/// \param[in] option
6638/// - "base" is given, number of bins and ranges are also printed
6639/// - "range" is given, bin contents and errors are also printed
6640/// for all bins in the current range (default 1-->nbins)
6641/// - "all" is given, bin contents and errors are also printed
6642/// for all bins including under and overflows.
6643
6644void TH1::Print(Option_t *option) const
6645{
6646 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
6647 printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
6648 TString opt = option;
6649 opt.ToLower();
6650 Int_t all;
6651 if (opt.Contains("all")) all = 0;
6652 else if (opt.Contains("range")) all = 1;
6653 else if (opt.Contains("base")) all = 2;
6654 else return;
6655
6656 Int_t bin, binx, biny, binz;
6657 Int_t firstx=0,lastx=0,firsty=0,lasty=0,firstz=0,lastz=0;
6658 if (all == 0) {
6659 lastx = fXaxis.GetNbins()+1;
6660 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
6661 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
6662 } else {
6663 firstx = fXaxis.GetFirst(); lastx = fXaxis.GetLast();
6664 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
6665 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
6666 }
6667
6668 if (all== 2) {
6669 printf(" Title = %s\n", GetTitle());
6670 printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
6671 if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
6672 if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
6673 printf("\n");
6674 return;
6675 }
6676
6677 Double_t w,e;
6678 Double_t x,y,z;
6679 if (fDimension == 1) {
6680 for (binx=firstx;binx<=lastx;binx++) {
6681 x = fXaxis.GetBinCenter(binx);
6682 w = RetrieveBinContent(binx);
6683 e = GetBinError(binx);
6684 if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
6685 else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
6686 }
6687 }
6688 if (fDimension == 2) {
6689 for (biny=firsty;biny<=lasty;biny++) {
6690 y = fYaxis.GetBinCenter(biny);
6691 for (binx=firstx;binx<=lastx;binx++) {
6692 bin = GetBin(binx,biny);
6693 x = fXaxis.GetBinCenter(binx);
6694 w = RetrieveBinContent(bin);
6695 e = GetBinError(bin);
6696 if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
6697 else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
6698 }
6699 }
6700 }
6701 if (fDimension == 3) {
6702 for (binz=firstz;binz<=lastz;binz++) {
6703 z = fZaxis.GetBinCenter(binz);
6704 for (biny=firsty;biny<=lasty;biny++) {
6705 y = fYaxis.GetBinCenter(biny);
6706 for (binx=firstx;binx<=lastx;binx++) {
6707 bin = GetBin(binx,biny,binz);
6708 x = fXaxis.GetBinCenter(binx);
6709 w = RetrieveBinContent(bin);
6710 e = GetBinError(bin);
6711 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);
6712 else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
6713 }
6714 }
6715 }
6716 }
6717}
6718
6719////////////////////////////////////////////////////////////////////////////////
6720/// Using the current bin info, recompute the arrays for contents and errors
6721
6722void TH1::Rebuild(Option_t *)
6723{
6724 SetBinsLength();
6725 if (fSumw2.fN) {
6727 }
6728}
6729
6730////////////////////////////////////////////////////////////////////////////////
6731/// Reset this histogram: contents, errors, etc.
6732/// \param[in] option
6733/// - if "ICE" is specified, resets only Integral, Contents and Errors.
6734/// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
6735/// This option is used
6736/// - if "M" is specified, resets also Minimum and Maximum
6737
6738void TH1::Reset(Option_t *option)
6739{
6740 // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
6741 // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
6742
6743 TString opt = option;
6744 opt.ToUpper();
6745 fSumw2.Reset();
6746 if (fIntegral) {delete [] fIntegral; fIntegral = 0;}
6747
6748 if (opt.Contains("M")) {
6749 SetMinimum();
6750 SetMaximum();
6751 }
6752
6753 if (opt.Contains("ICE") && !opt.Contains("S")) return;
6754
6755 // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
6756 // But what is the sense of calling BufferEmpty() ? For making the axes ?
6757 // BufferEmpty will update contents that later will be
6758 // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
6759 // It may be needed for computing the axis limits....
6760 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
6761
6762 // need to reset also the statistics
6763 // (needs to be done after calling BufferEmpty() )
6764 fTsumw = 0;
6765 fTsumw2 = 0;
6766 fTsumwx = 0;
6767 fTsumwx2 = 0;
6768 fEntries = 0;
6769
6770 if (opt == "ICES") return;
6771
6772
6773 TObject *stats = fFunctions->FindObject("stats");
6774 fFunctions->Remove(stats);
6775 //special logic to support the case where the same object is
6776 //added multiple times in fFunctions.
6777 //This case happens when the same object is added with different
6778 //drawing modes
6779 TObject *obj;
6780 while ((obj = fFunctions->First())) {
6781 while(fFunctions->Remove(obj)) { }
6782 delete obj;
6783 }
6784 if(stats) fFunctions->Add(stats);
6785 fContour.Set(0);
6786}
6787
6788////////////////////////////////////////////////////////////////////////////////
6789/// Save primitive as a C++ statement(s) on output stream out
6790
6791void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
6792{
6793 // empty the buffer before if it exists
6794 if (fBuffer) BufferEmpty();
6795
6796 Bool_t nonEqiX = kFALSE;
6797 Bool_t nonEqiY = kFALSE;
6798 Bool_t nonEqiZ = kFALSE;
6799 Int_t i;
6800 static Int_t nxaxis = 0;
6801 static Int_t nyaxis = 0;
6802 static Int_t nzaxis = 0;
6803 TString sxaxis="xAxis",syaxis="yAxis",szaxis="zAxis";
6804
6805 // Check if the histogram has equidistant X bins or not. If not, we
6806 // create an array holding the bins.
6807 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
6808 nonEqiX = kTRUE;
6809 nxaxis++;
6810 sxaxis += nxaxis;
6811 out << " Double_t "<<sxaxis<<"[" << GetXaxis()->GetXbins()->fN
6812 << "] = {";
6813 for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
6814 if (i != 0) out << ", ";
6815 out << GetXaxis()->GetXbins()->fArray[i];
6816 }
6817 out << "}; " << std::endl;
6818 }
6819 // If the histogram is 2 or 3 dimensional, check if the histogram
6820 // has equidistant Y bins or not. If not, we create an array
6821 // holding the bins.
6822 if (fDimension > 1 && GetYaxis()->GetXbins()->fN &&
6823 GetYaxis()->GetXbins()->fArray) {
6824 nonEqiY = kTRUE;
6825 nyaxis++;
6826 syaxis += nyaxis;
6827 out << " Double_t "<<syaxis<<"[" << GetYaxis()->GetXbins()->fN
6828 << "] = {";
6829 for (i = 0; i < GetYaxis()->GetXbins()->fN; i++) {
6830 if (i != 0) out << ", ";
6831 out << GetYaxis()->GetXbins()->fArray[i];
6832 }
6833 out << "}; " << std::endl;
6834 }
6835 // IF the histogram is 3 dimensional, check if the histogram
6836 // has equidistant Z bins or not. If not, we create an array
6837 // holding the bins.
6838 if (fDimension > 2 && GetZaxis()->GetXbins()->fN &&
6839 GetZaxis()->GetXbins()->fArray) {
6840 nonEqiZ = kTRUE;
6841 nzaxis++;
6842 szaxis += nzaxis;
6843 out << " Double_t "<<szaxis<<"[" << GetZaxis()->GetXbins()->fN
6844 << "] = {";
6845 for (i = 0; i < GetZaxis()->GetXbins()->fN; i++) {
6846 if (i != 0) out << ", ";
6847 out << GetZaxis()->GetXbins()->fArray[i];
6848 }
6849 out << "}; " << std::endl;
6850 }
6851
6852 char quote = '"';
6853 out <<" "<<std::endl;
6854 out <<" "<< ClassName() <<" *";
6855
6856 // Histogram pointer has by default the histogram name with an incremental suffix.
6857 // If the histogram belongs to a graph or a stack the suffix is not added because
6858 // the graph and stack objects are not aware of this new name. Same thing if
6859 // the histogram is drawn with the option COLZ because the TPaletteAxis drawn
6860 // when this option is selected, does not know this new name either.
6861 TString opt = option;
6862 opt.ToLower();
6863 static Int_t hcounter = 0;
6864 TString histName = GetName();
6865 if ( !histName.Contains("Graph")
6866 && !histName.Contains("_stack_")
6867 && !opt.Contains("colz")) {
6868 hcounter++;
6869 histName += "__";
6870 histName += hcounter;
6871 }
6872 histName = gInterpreter-> MapCppName(histName);
6873 const char *hname = histName.Data();
6874 if (!strlen(hname)) hname = "unnamed";
6875 TString savedName = GetName();
6876 this->SetName(hname);
6877 TString t(GetTitle());
6878 t.ReplaceAll("\\","\\\\");
6879 t.ReplaceAll("\"","\\\"");
6880 out << hname << " = new " << ClassName() << "(" << quote
6881 << hname << quote << "," << quote<< t.Data() << quote
6882 << "," << GetXaxis()->GetNbins();
6883 if (nonEqiX)
6884 out << ", "<<sxaxis;
6885 else
6886 out << "," << GetXaxis()->GetXmin()
6887 << "," << GetXaxis()->GetXmax();
6888 if (fDimension > 1) {
6889 out << "," << GetYaxis()->GetNbins();
6890 if (nonEqiY)
6891 out << ", "<<syaxis;
6892 else
6893 out << "," << GetYaxis()->GetXmin()
6894 << "," << GetYaxis()->GetXmax();
6895 }
6896 if (fDimension > 2) {
6897 out << "," << GetZaxis()->GetNbins();
6898 if (nonEqiZ)
6899 out << ", "<<szaxis;
6900 else
6901 out << "," << GetZaxis()->GetXmin()
6902 << "," << GetZaxis()->GetXmax();
6903 }
6904 out << ");" << std::endl;
6905
6906 // save bin contents
6907 Int_t bin;
6908 for (bin=0;bin<fNcells;bin++) {
6909 Double_t bc = RetrieveBinContent(bin);
6910 if (bc) {
6911 out<<" "<<hname<<"->SetBinContent("<<bin<<","<<bc<<");"<<std::endl;
6912 }
6913 }
6914
6915 // save bin errors
6916 if (fSumw2.fN) {
6917 for (bin=0;bin<fNcells;bin++) {
6918 Double_t be = GetBinError(bin);
6919 if (be) {
6920 out<<" "<<hname<<"->SetBinError("<<bin<<","<<be<<");"<<std::endl;
6921 }
6922 }
6923 }
6924
6925 TH1::SavePrimitiveHelp(out, hname, option);
6926 this->SetName(savedName.Data());
6927}
6928
6929////////////////////////////////////////////////////////////////////////////////
6930/// Helper function for the SavePrimitive functions from TH1
6931/// or classes derived from TH1, eg TProfile, TProfile2D.
6932
6933void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
6934{
6935 char quote = '"';
6936 if (TMath::Abs(GetBarOffset()) > 1e-5) {
6937 out<<" "<<hname<<"->SetBarOffset("<<GetBarOffset()<<");"<<std::endl;
6938 }
6939 if (TMath::Abs(GetBarWidth()-1) > 1e-5) {
6940 out<<" "<<hname<<"->SetBarWidth("<<GetBarWidth()<<");"<<std::endl;
6941 }
6942 if (fMinimum != -1111) {
6943 out<<" "<<hname<<"->SetMinimum("<<fMinimum<<");"<<std::endl;
6944 }
6945 if (fMaximum != -1111) {
6946 out<<" "<<hname<<"->SetMaximum("<<fMaximum<<");"<<std::endl;
6947 }
6948 if (fNormFactor != 0) {
6949 out<<" "<<hname<<"->SetNormFactor("<<fNormFactor<<");"<<std::endl;
6950 }
6951 if (fEntries != 0) {
6952 out<<" "<<hname<<"->SetEntries("<<fEntries<<");"<<std::endl;
6953 }
6954 if (fDirectory == 0) {
6955 out<<" "<<hname<<"->SetDirectory(0);"<<std::endl;
6956 }
6957 if (TestBit(kNoStats)) {
6958 out<<" "<<hname<<"->SetStats(0);"<<std::endl;
6959 }
6960 if (fOption.Length() != 0) {
6961 out<<" "<<hname<<"->SetOption("<<quote<<fOption.Data()<<quote<<");"<<std::endl;
6962 }
6963
6964 // save contour levels
6965 Int_t ncontours = GetContour();
6966 if (ncontours > 0) {
6967 out<<" "<<hname<<"->SetContour("<<ncontours<<");"<<std::endl;
6968 Double_t zlevel;
6969 for (Int_t bin=0;bin<ncontours;bin++) {
6970 if (gPad->GetLogz()) {
6971 zlevel = TMath::Power(10,GetContourLevel(bin));
6972 } else {
6973 zlevel = GetContourLevel(bin);
6974 }
6975 out<<" "<<hname<<"->SetContourLevel("<<bin<<","<<zlevel<<");"<<std::endl;
6976 }
6977 }
6978
6979 // save list of functions
6981 TObject *obj;
6982 static Int_t funcNumber = 0;
6983 while (lnk) {
6984 obj = lnk->GetObject();
6985 obj->SavePrimitive(out,Form("nodraw #%d\n",++funcNumber));
6986 if (obj->InheritsFrom(TF1::Class())) {
6987 TString fname;
6988 fname.Form("%s%d",obj->GetName(),funcNumber);
6989 out << " " << fname << "->SetParent(" << hname << ");\n";
6990 out<<" "<<hname<<"->GetListOfFunctions()->Add("
6991 << fname <<");"<<std::endl;
6992 } else if (obj->InheritsFrom("TPaveStats")) {
6993 out<<" "<<hname<<"->GetListOfFunctions()->Add(ptstats);"<<std::endl;
6994 out<<" ptstats->SetParent("<<hname<<");"<<std::endl;
6995 } else if (obj->InheritsFrom("TPolyMarker")) {
6996 out<<" "<<hname<<"->GetListOfFunctions()->Add("
6997 <<"pmarker ,"<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
6998 } else {
6999 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7000 <<obj->GetName()
7001 <<","<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
7002 }
7003 lnk = (TObjOptLink*)lnk->Next();
7004 }
7005
7006 // save attributes
7007 SaveFillAttributes(out,hname,0,1001);
7008 SaveLineAttributes(out,hname,1,1,1);
7009 SaveMarkerAttributes(out,hname,1,1,1);
7010 fXaxis.SaveAttributes(out,hname,"->GetXaxis()");
7011 fYaxis.SaveAttributes(out,hname,"->GetYaxis()");
7012 fZaxis.SaveAttributes(out,hname,"->GetZaxis()");
7013 TString opt = option;
7014 opt.ToLower();
7015 if (!opt.Contains("nodraw")) {
7016 out<<" "<<hname<<"->Draw("
7017 <<quote<<option<<quote<<");"<<std::endl;
7018 }
7019}
7020
7021////////////////////////////////////////////////////////////////////////////////
7022/// Copy current attributes from/to current style
7023
7025{
7026 if (!gStyle) return;
7027 if (gStyle->IsReading()) {
7028 fXaxis.ResetAttAxis("X");
7029 fYaxis.ResetAttAxis("Y");
7030 fZaxis.ResetAttAxis("Z");
7041 Int_t dostat = gStyle->GetOptStat();
7042 if (gStyle->GetOptFit() && !dostat) dostat = 1000000001;
7043 SetStats(dostat);
7044 } else {
7056 }
7057 TIter next(GetListOfFunctions());
7058 TObject *obj;
7059
7060 while ((obj = next())) {
7061 obj->UseCurrentStyle();
7062 }
7063}
7064
7065////////////////////////////////////////////////////////////////////////////////
7066/// For axis = 1,2 or 3 returns the mean value of the histogram along
7067/// X,Y or Z axis.
7068///
7069/// For axis = 11, 12, 13 returns the standard error of the mean value
7070/// of the histogram along X, Y or Z axis
7071///
7072/// Note that the mean value/StdDev is computed using the bins in the currently
7073/// defined range (see TAxis::SetRange). By default the range includes
7074/// all bins from 1 to nbins included, excluding underflows and overflows.
7075/// To force the underflows and overflows in the computation, one must
7076/// call the static function TH1::StatOverflows(kTRUE) before filling
7077/// the histogram.
7078///
7079/// Return mean value of this histogram along the X axis.
7080///
7081/// Note that the mean value/StdDev is computed using the bins in the currently
7082/// defined range (see TAxis::SetRange). By default the range includes
7083/// all bins from 1 to nbins included, excluding underflows and overflows.
7084/// To force the underflows and overflows in the computation, one must
7085/// call the static function TH1::StatOverflows(kTRUE) before filling
7086/// the histogram.
7087
7088Double_t TH1::GetMean(Int_t axis) const
7089{
7090 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7091 Double_t stats[kNstat];
7092 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7093 GetStats(stats);
7094 if (stats[0] == 0) return 0;
7095 if (axis<4){
7096 Int_t ax[3] = {2,4,7};
7097 return stats[ax[axis-1]]/stats[0];
7098 } else {
7099 // mean error = StdDev / sqrt( Neff )
7100 Double_t stddev = GetStdDev(axis-10);
7102 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7103 }
7104}
7105
7106////////////////////////////////////////////////////////////////////////////////
7107/// Return standard error of mean of this histogram along the X axis.
7108///
7109/// Note that the mean value/StdDev is computed using the bins in the currently
7110/// defined range (see TAxis::SetRange). By default the range includes
7111/// all bins from 1 to nbins included, excluding underflows and overflows.
7112/// To force the underflows and overflows in the computation, one must
7113/// call the static function TH1::StatOverflows(kTRUE) before filling
7114/// the histogram.
7115///
7116/// Also note, that although the definition of standard error doesn't include the
7117/// assumption of normality, many uses of this feature implicitly assume it.
7118
7120{
7121 return GetMean(axis+10);
7122}
7123
7124////////////////////////////////////////////////////////////////////////////////
7125/// Returns the Standard Deviation (Sigma).
7126/// The Sigma estimate is computed as
7127/// \f[
7128/// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7129/// \f]
7130/// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7131/// X, Y or Z axis
7132/// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7133/// X, Y or Z axis for Normal distribution
7134///
7135/// Note that the mean value/sigma is computed using the bins in the currently
7136/// defined range (see TAxis::SetRange). By default the range includes
7137/// all bins from 1 to nbins included, excluding underflows and overflows.
7138/// To force the underflows and overflows in the computation, one must
7139/// call the static function TH1::StatOverflows(kTRUE) before filling
7140/// the histogram.
7141
7142Double_t TH1::GetStdDev(Int_t axis) const
7143{
7144 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7145
7146 Double_t x, stddev2, stats[kNstat];
7147 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7148 GetStats(stats);
7149 if (stats[0] == 0) return 0;
7150 Int_t ax[3] = {2,4,7};
7151 Int_t axm = ax[axis%10 - 1];
7152 x = stats[axm]/stats[0];
7153 // for negative stddev (e.g. when having negative weights) - return stdev=0
7154 stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7155 if (axis<10)
7156 return TMath::Sqrt(stddev2);
7157 else {
7158 // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7159 // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7161 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7162 }
7163}
7164
7165////////////////////////////////////////////////////////////////////////////////
7166/// Return error of standard deviation estimation for Normal distribution
7167///
7168/// Note that the mean value/StdDev is computed using the bins in the currently
7169/// defined range (see TAxis::SetRange). By default the range includes
7170/// all bins from 1 to nbins included, excluding underflows and overflows.
7171/// To force the underflows and overflows in the computation, one must
7172/// call the static function TH1::StatOverflows(kTRUE) before filling
7173/// the histogram.
7174///
7175/// Value returned is standard deviation of sample standard deviation.
7176/// Note that it is an approximated value which is valid only in the case that the
7177/// original data distribution is Normal. The correct one would require
7178/// the 4-th momentum value, which cannot be accurately estimated from an histogram since
7179/// the x-information for all entries is not kept.
7180
7182{
7183 return GetStdDev(axis+10);
7184}
7185
7186////////////////////////////////////////////////////////////////////////////////
7187/// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7188/// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7189/// of the histogram along x, y or z axis
7190///
7191///Note, that since third and fourth moment are not calculated
7192///at the fill time, skewness and its standard error are computed bin by bin
7193
7195{
7196
7197 if (axis > 0 && axis <= 3){
7198
7199 Double_t mean = GetMean(axis);
7200 Double_t stddev = GetStdDev(axis);
7201 Double_t stddev3 = stddev*stddev*stddev;
7202
7203 Int_t firstBinX = fXaxis.GetFirst();
7204 Int_t lastBinX = fXaxis.GetLast();
7205 Int_t firstBinY = fYaxis.GetFirst();
7206 Int_t lastBinY = fYaxis.GetLast();
7207 Int_t firstBinZ = fZaxis.GetFirst();
7208 Int_t lastBinZ = fZaxis.GetLast();
7209 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7212 if (firstBinX == 1) firstBinX = 0;
7213 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7214 }
7216 if (firstBinY == 1) firstBinY = 0;
7217 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7218 }
7220 if (firstBinZ == 1) firstBinZ = 0;
7221 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7222 }
7223 }
7224
7225 Double_t x = 0;
7226 Double_t sum=0;
7227 Double_t np=0;
7228 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7229 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7230 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7231 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7232 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7233 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7234 Double_t w = GetBinContent(binx,biny,binz);
7235 np+=w;
7236 sum+=w*(x-mean)*(x-mean)*(x-mean);
7237 }
7238 }
7239 }
7240 sum/=np*stddev3;
7241 return sum;
7242 }
7243 else if (axis > 10 && axis <= 13) {
7244 //compute standard error of skewness
7245 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7247 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7248 }
7249 else {
7250 Error("GetSkewness", "illegal value of parameter");
7251 return 0;
7252 }
7253}
7254
7255////////////////////////////////////////////////////////////////////////////////
7256/// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7257/// Kurtosis(gaussian(0, 1)) = 0.
7258/// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7259/// of the histogram along x, y or z axis
7260////
7261/// Note, that since third and fourth moment are not calculated
7262/// at the fill time, kurtosis and its standard error are computed bin by bin
7263
7265{
7266 if (axis > 0 && axis <= 3){
7267
7268 Double_t mean = GetMean(axis);
7269 Double_t stddev = GetStdDev(axis);
7270 Double_t stddev4 = stddev*stddev*stddev*stddev;
7271
7272 Int_t firstBinX = fXaxis.GetFirst();
7273 Int_t lastBinX = fXaxis.GetLast();
7274 Int_t firstBinY = fYaxis.GetFirst();
7275 Int_t lastBinY = fYaxis.GetLast();
7276 Int_t firstBinZ = fZaxis.GetFirst();
7277 Int_t lastBinZ = fZaxis.GetLast();
7278 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7281 if (firstBinX == 1) firstBinX = 0;
7282 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7283 }
7285 if (firstBinY == 1) firstBinY = 0;
7286 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7287 }
7289 if (firstBinZ == 1) firstBinZ = 0;
7290 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7291 }
7292 }
7293
7294 Double_t x = 0;
7295 Double_t sum=0;
7296 Double_t np=0;
7297 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7298 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7299 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7300 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7301 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7302 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7303 Double_t w = GetBinContent(binx,biny,binz);
7304 np+=w;
7305 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7306 }
7307 }
7308 }
7309 sum/=(np*stddev4);
7310 return sum-3;
7311
7312 } else if (axis > 10 && axis <= 13) {
7313 //compute standard error of skewness
7314 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7316 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7317 }
7318 else {
7319 Error("GetKurtosis", "illegal value of parameter");
7320 return 0;
7321 }
7322}
7323
7324////////////////////////////////////////////////////////////////////////////////
7325/// fill the array stats from the contents of this histogram
7326/// The array stats must be correctly dimensioned in the calling program.
7327///
7328/// ~~~ {.cpp}
7329/// stats[0] = sumw
7330/// stats[1] = sumw2
7331/// stats[2] = sumwx
7332/// stats[3] = sumwx2
7333/// ~~~
7334///
7335/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7336/// is simply a copy of the statistics quantities computed at filling time.
7337/// If a sub-range is specified, the function recomputes these quantities
7338/// from the bin contents in the current axis range.
7339///
7340/// Note that the mean value/StdDev is computed using the bins in the currently
7341/// defined range (see TAxis::SetRange). By default the range includes
7342/// all bins from 1 to nbins included, excluding underflows and overflows.
7343/// To force the underflows and overflows in the computation, one must
7344/// call the static function TH1::StatOverflows(kTRUE) before filling
7345/// the histogram.
7346
7347void TH1::GetStats(Double_t *stats) const
7348{
7349 if (fBuffer) ((TH1*)this)->BufferEmpty();
7350
7351 // Loop on bins (possibly including underflows/overflows)
7352 Int_t bin, binx;
7353 Double_t w,err;
7354 Double_t x;
7355 // identify the case of labels with extension of axis range
7356 // in this case the statistics in x does not make any sense
7357 Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && CanExtendAllAxes() );
7358 // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7359 if ((fTsumw == 0 && fEntries > 0) || ( fXaxis.TestBit(TAxis::kAxisRange) && !labelHist) ) {
7360 for (bin=0;bin<4;bin++) stats[bin] = 0;
7361
7362 Int_t firstBinX = fXaxis.GetFirst();
7363 Int_t lastBinX = fXaxis.GetLast();
7364 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7366 if (firstBinX == 1) firstBinX = 0;
7367 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7368 }
7369 for (binx = firstBinX; binx <= lastBinX; binx++) {
7370 x = fXaxis.GetBinCenter(binx);
7371 //w = TMath::Abs(RetrieveBinContent(binx));
7372 // not sure what to do here if w < 0
7373 w = RetrieveBinContent(binx);
7374 err = TMath::Abs(GetBinError(binx));
7375 stats[0] += w;
7376 stats[1] += err*err;
7377 // statistics in x makes sense only for not labels histograms
7378 if (!labelHist) {
7379 stats[2] += w*x;
7380 stats[3] += w*x*x;
7381 }
7382 }
7383 // if (stats[0] < 0) {
7384 // // in case total is negative do something ??
7385 // stats[0] = 0;
7386 // }
7387 } else {
7388 stats[0] = fTsumw;
7389 stats[1] = fTsumw2;
7390 stats[2] = fTsumwx;
7391 stats[3] = fTsumwx2;
7392 }
7393}
7394
7395////////////////////////////////////////////////////////////////////////////////
7396/// Replace current statistics with the values in array stats
7397
7398void TH1::PutStats(Double_t *stats)
7399{
7400 fTsumw = stats[0];
7401 fTsumw2 = stats[1];
7402 fTsumwx = stats[2];
7403 fTsumwx2 = stats[3];
7404}
7405
7406////////////////////////////////////////////////////////////////////////////////
7407/// Reset the statistics including the number of entries
7408/// and replace with values calculates from bin content
7409///
7410/// The number of entries is set to the total bin content or (in case of weighted histogram)
7411/// to number of effective entries
7412
7413void TH1::ResetStats()
7414{
7415 Double_t stats[kNstat] = {0};
7416 fTsumw = 0;
7417 fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
7418 GetStats(stats);
7419 PutStats(stats);
7421 // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
7422 if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
7423}
7424
7425////////////////////////////////////////////////////////////////////////////////
7426/// Return the sum of weights excluding under/overflows.
7427
7429{
7430 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7431
7432 Int_t bin,binx,biny,binz;
7433 Double_t sum =0;
7434 for(binz=1; binz<=fZaxis.GetNbins(); binz++) {
7435 for(biny=1; biny<=fYaxis.GetNbins(); biny++) {
7436 for(binx=1; binx<=fXaxis.GetNbins(); binx++) {
7437 bin = GetBin(binx,biny,binz);
7438 sum += RetrieveBinContent(bin);
7439 }
7440 }
7441 }
7442 return sum;
7443}
7444
7445////////////////////////////////////////////////////////////////////////////////
7446///Return integral of bin contents. Only bins in the bins range are considered.
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(Option_t *option) const
7453{
7454 return Integral(fXaxis.GetFirst(),fXaxis.GetLast(),option);
7455}
7456
7457////////////////////////////////////////////////////////////////////////////////
7458/// Return integral of bin contents in range [binx1,binx2].
7459///
7460/// By default the integral is computed as the sum of bin contents in the range.
7461/// if option "width" is specified, the integral is the sum of
7462/// the bin contents multiplied by the bin width in x.
7463
7464Double_t TH1::Integral(Int_t binx1, Int_t binx2, Option_t *option) const
7465{
7466 double err = 0;
7467 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
7468}
7469
7470////////////////////////////////////////////////////////////////////////////////
7471/// Return integral of bin contents in range [binx1,binx2] and its error.
7472///
7473/// By default the integral is computed as the sum of bin contents in the range.
7474/// if option "width" is specified, the integral is the sum of
7475/// the bin contents multiplied by the bin width in x.
7476/// the error is computed using error propagation from the bin errors assuming that
7477/// all the bins are uncorrelated
7478
7479Double_t TH1::IntegralAndError(Int_t binx1, Int_t binx2, Double_t & error, Option_t *option) const
7480{
7481 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
7482}
7483
7484////////////////////////////////////////////////////////////////////////////////
7485/// Internal function compute integral and optionally the error between the limits
7486/// specified by the bin number values working for all histograms (1D, 2D and 3D)
7487
7488Double_t TH1::DoIntegral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error ,
7489 Option_t *option, Bool_t doError) const
7490{
7491 if (fBuffer) ((TH1*)this)->BufferEmpty();
7492
7493 Int_t nx = GetNbinsX() + 2;
7494 if (binx1 < 0) binx1 = 0;
7495 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
7496
7497 if (GetDimension() > 1) {
7498 Int_t ny = GetNbinsY() + 2;
7499 if (biny1 < 0) biny1 = 0;
7500 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
7501 } else {
7502 biny1 = 0; biny2 = 0;
7503 }
7504
7505 if (GetDimension() > 2) {
7506 Int_t nz = GetNbinsZ() + 2;
7507 if (binz1 < 0) binz1 = 0;
7508 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
7509 } else {
7510 binz1 = 0; binz2 = 0;
7511 }
7512
7513 // - Loop on bins in specified range
7514 TString opt = option;
7515 opt.ToLower();
7517 if (opt.Contains("width")) width = kTRUE;
7518
7519
7520 Double_t dx = 1., dy = .1, dz =.1;
7521 Double_t integral = 0;
7522 Double_t igerr2 = 0;
7523 for (Int_t binx = binx1; binx <= binx2; ++binx) {
7524 if (width) dx = fXaxis.GetBinWidth(binx);
7525 for (Int_t biny = biny1; biny <= biny2; ++biny) {
7526 if (width) dy = fYaxis.GetBinWidth(biny);
7527 for (Int_t binz = binz1; binz <= binz2; ++binz) {
7528 Int_t bin = GetBin(binx, biny, binz);
7529 Double_t dv = 0.0;
7530 if (width) {
7531 dz = fZaxis.GetBinWidth(binz);
7532 dv = dx * dy * dz;
7533 integral += RetrieveBinContent(bin) * dv;
7534 } else {
7535 integral += RetrieveBinContent(bin);
7536 }
7537 if (doError) {
7538 if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
7539 else igerr2 += GetBinErrorSqUnchecked(bin);
7540 }
7541 }
7542 }
7543 }
7544
7545 if (doError) error = TMath::Sqrt(igerr2);
7546 return integral;
7547}
7548
7549////////////////////////////////////////////////////////////////////////////////
7550/// Statistical test of compatibility in shape between
7551/// this histogram and h2, using the Anderson-Darling 2 sample test.
7552///
7553/// The AD 2 sample test formula are derived from the paper
7554/// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
7555///
7556/// The test is implemented in root in the ROOT::Math::GoFTest class
7557/// It is the same formula ( (6) in the paper), and also shown in
7558/// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
7559///
7560/// Binned data are considered as un-binned data
7561/// with identical observation happening in the bin center.
7562///
7563/// \param[in] option is a character string to specify options
7564/// - "D" Put out a line of "Debug" printout
7565/// - "T" Return the normalized A-D test statistic
7566///
7567/// - Note1: Underflow and overflow are not considered in the test
7568/// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
7569/// - Note3: The histograms are not required to have the same X axis
7570/// - Note4: The test works only for 1-dimensional histograms
7571
7572Double_t TH1::AndersonDarlingTest(const TH1 *h2, Option_t *option) const
7573{
7574 Double_t advalue = 0;
7575 Double_t pvalue = AndersonDarlingTest(h2, advalue);
7576
7577 TString opt = option;
7578 opt.ToUpper();
7579 if (opt.Contains("D") ) {
7580 printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
7581 }
7582 if (opt.Contains("T") ) return advalue;
7583
7584 return pvalue;
7585}
7586
7587////////////////////////////////////////////////////////////////////////////////
7588/// Same function as above but returning also the test statistic value
7589
7590Double_t TH1::AndersonDarlingTest(const TH1 *h2, Double_t & advalue) const
7591{
7592 if (GetDimension() != 1 || h2->GetDimension() != 1) {
7593 Error("AndersonDarlingTest","Histograms must be 1-D");
7594 return -1;
7595 }
7596
7597 // empty the buffer. Probably we could add as an unbinned test
7598 if (fBuffer) ((TH1*)this)->BufferEmpty();
7599
7600 // use the BinData class
7601 ROOT::Fit::BinData data1;
7602 ROOT::Fit::BinData data2;
7603
7604 ROOT::Fit::FillData(data1, this, 0);
7605 ROOT::Fit::FillData(data2, h2, 0);
7606
7607 double pvalue;
7608 ROOT::Math::GoFTest::AndersonDarling2SamplesTest(data1,data2, pvalue,advalue);
7609
7610 return pvalue;
7611}
7612
7613////////////////////////////////////////////////////////////////////////////////
7614/// Statistical test of compatibility in shape between
7615/// this histogram and h2, using Kolmogorov test.
7616/// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
7617/// and not for binned data as in the case of the histogram (see NOTE 3 below).
7618/// So, before using this method blindly, read the NOTE 3.
7619///
7620/// Default: Ignore under- and overflow bins in comparison
7621///
7622/// \param[in] h2 histogram
7623/// \param[in] option is a character string to specify options
7624/// - "U" include Underflows in test (also for 2-dim)
7625/// - "O" include Overflows (also valid for 2-dim)
7626/// - "N" include comparison of normalizations
7627/// - "D" Put out a line of "Debug" printout
7628/// - "M" Return the Maximum Kolmogorov distance instead of prob
7629/// - "X" Run the pseudo experiments post-processor with the following procedure:
7630/// make pseudoexperiments based on random values from the parent distribution,
7631/// compare the KS distance of the pseudoexperiment to the parent
7632/// distribution, and count all the KS values above the value
7633/// obtained from the original data to Monte Carlo distribution.
7634/// The number of pseudo-experiments nEXPT is currently fixed at 1000.
7635/// The function returns the probability.
7636/// (thanks to Ben Kilminster to submit this procedure). Note that
7637/// this option "X" is much slower.
7638///
7639/// The returned function value is the probability of test
7640/// (much less than one means NOT compatible)
7641///
7642/// Code adapted by Rene Brun from original HBOOK routine HDIFF
7643///
7644/// NOTE1
7645/// A good description of the Kolmogorov test can be seen at:
7646/// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
7647///
7648/// NOTE2
7649/// see also alternative function TH1::Chi2Test
7650/// The Kolmogorov test is assumed to give better results than Chi2Test
7651/// in case of histograms with low statistics.
7652///
7653/// NOTE3 (Jan Conrad, Fred James)
7654/// "The returned value PROB is calculated such that it will be
7655/// uniformly distributed between zero and one for compatible histograms,
7656/// provided the data are not binned (or the number of bins is very large
7657/// compared with the number of events). Users who have access to unbinned
7658/// data and wish exact confidence levels should therefore not put their data
7659/// into histograms, but should call directly TMath::KolmogorovTest. On
7660/// the other hand, since TH1 is a convenient way of collecting data and
7661/// saving space, this function has been provided. However, the values of
7662/// PROB for binned data will be shifted slightly higher than expected,
7663/// depending on the effects of the binning. For example, when comparing two
7664/// uniform distributions of 500 events in 100 bins, the values of PROB,
7665/// instead of being exactly uniformly distributed between zero and one, have
7666/// a mean value of about 0.56. We can apply a useful
7667/// rule: As long as the bin width is small compared with any significant
7668/// physical effect (for example the experimental resolution) then the binning
7669/// cannot have an important effect. Therefore, we believe that for all
7670/// practical purposes, the probability value PROB is calculated correctly
7671/// provided the user is aware that:
7672///
7673/// 1. The value of PROB should not be expected to have exactly the correct
7674/// distribution for binned data.
7675/// 2. The user is responsible for seeing to it that the bin widths are
7676/// small compared with any physical phenomena of interest.
7677/// 3. The effect of binning (if any) is always to make the value of PROB
7678/// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
7679/// will assure that at most 5% of truly compatible histograms are rejected,
7680/// and usually somewhat less."
7681///
7682/// Note also that for GoF test of unbinned data ROOT provides also the class
7683/// ROOT::Math::GoFTest. The class has also method for doing one sample tests
7684/// (i.e. comparing the data with a given distribution).
7685
7686Double_t TH1::KolmogorovTest(const TH1 *h2, Option_t *option) const
7687{
7688 TString opt = option;
7689 opt.ToUpper();
7690
7691 Double_t prob = 0;
7692 TH1 *h1 = (TH1*)this;
7693 if (h2 == 0) return 0;
7694 const TAxis *axis1 = h1->GetXaxis();
7695 const TAxis *axis2 = h2->GetXaxis();
7696 Int_t ncx1 = axis1->GetNbins();
7697 Int_t ncx2 = axis2->GetNbins();
7698
7699 // Check consistency of dimensions
7700 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
7701 Error("KolmogorovTest","Histograms must be 1-D\n");
7702 return 0;
7703 }
7704
7705 // Check consistency in number of channels
7706 if (ncx1 != ncx2) {
7707 Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
7708 return 0;
7709 }
7710
7711 // empty the buffer. Probably we could add as an unbinned test
7712 if (fBuffer) ((TH1*)this)->BufferEmpty();
7713
7714 // Check consistency in bin edges
7715 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
7716 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
7717 Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
7718 return 0;
7719 }
7720 }
7721
7722 Bool_t afunc1 = kFALSE;
7723 Bool_t afunc2 = kFALSE;
7724 Double_t sum1 = 0, sum2 = 0;
7725 Double_t ew1, ew2, w1 = 0, w2 = 0;
7726 Int_t bin;
7727 Int_t ifirst = 1;
7728 Int_t ilast = ncx1;
7729 // integral of all bins (use underflow/overflow if option)
7730 if (opt.Contains("U")) ifirst = 0;
7731 if (opt.Contains("O")) ilast = ncx1 +1;
7732 for (bin = ifirst; bin <= ilast; bin++) {
7733 sum1 += h1->RetrieveBinContent(bin);
7734 sum2 += h2->RetrieveBinContent(bin);
7735 ew1 = h1->GetBinError(bin);
7736 ew2 = h2->GetBinError(bin);
7737 w1 += ew1*ew1;
7738 w2 += ew2*ew2;
7739 }
7740 if (sum1 == 0) {
7741 Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
7742 return 0;
7743 }
7744 if (sum2 == 0) {
7745 Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
7746 return 0;
7747 }
7748
7749 // calculate the effective entries.
7750 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
7751 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
7752 Double_t esum1 = 0, esum2 = 0;
7753 if (w1 > 0)
7754 esum1 = sum1 * sum1 / w1;
7755 else
7756 afunc1 = kTRUE; // use later for calculating z
7757
7758 if (w2 > 0)
7759 esum2 = sum2 * sum2 / w2;
7760 else
7761 afunc2 = kTRUE; // use later for calculating z
7762
7763 if (afunc2 && afunc1) {
7764 Error("KolmogorovTest","Errors are zero for both histograms\n");
7765 return 0;
7766 }
7767
7768
7769 Double_t s1 = 1/sum1;
7770 Double_t s2 = 1/sum2;
7771
7772 // Find largest difference for Kolmogorov Test
7773 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
7774
7775 for (bin=ifirst;bin<=ilast;bin++) {
7776 rsum1 += s1*h1->RetrieveBinContent(bin);
7777 rsum2 += s2*h2->RetrieveBinContent(bin);
7778 dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
7779 }
7780
7781 // Get Kolmogorov probability
7782 Double_t z, prb1=0, prb2=0, prb3=0;
7783
7784 // case h1 is exact (has zero errors)
7785 if (afunc1)
7786 z = dfmax*TMath::Sqrt(esum2);
7787 // case h2 has zero errors
7788 else if (afunc2)
7789 z = dfmax*TMath::Sqrt(esum1);
7790 else
7791 // for comparison between two data sets
7792 z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
7793
7794 prob = TMath::KolmogorovProb(z);
7795
7796 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
7797 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
7798 // Combine probabilities for shape and normalization,
7799 prb1 = prob;
7800 Double_t d12 = esum1-esum2;
7801 Double_t chi2 = d12*d12/(esum1+esum2);
7802 prb2 = TMath::Prob(chi2,1);
7803 // see Eadie et al., section 11.6.2
7804 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
7805 else prob = 0;
7806 }
7807 // X option. Pseudo-experiments post-processor to determine KS probability
7808 const Int_t nEXPT = 1000;
7809 if (opt.Contains("X") && !(afunc1 || afunc2 ) ) {
7810 Double_t dSEXPT;
7811 TH1 *h1_cpy = (TH1 *)(gDirectory ? gDirectory->CloneObject(this, kFALSE) : gROOT->CloneObject(this, kFALSE));
7812 TH1 *h1Expt = (TH1*)(gDirectory ? gDirectory->CloneObject(this,kFALSE) : gROOT->CloneObject(this,kFALSE));
7813 TH1 *h2Expt = (TH1*)(gDirectory ? gDirectory->CloneObject(this,kFALSE) : gROOT->CloneObject(this,kFALSE));
7814
7815 if (GetMinimum() < 0.0) {
7816 // we need to create a new histogram
7817 // With negative bins we can't draw random samples in a meaningful way.
7818 Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
7819 "skewed. Reduce number of bins for histogram?");
7820 while (h1_cpy->GetMinimum() < 0.0) {
7821 Int_t idx = h1_cpy->GetMinimumBin();
7822 h1_cpy->SetBinContent(idx, 0.0);
7823 }
7824 }
7825
7826 // make nEXPT experiments (this should be a parameter)
7827 prb3 = 0;
7828 for (Int_t i=0; i < nEXPT; i++) {
7829 h1Expt->Reset();
7830 h2Expt->Reset();
7831 h1Expt->FillRandom(h1_cpy, (Int_t)esum1);
7832 h2Expt->FillRandom(h1_cpy, (Int_t)esum2);
7833 dSEXPT = h1Expt->KolmogorovTest(h2Expt,"M");
7834 if (dSEXPT>dfmax) prb3 += 1.0;
7835 }
7836 prb3 /= (Double_t)nEXPT;
7837 delete h1_cpy;
7838 delete h1Expt;
7839 delete h2Expt;
7840 }
7841
7842 // debug printout
7843 if (opt.Contains("D")) {
7844 printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
7845 printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
7846 printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
7847 if (opt.Contains("N"))
7848 printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
7849 if (opt.Contains("X"))
7850 printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
7851 }
7852 // This numerical error condition should never occur:
7853 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
7854 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
7855
7856 if(opt.Contains("M")) return dfmax;
7857 else if(opt.Contains("X")) return prb3;
7858 else return prob;
7859}
7860
7861////////////////////////////////////////////////////////////////////////////////
7862/// Replace bin contents by the contents of array content
7863
7864void TH1::SetContent(const Double_t *content)
7865{
7866 fEntries = fNcells;
7867 fTsumw = 0;
7868 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
7869}
7870
7871////////////////////////////////////////////////////////////////////////////////
7872/// Return contour values into array levels if pointer levels is non zero.
7873///
7874/// The function returns the number of contour levels.
7875/// see GetContourLevel to return one contour only
7876
7878{
7879 Int_t nlevels = fContour.fN;
7880 if (levels) {
7881 if (nlevels == 0) {
7882 nlevels = 20;
7883 SetContour(nlevels);
7884 } else {
7885 if (TestBit(kUserContour) == 0) SetContour(nlevels);
7886 }
7887 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
7888 }
7889 return nlevels;
7890}
7891
7892////////////////////////////////////////////////////////////////////////////////
7893/// Return value of contour number level.
7894/// Use GetContour to return the array of all contour levels
7895
7897{
7898 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
7899}
7900
7901////////////////////////////////////////////////////////////////////////////////
7902/// Return the value of contour number "level" in Pad coordinates.
7903/// ie: if the Pad is in log scale along Z it returns le log of the contour level
7904/// value. See GetContour to return the array of all contour levels
7905
7907{
7908 if (level <0 || level >= fContour.fN) return 0;
7909 Double_t zlevel = fContour.fArray[level];
7910
7911 // In case of user defined contours and Pad in log scale along Z,
7912 // fContour.fArray doesn't contain the log of the contour whereas it does
7913 // in case of equidistant contours.
7914 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
7915 if (zlevel <= 0) return 0;
7916 zlevel = TMath::Log10(zlevel);
7917 }
7918 return zlevel;
7919}
7920
7921////////////////////////////////////////////////////////////////////////////////
7922/// Set the maximum number of entries to be kept in the buffer.
7923
7924void TH1::SetBuffer(Int_t buffersize, Option_t * /*option*/)
7925{
7926 if (fBuffer) {
7927 BufferEmpty();
7928 delete [] fBuffer;
7929 fBuffer = 0;
7930 }
7931 if (buffersize <= 0) {
7932 fBufferSize = 0;
7933 return;
7934 }
7935 if (buffersize < 100) buffersize = 100;
7936 fBufferSize = 1 + buffersize*(fDimension+1);
7938 memset(fBuffer,0,sizeof(Double_t)*fBufferSize);
7939}
7940
7941////////////////////////////////////////////////////////////////////////////////
7942/// Set the number and values of contour levels.
7943///
7944/// By default the number of contour levels is set to 20. The contours values
7945/// in the array "levels" should be specified in increasing order.
7946///
7947/// if argument levels = 0 or missing, equidistant contours are computed
7948
7949void TH1::SetContour(Int_t nlevels, const Double_t *levels)
7950{
7951 Int_t level;
7953 if (nlevels <=0 ) {
7954 fContour.Set(0);
7955 return;
7956 }
7957 fContour.Set(nlevels);
7958
7959 // - Contour levels are specified
7960 if (levels) {
7962 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
7963 } else {
7964 // - contour levels are computed automatically as equidistant contours
7965 Double_t zmin = GetMinimum();
7966 Double_t zmax = GetMaximum();
7967 if ((zmin == zmax) && (zmin != 0)) {
7968 zmax += 0.01*TMath::Abs(zmax);
7969 zmin -= 0.01*TMath::Abs(zmin);
7970 }
7971 Double_t dz = (zmax-zmin)/Double_t(nlevels);
7972 if (gPad && gPad->GetLogz()) {
7973 if (zmax <= 0) return;
7974 if (zmin <= 0) zmin = 0.001*zmax;
7975 zmin = TMath::Log10(zmin);
7976 zmax = TMath::Log10(zmax);
7977 dz = (zmax-zmin)/Double_t(nlevels);
7978 }
7979 for (level=0; level<nlevels; level++) {
7980 fContour.fArray[level] = zmin + dz*Double_t(level);
7981 }
7982 }
7983}
7984
7985////////////////////////////////////////////////////////////////////////////////
7986/// Set value for one contour level.
7987
7988void TH1::SetContourLevel(Int_t level, Double_t value)
7989{
7990 if (level < 0 || level >= fContour.fN) return;
7992 fContour.fArray[level] = value;
7993}
7994
7995////////////////////////////////////////////////////////////////////////////////
7996/// Return maximum value smaller than maxval of bins in the range,
7997/// unless the value has been overridden by TH1::SetMaximum,
7998/// in which case it returns that value. (This happens, for example,
7999/// when the histogram is drawn and the y or z axis limits are changed
8000///
8001/// To get the maximum value of bins in the histogram regardless of
8002/// whether the value has been overridden, use
8003///
8004/// ~~~ {.cpp}
8005/// h->GetBinContent(h->GetMaximumBin())
8006/// ~~~
8007
8008Double_t TH1::GetMaximum(Double_t maxval) const
8009{
8010 if (fMaximum != -1111) return fMaximum;
8011
8012 // empty the buffer
8013 if (fBuffer) ((TH1*)this)->BufferEmpty();
8014
8015 Int_t bin, binx, biny, binz;
8016 Int_t xfirst = fXaxis.GetFirst();
8017 Int_t xlast = fXaxis.GetLast();
8018 Int_t yfirst = fYaxis.GetFirst();
8019 Int_t ylast = fYaxis.GetLast();
8020 Int_t zfirst = fZaxis.GetFirst();
8021 Int_t zlast = fZaxis.GetLast();
8022 Double_t maximum = -FLT_MAX, value;
8023 for (binz=zfirst;binz<=zlast;binz++) {
8024 for (biny=yfirst;biny<=ylast;biny++) {
8025 for (binx=xfirst;binx<=xlast;binx++) {
8026 bin = GetBin(binx,biny,binz);
8027 value = RetrieveBinContent(bin);
8028 if (value > maximum && value < maxval) maximum = value;
8029 }
8030 }
8031 }
8032 return maximum;
8033}
8034
8035////////////////////////////////////////////////////////////////////////////////
8036/// Return location of bin with maximum value in the range.
8037
8039{
8040 Int_t locmax, locmay, locmaz;
8041 return GetMaximumBin(locmax, locmay, locmaz);
8042}
8043
8044////////////////////////////////////////////////////////////////////////////////
8045/// Return location of bin with maximum value in the range.
8046
8047Int_t TH1::GetMaximumBin(Int_t &locmax, Int_t &locmay, Int_t &locmaz) const
8048{
8049 // empty the buffer
8050 if (fBuffer) ((TH1*)this)->BufferEmpty();
8051
8052 Int_t bin, binx, biny, binz;
8053 Int_t locm;
8054 Int_t xfirst = fXaxis.GetFirst();
8055 Int_t xlast = fXaxis.GetLast();
8056 Int_t yfirst = fYaxis.GetFirst();
8057 Int_t ylast = fYaxis.GetLast();
8058 Int_t zfirst = fZaxis.GetFirst();
8059 Int_t zlast = fZaxis.GetLast();
8060 Double_t maximum = -FLT_MAX, value;
8061 locm = locmax = locmay = locmaz = 0;
8062 for (binz=zfirst;binz<=zlast;binz++) {
8063 for (biny=yfirst;biny<=ylast;biny++) {
8064 for (binx=xfirst;binx<=xlast;binx++) {
8065 bin = GetBin(binx,biny,binz);
8066 value = RetrieveBinContent(bin);
8067 if (value > maximum) {
8068 maximum = value;
8069 locm = bin;
8070 locmax = binx;
8071 locmay = biny;
8072 locmaz = binz;
8073 }
8074 }
8075 }
8076 }
8077 return locm;
8078}
8079
8080////////////////////////////////////////////////////////////////////////////////
8081/// Return minimum value larger than minval of bins in the range,
8082/// unless the value has been overridden by TH1::SetMinimum,
8083/// in which case it returns that value. (This happens, for example,
8084/// when the histogram is drawn and the y or z axis limits are changed
8085///
8086/// To get the minimum value of bins in the histogram regardless of
8087/// whether the value has been overridden, use
8088///
8089/// ~~~ {.cpp}
8090/// h->GetBinContent(h->GetMinimumBin())
8091/// ~~~
8092
8093Double_t TH1::GetMinimum(Double_t minval) const
8094{
8095 if (fMinimum != -1111) return fMinimum;
8096
8097 // empty the buffer
8098 if (fBuffer) ((TH1*)this)->BufferEmpty();
8099
8100 Int_t bin, binx, biny, binz;
8101 Int_t xfirst = fXaxis.GetFirst();
8102 Int_t xlast = fXaxis.GetLast();
8103 Int_t yfirst = fYaxis.GetFirst();
8104 Int_t ylast = fYaxis.GetLast();
8105 Int_t zfirst = fZaxis.GetFirst();
8106 Int_t zlast = fZaxis.GetLast();
8107 Double_t minimum=FLT_MAX, value;
8108 for (binz=zfirst;binz<=zlast;binz++) {
8109 for (biny=yfirst;biny<=ylast;biny++) {
8110 for (binx=xfirst;binx<=xlast;binx++) {
8111 bin = GetBin(binx,biny,binz);
8112 value = RetrieveBinContent(bin);
8113 if (value < minimum && value > minval) minimum = value;
8114 }
8115 }
8116 }
8117 return minimum;
8118}
8119
8120////////////////////////////////////////////////////////////////////////////////
8121/// Return location of bin with minimum value in the range.
8122
8124{
8125 Int_t locmix, locmiy, locmiz;
8126 return GetMinimumBin(locmix, locmiy, locmiz);
8127}
8128
8129////////////////////////////////////////////////////////////////////////////////
8130/// Return location of bin with minimum value in the range.
8131
8132Int_t TH1::GetMinimumBin(Int_t &locmix, Int_t &locmiy, Int_t &locmiz) const
8133{
8134 // empty the buffer
8135 if (fBuffer) ((TH1*)this)->BufferEmpty();
8136
8137 Int_t bin, binx, biny, binz;
8138 Int_t locm;
8139 Int_t xfirst = fXaxis.GetFirst();
8140 Int_t xlast = fXaxis.GetLast();
8141 Int_t yfirst = fYaxis.GetFirst();
8142 Int_t ylast = fYaxis.GetLast();
8143 Int_t zfirst = fZaxis.GetFirst();
8144 Int_t zlast = fZaxis.GetLast();
8145 Double_t minimum = FLT_MAX, value;
8146 locm = locmix = locmiy = locmiz = 0;
8147 for (binz=zfirst;binz<=zlast;binz++) {
8148 for (biny=yfirst;biny<=ylast;biny++) {
8149 for (binx=xfirst;binx<=xlast;binx++) {
8150 bin = GetBin(binx,biny,binz);
8151 value = RetrieveBinContent(bin);
8152 if (value < minimum) {
8153 minimum = value;
8154 locm = bin;
8155 locmix = binx;
8156 locmiy = biny;
8157 locmiz = binz;
8158 }
8159 }
8160 }
8161 }
8162 return locm;
8163}
8164
8165///////////////////////////////////////////////////////////////////////////////
8166/// Retrieve the minimum and maximum values in the histogram
8167///
8168/// This will not return a cached value and will always search the
8169/// histogram for the min and max values. The user can condition whether
8170/// or not to call this with the GetMinimumStored() and GetMaximumStored()
8171/// methods. If the cache is empty, then the value will be -1111. Users
8172/// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8173/// For example, the following recipe will make efficient use of this method
8174/// and the cached minimum and maximum values.
8175//
8176/// \code{.cpp}
8177/// Double_t currentMin = pHist->GetMinimumStored();
8178/// Double_t currentMax = pHist->GetMaximumStored();
8179/// if ((currentMin == -1111) || (currentMax == -1111)) {
8180/// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8181/// pHist->SetMinimum(currentMin);
8182/// pHist->SetMaximum(currentMax);
8183/// }
8184/// \endcode
8185///
8186/// \param min reference to variable that will hold found minimum value
8187/// \param max reference to variable that will hold found maximum value
8188
8189void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8190{
8191 // empty the buffer
8192 if (fBuffer) ((TH1*)this)->BufferEmpty();
8193
8194 Int_t bin, binx, biny, binz;
8195 Int_t xfirst = fXaxis.GetFirst();
8196 Int_t xlast = fXaxis.GetLast();
8197 Int_t yfirst = fYaxis.GetFirst();
8198 Int_t ylast = fYaxis.GetLast();
8199 Int_t zfirst = fZaxis.GetFirst();
8200 Int_t zlast = fZaxis.GetLast();
8201 min=TMath::Infinity();
8202 max=-TMath::Infinity();
8203 Double_t value;
8204 for (binz=zfirst;binz<=zlast;binz++) {
8205 for (biny=yfirst;biny<=ylast;biny++) {
8206 for (binx=xfirst;binx<=xlast;binx++) {
8207 bin = GetBin(binx,biny,binz);
8208 value = RetrieveBinContent(bin);
8209 if (value < min) min = value;
8210 if (value > max) max = value;
8211 }
8212 }
8213 }
8214}
8215
8216////////////////////////////////////////////////////////////////////////////////
8217/// Redefine x axis parameters.
8218///
8219/// The X axis parameters are modified.
8220/// The bins content array is resized
8221/// if errors (Sumw2) the errors array is resized
8222/// The previous bin contents are lost
8223/// To change only the axis limits, see TAxis::SetRange
8224
8226{
8227 if (GetDimension() != 1) {
8228 Error("SetBins","Operation only valid for 1-d histograms");
8229 return;
8230 }
8231 fXaxis.SetRange(0,0);
8232 fXaxis.Set(nx,xmin,xmax);
8233 fYaxis.Set(1,0,1);
8234 fZaxis.Set(1,0,1);
8235 fNcells = nx+2;
8237 if (fSumw2.fN) {
8239 }
8240}
8241
8242////////////////////////////////////////////////////////////////////////////////
8243/// Redefine x axis parameters with variable bin sizes.
8244///
8245/// The X axis parameters are modified.
8246/// The bins content array is resized
8247/// if errors (Sumw2) the errors array is resized
8248/// The previous bin contents are lost
8249/// To change only the axis limits, see TAxis::SetRange
8250/// xBins is supposed to be of length nx+1
8251
8252void TH1::SetBins(Int_t nx, const Double_t *xBins)
8253{
8254 if (GetDimension() != 1) {
8255 Error("SetBins","Operation only valid for 1-d histograms");
8256 return;
8257 }
8258 fXaxis.SetRange(0,0);
8259 fXaxis.Set(nx,xBins);
8260 fYaxis.Set(1,0,1);
8261 fZaxis.Set(1,0,1);
8262 fNcells = nx+2;
8264 if (fSumw2.fN) {
8266 }
8267}
8268
8269////////////////////////////////////////////////////////////////////////////////
8270/// Redefine x and y axis parameters.
8271///
8272/// The X and Y axis parameters are modified.
8273/// The bins content array is resized
8274/// if errors (Sumw2) the errors array is resized
8275/// The previous bin contents are lost
8276/// To change only the axis limits, see TAxis::SetRange
8277
8279{
8280 if (GetDimension() != 2) {
8281 Error("SetBins","Operation only valid for 2-D histograms");
8282 return;
8283 }
8284 fXaxis.SetRange(0,0);
8285 fYaxis.SetRange(0,0);
8286 fXaxis.Set(nx,xmin,xmax);
8287 fYaxis.Set(ny,ymin,ymax);
8288 fZaxis.Set(1,0,1);
8289 fNcells = (nx+2)*(ny+2);
8291 if (fSumw2.fN) {
8293 }
8294}
8295
8296////////////////////////////////////////////////////////////////////////////////
8297/// Redefine x and y axis parameters with variable bin sizes.
8298///
8299/// The X and Y axis parameters are modified.
8300/// The bins content array is resized
8301/// if errors (Sumw2) the errors array is resized
8302/// The previous bin contents are lost
8303/// To change only the axis limits, see TAxis::SetRange
8304/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
8305
8306void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
8307{
8308 if (GetDimension() != 2) {
8309 Error("SetBins","Operation only valid for 2-D histograms");
8310 return;
8311 }
8312 fXaxis.SetRange(0,0);
8313 fYaxis.SetRange(0,0);
8314 fXaxis.Set(nx,xBins);
8315 fYaxis.Set(ny,yBins);
8316 fZaxis.Set(1,0,1);
8317 fNcells = (nx+2)*(ny+2);
8319 if (fSumw2.fN) {
8321 }
8322}
8323
8324////////////////////////////////////////////////////////////////////////////////
8325/// Redefine x, y and z axis parameters.
8326///
8327/// The X, Y and Z axis parameters are modified.
8328/// The bins content array is resized
8329/// if errors (Sumw2) the errors array is resized
8330/// The previous bin contents are lost
8331/// To change only the axis limits, see TAxis::SetRange
8332
8334{
8335 if (GetDimension() != 3) {
8336 Error("SetBins","Operation only valid for 3-D histograms");
8337 return;
8338 }
8339 fXaxis.SetRange(0,0);
8340 fYaxis.SetRange(0,0);
8341 fZaxis.SetRange(0,0);
8342 fXaxis.Set(nx,xmin,xmax);
8343 fYaxis.Set(ny,ymin,ymax);
8344 fZaxis.Set(nz,zmin,zmax);
8345 fNcells = (nx+2)*(ny+2)*(nz+2);
8347 if (fSumw2.fN) {
8349 }
8350}
8351
8352////////////////////////////////////////////////////////////////////////////////
8353/// Redefine x, y and z axis parameters with variable bin sizes.
8354///
8355/// The X, Y and Z axis parameters are modified.
8356/// The bins content array is resized
8357/// if errors (Sumw2) the errors array is resized
8358/// The previous bin contents are lost
8359/// To change only the axis limits, see TAxis::SetRange
8360/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
8361/// zBins is supposed to be of length nz+1
8362
8363void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
8364{
8365 if (GetDimension() != 3) {
8366 Error("SetBins","Operation only valid for 3-D histograms");
8367 return;
8368 }
8369 fXaxis.SetRange(0,0);
8370 fYaxis.SetRange(0,0);
8371 fZaxis.SetRange(0,0);
8372 fXaxis.Set(nx,xBins);
8373 fYaxis.Set(ny,yBins);
8374 fZaxis.Set(nz,zBins);
8375 fNcells = (nx+2)*(ny+2)*(nz+2);
8377 if (fSumw2.fN) {
8379 }
8380}
8381
8382////////////////////////////////////////////////////////////////////////////////
8383/// By default when an histogram is created, it is added to the list
8384/// of histogram objects in the current directory in memory.
8385/// Remove reference to this histogram from current directory and add
8386/// reference to new directory dir. dir can be 0 in which case the
8387/// histogram does not belong to any directory.
8388///
8389/// Note that the directory is not a real property of the histogram and
8390/// it will not be copied when the histogram is copied or cloned.
8391/// If the user wants to have the copied (cloned) histogram in the same
8392/// directory, he needs to set again the directory using SetDirectory to the
8393/// copied histograms
8394
8396{
8397 if (fDirectory == dir) return;
8398 if (fDirectory) fDirectory->Remove(this);
8399 fDirectory = dir;
8400 if (fDirectory) {
8402 fDirectory->Append(this);
8403 }
8404}
8405
8406////////////////////////////////////////////////////////////////////////////////
8407/// Replace bin errors by values in array error.
8408
8409void TH1::SetError(const Double_t *error)
8410{
8411 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
8412}
8413
8414////////////////////////////////////////////////////////////////////////////////
8415/// Change the name of this histogram
8417
8418void TH1::SetName(const char *name)
8419{
8420 // Histograms are named objects in a THashList.
8421 // We must update the hashlist if we change the name
8422 // We protect this operation
8424 if (fDirectory) fDirectory->Remove(this);
8425 fName = name;
8426 if (fDirectory) fDirectory->Append(this);
8427}
8428
8429////////////////////////////////////////////////////////////////////////////////
8430/// Change the name and title of this histogram
8431
8432void TH1::SetNameTitle(const char *name, const char *title)
8433{
8434 // Histograms are named objects in a THashList.
8435 // We must update the hashlist if we change the name
8436 SetName(name);
8437 SetTitle(title);
8438}
8439
8440////////////////////////////////////////////////////////////////////////////////
8441/// Set statistics option on/off
8442///
8443/// By default, the statistics box is drawn.
8444/// The paint options can be selected via gStyle->SetOptStats.
8445/// This function sets/resets the kNoStats bin in the histogram object.
8446/// It has priority over the Style option.
8447
8448void TH1::SetStats(Bool_t stats)
8449{
8451 if (!stats) {
8453 //remove the "stats" object from the list of functions
8454 if (fFunctions) {
8455 TObject *obj = fFunctions->FindObject("stats");
8456 if (obj) {
8457 fFunctions->Remove(obj);
8458 delete obj;
8459 }
8460 }
8461 }
8462}
8463
8464////////////////////////////////////////////////////////////////////////////////
8465/// Create structure to store sum of squares of weights.
8466///
8467/// if histogram is already filled, the sum of squares of weights
8468/// is filled with the existing bin contents
8469///
8470/// The error per bin will be computed as sqrt(sum of squares of weight)
8471/// for each bin.
8472///
8473/// This function is automatically called when the histogram is created
8474/// if the static function TH1::SetDefaultSumw2 has been called before.
8475/// If flag = false the structure containing the sum of the square of weights
8476/// is rest and it will be empty, but it is not deleted (i.e. GetSumw2()->fN = 0)
8477
8478void TH1::Sumw2(Bool_t flag)
8479{
8480 if (!flag) {
8481 // clear the array if existing - do nothing otherwise
8482 if (fSumw2.fN > 0 ) fSumw2.Set(0);
8483 return;
8484 }
8485
8486 if (fSumw2.fN == fNcells) {
8487 if (!fgDefaultSumw2 )
8488 Warning("Sumw2","Sum of squares of weights structure already created");
8489 return;
8490 }
8491
8493
8494 // empty the buffer
8495 if (fBuffer) BufferEmpty();
8496
8497 if (fEntries > 0)
8498 for (Int_t i = 0; i < fNcells; ++i)
8500}
8501
8502////////////////////////////////////////////////////////////////////////////////
8503/// Return pointer to function with name.
8504///
8505///
8506/// Functions such as TH1::Fit store the fitted function in the list of
8507/// functions of this histogram.
8508
8509TF1 *TH1::GetFunction(const char *name) const
8510{
8511 return (TF1*)fFunctions->FindObject(name);
8512}
8513
8514////////////////////////////////////////////////////////////////////////////////
8515/// Return value of error associated to bin number bin.
8516///
8517/// if the sum of squares of weights has been defined (via Sumw2),
8518/// this function returns the sqrt(sum of w2).
8519/// otherwise it returns the sqrt(contents) for this bin.
8520
8522{
8523 if (bin < 0) bin = 0;
8524 if (bin >= fNcells) bin = fNcells-1;
8525 if (fBuffer) ((TH1*)this)->BufferEmpty();
8526 if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
8527
8529}
8530
8531////////////////////////////////////////////////////////////////////////////////
8532/// Return lower error associated to bin number bin.
8533///
8534/// The error will depend on the statistic option used will return
8535/// the binContent - lower interval value
8536
8538{
8539 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
8540 // in case of weighted histogram check if it is really weighted
8541 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
8542
8543 if (bin < 0) bin = 0;
8544 if (bin >= fNcells) bin = fNcells-1;
8545 if (fBuffer) ((TH1*)this)->BufferEmpty();
8546
8547 Double_t alpha = 1.- 0.682689492;
8548 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
8549
8551 Int_t n = int(c);
8552 if (n < 0) {
8553 Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
8554 ((TH1*)this)->fBinStatErrOpt = kNormal;
8555 return GetBinError(bin);
8556 }
8557
8558 if (n == 0) return 0;
8559 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
8560}
8561
8562////////////////////////////////////////////////////////////////////////////////
8563/// Return upper error associated to bin number bin.
8564///
8565/// The error will depend on the statistic option used will return
8566/// the binContent - upper interval value
8567
8569{
8570 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
8571 // in case of weighted histogram check if it is really weighted
8572 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
8573 if (bin < 0) bin = 0;
8574 if (bin >= fNcells) bin = fNcells-1;
8575 if (fBuffer) ((TH1*)this)->BufferEmpty();
8576
8577 Double_t alpha = 1.- 0.682689492;
8578 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
8579
8581 Int_t n = int(c);
8582 if (n < 0) {
8583 Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
8584 ((TH1*)this)->fBinStatErrOpt = kNormal;
8585 return GetBinError(bin);
8586 }
8587
8588 // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
8589 // decide to return always (1-alpha)/2 upper interval
8590 //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
8591 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
8592}
8593
8594//L.M. These following getters are useless and should be probably deprecated
8595////////////////////////////////////////////////////////////////////////////////
8596/// Return bin center for 1D histogram.
8597/// Better to use h1.GetXaxis().GetBinCenter(bin)
8598
8600{
8601 if (fDimension == 1) return fXaxis.GetBinCenter(bin);
8602 Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
8603 return TMath::QuietNaN();
8604}
8605
8606////////////////////////////////////////////////////////////////////////////////
8607/// Return bin lower edge for 1D histogram.
8608/// Better to use h1.GetXaxis().GetBinLowEdge(bin)
8609
8611{
8612 if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
8613 Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
8614 return TMath::QuietNaN();
8615}
8616
8617////////////////////////////////////////////////////////////////////////////////
8618/// Return bin width for 1D histogram.
8619/// Better to use h1.GetXaxis().GetBinWidth(bin)
8620
8622{
8623 if (fDimension == 1) return fXaxis.GetBinWidth(bin);
8624 Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
8625 return TMath::QuietNaN();
8626}
8627
8628////////////////////////////////////////////////////////////////////////////////
8629/// Fill array with center of bins for 1D histogram
8630/// Better to use h1.GetXaxis().GetCenter(center)
8631
8632void TH1::GetCenter(Double_t *center) const
8633{
8634 if (fDimension == 1) {
8635 fXaxis.GetCenter(center);
8636 return;
8637 }
8638 Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
8639}
8640
8641////////////////////////////////////////////////////////////////////////////////
8642/// Fill array with low edge of bins for 1D histogram
8643/// Better to use h1.GetXaxis().GetLowEdge(edge)
8644
8645void TH1::GetLowEdge(Double_t *edge) const
8646{
8647 if (fDimension == 1) {
8648 fXaxis.GetLowEdge(edge);
8649 return;
8650 }
8651 Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
8652}
8653
8654////////////////////////////////////////////////////////////////////////////////
8655/// Set the bin Error
8656/// Note that this resets the bin eror option to be of Normal Type and for the
8657/// non-empty bin the bin error is set by default to the square root of their content.
8658/// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
8659/// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
8660/// will not recalcualated after setting the content and a default error = 0 will be used for those bins.
8661///
8662/// See convention for numbering bins in TH1::GetBin
8663
8664void TH1::SetBinError(Int_t bin, Double_t error)
8665{
8666 if (bin < 0 || bin>= fNcells) return;
8667 if (!fSumw2.fN) Sumw2();
8668 fSumw2.fArray[bin] = error * error;
8669 // reset the bin error option
8671}
8672
8673////////////////////////////////////////////////////////////////////////////////
8674/// Set bin content
8675/// see convention for numbering bins in TH1::GetBin
8676/// In case the bin number is greater than the number of bins and
8677/// the timedisplay option is set or CanExtendAllAxes(),
8678/// the number of bins is automatically doubled to accommodate the new bin
8679
8680void TH1::SetBinContent(Int_t bin, Double_t content)
8681{
8682 fEntries++;
8683 fTsumw = 0;
8684 if (bin < 0) return;
8685 if (bin >= fNcells-1) {
8687 while (bin >= fNcells-1) LabelsInflate();
8688 } else {
8689 if (bin == fNcells-1) UpdateBinContent(bin, content);
8690 return;
8691 }
8692 }
8693 UpdateBinContent(bin, content);
8694}
8695
8696////////////////////////////////////////////////////////////////////////////////
8697/// See convention for numbering bins in TH1::GetBin
8698
8699void TH1::SetBinError(Int_t binx, Int_t biny, Double_t error)
8700{
8701 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
8702 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
8703 SetBinError(GetBin(binx, biny), error);
8704}
8705
8706////////////////////////////////////////////////////////////////////////////////
8707/// See convention for numbering bins in TH1::GetBin
8708
8709void TH1::SetBinError(Int_t binx, Int_t biny, Int_t binz, Double_t error)
8710{
8711 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
8712 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
8713 if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
8714 SetBinError(GetBin(binx, biny, binz), error);
8715}
8716
8717////////////////////////////////////////////////////////////////////////////////
8718/// This function calculates the background spectrum in this histogram.
8719/// The background is returned as a histogram.
8720///
8721/// \param[in] niter number of iterations (default value = 2)
8722/// Increasing niter make the result smoother and lower.
8723/// \param[in] option may contain one of the following options
8724/// - to set the direction parameter
8725/// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
8726/// - filterOrder-order of clipping filter (default "BackOrder2")
8727/// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
8728/// - "nosmoothing" - if selected, the background is not smoothed
8729/// By default the background is smoothed.
8730/// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
8731/// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
8732/// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
8733/// - "nocompton" - if selected the estimation of Compton edge
8734/// will be not be included (by default the compton estimation is set)
8735/// - "same" if this option is specified, the resulting background
8736/// histogram is superimposed on the picture in the current pad.
8737/// This option is given by default.
8738///
8739/// NOTE that the background is only evaluated in the current range of this histogram.
8740/// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
8741/// the returned histogram will be created with the same number of bins
8742/// as this input histogram, but only bins from binmin to binmax will be filled
8743/// with the estimated background.
8744
8745TH1 *TH1::ShowBackground(Int_t niter, Option_t *option)
8746{
8747
8748 return (TH1*)gROOT->ProcessLineFast(Form("TSpectrum::StaticBackground((TH1*)0x%lx,%d,\"%s\")",
8749 (ULong_t)this, niter, option));
8750}
8751
8752////////////////////////////////////////////////////////////////////////////////
8753/// Interface to TSpectrum::Search.
8754/// The function finds peaks in this histogram where the width is > sigma
8755/// and the peak maximum greater than threshold*maximum bin content of this.
8756/// For more details see TSpectrum::Search.
8757/// Note the difference in the default value for option compared to TSpectrum::Search
8758/// option="" by default (instead of "goff").
8759
8761{
8762 return (Int_t)gROOT->ProcessLineFast(Form("TSpectrum::StaticSearch((TH1*)0x%lx,%g,\"%s\",%g)",
8763 (ULong_t)this, sigma, option, threshold));
8764}
8765
8766////////////////////////////////////////////////////////////////////////////////
8767/// For a given transform (first parameter), fills the histogram (second parameter)
8768/// with the transform output data, specified in the third parameter
8769/// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
8770/// and the user is responsible for deleting it.
8771///
8772/// Available options:
8773/// - "RE" - real part of the output
8774/// - "IM" - imaginary part of the output
8775/// - "MAG" - magnitude of the output
8776/// - "PH" - phase of the output
8777
8778TH1* TH1::TransformHisto(TVirtualFFT *fft, TH1* h_output, Option_t *option)
8779{
8780 if (!fft || !fft->GetN() ) {
8781 ::Error("TransformHisto","Invalid FFT transform class");
8782 return 0;
8783 }
8784
8785 if (fft->GetNdim()>2){
8786 ::Error("TransformHisto","Only 1d and 2D transform are supported");
8787 return 0;
8788 }
8789 Int_t binx,biny;
8790 TString opt = option;
8791 opt.ToUpper();
8792 Int_t *n = fft->GetN();
8793 TH1 *hout=0;
8794 if (h_output) {
8795 hout = h_output;
8796 }
8797 else {
8798 TString name = TString::Format("out_%s", opt.Data());
8799 if (fft->GetNdim()==1)
8800 hout = new TH1D(name, name,n[0], 0, n[0]);
8801 else if (fft->GetNdim()==2)
8802 hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
8803 }
8804 R__ASSERT(hout != 0);
8805 TString type=fft->GetType();
8806 Int_t ind[2];
8807 if (opt.Contains("RE")){
8808 if (type.Contains("2C") || type.Contains("2HC")) {
8809 Double_t re, im;
8810 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8811 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8812 ind[0] = binx-1; ind[1] = biny-1;
8813 fft->GetPointComplex(ind, re, im);
8814 hout->SetBinContent(binx, biny, re);
8815 }
8816 }
8817 } else {
8818 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8819 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8820 ind[0] = binx-1; ind[1] = biny-1;
8821 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
8822 }
8823 }
8824 }
8825 }
8826 if (opt.Contains("IM")) {
8827 if (type.Contains("2C") || type.Contains("2HC")) {
8828 Double_t re, im;
8829 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8830 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8831 ind[0] = binx-1; ind[1] = biny-1;
8832 fft->GetPointComplex(ind, re, im);
8833 hout->SetBinContent(binx, biny, im);
8834 }
8835 }
8836 } else {
8837 ::Error("TransformHisto","No complex numbers in the output");
8838 return 0;
8839 }
8840 }
8841 if (opt.Contains("MA")) {
8842 if (type.Contains("2C") || type.Contains("2HC")) {
8843 Double_t re, im;
8844 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8845 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8846 ind[0] = binx-1; ind[1] = biny-1;
8847 fft->GetPointComplex(ind, re, im);
8848 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
8849 }
8850 }
8851 } else {
8852 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8853 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8854 ind[0] = binx-1; ind[1] = biny-1;
8855 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
8856 }
8857 }
8858 }
8859 }
8860 if (opt.Contains("PH")) {
8861 if (type.Contains("2C") || type.Contains("2HC")){
8862 Double_t re, im, ph;
8863 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
8864 for (biny=1; biny<=hout->GetNbinsY(); biny++){
8865 ind[0] = binx-1; ind[1] = biny-1;
8866 fft->GetPointComplex(ind, re, im);
8867 if (TMath::Abs(re) > 1e-13){
8868 ph = TMath::ATan(im/re);
8869 //find the correct quadrant
8870 if (re<0 && im<0)
8871 ph -= TMath::Pi();
8872 if (re<0 && im>=0)
8873 ph += TMath::Pi();
8874 } else {
8875 if (TMath::Abs(im) < 1e-13)
8876 ph = 0;
8877 else if (im>0)
8878 ph = TMath::Pi()*0.5;
8879 else
8880 ph = -TMath::Pi()*0.5;
8881 }
8882 hout->SetBinContent(binx, biny, ph);
8883 }
8884 }
8885 } else {
8886 printf("Pure real output, no phase");
8887 return 0;
8888 }
8889 }
8890
8891 return hout;
8892}
8893
8894////////////////////////////////////////////////////////////////////////////////
8895/// Raw retrieval of bin content on internal data structure
8896/// see convention for numbering bins in TH1::GetBin
8897
8899{
8900 AbstractMethod("RetrieveBinContent");
8901 return 0;
8902}
8903
8904////////////////////////////////////////////////////////////////////////////////
8905/// Raw update of bin content on internal data structure
8906/// see convention for numbering bins in TH1::GetBin
8907
8909{
8910 AbstractMethod("UpdateBinContent");
8911}
8912
8913////////////////////////////////////////////////////////////////////////////////
8914/// Print value overload
8915
8916std::string cling::printValue(TH1 *val) {
8917 std::ostringstream strm;
8918 strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
8919 return strm.str();
8920}
8921
8922//______________________________________________________________________________
8923// TH1C methods
8924// TH1C : histograms with one byte per channel. Maximum bin content = 127
8925//______________________________________________________________________________
8926
8927ClassImp(TH1C);
8928
8929////////////////////////////////////////////////////////////////////////////////
8930/// Constructor.
8931
8932TH1C::TH1C(): TH1(), TArrayC()
8933{
8934 fDimension = 1;
8935 SetBinsLength(3);
8936 if (fgDefaultSumw2) Sumw2();
8937}
8938
8939////////////////////////////////////////////////////////////////////////////////
8940/// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
8941/// (see TH1::TH1 for explanation of parameters)
8942
8943TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
8944: TH1(name,title,nbins,xlow,xup)
8945{
8946 fDimension = 1;
8948
8949 if (xlow >= xup) SetBuffer(fgBufferSize);
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 Float_t *xbins)
8958: TH1(name,title,nbins,xbins)
8959{
8960 fDimension = 1;
8962 if (fgDefaultSumw2) Sumw2();
8963}
8964
8965////////////////////////////////////////////////////////////////////////////////
8966/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
8967/// (see TH1::TH1 for explanation of parameters)
8968
8969TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
8970: TH1(name,title,nbins,xbins)
8971{
8972 fDimension = 1;
8974 if (fgDefaultSumw2) Sumw2();
8975}
8976
8977////////////////////////////////////////////////////////////////////////////////
8978/// Destructor.
8979
8981{
8982}
8983
8984////////////////////////////////////////////////////////////////////////////////
8985/// Copy constructor.
8986
8987TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
8988{
8989 ((TH1C&)h1c).Copy(*this);
8990}
8991
8992////////////////////////////////////////////////////////////////////////////////
8993/// Increment bin content by 1.
8994
8995void TH1C::AddBinContent(Int_t bin)
8996{
8997 if (fArray[bin] < 127) fArray[bin]++;
8998}
8999
9000////////////////////////////////////////////////////////////////////////////////
9001/// Increment bin content by w.
9002
9004{
9005 Int_t newval = fArray[bin] + Int_t(w);
9006 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
9007 if (newval < -127) fArray[bin] = -127;
9008 if (newval > 127) fArray[bin] = 127;
9009}
9010
9011////////////////////////////////////////////////////////////////////////////////
9012/// Copy this to newth1
9013
9014void TH1C::Copy(TObject &newth1) const
9015{
9016 TH1::Copy(newth1);
9017}
9018
9019////////////////////////////////////////////////////////////////////////////////
9020/// Reset.
9021
9022void TH1C::Reset(Option_t *option)
9023{
9024 TH1::Reset(option);
9026}
9027
9028////////////////////////////////////////////////////////////////////////////////
9029/// Set total number of bins including under/overflow
9030/// Reallocate bin contents array
9031
9033{
9034 if (n < 0) n = fXaxis.GetNbins() + 2;
9035 fNcells = n;
9036 TArrayC::Set(n);
9037}
9038
9039////////////////////////////////////////////////////////////////////////////////
9040/// Operator =
9041
9042TH1C& TH1C::operator=(const TH1C &h1)
9043{
9044 if (this != &h1) ((TH1C&)h1).Copy(*this);
9045 return *this;
9046}
9047
9048////////////////////////////////////////////////////////////////////////////////
9049/// Operator *
9050
9052{
9053 TH1C hnew = h1;
9054 hnew.Scale(c1);
9055 hnew.SetDirectory(0);
9056 return hnew;
9057}
9058
9059////////////////////////////////////////////////////////////////////////////////
9060/// Operator +
9061
9062TH1C operator+(const TH1C &h1, const TH1C &h2)
9063{
9064 TH1C hnew = h1;
9065 hnew.Add(&h2,1);
9066 hnew.SetDirectory(0);
9067 return hnew;
9068}
9069
9070////////////////////////////////////////////////////////////////////////////////
9071/// Operator -
9072
9073TH1C operator-(const TH1C &h1, const TH1C &h2)
9074{
9075 TH1C hnew = h1;
9076 hnew.Add(&h2,-1);
9077 hnew.SetDirectory(0);
9078 return hnew;
9079}
9080
9081////////////////////////////////////////////////////////////////////////////////
9082/// Operator *
9083
9084TH1C operator*(const TH1C &h1, const TH1C &h2)
9085{
9086 TH1C hnew = h1;
9087 hnew.Multiply(&h2);
9088 hnew.SetDirectory(0);
9089 return hnew;
9090}
9091
9092////////////////////////////////////////////////////////////////////////////////
9093/// Operator /
9094
9095TH1C operator/(const TH1C &h1, const TH1C &h2)
9096{
9097 TH1C hnew = h1;
9098 hnew.Divide(&h2);
9099 hnew.SetDirectory(0);
9100 return hnew;
9101}
9102
9103//______________________________________________________________________________
9104// TH1S methods
9105// TH1S : histograms with one short per channel. Maximum bin content = 32767
9106//______________________________________________________________________________
9107
9108ClassImp(TH1S);
9109
9110////////////////////////////////////////////////////////////////////////////////
9111/// Constructor.
9112
9113TH1S::TH1S(): TH1(), TArrayS()
9114{
9115 fDimension = 1;
9116 SetBinsLength(3);
9117 if (fgDefaultSumw2) Sumw2();
9118}
9119
9120////////////////////////////////////////////////////////////////////////////////
9121/// Create a 1-Dim histogram with fix bins of type short
9122/// (see TH1::TH1 for explanation of parameters)
9123
9124TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9125: TH1(name,title,nbins,xlow,xup)
9126{
9127 fDimension = 1;
9129
9130 if (xlow >= xup) SetBuffer(fgBufferSize);
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 Float_t *xbins)
9139: TH1(name,title,nbins,xbins)
9140{
9141 fDimension = 1;
9143 if (fgDefaultSumw2) Sumw2();
9144}
9145
9146////////////////////////////////////////////////////////////////////////////////
9147/// Create a 1-Dim histogram with variable bins of type short
9148/// (see TH1::TH1 for explanation of parameters)
9149
9150TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9151: TH1(name,title,nbins,xbins)
9152{
9153 fDimension = 1;
9155 if (fgDefaultSumw2) Sumw2();
9156}
9157
9158////////////////////////////////////////////////////////////////////////////////
9159/// Destructor.
9160
9162{
9163}
9164
9165////////////////////////////////////////////////////////////////////////////////
9166/// Copy constructor.
9167
9168TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9169{
9170 ((TH1S&)h1s).Copy(*this);
9171}
9172
9173////////////////////////////////////////////////////////////////////////////////
9174/// Increment bin content by 1.
9175
9176void TH1S::AddBinContent(Int_t bin)
9177{
9178 if (fArray[bin] < 32767) fArray[bin]++;
9179}
9180
9181////////////////////////////////////////////////////////////////////////////////
9182/// Increment bin content by w
9183
9185{
9186 Int_t newval = fArray[bin] + Int_t(w);
9187 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9188 if (newval < -32767) fArray[bin] = -32767;
9189 if (newval > 32767) fArray[bin] = 32767;
9190}
9191
9192////////////////////////////////////////////////////////////////////////////////
9193/// Copy this to newth1
9194
9195void TH1S::Copy(TObject &newth1) const
9196{
9197 TH1::Copy(newth1);
9198}
9199
9200////////////////////////////////////////////////////////////////////////////////
9201/// Reset.
9202
9203void TH1S::Reset(Option_t *option)
9204{
9205 TH1::Reset(option);
9207}
9208
9209////////////////////////////////////////////////////////////////////////////////
9210/// Set total number of bins including under/overflow
9211/// Reallocate bin contents array
9212
9214{
9215 if (n < 0) n = fXaxis.GetNbins() + 2;
9216 fNcells = n;
9217 TArrayS::Set(n);
9218}
9219
9220////////////////////////////////////////////////////////////////////////////////
9221/// Operator =
9222
9223TH1S& TH1S::operator=(const TH1S &h1)
9224{
9225 if (this != &h1) ((TH1S&)h1).Copy(*this);
9226 return *this;
9227}
9228
9229////////////////////////////////////////////////////////////////////////////////
9230/// Operator *
9231
9233{
9234 TH1S hnew = h1;
9235 hnew.Scale(c1);
9236 hnew.SetDirectory(0);
9237 return hnew;
9238}
9239
9240////////////////////////////////////////////////////////////////////////////////
9241/// Operator +
9242
9243TH1S operator+(const TH1S &h1, const TH1S &h2)
9244{
9245 TH1S hnew = h1;
9246 hnew.Add(&h2,1);
9247 hnew.SetDirectory(0);
9248 return hnew;
9249}
9250
9251////////////////////////////////////////////////////////////////////////////////
9252/// Operator -
9253
9254TH1S operator-(const TH1S &h1, const TH1S &h2)
9255{
9256 TH1S hnew = h1;
9257 hnew.Add(&h2,-1);
9258 hnew.SetDirectory(0);
9259 return hnew;
9260}
9261
9262////////////////////////////////////////////////////////////////////////////////
9263/// Operator *
9264
9265TH1S operator*(const TH1S &h1, const TH1S &h2)
9266{
9267 TH1S hnew = h1;
9268 hnew.Multiply(&h2);
9269 hnew.SetDirectory(0);
9270 return hnew;
9271}
9272
9273////////////////////////////////////////////////////////////////////////////////
9274/// Operator /
9275
9276TH1S operator/(const TH1S &h1, const TH1S &h2)
9277{
9278 TH1S hnew = h1;
9279 hnew.Divide(&h2);
9280 hnew.SetDirectory(0);
9281 return hnew;
9282}
9283
9284//______________________________________________________________________________
9285// TH1I methods
9286// TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9287//______________________________________________________________________________
9288
9289ClassImp(TH1I);
9290
9291////////////////////////////////////////////////////////////////////////////////
9292/// Constructor.
9293
9294TH1I::TH1I(): TH1(), TArrayI()
9295{
9296 fDimension = 1;
9297 SetBinsLength(3);
9298 if (fgDefaultSumw2) Sumw2();
9299}
9300
9301////////////////////////////////////////////////////////////////////////////////
9302/// Create a 1-Dim histogram with fix bins of type integer
9303/// (see TH1::TH1 for explanation of parameters)
9304
9305TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9306: TH1(name,title,nbins,xlow,xup)
9307{
9308 fDimension = 1;
9310
9311 if (xlow >= xup) SetBuffer(fgBufferSize);
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 Float_t *xbins)
9320: TH1(name,title,nbins,xbins)
9321{
9322 fDimension = 1;
9324 if (fgDefaultSumw2) Sumw2();
9325}
9326
9327////////////////////////////////////////////////////////////////////////////////
9328/// Create a 1-Dim histogram with variable bins of type integer
9329/// (see TH1::TH1 for explanation of parameters)
9330
9331TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9332: TH1(name,title,nbins,xbins)
9333{
9334 fDimension = 1;
9336 if (fgDefaultSumw2) Sumw2();
9337}
9338
9339////////////////////////////////////////////////////////////////////////////////
9340/// Destructor.
9341
9343{
9344}
9345
9346////////////////////////////////////////////////////////////////////////////////
9347/// Copy constructor.
9348
9349TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
9350{
9351 ((TH1I&)h1i).Copy(*this);
9352}
9353
9354////////////////////////////////////////////////////////////////////////////////
9355/// Increment bin content by 1.
9356
9357void TH1I::AddBinContent(Int_t bin)
9358{
9359 if (fArray[bin] < 2147483647) fArray[bin]++;
9360}
9361
9362////////////////////////////////////////////////////////////////////////////////
9363/// Increment bin content by w
9364
9366{
9367 Long64_t newval = fArray[bin] + Long64_t(w);
9368 if (newval > -2147483647 && newval < 2147483647) {fArray[bin] = Int_t(newval); return;}
9369 if (newval < -2147483647) fArray[bin] = -2147483647;
9370 if (newval > 2147483647) fArray[bin] = 2147483647;
9371}
9372
9373////////////////////////////////////////////////////////////////////////////////
9374/// Copy this to newth1
9375
9376void TH1I::Copy(TObject &newth1) const
9377{
9378 TH1::Copy(newth1);
9379}
9380
9381////////////////////////////////////////////////////////////////////////////////
9382/// Reset.
9383
9384void TH1I::Reset(Option_t *option)
9385{
9386 TH1::Reset(option);
9388}
9389
9390////////////////////////////////////////////////////////////////////////////////
9391/// Set total number of bins including under/overflow
9392/// Reallocate bin contents array
9393
9395{
9396 if (n < 0) n = fXaxis.GetNbins() + 2;
9397 fNcells = n;
9398 TArrayI::Set(n);
9399}
9400
9401////////////////////////////////////////////////////////////////////////////////
9402/// Operator =
9403
9404TH1I& TH1I::operator=(const TH1I &h1)
9405{
9406 if (this != &h1) ((TH1I&)h1).Copy(*this);
9407 return *this;
9408}
9409
9410
9411////////////////////////////////////////////////////////////////////////////////
9412/// Operator *
9413
9415{
9416 TH1I hnew = h1;
9417 hnew.Scale(c1);
9418 hnew.SetDirectory(0);
9419 return hnew;
9420}
9421
9422////////////////////////////////////////////////////////////////////////////////
9423/// Operator +
9424
9425TH1I operator+(const TH1I &h1, const TH1I &h2)
9426{
9427 TH1I hnew = h1;
9428 hnew.Add(&h2,1);
9429 hnew.SetDirectory(0);
9430 return hnew;
9431}
9432
9433////////////////////////////////////////////////////////////////////////////////
9434/// Operator -
9435
9436TH1I operator-(const TH1I &h1, const TH1I &h2)
9437{
9438 TH1I hnew = h1;
9439 hnew.Add(&h2,-1);
9440 hnew.SetDirectory(0);
9441 return hnew;
9442}
9443
9444////////////////////////////////////////////////////////////////////////////////
9445/// Operator *
9446
9447TH1I operator*(const TH1I &h1, const TH1I &h2)
9448{
9449 TH1I hnew = h1;
9450 hnew.Multiply(&h2);
9451 hnew.SetDirectory(0);
9452 return hnew;
9453}
9454
9455////////////////////////////////////////////////////////////////////////////////
9456/// Operator /
9457
9458TH1I operator/(const TH1I &h1, const TH1I &h2)
9459{
9460 TH1I hnew = h1;
9461 hnew.Divide(&h2);
9462 hnew.SetDirectory(0);
9463 return hnew;
9464}
9465
9466//______________________________________________________________________________
9467// TH1F methods
9468// TH1F : histograms with one float per channel. Maximum precision 7 digits
9469//______________________________________________________________________________
9470
9471ClassImp(TH1F);
9472
9473////////////////////////////////////////////////////////////////////////////////
9474/// Constructor.
9475
9476TH1F::TH1F(): TH1(), TArrayF()
9477{
9478 fDimension = 1;
9479 SetBinsLength(3);
9480 if (fgDefaultSumw2) Sumw2();
9481}
9482
9483////////////////////////////////////////////////////////////////////////////////
9484/// Create a 1-Dim histogram with fix bins of type float
9485/// (see TH1::TH1 for explanation of parameters)
9486
9487TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9488: TH1(name,title,nbins,xlow,xup)
9489{
9490 fDimension = 1;
9492
9493 if (xlow >= xup) SetBuffer(fgBufferSize);
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 Float_t *xbins)
9502: TH1(name,title,nbins,xbins)
9503{
9504 fDimension = 1;
9506 if (fgDefaultSumw2) Sumw2();
9507}
9508
9509////////////////////////////////////////////////////////////////////////////////
9510/// Create a 1-Dim histogram with variable bins of type float
9511/// (see TH1::TH1 for explanation of parameters)
9512
9513TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9514: TH1(name,title,nbins,xbins)
9515{
9516 fDimension = 1;
9518 if (fgDefaultSumw2) Sumw2();
9519}
9520
9521////////////////////////////////////////////////////////////////////////////////
9522/// Create a histogram from a TVectorF
9523/// by default the histogram name is "TVectorF" and title = ""
9524
9525TH1F::TH1F(const TVectorF &v)
9526: TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
9527{
9529 fDimension = 1;
9530 Int_t ivlow = v.GetLwb();
9531 for (Int_t i=0;i<fNcells-2;i++) {
9532 SetBinContent(i+1,v(i+ivlow));
9533 }
9535 if (fgDefaultSumw2) Sumw2();
9536}
9537
9538////////////////////////////////////////////////////////////////////////////////
9539/// Copy Constructor.
9540
9541TH1F::TH1F(const TH1F &h) : TH1(), TArrayF()
9542{
9543 ((TH1F&)h).Copy(*this);
9544}
9545
9546////////////////////////////////////////////////////////////////////////////////
9547/// Destructor.
9548
9550{
9551}
9552
9553////////////////////////////////////////////////////////////////////////////////
9554/// Copy this to newth1.
9555
9556void TH1F::Copy(TObject &newth1) const
9557{
9558 TH1::Copy(newth1);
9559}
9560
9561////////////////////////////////////////////////////////////////////////////////
9562/// Reset.
9563
9564void TH1F::Reset(Option_t *option)
9565{
9566 TH1::Reset(option);
9568}
9569
9570////////////////////////////////////////////////////////////////////////////////
9571/// Set total number of bins including under/overflow
9572/// Reallocate bin contents array
9573
9575{
9576 if (n < 0) n = fXaxis.GetNbins() + 2;
9577 fNcells = n;
9578 TArrayF::Set(n);
9579}
9580
9581////////////////////////////////////////////////////////////////////////////////
9582/// Operator =
9583
9584TH1F& TH1F::operator=(const TH1F &h1)
9585{
9586 if (this != &h1) ((TH1F&)h1).Copy(*this);
9587 return *this;
9588}
9589
9590////////////////////////////////////////////////////////////////////////////////
9591/// Operator *
9592
9594{
9595 TH1F hnew = h1;
9596 hnew.Scale(c1);
9597 hnew.SetDirectory(0);
9598 return hnew;
9599}
9600
9601////////////////////////////////////////////////////////////////////////////////
9602/// Operator +
9603
9604TH1F operator+(const TH1F &h1, const TH1F &h2)
9605{
9606 TH1F hnew = h1;
9607 hnew.Add(&h2,1);
9608 hnew.SetDirectory(0);
9609 return hnew;
9610}
9611
9612////////////////////////////////////////////////////////////////////////////////
9613/// Operator -
9614
9615TH1F operator-(const TH1F &h1, const TH1F &h2)
9616{
9617 TH1F hnew = h1;
9618 hnew.Add(&h2,-1);
9619 hnew.SetDirectory(0);
9620 return hnew;
9621}
9622
9623////////////////////////////////////////////////////////////////////////////////
9624/// Operator *
9625
9626TH1F operator*(const TH1F &h1, const TH1F &h2)
9627{
9628 TH1F hnew = h1;
9629 hnew.Multiply(&h2);
9630 hnew.SetDirectory(0);
9631 return hnew;
9632}
9633
9634////////////////////////////////////////////////////////////////////////////////
9635/// Operator /
9636
9637TH1F operator/(const TH1F &h1, const TH1F &h2)
9638{
9639 TH1F hnew = h1;
9640 hnew.Divide(&h2);
9641 hnew.SetDirectory(0);
9642 return hnew;
9643}
9644
9645//______________________________________________________________________________
9646// TH1D methods
9647// TH1D : histograms with one double per channel. Maximum precision 14 digits
9648//______________________________________________________________________________
9649
9650ClassImp(TH1D);
9651
9652////////////////////////////////////////////////////////////////////////////////
9653/// Constructor.
9654
9655TH1D::TH1D(): TH1(), TArrayD()
9656{
9657 fDimension = 1;
9658 SetBinsLength(3);
9659 if (fgDefaultSumw2) Sumw2();
9660}
9661
9662////////////////////////////////////////////////////////////////////////////////
9663/// Create a 1-Dim histogram with fix bins of type double
9664/// (see TH1::TH1 for explanation of parameters)
9665
9666TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9667: TH1(name,title,nbins,xlow,xup)
9668{
9669 fDimension = 1;
9671
9672 if (xlow >= xup) SetBuffer(fgBufferSize);
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 Float_t *xbins)
9681: TH1(name,title,nbins,xbins)
9682{
9683 fDimension = 1;
9685 if (fgDefaultSumw2) Sumw2();
9686}
9687
9688////////////////////////////////////////////////////////////////////////////////
9689/// Create a 1-Dim histogram with variable bins of type double
9690/// (see TH1::TH1 for explanation of parameters)
9691
9692TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9693: TH1(name,title,nbins,xbins)
9694{
9695 fDimension = 1;
9697 if (fgDefaultSumw2) Sumw2();
9698}
9699
9700////////////////////////////////////////////////////////////////////////////////
9701/// Create a histogram from a TVectorD
9702/// by default the histogram name is "TVectorD" and title = ""
9703
9704TH1D::TH1D(const TVectorD &v)
9705: TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
9706{
9708 fDimension = 1;
9709 Int_t ivlow = v.GetLwb();
9710 for (Int_t i=0;i<fNcells-2;i++) {
9711 SetBinContent(i+1,v(i+ivlow));
9712 }
9714 if (fgDefaultSumw2) Sumw2();
9715}
9716
9717////////////////////////////////////////////////////////////////////////////////
9718/// Destructor.
9719
9721{
9722}
9723
9724////////////////////////////////////////////////////////////////////////////////
9725/// Constructor.
9726
9727TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
9728{
9729 ((TH1D&)h1d).Copy(*this);
9730}
9731
9732////////////////////////////////////////////////////////////////////////////////
9733/// Copy this to newth1
9734
9735void TH1D::Copy(TObject &newth1) const
9736{
9737 TH1::Copy(newth1);
9738}
9739
9740////////////////////////////////////////////////////////////////////////////////
9741/// Reset.
9742
9743void TH1D::Reset(Option_t *option)
9744{
9745 TH1::Reset(option);
9747}
9748
9749////////////////////////////////////////////////////////////////////////////////
9750/// Set total number of bins including under/overflow
9751/// Reallocate bin contents array
9752
9754{
9755 if (n < 0) n = fXaxis.GetNbins() + 2;
9756 fNcells = n;
9757 TArrayD::Set(n);
9758}
9759
9760////////////////////////////////////////////////////////////////////////////////
9761/// Operator =
9762
9763TH1D& TH1D::operator=(const TH1D &h1)
9764{
9765 if (this != &h1) ((TH1D&)h1).Copy(*this);
9766 return *this;
9767}
9768
9769////////////////////////////////////////////////////////////////////////////////
9770/// Operator *
9771
9773{
9774 TH1D hnew = h1;
9775 hnew.Scale(c1);
9776 hnew.SetDirectory(0);
9777 return hnew;
9778}
9779
9780////////////////////////////////////////////////////////////////////////////////
9781/// Operator +
9782
9783TH1D operator+(const TH1D &h1, const TH1D &h2)
9784{
9785 TH1D hnew = h1;
9786 hnew.Add(&h2,1);
9787 hnew.SetDirectory(0);
9788 return hnew;
9789}
9790
9791////////////////////////////////////////////////////////////////////////////////
9792/// Operator -
9793
9794TH1D operator-(const TH1D &h1, const TH1D &h2)
9795{
9796 TH1D hnew = h1;
9797 hnew.Add(&h2,-1);
9798 hnew.SetDirectory(0);
9799 return hnew;
9800}
9801
9802////////////////////////////////////////////////////////////////////////////////
9803/// Operator *
9804
9805TH1D operator*(const TH1D &h1, const TH1D &h2)
9806{
9807 TH1D hnew = h1;
9808 hnew.Multiply(&h2);
9809 hnew.SetDirectory(0);
9810 return hnew;
9811}
9812
9813////////////////////////////////////////////////////////////////////////////////
9814/// Operator /
9815
9816TH1D operator/(const TH1D &h1, const TH1D &h2)
9817{
9818 TH1D hnew = h1;
9819 hnew.Divide(&h2);
9820 hnew.SetDirectory(0);
9821 return hnew;
9822}
9823
9824////////////////////////////////////////////////////////////////////////////////
9825///return pointer to histogram with name
9826///hid if id >=0
9827///h_id if id <0
9828
9829TH1 *R__H(Int_t hid)
9830{
9831 TString hname;
9832 if(hid >= 0) hname.Form("h%d",hid);
9833 else hname.Form("h_%d",hid);
9834 return (TH1*)gDirectory->Get(hname);
9835}
9836
9837////////////////////////////////////////////////////////////////////////////////
9838///return pointer to histogram with name hname
9839
9840TH1 *R__H(const char * hname)
9841{
9842 return (TH1*)gDirectory->Get(hname);
9843}
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:43
short Version_t
Definition: RtypesCore.h:63
char Char_t
Definition: RtypesCore.h:31
unsigned int UInt_t
Definition: RtypesCore.h:44
const Bool_t kFALSE
Definition: RtypesCore.h:90
unsigned long ULong_t
Definition: RtypesCore.h:53
bool Bool_t
Definition: RtypesCore.h:61
short Short_t
Definition: RtypesCore.h:37
double Double_t
Definition: RtypesCore.h:57
double Stat_t
Definition: RtypesCore.h:75
short Color_t
Definition: RtypesCore.h:81
long long Long64_t
Definition: RtypesCore.h:71
short Style_t
Definition: RtypesCore.h:78
float Float_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:89
const char Option_t
Definition: RtypesCore.h:64
#define ClassImp(name)
Definition: Rtypes.h:361
#define gDirectory
Definition: TDirectory.h:229
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:5491
void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
Least square linear fit without weights.
Definition: TH1.cxx:4674
void H1InitGaus()
Compute Initial values of parameters for a gaussian.
Definition: TH1.cxx:4509
void H1InitExpo()
Compute Initial values of parameters for an exponential.
Definition: TH1.cxx:4565
TH1C operator+(const TH1C &h1, const TH1C &h2)
Operator +.
Definition: TH1.cxx:9060
TH1C operator-(const TH1C &h1, const TH1C &h2)
Operator -.
Definition: TH1.cxx:9071
TH1C operator/(const TH1C &h1, const TH1C &h2)
Operator /.
Definition: TH1.cxx:9093
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:4720
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:5474
static Bool_t AlmostInteger(Double_t a, Double_t epsilon=0.00000001)
Test if a double is almost an integer.
Definition: TH1.cxx:5482
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:9827
TH1C operator*(Double_t c1, const TH1C &h1)
Operator *.
Definition: TH1.cxx:9049
void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
Least squares lpolynomial fitting without weights.
Definition: TH1.cxx:4615
void H1InitPolynom()
Compute Initial values of parameters for a polynom.
Definition: TH1.cxx:4585
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:556
int isnan(double)
double ldexp(double, int)
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:59
#define gROOT
Definition: TROOT.h:406
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:410
#define R__LOCKGUARD(mutex)
#define gPad
Definition: TVirtualPad.h:287
#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:339
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:235
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:550
virtual Bool_t GetTimeDisplay() const
Definition: TAxis.h:126
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition: TAxis.cxx:475
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:658
@ 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:437
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:290
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:515
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:728
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition: TAxis.cxx:416
virtual void Copy(TObject &axis) const
Copy axis structure to another axis.
Definition: TAxis.cxx:207
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:466
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:559
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:914
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:537
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition: TAxis.cxx:525
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:455
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:40
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
Definition: TDirectory.cxx:191
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:210
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:3647
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function.
Definition: TF1.cxx:1567
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:2505
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=0)
Evaluate function with given coordinates and parameters.
Definition: TF1.cxx:1461
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition: TF1.cxx:2457
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition: TF1.cxx:2266
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set limits for parameter ipar.
Definition: TF1.cxx:3500
static Bool_t RejectedPoint()
See TF1::RejectPoint above.
Definition: TF1.cxx:3656
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:1432
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:9040
TH1C()
Constructor.
Definition: TH1.cxx:8930
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:9012
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9030
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH1.cxx:8993
virtual ~TH1C()
Destructor.
Definition: TH1.cxx:8978
virtual void Reset(Option_t *option="")
Reset.
Definition: TH1.cxx:9020
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:9733
virtual ~TH1D()
Destructor.
Definition: TH1.cxx:9718
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9751
TH1D()
Constructor.
Definition: TH1.cxx:9653
TH1D & operator=(const TH1D &h1)
Operator =.
Definition: TH1.cxx:9761
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:9547
TH1F & operator=(const TH1F &h1)
Operator =.
Definition: TH1.cxx:9582
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9572
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:9554
TH1F()
Constructor.
Definition: TH1.cxx:9474
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:9374
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH1.cxx:9355
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9392
virtual ~TH1I()
Destructor.
Definition: TH1.cxx:9340
TH1I()
Constructor.
Definition: TH1.cxx:9292
TH1I & operator=(const TH1I &h1)
Operator =.
Definition: TH1.cxx:9402
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:9174
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition: TH1.cxx:9211
virtual ~TH1S()
Destructor.
Definition: TH1.cxx:9159
TH1S & operator=(const TH1S &h1)
Operator =.
Definition: TH1.cxx:9221
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition: TH1.cxx:9193
TH1S()
Constructor.
Definition: TH1.cxx:9111
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:8407
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:8393
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition: TH1.cxx:4163
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
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition: TH1.cxx:4327
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TH1.cxx:6789
virtual void SetTitle(const char *title)
See GetStatOverflows for more information.
Definition: TH1.cxx:6345
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition: TH1.cxx:6512
virtual void Print(Option_t *option="") const
Print some global quantities for this histogram.
Definition: TH1.cxx:6642
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition: TH1.cxx:8597
virtual void Rebuild(Option_t *option="")
Using the current bin info, recompute the arrays for contents and errors.
Definition: TH1.cxx:6720
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:5662
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:7345
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:6558
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:4459
static Int_t GetDefaultBufferSize()
Static function return the default buffer size for automatic histograms the parameter fgBufferSize ma...
Definition: TH1.cxx:4285
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:7486
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:7140
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:8776
virtual void LabelsOption(Option_t *option="h", Option_t *axis="X")
Set option(s) to draw axis with labels.
Definition: TH1.cxx:5222
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:8519
static Int_t FitOptionsMake(Option_t *option, Foption_t &Foption)
Decode string choptin and fill fitOption structure.
Definition: TH1.cxx:4500
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:7086
virtual Double_t GetSkewness(Int_t axis=1) const
Definition: TH1.cxx:7192
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:7904
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:4856
virtual void SetContourLevel(Int_t level, Double_t value)
Set value for one contour level.
Definition: TH1.cxx:7986
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition: TH1.cxx:6278
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:6736
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:4822
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:7022
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:8758
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition: TH1.cxx:5521
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition: TH1.cxx:7396
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition: TH1.cxx:4368
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:4294
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:4809
@ 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 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:8006
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:5161
virtual TH1 * ShowBackground(Int_t niter=20, Option_t *option="same")
This function calculates the background spectrum in this histogram.
Definition: TH1.cxx:8743
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:5511
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:6218
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:8896
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:7477
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:8662
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:8535
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition: TH1.cxx:7862
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:6931
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:7947
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:5060
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:4961
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:6330
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition: TH1.cxx:5028
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:7450
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:8678
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:8643
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8608
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:4302
virtual TF1 * GetFunction(const char *name) const
Return pointer to function with name.
Definition: TH1.cxx:8507
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:4932
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:6291
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:5010
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition: TH1.cxx:7117
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:7570
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculates from bin cont...
Definition: TH1.cxx:7411
static void SetDefaultBufferSize(Int_t buffersize=1000)
Static function to set the default buffer size for automatic histograms.
Definition: TH1.cxx:6320
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:7922
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Definition: TH1.cxx:3106
@ kNstat
Definition: TH1.h:179
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:8187
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition: TH1.cxx:8036
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:8416
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:8906
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:4907
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:6146
virtual void SetNameTitle(const char *name, const char *title)
Change the name and title of this histogram.
Definition: TH1.cxx:8430
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8619
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:4218
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition: TH1.cxx:7894
virtual void SetHighlight(Bool_t set=kTRUE)
Set highlight (enable/disable) mode for the histogram by default highlight mode is disable.
Definition: TH1.cxx:4338
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition: TH1.cxx:8566
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition: TH1.cxx:6246
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms.
Definition: TH1.cxx:5837
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition: TH1.cxx:8121
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:7179
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:8091
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:7684
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7426
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:6394
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:8630
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:8223
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:4359
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition: TH1.cxx:8476
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:6089
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:5091
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:7875
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:8446
virtual TH1 * Rebin(Int_t ngroup=2, const char *newname="", const Double_t *xbins=0)
Rebin this histogram.
Definition: TH1.cxx:5904
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition: TH1.cxx:7262
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:821
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:577
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:356
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: TList.cxx:763
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:469
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:658
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:933
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:187
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:877
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:891
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:705
void ResetBit(UInt_t f)
Definition: TObject.h:186
@ 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:865
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:234
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:1590
void SetHistFillColor(Color_t color=1)
Definition: TStyle.h:360
Color_t GetHistLineColor() const
Definition: TStyle.h:222
Bool_t IsReading() const
Definition: TStyle.h:280
Float_t GetBarOffset() const
Definition: TStyle.h:172
void SetHistLineStyle(Style_t styl=0)
Definition: TStyle.h:363
Style_t GetHistFillStyle() const
Definition: TStyle.h:223
Color_t GetHistFillColor() const
Definition: TStyle.h:221
Float_t GetBarWidth() const
Definition: TStyle.h:173
Bool_t GetCanvasPreferGL() const
Definition: TStyle.h:177
void SetHistLineColor(Color_t color=1)
Definition: TStyle.h:361
void SetBarOffset(Float_t baroff=0.5)
Definition: TStyle.h:317
Style_t GetHistLineStyle() const
Definition: TStyle.h:224
void SetBarWidth(Float_t barwidth=0.5)
Definition: TStyle.h:318
void SetHistFillStyle(Style_t styl=0)
Definition: TStyle.h:362
Width_t GetHistLineWidth() const
Definition: TStyle.h:225
Int_t GetOptFit() const
Definition: TStyle.h:233
void SetHistLineWidth(Width_t width=1)
Definition: TStyle.h:364
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:972
void FitOptionsMake(EFitObjectType type, const char *option, Foption_t &fitOption)
Decode list of options into fitOption.
Definition: HFitImpl.cxx:685
void FillData(BinData &dv, const TH1 *hist, TF1 *func=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:1026
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:614
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:656
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:2275
REAL epsilon
Definition: triangle.c:617