Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TH1.cxx
Go to the documentation of this file.
1// @(#)root/hist:$Id$
2// Author: Rene Brun 26/12/94
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <cstdlib>
13#include <cstring>
14#include <cstdio>
15#include <cctype>
16#include <climits>
17#include <sstream>
18#include <cmath>
19#include <iostream>
20
21#include "TROOT.h"
22#include "TBuffer.h"
23#include "TEnv.h"
24#include "TClass.h"
25#include "TMath.h"
26#include "THashList.h"
27#include "TH1.h"
28#include "TH2.h"
29#include "TH3.h"
30#include "TF2.h"
31#include "TF3.h"
32#include "TPluginManager.h"
33#include "TVirtualPad.h"
34#include "TRandom.h"
35#include "TVirtualFitter.h"
36#include "THLimitsFinder.h"
37#include "TProfile.h"
38#include "TStyle.h"
39#include "TVectorF.h"
40#include "TVectorD.h"
41#include "TBrowser.h"
42#include "TError.h"
43#include "TVirtualHistPainter.h"
44#include "TVirtualFFT.h"
45#include "TVirtualPaveStats.h"
46
47#include "HFitInterface.h"
48#include "Fit/DataRange.h"
49#include "Fit/BinData.h"
50#include "Math/GoFTest.h"
53
54#include "TH1Merger.h"
55
56/** \addtogroup 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
72TH1 is the base class of all histogram classes in %ROOT.
73
74It provides the common interface for operations such as binning, filling, drawing, which
75will be detailed below.
76
77-# [Creating histograms](\ref creating-histograms)
78 - [Labelling axes](\ref labelling-axis)
79-# [Binning](\ref binning)
80 - [Fix or variable bin size](\ref fix-var)
81 - [Convention for numbering bins](\ref convention)
82 - [Alphanumeric Bin Labels](\ref alpha)
83 - [Histograms with automatic bins](\ref auto-bin)
84 - [Rebinning](\ref rebinning)
85-# [Filling histograms](\ref filling-histograms)
86 - [Associated errors](\ref associated-errors)
87 - [Associated functions](\ref associated-functions)
88 - [Projections of histograms](\ref prof-hist)
89 - [Random Numbers and histograms](\ref random-numbers)
90 - [Making a copy of an histogram](\ref making-a-copy)
91 - [Normalizing histograms](\ref normalizing)
92-# [Drawing histograms](\ref drawing-histograms)
93 - [Setting Drawing histogram contour levels (2-D hists only)](\ref cont-level)
94 - [Setting histogram graphics attributes](\ref graph-att)
95 - [Customising how axes are drawn](\ref axis-drawing)
96-# [Saving/reading histograms to/from a ROOT file](\ref saving-histograms)
97-# [Operations on histograms](\ref operations-on-histograms)
98 - [Fitting histograms](\ref fitting-histograms)
99-# [Miscellaneous operations](\ref misc)
100
101ROOT supports the following histogram types:
102
103 - 1-D histograms:
104 - TH1C : histograms with one byte per channel. Maximum bin content = 127
105 - TH1S : histograms with one short per channel. Maximum bin content = 32767
106 - TH1I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
107 - TH1F : histograms with one float per channel. Maximum precision 7 digits
108 - TH1D : histograms with one double per channel. Maximum precision 14 digits
109 - 2-D histograms:
110 - TH2C : histograms with one byte per channel. Maximum bin content = 127
111 - TH2S : histograms with one short per channel. Maximum bin content = 32767
112 - TH2I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
113 - TH2F : histograms with one float per channel. Maximum precision 7 digits
114 - TH2D : histograms with one double per channel. Maximum precision 14 digits
115 - 3-D histograms:
116 - TH3C : histograms with one byte per channel. Maximum bin content = 127
117 - TH3S : histograms with one short per channel. Maximum bin content = 32767
118 - TH3I : histograms with one int per channel. Maximum bin content = INT_MAX (\ref intmax "*")
119 - TH3F : histograms with one float per channel. Maximum precision 7 digits
120 - TH3D : histograms with one double per channel. Maximum precision 14 digits
121 - Profile histograms: See classes TProfile, TProfile2D and TProfile3D.
122 Profile histograms are used to display the mean value of Y and its standard deviation
123 for each bin in X. Profile histograms are in many cases an elegant
124 replacement of two-dimensional histograms : the inter-relation of two
125 measured quantities X and Y can always be visualized by a two-dimensional
126 histogram or scatter-plot; If Y is an unknown (but single-valued)
127 approximate function of X, this function is displayed by a profile
128 histogram with much better precision than by a scatter-plot.
129
130<sup>
131\anchor intmax (*) INT_MAX = 2147483647 is the [maximum value for a variable of type int.](https://docs.microsoft.com/en-us/cpp/c-language/cpp-integer-limits)
132</sup>
133
134The inheritance hierarchy looks as follows:
135
136\image html classTH1__inherit__graph_org.svg width=100%
137
138\anchor creating-histograms
139## Creating histograms
140
141Histograms are created by invoking one of the constructors, e.g.
142~~~ {.cpp}
143 TH1F *h1 = new TH1F("h1", "h1 title", 100, 0, 4.4);
144 TH2F *h2 = new TH2F("h2", "h2 title", 40, 0, 4, 30, -3, 3);
145~~~
146Histograms may also be created by:
147
148 - calling the Clone function, see below
149 - making a projection from a 2-D or 3-D histogram, see below
150 - reading an histogram from a file
151
152 When a histogram is created, a reference to it is automatically added
153 to the list of in-memory objects for the current file or directory.
154 This default behaviour can be changed by:
155~~~ {.cpp}
156 h->SetDirectory(0); // for the current histogram h
157 TH1::AddDirectory(kFALSE); // sets a global switch disabling the referencing
158~~~
159 When the histogram is deleted, the reference to it is removed from
160 the list of objects in memory.
161 When a file is closed, all histograms in memory associated with this file
162 are automatically deleted.
163
164\anchor labelling-axis
165### Labelling axes
166
167 Axis titles can be specified in the title argument of the constructor.
168 They must be separated by ";":
169~~~ {.cpp}
170 TH1F* h=new TH1F("h", "Histogram title;X Axis;Y Axis", 100, 0, 1);
171~~~
172 The histogram title and the axis titles can be any TLatex string, and
173 are persisted if a histogram is written to a file.
174
175 Any title can be omitted:
176~~~ {.cpp}
177 TH1F* h=new TH1F("h", "Histogram title;;Y Axis", 100, 0, 1);
178 TH1F* h=new TH1F("h", ";;Y Axis", 100, 0, 1);
179~~~
180 The method SetTitle() has the same syntax:
181~~~ {.cpp}
182 h->SetTitle("Histogram title;Another X title Axis");
183~~~
184Alternatively, the title of each axis can be set directly:
185~~~ {.cpp}
186 h->GetXaxis()->SetTitle("X axis title");
187 h->GetYaxis()->SetTitle("Y axis title");
188~~~
189For bin labels see \ref binning.
190
191\anchor binning
192## Binning
193
194\anchor fix-var
195### Fix or variable bin size
196
197 All histogram types support either fix or variable bin sizes.
198 2-D histograms may have fix size bins along X and variable size bins
199 along Y or vice-versa. The functions to fill, manipulate, draw or access
200 histograms are identical in both cases.
201
202 Each histogram always contains 3 axis objects of type TAxis: fXaxis, fYaxis and fZaxis.
203 To access the axis parameters, use:
204~~~ {.cpp}
205 TAxis *xaxis = h->GetXaxis(); etc.
206 Double_t binCenter = xaxis->GetBinCenter(bin), etc.
207~~~
208 See class TAxis for a description of all the access functions.
209 The axis range is always stored internally in double precision.
210
211\anchor convention
212### Convention for numbering bins
213
214 For all histogram types: nbins, xlow, xup
215~~~ {.cpp}
216 bin = 0; underflow bin
217 bin = 1; first bin with low-edge xlow INCLUDED
218 bin = nbins; last bin with upper-edge xup EXCLUDED
219 bin = nbins+1; overflow bin
220~~~
221 In case of 2-D or 3-D histograms, a "global bin" number is defined.
222 For example, assuming a 3-D histogram with (binx, biny, binz), the function
223~~~ {.cpp}
224 Int_t gbin = h->GetBin(binx, biny, binz);
225~~~
226 returns a global/linearized gbin number. This global gbin is useful
227 to access the bin content/error information independently of the dimension.
228 Note that to access the information other than bin content and errors
229 one should use the TAxis object directly with e.g.:
230~~~ {.cpp}
231 Double_t xcenter = h3->GetZaxis()->GetBinCenter(27);
232~~~
233 returns the center along z of bin number 27 (not the global bin)
234 in the 3-D histogram h3.
235
236\anchor alpha
237### Alphanumeric Bin Labels
238
239 By default, an histogram axis is drawn with its numeric bin labels.
240 One can specify alphanumeric labels instead with:
241
242 - call TAxis::SetBinLabel(bin, label);
243 This can always be done before or after filling.
244 When the histogram is drawn, bin labels will be automatically drawn.
245 See examples labels1.C and labels2.C
246 - call to a Fill function with one of the arguments being a string, e.g.
247~~~ {.cpp}
248 hist1->Fill(somename, weight);
249 hist2->Fill(x, somename, weight);
250 hist2->Fill(somename, y, weight);
251 hist2->Fill(somenamex, somenamey, weight);
252~~~
253 See examples hlabels1.C and hlabels2.C
254 - via TTree::Draw. see for example cernstaff.C
255~~~ {.cpp}
256 tree.Draw("Nation::Division");
257~~~
258 where "Nation" and "Division" are two branches of a Tree.
259
260When using the options 2 or 3 above, the labels are automatically
261 added to the list (THashList) of labels for a given axis.
262 By default, an axis is drawn with the order of bins corresponding
263 to the filling sequence. It is possible to reorder the axis
264
265 - alphabetically
266 - by increasing or decreasing values
267
268 The reordering can be triggered via the TAxis context menu by selecting
269 the menu item "LabelsOption" or by calling directly
270 TH1::LabelsOption(option, axis) where
272 - axis may be "X", "Y" or "Z"
273 - option may be:
274 - "a" sort by alphabetic order
275 - ">" sort by decreasing values
276 - "<" sort by increasing values
277 - "h" draw labels horizontal
278 - "v" draw labels vertical
279 - "u" draw labels up (end of label right adjusted)
280 - "d" draw labels down (start of label left adjusted)
281
282 When using the option 2 above, new labels are added by doubling the current
283 number of bins in case one label does not exist yet.
284 When the Filling is terminated, it is possible to trim the number
285 of bins to match the number of active labels by calling
286~~~ {.cpp}
287 TH1::LabelsDeflate(axis) with axis = "X", "Y" or "Z"
288~~~
289 This operation is automatic when using TTree::Draw.
290 Once bin labels have been created, they become persistent if the histogram
291 is written to a file or when generating the C++ code via SavePrimitive.
292
293\anchor auto-bin
294### Histograms with automatic bins
295
296 When an histogram is created with an axis lower limit greater or equal
297 to its upper limit, the SetBuffer is automatically called with an
298 argument fBufferSize equal to fgBufferSize (default value=1000).
299 fgBufferSize may be reset via the static function TH1::SetDefaultBufferSize.
300 The axis limits will be automatically computed when the buffer will
301 be full or when the function BufferEmpty is called.
302
303\anchor rebinning
304### Rebinning
305
306 At any time, an histogram can be rebinned via TH1::Rebin. This function
307 returns a new histogram with the rebinned contents.
308 If bin errors were stored, they are recomputed during the rebinning.
309
310
311\anchor filling-histograms
312## Filling histograms
313
314 An histogram is typically filled with statements like:
315~~~ {.cpp}
316 h1->Fill(x);
317 h1->Fill(x, w); //fill with weight
318 h2->Fill(x, y)
319 h2->Fill(x, y, w)
320 h3->Fill(x, y, z)
321 h3->Fill(x, y, z, w)
322~~~
323 or via one of the Fill functions accepting names described above.
324 The Fill functions compute the bin number corresponding to the given
325 x, y or z argument and increment this bin by the given weight.
326 The Fill functions return the bin number for 1-D histograms or global
327 bin number for 2-D and 3-D histograms.
328 If TH1::Sumw2 has been called before filling, the sum of squares of
329 weights is also stored.
330 One can also increment directly a bin number via TH1::AddBinContent
331 or replace the existing content via TH1::SetBinContent.
332 To access the bin content of a given bin, do:
333~~~ {.cpp}
334 Double_t binContent = h->GetBinContent(bin);
335~~~
336
337 By default, the bin number is computed using the current axis ranges.
338 If the automatic binning option has been set via
339~~~ {.cpp}
340 h->SetCanExtend(TH1::kAllAxes);
341~~~
342 then, the Fill Function will automatically extend the axis range to
343 accomodate the new value specified in the Fill argument. The method
344 used is to double the bin size until the new value fits in the range,
345 merging bins two by two. This automatic binning options is extensively
346 used by the TTree::Draw function when histogramming Tree variables
347 with an unknown range.
348 This automatic binning option is supported for 1-D, 2-D and 3-D histograms.
349
350 During filling, some statistics parameters are incremented to compute
351 the mean value and Root Mean Square with the maximum precision.
352
353 In case of histograms of type TH1C, TH1S, TH2C, TH2S, TH3C, TH3S
354 a check is made that the bin contents do not exceed the maximum positive
355 capacity (127 or 32767). Histograms of all types may have positive
356 or/and negative bin contents.
357
358\anchor associated-errors
359### Associated errors
360 By default, for each bin, the sum of weights is computed at fill time.
361 One can also call TH1::Sumw2 to force the storage and computation
362 of the sum of the square of weights per bin.
363 If Sumw2 has been called, the error per bin is computed as the
364 sqrt(sum of squares of weights), otherwise the error is set equal
365 to the sqrt(bin content).
366 To return the error for a given bin number, do:
367~~~ {.cpp}
368 Double_t error = h->GetBinError(bin);
369~~~
370
371\anchor associated-functions
372### Associated functions
373 One or more object (typically a TF1*) can be added to the list
374 of functions (fFunctions) associated to each histogram.
375 When TH1::Fit is invoked, the fitted function is added to this list.
376 Given an histogram h, one can retrieve an associated function
377 with:
378~~~ {.cpp}
379 TF1 *myfunc = h->GetFunction("myfunc");
380~~~
381
382
383\anchor operations-on-histograms
384## Operations on histograms
385
386 Many types of operations are supported on histograms or between histograms
387
388 - Addition of an histogram to the current histogram.
389 - Additions of two histograms with coefficients and storage into the current
390 histogram.
391 - Multiplications and Divisions are supported in the same way as additions.
392 - The Add, Divide and Multiply functions also exist to add, divide or multiply
393 an histogram by a function.
394
395 If an histogram has associated error bars (TH1::Sumw2 has been called),
396 the resulting error bars are also computed assuming independent histograms.
397 In case of divisions, Binomial errors are also supported.
398 One can mark a histogram to be an "average" histogram by setting its bit kIsAverage via
399 myhist.SetBit(TH1::kIsAverage);
400 When adding (see TH1::Add) average histograms, the histograms are averaged and not summed.
401
402\anchor fitting-histograms
403### Fitting histograms
404
405 Histograms (1-D, 2-D, 3-D and Profiles) can be fitted with a user
406 specified function via TH1::Fit. When an histogram is fitted, the
407 resulting function with its parameters is added to the list of functions
408 of this histogram. If the histogram is made persistent, the list of
409 associated functions is also persistent. Given a pointer (see above)
410 to an associated function myfunc, one can retrieve the function/fit
411 parameters with calls such as:
412~~~ {.cpp}
413 Double_t chi2 = myfunc->GetChisquare();
414 Double_t par0 = myfunc->GetParameter(0); value of 1st parameter
415 Double_t err0 = myfunc->GetParError(0); error on first parameter
416~~~
417
418\anchor prof-hist
419### Projections of histograms
420
421 One can:
422
423 - make a 1-D projection of a 2-D histogram or Profile
424 see functions TH2::ProjectionX,Y, TH2::ProfileX,Y, TProfile::ProjectionX
425 - make a 1-D, 2-D or profile out of a 3-D histogram
426 see functions TH3::ProjectionZ, TH3::Project3D.
427
428 One can fit these projections via:
429~~~ {.cpp}
430 TH2::FitSlicesX,Y, TH3::FitSlicesZ.
431~~~
432
433\anchor random-numbers
434### Random Numbers and histograms
435
436 TH1::FillRandom can be used to randomly fill an histogram using
437 the contents of an existing TF1 function or another
438 TH1 histogram (for all dimensions).
439 For example the following two statements create and fill an histogram
440 10000 times with a default gaussian distribution of mean 0 and sigma 1:
441~~~ {.cpp}
442 TH1F h1("h1", "histo from a gaussian", 100, -3, 3);
443 h1.FillRandom("gaus", 10000);
444~~~
445 TH1::GetRandom can be used to return a random number distributed
446 according the contents of an histogram.
447
448\anchor making-a-copy
449### Making a copy of an histogram
450 Like for any other ROOT object derived from TObject, one can use
451 the Clone() function. This makes an identical copy of the original
452 histogram including all associated errors and functions, e.g.:
453~~~ {.cpp}
454 TH1F *hnew = (TH1F*)h->Clone("hnew");
455~~~
456
457\anchor normalizing
458### Normalizing histograms
459
460 One can scale an histogram such that the bins integral is equal to
461 the normalization parameter via TH1::Scale(Double_t norm), where norm
462 is the desired normalization divided by the integral of the histogram.
463
464
465\anchor drawing-histograms
466## Drawing histograms
467
468 Histograms are drawn via the THistPainter class. Each histogram has
469 a pointer to its own painter (to be usable in a multithreaded program).
470 Many drawing options are supported.
471 See THistPainter::Paint() for more details.
472
473 The same histogram can be drawn with different options in different pads.
474 When an histogram drawn in a pad is deleted, the histogram is
475 automatically removed from the pad or pads where it was drawn.
476 If an histogram is drawn in a pad, then filled again, the new status
477 of the histogram will be automatically shown in the pad next time
478 the pad is updated. One does not need to redraw the histogram.
479 To draw the current version of an histogram in a pad, one can use
480~~~ {.cpp}
481 h->DrawCopy();
482~~~
483 This makes a clone (see Clone below) of the histogram. Once the clone
484 is drawn, the original histogram may be modified or deleted without
485 affecting the aspect of the clone.
486
487 One can use TH1::SetMaximum() and TH1::SetMinimum() to force a particular
488 value for the maximum or the minimum scale on the plot. (For 1-D
489 histograms this means the y-axis, while for 2-D histograms these
490 functions affect the z-axis).
491
492 TH1::UseCurrentStyle() can be used to change all histogram graphics
493 attributes to correspond to the current selected style.
494 This function must be called for each histogram.
495 In case one reads and draws many histograms from a file, one can force
496 the histograms to inherit automatically the current graphics style
497 by calling before gROOT->ForceStyle().
498
499\anchor cont-level
500### Setting Drawing histogram contour levels (2-D hists only)
501
502 By default contours are automatically generated at equidistant
503 intervals. A default value of 20 levels is used. This can be modified
504 via TH1::SetContour() or TH1::SetContourLevel().
505 the contours level info is used by the drawing options "cont", "surf",
506 and "lego".
507
508\anchor graph-att
509### Setting histogram graphics attributes
510
511 The histogram classes inherit from the attribute classes:
512 TAttLine, TAttFill, and TAttMarker.
513 See the member functions of these classes for the list of options.
514
515\anchor axis-drawing
516### Customising how axes are drawn
517
518 Use the functions of TAxis, such as
519~~~ {.cpp}
520 histogram.GetXaxis()->SetTicks("+");
521 histogram.GetYaxis()->SetRangeUser(1., 5.);
522~~~
523
524\anchor saving-histograms
525## Saving/reading histograms to/from a ROOT file
526
527 The following statements create a ROOT file and store an histogram
528 on the file. Because TH1 derives from TNamed, the key identifier on
529 the file is the histogram name:
530~~~ {.cpp}
531 TFile f("histos.root", "new");
532 TH1F h1("hgaus", "histo from a gaussian", 100, -3, 3);
533 h1.FillRandom("gaus", 10000);
534 h1->Write();
535~~~
536 To read this histogram in another Root session, do:
537~~~ {.cpp}
538 TFile f("histos.root");
539 TH1F *h = (TH1F*)f.Get("hgaus");
540~~~
541 One can save all histograms in memory to the file by:
542~~~ {.cpp}
543 file->Write();
544~~~
545
546
547\anchor misc
548## Miscellaneous operations
549
550~~~ {.cpp}
551 TH1::KolmogorovTest(): statistical test of compatibility in shape
552 between two histograms
553 TH1::Smooth() smooths the bin contents of a 1-d histogram
554 TH1::Integral() returns the integral of bin contents in a given bin range
555 TH1::GetMean(int axis) returns the mean value along axis
556 TH1::GetStdDev(int axis) returns the sigma distribution along axis
557 TH1::GetEntries() returns the number of entries
558 TH1::Reset() resets the bin contents and errors of an histogram
559~~~
560 IMPORTANT NOTE: The returned values for GetMean and GetStdDev depend on how the
561 histogram statistics are calculated. By default, if no range has been set, the
562 returned values are the (unbinned) ones calculated at fill time. If a range has been
563 set, however, the values are calculated using the bins in range; THIS IS TRUE EVEN
564 IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset the range.
565 To ensure that the returned values are always those of the binned data stored in the
566 histogram, call TH1::ResetStats. See TH1::GetStats.
567*/
568
569TF1 *gF1=0; //left for back compatibility (use TVirtualFitter::GetUserFunc instead)
570
575
576extern void H1InitGaus();
577extern void H1InitExpo();
578extern void H1InitPolynom();
579extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
580extern void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail);
581extern void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b);
582
583// Internal exceptions for the CheckConsistency method
584class DifferentDimension: public std::exception {};
585class DifferentNumberOfBins: public std::exception {};
586class DifferentAxisLimits: public std::exception {};
587class DifferentBinLimits: public std::exception {};
588class DifferentLabels: public std::exception {};
589
591
592////////////////////////////////////////////////////////////////////////////////
593/// Histogram default constructor.
594
596{
597 fDirectory = 0;
598 fFunctions = new TList;
599 fNcells = 0;
600 fIntegral = 0;
601 fPainter = 0;
602 fEntries = 0;
603 fNormFactor = 0;
605 fMaximum = -1111;
606 fMinimum = -1111;
607 fBufferSize = 0;
608 fBuffer = 0;
611 fXaxis.SetName("xaxis");
612 fYaxis.SetName("yaxis");
613 fZaxis.SetName("zaxis");
614 fXaxis.SetParent(this);
615 fYaxis.SetParent(this);
616 fZaxis.SetParent(this);
618}
619
620////////////////////////////////////////////////////////////////////////////////
621/// Histogram default destructor.
622
624{
625 if (!TestBit(kNotDeleted)) {
626 return;
627 }
628 delete[] fIntegral;
629 fIntegral = 0;
630 delete[] fBuffer;
631 fBuffer = 0;
632 if (fFunctions) {
634
636 TObject* obj = 0;
637 //special logic to support the case where the same object is
638 //added multiple times in fFunctions.
639 //This case happens when the same object is added with different
640 //drawing modes
641 //In the loop below we must be careful with objects (eg TCutG) that may
642 // have been added to the list of functions of several histograms
643 //and may have been already deleted.
644 while ((obj = fFunctions->First())) {
645 while(fFunctions->Remove(obj)) { }
646 if (!obj->TestBit(kNotDeleted)) {
647 break;
648 }
649 delete obj;
650 obj = 0;
651 }
652 delete fFunctions;
653 fFunctions = 0;
654 }
655 if (fDirectory) {
656 fDirectory->Remove(this);
657 fDirectory = 0;
658 }
659 delete fPainter;
660 fPainter = 0;
661}
662
663////////////////////////////////////////////////////////////////////////////////
664/// Normal constructor for fix bin size histograms.
665/// Creates the main histogram structure.
666///
667/// \param[in] name name of histogram (avoid blanks)
668/// \param[in] title histogram title.
669/// If title is of the form `stringt;stringx;stringy;stringz`,
670/// the histogram title is set to `stringt`,
671/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
672/// \param[in] nbins number of bins
673/// \param[in] xlow low edge of first bin
674/// \param[in] xup upper edge of last bin (not included in last bin)
675///
676/// When an histogram is created, it is automatically added to the list
677/// of special objects in the current directory.
678/// To find the pointer to this histogram in the current directory
679/// by its name, do:
680/// ~~~ {.cpp}
681/// TH1F *h1 = (TH1F*)gDirectory->FindObject(name);
682/// ~~~
683
684TH1::TH1(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
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 fXaxis.Set(nbins,xlow,xup);
690 fNcells = fXaxis.GetNbins()+2;
691}
692
693////////////////////////////////////////////////////////////////////////////////
694/// Normal constructor for variable bin size histograms.
695/// Creates the main histogram structure.
696///
697/// \param[in] name name of histogram (avoid blanks)
698/// \param[in] title histogram title.
699/// If title is of the form `stringt;stringx;stringy;stringz`
700/// the histogram title is set to `stringt`,
701/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
702/// \param[in] nbins number of bins
703/// \param[in] xbins array of low-edges for each bin.
704/// This is an array of size nbins+1
705
706TH1::TH1(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
707 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
708{
709 Build();
710 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
711 if (xbins) fXaxis.Set(nbins,xbins);
712 else fXaxis.Set(nbins,0,1);
713 fNcells = fXaxis.GetNbins()+2;
714}
715
716////////////////////////////////////////////////////////////////////////////////
717/// Normal constructor for variable bin size histograms.
718///
719/// \param[in] name name of histogram (avoid blanks)
720/// \param[in] title histogram title.
721/// If title is of the form `stringt;stringx;stringy;stringz`
722/// the histogram title is set to `stringt`,
723/// the x axis title to `stringx`, the y axis title to `stringy`, etc.
724/// \param[in] nbins number of bins
725/// \param[in] xbins array of low-edges for each bin.
726/// This is an array of size nbins+1
727
728TH1::TH1(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
729 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
730{
731 Build();
732 if (nbins <= 0) {Warning("TH1","nbins is <=0 - set to nbins = 1"); nbins = 1; }
733 if (xbins) fXaxis.Set(nbins,xbins);
734 else fXaxis.Set(nbins,0,1);
735 fNcells = fXaxis.GetNbins()+2;
736}
737
738////////////////////////////////////////////////////////////////////////////////
739/// Copy constructor.
740/// The list of functions is not copied. (Use Clone if needed)
741
743{
744 ((TH1&)h).Copy(*this);
745}
746
747////////////////////////////////////////////////////////////////////////////////
748/// Static function: cannot be inlined on Windows/NT.
749
751{
752 return fgAddDirectory;
753}
754
755////////////////////////////////////////////////////////////////////////////////
756/// Browse the Histogram object.
757
759{
760 Draw(b ? b->GetDrawOption() : "");
761 gPad->Update();
762}
763
764////////////////////////////////////////////////////////////////////////////////
765/// Creates histogram basic data structure.
766
768{
769 fDirectory = 0;
770 fPainter = 0;
771 fIntegral = 0;
772 fEntries = 0;
773 fNormFactor = 0;
775 fMaximum = -1111;
776 fMinimum = -1111;
777 fBufferSize = 0;
778 fBuffer = 0;
781 fXaxis.SetName("xaxis");
782 fYaxis.SetName("yaxis");
783 fZaxis.SetName("zaxis");
784 fYaxis.Set(1,0.,1.);
785 fZaxis.Set(1,0.,1.);
786 fXaxis.SetParent(this);
787 fYaxis.SetParent(this);
788 fZaxis.SetParent(this);
789
791
792 fFunctions = new TList;
793
795
798 if (fDirectory) {
800 fDirectory->Append(this,kTRUE);
801 }
802 }
803}
804
805////////////////////////////////////////////////////////////////////////////////
806/// Performs the operation: `this = this + c1*f1`
807/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
808///
809/// By default, the function is computed at the centre of the bin.
810/// if option "I" is specified (1-d histogram only), the integral of the
811/// function in each bin is used instead of the value of the function at
812/// the centre of the bin.
813///
814/// Only bins inside the function range are recomputed.
815///
816/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
817/// you should call Sumw2 before making this operation.
818/// This is particularly important if you fit the histogram after TH1::Add
819///
820/// The function return kFALSE if the Add operation failed
821
823{
824 if (!f1) {
825 Error("Add","Attempt to add a non-existing function");
826 return kFALSE;
827 }
828
829 TString opt = option;
830 opt.ToLower();
831 Bool_t integral = kFALSE;
832 if (opt.Contains("i") && fDimension == 1) integral = kTRUE;
833
834 Int_t ncellsx = GetNbinsX() + 2; // cells = normal bins + underflow bin + overflow bin
835 Int_t ncellsy = GetNbinsY() + 2;
836 Int_t ncellsz = GetNbinsZ() + 2;
837 if (fDimension < 2) ncellsy = 1;
838 if (fDimension < 3) ncellsz = 1;
839
840 // delete buffer if it is there since it will become invalid
841 if (fBuffer) BufferEmpty(1);
842
843 // - Add statistics
844 Double_t s1[10];
845 for (Int_t i = 0; i < 10; ++i) s1[i] = 0;
846 PutStats(s1);
847 SetMinimum();
848 SetMaximum();
849
850 // - Loop on bins (including underflows/overflows)
851 Int_t bin, binx, biny, binz;
852 Double_t cu=0;
853 Double_t xx[3];
854 Double_t *params = 0;
855 f1->InitArgs(xx,params);
856 for (binz = 0; binz < ncellsz; ++binz) {
857 xx[2] = fZaxis.GetBinCenter(binz);
858 for (biny = 0; biny < ncellsy; ++biny) {
859 xx[1] = fYaxis.GetBinCenter(biny);
860 for (binx = 0; binx < ncellsx; ++binx) {
861 xx[0] = fXaxis.GetBinCenter(binx);
862 if (!f1->IsInside(xx)) continue;
864 bin = binx + ncellsx * (biny + ncellsy * binz);
865 if (integral) {
866 cu = c1*f1->Integral(fXaxis.GetBinLowEdge(binx), fXaxis.GetBinUpEdge(binx), 0.) / fXaxis.GetBinWidth(binx);
867 } else {
868 cu = c1*f1->EvalPar(xx);
869 }
870 if (TF1::RejectedPoint()) continue;
871 AddBinContent(bin,cu);
872 }
873 }
874 }
875
876 return kTRUE;
877}
878
879////////////////////////////////////////////////////////////////////////////////
880/// Performs the operation: `this = this + c1*h1`
881/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
882///
883/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
884/// if not already set.
885///
886/// Note also that adding histogram with labels is not supported, histogram will be
887/// added merging them by bin number independently of the labels.
888/// For adding histogram with labels one should use TH1::Merge
889///
890/// SPECIAL CASE (Average/Efficiency histograms)
891/// For histograms representing averages or efficiencies, one should compute the average
892/// of the two histograms and not the sum. One can mark a histogram to be an average
893/// histogram by setting its bit kIsAverage with
894/// myhist.SetBit(TH1::kIsAverage);
895/// Note that the two histograms must have their kIsAverage bit set
896///
897/// IMPORTANT NOTE1: If you intend to use the errors of this histogram later
898/// you should call Sumw2 before making this operation.
899/// This is particularly important if you fit the histogram after TH1::Add
900///
901/// IMPORTANT NOTE2: if h1 has a normalisation factor, the normalisation factor
902/// is used , ie this = this + c1*factor*h1
903/// Use the other TH1::Add function if you do not want this feature
904///
905/// IMPORTANT NOTE3: You should be careful about the statistics of the
906/// returned histogram, whose statistics may be binned or unbinned,
907/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
908/// and whether TH1::ResetStats has been called on either this or h1.
909/// See TH1::GetStats.
910///
911/// The function return kFALSE if the Add operation failed
912
914{
915 if (!h1) {
916 Error("Add","Attempt to add a non-existing histogram");
917 return kFALSE;
918 }
919
920 // delete buffer if it is there since it will become invalid
921 if (fBuffer) BufferEmpty(1);
922
923 bool useMerge = (c1 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
924 try {
925 CheckConsistency(this,h1);
926 useMerge = kFALSE;
927 } catch(DifferentNumberOfBins&) {
928 if (useMerge)
929 Info("Add","Attempt to add histograms with different number of bins - trying to use TH1::Merge");
930 else {
931 Error("Add","Attempt to add histograms with different number of bins : nbins h1 = %d , nbins h2 = %d",GetNbinsX(), h1->GetNbinsX());
932 return kFALSE;
933 }
934 } catch(DifferentAxisLimits&) {
935 if (useMerge)
936 Info("Add","Attempt to add histograms with different axis limits - trying to use TH1::Merge");
937 else
938 Warning("Add","Attempt to add histograms with different axis limits");
939 } catch(DifferentBinLimits&) {
940 if (useMerge)
941 Info("Add","Attempt to add histograms with different bin limits - trying to use TH1::Merge");
942 else
943 Warning("Add","Attempt to add histograms with different bin limits");
944 } catch(DifferentLabels&) {
945 // in case of different labels -
946 if (useMerge)
947 Info("Add","Attempt to add histograms with different labels - trying to use TH1::Merge");
948 else
949 Info("Warning","Attempt to add histograms with different labels");
950 }
951
952 if (useMerge) {
953 TList l;
954 l.Add(const_cast<TH1*>(h1));
955 auto iret = Merge(&l);
956 return (iret >= 0);
957 }
958
959 // Create Sumw2 if h1 has Sumw2 set
960 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
961
962 // - Add statistics
963 Double_t entries = TMath::Abs( GetEntries() + c1 * h1->GetEntries() );
964
965 // statistics can be preserved only in case of positive coefficients
966 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
967 Bool_t resetStats = (c1 < 0);
968 Double_t s1[kNstat] = {0};
969 Double_t s2[kNstat] = {0};
970 if (!resetStats) {
971 // need to initialize to zero s1 and s2 since
972 // GetStats fills only used elements depending on dimension and type
973 GetStats(s1);
974 h1->GetStats(s2);
975 }
976
977 SetMinimum();
978 SetMaximum();
979
980 // - Loop on bins (including underflows/overflows)
981 Double_t factor = 1;
982 if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();;
983 Double_t c1sq = c1 * c1;
984 Double_t factsq = factor * factor;
985
986 for (Int_t bin = 0; bin < fNcells; ++bin) {
987 //special case where histograms have the kIsAverage bit set
988 if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
989 Double_t y1 = h1->RetrieveBinContent(bin);
990 Double_t y2 = this->RetrieveBinContent(bin);
992 Double_t e2sq = this->GetBinErrorSqUnchecked(bin);
993 Double_t w1 = 1., w2 = 1.;
994
995 // consider all special cases when bin errors are zero
996 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
997 if (e1sq) w1 = 1. / e1sq;
998 else if (h1->fSumw2.fN) {
999 w1 = 1.E200; // use an arbitrary huge value
1000 if (y1 == 0) {
1001 // use an estimated error from the global histogram scale
1002 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1003 w1 = 1./(sf*sf);
1004 }
1005 }
1006 if (e2sq) w2 = 1. / e2sq;
1007 else if (fSumw2.fN) {
1008 w2 = 1.E200; // use an arbitrary huge value
1009 if (y2 == 0) {
1010 // use an estimated error from the global histogram scale
1011 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1012 w2 = 1./(sf*sf);
1013 }
1014 }
1015
1016 double y = (w1*y1 + w2*y2)/(w1 + w2);
1017 UpdateBinContent(bin, y);
1018 if (fSumw2.fN) {
1019 double err2 = 1./(w1 + w2);
1020 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1021 fSumw2.fArray[bin] = err2;
1022 }
1023 } else { // normal case of addition between histograms
1024 AddBinContent(bin, c1 * factor * h1->RetrieveBinContent(bin));
1025 if (fSumw2.fN) fSumw2.fArray[bin] += c1sq * factsq * h1->GetBinErrorSqUnchecked(bin);
1026 }
1027 }
1028
1029 // update statistics (do here to avoid changes by SetBinContent)
1030 if (resetStats) {
1031 // statistics need to be reset in case coefficient are negative
1032 ResetStats();
1033 }
1034 else {
1035 for (Int_t i=0;i<kNstat;i++) {
1036 if (i == 1) s1[i] += c1*c1*s2[i];
1037 else s1[i] += c1*s2[i];
1038 }
1039 PutStats(s1);
1040 SetEntries(entries);
1041 }
1042 return kTRUE;
1043}
1044
1045////////////////////////////////////////////////////////////////////////////////
1046/// Replace contents of this histogram by the addition of h1 and h2.
1047///
1048/// `this = c1*h1 + c2*h2`
1049/// if errors are defined (see TH1::Sumw2), errors are also recalculated
1050///
1051/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
1052/// if not already set.
1053///
1054/// Note also that adding histogram with labels is not supported, histogram will be
1055/// added merging them by bin number independently of the labels.
1056/// For adding histogram ith labels one should use TH1::Merge
1057///
1058/// SPECIAL CASE (Average/Efficiency histograms)
1059/// For histograms representing averages or efficiencies, one should compute the average
1060/// of the two histograms and not the sum. One can mark a histogram to be an average
1061/// histogram by setting its bit kIsAverage with
1062/// myhist.SetBit(TH1::kIsAverage);
1063/// Note that the two histograms must have their kIsAverage bit set
1064///
1065/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
1066/// you should call Sumw2 before making this operation.
1067/// This is particularly important if you fit the histogram after TH1::Add
1068///
1069/// IMPORTANT NOTE2: You should be careful about the statistics of the
1070/// returned histogram, whose statistics may be binned or unbinned,
1071/// depending on whether c1 is negative, whether TAxis::kAxisRange is true,
1072/// and whether TH1::ResetStats has been called on either this or h1.
1073/// See TH1::GetStats.
1074///
1075/// ANOTHER SPECIAL CASE : h1 = h2 and c2 < 0
1076/// do a scaling this = c1 * h1 / (bin Volume)
1077///
1078/// The function returns kFALSE if the Add operation failed
1079
1081{
1082
1083 if (!h1 || !h2) {
1084 Error("Add","Attempt to add a non-existing histogram");
1085 return kFALSE;
1086 }
1087
1088 // delete buffer if it is there since it will become invalid
1089 if (fBuffer) BufferEmpty(1);
1090
1091 Bool_t normWidth = kFALSE;
1092 if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
1093
1094 if (h1 != h2) {
1095 bool useMerge = (c1 == 1. && c2 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
1096
1097 try {
1098 CheckConsistency(h1,h2);
1099 CheckConsistency(this,h1);
1100 useMerge = kFALSE;
1101 } catch(DifferentNumberOfBins&) {
1102 if (useMerge)
1103 Info("Add","Attempt to add histograms with different number of bins - trying to use TH1::Merge");
1104 else {
1105 Error("Add","Attempt to add histograms with different number of bins : nbins h1 = %d , nbins h2 = %d",GetNbinsX(), h1->GetNbinsX());
1106 return kFALSE;
1107 }
1108 } catch(DifferentAxisLimits&) {
1109 if (useMerge)
1110 Info("Add","Attempt to add histograms with different axis limits - trying to use TH1::Merge");
1111 else
1112 Warning("Add","Attempt to add histograms with different axis limits");
1113 } catch(DifferentBinLimits&) {
1114 if (useMerge)
1115 Info("Add","Attempt to add histograms with different bin limits - trying to use TH1::Merge");
1116 else
1117 Warning("Add","Attempt to add histograms with different bin limits");
1118 } catch(DifferentLabels&) {
1119 // in case of different labels -
1120 if (useMerge)
1121 Info("Add","Attempt to add histograms with different labels - trying to use TH1::Merge");
1122 else
1123 Info("Warning","Attempt to add histograms with different labels");
1124 }
1125
1126 if (useMerge) {
1127 TList l;
1128 // why TList takes non-const pointers ????
1129 l.Add(const_cast<TH1*>(h1));
1130 l.Add(const_cast<TH1*>(h2));
1131 Reset("ICE");
1132 auto iret = Merge(&l);
1133 return (iret >= 0);
1134 }
1135 }
1136
1137 // Create Sumw2 if h1 or h2 have Sumw2 set
1138 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
1139
1140 // - Add statistics
1141 Double_t nEntries = TMath::Abs( c1*h1->GetEntries() + c2*h2->GetEntries() );
1142
1143 // TODO remove
1144 // statistics can be preserved only in case of positive coefficients
1145 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
1146 // also in case of scaling with the width we cannot preserve the statistics
1147 Double_t s1[kNstat] = {0};
1148 Double_t s2[kNstat] = {0};
1149 Double_t s3[kNstat];
1150
1151
1152 Bool_t resetStats = (c1*c2 < 0) || normWidth;
1153 if (!resetStats) {
1154 // need to initialize to zero s1 and s2 since
1155 // GetStats fills only used elements depending on dimension and type
1156 h1->GetStats(s1);
1157 h2->GetStats(s2);
1158 for (Int_t i=0;i<kNstat;i++) {
1159 if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
1160 //else s3[i] = TMath::Abs(c1)*s1[i] + TMath::Abs(c2)*s2[i];
1161 else s3[i] = c1*s1[i] + c2*s2[i];
1162 }
1163 }
1164
1165 SetMinimum();
1166 SetMaximum();
1167
1168 if (normWidth) { // DEPRECATED CASE: belongs to fitting / drawing modules
1169
1170 Int_t nbinsx = GetNbinsX() + 2; // normal bins + underflow, overflow
1171 Int_t nbinsy = GetNbinsY() + 2;
1172 Int_t nbinsz = GetNbinsZ() + 2;
1173
1174 if (fDimension < 2) nbinsy = 1;
1175 if (fDimension < 3) nbinsz = 1;
1176
1177 Int_t bin, binx, biny, binz;
1178 for (binz = 0; binz < nbinsz; ++binz) {
1179 Double_t wz = h1->GetZaxis()->GetBinWidth(binz);
1180 for (biny = 0; biny < nbinsy; ++biny) {
1181 Double_t wy = h1->GetYaxis()->GetBinWidth(biny);
1182 for (binx = 0; binx < nbinsx; ++binx) {
1183 Double_t wx = h1->GetXaxis()->GetBinWidth(binx);
1184 bin = GetBin(binx, biny, binz);
1185 Double_t w = wx*wy*wz;
1186 UpdateBinContent(bin, c1 * h1->RetrieveBinContent(bin) / w);
1187 if (fSumw2.fN) {
1188 Double_t e1 = h1->GetBinError(bin)/w;
1189 fSumw2.fArray[bin] = c1*c1*e1*e1;
1190 }
1191 }
1192 }
1193 }
1194 } else if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
1195 for (Int_t i = 0; i < fNcells; ++i) { // loop on cells (bins including underflow / overflow)
1196 // special case where histograms have the kIsAverage bit set
1198 Double_t y2 = h2->RetrieveBinContent(i);
1200 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
1201 Double_t w1 = 1., w2 = 1.;
1202
1203 // consider all special cases when bin errors are zero
1204 // see http://root-forum.cern.ch/viewtopic.php?f=3&t=13299
1205 if (e1sq) w1 = 1./ e1sq;
1206 else if (h1->fSumw2.fN) {
1207 w1 = 1.E200; // use an arbitrary huge value
1208 if (y1 == 0 ) { // use an estimated error from the global histogram scale
1209 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1210 w1 = 1./(sf*sf);
1211 }
1212 }
1213 if (e2sq) w2 = 1./ e2sq;
1214 else if (h2->fSumw2.fN) {
1215 w2 = 1.E200; // use an arbitrary huge value
1216 if (y2 == 0) { // use an estimated error from the global histogram scale
1217 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1218 w2 = 1./(sf*sf);
1219 }
1220 }
1221
1222 double y = (w1*y1 + w2*y2)/(w1 + w2);
1223 UpdateBinContent(i, y);
1224 if (fSumw2.fN) {
1225 double err2 = 1./(w1 + w2);
1226 if (err2 < 1.E-200) err2 = 0; // to remove arbitrary value when e1=0 AND e2=0
1227 fSumw2.fArray[i] = err2;
1228 }
1229 }
1230 } else { // case of simple histogram addition
1231 Double_t c1sq = c1 * c1;
1232 Double_t c2sq = c2 * c2;
1233 for (Int_t i = 0; i < fNcells; ++i) { // Loop on cells (bins including underflows/overflows)
1235 if (fSumw2.fN) {
1236 fSumw2.fArray[i] = c1sq * h1->GetBinErrorSqUnchecked(i) + c2sq * h2->GetBinErrorSqUnchecked(i);
1237 }
1238 }
1239 }
1240
1241 if (resetStats) {
1242 // statistics need to be reset in case coefficient are negative
1243 ResetStats();
1244 }
1245 else {
1246 // update statistics (do here to avoid changes by SetBinContent) FIXME remove???
1247 PutStats(s3);
1248 SetEntries(nEntries);
1249 }
1250
1251 return kTRUE;
1252}
1253
1254////////////////////////////////////////////////////////////////////////////////
1255/// Increment bin content by 1.
1256
1258{
1259 AbstractMethod("AddBinContent");
1260}
1261
1262////////////////////////////////////////////////////////////////////////////////
1263/// Increment bin content by a weight w.
1264
1266{
1267 AbstractMethod("AddBinContent");
1268}
1269
1270////////////////////////////////////////////////////////////////////////////////
1271/// Sets the flag controlling the automatic add of histograms in memory
1272///
1273/// By default (fAddDirectory = kTRUE), histograms are automatically added
1274/// to the list of objects in memory.
1275/// Note that one histogram can be removed from its support directory
1276/// by calling h->SetDirectory(0) or h->SetDirectory(dir) to add it
1277/// to the list of objects in the directory dir.
1278///
1279/// NOTE that this is a static function. To call it, use;
1280/// TH1::AddDirectory
1281
1283{
1284 fgAddDirectory = add;
1285}
1286
1287////////////////////////////////////////////////////////////////////////////////
1288/// Auxiliary function to get the power of 2 next (larger) or previous (smaller)
1289/// a given x
1290///
1291/// next = kTRUE : next larger
1292/// next = kFALSE : previous smaller
1293///
1294/// Used by the autobin power of 2 algorithm
1295
1297{
1298 Int_t nn;
1299 Double_t f2 = std::frexp(x, &nn);
1300 return ((next && x > 0.) || (!next && x <= 0.)) ? std::ldexp(std::copysign(1., f2), nn)
1301 : std::ldexp(std::copysign(1., f2), --nn);
1302}
1303
1304////////////////////////////////////////////////////////////////////////////////
1305/// Auxiliary function to get the next power of 2 integer value larger then n
1306///
1307/// Used by the autobin power of 2 algorithm
1308
1310{
1311 Int_t nn;
1312 Double_t f2 = std::frexp(n, &nn);
1313 if (TMath::Abs(f2 - .5) > 0.001)
1314 return (Int_t)std::ldexp(1., nn);
1315 return n;
1316}
1317
1318////////////////////////////////////////////////////////////////////////////////
1319/// Buffer-based estimate of the histogram range using the power of 2 algorithm.
1320///
1321/// Used by the autobin power of 2 algorithm.
1322///
1323/// Works on arguments (min and max from fBuffer) and internal inputs: fXmin,
1324/// fXmax, NBinsX (from fXaxis), ...
1325/// Result save internally in fXaxis.
1326///
1327/// Overloaded by TH2 and TH3.
1328///
1329/// Return -1 if internal inputs are inconsistent, 0 otherwise.
1330
1332{
1333 // We need meaningful raw limits
1334 if (xmi >= xma)
1335 return -1;
1336
1338 Double_t xhmi = fXaxis.GetXmin();
1339 Double_t xhma = fXaxis.GetXmax();
1340
1341 // Now adjust
1342 if (TMath::Abs(xhma) > TMath::Abs(xhmi)) {
1343 // Start from the upper limit
1344 xhma = TH1::AutoP2GetPower2(xhma);
1345 xhmi = xhma - TH1::AutoP2GetPower2(xhma - xhmi);
1346 } else {
1347 // Start from the lower limit
1348 xhmi = TH1::AutoP2GetPower2(xhmi, kFALSE);
1349 xhma = xhmi + TH1::AutoP2GetPower2(xhma - xhmi);
1350 }
1351
1352 // Round the bins to the next power of 2; take into account the possible inflation
1353 // of the range
1354 Double_t rr = (xhma - xhmi) / (xma - xmi);
1355 Int_t nb = TH1::AutoP2GetBins((Int_t)(rr * GetNbinsX()));
1356
1357 // Adjust using the same bin width and offsets
1358 Double_t bw = (xhma - xhmi) / nb;
1359 // Bins to left free on each side
1360 Double_t autoside = gEnv->GetValue("Hist.Binning.Auto.Side", 0.05);
1361 Int_t nbside = (Int_t)(nb * autoside);
1362
1363 // Side up
1364 Int_t nbup = (xhma - xma) / bw;
1365 if (nbup % 2 != 0)
1366 nbup++; // Must be even
1367 if (nbup != nbside) {
1368 // Accounts also for both case: larger or smaller
1369 xhma -= bw * (nbup - nbside);
1370 nb -= (nbup - nbside);
1371 }
1372
1373 // Side low
1374 Int_t nblw = (xmi - xhmi) / bw;
1375 if (nblw % 2 != 0)
1376 nblw++; // Must be even
1377 if (nblw != nbside) {
1378 // Accounts also for both case: larger or smaller
1379 xhmi += bw * (nblw - nbside);
1380 nb -= (nblw - nbside);
1381 }
1382
1383 // Set everything and project
1384 SetBins(nb, xhmi, xhma);
1385
1386 // Done
1387 return 0;
1388}
1389
1390/// Fill histogram with all entries in the buffer.
1391///
1392/// - action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
1393/// - action = 0 histogram is reset and filled from the buffer. When the histogram is filled from the
1394/// buffer the value fBuffer[0] is set to a negative number (= - number of entries)
1395/// When calling with action == 0 the histogram is NOT refilled when fBuffer[0] is < 0
1396/// While when calling with action = -1 the histogram is reset and ALWAYS refilled independently if
1397/// the histogram was filled before. This is needed when drawing the histogram
1398/// - action = 1 histogram is filled and buffer is deleted
1399/// The buffer is automatically deleted when filling the histogram and the entries is
1400/// larger than the buffer size
1401
1403{
1404 // do we need to compute the bin size?
1405 if (!fBuffer) return 0;
1406 Int_t nbentries = (Int_t)fBuffer[0];
1407
1408 // nbentries correspond to the number of entries of histogram
1409
1410 if (nbentries == 0) {
1411 // if action is 1 we delete the buffer
1412 // this will avoid infinite recursion
1413 if (action > 0) {
1414 delete [] fBuffer;
1415 fBuffer = 0;
1416 fBufferSize = 0;
1417 }
1418 return 0;
1419 }
1420 if (nbentries < 0 && action == 0) return 0; // case histogram has been already filled from the buffer
1421
1422 Double_t *buffer = fBuffer;
1423 if (nbentries < 0) {
1424 nbentries = -nbentries;
1425 // a reset might call BufferEmpty() giving an infinite recursion
1426 // Protect it by setting fBuffer = 0
1427 fBuffer=0;
1428 //do not reset the list of functions
1429 Reset("ICES");
1430 fBuffer = buffer;
1431 }
1432 if (CanExtendAllAxes() || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
1433 //find min, max of entries in buffer
1434 Double_t xmin = fBuffer[2];
1435 Double_t xmax = xmin;
1436 for (Int_t i=1;i<nbentries;i++) {
1437 Double_t x = fBuffer[2*i+2];
1438 if (x < xmin) xmin = x;
1439 if (x > xmax) xmax = x;
1440 }
1441 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
1442 Int_t rc = -1;
1444 if ((rc = AutoP2FindLimits(xmin, xmax)) < 0)
1445 Warning("BufferEmpty",
1446 "inconsistency found by power-of-2 autobin algorithm: fallback to standard method");
1447 }
1448 if (rc < 0)
1450 } else {
1451 fBuffer = 0;
1452 Int_t keep = fBufferSize; fBufferSize = 0;
1454 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax, &fXaxis);
1455 fBuffer = buffer;
1456 fBufferSize = keep;
1457 }
1458 }
1459
1460 // call DoFillN which will not put entries in the buffer as FillN does
1461 // set fBuffer to zero to avoid re-emptying the buffer from functions called
1462 // by DoFillN (e.g Sumw2)
1463 buffer = fBuffer; fBuffer = 0;
1464 DoFillN(nbentries,&buffer[2],&buffer[1],2);
1465 fBuffer = buffer;
1466
1467 // if action == 1 - delete the buffer
1468 if (action > 0) {
1469 delete [] fBuffer;
1470 fBuffer = 0;
1471 fBufferSize = 0;
1472 } else {
1473 // if number of entries is consistent with buffer - set it negative to avoid
1474 // refilling the histogram every time BufferEmpty(0) is called
1475 // In case it is not consistent, by setting fBuffer[0]=0 is like resetting the buffer
1476 // (it will not be used anymore the next time BufferEmpty is called)
1477 if (nbentries == (Int_t)fEntries)
1478 fBuffer[0] = -nbentries;
1479 else
1480 fBuffer[0] = 0;
1481 }
1482 return nbentries;
1483}
1484
1485////////////////////////////////////////////////////////////////////////////////
1486/// accumulate arguments in buffer. When buffer is full, empty the buffer
1487///
1488/// - `fBuffer[0]` = number of entries in buffer
1489/// - `fBuffer[1]` = w of first entry
1490/// - `fBuffer[2]` = x of first entry
1491
1493{
1494 if (!fBuffer) return -2;
1495 Int_t nbentries = (Int_t)fBuffer[0];
1496
1497
1498 if (nbentries < 0) {
1499 // reset nbentries to a positive value so next time BufferEmpty() is called
1500 // the histogram will be refilled
1501 nbentries = -nbentries;
1502 fBuffer[0] = nbentries;
1503 if (fEntries > 0) {
1504 // set fBuffer to zero to avoid calling BufferEmpty in Reset
1505 Double_t *buffer = fBuffer; fBuffer=0;
1506 Reset("ICES"); // do not reset list of functions
1507 fBuffer = buffer;
1508 }
1509 }
1510 if (2*nbentries+2 >= fBufferSize) {
1511 BufferEmpty(1);
1512 if (!fBuffer)
1513 // to avoid infinite recursion Fill->BufferFill->Fill
1514 return Fill(x,w);
1515 // this cannot happen
1516 R__ASSERT(0);
1517 }
1518 fBuffer[2*nbentries+1] = w;
1519 fBuffer[2*nbentries+2] = x;
1520 fBuffer[0] += 1;
1521 return -2;
1522}
1523
1524////////////////////////////////////////////////////////////////////////////////
1525/// Check bin limits.
1526
1527bool TH1::CheckBinLimits(const TAxis* a1, const TAxis * a2)
1528{
1529 const TArrayD * h1Array = a1->GetXbins();
1530 const TArrayD * h2Array = a2->GetXbins();
1531 Int_t fN = h1Array->fN;
1532 if ( fN != 0 ) {
1533 if ( h2Array->fN != fN ) {
1534 throw DifferentBinLimits();
1535 return false;
1536 }
1537 else {
1538 for ( int i = 0; i < fN; ++i ) {
1539 // for i==fN (nbin+1) a->GetBinWidth() returns last bin width
1540 // we do not need to exclude that case
1541 double binWidth = a1->GetBinWidth(i);
1542 if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), binWidth*1E-10 ) ) {
1543 throw DifferentBinLimits();
1544 return false;
1545 }
1546 }
1547 }
1548 }
1549
1550 return true;
1551}
1552
1553////////////////////////////////////////////////////////////////////////////////
1554/// Check that axis have same labels.
1555
1556bool TH1::CheckBinLabels(const TAxis* a1, const TAxis * a2)
1557{
1558 THashList *l1 = a1->GetLabels();
1559 THashList *l2 = a2->GetLabels();
1560
1561 if (!l1 && !l2 )
1562 return true;
1563 if (!l1 || !l2 ) {
1564 throw DifferentLabels();
1565 return false;
1566 }
1567 // check now labels sizes are the same
1568 if (l1->GetSize() != l2->GetSize() ) {
1569 throw DifferentLabels();
1570 return false;
1571 }
1572 for (int i = 1; i <= a1->GetNbins(); ++i) {
1573 TString label1 = a1->GetBinLabel(i);
1574 TString label2 = a2->GetBinLabel(i);
1575 if (label1 != label2) {
1576 throw DifferentLabels();
1577 return false;
1578 }
1579 }
1580
1581 return true;
1582}
1583
1584////////////////////////////////////////////////////////////////////////////////
1585/// Check that the axis limits of the histograms are the same.
1586/// If a first and last bin is passed the axis is compared between the given range
1587
1588bool TH1::CheckAxisLimits(const TAxis *a1, const TAxis *a2 )
1589{
1590 double firstBin = a1->GetBinWidth(1);
1591 double lastBin = a1->GetBinWidth( a1->GetNbins() );
1592 if ( ! TMath::AreEqualAbs(a1->GetXmin(), a2->GetXmin(), firstBin* 1.E-10) ||
1593 ! TMath::AreEqualAbs(a1->GetXmax(), a2->GetXmax(), lastBin*1.E-10) ) {
1594 throw DifferentAxisLimits();
1595 return false;
1596 }
1597 return true;
1598}
1599
1600////////////////////////////////////////////////////////////////////////////////
1601/// Check that the axis are the same
1602
1603bool TH1::CheckEqualAxes(const TAxis *a1, const TAxis *a2 )
1604{
1605 if (a1->GetNbins() != a2->GetNbins() ) {
1606 //throw DifferentNumberOfBins();
1607 ::Info("CheckEqualAxes","Axes have different number of bins : nbin1 = %d nbin2 = %d",a1->GetNbins(),a2->GetNbins() );
1608 return false;
1609 }
1610 try {
1611 CheckAxisLimits(a1,a2);
1612 } catch (DifferentAxisLimits&) {
1613 ::Info("CheckEqualAxes","Axes have different limits");
1614 return false;
1615 }
1616 try {
1617 CheckBinLimits(a1,a2);
1618 } catch (DifferentBinLimits&) {
1619 ::Info("CheckEqualAxes","Axes have different bin limits");
1620 return false;
1621 }
1622
1623 // check labels
1624 try {
1625 CheckBinLabels(a1,a2);
1626 } catch (DifferentLabels&) {
1627 ::Info("CheckEqualAxes","Axes have different labels");
1628 return false;
1629 }
1630
1631 return true;
1632}
1633
1634////////////////////////////////////////////////////////////////////////////////
1635/// Check that two sub axis are the same.
1636/// The limits are defined by first bin and last bin
1637/// N.B. no check is done in this case for variable bins
1638
1639bool TH1::CheckConsistentSubAxes(const TAxis *a1, Int_t firstBin1, Int_t lastBin1, const TAxis * a2, Int_t firstBin2, Int_t lastBin2 )
1640{
1641 // By default is assumed that no bins are given for the second axis
1642 Int_t nbins1 = lastBin1-firstBin1 + 1;
1643 Double_t xmin1 = a1->GetBinLowEdge(firstBin1);
1644 Double_t xmax1 = a1->GetBinUpEdge(lastBin1);
1645
1646 Int_t nbins2 = a2->GetNbins();
1647 Double_t xmin2 = a2->GetXmin();
1648 Double_t xmax2 = a2->GetXmax();
1649
1650 if (firstBin2 < lastBin2) {
1651 // in this case assume no bins are given for the second axis
1652 nbins2 = lastBin1-firstBin1 + 1;
1653 xmin2 = a1->GetBinLowEdge(firstBin1);
1654 xmax2 = a1->GetBinUpEdge(lastBin1);
1655 }
1656
1657 if (nbins1 != nbins2 ) {
1658 ::Info("CheckConsistentSubAxes","Axes have different number of bins");
1659 return false;
1660 }
1661
1662 Double_t firstBin = a1->GetBinWidth(firstBin1);
1663 Double_t lastBin = a1->GetBinWidth(lastBin1);
1664 if ( ! TMath::AreEqualAbs(xmin1,xmin2,1.E-10 * firstBin) ||
1665 ! TMath::AreEqualAbs(xmax1,xmax2,1.E-10 * lastBin) ) {
1666 ::Info("CheckConsistentSubAxes","Axes have different limits");
1667 return false;
1668 }
1669
1670 return true;
1671}
1672
1673////////////////////////////////////////////////////////////////////////////////
1674/// Check histogram compatibility.
1675
1676bool TH1::CheckConsistency(const TH1* h1, const TH1* h2)
1677{
1678 if (h1 == h2) return true;
1679
1680 if (h1->GetDimension() != h2->GetDimension() ) {
1681 throw DifferentDimension();
1682 return false;
1683 }
1684 Int_t dim = h1->GetDimension();
1685
1686 // returns kTRUE if number of bins and bin limits are identical
1687 Int_t nbinsx = h1->GetNbinsX();
1688 Int_t nbinsy = h1->GetNbinsY();
1689 Int_t nbinsz = h1->GetNbinsZ();
1690
1691 // Check whether the histograms have the same number of bins.
1692 if (nbinsx != h2->GetNbinsX() ||
1693 (dim > 1 && nbinsy != h2->GetNbinsY()) ||
1694 (dim > 2 && nbinsz != h2->GetNbinsZ()) ) {
1695 throw DifferentNumberOfBins();
1696 return false;
1697 }
1698
1699 bool ret = true;
1700
1701 // check axis limits
1702 ret &= CheckAxisLimits(h1->GetXaxis(), h2->GetXaxis());
1703 if (dim > 1) ret &= CheckAxisLimits(h1->GetYaxis(), h2->GetYaxis());
1704 if (dim > 2) ret &= CheckAxisLimits(h1->GetZaxis(), h2->GetZaxis());
1705
1706 // check bin limits
1707 ret &= CheckBinLimits(h1->GetXaxis(), h2->GetXaxis());
1708 if (dim > 1) ret &= CheckBinLimits(h1->GetYaxis(), h2->GetYaxis());
1709 if (dim > 2) ret &= CheckBinLimits(h1->GetZaxis(), h2->GetZaxis());
1710
1711 // check labels if histograms are both not empty
1712 if ( !h1->IsEmpty() && !h2->IsEmpty() ) {
1713 ret &= CheckBinLabels(h1->GetXaxis(), h2->GetXaxis());
1714 if (dim > 1) ret &= CheckBinLabels(h1->GetYaxis(), h2->GetYaxis());
1715 if (dim > 2) ret &= CheckBinLabels(h1->GetZaxis(), h2->GetZaxis());
1716 }
1717
1718 return ret;
1719}
1720
1721////////////////////////////////////////////////////////////////////////////////
1722/// \f$ \chi^{2} \f$ test for comparing weighted and unweighted histograms
1723///
1724/// Function: Returns p-value. Other return values are specified by the 3rd parameter
1725///
1726/// \param[in] h2 the second histogram
1727/// \param[in] option
1728/// - "UU" = experiment experiment comparison (unweighted-unweighted)
1729/// - "UW" = experiment MC comparison (unweighted-weighted). Note that
1730/// the first histogram should be unweighted
1731/// - "WW" = MC MC comparison (weighted-weighted)
1732/// - "NORM" = to be used when one or both of the histograms is scaled
1733/// but the histogram originally was unweighted
1734/// - by default underflows and overflows are not included:
1735/// * "OF" = overflows included
1736/// * "UF" = underflows included
1737/// - "P" = print chi2, ndf, p_value, igood
1738/// - "CHI2" = returns chi2 instead of p-value
1739/// - "CHI2/NDF" = returns \f$ \chi^{2} \f$/ndf
1740/// \param[in] res not empty - computes normalized residuals and returns them in this array
1741///
1742/// The current implementation is based on the papers \f$ \chi^{2} \f$ test for comparison
1743/// of weighted and unweighted histograms" in Proceedings of PHYSTAT05 and
1744/// "Comparison weighted and unweighted histograms", arXiv:physics/0605123
1745/// by N.Gagunashvili. This function has been implemented by Daniel Haertl in August 2006.
1746///
1747/// #### Introduction:
1748///
1749/// A frequently used technique in data analysis is the comparison of
1750/// histograms. First suggested by Pearson [1] the \f$ \chi^{2} \f$ test of
1751/// homogeneity is used widely for comparing usual (unweighted) histograms.
1752/// This paper describes the implementation modified \f$ \chi^{2} \f$ tests
1753/// for comparison of weighted and unweighted histograms and two weighted
1754/// histograms [2] as well as usual Pearson's \f$ \chi^{2} \f$ test for
1755/// comparison two usual (unweighted) histograms.
1756///
1757/// #### Overview:
1758///
1759/// Comparison of two histograms expect hypotheses that two histograms
1760/// represent identical distributions. To make a decision p-value should
1761/// be calculated. The hypotheses of identity is rejected if the p-value is
1762/// lower then some significance level. Traditionally significance levels
1763/// 0.1, 0.05 and 0.01 are used. The comparison procedure should include an
1764/// analysis of the residuals which is often helpful in identifying the
1765/// bins of histograms responsible for a significant overall \f$ \chi^{2} \f$ value.
1766/// Residuals are the difference between bin contents and expected bin
1767/// contents. Most convenient for analysis are the normalized residuals. If
1768/// hypotheses of identity are valid then normalized residuals are
1769/// approximately independent and identically distributed random variables
1770/// having N(0,1) distribution. Analysis of residuals expect test of above
1771/// mentioned properties of residuals. Notice that indirectly the analysis
1772/// of residuals increase the power of \f$ \chi^{2} \f$ test.
1773///
1774/// #### Methods of comparison:
1775///
1776/// \f$ \chi^{2} \f$ test for comparison two (unweighted) histograms:
1777/// Let us consider two histograms with the same binning and the number
1778/// of bins equal to r. Let us denote the number of events in the ith bin
1779/// in the first histogram as ni and as mi in the second one. The total
1780/// number of events in the first histogram is equal to:
1781/// \f[
1782/// N = \sum_{i=1}^{r} n_{i}
1783/// \f]
1784/// and
1785/// \f[
1786/// M = \sum_{i=1}^{r} m_{i}
1787/// \f]
1788/// in the second histogram. The hypothesis of identity (homogeneity) [3]
1789/// is that the two histograms represent random values with identical
1790/// distributions. It is equivalent that there exist r constants p1,...,pr,
1791/// such that
1792/// \f[
1793///\sum_{i=1}^{r} p_{i}=1
1794/// \f]
1795/// and the probability of belonging to the ith bin for some measured value
1796/// in both experiments is equal to pi. The number of events in the ith
1797/// bin is a random variable with a distribution approximated by a Poisson
1798/// probability distribution
1799/// \f[
1800///\frac{e^{-Np_{i}}(Np_{i})^{n_{i}}}{n_{i}!}
1801/// \f]
1802///for the first histogram and with distribution
1803/// \f[
1804///\frac{e^{-Mp_{i}}(Mp_{i})^{m_{i}}}{m_{i}!}
1805/// \f]
1806/// for the second histogram. If the hypothesis of homogeneity is valid,
1807/// then the maximum likelihood estimator of pi, i=1,...,r, is
1808/// \f[
1809///\hat{p}_{i}= \frac{n_{i}+m_{i}}{N+M}
1810/// \f]
1811/// and then
1812/// \f[
1813/// 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}}
1814/// \f]
1815/// has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [3].
1816/// The comparison procedure can include an analysis of the residuals which
1817/// is often helpful in identifying the bins of histograms responsible for
1818/// a significant overall \f$ \chi^{2} \f$ value. Most convenient for
1819/// analysis are the adjusted (normalized) residuals [4]
1820/// \f[
1821/// 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))}}
1822/// \f]
1823/// If hypotheses of homogeneity are valid then residuals ri are
1824/// approximately independent and identically distributed random variables
1825/// having N(0,1) distribution. The application of the \f$ \chi^{2} \f$ test has
1826/// restrictions related to the value of the expected frequencies Npi,
1827/// Mpi, i=1,...,r. A conservative rule formulated in [5] is that all the
1828/// expectations must be 1 or greater for both histograms. In practical
1829/// cases when expected frequencies are not known the estimated expected
1830/// frequencies \f$ M\hat{p}_{i}, N\hat{p}_{i}, i=1,...,r \f$ can be used.
1831///
1832/// #### Unweighted and weighted histograms comparison:
1833///
1834/// A simple modification of the ideas described above can be used for the
1835/// comparison of the usual (unweighted) and weighted histograms. Let us
1836/// denote the number of events in the ith bin in the unweighted
1837/// histogram as ni and the common weight of events in the ith bin of the
1838/// weighted histogram as wi. The total number of events in the
1839/// unweighted histogram is equal to
1840///\f[
1841/// N = \sum_{i=1}^{r} n_{i}
1842///\f]
1843/// and the total weight of events in the weighted histogram is equal to
1844///\f[
1845/// W = \sum_{i=1}^{r} w_{i}
1846///\f]
1847/// Let us formulate the hypothesis of identity of an unweighted histogram
1848/// to a weighted histogram so that there exist r constants p1,...,pr, such
1849/// that
1850///\f[
1851/// \sum_{i=1}^{r} p_{i} = 1
1852///\f]
1853/// for the unweighted histogram. The weight wi is a random variable with a
1854/// distribution approximated by the normal probability distribution
1855/// \f$ N(Wp_{i},\sigma_{i}^{2}) \f$ where \f$ \sigma_{i}^{2} \f$ is the variance of the weight wi.
1856/// If we replace the variance \f$ \sigma_{i}^{2} \f$
1857/// with estimate \f$ s_{i}^{2} \f$ (sum of squares of weights of
1858/// events in the ith bin) and the hypothesis of identity is valid, then the
1859/// maximum likelihood estimator of pi,i=1,...,r, is
1860///\f[
1861/// \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}}
1862///\f]
1863/// We may then use the test statistic
1864///\f[
1865/// 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}}
1866///\f]
1867/// and it has approximately a \f$ \sigma^{2}_{(r-1)} \f$ distribution [2]. This test, as well
1868/// as the original one [3], has a restriction on the expected frequencies. The
1869/// expected frequencies recommended for the weighted histogram is more than 25.
1870/// The value of the minimal expected frequency can be decreased down to 10 for
1871/// the case when the weights of the events are close to constant. In the case
1872/// of a weighted histogram if the number of events is unknown, then we can
1873/// apply this recommendation for the equivalent number of events as
1874///\f[
1875/// n_{i}^{equiv} = \frac{ w_{i}^{2} }{ s_{i}^{2} }
1876///\f]
1877/// The minimal expected frequency for an unweighted histogram must be 1. Notice
1878/// that any usual (unweighted) histogram can be considered as a weighted
1879/// histogram with events that have constant weights equal to 1.
1880/// The variance \f$ z_{i}^{2} \f$ of the difference between the weight wi
1881/// and the estimated expectation value of the weight is approximately equal to:
1882///\f[
1883/// 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}
1884///\f]
1885/// The residuals
1886///\f[
1887/// r_{i} = \frac{w_{i}-W\hat{p}_{i}}{z_{i}}
1888///\f]
1889/// have approximately a normal distribution with mean equal to 0 and standard
1890/// deviation equal to 1.
1891///
1892/// #### Two weighted histograms comparison:
1893///
1894/// Let us denote the common weight of events of the ith bin in the first
1895/// histogram as w1i and as w2i in the second one. The total weight of events
1896/// in the first histogram is equal to
1897///\f[
1898/// W_{1} = \sum_{i=1}^{r} w_{1i}
1899///\f]
1900/// and
1901///\f[
1902/// W_{2} = \sum_{i=1}^{r} w_{2i}
1903///\f]
1904/// in the second histogram. Let us formulate the hypothesis of identity of
1905/// weighted histograms so that there exist r constants p1,...,pr, such that
1906///\f[
1907/// \sum_{i=1}^{r} p_{i} = 1
1908///\f]
1909/// and also expectation value of weight w1i equal to W1pi and expectation value
1910/// of weight w2i equal to W2pi. Weights in both the histograms are random
1911/// variables with distributions which can be approximated by a normal
1912/// probability distribution \f$ N(W_{1}p_{i},\sigma_{1i}^{2}) \f$ for the first histogram
1913/// and by a distribution \f$ N(W_{2}p_{i},\sigma_{2i}^{2}) \f$ for the second.
1914/// Here \f$ \sigma_{1i}^{2} \f$ and \f$ \sigma_{2i}^{2} \f$ are the variances
1915/// of w1i and w2i with estimators \f$ s_{1i}^{2} \f$ and \f$ s_{2i}^{2} \f$ respectively.
1916/// If the hypothesis of identity is valid, then the maximum likelihood and
1917/// Least Square Method estimator of pi,i=1,...,r, is
1918///\f[
1919/// \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}}
1920///\f]
1921/// We may then use the test statistic
1922///\f[
1923/// 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}}
1924///\f]
1925/// and it has approximately a \f$ \chi^{2}_{(r-1)} \f$ distribution [2].
1926/// The normalized or studentised residuals [6]
1927///\f[
1928/// 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})}}}
1929///\f]
1930/// have approximately a normal distribution with mean equal to 0 and standard
1931/// deviation 1. A recommended minimal expected frequency is equal to 10 for
1932/// the proposed test.
1933///
1934/// #### Numerical examples:
1935///
1936/// The method described herein is now illustrated with an example.
1937/// We take a distribution
1938///\f[
1939/// \phi(x) = \frac{2}{(x-10)^{2}+1} + \frac{1}{(x-14)^{2}+1} (1)
1940///\f]
1941/// defined on the interval [4,16]. Events distributed according to the formula
1942/// (1) are simulated to create the unweighted histogram. Uniformly distributed
1943/// events are simulated for the weighted histogram with weights calculated by
1944/// formula (1). Each histogram has the same number of bins: 20. Fig.1 shows
1945/// the result of comparison of the unweighted histogram with 200 events
1946/// (minimal expected frequency equal to one) and the weighted histogram with
1947/// 500 events (minimal expected frequency equal to 25)
1948/// Begin_Macro
1949/// ../../../tutorials/math/chi2test.C
1950/// End_Macro
1951/// Fig 1. An example of comparison of the unweighted histogram with 200 events
1952/// and the weighted histogram with 500 events:
1953/// 1. unweighted histogram;
1954/// 2. weighted histogram;
1955/// 3. normalized residuals plot;
1956/// 4. normal Q-Q plot of residuals.
1957///
1958/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1959/// 21.09 with p-value equal to 0.33, therefore the hypothesis of identity of
1960/// the two histograms can be accepted for 0.05 significant level. The behavior
1961/// of the normalized residuals plot (see Fig. 1c) and the normal Q-Q plot
1962/// (see Fig. 1d) of residuals are regular and we cannot identify the outliers
1963/// or bins with a big influence on \f$ \chi^{2} \f$.
1964///
1965/// The second example presents the same two histograms but 17 events was added
1966/// to content of bin number 15 in unweighted histogram. Fig.2 shows the result
1967/// of comparison of the unweighted histogram with 217 events (minimal expected
1968/// frequency equal to one) and the weighted histogram with 500 events (minimal
1969/// expected frequency equal to 25)
1970/// Begin_Macro
1971/// ../../../tutorials/math/chi2test.C(17)
1972/// End_Macro
1973/// Fig 2. An example of comparison of the unweighted histogram with 217 events
1974/// and the weighted histogram with 500 events:
1975/// 1. unweighted histogram;
1976/// 2. weighted histogram;
1977/// 3. normalized residuals plot;
1978/// 4. normal Q-Q plot of residuals.
1979///
1980/// The value of the test statistic \f$ \chi^{2} \f$ is equal to
1981/// 32.33 with p-value equal to 0.029, therefore the hypothesis of identity of
1982/// the two histograms is rejected for 0.05 significant level. The behavior of
1983/// the normalized residuals plot (see Fig. 2c) and the normal Q-Q plot (see
1984/// Fig. 2d) of residuals are not regular and we can identify the outlier or
1985/// bin with a big influence on \f$ \chi^{2} \f$.
1986///
1987/// #### References:
1988///
1989/// - [1] Pearson, K., 1904. On the Theory of Contingency and Its Relation to
1990/// Association and Normal Correlation. Drapers' Co. Memoirs, Biometric
1991/// Series No. 1, London.
1992/// - [2] Gagunashvili, N., 2006. \f$ \sigma^{2} \f$ test for comparison
1993/// of weighted and unweighted histograms. Statistical Problems in Particle
1994/// Physics, Astrophysics and Cosmology, Proceedings of PHYSTAT05,
1995/// Oxford, UK, 12-15 September 2005, Imperial College Press, London, 43-44.
1996/// Gagunashvili,N., Comparison of weighted and unweighted histograms,
1997/// arXiv:physics/0605123, 2006.
1998/// - [3] Cramer, H., 1946. Mathematical methods of statistics.
1999/// Princeton University Press, Princeton.
2000/// - [4] Haberman, S.J., 1973. The analysis of residuals in cross-classified tables.
2001/// Biometrics 29, 205-220.
2002/// - [5] Lewontin, R.C. and Felsenstein, J., 1965. The robustness of homogeneity
2003/// test in 2xN tables. Biometrics 21, 19-33.
2004/// - [6] Seber, G.A.F., Lee, A.J., 2003, Linear Regression Analysis.
2005/// John Wiley & Sons Inc., New York.
2006
2007Double_t TH1::Chi2Test(const TH1* h2, Option_t *option, Double_t *res) const
2008{
2009 Double_t chi2 = 0;
2010 Int_t ndf = 0, igood = 0;
2011
2012 TString opt = option;
2013 opt.ToUpper();
2014
2015 Double_t prob = Chi2TestX(h2,chi2,ndf,igood,option,res);
2016
2017 if(opt.Contains("P")) {
2018 printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
2019 }
2020 if(opt.Contains("CHI2/NDF")) {
2021 if (ndf == 0) return 0;
2022 return chi2/ndf;
2023 }
2024 if(opt.Contains("CHI2")) {
2025 return chi2;
2026 }
2027
2028 return prob;
2029}
2030
2031////////////////////////////////////////////////////////////////////////////////
2032/// The computation routine of the Chisquare test. For the method description,
2033/// see Chi2Test() function.
2034///
2035/// \return p-value
2036/// \param[in] h2 the second histogram
2037/// \param[in] option
2038/// - "UU" = experiment experiment comparison (unweighted-unweighted)
2039/// - "UW" = experiment MC comparison (unweighted-weighted). Note that the first
2040/// histogram should be unweighted
2041/// - "WW" = MC MC comparison (weighted-weighted)
2042/// - "NORM" = if one or both histograms is scaled
2043/// - "OF" = overflows included
2044/// - "UF" = underflows included
2045/// by default underflows and overflows are not included
2046/// \param[out] igood test output
2047/// - igood=0 - no problems
2048/// - For unweighted unweighted comparison
2049/// - igood=1'There is a bin in the 1st histogram with less than 1 event'
2050/// - igood=2'There is a bin in the 2nd histogram with less than 1 event'
2051/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2052/// - For unweighted weighted comparison
2053/// - igood=1'There is a bin in the 1st histogram with less then 1 event'
2054/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective number of events'
2055/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2056/// - For weighted weighted comparison
2057/// - igood=1'There is a bin in the 1st histogram with less then 10 effective
2058/// number of events'
2059/// - igood=2'There is a bin in the 2nd histogram with less then 10 effective
2060/// number of events'
2061/// - igood=3'when the conditions for igood=1 and igood=2 are satisfied'
2062/// \param[out] chi2 chisquare of the test
2063/// \param[out] ndf number of degrees of freedom (important, when both histograms have the same empty bins)
2064/// \param[out] res normalized residuals for further analysis
2065
2066Double_t TH1::Chi2TestX(const TH1* h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option, Double_t *res) const
2067{
2068
2069 Int_t i_start, i_end;
2070 Int_t j_start, j_end;
2071 Int_t k_start, k_end;
2072
2073 Double_t sum1 = 0.0, sumw1 = 0.0;
2074 Double_t sum2 = 0.0, sumw2 = 0.0;
2075
2076 chi2 = 0.0;
2077 ndf = 0;
2078
2079 TString opt = option;
2080 opt.ToUpper();
2081
2082 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
2083
2084 const TAxis *xaxis1 = GetXaxis();
2085 const TAxis *xaxis2 = h2->GetXaxis();
2086 const TAxis *yaxis1 = GetYaxis();
2087 const TAxis *yaxis2 = h2->GetYaxis();
2088 const TAxis *zaxis1 = GetZaxis();
2089 const TAxis *zaxis2 = h2->GetZaxis();
2090
2091 Int_t nbinx1 = xaxis1->GetNbins();
2092 Int_t nbinx2 = xaxis2->GetNbins();
2093 Int_t nbiny1 = yaxis1->GetNbins();
2094 Int_t nbiny2 = yaxis2->GetNbins();
2095 Int_t nbinz1 = zaxis1->GetNbins();
2096 Int_t nbinz2 = zaxis2->GetNbins();
2097
2098 //check dimensions
2099 if (this->GetDimension() != h2->GetDimension() ){
2100 Error("Chi2TestX","Histograms have different dimensions.");
2101 return 0.0;
2102 }
2103
2104 //check number of channels
2105 if (nbinx1 != nbinx2) {
2106 Error("Chi2TestX","different number of x channels");
2107 }
2108 if (nbiny1 != nbiny2) {
2109 Error("Chi2TestX","different number of y channels");
2110 }
2111 if (nbinz1 != nbinz2) {
2112 Error("Chi2TestX","different number of z channels");
2113 }
2114
2115 //check for ranges
2116 i_start = j_start = k_start = 1;
2117 i_end = nbinx1;
2118 j_end = nbiny1;
2119 k_end = nbinz1;
2120
2121 if (xaxis1->TestBit(TAxis::kAxisRange)) {
2122 i_start = xaxis1->GetFirst();
2123 i_end = xaxis1->GetLast();
2124 }
2125 if (yaxis1->TestBit(TAxis::kAxisRange)) {
2126 j_start = yaxis1->GetFirst();
2127 j_end = yaxis1->GetLast();
2128 }
2129 if (zaxis1->TestBit(TAxis::kAxisRange)) {
2130 k_start = zaxis1->GetFirst();
2131 k_end = zaxis1->GetLast();
2132 }
2133
2134
2135 if (opt.Contains("OF")) {
2136 if (GetDimension() == 3) k_end = ++nbinz1;
2137 if (GetDimension() >= 2) j_end = ++nbiny1;
2138 if (GetDimension() >= 1) i_end = ++nbinx1;
2139 }
2140
2141 if (opt.Contains("UF")) {
2142 if (GetDimension() == 3) k_start = 0;
2143 if (GetDimension() >= 2) j_start = 0;
2144 if (GetDimension() >= 1) i_start = 0;
2145 }
2146
2147 ndf = (i_end - i_start + 1) * (j_end - j_start + 1) * (k_end - k_start + 1) - 1;
2148
2149 Bool_t comparisonUU = opt.Contains("UU");
2150 Bool_t comparisonUW = opt.Contains("UW");
2151 Bool_t comparisonWW = opt.Contains("WW");
2152 Bool_t scaledHistogram = opt.Contains("NORM");
2153
2154 if (scaledHistogram && !comparisonUU) {
2155 Info("Chi2TestX", "NORM option should be used together with UU option. It is ignored");
2156 }
2157
2158 // look at histo global bin content and effective entries
2159 Stat_t s[kNstat];
2160 GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2161 Double_t sumBinContent1 = s[0];
2162 Double_t effEntries1 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2163
2164 h2->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
2165 Double_t sumBinContent2 = s[0];
2166 Double_t effEntries2 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2167
2168 if (!comparisonUU && !comparisonUW && !comparisonWW ) {
2169 // deduce automatically from type of histogram
2170 if (TMath::Abs(sumBinContent1 - effEntries1) < 1) {
2171 if ( TMath::Abs(sumBinContent2 - effEntries2) < 1) comparisonUU = true;
2172 else comparisonUW = true;
2173 }
2174 else comparisonWW = true;
2175 }
2176 // check unweighted histogram
2177 if (comparisonUW) {
2178 if (TMath::Abs(sumBinContent1 - effEntries1) >= 1) {
2179 Warning("Chi2TestX","First histogram is not unweighted and option UW has been requested");
2180 }
2181 }
2182 if ( (!scaledHistogram && comparisonUU) ) {
2183 if ( ( TMath::Abs(sumBinContent1 - effEntries1) >= 1) || (TMath::Abs(sumBinContent2 - effEntries2) >= 1) ) {
2184 Warning("Chi2TestX","Both histograms are not unweighted and option UU has been requested");
2185 }
2186 }
2187
2188
2189 //get number of events in histogram
2190 if (comparisonUU && scaledHistogram) {
2191 for (Int_t i = i_start; i <= i_end; ++i) {
2192 for (Int_t j = j_start; j <= j_end; ++j) {
2193 for (Int_t k = k_start; k <= k_end; ++k) {
2194
2195 Int_t bin = GetBin(i, j, k);
2196
2197 Double_t cnt1 = RetrieveBinContent(bin);
2198 Double_t cnt2 = h2->RetrieveBinContent(bin);
2199 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2200 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2201
2202 if (e1sq > 0.0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2203 else cnt1 = 0.0;
2204
2205 if (e2sq > 0.0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2206 else cnt2 = 0.0;
2207
2208 // sum contents
2209 sum1 += cnt1;
2210 sum2 += cnt2;
2211 sumw1 += e1sq;
2212 sumw2 += e2sq;
2213 }
2214 }
2215 }
2216 if (sumw1 <= 0.0 || sumw2 <= 0.0) {
2217 Error("Chi2TestX", "Cannot use option NORM when one histogram has all zero errors");
2218 return 0.0;
2219 }
2220
2221 } else {
2222 for (Int_t i = i_start; i <= i_end; ++i) {
2223 for (Int_t j = j_start; j <= j_end; ++j) {
2224 for (Int_t k = k_start; k <= k_end; ++k) {
2225
2226 Int_t bin = GetBin(i, j, k);
2227
2228 sum1 += RetrieveBinContent(bin);
2229 sum2 += h2->RetrieveBinContent(bin);
2230
2231 if ( comparisonWW ) sumw1 += GetBinErrorSqUnchecked(bin);
2232 if ( comparisonUW || comparisonWW ) sumw2 += h2->GetBinErrorSqUnchecked(bin);
2233 }
2234 }
2235 }
2236 }
2237 //checks that the histograms are not empty
2238 if (sum1 == 0.0 || sum2 == 0.0) {
2239 Error("Chi2TestX","one histogram is empty");
2240 return 0.0;
2241 }
2242
2243 if ( comparisonWW && ( sumw1 <= 0.0 && sumw2 <= 0.0 ) ){
2244 Error("Chi2TestX","Hist1 and Hist2 have both all zero errors\n");
2245 return 0.0;
2246 }
2247
2248 //THE TEST
2249 Int_t m = 0, n = 0;
2250
2251 //Experiment - experiment comparison
2252 if (comparisonUU) {
2253 Double_t sum = sum1 + sum2;
2254 for (Int_t i = i_start; i <= i_end; ++i) {
2255 for (Int_t j = j_start; j <= j_end; ++j) {
2256 for (Int_t k = k_start; k <= k_end; ++k) {
2257
2258 Int_t bin = GetBin(i, j, k);
2259
2260 Double_t cnt1 = RetrieveBinContent(bin);
2261 Double_t cnt2 = h2->RetrieveBinContent(bin);
2262
2263 if (scaledHistogram) {
2264 // scale bin value to effective bin entries
2265 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2266 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2267
2268 if (e1sq > 0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5); // avoid rounding errors
2269 else cnt1 = 0;
2270
2271 if (e2sq > 0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5); // avoid rounding errors
2272 else cnt2 = 0;
2273 }
2274
2275 if (Int_t(cnt1) == 0 && Int_t(cnt2) == 0) --ndf; // no data means one degree of freedom less
2276 else {
2277
2278 Double_t cntsum = cnt1 + cnt2;
2279 Double_t nexp1 = cntsum * sum1 / sum;
2280 //Double_t nexp2 = binsum*sum2/sum;
2281
2282 if (res) res[i - i_start] = (cnt1 - nexp1) / TMath::Sqrt(nexp1);
2283
2284 if (cnt1 < 1) ++m;
2285 if (cnt2 < 1) ++n;
2286
2287 //Habermann correction for residuals
2288 Double_t correc = (1. - sum1 / sum) * (1. - cntsum / sum);
2289 if (res) res[i - i_start] /= TMath::Sqrt(correc);
2290
2291 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2292 chi2 += delta * delta / cntsum;
2293 }
2294 }
2295 }
2296 }
2297 chi2 /= sum1 * sum2;
2298
2299 // flag error only when of the two histogram is zero
2300 if (m) {
2301 igood += 1;
2302 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2303 }
2304 if (n) {
2305 igood += 2;
2306 Info("Chi2TestX","There is a bin in h2 with less than 1 event.\n");
2307 }
2308
2309 Double_t prob = TMath::Prob(chi2,ndf);
2310 return prob;
2311
2312 }
2313
2314 // unweighted - weighted comparison
2315 // case of error = 0 and content not zero is treated without problems by excluding second chi2 sum
2316 // and can be considered as a data-theory comparison
2317 if ( comparisonUW ) {
2318 for (Int_t i = i_start; i <= i_end; ++i) {
2319 for (Int_t j = j_start; j <= j_end; ++j) {
2320 for (Int_t k = k_start; k <= k_end; ++k) {
2321
2322 Int_t bin = GetBin(i, j, k);
2323
2324 Double_t cnt1 = RetrieveBinContent(bin);
2325 Double_t cnt2 = h2->RetrieveBinContent(bin);
2326 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2327
2328 // case both histogram have zero bin contents
2329 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2330 --ndf; //no data means one degree of freedom less
2331 continue;
2332 }
2333
2334 // case weighted histogram has zero bin content and error
2335 if (cnt2 * cnt2 == 0 && e2sq == 0) {
2336 if (sumw2 > 0) {
2337 // use as approximated error as 1 scaled by a scaling ratio
2338 // estimated from the total sum weight and sum weight squared
2339 e2sq = sumw2 / sum2;
2340 }
2341 else {
2342 // return error because infinite discrepancy here:
2343 // bin1 != 0 and bin2 =0 in a histogram with all errors zero
2344 Error("Chi2TestX","Hist2 has in bin (%d,%d,%d) zero content and zero errors\n", i, j, k);
2345 chi2 = 0; return 0;
2346 }
2347 }
2348
2349 if (cnt1 < 1) m++;
2350 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2351
2352 Double_t var1 = sum2 * cnt2 - sum1 * e2sq;
2353 Double_t var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2354
2355 // if cnt1 is zero and cnt2 = 1 and sum1 = sum2 var1 = 0 && var2 == 0
2356 // approximate by incrementing cnt1
2357 // LM (this need to be fixed for numerical errors)
2358 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2359 sum1++;
2360 cnt1++;
2361 var1 = sum2 * cnt2 - sum1 * e2sq;
2362 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2363 }
2364 var2 = TMath::Sqrt(var2);
2365
2366 while (var1 + var2 == 0) {
2367 sum1++;
2368 cnt1++;
2369 var1 = sum2 * cnt2 - sum1 * e2sq;
2370 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2371 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2372 sum1++;
2373 cnt1++;
2374 var1 = sum2 * cnt2 - sum1 * e2sq;
2375 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2376 }
2377 var2 = TMath::Sqrt(var2);
2378 }
2379
2380 Double_t probb = (var1 + var2) / (2. * sum2 * sum2);
2381
2382 Double_t nexp1 = probb * sum1;
2383 Double_t nexp2 = probb * sum2;
2384
2385 Double_t delta1 = cnt1 - nexp1;
2386 Double_t delta2 = cnt2 - nexp2;
2387
2388 chi2 += delta1 * delta1 / nexp1;
2389
2390 if (e2sq > 0) {
2391 chi2 += delta2 * delta2 / e2sq;
2392 }
2393
2394 if (res) {
2395 if (e2sq > 0) {
2396 Double_t temp1 = sum2 * e2sq / var2;
2397 Double_t temp2 = 1.0 + (sum1 * e2sq - sum2 * cnt2) / var2;
2398 temp2 = temp1 * temp1 * sum1 * probb * (1.0 - probb) + temp2 * temp2 * e2sq / 4.0;
2399 // invert sign here
2400 res[i - i_start] = - delta2 / TMath::Sqrt(temp2);
2401 }
2402 else
2403 res[i - i_start] = delta1 / TMath::Sqrt(nexp1);
2404 }
2405 }
2406 }
2407 }
2408
2409 if (m) {
2410 igood += 1;
2411 Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
2412 }
2413 if (n) {
2414 igood += 2;
2415 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2416 }
2417
2418 Double_t prob = TMath::Prob(chi2, ndf);
2419
2420 return prob;
2421 }
2422
2423 // weighted - weighted comparison
2424 if (comparisonWW) {
2425 for (Int_t i = i_start; i <= i_end; ++i) {
2426 for (Int_t j = j_start; j <= j_end; ++j) {
2427 for (Int_t k = k_start; k <= k_end; ++k) {
2428
2429 Int_t bin = GetBin(i, j, k);
2430 Double_t cnt1 = RetrieveBinContent(bin);
2431 Double_t cnt2 = h2->RetrieveBinContent(bin);
2432 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2433 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2434
2435 // case both histogram have zero bin contents
2436 // (use square of content to avoid numerical errors)
2437 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2438 --ndf; //no data means one degree of freedom less
2439 continue;
2440 }
2441
2442 if (e1sq == 0 && e2sq == 0) {
2443 // cannot treat case of booth histogram have zero zero errors
2444 Error("Chi2TestX","h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
2445 chi2 = 0; return 0;
2446 }
2447
2448 Double_t sigma = sum1 * sum1 * e2sq + sum2 * sum2 * e1sq;
2449 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2450 chi2 += delta * delta / sigma;
2451
2452 if (res) {
2453 Double_t temp = cnt1 * sum1 * e2sq + cnt2 * sum2 * e1sq;
2454 Double_t probb = temp / sigma;
2455 Double_t z = 0;
2456 if (e1sq > e2sq) {
2457 Double_t d1 = cnt1 - sum1 * probb;
2458 Double_t s1 = e1sq * ( 1. - e2sq * sum1 * sum1 / sigma );
2459 z = d1 / TMath::Sqrt(s1);
2460 }
2461 else {
2462 Double_t d2 = cnt2 - sum2 * probb;
2463 Double_t s2 = e2sq * ( 1. - e1sq * sum2 * sum2 / sigma );
2464 z = -d2 / TMath::Sqrt(s2);
2465 }
2466 res[i - i_start] = z;
2467 }
2468
2469 if (e1sq > 0 && cnt1 * cnt1 / e1sq < 10) m++;
2470 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2471 }
2472 }
2473 }
2474 if (m) {
2475 igood += 1;
2476 Info("Chi2TestX","There is a bin in h1 with less than 10 effective events.\n");
2477 }
2478 if (n) {
2479 igood += 2;
2480 Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
2481 }
2482 Double_t prob = TMath::Prob(chi2, ndf);
2483 return prob;
2484 }
2485 return 0;
2486}
2487////////////////////////////////////////////////////////////////////////////////
2488/// Compute and return the chisquare of this histogram with respect to a function
2489/// The chisquare is computed by weighting each histogram point by the bin error
2490/// By default the full range of the histogram is used.
2491/// Use option "R" for restricting the chisquare calculation to the given range of the function
2492/// Use option "L" for using the chisquare based on the poisson likelihood (Baker-Cousins Chisquare)
2493
2494Double_t TH1::Chisquare(TF1 * func, Option_t *option) const
2495{
2496 if (!func) {
2497 Error("Chisquare","Function pointer is Null - return -1");
2498 return -1;
2499 }
2500
2501 TString opt(option); opt.ToUpper();
2502 bool useRange = opt.Contains("R");
2503 bool usePL = opt.Contains("L");
2504
2505 return ROOT::Fit::Chisquare(*this, *func, useRange, usePL);
2506}
2507
2508////////////////////////////////////////////////////////////////////////////////
2509/// Remove all the content from the underflow and overflow bins, without changing the number of entries
2510/// After calling this method, every undeflow and overflow bins will have content 0.0
2511/// The Sumw2 is also cleared, since there is no more content in the bins
2512
2514{
2515 for (Int_t bin = 0; bin < fNcells; ++bin)
2516 if (IsBinUnderflow(bin) || IsBinOverflow(bin)) {
2517 UpdateBinContent(bin, 0.0);
2518 if (fSumw2.fN) fSumw2.fArray[bin] = 0.0;
2519 }
2520}
2521
2522////////////////////////////////////////////////////////////////////////////////
2523/// Compute integral (cumulative sum of bins)
2524/// The result stored in fIntegral is used by the GetRandom functions.
2525/// This function is automatically called by GetRandom when the fIntegral
2526/// array does not exist or when the number of entries in the histogram
2527/// has changed since the previous call to GetRandom.
2528/// The resulting integral is normalized to 1
2529/// If the routine is called with the onlyPositive flag set an error will
2530/// be produced in case of negative bin content and a NaN value returned
2531
2533{
2534 if (fBuffer) BufferEmpty();
2535
2536 // delete previously computed integral (if any)
2537 if (fIntegral) delete [] fIntegral;
2538
2539 // - Allocate space to store the integral and compute integral
2540 Int_t nbinsx = GetNbinsX();
2541 Int_t nbinsy = GetNbinsY();
2542 Int_t nbinsz = GetNbinsZ();
2543 Int_t nbins = nbinsx * nbinsy * nbinsz;
2544
2545 fIntegral = new Double_t[nbins + 2];
2546 Int_t ibin = 0; fIntegral[ibin] = 0;
2547
2548 for (Int_t binz=1; binz <= nbinsz; ++binz) {
2549 for (Int_t biny=1; biny <= nbinsy; ++biny) {
2550 for (Int_t binx=1; binx <= nbinsx; ++binx) {
2551 ++ibin;
2552 Double_t y = RetrieveBinContent(GetBin(binx, biny, binz));
2553 if (onlyPositive && y < 0) {
2554 Error("ComputeIntegral","Bin content is negative - return a NaN value");
2555 fIntegral[nbins] = TMath::QuietNaN();
2556 break;
2557 }
2558 fIntegral[ibin] = fIntegral[ibin - 1] + y;
2559 }
2560 }
2561 }
2562
2563 // - Normalize integral to 1
2564 if (fIntegral[nbins] == 0 ) {
2565 Error("ComputeIntegral", "Integral = zero"); return 0;
2566 }
2567 for (Int_t bin=1; bin <= nbins; ++bin) fIntegral[bin] /= fIntegral[nbins];
2568 fIntegral[nbins+1] = fEntries;
2569 return fIntegral[nbins];
2570}
2571
2572////////////////////////////////////////////////////////////////////////////////
2573/// Return a pointer to the array of bins integral.
2574/// if the pointer fIntegral is null, TH1::ComputeIntegral is called
2575/// The array dimension is the number of bins in the histograms
2576/// including underflow and overflow (fNCells)
2577/// the last value integral[fNCells] is set to the number of entries of
2578/// the histogram
2579
2581{
2582 if (!fIntegral) ComputeIntegral();
2583 return fIntegral;
2584}
2585
2586////////////////////////////////////////////////////////////////////////////////
2587/// Return a pointer to an histogram containing the cumulative content.
2588/// The cumulative can be computed both in the forward (default) or backward
2589/// direction; the name of the new histogram is constructed from
2590/// the name of this histogram with the suffix "suffix" appended provided
2591/// by the user. If not provided a default suffix="_cumulative" is used.
2592///
2593/// The cumulative distribution is formed by filling each bin of the
2594/// resulting histogram with the sum of that bin and all previous
2595/// (forward == kTRUE) or following (forward = kFALSE) bins.
2596///
2597/// Note: while cumulative distributions make sense in one dimension, you
2598/// may not be getting what you expect in more than 1D because the concept
2599/// of a cumulative distribution is much trickier to define; make sure you
2600/// understand the order of summation before you use this method with
2601/// histograms of dimension >= 2.
2602///
2603/// Note 2: By default the cumulative is computed from bin 1 to Nbins
2604/// If an axis range is set, values between the minimum and maximum of the range
2605/// are set.
2606/// Setting an axis range can also be used for including underflow and overflow in
2607/// the cumulative (e.g. by setting h->GetXaxis()->SetRange(0, h->GetNbinsX()+1); )
2609
2610TH1 *TH1::GetCumulative(Bool_t forward, const char* suffix) const
2611{
2612 const Int_t firstX = fXaxis.GetFirst();
2613 const Int_t lastX = fXaxis.GetLast();
2614 const Int_t firstY = (fDimension > 1) ? fYaxis.GetFirst() : 1;
2615 const Int_t lastY = (fDimension > 1) ? fYaxis.GetLast() : 1;
2616 const Int_t firstZ = (fDimension > 1) ? fZaxis.GetFirst() : 1;
2617 const Int_t lastZ = (fDimension > 1) ? fZaxis.GetLast() : 1;
2618
2619 TH1* hintegrated = (TH1*) Clone(fName + suffix);
2620 hintegrated->Reset();
2621 Double_t sum = 0.;
2622 Double_t esum = 0;
2623 if (forward) { // Forward computation
2624 for (Int_t binz = firstZ; binz <= lastZ; ++binz) {
2625 for (Int_t biny = firstY; biny <= lastY; ++biny) {
2626 for (Int_t binx = firstX; binx <= lastX; ++binx) {
2627 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2628 sum += RetrieveBinContent(bin);
2629 hintegrated->AddBinContent(bin, sum);
2630 if (fSumw2.fN) {
2631 esum += GetBinErrorSqUnchecked(bin);
2632 fSumw2.fArray[bin] = esum;
2633 }
2634 }
2635 }
2636 }
2637 } else { // Backward computation
2638 for (Int_t binz = lastZ; binz >= firstZ; --binz) {
2639 for (Int_t biny = lastY; biny >= firstY; --biny) {
2640 for (Int_t binx = lastX; binx >= firstX; --binx) {
2641 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2642 sum += RetrieveBinContent(bin);
2643 hintegrated->AddBinContent(bin, sum);
2644 if (fSumw2.fN) {
2645 esum += GetBinErrorSqUnchecked(bin);
2646 fSumw2.fArray[bin] = esum;
2647 }
2648 }
2649 }
2650 }
2651 }
2652 return hintegrated;
2653}
2654
2655////////////////////////////////////////////////////////////////////////////////
2656/// Copy this histogram structure to newth1.
2657///
2658/// Note that this function does not copy the list of associated functions.
2659/// Use TObject::Clone to make a full copy of an histogram.
2660///
2661/// Note also that the histogram it will be created in gDirectory (if AddDirectoryStatus()=true)
2662/// or will not be added to any directory if AddDirectoryStatus()=false
2663/// independently of the current directory stored in the original histogram
2664
2665void TH1::Copy(TObject &obj) const
2666{
2667 if (((TH1&)obj).fDirectory) {
2668 // We are likely to change the hash value of this object
2669 // with TNamed::Copy, to keep things correct, we need to
2670 // clean up its existing entries.
2671 ((TH1&)obj).fDirectory->Remove(&obj);
2672 ((TH1&)obj).fDirectory = 0;
2673 }
2674 TNamed::Copy(obj);
2675 ((TH1&)obj).fDimension = fDimension;
2676 ((TH1&)obj).fNormFactor= fNormFactor;
2677 ((TH1&)obj).fNcells = fNcells;
2678 ((TH1&)obj).fBarOffset = fBarOffset;
2679 ((TH1&)obj).fBarWidth = fBarWidth;
2680 ((TH1&)obj).fOption = fOption;
2681 ((TH1&)obj).fBinStatErrOpt = fBinStatErrOpt;
2682 ((TH1&)obj).fBufferSize= fBufferSize;
2683 // copy the Buffer
2684 // delete first a previously existing buffer
2685 if (((TH1&)obj).fBuffer != 0) {
2686 delete [] ((TH1&)obj).fBuffer;
2687 ((TH1&)obj).fBuffer = 0;
2688 }
2689 if (fBuffer) {
2690 Double_t *buf = new Double_t[fBufferSize];
2691 for (Int_t i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
2692 // obj.fBuffer has been deleted before
2693 ((TH1&)obj).fBuffer = buf;
2694 }
2695
2696
2697 TArray* a = dynamic_cast<TArray*>(&obj);
2698 if (a) a->Set(fNcells);
2699 for (Int_t i = 0; i < fNcells; i++) ((TH1&)obj).UpdateBinContent(i, RetrieveBinContent(i));
2700
2701 ((TH1&)obj).fEntries = fEntries;
2702
2703 // which will call BufferEmpty(0) and set fBuffer[0] to a Maybe one should call
2704 // assignment operator on the TArrayD
2705
2706 ((TH1&)obj).fTsumw = fTsumw;
2707 ((TH1&)obj).fTsumw2 = fTsumw2;
2708 ((TH1&)obj).fTsumwx = fTsumwx;
2709 ((TH1&)obj).fTsumwx2 = fTsumwx2;
2710 ((TH1&)obj).fMaximum = fMaximum;
2711 ((TH1&)obj).fMinimum = fMinimum;
2712
2713 TAttLine::Copy(((TH1&)obj));
2714 TAttFill::Copy(((TH1&)obj));
2715 TAttMarker::Copy(((TH1&)obj));
2716 fXaxis.Copy(((TH1&)obj).fXaxis);
2717 fYaxis.Copy(((TH1&)obj).fYaxis);
2718 fZaxis.Copy(((TH1&)obj).fZaxis);
2719 ((TH1&)obj).fXaxis.SetParent(&obj);
2720 ((TH1&)obj).fYaxis.SetParent(&obj);
2721 ((TH1&)obj).fZaxis.SetParent(&obj);
2722 fContour.Copy(((TH1&)obj).fContour);
2723 fSumw2.Copy(((TH1&)obj).fSumw2);
2724 // fFunctions->Copy(((TH1&)obj).fFunctions);
2725 // when copying an histogram if the AddDirectoryStatus() is true it
2726 // will be added to gDirectory independently of the fDirectory stored.
2727 // and if the AddDirectoryStatus() is false it will not be added to
2728 // any directory (fDirectory = 0)
2729 if (fgAddDirectory && gDirectory) {
2730 gDirectory->Append(&obj);
2731 ((TH1&)obj).fFunctions->UseRWLock();
2732 ((TH1&)obj).fDirectory = gDirectory;
2733 } else
2734 ((TH1&)obj).fDirectory = 0;
2735
2736}
2737
2738////////////////////////////////////////////////////////////////////////////////
2739/// Make a complete copy of the underlying object. If 'newname' is set,
2740/// the copy's name will be set to that name.
2741
2742TObject* TH1::Clone(const char* newname) const
2743{
2744 TH1* obj = (TH1*)IsA()->GetNew()(0);
2745 Copy(*obj);
2746
2747 // Now handle the parts that Copy doesn't do
2748 if(fFunctions) {
2749 // The Copy above might have published 'obj' to the ListOfCleanups.
2750 // Clone can call RecursiveRemove, for example via TCheckHashRecursiveRemoveConsistency
2751 // when dictionary information is initialized, so we need to
2752 // keep obj->fFunction valid during its execution and
2753 // protect the update with the write lock.
2754
2755 // Reset stats parent - else cloning the stats will clone this histogram, too.
2756 auto oldstats = dynamic_cast<TVirtualPaveStats*>(fFunctions->FindObject("stats"));
2757 TObject *oldparent = nullptr;
2758 if (oldstats) {
2759 oldparent = oldstats->GetParent();
2760 oldstats->SetParent(nullptr);
2761 }
2762
2763 auto newlist = (TList*)fFunctions->Clone();
2764
2765 if (oldstats)
2766 oldstats->SetParent(oldparent);
2767 auto newstats = dynamic_cast<TVirtualPaveStats*>(obj->fFunctions->FindObject("stats"));
2768 if (newstats)
2769 newstats->SetParent(obj);
2770
2771 auto oldlist = obj->fFunctions;
2772 {
2774 obj->fFunctions = newlist;
2775 }
2776 delete oldlist;
2777 }
2778 if(newname && strlen(newname) ) {
2779 obj->SetName(newname);
2780 }
2781 return obj;
2782}
2783
2784////////////////////////////////////////////////////////////////////////////////
2785/// Perform the automatic addition of the histogram to the given directory
2786///
2787/// Note this function is called in place when the semantic requires
2788/// this object to be added to a directory (I.e. when being read from
2789/// a TKey or being Cloned)
2790
2792{
2793 Bool_t addStatus = TH1::AddDirectoryStatus();
2794 if (addStatus) {
2795 SetDirectory(dir);
2796 if (dir) {
2798 }
2799 }
2800}
2801
2802////////////////////////////////////////////////////////////////////////////////
2803/// Compute distance from point px,py to a line.
2804///
2805/// Compute the closest distance of approach from point px,py to elements
2806/// of an histogram.
2807/// The distance is computed in pixels units.
2808///
2809/// #### Algorithm:
2810/// Currently, this simple model computes the distance from the mouse
2811/// to the histogram contour only.
2812
2814{
2815 if (!fPainter) return 9999;
2816 return fPainter->DistancetoPrimitive(px,py);
2817}
2818
2819////////////////////////////////////////////////////////////////////////////////
2820/// Performs the operation: `this = this/(c1*f1)`
2821/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2822///
2823/// Only bins inside the function range are recomputed.
2824/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2825/// you should call Sumw2 before making this operation.
2826/// This is particularly important if you fit the histogram after TH1::Divide
2827///
2828/// The function return kFALSE if the divide operation failed
2829
2831{
2832 if (!f1) {
2833 Error("Divide","Attempt to divide by a non-existing function");
2834 return kFALSE;
2835 }
2836
2837 // delete buffer if it is there since it will become invalid
2838 if (fBuffer) BufferEmpty(1);
2839
2840 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of
2841 Int_t ny = GetNbinsY() + 2;
2842 Int_t nz = GetNbinsZ() + 2;
2843 if (fDimension < 2) ny = 1;
2844 if (fDimension < 3) nz = 1;
2845
2846
2847 SetMinimum();
2848 SetMaximum();
2849
2850 // - Loop on bins (including underflows/overflows)
2851 Int_t bin, binx, biny, binz;
2852 Double_t cu, w;
2853 Double_t xx[3];
2854 Double_t *params = 0;
2855 f1->InitArgs(xx,params);
2856 for (binz = 0; binz < nz; ++binz) {
2857 xx[2] = fZaxis.GetBinCenter(binz);
2858 for (biny = 0; biny < ny; ++biny) {
2859 xx[1] = fYaxis.GetBinCenter(biny);
2860 for (binx = 0; binx < nx; ++binx) {
2861 xx[0] = fXaxis.GetBinCenter(binx);
2862 if (!f1->IsInside(xx)) continue;
2864 bin = binx + nx * (biny + ny * binz);
2865 cu = c1 * f1->EvalPar(xx);
2866 if (TF1::RejectedPoint()) continue;
2867 if (cu) w = RetrieveBinContent(bin) / cu;
2868 else w = 0;
2869 UpdateBinContent(bin, w);
2870 if (fSumw2.fN) {
2871 if (cu != 0) fSumw2.fArray[bin] = GetBinErrorSqUnchecked(bin) / (cu * cu);
2872 else fSumw2.fArray[bin] = 0;
2873 }
2874 }
2875 }
2876 }
2877 ResetStats();
2878 return kTRUE;
2879}
2880
2881////////////////////////////////////////////////////////////////////////////////
2882/// Divide this histogram by h1.
2883///
2884/// `this = this/h1`
2885/// if errors are defined (see TH1::Sumw2), errors are also recalculated.
2886/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
2887/// if not already set.
2888/// The resulting errors are calculated assuming uncorrelated histograms.
2889/// See the other TH1::Divide that gives the possibility to optionally
2890/// compute binomial errors.
2891///
2892/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2893/// you should call Sumw2 before making this operation.
2894/// This is particularly important if you fit the histogram after TH1::Scale
2895///
2896/// The function return kFALSE if the divide operation failed
2897
2898Bool_t TH1::Divide(const TH1 *h1)
2899{
2900 if (!h1) {
2901 Error("Divide", "Input histogram passed does not exist (NULL).");
2902 return kFALSE;
2903 }
2904
2905 // delete buffer if it is there since it will become invalid
2906 if (fBuffer) BufferEmpty(1);
2907
2908 try {
2909 CheckConsistency(this,h1);
2910 } catch(DifferentNumberOfBins&) {
2911 Error("Divide","Cannot divide histograms with different number of bins");
2912 return kFALSE;
2913 } catch(DifferentAxisLimits&) {
2914 Warning("Divide","Dividing histograms with different axis limits");
2915 } catch(DifferentBinLimits&) {
2916 Warning("Divide","Dividing histograms with different bin limits");
2917 } catch(DifferentLabels&) {
2918 Warning("Divide","Dividing histograms with different labels");
2919 }
2920
2921 // Create Sumw2 if h1 has Sumw2 set
2922 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
2923
2924 // - Loop on bins (including underflows/overflows)
2925 for (Int_t i = 0; i < fNcells; ++i) {
2928 if (c1) UpdateBinContent(i, c0 / c1);
2929 else UpdateBinContent(i, 0);
2930
2931 if(fSumw2.fN) {
2932 if (c1 == 0) { fSumw2.fArray[i] = 0; continue; }
2933 Double_t c1sq = c1 * c1;
2934 fSumw2.fArray[i] = (GetBinErrorSqUnchecked(i) * c1sq + h1->GetBinErrorSqUnchecked(i) * c0 * c0) / (c1sq * c1sq);
2935 }
2936 }
2937 ResetStats();
2938 return kTRUE;
2939}
2940
2941////////////////////////////////////////////////////////////////////////////////
2942/// Replace contents of this histogram by the division of h1 by h2.
2943///
2944/// `this = c1*h1/(c2*h2)`
2945///
2946/// If errors are defined (see TH1::Sumw2), errors are also recalculated
2947/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
2948/// if not already set.
2949/// The resulting errors are calculated assuming uncorrelated histograms.
2950/// However, if option ="B" is specified, Binomial errors are computed.
2951/// In this case c1 and c2 do not make real sense and they are ignored.
2952///
2953/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
2954/// you should call Sumw2 before making this operation.
2955/// This is particularly important if you fit the histogram after TH1::Divide
2956///
2957/// Please note also that in the binomial case errors are calculated using standard
2958/// binomial statistics, which means when b1 = b2, the error is zero.
2959/// If you prefer to have efficiency errors not going to zero when the efficiency is 1, you must
2960/// use the function TGraphAsymmErrors::BayesDivide, which will return an asymmetric and non-zero lower
2961/// error for the case b1=b2.
2962///
2963/// The function return kFALSE if the divide operation failed
2964
2965Bool_t TH1::Divide(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
2966{
2967
2968 TString opt = option;
2969 opt.ToLower();
2970 Bool_t binomial = kFALSE;
2971 if (opt.Contains("b")) binomial = kTRUE;
2972 if (!h1 || !h2) {
2973 Error("Divide", "At least one of the input histograms passed does not exist (NULL).");
2974 return kFALSE;
2975 }
2976
2977 // delete buffer if it is there since it will become invalid
2978 if (fBuffer) BufferEmpty(1);
2979
2980 try {
2981 CheckConsistency(h1,h2);
2982 CheckConsistency(this,h1);
2983 } catch(DifferentNumberOfBins&) {
2984 Error("Divide","Cannot divide histograms with different number of bins");
2985 return kFALSE;
2986 } catch(DifferentAxisLimits&) {
2987 Warning("Divide","Dividing histograms with different axis limits");
2988 } catch(DifferentBinLimits&) {
2989 Warning("Divide","Dividing histograms with different bin limits");
2990 } catch(DifferentLabels&) {
2991 Warning("Divide","Dividing histograms with different labels");
2992 }
2993
2994
2995 if (!c2) {
2996 Error("Divide","Coefficient of dividing histogram cannot be zero");
2997 return kFALSE;
2998 }
2999
3000 // Create Sumw2 if h1 or h2 have Sumw2 set, or if binomial errors are explicitly requested
3001 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0 || binomial)) Sumw2();
3002
3003 SetMinimum();
3004 SetMaximum();
3005
3006 // - Loop on bins (including underflows/overflows)
3007 for (Int_t i = 0; i < fNcells; ++i) {
3009 Double_t b2 = h2->RetrieveBinContent(i);
3010 if (b2) UpdateBinContent(i, c1 * b1 / (c2 * b2));
3011 else UpdateBinContent(i, 0);
3012
3013 if (fSumw2.fN) {
3014 if (b2 == 0) { fSumw2.fArray[i] = 0; continue; }
3015 Double_t b1sq = b1 * b1; Double_t b2sq = b2 * b2;
3016 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
3018 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
3019 if (binomial) {
3020 if (b1 != b2) {
3021 // in the case of binomial statistics c1 and c2 must be 1 otherwise it does not make sense
3022 // c1 and c2 are ignored
3023 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));//this is the formula in Hbook/Hoper1
3024 //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2); // old formula from G. Flucke
3025 // formula which works also for weighted histogram (see http://root-forum.cern.ch/viewtopic.php?t=3753 )
3026 fSumw2.fArray[i] = TMath::Abs( ( (1. - 2.* b1 / b2) * e1sq + b1sq * e2sq / b2sq ) / b2sq );
3027 } else {
3028 //in case b1=b2 error is zero
3029 //use TGraphAsymmErrors::BayesDivide for getting the asymmetric error not equal to zero
3030 fSumw2.fArray[i] = 0;
3031 }
3032 } else {
3033 fSumw2.fArray[i] = c1sq * c2sq * (e1sq * b2sq + e2sq * b1sq) / (c2sq * c2sq * b2sq * b2sq);
3034 }
3035 }
3036 }
3037 ResetStats();
3038 if (binomial)
3039 // in case of binomial division use denominator for number of entries
3040 SetEntries ( h2->GetEntries() );
3041
3042 return kTRUE;
3043}
3044
3045////////////////////////////////////////////////////////////////////////////////
3046/// Draw this histogram with options.
3047///
3048/// Histograms are drawn via the THistPainter class. Each histogram has
3049/// a pointer to its own painter (to be usable in a multithreaded program).
3050/// The same histogram can be drawn with different options in different pads.
3051/// When an histogram drawn in a pad is deleted, the histogram is
3052/// automatically removed from the pad or pads where it was drawn.
3053/// If an histogram is drawn in a pad, then filled again, the new status
3054/// of the histogram will be automatically shown in the pad next time
3055/// the pad is updated. One does not need to redraw the histogram.
3056/// To draw the current version of an histogram in a pad, one can use
3057/// `h->DrawCopy();`
3058/// This makes a clone of the histogram. Once the clone is drawn, the original
3059/// histogram may be modified or deleted without affecting the aspect of the
3060/// clone.
3061/// By default, TH1::Draw clears the current pad.
3062///
3063/// One can use TH1::SetMaximum and TH1::SetMinimum to force a particular
3064/// value for the maximum or the minimum scale on the plot.
3065///
3066/// TH1::UseCurrentStyle can be used to change all histogram graphics
3067/// attributes to correspond to the current selected style.
3068/// This function must be called for each histogram.
3069/// In case one reads and draws many histograms from a file, one can force
3070/// the histograms to inherit automatically the current graphics style
3071/// by calling before gROOT->ForceStyle();
3072///
3073/// See the THistPainter class for a description of all the drawing options.
3074
3075void TH1::Draw(Option_t *option)
3076{
3077 TString opt1 = option; opt1.ToLower();
3078 TString opt2 = option;
3079 Int_t index = opt1.Index("same");
3080
3081 // Check if the string "same" is part of a TCutg name.
3082 if (index>=0) {
3083 Int_t indb = opt1.Index("[");
3084 if (indb>=0) {
3085 Int_t indk = opt1.Index("]");
3086 if (index>indb && index<indk) index = -1;
3087 }
3088 }
3089
3090 // If there is no pad or an empty pad the "same" option is ignored.
3091 if (gPad) {
3092 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
3093 if (index>=0) {
3094 if (gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
3095 gPad->GetY1() == 0 && gPad->GetY2() == 1 &&
3096 gPad->GetListOfPrimitives()->GetSize()==0) opt2.Remove(index,4);
3097 } else {
3098 //the following statement is necessary in case one attempts to draw
3099 //a temporary histogram already in the current pad
3100 if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(this);
3101 gPad->Clear();
3102 }
3103 gPad->IncrementPaletteColor(1, opt1);
3104 } else {
3105 if (index>=0) opt2.Remove(index,4);
3106 }
3107
3108 AppendPad(opt2.Data());
3109}
3110
3111////////////////////////////////////////////////////////////////////////////////
3112/// Copy this histogram and Draw in the current pad.
3113///
3114/// Once the histogram is drawn into the pad, any further modification
3115/// using graphics input will be made on the copy of the histogram,
3116/// and not to the original object.
3117/// By default a postfix "_copy" is added to the histogram name. Pass an empty postfix in case
3118/// you want to draw an histogram with the same name
3119///
3120/// See Draw for the list of options
3121
3122TH1 *TH1::DrawCopy(Option_t *option, const char * name_postfix) const
3123{
3124 TString opt = option;
3125 opt.ToLower();
3126 if (gPad && !opt.Contains("same")) gPad->Clear();
3127 TString newName = (name_postfix) ? TString::Format("%s%s",GetName(),name_postfix) : "";
3128 TH1 *newth1 = (TH1 *)Clone(newName);
3129 newth1->SetDirectory(0);
3130 newth1->SetBit(kCanDelete);
3131 if (gPad) gPad->IncrementPaletteColor(1, opt);
3132
3133 newth1->AppendPad(option);
3134 return newth1;
3135}
3136
3137////////////////////////////////////////////////////////////////////////////////
3138/// Draw a normalized copy of this histogram.
3139///
3140/// A clone of this histogram is normalized to norm and drawn with option.
3141/// A pointer to the normalized histogram is returned.
3142/// The contents of the histogram copy are scaled such that the new
3143/// sum of weights (excluding under and overflow) is equal to norm.
3144/// Note that the returned normalized histogram is not added to the list
3145/// of histograms in the current directory in memory.
3146/// It is the user's responsibility to delete this histogram.
3147/// The kCanDelete bit is set for the returned object. If a pad containing
3148/// this copy is cleared, the histogram will be automatically deleted.
3149///
3150/// See Draw for the list of options
3151
3152TH1 *TH1::DrawNormalized(Option_t *option, Double_t norm) const
3153{
3155 if (sum == 0) {
3156 Error("DrawNormalized","Sum of weights is null. Cannot normalize histogram: %s",GetName());
3157 return 0;
3158 }
3159 Bool_t addStatus = TH1::AddDirectoryStatus();
3161 TH1 *h = (TH1*)Clone();
3163 // in case of drawing with error options - scale correctly the error
3164 TString opt(option); opt.ToUpper();
3165 if (fSumw2.fN == 0) {
3166 h->Sumw2();
3167 // do not use in this case the "Error option " for drawing which is enabled by default since the normalized histogram has now errors
3168 if (opt.IsNull() || opt == "SAME") opt += "HIST";
3169 }
3170 h->Scale(norm/sum);
3171 if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
3172 if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
3173 h->Draw(opt);
3174 TH1::AddDirectory(addStatus);
3175 return h;
3176}
3177
3178////////////////////////////////////////////////////////////////////////////////
3179/// Display a panel with all histogram drawing options.
3180///
3181/// See class TDrawPanelHist for example
3182
3183void TH1::DrawPanel()
3184{
3185 if (!fPainter) {Draw(); if (gPad) gPad->Update();}
3186 if (fPainter) fPainter->DrawPanel();
3187}
3188
3189////////////////////////////////////////////////////////////////////////////////
3190/// Evaluate function f1 at the center of bins of this histogram.
3191///
3192/// - If option "R" is specified, the function is evaluated only
3193/// for the bins included in the function range.
3194/// - If option "A" is specified, the value of the function is added to the
3195/// existing bin contents
3196/// - If option "S" is specified, the value of the function is used to
3197/// generate a value, distributed according to the Poisson
3198/// distribution, with f1 as the mean.
3199
3200void TH1::Eval(TF1 *f1, Option_t *option)
3201{
3202 Double_t x[3];
3203 Int_t range, stat, add;
3204 if (!f1) return;
3205
3206 TString opt = option;
3207 opt.ToLower();
3208 if (opt.Contains("a")) add = 1;
3209 else add = 0;
3210 if (opt.Contains("s")) stat = 1;
3211 else stat = 0;
3212 if (opt.Contains("r")) range = 1;
3213 else range = 0;
3214
3215 // delete buffer if it is there since it will become invalid
3216 if (fBuffer) BufferEmpty(1);
3217
3218 Int_t nbinsx = fXaxis.GetNbins();
3219 Int_t nbinsy = fYaxis.GetNbins();
3220 Int_t nbinsz = fZaxis.GetNbins();
3221 if (!add) Reset();
3222
3223 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
3224 x[2] = fZaxis.GetBinCenter(binz);
3225 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
3226 x[1] = fYaxis.GetBinCenter(biny);
3227 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
3228 Int_t bin = GetBin(binx,biny,binz);
3229 x[0] = fXaxis.GetBinCenter(binx);
3230 if (range && !f1->IsInside(x)) continue;
3231 Double_t fu = f1->Eval(x[0], x[1], x[2]);
3232 if (stat) fu = gRandom->PoissonD(fu);
3233 AddBinContent(bin, fu);
3234 if (fSumw2.fN) fSumw2.fArray[bin] += TMath::Abs(fu);
3235 }
3236 }
3237 }
3238}
3239
3240////////////////////////////////////////////////////////////////////////////////
3241/// Execute action corresponding to one event.
3242///
3243/// This member function is called when a histogram is clicked with the locator
3244///
3245/// If Left button clicked on the bin top value, then the content of this bin
3246/// is modified according to the new position of the mouse when it is released.
3247
3248void TH1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3249{
3250 if (fPainter) fPainter->ExecuteEvent(event, px, py);
3251}
3252
3253////////////////////////////////////////////////////////////////////////////////
3254/// This function allows to do discrete Fourier transforms of TH1 and TH2.
3255/// Available transform types and flags are described below.
3256///
3257/// To extract more information about the transform, use the function
3258/// TVirtualFFT::GetCurrentTransform() to get a pointer to the current
3259/// transform object.
3260///
3261/// \param[out] h_output histogram for the output. If a null pointer is passed, a new histogram is created
3262/// and returned, otherwise, the provided histogram is used and should be big enough
3263/// \param[in] option option parameters consists of 3 parts:
3264/// - option on what to return
3265/// - "RE" - returns a histogram of the real part of the output
3266/// - "IM" - returns a histogram of the imaginary part of the output
3267/// - "MAG"- returns a histogram of the magnitude of the output
3268/// - "PH" - returns a histogram of the phase of the output
3269/// - option of transform type
3270/// - "R2C" - real to complex transforms - default
3271/// - "R2HC" - real to halfcomplex (special format of storing output data,
3272/// results the same as for R2C)
3273/// - "DHT" - discrete Hartley transform
3274/// real to real transforms (sine and cosine):
3275/// - "R2R_0", "R2R_1", "R2R_2", "R2R_3" - discrete cosine transforms of types I-IV
3276/// - "R2R_4", "R2R_5", "R2R_6", "R2R_7" - discrete sine transforms of types I-IV
3277/// To specify the type of each dimension of a 2-dimensional real to real
3278/// transform, use options of form "R2R_XX", for example, "R2R_02" for a transform,
3279/// which is of type "R2R_0" in 1st dimension and "R2R_2" in the 2nd.
3280/// - option of transform flag
3281/// - "ES" (from "estimate") - no time in preparing the transform, but probably sub-optimal
3282/// performance
3283/// - "M" (from "measure") - some time spend in finding the optimal way to do the transform
3284/// - "P" (from "patient") - more time spend in finding the optimal way to do the transform
3285/// - "EX" (from "exhaustive") - the most optimal way is found
3286/// This option should be chosen depending on how many transforms of the same size and
3287/// type are going to be done. Planning is only done once, for the first transform of this
3288/// size and type. Default is "ES".
3289///
3290/// Examples of valid options: "Mag R2C M" "Re R2R_11" "Im R2C ES" "PH R2HC EX"
3291
3292TH1* TH1::FFT(TH1* h_output, Option_t *option)
3293{
3294
3295 Int_t ndim[3];
3296 ndim[0] = this->GetNbinsX();
3297 ndim[1] = this->GetNbinsY();
3298 ndim[2] = this->GetNbinsZ();
3299
3300 TVirtualFFT *fft;
3301 TString opt = option;
3302 opt.ToUpper();
3303 if (!opt.Contains("2R")){
3304 if (!opt.Contains("2C") && !opt.Contains("2HC") && !opt.Contains("DHT")) {
3305 //no type specified, "R2C" by default
3306 opt.Append("R2C");
3307 }
3308 fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
3309 }
3310 else {
3311 //find the kind of transform
3312 Int_t ind = opt.Index("R2R", 3);
3313 Int_t *kind = new Int_t[2];
3314 char t;
3315 t = opt[ind+4];
3316 kind[0] = atoi(&t);
3317 if (h_output->GetDimension()>1) {
3318 t = opt[ind+5];
3319 kind[1] = atoi(&t);
3320 }
3321 fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
3322 delete [] kind;
3323 }
3324
3325 if (!fft) return 0;
3326 Int_t in=0;
3327 for (Int_t binx = 1; binx<=ndim[0]; binx++) {
3328 for (Int_t biny=1; biny<=ndim[1]; biny++) {
3329 for (Int_t binz=1; binz<=ndim[2]; binz++) {
3330 fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
3331 in++;
3332 }
3333 }
3334 }
3335 fft->Transform();
3336 h_output = TransformHisto(fft, h_output, option);
3337 return h_output;
3338}
3339
3340////////////////////////////////////////////////////////////////////////////////
3341/// Increment bin with abscissa X by 1.
3342///
3343/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3344/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3345///
3346/// If the storage of the sum of squares of weights has been triggered,
3347/// via the function Sumw2, then the sum of the squares of weights is incremented
3348/// by 1 in the bin corresponding to x.
3349///
3350/// The function returns the corresponding bin number which has its content incremented by 1
3351
3353{
3354 if (fBuffer) return BufferFill(x,1);
3355
3356 Int_t bin;
3357 fEntries++;
3358 bin =fXaxis.FindBin(x);
3359 if (bin <0) return -1;
3360 AddBinContent(bin);
3361 if (fSumw2.fN) ++fSumw2.fArray[bin];
3362 if (bin == 0 || bin > fXaxis.GetNbins()) {
3363 if (!GetStatOverflowsBehaviour()) return -1;
3364 }
3365 ++fTsumw;
3366 ++fTsumw2;
3367 fTsumwx += x;
3368 fTsumwx2 += x*x;
3369 return bin;
3370}
3371
3372////////////////////////////////////////////////////////////////////////////////
3373/// Increment bin with abscissa X with a weight w.
3374///
3375/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3376/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3377///
3378/// If the weight is not equal to 1, the storage of the sum of squares of
3379/// weights is automatically triggered and the sum of the squares of weights is incremented
3380/// by \f$ w^2 \f$ in the bin corresponding to x.
3381///
3382/// The function returns the corresponding bin number which has its content incremented by w
3383
3385{
3386
3387 if (fBuffer) return BufferFill(x,w);
3388
3389 Int_t bin;
3390 fEntries++;
3391 bin =fXaxis.FindBin(x);
3392 if (bin <0) return -1;
3393 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW) ) Sumw2(); // must be called before AddBinContent
3394 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3395 AddBinContent(bin, w);
3396 if (bin == 0 || bin > fXaxis.GetNbins()) {
3397 if (!GetStatOverflowsBehaviour()) return -1;
3398 }
3399 Double_t z= w;
3400 fTsumw += z;
3401 fTsumw2 += z*z;
3402 fTsumwx += z*x;
3403 fTsumwx2 += z*x*x;
3404 return bin;
3405}
3406
3407////////////////////////////////////////////////////////////////////////////////
3408/// Increment bin with namex with a weight w
3409///
3410/// if x is less than the low-edge of the first bin, the Underflow bin is incremented
3411/// if x is equal to or greater than the upper edge of last bin, the Overflow bin is incremented
3412///
3413/// If the weight is not equal to 1, the storage of the sum of squares of
3414/// weights is automatically triggered and the sum of the squares of weights is incremented
3415/// by \f$ w^2 \f$ in the bin corresponding to x.
3416///
3417/// The function returns the corresponding bin number which has its content
3418/// incremented by w.
3419
3420Int_t TH1::Fill(const char *namex, Double_t w)
3421{
3422 Int_t bin;
3423 fEntries++;
3424 bin =fXaxis.FindBin(namex);
3425 if (bin <0) return -1;
3426 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3427 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3428 AddBinContent(bin, w);
3429 if (bin == 0 || bin > fXaxis.GetNbins()) return -1;
3430 Double_t z= w;
3431 fTsumw += z;
3432 fTsumw2 += z*z;
3433 // this make sense if the histogram is not expanding (the x axis cannot be extended)
3434 if (!fXaxis.CanExtend() || !fXaxis.IsAlphanumeric()) {
3436 fTsumwx += z*x;
3437 fTsumwx2 += z*x*x;
3438 }
3439 return bin;
3440}
3441
3442////////////////////////////////////////////////////////////////////////////////
3443/// Fill this histogram with an array x and weights w.
3444///
3445/// \param[in] ntimes number of entries in arrays x and w (array size must be ntimes*stride)
3446/// \param[in] x array of values to be histogrammed
3447/// \param[in] w array of weighs
3448/// \param[in] stride step size through arrays x and w
3449///
3450/// If the weight is not equal to 1, the storage of the sum of squares of
3451/// weights is automatically triggered and the sum of the squares of weights is incremented
3452/// by \f$ w^2 \f$ in the bin corresponding to x.
3453/// if w is NULL each entry is assumed a weight=1
3454
3455void TH1::FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3456{
3457 //If a buffer is activated, fill buffer
3458 if (fBuffer) {
3459 ntimes *= stride;
3460 Int_t i = 0;
3461 for (i=0;i<ntimes;i+=stride) {
3462 if (!fBuffer) break; // buffer can be deleted in BufferFill when is empty
3463 if (w) BufferFill(x[i],w[i]);
3464 else BufferFill(x[i], 1.);
3465 }
3466 // fill the remaining entries if the buffer has been deleted
3467 if (i < ntimes && fBuffer==0) {
3468 auto weights = w ? &w[i] : nullptr;
3469 DoFillN((ntimes-i)/stride,&x[i],weights,stride);
3470 }
3471 return;
3472 }
3473 // call internal method
3474 DoFillN(ntimes, x, w, stride);
3475}
3476
3477////////////////////////////////////////////////////////////////////////////////
3478/// Internal method to fill histogram content from a vector
3479/// called directly by TH1::BufferEmpty
3480
3481void TH1::DoFillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
3482{
3483 Int_t bin,i;
3484
3485 fEntries += ntimes;
3486 Double_t ww = 1;
3487 Int_t nbins = fXaxis.GetNbins();
3488 ntimes *= stride;
3489 for (i=0;i<ntimes;i+=stride) {
3490 bin =fXaxis.FindBin(x[i]);
3491 if (bin <0) continue;
3492 if (w) ww = w[i];
3493 if (!fSumw2.fN && ww != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3494 if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
3495 AddBinContent(bin, ww);
3496 if (bin == 0 || bin > nbins) {
3497 if (!GetStatOverflowsBehaviour()) continue;
3498 }
3499 Double_t z= ww;
3500 fTsumw += z;
3501 fTsumw2 += z*z;
3502 fTsumwx += z*x[i];
3503 fTsumwx2 += z*x[i]*x[i];
3504 }
3505}
3506
3507////////////////////////////////////////////////////////////////////////////////
3508/// Fill histogram following distribution in function fname.
3509///
3510/// @param fname : Function name used for filling the histogram
3511/// @param ntimes : number of times the histogram is filled
3512/// @param rng : (optional) Random number generator used to sample
3513///
3514///
3515/// The distribution contained in the function fname (TF1) is integrated
3516/// over the channel contents for the bin range of this histogram.
3517/// It is normalized to 1.
3518///
3519/// Getting one random number implies:
3520/// - Generating a random number between 0 and 1 (say r1)
3521/// - Look in which bin in the normalized integral r1 corresponds to
3522/// - Fill histogram channel
3523/// ntimes random numbers are generated
3524///
3525/// One can also call TF1::GetRandom to get a random variate from a function.
3526
3527void TH1::FillRandom(const char *fname, Int_t ntimes, TRandom * rng)
3528{
3529 Int_t bin, binx, ibin, loop;
3530 Double_t r1, x;
3531 // - Search for fname in the list of ROOT defined functions
3532 TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
3533 if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
3534
3535 // - Allocate temporary space to store the integral and compute integral
3536
3537 TAxis * xAxis = &fXaxis;
3538
3539 // in case axis of histogram is not defined use the function axis
3540 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
3542 f1->GetRange(xmin,xmax);
3543 Info("FillRandom","Using function axis and range [%g,%g]",xmin, xmax);
3544 xAxis = f1->GetHistogram()->GetXaxis();
3545 }
3546
3547 Int_t first = xAxis->GetFirst();
3548 Int_t last = xAxis->GetLast();
3549 Int_t nbinsx = last-first+1;
3550
3551 Double_t *integral = new Double_t[nbinsx+1];
3552 integral[0] = 0;
3553 for (binx=1;binx<=nbinsx;binx++) {
3554 Double_t fint = f1->Integral(xAxis->GetBinLowEdge(binx+first-1),xAxis->GetBinUpEdge(binx+first-1), 0.);
3555 integral[binx] = integral[binx-1] + fint;
3556 }
3557
3558 // - Normalize integral to 1
3559 if (integral[nbinsx] == 0 ) {
3560 delete [] integral;
3561 Error("FillRandom", "Integral = zero"); return;
3562 }
3563 for (bin=1;bin<=nbinsx;bin++) integral[bin] /= integral[nbinsx];
3564
3565 // --------------Start main loop ntimes
3566 for (loop=0;loop<ntimes;loop++) {
3567 r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
3568 ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
3569 //binx = 1 + ibin;
3570 //x = xAxis->GetBinCenter(binx); //this is not OK when SetBuffer is used
3571 x = xAxis->GetBinLowEdge(ibin+first)
3572 +xAxis->GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
3573 Fill(x);
3574 }
3575 delete [] integral;
3576}
3577
3578////////////////////////////////////////////////////////////////////////////////
3579/// Fill histogram following distribution in histogram h.
3580///
3581/// @param h : Histogram pointer used for sampling random number
3582/// @param ntimes : number of times the histogram is filled
3583/// @param rng : (optional) Random number generator used for sampling
3584///
3585/// The distribution contained in the histogram h (TH1) is integrated
3586/// over the channel contents for the bin range of this histogram.
3587/// It is normalized to 1.
3588///
3589/// Getting one random number implies:
3590/// - Generating a random number between 0 and 1 (say r1)
3591/// - Look in which bin in the normalized integral r1 corresponds to
3592/// - Fill histogram channel ntimes random numbers are generated
3593///
3594/// SPECIAL CASE when the target histogram has the same binning as the source.
3595/// in this case we simply use a poisson distribution where
3596/// the mean value per bin = bincontent/integral.
3597
3598void TH1::FillRandom(TH1 *h, Int_t ntimes, TRandom * rng)
3599{
3600 if (!h) { Error("FillRandom", "Null histogram"); return; }
3601 if (fDimension != h->GetDimension()) {
3602 Error("FillRandom", "Histograms with different dimensions"); return;
3603 }
3604 if (std::isnan(h->ComputeIntegral(true))) {
3605 Error("FillRandom", "Histograms contains negative bins, does not represent probabilities");
3606 return;
3607 }
3608
3609 //in case the target histogram has the same binning and ntimes much greater
3610 //than the number of bins we can use a fast method
3612 Int_t last = fXaxis.GetLast();
3613 Int_t nbins = last-first+1;
3614 if (ntimes > 10*nbins) {
3615 try {
3616 CheckConsistency(this,h);
3617 Double_t sumw = h->Integral(first,last);
3618 if (sumw == 0) return;
3619 Double_t sumgen = 0;
3620 for (Int_t bin=first;bin<=last;bin++) {
3621 Double_t mean = h->RetrieveBinContent(bin)*ntimes/sumw;
3622 Double_t cont = (rng) ? rng->Poisson(mean) : gRandom->Poisson(mean);
3623 sumgen += cont;
3624 AddBinContent(bin,cont);
3625 if (fSumw2.fN) fSumw2.fArray[bin] += cont;
3626 }
3627
3628 // fix for the fluctuations in the total number n
3629 // since we use Poisson instead of multinomial
3630 // add a correction to have ntimes as generated entries
3631 Int_t i;
3632 if (sumgen < ntimes) {
3633 // add missing entries
3634 for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
3635 {
3636 Double_t x = h->GetRandom();
3637 Fill(x);
3638 }
3639 }
3640 else if (sumgen > ntimes) {
3641 // remove extra entries
3642 i = Int_t(sumgen+0.5);
3643 while( i > ntimes) {
3644 Double_t x = h->GetRandom(rng);
3645 Int_t ibin = fXaxis.FindBin(x);
3647 // skip in case bin is empty
3648 if (y > 0) {
3649 SetBinContent(ibin, y-1.);
3650 i--;
3651 }
3652 }
3653 }
3654
3655 ResetStats();
3656 return;
3657 }
3658 catch(std::exception&) {} // do nothing
3659 }
3660 // case of different axis and not too large ntimes
3661
3662 if (h->ComputeIntegral() ==0) return;
3663 Int_t loop;
3664 Double_t x;
3665 for (loop=0;loop<ntimes;loop++) {
3666 x = h->GetRandom();
3667 Fill(x);
3668 }
3669}
3670
3671////////////////////////////////////////////////////////////////////////////////
3672/// Return Global bin number corresponding to x,y,z
3673///
3674/// 2-D and 3-D histograms are represented with a one dimensional
3675/// structure. This has the advantage that all existing functions, such as
3676/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3677/// This function tries to extend the axis if the given point belongs to an
3678/// under-/overflow bin AND if CanExtendAllAxes() is true.
3679///
3680/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3681
3683{
3684 if (GetDimension() < 2) {
3685 return fXaxis.FindBin(x);
3686 }
3687 if (GetDimension() < 3) {
3688 Int_t nx = fXaxis.GetNbins()+2;
3689 Int_t binx = fXaxis.FindBin(x);
3690 Int_t biny = fYaxis.FindBin(y);
3691 return binx + nx*biny;
3692 }
3693 if (GetDimension() < 4) {
3694 Int_t nx = fXaxis.GetNbins()+2;
3695 Int_t ny = fYaxis.GetNbins()+2;
3696 Int_t binx = fXaxis.FindBin(x);
3697 Int_t biny = fYaxis.FindBin(y);
3698 Int_t binz = fZaxis.FindBin(z);
3699 return binx + nx*(biny +ny*binz);
3700 }
3701 return -1;
3702}
3703
3704////////////////////////////////////////////////////////////////////////////////
3705/// Return Global bin number corresponding to x,y,z.
3706///
3707/// 2-D and 3-D histograms are represented with a one dimensional
3708/// structure. This has the advantage that all existing functions, such as
3709/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
3710/// This function DOES NOT try to extend the axis if the given point belongs
3711/// to an under-/overflow bin.
3712///
3713/// See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
3714
3716{
3717 if (GetDimension() < 2) {
3718 return fXaxis.FindFixBin(x);
3719 }
3720 if (GetDimension() < 3) {
3721 Int_t nx = fXaxis.GetNbins()+2;
3722 Int_t binx = fXaxis.FindFixBin(x);
3723 Int_t biny = fYaxis.FindFixBin(y);
3724 return binx + nx*biny;
3725 }
3726 if (GetDimension() < 4) {
3727 Int_t nx = fXaxis.GetNbins()+2;
3728 Int_t ny = fYaxis.GetNbins()+2;
3729 Int_t binx = fXaxis.FindFixBin(x);
3730 Int_t biny = fYaxis.FindFixBin(y);
3731 Int_t binz = fZaxis.FindFixBin(z);
3732 return binx + nx*(biny +ny*binz);
3733 }
3734 return -1;
3735}
3736
3737////////////////////////////////////////////////////////////////////////////////
3738/// Find first bin with content > threshold for axis (1=x, 2=y, 3=z)
3739/// if no bins with content > threshold is found the function returns -1.
3740/// The search will occur between the specified first and last bin. Specifying
3741/// the value of the last bin to search to less than zero will search until the
3742/// last defined bin.
3743
3744Int_t TH1::FindFirstBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3745{
3746 if (fBuffer) ((TH1*)this)->BufferEmpty();
3747
3748 if (axis < 1 || (axis > 1 && GetDimension() == 1 ) ||
3749 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3 ) ) {
3750 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3751 axis = 1;
3752 }
3753 if (firstBin < 1) {
3754 firstBin = 1;
3755 }
3756 Int_t nbinsx = fXaxis.GetNbins();
3757 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3758 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3759
3760 if (axis == 1) {
3761 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3762 lastBin = fXaxis.GetNbins();
3763 }
3764 for (Int_t binx = firstBin; binx <= lastBin; binx++) {
3765 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3766 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3767 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binx;
3768 }
3769 }
3770 }
3771 }
3772 else if (axis == 2) {
3773 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3774 lastBin = fYaxis.GetNbins();
3775 }
3776 for (Int_t biny = firstBin; biny <= lastBin; biny++) {
3777 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3778 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3779 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return biny;
3780 }
3781 }
3782 }
3783 }
3784 else if (axis == 3) {
3785 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3786 lastBin = fZaxis.GetNbins();
3787 }
3788 for (Int_t binz = firstBin; binz <= lastBin; binz++) {
3789 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3790 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3791 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold) return binz;
3792 }
3793 }
3794 }
3795 }
3796
3797 return -1;
3798}
3799
3800////////////////////////////////////////////////////////////////////////////////
3801/// Find last bin with content > threshold for axis (1=x, 2=y, 3=z)
3802/// if no bins with content > threshold is found the function returns -1.
3803/// The search will occur between the specified first and last bin. Specifying
3804/// the value of the last bin to search to less than zero will search until the
3805/// last defined bin.
3806
3807Int_t TH1::FindLastBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin) const
3808{
3809 if (fBuffer) ((TH1*)this)->BufferEmpty();
3810
3811
3812 if (axis < 1 || ( axis > 1 && GetDimension() == 1 ) ||
3813 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3) ) {
3814 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
3815 axis = 1;
3816 }
3817 if (firstBin < 1) {
3818 firstBin = 1;
3819 }
3820 Int_t nbinsx = fXaxis.GetNbins();
3821 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3822 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3823
3824 if (axis == 1) {
3825 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3826 lastBin = fXaxis.GetNbins();
3827 }
3828 for (Int_t binx = lastBin; binx >= firstBin; binx--) {
3829 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3830 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3831 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binx;
3832 }
3833 }
3834 }
3835 }
3836 else if (axis == 2) {
3837 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3838 lastBin = fYaxis.GetNbins();
3839 }
3840 for (Int_t biny = lastBin; biny >= firstBin; biny--) {
3841 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3842 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3843 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return biny;
3844 }
3845 }
3846 }
3847 }
3848 else if (axis == 3) {
3849 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3850 lastBin = fZaxis.GetNbins();
3851 }
3852 for (Int_t binz = lastBin; binz >= firstBin; binz--) {
3853 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3854 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3855 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold) return binz;
3856 }
3857 }
3858 }
3859 }
3860
3861 return -1;
3862}
3863
3864////////////////////////////////////////////////////////////////////////////////
3865/// Search object named name in the list of functions.
3866
3867TObject *TH1::FindObject(const char *name) const
3868{
3869 if (fFunctions) return fFunctions->FindObject(name);
3870 return 0;
3871}
3872
3873////////////////////////////////////////////////////////////////////////////////
3874/// Search object obj in the list of functions.
3875
3876TObject *TH1::FindObject(const TObject *obj) const
3877{
3878 if (fFunctions) return fFunctions->FindObject(obj);
3879 return 0;
3880}
3881
3882////////////////////////////////////////////////////////////////////////////////
3883/// Fit histogram with function fname.
3884///
3885/// fname is the name of an already predefined function created by TF1 or TF2
3886/// Predefined functions such as gaus, expo and poln are automatically
3887/// created by ROOT.
3888/// fname can also be a formula, accepted by the linear fitter (linear parts divided
3889/// by "++" sign), for example "x++sin(x)" for fitting "[0]*x+[1]*sin(x)"
3890///
3891/// This function finds a pointer to the TF1 object with name fname
3892/// and calls TH1::Fit(TF1 *f1,...)
3893
3894TFitResultPtr TH1::Fit(const char *fname ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
3895{
3896 char *linear;
3897 linear= (char*)strstr(fname, "++");
3898 Int_t ndim=GetDimension();
3899 if (linear){
3900 if (ndim<2){
3901 TF1 f1(fname, fname, xxmin, xxmax);
3902 return Fit(&f1,option,goption,xxmin,xxmax);
3903 }
3904 else if (ndim<3){
3905 TF2 f2(fname, fname);
3906 return Fit(&f2,option,goption,xxmin,xxmax);
3907 }
3908 else{
3909 TF3 f3(fname, fname);
3910 return Fit(&f3,option,goption,xxmin,xxmax);
3911 }
3912 }
3913 else{
3914 TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
3915 if (!f1) { Printf("Unknown function: %s",fname); return -1; }
3916 return Fit(f1,option,goption,xxmin,xxmax);
3917 }
3918}
3919
3920////////////////////////////////////////////////////////////////////////////////
3921/// Fit histogram with function f1.
3922///
3923/// \param[in] option fit options is given in parameter option.
3924/// - "W" Ignore the bin uncertainties when fitting using the default least square (chi2) method but skip empty bins
3925/// - "WW" Ignore the bin uncertainties when fitting using the default least square (chi2) method and include also the empty bins
3926/// - "I" Use integral of function in bin, normalized by the bin volume,
3927/// instead of value at bin center
3928/// - "L" Use Loglikelihood method (default is chisquare method)
3929/// - "WL" Use Loglikelihood method and bin contents are not integer,
3930/// i.e. histogram is weighted (must have Sumw2() set)
3931/// -"MULTI" Use Loglikelihood method based on multi-nomial distribution.
3932/// In this case function must be normalized and one fits only the function shape (a not extended binned
3933/// likelihood fit)
3934/// - "P" Use Pearson chi2 (using expected errors instead of observed errors)
3935/// - "U" Use a User specified fitting algorithm (via SetFCN)
3936/// - "Q" Quiet mode (minimum printing)
3937/// - "V" Verbose mode (default is between Q and V)
3938/// - "E" Perform better Errors estimation using Minos technique
3939/// - "B" User defined parameter settings are used for predefined functions
3940/// like "gaus", "expo", "poln", "landau".
3941/// Use this option when you want to fix one or more parameters for these functions.
3942/// - "M" More. Improve fit results.
3943/// It uses the IMPROVE command of TMinuit (see TMinuit::mnimpr).
3944/// This algorithm attempts to improve the found local minimum by searching for a
3945/// better one.
3946/// - "R" Use the Range specified in the function range
3947/// - "N" Do not store the graphics function, do not draw
3948/// - "0" Do not plot the result of the fit. By default the fitted function
3949/// is drawn unless the option"N" above is specified.
3950/// - "+" Add this new fitted function to the list of fitted functions
3951/// (by default, any previous function is deleted)
3952/// - "C" In case of linear fitting, don't calculate the chisquare
3953/// (saves time)
3954/// - "F" If fitting a polN, switch to minuit fitter
3955/// - "S" The result of the fit is returned in the TFitResultPtr
3956/// (see below Access to the Fit Result)
3957/// \param[in] goption specify a list of graphics options. See TH1::Draw for a complete list of these options.
3958/// \param[in] xxmin range
3959/// \param[in] xxmax range
3960///
3961/// In order to use the Range option, one must first create a function
3962/// with the expression to be fitted. For example, if your histogram
3963/// has a defined range between -4 and 4 and you want to fit a gaussian
3964/// only in the interval 1 to 3, you can do:
3965///
3966/// ~~~ {.cpp}
3967/// TF1 *f1 = new TF1("f1", "gaus", 1, 3);
3968/// histo->Fit("f1", "R");
3969/// ~~~
3970///
3971/// ## Setting initial conditions
3972/// Parameters must be initialized before invoking the Fit function.
3973/// The setting of the parameter initial values is automatic for the
3974/// predefined functions : poln, expo, gaus, landau. One can however disable
3975/// this automatic computation by specifying the option "B".
3976/// Note that if a predefined function is defined with an argument,
3977/// eg, gaus(0), expo(1), you must specify the initial values for
3978/// the parameters.
3979/// You can specify boundary limits for some or all parameters via
3980///
3981/// ~~~ {.cpp}
3982/// f1->SetParLimits(p_number, parmin, parmax);
3983/// ~~~
3984///
3985/// if parmin>=parmax, the parameter is fixed
3986/// Note that you are not forced to fix the limits for all parameters.
3987/// For example, if you fit a function with 6 parameters, you can do:
3988///
3989/// ~~~ {.cpp}
3990/// func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
3991/// func->SetParLimits(3, -10, -4);
3992/// func->FixParameter(4, 0);
3993/// func->SetParLimits(5, 1, 1);
3994/// ~~~
3995///
3996/// With this setup, parameters 0->2 can vary freely
3997/// Parameter 3 has boundaries [-10,-4] with initial value -8
3998/// Parameter 4 is fixed to 0
3999/// Parameter 5 is fixed to 100.
4000/// When the lower limit and upper limit are equal, the parameter is fixed.
4001/// However to fix a parameter to 0, one must call the FixParameter function.
4002///
4003///
4004/// #### Changing the fitting objective function
4005///
4006/// By default a chi square function is used for fitting. When option "L" (or "LL") is used
4007/// a Poisson likelihood function (see note below) is used.
4008/// Using option "MULTI" a multinomial likelihood fit is used. In this case the function normalization is not fitted
4009/// but only the function shape. Therefore the provided function must be normalized.
4010/// The functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
4011/// are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
4012/// the file math/mathcore/src/FitUtil.cxx.
4013/// To specify a User defined fitting function, specify option "U" and
4014/// call the following functions:
4015///
4016/// ~~~ {.cpp}
4017/// TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction)
4018/// ~~~
4019///
4020/// where MyFittingFunction is of type:
4021///
4022/// ~~~ {.cpp}
4023/// extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
4024/// ~~~
4025///
4026/// #### Chi2 Fits
4027///
4028/// By default a chi2 (least-square) fit is performed on the histogram. The so-called modified least-square method
4029/// is used where the residual for each bin is computed using as error the observed value (the bin error)
4030///
4031/// \f[
4032/// Chi2 = \sum{ \left(\frac{y(i) - f(x(i) | p )}{e(i)} \right)^2 }
4033/// \f]
4034///
4035/// 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
4036/// an un-weighted histogram. Bins with zero errors are excluded from the fit. See also later the note on the treatment
4037/// of empty bins. When using option "I" the residual is computed not using the function value at the bin center, f
4038/// (x(i) | p), but the integral of the function in the bin, Integral{ f(x|p)dx } divided by the bin volume
4039///
4040/// #### Likelihood Fits
4041///
4042/// When using option "L" a likelihood fit is used instead of the default chi2 square fit.
4043/// The likelihood is built assuming a Poisson probability density function for each bin.
4044/// The negative log-likelihood to be minimized is
4045///
4046/// \f[
4047/// NLL = \sum{ log Poisson ( y(i) | f(x(i) | p ) ) }
4048/// \f]
4049///
4050/// The exact likelihood used is the Poisson likelihood described in this paper:
4051/// S. Baker and R. D. Cousins, “Clarification of the use of chi-square and likelihood functions in fits to histograms,”
4052/// Nucl. Instrum. Meth. 221 (1984) 437.
4053///
4054/// This method can then be used only when the bin content represents counts (i.e. errors are sqrt(N) ).
4055/// The likelihood method has the advantage of treating correctly bins with low statistics. In case of high
4056/// statistics/bin the distribution of the bin content becomes a normal distribution and the likelihood and chi2 fit
4057/// give the same result.
4058///
4059/// The likelihood method, although a bit slower, it is therefore the recommended method in case of low
4060/// bin statistics, where the chi2 method may give incorrect results, in particular when there are
4061/// several empty bins (see also below).
4062/// In case of a weighted histogram, it is possible to perform a likelihood fit by using the
4063/// option "WL". Note a weighted histogram is an histogram which has been filled with weights and it
4064/// contains the sum of the weight square ( TH1::Sumw2() has been called). The bin error for a weighted
4065/// histogram is the square root of the sum of the weight square.
4066///
4067/// #### Treatment of Empty Bins
4068///
4069/// Empty bins, which have the content equal to zero AND error equal to zero,
4070/// are excluded by default from the chisquare fit, but they are considered in the likelihood fit.
4071/// since they affect the likelihood if the function value in these bins is not negligible.
4072/// When using option "WW" these bins will be considered in the chi2 fit with an error of 1.
4073/// Note that if the histogram is having bins with zero content and non zero-errors they are considered as
4074/// any other bins in the fit. Instead bins with zero error and non-zero content are excluded in the chi2 fit.
4075/// A likelihood fit should also not be performed on such an histogram, since we are assuming a wrong pdf for each bin.
4076/// In general, one should not fit an histogram with non-empty bins and zero errors, apart if all the bins have zero
4077/// errors. In this case one could use the option "w", which gives a weight=1 for each bin (unweighted least-square
4078/// fit).
4079/// Note that in case of histogram with no errors (chi2 fit with option W or W1) the resulting fitted parameter errors
4080/// are corrected by the obtained chi2 value using this expression: errorp *= sqrt(chisquare/(ndf-1))
4081///
4082/// #### Fitting a histogram of dimension N with a function of dimension N-1
4083///
4084/// It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
4085/// In this case the option "Integral" is not allowed and each cell has
4086/// equal weight. Also in this case the obtained parameter error are corrected as in the case when the
4087/// option "W" is used (see above)
4088///
4089/// #### Associated functions
4090///
4091/// One or more object (typically a TF1*) can be added to the list
4092/// of functions (fFunctions) associated to each histogram.
4093/// When TH1::Fit is invoked, the fitted function is added to this list.
4094/// Given an histogram h, one can retrieve an associated function
4095/// with:
4096///
4097/// ~~~ {.cpp}
4098/// TF1 *myfunc = h->GetFunction("myfunc");
4099/// ~~~
4100///
4101/// #### Access to the fit result
4102///
4103/// The function returns a TFitResultPtr which can hold a pointer to a TFitResult object.
4104/// By default the TFitResultPtr contains only the status of the fit which is return by an
4105/// automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
4106///
4107/// ~~~ {.cpp}
4108/// Int_t fitStatus = h->Fit(myFunc)
4109/// ~~~
4110///
4111/// If the option "S" is instead used, TFitResultPtr contains the TFitResult and behaves as a smart
4112/// pointer to it. For example one can do:
4113///
4114/// ~~~ {.cpp}
4115/// TFitResultPtr r = h->Fit(myFunc,"S");
4116/// TMatrixDSym cov = r->GetCovarianceMatrix(); // to access the covariance matrix
4117/// Double_t chi2 = r->Chi2(); // to retrieve the fit chi2
4118/// Double_t par0 = r->Parameter(0); // retrieve the value for the parameter 0
4119/// Double_t err0 = r->ParError(0); // retrieve the error for the parameter 0
4120/// r->Print("V"); // print full information of fit including covariance matrix
4121/// r->Write(); // store the result in a file
4122/// ~~~
4123///
4124/// The fit parameters, error and chi2 (but not covariance matrix) can be retrieved also
4125/// from the fitted function.
4126/// If the histogram is made persistent, the list of
4127/// associated functions is also persistent. Given a pointer (see above)
4128/// to an associated function myfunc, one can retrieve the function/fit
4129/// parameters with calls such as:
4130///
4131/// ~~~ {.cpp}
4132/// Double_t chi2 = myfunc->GetChisquare();
4133/// Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
4134/// Double_t err0 = myfunc->GetParError(0); //error on first parameter
4135/// ~~~
4136///
4137/// #### Access to the fit status
4138///
4139/// The status of the fit can be obtained converting the TFitResultPtr to an integer
4140/// independently if the fit option "S" is used or not:
4141///
4142/// ~~~ {.cpp}
4143/// TFitResultPtr r = h->Fit(myFunc,opt);
4144/// Int_t fitStatus = r;
4145/// ~~~
4146///
4147/// The fitStatus is 0 if the fit is OK (i.e no error occurred).
4148/// The value of the fit status code is negative in case of an error not connected with the
4149/// minimization procedure, for example when a wrong function is used.
4150/// Otherwise the return value is the one returned from the minimization procedure.
4151/// When TMinuit (default case) or Minuit2 are used as minimizer the status returned is :
4152/// `fitStatus = migradResult + 10*minosResult + 100*hesseResult + 1000*improveResult`.
4153/// TMinuit will return 0 (for migrad, minos, hesse or improve) in case of success and 4 in
4154/// case of error (see the documentation of TMinuit::mnexcm). So for example, for an error
4155/// only in Minos but not in Migrad a fitStatus of 40 will be returned.
4156/// Minuit2 will return also 0 in case of success and different values in migrad minos or
4157/// hesse depending on the error. See in this case the documentation of
4158/// Minuit2Minimizer::Minimize for the migradResult, Minuit2Minimizer::GetMinosError for the
4159/// minosResult and Minuit2Minimizer::Hesse for the hesseResult.
4160/// If other minimizers are used see their specific documentation for the status code returned.
4161/// For example in the case of Fumili, for the status returned see TFumili::Minimize.
4162///
4163/// #### Excluding points
4164///
4165/// Use TF1::RejectPoint inside your fitting function to exclude points
4166/// within a certain range from the fit. Example:
4167///
4168/// ~~~ {.cpp}
4169/// Double_t fline(Double_t *x, Double_t *par)
4170/// {
4171/// if (x[0] > 2.5 && x[0] < 3.5) {
4172/// TF1::RejectPoint();
4173/// return 0;
4174/// }
4175/// return par[0] + par[1]*x[0];
4176/// }
4177///
4178/// void exclude() {
4179/// TF1 *f1 = new TF1("f1", "[0] +[1]*x +gaus(2)", 0, 5);
4180/// f1->SetParameters(6, -1,5, 3, 0.2);
4181/// TH1F *h = new TH1F("h", "background + signal", 100, 0, 5);
4182/// h->FillRandom("f1", 2000);
4183/// TF1 *fline = new TF1("fline", fline, 0, 5, 2);
4184/// fline->SetParameters(2, -1);
4185/// h->Fit("fline", "l");
4186/// }
4187/// ~~~
4188///
4189/// #### Warning when using the option "0"
4190///
4191/// When selecting the option "0", the fitted function is added to
4192/// the list of functions of the histogram, but it is not drawn.
4193/// You can undo what you disabled in the following way:
4194///
4195/// ~~~ {.cpp}
4196/// h.Fit("myFunction", "0"); // fit, store function but do not draw
4197/// h.Draw(); function is not drawn
4198/// const Int_t kNotDraw = 1<<9;
4199/// h.GetFunction("myFunction")->ResetBit(kNotDraw);
4200/// h.Draw(); // function is visible again
4201/// ~~~
4202///
4203/// #### Access to the Minimizer information during fitting
4204///
4205/// This function calls, the ROOT::Fit::FitObject function implemented in HFitImpl.cxx
4206/// which uses the ROOT::Fit::Fitter class. The Fitter class creates the objective function
4207/// (e.g. chi2 or likelihood) and uses an implementation of the Minimizer interface for minimizing
4208/// the function.
4209/// The default minimizer is Minuit (class TMinuitMinimizer which calls TMinuit).
4210/// The default can be set in the resource file in etc/system.rootrc. For example
4211///
4212/// ~~~ {.cpp}
4213/// Root.Fitter: Minuit2
4214/// ~~~
4215///
4216/// A different fitter can also be set via ROOT::Math::MinimizerOptions::SetDefaultMinimizer
4217/// (or TVirtualFitter::SetDefaultFitter).
4218/// For example ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");
4219/// will set the usage of the BFGS algorithm of the GSL multi-dimensional minimization
4220/// (implemented in libMathMore). ROOT::Math::MinimizerOptions can be used also to set other
4221/// default options, like maximum number of function calls, minimization tolerance or print
4222/// level. See the documentation of this class.
4223///
4224/// For fitting linear functions (containing the "++" sign" and polN functions,
4225/// the linear fitter is automatically initialized.
4226
4227TFitResultPtr TH1::Fit(TF1 *f1 ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
4228{
4229 // implementation of Fit method is in file hist/src/HFitImpl.cxx
4230 Foption_t fitOption;
4232
4233 // create range and minimizer options with default values
4234 ROOT::Fit::DataRange range(xxmin,xxmax);
4236
4237 // need to empty the buffer before
4238 // (t.b.d. do a ML unbinned fit with buffer data)
4239 if (fBuffer) BufferEmpty();
4240
4241 return ROOT::Fit::FitObject(this, f1 , fitOption , minOption, goption, range);
4242}
4243
4244////////////////////////////////////////////////////////////////////////////////
4245/// Display a panel with all histogram fit options.
4246///
4247/// See class TFitPanel for example
4248
4249void TH1::FitPanel()
4250{
4251 if (!gPad)
4252 gROOT->MakeDefCanvas();
4253
4254 if (!gPad) {
4255 Error("FitPanel", "Unable to create a default canvas");
4256 return;
4257 }
4258
4259
4260 // use plugin manager to create instance of TFitEditor
4261 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
4262 if (handler && handler->LoadPlugin() != -1) {
4263 if (handler->ExecPlugin(2, gPad, this) == 0)
4264 Error("FitPanel", "Unable to create the FitPanel");
4265 }
4266 else
4267 Error("FitPanel", "Unable to find the FitPanel plug-in");
4268}
4269
4270////////////////////////////////////////////////////////////////////////////////
4271/// Return an histogram containing the asymmetry of this histogram with h2,
4272/// where the asymmetry is defined as:
4273///
4274/// ~~~ {.cpp}
4275/// Asymmetry = (h1 - h2)/(h1 + h2) where h1 = this
4276/// ~~~
4277///
4278/// works for 1D, 2D, etc. histograms
4279/// c2 is an optional argument that gives a relative weight between the two
4280/// histograms, and dc2 is the error on this weight. This is useful, for example,
4281/// when forming an asymmetry between two histograms from 2 different data sets that
4282/// need to be normalized to each other in some way. The function calculates
4283/// the errors assuming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
4284///
4285/// example: assuming 'h1' and 'h2' are already filled
4286///
4287/// ~~~ {.cpp}
4288/// h3 = h1->GetAsymmetry(h2)
4289/// ~~~
4290///
4291/// then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
4292/// h1 and h2 are left intact.
4293///
4294/// Note that it is the user's responsibility to manage the created histogram.
4295/// The name of the returned histogram will be `Asymmetry_nameOfh1-nameOfh2`
4296///
4297/// code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
4298///
4299/// clone the histograms so top and bottom will have the
4300/// correct dimensions:
4301/// Sumw2 just makes sure the errors will be computed properly
4302/// when we form sums and ratios below.
4303
4305{
4306 TH1 *h1 = this;
4307 TString name = TString::Format("Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4308 TH1 *asym = (TH1*)Clone(name);
4309
4310 // set also the title
4311 TString title = TString::Format("(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4312 asym->SetTitle(title);
4313
4314 asym->Sumw2();
4315 Bool_t addStatus = TH1::AddDirectoryStatus();
4317 TH1 *top = (TH1*)asym->Clone();
4318 TH1 *bottom = (TH1*)asym->Clone();
4319 TH1::AddDirectory(addStatus);
4320
4321 // form the top and bottom of the asymmetry, and then divide:
4322 top->Add(h1,h2,1,-c2);
4323 bottom->Add(h1,h2,1,c2);
4324 asym->Divide(top,bottom);
4325
4326 Int_t xmax = asym->GetNbinsX();
4327 Int_t ymax = asym->GetNbinsY();
4328 Int_t zmax = asym->GetNbinsZ();
4329
4330 if (h1->fBuffer) h1->BufferEmpty(1);
4331 if (h2->fBuffer) h2->BufferEmpty(1);
4332 if (bottom->fBuffer) bottom->BufferEmpty(1);
4333
4334 // now loop over bins to calculate the correct errors
4335 // the reason this error calculation looks complex is because of c2
4336 for(Int_t i=1; i<= xmax; i++){
4337 for(Int_t j=1; j<= ymax; j++){
4338 for(Int_t k=1; k<= zmax; k++){
4339 Int_t bin = GetBin(i, j, k);
4340 // here some bin contents are written into variables to make the error
4341 // calculation a little more legible:
4343 Double_t b = h2->RetrieveBinContent(bin);
4344 Double_t bot = bottom->RetrieveBinContent(bin);
4345
4346 // make sure there are some events, if not, then the errors are set = 0
4347 // automatically.
4348 //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
4349 if(bot < 1e-6){}
4350 else{
4351 // computation of errors by Christos Leonidopoulos
4352 Double_t dasq = h1->GetBinErrorSqUnchecked(bin);
4353 Double_t dbsq = h2->GetBinErrorSqUnchecked(bin);
4354 Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4355 asym->SetBinError(i,j,k,error);
4356 }
4357 }
4358 }
4359 }
4360 delete top;
4361 delete bottom;
4362
4363 return asym;
4364}
4365
4366////////////////////////////////////////////////////////////////////////////////
4367/// Static function
4368/// return the default buffer size for automatic histograms
4369/// the parameter fgBufferSize may be changed via SetDefaultBufferSize
4370
4372{
4373 return fgBufferSize;
4374}
4375
4376////////////////////////////////////////////////////////////////////////////////
4377/// Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
4378/// see TH1::SetDefaultSumw2.
4379
4381{
4382 return fgDefaultSumw2;
4383}
4384
4385////////////////////////////////////////////////////////////////////////////////
4386/// Return the current number of entries.
4387
4389{
4390 if (fBuffer) {
4391 Int_t nentries = (Int_t) fBuffer[0];
4392 if (nentries > 0) return nentries;
4393 }
4394
4395 return fEntries;
4396}
4397
4398////////////////////////////////////////////////////////////////////////////////
4399/// Number of effective entries of the histogram.
4400///
4401/// \f[
4402/// neff = \frac{(\sum Weights )^2}{(\sum Weight^2 )}
4403/// \f]
4404///
4405/// In case of an unweighted histogram this number is equivalent to the
4406/// number of entries of the histogram.
4407/// For a weighted histogram, this number corresponds to the hypothetical number of unweighted entries
4408/// a histogram would need to have the same statistical power as this weighted histogram.
4409/// Note: The underflow/overflow are included if one has set the TH1::StatOverFlows flag
4410/// and if the statistics has been computed at filling time.
4411/// If a range is set in the histogram the number is computed from the given range.
4412
4414{
4415 Stat_t s[kNstat];
4416 this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
4417 return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4418}
4419
4420////////////////////////////////////////////////////////////////////////////////
4421/// Set highlight (enable/disable) mode for the histogram
4422/// by default highlight mode is disable
4423
4424void TH1::SetHighlight(Bool_t set)
4425{
4426 if (IsHighlight() == set) return;
4427 if (fDimension > 2) {
4428 Info("SetHighlight", "Supported only 1-D or 2-D histograms");
4429 return;
4430 }
4431
4432 if (!fPainter) {
4433 Info("SetHighlight", "Need to draw histogram first");
4434 return;
4435 }
4436 SetBit(kIsHighlight, set);
4438}
4439
4440////////////////////////////////////////////////////////////////////////////////
4441/// Redefines TObject::GetObjectInfo.
4442/// Displays the histogram info (bin number, contents, integral up to bin
4443/// corresponding to cursor position px,py
4444
4445char *TH1::GetObjectInfo(Int_t px, Int_t py) const
4446{
4447 return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
4448}
4449
4450////////////////////////////////////////////////////////////////////////////////
4451/// Return pointer to painter.
4452/// If painter does not exist, it is created
4453
4455{
4456 if (!fPainter) {
4457 TString opt = option;
4458 opt.ToLower();
4459 if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
4460 //try to create TGLHistPainter
4461 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
4462
4463 if (handler && handler->LoadPlugin() != -1)
4464 fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
4465 }
4466 }
4467
4469
4470 return fPainter;
4471}
4472
4473////////////////////////////////////////////////////////////////////////////////
4474/// Compute Quantiles for this histogram
4475/// Quantile x_q of a probability distribution Function F is defined as
4476///
4477/// ~~~ {.cpp}
4478/// F(x_q) = q with 0 <= q <= 1.
4479/// ~~~
4480///
4481/// For instance the median x_0.5 of a distribution is defined as that value
4482/// of the random variable for which the distribution function equals 0.5:
4483///
4484/// ~~~ {.cpp}
4485/// F(x_0.5) = Probability(x < x_0.5) = 0.5
4486/// ~~~
4487///
4488/// code from Eddy Offermann, Renaissance
4489///
4490/// \param[in] nprobSum maximum size of array q and size of array probSum (if given)
4491/// \param[in] probSum array of positions where quantiles will be computed.
4492/// - if probSum is null, probSum will be computed internally and will
4493/// have a size = number of bins + 1 in h. it will correspond to the
4494/// quantiles calculated at the lowest edge of the histogram (quantile=0) and
4495/// all the upper edges of the bins.
4496/// - if probSum is not null, it is assumed to contain at least nprobSum values.
4497/// \param[out] q array q filled with nq quantiles
4498/// \return value nq (<=nprobSum) with the number of quantiles computed
4499///
4500/// Note that the Integral of the histogram is automatically recomputed
4501/// if the number of entries is different of the number of entries when
4502/// the integral was computed last time. In case you do not use the Fill
4503/// functions to fill your histogram, but SetBinContent, you must call
4504/// TH1::ComputeIntegral before calling this function.
4505///
4506/// Getting quantiles q from two histograms and storing results in a TGraph,
4507/// a so-called QQ-plot
4508///
4509/// ~~~ {.cpp}
4510/// TGraph *gr = new TGraph(nprob);
4511/// h1->GetQuantiles(nprob,gr->GetX());
4512/// h2->GetQuantiles(nprob,gr->GetY());
4513/// gr->Draw("alp");
4514/// ~~~
4515///
4516/// Example:
4517///
4518/// ~~~ {.cpp}
4519/// void quantiles() {
4520/// // demo for quantiles
4521/// const Int_t nq = 20;
4522/// TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
4523/// h->FillRandom("gaus",5000);
4524///
4525/// Double_t xq[nq]; // position where to compute the quantiles in [0,1]
4526/// Double_t yq[nq]; // array to contain the quantiles
4527/// for (Int_t i=0;i<nq;i++) xq[i] = Float_t(i+1)/nq;
4528/// h->GetQuantiles(nq,yq,xq);
4529///
4530/// //show the original histogram in the top pad
4531/// TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
4532/// c1->Divide(1,2);
4533/// c1->cd(1);
4534/// h->Draw();
4535///
4536/// // show the quantiles in the bottom pad
4537/// c1->cd(2);
4538/// gPad->SetGrid();
4539/// TGraph *gr = new TGraph(nq,xq,yq);
4540/// gr->SetMarkerStyle(21);
4541/// gr->Draw("alp");
4542/// }
4543/// ~~~
4544
4545Int_t TH1::GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
4546{
4547 if (GetDimension() > 1) {
4548 Error("GetQuantiles","Only available for 1-d histograms");
4549 return 0;
4550 }
4551
4552 const Int_t nbins = GetXaxis()->GetNbins();
4553 if (!fIntegral) ComputeIntegral();
4554 if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4555
4556 Int_t i, ibin;
4557 Double_t *prob = (Double_t*)probSum;
4558 Int_t nq = nprobSum;
4559 if (probSum == 0) {
4560 nq = nbins+1;
4561 prob = new Double_t[nq];
4562 prob[0] = 0;
4563 for (i=1;i<nq;i++) {
4564 prob[i] = fIntegral[i]/fIntegral[nbins];
4565 }
4566 }
4567
4568 for (i = 0; i < nq; i++) {
4569 ibin = TMath::BinarySearch(nbins,fIntegral,prob[i]);
4570 while (ibin < nbins-1 && fIntegral[ibin+1] == prob[i]) {
4571 if (fIntegral[ibin+2] == prob[i]) ibin++;
4572 else break;
4573 }
4574 q[i] = GetBinLowEdge(ibin+1);
4575 const Double_t dint = fIntegral[ibin+1]-fIntegral[ibin];
4576 if (dint > 0) q[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4577 }
4578
4579 if (!probSum) delete [] prob;
4580 return nq;
4581}
4582
4583////////////////////////////////////////////////////////////////////////////////
4584/// Decode string choptin and fill fitOption structure.
4585
4586Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
4587{
4589 return 1;
4590}
4591
4592////////////////////////////////////////////////////////////////////////////////
4593/// Compute Initial values of parameters for a gaussian.
4594
4595void H1InitGaus()
4596{
4597 Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4598 Int_t bin;
4599 const Double_t sqrtpi = 2.506628;
4600
4601 // - Compute mean value and StdDev of the histogram in the given range
4603 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4604 Int_t hxfirst = hFitter->GetXfirst();
4605 Int_t hxlast = hFitter->GetXlast();
4606 Double_t valmax = curHist->GetBinContent(hxfirst);
4607 Double_t binwidx = curHist->GetBinWidth(hxfirst);
4608 allcha = sumx = sumx2 = 0;
4609 for (bin=hxfirst;bin<=hxlast;bin++) {
4610 x = curHist->GetBinCenter(bin);
4611 val = TMath::Abs(curHist->GetBinContent(bin));
4612 if (val > valmax) valmax = val;
4613 sumx += val*x;
4614 sumx2 += val*x*x;
4615 allcha += val;
4616 }
4617 if (allcha == 0) return;
4618 mean = sumx/allcha;
4619 stddev = sumx2/allcha - mean*mean;
4620 if (stddev > 0) stddev = TMath::Sqrt(stddev);
4621 else stddev = 0;
4622 if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4623 //if the distribution is really gaussian, the best approximation
4624 //is binwidx*allcha/(sqrtpi*stddev)
4625 //However, in case of non-gaussian tails, this underestimates
4626 //the normalisation constant. In this case the maximum value
4627 //is a better approximation.
4628 //We take the average of both quantities
4629 Double_t constant = 0.5*(valmax+binwidx*allcha/(sqrtpi*stddev));
4630
4631 //In case the mean value is outside the histo limits and
4632 //the StdDev is bigger than the range, we take
4633 // mean = center of bins
4634 // stddev = half range
4635 Double_t xmin = curHist->GetXaxis()->GetXmin();
4636 Double_t xmax = curHist->GetXaxis()->GetXmax();
4637 if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4638 mean = 0.5*(xmax+xmin);
4639 stddev = 0.5*(xmax-xmin);
4640 }
4641 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4642 f1->SetParameter(0,constant);
4643 f1->SetParameter(1,mean);
4644 f1->SetParameter(2,stddev);
4645 f1->SetParLimits(2,0,10*stddev);
4646}
4647
4648////////////////////////////////////////////////////////////////////////////////
4649/// Compute Initial values of parameters for an exponential.
4650
4651void H1InitExpo()
4652{
4653 Double_t constant, slope;
4654 Int_t ifail;
4656 Int_t hxfirst = hFitter->GetXfirst();
4657 Int_t hxlast = hFitter->GetXlast();
4658 Int_t nchanx = hxlast - hxfirst + 1;
4659
4660 H1LeastSquareLinearFit(-nchanx, constant, slope, ifail);
4661
4662 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4663 f1->SetParameter(0,constant);
4664 f1->SetParameter(1,slope);
4665
4666}
4667
4668////////////////////////////////////////////////////////////////////////////////
4669/// Compute Initial values of parameters for a polynom.
4670
4671void H1InitPolynom()
4672{
4673 Double_t fitpar[25];
4674
4676 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4677 Int_t hxfirst = hFitter->GetXfirst();
4678 Int_t hxlast = hFitter->GetXlast();
4679 Int_t nchanx = hxlast - hxfirst + 1;
4680 Int_t npar = f1->GetNpar();
4681
4682 if (nchanx <=1 || npar == 1) {
4683 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4684 fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4685 } else {
4686 H1LeastSquareFit( nchanx, npar, fitpar);
4687 }
4688 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4689}
4690
4691////////////////////////////////////////////////////////////////////////////////
4692/// Least squares lpolynomial fitting without weights.
4693///
4694/// \param[in] n number of points to fit
4695/// \param[in] m number of parameters
4696/// \param[in] a array of parameters
4697///
4698/// based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
4699/// (E.Keil. revised by B.Schorr, 23.10.1981.)
4700
4702{
4703 const Double_t zero = 0.;
4704 const Double_t one = 1.;
4705 const Int_t idim = 20;
4706
4707 Double_t b[400] /* was [20][20] */;
4708 Int_t i, k, l, ifail;
4709 Double_t power;
4710 Double_t da[20], xk, yk;
4711
4712 if (m <= 2) {
4713 H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4714 return;
4715 }
4716 if (m > idim || m > n) return;
4717 b[0] = Double_t(n);
4718 da[0] = zero;
4719 for (l = 2; l <= m; ++l) {
4720 b[l-1] = zero;
4721 b[m + l*20 - 21] = zero;
4722 da[l-1] = zero;
4723 }
4725 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4726 Int_t hxfirst = hFitter->GetXfirst();
4727 Int_t hxlast = hFitter->GetXlast();
4728 for (k = hxfirst; k <= hxlast; ++k) {
4729 xk = curHist->GetBinCenter(k);
4730 yk = curHist->GetBinContent(k);
4731 power = one;
4732 da[0] += yk;
4733 for (l = 2; l <= m; ++l) {
4734 power *= xk;
4735 b[l-1] += power;
4736 da[l-1] += power*yk;
4737 }
4738 for (l = 2; l <= m; ++l) {
4739 power *= xk;
4740 b[m + l*20 - 21] += power;
4741 }
4742 }
4743 for (i = 3; i <= m; ++i) {
4744 for (k = i; k <= m; ++k) {
4745 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4746 }
4747 }
4748 H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
4749
4750 for (i=0; i<m; ++i) a[i] = da[i];
4751
4752}
4753
4754////////////////////////////////////////////////////////////////////////////////
4755/// Least square linear fit without weights.
4756///
4757/// extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
4758/// (added to LSQ by B. Schorr, 15.02.1982.)
4759
4760void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
4761{
4762 Double_t xbar, ybar, x2bar;
4763 Int_t i, n;
4764 Double_t xybar;
4765 Double_t fn, xk, yk;
4766 Double_t det;
4767
4768 n = TMath::Abs(ndata);
4769 ifail = -2;
4770 xbar = ybar = x2bar = xybar = 0;
4772 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4773 Int_t hxfirst = hFitter->GetXfirst();
4774 Int_t hxlast = hFitter->GetXlast();
4775 for (i = hxfirst; i <= hxlast; ++i) {
4776 xk = curHist->GetBinCenter(i);
4777 yk = curHist->GetBinContent(i);
4778 if (ndata < 0) {
4779 if (yk <= 0) yk = 1e-9;
4780 yk = TMath::Log(yk);
4781 }
4782 xbar += xk;
4783 ybar += yk;
4784 x2bar += xk*xk;
4785 xybar += xk*yk;
4786 }
4787 fn = Double_t(n);
4788 det = fn*x2bar - xbar*xbar;
4789 ifail = -1;
4790 if (det <= 0) {
4791 a0 = ybar/fn;
4792 a1 = 0;
4793 return;
4794 }
4795 ifail = 0;
4796 a0 = (x2bar*ybar - xbar*xybar) / det;
4797 a1 = (fn*xybar - xbar*ybar) / det;
4798
4799}
4800
4801////////////////////////////////////////////////////////////////////////////////
4802/// Extracted from CERN Program library routine DSEQN.
4803///
4804/// Translated to C++ by Rene Brun
4805
4806void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b)
4807{
4808 Int_t a_dim1, a_offset, b_dim1, b_offset;
4809 Int_t nmjp1, i, j, l;
4810 Int_t im1, jp1, nm1, nmi;
4811 Double_t s1, s21, s22;
4812 const Double_t one = 1.;
4813
4814 /* Parameter adjustments */
4815 b_dim1 = idim;
4816 b_offset = b_dim1 + 1;
4817 b -= b_offset;
4818 a_dim1 = idim;
4819 a_offset = a_dim1 + 1;
4820 a -= a_offset;
4821
4822 if (idim < n) return;
4823
4824 ifail = 0;
4825 for (j = 1; j <= n; ++j) {
4826 if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
4827 a[j + j*a_dim1] = one / a[j + j*a_dim1];
4828 if (j == n) continue;
4829 jp1 = j + 1;
4830 for (l = jp1; l <= n; ++l) {
4831 a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4832 s1 = -a[l + (j+1)*a_dim1];
4833 for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4834 a[l + (j+1)*a_dim1] = -s1;
4835 }
4836 }
4837 if (k <= 0) return;
4838
4839 for (l = 1; l <= k; ++l) {
4840 b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
4841 }
4842 if (n == 1) return;
4843 for (l = 1; l <= k; ++l) {
4844 for (i = 2; i <= n; ++i) {
4845 im1 = i - 1;
4846 s21 = -b[i + l*b_dim1];
4847 for (j = 1; j <= im1; ++j) {
4848 s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
4849 }
4850 b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
4851 }
4852 nm1 = n - 1;
4853 for (i = 1; i <= nm1; ++i) {
4854 nmi = n - i;
4855 s22 = -b[nmi + l*b_dim1];
4856 for (j = 1; j <= i; ++j) {
4857 nmjp1 = n - j + 1;
4858 s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
4859 }
4860 b[nmi + l*b_dim1] = -s22;
4861 }
4862 }
4863}
4864
4865////////////////////////////////////////////////////////////////////////////////
4866/// Return Global bin number corresponding to binx,y,z.
4867///
4868/// 2-D and 3-D histograms are represented with a one dimensional
4869/// structure.
4870/// This has the advantage that all existing functions, such as
4871/// GetBinContent, GetBinError, GetBinFunction work for all dimensions.
4872///
4873/// In case of a TH1x, returns binx directly.
4874/// see TH1::GetBinXYZ for the inverse transformation.
4875///
4876/// Convention for numbering bins
4877///
4878/// For all histogram types: nbins, xlow, xup
4879///
4880/// - bin = 0; underflow bin
4881/// - bin = 1; first bin with low-edge xlow INCLUDED
4882/// - bin = nbins; last bin with upper-edge xup EXCLUDED
4883/// - bin = nbins+1; overflow bin
4884///
4885/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4886/// For example, assuming a 3-D histogram with binx,biny,binz, the function
4887///
4888/// ~~~ {.cpp}
4889/// Int_t bin = h->GetBin(binx,biny,binz);
4890/// ~~~
4891///
4892/// returns a global/linearized bin number. This global bin is useful
4893/// to access the bin information independently of the dimension.
4894
4895Int_t TH1::GetBin(Int_t binx, Int_t, Int_t) const
4896{
4897 Int_t ofx = fXaxis.GetNbins() + 1; // overflow bin
4898 if (binx < 0) binx = 0;
4899 if (binx > ofx) binx = ofx;
4900
4901 return binx;
4902}
4903
4904////////////////////////////////////////////////////////////////////////////////
4905/// Return binx, biny, binz corresponding to the global bin number globalbin
4906/// see TH1::GetBin function above
4907
4908void TH1::GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz) const
4909{
4910 Int_t nx = fXaxis.GetNbins()+2;
4911 Int_t ny = fYaxis.GetNbins()+2;
4912
4913 if (GetDimension() == 1) {
4914 binx = binglobal%nx;
4915 biny = 0;
4916 binz = 0;
4917 return;
4918 }
4919 if (GetDimension() == 2) {
4920 binx = binglobal%nx;
4921 biny = ((binglobal-binx)/nx)%ny;
4922 binz = 0;
4923 return;
4924 }
4925 if (GetDimension() == 3) {
4926 binx = binglobal%nx;
4927 biny = ((binglobal-binx)/nx)%ny;
4928 binz = ((binglobal-binx)/nx -biny)/ny;
4929 }
4930}
4931
4932////////////////////////////////////////////////////////////////////////////////
4933/// Return a random number distributed according the histogram bin contents.
4934/// This function checks if the bins integral exists. If not, the integral
4935/// is evaluated, normalized to one.
4936///
4937/// @param rng (optional) Random number generator pointer used (default is gRandom)
4938///
4939/// The integral is automatically recomputed if the number of entries
4940/// is not the same then when the integral was computed.
4941/// NB Only valid for 1-d histograms. Use GetRandom2 or 3 otherwise.
4942/// If the histogram has a bin with negative content a NaN is returned
4943
4944Double_t TH1::GetRandom(TRandom * rng) const
4945{
4946 if (fDimension > 1) {
4947 Error("GetRandom","Function only valid for 1-d histograms");
4948 return 0;
4949 }
4950 Int_t nbinsx = GetNbinsX();
4951 Double_t integral = 0;
4952 // compute integral checking that all bins have positive content (see ROOT-5894)
4953 if (fIntegral) {
4954 if (fIntegral[nbinsx+1] != fEntries) integral = ((TH1*)this)->ComputeIntegral(true);
4955 else integral = fIntegral[nbinsx];
4956 } else {
4957 integral = ((TH1*)this)->ComputeIntegral(true);
4958 }
4959 if (integral == 0) return 0;
4960 // return a NaN in case some bins have negative content
4961 if (integral == TMath::QuietNaN() ) return TMath::QuietNaN();
4962
4963 Double_t r1 = (rng) ? rng->Rndm() : gRandom->Rndm();
4964 Int_t ibin = TMath::BinarySearch(nbinsx,fIntegral,r1);
4965 Double_t x = GetBinLowEdge(ibin+1);
4966 if (r1 > fIntegral[ibin]) x +=
4967 GetBinWidth(ibin+1)*(r1-fIntegral[ibin])/(fIntegral[ibin+1] - fIntegral[ibin]);
4968 return x;
4969}
4970
4971////////////////////////////////////////////////////////////////////////////////
4972/// Return content of bin number bin.
4973///
4974/// Implemented in TH1C,S,F,D
4975///
4976/// Convention for numbering bins
4977///
4978/// For all histogram types: nbins, xlow, xup
4979///
4980/// - bin = 0; underflow bin
4981/// - bin = 1; first bin with low-edge xlow INCLUDED
4982/// - bin = nbins; last bin with upper-edge xup EXCLUDED
4983/// - bin = nbins+1; overflow bin
4984///
4985/// In case of 2-D or 3-D histograms, a "global bin" number is defined.
4986/// For example, assuming a 3-D histogram with binx,biny,binz, the function
4987///
4988/// ~~~ {.cpp}
4989/// Int_t bin = h->GetBin(binx,biny,binz);
4990/// ~~~
4991///
4992/// returns a global/linearized bin number. This global bin is useful
4993/// to access the bin information independently of the dimension.
4994
4996{
4997 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
4998 if (bin < 0) bin = 0;
4999 if (bin >= fNcells) bin = fNcells-1;
5000
5001 return RetrieveBinContent(bin);
5002}
5003
5004////////////////////////////////////////////////////////////////////////////////
5005/// Compute first binx in the range [firstx,lastx] for which
5006/// diff = abs(bin_content-c) <= maxdiff
5007///
5008/// In case several bins in the specified range with diff=0 are found
5009/// the first bin found is returned in binx.
5010/// In case several bins in the specified range satisfy diff <=maxdiff
5011/// the bin with the smallest difference is returned in binx.
5012/// In all cases the function returns the smallest difference.
5013///
5014/// NOTE1: if firstx <= 0, firstx is set to bin 1
5015/// if (lastx < firstx then firstx is set to the number of bins
5016/// ie if firstx=0 and lastx=0 (default) the search is on all bins.
5017///
5018/// NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
5019
5020Double_t TH1::GetBinWithContent(Double_t c, Int_t &binx, Int_t firstx, Int_t lastx,Double_t maxdiff) const
5021{
5022 if (fDimension > 1) {
5023 binx = 0;
5024 Error("GetBinWithContent","function is only valid for 1-D histograms");
5025 return 0;
5026 }
5027
5028 if (fBuffer) ((TH1*)this)->BufferEmpty();
5029
5030 if (firstx <= 0) firstx = 1;
5031 if (lastx < firstx) lastx = fXaxis.GetNbins();
5032 Int_t binminx = 0;
5033 Double_t diff, curmax = 1.e240;
5034 for (Int_t i=firstx;i<=lastx;i++) {
5035 diff = TMath::Abs(RetrieveBinContent(i)-c);
5036 if (diff <= 0) {binx = i; return diff;}
5037 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
5038 }
5039 binx = binminx;
5040 return curmax;
5041}
5042
5043////////////////////////////////////////////////////////////////////////////////
5044/// Given a point x, approximates the value via linear interpolation
5045/// based on the two nearest bin centers
5046///
5047/// Andy Mastbaum 10/21/08
5048
5050{
5051 if (fBuffer) ((TH1*)this)->BufferEmpty();
5052
5053 Int_t xbin = fXaxis.FindFixBin(x);
5054 Double_t x0,x1,y0,y1;
5055
5056 if(x<=GetBinCenter(1)) {
5057 return RetrieveBinContent(1);
5058 } else if(x>=GetBinCenter(GetNbinsX())) {
5059 return RetrieveBinContent(GetNbinsX());
5060 } else {
5061 if(x<=GetBinCenter(xbin)) {
5062 y0 = RetrieveBinContent(xbin-1);
5063 x0 = GetBinCenter(xbin-1);
5064 y1 = RetrieveBinContent(xbin);
5065 x1 = GetBinCenter(xbin);
5066 } else {
5067 y0 = RetrieveBinContent(xbin);
5068 x0 = GetBinCenter(xbin);
5069 y1 = RetrieveBinContent(xbin+1);
5070 x1 = GetBinCenter(xbin+1);
5071 }
5072 return y0 + (x-x0)*((y1-y0)/(x1-x0));
5073 }
5074}
5075
5076////////////////////////////////////////////////////////////////////////////////
5077/// 2d Interpolation. Not yet implemented.
5078
5080{
5081 Error("Interpolate","This function must be called with 1 argument for a TH1");
5082 return 0;
5083}
5084
5085////////////////////////////////////////////////////////////////////////////////
5086/// 3d Interpolation. Not yet implemented.
5087
5089{
5090 Error("Interpolate","This function must be called with 1 argument for a TH1");
5091 return 0;
5092}
5093
5094///////////////////////////////////////////////////////////////////////////////
5095/// Check if an histogram is empty
5096/// (this a protected method used mainly by TH1Merger )
5097
5098Bool_t TH1::IsEmpty() const
5099{
5100 // if fTsumw or fentries are not zero histogram is not empty
5101 // need to use GetEntries() instead of fEntries in case of bugger histograms
5102 // so we will flash the buffer
5103 if (fTsumw != 0) return kFALSE;
5104 if (GetEntries() != 0) return kFALSE;
5105 // case fTSumw == 0 amd entries are also zero
5106 // this should not really happening, but if one sets content by hand
5107 // it can happen. a call to ResetStats() should be done in such cases
5108 double sumw = 0;
5109 for (int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
5110 return (sumw != 0) ? kFALSE : kTRUE;
5111}
5112
5113////////////////////////////////////////////////////////////////////////////////
5114/// Return true if the bin is overflow.
5115
5116Bool_t TH1::IsBinOverflow(Int_t bin, Int_t iaxis) const
5117{
5118 Int_t binx, biny, binz;
5119 GetBinXYZ(bin, binx, biny, binz);
5120
5121 if (iaxis == 0) {
5122 if ( fDimension == 1 )
5123 return binx >= GetNbinsX() + 1;
5124 if ( fDimension == 2 )
5125 return (binx >= GetNbinsX() + 1) ||
5126 (biny >= GetNbinsY() + 1);
5127 if ( fDimension == 3 )
5128 return (binx >= GetNbinsX() + 1) ||
5129 (biny >= GetNbinsY() + 1) ||
5130 (binz >= GetNbinsZ() + 1);
5131 return kFALSE;
5132 }
5133 if (iaxis == 1)
5134 return binx >= GetNbinsX() + 1;
5135 if (iaxis == 2)
5136 return biny >= GetNbinsY() + 1;
5137 if (iaxis == 3)
5138 return binz >= GetNbinsZ() + 1;
5139
5140 Error("IsBinOverflow","Invalid axis value");
5141 return kFALSE;
5142}
5143
5144////////////////////////////////////////////////////////////////////////////////
5145/// Return true if the bin is underflow.
5146/// If iaxis = 0 make OR with all axes otherwise check only for the given axis
5147
5148Bool_t TH1::IsBinUnderflow(Int_t bin, Int_t iaxis) const
5149{
5150 Int_t binx, biny, binz;
5151 GetBinXYZ(bin, binx, biny, binz);
5152
5153 if (iaxis == 0) {
5154 if ( fDimension == 1 )
5155 return (binx <= 0);
5156 else if ( fDimension == 2 )
5157 return (binx <= 0 || biny <= 0);
5158 else if ( fDimension == 3 )
5159 return (binx <= 0 || biny <= 0 || binz <= 0);
5160 else
5161 return kFALSE;
5162 }
5163 if (iaxis == 1)
5164 return (binx <= 0);
5165 if (iaxis == 2)
5166 return (biny <= 0);
5167 if (iaxis == 3)
5168 return (binz <= 0);
5169
5170 Error("IsBinUnderflow","Invalid axis value");
5171 return kFALSE;
5172}
5173
5174////////////////////////////////////////////////////////////////////////////////
5175/// Reduce the number of bins for the axis passed in the option to the number of bins having a label.
5176/// The method will remove only the extra bins existing after the last "labeled" bin.
5177/// Note that if there are "un-labeled" bins present between "labeled" bins they will not be removed
5178
5180{
5181 Int_t iaxis = AxisChoice(ax);
5182 TAxis *axis = 0;
5183 if (iaxis == 1) axis = GetXaxis();
5184 if (iaxis == 2) axis = GetYaxis();
5185 if (iaxis == 3) axis = GetZaxis();
5186 if (!axis) {
5187 Error("LabelsDeflate","Invalid axis option %s",ax);
5188 return;
5189 }
5190 if (!axis->GetLabels()) return;
5191
5192 // find bin with last labels
5193 // bin number is object ID in list of labels
5194 // therefore max bin number is number of bins of the deflated histograms
5195 TIter next(axis->GetLabels());
5196 TObject *obj;
5197 Int_t nbins = 0;
5198 while ((obj = next())) {
5199 Int_t ibin = obj->GetUniqueID();
5200 if (ibin > nbins) nbins = ibin;
5201 }
5202 if (nbins < 1) nbins = 1;
5203
5204 // Do nothing in case it was the last bin
5205 if (nbins==axis->GetNbins()) return;
5206
5207 TH1 *hold = (TH1*)IsA()->New();
5208 R__ASSERT(hold);
5209 hold->SetDirectory(0);
5210 Copy(*hold);
5211
5212 Bool_t timedisp = axis->GetTimeDisplay();
5213 Double_t xmin = axis->GetXmin();
5214 Double_t xmax = axis->GetBinUpEdge(nbins);
5215 if (xmax <= xmin) xmax = xmin +nbins;
5216 axis->SetRange(0,0);
5217 axis->Set(nbins,xmin,xmax);
5218 SetBinsLength(-1); // reset the number of cells
5219 Int_t errors = fSumw2.fN;
5220 if (errors) fSumw2.Set(fNcells);
5221 axis->SetTimeDisplay(timedisp);
5222 // reset histogram content
5223 Reset("ICE");
5224
5225 //now loop on all bins and refill
5226 // NOTE that if the bins without labels have content
5227 // it will be put in the underflow/overflow.
5228 // For this reason we use AddBinContent method
5229 Double_t oldEntries = fEntries;
5230 Int_t bin,binx,biny,binz;
5231 for (bin=0; bin < hold->fNcells; ++bin) {
5232 hold->GetBinXYZ(bin,binx,biny,binz);
5233 Int_t ibin = GetBin(binx,biny,binz);
5234 Double_t cu = hold->RetrieveBinContent(bin);
5235 AddBinContent(ibin,cu);
5236 if (errors) {
5237 fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5238 }
5239 }
5240 fEntries = oldEntries;
5241 delete hold;
5242}
5243
5244////////////////////////////////////////////////////////////////////////////////
5245/// Double the number of bins for axis.
5246/// Refill histogram
5247/// This function is called by TAxis::FindBin(const char *label)
5248
5250{
5251 Int_t iaxis = AxisChoice(ax);
5252 TAxis *axis = 0;
5253 if (iaxis == 1) axis = GetXaxis();
5254 if (iaxis == 2) axis = GetYaxis();
5255 if (iaxis == 3) axis = GetZaxis();
5256 if (!axis) return;
5257
5258 TH1 *hold = (TH1*)IsA()->New();;
5259 hold->SetDirectory(0);
5260 Copy(*hold);
5261
5262 Bool_t timedisp = axis->GetTimeDisplay();
5263 Int_t nbins = axis->GetNbins();
5264 Double_t xmin = axis->GetXmin();
5265 Double_t xmax = axis->GetXmax();
5266 xmax = xmin + 2*(xmax-xmin);
5267 axis->SetRange(0,0);
5268 // double the bins and recompute ncells
5269 axis->Set(2*nbins,xmin,xmax);
5270 SetBinsLength(-1);
5271 Int_t errors = fSumw2.fN;
5272 if (errors) fSumw2.Set(fNcells);
5273 axis->SetTimeDisplay(timedisp);
5274
5275 Reset("ICE"); // reset content and error
5276
5277 //now loop on all bins and refill
5278 Double_t oldEntries = fEntries;
5279 Int_t bin,ibin,binx,biny,binz;
5280 for (ibin =0; ibin < hold->fNcells; ibin++) {
5281 // get the binx,y,z values . The x-y-z (axis) bin values will stay the same between new-old after the expanding
5282 hold->GetBinXYZ(ibin,binx,biny,binz);
5283 bin = GetBin(binx,biny,binz);
5284
5285 // underflow and overflow will be cleaned up because their meaning has been altered
5286 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5287 continue;
5288 }
5289 else {
5290 AddBinContent(bin, hold->RetrieveBinContent(ibin));
5291 if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5292 }
5293 }
5294 fEntries = oldEntries;
5295 delete hold;
5296}
5297
5298////////////////////////////////////////////////////////////////////////////////
5299/// Sort bins with labels or set option(s) to draw axis with labels
5300/// \param[in] option
5301/// - "a" sort by alphabetic order
5302/// - ">" sort by decreasing values
5303/// - "<" sort by increasing values
5304/// - "h" draw labels horizontal
5305/// - "v" draw labels vertical
5306/// - "u" draw labels up (end of label right adjusted)
5307/// - "d" draw labels down (start of label left adjusted)
5308///
5309/// In case not all bins have labels sorting will work only in the case
5310/// the first `n` consecutive bins have all labels and sorting will be performed on
5311/// those label bins.
5312///
5313/// \param[in] ax axis
5314
5315void TH1::LabelsOption(Option_t *option, Option_t *ax)
5316{
5317 Int_t iaxis = AxisChoice(ax);
5318 TAxis *axis = 0;
5319 if (iaxis == 1)
5320 axis = GetXaxis();
5321 if (iaxis == 2)
5322 axis = GetYaxis();
5323 if (iaxis == 3)
5324 axis = GetZaxis();
5325 if (!axis)
5326 return;
5327 THashList *labels = axis->GetLabels();
5328 if (!labels) {
5329 Warning("LabelsOption", "Axis %s has no labels!",axis->GetName());
5330 return;
5331 }
5332 TString opt = option;
5333 opt.ToLower();
5334 Int_t iopt = -1;
5335 if (opt.Contains("h")) {
5340 iopt = 0;
5341 }
5342 if (opt.Contains("v")) {
5347 iopt = 1;
5348 }
5349 if (opt.Contains("u")) {
5350 axis->SetBit(TAxis::kLabelsUp);
5354 iopt = 2;
5355 }
5356 if (opt.Contains("d")) {
5361 iopt = 3;
5362 }
5363 Int_t sort = -1;
5364 if (opt.Contains("a"))
5365 sort = 0;
5366 if (opt.Contains(">"))
5367 sort = 1;
5368 if (opt.Contains("<"))
5369 sort = 2;
5370 if (sort < 0) {
5371 if (iopt < 0)
5372 Error("LabelsOption", "%s is an invalid label placement option!",opt.Data());
5373 return;
5374 }
5375
5376 // Code works only if first n bins have labels if we uncomment following line
5377 // but we don't want to support this special case
5378 // Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5379
5380 // support only cases where each bin has a labels (should be when axis is alphanumeric)
5381 Int_t n = labels->GetSize();
5382 if (n != axis->GetNbins()) {
5383 // check if labels are all consecutive and starts from the first bin
5384 // in that case the current code will work fine
5385 Int_t firstLabelBin = axis->GetNbins()+1;
5386 Int_t lastLabelBin = -1;
5387 for (Int_t i = 0; i < n; ++i) {
5388 Int_t bin = labels->At(i)->GetUniqueID();
5389 if (bin < firstLabelBin) firstLabelBin = bin;
5390 if (bin > lastLabelBin) lastLabelBin = bin;
5391 }
5392 if (firstLabelBin != 1 || lastLabelBin-firstLabelBin +1 != n) {
5393 Error("LabelsOption", "%s of Histogram %s contains bins without labels. Sorting will not work correctly - return",
5394 axis->GetName(), GetName());
5395 return;
5396 }
5397 // case where label bins are consecutive starting from first bin will work
5398 // calling before a TH1::LabelsDeflate() will avoid this error message
5399 Warning("LabelsOption", "axis %s of Histogram %s has extra following bins without labels. Sorting will work only for first label bins",
5400 axis->GetName(), GetName());
5401 }
5402 std::vector<Int_t> a(n);
5403 std::vector<Int_t> b(n);
5404
5405
5406 Int_t i, j, k;
5407 std::vector<Double_t> cont;
5408 std::vector<Double_t> errors2;
5409 THashList *labold = new THashList(labels->GetSize(), 1);
5410 TIter nextold(labels);
5411 TObject *obj = nullptr;
5412 labold->AddAll(labels);
5413 labels->Clear();
5414
5415 // delete buffer if it is there since bins will be reordered.
5416 if (fBuffer)
5417 BufferEmpty(1);
5418
5419 if (sort > 0) {
5420 //---sort by values of bins
5421 if (GetDimension() == 1) {
5422 cont.resize(n);
5423 if (fSumw2.fN)
5424 errors2.resize(n);
5425 for (i = 0; i < n; i++) {
5426 cont[i] = RetrieveBinContent(i + 1);
5427 if (!errors2.empty())
5428 errors2[i] = GetBinErrorSqUnchecked(i + 1);
5429 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5430 a[i] = i;
5431 }
5432 if (sort == 1)
5433 TMath::Sort(n, cont.data(), a.data(), kTRUE); // sort by decreasing values
5434 else
5435 TMath::Sort(n, cont.data(), a.data(), kFALSE); // sort by increasing values
5436 for (i = 0; i < n; i++) {
5437 // use UpdateBinCOntent to not screw up histogram entries
5438 UpdateBinContent(i + 1, cont[b[a[i]] - 1]); // b[a[i]] returns bin number. .we need to subtract 1
5439 if (gDebug)
5440 Info("LabelsOption","setting bin %d value %f from bin %d label %s at pos %d ",
5441 i+1,cont[b[a[i]] - 1],b[a[i]],labold->At(a[i])->GetName(),a[i]);
5442 if (!errors2.empty())
5443 fSumw2.fArray[i + 1] = errors2[b[a[i]] - 1];
5444 }
5445 for (i = 0; i < n; i++) {
5446 obj = labold->At(a[i]);
5447 labels->Add(obj);
5448 obj->SetUniqueID(i + 1);
5449 }
5450 } else if (GetDimension() == 2) {
5451 std::vector<Double_t> pcont(n + 2);
5452 Int_t nx = fXaxis.GetNbins() + 2;
5453 Int_t ny = fYaxis.GetNbins() + 2;
5454 cont.resize((nx + 2) * (ny + 2));
5455 if (fSumw2.fN)
5456 errors2.resize((nx + 2) * (ny + 2));
5457 for (i = 0; i < nx; i++) {
5458 for (j = 0; j < ny; j++) {
5459 Int_t bin = GetBin(i,j);
5460 cont[i + nx * j] = RetrieveBinContent(bin);
5461 if (!errors2.empty())
5462 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5463 if (axis == GetXaxis())
5464 k = i - 1;
5465 else
5466 k = j - 1;
5467 if (k >= 0 && k < n) { // we consider underflow/overflows in y for ordering the bins
5468 pcont[k] += cont[i + nx * j];
5469 a[k] = k;
5470 }
5471 }
5472 }
5473 if (sort == 1)
5474 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5475 else
5476 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5477 for (i = 0; i < n; i++) {
5478 // iterate on old label list to find corresponding bin match
5479 TIter next(labold);
5480 UInt_t bin = a[i] + 1;
5481 while ((obj = next())) {
5482 if (obj->GetUniqueID() == (UInt_t)bin)
5483 break;
5484 else
5485 obj = nullptr;
5486 }
5487 if (!obj) {
5488 // this should not really happen
5489 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5490 return;
5491 }
5492
5493 labels->Add(obj);
5494 if (gDebug)
5495 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from order " << a[i] << " bin "
5496 << b[a[i]] << "content " << pcont[a[i]] << std::endl;
5497 }
5498 // need to set here new ordered labels - otherwise loop before does not work since labold and labels list
5499 // contain same objects
5500 for (i = 0; i < n; i++) {
5501 labels->At(i)->SetUniqueID(i + 1);
5502 }
5503 // set now the bin contents
5504 if (axis == GetXaxis()) {
5505 for (i = 0; i < n; i++) {
5506 Int_t ix = a[i] + 1;
5507 for (j = 0; j < ny; j++) {
5508 Int_t bin = GetBin(i + 1, j);
5509 UpdateBinContent(bin, cont[ix + nx * j]);
5510 if (!errors2.empty())
5511 fSumw2.fArray[bin] = errors2[ix + nx * j];
5512 }
5513 }
5514 } else {
5515 // using y axis
5516 for (i = 0; i < nx; i++) {
5517 for (j = 0; j < n; j++) {
5518 Int_t iy = a[j] + 1;
5519 Int_t bin = GetBin(i, j + 1);
5520 UpdateBinContent(bin, cont[i + nx * iy]);
5521 if (!errors2.empty())
5522 fSumw2.fArray[bin] = errors2[i + nx * iy];
5523 }
5524 }
5525 }
5526 } else {
5527 // sorting histograms: 3D case
5528 std::vector<Double_t> pcont(n + 2);
5529 Int_t nx = fXaxis.GetNbins() + 2;
5530 Int_t ny = fYaxis.GetNbins() + 2;
5531 Int_t nz = fZaxis.GetNbins() + 2;
5532 Int_t l = 0;
5533 cont.resize((nx + 2) * (ny + 2) * (nz + 2));
5534 if (fSumw2.fN)
5535 errors2.resize((nx + 2) * (ny + 2) * (nz + 2));
5536 for (i = 0; i < nx; i++) {
5537 for (j = 0; j < ny; j++) {
5538 for (k = 0; k < nz; k++) {
5539 Int_t bin = GetBin(i,j,k);
5541 if (axis == GetXaxis())
5542 l = i - 1;
5543 else if (axis == GetYaxis())
5544 l = j - 1;
5545 else
5546 l = k - 1;
5547 if (l >= 0 && l < n) { // we consider underflow/overflows in y for ordering the bins
5548 pcont[l] += c;
5549 a[l] = l;
5550 }
5551 cont[i + nx * (j + ny * k)] = c;
5552 if (!errors2.empty())
5553 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5554 }
5555 }
5556 }
5557 if (sort == 1)
5558 TMath::Sort(n, pcont.data(), a.data(), kTRUE); // sort by decreasing values
5559 else
5560 TMath::Sort(n, pcont.data(), a.data(), kFALSE); // sort by increasing values
5561 for (i = 0; i < n; i++) {
5562 // iterate on the old label list to find corresponding bin match
5563 TIter next(labold);
5564 UInt_t bin = a[i] + 1;
5565 obj = nullptr;
5566 while ((obj = next())) {
5567 if (obj->GetUniqueID() == (UInt_t)bin) {
5568 break;
5569 }
5570 else
5571 obj = nullptr;
5572 }
5573 if (!obj) {
5574 R__ASSERT("LabelsOption - No corresponding bin found when ordering labels");
5575 return;
5576 }
5577 labels->Add(obj);
5578 if (gDebug)
5579 std::cout << " set label " << obj->GetName() << " to bin " << i + 1 << " from bin " << a[i] << "content "
5580 << pcont[a[i]] << std::endl;
5581 }
5582
5583 // need to set here new ordered labels - otherwise loop before does not work since labold and llabels list
5584 // contain same objects
5585 for (i = 0; i < n; i++) {
5586 labels->At(i)->SetUniqueID(i + 1);
5587 }
5588 // set now the bin contents
5589 if (axis == GetXaxis()) {
5590 for (i = 0; i < n; i++) {
5591 Int_t ix = a[i] + 1;
5592 for (j = 0; j < ny; j++) {
5593 for (k = 0; k < nz; k++) {
5594 Int_t bin = GetBin(i + 1, j, k);
5595 UpdateBinContent(bin, cont[ix + nx * (j + ny * k)]);
5596 if (!errors2.empty())
5597 fSumw2.fArray[bin] = errors2[ix + nx * (j + ny * k)];
5598 }
5599 }
5600 }
5601 } else if (axis == GetYaxis()) {
5602 // using y axis
5603 for (i = 0; i < nx; i++) {
5604 for (j = 0; j < n; j++) {
5605 Int_t iy = a[j] + 1;
5606 for (k = 0; k < nz; k++) {
5607 Int_t bin = GetBin(i, j + 1, k);
5608 UpdateBinContent(bin, cont[i + nx * (iy + ny * k)]);
5609 if (!errors2.empty())
5610 fSumw2.fArray[bin] = errors2[i + nx * (iy + ny * k)];
5611 }
5612 }
5613 }
5614 } else {
5615 // using z axis
5616 for (i = 0; i < nx; i++) {
5617 for (j = 0; j < ny; j++) {
5618 for (k = 0; k < n; k++) {
5619 Int_t iz = a[k] + 1;
5620 Int_t bin = GetBin(i, j , k +1);
5621 UpdateBinContent(bin, cont[i + nx * (j + ny * iz)]);
5622 if (!errors2.empty())
5623 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * iz)];
5624 }
5625 }
5626 }
5627 }
5628 }
5629 } else {
5630 //---alphabetic sort
5631 // sort labels using vector of strings and TMath::Sort
5632 // I need to array because labels order in list is not necessary that of the bins
5633 std::vector<std::string> vecLabels(n);
5634 for (i = 0; i < n; i++) {
5635 vecLabels[i] = labold->At(i)->GetName();
5636 b[i] = labold->At(i)->GetUniqueID(); // this is the bin corresponding to the label
5637 a[i] = i;
5638 }
5639 // sort in ascending order for strings
5640 TMath::Sort(n, vecLabels.data(), a.data(), kFALSE);
5641 // set the new labels
5642 for (i = 0; i < n; i++) {
5643 TObject *labelObj = labold->At(a[i]);
5644 labels->Add(labold->At(a[i]));
5645 // set the corresponding bin. NB bin starts from 1
5646 labelObj->SetUniqueID(i + 1);
5647 if (gDebug)
5648 std::cout << "bin " << i + 1 << " setting new labels for axis " << labold->At(a[i])->GetName() << " from "
5649 << b[a[i]] << std::endl;
5650 }
5651
5652 if (GetDimension() == 1) {
5653 cont.resize(n + 2);
5654 if (fSumw2.fN)
5655 errors2.resize(n + 2);
5656 for (i = 0; i < n; i++) {
5657 cont[i] = RetrieveBinContent(b[a[i]]);
5658 if (!errors2.empty())
5659 errors2[i] = GetBinErrorSqUnchecked(b[a[i]]);
5660 }
5661 for (i = 0; i < n; i++) {
5662 UpdateBinContent(i + 1, cont[i]);
5663 if (!errors2.empty())
5664 fSumw2.fArray[i+1] = errors2[i];
5665 }
5666 } else if (GetDimension() == 2) {
5667 Int_t nx = fXaxis.GetNbins() + 2;
5668 Int_t ny = fYaxis.GetNbins() + 2;
5669 cont.resize(nx * ny);
5670 if (fSumw2.fN)
5671 errors2.resize(nx * ny);
5672 // copy old bin contents and then set to new ordered bins
5673 // N.B. bin in histograms starts from 1, but in y we consider under/overflows
5674 for (i = 0; i < nx; i++) {
5675 for (j = 0; j < ny; j++) { // ny is nbins+2
5676 Int_t bin = GetBin(i, j);
5677 cont[i + nx * j] = RetrieveBinContent(bin);
5678 if (!errors2.empty())
5679 errors2[i + nx * j] = GetBinErrorSqUnchecked(bin);
5680 }
5681 }
5682 if (axis == GetXaxis()) {
5683 for (i = 0; i < n; i++) {
5684 for (j = 0; j < ny; j++) {
5685 Int_t bin = GetBin(i + 1 , j);
5686 UpdateBinContent(bin, cont[b[a[i]] + nx * j]);
5687 if (!errors2.empty())
5688 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * j];
5689 }
5690 }
5691 } else {
5692 for (i = 0; i < nx; i++) {
5693 for (j = 0; j < n; j++) {
5694 Int_t bin = GetBin(i, j + 1);
5695 UpdateBinContent(bin, cont[i + nx * b[a[j]]]);
5696 if (!errors2.empty())
5697 fSumw2.fArray[bin] = errors2[i + nx * b[a[j]]];
5698 }
5699 }
5700 }
5701 } else {
5702 // case of 3D (needs to be tested)
5703 Int_t nx = fXaxis.GetNbins() + 2;
5704 Int_t ny = fYaxis.GetNbins() + 2;
5705 Int_t nz = fZaxis.GetNbins() + 2;
5706 cont.resize(nx * ny * nz);
5707 if (fSumw2.fN)
5708 errors2.resize(nx * ny * nz);
5709 for (i = 0; i < nx; i++) {
5710 for (j = 0; j < ny; j++) {
5711 for (k = 0; k < nz; k++) {
5712 Int_t bin = GetBin(i, j, k);
5713 cont[i + nx * (j + ny * k)] = RetrieveBinContent(bin);
5714 if (!errors2.empty())
5715 errors2[i + nx * (j + ny * k)] = GetBinErrorSqUnchecked(bin);
5716 }
5717 }
5718 }
5719 if (axis == GetXaxis()) {
5720 // labels on x axis
5721 for (i = 0; i < n; i++) { // for x we loop only on bins with the labels
5722 for (j = 0; j < ny; j++) {
5723 for (k = 0; k < nz; k++) {
5724 Int_t bin = GetBin(i + 1, j, k);
5725 UpdateBinContent(bin, cont[b[a[i]] + nx * (j + ny * k)]);
5726 if (!errors2.empty())
5727 fSumw2.fArray[bin] = errors2[b[a[i]] + nx * (j + ny * k)];
5728 }
5729 }
5730 }
5731 } else if (axis == GetYaxis()) {
5732 // labels on y axis
5733 for (i = 0; i < nx; i++) {
5734 for (j = 0; j < n; j++) {
5735 for (k = 0; k < nz; k++) {
5736 Int_t bin = GetBin(i, j+1, k);
5737 UpdateBinContent(bin, cont[i + nx * (b[a[j]] + ny * k)]);
5738 if (!errors2.empty())
5739 fSumw2.fArray[bin] = errors2[i + nx * (b[a[j]] + ny * k)];
5740 }
5741 }
5742 }
5743 } else {
5744 // labels on z axis
5745 for (i = 0; i < nx; i++) {
5746 for (j = 0; j < ny; j++) {
5747 for (k = 0; k < n; k++) {
5748 Int_t bin = GetBin(i, j, k+1);
5749 UpdateBinContent(bin, cont[i + nx * (j + ny * b[a[k]])]);
5750 if (!errors2.empty())
5751 fSumw2.fArray[bin] = errors2[i + nx * (j + ny * b[a[k]])];
5752 }
5753 }
5754 }
5755 }
5756 }
5757 }
5758 // need to set to zero the statistics if axis has been sorted
5759 // see for example TH3::PutStats for definition of s vector
5760 bool labelsAreSorted = kFALSE;
5761 for (i = 0; i < n; ++i) {
5762 if (a[i] != i) {
5763 labelsAreSorted = kTRUE;
5764 break;
5765 }
5766 }
5767 if (labelsAreSorted) {
5768 double s[TH1::kNstat];
5769 GetStats(s);
5770 if (iaxis == 1) {
5771 s[2] = 0; // fTsumwx
5772 s[3] = 0; // fTsumwx2
5773 s[6] = 0; // fTsumwxy
5774 s[9] = 0; // fTsumwxz
5775 } else if (iaxis == 2) {
5776 s[4] = 0; // fTsumwy
5777 s[5] = 0; // fTsumwy2
5778 s[6] = 0; // fTsumwxy
5779 s[10] = 0; // fTsumwyz
5780 } else if (iaxis == 3) {
5781 s[7] = 0; // fTsumwz
5782 s[8] = 0; // fTsumwz2
5783 s[9] = 0; // fTsumwxz
5784 s[10] = 0; // fTsumwyz
5785 }
5786 PutStats(s);
5787 }
5788 delete labold;
5789}
5790
5791////////////////////////////////////////////////////////////////////////////////
5792/// Test if two double are almost equal.
5793
5794static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5795{
5796 return TMath::Abs(a - b) < epsilon;
5797}
5798
5799////////////////////////////////////////////////////////////////////////////////
5800/// Test if a double is almost an integer.
5801
5802static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5803{
5804 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5806}
5807
5808////////////////////////////////////////////////////////////////////////////////
5809/// Test if the binning is equidistant.
5810
5811static inline bool IsEquidistantBinning(const TAxis& axis)
5812{
5813 // check if axis bin are equals
5814 if (!axis.GetXbins()->fN) return true; //
5815 // not able to check if there is only one axis entry
5816 bool isEquidistant = true;
5817 const Double_t firstBinWidth = axis.GetBinWidth(1);
5818 for (int i = 1; i < axis.GetNbins(); ++i) {
5819 const Double_t binWidth = axis.GetBinWidth(i);
5820 const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5821 isEquidistant &= match;
5822 if (!match)
5823 break;
5824 }
5825 return isEquidistant;
5826}
5827
5828////////////////////////////////////////////////////////////////////////////////
5829/// Same limits and bins.
5830
5831Bool_t TH1::SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2){
5832 return axis1.GetNbins() == axis2.GetNbins() &&
5833 TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
5834 TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
5835}
5836
5837////////////////////////////////////////////////////////////////////////////////
5838/// Finds new limits for the axis for the Merge function.
5839/// returns false if the limits are incompatible
5840
5841Bool_t TH1::RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
5842{
5843 if (SameLimitsAndNBins(destAxis, anAxis))
5844 return kTRUE;
5845
5846 if (!IsEquidistantBinning(destAxis) || !IsEquidistantBinning(anAxis))
5847 return kFALSE; // not equidistant user binning not supported
5848
5849 Double_t width1 = destAxis.GetBinWidth(0);
5850 Double_t width2 = anAxis.GetBinWidth(0);
5851 if (width1 == 0 || width2 == 0)
5852 return kFALSE; // no binning not supported
5853
5854 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
5855 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
5856 Double_t width = TMath::Max(width1, width2);
5857
5858 // check the bin size
5859 if (!AlmostInteger(width/width1) || !AlmostInteger(width/width2))
5860 return kFALSE;
5861
5862 // std::cout << "Find new limit using given axis " << anAxis.GetXmin() << " , " << anAxis.GetXmax() << " bin width " << width2 << std::endl;
5863 // std::cout << " and destination axis " << destAxis.GetXmin() << " , " << destAxis.GetXmax() << " bin width " << width1 << std::endl;
5864
5865
5866 // check the limits
5867 Double_t delta;
5868 delta = (destAxis.GetXmin() - xmin)/width1;
5869 if (!AlmostInteger(delta))
5870 xmin -= (TMath::Ceil(delta) - delta)*width1;
5871
5872 delta = (anAxis.GetXmin() - xmin)/width2;
5873 if (!AlmostInteger(delta))
5874 xmin -= (TMath::Ceil(delta) - delta)*width2;
5875
5876
5877 delta = (destAxis.GetXmin() - xmin)/width1;
5878 if (!AlmostInteger(delta))
5879 return kFALSE;
5880
5881
5882 delta = (xmax - destAxis.GetXmax())/width1;
5883 if (!AlmostInteger(delta))
5884 xmax += (TMath::Ceil(delta) - delta)*width1;
5885
5886
5887 delta = (xmax - anAxis.GetXmax())/width2;
5888 if (!AlmostInteger(delta))
5889 xmax += (TMath::Ceil(delta) - delta)*width2;
5890
5891
5892 delta = (xmax - destAxis.GetXmax())/width1;
5893 if (!AlmostInteger(delta))
5894 return kFALSE;
5895#ifdef DEBUG
5896 if (!AlmostInteger((xmax - xmin) / width)) { // unnecessary check
5897 printf("TH1::RecomputeAxisLimits - Impossible\n");
5898 return kFALSE;
5899 }
5900#endif
5901
5902
5903 destAxis.Set(TMath::Nint((xmax - xmin)/width), xmin, xmax);
5904
5905 //std::cout << "New re-computed axis : [ " << xmin << " , " << xmax << " ] width = " << width << " nbins " << destAxis.GetNbins() << std::endl;
5906
5907 return kTRUE;
5908}
5909
5910////////////////////////////////////////////////////////////////////////////////
5911/// Add all histograms in the collection to this histogram.
5912/// This function computes the min/max for the x axis,
5913/// compute a new number of bins, if necessary,
5914/// add bin contents, errors and statistics.
5915/// If all histograms have bin labels, bins with identical labels
5916/// will be merged, no matter what their order is.
5917/// If overflows are present and limits are different the function will fail.
5918/// The function returns the total number of entries in the result histogram
5919/// if the merge is successful, -1 otherwise.
5920///
5921/// Possible option:
5922/// -NOL : the merger will ignore the labels and merge the histograms bin by bin using bin center values to match bins
5923/// -NOCHECK: the histogram will not perform a check for duplicate labels in case of axes with labels. The check
5924/// (enabled by default) slows down the merging
5925///
5926/// IMPORTANT remark. The axis x may have different number
5927/// of bins and different limits, BUT the largest bin width must be
5928/// a multiple of the smallest bin width and the upper limit must also
5929/// be a multiple of the bin width.
5930/// Example:
5931///
5932/// ~~~ {.cpp}
5933/// void atest() {
5934/// TH1F *h1 = new TH1F("h1","h1",110,-110,0);
5935/// TH1F *h2 = new TH1F("h2","h2",220,0,110);
5936/// TH1F *h3 = new TH1F("h3","h3",330,-55,55);
5937/// TRandom r;
5938/// for (Int_t i=0;i<10000;i++) {
5939/// h1->Fill(r.Gaus(-55,10));
5940/// h2->Fill(r.Gaus(55,10));
5941/// h3->Fill(r.Gaus(0,10));
5942/// }
5943///
5944/// TList *list = new TList;
5945/// list->Add(h1);
5946/// list->Add(h2);
5947/// list->Add(h3);
5948/// TH1F *h = (TH1F*)h1->Clone("h");
5949/// h->Reset();
5950/// h->Merge(list);
5951/// h->Draw();
5952/// }
5953/// ~~~
5954
5956{
5957 if (!li) return 0;
5958 if (li->IsEmpty()) return (Long64_t) GetEntries();
5959
5960 // use TH1Merger class
5961 TH1Merger merger(*this,*li,opt);
5962 Bool_t ret = merger();
5963
5964 return (ret) ? GetEntries() : -1;
5965}
5966
5967
5968////////////////////////////////////////////////////////////////////////////////
5969/// Performs the operation:
5970///
5971/// `this = this*c1*f1`
5972///
5973/// If errors are defined (see TH1::Sumw2), errors are also recalculated.
5974///
5975/// Only bins inside the function range are recomputed.
5976/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
5977/// you should call Sumw2 before making this operation.
5978/// This is particularly important if you fit the histogram after TH1::Multiply
5979///
5980/// The function return kFALSE if the Multiply operation failed
5981
5983{
5984 if (!f1) {
5985 Error("Multiply","Attempt to multiply by a non-existing function");
5986 return kFALSE;
5987 }
5988
5989 // delete buffer if it is there since it will become invalid
5990 if (fBuffer) BufferEmpty(1);
5991
5992 Int_t nx = GetNbinsX() + 2; // normal bins + uf / of (cells)
5993 Int_t ny = GetNbinsY() + 2;
5994 Int_t nz = GetNbinsZ() + 2;
5995 if (fDimension < 2) ny = 1;
5996 if (fDimension < 3) nz = 1;
5997
5998 // reset min-maximum
5999 SetMinimum();
6000 SetMaximum();
6001
6002 // - Loop on bins (including underflows/overflows)
6003 Double_t xx[3];
6004 Double_t *params = 0;
6005 f1->InitArgs(xx,params);
6006
6007 for (Int_t binz = 0; binz < nz; ++binz) {
6008 xx[2] = fZaxis.GetBinCenter(binz);
6009 for (Int_t biny = 0; biny < ny; ++biny) {
6010 xx[1] = fYaxis.GetBinCenter(biny);
6011 for (Int_t binx = 0; binx < nx; ++binx) {
6012 xx[0] = fXaxis.GetBinCenter(binx);
6013 if (!f1->IsInside(xx)) continue;
6015 Int_t bin = binx + nx * (biny + ny *binz);
6016 Double_t cu = c1*f1->EvalPar(xx);
6017 if (TF1::RejectedPoint()) continue;
6018 UpdateBinContent(bin, RetrieveBinContent(bin) * cu);
6019 if (fSumw2.fN) {
6020 fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
6021 }
6022 }
6023 }
6024 }
6025 ResetStats();
6026 return kTRUE;
6027}
6028
6029////////////////////////////////////////////////////////////////////////////////
6030/// Multiply this histogram by h1.
6031///
6032/// `this = this*h1`
6033///
6034/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6035/// Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
6036/// if not already set.
6037///
6038/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6039/// you should call Sumw2 before making this operation.
6040/// This is particularly important if you fit the histogram after TH1::Multiply
6041///
6042/// The function return kFALSE if the Multiply operation failed
6043
6044Bool_t TH1::Multiply(const TH1 *h1)
6045{
6046 if (!h1) {
6047 Error("Multiply","Attempt to multiply by a non-existing histogram");
6048 return kFALSE;
6049 }
6050
6051 // delete buffer if it is there since it will become invalid
6052 if (fBuffer) BufferEmpty(1);
6053
6054 try {
6055 CheckConsistency(this,h1);
6056 } catch(DifferentNumberOfBins&) {
6057 Error("Multiply","Attempt to multiply histograms with different number of bins");
6058 return kFALSE;
6059 } catch(DifferentAxisLimits&) {
6060 Warning("Multiply","Attempt to multiply histograms with different axis limits");
6061 } catch(DifferentBinLimits&) {
6062 Warning("Multiply","Attempt to multiply histograms with different bin limits");
6063 } catch(DifferentLabels&) {
6064 Warning("Multiply","Attempt to multiply histograms with different labels");
6065 }
6066
6067 // Create Sumw2 if h1 has Sumw2 set
6068 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
6069
6070 // - Reset min- maximum
6071 SetMinimum();
6072 SetMaximum();
6073
6074 // - Loop on bins (including underflows/overflows)
6075 for (Int_t i = 0; i < fNcells; ++i) {
6078 UpdateBinContent(i, c0 * c1);
6079 if (fSumw2.fN) {
6081 }
6082 }
6083 ResetStats();
6084 return kTRUE;
6085}
6086
6087////////////////////////////////////////////////////////////////////////////////
6088/// Replace contents of this histogram by multiplication of h1 by h2.
6089///
6090/// `this = (c1*h1)*(c2*h2)`
6091///
6092/// If errors of this are available (TH1::Sumw2), errors are recalculated.
6093/// Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
6094/// if not already set.
6095///
6096/// IMPORTANT NOTE: If you intend to use the errors of this histogram later
6097/// you should call Sumw2 before making this operation.
6098/// This is particularly important if you fit the histogram after TH1::Multiply
6099///
6100/// The function return kFALSE if the Multiply operation failed
6101
6102Bool_t TH1::Multiply(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
6103{
6104 TString opt = option;
6105 opt.ToLower();
6106 // Bool_t binomial = kFALSE;
6107 // if (opt.Contains("b")) binomial = kTRUE;
6108 if (!h1 || !h2) {
6109 Error("Multiply","Attempt to multiply by a non-existing histogram");
6110 return kFALSE;
6111 }
6112
6113 // delete buffer if it is there since it will become invalid
6114 if (fBuffer) BufferEmpty(1);
6115
6116 try {
6117 CheckConsistency(h1,h2);
6118 CheckConsistency(this,h1);
6119 } catch(DifferentNumberOfBins&) {
6120 Error("Multiply","Attempt to multiply histograms with different number of bins");
6121 return kFALSE;
6122 } catch(DifferentAxisLimits&) {
6123 Warning("Multiply","Attempt to multiply histograms with different axis limits");
6124 } catch(DifferentBinLimits&) {
6125 Warning("Multiply","Attempt to multiply histograms with different bin limits");
6126 } catch(DifferentLabels&) {
6127 Warning("Multiply","Attempt to multiply histograms with different labels");
6128 }
6129
6130 // Create Sumw2 if h1 or h2 have Sumw2 set
6131 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
6132
6133 // - Reset min - maximum
6134 SetMinimum();
6135 SetMaximum();
6136
6137 // - Loop on bins (including underflows/overflows)
6138 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
6139 for (Int_t i = 0; i < fNcells; ++i) {
6141 Double_t b2 = h2->RetrieveBinContent(i);
6142 UpdateBinContent(i, c1 * b1 * c2 * b2);
6143 if (fSumw2.fN) {
6144 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
6145 }
6146 }
6147 ResetStats();
6148 return kTRUE;
6149}
6150
6151////////////////////////////////////////////////////////////////////////////////
6152/// Control routine to paint any kind of histograms.
6153///
6154/// This function is automatically called by TCanvas::Update.
6155/// (see TH1::Draw for the list of options)
6156
6157void TH1::Paint(Option_t *option)
6158{
6159 GetPainter(option);
6160
6161 if (fPainter) {
6162 if (strlen(option) > 0) fPainter->Paint(option);
6163 else fPainter->Paint(fOption.Data());
6164 }
6165}
6166
6167////////////////////////////////////////////////////////////////////////////////
6168/// Rebin this histogram
6169///
6170/// #### case 1 xbins=0
6171///
6172/// If newname is blank (default), the current histogram is modified and
6173/// a pointer to it is returned.
6174///
6175/// If newname is not blank, the current histogram is not modified, and a
6176/// new histogram is returned which is a Clone of the current histogram
6177/// with its name set to newname.
6178///
6179/// The parameter ngroup indicates how many bins of this have to be merged
6180/// into one bin of the result.
6181///
6182/// If the original histogram has errors stored (via Sumw2), the resulting
6183/// histograms has new errors correctly calculated.
6184///
6185/// examples: if h1 is an existing TH1F histogram with 100 bins
6186///
6187/// ~~~ {.cpp}
6188/// h1->Rebin(); //merges two bins in one in h1: previous contents of h1 are lost
6189/// h1->Rebin(5); //merges five bins in one in h1
6190/// TH1F *hnew = dynamic_cast<TH1F*>(h1->Rebin(5,"hnew")); // creates a new histogram hnew
6191/// // merging 5 bins of h1 in one bin
6192/// ~~~
6193///
6194/// NOTE: If ngroup is not an exact divider of the number of bins,
6195/// the top limit of the rebinned histogram is reduced
6196/// to the upper edge of the last bin that can make a complete
6197/// group. The remaining bins are added to the overflow bin.
6198/// Statistics will be recomputed from the new bin contents.
6199///
6200/// #### case 2 xbins!=0
6201///
6202/// A new histogram is created (you should specify newname).
6203/// The parameter ngroup is the number of variable size bins in the created histogram.
6204/// The array xbins must contain ngroup+1 elements that represent the low-edges
6205/// of the bins.
6206/// If the original histogram has errors stored (via Sumw2), the resulting
6207/// histograms has new errors correctly calculated.
6208///
6209/// NOTE: The bin edges specified in xbins should correspond to bin edges
6210/// in the original histogram. If a bin edge in the new histogram is
6211/// in the middle of a bin in the original histogram, all entries in
6212/// the split bin in the original histogram will be transfered to the
6213/// lower of the two possible bins in the new histogram. This is
6214/// probably not what you want. A warning message is emitted in this
6215/// case
6216///
6217/// examples: if h1 is an existing TH1F histogram with 100 bins
6218///
6219/// ~~~ {.cpp}
6220/// Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
6221/// h1->Rebin(24,"hnew",xbins); //creates a new variable bin size histogram hnew
6222/// ~~~
6223
6224TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
6225{
6226 Int_t nbins = fXaxis.GetNbins();
6229 if ((ngroup <= 0) || (ngroup > nbins)) {
6230 Error("Rebin", "Illegal value of ngroup=%d",ngroup);
6231 return 0;
6232 }
6233
6234 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
6235 Error("Rebin", "Operation valid on 1-D histograms only");
6236 return 0;
6237 }
6238 if (!newname && xbins) {
6239 Error("Rebin","if xbins is specified, newname must be given");
6240 return 0;
6241 }
6242
6243 Int_t newbins = nbins/ngroup;
6244 if (!xbins) {
6245 Int_t nbg = nbins/ngroup;
6246 if (nbg*ngroup != nbins) {
6247 Warning("Rebin", "ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
6248 }
6249 }
6250 else {
6251 // in the case that xbins is given (rebinning in variable bins), ngroup is
6252 // the new number of bins and number of grouped bins is not constant.
6253 // when looping for setting the contents for the new histogram we
6254 // need to loop on all bins of original histogram. Then set ngroup=nbins
6255 newbins = ngroup;
6256 ngroup = nbins;
6257 }
6258
6259 // Save old bin contents into a new array
6260 Double_t entries = fEntries;
6261 Double_t *oldBins = new Double_t[nbins+2];
6262 Int_t bin, i;
6263 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
6264 Double_t *oldErrors = 0;
6265 if (fSumw2.fN != 0) {
6266 oldErrors = new Double_t[nbins+2];
6267 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
6268 }
6269 // rebin will not include underflow/overflow if new axis range is larger than old axis range
6270 if (xbins) {
6271 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
6272 Warning("Rebin","underflow entries will not be used when rebinning");
6273 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
6274 Warning("Rebin","overflow entries will not be used when rebinning");
6275 }
6276
6277
6278 // create a clone of the old histogram if newname is specified
6279 TH1 *hnew = this;
6280 if ((newname && strlen(newname) > 0) || xbins) {
6281 hnew = (TH1*)Clone(newname);
6282 }
6283
6284 //reset can extend bit to avoid an axis extension in SetBinContent
6285 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
6286
6287 // save original statistics
6288 Double_t stat[kNstat];
6289 GetStats(stat);
6290 bool resetStat = false;
6291 // change axis specs and rebuild bin contents array::RebinAx
6292 if(!xbins && (newbins*ngroup != nbins)) {
6293 xmax = fXaxis.GetBinUpEdge(newbins*ngroup);
6294 resetStat = true; //stats must be reset because top bins will be moved to overflow bin
6295 }
6296 // save the TAttAxis members (reset by SetBins)
6297 Int_t nDivisions = fXaxis.GetNdivisions();
6298 Color_t axisColor = fXaxis.GetAxisColor();
6299 Color_t labelColor = fXaxis.GetLabelColor();
6300 Style_t labelFont = fXaxis.GetLabelFont();
6301 Float_t labelOffset = fXaxis.GetLabelOffset();
6302 Float_t labelSize = fXaxis.GetLabelSize();
6303 Float_t tickLength = fXaxis.GetTickLength();
6304 Float_t titleOffset = fXaxis.GetTitleOffset();
6305 Float_t titleSize = fXaxis.GetTitleSize();
6306 Color_t titleColor = fXaxis.GetTitleColor();
6307 Style_t titleFont = fXaxis.GetTitleFont();
6308
6309 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
6310 Double_t *bins = new Double_t[newbins+1];
6311 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
6312 hnew->SetBins(newbins,bins); //this also changes errors array (if any)
6313 delete [] bins;
6314 } else if (xbins) {
6315 hnew->SetBins(newbins,xbins);
6316 } else {
6317 hnew->SetBins(newbins,xmin,xmax);
6318 }
6319
6320 // Restore axis attributes
6321 fXaxis.SetNdivisions(nDivisions);
6322 fXaxis.SetAxisColor(axisColor);
6323 fXaxis.SetLabelColor(labelColor);
6324 fXaxis.SetLabelFont(labelFont);
6325 fXaxis.SetLabelOffset(labelOffset);
6326 fXaxis.SetLabelSize(labelSize);
6327 fXaxis.SetTickLength(tickLength);
6328 fXaxis.SetTitleOffset(titleOffset);
6329 fXaxis.SetTitleSize(titleSize);
6330 fXaxis.SetTitleColor(titleColor);
6331 fXaxis.SetTitleFont(titleFont);
6332
6333 // copy merged bin contents (ignore under/overflows)
6334 // Start merging only once the new lowest edge is reached
6335 Int_t startbin = 1;
6336 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
6337 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
6338 startbin++;
6339 }
6340 Int_t oldbin = startbin;
6341 Double_t binContent, binError;
6342 for (bin = 1;bin<=newbins;bin++) {
6343 binContent = 0;
6344 binError = 0;
6345 Int_t imax = ngroup;
6346 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6347 // check bin edges for the cases when we provide an array of bins
6348 // be careful in case bins can have zero width
6349 if (xbins && !TMath::AreEqualAbs(fXaxis.GetBinLowEdge(oldbin),
6350 hnew->GetXaxis()->GetBinLowEdge(bin),
6351 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6352 {
6353 Warning("Rebin","Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6354 }
6355 for (i=0;i<ngroup;i++) {
6356 if( (oldbin+i > nbins) ||
6357 ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6358 imax = i;
6359 break;
6360 }
6361 binContent += oldBins[oldbin+i];
6362 if (oldErrors) binError += oldErrors[oldbin+i]*oldErrors[oldbin+i];
6363 }
6364 hnew->SetBinContent(bin,binContent);
6365 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6366 oldbin += imax;
6367 }
6368
6369 // sum underflow and overflow contents until startbin
6370 binContent = 0;
6371 binError = 0;
6372 for (i = 0; i < startbin; ++i) {
6373 binContent += oldBins[i];
6374 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6375 }
6376 hnew->SetBinContent(0,binContent);
6377 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6378 // sum overflow
6379 binContent = 0;
6380 binError = 0;
6381 for (i = oldbin; i <= nbins+1; ++i) {
6382 binContent += oldBins[i];
6383 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6384 }
6385 hnew->SetBinContent(newbins+1,binContent);
6386 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6387
6388 hnew->SetCanExtend(oldExtendBitMask); // restore previous state
6389
6390 // restore statistics and entries modified by SetBinContent
6391 hnew->SetEntries(entries);
6392 if (!resetStat) hnew->PutStats(stat);
6393 delete [] oldBins;
6394 if (oldErrors) delete [] oldErrors;
6395 return hnew;
6396}
6397
6398////////////////////////////////////////////////////////////////////////////////
6399/// finds new limits for the axis so that *point* is within the range and
6400/// the limits are compatible with the previous ones (see TH1::Merge).
6401/// new limits are put into *newMin* and *newMax* variables.
6402/// axis - axis whose limits are to be recomputed
6403/// point - point that should fit within the new axis limits
6404/// newMin - new minimum will be stored here
6405/// newMax - new maximum will be stored here.
6406/// false if failed (e.g. if the initial axis limits are wrong
6407/// or the new range is more than \f$ 2^{64} \f$ times the old one).
6408
6409Bool_t TH1::FindNewAxisLimits(const TAxis* axis, const Double_t point, Double_t& newMin, Double_t &newMax)
6410{
6411 Double_t xmin = axis->GetXmin();
6412 Double_t xmax = axis->GetXmax();
6413 if (xmin >= xmax) return kFALSE;
6414 Double_t range = xmax-xmin;
6415 Double_t binsize = range / axis->GetNbins();
6416
6417 //recompute new axis limits by doubling the current range
6418 Int_t ntimes = 0;
6419 while (point < xmin) {
6420 if (ntimes++ > 64)
6421 return kFALSE;
6422 xmin = xmin - range;
6423 range *= 2;
6424 binsize *= 2;
6425 // // make sure that the merging will be correct
6426 // if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
6427 // xmin += 0.5 * binsize;
6428 // xmax += 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
6429 // }
6430 }
6431 while (point >= xmax) {
6432 if (ntimes++ > 64)
6433 return kFALSE;
6434 xmax = xmax + range;
6435 range *= 2;
6436 binsize *= 2;
6437 // // make sure that the merging will be correct
6438 // if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
6439 // xmin -= 0.5 * binsize;
6440 // xmax -= 0.5 * binsize; // won't work with a histogram with only one bin, but I don't care
6441 // }
6442 }
6443 newMin = xmin;
6444 newMax = xmax;
6445 // Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
6446 // axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
6447
6448 return kTRUE;
6449}
6450
6451////////////////////////////////////////////////////////////////////////////////
6452/// Histogram is resized along axis such that x is in the axis range.
6453/// The new axis limits are recomputed by doubling iteratively
6454/// the current axis range until the specified value x is within the limits.
6455/// The algorithm makes a copy of the histogram, then loops on all bins
6456/// of the old histogram to fill the extended histogram.
6457/// Takes into account errors (Sumw2) if any.
6458/// The algorithm works for 1-d, 2-D and 3-D histograms.
6459/// The axis must be extendable before invoking this function.
6460/// Ex:
6461///
6462/// ~~~ {.cpp}
6463/// h->GetXaxis()->SetCanExtend(kTRUE);
6464/// ~~~
6465
6466void TH1::ExtendAxis(Double_t x, TAxis *axis)
6467{
6468 if (!axis->CanExtend()) return;
6469 if (TMath::IsNaN(x)) { // x may be a NaN
6471 return;
6472 }
6473
6474 if (axis->GetXmin() >= axis->GetXmax()) return;
6475 if (axis->GetNbins() <= 0) return;
6476
6478 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6479 return;
6480
6481 //save a copy of this histogram
6482 TH1 *hold = (TH1*)IsA()->New();
6483 hold->SetDirectory(0);
6484 Copy(*hold);
6485 //set new axis limits
6486 axis->SetLimits(xmin,xmax);
6487
6488
6489 //now loop on all bins and refill
6490 Int_t errors = GetSumw2N();
6491
6492 Reset("ICE"); //reset only Integral, contents and Errors
6493
6494 int iaxis = 0;
6495 if (axis == &fXaxis) iaxis = 1;
6496 if (axis == &fYaxis) iaxis = 2;
6497 if (axis == &fZaxis) iaxis = 3;
6498 bool firstw = kTRUE;
6499 Int_t binx,biny, binz = 0;
6500 Int_t ix = 0,iy = 0,iz = 0;
6501 Double_t bx,by,bz;
6502 Int_t ncells = hold->GetNcells();
6503 for (Int_t bin = 0; bin < ncells; ++bin) {
6504 hold->GetBinXYZ(bin,binx,biny,binz);
6505 bx = hold->GetXaxis()->GetBinCenter(binx);
6506 ix = fXaxis.FindFixBin(bx);
6507 if (fDimension > 1) {
6508 by = hold->GetYaxis()->GetBinCenter(biny);
6509 iy = fYaxis.FindFixBin(by);
6510 if (fDimension > 2) {
6511 bz = hold->GetZaxis()->GetBinCenter(binz);
6512 iz = fZaxis.FindFixBin(bz);
6513 }
6514 }
6515 // exclude underflow/overflow
6516 double content = hold->RetrieveBinContent(bin);
6517 if (content == 0) continue;
6518 if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6519 if (firstw) {
6520 Warning("ExtendAxis","Histogram %s has underflow or overflow in the axis that is extendable"
6521 " their content will be lost",GetName() );
6522 firstw= kFALSE;
6523 }
6524 continue;
6525 }
6526 Int_t ibin= GetBin(ix,iy,iz);
6527 AddBinContent(ibin, content);
6528 if (errors) {
6529 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6530 }
6531 }
6532 delete hold;
6533}
6534
6535////////////////////////////////////////////////////////////////////////////////
6536/// Recursively remove object from the list of functions
6537
6539{
6540 // Rely on TROOT::RecursiveRemove to take the readlock.
6541
6542 if (fFunctions) {
6544 }
6545}
6546
6547////////////////////////////////////////////////////////////////////////////////
6548/// Multiply this histogram by a constant c1.
6549///
6550/// `this = c1*this`
6551///
6552/// Note that both contents and errors (if any) are scaled.
6553/// This function uses the services of TH1::Add
6554///
6555/// IMPORTANT NOTE: Sumw2() is called automatically when scaling.
6556/// If you are not interested in the histogram statistics you can call
6557/// Sumw2(kFALSE) or use the option "nosw2"
6558///
6559/// One can scale an histogram such that the bins integral is equal to
6560/// the normalization parameter via TH1::Scale(Double_t norm), where norm
6561/// is the desired normalization divided by the integral of the histogram.
6562///
6563/// If option contains "width" the bin contents and errors are divided
6564/// by the bin width.
6565
6566void TH1::Scale(Double_t c1, Option_t *option)
6567{
6568
6569 TString opt = option; opt.ToLower();
6570 // store bin errors when scaling since cannot anymore be computed as sqrt(N)
6571 if (!opt.Contains("nosw2") && GetSumw2N() == 0) Sumw2();
6572 if (opt.Contains("width")) Add(this, this, c1, -1);
6573 else {
6574 if (fBuffer) BufferEmpty(1);
6575 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6576 if (fSumw2.fN) for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1); // update errors
6577 // update global histograms statistics
6578 Double_t s[kNstat] = {0};
6579 GetStats(s);
6580 for (Int_t i=0 ; i < kNstat; i++) {
6581 if (i == 1) s[i] = c1*c1*s[i];
6582 else s[i] = c1*s[i];
6583 }
6584 PutStats(s);
6585 SetMinimum(); SetMaximum(); // minimum and maximum value will be recalculated the next time
6586 }
6587
6588 // if contours set, must also scale contours
6589 Int_t ncontours = GetContour();
6590 if (ncontours == 0) return;
6591 Double_t* levels = fContour.GetArray();
6592 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6593}
6594
6595////////////////////////////////////////////////////////////////////////////////
6596/// Returns true if all axes are extendable.
6597
6599{
6600 Bool_t canExtend = fXaxis.CanExtend();
6601 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6602 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6603
6604 return canExtend;
6605}
6606
6607////////////////////////////////////////////////////////////////////////////////
6608/// Make the histogram axes extendable / not extendable according to the bit mask
6609/// returns the previous bit mask specifying which axes are extendable
6610
6611UInt_t TH1::SetCanExtend(UInt_t extendBitMask)
6612{
6613 UInt_t oldExtendBitMask = kNoAxis;
6614
6615 if (fXaxis.CanExtend()) oldExtendBitMask |= kXaxis;
6616 if (extendBitMask & kXaxis) fXaxis.SetCanExtend(kTRUE);
6618
6619 if (GetDimension() > 1) {
6620 if (fYaxis.CanExtend()) oldExtendBitMask |= kYaxis;
6621 if (extendBitMask & kYaxis) fYaxis.SetCanExtend(kTRUE);
6623 }
6624
6625 if (GetDimension() > 2) {
6626 if (fZaxis.CanExtend()) oldExtendBitMask |= kZaxis;
6627 if (extendBitMask & kZaxis) fZaxis.SetCanExtend(kTRUE);
6629 }
6630
6631 return oldExtendBitMask;
6632}
6633
6634///////////////////////////////////////////////////////////////////////////////
6635/// Internal function used in TH1::Fill to see which axis is full alphanumeric
6636/// i.e. can be extended and is alphanumeric
6638{
6639 UInt_t bitMask = kNoAxis;
6640 if (fXaxis.CanExtend() && fXaxis.IsAlphanumeric() ) bitMask |= kXaxis;
6642 bitMask |= kYaxis;
6644 bitMask |= kZaxis;
6645
6646 return bitMask;
6647}
6648
6649////////////////////////////////////////////////////////////////////////////////
6650/// Static function to set the default buffer size for automatic histograms.
6651/// When an histogram is created with one of its axis lower limit greater
6652/// or equal to its upper limit, the function SetBuffer is automatically
6653/// called with the default buffer size.
6654
6655void TH1::SetDefaultBufferSize(Int_t buffersize)
6656{
6657 fgBufferSize = buffersize > 0 ? buffersize : 0;
6658}
6659
6660////////////////////////////////////////////////////////////////////////////////
6661/// When this static function is called with `sumw2=kTRUE`, all new
6662/// histograms will automatically activate the storage
6663/// of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
6664
6665void TH1::SetDefaultSumw2(Bool_t sumw2)
6666{
6667 fgDefaultSumw2 = sumw2;
6668}
6669
6670////////////////////////////////////////////////////////////////////////////////
6671/// Change (i.e. set) the title
6672///
6673/// if title is in the form `stringt;stringx;stringy;stringz`
6674/// the histogram title is set to `stringt`, the x axis title to `stringx`,
6675/// the y axis title to `stringy`, and the z axis title to `stringz`.
6676///
6677/// To insert the character `;` in one of the titles, one should use `#;`
6678/// or `#semicolon`.
6679
6680void TH1::SetTitle(const char *title)
6681{
6682 fTitle = title;
6683 fTitle.ReplaceAll("#;",2,"#semicolon",10);
6684
6685 // Decode fTitle. It may contain X, Y and Z titles
6686 TString str1 = fTitle, str2;
6687 Int_t isc = str1.Index(";");
6688 Int_t lns = str1.Length();
6689
6690 if (isc >=0 ) {
6691 fTitle = str1(0,isc);
6692 str1 = str1(isc+1, lns);
6693 isc = str1.Index(";");
6694 if (isc >=0 ) {
6695 str2 = str1(0,isc);
6696 str2.ReplaceAll("#semicolon",10,";",1);
6697 fXaxis.SetTitle(str2.Data());
6698 lns = str1.Length();
6699 str1 = str1(isc+1, lns);
6700 isc = str1.Index(";");
6701 if (isc >=0 ) {
6702 str2 = str1(0,isc);
6703 str2.ReplaceAll("#semicolon",10,";",1);
6704 fYaxis.SetTitle(str2.Data());
6705 lns = str1.Length();
6706 str1 = str1(isc+1, lns);
6707 str1.ReplaceAll("#semicolon",10,";",1);
6708 fZaxis.SetTitle(str1.Data());
6709 } else {
6710 str1.ReplaceAll("#semicolon",10,";",1);
6711 fYaxis.SetTitle(str1.Data());
6712 }
6713 } else {
6714 str1.ReplaceAll("#semicolon",10,";",1);
6715 fXaxis.SetTitle(str1.Data());
6716 }
6717 }
6718
6719 fTitle.ReplaceAll("#semicolon",10,";",1);
6720
6721 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6722}
6723
6724////////////////////////////////////////////////////////////////////////////////
6725/// Smooth array xx, translation of Hbook routine hsmoof.F
6726/// based on algorithm 353QH twice presented by J. Friedman
6727/// in Proc.of the 1974 CERN School of Computing, Norway, 11-24 August, 1974.
6728
6729void TH1::SmoothArray(Int_t nn, Double_t *xx, Int_t ntimes)
6730{
6731 if (nn < 3 ) {
6732 ::Error("SmoothArray","Need at least 3 points for smoothing: n = %d",nn);
6733 return;
6734 }
6735
6736 Int_t ii;
6737 Double_t hh[6] = {0,0,0,0,0,0};
6738
6739 std::vector<double> yy(nn);
6740 std::vector<double> zz(nn);
6741 std::vector<double> rr(nn);
6742
6743 for (Int_t pass=0;pass<ntimes;pass++) {
6744 // first copy original data into temp array
6745 std::copy(xx, xx+nn, zz.begin() );
6746
6747 for (int noent = 0; noent < 2; ++noent) { // run algorithm two times
6748
6749 // do 353 i.e. running median 3, 5, and 3 in a single loop
6750 for (int kk = 0; kk < 3; kk++) {
6751 std::copy(zz.begin(), zz.end(), yy.begin());
6752 int medianType = (kk != 1) ? 3 : 5;
6753 int ifirst = (kk != 1 ) ? 1 : 2;
6754 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6755 //nn2 = nn - ik - 1;
6756 // do all elements beside the first and last point for median 3
6757 // and first two and last 2 for median 5
6758 for ( ii = ifirst; ii < ilast; ii++) {
6759 assert(ii - ifirst >= 0);
6760 for (int jj = 0; jj < medianType; jj++) {
6761 hh[jj] = yy[ii - ifirst + jj ];
6762 }
6763 zz[ii] = TMath::Median(medianType, hh);
6764 }
6765
6766 if (kk == 0) { // first median 3
6767 // first point
6768 hh[0] = zz[1];
6769 hh[1] = zz[0];
6770 hh[2] = 3*zz[1] - 2*zz[2];
6771 zz[0] = TMath::Median(3, hh);
6772 // last point
6773 hh[0] = zz[nn - 2];
6774 hh[1] = zz[nn - 1];
6775 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6776 zz[nn - 1] = TMath::Median(3, hh);
6777 }
6778
6779 if (kk == 1) { // median 5
6780 for (ii = 0; ii < 3; ii++) {
6781 hh[ii] = yy[ii];
6782 }
6783 zz[1] = TMath::Median(3, hh);
6784 // last two points
6785 for (ii = 0; ii < 3; ii++) {
6786 hh[ii] = yy[nn - 3 + ii];
6787 }
6788 zz[nn - 2] = TMath::Median(3, hh);
6789 }
6790
6791 }
6792
6793 std::copy ( zz.begin(), zz.end(), yy.begin() );
6794
6795 // quadratic interpolation for flat segments
6796 for (ii = 2; ii < (nn - 2); ii++) {
6797 if (zz[ii - 1] != zz[ii]) continue;
6798 if (zz[ii] != zz[ii + 1]) continue;
6799 hh[0] = zz[ii - 2] - zz[ii];
6800 hh[1] = zz[ii + 2] - zz[ii];
6801 if (hh[0] * hh[1] <= 0) continue;
6802 int jk = 1;
6803 if ( TMath::Abs(hh[1]) > TMath::Abs(hh[0]) ) jk = -1;
6804 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6805 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6806 }
6807
6808 // running means
6809 //std::copy(zz.begin(), zz.end(), yy.begin());
6810 for (ii = 1; ii < nn - 1; ii++) {
6811 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6812 }
6813 zz[0] = yy[0];
6814 zz[nn - 1] = yy[nn - 1];
6815
6816 if (noent == 0) {
6817
6818 // save computed values
6819 std::copy(zz.begin(), zz.end(), rr.begin());
6820
6821 // COMPUTE residuals
6822 for (ii = 0; ii < nn; ii++) {
6823 zz[ii] = xx[ii] - zz[ii];
6824 }
6825 }
6826
6827 } // end loop on noent
6828
6829
6830 double xmin = TMath::MinElement(nn,xx);
6831 for (ii = 0; ii < nn; ii++) {
6832 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6833 // make smoothing defined positive - not better using 0 ?
6834 else xx[ii] = TMath::Max((rr[ii] + zz[ii]),0.0 );
6835 }
6836 }
6837}
6838
6839////////////////////////////////////////////////////////////////////////////////
6840/// Smooth bin contents of this histogram.
6841/// if option contains "R" smoothing is applied only to the bins
6842/// defined in the X axis range (default is to smooth all bins)
6843/// Bin contents are replaced by their smooth values.
6844/// Errors (if any) are not modified.
6845/// the smoothing procedure is repeated ntimes (default=1)
6846
6847void TH1::Smooth(Int_t ntimes, Option_t *option)
6848{
6849 if (fDimension != 1) {
6850 Error("Smooth","Smooth only supported for 1-d histograms");
6851 return;
6852 }
6853 Int_t nbins = fXaxis.GetNbins();
6854 if (nbins < 3) {
6855 Error("Smooth","Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
6856 return;
6857 }
6858
6859 // delete buffer if it is there since it will become invalid
6860 if (fBuffer) BufferEmpty(1);
6861
6862 Int_t firstbin = 1, lastbin = nbins;
6863 TString opt = option;
6864 opt.ToLower();
6865 if (opt.Contains("r")) {
6866 firstbin= fXaxis.GetFirst();
6867 lastbin = fXaxis.GetLast();
6868 }
6869 nbins = lastbin - firstbin + 1;
6870 Double_t *xx = new Double_t[nbins];
6871 Double_t nent = fEntries;
6872 Int_t i;
6873 for (i=0;i<nbins;i++) {
6874 xx[i] = RetrieveBinContent(i+firstbin);
6875 }
6876
6877 TH1::SmoothArray(nbins,xx,ntimes);
6878
6879 for (i=0;i<nbins;i++) {
6880 UpdateBinContent(i+firstbin,xx[i]);
6881 }
6882 fEntries = nent;
6883 delete [] xx;
6884
6885 if (gPad) gPad->Modified();
6886}
6887
6888////////////////////////////////////////////////////////////////////////////////
6889/// if flag=kTRUE, underflows and overflows are used by the Fill functions
6890/// in the computation of statistics (mean value, StdDev).
6891/// By default, underflows or overflows are not used.
6892
6893void TH1::StatOverflows(Bool_t flag)
6894{
6895 fgStatOverflows = flag;
6896}
6897
6898////////////////////////////////////////////////////////////////////////////////
6899/// Stream a class object.
6900
6901void TH1::Streamer(TBuffer &b)
6902{
6903 if (b.IsReading()) {
6904 UInt_t R__s, R__c;
6905 Version_t R__v = b.ReadVersion(&R__s, &R__c);
6906 if (fDirectory) fDirectory->Remove(this);
6907 fDirectory = 0;
6908 if (R__v > 2) {
6909 b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
6910
6912 fXaxis.SetParent(this);
6913 fYaxis.SetParent(this);
6914 fZaxis.SetParent(this);
6915 TIter next(fFunctions);
6916 TObject *obj;
6917 while ((obj=next())) {
6918 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
6919 }
6920 return;
6921 }
6922 //process old versions before automatic schema evolution
6923 TNamed::Streamer(b);
6924 TAttLine::Streamer(b);
6925 TAttFill::Streamer(b);
6926 TAttMarker::Streamer(b);
6927 b >> fNcells;
6928 fXaxis.Streamer(b);
6929 fYaxis.Streamer(b);
6930 fZaxis.Streamer(b);
6931 fXaxis.SetParent(this);
6932 fYaxis.SetParent(this);
6933 fZaxis.SetParent(this);
6934 b >> fBarOffset;
6935 b >> fBarWidth;
6936 b >> fEntries;
6937 b >> fTsumw;
6938 b >> fTsumw2;
6939 b >> fTsumwx;
6940 b >> fTsumwx2;
6941 if (R__v < 2) {
6942 Float_t maximum, minimum, norm;
6943 Float_t *contour=0;
6944 b >> maximum; fMaximum = maximum;
6945 b >> minimum; fMinimum = minimum;
6946 b >> norm; fNormFactor = norm;
6947 Int_t n = b.ReadArray(contour);
6948 fContour.Set(n);
6949 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
6950 delete [] contour;
6951 } else {
6952 b >> fMaximum;
6953 b >> fMinimum;
6954 b >> fNormFactor;
6955 fContour.Streamer(b);
6956 }
6957 fSumw2.Streamer(b);
6958 fOption.Streamer(b);
6959 fFunctions->Delete();
6960 fFunctions->Streamer(b);
6961 b.CheckByteCount(R__s, R__c, TH1::IsA());
6962
6963 } else {
6964 b.WriteClassBuffer(TH1::Class(),this);
6965 }
6966}
6967
6968////////////////////////////////////////////////////////////////////////////////
6969/// Print some global quantities for this histogram.
6970/// \param[in] option
6971/// - "base" is given, number of bins and ranges are also printed
6972/// - "range" is given, bin contents and errors are also printed
6973/// for all bins in the current range (default 1-->nbins)
6974/// - "all" is given, bin contents and errors are also printed
6975/// for all bins including under and overflows.
6976
6977void TH1::Print(Option_t *option) const
6978{
6979 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
6980 printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
6981 TString opt = option;
6982 opt.ToLower();
6983 Int_t all;
6984 if (opt.Contains("all")) all = 0;
6985 else if (opt.Contains("range")) all = 1;
6986 else if (opt.Contains("base")) all = 2;
6987 else return;
6988
6989 Int_t bin, binx, biny, binz;
6990 Int_t firstx=0,lastx=0,firsty=0,lasty=0,firstz=0,lastz=0;
6991 if (all == 0) {
6992 lastx = fXaxis.GetNbins()+1;
6993 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
6994 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
6995 } else {
6996 firstx = fXaxis.GetFirst(); lastx = fXaxis.GetLast();
6997 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
6998 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
6999 }
7000
7001 if (all== 2) {
7002 printf(" Title = %s\n", GetTitle());
7003 printf(" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
7004 if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
7005 if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
7006 printf("\n");
7007 return;
7008 }
7009
7010 Double_t w,e;
7011 Double_t x,y,z;
7012 if (fDimension == 1) {
7013 for (binx=firstx;binx<=lastx;binx++) {
7014 x = fXaxis.GetBinCenter(binx);
7015 w = RetrieveBinContent(binx);
7016 e = GetBinError(binx);
7017 if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
7018 else printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
7019 }
7020 }
7021 if (fDimension == 2) {
7022 for (biny=firsty;biny<=lasty;biny++) {
7023 y = fYaxis.GetBinCenter(biny);
7024 for (binx=firstx;binx<=lastx;binx++) {
7025 bin = GetBin(binx,biny);
7026 x = fXaxis.GetBinCenter(binx);
7027 w = RetrieveBinContent(bin);
7028 e = GetBinError(bin);
7029 if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
7030 else printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
7031 }
7032 }
7033 }
7034 if (fDimension == 3) {
7035 for (binz=firstz;binz<=lastz;binz++) {
7036 z = fZaxis.GetBinCenter(binz);
7037 for (biny=firsty;biny<=lasty;biny++) {
7038 y = fYaxis.GetBinCenter(biny);
7039 for (binx=firstx;binx<=lastx;binx++) {
7040 bin = GetBin(binx,biny,binz);
7041 x = fXaxis.GetBinCenter(binx);
7042 w = RetrieveBinContent(bin);
7043 e = GetBinError(bin);
7044 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);
7045 else printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
7046 }
7047 }
7048 }
7049 }
7050}
7051
7052////////////////////////////////////////////////////////////////////////////////
7053/// Using the current bin info, recompute the arrays for contents and errors
7054
7055void TH1::Rebuild(Option_t *)
7056{
7057 SetBinsLength();
7058 if (fSumw2.fN) {
7060 }
7061}
7062
7063////////////////////////////////////////////////////////////////////////////////
7064/// Reset this histogram: contents, errors, etc.
7065/// \param[in] option
7066/// - if "ICE" is specified, resets only Integral, Contents and Errors.
7067/// - if "ICES" is specified, resets only Integral, Contents, Errors and Statistics
7068/// This option is used
7069/// - if "M" is specified, resets also Minimum and Maximum
7070
7071void TH1::Reset(Option_t *option)
7072{
7073 // The option "ICE" is used when extending the histogram (in ExtendAxis, LabelInflate, etc..)
7074 // The option "ICES is used in combination with the buffer (see BufferEmpty and BufferFill)
7075
7076 TString opt = option;
7077 opt.ToUpper();
7078 fSumw2.Reset();
7079 if (fIntegral) {delete [] fIntegral; fIntegral = 0;}
7080
7081 if (opt.Contains("M")) {
7082 SetMinimum();
7083 SetMaximum();
7084 }
7085
7086 if (opt.Contains("ICE") && !opt.Contains("S")) return;
7087
7088 // Setting fBuffer[0] = 0 is like resetting the buffer but not deleting it
7089 // But what is the sense of calling BufferEmpty() ? For making the axes ?
7090 // BufferEmpty will update contents that later will be
7091 // reset in calling TH1D::Reset. For this we need to reset the stats afterwards
7092 // It may be needed for computing the axis limits....
7093 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
7094
7095 // need to reset also the statistics
7096 // (needs to be done after calling BufferEmpty() )
7097 fTsumw = 0;
7098 fTsumw2 = 0;
7099 fTsumwx = 0;
7100 fTsumwx2 = 0;
7101 fEntries = 0;
7102
7103 if (opt == "ICES") return;
7104
7105
7106 TObject *stats = fFunctions->FindObject("stats");
7107 fFunctions->Remove(stats);
7108 //special logic to support the case where the same object is
7109 //added multiple times in fFunctions.
7110 //This case happens when the same object is added with different
7111 //drawing modes
7112 TObject *obj;
7113 while ((obj = fFunctions->First())) {
7114 while(fFunctions->Remove(obj)) { }
7115 delete obj;
7116 }
7117 if(stats) fFunctions->Add(stats);
7118 fContour.Set(0);
7119}
7120
7121////////////////////////////////////////////////////////////////////////////////
7122/// Save primitive as a C++ statement(s) on output stream out
7123
7124void TH1::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
7125{
7126 // empty the buffer before if it exists
7127 if (fBuffer) BufferEmpty();
7128
7129 Bool_t nonEqiX = kFALSE;
7130 Bool_t nonEqiY = kFALSE;
7131 Bool_t nonEqiZ = kFALSE;
7132 Int_t i;
7133 static Int_t nxaxis = 0;
7134 static Int_t nyaxis = 0;
7135 static Int_t nzaxis = 0;
7136 TString sxaxis="xAxis",syaxis="yAxis",szaxis="zAxis";
7137
7138 // Check if the histogram has equidistant X bins or not. If not, we
7139 // create an array holding the bins.
7140 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
7141 nonEqiX = kTRUE;
7142 nxaxis++;
7143 sxaxis += nxaxis;
7144 out << " Double_t "<<sxaxis<<"[" << GetXaxis()->GetXbins()->fN
7145 << "] = {";
7146 for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
7147 if (i != 0) out << ", ";
7148 out << GetXaxis()->GetXbins()->fArray[i];
7149 }
7150 out << "}; " << std::endl;
7151 }
7152 // If the histogram is 2 or 3 dimensional, check if the histogram
7153 // has equidistant Y bins or not. If not, we create an array
7154 // holding the bins.
7155 if (fDimension > 1 && GetYaxis()->GetXbins()->fN &&
7156 GetYaxis()->GetXbins()->fArray) {
7157 nonEqiY = kTRUE;
7158 nyaxis++;
7159 syaxis += nyaxis;
7160 out << " Double_t "<<syaxis<<"[" << GetYaxis()->GetXbins()->fN
7161 << "] = {";
7162 for (i = 0; i < GetYaxis()->GetXbins()->fN; i++) {
7163 if (i != 0) out << ", ";
7164 out << GetYaxis()->GetXbins()->fArray[i];
7165 }
7166 out << "}; " << std::endl;
7167 }
7168 // IF the histogram is 3 dimensional, check if the histogram
7169 // has equidistant Z bins or not. If not, we create an array
7170 // holding the bins.
7171 if (fDimension > 2 && GetZaxis()->GetXbins()->fN &&
7172 GetZaxis()->GetXbins()->fArray) {
7173 nonEqiZ = kTRUE;
7174 nzaxis++;
7175 szaxis += nzaxis;
7176 out << " Double_t "<<szaxis<<"[" << GetZaxis()->GetXbins()->fN
7177 << "] = {";
7178 for (i = 0; i < GetZaxis()->GetXbins()->fN; i++) {
7179 if (i != 0) out << ", ";
7180 out << GetZaxis()->GetXbins()->fArray[i];
7181 }
7182 out << "}; " << std::endl;
7183 }
7184
7185 char quote = '"';
7186 out <<" "<<std::endl;
7187 out <<" "<< ClassName() <<" *";
7188
7189 // Histogram pointer has by default the histogram name with an incremental suffix.
7190 // If the histogram belongs to a graph or a stack the suffix is not added because
7191 // the graph and stack objects are not aware of this new name. Same thing if
7192 // the histogram is drawn with the option COLZ because the TPaletteAxis drawn
7193 // when this option is selected, does not know this new name either.
7194 TString opt = option;
7195 opt.ToLower();
7196 static Int_t hcounter = 0;
7197 TString histName = GetName();
7198 if ( !histName.Contains("Graph")
7199 && !histName.Contains("_stack_")
7200 && !opt.Contains("colz")) {
7201 hcounter++;
7202 histName += "__";
7203 histName += hcounter;
7204 }
7205 histName = gInterpreter-> MapCppName(histName);
7206 const char *hname = histName.Data();
7207 if (!strlen(hname)) hname = "unnamed";
7208 TString savedName = GetName();
7209 this->SetName(hname);
7210 TString t(GetTitle());
7211 t.ReplaceAll("\\","\\\\");
7212 t.ReplaceAll("\"","\\\"");
7213 out << hname << " = new " << ClassName() << "(" << quote
7214 << hname << quote << "," << quote<< t.Data() << quote
7215 << "," << GetXaxis()->GetNbins();
7216 if (nonEqiX)
7217 out << ", "<<sxaxis;
7218 else
7219 out << "," << GetXaxis()->GetXmin()
7220 << "," << GetXaxis()->GetXmax();
7221 if (fDimension > 1) {
7222 out << "," << GetYaxis()->GetNbins();
7223 if (nonEqiY)
7224 out << ", "<<syaxis;
7225 else
7226 out << "," << GetYaxis()->GetXmin()
7227 << "," << GetYaxis()->GetXmax();
7228 }
7229 if (fDimension > 2) {
7230 out << "," << GetZaxis()->GetNbins();
7231 if (nonEqiZ)
7232 out << ", "<<szaxis;
7233 else
7234 out << "," << GetZaxis()->GetXmin()
7235 << "," << GetZaxis()->GetXmax();
7236 }
7237 out << ");" << std::endl;
7238
7239 // save bin contents
7240 Int_t bin;
7241 for (bin=0;bin<fNcells;bin++) {
7242 Double_t bc = RetrieveBinContent(bin);
7243 if (bc) {
7244 out<<" "<<hname<<"->SetBinContent("<<bin<<","<<bc<<");"<<std::endl;
7245 }
7246 }
7247
7248 // save bin errors
7249 if (fSumw2.fN) {
7250 for (bin=0;bin<fNcells;bin++) {
7251 Double_t be = GetBinError(bin);
7252 if (be) {
7253 out<<" "<<hname<<"->SetBinError("<<bin<<","<<be<<");"<<std::endl;
7254 }
7255 }
7256 }
7257
7258 TH1::SavePrimitiveHelp(out, hname, option);
7259 this->SetName(savedName.Data());
7260}
7261
7262////////////////////////////////////////////////////////////////////////////////
7263/// Helper function for the SavePrimitive functions from TH1
7264/// or classes derived from TH1, eg TProfile, TProfile2D.
7265
7266void TH1::SavePrimitiveHelp(std::ostream &out, const char *hname, Option_t *option /*= ""*/)
7267{
7268 char quote = '"';
7269 if (TMath::Abs(GetBarOffset()) > 1e-5) {
7270 out<<" "<<hname<<"->SetBarOffset("<<GetBarOffset()<<");"<<std::endl;
7271 }
7272 if (TMath::Abs(GetBarWidth()-1) > 1e-5) {
7273 out<<" "<<hname<<"->SetBarWidth("<<GetBarWidth()<<");"<<std::endl;
7274 }
7275 if (fMinimum != -1111) {
7276 out<<" "<<hname<<"->SetMinimum("<<fMinimum<<");"<<std::endl;
7277 }
7278 if (fMaximum != -1111) {
7279 out<<" "<<hname<<"->SetMaximum("<<fMaximum<<");"<<std::endl;
7280 }
7281 if (fNormFactor != 0) {
7282 out<<" "<<hname<<"->SetNormFactor("<<fNormFactor<<");"<<std::endl;
7283 }
7284 if (fEntries != 0) {
7285 out<<" "<<hname<<"->SetEntries("<<fEntries<<");"<<std::endl;
7286 }
7287 if (fDirectory == 0) {
7288 out<<" "<<hname<<"->SetDirectory(0);"<<std::endl;
7289 }
7290 if (TestBit(kNoStats)) {
7291 out<<" "<<hname<<"->SetStats(0);"<<std::endl;
7292 }
7293 if (fOption.Length() != 0) {
7294 out<<" "<<hname<<"->SetOption("<<quote<<fOption.Data()<<quote<<");"<<std::endl;
7295 }
7296
7297 // save contour levels
7298 Int_t ncontours = GetContour();
7299 if (ncontours > 0) {
7300 out<<" "<<hname<<"->SetContour("<<ncontours<<");"<<std::endl;
7301 Double_t zlevel;
7302 for (Int_t bin=0;bin<ncontours;bin++) {
7303 if (gPad->GetLogz()) {
7304 zlevel = TMath::Power(10,GetContourLevel(bin));
7305 } else {
7306 zlevel = GetContourLevel(bin);
7307 }
7308 out<<" "<<hname<<"->SetContourLevel("<<bin<<","<<zlevel<<");"<<std::endl;
7309 }
7310 }
7311
7312 // save list of functions
7314 TObject *obj;
7315 static Int_t funcNumber = 0;
7316 while (lnk) {
7317 obj = lnk->GetObject();
7318 obj->SavePrimitive(out,Form("nodraw #%d\n",++funcNumber));
7319 if (obj->InheritsFrom(TF1::Class())) {
7320 TString fname;
7321 fname.Form("%s%d",obj->GetName(),funcNumber);
7322 out << " " << fname << "->SetParent(" << hname << ");\n";
7323 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7324 << fname <<");"<<std::endl;
7325 } else if (obj->InheritsFrom("TPaveStats")) {
7326 out<<" "<<hname<<"->GetListOfFunctions()->Add(ptstats);"<<std::endl;
7327 out<<" ptstats->SetParent("<<hname<<");"<<std::endl;
7328 } else if (obj->InheritsFrom("TPolyMarker")) {
7329 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7330 <<"pmarker ,"<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
7331 } else {
7332 out<<" "<<hname<<"->GetListOfFunctions()->Add("
7333 <<obj->GetName()
7334 <<","<<quote<<lnk->GetOption()<<quote<<");"<<std::endl;
7335 }
7336 lnk = (TObjOptLink*)lnk->Next();
7337 }
7338
7339 // save attributes
7340 SaveFillAttributes(out,hname,0,1001);
7341 SaveLineAttributes(out,hname,1,1,1);
7342 SaveMarkerAttributes(out,hname,1,1,1);
7343 fXaxis.SaveAttributes(out,hname,"->GetXaxis()");
7344 fYaxis.SaveAttributes(out,hname,"->GetYaxis()");
7345 fZaxis.SaveAttributes(out,hname,"->GetZaxis()");
7346 TString opt = option;
7347 opt.ToLower();
7348 if (!opt.Contains("nodraw")) {
7349 out<<" "<<hname<<"->Draw("
7350 <<quote<<option<<quote<<");"<<std::endl;
7351 }
7352}
7353
7354////////////////////////////////////////////////////////////////////////////////
7355/// Copy current attributes from/to current style
7356
7358{
7359 if (!gStyle) return;
7360 if (gStyle->IsReading()) {
7361 fXaxis.ResetAttAxis("X");
7362 fYaxis.ResetAttAxis("Y");
7363 fZaxis.ResetAttAxis("Z");
7374 Int_t dostat = gStyle->GetOptStat();
7375 if (gStyle->GetOptFit() && !dostat) dostat = 1000000001;
7376 SetStats(dostat);
7377 } else {
7389 }
7390 TIter next(GetListOfFunctions());
7391 TObject *obj;
7392
7393 while ((obj = next())) {
7394 obj->UseCurrentStyle();
7395 }
7396}
7397
7398////////////////////////////////////////////////////////////////////////////////
7399/// For axis = 1,2 or 3 returns the mean value of the histogram along
7400/// X,Y or Z axis.
7401///
7402/// For axis = 11, 12, 13 returns the standard error of the mean value
7403/// of the histogram along X, Y or Z axis
7404///
7405/// Note that the mean value/StdDev is computed using the bins in the currently
7406/// defined range (see TAxis::SetRange). By default the range includes
7407/// all bins from 1 to nbins included, excluding underflows and overflows.
7408/// To force the underflows and overflows in the computation, one must
7409/// call the static function TH1::StatOverflows(kTRUE) before filling
7410/// the histogram.
7411///
7412/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7413/// are calculated. By default, if no range has been set, the returned mean is
7414/// the (unbinned) one calculated at fill time. If a range has been set, however,
7415/// the mean is calculated using the bins in range, as described above; THIS
7416/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7417/// the range. To ensure that the returned mean (and all other statistics) is
7418/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7419/// See TH1::GetStats.
7420///
7421/// Return mean value of this histogram along the X axis.
7422///
7423/// Note that the mean value/StdDev is computed using the bins in the currently
7424/// defined range (see TAxis::SetRange). By default the range includes
7425/// all bins from 1 to nbins included, excluding underflows and overflows.
7426/// To force the underflows and overflows in the computation, one must
7427/// call the static function TH1::StatOverflows(kTRUE) before filling
7428/// the histogram.
7429
7430Double_t TH1::GetMean(Int_t axis) const
7431{
7432 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7433 Double_t stats[kNstat];
7434 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7435 GetStats(stats);
7436 if (stats[0] == 0) return 0;
7437 if (axis<4){
7438 Int_t ax[3] = {2,4,7};
7439 return stats[ax[axis-1]]/stats[0];
7440 } else {
7441 // mean error = StdDev / sqrt( Neff )
7442 Double_t stddev = GetStdDev(axis-10);
7444 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7445 }
7446}
7447
7448////////////////////////////////////////////////////////////////////////////////
7449/// Return standard error of mean of this histogram along the X axis.
7450///
7451/// Note that the mean value/StdDev is computed using the bins in the currently
7452/// defined range (see TAxis::SetRange). By default the range includes
7453/// all bins from 1 to nbins included, excluding underflows and overflows.
7454/// To force the underflows and overflows in the computation, one must
7455/// call the static function TH1::StatOverflows(kTRUE) before filling
7456/// the histogram.
7457///
7458/// Also note, that although the definition of standard error doesn't include the
7459/// assumption of normality, many uses of this feature implicitly assume it.
7460///
7461/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7462/// are calculated. By default, if no range has been set, the returned value is
7463/// the (unbinned) one calculated at fill time. If a range has been set, however,
7464/// the value is calculated using the bins in range, as described above; THIS
7465/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7466/// the range. To ensure that the returned value (and all other statistics) is
7467/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7468/// See TH1::GetStats.
7469
7471{
7472 return GetMean(axis+10);
7473}
7474
7475////////////////////////////////////////////////////////////////////////////////
7476/// Returns the Standard Deviation (Sigma).
7477/// The Sigma estimate is computed as
7478/// \f[
7479/// \sqrt{\frac{1}{N}(\sum(x_i-x_{mean})^2)}
7480/// \f]
7481/// For axis = 1,2 or 3 returns the Sigma value of the histogram along
7482/// X, Y or Z axis
7483/// For axis = 11, 12 or 13 returns the error of StdDev estimation along
7484/// X, Y or Z axis for Normal distribution
7485///
7486/// Note that the mean value/sigma is computed using the bins in the currently
7487/// defined range (see TAxis::SetRange). By default the range includes
7488/// all bins from 1 to nbins included, excluding underflows and overflows.
7489/// To force the underflows and overflows in the computation, one must
7490/// call the static function TH1::StatOverflows(kTRUE) before filling
7491/// the histogram.
7492///
7493/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7494/// are calculated. By default, if no range has been set, the returned standard
7495/// deviation is the (unbinned) one calculated at fill time. If a range has been
7496/// set, however, the standard deviation is calculated using the bins in range,
7497/// as described above; THIS IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use
7498/// TAxis::SetRange(0, 0) to unset the range. To ensure that the returned standard
7499/// deviation (and all other statistics) is always that of the binned data stored
7500/// in the histogram, call TH1::ResetStats. See TH1::GetStats.
7501
7502Double_t TH1::GetStdDev(Int_t axis) const
7503{
7504 if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
7505
7506 Double_t x, stddev2, stats[kNstat];
7507 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7508 GetStats(stats);
7509 if (stats[0] == 0) return 0;
7510 Int_t ax[3] = {2,4,7};
7511 Int_t axm = ax[axis%10 - 1];
7512 x = stats[axm]/stats[0];
7513 // for negative stddev (e.g. when having negative weights) - return stdev=0
7514 stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7515 if (axis<10)
7516 return TMath::Sqrt(stddev2);
7517 else {
7518 // The right formula for StdDev error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
7519 // formula valid for only gaussian distribution ( 4-th momentum = 3 * sigma^4 )
7521 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7522 }
7523}
7524
7525////////////////////////////////////////////////////////////////////////////////
7526/// Return error of standard deviation estimation for Normal distribution
7527///
7528/// Note that the mean value/StdDev is computed using the bins in the currently
7529/// defined range (see TAxis::SetRange). By default the range includes
7530/// all bins from 1 to nbins included, excluding underflows and overflows.
7531/// To force the underflows and overflows in the computation, one must
7532/// call the static function TH1::StatOverflows(kTRUE) before filling
7533/// the histogram.
7534///
7535/// Value returned is standard deviation of sample standard deviation.
7536/// Note that it is an approximated value which is valid only in the case that the
7537/// original data distribution is Normal. The correct one would require
7538/// the 4-th momentum value, which cannot be accurately estimated from an histogram since
7539/// the x-information for all entries is not kept.
7540///
7541/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7542/// are calculated. By default, if no range has been set, the returned value is
7543/// the (unbinned) one calculated at fill time. If a range has been set, however,
7544/// the value is calculated using the bins in range, as described above; THIS
7545/// IS TRUE EVEN IF THE RANGE INCLUDES ALL BINS--use TAxis::SetRange(0, 0) to unset
7546/// the range. To ensure that the returned value (and all other statistics) is
7547/// always that of the binned data stored in the histogram, call TH1::ResetStats.
7548/// See TH1::GetStats.
7549
7551{
7552 return GetStdDev(axis+10);
7553}
7554
7555////////////////////////////////////////////////////////////////////////////////
7556/// - For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
7557/// - For axis = 11, 12 or 13 returns the approximate standard error of skewness
7558/// of the histogram along x, y or z axis
7559///
7560///Note, that since third and fourth moment are not calculated
7561///at the fill time, skewness and its standard error are computed bin by bin
7562///
7563/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7564/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7565
7567{
7568
7569 if (axis > 0 && axis <= 3){
7570
7571 Double_t mean = GetMean(axis);
7572 Double_t stddev = GetStdDev(axis);
7573 Double_t stddev3 = stddev*stddev*stddev;
7574
7575 Int_t firstBinX = fXaxis.GetFirst();
7576 Int_t lastBinX = fXaxis.GetLast();
7577 Int_t firstBinY = fYaxis.GetFirst();
7578 Int_t lastBinY = fYaxis.GetLast();
7579 Int_t firstBinZ = fZaxis.GetFirst();
7580 Int_t lastBinZ = fZaxis.GetLast();
7581 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7584 if (firstBinX == 1) firstBinX = 0;
7585 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7586 }
7588 if (firstBinY == 1) firstBinY = 0;
7589 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7590 }
7592 if (firstBinZ == 1) firstBinZ = 0;
7593 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7594 }
7595 }
7596
7597 Double_t x = 0;
7598 Double_t sum=0;
7599 Double_t np=0;
7600 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7601 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7602 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7603 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7604 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7605 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7606 Double_t w = GetBinContent(binx,biny,binz);
7607 np+=w;
7608 sum+=w*(x-mean)*(x-mean)*(x-mean);
7609 }
7610 }
7611 }
7612 sum/=np*stddev3;
7613 return sum;
7614 }
7615 else if (axis > 10 && axis <= 13) {
7616 //compute standard error of skewness
7617 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7619 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7620 }
7621 else {
7622 Error("GetSkewness", "illegal value of parameter");
7623 return 0;
7624 }
7625}
7626
7627////////////////////////////////////////////////////////////////////////////////
7628/// - For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
7629/// Kurtosis(gaussian(0, 1)) = 0.
7630/// - For axis =11, 12 or 13 returns the approximate standard error of kurtosis
7631/// of the histogram along x, y or z axis
7632////
7633/// Note, that since third and fourth moment are not calculated
7634/// at the fill time, kurtosis and its standard error are computed bin by bin
7635///
7636/// IMPORTANT NOTE: The returned value depends on how the histogram statistics
7637/// are calculated. See TH1::GetMean and TH1::GetStdDev.
7638
7640{
7641 if (axis > 0 && axis <= 3){
7642
7643 Double_t mean = GetMean(axis);
7644 Double_t stddev = GetStdDev(axis);
7645 Double_t stddev4 = stddev*stddev*stddev*stddev;
7646
7647 Int_t firstBinX = fXaxis.GetFirst();
7648 Int_t lastBinX = fXaxis.GetLast();
7649 Int_t firstBinY = fYaxis.GetFirst();
7650 Int_t lastBinY = fYaxis.GetLast();
7651 Int_t firstBinZ = fZaxis.GetFirst();
7652 Int_t lastBinZ = fZaxis.GetLast();
7653 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7656 if (firstBinX == 1) firstBinX = 0;
7657 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7658 }
7660 if (firstBinY == 1) firstBinY = 0;
7661 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7662 }
7664 if (firstBinZ == 1) firstBinZ = 0;
7665 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7666 }
7667 }
7668
7669 Double_t x = 0;
7670 Double_t sum=0;
7671 Double_t np=0;
7672 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7673 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7674 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7675 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7676 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7677 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7678 Double_t w = GetBinContent(binx,biny,binz);
7679 np+=w;
7680 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7681 }
7682 }
7683 }
7684 sum/=(np*stddev4);
7685 return sum-3;
7686
7687 } else if (axis > 10 && axis <= 13) {
7688 //compute standard error of skewness
7689 // assume parent normal distribution use formula from Kendall-Stuart, Vol 1 pag 243, second edition
7691 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7692 }
7693 else {
7694 Error("GetKurtosis", "illegal value of parameter");
7695 return 0;
7696 }
7697}
7698
7699////////////////////////////////////////////////////////////////////////////////
7700/// fill the array stats from the contents of this histogram
7701/// The array stats must be correctly dimensioned in the calling program.
7702///
7703/// ~~~ {.cpp}
7704/// stats[0] = sumw
7705/// stats[1] = sumw2
7706/// stats[2] = sumwx
7707/// stats[3] = sumwx2
7708/// ~~~
7709///
7710/// If no axis-subrange is specified (via TAxis::SetRange), the array stats
7711/// is simply a copy of the statistics quantities computed at filling time.
7712/// If a sub-range is specified, the function recomputes these quantities
7713/// from the bin contents in the current axis range.
7714///
7715/// IMPORTANT NOTE: This means that the returned statistics are context-dependent.
7716/// If TAxis::kAxisRange, the returned statistics are dependent on the binning;
7717/// otherwise, they are a copy of the histogram statistics computed at fill time,
7718/// which are unbinned by default (calling TH1::ResetStats forces them to use
7719/// binned statistics). You can reset TAxis::kAxisRange using TAxis::SetRange(0, 0).
7720///
7721/// Note that the mean value/StdDev is computed using the bins in the currently
7722/// defined range (see TAxis::SetRange). By default the range includes
7723/// all bins from 1 to nbins included, excluding underflows and overflows.
7724/// To force the underflows and overflows in the computation, one must
7725/// call the static function TH1::StatOverflows(kTRUE) before filling
7726/// the histogram.
7727
7728void TH1::GetStats(Double_t *stats) const
7729{
7730 if (fBuffer) ((TH1*)this)->BufferEmpty();
7731
7732 // Loop on bins (possibly including underflows/overflows)
7733 Int_t bin, binx;
7734 Double_t w,err;
7735 Double_t x;
7736 // identify the case of labels with extension of axis range
7737 // in this case the statistics in x does not make any sense
7738 Bool_t labelHist = ((const_cast<TAxis&>(fXaxis)).GetLabels() && fXaxis.CanExtend() );
7739 // fTsumw == 0 && fEntries > 0 is a special case when uses SetBinContent or calls ResetStats before
7740 if ( (fTsumw == 0 && fEntries > 0) || fXaxis.TestBit(TAxis::kAxisRange) ) {
7741 for (bin=0;bin<4;bin++) stats[bin] = 0;
7742
7743 Int_t firstBinX = fXaxis.GetFirst();
7744 Int_t lastBinX = fXaxis.GetLast();
7745 // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
7747 if (firstBinX == 1) firstBinX = 0;
7748 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7749 }
7750 for (binx = firstBinX; binx <= lastBinX; binx++) {
7751 x = fXaxis.GetBinCenter(binx);
7752 //w = TMath::Abs(RetrieveBinContent(binx));
7753 // not sure what to do here if w < 0
7754 w = RetrieveBinContent(binx);
7755 err = TMath::Abs(GetBinError(binx));
7756 stats[0] += w;
7757 stats[1] += err*err;
7758 // statistics in x makes sense only for not labels histograms
7759 if (!labelHist) {
7760 stats[2] += w*x;
7761 stats[3] += w*x*x;
7762 }
7763 }
7764 // if (stats[0] < 0) {
7765 // // in case total is negative do something ??
7766 // stats[0] = 0;
7767 // }
7768 } else {
7769 stats[0] = fTsumw;
7770 stats[1] = fTsumw2;
7771 stats[2] = fTsumwx;
7772 stats[3] = fTsumwx2;
7773 }
7774}
7775
7776////////////////////////////////////////////////////////////////////////////////
7777/// Replace current statistics with the values in array stats
7778
7779void TH1::PutStats(Double_t *stats)
7780{
7781 fTsumw = stats[0];
7782 fTsumw2 = stats[1];
7783 fTsumwx = stats[2];
7784 fTsumwx2 = stats[3];
7785}
7786
7787////////////////////////////////////////////////////////////////////////////////
7788/// Reset the statistics including the number of entries
7789/// and replace with values calculated from bin content
7790///
7791/// The number of entries is set to the total bin content or (in case of weighted histogram)
7792/// to number of effective entries
7793///
7794/// Note that, by default, before calling this function, statistics are those
7795/// computed at fill time, which are unbinned. See TH1::GetStats.
7796
7797void TH1::ResetStats()
7798{
7799 Double_t stats[kNstat] = {0};
7800 fTsumw = 0;
7801 fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
7802 GetStats(stats);
7803 PutStats(stats);
7805 // use effective entries for weighted histograms: (sum_w) ^2 / sum_w2
7806 if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
7807}
7808
7809////////////////////////////////////////////////////////////////////////////////
7810/// Return the sum of weights excluding under/overflows.
7811
7813{
7814 if (fBuffer) const_cast<TH1*>(this)->BufferEmpty();
7815
7816 Int_t bin,binx,biny,binz;
7817 Double_t sum =0;
7818 for(binz=1; binz<=fZaxis.GetNbins(); binz++) {
7819 for(biny=1; biny<=fYaxis.GetNbins(); biny++) {
7820 for(binx=1; binx<=fXaxis.GetNbins(); binx++) {
7821 bin = GetBin(binx,biny,binz);
7822 sum += RetrieveBinContent(bin);
7823 }
7824 }
7825 }
7826 return sum;
7827}
7828
7829////////////////////////////////////////////////////////////////////////////////
7830///Return integral of bin contents. Only bins in the bins range are considered.
7831///
7832/// By default the integral is computed as the sum of bin contents in the range.
7833/// if option "width" is specified, the integral is the sum of
7834/// the bin contents multiplied by the bin width in x.
7835
7836Double_t TH1::Integral(Option_t *option) const
7837{
7838 return Integral(fXaxis.GetFirst(),fXaxis.GetLast(),option);
7839}
7840
7841////////////////////////////////////////////////////////////////////////////////
7842/// Return integral of bin contents in range [binx1,binx2].
7843///
7844/// By default the integral is computed as the sum of bin contents in the range.
7845/// if option "width" is specified, the integral is the sum of
7846/// the bin contents multiplied by the bin width in x.
7847
7848Double_t TH1::Integral(Int_t binx1, Int_t binx2, Option_t *option) const
7849{
7850 double err = 0;
7851 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
7852}
7853
7854////////////////////////////////////////////////////////////////////////////////
7855/// Return integral of bin contents in range [binx1,binx2] and its error.
7856///
7857/// By default the integral is computed as the sum of bin contents in the range.
7858/// if option "width" is specified, the integral is the sum of
7859/// the bin contents multiplied by the bin width in x.
7860/// the error is computed using error propagation from the bin errors assuming that
7861/// all the bins are uncorrelated
7862
7863Double_t TH1::IntegralAndError(Int_t binx1, Int_t binx2, Double_t & error, Option_t *option) const
7864{
7865 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
7866}
7867
7868////////////////////////////////////////////////////////////////////////////////
7869/// Internal function compute integral and optionally the error between the limits
7870/// specified by the bin number values working for all histograms (1D, 2D and 3D)
7871
7872Double_t TH1::DoIntegral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error ,
7873 Option_t *option, Bool_t doError) const
7874{
7875 if (fBuffer) ((TH1*)this)->BufferEmpty();
7876
7877 Int_t nx = GetNbinsX() + 2;
7878 if (binx1 < 0) binx1 = 0;
7879 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
7880
7881 if (GetDimension() > 1) {
7882 Int_t ny = GetNbinsY() + 2;
7883 if (biny1 < 0) biny1 = 0;
7884 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
7885 } else {
7886 biny1 = 0; biny2 = 0;
7887 }
7888
7889 if (GetDimension() > 2) {
7890 Int_t nz = GetNbinsZ() + 2;
7891 if (binz1 < 0) binz1 = 0;
7892 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
7893 } else {
7894 binz1 = 0; binz2 = 0;
7895 }
7896
7897 // - Loop on bins in specified range
7898 TString opt = option;
7899 opt.ToLower();
7901 if (opt.Contains("width")) width = kTRUE;
7902
7903
7904 Double_t dx = 1., dy = .1, dz =.1;
7905 Double_t integral = 0;
7906 Double_t igerr2 = 0;
7907 for (Int_t binx = binx1; binx <= binx2; ++binx) {
7908 if (width) dx = fXaxis.GetBinWidth(binx);
7909 for (Int_t biny = biny1; biny <= biny2; ++biny) {
7910 if (width) dy = fYaxis.GetBinWidth(biny);
7911 for (Int_t binz = binz1; binz <= binz2; ++binz) {
7912 Int_t bin = GetBin(binx, biny, binz);
7913 Double_t dv = 0.0;
7914 if (width) {
7915 dz = fZaxis.GetBinWidth(binz);
7916 dv = dx * dy * dz;
7917 integral += RetrieveBinContent(bin) * dv;
7918 } else {
7919 integral += RetrieveBinContent(bin);
7920 }
7921 if (doError) {
7922 if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
7923 else igerr2 += GetBinErrorSqUnchecked(bin);
7924 }
7925 }
7926 }
7927 }
7928
7929 if (doError) error = TMath::Sqrt(igerr2);
7930 return integral;
7931}
7932
7933////////////////////////////////////////////////////////////////////////////////
7934/// Statistical test of compatibility in shape between
7935/// this histogram and h2, using the Anderson-Darling 2 sample test.
7936///
7937/// The AD 2 sample test formula are derived from the paper
7938/// F.W Scholz, M.A. Stephens "k-Sample Anderson-Darling Test".
7939///
7940/// The test is implemented in root in the ROOT::Math::GoFTest class
7941/// It is the same formula ( (6) in the paper), and also shown in
7942/// [this preprint](http://arxiv.org/pdf/0804.0380v1.pdf)
7943///
7944/// Binned data are considered as un-binned data
7945/// with identical observation happening in the bin center.
7946///
7947/// \param[in] option is a character string to specify options
7948/// - "D" Put out a line of "Debug" printout
7949/// - "T" Return the normalized A-D test statistic
7950///
7951/// - Note1: Underflow and overflow are not considered in the test
7952/// - Note2: The test works only for un-weighted histogram (i.e. representing counts)
7953/// - Note3: The histograms are not required to have the same X axis
7954/// - Note4: The test works only for 1-dimensional histograms
7955
7956Double_t TH1::AndersonDarlingTest(const TH1 *h2, Option_t *option) const
7957{
7958 Double_t advalue = 0;
7959 Double_t pvalue = AndersonDarlingTest(h2, advalue);
7960
7961 TString opt = option;
7962 opt.ToUpper();
7963 if (opt.Contains("D") ) {
7964 printf(" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
7965 }
7966 if (opt.Contains("T") ) return advalue;
7967
7968 return pvalue;
7969}
7970
7971////////////////////////////////////////////////////////////////////////////////
7972/// Same function as above but returning also the test statistic value
7973
7974Double_t TH1::AndersonDarlingTest(const TH1 *h2, Double_t & advalue) const
7975{
7976 if (GetDimension() != 1 || h2->GetDimension() != 1) {
7977 Error("AndersonDarlingTest","Histograms must be 1-D");
7978 return -1;
7979 }
7980
7981 // empty the buffer. Probably we could add as an unbinned test
7982 if (fBuffer) ((TH1*)this)->BufferEmpty();
7983
7984 // use the BinData class
7985 ROOT::Fit::BinData data1;
7986 ROOT::Fit::BinData data2;
7987
7988 ROOT::Fit::FillData(data1, this, 0);
7989 ROOT::Fit::FillData(data2, h2, 0);
7990
7991 double pvalue;
7992 ROOT::Math::GoFTest::AndersonDarling2SamplesTest(data1,data2, pvalue,advalue);
7993
7994 return pvalue;
7995}
7996
7997////////////////////////////////////////////////////////////////////////////////
7998/// Statistical test of compatibility in shape between
7999/// this histogram and h2, using Kolmogorov test.
8000/// Note that the KolmogorovTest (KS) test should in theory be used only for unbinned data
8001/// and not for binned data as in the case of the histogram (see NOTE 3 below).
8002/// So, before using this method blindly, read the NOTE 3.
8003///
8004/// Default: Ignore under- and overflow bins in comparison
8005///
8006/// \param[in] h2 histogram
8007/// \param[in] option is a character string to specify options
8008/// - "U" include Underflows in test (also for 2-dim)
8009/// - "O" include Overflows (also valid for 2-dim)
8010/// - "N" include comparison of normalizations
8011/// - "D" Put out a line of "Debug" printout
8012/// - "M" Return the Maximum Kolmogorov distance instead of prob
8013/// - "X" Run the pseudo experiments post-processor with the following procedure:
8014/// make pseudoexperiments based on random values from the parent distribution,
8015/// compare the KS distance of the pseudoexperiment to the parent
8016/// distribution, and count all the KS values above the value
8017/// obtained from the original data to Monte Carlo distribution.
8018/// The number of pseudo-experiments nEXPT is currently fixed at 1000.
8019/// The function returns the probability.
8020/// (thanks to Ben Kilminster to submit this procedure). Note that
8021/// this option "X" is much slower.
8022///
8023/// The returned function value is the probability of test
8024/// (much less than one means NOT compatible)
8025///
8026/// Code adapted by Rene Brun from original HBOOK routine HDIFF
8027///
8028/// NOTE1
8029/// A good description of the Kolmogorov test can be seen at:
8030/// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
8031///
8032/// NOTE2
8033/// see also alternative function TH1::Chi2Test
8034/// The Kolmogorov test is assumed to give better results than Chi2Test
8035/// in case of histograms with low statistics.
8036///
8037/// NOTE3 (Jan Conrad, Fred James)
8038/// "The returned value PROB is calculated such that it will be
8039/// uniformly distributed between zero and one for compatible histograms,
8040/// provided the data are not binned (or the number of bins is very large
8041/// compared with the number of events). Users who have access to unbinned
8042/// data and wish exact confidence levels should therefore not put their data
8043/// into histograms, but should call directly TMath::KolmogorovTest. On
8044/// the other hand, since TH1 is a convenient way of collecting data and
8045/// saving space, this function has been provided. However, the values of
8046/// PROB for binned data will be shifted slightly higher than expected,
8047/// depending on the effects of the binning. For example, when comparing two
8048/// uniform distributions of 500 events in 100 bins, the values of PROB,
8049/// instead of being exactly uniformly distributed between zero and one, have
8050/// a mean value of about 0.56. We can apply a useful
8051/// rule: As long as the bin width is small compared with any significant
8052/// physical effect (for example the experimental resolution) then the binning
8053/// cannot have an important effect. Therefore, we believe that for all
8054/// practical purposes, the probability value PROB is calculated correctly
8055/// provided the user is aware that:
8056///
8057/// 1. The value of PROB should not be expected to have exactly the correct
8058/// distribution for binned data.
8059/// 2. The user is responsible for seeing to it that the bin widths are
8060/// small compared with any physical phenomena of interest.
8061/// 3. The effect of binning (if any) is always to make the value of PROB
8062/// slightly too big. That is, setting an acceptance criterion of (PROB>0.05
8063/// will assure that at most 5% of truly compatible histograms are rejected,
8064/// and usually somewhat less."
8065///
8066/// Note also that for GoF test of unbinned data ROOT provides also the class
8067/// ROOT::Math::GoFTest. The class has also method for doing one sample tests
8068/// (i.e. comparing the data with a given distribution).
8069
8070Double_t TH1::KolmogorovTest(const TH1 *h2, Option_t *option) const
8071{
8072 TString opt = option;
8073 opt.ToUpper();
8074
8075 Double_t prob = 0;
8076 TH1 *h1 = (TH1*)this;
8077 if (h2 == 0) return 0;
8078 const TAxis *axis1 = h1->GetXaxis();
8079 const TAxis *axis2 = h2->GetXaxis();
8080 Int_t ncx1 = axis1->GetNbins();
8081 Int_t ncx2 = axis2->GetNbins();
8082
8083 // Check consistency of dimensions
8084 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
8085 Error("KolmogorovTest","Histograms must be 1-D\n");
8086 return 0;
8087 }
8088
8089 // Check consistency in number of channels
8090 if (ncx1 != ncx2) {
8091 Error("KolmogorovTest","Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
8092 return 0;
8093 }
8094
8095 // empty the buffer. Probably we could add as an unbinned test
8096 if (fBuffer) ((TH1*)this)->BufferEmpty();
8097
8098 // Check consistency in bin edges
8099 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
8100 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
8101 Error("KolmogorovTest","Histograms are not consistent: they have different bin edges");
8102 return 0;
8103 }
8104 }
8105
8106 Bool_t afunc1 = kFALSE;
8107 Bool_t afunc2 = kFALSE;
8108 Double_t sum1 = 0, sum2 = 0;
8109 Double_t ew1, ew2, w1 = 0, w2 = 0;
8110 Int_t bin;
8111 Int_t ifirst = 1;
8112 Int_t ilast = ncx1;
8113 // integral of all bins (use underflow/overflow if option)
8114 if (opt.Contains("U")) ifirst = 0;
8115 if (opt.Contains("O")) ilast = ncx1 +1;
8116 for (bin = ifirst; bin <= ilast; bin++) {
8117 sum1 += h1->RetrieveBinContent(bin);
8118 sum2 += h2->RetrieveBinContent(bin);
8119 ew1 = h1->GetBinError(bin);
8120 ew2 = h2->GetBinError(bin);
8121 w1 += ew1*ew1;
8122 w2 += ew2*ew2;
8123 }
8124 if (sum1 == 0) {
8125 Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
8126 return 0;
8127 }
8128 if (sum2 == 0) {
8129 Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
8130 return 0;
8131 }
8132
8133 // calculate the effective entries.
8134 // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
8135 // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
8136 Double_t esum1 = 0, esum2 = 0;
8137 if (w1 > 0)
8138 esum1 = sum1 * sum1 / w1;
8139 else
8140 afunc1 = kTRUE; // use later for calculating z
8141
8142 if (w2 > 0)
8143 esum2 = sum2 * sum2 / w2;
8144 else
8145 afunc2 = kTRUE; // use later for calculating z
8146
8147 if (afunc2 && afunc1) {
8148 Error("KolmogorovTest","Errors are zero for both histograms\n");
8149 return 0;
8150 }
8151
8152
8153 Double_t s1 = 1/sum1;
8154 Double_t s2 = 1/sum2;
8155
8156 // Find largest difference for Kolmogorov Test
8157 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
8158
8159 for (bin=ifirst;bin<=ilast;bin++) {
8160 rsum1 += s1*h1->RetrieveBinContent(bin);
8161 rsum2 += s2*h2->RetrieveBinContent(bin);
8162 dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
8163 }
8164
8165 // Get Kolmogorov probability
8166 Double_t z, prb1=0, prb2=0, prb3=0;
8167
8168 // case h1 is exact (has zero errors)
8169 if (afunc1)
8170 z = dfmax*TMath::Sqrt(esum2);
8171 // case h2 has zero errors
8172 else if (afunc2)
8173 z = dfmax*TMath::Sqrt(esum1);
8174 else
8175 // for comparison between two data sets
8176 z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
8177
8178 prob = TMath::KolmogorovProb(z);
8179
8180 // option N to combine normalization makes sense if both afunc1 and afunc2 are false
8181 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
8182 // Combine probabilities for shape and normalization,
8183 prb1 = prob;
8184 Double_t d12 = esum1-esum2;
8185 Double_t chi2 = d12*d12/(esum1+esum2);
8186 prb2 = TMath::Prob(chi2,1);
8187 // see Eadie et al., section 11.6.2
8188 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
8189 else prob = 0;
8190 }
8191 // X option. Pseudo-experiments post-processor to determine KS probability
8192 const Int_t nEXPT = 1000;
8193 if (opt.Contains("X") && !(afunc1 || afunc2 ) ) {
8194 Double_t dSEXPT;
8195 TH1 *h1_cpy = (TH1 *)(gDirectory ? gDirectory->CloneObject(this, kFALSE) : gROOT->CloneObject(this, kFALSE));
8196 TH1 *h1Expt = (TH1*)(gDirectory ? gDirectory->CloneObject(this,kFALSE) : gROOT->CloneObject(this,kFALSE));
8197 TH1 *h2Expt = (TH1*)(gDirectory ? gDirectory->CloneObject(this,kFALSE) : gROOT->CloneObject(this,kFALSE));
8198
8199 if (GetMinimum() < 0.0) {
8200 // we need to create a new histogram
8201 // With negative bins we can't draw random samples in a meaningful way.
8202 Warning("KolmogorovTest", "Detected bins with negative weights, these have been ignored and output might be "
8203 "skewed. Reduce number of bins for histogram?");
8204 while (h1_cpy->GetMinimum() < 0.0) {
8205 Int_t idx = h1_cpy->GetMinimumBin();
8206 h1_cpy->SetBinContent(idx, 0.0);
8207 }
8208 }
8209
8210 // make nEXPT experiments (this should be a parameter)
8211 prb3 = 0;
8212 for (Int_t i=0; i < nEXPT; i++) {
8213 h1Expt->Reset();
8214 h2Expt->Reset();
8215 h1Expt->FillRandom(h1_cpy, (Int_t)esum1);
8216 h2Expt->FillRandom(h1_cpy, (Int_t)esum2);
8217 dSEXPT = h1Expt->KolmogorovTest(h2Expt,"M");
8218 if (dSEXPT>dfmax) prb3 += 1.0;
8219 }
8220 prb3 /= (Double_t)nEXPT;
8221 delete h1_cpy;
8222 delete h1Expt;
8223 delete h2Expt;
8224 }
8225
8226 // debug printout
8227 if (opt.Contains("D")) {
8228 printf(" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
8229 printf(" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
8230 printf(" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
8231 if (opt.Contains("N"))
8232 printf(" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
8233 if (opt.Contains("X"))
8234 printf(" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
8235 }
8236 // This numerical error condition should never occur:
8237 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
8238 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
8239
8240 if(opt.Contains("M")) return dfmax;
8241 else if(opt.Contains("X")) return prb3;
8242 else return prob;
8243}
8244
8245////////////////////////////////////////////////////////////////////////////////
8246/// Replace bin contents by the contents of array content
8247
8248void TH1::SetContent(const Double_t *content)
8249{
8250 fEntries = fNcells;
8251 fTsumw = 0;
8252 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
8253}
8254
8255////////////////////////////////////////////////////////////////////////////////
8256/// Return contour values into array levels if pointer levels is non zero.
8257///
8258/// The function returns the number of contour levels.
8259/// see GetContourLevel to return one contour only
8260
8262{
8263 Int_t nlevels = fContour.fN;
8264 if (levels) {
8265 if (nlevels == 0) {
8266 nlevels = 20;
8267 SetContour(nlevels);
8268 } else {
8269 if (TestBit(kUserContour) == 0) SetContour(nlevels);
8270 }
8271 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
8272 }
8273 return nlevels;
8274}
8275
8276////////////////////////////////////////////////////////////////////////////////
8277/// Return value of contour number level.
8278/// Use GetContour to return the array of all contour levels
8279
8281{
8282 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
8283}
8284
8285////////////////////////////////////////////////////////////////////////////////
8286/// Return the value of contour number "level" in Pad coordinates.
8287/// ie: if the Pad is in log scale along Z it returns le log of the contour level
8288/// value. See GetContour to return the array of all contour levels
8289
8291{
8292 if (level <0 || level >= fContour.fN) return 0;
8293 Double_t zlevel = fContour.fArray[level];
8294
8295 // In case of user defined contours and Pad in log scale along Z,
8296 // fContour.fArray doesn't contain the log of the contour whereas it does
8297 // in case of equidistant contours.
8298 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
8299 if (zlevel <= 0) return 0;
8300 zlevel = TMath::Log10(zlevel);
8301 }
8302 return zlevel;
8303}
8304
8305////////////////////////////////////////////////////////////////////////////////
8306/// Set the maximum number of entries to be kept in the buffer.
8307
8308void TH1::SetBuffer(Int_t buffersize, Option_t * /*option*/)
8309{
8310 if (fBuffer) {
8311 BufferEmpty();
8312 delete [] fBuffer;
8313 fBuffer = 0;
8314 }
8315 if (buffersize <= 0) {
8316 fBufferSize = 0;
8317 return;
8318 }
8319 if (buffersize < 100) buffersize = 100;
8320 fBufferSize = 1 + buffersize*(fDimension+1);
8322 memset(fBuffer,0,sizeof(Double_t)*fBufferSize);
8323}
8324
8325////////////////////////////////////////////////////////////////////////////////
8326/// Set the number and values of contour levels.
8327///
8328/// By default the number of contour levels is set to 20. The contours values
8329/// in the array "levels" should be specified in increasing order.
8330///
8331/// if argument levels = 0 or missing, equidistant contours are computed
8332
8333void TH1::SetContour(Int_t nlevels, const Double_t *levels)
8334{
8335 Int_t level;
8337 if (nlevels <=0 ) {
8338 fContour.Set(0);
8339 return;
8340 }
8341 fContour.Set(nlevels);
8342
8343 // - Contour levels are specified
8344 if (levels) {
8346 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
8347 } else {
8348 // - contour levels are computed automatically as equidistant contours
8349 Double_t zmin = GetMinimum();
8350 Double_t zmax = GetMaximum();
8351 if ((zmin == zmax) && (zmin != 0)) {
8352 zmax += 0.01*TMath::Abs(zmax);
8353 zmin -= 0.01*TMath::Abs(zmin);
8354 }
8355 Double_t dz = (zmax-zmin)/Double_t(nlevels);
8356 if (gPad && gPad->GetLogz()) {
8357 if (zmax <= 0) return;
8358 if (zmin <= 0) zmin = 0.001*zmax;
8359 zmin = TMath::Log10(zmin);
8360 zmax = TMath::Log10(zmax);
8361 dz = (zmax-zmin)/Double_t(nlevels);
8362 }
8363 for (level=0; level<nlevels; level++) {
8364 fContour.fArray[level] = zmin + dz*Double_t(level);
8365 }
8366 }
8367}
8368
8369////////////////////////////////////////////////////////////////////////////////
8370/// Set value for one contour level.
8371
8372void TH1::SetContourLevel(Int_t level, Double_t value)
8373{
8374 if (level < 0 || level >= fContour.fN) return;
8376 fContour.fArray[level] = value;
8377}
8378
8379////////////////////////////////////////////////////////////////////////////////
8380/// Return maximum value smaller than maxval of bins in the range,
8381/// unless the value has been overridden by TH1::SetMaximum,
8382/// in which case it returns that value. (This happens, for example,
8383/// when the histogram is drawn and the y or z axis limits are changed
8384///
8385/// To get the maximum value of bins in the histogram regardless of
8386/// whether the value has been overridden, use
8387///
8388/// ~~~ {.cpp}
8389/// h->GetBinContent(h->GetMaximumBin())
8390/// ~~~
8391
8392Double_t TH1::GetMaximum(Double_t maxval) const
8393{
8394 if (fMaximum != -1111) return fMaximum;
8395
8396 // empty the buffer
8397 if (fBuffer) ((TH1*)this)->BufferEmpty();
8398
8399 Int_t bin, binx, biny, binz;
8400 Int_t xfirst = fXaxis.GetFirst();
8401 Int_t xlast = fXaxis.GetLast();
8402 Int_t yfirst = fYaxis.GetFirst();
8403 Int_t ylast = fYaxis.GetLast();
8404 Int_t zfirst = fZaxis.GetFirst();
8405 Int_t zlast = fZaxis.GetLast();
8406 Double_t maximum = -FLT_MAX, value;
8407 for (binz=zfirst;binz<=zlast;binz++) {
8408 for (biny=yfirst;biny<=ylast;biny++) {
8409 for (binx=xfirst;binx<=xlast;binx++) {
8410 bin = GetBin(binx,biny,binz);
8411 value = RetrieveBinContent(bin);
8412 if (value > maximum && value < maxval) maximum = value;
8413 }
8414 }
8415 }
8416 return maximum;
8417}
8418
8419////////////////////////////////////////////////////////////////////////////////
8420/// Return location of bin with maximum value in the range.
8421
8423{
8424 Int_t locmax, locmay, locmaz;
8425 return GetMaximumBin(locmax, locmay, locmaz);
8426}
8427
8428////////////////////////////////////////////////////////////////////////////////
8429/// Return location of bin with maximum value in the range.
8430
8431Int_t TH1::GetMaximumBin(Int_t &locmax, Int_t &locmay, Int_t &locmaz) const
8432{
8433 // empty the buffer
8434 if (fBuffer) ((TH1*)this)->BufferEmpty();
8435
8436 Int_t bin, binx, biny, binz;
8437 Int_t locm;
8438 Int_t xfirst = fXaxis.GetFirst();
8439 Int_t xlast = fXaxis.GetLast();
8440 Int_t yfirst = fYaxis.GetFirst();
8441 Int_t ylast = fYaxis.GetLast();
8442 Int_t zfirst = fZaxis.GetFirst();
8443 Int_t zlast = fZaxis.GetLast();
8444 Double_t maximum = -FLT_MAX, value;
8445 locm = locmax = locmay = locmaz = 0;
8446 for (binz=zfirst;binz<=zlast;binz++) {
8447 for (biny=yfirst;biny<=ylast;biny++) {
8448 for (binx=xfirst;binx<=xlast;binx++) {
8449 bin = GetBin(binx,biny,binz);
8450 value = RetrieveBinContent(bin);
8451 if (value > maximum) {
8452 maximum = value;
8453 locm = bin;
8454 locmax = binx;
8455 locmay = biny;
8456 locmaz = binz;
8457 }
8458 }
8459 }
8460 }
8461 return locm;
8462}
8463
8464////////////////////////////////////////////////////////////////////////////////
8465/// Return minimum value larger than minval of bins in the range,
8466/// unless the value has been overridden by TH1::SetMinimum,
8467/// in which case it returns that value. (This happens, for example,
8468/// when the histogram is drawn and the y or z axis limits are changed
8469///
8470/// To get the minimum value of bins in the histogram regardless of
8471/// whether the value has been overridden, use
8472///
8473/// ~~~ {.cpp}
8474/// h->GetBinContent(h->GetMinimumBin())
8475/// ~~~
8476
8477Double_t TH1::GetMinimum(Double_t minval) const
8478{
8479 if (fMinimum != -1111) return fMinimum;
8480
8481 // empty the buffer
8482 if (fBuffer) ((TH1*)this)->BufferEmpty();
8483
8484 Int_t bin, binx, biny, binz;
8485 Int_t xfirst = fXaxis.GetFirst();
8486 Int_t xlast = fXaxis.GetLast();
8487 Int_t yfirst = fYaxis.GetFirst();
8488 Int_t ylast = fYaxis.GetLast();
8489 Int_t zfirst = fZaxis.GetFirst();
8490 Int_t zlast = fZaxis.GetLast();
8491 Double_t minimum=FLT_MAX, value;
8492 for (binz=zfirst;binz<=zlast;binz++) {
8493 for (biny=yfirst;biny<=ylast;biny++) {
8494 for (binx=xfirst;binx<=xlast;binx++) {
8495 bin = GetBin(binx,biny,binz);
8496 value = RetrieveBinContent(bin);
8497 if (value < minimum && value > minval) minimum = value;
8498 }
8499 }
8500 }
8501 return minimum;
8502}
8503
8504////////////////////////////////////////////////////////////////////////////////
8505/// Return location of bin with minimum value in the range.
8506
8508{
8509 Int_t locmix, locmiy, locmiz;
8510 return GetMinimumBin(locmix, locmiy, locmiz);
8511}
8512
8513////////////////////////////////////////////////////////////////////////////////
8514/// Return location of bin with minimum value in the range.
8515
8516Int_t TH1::GetMinimumBin(Int_t &locmix, Int_t &locmiy, Int_t &locmiz) const
8517{
8518 // empty the buffer
8519 if (fBuffer) ((TH1*)this)->BufferEmpty();
8520
8521 Int_t bin, binx, biny, binz;
8522 Int_t locm;
8523 Int_t xfirst = fXaxis.GetFirst();
8524 Int_t xlast = fXaxis.GetLast();
8525 Int_t yfirst = fYaxis.GetFirst();
8526 Int_t ylast = fYaxis.GetLast();
8527 Int_t zfirst = fZaxis.GetFirst();
8528 Int_t zlast = fZaxis.GetLast();
8529 Double_t minimum = FLT_MAX, value;
8530 locm = locmix = locmiy = locmiz = 0;
8531 for (binz=zfirst;binz<=zlast;binz++) {
8532 for (biny=yfirst;biny<=ylast;biny++) {
8533 for (binx=xfirst;binx<=xlast;binx++) {
8534 bin = GetBin(binx,biny,binz);
8535 value = RetrieveBinContent(bin);
8536 if (value < minimum) {
8537 minimum = value;
8538 locm = bin;
8539 locmix = binx;
8540 locmiy = biny;
8541 locmiz = binz;
8542 }
8543 }
8544 }
8545 }
8546 return locm;
8547}
8548
8549///////////////////////////////////////////////////////////////////////////////
8550/// Retrieve the minimum and maximum values in the histogram
8551///
8552/// This will not return a cached value and will always search the
8553/// histogram for the min and max values. The user can condition whether
8554/// or not to call this with the GetMinimumStored() and GetMaximumStored()
8555/// methods. If the cache is empty, then the value will be -1111. Users
8556/// can then use the SetMinimum() or SetMaximum() methods to cache the results.
8557/// For example, the following recipe will make efficient use of this method
8558/// and the cached minimum and maximum values.
8559//
8560/// \code{.cpp}
8561/// Double_t currentMin = pHist->GetMinimumStored();
8562/// Double_t currentMax = pHist->GetMaximumStored();
8563/// if ((currentMin == -1111) || (currentMax == -1111)) {
8564/// pHist->GetMinimumAndMaximum(currentMin, currentMax);
8565/// pHist->SetMinimum(currentMin);
8566/// pHist->SetMaximum(currentMax);
8567/// }
8568/// \endcode
8569///
8570/// \param min reference to variable that will hold found minimum value
8571/// \param max reference to variable that will hold found maximum value
8572
8573void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max) const
8574{
8575 // empty the buffer
8576 if (fBuffer) ((TH1*)this)->BufferEmpty();
8577
8578 Int_t bin, binx, biny, binz;
8579 Int_t xfirst = fXaxis.GetFirst();
8580 Int_t xlast = fXaxis.GetLast();
8581 Int_t yfirst = fYaxis.GetFirst();
8582 Int_t ylast = fYaxis.GetLast();
8583 Int_t zfirst = fZaxis.GetFirst();
8584 Int_t zlast = fZaxis.GetLast();
8585 min=TMath::Infinity();
8586 max=-TMath::Infinity();
8587 Double_t value;
8588 for (binz=zfirst;binz<=zlast;binz++) {
8589 for (biny=yfirst;biny<=ylast;biny++) {
8590 for (binx=xfirst;binx<=xlast;binx++) {
8591 bin = GetBin(binx,biny,binz);
8592 value = RetrieveBinContent(bin);
8593 if (value < min) min = value;
8594 if (value > max) max = value;
8595 }
8596 }
8597 }
8598}
8599
8600////////////////////////////////////////////////////////////////////////////////
8601/// Redefine x axis parameters.
8602///
8603/// The X axis parameters are modified.
8604/// The bins content array is resized
8605/// if errors (Sumw2) the errors array is resized
8606/// The previous bin contents are lost
8607/// To change only the axis limits, see TAxis::SetRange
8608
8610{
8611 if (GetDimension() != 1) {
8612 Error("SetBins","Operation only valid for 1-d histograms");
8613 return;
8614 }
8615 fXaxis.SetRange(0,0);
8616 fXaxis.Set(nx,xmin,xmax);
8617 fYaxis.Set(1,0,1);
8618 fZaxis.Set(1,0,1);
8619 fNcells = nx+2;
8621 if (fSumw2.fN) {
8623 }
8624}
8625
8626////////////////////////////////////////////////////////////////////////////////
8627/// Redefine x axis parameters with variable bin sizes.
8628///
8629/// The X axis parameters are modified.
8630/// The bins content array is resized
8631/// if errors (Sumw2) the errors array is resized
8632/// The previous bin contents are lost
8633/// To change only the axis limits, see TAxis::SetRange
8634/// xBins is supposed to be of length nx+1
8635
8636void TH1::SetBins(Int_t nx, const Double_t *xBins)
8637{
8638 if (GetDimension() != 1) {
8639 Error("SetBins","Operation only valid for 1-d histograms");
8640 return;
8641 }
8642 fXaxis.SetRange(0,0);
8643 fXaxis.Set(nx,xBins);
8644 fYaxis.Set(1,0,1);
8645 fZaxis.Set(1,0,1);
8646 fNcells = nx+2;
8648 if (fSumw2.fN) {
8650 }
8651}
8652
8653////////////////////////////////////////////////////////////////////////////////
8654/// Redefine x and y axis parameters.
8655///
8656/// The X and Y axis parameters are modified.
8657/// The bins content array is resized
8658/// if errors (Sumw2) the errors array is resized
8659/// The previous bin contents are lost
8660/// To change only the axis limits, see TAxis::SetRange
8661
8663{
8664 if (GetDimension() != 2) {
8665 Error("SetBins","Operation only valid for 2-D histograms");
8666 return;
8667 }
8668 fXaxis.SetRange(0,0);
8669 fYaxis.SetRange(0,0);
8670 fXaxis.Set(nx,xmin,xmax);
8671 fYaxis.Set(ny,ymin,ymax);
8672 fZaxis.Set(1,0,1);
8673 fNcells = (nx+2)*(ny+2);
8675 if (fSumw2.fN) {
8677 }
8678}
8679
8680////////////////////////////////////////////////////////////////////////////////
8681/// Redefine x and y axis parameters with variable bin sizes.
8682///
8683/// The X and Y axis parameters are modified.
8684/// The bins content array is resized
8685/// if errors (Sumw2) the errors array is resized
8686/// The previous bin contents are lost
8687/// To change only the axis limits, see TAxis::SetRange
8688/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
8689
8690void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
8691{
8692 if (GetDimension() != 2) {
8693 Error("SetBins","Operation only valid for 2-D histograms");
8694 return;
8695 }
8696 fXaxis.SetRange(0,0);
8697 fYaxis.SetRange(0,0);
8698 fXaxis.Set(nx,xBins);
8699 fYaxis.Set(ny,yBins);
8700 fZaxis.Set(1,0,1);
8701 fNcells = (nx+2)*(ny+2);
8703 if (fSumw2.fN) {
8705 }
8706}
8707
8708////////////////////////////////////////////////////////////////////////////////
8709/// Redefine x, y and z axis parameters.
8710///
8711/// The X, Y and Z axis parameters are modified.
8712/// The bins content array is resized
8713/// if errors (Sumw2) the errors array is resized
8714/// The previous bin contents are lost
8715/// To change only the axis limits, see TAxis::SetRange
8716
8718{
8719 if (GetDimension() != 3) {
8720 Error("SetBins","Operation only valid for 3-D histograms");
8721 return;
8722 }
8723 fXaxis.SetRange(0,0);
8724 fYaxis.SetRange(0,0);
8725 fZaxis.SetRange(0,0);
8726 fXaxis.Set(nx,xmin,xmax);
8727 fYaxis.Set(ny,ymin,ymax);
8728 fZaxis.Set(nz,zmin,zmax);
8729 fNcells = (nx+2)*(ny+2)*(nz+2);
8731 if (fSumw2.fN) {
8733 }
8734}
8735
8736////////////////////////////////////////////////////////////////////////////////
8737/// Redefine x, y and z axis parameters with variable bin sizes.
8738///
8739/// The X, Y and Z axis parameters are modified.
8740/// The bins content array is resized
8741/// if errors (Sumw2) the errors array is resized
8742/// The previous bin contents are lost
8743/// To change only the axis limits, see TAxis::SetRange
8744/// xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
8745/// zBins is supposed to be of length nz+1
8746
8747void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
8748{
8749 if (GetDimension() != 3) {
8750 Error("SetBins","Operation only valid for 3-D histograms");
8751 return;
8752 }
8753 fXaxis.SetRange(0,0);
8754 fYaxis.SetRange(0,0);
8755 fZaxis.SetRange(0,0);
8756 fXaxis.Set(nx,xBins);
8757 fYaxis.Set(ny,yBins);
8758 fZaxis.Set(nz,zBins);
8759 fNcells = (nx+2)*(ny+2)*(nz+2);
8761 if (fSumw2.fN) {
8763 }
8764}
8765
8766////////////////////////////////////////////////////////////////////////////////
8767/// By default when an histogram is created, it is added to the list
8768/// of histogram objects in the current directory in memory.
8769/// Remove reference to this histogram from current directory and add
8770/// reference to new directory dir. dir can be 0 in which case the
8771/// histogram does not belong to any directory.
8772///
8773/// Note that the directory is not a real property of the histogram and
8774/// it will not be copied when the histogram is copied or cloned.
8775/// If the user wants to have the copied (cloned) histogram in the same
8776/// directory, he needs to set again the directory using SetDirectory to the
8777/// copied histograms
8778
8780{
8781 if (fDirectory == dir) return;
8782 if (fDirectory) fDirectory->Remove(this);
8783 fDirectory = dir;
8784 if (fDirectory) {
8786 fDirectory->Append(this);
8787 }
8788}
8789
8790////////////////////////////////////////////////////////////////////////////////
8791/// Replace bin errors by values in array error.
8792
8793void TH1::SetError(const Double_t *error)
8794{
8795 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
8796}
8797
8798////////////////////////////////////////////////////////////////////////////////
8799/// Change the name of this histogram
8801
8802void TH1::SetName(const char *name)
8803{
8804 // Histograms are named objects in a THashList.
8805 // We must update the hashlist if we change the name
8806 // We protect this operation
8808 if (fDirectory) fDirectory->Remove(this);
8809 fName = name;
8810 if (fDirectory) fDirectory->Append(this);
8811}
8812
8813////////////////////////////////////////////////////////////////////////////////
8814/// Change the name and title of this histogram
8815
8816void TH1::SetNameTitle(const char *name, const char *title)
8817{
8818 // Histograms are named objects in a THashList.
8819 // We must update the hashlist if we change the name
8820 SetName(name);
8821 SetTitle(title);
8822}
8823
8824////////////////////////////////////////////////////////////////////////////////
8825/// Set statistics option on/off.
8826///
8827/// By default, the statistics box is drawn.
8828/// The paint options can be selected via gStyle->SetOptStats.
8829/// This function sets/resets the kNoStats bit in the histogram object.
8830/// It has priority over the Style option.
8831
8832void TH1::SetStats(Bool_t stats)
8833{
8835 if (!stats) {
8837 //remove the "stats" object from the list of functions
8838 if (fFunctions) {
8839 TObject *obj = fFunctions->FindObject("stats");
8840 if (obj) {
8841 fFunctions->Remove(obj);
8842 delete obj;
8843 }
8844 }
8845 }
8846}
8847
8848////////////////////////////////////////////////////////////////////////////////
8849/// Create structure to store sum of squares of weights.
8850///
8851/// if histogram is already filled, the sum of squares of weights
8852/// is filled with the existing bin contents
8853///
8854/// The error per bin will be computed as sqrt(sum of squares of weight)
8855/// for each bin.
8856///
8857/// This function is automatically called when the histogram is created
8858/// if the static function TH1::SetDefaultSumw2 has been called before.
8859/// If flag = false the structure containing the sum of the square of weights
8860/// is rest and it will be empty, but it is not deleted (i.e. GetSumw2()->fN = 0)
8861
8862void TH1::Sumw2(Bool_t flag)
8863{
8864 if (!flag) {
8865 // clear the array if existing - do nothing otherwise
8866 if (fSumw2.fN > 0 ) fSumw2.Set(0);
8867 return;
8868 }
8869
8870 if (fSumw2.fN == fNcells) {
8871 if (!fgDefaultSumw2 )
8872 Warning("Sumw2","Sum of squares of weights structure already created");
8873 return;
8874 }
8875
8877
8878 // empty the buffer
8879 if (fBuffer) BufferEmpty();
8880
8881 if (fEntries > 0)
8882 for (Int_t i = 0; i < fNcells; ++i)
8884}
8885
8886////////////////////////////////////////////////////////////////////////////////
8887/// Return pointer to function with name.
8888///
8889///
8890/// Functions such as TH1::Fit store the fitted function in the list of
8891/// functions of this histogram.
8892
8893TF1 *TH1::GetFunction(const char *name) const
8894{
8895 return (TF1*)fFunctions->FindObject(name);
8896}
8897
8898////////////////////////////////////////////////////////////////////////////////
8899/// Return value of error associated to bin number bin.
8900///
8901/// if the sum of squares of weights has been defined (via Sumw2),
8902/// this function returns the sqrt(sum of w2).
8903/// otherwise it returns the sqrt(contents) for this bin.
8904
8906{
8907 if (bin < 0) bin = 0;
8908 if (bin >= fNcells) bin = fNcells-1;
8909 if (fBuffer) ((TH1*)this)->BufferEmpty();
8910 if (fSumw2.fN) return TMath::Sqrt(fSumw2.fArray[bin]);
8911
8913}
8914
8915////////////////////////////////////////////////////////////////////////////////
8916/// Return lower error associated to bin number bin.
8917///
8918/// The error will depend on the statistic option used will return
8919/// the binContent - lower interval value
8920
8922{
8923 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
8924 // in case of weighted histogram check if it is really weighted
8925 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
8926
8927 if (bin < 0) bin = 0;
8928 if (bin >= fNcells) bin = fNcells-1;
8929 if (fBuffer) ((TH1*)this)->BufferEmpty();
8930
8931 Double_t alpha = 1.- 0.682689492;
8932 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
8933
8935 Int_t n = int(c);
8936 if (n < 0) {
8937 Warning("GetBinErrorLow","Histogram has negative bin content-force usage to normal errors");
8938 ((TH1*)this)->fBinStatErrOpt = kNormal;
8939 return GetBinError(bin);
8940 }
8941
8942 if (n == 0) return 0;
8943 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
8944}
8945
8946////////////////////////////////////////////////////////////////////////////////
8947/// Return upper error associated to bin number bin.
8948///
8949/// The error will depend on the statistic option used will return
8950/// the binContent - upper interval value
8951
8953{
8954 if (fBinStatErrOpt == kNormal) return GetBinError(bin);
8955 // in case of weighted histogram check if it is really weighted
8956 if (fSumw2.fN && fTsumw != fTsumw2) return GetBinError(bin);
8957 if (bin < 0) bin = 0;
8958 if (bin >= fNcells) bin = fNcells-1;
8959 if (fBuffer) ((TH1*)this)->BufferEmpty();
8960
8961 Double_t alpha = 1.- 0.682689492;
8962 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
8963
8965 Int_t n = int(c);
8966 if (n < 0) {
8967 Warning("GetBinErrorUp","Histogram has negative bin content-force usage to normal errors");
8968 ((TH1*)this)->fBinStatErrOpt = kNormal;
8969 return GetBinError(bin);
8970 }
8971
8972 // for N==0 return an upper limit at 0.68 or (1-alpha)/2 ?
8973 // decide to return always (1-alpha)/2 upper interval
8974 //if (n == 0) return ROOT::Math::gamma_quantile_c(alpha,n+1,1);
8975 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
8976}
8977
8978//L.M. These following getters are useless and should be probably deprecated
8979////////////////////////////////////////////////////////////////////////////////
8980/// Return bin center for 1D histogram.
8981/// Better to use h1.GetXaxis()->GetBinCenter(bin)
8982
8984{
8985 if (fDimension == 1) return fXaxis.GetBinCenter(bin);
8986 Error("GetBinCenter","Invalid method for a %d-d histogram - return a NaN",fDimension);
8987 return TMath::QuietNaN();
8988}
8989
8990////////////////////////////////////////////////////////////////////////////////
8991/// Return bin lower edge for 1D histogram.
8992/// Better to use h1.GetXaxis()->GetBinLowEdge(bin)
8993
8995{
8996 if (fDimension == 1) return fXaxis.GetBinLowEdge(bin);
8997 Error("GetBinLowEdge","Invalid method for a %d-d histogram - return a NaN",fDimension);
8998 return TMath::QuietNaN();
8999}
9000
9001////////////////////////////////////////////////////////////////////////////////
9002/// Return bin width for 1D histogram.
9003/// Better to use h1.GetXaxis()->GetBinWidth(bin)
9004
9006{
9007 if (fDimension == 1) return fXaxis.GetBinWidth(bin);
9008 Error("GetBinWidth","Invalid method for a %d-d histogram - return a NaN",fDimension);
9009 return TMath::QuietNaN();
9010}
9011
9012////////////////////////////////////////////////////////////////////////////////
9013/// Fill array with center of bins for 1D histogram
9014/// Better to use h1.GetXaxis()->GetCenter(center)
9015
9016void TH1::GetCenter(Double_t *center) const
9017{
9018 if (fDimension == 1) {
9019 fXaxis.GetCenter(center);
9020 return;
9021 }
9022 Error("GetCenter","Invalid method for a %d-d histogram ",fDimension);
9023}
9024
9025////////////////////////////////////////////////////////////////////////////////
9026/// Fill array with low edge of bins for 1D histogram
9027/// Better to use h1.GetXaxis()->GetLowEdge(edge)
9028
9029void TH1::GetLowEdge(Double_t *edge) const
9030{
9031 if (fDimension == 1) {
9032 fXaxis.GetLowEdge(edge);
9033 return;
9034 }
9035 Error("GetLowEdge","Invalid method for a %d-d histogram ",fDimension);
9036}
9037
9038////////////////////////////////////////////////////////////////////////////////
9039/// Set the bin Error
9040/// Note that this resets the bin eror option to be of Normal Type and for the
9041/// non-empty bin the bin error is set by default to the square root of their content.
9042/// Note that in case the user sets after calling SetBinError explicitly a new bin content (e.g. using SetBinContent)
9043/// he needs then to provide also the corresponding bin error (using SetBinError) since the bin error
9044/// will not be recalculated after setting the content and a default error = 0 will be used for those bins.
9045///
9046/// See convention for numbering bins in TH1::GetBin
9047
9048void TH1::SetBinError(Int_t bin, Double_t error)
9049{
9050 if (bin < 0 || bin>= fNcells) return;
9051 if (!fSumw2.fN) Sumw2();
9052 fSumw2.fArray[bin] = error * error;
9053 // reset the bin error option
9055}
9056
9057////////////////////////////////////////////////////////////////////////////////
9058/// Set bin content
9059/// see convention for numbering bins in TH1::GetBin
9060/// In case the bin number is greater than the number of bins and
9061/// the timedisplay option is set or CanExtendAllAxes(),
9062/// the number of bins is automatically doubled to accommodate the new bin
9063
9064void TH1::SetBinContent(Int_t bin, Double_t content)
9065{
9066 fEntries++;
9067 fTsumw = 0;
9068 if (bin < 0) return;
9069 if (bin >= fNcells-1) {
9071 while (bin >= fNcells-1) LabelsInflate();
9072 } else {
9073 if (bin == fNcells-1) UpdateBinContent(bin, content);
9074 return;
9075 }
9076 }
9077 UpdateBinContent(bin, content);
9078}
9079
9080////////////////////////////////////////////////////////////////////////////////
9081/// See convention for numbering bins in TH1::GetBin
9082
9083void TH1::SetBinError(Int_t binx, Int_t biny, Double_t error)
9084{
9085 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9086 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9087 SetBinError(GetBin(binx, biny), error);
9088}
9089
9090////////////////////////////////////////////////////////////////////////////////
9091/// See convention for numbering bins in TH1::GetBin
9092
9093void TH1::SetBinError(Int_t binx, Int_t biny, Int_t binz, Double_t error)
9094{
9095 if (binx < 0 || binx > fXaxis.GetNbins() + 1) return;
9096 if (biny < 0 || biny > fYaxis.GetNbins() + 1) return;
9097 if (binz < 0 || binz > fZaxis.GetNbins() + 1) return;
9098 SetBinError(GetBin(binx, biny, binz), error);
9099}
9100
9101////////////////////////////////////////////////////////////////////////////////
9102/// This function calculates the background spectrum in this histogram.
9103/// The background is returned as a histogram.
9104///
9105/// \param[in] niter number of iterations (default value = 2)
9106/// Increasing niter make the result smoother and lower.
9107/// \param[in] option may contain one of the following options
9108/// - to set the direction parameter
9109/// "BackDecreasingWindow". By default the direction is BackIncreasingWindow
9110/// - filterOrder-order of clipping filter (default "BackOrder2")
9111/// possible values= "BackOrder4" "BackOrder6" "BackOrder8"
9112/// - "nosmoothing" - if selected, the background is not smoothed
9113/// By default the background is smoothed.
9114/// - smoothWindow - width of smoothing window, (default is "BackSmoothing3")
9115/// possible values= "BackSmoothing5" "BackSmoothing7" "BackSmoothing9"
9116/// "BackSmoothing11" "BackSmoothing13" "BackSmoothing15"
9117/// - "nocompton" - if selected the estimation of Compton edge
9118/// will be not be included (by default the compton estimation is set)
9119/// - "same" if this option is specified, the resulting background
9120/// histogram is superimposed on the picture in the current pad.
9121/// This option is given by default.
9122///
9123/// NOTE that the background is only evaluated in the current range of this histogram.
9124/// i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
9125/// the returned histogram will be created with the same number of bins
9126/// as this input histogram, but only bins from binmin to binmax will be filled
9127/// with the estimated background.
9128
9129TH1 *TH1::ShowBackground(Int_t niter, Option_t *option)
9130{
9131
9132 return (TH1*)gROOT->ProcessLineFast(Form("TSpectrum::StaticBackground((TH1*)0x%lx,%d,\"%s\")",
9133 (ULong_t)this, niter, option));
9134}
9135
9136////////////////////////////////////////////////////////////////////////////////
9137/// Interface to TSpectrum::Search.
9138/// The function finds peaks in this histogram where the width is > sigma
9139/// and the peak maximum greater than threshold*maximum bin content of this.
9140/// For more details see TSpectrum::Search.
9141/// Note the difference in the default value for option compared to TSpectrum::Search
9142/// option="" by default (instead of "goff").
9143
9145{
9146 return (Int_t)gROOT->ProcessLineFast(Form("TSpectrum::StaticSearch((TH1*)0x%lx,%g,\"%s\",%g)",
9147 (ULong_t)this, sigma, option, threshold));
9148}
9149
9150////////////////////////////////////////////////////////////////////////////////
9151/// For a given transform (first parameter), fills the histogram (second parameter)
9152/// with the transform output data, specified in the third parameter
9153/// If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
9154/// and the user is responsible for deleting it.
9155///
9156/// Available options:
9157/// - "RE" - real part of the output
9158/// - "IM" - imaginary part of the output
9159/// - "MAG" - magnitude of the output
9160/// - "PH" - phase of the output
9161
9162TH1* TH1::TransformHisto(TVirtualFFT *fft, TH1* h_output, Option_t *option)
9163{
9164 if (!fft || !fft->GetN() ) {
9165 ::Error("TransformHisto","Invalid FFT transform class");
9166 return 0;
9167 }
9168
9169 if (fft->GetNdim()>2){
9170 ::Error("TransformHisto","Only 1d and 2D transform are supported");
9171 return 0;
9172 }
9173 Int_t binx,biny;
9174 TString opt = option;
9175 opt.ToUpper();
9176 Int_t *n = fft->GetN();
9177 TH1 *hout=0;
9178 if (h_output) {
9179 hout = h_output;
9180 }
9181 else {
9182 TString name = TString::Format("out_%s", opt.Data());
9183 if (fft->GetNdim()==1)
9184 hout = new TH1D(name, name,n[0], 0, n[0]);
9185 else if (fft->GetNdim()==2)
9186 hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
9187 }
9188 R__ASSERT(hout != 0);
9189 TString type=fft->GetType();
9190 Int_t ind[2];
9191 if (opt.Contains("RE")){
9192 if (type.Contains("2C") || type.Contains("2HC")) {
9193 Double_t re, im;
9194 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9195 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9196 ind[0] = binx-1; ind[1] = biny-1;
9197 fft->GetPointComplex(ind, re, im);
9198 hout->SetBinContent(binx, biny, re);
9199 }
9200 }
9201 } else {
9202 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9203 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9204 ind[0] = binx-1; ind[1] = biny-1;
9205 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
9206 }
9207 }
9208 }
9209 }
9210 if (opt.Contains("IM")) {
9211 if (type.Contains("2C") || type.Contains("2HC")) {
9212 Double_t re, im;
9213 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9214 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9215 ind[0] = binx-1; ind[1] = biny-1;
9216 fft->GetPointComplex(ind, re, im);
9217 hout->SetBinContent(binx, biny, im);
9218 }
9219 }
9220 } else {
9221 ::Error("TransformHisto","No complex numbers in the output");
9222 return 0;
9223 }
9224 }
9225 if (opt.Contains("MA")) {
9226 if (type.Contains("2C") || type.Contains("2HC")) {
9227 Double_t re, im;
9228 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9229 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9230 ind[0] = binx-1; ind[1] = biny-1;
9231 fft->GetPointComplex(ind, re, im);
9232 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
9233 }
9234 }
9235 } else {
9236 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
9237 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
9238 ind[0] = binx-1; ind[1] = biny-1;
9239 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
9240 }
9241 }
9242 }
9243 }
9244 if (opt.Contains("PH")) {
9245 if (type.Contains("2C") || type.Contains("2HC")){
9246 Double_t re, im, ph;
9247 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
9248 for (biny=1; biny<=hout->GetNbinsY(); biny++){
9249 ind[0] = binx-1; ind[1] = biny-1;
9250 fft->GetPointComplex(ind, re, im);
9251 if (TMath::Abs(re) > 1e-13){
9252 ph = TMath::ATan(im/re);
9253 //find the correct quadrant
9254 if (re<0 && im<0)
9255 ph -= TMath::Pi();
9256 if (re<0 && im>=0)
9257 ph += TMath::Pi();
9258 } else {
9259 if (TMath::Abs(im) < 1e-13)
9260 ph = 0;
9261 else if (im>0)
9262 ph = TMath::Pi()*0.5;
9263 else
9264 ph = -TMath::Pi()*0.5;
9265 }
9266 hout->SetBinContent(binx, biny, ph);
9267 }
9268 }
9269 } else {
9270 printf("Pure real output, no phase");
9271 return 0;
9272 }
9273 }
9274
9275 return hout;
9276}
9277
9278////////////////////////////////////////////////////////////////////////////////
9279/// Raw retrieval of bin content on internal data structure
9280/// see convention for numbering bins in TH1::GetBin
9281
9283{
9284 AbstractMethod("RetrieveBinContent");
9285 return 0;
9286}
9287
9288////////////////////////////////////////////////////////////////////////////////
9289/// Raw update of bin content on internal data structure
9290/// see convention for numbering bins in TH1::GetBin
9291
9293{
9294 AbstractMethod("UpdateBinContent");
9295}
9296
9297////////////////////////////////////////////////////////////////////////////////
9298/// Print value overload
9299
9300std::string cling::printValue(TH1 *val) {
9301 std::ostringstream strm;
9302 strm << cling::printValue((TObject*)val) << " NbinsX: " << val->GetNbinsX();
9303 return strm.str();
9304}
9305
9306//______________________________________________________________________________
9307// TH1C methods
9308// TH1C : histograms with one byte per channel. Maximum bin content = 127
9309//______________________________________________________________________________
9310
9311ClassImp(TH1C);
9312
9313////////////////////////////////////////////////////////////////////////////////
9314/// Constructor.
9315
9316TH1C::TH1C(): TH1(), TArrayC()
9317{
9318 fDimension = 1;
9319 SetBinsLength(3);
9320 if (fgDefaultSumw2) Sumw2();
9321}
9322
9323////////////////////////////////////////////////////////////////////////////////
9324/// Create a 1-Dim histogram with fix bins of type char (one byte per channel)
9325/// (see TH1::TH1 for explanation of parameters)
9326
9327TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9328: TH1(name,title,nbins,xlow,xup)
9329{
9330 fDimension = 1;
9332
9333 if (xlow >= xup) SetBuffer(fgBufferSize);
9334 if (fgDefaultSumw2) Sumw2();
9335}
9336
9337////////////////////////////////////////////////////////////////////////////////
9338/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9339/// (see TH1::TH1 for explanation of parameters)
9340
9341TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9342: TH1(name,title,nbins,xbins)
9343{
9344 fDimension = 1;
9346 if (fgDefaultSumw2) Sumw2();
9347}
9348
9349////////////////////////////////////////////////////////////////////////////////
9350/// Create a 1-Dim histogram with variable bins of type char (one byte per channel)
9351/// (see TH1::TH1 for explanation of parameters)
9352
9353TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9354: TH1(name,title,nbins,xbins)
9355{
9356 fDimension = 1;
9358 if (fgDefaultSumw2) Sumw2();
9359}
9360
9361////////////////////////////////////////////////////////////////////////////////
9362/// Destructor.
9363
9365{
9366}
9367
9368////////////////////////////////////////////////////////////////////////////////
9369/// Copy constructor.
9370
9371TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
9372{
9373 ((TH1C&)h1c).Copy(*this);
9374}
9375
9376////////////////////////////////////////////////////////////////////////////////
9377/// Increment bin content by 1.
9378
9379void TH1C::AddBinContent(Int_t bin)
9380{
9381 if (fArray[bin] < 127) fArray[bin]++;
9382}
9383
9384////////////////////////////////////////////////////////////////////////////////
9385/// Increment bin content by w.
9386
9388{
9389 Int_t newval = fArray[bin] + Int_t(w);
9390 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
9391 if (newval < -127) fArray[bin] = -127;
9392 if (newval > 127) fArray[bin] = 127;
9393}
9394
9395////////////////////////////////////////////////////////////////////////////////
9396/// Copy this to newth1
9397
9398void TH1C::Copy(TObject &newth1) const
9399{
9400 TH1::Copy(newth1);
9401}
9402
9403////////////////////////////////////////////////////////////////////////////////
9404/// Reset.
9405
9406void TH1C::Reset(Option_t *option)
9407{
9408 TH1::Reset(option);
9410}
9411
9412////////////////////////////////////////////////////////////////////////////////
9413/// Set total number of bins including under/overflow
9414/// Reallocate bin contents array
9415
9417{
9418 if (n < 0) n = fXaxis.GetNbins() + 2;
9419 fNcells = n;
9420 TArrayC::Set(n);
9421}
9422
9423////////////////////////////////////////////////////////////////////////////////
9424/// Operator =
9425
9426TH1C& TH1C::operator=(const TH1C &h1)
9427{
9428 if (this != &h1) ((TH1C&)h1).Copy(*this);
9429 return *this;
9430}
9431
9432////////////////////////////////////////////////////////////////////////////////
9433/// Operator *
9434
9436{
9437 TH1C hnew = h1;
9438 hnew.Scale(c1);
9439 hnew.SetDirectory(0);
9440 return hnew;
9441}
9442
9443////////////////////////////////////////////////////////////////////////////////
9444/// Operator +
9445
9446TH1C operator+(const TH1C &h1, const TH1C &h2)
9447{
9448 TH1C hnew = h1;
9449 hnew.Add(&h2,1);
9450 hnew.SetDirectory(0);
9451 return hnew;
9452}
9453
9454////////////////////////////////////////////////////////////////////////////////
9455/// Operator -
9456
9457TH1C operator-(const TH1C &h1, const TH1C &h2)
9458{
9459 TH1C hnew = h1;
9460 hnew.Add(&h2,-1);
9461 hnew.SetDirectory(0);
9462 return hnew;
9463}
9464
9465////////////////////////////////////////////////////////////////////////////////
9466/// Operator *
9467
9468TH1C operator*(const TH1C &h1, const TH1C &h2)
9469{
9470 TH1C hnew = h1;
9471 hnew.Multiply(&h2);
9472 hnew.SetDirectory(0);
9473 return hnew;
9474}
9475
9476////////////////////////////////////////////////////////////////////////////////
9477/// Operator /
9478
9479TH1C operator/(const TH1C &h1, const TH1C &h2)
9480{
9481 TH1C hnew = h1;
9482 hnew.Divide(&h2);
9483 hnew.SetDirectory(0);
9484 return hnew;
9485}
9486
9487//______________________________________________________________________________
9488// TH1S methods
9489// TH1S : histograms with one short per channel. Maximum bin content = 32767
9490//______________________________________________________________________________
9491
9492ClassImp(TH1S);
9493
9494////////////////////////////////////////////////////////////////////////////////
9495/// Constructor.
9496
9497TH1S::TH1S(): TH1(), TArrayS()
9498{
9499 fDimension = 1;
9500 SetBinsLength(3);
9501 if (fgDefaultSumw2) Sumw2();
9502}
9503
9504////////////////////////////////////////////////////////////////////////////////
9505/// Create a 1-Dim histogram with fix bins of type short
9506/// (see TH1::TH1 for explanation of parameters)
9507
9508TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9509: TH1(name,title,nbins,xlow,xup)
9510{
9511 fDimension = 1;
9513
9514 if (xlow >= xup) SetBuffer(fgBufferSize);
9515 if (fgDefaultSumw2) Sumw2();
9516}
9517
9518////////////////////////////////////////////////////////////////////////////////
9519/// Create a 1-Dim histogram with variable bins of type short
9520/// (see TH1::TH1 for explanation of parameters)
9521
9522TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9523: TH1(name,title,nbins,xbins)
9524{
9525 fDimension = 1;
9527 if (fgDefaultSumw2) Sumw2();
9528}
9529
9530////////////////////////////////////////////////////////////////////////////////
9531/// Create a 1-Dim histogram with variable bins of type short
9532/// (see TH1::TH1 for explanation of parameters)
9533
9534TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9535: TH1(name,title,nbins,xbins)
9536{
9537 fDimension = 1;
9539 if (fgDefaultSumw2) Sumw2();
9540}
9541
9542////////////////////////////////////////////////////////////////////////////////
9543/// Destructor.
9544
9546{
9547}
9548
9549////////////////////////////////////////////////////////////////////////////////
9550/// Copy constructor.
9551
9552TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
9553{
9554 ((TH1S&)h1s).Copy(*this);
9555}
9556
9557////////////////////////////////////////////////////////////////////////////////
9558/// Increment bin content by 1.
9559
9560void TH1S::AddBinContent(Int_t bin)
9561{
9562 if (fArray[bin] < 32767) fArray[bin]++;
9563}
9564
9565////////////////////////////////////////////////////////////////////////////////
9566/// Increment bin content by w
9567
9569{
9570 Int_t newval = fArray[bin] + Int_t(w);
9571 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
9572 if (newval < -32767) fArray[bin] = -32767;
9573 if (newval > 32767) fArray[bin] = 32767;
9574}
9575
9576////////////////////////////////////////////////////////////////////////////////
9577/// Copy this to newth1
9578
9579void TH1S::Copy(TObject &newth1) const
9580{
9581 TH1::Copy(newth1);
9582}
9583
9584////////////////////////////////////////////////////////////////////////////////
9585/// Reset.
9586
9587void TH1S::Reset(Option_t *option)
9588{
9589 TH1::Reset(option);
9591}
9592
9593////////////////////////////////////////////////////////////////////////////////
9594/// Set total number of bins including under/overflow
9595/// Reallocate bin contents array
9596
9598{
9599 if (n < 0) n = fXaxis.GetNbins() + 2;
9600 fNcells = n;
9601 TArrayS::Set(n);
9602}
9603
9604////////////////////////////////////////////////////////////////////////////////
9605/// Operator =
9606
9607TH1S& TH1S::operator=(const TH1S &h1)
9608{
9609 if (this != &h1) ((TH1S&)h1).Copy(*this);
9610 return *this;
9611}
9612
9613////////////////////////////////////////////////////////////////////////////////
9614/// Operator *
9615
9617{
9618 TH1S hnew = h1;
9619 hnew.Scale(c1);
9620 hnew.SetDirectory(0);
9621 return hnew;
9622}
9623
9624////////////////////////////////////////////////////////////////////////////////
9625/// Operator +
9626
9627TH1S operator+(const TH1S &h1, const TH1S &h2)
9628{
9629 TH1S hnew = h1;
9630 hnew.Add(&h2,1);
9631 hnew.SetDirectory(0);
9632 return hnew;
9633}
9634
9635////////////////////////////////////////////////////////////////////////////////
9636/// Operator -
9637
9638TH1S operator-(const TH1S &h1, const TH1S &h2)
9639{
9640 TH1S hnew = h1;
9641 hnew.Add(&h2,-1);
9642 hnew.SetDirectory(0);
9643 return hnew;
9644}
9645
9646////////////////////////////////////////////////////////////////////////////////
9647/// Operator *
9648
9649TH1S operator*(const TH1S &h1, const TH1S &h2)
9650{
9651 TH1S hnew = h1;
9652 hnew.Multiply(&h2);
9653 hnew.SetDirectory(0);
9654 return hnew;
9655}
9656
9657////////////////////////////////////////////////////////////////////////////////
9658/// Operator /
9659
9660TH1S operator/(const TH1S &h1, const TH1S &h2)
9661{
9662 TH1S hnew = h1;
9663 hnew.Divide(&h2);
9664 hnew.SetDirectory(0);
9665 return hnew;
9666}
9667
9668//______________________________________________________________________________
9669// TH1I methods
9670// TH1I : histograms with one int per channel. Maximum bin content = 2147483647
9671// 2147483647 = INT_MAX
9672//______________________________________________________________________________
9673
9674ClassImp(TH1I);
9675
9676////////////////////////////////////////////////////////////////////////////////
9677/// Constructor.
9678
9679TH1I::TH1I(): TH1(), TArrayI()
9680{
9681 fDimension = 1;
9682 SetBinsLength(3);
9683 if (fgDefaultSumw2) Sumw2();
9684}
9685
9686////////////////////////////////////////////////////////////////////////////////
9687/// Create a 1-Dim histogram with fix bins of type integer
9688/// (see TH1::TH1 for explanation of parameters)
9689
9690TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9691: TH1(name,title,nbins,xlow,xup)
9692{
9693 fDimension = 1;
9695
9696 if (xlow >= xup) SetBuffer(fgBufferSize);
9697 if (fgDefaultSumw2) Sumw2();
9698}
9699
9700////////////////////////////////////////////////////////////////////////////////
9701/// Create a 1-Dim histogram with variable bins of type integer
9702/// (see TH1::TH1 for explanation of parameters)
9703
9704TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9705: TH1(name,title,nbins,xbins)
9706{
9707 fDimension = 1;
9709 if (fgDefaultSumw2) Sumw2();
9710}
9711
9712////////////////////////////////////////////////////////////////////////////////
9713/// Create a 1-Dim histogram with variable bins of type integer
9714/// (see TH1::TH1 for explanation of parameters)
9715
9716TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9717: TH1(name,title,nbins,xbins)
9718{
9719 fDimension = 1;
9721 if (fgDefaultSumw2) Sumw2();
9722}
9723
9724////////////////////////////////////////////////////////////////////////////////
9725/// Destructor.
9726
9728{
9729}
9730
9731////////////////////////////////////////////////////////////////////////////////
9732/// Copy constructor.
9733
9734TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
9735{
9736 ((TH1I&)h1i).Copy(*this);
9737}
9738
9739////////////////////////////////////////////////////////////////////////////////
9740/// Increment bin content by 1.
9741
9742void TH1I::AddBinContent(Int_t bin)
9743{
9744 if (fArray[bin] < INT_MAX) fArray[bin]++;
9745}
9746
9747////////////////////////////////////////////////////////////////////////////////
9748/// Increment bin content by w
9749
9751{
9752 Long64_t newval = fArray[bin] + Long64_t(w);
9753 if (newval > -INT_MAX && newval < INT_MAX) {fArray[bin] = Int_t(newval); return;}
9754 if (newval < -INT_MAX) fArray[bin] = -INT_MAX;
9755 if (newval > INT_MAX) fArray[bin] = INT_MAX;
9756}
9757
9758////////////////////////////////////////////////////////////////////////////////
9759/// Copy this to newth1
9760
9761void TH1I::Copy(TObject &newth1) const
9762{
9763 TH1::Copy(newth1);
9764}
9765
9766////////////////////////////////////////////////////////////////////////////////
9767/// Reset.
9768
9769void TH1I::Reset(Option_t *option)
9770{
9771 TH1::Reset(option);
9773}
9774
9775////////////////////////////////////////////////////////////////////////////////
9776/// Set total number of bins including under/overflow
9777/// Reallocate bin contents array
9778
9780{
9781 if (n < 0) n = fXaxis.GetNbins() + 2;
9782 fNcells = n;
9783 TArrayI::Set(n);
9784}
9785
9786////////////////////////////////////////////////////////////////////////////////
9787/// Operator =
9788
9789TH1I& TH1I::operator=(const TH1I &h1)
9790{
9791 if (this != &h1) ((TH1I&)h1).Copy(*this);
9792 return *this;
9793}
9794
9795
9796////////////////////////////////////////////////////////////////////////////////
9797/// Operator *
9798
9800{
9801 TH1I hnew = h1;
9802 hnew.Scale(c1);
9803 hnew.SetDirectory(0);
9804 return hnew;
9805}
9806
9807////////////////////////////////////////////////////////////////////////////////
9808/// Operator +
9809
9810TH1I operator+(const TH1I &h1, const TH1I &h2)
9811{
9812 TH1I hnew = h1;
9813 hnew.Add(&h2,1);
9814 hnew.SetDirectory(0);
9815 return hnew;
9816}
9817
9818////////////////////////////////////////////////////////////////////////////////
9819/// Operator -
9820
9821TH1I operator-(const TH1I &h1, const TH1I &h2)
9822{
9823 TH1I hnew = h1;
9824 hnew.Add(&h2,-1);
9825 hnew.SetDirectory(0);
9826 return hnew;
9827}
9828
9829////////////////////////////////////////////////////////////////////////////////
9830/// Operator *
9831
9832TH1I operator*(const TH1I &h1, const TH1I &h2)
9833{
9834 TH1I hnew = h1;
9835 hnew.Multiply(&h2);
9836 hnew.SetDirectory(0);
9837 return hnew;
9838}
9839
9840////////////////////////////////////////////////////////////////////////////////
9841/// Operator /
9842
9843TH1I operator/(const TH1I &h1, const TH1I &h2)
9844{
9845 TH1I hnew = h1;
9846 hnew.Divide(&h2);
9847 hnew.SetDirectory(0);
9848 return hnew;
9849}
9850
9851//______________________________________________________________________________
9852// TH1F methods
9853// TH1F : histograms with one float per channel. Maximum precision 7 digits
9854//______________________________________________________________________________
9855
9856ClassImp(TH1F);
9857
9858////////////////////////////////////////////////////////////////////////////////
9859/// Constructor.
9860
9861TH1F::TH1F(): TH1(), TArrayF()
9862{
9863 fDimension = 1;
9864 SetBinsLength(3);
9865 if (fgDefaultSumw2) Sumw2();
9866}
9867
9868////////////////////////////////////////////////////////////////////////////////
9869/// Create a 1-Dim histogram with fix bins of type float
9870/// (see TH1::TH1 for explanation of parameters)
9871
9872TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9873: TH1(name,title,nbins,xlow,xup)
9874{
9875 fDimension = 1;
9877
9878 if (xlow >= xup) SetBuffer(fgBufferSize);
9879 if (fgDefaultSumw2) Sumw2();
9880}
9881
9882////////////////////////////////////////////////////////////////////////////////
9883/// Create a 1-Dim histogram with variable bins of type float
9884/// (see TH1::TH1 for explanation of parameters)
9885
9886TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
9887: TH1(name,title,nbins,xbins)
9888{
9889 fDimension = 1;
9891 if (fgDefaultSumw2) Sumw2();
9892}
9893
9894////////////////////////////////////////////////////////////////////////////////
9895/// Create a 1-Dim histogram with variable bins of type float
9896/// (see TH1::TH1 for explanation of parameters)
9897
9898TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
9899: TH1(name,title,nbins,xbins)
9900{
9901 fDimension = 1;
9903 if (fgDefaultSumw2) Sumw2();
9904}
9905
9906////////////////////////////////////////////////////////////////////////////////
9907/// Create a histogram from a TVectorF
9908/// by default the histogram name is "TVectorF" and title = ""
9909
9910TH1F::TH1F(const TVectorF &v)
9911: TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
9912{
9914 fDimension = 1;
9915 Int_t ivlow = v.GetLwb();
9916 for (Int_t i=0;i<fNcells-2;i++) {
9917 SetBinContent(i+1,v(i+ivlow));
9918 }
9920 if (fgDefaultSumw2) Sumw2();
9921}
9922
9923////////////////////////////////////////////////////////////////////////////////
9924/// Copy Constructor.
9925
9926TH1F::TH1F(const TH1F &h) : TH1(), TArrayF()
9927{
9928 ((TH1F&)h).Copy(*this);
9929}
9930
9931////////////////////////////////////////////////////////////////////////////////
9932/// Destructor.
9933
9935{
9936}
9937
9938////////////////////////////////////////////////////////////////////////////////
9939/// Copy this to newth1.
9940
9941void TH1F::Copy(TObject &newth1) const
9942{
9943 TH1::Copy(newth1);
9944}
9945
9946////////////////////////////////////////////////////////////////////////////////
9947/// Reset.
9948
9949void TH1F::Reset(Option_t *option)
9950{
9951 TH1::Reset(option);
9953}
9954
9955////////////////////////////////////////////////////////////////////////////////
9956/// Set total number of bins including under/overflow
9957/// Reallocate bin contents array
9958
9960{
9961 if (n < 0) n = fXaxis.GetNbins() + 2;
9962 fNcells = n;
9963 TArrayF::Set(n);
9964}
9965
9966////////////////////////////////////////////////////////////////////////////////
9967/// Operator =
9968
9969TH1F& TH1F::operator=(const TH1F &h1)
9970{
9971 if (this != &h1) ((TH1F&)h1).Copy(*this);
9972 return *this;
9973}
9974
9975////////////////////////////////////////////////////////////////////////////////
9976/// Operator *
9977
9979{
9980 TH1F hnew = h1;
9981 hnew.Scale(c1);
9982 hnew.SetDirectory(0);
9983 return hnew;
9984}
9985
9986////////////////////////////////////////////////////////////////////////////////
9987/// Operator +
9988
9989TH1F operator+(const TH1F &h1, const TH1F &h2)
9990{
9991 TH1F hnew = h1;
9992 hnew.Add(&h2,1);
9993 hnew.SetDirectory(0);
9994 return hnew;
9995}
9996
9997////////////////////////////////////////////////////////////////////////////////
9998/// Operator -
9999
10000TH1F operator-(const TH1F &h1, const TH1F &h2)
10001{
10002 TH1F hnew = h1;
10003 hnew.Add(&h2,-1);
10004 hnew.SetDirectory(0);
10005 return hnew;
10006}
10007
10008////////////////////////////////////////////////////////////////////////////////
10009/// Operator *
10010
10011TH1F operator*(const TH1F &h1, const TH1F &h2)
10012{
10013 TH1F hnew = h1;
10014 hnew.Multiply(&h2);
10015 hnew.SetDirectory(0);
10016 return hnew;
10017}
10018
10019////////////////////////////////////////////////////////////////////////////////
10020/// Operator /
10021
10022TH1F operator/(const TH1F &h1, const TH1F &h2)
10023{
10024 TH1F hnew = h1;
10025 hnew.Divide(&h2);
10026 hnew.SetDirectory(0);
10027 return hnew;
10028}
10029
10030//______________________________________________________________________________
10031// TH1D methods
10032// TH1D : histograms with one double per channel. Maximum precision 14 digits
10033//______________________________________________________________________________
10034
10035ClassImp(TH1D);
10036
10037////////////////////////////////////////////////////////////////////////////////
10038/// Constructor.
10039
10040TH1D::TH1D(): TH1(), TArrayD()
10041{
10042 fDimension = 1;
10043 SetBinsLength(3);
10044 if (fgDefaultSumw2) Sumw2();
10045}
10046
10047////////////////////////////////////////////////////////////////////////////////
10048/// Create a 1-Dim histogram with fix bins of type double
10049/// (see TH1::TH1 for explanation of parameters)
10050
10051TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
10052: TH1(name,title,nbins,xlow,xup)
10053{
10054 fDimension = 1;
10056
10057 if (xlow >= xup) SetBuffer(fgBufferSize);
10058 if (fgDefaultSumw2) Sumw2();
10059}
10060
10061////////////////////////////////////////////////////////////////////////////////
10062/// Create a 1-Dim histogram with variable bins of type double
10063/// (see TH1::TH1 for explanation of parameters)
10064
10065TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
10066: TH1(name,title,nbins,xbins)
10067{
10068 fDimension = 1;
10070 if (fgDefaultSumw2) Sumw2();
10071}
10072
10073////////////////////////////////////////////////////////////////////////////////
10074/// Create a 1-Dim histogram with variable bins of type double
10075/// (see TH1::TH1 for explanation of parameters)
10076
10077TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
10078: TH1(name,title,nbins,xbins)
10079{
10080 fDimension = 1;
10082 if (fgDefaultSumw2) Sumw2();
10083}
10084
10085////////////////////////////////////////////////////////////////////////////////
10086/// Create a histogram from a TVectorD
10087/// by default the histogram name is "TVectorD" and title = ""
10088
10089TH1D::TH1D(const TVectorD &v)
10090: TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
10091{
10093 fDimension = 1;
10094 Int_t ivlow = v.GetLwb();
10095 for (Int_t i=0;i<fNcells-2;i++) {
10096 SetBinContent(i+1,v(i+ivlow));
10097 }
10099 if (fgDefaultSumw2) Sumw2();
10100}
10101
10102////////////////////////////////////////////////////////////////////////////////
10103/// Destructor.
10104
10106{
10107}
10108
10109////////////////////////////////////////////////////////////////////////////////
10110/// Constructor.
10111
10112TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
10113{
10114 ((TH1D&)h1d).Copy(*this);
10115}
10116
10117////////////////////////////////////////////////////////////////////////////////
10118/// Copy this to newth1
10119
10120void TH1D::Copy(TObject &newth1) const
10121{
10122 TH1::Copy(newth1);
10123}
10124
10125////////////////////////////////////////////////////////////////////////////////
10126/// Reset.
10127
10128void TH1D::Reset(Option_t *option)
10129{
10130 TH1::Reset(option);
10132}
10133
10134////////////////////////////////////////////////////////////////////////////////
10135/// Set total number of bins including under/overflow
10136/// Reallocate bin contents array
10137
10139{
10140 if (n < 0) n = fXaxis.GetNbins() + 2;
10141 fNcells = n;
10142 TArrayD::Set(n);
10143}
10144
10145////////////////////////////////////////////////////////////////////////////////
10146/// Operator =
10147
10148TH1D& TH1D::operator=(const TH1D &h1)
10149{
10150 if (this != &h1) ((TH1D&)h1).Copy(*this);
10151 return *this;
10152}
10153
10154////////////////////////////////////////////////////////////////////////////////
10155/// Operator *
10156
10158{
10159 TH1D hnew = h1;
10160 hnew.Scale(c1);
10161 hnew.SetDirectory(0);
10162 return hnew;
10163}
10164
10165////////////////////////////////////////////////////////////////////////////////
10166/// Operator +
10167
10168TH1D operator+(const TH1D &h1, const TH1D &h2)
10169{
10170 TH1D hnew = h1;
10171 hnew.Add(&h2,1);
10172 hnew.SetDirectory(0);
10173 return hnew;
10174}
10175
10176////////////////////////////////////////////////////////////////////////////////
10177/// Operator -
10178
10179TH1D operator-(const TH1D &h1, const TH1D &h2)
10180{
10181 TH1D hnew = h1;
10182 hnew.Add(&h2,-1);
10183 hnew.SetDirectory(0);
10184 return hnew;
10185}
10186
10187////////////////////////////////////////////////////////////////////////////////
10188/// Operator *
10189
10190TH1D operator*(const TH1D &h1, const TH1D &h2)
10191{
10192 TH1D hnew = h1;
10193 hnew.Multiply(&h2);
10194 hnew.SetDirectory(0);
10195 return hnew;
10196}
10197
10198////////////////////////////////////////////////////////////////////////////////
10199/// Operator /
10200
10201TH1D operator/(const TH1D &h1, const TH1D &h2)
10202{
10203 TH1D hnew = h1;
10204 hnew.Divide(&h2);
10205 hnew.SetDirectory(0);
10206 return hnew;
10207}
10208
10209////////////////////////////////////////////////////////////////////////////////
10210///return pointer to histogram with name
10211///hid if id >=0
10212///h_id if id <0
10213
10214TH1 *R__H(Int_t hid)
10215{
10216 TString hname;
10217 if(hid >= 0) hname.Form("h%d",hid);
10218 else hname.Form("h_%d",hid);
10219 return (TH1*)gDirectory->Get(hname);
10220}
10221
10222////////////////////////////////////////////////////////////////////////////////
10223///return pointer to histogram with name hname
10224
10225TH1 *R__H(const char * hname)
10226{
10227 return (TH1*)gDirectory->Get(hname);
10228}
10229
10230
10231/// \fn void TH1::SetBarOffset(Float_t offset)
10232/// Set the bar offset as fraction of the bin width for drawing mode "B".
10233/// This shifts bars to the right on the x axis, and helps to draw bars next to each other.
10234/// \see THistPainter, SetBarWidth()
10235
10236/// \fn void TH1::SetBarWidth(Float_t width)
10237/// Set the width of bars as fraction of the bin width for drawing mode "B".
10238/// This allows for making bars narrower than the bin width. With SetBarOffset(), this helps to draw multiple bars next to each other.
10239/// \see THistPainter, SetBarOffset()
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define s1(x)
Definition RSha256.hxx:91
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
static const double x1[5]
int Int_t
Definition RtypesCore.h:45
short Version_t
Definition RtypesCore.h:65
char Char_t
Definition RtypesCore.h:37
unsigned int UInt_t
Definition RtypesCore.h:46
const Bool_t kFALSE
Definition RtypesCore.h:92
unsigned long ULong_t
Definition RtypesCore.h:55
bool Bool_t
Definition RtypesCore.h:63
short Short_t
Definition RtypesCore.h:39
double Double_t
Definition RtypesCore.h:59
double Stat_t
Definition RtypesCore.h:77
short Color_t
Definition RtypesCore.h:83
long long Long64_t
Definition RtypesCore.h:73
short Style_t
Definition RtypesCore.h:80
float Float_t
Definition RtypesCore.h:57
const Bool_t kTRUE
Definition RtypesCore.h:91
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:364
#define gDirectory
Definition TDirectory.h:290
include TDocParser_001 C image html pict1_TDocParser_001 png width
R__EXTERN TEnv * gEnv
Definition TEnv.h:171
#define R__ASSERT(e)
Definition TError.h:120
char name[80]
Definition TGX11.cxx:110
int type
Definition TGX11.cxx:121
static bool IsEquidistantBinning(const TAxis &axis)
Test if the binning is equidistant.
Definition TH1.cxx:5809
void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
Least square linear fit without weights.
Definition TH1.cxx:4758
void H1InitGaus()
Compute Initial values of parameters for a gaussian.
Definition TH1.cxx:4593
void H1InitExpo()
Compute Initial values of parameters for an exponential.
Definition TH1.cxx:4649
TH1C operator+(const TH1C &h1, const TH1C &h2)
Operator +.
Definition TH1.cxx:9444
TH1C operator-(const TH1C &h1, const TH1C &h2)
Operator -.
Definition TH1.cxx:9455
TH1C operator/(const TH1C &h1, const TH1C &h2)
Operator /.
Definition TH1.cxx:9477
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:4804
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:5792
static Bool_t AlmostInteger(Double_t a, Double_t epsilon=0.00000001)
Test if a double is almost an integer.
Definition TH1.cxx:5800
TF1 * gF1
Definition TH1.cxx:569
TH1 * R__H(Int_t hid)
return pointer to histogram with name hid if id >=0 h_id if id <0
Definition TH1.cxx:10212
TH1C operator*(Double_t c1, const TH1C &h1)
Operator *.
Definition TH1.cxx:9433
void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
Least squares lpolynomial fitting without weights.
Definition TH1.cxx:4699
void H1InitPolynom()
Compute Initial values of parameters for a polynom.
Definition TH1.cxx:4669
float xmin
int nentries
float * q
float ymin
float xmax
float ymax
#define gInterpreter
Int_t gDebug
Definition TROOT.cxx:590
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#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:412
#define R__LOCKGUARD(mutex)
#define gPad
#define R__WRITE_LOCKGUARD(mutex)
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition BinData.h:52
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition DataRange.h:35
void AndersonDarling2SamplesTest(Double_t &pvalue, Double_t &testStat) const
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
virtual void Set(Int_t n)=0
Int_t GetSize() const
Definition TArray.h:47
virtual Color_t GetTitleColor() const
Definition TAttAxis.h:46
virtual Color_t GetLabelColor() const
Definition TAttAxis.h:38
virtual Int_t GetNdivisions() const
Definition TAttAxis.h:36
virtual Color_t GetAxisColor() const
Definition TAttAxis.h:37
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition TAttAxis.cxx:293
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:162
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
Definition TAttAxis.cxx:203
virtual Style_t GetLabelFont() const
Definition TAttAxis.h:39
virtual void SetTitleFont(Style_t font=62)
Set the title font.
Definition TAttAxis.cxx:321
virtual void SetLabelOffset(Float_t offset=0.005)
Set distance between the axis and the labels.
Definition TAttAxis.cxx:192
virtual void SetLabelFont(Style_t font=62)
Set labels' font.
Definition TAttAxis.cxx:182
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title.
Definition TAttAxis.cxx:303
virtual void SetTitleColor(Color_t color=1)
Set color of axis title.
Definition TAttAxis.cxx:312
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:78
virtual Float_t GetTitleOffset() const
Definition TAttAxis.h:43
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length.
Definition TAttAxis.cxx:279
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Definition TAttAxis.cxx:228
virtual void SetLabelColor(Color_t color=1, Float_t alpha=1.)
Set color of labels.
Definition TAttAxis.cxx:172
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.
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition TAttMarker.h:32
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition TAttMarker.h:38
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:31
virtual Size_t GetMarkerSize() const
Return the marker size.
Definition TAttMarker.h:33
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition TAttMarker.h:40
void Copy(TAttMarker &attmarker) const
Copy this marker attributes to a new TAttMarker.
virtual void 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:553
virtual Bool_t GetTimeDisplay() const
Definition TAxis.h:126
Bool_t IsAlphanumeric() const
Definition TAxis.h:84
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:478
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:661
@ 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:440
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:293
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:518
virtual void SetTimeDisplay(Int_t value)
Definition TAxis.h:161
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Definition TAxis.cxx:731
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:419
virtual void Copy(TObject &axis) const
Copy axis structure to another axis.
Definition TAxis.cxx:210
Int_t GetLast() const
Return last bin on the axis i.e.
Definition TAxis.cxx:469
virtual void SetLimits(Double_t xmin, Double_t xmax)
Definition TAxis.h: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:562
virtual void SetRange(Int_t first=0, Int_t last=0)
Set the viewing range for the axis using bin numbers.
Definition TAxis.cxx:920
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:540
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:528
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition TAxis.cxx:458
THashList * GetLabels() const
Definition TAxis.h:117
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
Buffer base class used for serializing objects.
Definition TBuffer.h:43
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 void AddAll(const TCollection *col)
Add all objects from collection col to this collection.
virtual TObject * Clone(const char *newname="") const
Make a clone of an collection using the Streamer facility.
virtual Bool_t IsEmpty() const
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Describe directory structure in memory.
Definition TDirectory.h:45
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:491
1-Dim function class
Definition TF1.h:213
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:3658
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function Note that this histogram is managed ...
Definition TF1.cxx:1574
virtual Int_t GetNpar() const
Definition TF1.h:481
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
IntegralOneDim or analytical integral.
Definition TF1.cxx:2515
virtual Double_t EvalPar(const Double_t *x, const Double_t *params=0)
Evaluate function with given coordinates and parameters.
Definition TF1.cxx:1463
virtual void InitArgs(const Double_t *x, const Double_t *params)
Initialize parameters addresses.
Definition TF1.cxx:2467
virtual void GetRange(Double_t *xmin, Double_t *xmax) const
Return range of a generic N-D function.
Definition TF1.cxx:2269
virtual void SetParLimits(Int_t ipar, Double_t parmin, Double_t parmax)
Set limits for parameter ipar.
Definition TF1.cxx:3511
static Bool_t RejectedPoint()
See TF1::RejectPoint above.
Definition TF1.cxx:3667
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:1434
virtual void SetParameter(Int_t param, Double_t value)
Definition TF1.h:634
virtual Bool_t IsInside(const Double_t *x) const
return kTRUE if the point is inside the function range
Definition TF1.h:598
A 2-Dim function with parameters.
Definition TF2.h:29
A 3-Dim function with parameters.
Definition TF3.h:28
Provides an indirection to the TFitResult class and with a semantics identical to a TFitResult pointe...
1-D histogram with a byte per channel (see TH1 documentation)
Definition TH1.h:452
TH1C & operator=(const TH1C &h1)
Operator =.
Definition TH1.cxx:9424
TH1C()
Constructor.
Definition TH1.cxx:9314
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition TH1.cxx:9396
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9414
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition TH1.cxx:9377
virtual ~TH1C()
Destructor.
Definition TH1.cxx:9362
virtual void Reset(Option_t *option="")
Reset.
Definition TH1.cxx:9404
1-D histogram with a double per channel (see TH1 documentation)}
Definition TH1.h:618
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition TH1.cxx:10118
virtual ~TH1D()
Destructor.
Definition TH1.cxx:10103
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:10136
TH1D()
Constructor.
Definition TH1.cxx:10038
TH1D & operator=(const TH1D &h1)
Operator =.
Definition TH1.cxx:10146
1-D histogram with a float per channel (see TH1 documentation)}
Definition TH1.h:575
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:604
virtual ~TH1F()
Destructor.
Definition TH1.cxx:9932
TH1F & operator=(const TH1F &h1)
Operator =.
Definition TH1.cxx:9967
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9957
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition TH1.cxx:9939
TH1F()
Constructor.
Definition TH1.cxx:9859
1-D histogram with an int per channel (see TH1 documentation)}
Definition TH1.h:534
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition TH1.cxx:9759
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition TH1.cxx:9740
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9777
virtual ~TH1I()
Destructor.
Definition TH1.cxx:9725
TH1I()
Constructor.
Definition TH1.cxx:9677
TH1I & operator=(const TH1I &h1)
Operator =.
Definition TH1.cxx:9787
1-D histogram with a short per channel (see TH1 documentation)
Definition TH1.h:493
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition TH1.cxx:9558
virtual void SetBinsLength(Int_t n=-1)
Set total number of bins including under/overflow Reallocate bin contents array.
Definition TH1.cxx:9595
virtual ~TH1S()
Destructor.
Definition TH1.cxx:9543
TH1S & operator=(const TH1S &h1)
Operator =.
Definition TH1.cxx:9605
virtual void Copy(TObject &hnew) const
Copy this to newth1.
Definition TH1.cxx:9577
TH1S()
Constructor.
Definition TH1.cxx:9495
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:58
virtual void SetError(const Double_t *error)
Replace bin errors by values in array error.
Definition TH1.cxx:8791
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:8777
virtual void FitPanel()
Display a panel with all histogram fit options.
Definition TH1.cxx:4247
Double_t * fBuffer
[fBufferSize] entry buffer
Definition TH1.h:107
virtual Int_t AutoP2FindLimits(Double_t min, Double_t max)
Buffer-based estimate of the histogram range using the power of 2 algorithm.
Definition TH1.cxx:1331
virtual Double_t GetEffectiveEntries() const
Number of effective entries of the histogram.
Definition TH1.cxx:4411
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition TH1.cxx:7122
virtual void SetTitle(const char *title)
See GetStatOverflows for more information.
Definition TH1.cxx:6678
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition TH1.cxx:6845
virtual void Print(Option_t *option="") const
Print some global quantities for this histogram.
Definition TH1.cxx:6975
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:8981
virtual void Rebuild(Option_t *option="")
Using the current bin info, recompute the arrays for contents and errors.
Definition TH1.cxx:7053
virtual void SetBarOffset(Float_t offset=0.25)
Set the bar offset as fraction of the bin width for drawing mode "B".
Definition TH1.h:359
static Bool_t fgStatOverflows
!flag to use under/overflows in statistics
Definition TH1.h:116
virtual Int_t FindLastBinAbove(Double_t threshold=0, Int_t axis=1, Int_t firstBin=1, Int_t lastBin=-1) const
Find last bin with content > threshold for axis (1=x, 2=y, 3=z) if no bins with content > threshold i...
Definition TH1.cxx:3805
TAxis * GetZaxis()
Definition TH1.h:322
virtual Bool_t Multiply(TF1 *f1, Double_t c1=1)
Performs the operation:
Definition TH1.cxx:5980
virtual void Browse(TBrowser *b)
Browse the Histogram object.
Definition TH1.cxx:758
Int_t fNcells
number of bins(1D), cells (2D) +U/Overflows
Definition TH1.h:88
virtual void GetStats(Double_t *stats) const
fill the array stats from the contents of this histogram The array stats must be correctly dimensione...
Definition TH1.cxx:7726
Double_t fTsumw
Total Sum of weights.
Definition TH1.h:95
virtual Float_t GetBarWidth() const
Definition TH1.h:256
Double_t fTsumw2
Total Sum of squares of weights.
Definition TH1.h:96
static void StatOverflows(Bool_t flag=kTRUE)
if flag=kTRUE, underflows and overflows are used by the Fill functions in the computation of statisti...
Definition TH1.cxx:6891
virtual Float_t GetBarOffset() const
Definition TH1.h:255
virtual ~TH1()
Histogram default destructor.
Definition TH1.cxx:623
TList * fFunctions
->Pointer to list of functions (fits and user)
Definition TH1.h:105
static Bool_t fgAddDirectory
!flag to add histograms to the directory
Definition TH1.h:115
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:4543
static Int_t GetDefaultBufferSize()
Static function return the default buffer size for automatic histograms the parameter fgBufferSize ma...
Definition TH1.cxx:4369
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:7870
Double_t fTsumwx2
Total Sum of weight*X*X.
Definition TH1.h:98
virtual Double_t GetStdDev(Int_t axis=1) const
Returns the Standard Deviation (Sigma).
Definition TH1.cxx:7500
TH1()
Histogram default constructor.
Definition TH1.cxx:595
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:9160
virtual void LabelsOption(Option_t *option="h", Option_t *axis="X")
Sort bins with labels or set option(s) to draw axis with labels.
Definition TH1.cxx:5313
virtual Int_t GetNbinsY() const
Definition TH1.h:297
Short_t fBarOffset
(1000*offset) for bar charts or legos
Definition TH1.h:92
static bool CheckBinLimits(const TAxis *a1, const TAxis *a2)
Check bin limits.
Definition TH1.cxx:1527
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition TH1.cxx:1257
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition TH1.cxx:8903
static Int_t FitOptionsMake(Option_t *option, Foption_t &Foption)
Decode string choptin and fill fitOption structure.
Definition TH1.cxx:4584
virtual Int_t GetNbinsZ() const
Definition TH1.h:298
virtual Double_t GetNormFactor() const
Definition TH1.h:300
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:7428
virtual Double_t GetSkewness(Int_t axis=1) const
Definition TH1.cxx:7564
virtual void ClearUnderflowAndOverflow()
Remove all the content from the underflow and overflow bins, without changing the number of entries A...
Definition TH1.cxx:2511
virtual Double_t GetContourLevelPad(Int_t level) const
Return the value of contour number "level" in Pad coordinates.
Definition TH1.cxx:8288
virtual TH1 * DrawNormalized(Option_t *option="", Double_t norm=1) const
Draw a normalized copy of this histogram.
Definition TH1.cxx:3150
@ kNeutral
Adapt to the global flag.
Definition TH1.h:82
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:2064
virtual Int_t GetDimension() const
Definition TH1.h:282
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1282
@ kIsAverage
Bin contents are average (used by Add)
Definition TH1.h:170
@ kUserContour
user specified contour levels
Definition TH1.h:165
@ kNoStats
don't draw stats box
Definition TH1.h:164
@ kAutoBinPTwo
Use Power(2)-based algorithm for autobinning.
Definition TH1.h:173
@ kIsNotW
Histogram is forced to be not weighted even when the histogram is filled with weighted different than...
Definition TH1.h:171
@ kIsHighlight
bit set if histo is highlight
Definition TH1.h:174
virtual void SetContourLevel(Int_t level, Double_t value)
Set value for one contour level.
Definition TH1.cxx:8370
virtual Bool_t CanExtendAllAxes() const
Returns true if all axes are extendable.
Definition TH1.cxx:6596
TDirectory * fDirectory
!Pointer to directory holding this histogram
Definition TH1.h:108
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition TH1.cxx:7069
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition TH1.h:320
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:4906
TH1 * GetCumulative(Bool_t forward=kTRUE, const char *suffix="_cumulative") const
Return a pointer to an histogram containing the cumulative content.
Definition TH1.cxx:2608
void UseCurrentStyle()
Copy current attributes from/to current style.
Definition TH1.cxx:7355
static Double_t AutoP2GetPower2(Double_t x, Bool_t next=kTRUE)
Auxiliary function to get the power of 2 next (larger) or previous (smaller) a given x.
Definition TH1.cxx:1296
virtual Int_t GetNcells() const
Definition TH1.h:299
virtual Int_t ShowPeaks(Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
Interface to TSpectrum::Search.
Definition TH1.cxx:9142
static Bool_t RecomputeAxisLimits(TAxis &destAxis, const TAxis &anAxis)
Finds new limits for the axis for the Merge function.
Definition TH1.cxx:5839
virtual void PutStats(Double_t *stats)
Replace current statistics with the values in array stats.
Definition TH1.cxx:7777
TVirtualHistPainter * GetPainter(Option_t *option="")
Return pointer to painter.
Definition TH1.cxx:4452
TObject * Clone(const char *newname=0) const
Make a complete copy of the underlying object.
Definition TH1.cxx:2740
virtual void FillRandom(const char *fname, Int_t ntimes=5000, TRandom *rng=nullptr)
Fill histogram following distribution in function fname.
Definition TH1.cxx:3525
static Bool_t GetDefaultSumw2()
Return kTRUE if TH1::Sumw2 must be called when creating new histograms.
Definition TH1.cxx:4378
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:3742
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:3892
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:4893
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:8390
virtual Int_t GetNbinsX() const
Definition TH1.h:296
virtual void SetMaximum(Double_t maximum=-1111)
Definition TH1.h:398
virtual TH1 * FFT(TH1 *h_output, Option_t *option)
This function allows to do discrete Fourier transforms of TH1 and TH2.
Definition TH1.cxx:3290
virtual void LabelsInflate(Option_t *axis="X")
Double the number of bins for axis.
Definition TH1.cxx:5247
virtual TH1 * ShowBackground(Int_t niter=20, Option_t *option="same")
This function calculates the background spectrum in this histogram.
Definition TH1.cxx:9127
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:2005
static Bool_t SameLimitsAndNBins(const TAxis &axis1, const TAxis &axis2)
Same limits and bins.
Definition TH1.cxx:5829
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:822
Double_t fMaximum
Maximum value for plotting.
Definition TH1.h:99
Int_t fBufferSize
fBuffer size
Definition TH1.h:106
virtual void RecursiveRemove(TObject *obj)
Recursively remove object from the list of functions.
Definition TH1.cxx:6536
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:9280
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:7861
Int_t fDimension
!Histogram dimension (1, 2 or 3 dim)
Definition TH1.h:109
virtual void SetBinError(Int_t bin, Double_t error)
Set the bin Error Note that this resets the bin eror option to be of Normal Type and for the non-empt...
Definition TH1.cxx:9046
EBinErrorOpt fBinStatErrOpt
option for bin statistical errors
Definition TH1.h:112
static Int_t fgBufferSize
!default buffer size for automatic histograms
Definition TH1.h:114
virtual void SetBinsLength(Int_t=-1)
Definition TH1.h:375
Double_t fNormFactor
Normalization factor.
Definition TH1.h:101
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3350
virtual TObject * FindObject(const char *name) const
Search object named name in the list of functions.
Definition TH1.cxx:3865
TAxis * GetYaxis()
Definition TH1.h:321
TArrayD fContour
Array to display contour levels.
Definition TH1.h:102
virtual Double_t GetBinErrorLow(Int_t bin) const
Return lower error associated to bin number bin.
Definition TH1.cxx:8919
virtual void SetContent(const Double_t *content)
Replace bin contents by the contents of array content.
Definition TH1.cxx:8246
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:7264
Short_t fBarWidth
(1000*width) for bar charts or legos
Definition TH1.h:93
virtual void SetContour(Int_t nlevels, const Double_t *levels=0)
Set the number and values of contour levels.
Definition TH1.cxx:8331
virtual Double_t GetBinErrorSqUnchecked(Int_t bin) const
Definition TH1.h:443
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:399
Bool_t IsBinUnderflow(Int_t bin, Int_t axis=0) const
Return true if the bin is underflow.
Definition TH1.cxx:5146
static bool CheckBinLabels(const TAxis *a1, const TAxis *a2)
Check that axis have same labels.
Definition TH1.cxx:1556
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:5047
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:6663
Bool_t IsBinOverflow(Int_t bin, Int_t axis=0) const
Return true if the bin is overflow.
Definition TH1.cxx:5114
UInt_t GetAxisLabelStatus() const
Internal function used in TH1::Fill to see which axis is full alphanumeric i.e.
Definition TH1.cxx:6635
Double_t * fIntegral
!Integral of bins used by GetRandom
Definition TH1.h:110
Double_t fMinimum
Minimum value for plotting.
Definition TH1.h:100
virtual Double_t Integral(Option_t *option="") const
Return integral of bin contents.
Definition TH1.cxx:7834
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:9062
virtual void DirectoryAutoAdd(TDirectory *)
Perform the automatic addition of the histogram to the given directory.
Definition TH1.cxx:2789
@ kNstat
Definition TH1.h:183
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:9027
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:8992
void Build()
Creates histogram basic data structure.
Definition TH1.cxx:767
virtual Double_t GetEntries() const
Return the current number of entries.
Definition TH1.cxx:4386
virtual TF1 * GetFunction(const char *name) const
Return pointer to function with name.
Definition TH1.cxx:8891
virtual Int_t BufferFill(Double_t x, Double_t w)
accumulate arguments in buffer.
Definition TH1.cxx:1492
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:5018
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:6609
TList * GetListOfFunctions() const
Definition TH1.h:243
virtual TH1 * DrawCopy(Option_t *option="", const char *name_postfix="_copy") const
Copy this histogram and Draw in the current pad.
Definition TH1.cxx:3120
virtual void Copy(TObject &hnew) const
Copy this histogram structure to newth1.
Definition TH1.cxx:2663
Bool_t IsEmpty() const
Check if an histogram is empty (this a protected method used mainly by TH1Merger )
Definition TH1.cxx:5096
virtual Double_t GetMeanError(Int_t axis=1) const
Return standard error of mean of this histogram along the X axis.
Definition TH1.cxx:7468
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition TH1.cxx:3073
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:7954
virtual void ResetStats()
Reset the statistics including the number of entries and replace with values calculated from bin cont...
Definition TH1.cxx:7795
static void SetDefaultBufferSize(Int_t buffersize=1000)
Static function to set the default buffer size for automatic histograms.
Definition TH1.cxx:6653
virtual void SetBinErrorOption(EBinErrorOpt type)
Definition TH1.h:376
virtual void SetBuffer(Int_t buffersize, Option_t *option="")
Set the maximum number of entries to be kept in the buffer.
Definition TH1.cxx:8306
virtual void DrawPanel()
Display a panel with all histogram drawing options.
Definition TH1.cxx:3181
@ kXaxis
Definition TH1.h:72
@ kNoAxis
NOTE: Must always be 0 !!!
Definition TH1.h:71
@ kZaxis
Definition TH1.h:74
@ kYaxis
Definition TH1.h:73
virtual Double_t GetRandom(TRandom *rng=nullptr) const
Return a random number distributed according the histogram bin contents.
Definition TH1.cxx:4942
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:2492
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:3479
virtual void GetMinimumAndMaximum(Double_t &min, Double_t &max) const
Retrieve the minimum and maximum values in the histogram.
Definition TH1.cxx:8571
virtual Int_t GetMaximumBin() const
Return location of bin with maximum value in the range.
Definition TH1.cxx:8420
static Int_t AutoP2GetBins(Int_t n)
Auxiliary function to get the next power of 2 integer value larger then n.
Definition TH1.cxx:1309
Double_t fEntries
Number of entries.
Definition TH1.h:94
virtual Long64_t Merge(TCollection *list)
Definition TH1.h:341
virtual void SetName(const char *name)
Change the name of this histogram.
Definition TH1.cxx:8800
virtual Double_t * GetIntegral()
Return a pointer to the array of bins integral.
Definition TH1.cxx:2578
TAxis fZaxis
Z axis descriptor.
Definition TH1.h:91
EStatOverflows fStatOverflows
per object flag to use under/overflows in statistics
Definition TH1.h:113
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:3453
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:9290
static bool CheckEqualAxes(const TAxis *a1, const TAxis *a2)
Check that the axis are the same.
Definition TH1.cxx:1603
@ kPoisson2
errors from Poisson interval at 95% CL (~ 2 sigma)
Definition TH1.h:66
@ kNormal
errors with Normal (Wald) approximation: errorUp=errorLow= sqrt(N)
Definition TH1.h:64
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:4993
TAxis fXaxis
X axis descriptor.
Definition TH1.h:89
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
Definition TH1.cxx:3246
virtual Bool_t IsHighlight() const
Definition TH1.h:334
virtual void ExtendAxis(Double_t x, TAxis *axis)
Histogram is resized along axis such that x is in the axis range.
Definition TH1.cxx:6464
virtual void SetNameTitle(const char *name, const char *title)
Change the name and title of this histogram.
Definition TH1.cxx:8814
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:9003
static bool CheckConsistency(const TH1 *h1, const TH1 *h2)
Check histogram compatibility.
Definition TH1.cxx:1676
TArrayD fSumw2
Array of sum of squares of weights.
Definition TH1.h:103
TH1 * GetAsymmetry(TH1 *h2, Double_t c2=1, Double_t dc2=0)
Return an histogram containing the asymmetry of this histogram with h2, where the asymmetry is define...
Definition TH1.cxx:4302
virtual Double_t GetContourLevel(Int_t level) const
Return value of contour number level.
Definition TH1.cxx:8278
virtual void SetHighlight(Bool_t set=kTRUE)
Set highlight (enable/disable) mode for the histogram by default highlight mode is disable.
Definition TH1.cxx:4422
virtual Double_t GetBinErrorUp(Int_t bin) const
Return upper error associated to bin number bin.
Definition TH1.cxx:8950
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition TH1.cxx:6564
virtual void Paint(Option_t *option="")
Control routine to paint any kind of histograms.
Definition TH1.cxx:6155
virtual Int_t GetMinimumBin() const
Return location of bin with minimum value in the range.
Definition TH1.cxx:8505
virtual Int_t GetSumw2N() const
Definition TH1.h:314
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:3680
Bool_t GetStatOverflowsBehaviour() const
Definition TH1.h:152
virtual Double_t GetStdDevError(Int_t axis=1) const
Return error of standard deviation estimation for Normal distribution.
Definition TH1.cxx:7548
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:2828
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:8475
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:1639
TAxis fYaxis
Y axis descriptor.
Definition TH1.h:90
virtual Double_t KolmogorovTest(const TH1 *h2, Option_t *option="") const
Statistical test of compatibility in shape between this histogram and h2, using Kolmogorov test.
Definition TH1.cxx:8068
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition TH1.cxx:7810
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:6727
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:9014
TVirtualHistPainter * fPainter
!pointer to histogram painter
Definition TH1.h:111
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition TH1.cxx:8607
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:3713
virtual char * GetObjectInfo(Int_t px, Int_t py) const
Redefines TObject::GetObjectInfo.
Definition TH1.cxx:4443
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:8860
virtual void SetEntries(Double_t n)
Definition TH1.h:385
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:6407
static bool CheckAxisLimits(const TAxis *a1, const TAxis *a2)
Check that the axis limits of the histograms are the same.
Definition TH1.cxx:1588
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition TH1.cxx:750
static Bool_t fgDefaultSumw2
!flag to call TH1::Sumw2 automatically at histogram creation time
Definition TH1.h:117
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
Compute distance from point px,py to a line.
Definition TH1.cxx:2811
Double_t fTsumwx
Total Sum of weight*X.
Definition TH1.h:97
virtual void LabelsDeflate(Option_t *axis="X")
Reduce the number of bins for the axis passed in the option to the number of bins having a label.
Definition TH1.cxx:5177
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:2530
TString fOption
histogram options
Definition TH1.h:104
virtual Int_t GetContour(Double_t *levels=0)
Return contour values into array levels if pointer levels is non zero.
Definition TH1.cxx:8259
virtual void Eval(TF1 *f1, Option_t *option="")
Evaluate function f1 at the center of bins of this histogram.
Definition TH1.cxx:3198
virtual void SetBarWidth(Float_t width=0.5)
Set the width of bars as fraction of the bin width for drawing mode "B".
Definition TH1.h:360
virtual Int_t BufferEmpty(Int_t action=0)
Fill histogram with all entries in the buffer.
Definition TH1.cxx:1402
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition TH1.cxx:8830
virtual TH1 * Rebin(Int_t ngroup=2, const char *newname="", const Double_t *xbins=0)
Rebin this histogram.
Definition TH1.cxx:6222
virtual Double_t GetKurtosis(Int_t axis=1) const
Definition TH1.cxx:7637
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.
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:822
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition TList.cxx:578
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:357
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition TList.cxx:764
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:470
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:659
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:935
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:359
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:377
@ 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:130
virtual void UseCurrentStyle()
Set current style settings in this object This function is called when either TCanvas::UseCurrentStyl...
Definition TObject.cxx:717
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:879
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:107
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition TObject.cxx:666
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:696
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:445
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:893
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:707
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:867
Long_t ExecPlugin(int nargs, const T &... params)
Int_t LoadPlugin()
Load the plugin library for this handler.
This is the base class for the ROOT Random number generators.
Definition TRandom.h:27
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition TRandom.cxx:402
virtual Double_t PoissonD(Double_t mean)
Generates a random number according to a Poisson law.
Definition TRandom.cxx:454
virtual Double_t Rndm()
Machine independent random number generator.
Definition TRandom.cxx:552
Basic string class.
Definition TString.h:136
Ssiz_t Length() const
Definition TString.h:410
void ToLower()
Change string to lower-case.
Definition TString.cxx:1145
void Clear()
Clear string without changing its capacity.
Definition TString.cxx:1196
const char * Data() const
Definition TString.h:369
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:692
void ToUpper()
Change string to upper case.
Definition TString.cxx:1158
Bool_t IsNull() const
Definition TString.h:407
TString & Remove(Ssiz_t pos)
Definition TString.h:673
TString & Append(const char *cs)
Definition TString.h:564
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:2331
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2309
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:624
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:639
Int_t GetOptStat() const
Definition TStyle.h:236
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:1589
void SetHistFillColor(Color_t color=1)
Definition TStyle.h:362
Color_t GetHistLineColor() const
Definition TStyle.h:224
Bool_t IsReading() const
Definition TStyle.h:282
Float_t GetBarOffset() const
Definition TStyle.h:174
void SetHistLineStyle(Style_t styl=0)
Definition TStyle.h:365
Style_t GetHistFillStyle() const
Definition TStyle.h:225
Color_t GetHistFillColor() const
Definition TStyle.h:223
Float_t GetBarWidth() const
Definition TStyle.h:175
Bool_t GetCanvasPreferGL() const
Definition TStyle.h:179
void SetHistLineColor(Color_t color=1)
Definition TStyle.h:363
void SetBarOffset(Float_t baroff=0.5)
Definition TStyle.h:319
Style_t GetHistLineStyle() const
Definition TStyle.h:226
void SetBarWidth(Float_t barwidth=0.5)
Definition TStyle.h:320
void SetHistFillStyle(Style_t styl=0)
Definition TStyle.h:364
Width_t GetHistLineWidth() const
Definition TStyle.h:227
Int_t GetOptFit() const
Definition TStyle.h:235
void SetHistLineWidth(Width_t width=1)
Definition TStyle.h:366
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:971
void FitOptionsMake(EFitObjectType type, const char *option, Foption_t &fitOption)
Decode list of options into fitOption.
Definition HFitImpl.cxx:684
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)
R__EXTERN TVirtualRWMutex * gCoreMutex
Bool_t IsNaN(Double_t x)
Definition TMath.h:892
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition TMath.h:713
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:901
Double_t Floor(Double_t x)
Definition TMath.h:703
Double_t ATan(Double_t)
Definition TMath.h:675
Double_t Ceil(Double_t x)
Definition TMath.h:695
T MinElement(Long64_t n, const T *a)
Return minimum of array a of length n.
Definition TMath.h:952
Double_t Log(Double_t x)
Definition TMath.h:760
Double_t Sqrt(Double_t x)
Definition TMath.h:691
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition TMath.h:735
Short_t Min(Short_t a, Short_t b)
Definition TMathBase.h:180
constexpr Double_t Pi()
Definition TMath.h:37
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Definition TMath.h:430
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
Definition TMath.h:424
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:1247
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition TMathBase.h:278
Double_t Log10(Double_t x)
Definition TMath.h:764
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:914
Definition first.py:1
th1 Draw()
auto * m
Definition textangle.C:8
auto * l
Definition textangle.C:4
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345
REAL epsilon
Definition triangle.c:617