TH1.cxx

Go to the documentation of this file.
00001 // @(#)root/hist:$Id: TH1.cxx 36711 2010-11-17 08:32:33Z couet $
00002 // Author: Rene Brun   26/12/94
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include <stdlib.h>
00013 #include <string.h>
00014 #include <stdio.h>
00015 #include <ctype.h>
00016 
00017 #include "Riostream.h"
00018 #include "TROOT.h"
00019 #include "TClass.h"
00020 #include "TMath.h"
00021 #include "THashList.h"
00022 #include "TH1.h"
00023 #include "TH2.h"
00024 #include "TF2.h"
00025 #include "TF3.h"
00026 #include "TPluginManager.h"
00027 #include "TVirtualPad.h"
00028 #include "TRandom.h"
00029 #include "TVirtualFitter.h"
00030 #include "THLimitsFinder.h"
00031 #include "TProfile.h"
00032 #include "TStyle.h"
00033 #include "TVectorF.h"
00034 #include "TVectorD.h"
00035 #include "TBrowser.h"
00036 #include "TObjString.h"
00037 #include "TError.h"
00038 #include "TVirtualHistPainter.h"
00039 #include "TVirtualFFT.h"
00040 #include "TSystem.h"
00041 
00042 #include "HFitInterface.h"
00043 #include "Fit/DataRange.h"
00044 #include "Math/MinimizerOptions.h"
00045 
00046 //______________________________________________________________________________
00047 /* Begin_Html
00048 <center><h2>The Histogram classes</h2></center>
00049 ROOT supports the following histogram types:
00050 <ul>
00051   <li>1-D histograms:
00052    <ul>
00053          <li>TH1C : histograms with one byte per channel.   Maximum bin content = 127
00054          <li>TH1S : histograms with one short per channel.  Maximum bin content = 32767
00055          <li>TH1I : histograms with one int per channel.    Maximum bin content = 2147483647
00056          <li>TH1F : histograms with one float per channel.  Maximum precision 7 digits
00057          <li>TH1D : histograms with one double per channel. Maximum precision 14 digits
00058    </ul>
00059 
00060   <li>2-D histograms:
00061    <ul>
00062          <li>TH2C : histograms with one byte per channel.   Maximum bin content = 127
00063          <li>TH2S : histograms with one short per channel.  Maximum bin content = 32767
00064          <li>TH2I : histograms with one int per channel.    Maximum bin content = 2147483647
00065          <li>TH2F : histograms with one float per channel.  Maximum precision 7 digits
00066          <li>TH2D : histograms with one double per channel. Maximum precision 14 digits
00067    </ul>
00068 
00069   <li>3-D histograms:
00070    <ul>
00071          <li>TH3C : histograms with one byte per channel.   Maximum bin content = 127
00072          <li>TH3S : histograms with one short per channel.  Maximum bin content = 32767
00073          <li>TH3I : histograms with one int per channel.    Maximum bin content = 2147483647
00074          <li>TH3F : histograms with one float per channel.  Maximum precision 7 digits
00075          <li>TH3D : histograms with one double per channel. Maximum precision 14 digits
00076    </ul>
00077   <li>Profile histograms: See classes  TProfile, TProfile2D and TProfile3D.
00078       Profile histograms are used to display the mean value of Y and its RMS
00079       for each bin in X. Profile histograms are in many cases an elegant
00080       replacement of two-dimensional histograms : the inter-relation of two
00081       measured quantities X and Y can always be visualized by a two-dimensional
00082       histogram or scatter-plot; If Y is an unknown (but single-valued)
00083       approximate function of X, this function is displayed by a profile
00084       histogram with much better precision than by a scatter-plot.
00085 </ul>
00086 
00087 All histogram classes are derived from the base class TH1
00088 <pre>
00089                                 TH1
00090                                  ^
00091                                  |
00092                                  |
00093                                  |
00094          -----------------------------------------------------------
00095                 |                |       |      |      |     |     |
00096                 |                |      TH1C   TH1S   TH1I  TH1F  TH1D
00097                 |                |                                 |
00098                 |                |                                 |
00099                 |               TH2                             TProfile
00100                 |                |
00101                 |                |
00102                 |                ----------------------------------
00103                 |                        |      |      |     |     |
00104                 |                       TH2C   TH2S   TH2I  TH2F  TH2D
00105                 |                                                  |
00106                TH3                                                 |
00107                 |                                               TProfile2D
00108                 |
00109                 -------------------------------------
00110                         |      |      |      |      |
00111                        TH3C   TH3S   TH3I   TH3F   TH3D
00112                                                     |
00113                                                     |
00114                                                  TProfile3D
00115 
00116       The TH*C classes also inherit from the array class TArrayC.
00117       The TH*S classes also inherit from the array class TArrayS.
00118       The TH*I classes also inherit from the array class TArrayI.
00119       The TH*F classes also inherit from the array class TArrayF.
00120       The TH*D classes also inherit from the array class TArrayD.
00121 </pre>
00122 
00123 <h4>Creating histograms</h4>
00124 <p>
00125      Histograms are created by invoking one of the constructors, e.g.
00126 <pre>
00127        TH1F *h1 = new TH1F("h1", "h1 title", 100, 0, 4.4);
00128        TH2F *h2 = new TH2F("h2", "h2 title", 40, 0, 4, 30, -3, 3);
00129 </pre>
00130 <p>  Histograms may also be created by:
00131   <ul>
00132       <li> calling the Clone function, see below
00133       <li> making a projection from a 2-D or 3-D histogram, see below
00134       <li> reading an histogram from a file
00135    </ul>
00136 <p>  When an histogram is created, a reference to it is automatically added
00137      to the list of in-memory objects for the current file or directory.
00138      This default behaviour can be changed by:
00139 <pre>
00140        h->SetDirectory(0);          for the current histogram h
00141        TH1::AddDirectory(kFALSE);   sets a global switch disabling the reference
00142 </pre>
00143      When the histogram is deleted, the reference to it is removed from
00144      the list of objects in memory.
00145      When a file is closed, all histograms in memory associated with this file
00146      are automatically deleted.
00147 
00148 <h4>Fix or variable bin size</h4>
00149 
00150      All histogram types support either fix or variable bin sizes.
00151      2-D histograms may have fix size bins along X and variable size bins
00152      along Y or vice-versa. The functions to fill, manipulate, draw or access
00153      histograms are identical in both cases.
00154 <p>     Each histogram always contains 3 objects TAxis: fXaxis, fYaxis and fZaxis
00155      To access the axis parameters, do:
00156 <pre>
00157         TAxis *xaxis = h->GetXaxis(); etc.
00158         Double_t binCenter = xaxis->GetBinCenter(bin), etc.
00159 </pre>
00160      See class TAxis for a description of all the access functions.
00161      The axis range is always stored internally in double precision.
00162 
00163 <h4>Convention for numbering bins</h4>
00164 
00165       For all histogram types: nbins, xlow, xup
00166 <pre>
00167         bin = 0;       underflow bin
00168         bin = 1;       first bin with low-edge xlow INCLUDED
00169         bin = nbins;   last bin with upper-edge xup EXCLUDED
00170         bin = nbins+1; overflow bin
00171 </pre>
00172 <p>      In case of 2-D or 3-D histograms, a "global bin" number is defined.
00173       For example, assuming a 3-D histogram with (binx, biny, binz), the function
00174 <pre>
00175         Int_t gbin = h->GetBin(binx, biny, binz);
00176 </pre>
00177       returns a global/linearized gbin number. This global gbin is useful
00178       to access the bin content/error information independently of the dimension.
00179       Note that to access the information other than bin content and errors
00180       one should use the TAxis object directly with e.g.:
00181 <pre>
00182          Double_t xcenter = h3->GetZaxis()->GetBinCenter(27);
00183 </pre>
00184        returns the center along z of bin number 27 (not the global bin)
00185        in the 3-D histogram h3.
00186 
00187 <h4>Alphanumeric Bin Labels</h4>
00188 
00189      By default, an histogram axis is drawn with its numeric bin labels.
00190      One can specify alphanumeric labels instead with:
00191 <ul>
00192        <li> call TAxis::SetBinLabel(bin, label);
00193            This can always be done before or after filling.
00194            When the histogram is drawn, bin labels will be automatically drawn.
00195            See example in $ROOTSYS/tutorials/graphs/labels1.C, labels2.C
00196        <li> call to a Fill function with one of the arguments being a string, e.g.
00197 <pre>
00198            hist1->Fill(somename, weigth);
00199            hist2->Fill(x, somename, weight);
00200            hist2->Fill(somename, y, weight);
00201            hist2->Fill(somenamex, somenamey, weight);
00202 </pre>
00203            See example in $ROOTSYS/tutorials/hist/hlabels1.C, hlabels2.C
00204        <li> via TTree::Draw.
00205            see for example $ROOTSYS/tutorials/tree/cernstaff.C
00206 <pre>
00207            tree.Draw("Nation::Division");
00208 </pre>
00209            where "Nation" and "Division" are two branches of a Tree.
00210 </ul>
00211 
00212 <p>     When using the options 2 or 3 above, the labels are automatically
00213      added to the list (THashList) of labels for a given axis.
00214      By default, an axis is drawn with the order of bins corresponding
00215      to the filling sequence. It is possible to reorder the axis
00216 
00217 <ul>
00218           <li>alphabetically
00219           <li>by increasing or decreasing values
00220 </ul>
00221 
00222 <p>     The reordering can be triggered via the TAxis context menu by selecting
00223      the menu item "LabelsOption" or by calling directly
00224         TH1::LabelsOption(option, axis) where
00225 <ul>
00226           <li>axis may be "X", "Y" or "Z"
00227           <li>option may be:
00228            <ul>
00229              <li>"a" sort by alphabetic order
00230              <li>">" sort by decreasing values
00231              <li>"<" sort by increasing values
00232              <li>"h" draw labels horizonthal
00233              <li>"v" draw labels vertical
00234              <li>"u" draw labels up (end of label right adjusted)
00235              <li>"d" draw labels down (start of label left adjusted)
00236            </ul>
00237 </ul>
00238 <p>     When using the option 2 above, new labels are added by doubling the current
00239      number of bins in case one label does not exist yet.
00240      When the Filling is terminated, it is possible to trim the number
00241      of bins to match the number of active labels by calling
00242 <pre>
00243            TH1::LabelsDeflate(axis) with axis = "X", "Y" or "Z"
00244 </pre>
00245      This operation is automatic when using TTree::Draw.
00246      Once bin labels have been created, they become persistent if the histogram
00247      is written to a file or when generating the C++ code via SavePrimitive.
00248 
00249 <h4>Histograms with automatic bins</h4>
00250 
00251      When an histogram is created with an axis lower limit greater or equal
00252      to its upper limit, the SetBuffer is automatically called with an
00253      argument fBufferSize equal to fgBufferSize (default value=1000).
00254      fgBufferSize may be reset via the static function TH1::SetDefaultBufferSize.
00255      The axis limits will be automatically computed when the buffer will
00256      be full or when the function BufferEmpty is called.
00257 
00258 <h4>Filling histograms</h4>
00259 
00260      An histogram is typically filled with statements like:
00261 <pre>
00262        h1->Fill(x);
00263        h1->Fill(x, w); //fill with weight
00264        h2->Fill(x, y)
00265        h2->Fill(x, y, w)
00266        h3->Fill(x, y, z)
00267        h3->Fill(x, y, z, w)
00268 </pre>
00269      or via one of the Fill functions accepting names described above.
00270      The Fill functions compute the bin number corresponding to the given
00271      x, y or z argument and increment this bin by the given weight.
00272      The Fill functions return the bin number for 1-D histograms or global
00273      bin number for 2-D and 3-D histograms.
00274 <p>     If TH1::Sumw2 has been called before filling, the sum of squares of
00275      weights is also stored.
00276      One can also increment directly a bin number via TH1::AddBinContent
00277      or replace the existing content via TH1::SetBinContent.
00278      To access the bin content of a given bin, do:
00279 <pre>
00280        Double_t binContent = h->GetBinContent(bin);
00281 </pre>
00282 
00283 <p>     By default, the bin number is computed using the current axis ranges.
00284      If the automatic binning option has been set via
00285 <pre>
00286        h->SetBit(TH1::kCanRebin);
00287 </pre>
00288      then, the Fill Function will automatically extend the axis range to
00289      accomodate the new value specified in the Fill argument. The method
00290      used is to double the bin size until the new value fits in the range,
00291      merging bins two by two. This automatic binning options is extensively
00292      used by the TTree::Draw function when histogramming Tree variables
00293      with an unknown range.
00294 <p>     This automatic binning option is supported for 1-D, 2-D and 3-D histograms.
00295 
00296      During filling, some statistics parameters are incremented to compute
00297      the mean value and Root Mean Square with the maximum precision.
00298 
00299 <p>     In case of histograms of type TH1C, TH1S, TH2C, TH2S, TH3C, TH3S
00300      a check is made that the bin contents do not exceed the maximum positive
00301      capacity (127 or 32767). Histograms of all types may have positive
00302      or/and negative bin contents.
00303 
00304 <h4>Rebinning</h4>
00305 
00306      At any time, an histogram can be rebinned via TH1::Rebin. This function
00307      returns a new histogram with the rebinned contents.
00308      If bin errors were stored, they are recomputed during the rebinning.
00309 
00310 <h4>Associated errors</h4>
00311 
00312      By default, for each bin, the sum of weights is computed at fill time.
00313      One can also call TH1::Sumw2 to force the storage and computation
00314      of the sum of the square of weights per bin.
00315      If Sumw2 has been called, the error per bin is computed as the
00316      sqrt(sum of squares of weights), otherwise the error is set equal
00317      to the sqrt(bin content).
00318      To return the error for a given bin number, do:
00319 <pre>
00320         Double_t error = h->GetBinError(bin);
00321 </pre>
00322 
00323 <h4>Associated functions</h4>
00324 
00325      One or more object (typically a TF1*) can be added to the list
00326      of functions (fFunctions) associated to each histogram.
00327      When TH1::Fit is invoked, the fitted function is added to this list.
00328      Given an histogram h, one can retrieve an associated function
00329      with:
00330 <pre>
00331         TF1 *myfunc = h->GetFunction("myfunc");
00332 </pre>
00333 
00334 <h4>Operations on histograms</h4>
00335 
00336 
00337      Many types of operations are supported on histograms or between histograms
00338 <ul>
00339      <li> Addition of an histogram to the current histogram.
00340      <li> Additions of two histograms with coefficients and storage into the current
00341        histogram.
00342      <li> Multiplications and Divisions are supported in the same way as additions.
00343      <li> The Add, Divide and Multiply functions also exist to add, divide or multiply
00344        an histogram by a function.
00345 </ul>
00346      If an histogram has associated error bars (TH1::Sumw2 has been called),
00347      the resulting error bars are also computed assuming independent histograms.
00348      In case of divisions, Binomial errors are also supported.
00349      One can mark a histogram to be an "average" histogram by setting its bit kIsAverage via
00350        myhist.SetBit(TH1::kIsAverage);
00351      When adding (see TH1::Add) average histograms, the histograms are averaged and not summed.
00352 
00353 
00354 
00355 <h4>Fitting histograms</h4>
00356 
00357      Histograms (1-D, 2-D, 3-D and Profiles) can be fitted with a user
00358      specified function via TH1::Fit. When an histogram is fitted, the
00359      resulting function with its parameters is added to the list of functions
00360      of this histogram. If the histogram is made persistent, the list of
00361      associated functions is also persistent. Given a pointer (see above)
00362      to an associated function myfunc, one can retrieve the function/fit
00363      parameters with calls such as:
00364 <pre>
00365        Double_t chi2 = myfunc->GetChisquare();
00366        Double_t par0 = myfunc->GetParameter(0); value of 1st parameter
00367        Double_t err0 = myfunc->GetParError(0);  error on first parameter
00368 </pre>
00369 
00370 <h4>Projections of histograms</h4>
00371 
00372 <p>     One can:
00373 <ul>
00374       <li> make a 1-D projection of a 2-D histogram or Profile
00375         see functions TH2::ProjectionX,Y, TH2::ProfileX,Y, TProfile::ProjectionX
00376       <li> make a 1-D, 2-D or profile out of a 3-D histogram
00377         see functions TH3::ProjectionZ, TH3::Project3D.
00378 </ul>
00379 
00380 <p>     One can fit these projections via:
00381 <pre>
00382       TH2::FitSlicesX,Y, TH3::FitSlicesZ.
00383 </pre>
00384 
00385 <h4>Random Numbers and histograms</h4>
00386 
00387      TH1::FillRandom can be used to randomly fill an histogram using
00388                     the contents of an existing TF1 function or another
00389                     TH1 histogram (for all dimensions).
00390 <p>     For example the following two statements create and fill an histogram
00391      10000 times with a default gaussian distribution of mean 0 and sigma 1:
00392 <pre>
00393        TH1F h1("h1", "histo from a gaussian", 100, -3, 3);
00394        h1.FillRandom("gaus", 10000);
00395 </pre>
00396      TH1::GetRandom can be used to return a random number distributed
00397                     according the contents of an histogram.
00398 
00399 <h4>Making a copy of an histogram</h4>
00400 
00401      Like for any other ROOT object derived from TObject, one can use
00402      the Clone() function. This makes an identical copy of the original
00403      histogram including all associated errors and functions, e.g.:
00404 <pre>
00405        TH1F *hnew = (TH1F*)h->Clone("hnew");
00406 </pre>
00407 
00408 <h4>Normalizing histograms</h4>
00409 
00410      One can scale an histogram such that the bins integral is equal to
00411      the normalization parameter via TH1::Scale(Double_t norm), where norm
00412      is the desired normalization divided by the integral of the histogram.
00413 
00414 <h4>Drawing histograms</h4>
00415 
00416      Histograms are drawn via the THistPainter class. Each histogram has
00417      a pointer to its own painter (to be usable in a multithreaded program).
00418      Many drawing options are supported.
00419      See THistPainter::Paint() for more details.
00420 <p>
00421     The same histogram can be drawn with different options in different pads.
00422      When an histogram drawn in a pad is deleted, the histogram is
00423      automatically removed from the pad or pads where it was drawn.
00424      If an histogram is drawn in a pad, then filled again, the new status
00425      of the histogram will be automatically shown in the pad next time
00426      the pad is updated. One does not need to redraw the histogram.
00427      To draw the current version of an histogram in a pad, one can use
00428 <pre>
00429         h->DrawCopy();
00430 </pre>
00431      This makes a clone (see Clone below) of the histogram. Once the clone
00432      is drawn, the original histogram may be modified or deleted without
00433      affecting the aspect of the clone.
00434 <p>
00435      One can use TH1::SetMaximum() and TH1::SetMinimum() to force a particular
00436      value for the maximum or the minimum scale on the plot. (For 1-D
00437      histograms this means the y-axis, while for 2-D histograms these
00438      functions affect the z-axis).
00439 <p>
00440      TH1::UseCurrentStyle() can be used to change all histogram graphics
00441      attributes to correspond to the current selected style.
00442      This function must be called for each histogram.
00443      In case one reads and draws many histograms from a file, one can force
00444      the histograms to inherit automatically the current graphics style
00445      by calling before gROOT->ForceStyle().
00446 
00447 
00448 <h4>Setting Drawing histogram contour levels (2-D hists only)</h4>
00449 
00450      By default contours are automatically generated at equidistant
00451      intervals. A default value of 20 levels is used. This can be modified
00452      via TH1::SetContour() or TH1::SetContourLevel().
00453      the contours level info is used by the drawing options "cont", "surf",
00454      and "lego".
00455 
00456 <h4>Setting histogram graphics attributes</h4>
00457 
00458      The histogram classes inherit from the attribute classes:
00459        TAttLine, TAttFill, TAttMarker and TAttText.
00460      See the member functions of these classes for the list of options.
00461 
00462 <h4>Giving titles to the X, Y and Z axis</h4>
00463 <pre>
00464        h->GetXaxis()->SetTitle("X axis title");
00465        h->GetYaxis()->SetTitle("Y axis title");
00466 </pre>
00467      The histogram title and the axis titles can be any TLatex string.
00468      The titles are part of the persistent histogram.
00469      It is also possible to specify the histogram title and the axis
00470      titles at creation time. These titles can be given in the "title"
00471      parameter. They must be separated by ";":
00472 <pre>
00473         TH1F* h=new TH1F("h", "Histogram title;X Axis;Y Axis;Z Axis", 100, 0, 1);
00474 </pre>
00475      Any title can be omitted:
00476 <pre>
00477         TH1F* h=new TH1F("h", "Histogram title;;Y Axis", 100, 0, 1);
00478         TH1F* h=new TH1F("h", ";;Y Axis", 100, 0, 1);
00479 </pre>
00480      The method SetTitle has the same syntax:
00481 <pre>
00482 </pre>
00483         h->SetTitle("Histogram title;Another X title Axis");
00484 
00485 <h4>Saving/Reading histograms to/from a ROOT file</h4>
00486 
00487      The following statements create a ROOT file and store an histogram
00488      on the file. Because TH1 derives from TNamed, the key identifier on
00489      the file is the histogram name:
00490 <pre>
00491         TFile f("histos.root", "new");
00492         TH1F h1("hgaus", "histo from a gaussian", 100, -3, 3);
00493         h1.FillRandom("gaus", 10000);
00494         h1->Write();
00495 </pre>
00496      To read this histogram in another Root session, do:
00497 <pre>
00498         TFile f("histos.root");
00499         TH1F *h = (TH1F*)f.Get("hgaus");
00500 </pre>
00501      One can save all histograms in memory to the file by:
00502 <pre>
00503         file->Write();
00504 </pre>
00505 
00506 <h4>Miscelaneous operations</h4>
00507 
00508 <pre>
00509         TH1::KolmogorovTest(): statistical test of compatibility in shape
00510                              between two histograms
00511         TH1::Smooth() smooths the bin contents of a 1-d histogram
00512         TH1::Integral() returns the integral of bin contents in a given bin range
00513         TH1::GetMean(int axis) returns the mean value along axis
00514         TH1::GetRMS(int axis)  returns the sigma distribution along axis
00515         TH1::GetEntries() returns the number of entries
00516         TH1::Reset() resets the bin contents and errors of an histogram
00517 </pre>
00518 End_Html */
00519 
00520 
00521 
00522 TF1 *gF1=0;  //left for back compatibility (use TVirtualFitter::GetUserFunc instead)
00523 
00524 Int_t  TH1::fgBufferSize   = 1000;
00525 Bool_t TH1::fgAddDirectory = kTRUE;
00526 Bool_t TH1::fgDefaultSumw2 = kFALSE;
00527 Bool_t TH1::fgStatOverflows= kFALSE;
00528 
00529 extern void H1InitGaus();
00530 extern void H1InitExpo();
00531 extern void H1InitPolynom();
00532 extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
00533 extern void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail);
00534 extern void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b);
00535 
00536 // Internal exceptions for the CheckConsistency method
00537 class DifferentNumberOfBins: public std::exception {};
00538 class DifferentAxisLimits: public std::exception {};
00539 class DifferentBinLimits: public std::exception {};
00540 
00541 ClassImp(TH1)
00542 
00543 //______________________________________________________________________________
00544 TH1::TH1(): TNamed(), TAttLine(), TAttFill(), TAttMarker()
00545 {
00546 //   -*-*-*-*-*-*-*-*-*Histogram default constructor*-*-*-*-*-*-*-*-*-*-*-*-*
00547 //                     =============================
00548    fDirectory     = 0;
00549    fFunctions     = new TList;
00550    fNcells        = 0;
00551    fIntegral      = 0;
00552    fPainter       = 0;
00553    fEntries       = 0;
00554    fNormFactor    = 0;
00555    fTsumw         = fTsumw2=fTsumwx=fTsumwx2=0;
00556    fMaximum       = -1111;
00557    fMinimum       = -1111;
00558    fBufferSize    = 0;
00559    fBuffer        = 0;
00560    fXaxis.SetName("xaxis");
00561    fYaxis.SetName("yaxis");
00562    fZaxis.SetName("zaxis");
00563    fXaxis.SetParent(this);
00564    fYaxis.SetParent(this);
00565    fZaxis.SetParent(this);
00566    UseCurrentStyle();
00567 }
00568 
00569 //______________________________________________________________________________
00570 TH1::~TH1()
00571 {
00572 //   -*-*-*-*-*-*-*-*-*Histogram default destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*
00573 //                     ============================
00574 
00575    if (!TestBit(kNotDeleted)) {
00576       return;
00577    }
00578    delete[] fIntegral;
00579    fIntegral = 0;
00580    delete[] fBuffer;
00581    fBuffer = 0;
00582    if (fFunctions) {
00583       fFunctions->SetBit(kInvalidObject);
00584       TObject* obj = 0;
00585       //special logic to support the case where the same object is
00586       //added multiple times in fFunctions.
00587       //This case happens when the same object is added with different
00588       //drawing modes
00589       //In the loop below we must be careful with objects (eg TCutG) that may
00590       // have been added to the list of functions of several histograms
00591       //and may have been already deleted.
00592       while ((obj  = fFunctions->First())) {
00593          while(fFunctions->Remove(obj)) { }
00594          if (!obj->TestBit(kNotDeleted)) {
00595             break;
00596          }
00597          delete obj;
00598          obj = 0;
00599       }
00600       delete fFunctions;
00601       fFunctions = 0;
00602    }
00603    if (fDirectory) {
00604       fDirectory->Remove(this);
00605       fDirectory = 0;
00606    }
00607    delete fPainter;
00608    fPainter = 0;
00609 }
00610 
00611 //______________________________________________________________________________
00612 TH1::TH1(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
00613     :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
00614 {
00615 //   -*-*-*-*-*-*-*Normal constructor for fix bin size histograms*-*-*-*-*-*-*
00616 //                 ==============================================
00617 //
00618 //     Creates the main histogram structure:
00619 //        name   : name of histogram (avoid blanks)
00620 //        title  : histogram title
00621 //                 if title is of the form "stringt;stringx;stringy;stringz"
00622 //                 the histogram title is set to stringt,
00623 //                 the x axis title to stringy, the y axis title to stringy, etc.
00624 //        nbins  : number of bins
00625 //        xlow   : low edge of first bin
00626 //        xup    : upper edge of last bin (not included in last bin)
00627 //
00628 //      When an histogram is created, it is automatically added to the list
00629 //      of special objects in the current directory.
00630 //      To find the pointer to this histogram in the current directory
00631 //      by its name, do:
00632 //      TH1F *h1 = (TH1F*)gDirectory->FindObject(name);
00633 //
00634 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
00635 
00636    Build();
00637    if (nbins <= 0) nbins = 1;
00638    fXaxis.Set(nbins,xlow,xup);
00639    fNcells = fXaxis.GetNbins()+2;
00640 }
00641 
00642 //______________________________________________________________________________
00643 TH1::TH1(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
00644     :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
00645 {
00646 //   -*-*-*-*-*Normal constructor for variable bin size histograms*-*-*-*-*-*-*
00647 //             ===================================================
00648 //
00649 //  Creates the main histogram structure:
00650 //     name   : name of histogram (avoid blanks)
00651 //     title  : histogram title
00652 //              if title is of the form "stringt;stringx;stringy;stringz"
00653 //              the histogram title is set to stringt,
00654 //              the x axis title to stringx, the y axis title to stringy, etc.
00655 //     nbins  : number of bins
00656 //     xbins  : array of low-edges for each bin
00657 //              This is an array of size nbins+1
00658 //
00659 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
00660    Build();
00661    if (nbins <= 0) nbins = 1;
00662    if (xbins) fXaxis.Set(nbins,xbins);
00663    else       fXaxis.Set(nbins,0,1);
00664    fNcells = fXaxis.GetNbins()+2;
00665 }
00666 
00667 //______________________________________________________________________________
00668 TH1::TH1(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
00669     :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
00670 {
00671 //   -*-*-*-*-*Normal constructor for variable bin size histograms*-*-*-*-*-*-*
00672 //             ===================================================
00673 //
00674 //  Creates the main histogram structure:
00675 //     name   : name of histogram (avoid blanks)
00676 //     title  : histogram title
00677 //              if title is of the form "stringt;stringx;stringy;stringz"
00678 //              the histogram title is set to stringt,
00679 //              the x axis title to stringx, the y axis title to stringy, etc.
00680 //     nbins  : number of bins
00681 //     xbins  : array of low-edges for each bin
00682 //              This is an array of size nbins+1
00683 //
00684 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
00685    Build();
00686    if (nbins <= 0) nbins = 1;
00687    if (xbins) fXaxis.Set(nbins,xbins);
00688    else       fXaxis.Set(nbins,0,1);
00689    fNcells = fXaxis.GetNbins()+2;
00690 }
00691 
00692 //______________________________________________________________________________
00693 TH1::TH1(const TH1 &h) : TNamed(), TAttLine(), TAttFill(), TAttMarker()
00694 {
00695    // Copy constructor.
00696    // The list of functions is not copied. (Use Clone if needed)
00697 
00698    ((TH1&)h).Copy(*this);
00699 }
00700 
00701 //______________________________________________________________________________
00702 Bool_t TH1::AddDirectoryStatus()
00703 {
00704    //static function: cannot be inlined on Windows/NT
00705    return fgAddDirectory;
00706 }
00707 
00708 //______________________________________________________________________________
00709 void TH1::Browse(TBrowser *b)
00710 {
00711    // Browe the Histogram object.
00712 
00713    Draw(b ? b->GetDrawOption() : "");
00714    gPad->Update();
00715 }
00716 
00717 
00718 //______________________________________________________________________________
00719 void TH1::Build()
00720 {
00721 //   -*-*-*-*-*-*-*-*Creates histogram basic data structure*-*-*-*-*-*-*-*-*-*
00722 //                   ======================================
00723 
00724    fDirectory     = 0;
00725    fPainter       = 0;
00726    fIntegral      = 0;
00727    fEntries       = 0;
00728    fNormFactor    = 0;
00729    fTsumw         = fTsumw2=fTsumwx=fTsumwx2=0;
00730    fMaximum       = -1111;
00731    fMinimum       = -1111;
00732    fBufferSize    = 0;
00733    fBuffer        = 0;
00734    fXaxis.SetName("xaxis");
00735    fYaxis.SetName("yaxis");
00736    fZaxis.SetName("zaxis");
00737    fYaxis.Set(1,0.,1.);
00738    fZaxis.Set(1,0.,1.);
00739    fXaxis.SetParent(this);
00740    fYaxis.SetParent(this);
00741    fZaxis.SetParent(this);
00742 
00743    SetTitle(fTitle.Data());
00744 
00745    fFunctions = new TList;
00746 
00747    UseCurrentStyle();
00748 
00749    if (TH1::AddDirectoryStatus()) {
00750       fDirectory = gDirectory;
00751       if (fDirectory) {
00752          fDirectory->Append(this,kTRUE);
00753       }
00754    }
00755 }
00756 
00757 //______________________________________________________________________________
00758 void TH1::Add(TF1 *f1, Double_t c1, Option_t *option)
00759 {
00760 // Performs the operation: this = this + c1*f1
00761 // if errors are defined (see TH1::Sumw2), errors are also recalculated.
00762 //
00763 // By default, the function is computed at the centre of the bin.
00764 // if option "I" is specified (1-d histogram only), the integral of the
00765 // function in each bin is used instead of the value of the function at
00766 // the centre of the bin.
00767 // Only bins inside the function range are recomputed.
00768 // IMPORTANT NOTE: If you intend to use the errors of this histogram later
00769 // you should call Sumw2 before making this operation.
00770 // This is particularly important if you fit the histogram after TH1::Add
00771 
00772    if (!f1) {
00773       Error("Add","Attempt to add a non-existing function");
00774       return;
00775    }
00776 
00777    TString opt = option;
00778    opt.ToLower();
00779    Bool_t integral = kFALSE;
00780    if (opt.Contains("i") && fDimension ==1) integral = kTRUE;
00781 
00782    Int_t nbinsx = GetNbinsX();
00783    Int_t nbinsy = GetNbinsY();
00784    Int_t nbinsz = GetNbinsZ();
00785    if (fDimension < 2) nbinsy = -1;
00786    if (fDimension < 3) nbinsz = -1;
00787 
00788 //   - Add statistics
00789    Double_t s1[10];
00790    Int_t i;
00791    for (i=0;i<10;i++) {s1[i] = 0;}
00792    PutStats(s1);
00793    SetMinimum();
00794    SetMaximum();
00795 
00796 //   - Loop on bins (including underflows/overflows)
00797    Int_t bin, binx, biny, binz;
00798    Double_t cu=0;
00799    Double_t xx[3];
00800    Double_t *params = 0;
00801    f1->InitArgs(xx,params);
00802    for (binz=0;binz<=nbinsz+1;binz++) {
00803       xx[2] = fZaxis.GetBinCenter(binz);
00804       for (biny=0;biny<=nbinsy+1;biny++) {
00805          xx[1] = fYaxis.GetBinCenter(biny);
00806          for (binx=0;binx<=nbinsx+1;binx++) {
00807             xx[0] = fXaxis.GetBinCenter(binx);
00808             if (!f1->IsInside(xx)) continue;
00809             TF1::RejectPoint(kFALSE);
00810             bin = binx +(nbinsx+2)*(biny + (nbinsy+2)*binz);
00811             if (integral) {
00812                xx[0] = fXaxis.GetBinLowEdge(binx);
00813                cu  = c1*f1->EvalPar(xx);
00814                cu += c1*f1->Integral(fXaxis.GetBinLowEdge(binx),fXaxis.GetBinUpEdge(binx))*fXaxis.GetBinWidth(binx);
00815             } else {
00816                cu  = c1*f1->EvalPar(xx);
00817             }
00818             if (TF1::RejectedPoint()) continue;
00819             Double_t error1 = GetBinError(bin);
00820             AddBinContent(bin,cu);
00821             if (fSumw2.fN) {
00822                //errors are unchanged: error on f1 assumed 0
00823                fSumw2.fArray[bin] = error1*error1;
00824             }
00825          }
00826       }
00827    }
00828 }
00829 
00830 //______________________________________________________________________________
00831 void TH1::Add(const TH1 *h1, Double_t c1)
00832 {
00833 // Performs the operation: this = this + c1*h1
00834 // if errors are defined (see TH1::Sumw2), errors are also recalculated.
00835 // Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
00836 // if not already set.
00837 //
00838 // SPECIAL CASE (Average/Efficiency histograms)
00839 // For histograms representing averages or efficiencies, one should compute the average
00840 // of the two histograms and not the sum. One can mark a histogram to be an average
00841 // histogram by setting its bit kIsAverage with
00842 //    myhist.SetBit(TH1::kIsAverage);
00843 // Note that the two histograms must have their kIsAverage bit set
00844 //
00845 // IMPORTANT NOTE1: If you intend to use the errors of this histogram later
00846 // you should call Sumw2 before making this operation.
00847 // This is particularly important if you fit the histogram after TH1::Add
00848 //
00849 // IMPORTANT NOTE2: if h1 has a normalisation factor, the normalisation factor
00850 // is used , ie  this = this + c1*factor*h1
00851 // Use the other TH1::Add function if you do not want this feature
00852 
00853    if (!h1) {
00854       Error("Add","Attempt to add a non-existing histogram");
00855       return;
00856    }
00857 
00858    Int_t nbinsx = GetNbinsX();
00859    Int_t nbinsy = GetNbinsY();
00860    Int_t nbinsz = GetNbinsZ();
00861 
00862    try {
00863       CheckConsistency(this,h1);
00864    } catch(DifferentNumberOfBins&) {
00865       Error("Add","Attempt to add histograms with different number of bins");
00866       return;
00867    } catch(DifferentAxisLimits&) {
00868       Warning("Add","Attempt to add histograms with different axis limits");
00869    } catch(DifferentBinLimits&) {
00870       Warning("Add","Attempt to add histograms with different bin limits");
00871    }
00872 
00873    if (fDimension < 2) nbinsy = -1;
00874    if (fDimension < 3) nbinsz = -1;
00875 
00876 //    Create Sumw2 if h1 has Sumw2 set
00877    if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
00878 
00879 //   - Add statistics
00880    Double_t entries = TMath::Abs( GetEntries() + c1 * h1->GetEntries() );
00881    Double_t s1[kNstat], s2[kNstat];
00882 // statistics can be preserbed only in case of positive coefficients
00883 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
00884    Bool_t resetStats = (c1 < 0);
00885    if (!resetStats) {
00886       // need to initialize to zero s1 and s2 since 
00887       // GetStats fills only used elements depending on dimension and type
00888       for (Int_t i=0;i<kNstat;i++) {
00889          s1[i] = 0; 
00890          s2[i] = 0; 
00891       }      
00892       GetStats(s1);
00893       h1->GetStats(s2);
00894       for (Int_t i=0;i<kNstat;i++) {
00895          if (i == 1) s1[i] += c1*c1*s2[i];
00896          else        s1[i] += c1*s2[i];
00897       }
00898    }
00899 
00900    SetMinimum();
00901    SetMaximum();
00902 
00903 //   - Loop on bins (including underflows/overflows)
00904    Int_t bin, binx, biny, binz;
00905    Double_t cu;
00906    Double_t factor =1;
00907    if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();;
00908    for (binz=0;binz<=nbinsz+1;binz++) {
00909       for (biny=0;biny<=nbinsy+1;biny++) {
00910          for (binx=0;binx<=nbinsx+1;binx++) {
00911             bin = binx +(nbinsx+2)*(biny + (nbinsy+2)*binz);
00912             //special case where histograms have the kIsAverage bit set
00913             if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
00914                Double_t y1 = h1->GetBinContent(bin);
00915                Double_t y2 = this->GetBinContent(bin);
00916                Double_t e1 = h1->GetBinError(bin);
00917                Double_t e2 = this->GetBinError(bin);
00918                Double_t w1 = 1., w2 = 1.;
00919                if (e1 > 0) w1 = 1./(e1*e1);
00920                if (e2 > 0) w2 = 1./(e2*e2);
00921                SetBinContent(bin, (w1*y1 + w2*y2)/(w1 + w2));
00922                if (fSumw2.fN) fSumw2.fArray[bin] = 1./(w1 + w2);
00923             } else {
00924                cu  = c1*factor*h1->GetBinContent(bin);
00925                AddBinContent(bin,cu);
00926                if (fSumw2.fN) {
00927                   Double_t e1 = factor*h1->GetBinError(bin);
00928                   fSumw2.fArray[bin] += c1*c1*e1*e1;
00929                }
00930             }
00931          }
00932       }
00933    }
00934 
00935    // update statistics (do here to avoid changes by SetBinContent)
00936    if (resetStats)  {
00937       // statistics need to be reset in case coefficient are negative
00938       ResetStats();
00939    }
00940    else {
00941       PutStats(s1);
00942       SetEntries(entries);
00943    }
00944 }
00945 
00946 //______________________________________________________________________________
00947 void TH1::Add(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2)
00948 {
00949 //   -*-*-*Replace contents of this histogram by the addition of h1 and h2*-*-*
00950 //         ===============================================================
00951 //
00952 //   this = c1*h1 + c2*h2
00953 //   if errors are defined (see TH1::Sumw2), errors are also recalculated
00954 //   Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
00955 //   if not already set.
00956 //
00957 // SPECIAL CASE (Average/Efficiency histograms)
00958 // For histograms representing averages or efficiencies, one should compute the average
00959 // of the two histograms and not the sum. One can mark a histogram to be an average
00960 // histogram by setting its bit kIsAverage with
00961 //    myhist.SetBit(TH1::kIsAverage);
00962 // Note that the two histograms must have their kIsAverage bit set
00963 //
00964 // IMPORTANT NOTE: If you intend to use the errors of this histogram later
00965 // you should call Sumw2 before making this operation.
00966 // This is particularly important if you fit the histogram after TH1::Add
00967 
00968    if (!h1 || !h2) {
00969       Error("Add","Attempt to add a non-existing histogram");
00970       return;
00971    }
00972 
00973    Bool_t normWidth = kFALSE;
00974    if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
00975    Int_t nbinsx = GetNbinsX();
00976    Int_t nbinsy = GetNbinsY();
00977    Int_t nbinsz = GetNbinsZ();
00978 
00979    try {
00980       CheckConsistency(h1,h2);
00981       CheckConsistency(this,h1);
00982    } catch(DifferentNumberOfBins&) {
00983       Error("Add","Attempt to add histograms with different number of bins");
00984       return;
00985    } catch(DifferentAxisLimits&) {
00986       Warning("Add","Attempt to add histograms with different axis limits");
00987    } catch(DifferentBinLimits&) {
00988       Warning("Add","Attempt to add histograms with different bin limits");
00989    }
00990 
00991    if (fDimension < 2) nbinsy = -1;
00992    if (fDimension < 3) nbinsz = -1;
00993    if (fDimension < 3) nbinsz = -1;
00994 
00995 //    Create Sumw2 if h1 or h2 have Sumw2 set
00996    if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
00997 
00998 //   - Add statistics
00999    Double_t nEntries = TMath::Abs( c1*h1->GetEntries() + c2*h2->GetEntries() );
01000    Double_t s1[kNstat], s2[kNstat], s3[kNstat];
01001 
01002 // statistics can be preserbed only in case of positive coefficients
01003 // otherwise with negative c1 (histogram subtraction) one risks to get negative variances
01004    Bool_t resetStats = (c1*c2 < 0);
01005    if (!resetStats) {
01006       // need to initialize to zero s1 and s2 since 
01007       // GetStats fills only used elements depending on dimension and type
01008       for (Int_t i=0;i<kNstat;i++) {
01009          s1[i] = 0; 
01010          s2[i] = 0; 
01011       }      
01012       h1->GetStats(s1);
01013       h2->GetStats(s2);
01014       for (Int_t i=0;i<kNstat;i++) {
01015          if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
01016          else        s3[i] = TMath::Abs(c1)*s1[i] + TMath::Abs(c2)*s2[i];
01017       }
01018    }
01019 
01020    SetMinimum();
01021    SetMaximum();
01022 
01023 //    Reset the kCanRebin option. Otherwise SetBinContent on the overflow bin
01024 //    would resize the axis limits!
01025    ResetBit(kCanRebin);
01026 
01027 
01028 //   - Loop on bins (including underflows/overflows)
01029    Int_t bin, binx, biny, binz;
01030    Double_t cu;
01031    for (binz=0;binz<=nbinsz+1;binz++) {
01032       Double_t wz = h1->GetZaxis()->GetBinWidth(binz);
01033       for (biny=0;biny<=nbinsy+1;biny++) {
01034          Double_t wy = h1->GetYaxis()->GetBinWidth(biny);
01035          for (binx=0;binx<=nbinsx+1;binx++) {
01036             Double_t wx = h1->GetXaxis()->GetBinWidth(binx);
01037             bin = binx +(nbinsx+2)*(biny + (nbinsy+2)*binz);
01038             //special case where histograms have the kIsAverage bit set
01039             if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
01040                Double_t y1 = h1->GetBinContent(bin);
01041                Double_t y2 = h2->GetBinContent(bin);
01042                Double_t e1 = h1->GetBinError(bin);
01043                Double_t e2 = h2->GetBinError(bin);
01044                Double_t w1 = 1., w2 = 1.;
01045                if (e1 > 0) w1 = 1./(e1*e1);
01046                if (e2 > 0) w2 = 1./(e2*e2);
01047                SetBinContent(bin, (w1*y1 + w2*y2)/(w1 + w2));
01048                if (fSumw2.fN) fSumw2.fArray[bin] = 1./(w1 + w2);
01049             } else {
01050                if (normWidth) {
01051                   Double_t w = wx*wy*wz;
01052                   cu  = c1*h1->GetBinContent(bin)/w;
01053                   SetBinContent(bin,cu);
01054                   if (fSumw2.fN) {
01055                      Double_t e1 = h1->GetBinError(bin)/w;
01056                      fSumw2.fArray[bin] = c1*c1*e1*e1;
01057                   }
01058                } else {
01059                   cu  = c1*h1->GetBinContent(bin)+ c2*h2->GetBinContent(bin);
01060                   SetBinContent(bin,cu);
01061                   if (fSumw2.fN) {
01062                      Double_t e1 = h1->GetBinError(bin);
01063                      Double_t e2 = h2->GetBinError(bin);
01064                      fSumw2.fArray[bin] = c1*c1*e1*e1 + c2*c2*e2*e2;
01065                   }
01066                }
01067             }
01068          }
01069       }
01070    }
01071    if (resetStats)  {
01072       // statistics need to be reset in case coefficient are negative
01073       ResetStats();
01074    }
01075    else {
01076       // update statistics (do here to avoid changes by SetBinContent)
01077       PutStats(s3);
01078       SetEntries(nEntries);
01079    }
01080 }
01081 
01082 
01083 //______________________________________________________________________________
01084 void TH1::AddBinContent(Int_t)
01085 {
01086 //   -*-*-*-*-*-*-*-*Increment bin content by 1*-*-*-*-*-*-*-*-*-*-*-*-*-*
01087 //                   ==========================
01088    AbstractMethod("AddBinContent");
01089 }
01090 
01091 //______________________________________________________________________________
01092 void TH1::AddBinContent(Int_t, Double_t)
01093 {
01094 //   -*-*-*-*-*-*-*-*Increment bin content by a weight w*-*-*-*-*-*-*-*-*-*-*
01095 //                   ===================================
01096    AbstractMethod("AddBinContent");
01097 }
01098 
01099 //______________________________________________________________________________
01100 void TH1::AddDirectory(Bool_t add)
01101 {
01102 // Sets the flag controlling the automatic add of histograms in memory
01103 //
01104 // By default (fAddDirectory = kTRUE), histograms are automatically added
01105 // to the list of objects in memory.
01106 // Note that one histogram can be removed from its support directory
01107 // by calling h->SetDirectory(0) or h->SetDirectory(dir) to add it
01108 // to the list of objects in the directory dir.
01109 //
01110 //  NOTE that this is a static function. To call it, use;
01111 //     TH1::AddDirectory
01112 
01113    fgAddDirectory = add;
01114 }
01115 
01116 
01117 //______________________________________________________________________________
01118 Int_t TH1::BufferEmpty(Int_t action)
01119 {
01120 // Fill histogram with all entries in the buffer.
01121 // action = -1 histogram is reset and refilled from the buffer (called by THistPainter::Paint)
01122 // action =  0 histogram is filled from the buffer
01123 // action =  1 histogram is filled and buffer is deleted
01124 //             The buffer is automatically deleted when the number of entries
01125 //             in the buffer is greater than the number of entries in the histogram
01126 
01127    // do we need to compute the bin size?
01128    if (!fBuffer) return 0;
01129    Int_t nbentries = (Int_t)fBuffer[0];
01130    if (!nbentries) return 0;
01131    Double_t *buffer = fBuffer;
01132    if (nbentries < 0) {
01133       if (action == 0) return 0;
01134       nbentries  = -nbentries;
01135       fBuffer=0;
01136       Reset("ICE"); //do not reset the list of functions
01137       fBuffer = buffer;
01138    }
01139    if (TestBit(kCanRebin) || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
01140       //find min, max of entries in buffer
01141       Double_t xmin = fBuffer[2];
01142       Double_t xmax = xmin;
01143       for (Int_t i=1;i<nbentries;i++) {
01144          Double_t x = fBuffer[2*i+2];
01145          if (x < xmin) xmin = x;
01146          if (x > xmax) xmax = x;
01147       }
01148       if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
01149          THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax);
01150       } else {
01151          fBuffer = 0;
01152          Int_t keep = fBufferSize; fBufferSize = 0;
01153          if (xmin <  fXaxis.GetXmin()) RebinAxis(xmin,&fXaxis);
01154          if (xmax >= fXaxis.GetXmax()) RebinAxis(xmax,&fXaxis);
01155          fBuffer = buffer;
01156          fBufferSize = keep;
01157       }
01158    }
01159 
01160    FillN(nbentries,&fBuffer[2],&fBuffer[1],2);
01161 
01162    if (action > 0) { delete [] fBuffer; fBuffer = 0; fBufferSize = 0;}
01163    else {
01164       if (nbentries == (Int_t)fEntries) fBuffer[0] = -nbentries;
01165       else                              fBuffer[0] = 0;
01166    }
01167    return nbentries;
01168 }
01169 
01170 //______________________________________________________________________________
01171 Int_t TH1::BufferFill(Double_t x, Double_t w)
01172 {
01173 // accumulate arguments in buffer. When buffer is full, empty the buffer
01174 // fBuffer[0] = number of entries in buffer
01175 // fBuffer[1] = w of first entry
01176 // fBuffer[2] = x of first entry
01177 
01178    if (!fBuffer) return -2;
01179    Int_t nbentries = (Int_t)fBuffer[0];
01180    if (nbentries < 0) {
01181       nbentries  = -nbentries;
01182       fBuffer[0] =  nbentries;
01183       if (fEntries > 0) {
01184          Double_t *buffer = fBuffer; fBuffer=0;
01185          Reset();
01186          fBuffer = buffer;
01187       }
01188    }
01189    if (2*nbentries+2 >= fBufferSize) {
01190       BufferEmpty(1);
01191       return Fill(x,w);
01192    }
01193    fBuffer[2*nbentries+1] = w;
01194    fBuffer[2*nbentries+2] = x;
01195    fBuffer[0] += 1;
01196    return -2;
01197 }
01198 
01199 bool CheckBinLimits(const TArrayD* h1Array, const TArrayD* h2Array)
01200 {
01201    Int_t fN = h1Array->fN;
01202    if ( fN != 0 ) {
01203       if ( h2Array->fN != fN ) {
01204          throw DifferentBinLimits();
01205          return false;
01206       }
01207       else {
01208          for ( int i = 0; i < fN; ++i ) {
01209             if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), 1E-10 ) ) {
01210                throw DifferentBinLimits();
01211                return false;
01212             }
01213          }
01214       }
01215    }
01216 
01217    return true;
01218 }
01219 
01220 //___________________________________________________________________________
01221 bool TH1::CheckConsistency(const TH1* h1, const TH1* h2)
01222 {
01223    // Check histogram compatibility
01224    // returns kTRUE if number of bins and bin limits are identical
01225    Int_t nbinsx = h1->GetNbinsX();
01226    Int_t nbinsy = h1->GetNbinsY();
01227    Int_t nbinsz = h1->GetNbinsZ();
01228 
01229    // Check whether the histograms have the same number of bins.
01230    if (nbinsx != h2->GetNbinsX() || nbinsy != h2->GetNbinsY() || nbinsz != h2->GetNbinsZ()) {
01231       throw DifferentNumberOfBins();
01232       return false;
01233    }
01234    // Check that the axis limits of the histograms are the same
01235    if (h1->fXaxis.GetXmin() != h2->fXaxis.GetXmin() ||
01236        h1->fXaxis.GetXmax() != h2->fXaxis.GetXmax() ||
01237        h1->fYaxis.GetXmin() != h2->fYaxis.GetXmin() ||
01238        h1->fYaxis.GetXmax() != h2->fYaxis.GetXmax() ||
01239        h1->fZaxis.GetXmin() != h2->fZaxis.GetXmin() ||
01240        h1->fZaxis.GetXmax() != h2->fZaxis.GetXmax()) {
01241       throw DifferentAxisLimits();
01242       return false;
01243    }
01244 
01245    bool ret = true;
01246 
01247    ret &= CheckBinLimits(h1->GetXaxis()->GetXbins(), h2->GetXaxis()->GetXbins());
01248    ret &= CheckBinLimits(h1->GetYaxis()->GetXbins(), h2->GetYaxis()->GetXbins());
01249    ret &= CheckBinLimits(h1->GetZaxis()->GetXbins(), h2->GetZaxis()->GetXbins());
01250 
01251    return ret;
01252 }
01253 
01254 //___________________________________________________________________________
01255 Double_t TH1::Chi2Test(const TH1* h2, Option_t *option, Double_t *res) const
01256 {
01257    // Begin_Latex #chi^{2} End_Latex test for comparing weighted and unweighted histograms
01258    //
01259    // Function: Returns p-value. Other return values are specified by the 3rd parameter <br>
01260    //
01261    // Parameters:
01262    //
01263    //    - h2: the second histogram
01264    //    - option:
01265    //       o "UU" = experiment experiment comparison (unweighted-unweighted)
01266    //       o "UW" = experiment MC comparison (unweighted-weighted). Note that
01267    //          the first histogram should be unweighted
01268    //       o "WW" = MC MC comparison (weighted-weighted)
01269    //       o "NORM" = to be used when one or both of the histograms is scaled
01270    //                  but the histogram originally was unweighted
01271    //       o by default underflows and overlows are not included:
01272    //          * "OF" = overflows included
01273    //          * "UF" = underflows included
01274    //       o "P" = print chi2, ndf, p_value, igood
01275    //       o "CHI2" = returns chi2 instead of p-value
01276    //       o "CHI2/NDF" = returns Begin_Latex #chi^{2}/ndf End_Latex
01277    //    - res: not empty - computes normalized residuals and returns them in
01278    //      this array
01279    //
01280    // The current implementation is based on the papers Begin_Latex #chi^{2} End_Latex test for comparison
01281    // of weighted and unweighted histograms" in Proceedings of PHYSTAT05 and
01282    // "Comparison weighted and unweighted histograms", arXiv:physics/0605123
01283    // by N.Gagunashvili. This function has been implemented by Daniel Haertl in August 2006.
01284    //
01285    // Introduction:
01286    //
01287    //   A frequently used technique in data analysis is the comparison of
01288    //   histograms. First suggested by Pearson [1] the Begin_Latex #chi^{2} End_Latex test of
01289    //   homogeneity is used widely for comparing usual (unweighted) histograms.
01290    //   This paper describes the implementation modified Begin_Latex #chi^{2} End_Latex tests
01291    //   for comparison of weighted and unweighted  histograms and two weighted
01292    //   histograms [2] as well as usual Pearson's Begin_Latex #chi^{2} End_Latex test for
01293    //   comparison two usual (unweighted) histograms.
01294    //
01295    // Overview:
01296    //
01297    //   Comparison of two histograms expect hypotheses that two histograms
01298    //   represent identical distributions. To make a decision p-value should
01299    //   be calculated. The hypotheses of identity is rejected if the p-value is
01300    //   lower then some significance level. Traditionally significance levels
01301    //   0.1, 0.05 and 0.01 are used. The comparison procedure should include an
01302    //   analysis of the residuals which is often helpful in identifying the
01303    //   bins of histograms responsible for a significant overall Begin_Latex #chi^{2} End_Latex value.
01304    //   Residuals are the difference between bin contents and expected bin
01305    //   contents. Most convenient for analysis are the normalized residuals. If
01306    //   hypotheses of identity are valid then normalized residuals are
01307    //   approximately independent and identically distributed random variables
01308    //   having N(0,1) distribution. Analysis of residuals expect test of above
01309    //   mentioned properties of residuals. Notice that indirectly the analysis
01310    //   of residuals increase the power of Begin_Latex #chi^{2} End_Latex test.
01311    //
01312    // Methods of comparison:
01313    //
01314    //  Begin_Latex #chi^{2} End_Latex test for comparison two (unweighted) histograms:
01315    //   Let us consider two  histograms with the  same binning and the  number
01316    //   of bins equal to r. Let us denote the number of events in the ith bin
01317    //   in the first histogram as ni and as mi in the second one. The total
01318    //   number of events in the first histogram is equal to:
01319    //Begin_Latex
01320    //   N = #sum_{i=1}^{r} n_{i}
01321    //End_Latex
01322    //   and
01323    //Begin_Latex
01324    //   M = #sum_{i=1}^{r} m_{i}
01325    //End_Latex
01326    //   in the second histogram. The hypothesis of identity (homogeneity) [3]
01327    //   is that the two histograms represent random values with identical
01328    //   distributions. It is equivalent that there exist r constants p1,...,pr,
01329    //   such that
01330    //Begin_Latex
01331    //   #sum_{i=1}^{r} p_{i}=1
01332    //End_Latex
01333    //    and the probability of belonging to the ith bin for some measured value
01334    //    in both experiments is equal to pi. The number of events in the ith
01335    //    bin is a random variable with a distribution approximated by a Poisson
01336    //    probability distribution
01337    //Begin_Latex
01338    //   #frac{e^{-Np_{i}}(Np_{i})^{n_{i}}}{n_{i}!}
01339    //End_Latex
01340    //   for the first histogram and with distribution
01341    //Begin_Latex
01342    //   #frac{e^{-Mp_{i}}(Mp_{i})^{m_{i}}}{m_{i}!}
01343    //End_Latex
01344    //   for the second histogram. If the hypothesis of homogeneity is valid,
01345    //   then the  maximum likelihood estimator of pi, i=1,...,r, is
01346    //Begin_Latex
01347    //   #hat{p}_{i}= #frac{n_{i}+m_{i}}{N+M}
01348    //End_Latex
01349    //   and then
01350    //Begin_Latex
01351    //   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}}
01352    //End_Latex
01353    //   has approximately a Begin_Latex #chi^{2}_{(r-1)} End_Latex distribution [3].
01354    //   The comparison procedure can include an analysis of the residuals which
01355    //   is often helpful in identifying the bins of histograms responsible for
01356    //   a significant overall Begin_Latex #chi^{2} End_Latexvalue. Most convenient for
01357    //   analysis are the adjusted (normalized) residuals [4]
01358    //Begin_Latex
01359    //   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))}}
01360    //End_Latex
01361    //   If hypotheses of  homogeneity are valid then residuals ri are
01362    //   approximately independent and identically distributed random variables
01363    //   having N(0,1) distribution. The application of the Begin_Latex #chi^{2} End_latex test has
01364    //   restrictions related to the value of the expected frequencies Npi,
01365    //   Mpi, i=1,...,r. A conservative rule formulated in [5] is that all the
01366    //   expectations must be 1 or greater for both histograms. In practical
01367    //   cases when expected frequencies are not known the estimated expected
01368    //   frequencies Begin_Latex M#hat{p}_{i}, N#hat{p}_{i}, i=1,...,r End_Latex  can be used.
01369    //
01370    //  Unweighted and weighted histograms comparison:
01371    //
01372    //   A simple modification of the ideas described above can be used for the
01373    //   comparison of the usual (unweighted) and weighted histograms. Let us
01374    //   denote the number of events in the ith bin in the unweighted
01375    //   histogram as ni and the common weight of events in the ith bin of the
01376    //   weighted histogram as wi. The total number of events in the
01377    //   unweighted histogram is equal to
01378    //Begin_Latex
01379    //   N = #sum_{i=1}^{r} n_{i}
01380    //End_Latex
01381    //   and the total weight of events in the weighted histogram is equal to
01382    //Begin_Latex
01383    //   W = #sum_{i=1}^{r} w_{i}
01384    //End_Latex
01385    //   Let us formulate the hypothesis of identity of an unweighted histogram
01386    //   to a weighted histogram so that there exist r constants p1,...,pr, such
01387    //   that
01388    //Begin_Latex
01389    //   #sum_{i=1}^{r} p_{i} = 1
01390    //End_Latex
01391    //   for the unweighted histogram. The weight wi is a random variable with a
01392    //   distribution approximated by the normal probability distribution
01393    //   Begin_Latex N(Wp_{i},#sigma_{i}^{2}) End_Latex where Begin_Latex #sigma_{i}^{2} End_Latex is the variance of the weight wi.
01394    //   If we replace the variance Begin_Latex #sigma_{i}^{2} End_Latex
01395    //   with estimate Begin_Latex s_{i}^{2} End_Latex (sum of squares of weights of
01396    //   events in the ith bin) and the hypothesis of identity is valid, then the
01397    //   maximum likelihood estimator of  pi,i=1,...,r, is
01398    //Begin_Latex
01399    //   #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}}
01400    //End_Latex
01401    //   We may then use the test statistic
01402    //Begin_Latex
01403    //   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}}
01404    //End_Latex
01405    //   and it has approximately a Begin_Latex #chi^{2}_{(r-1)} End_Latex distribution [2]. This test, as well
01406    //   as the original one [3], has a restriction on the expected frequencies. The
01407    //   expected frequencies recommended for the weighted histogram is more than 25.
01408    //   The value of the minimal expected frequency can be decreased down to 10 for
01409    //   the case when the weights of the events are close to constant. In the case
01410    //   of a weighted histogram if the number of events is unknown, then we can
01411    //   apply this recommendation for the equivalent number of events as
01412    //Begin_Latex
01413    //   n_{i}^{equiv} = #frac{ w_{i}^{2} }{ s_{i}^{2} }
01414    //End_Latex
01415    //   The minimal expected frequency for an unweighted histogram must be 1. Notice
01416    //   that any usual (unweighted) histogram can be considered as a weighted
01417    //   histogram with events that have constant weights equal to 1.
01418    //   The variance Begin_Latex z_{i}^{2} End_Latex of the difference between the weight wi
01419    //   and the estimated expectation value of the weight is approximately equal to:
01420    //Begin_Latex
01421    //   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}
01422    //End_Latex
01423    //   The  residuals
01424    //Begin_Latex
01425    //   r_{i} = #frac{w_{i}-W#hat{p}_{i}}{z_{i}}
01426    //End_Latex
01427    //   have approximately a normal distribution with mean equal to 0 and standard
01428    //   deviation  equal to 1.
01429    //
01430    //  Two weighted histograms comparison:
01431    //
01432    //   Let us denote the common  weight of events of the ith bin in the first
01433    //   histogram as w1i and as w2i in the second one. The total weight of events
01434    //   in the first histogram is equal to
01435    //Begin_Latex
01436    //   W_{1} = #sum_{i=1}^{r} w_{1i}
01437    //End_Latex
01438    //   and
01439    //Begin_Latex
01440    //   W_{2} = #sum_{i=1}^{r} w_{2i}
01441    //End_Latex
01442    //   in the second histogram. Let us formulate the hypothesis of identity of
01443    //   weighted histograms so that there exist r constants p1,...,pr, such that
01444    //Begin_Latex
01445    //   #sum_{i=1}^{r} p_{i} = 1
01446    //End_Latex
01447    //   and also expectation value of weight w1i equal to W1pi and expectation value
01448    //   of weight w2i equal to W2pi. Weights in both the histograms are random
01449    //   variables with distributions which can be approximated by a normal
01450    //   probability distribution Begin_Latex N(W_{1}p_{i},#sigma_{1i}^{2}) End_Latex for the first histogram
01451    //   and by a distribution Begin_Latex N(W_{2}p_{i},#sigma_{2i}^{2}) End_Latex for the second.
01452    //   Here Begin_Latex #sigma_{1i}^{2} End_Latex and Begin_Latex #sigma_{2i}^{2} End_Latex are the variances
01453    //   of w1i and w2i with estimators Begin_Latex s_{1i}^{2} End_Latex and Begin_Latex s_{2i}^{2} End_Latex respectively.
01454    //   If the hypothesis of identity is valid, then the maximum likelihood and
01455    //   Least Square Method estimator of pi,i=1,...,r, is
01456    //Begin_Latex
01457    //   #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}}
01458    //End_Latex
01459    //   We may then use the test statistic
01460    //Begin_Latex
01461    //   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}}
01462    //End_Latex
01463    //   and it has approximately a Begin_Latex #chi^{2}_{(r-1)} End_Latex distribution [2].
01464    //   The normalized or studentised residuals [6]
01465    //Begin_Latex
01466    //   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})}}}
01467    //End_Latex
01468    //   have approximately a normal distribution with mean equal to 0 and standard
01469    //   deviation 1. A recommended minimal expected frequency is equal to 10 for
01470    //   the proposed test.
01471    //
01472    // Numerical examples:
01473    //
01474    //   The method described herein is now illustrated with an example.
01475    //   We take a distribution
01476    //Begin_Latex
01477    //   #phi(x) = #frac{2}{(x-10)^{2}+1} + #frac{1}{(x-14)^{2}+1}       (1)
01478    //End_Latex
01479    //   defined on the interval [4,16]. Events distributed according to the formula
01480    //   (1) are simulated to create the unweighted histogram. Uniformly distributed
01481    //   events are simulated for the weighted histogram with weights calculated by
01482    //   formula (1). Each histogram has the same number of bins: 20. Fig.1 shows
01483    //   the result of comparison of the unweighted histogram with 200 events
01484    //   (minimal expected frequency equal to one) and the weighted histogram with
01485    //   500 events (minimal expected frequency equal to 25)
01486    //Begin_Macro
01487    // ../../../tutorials/math/chi2test.C
01488    //End_Macro
01489    //   Fig 1. An example of comparison of the unweighted histogram with 200 events
01490    //   and the weighted histogram with 500 events:
01491    //      a) unweighted histogram;
01492    //      b) weighted histogram;
01493    //      c) normalized residuals plot;
01494    //      d) normal Q-Q plot of residuals.
01495    //
01496    //   The value of the test statistic Begin_Latex #chi^{2} End_Latex is equal to
01497    //   21.09 with p-value equal to 0.33, therefore the hypothesis of identity of
01498    //   the two histograms can be accepted for 0.05 significant level. The behavior
01499    //   of the normalized residuals plot (see Fig. 1c) and the normal Q-Q plot
01500    //   (see Fig. 1d) of residuals are regular and we cannot identify the outliers
01501    //   or bins with a big influence on Begin_Latex #chi^{2} End_Latex.
01502    //
01503    //   The second example presents the same two histograms but 17 events was added
01504    //   to content of bin number 15 in unweighted histogram. Fig.2 shows the result
01505    //   of comparison of the unweighted histogram with 217 events (minimal expected
01506    //   frequency equal to one) and the weighted histogram with 500 events (minimal
01507    //   expected frequency equal to 25)
01508    //Begin_Macro
01509    // ../../../tutorials/math/chi2test.C(17)
01510    //End_Macro
01511    //   Fig 2. An example of comparison of the unweighted histogram with 217 events
01512    //   and the weighted histogram with 500 events:
01513    //      a) unweighted histogram;
01514    //      b) weighted histogram;
01515    //      c) normalized residuals plot;
01516    //      d) normal Q-Q plot of residuals.
01517    //
01518    //   The value of the test statistic Begin_Latex #chi^{2} End_Latex is equal to
01519    //   32.33 with p-value equal to 0.029, therefore the hypothesis of identity of
01520    //   the two histograms is rejected for 0.05 significant level. The behavior of
01521    //   the normalized residuals plot (see Fig. 2c) and the normal Q-Q plot (see
01522    //   Fig. 2d) of residuals are not regular and we can identify the outlier or
01523    //   bin with a big influence on Begin_Latex #chi^{2} End_Latex.
01524    //
01525    // References:
01526    //
01527    // [1] Pearson, K., 1904. On the Theory of Contingency and Its Relation to
01528    //     Association and Normal Correlation. Drapers' Co. Memoirs, Biometric
01529    //     Series No. 1, London.
01530    // [2] Gagunashvili, N., 2006. Begin_Latex #chi^{2} End_Latex test for comparison
01531    //     of weighted and unweighted histograms. Statistical Problems in Particle
01532    //     Physics, Astrophysics and Cosmology, Proceedings of PHYSTAT05,
01533    //     Oxford, UK, 12-15 September 2005, Imperial College Press, London, 43-44.
01534    //     Gagunashvili,N., Comparison of weighted and unweighted histograms,
01535    //     arXiv:physics/0605123, 2006.
01536    // [3] Cramer, H., 1946. Mathematical methods of statistics.
01537    //     Princeton University Press, Princeton.
01538    // [4] Haberman, S.J., 1973. The analysis of residuals in cross-classified tables.
01539    //     Biometrics 29, 205-220.
01540    // [5] Lewontin, R.C. and Felsenstein, J., 1965. The robustness of homogeneity
01541    //     test in 2xN tables. Biometrics 21, 19-33.
01542    // [6] Seber, G.A.F., Lee, A.J., 2003, Linear Regression Analysis.
01543    //     John Wiley & Sons Inc., New York.
01544 
01545    Double_t chi2 = 0;
01546    Int_t ndf = 0, igood = 0;
01547 
01548    TString opt = option;
01549    opt.ToUpper();
01550 
01551    Double_t prob = Chi2TestX(h2,chi2,ndf,igood,option,res);
01552 
01553    if(opt.Contains("P")) {
01554       printf("Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
01555    }
01556    if(opt.Contains("CHI2/NDF")) {
01557       if (ndf == 0) return 0;
01558       return chi2/ndf;
01559    }
01560    if(opt.Contains("CHI2")) {
01561       return chi2;
01562    }
01563 
01564    return prob;
01565 }
01566 
01567 //___________________________________________________________________________
01568 Double_t TH1::Chi2TestX(const TH1* h2,  Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option,  Double_t *res) const
01569 {
01570    // The computation routine of the Chisquare test. For the method description,
01571    // see Chi2Test() function.
01572    // Returns p-value
01573    // parameters:
01574    //  - h2-second histogram
01575    //  - option:
01576    //     "UU" = experiment experiment comparison (unweighted-unweighted)
01577    //     "UW" = experiment MC comparison (unweighted-weighted). Note that the first
01578    //           histogram should be unweighted
01579    //     "WW" = MC MC comparison (weighted-weighted)
01580    //
01581    //     "NORM" = if one or both histograms is scaled
01582    //
01583    //     "OF" = overflows included
01584    //     "UF" = underflows included
01585    //         by default underflows and overlows are not included
01586    //
01587    //  - igood:
01588    //       igood=0 - no problems
01589    //        For unweighted unweighted  comparison
01590    //       igood=1'There is a bin in the 1st histogram with less than 1 event'
01591    //       igood=2'There is a bin in the 2nd histogram with less than 1 event'
01592    //       igood=3'when the conditions for igood=1 and igood=2 are satisfied'
01593    //        For  unweighted weighted  comparison
01594    //       igood=1'There is a bin in the 1st histogram with less then 1 event'
01595    //       igood=2'There is a bin in the 2nd histogram with less then 10 effective number of events'
01596    //       igood=3'when the conditions for igood=1 and igood=2 are satisfied'
01597    //        For  weighted weighted  comparison
01598    //       igood=1'There is a bin in the 1st  histogram with less then 10 effective
01599    //        number of events'
01600    //       igood=2'There is a bin in the 2nd  histogram with less then 10 effective
01601    //               number of events'
01602    //       igood=3'when the conditions for igood=1 and igood=2 are satisfied'
01603    //
01604    //  - chi2 - chisquare of the test
01605    //  - ndf  - number of degrees of freedom (important, when both histograms have the same
01606    //         empty bins)
01607    //  - res -  normalized residuals for further analysis
01608 
01609 
01610    Int_t i = 0, j=0, k = 0;
01611    Int_t i_start, i_end;
01612    Int_t j_start, j_end;
01613    Int_t k_start, k_end;
01614 
01615    Double_t bin1, bin2;
01616    Double_t err1,err2;
01617    Double_t sum1=0, sum2=0;
01618    Double_t sumw1=0, sumw2=0;
01619 
01620 
01621    chi2 = 0;
01622    ndf = 0;
01623 
01624    TString opt = option;
01625    opt.ToUpper();
01626 
01627    TAxis *xaxis1 = this->GetXaxis();
01628    TAxis *xaxis2 = h2->GetXaxis();
01629    TAxis *yaxis1 = this->GetYaxis();
01630    TAxis *yaxis2 = h2->GetYaxis();
01631    TAxis *zaxis1 = this->GetZaxis();
01632    TAxis *zaxis2 = h2->GetZaxis();
01633 
01634    Int_t nbinx1 = xaxis1->GetNbins();
01635    Int_t nbinx2 = xaxis2->GetNbins();
01636    Int_t nbiny1 = yaxis1->GetNbins();
01637    Int_t nbiny2 = yaxis2->GetNbins();
01638    Int_t nbinz1 = zaxis1->GetNbins();
01639    Int_t nbinz2 = zaxis2->GetNbins();
01640 
01641    //check dimensions
01642    if (this->GetDimension() != h2->GetDimension() ){
01643       Error("Chi2TestX","Histograms have different dimensions.");
01644       return 0;
01645    }
01646 
01647    //check number of channels
01648    if (nbinx1 != nbinx2) {
01649       Error("Chi2TestX","different number of x channels");
01650    }
01651    if (nbiny1 != nbiny2) {
01652       Error("Chi2TestX","different number of y channels");
01653    }
01654    if (nbinz1 != nbinz2) {
01655       Error("Chi2TestX","different number of z channels");
01656    }
01657 
01658    //check for ranges
01659    i_start = j_start = k_start = 1;
01660    i_end = nbinx1;
01661    j_end = nbiny1;
01662    k_end = nbinz1;
01663 
01664    if (xaxis1->TestBit(TAxis::kAxisRange)) {
01665       i_start = xaxis1->GetFirst();
01666       i_end   = xaxis1->GetLast();
01667    }
01668    if (yaxis1->TestBit(TAxis::kAxisRange)) {
01669       j_start = yaxis1->GetFirst();
01670       j_end   = yaxis1->GetLast();
01671    }
01672    if (zaxis1->TestBit(TAxis::kAxisRange)) {
01673       k_start = zaxis1->GetFirst();
01674       k_end   = zaxis1->GetLast();
01675    }
01676 
01677 
01678    if (opt.Contains("OF")) {
01679       if (this->GetDimension() == 3) k_end = ++nbinz1;
01680       if (this->GetDimension() >= 2) j_end = ++nbiny1;
01681       if (this->GetDimension() >= 1) i_end = ++nbinx1;
01682    }
01683 
01684    if (opt.Contains("UF")) {
01685       if (this->GetDimension() == 3) k_start = 0;
01686       if (this->GetDimension() >= 2) j_start = 0;
01687       if (this->GetDimension() >= 1) i_start = 0;
01688    }
01689 
01690    ndf = (i_end - i_start + 1)*(j_end - j_start + 1)*(k_end - k_start + 1) - 1;
01691 
01692    Bool_t comparisonUU = opt.Contains("UU");
01693    Bool_t comparisonUW = opt.Contains("UW");
01694    Bool_t comparisonWW = opt.Contains("WW");
01695    Bool_t scaledHistogram  = opt.Contains("NORM");
01696    if (scaledHistogram && !comparisonUU) {
01697       Info("Chi2TestX","NORM option should be used together with UU option. It is ignored");
01698    }
01699    // look at histo global bin content and effective entries
01700    Stat_t s[kNstat];
01701    this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
01702    double sumBinContent1 = s[0];
01703    double effEntries1 = (s[1] ? s[0]*s[0]/s[1] : 0.);
01704 
01705    h2->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
01706    double sumBinContent2 = s[0];
01707    double effEntries2 = (s[1] ? s[0]*s[0]/s[1] : 0.);
01708 
01709    if (!comparisonUU && !comparisonUW && !comparisonWW ) {
01710       // deduce automatically from type of histogram
01711       if (TMath::Abs(sumBinContent1 - effEntries1) < 1) {
01712          if ( TMath::Abs(sumBinContent2 - effEntries2) < 1) comparisonUU = true;
01713          else comparisonUW = true;
01714       }
01715       else comparisonWW = true;
01716    }
01717    // check unweighted histogram
01718    if (comparisonUW) {
01719       if (TMath::Abs(sumBinContent1 - effEntries1) >= 1) {
01720          Warning("Chi2TestX","First histogram is not unweighted and option UW has been requested");
01721       }
01722    }
01723    if ( (!scaledHistogram && comparisonUU)   ) {
01724       if ( ( TMath::Abs(sumBinContent1 - effEntries1) >= 1) || (TMath::Abs(sumBinContent2 - effEntries2) >= 1) ) {
01725          Warning("Chi2TestX","Both histograms are not unweighted and option UU has been requested");
01726       }
01727    }
01728 
01729 
01730    //get number of events in histogramm
01731    if (comparisonUU && scaledHistogram) {
01732       for (i=i_start; i<=i_end; i++) {
01733          for (j=j_start; j<=j_end; j++) {
01734             for (k=k_start; k<=k_end; k++) {
01735                bin1 = this->GetBinContent(i,j,k);
01736                bin2 = h2->GetBinContent(i,j,k);
01737                err1 = this->GetBinError(i,j,k);
01738                err2 = h2->GetBinError(i,j,k);
01739                if (err1 > 0 ) {
01740                   bin1 *= bin1/(err1*err1);
01741                   //avoid rounding errors
01742                   bin1 = TMath::Floor(bin1+0.5);
01743                }
01744                else
01745                   bin1 = 0;
01746 
01747                if (err2 > 0) {
01748                   bin2 *= bin2/(err2*err2);
01749                   //avoid rounding errors
01750                   bin2 = TMath::Floor(bin2+0.5);
01751                }
01752                else
01753                   bin2 = 0;
01754 
01755                // sum contents
01756                sum1 += bin1;
01757                sum2 += bin2;
01758                sumw1 += err1*err1;
01759                sumw2 += err2*err2;
01760             }
01761          }
01762       }
01763       if (sumw1 <= 0 || sumw2 <= 0) {
01764          Error("Chi2TestX","Cannot use option NORM when one histogram has all zero errors");
01765          return 0;
01766       }
01767 
01768    } else {
01769       for (i=i_start; i<=i_end; i++) {
01770          for (j=j_start; j<=j_end; j++) {
01771             for (k=k_start; k<=k_end; k++) {
01772                sum1 += this->GetBinContent(i,j,k);
01773                sum2 += h2->GetBinContent(i,j,k);
01774                if ( comparisonWW ) {
01775                   err1 = this->GetBinError(i,j,k);
01776                   sumw1 += err1*err1;
01777                }
01778                if ( comparisonUW || comparisonWW ) {
01779                   err2 = h2->GetBinError(i,j,k);
01780                   sumw2 += err2*err2;
01781                }
01782             }
01783          }
01784       }
01785    }
01786    //checks that the histograms are not empty
01787    if (sum1 == 0 || sum2 == 0) {
01788       Error("Chi2TestX","one histogram is empty");
01789       return 0;
01790    }
01791 
01792    if ( comparisonWW  && ( sumw1 <= 0 && sumw2 <=0 ) ){
01793       Error("Chi2TestX","Hist1 and Hist2 have both all zero errors\n");
01794       return 0;
01795    }
01796 
01797    //THE TEST
01798    Int_t m=0, n=0;
01799 
01800    //Experiment - experiment comparison
01801    if (comparisonUU) {
01802       Double_t sum = sum1 + sum2;
01803       for (i=i_start; i<=i_end; i++) {
01804          for (j=j_start; j<=j_end; j++) {
01805             for (k=k_start; k<=k_end; k++) {
01806                bin1 = this->GetBinContent(i,j,k);
01807                bin2 = h2->GetBinContent(i,j,k);
01808 
01809                if ( (bin1 == 0)  && (bin2 == 0) ) {
01810                   --ndf;  //no data means one degree of freedom less
01811                } else {
01812                   if (scaledHistogram) {
01813                      // scale bin value to effective bin entries
01814                      err1 = this->GetBinError(i,j,k);
01815                      if (err1 > 0 ) {
01816                         bin1 *= bin1/(err1*err1);
01817                         //avoid rounding errors
01818                         bin1 = TMath::Floor(bin1+0.5);
01819                      }
01820                      else
01821                         bin1 = 0;
01822 
01823                      err2 = h2->GetBinError(i,j,k);
01824                      if (err2 > 0) {
01825                         bin2 *= bin2/(err2*err2);
01826                         //avoid rounding errors
01827                         bin2 = TMath::Floor(bin2+0.5);
01828                      }
01829                      else
01830                         bin2 = 0;
01831 
01832                   }
01833 
01834 
01835 
01836                   Double_t binsum = bin1 + bin2;
01837                   Double_t nexp1 = binsum*sum1/sum;
01838                   //Double_t nexp2 = binsum*sum2/sum;
01839 
01840 //                  if(opt.Contains("P")) printf("bin %d p = %g\t",i,binsum/sum);
01841 
01842                   if (res)
01843                      res[i-i_start] = (bin1-nexp1)/TMath::Sqrt(nexp1);
01844 
01845                   if (bin1 < 1) {
01846                      m++;
01847                   }
01848                   if (bin2 < 1) {
01849                      n++;
01850                   }
01851 
01852                   //Habermann correction for residuals
01853                   Double_t correc = (1-sum1/sum)*(1-binsum/sum);
01854                   if (res) {
01855                      res[i-i_start] /= TMath::Sqrt(correc);
01856                   }
01857 
01858                   Double_t delta = sum2*bin1-sum1*bin2;
01859                   chi2 += delta*delta/binsum;
01860 
01861                }
01862             }
01863          }
01864       }
01865 
01866       chi2 /= (sum1*sum2);
01867       // flag error only when of the two histogram is zero
01868       if (m) {
01869          igood += 1;
01870          Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
01871       }
01872       if (n) {
01873          igood += 2;
01874          Info("Chi2TestX","There is a bin in h2 with less than 1 event.\n");
01875       }
01876 
01877       Double_t prob = TMath::Prob(chi2,ndf);
01878       return prob;
01879 
01880    }
01881 
01882 
01883    //unweighted - weighted  comparison
01884    if ( comparisonUW ) {
01885       for (i=i_start; i<=i_end; i++) {
01886          for (j=j_start; j<=j_end; j++) {
01887             for (k=k_start; k<=k_end; k++) {
01888                Int_t x=0, y=0;
01889                bin1 = this->GetBinContent(i,j,k);
01890                bin2 = h2->GetBinContent(i,j,k);
01891                err2 = h2->GetBinError(i,j,k);
01892 
01893                err2 *= err2;
01894 
01895                // case both histogram have zero biin contents
01896                if ( (bin1 == 0) && (bin2 == 0) ) {
01897                   --ndf;  //no data means one degree of freedom less
01898                   continue;
01899                }
01900 
01901                // case weighted histogram has zero bin content and error
01902                if (bin2 == 0 && err2 == 0) {
01903                   if (sumw2 > 0) {
01904                      // use as approximated  error as 1 scaled by a scaling ratio
01905                      // estimated from the total sum weight and sum weight squared
01906                      err2 = sumw2/sum2;
01907                   }
01908                   else {
01909                      // return error because infinite discrepancy here:
01910                      // bin1 != 0 and bin2 =0 in a histogram with all errors zero
01911                      Error("Chi2TestX","Hist2 has in bin %d,%d,%d zero content and all zero errors\n", i,j,k);
01912                      chi2 = 0; return 0;
01913                   }
01914                }
01915                // case of err2 = 0 and bin2 not zero is treated without problems
01916                // by excluding second chi2 sum
01917 
01918                if (bin1 < 1)  m++;
01919                if (err2 > 0 && bin2*bin2/err2 < 10) n++;
01920 
01921                Double_t var1 = sum2*bin2 - sum1*err2;
01922                Double_t var2 = var1*var1 + 4*sum2*sum2*bin1*err2;
01923                // if bin1 is zero and bin2=1 and sum1=sum2 var1=0 && var2 ==0
01924                // approximate by adding +1 to bin1
01925                while (var1*var1+bin1 == 0 || var1+var2 == 0) {
01926                   sum1++;
01927                   bin1++;
01928                   x++;
01929                   y=1;
01930                   var1 = sum2*bin2 - sum1*err2;
01931                   var2 = var1*var1 + 4*sum2*sum2*bin1*err2;
01932                }
01933                var2 = TMath::Sqrt(var2);
01934                while (var1+var2 == 0) {
01935                   sum1++;
01936                   bin1++;
01937                   x++;
01938                   y=1;
01939                   var1 = sum2*bin2 - sum1*err2;
01940                   var2 = var1*var1 + 4*sum2*sum2*bin1*err2;
01941                   while (var1*var1+bin1 == 0 || var1+var2 == 0) {
01942                      sum1++;
01943                      bin1++;
01944                      x++;
01945                      y=1;
01946                      var1 = sum2*bin2 - sum1*err2;
01947                      var2 = var1*var1 + 4*sum2*sum2*bin1*err2;
01948                   }
01949                   var2 = TMath::Sqrt(var2);
01950                }
01951 
01952                Double_t probb = (var1+var2)/(2*sum2*sum2);
01953 
01954                Double_t nexp1 = probb * sum1;
01955                Double_t nexp2 = probb * sum2;
01956 
01957 //               if(opt.Contains("P")) printf("bin %d p = %g\t",i,probb);
01958 
01959                Double_t delta1 = bin1 - nexp1;
01960                Double_t delta2 = bin2 - nexp2;
01961 
01962                chi2 += delta1*delta1/nexp1;
01963 
01964                if (err2 > 0) {
01965                   chi2 += delta2*delta2/err2;
01966                }
01967 
01968                if (res) {
01969                   if (err2 > 0) {
01970                      Double_t temp1 = sum2*err2/var2;
01971                      Double_t temp2 = 1 + (sum1*err2 - sum2*bin2)/var2;
01972                      temp2 = temp1*temp1*sum1*probb*(1-probb) + temp2*temp2*err2/4;
01973                      // invert sign here
01974                      res[i-i_start] = - delta2/TMath::Sqrt(temp2);
01975                   }
01976                   else
01977                      res[i-i_start] = delta1/TMath::Sqrt(nexp1);
01978 
01979                }
01980             }
01981          }
01982       }
01983 
01984       if (m) {
01985          igood += 1;
01986          Info("Chi2TestX","There is a bin in h1 with less than 1 event.\n");
01987       }
01988       if (n) {
01989          igood += 2;
01990          Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
01991       }
01992 
01993       Double_t prob = TMath::Prob(chi2,ndf);
01994 
01995       return prob;
01996    }
01997 
01998    // weighted - weighted  comparison
01999    if (comparisonWW) {
02000       for (i=i_start; i<=i_end; i++) {
02001          for (j=j_start; j<=j_end; j++) {
02002             for (k=k_start; k<=k_end; k++) {
02003                bin1 = this->GetBinContent(i,j,k);
02004                bin2 = h2->GetBinContent(i,j,k);
02005                err1 = this->GetBinError(i,j,k);
02006                err2 = h2->GetBinError(i,j,k);
02007                err1 *= err1;
02008                err2 *= err2;
02009 
02010                // case both histogram have zero biin contents
02011                if ( (bin1 == 0) && (bin2 == 0) ) {
02012                   --ndf;  //no data means one degree of freedom less
02013                   continue;
02014                }
02015                if ( (err1 == 0) && (err2 == 0) ) {
02016                   // case of zero errors but non zero bin content
02017                   Error("Chi2TestX","h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
02018                   chi2 = 0; return 0;
02019                }
02020 
02021                Double_t sigma  = sum1*sum1*err2 + sum2*sum2*err1;
02022                Double_t delta = sum2*bin1 - sum1*bin2;
02023                chi2 += delta*delta/sigma;
02024 
02025 //               if(opt.Contains("P")) printf("bin %d p = %g\t",i, (bin1*sum1/err1 + bin2*sum2/err2)/(sum1*sum1/err1 + sum2*sum2/err2));
02026 
02027                if (res) {
02028                   Double_t temp = bin1*sum1*err2 + bin2*sum2*err1;
02029                   Double_t probb = temp/sigma;
02030                   Double_t z = 0;
02031                   if (err1 > err2 ) {
02032                      Double_t d1 = (bin1 - sum1 * probb);
02033                      Double_t s1 = err1* ( 1. - err2 * sum1 * sum1 / sigma );
02034                      z = d1/ TMath::Sqrt(s1);
02035                   }
02036                   else {
02037                      Double_t d2 = (bin2 - sum2 * probb);
02038                      Double_t s2 = err2* ( 1. - err1 * sum2 * sum2 / sigma );
02039                      z = -d2/ TMath::Sqrt(s2);
02040                   }
02041 
02042                   res[i-i_start] = z;
02043                }
02044 
02045                if (err1 > 0 && bin1*bin1/err1 < 10) m++;
02046                if (err2 > 0 && bin2*bin2/err2 < 10) n++;
02047             }
02048          }
02049       }
02050       if (m) {
02051          igood += 1;
02052          Info("Chi2TestX","There is a bin in h1 with less than 10 effective events.\n");
02053       }
02054       if (n) {
02055          igood += 2;
02056          Info("Chi2TestX","There is a bin in h2 with less than 10 effective events.\n");
02057       }
02058       Double_t prob = TMath::Prob(chi2,ndf);
02059       return prob;
02060    }
02061    return 0;
02062 }
02063 
02064 //______________________________________________________________________________
02065 Double_t TH1::ComputeIntegral()
02066 {
02067    //  Compute integral (cumulative sum of bins)
02068    //  The result stored in fIntegral is used by the GetRandom functions.
02069    //  This function is automatically called by GetRandom when the fIntegral
02070    //  array does not exist or when the number of entries in the histogram
02071    //  has changed since the previous call to GetRandom.
02072    //  The resulting integral is normalized to 1
02073 
02074    Int_t bin, binx, biny, binz, ibin;
02075 
02076    // delete previously computed integral (if any)
02077    if (fIntegral) delete [] fIntegral;
02078 
02079    //   - Allocate space to store the integral and compute integral
02080    Int_t nbinsx = GetNbinsX();
02081    Int_t nbinsy = GetNbinsY();
02082    Int_t nbinsz = GetNbinsZ();
02083    Int_t nxy    = nbinsx*nbinsy;
02084    Int_t nbins  = nxy*nbinsz;
02085 
02086    fIntegral = new Double_t[nbins+2];
02087    ibin = 0;
02088    fIntegral[ibin] = 0;
02089    for (binz=1;binz<=nbinsz;binz++) {
02090       for (biny=1;biny<=nbinsy;biny++) {
02091          for (binx=1;binx<=nbinsx;binx++) {
02092             ibin++;
02093             bin  = GetBin(binx, biny, binz);
02094             fIntegral[ibin] = fIntegral[ibin-1] + GetBinContent(bin);
02095          }
02096       }
02097    }
02098 
02099    //   - Normalize integral to 1
02100    if (fIntegral[nbins] == 0 ) {
02101       Error("ComputeIntegral", "Integral = zero"); return 0;
02102    }
02103    for (bin=1;bin<=nbins;bin++)  fIntegral[bin] /= fIntegral[nbins];
02104    fIntegral[nbins+1] = fEntries;
02105    return fIntegral[nbins];
02106 }
02107 
02108 //______________________________________________________________________________
02109 Double_t *TH1::GetIntegral()
02110 {
02111    //  Return a pointer to the array of bins integral.
02112    //  if the pointer fIntegral is null, TH1::ComputeIntegral is called
02113 
02114    if (!fIntegral) ComputeIntegral();
02115    return fIntegral;
02116 }
02117 
02118 //______________________________________________________________________________
02119 void TH1::Copy(TObject &obj) const
02120 {
02121    //   -*-*-*-*-*Copy this histogram structure to newth1*-*-*-*-*-*-*-*-*-*-*-*
02122    //             =======================================
02123    //
02124    // Note that this function does not copy the list of associated functions.
02125    // Use TObJect::Clone to make a full copy of an histogram.
02126 
02127    if (((TH1&)obj).fDirectory) {
02128       // We are likely to change the hash value of this object
02129       // with TNamed::Copy, to keep things correct, we need to
02130       // clean up its existing entries.
02131       ((TH1&)obj).fDirectory->Remove(&obj);
02132       ((TH1&)obj).fDirectory = 0;
02133    }
02134    TNamed::Copy(obj);
02135    ((TH1&)obj).fDimension = fDimension;
02136    ((TH1&)obj).fNormFactor= fNormFactor;
02137    ((TH1&)obj).fNcells    = fNcells;
02138    ((TH1&)obj).fBarOffset = fBarOffset;
02139    ((TH1&)obj).fBarWidth  = fBarWidth;
02140    ((TH1&)obj).fOption    = fOption;
02141    ((TH1&)obj).fBuffer    = 0;
02142    ((TH1&)obj).fBufferSize= fBufferSize;
02143    Int_t i;
02144    if (fBuffer) {
02145       Double_t *buf = new Double_t[fBufferSize];
02146       for (i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
02147       ((TH1&)obj).fBuffer    = buf;
02148    }
02149 
02150    TArray* a = dynamic_cast<TArray*>(&obj);
02151    if (a) a->Set(fNcells);
02152    Int_t canRebin = ((TH1&)obj).TestBit(kCanRebin);
02153    ((TH1&)obj).ResetBit(kCanRebin);  //we want to avoid the call to LabelsInflate
02154    for (i=0;i<fNcells;i++) ((TH1&)obj).SetBinContent(i,this->GetBinContent(i));
02155    if (canRebin) ((TH1&)obj).SetBit(kCanRebin);
02156    ((TH1&)obj).fEntries   = fEntries;
02157 
02158    ((TH1&)obj).fTsumw     = fTsumw;
02159    ((TH1&)obj).fTsumw2    = fTsumw2;
02160    ((TH1&)obj).fTsumwx    = fTsumwx;
02161    ((TH1&)obj).fTsumwx2   = fTsumwx2;
02162    ((TH1&)obj).fMaximum   = fMaximum;
02163    ((TH1&)obj).fMinimum   = fMinimum;
02164 
02165    TAttLine::Copy(((TH1&)obj));
02166    TAttFill::Copy(((TH1&)obj));
02167    TAttMarker::Copy(((TH1&)obj));
02168    fXaxis.Copy(((TH1&)obj).fXaxis);
02169    fYaxis.Copy(((TH1&)obj).fYaxis);
02170    fZaxis.Copy(((TH1&)obj).fZaxis);
02171    ((TH1&)obj).fXaxis.SetParent(&obj);
02172    ((TH1&)obj).fYaxis.SetParent(&obj);
02173    ((TH1&)obj).fZaxis.SetParent(&obj);
02174    fContour.Copy(((TH1&)obj).fContour);
02175    fSumw2.Copy(((TH1&)obj).fSumw2);
02176    //   fFunctions->Copy(((TH1&)obj).fFunctions);
02177    if (fgAddDirectory && gDirectory) {
02178       gDirectory->Append(&obj);
02179       ((TH1&)obj).fDirectory = gDirectory;
02180    }
02181 }
02182 
02183 //______________________________________________________________________________
02184 void TH1::DirectoryAutoAdd(TDirectory *dir)
02185 {
02186    // Perform the automatic addition of the histogram to the given directory
02187    //
02188    // Note this function is called in place when the semantic requires
02189    // this object to be added to a directory (I.e. when being read from
02190    // a TKey or being Cloned)
02191    //
02192 
02193    Bool_t addStatus = TH1::AddDirectoryStatus();
02194    if (addStatus) {
02195       SetDirectory(dir);
02196       if (dir) {
02197          ResetBit(kCanDelete);
02198       }
02199    }
02200 }
02201 
02202 //______________________________________________________________________________
02203 Int_t TH1::DistancetoPrimitive(Int_t px, Int_t py)
02204 {
02205    //   -*-*-*-*-*-*-*-*-*Compute distance from point px,py to a line*-*-*-*-*-*
02206    //                     ===========================================
02207    //     Compute the closest distance of approach from point px,py to elements
02208    //     of an histogram.
02209    //     The distance is computed in pixels units.
02210    //
02211    //     Algorithm:
02212    //     Currently, this simple model computes the distance from the mouse
02213    //     to the histogram contour only.
02214    //
02215    //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
02216 
02217    if (!fPainter) return 9999;
02218    return fPainter->DistancetoPrimitive(px,py);
02219 }
02220 
02221 //______________________________________________________________________________
02222 void TH1::Divide(TF1 *f1, Double_t c1)
02223 {
02224 // Performs the operation: this = this/(c1*f1)
02225 // if errors are defined (see TH1::Sumw2), errors are also recalculated.
02226 //
02227 // Only bins inside the function range are recomputed.
02228 // IMPORTANT NOTE: If you intend to use the errors of this histogram later
02229 // you should call Sumw2 before making this operation.
02230 // This is particularly important if you fit the histogram after TH1::Divide
02231 
02232    if (!f1) {
02233       Error("Add","Attempt to divide by a non-existing function");
02234       return;
02235    }
02236 
02237    Int_t nbinsx = GetNbinsX();
02238    Int_t nbinsy = GetNbinsY();
02239    Int_t nbinsz = GetNbinsZ();
02240    if (fDimension < 2) nbinsy = -1;
02241    if (fDimension < 3) nbinsz = -1;
02242 
02243 
02244    SetMinimum();
02245    SetMaximum();
02246 
02247 //    Reset the kCanRebin option. Otherwise SetBinContent on the overflow bin
02248 //    would resize the axis limits!
02249    ResetBit(kCanRebin);
02250 
02251 
02252 //   - Loop on bins (including underflows/overflows)
02253    Int_t bin, binx, biny, binz;
02254    Double_t cu,w;
02255    Double_t xx[3];
02256    Double_t *params = 0;
02257    f1->InitArgs(xx,params);
02258    for (binz=0;binz<=nbinsz+1;binz++) {
02259       xx[2] = fZaxis.GetBinCenter(binz);
02260       for (biny=0;biny<=nbinsy+1;biny++) {
02261          xx[1] = fYaxis.GetBinCenter(biny);
02262          for (binx=0;binx<=nbinsx+1;binx++) {
02263             xx[0] = fXaxis.GetBinCenter(binx);
02264             if (!f1->IsInside(xx)) continue;
02265             TF1::RejectPoint(kFALSE);
02266             bin = binx +(nbinsx+2)*(biny + (nbinsy+2)*binz);
02267             Double_t error1 = GetBinError(bin);
02268             cu  = c1*f1->EvalPar(xx);
02269             if (TF1::RejectedPoint()) continue;
02270             if (cu) w = GetBinContent(bin)/cu;
02271             else    w = 0;
02272             SetBinContent(bin,w);
02273             if (fSumw2.fN) {
02274                if (cu != 0) fSumw2.fArray[bin] = error1*error1/(cu*cu);
02275                else         fSumw2.fArray[bin] = 0;
02276             }
02277          }
02278       }
02279    }
02280    ResetStats();
02281 }
02282 
02283 //______________________________________________________________________________
02284 void TH1::Divide(const TH1 *h1)
02285 {
02286 //   -*-*-*-*-*-*-*-*-*Divide this histogram by h1*-*-*-*-*-*-*-*-*-*-*-*-*
02287 //                     ===========================
02288 //
02289 //   this = this/h1
02290 //   if errors are defined (see TH1::Sumw2), errors are also recalculated.
02291 //   Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
02292 //   if not already set.
02293 //   The resulting errors are calculated assuming uncorrelated histograms.
02294 //   See the other TH1::Divide that gives the possibility to optionaly
02295 //   compute Binomial errors.
02296 //
02297 // IMPORTANT NOTE: If you intend to use the errors of this histogram later
02298 // you should call Sumw2 before making this operation.
02299 // This is particularly important if you fit the histogram after TH1::Scale
02300 
02301    if (!h1) {
02302       Error("Divide","Attempt to divide by a non-existing histogram");
02303       return;
02304    }
02305 
02306    Int_t nbinsx = GetNbinsX();
02307    Int_t nbinsy = GetNbinsY();
02308    Int_t nbinsz = GetNbinsZ();
02309 
02310 
02311    try {
02312       CheckConsistency(this,h1);
02313    } catch(DifferentNumberOfBins&) {
02314       Error("Divide","Attempt to divide histograms with different number of bins");
02315       return;
02316    } catch(DifferentAxisLimits&) {
02317       Warning("Divide","Attempt to divide histograms with different axis limits");
02318    } catch(DifferentBinLimits&) {
02319       Warning("Divide","Attempt to divide histograms with different bin limits");
02320    }
02321 
02322    if (fDimension < 2) nbinsy = -1;
02323    if (fDimension < 3) nbinsz = -1;
02324 
02325 //    Create Sumw2 if h1 has Sumw2 set
02326    if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
02327 
02328 
02329 //    Reset the kCanRebin option. Otherwise SetBinContent on the overflow bin
02330 //    would resize the axis limits!
02331    ResetBit(kCanRebin);
02332 
02333 //   - Loop on bins (including underflows/overflows)
02334    Int_t bin, binx, biny, binz;
02335    Double_t c0,c1,w;
02336    for (binz=0;binz<=nbinsz+1;binz++) {
02337       for (biny=0;biny<=nbinsy+1;biny++) {
02338          for (binx=0;binx<=nbinsx+1;binx++) {
02339             bin = GetBin(binx,biny,binz);
02340             c0  = GetBinContent(bin);
02341             c1  = h1->GetBinContent(bin);
02342             if (c1) w = c0/c1;
02343             else    w = 0;
02344             SetBinContent(bin,w);
02345             if (fSumw2.fN) {
02346                Double_t e0 = GetBinError(bin);
02347                Double_t e1 = h1->GetBinError(bin);
02348                Double_t c12= c1*c1;
02349                if (!c1) { fSumw2.fArray[bin] = 0; continue;}
02350                fSumw2.fArray[bin] = (e0*e0*c1*c1 + e1*e1*c0*c0)/(c12*c12);
02351             }
02352          }
02353       }
02354    }
02355    ResetStats();
02356 }
02357 
02358 
02359 //______________________________________________________________________________
02360 void TH1::Divide(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
02361 {
02362 //   -*-*-*Replace contents of this histogram by the division of h1 by h2*-*-*
02363 //         ==============================================================
02364 //
02365 //   this = c1*h1/(c2*h2)
02366 //
02367 //   if errors are defined (see TH1::Sumw2), errors are also recalculated
02368 //   Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
02369 //   if not already set.
02370 //   The resulting errors are calculated assuming uncorrelated histograms.
02371 //   However, if option ="B" is specified, Binomial errors are computed.
02372 //   In this case c1 and c2 do not make real sense and they are ignored.
02373 //
02374 // IMPORTANT NOTE: If you intend to use the errors of this histogram later
02375 // you should call Sumw2 before making this operation.
02376 // This is particularly important if you fit the histogram after TH1::Divide
02377 //
02378 //  Please note also that in the binomial case errors are calculated using standard
02379 //  binomial statistics, which means when b1 = b2, the error is zero.
02380 //  If you prefer to have efficiency errors not going to zero when the efficiency is 1, you must
02381 //  use the function TGraphAsymmErrors::BayesDivide, which will return an asymmetric and non-zero lower
02382 //  error for the case b1=b2.
02383 
02384    TString opt = option;
02385    opt.ToLower();
02386    Bool_t binomial = kFALSE;
02387    if (opt.Contains("b")) binomial = kTRUE;
02388    if (!h1 || !h2) {
02389       Error("Divide","Attempt to divide by a non-existing histogram");
02390       return;
02391    }
02392 
02393    Int_t nbinsx = GetNbinsX();
02394    Int_t nbinsy = GetNbinsY();
02395    Int_t nbinsz = GetNbinsZ();
02396 
02397    try {
02398       CheckConsistency(h1,h2);
02399       CheckConsistency(this,h1);
02400    } catch(DifferentNumberOfBins&) {
02401       Error("Divide","Attempt to divide histograms with different number of bins");
02402       return;
02403    } catch(DifferentAxisLimits&) {
02404       Warning("Divide","Attempt to divide histograms with different axis limits");
02405    } catch(DifferentBinLimits&) {
02406       Warning("Divide","Attempt to divide histograms with different bin limits");
02407    }
02408 
02409    if (!c2) {
02410       Error("Divide","Coefficient of dividing histogram cannot be zero");
02411       return;
02412    }
02413 
02414    if (fDimension < 2) nbinsy = -1;
02415    if (fDimension < 3) nbinsz = -1;
02416 
02417 //    Create Sumw2 if h1 or h2 have Sumw2 set
02418    if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
02419 
02420    SetMinimum();
02421    SetMaximum();
02422 
02423 //    Reset the kCanRebin option. Otherwise SetBinContent on the overflow bin
02424 //    would resize the axis limits!
02425    ResetBit(kCanRebin);
02426 
02427 //   - Loop on bins (including underflows/overflows)
02428    Int_t bin, binx, biny, binz;
02429    Double_t b1,b2,w,d1,d2;
02430    d1 = c1*c1;
02431    d2 = c2*c2;
02432    for (binz=0;binz<=nbinsz+1;binz++) {
02433       for (biny=0;biny<=nbinsy+1;biny++) {
02434          for (binx=0;binx<=nbinsx+1;binx++) {
02435             bin = binx +(nbinsx+2)*(biny + (nbinsy+2)*binz);
02436             b1  = h1->GetBinContent(bin);
02437             b2  = h2->GetBinContent(bin);
02438             if (b2) w = c1*b1/(c2*b2);
02439             else    w = 0;
02440             SetBinContent(bin,w);
02441             if (fSumw2.fN) {
02442                Double_t e1 = h1->GetBinError(bin);
02443                Double_t e2 = h2->GetBinError(bin);
02444                Double_t b22= b2*b2*d2;
02445                if (!b2) { fSumw2.fArray[bin] = 0; continue;}
02446                if (binomial) {
02447                   if (b1 != b2) {
02448                      // in the case of binomial statistics c1 and c2 must be 1 otherwise it does not make sense
02449                      w = b1/b2;    // c1 and c2 are ignored
02450                      //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));//this is the formula in Hbook/Hoper1
02451                      //fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2);     // old formula from G. Flucke
02452                      // formula which works also for weighted histogram (see http://root.cern.ch/phpBB2/viewtopic.php?t=3753 )
02453                      fSumw2.fArray[bin] = TMath::Abs( ( (1.-2.*w)*e1*e1 + w*w*e2*e2 )/(b2*b2) );
02454                   } else {
02455                      //in case b1=b2 error is zero
02456                      //use  TGraphAsymmErrors::BayesDivide for getting the asymmetric error not equal to zero
02457                      fSumw2.fArray[bin] = 0;
02458                   }
02459                } else {
02460                   fSumw2.fArray[bin] = d1*d2*(e1*e1*b2*b2 + e2*e2*b1*b1)/(b22*b22);
02461                }
02462             }
02463          }
02464       }
02465    }
02466    ResetStats();
02467    if (binomial)
02468       // in case of binomial division use denominator for number of entries
02469       SetEntries ( h2->GetEntries() );
02470 }
02471 
02472 //______________________________________________________________________________
02473 void TH1::Draw(Option_t *option)
02474 {
02475 //   -*-*-*-*-*-*-*-*-*Draw this histogram with options*-*-*-*-*-*-*-*-*-*-*-*
02476 //                     ================================
02477 //
02478 //     Histograms are drawn via the THistPainter class. Each histogram has
02479 //     a pointer to its own painter (to be usable in a multithreaded program).
02480 //     The same histogram can be drawn with different options in different pads.
02481 //     When an histogram drawn in a pad is deleted, the histogram is
02482 //     automatically removed from the pad or pads where it was drawn.
02483 //     If an histogram is drawn in a pad, then filled again, the new status
02484 //     of the histogram will be automatically shown in the pad next time
02485 //     the pad is updated. One does not need to redraw the histogram.
02486 //     To draw the current version of an histogram in a pad, one can use
02487 //        h->DrawCopy();
02488 //     This makes a clone of the histogram. Once the clone is drawn, the original
02489 //     histogram may be modified or deleted without affecting the aspect of the
02490 //     clone.
02491 //     By default, TH1::Draw clears the current pad.
02492 //
02493 //     One can use TH1::SetMaximum and TH1::SetMinimum to force a particular
02494 //     value for the maximum or the minimum scale on the plot.
02495 //
02496 //     TH1::UseCurrentStyle can be used to change all histogram graphics
02497 //     attributes to correspond to the current selected style.
02498 //     This function must be called for each histogram.
02499 //     In case one reads and draws many histograms from a file, one can force
02500 //     the histograms to inherit automatically the current graphics style
02501 //     by calling before gROOT->ForceStyle();
02502 //
02503 //     See THistPainter::Paint for a description of all the drawing options
02504 //     =======================
02505 //
02506 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
02507 
02508    TString opt = option;
02509    opt.ToLower();
02510    if (gPad) {
02511       if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
02512       if (opt.Contains("same")) {
02513          if (gPad->GetX1() == 0   && gPad->GetX2() == 1 &&
02514              gPad->GetY1() == 0   && gPad->GetY2() == 1 &&
02515              gPad->GetListOfPrimitives()->GetSize()==0) opt.ReplaceAll("same","");
02516       } else {
02517          //the following statement is necessary in case one attempts to draw
02518          //a temporary histogram already in the current pad
02519          if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(this);
02520          gPad->Clear();
02521       }
02522    } else {
02523       if (opt.Contains("same")) opt.ReplaceAll("same","");
02524    }
02525    AppendPad(option);
02526 }
02527 
02528 //______________________________________________________________________________
02529 TH1 *TH1::DrawCopy(Option_t *) const
02530 {
02531 //   -*-*-*-*-*Copy this histogram and Draw in the current pad*-*-*-*-*-*-*-*
02532 //             ===============================================
02533 //
02534 //     Once the histogram is drawn into the pad, any further modification
02535 //     using graphics input will be made on the copy of the histogram,
02536 //     and not to the original object.
02537 //
02538 //     See Draw for the list of options
02539 //
02540 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
02541    AbstractMethod("DrawCopy");
02542    return 0;
02543 }
02544 
02545 //______________________________________________________________________________
02546 TH1 *TH1::DrawNormalized(Option_t *option, Double_t norm) const
02547 {
02548 //  Draw a normalized copy of this histogram.
02549 //
02550 //  A clone of this histogram is normalized to norm and drawn with option.
02551 //  A pointer to the normalized histogram is returned.
02552 //  The contents of the histogram copy are scaled such that the new
02553 //  sum of weights (excluding under and overflow) is equal to norm.
02554 //  Note that the returned normalized histogram is not added to the list
02555 //  of histograms in the current directory in memory.
02556 //  It is the user's responsability to delete this histogram.
02557 //  The kCanDelete bit is set for the returned object. If a pad containing
02558 //  this copy is cleared, the histogram will be automatically deleted.
02559 //  See also remark about calling Sumw2 before scaling a histogram to get
02560 //  a correct computation of the error bars.
02561 //
02562 //     See Draw for the list of options
02563 //
02564 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
02565 
02566    Double_t sum = GetSumOfWeights();
02567    if (sum == 0) {
02568       Error("DrawNormalized","Sum of weights is null. Cannot normalize histogram: %s",GetName());
02569       return 0;
02570    }
02571    Bool_t addStatus = TH1::AddDirectoryStatus();
02572    TH1::AddDirectory(kFALSE);
02573    TH1 *h = (TH1*)Clone();
02574    h->SetBit(kCanDelete);
02575    h->Scale(norm/sum);
02576    if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
02577    if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
02578    h->Draw(option);
02579    TH1::AddDirectory(addStatus);
02580    return h;
02581 }
02582 
02583 //______________________________________________________________________________
02584 void TH1::DrawPanel()
02585 {
02586 //   -*-*-*-*-*Display a panel with all histogram drawing options*-*-*-*-*-*
02587 //             ==================================================
02588 //
02589 //      See class TDrawPanelHist for example
02590 
02591    if (!fPainter) {Draw(); if (gPad) gPad->Update();}
02592    if (fPainter) fPainter->DrawPanel();
02593 }
02594 
02595 //______________________________________________________________________________
02596 void TH1::Eval(TF1 *f1, Option_t *option)
02597 {
02598 //   -*-*-*Evaluate function f1 at the center of bins of this histogram-*-*-*-*
02599 //         ============================================================
02600 //
02601 //     If option "R" is specified, the function is evaluated only
02602 //     for the bins included in the function range.
02603 //     If option "A" is specified, the value of the function is added to the
02604 //     existing bin contents
02605 //     If option "S" is specified, the value of the function is used to
02606 //     generate a value, distributed according to the Poisson
02607 //     distribution, with f1 as the mean.
02608 //
02609 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
02610    Double_t x[3];
02611    Int_t range,stat,add,bin,binx,biny,binz,nbinsx, nbinsy, nbinsz;
02612    if (!f1) return;
02613    Double_t fu;
02614    Double_t e=0;
02615    TString opt = option;
02616    opt.ToLower();
02617    if (opt.Contains("a")) add   = 1;
02618    else                   add   = 0;
02619    if (opt.Contains("s")) stat  = 1;
02620    else                   stat  = 0;
02621    if (opt.Contains("r")) range = 1;
02622    else                   range = 0;
02623    nbinsx  = fXaxis.GetNbins();
02624    nbinsy  = fYaxis.GetNbins();
02625    nbinsz  = fZaxis.GetNbins();
02626    if (!add) Reset();
02627 
02628    for (binz=1;binz<=nbinsz;binz++) {
02629       x[2]  = fZaxis.GetBinCenter(binz);
02630       for (biny=1;biny<=nbinsy;biny++) {
02631          x[1]  = fYaxis.GetBinCenter(biny);
02632          for (binx=1;binx<=nbinsx;binx++) {
02633             bin = GetBin(binx,biny,binz);
02634             x[0]  = fXaxis.GetBinCenter(binx);
02635             if (range && !f1->IsInside(x)) continue;
02636             fu = f1->Eval(x[0],x[1],x[2]);
02637             if (stat) fu = gRandom->PoissonD(fu);
02638             if (fSumw2.fN) e = fSumw2.fArray[bin];
02639             AddBinContent(bin,fu);
02640             if (fSumw2.fN) fSumw2.fArray[bin] = e+ TMath::Abs(fu);
02641          }
02642       }
02643    }
02644 }
02645 
02646 //______________________________________________________________________________
02647 void TH1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
02648 {
02649 //   -*-*-*-*-*-*-*-*-*Execute action corresponding to one event*-*-*-*
02650 //                     =========================================
02651 //     This member function is called when a histogram is clicked with the locator
02652 //
02653 //     If Left button clicked on the bin top value, then the content of this bin
02654 //     is modified according to the new position of the mouse when it is released.
02655 //
02656 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
02657 
02658    if (fPainter) fPainter->ExecuteEvent(event, px, py);
02659 }
02660 
02661 //______________________________________________________________________________
02662 TH1* TH1::FFT(TH1* h_output, Option_t *option)
02663 {
02664 // This function allows to do discrete Fourier transforms of TH1 and TH2.
02665 // Available transform types and flags are described below.
02666 //
02667 // To extract more information about the transform, use the function
02668 //  TVirtualFFT::GetCurrentTransform() to get a pointer to the current
02669 //  transform object.
02670 //
02671 // Parameters:
02672 //  1st - histogram for the output. If a null pointer is passed, a new histogram is created
02673 //  and returned, otherwise, the provided histogram is used and should be big enough
02674 //
02675 //  Options: option parameters consists of 3 parts:
02676 //    - option on what to return
02677 //   "RE" - returns a histogram of the real part of the output
02678 //   "IM" - returns a histogram of the imaginary part of the output
02679 //   "MAG"- returns a histogram of the magnitude of the output
02680 //   "PH" - returns a histogram of the phase of the output
02681 //
02682 //    - option of transform type
02683 //   "R2C"  - real to complex transforms - default
02684 //   "R2HC" - real to halfcomplex (special format of storing output data,
02685 //          results the same as for R2C)
02686 //   "DHT" - discrete Hartley transform
02687 //         real to real transforms (sine and cosine):
02688 //   "R2R_0", "R2R_1", "R2R_2", "R2R_3" - discrete cosine transforms of types I-IV
02689 //   "R2R_4", "R2R_5", "R2R_6", "R2R_7" - discrete sine transforms of types I-IV
02690 //    To specify the type of each dimension of a 2-dimensional real to real
02691 //    transform, use options of form "R2R_XX", for example, "R2R_02" for a transform,
02692 //    which is of type "R2R_0" in 1st dimension and  "R2R_2" in the 2nd.
02693 //
02694 //    - option of transform flag
02695 //    "ES" (from "estimate") - no time in preparing the transform, but probably sub-optimal
02696 //       performance
02697 //    "M" (from "measure")   - some time spend in finding the optimal way to do the transform
02698 //    "P" (from "patient")   - more time spend in finding the optimal way to do the transform
02699 //    "EX" (from "exhaustive") - the most optimal way is found
02700 //     This option should be chosen depending on how many transforms of the same size and
02701 //     type are going to be done. Planning is only done once, for the first transform of this
02702 //     size and type. Default is "ES".
02703 //   Examples of valid options: "Mag R2C M" "Re R2R_11" "Im R2C ES" "PH R2HC EX"
02704 
02705 
02706    Int_t ndim[3];
02707    ndim[0] = this->GetNbinsX();
02708    ndim[1] = this->GetNbinsY();
02709    ndim[2] = this->GetNbinsZ();
02710 
02711    TVirtualFFT *fft;
02712    TString opt = option;
02713    opt.ToUpper();
02714    if (!opt.Contains("2R")){
02715       if (!opt.Contains("2C") && !opt.Contains("2HC") && !opt.Contains("DHT")) {
02716          //no type specified, "R2C" by default
02717          opt.Append("R2C");
02718       }
02719       fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
02720    }
02721    else {
02722       //find the kind of transform
02723       Int_t ind = opt.Index("R2R", 3);
02724       Int_t *kind = new Int_t[2];
02725       char t;
02726       t = opt[ind+4];
02727       kind[0] = atoi(&t);
02728       if (h_output->GetDimension()>1) {
02729          t = opt[ind+5];
02730          kind[1] = atoi(&t);
02731       }
02732       fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
02733       delete [] kind;
02734    }
02735 
02736    if (!fft) return 0;
02737    Int_t in=0;
02738    for (Int_t binx = 1; binx<=ndim[0]; binx++) {
02739       for (Int_t biny=1; biny<=ndim[1]; biny++) {
02740          for (Int_t binz=1; binz<=ndim[2]; binz++) {
02741             fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
02742             in++;
02743          }
02744       }
02745    }
02746    fft->Transform();
02747    h_output = TransformHisto(fft, h_output, option);
02748    return h_output;
02749 }
02750 
02751 //______________________________________________________________________________
02752 Int_t TH1::Fill(Double_t x)
02753 {
02754 //   -*-*-*-*-*-*-*-*Increment bin with abscissa X by 1*-*-*-*-*-*-*-*-*-*-*
02755 //                   ==================================
02756 //
02757 //    if x is less than the low-edge of the first bin, the Underflow bin is incremented
02758 //    if x is greater than the upper edge of last bin, the Overflow bin is incremented
02759 //
02760 //    If the storage of the sum of squares of weights has been triggered,
02761 //    via the function Sumw2, then the sum of the squares of weights is incremented
02762 //    by 1 in the bin corresponding to x.
02763 //
02764 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
02765 
02766    if (fBuffer) return BufferFill(x,1);
02767 
02768    Int_t bin;
02769    fEntries++;
02770    bin =fXaxis.FindBin(x);
02771    if (bin <0) return -1;
02772    AddBinContent(bin);
02773    if (fSumw2.fN) ++fSumw2.fArray[bin];
02774    if (bin == 0 || bin > fXaxis.GetNbins()) {
02775       if (!fgStatOverflows) return -1;
02776    }
02777    ++fTsumw;
02778    ++fTsumw2;
02779    fTsumwx  += x;
02780    fTsumwx2 += x*x;
02781    return bin;
02782 }
02783 
02784 //______________________________________________________________________________
02785 Int_t TH1::Fill(Double_t x, Double_t w)
02786 {
02787 //   -*-*-*-*-*-*Increment bin with abscissa X with a weight w*-*-*-*-*-*-*-*
02788 //               =============================================
02789 //
02790 //    if x is less than the low-edge of the first bin, the Underflow bin is incremented
02791 //    if x is greater than the upper edge of last bin, the Overflow bin is incremented
02792 //
02793 //    If the storage of the sum of squares of weights has been triggered,
02794 //    via the function Sumw2, then the sum of the squares of weights is incremented
02795 //    by w^2 in the bin corresponding to x.
02796 //
02797 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
02798 
02799    if (fBuffer) return BufferFill(x,w);
02800 
02801    Int_t bin;
02802    fEntries++;
02803    bin =fXaxis.FindBin(x);
02804    if (bin <0) return -1;
02805    AddBinContent(bin, w);
02806    if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
02807    if (bin == 0 || bin > fXaxis.GetNbins()) {
02808       if (!fgStatOverflows) return -1;
02809    }
02810    Double_t z= (w > 0 ? w : -w);
02811    fTsumw   += z;
02812    fTsumw2  += z*z;
02813    fTsumwx  += z*x;
02814    fTsumwx2 += z*x*x;
02815    return bin;
02816 }
02817 
02818 //______________________________________________________________________________
02819 Int_t TH1::Fill(const char *namex, Double_t w)
02820 {
02821 // Increment bin with namex with a weight w
02822 //
02823 // if x is less than the low-edge of the first bin, the Underflow bin is incremented
02824 // if x is greater than the upper edge of last bin, the Overflow bin is incremented
02825 //
02826 // If the storage of the sum of squares of weights has been triggered,
02827 // via the function Sumw2, then the sum of the squares of weights is incremented
02828 // by w^2 in the bin corresponding to x.
02829 //
02830 
02831    Int_t bin;
02832    fEntries++;
02833    bin =fXaxis.FindBin(namex);
02834    if (bin <0) return -1;
02835    AddBinContent(bin, w);
02836    if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
02837    if (bin == 0 || bin > fXaxis.GetNbins()) return -1;
02838    Double_t x = fXaxis.GetBinCenter(bin);
02839    Double_t z= (w > 0 ? w : -w);
02840    fTsumw   += z;
02841    fTsumw2  += z*z;
02842    fTsumwx  += z*x;
02843    fTsumwx2 += z*x*x;
02844    return bin;
02845 }
02846 
02847 //______________________________________________________________________________
02848 void TH1::FillN(Int_t ntimes, const Double_t *x, const Double_t *w, Int_t stride)
02849 {
02850 //   -*-*-*-*-*-*Fill this histogram with an array x and weights w*-*-*-*-*
02851 //               =================================================
02852 //
02853 //    ntimes:  number of entries in arrays x and w (array size must be ntimes*stride)
02854 //    x:       array of values to be histogrammed
02855 //    w:       array of weighs
02856 //    stride:  step size through arrays x and w
02857 //
02858 //    If the storage of the sum of squares of weights has been triggered,
02859 //    via the function Sumw2, then the sum of the squares of weights is incremented
02860 //    by w[i]^2 in the bin corresponding to x[i].
02861 //    if w is NULL each entry is assumed a weight=1
02862 //
02863 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
02864 
02865    Int_t bin,i;
02866    //If a buffer is activated, go via standard Fill (sorry)
02867    //if (fBuffer) {
02868    //   for (i=0;i<ntimes;i+=stride) {
02869    //      if (w) Fill(x[i],w[i]);
02870    //      else   Fill(x[i],0);
02871    //   }
02872    //   return;
02873    //}
02874 
02875    fEntries += ntimes;
02876    Double_t ww = 1;
02877    Int_t nbins   = fXaxis.GetNbins();
02878    ntimes *= stride;
02879    for (i=0;i<ntimes;i+=stride) {
02880       bin =fXaxis.FindBin(x[i]);
02881       if (bin <0) continue;
02882       if (w) ww = w[i];
02883       AddBinContent(bin, ww);
02884       if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
02885       if (bin == 0 || bin > nbins) {
02886          if (!fgStatOverflows) continue;
02887       }
02888       Double_t z= (ww > 0 ? ww : -ww);
02889       fTsumw   += z;
02890       fTsumw2  += z*z;
02891       fTsumwx  += z*x[i];
02892       fTsumwx2 += z*x[i]*x[i];
02893    }
02894 }
02895 
02896 //______________________________________________________________________________
02897 void TH1::FillRandom(const char *fname, Int_t ntimes)
02898 {
02899 //   -*-*-*-*-*Fill histogram following distribution in function fname*-*-*-*
02900 //             =======================================================
02901 //
02902 //      The distribution contained in the function fname (TF1) is integrated
02903 //      over the channel contents for the bin range of this histogram.
02904 //      It is normalized to 1.
02905 //      Getting one random number implies:
02906 //        - Generating a random number between 0 and 1 (say r1)
02907 //        - Look in which bin in the normalized integral r1 corresponds to
02908 //        - Fill histogram channel
02909 //      ntimes random numbers are generated
02910 //
02911 //     One can also call TF1::GetRandom to get a random variate from a function.
02912 //
02913 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*
02914 
02915    Int_t bin, binx, ibin, loop;
02916    Double_t r1, x;
02917 //   - Search for fname in the list of ROOT defined functions
02918    TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
02919    if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
02920 
02921 //   - Allocate temporary space to store the integral and compute integral
02922    Int_t first  = fXaxis.GetFirst();
02923    Int_t last   = fXaxis.GetLast();
02924    Int_t nbinsx = last-first+1;
02925 
02926    Double_t *integral = new Double_t[nbinsx+1];
02927    integral[0] = 0;
02928    for (binx=1;binx<=nbinsx;binx++) {
02929       Double_t fint = f1->Integral(fXaxis.GetBinLowEdge(binx+first-1),fXaxis.GetBinUpEdge(binx+first-1));
02930       integral[binx] = integral[binx-1] + fint;
02931    }
02932 
02933 //   - Normalize integral to 1
02934    if (integral[nbinsx] == 0 ) {
02935       delete [] integral;
02936       Error("FillRandom", "Integral = zero"); return;
02937    }
02938    for (bin=1;bin<=nbinsx;bin++)  integral[bin] /= integral[nbinsx];
02939 
02940 //   --------------Start main loop ntimes
02941    for (loop=0;loop<ntimes;loop++) {
02942       r1 = gRandom->Rndm(loop);
02943       ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
02944       //binx = 1 + ibin;
02945       //x    = fXaxis.GetBinCenter(binx); //this is not OK when SetBuffer is used
02946       x    = fXaxis.GetBinLowEdge(ibin+first)
02947              +fXaxis.GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
02948       Fill(x, 1.);
02949    }
02950    delete [] integral;
02951 }
02952 
02953 //______________________________________________________________________________
02954 void TH1::FillRandom(TH1 *h, Int_t ntimes)
02955 {
02956 //   -*-*-*-*-*Fill histogram following distribution in histogram h*-*-*-*
02957 //             ====================================================
02958 //
02959 //      The distribution contained in the histogram h (TH1) is integrated
02960 //      over the channel contents for the bin range of this histogram.
02961 //      It is normalized to 1.
02962 //      Getting one random number implies:
02963 //        - Generating a random number between 0 and 1 (say r1)
02964 //        - Look in which bin in the normalized integral r1 corresponds to
02965 //        - Fill histogram channel
02966 //      ntimes random numbers are generated
02967 //
02968 //    SPECIAL CASE when the target histogram has the same binning as the source.
02969 //   in this case we simply use a poisson distribution where
02970 //   the mean value per bin = bincontent/integral.
02971 //
02972 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*
02973 
02974    if (!h) { Error("FillRandom", "Null histogram"); return; }
02975    if (fDimension != h->GetDimension()) {
02976       Error("FillRandom", "Histograms with different dimensions"); return;
02977    }
02978 
02979    //in case the target histogram has the same binning and ntimes much greater
02980    //than the number of bins we can use a fast method
02981    Int_t first  = fXaxis.GetFirst();
02982    Int_t last   = fXaxis.GetLast();
02983    Int_t nbins = last-first+1;
02984    if (CheckConsistency(this,h) && ntimes > 10*nbins) {
02985       Double_t sumw = h->Integral(first,last);
02986       if (sumw == 0) return;
02987       Double_t sumgen = 0;
02988       for (Int_t bin=first;bin<=last;bin++) {
02989          Double_t mean = h->GetBinContent(bin)*ntimes/sumw;
02990          Double_t cont = (Double_t)gRandom->Poisson(mean);
02991          sumgen += cont;
02992          AddBinContent(bin,cont);
02993          if (fSumw2.fN) fSumw2.fArray[bin] += cont;
02994       }
02995 
02996       // fix for the fluctations in the total number n
02997       // since we use Poisson instead of multinomial
02998       // add a correction to have ntimes as generated entries
02999       Int_t i;
03000       if (sumgen < ntimes) {
03001          // add missing entries
03002          for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
03003          {
03004             Double_t x = h->GetRandom();
03005             Fill(x);
03006          }
03007       }
03008       else if (sumgen > ntimes) {
03009          // remove extra entries
03010          i =  Int_t(sumgen+0.5);
03011          while( i > ntimes) {
03012             Double_t x = h->GetRandom();
03013             Int_t ibin = fXaxis.FindBin(x);
03014             Double_t y = GetBinContent(ibin);
03015             // skip in case bin is empty
03016             if (y > 0) {
03017                SetBinContent(ibin, y-1.);
03018                i--;
03019             }
03020          }
03021       }
03022 
03023       ResetStats();
03024       return;
03025    }
03026 
03027    if (h->ComputeIntegral() ==0) return;
03028    Int_t loop;
03029    Double_t x;
03030    for (loop=0;loop<ntimes;loop++) {
03031       x = h->GetRandom();
03032       Fill(x);
03033    }
03034 }
03035 
03036 
03037 //______________________________________________________________________________
03038 Int_t TH1::FindBin(Double_t x, Double_t y, Double_t z)
03039 {
03040 //   Return Global bin number corresponding to x,y,z
03041 //   ===============================================
03042 //
03043 //      2-D and 3-D histograms are represented with a one dimensional
03044 //      structure. This function tries to rebin the axis if the given point
03045 //      belongs to an under-/overflow bin.
03046 //      This has the advantage that all existing functions, such as
03047 //        GetBinContent, GetBinError, GetBinFunction work for all dimensions.
03048 //     See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
03049 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03050 
03051    if (GetDimension() < 2) {
03052       return fXaxis.FindBin(x);
03053    }
03054    if (GetDimension() < 3) {
03055       Int_t nx   = fXaxis.GetNbins()+2;
03056       Int_t binx = fXaxis.FindBin(x);
03057       Int_t biny = fYaxis.FindBin(y);
03058       return  binx + nx*biny;
03059    }
03060    if (GetDimension() < 4) {
03061       Int_t nx   = fXaxis.GetNbins()+2;
03062       Int_t ny   = fYaxis.GetNbins()+2;
03063       Int_t binx = fXaxis.FindBin(x);
03064       Int_t biny = fYaxis.FindBin(y);
03065       Int_t binz = fZaxis.FindBin(z);
03066       return  binx + nx*(biny +ny*binz);
03067    }
03068    return -1;
03069 }
03070 
03071 //______________________________________________________________________________
03072 Int_t TH1::FindFixBin(Double_t x, Double_t y, Double_t z) const
03073 {
03074 //   Return Global bin number corresponding to x,y,z
03075 //   ===============================================
03076 //
03077 //      2-D and 3-D histograms are represented with a one dimensional
03078 //      structure. This function DOES not try to rebin the axis if the given
03079 //      point belongs to an under-/overflow bin.
03080 //      This has the advantage that all existing functions, such as
03081 //        GetBinContent, GetBinError, GetBinFunction work for all dimensions.
03082 //     See also TH1::GetBin, TAxis::FindBin and TAxis::FindFixBin
03083 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03084 
03085    if (GetDimension() < 2) {
03086       return fXaxis.FindFixBin(x);
03087    }
03088    if (GetDimension() < 3) {
03089       Int_t nx   = fXaxis.GetNbins()+2;
03090       Int_t binx = fXaxis.FindFixBin(x);
03091       Int_t biny = fYaxis.FindFixBin(y);
03092       return  binx + nx*biny;
03093    }
03094    if (GetDimension() < 4) {
03095       Int_t nx   = fXaxis.GetNbins()+2;
03096       Int_t ny   = fYaxis.GetNbins()+2;
03097       Int_t binx = fXaxis.FindFixBin(x);
03098       Int_t biny = fYaxis.FindFixBin(y);
03099       Int_t binz = fZaxis.FindFixBin(z);
03100       return  binx + nx*(biny +ny*binz);
03101    }
03102    return -1;
03103 }
03104 
03105 //______________________________________________________________________________
03106 Int_t TH1::FindFirstBinAbove(Double_t threshold, Int_t axis) const
03107 {
03108    //find first bin with content > threshold for axis (1=x, 2=y, 3=z)
03109    //if no bins with content > threshold is found the function returns -1.
03110 
03111    if (axis != 1) {
03112       Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
03113       axis = 1;
03114    }
03115    Int_t nbins = fXaxis.GetNbins();
03116    for (Int_t bin=1;bin<=nbins;bin++) {
03117       if (GetBinContent(bin) > threshold) return bin;
03118    }
03119    return -1;
03120 }
03121 
03122 
03123 //______________________________________________________________________________
03124 Int_t TH1::FindLastBinAbove(Double_t threshold, Int_t axis) const
03125 {
03126    //find last bin with content > threshold for axis (1=x, 2=y, 3=z)
03127    //if no bins with content > threshold is found the function returns -1.
03128 
03129    if (axis != 1) {
03130       Warning("FindLastBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
03131       axis = 1;
03132    }
03133    Int_t nbins = fXaxis.GetNbins();
03134    for (Int_t bin=nbins;bin>=1;bin--) {
03135       if (GetBinContent(bin) > threshold) return bin;
03136    }
03137    return -1;
03138 }
03139 
03140 //______________________________________________________________________________
03141 TObject *TH1::FindObject(const char *name) const
03142 {
03143 // search object named name in the list of functions
03144 
03145    if (fFunctions) return fFunctions->FindObject(name);
03146    return 0;
03147 }
03148 
03149 //______________________________________________________________________________
03150 TObject *TH1::FindObject(const TObject *obj) const
03151 {
03152 // search object obj in the list of functions
03153 
03154    if (fFunctions) return fFunctions->FindObject(obj);
03155    return 0;
03156 }
03157 
03158 //______________________________________________________________________________
03159 TFitResultPtr TH1::Fit(const char *fname ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
03160 {
03161 //                     Fit histogram with function fname
03162 //                     =================================
03163 //      fname is the name of an already predefined function created by TF1 or TF2
03164 //      Predefined functions such as gaus, expo and poln are automatically
03165 //      created by ROOT.
03166 //      fname can also be a formula, accepted by the linear fitter (linear parts divided
03167 //      by "++" sign), for example "x++sin(x)" for fitting "[0]*x+[1]*sin(x)"
03168 //
03169 //  This function finds a pointer to the TF1 object with name fname
03170 //  and calls TH1::Fit(TF1 *f1,...)
03171 
03172    char *linear;
03173    linear= (char*)strstr(fname, "++");
03174    TF1 *f1=0;
03175    TF2 *f2=0;
03176    TF3 *f3=0;
03177    Int_t ndim=GetDimension();
03178    if (linear){
03179       if (ndim<2){
03180          f1=new TF1(fname, fname, xxmin, xxmax);
03181          return Fit(f1,option,goption,xxmin,xxmax);
03182       }
03183       else if (ndim<3){
03184          f2=new TF2(fname, fname);
03185          return Fit(f2,option,goption,xxmin,xxmax);
03186       }
03187       else{
03188          f3=new TF3(fname, fname);
03189          return Fit(f3,option,goption,xxmin,xxmax);
03190       }
03191    }
03192 
03193    else{
03194       f1 = (TF1*)gROOT->GetFunction(fname);
03195       if (!f1) { Printf("Unknown function: %s",fname); return -1; }
03196       return Fit(f1,option,goption,xxmin,xxmax);
03197    }
03198 }
03199 
03200 //______________________________________________________________________________
03201 TFitResultPtr TH1::Fit(TF1 *f1 ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
03202 {
03203 //                     Fit histogram with function f1
03204 //                     ==============================
03205 //
03206 //      Fit this histogram with function f1.
03207 //
03208 //      The list of fit options is given in parameter option.
03209 //         option = "W"  Set all weights to 1 for non empty bins; ignore error bars
03210 //                = "WW" Set all weights to 1 including empty bins; ignore error bars
03211 //                = "I"  Use integral of function in bin, normalized by the bin volume,
03212 //                       instead of value at bin center
03213 //                = "L"  Use Loglikelihood method (default is chisquare method)
03214 //                = "LL" Use Loglikelihood method and bin contents are not integers)
03215 //                = "U"  Use a User specified fitting algorithm (via SetFCN)
03216 //                = "Q"  Quiet mode (minimum printing)
03217 //                = "V"  Verbose mode (default is between Q and V)
03218 //                = "E"  Perform better Errors estimation using Minos technique
03219 //                = "B"  User defined parameter settings are used for predefined functions
03220 //                       like "gaus", "expo", "poln", "landau".
03221 //                       Use this option when you want to fix one or more parameters for these functions.
03222 //                = "M"  More. Improve fit results.
03223 //                       It uses the IMPROVE command of TMinuit (see TMinuit::mnimpr).
03224 //                       This algorithm attempts to improve the found local minimum by searching for a
03225 //                       better one.
03226 //                = "R"  Use the Range specified in the function range
03227 //                = "N"  Do not store the graphics function, do not draw
03228 //                = "0"  Do not plot the result of the fit. By default the fitted function
03229 //                       is drawn unless the option"N" above is specified.
03230 //                = "+"  Add this new fitted function to the list of fitted functions
03231 //                       (by default, any previous function is deleted)
03232 //                = "C"  In case of linear fitting, don't calculate the chisquare
03233 //                       (saves time)
03234 //                = "F"  If fitting a polN, switch to minuit fitter
03235 //                = "S"  The result of the fit is returned in the TFitResultPtr
03236 //                       (see below Access to the Fit Result)
03237 //
03238 //      When the fit is drawn (by default), the parameter goption may be used
03239 //      to specify a list of graphics options. See TH1::Draw for a complete
03240 //      list of these options.
03241 //
03242 //      In order to use the Range option, one must first create a function
03243 //      with the expression to be fitted. For example, if your histogram
03244 //      has a defined range between -4 and 4 and you want to fit a gaussian
03245 //      only in the interval 1 to 3, you can do:
03246 //           TF1 *f1 = new TF1("f1", "gaus", 1, 3);
03247 //           histo->Fit("f1", "R");
03248 //
03249 //      Setting initial conditions
03250 //      ==========================
03251 //      Parameters must be initialized before invoking the Fit function.
03252 //      The setting of the parameter initial values is automatic for the
03253 //      predefined functions : poln, expo, gaus, landau. One can however disable
03254 //      this automatic computation by specifying the option "B".
03255 //      Note that if a predefined function is defined with an argument,
03256 //      eg, gaus(0), expo(1), you must specify the initial values for
03257 //      the parameters.
03258 //      You can specify boundary limits for some or all parameters via
03259 //           f1->SetParLimits(p_number, parmin, parmax);
03260 //      if parmin>=parmax, the parameter is fixed
03261 //      Note that you are not forced to fix the limits for all parameters.
03262 //      For example, if you fit a function with 6 parameters, you can do:
03263 //        func->SetParameters(0, 3.1, 1.e-6, -8, 0, 100);
03264 //        func->SetParLimits(3, -10, -4);
03265 //        func->FixParameter(4, 0);
03266 //        func->SetParLimits(5, 1, 1);
03267 //      With this setup, parameters 0->2 can vary freely
03268 //      Parameter 3 has boundaries [-10,-4] with initial value -8
03269 //      Parameter 4 is fixed to 0
03270 //      Parameter 5 is fixed to 100.
03271 //      When the lower limit and upper limit are equal, the parameter is fixed.
03272 //      However to fix a parameter to 0, one must call the FixParameter function.
03273 //
03274 //      Note that option "I" gives better results but is slower.
03275 //
03276 //
03277 //      Changing the fitting objective function
03278 //      =============================
03279 //     By default a chi square function is used for fitting. When option "L" (or "LL") is used
03280 //     a Poisson likelihood function (see note below) is used.
03281 //     The functions are defined in the header Fit/Chi2Func.h or Fit/PoissonLikelihoodFCN and they
03282 //     are implemented using the routines FitUtil::EvaluateChi2 or FitUtil::EvaluatePoissonLogL in
03283 //     the file math/mathcore/src/FitUtil.cxx.
03284 //     To specify a User defined fitting function, specify option "U" and
03285 //     call the following functions:
03286 //       TVirtualFitter::Fitter(myhist)->SetFCN(MyFittingFunction)
03287 //     where MyFittingFunction is of type:
03288 //     extern void MyFittingFunction(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
03289 //
03290 //     Likelihood Fits
03291 //     =================
03292 //     When using option "L" a likelihood fit is used instead of the default chi2 square fit.
03293 //     The likelihood is built assuming a Poisson probability density function for each bin.
03294 //     This method can then be used only when the bin content represents counts (i.e. errors are sqrt(N) ).
03295 //     The likelihood method has the advantage of treating correctly the empty bins and use them in the
03296 //     fit procedure.
03297 //     In the chi2 method the empty bins are skipped and not considered in the fit.
03298 //     The likelihood method, although a bit slower, it is the recommended method in case of low
03299 //     bin statistics, where the chi2 method may give incorrect results.
03300 //
03301 //      Fitting a histogram of dimension N with a function of dimension N-1
03302 //      ===================================================================
03303 //     It is possible to fit a TH2 with a TF1 or a TH3 with a TF2.
03304 //     In this case the option "Integral" is not allowed and each cell has
03305 //     equal weight.
03306 //
03307 //     Associated functions
03308 //     ====================
03309 //     One or more object (typically a TF1*) can be added to the list
03310 //     of functions (fFunctions) associated to each histogram.
03311 //     When TH1::Fit is invoked, the fitted function is added to this list.
03312 //     Given an histogram h, one can retrieve an associated function
03313 //     with:  TF1 *myfunc = h->GetFunction("myfunc");
03314 //
03315 //      Access to the fit result
03316 //      ========================
03317 //     The function returns a TFitResultPtr which can hold a  pointer to a TFitResult object.
03318 //     By default the TFitResultPtr contains only the status of the fit which is return by an
03319 //     automatic conversion of the TFitResultPtr to an integer. One can write in this case directly:
03320 //     Int_t fitStatus =  h->Fit(myFunc)
03321 //
03322 //     If the option "S" is instead used, TFitResultPtr contains the TFitResult and behaves as a smart
03323 //     pointer to it. For example one can do:
03324 //     TFitResultPtr r = h->Fit(myFunc,"S");
03325 //     TMatrixDSym cov = r->GetCovarianceMatrix();  //  to access the covariance matrix
03326 //     Double_t chi2   = r->Chi2(); // to retrieve the fit chi2
03327 //     Double_t par0   = r->Parameter(0); // retrieve the value for the parameter 0
03328 //     Double_t err0   = r->ParError(0); // retrieve the error for the parameter 0
03329 //     r->Print("V");     // print full information of fit including covariance matrix
03330 //     r->Write();        // store the result in a file
03331 //
03332 //     The fit parameters, error and chi2 (but not covariance matrix) can be retrieved also
03333 //     from the fitted function.
03334 //     If the histogram is made persistent, the list of
03335 //     associated functions is also persistent. Given a pointer (see above)
03336 //     to an associated function myfunc, one can retrieve the function/fit
03337 //     parameters with calls such as:
03338 //       Double_t chi2 = myfunc->GetChisquare();
03339 //       Double_t par0 = myfunc->GetParameter(0); //value of 1st parameter
03340 //       Double_t err0 = myfunc->GetParError(0);  //error on first parameter
03341 //
03342 //
03343 //     Access to the fit status
03344 //     =====================
03345 //     The status of the fit can be obtained converting the TFitResultPtr to an integer
03346 //     indipendently if the fit option "S" is used or not:
03347 //     TFitResultPtr r = h=>Fit(myFunc,opt);
03348 //     Int_t fitStatus = r;
03349 //
03350 //     The fitStatus is 0 if the fit is OK (i.e no error occurred).
03351 //     The value of the fit status code is negative in case of an error not connected with the
03352 //     minimization procedure, for example  when a wrong function is used.
03353 //     Otherwise the return value is the one returned from the minimization procedure.
03354 //     When TMinuit (default case) or Minuit2 are used as minimizer the status returned is :
03355 //     fitStatus =  migradResult + 10*minosResult + 100*hesseResult + 1000*improveResult.
03356 //     TMinuit will return 0 (for migrad, minos, hesse or improve) in case of success and 4 in
03357 //     case of error (see the documentation of TMinuit::mnexcm). So for example, for an error
03358 //     only in Minos but not in Migrad a fitStatus of 40 will be returned.
03359 //     Minuit2 will return also 0 in case of success and different values in migrad minos or
03360 //     hesse depending on the error. See in this case the documentation of
03361 //     Minuit2Minimizer::Minimize for the migradResult, Minuit2Minimizer::GetMinosError for the
03362 //     minosResult and Minuit2Minimizer::Hesse for the hesseResult.
03363 //     If other minimizers are used see their specific documentation for the status code returned.
03364 //     For example in the case of Fumili, for the status returned see TFumili::Minimize.
03365 //
03366 //      Excluding points
03367 //      ================
03368 //     Use TF1::RejectPoint inside your fitting function to exclude points
03369 //     within a certain range from the fit. Example:
03370 //     Double_t fline(Double_t *x, Double_t *par)
03371 //     {
03372 //         if (x[0] > 2.5 && x[0] < 3.5) {
03373 //           TF1::RejectPoint();
03374 //           return 0;
03375 //        }
03376 //        return par[0] + par[1]*x[0];
03377 //     }
03378 //
03379 //     void exclude() {
03380 //        TF1 *f1 = new TF1("f1", "[0] +[1]*x +gaus(2)", 0, 5);
03381 //        f1->SetParameters(6, -1,5, 3, 0.2);
03382 //        TH1F *h = new TH1F("h", "background + signal", 100, 0, 5);
03383 //        h->FillRandom("f1", 2000);
03384 //        TF1 *fline = new TF1("fline", fline, 0, 5, 2);
03385 //        fline->SetParameters(2, -1);
03386 //        h->Fit("fline", "l");
03387 //     }
03388 //
03389 //      Warning when using the option "0"
03390 //      =================================
03391 //     When selecting the option "0", the fitted function is added to
03392 //     the list of functions of the histogram, but it is not drawn.
03393 //     You can undo what you disabled in the following way:
03394 //       h.Fit("myFunction", "0"); // fit, store function but do not draw
03395 //       h.Draw(); function is not drawn
03396 //       const Int_t kNotDraw = 1<<9;
03397 //       h.GetFunction("myFunction")->ResetBit(kNotDraw);
03398 //       h.Draw();  // function is visible again
03399 //
03400 //      Access to the Minimizer information during fitting
03401 //      ===============================================
03402 //     This function calls, the ROOT::Fit::FitObject function implemented in HFitImpl.cxx
03403 //     which uses the ROOT::Fit::Fitter class. The Fitter class creates the objective fuction
03404 //     (e.g. chi2 or likelihood) and uses an implementation of the  Minimizer interface for minimizing
03405 //     the function.
03406 //     The default minimizer is Minuit (class TMinuitMinimizer which calls TMinuit).
03407 //     The default  can be set in the resource file in etc/system.rootrc. For example
03408 //     Root.Fitter:      Minuit2
03409 //     A different fitter can also be set via ROOT::Math::MinimizerOptions::SetDefaultMinimizer
03410 //     (or TVirtualFitter::SetDefaultFitter).
03411 //     For example ROOT::Math::MinimizerOptions::SetDefaultMinimizer("GSLMultiMin","BFGS");
03412 //     will set the usdage of the BFGS algorithm of the GSL multi-dimensional minimization
03413 //     (implemented in libMathMore). ROOT::Math::MinimizerOptions can be used also to set other
03414 //     default options, like maximum number of function calls, minimization tolerance or print
03415 //     level. See the documentation of this class.
03416 //
03417 //     For fitting linear functions (containing the "++" sign" and polN functions,
03418 //     the linear fitter is automatically initialized.
03419 //
03420 //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03421 
03422    // implementation of Fit method is in file hist/src/HFitImpl.cxx
03423    Foption_t fitOption;
03424 
03425    if (!FitOptionsMake(option,fitOption)) return 0;
03426    // create range and minimizer options with default values
03427    ROOT::Fit::DataRange range(xxmin,xxmax);
03428    ROOT::Math::MinimizerOptions minOption;
03429 
03430    return ROOT::Fit::FitObject(this, f1 , fitOption , minOption, goption, range);
03431 }
03432 
03433 //______________________________________________________________________________
03434 void TH1::FitPanel()
03435 {
03436 //   -*-*-*-*-*Display a panel with all histogram fit options*-*-*-*-*-*
03437 //             ==============================================
03438 //
03439 //      See class TFitPanel for example
03440 
03441    if (!gPad)
03442       gROOT->MakeDefCanvas();
03443 
03444    if (!gPad) {
03445       Error("FitPanel", "Unable to create a default canvas");
03446       return;
03447    }
03448 
03449 
03450    // use plugin manager to create instance of TFitEditor
03451    TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
03452    if (handler && handler->LoadPlugin() != -1) {
03453       if (handler->ExecPlugin(2, gPad, this) == 0)
03454          Error("FitPanel", "Unable to create the FitPanel");
03455    }
03456    else
03457          Error("FitPanel", "Unable to find the FitPanel plug-in");
03458 }
03459 
03460 //______________________________________________________________________________
03461 TH1 *TH1::GetAsymmetry(TH1* h2, Double_t c2, Double_t dc2)
03462 {
03463    //  return an histogram containing the asymmetry of this histogram with h2,
03464    //  where the asymmetry is defined as:
03465    //
03466    //  Asymmetry = (h1 - h2)/(h1 + h2)  where h1 = this
03467    //
03468    //  works for 1D, 2D, etc. histograms
03469    //  c2 is an optional argument that gives a relative weight between the two
03470    //  histograms, and dc2 is the error on this weight.  This is useful, for example,
03471    //  when forming an asymmetry between two histograms from 2 different data sets that
03472    //  need to be normalized to each other in some way.  The function calculates
03473    //  the errors asumming Poisson statistics on h1 and h2 (that is, dh = sqrt(h)).
03474    //
03475    //  example:  assuming 'h1' and 'h2' are already filled
03476    //
03477    //     h3 = h1->GetAsymmetry(h2)
03478    //
03479    //  then 'h3' is created and filled with the asymmetry between 'h1' and 'h2';
03480    //  h1 and h2 are left intact.
03481    //
03482    //  Note that it is the user's responsibility to manage the created histogram.
03483    //
03484    //  code proposed by Jason Seely (seely@mit.edu) and adapted by R.Brun
03485    //
03486    // clone the histograms so top and bottom will have the
03487    // correct dimensions:
03488    // Sumw2 just makes sure the errors will be computed properly
03489    // when we form sums and ratios below.
03490    Bool_t addStatus = TH1::AddDirectoryStatus();
03491    TH1::AddDirectory(kFALSE);
03492    TH1 *asym   = (TH1*)Clone();
03493    asym->Sumw2();
03494    TH1 *top    = (TH1*)asym->Clone();
03495    TH1 *bottom = (TH1*)asym->Clone();
03496    TH1::AddDirectory(addStatus);
03497 
03498    // form the top and bottom of the asymmetry, and then divide:
03499    TH1 *h1 = this;
03500    top->Add(h1,h2,1,-c2);
03501    bottom->Add(h1,h2,1,c2);
03502    asym->Divide(top,bottom);
03503 
03504    Int_t   xmax = asym->GetNbinsX();
03505    Int_t   ymax = asym->GetNbinsY();
03506    Int_t   zmax = asym->GetNbinsZ();
03507    Double_t bot, error, a, b, da, db;
03508 
03509    // now loop over bins to calculate the correct errors
03510    // the reason this error calculation looks complex is because of c2
03511    for(Int_t i=1; i<= xmax; i++){
03512       for(Int_t j=1; j<= ymax; j++){
03513          for(Int_t k=1; k<= zmax; k++){
03514 
03515             // here some bin contents are written into variables to make the error
03516             // calculation a little more legible:
03517             a   = h1->GetBinContent(i,j,k);
03518             b   = h2->GetBinContent(i,j,k);
03519             bot = bottom->GetBinContent(i,j,k);
03520 
03521             // make sure there are some events, if not, then the errors are set = 0
03522             // automatically.
03523             //if(bot < 1){} was changed to the next line from recommendation of Jason Seely (28 Nov 2005)
03524             if(bot < 1e-6){}
03525             else{
03526                // computation of errors by Christos Leonidopoulos
03527                da    = h1->GetBinError(i,j,k);
03528                db    = h2->GetBinError(i,j,k);
03529                error = 2*TMath::Sqrt(a*a*c2*c2*db*db + c2*c2*b*b*da*da+a*a*b*b*dc2*dc2)/(bot*bot);
03530                asym->SetBinError(i,j,k,error);
03531             }
03532          }
03533       }
03534    }
03535    delete top;
03536    delete bottom;
03537    return asym;
03538 }
03539 
03540 //______________________________________________________________________________
03541 Int_t TH1::GetDefaultBufferSize()
03542 {
03543    // static function
03544    // return the default buffer size for automatic histograms
03545    // the parameter fgBufferSize may be changed via SetDefaultBufferSize
03546 
03547    return fgBufferSize;
03548 }
03549 
03550 
03551 //______________________________________________________________________________
03552 Bool_t TH1::GetDefaultSumw2()
03553 {
03554    // static function
03555    // return kTRUE if TH1::Sumw2 must be called when creating new histograms.
03556    // see TH1::SetDefaultSumw2.
03557 
03558    return fgDefaultSumw2;
03559 }
03560 
03561 
03562 //______________________________________________________________________________
03563 Double_t TH1::GetEntries() const
03564 {
03565    // return the current number of entries
03566 
03567    if (fBuffer) ((TH1*)this)->BufferEmpty();
03568 
03569    return fEntries;
03570 }
03571 
03572 //______________________________________________________________________________
03573 Double_t TH1::GetEffectiveEntries() const
03574 {
03575    // number of effective entries of the histogram,
03576    // i.e. the number of unweighted entries a histogram would need to
03577    // have the same statistical power as this histogram with possibly
03578    // weighted entries (i.e. <= TH1::GetEntries())
03579 
03580    Stat_t s[kNstat];
03581    this->GetStats(s);// s[1] sum of squares of weights, s[0] sum of weights
03582    return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
03583 }
03584 
03585 //______________________________________________________________________________
03586 char *TH1::GetObjectInfo(Int_t px, Int_t py) const
03587 {
03588    //   Redefines TObject::GetObjectInfo.
03589    //   Displays the histogram info (bin number, contents, integral up to bin
03590    //   corresponding to cursor position px,py
03591    //
03592    return ((TH1*)this)->GetPainter()->GetObjectInfo(px,py);
03593 }
03594 
03595 //______________________________________________________________________________
03596 TVirtualHistPainter *TH1::GetPainter(Option_t *option)
03597 {
03598    // return pointer to painter
03599    // if painter does not exist, it is created
03600    if (!fPainter) {
03601       TString opt = option;
03602       opt.ToLower();
03603       if (opt.Contains("gl") || gStyle->GetCanvasPreferGL()) {
03604          //try to create TGLHistPainter
03605          TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TGLHistPainter");
03606 
03607          if (handler && handler->LoadPlugin() != -1)
03608             fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1, this));
03609       }
03610    }
03611 
03612    if (!fPainter) fPainter = TVirtualHistPainter::HistPainter(this);
03613 
03614    return fPainter;
03615 }
03616 
03617 //______________________________________________________________________________
03618 Int_t TH1::GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
03619 {
03620    //  Compute Quantiles for this histogram
03621    //     Quantile x_q of a probability distribution Function F is defined as
03622    //
03623    //        F(x_q) = q with 0 <= q <= 1.
03624    //
03625    //     For instance the median x_0.5 of a distribution is defined as that value
03626    //     of the random variable for which the distribution function equals 0.5:
03627    //
03628    //        F(x_0.5) = Probability(x < x_0.5) = 0.5
03629    //
03630    //  code from Eddy Offermann, Renaissance
03631    //
03632    // input parameters
03633    //   - this 1-d histogram (TH1F,D,etc). Could also be a TProfile
03634    //   - nprobSum maximum size of array q and size of array probSum (if given)
03635    //   - probSum array of positions where quantiles will be computed.
03636    //     if probSum is null, probSum will be computed internally and will
03637    //     have a size = number of bins + 1 in h. it will correspond to the
03638    //      quantiles calculated at the lowest edge of the histogram (quantile=0) and
03639    //     all the upper edges of the bins.
03640    //     if probSum is not null, it is assumed to contain at least nprobSum values.
03641    //  output
03642    //   - return value nq (<=nprobSum) with the number of quantiles computed
03643    //   - array q filled with nq quantiles
03644    //
03645    //  Note that the Integral of the histogram is automatically recomputed
03646    //  if the number of entries is different of the number of entries when
03647    //  the integral was computed last time. In case you do not use the Fill
03648    //  functions to fill your histogram, but SetBinContent, you must call
03649    //  TH1::ComputeIntegral before calling this function.
03650    //
03651    //  Getting quantiles q from two histograms and storing results in a TGraph,
03652    //   a so-called QQ-plot
03653    //
03654    //     TGraph *gr = new TGraph(nprob);
03655    //     h1->GetQuantiles(nprob,gr->GetX());
03656    //     h2->GetQuantiles(nprob,gr->GetY());
03657    //     gr->Draw("alp");
03658    //
03659    // Example:
03660    //     void quantiles() {
03661    //        // demo for quantiles
03662    //        const Int_t nq = 20;
03663    //        TH1F *h = new TH1F("h","demo quantiles",100,-3,3);
03664    //        h->FillRandom("gaus",5000);
03665    //
03666    //        Double_t xq[nq];  // position where to compute the quantiles in [0,1]
03667    //        Double_t yq[nq];  // array to contain the quantiles
03668    //        for (Int_t i=0;i<nq;i++) xq[i] = Float_t(i+1)/nq;
03669    //        h->GetQuantiles(nq,yq,xq);
03670    //
03671    //        //show the original histogram in the top pad
03672    //        TCanvas *c1 = new TCanvas("c1","demo quantiles",10,10,700,900);
03673    //        c1->Divide(1,2);
03674    //        c1->cd(1);
03675    //        h->Draw();
03676    //
03677    //        // show the quantiles in the bottom pad
03678    //        c1->cd(2);
03679    //        gPad->SetGrid();
03680    //        TGraph *gr = new TGraph(nq,xq,yq);
03681    //        gr->SetMarkerStyle(21);
03682    //        gr->Draw("alp");
03683    //     }
03684 
03685    if (GetDimension() > 1) {
03686       Error("GetQuantiles","Only available for 1-d histograms");
03687       return 0;
03688    }
03689 
03690    const Int_t nbins = GetXaxis()->GetNbins();
03691    if (!fIntegral) ComputeIntegral();
03692    if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
03693 
03694    Int_t i, ibin;
03695    Double_t *prob = (Double_t*)probSum;
03696    Int_t nq = nprobSum;
03697    if (probSum == 0) {
03698       nq = nbins+1;
03699       prob = new Double_t[nq];
03700       prob[0] = 0;
03701       for (i=1;i<nq;i++) {
03702          prob[i] = fIntegral[i]/fIntegral[nbins];
03703       }
03704    }
03705 
03706    for (i = 0; i < nq; i++) {
03707       ibin = TMath::BinarySearch(nbins,fIntegral,prob[i]);
03708       while (ibin < nbins-1 && fIntegral[ibin+1] == prob[i]) {
03709          if (fIntegral[ibin+2] == prob[i]) ibin++;
03710          else break;
03711       }
03712       q[i] = GetBinLowEdge(ibin+1);
03713       const Double_t dint = fIntegral[ibin+1]-fIntegral[ibin];
03714       if (dint > 0) q[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
03715    }
03716 
03717    if (!probSum) delete [] prob;
03718    return nq;
03719 }
03720 
03721 //______________________________________________________________________________
03722 Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
03723 {
03724    //   -*-*-*-*-*-*-*Decode string choptin and fill fitOption structure*-*-*-*-*-*
03725    //                 ================================================
03726 
03727    if (choptin == 0) return 1;
03728    if (strlen(choptin) == 0) return 1;
03729    TString opt = choptin;
03730    opt.ToUpper();
03731    if (opt.Contains("Q"))  fitOption.Quiet   = 1;
03732    if (opt.Contains("V")) {fitOption.Verbose = 1; fitOption.Quiet = 0;}
03733    if (opt.Contains("X"))  fitOption.Chi2    = 1;
03734    if (opt.Contains("L"))  fitOption.Like    = 1;
03735    if (opt.Contains("LL")) fitOption.Like    = 2;
03736    if (opt.Contains("W"))  fitOption.W1      = 1;
03737    if (opt.Contains("WW")) fitOption.W1      = 2; //all bins have weight=1, even empty bins
03738    if (opt.Contains("E"))  fitOption.Errors  = 1;
03739    if (opt.Contains("M"))  fitOption.More    = 1;
03740    if (opt.Contains("R"))  fitOption.Range   = 1;
03741    if (opt.Contains("G"))  fitOption.Gradient= 1;
03742    if (opt.Contains("N"))  fitOption.Nostore = 1;
03743    if (opt.Contains("0"))  fitOption.Nograph = 1;
03744    if (opt.Contains("+"))  fitOption.Plus    = 1;
03745    if (opt.Contains("I"))  fitOption.Integral= 1;
03746    if (opt.Contains("B"))  fitOption.Bound   = 1;
03747    if (opt.Contains("U")) {fitOption.User    = 1; fitOption.Like = 0;}
03748    if (opt.Contains("F"))  fitOption.Minuit = 1;
03749    if (opt.Contains("C"))  fitOption.Nochisq = 1;
03750    if (opt.Contains("S"))  fitOption.StoreResult = 1;
03751    return 1;
03752 }
03753 
03754 //______________________________________________________________________________
03755 void H1InitGaus()
03756 {
03757    //   -*-*-*-*Compute Initial values of parameters for a gaussian*-*-*-*-*-*-*
03758    //           ===================================================
03759 
03760    Double_t allcha, sumx, sumx2, x, val, rms, mean;
03761    Int_t bin;
03762    const Double_t sqrtpi = 2.506628;
03763 
03764    //   - Compute mean value and RMS of the histogram in the given range
03765    TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
03766    TH1 *curHist = (TH1*)hFitter->GetObjectFit();
03767    Int_t hxfirst = hFitter->GetXfirst();
03768    Int_t hxlast  = hFitter->GetXlast();
03769    Double_t valmax  = curHist->GetBinContent(hxfirst);
03770    Double_t binwidx = curHist->GetBinWidth(hxfirst);
03771    allcha = sumx = sumx2 = 0;
03772    for (bin=hxfirst;bin<=hxlast;bin++) {
03773       x       = curHist->GetBinCenter(bin);
03774       val     = TMath::Abs(curHist->GetBinContent(bin));
03775       if (val > valmax) valmax = val;
03776       sumx   += val*x;
03777       sumx2  += val*x*x;
03778       allcha += val;
03779    }
03780    if (allcha == 0) return;
03781    mean = sumx/allcha;
03782    rms  = sumx2/allcha - mean*mean;
03783    if (rms > 0) rms  = TMath::Sqrt(rms);
03784    else         rms  = 0;
03785    if (rms == 0) rms = binwidx*(hxlast-hxfirst+1)/4;
03786    //if the distribution is really gaussian, the best approximation
03787    //is binwidx*allcha/(sqrtpi*rms)
03788    //However, in case of non-gaussian tails, this underestimates
03789    //the normalisation constant. In this case the maximum value
03790    //is a better approximation.
03791    //We take the average of both quantities
03792    Double_t constant = 0.5*(valmax+binwidx*allcha/(sqrtpi*rms));
03793 
03794    //In case the mean value is outside the histo limits and
03795    //the RMS is bigger than the range, we take
03796    //  mean = center of bins
03797    //  rms  = half range
03798    Double_t xmin = curHist->GetXaxis()->GetXmin();
03799    Double_t xmax = curHist->GetXaxis()->GetXmax();
03800    if ((mean < xmin || mean > xmax) && rms > (xmax-xmin)) {
03801       mean = 0.5*(xmax+xmin);
03802       rms  = 0.5*(xmax-xmin);
03803    }
03804    TF1 *f1 = (TF1*)hFitter->GetUserFunc();
03805    f1->SetParameter(0,constant);
03806    f1->SetParameter(1,mean);
03807    f1->SetParameter(2,rms);
03808    f1->SetParLimits(2,0,10*rms);
03809 }
03810 
03811 //______________________________________________________________________________
03812 void H1InitExpo()
03813 {
03814    //   -*-*-*-*Compute Initial values of parameters for an exponential*-*-*-*-*
03815    //           =======================================================
03816 
03817    Double_t constant, slope;
03818    Int_t ifail;
03819    TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
03820    Int_t hxfirst = hFitter->GetXfirst();
03821    Int_t hxlast  = hFitter->GetXlast();
03822    Int_t nchanx  = hxlast - hxfirst + 1;
03823 
03824    H1LeastSquareLinearFit(-nchanx, constant, slope, ifail);
03825 
03826    TF1 *f1 = (TF1*)hFitter->GetUserFunc();
03827    f1->SetParameter(0,constant);
03828    f1->SetParameter(1,slope);
03829 
03830 }
03831 
03832 //______________________________________________________________________________
03833 void H1InitPolynom()
03834 {
03835    //   -*-*-*-*Compute Initial values of parameters for a polynom*-*-*-*-*-*-*
03836    //           ===================================================
03837 
03838    Double_t fitpar[25];
03839 
03840    TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
03841    TF1 *f1 = (TF1*)hFitter->GetUserFunc();
03842    Int_t hxfirst = hFitter->GetXfirst();
03843    Int_t hxlast  = hFitter->GetXlast();
03844    Int_t nchanx  = hxlast - hxfirst + 1;
03845    Int_t npar    = f1->GetNpar();
03846 
03847    if (nchanx <=1 || npar == 1) {
03848       TH1 *curHist = (TH1*)hFitter->GetObjectFit();
03849       fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
03850    } else {
03851       H1LeastSquareFit( nchanx, npar, fitpar);
03852    }
03853    for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
03854 }
03855 
03856 //______________________________________________________________________________
03857 void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
03858 {
03859    //   -*-*-*-*-*-*Least squares lpolynomial fitting without weights*-*-*-*-*-*-*
03860    //               =================================================
03861    //
03862    //     n   number of points to fit
03863    //     m   number of parameters
03864    //     a   array of parameters
03865    //
03866    //      based on CERNLIB routine LSQ: Translated to C++ by Rene Brun
03867    //      (E.Keil.  revised by B.Schorr, 23.10.1981.)
03868    //
03869    //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03870    const Double_t zero = 0.;
03871    const Double_t one = 1.;
03872    const Int_t idim = 20;
03873 
03874    Double_t  b[400]        /* was [20][20] */;
03875    Int_t i, k, l, ifail;
03876    Double_t power;
03877    Double_t da[20], xk, yk;
03878 
03879    if (m <= 2) {
03880       H1LeastSquareLinearFit(n, a[0], a[1], ifail);
03881       return;
03882    }
03883    if (m > idim || m > n) return;
03884    b[0]  = Double_t(n);
03885    da[0] = zero;
03886    for (l = 2; l <= m; ++l) {
03887       b[l-1]           = zero;
03888       b[m + l*20 - 21] = zero;
03889       da[l-1]          = zero;
03890    }
03891    TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
03892    TH1 *curHist  = (TH1*)hFitter->GetObjectFit();
03893    Int_t hxfirst = hFitter->GetXfirst();
03894    Int_t hxlast  = hFitter->GetXlast();
03895    for (k = hxfirst; k <= hxlast; ++k) {
03896       xk     = curHist->GetBinCenter(k);
03897       yk     = curHist->GetBinContent(k);
03898       power  = one;
03899       da[0] += yk;
03900       for (l = 2; l <= m; ++l) {
03901          power   *= xk;
03902          b[l-1]  += power;
03903          da[l-1] += power*yk;
03904       }
03905       for (l = 2; l <= m; ++l) {
03906          power            *= xk;
03907          b[m + l*20 - 21] += power;
03908       }
03909    }
03910    for (i = 3; i <= m; ++i) {
03911       for (k = i; k <= m; ++k) {
03912          b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
03913       }
03914    }
03915    H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
03916 
03917    for (i=0; i<m; ++i) a[i] = da[i];
03918 
03919 }
03920 
03921 //______________________________________________________________________________
03922 void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
03923 {
03924    //   -*-*-*-*-*-*-*-*Least square linear fit without weights*-*-*-*-*-*-*-*-*
03925    //                   =======================================
03926    //
03927    //      extracted from CERNLIB LLSQ: Translated to C++ by Rene Brun
03928    //      (added to LSQ by B. Schorr, 15.02.1982.)
03929    //
03930    //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03931 
03932    Double_t xbar, ybar, x2bar;
03933    Int_t i, n;
03934    Double_t xybar;
03935    Double_t fn, xk, yk;
03936    Double_t det;
03937 
03938    n     = TMath::Abs(ndata);
03939    ifail = -2;
03940    xbar  = ybar  = x2bar = xybar = 0;
03941    TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
03942    TH1 *curHist  = (TH1*)hFitter->GetObjectFit();
03943    Int_t hxfirst = hFitter->GetXfirst();
03944    Int_t hxlast  = hFitter->GetXlast();
03945    for (i = hxfirst; i <= hxlast; ++i) {
03946       xk = curHist->GetBinCenter(i);
03947       yk = curHist->GetBinContent(i);
03948       if (ndata < 0) {
03949          if (yk <= 0) yk = 1e-9;
03950          yk = TMath::Log(yk);
03951       }
03952       xbar  += xk;
03953       ybar  += yk;
03954       x2bar += xk*xk;
03955       xybar += xk*yk;
03956    }
03957    fn    = Double_t(n);
03958    det   = fn*x2bar - xbar*xbar;
03959    ifail = -1;
03960    if (det <= 0) {
03961       a0 = ybar/fn;
03962       a1 = 0;
03963       return;
03964    }
03965    ifail = 0;
03966    a0 = (x2bar*ybar - xbar*xybar) / det;
03967    a1 = (fn*xybar - xbar*ybar) / det;
03968 
03969 }
03970 
03971 //______________________________________________________________________________
03972 void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b)
03973 {
03974    //   -*-*-*-*-*-*Extracted from CERN Program library routine DSEQN*-*-*-*-*-*
03975    //               =================================================
03976    //
03977    //           : Translated to C++ by Rene Brun
03978    //
03979    //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
03980    Int_t a_dim1, a_offset, b_dim1, b_offset;
03981    Int_t nmjp1, i, j, l;
03982    Int_t im1, jp1, nm1, nmi;
03983    Double_t s1, s21, s22;
03984    const Double_t one = 1.;
03985 
03986    /* Parameter adjustments */
03987    b_dim1 = idim;
03988    b_offset = b_dim1 + 1;
03989    b -= b_offset;
03990    a_dim1 = idim;
03991    a_offset = a_dim1 + 1;
03992    a -= a_offset;
03993 
03994    if (idim < n) return;
03995 
03996    ifail = 0;
03997    for (j = 1; j <= n; ++j) {
03998       if (a[j + j*a_dim1] <= 0) { ifail = -1; return; }
03999       a[j + j*a_dim1] = one / a[j + j*a_dim1];
04000       if (j == n) continue;
04001       jp1 = j + 1;
04002       for (l = jp1; l <= n; ++l) {
04003          a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
04004          s1 = -a[l + (j+1)*a_dim1];
04005          for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
04006          a[l + (j+1)*a_dim1] = -s1;
04007       }
04008    }
04009    if (k <= 0) return;
04010 
04011    for (l = 1; l <= k; ++l) {
04012       b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
04013    }
04014    if (n == 1) return;
04015    for (l = 1; l <= k; ++l) {
04016       for (i = 2; i <= n; ++i) {
04017          im1 = i - 1;
04018          s21 = -b[i + l*b_dim1];
04019          for (j = 1; j <= im1; ++j) {
04020             s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
04021          }
04022          b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
04023       }
04024       nm1 = n - 1;
04025       for (i = 1; i <= nm1; ++i) {
04026          nmi = n - i;
04027          s22 = -b[nmi + l*b_dim1];
04028          for (j = 1; j <= i; ++j) {
04029             nmjp1 = n - j + 1;
04030             s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
04031          }
04032          b[nmi + l*b_dim1] = -s22;
04033       }
04034    }
04035 }
04036 
04037 
04038 //______________________________________________________________________________
04039 Int_t TH1::GetBin(Int_t binx, Int_t biny, Int_t binz) const
04040 {
04041    //   -*-*-*-*Return Global bin number corresponding to binx,y,z*-*-*-*-*-*-*
04042    //           ==================================================
04043    //
04044    //      2-D and 3-D histograms are represented with a one dimensional
04045    //      structure.
04046    //      This has the advantage that all existing functions, such as
04047    //        GetBinContent, GetBinError, GetBinFunction work for all dimensions.
04048    //
04049    //     In case of a TH1x, returns binx directly.
04050    //     see TH1::GetBinXYZ for the inverse transformation.
04051    //
04052    //      Convention for numbering bins
04053    //      =============================
04054    //      For all histogram types: nbins, xlow, xup
04055    //        bin = 0;       underflow bin
04056    //        bin = 1;       first bin with low-edge xlow INCLUDED
04057    //        bin = nbins;   last bin with upper-edge xup EXCLUDED
04058    //        bin = nbins+1; overflow bin
04059    //      In case of 2-D or 3-D histograms, a "global bin" number is defined.
04060    //      For example, assuming a 3-D histogram with binx,biny,binz, the function
04061    //        Int_t bin = h->GetBin(binx,biny,binz);
04062    //      returns a global/linearized bin number. This global bin is useful
04063    //      to access the bin information independently of the dimension.
04064    //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
04065    Int_t nx, ny, nz;
04066    if (GetDimension() < 2) {
04067       nx  = fXaxis.GetNbins()+2;
04068       if (binx < 0)   binx = 0;
04069       if (binx >= nx) binx = nx-1;
04070       return binx;
04071    }
04072    if (GetDimension() < 3) {
04073       nx  = fXaxis.GetNbins()+2;
04074       if (binx < 0)   binx = 0;
04075       if (binx >= nx) binx = nx-1;
04076       ny  = fYaxis.GetNbins()+2;
04077       if (biny < 0)   biny = 0;
04078       if (biny >= ny) biny = ny-1;
04079       return  binx + nx*biny;
04080    }
04081    if (GetDimension() < 4) {
04082       nx  = fXaxis.GetNbins()+2;
04083       if (binx < 0)   binx = 0;
04084       if (binx >= nx) binx = nx-1;
04085       ny  = fYaxis.GetNbins()+2;
04086       if (biny < 0)   biny = 0;
04087       if (biny >= ny) biny = ny-1;
04088       nz  = fZaxis.GetNbins()+2;
04089       if (binz < 0)   binz = 0;
04090       if (binz >= nz) binz = nz-1;
04091       return  binx + nx*(biny +ny*binz);
04092    }
04093    return -1;
04094 }
04095 //______________________________________________________________________________
04096 void TH1::GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz) const
04097 {
04098    // return binx, biny, binz corresponding to the global bin number globalbin
04099    // see TH1::GetBin function above
04100 
04101    Int_t nx  = fXaxis.GetNbins()+2;
04102    Int_t ny  = fYaxis.GetNbins()+2;
04103 
04104    if (GetDimension() < 2) {
04105       binx = binglobal%nx;
04106    }
04107    if (GetDimension() < 3) {
04108       binx = binglobal%nx;
04109       biny = ((binglobal-binx)/nx)%ny;
04110    }
04111    if (GetDimension() < 4) {
04112       binx = binglobal%nx;
04113       biny = ((binglobal-binx)/nx)%ny;
04114       binz = ((binglobal-binx)/nx -biny)/ny;
04115    }
04116 }
04117 
04118 
04119 //______________________________________________________________________________
04120 Double_t TH1::GetRandom() const
04121 {
04122    // return a random number distributed according the histogram bin contents.
04123    // This function checks if the bins integral exists. If not, the integral
04124    // is evaluated, normalized to one.
04125    // The integral is automatically recomputed if the number of entries
04126    // is not the same then when the integral was computed.
04127    // NB Only valid for 1-d histograms. Use GetRandom2 or 3 otherwise.
04128 
04129    if (fDimension > 1) {
04130       Error("GetRandom","Function only valid for 1-d histograms");
04131       return 0;
04132    }
04133    Int_t nbinsx = GetNbinsX();
04134    Double_t integral;
04135    if (fIntegral) {
04136       if (fIntegral[nbinsx+1] != fEntries) integral = ((TH1*)this)->ComputeIntegral();
04137    } else {
04138       integral = ((TH1*)this)->ComputeIntegral();
04139       if (integral == 0 || fIntegral == 0) return 0;
04140    }
04141    Double_t r1 = gRandom->Rndm();
04142    Int_t ibin = TMath::BinarySearch(nbinsx,fIntegral,r1);
04143    Double_t x = GetBinLowEdge(ibin+1);
04144    if (r1 > fIntegral[ibin]) x +=
04145       GetBinWidth(ibin+1)*(r1-fIntegral[ibin])/(fIntegral[ibin+1] - fIntegral[ibin]);
04146    return x;
04147 }
04148 
04149 //______________________________________________________________________________
04150 Double_t TH1::GetBinContent(Int_t) const
04151 {
04152    //   -*-*-*-*-*Return content of bin number bin
04153    //             ================================
04154    // Implemented in TH1C,S,F,D
04155    //
04156    //      Convention for numbering bins
04157    //      =============================
04158    //      For all histogram types: nbins, xlow, xup
04159    //        bin = 0;       underflow bin
04160    //        bin = 1;       first bin with low-edge xlow INCLUDED
04161    //        bin = nbins;   last bin with upper-edge xup EXCLUDED
04162    //        bin = nbins+1; overflow bin
04163    //      In case of 2-D or 3-D histograms, a "global bin" number is defined.
04164    //      For example, assuming a 3-D histogram with binx,biny,binz, the function
04165    //        Int_t bin = h->GetBin(binx,biny,binz);
04166    //      returns a global/linearized bin number. This global bin is useful
04167    //      to access the bin information independently of the dimension.
04168 
04169    AbstractMethod("GetBinContent");
04170    return 0;
04171 }
04172 
04173 //______________________________________________________________________________
04174 Double_t TH1::GetBinContent(Int_t binx, Int_t biny) const
04175 {
04176    //   -*-*-*-*-*Return content of bin number binx, biny
04177    //             =======================================
04178    // NB: Function to be called for 2-D histograms only
04179    // see convention for numbering bins in TH1::GetBin
04180 
04181    Int_t bin = GetBin(binx,biny);
04182    return GetBinContent(bin);
04183 }
04184 
04185 //______________________________________________________________________________
04186 Double_t TH1::GetBinContent(Int_t binx, Int_t biny, Int_t binz) const
04187 {
04188    //   -*-*-*-*-*Return content of bin number binx,biny,binz
04189    //             ===========================================
04190    // NB: Function to be called for 3-D histograms only
04191    // see convention for numbering bins in TH1::GetBin
04192 
04193    Int_t bin = GetBin(binx,biny,binz);
04194    return GetBinContent(bin);
04195 }
04196 
04197 //______________________________________________________________________________
04198 Double_t TH1::GetBinWithContent(Double_t c, Int_t &binx, Int_t firstx, Int_t lastx,Double_t maxdiff) const
04199 {
04200    // compute first binx in the range [firstx,lastx] for which
04201    // diff = abs(bin_content-c) <= maxdiff
04202    // In case several bins in the specified range with diff=0 are found
04203    // the first bin found is returned in binx.
04204    // In case several bins in the specified range satisfy diff <=maxdiff
04205    // the bin with the smallest difference is returned in binx.
04206    // In all cases the function returns the smallest difference.
04207    //
04208    // NOTE1: if firstx <= 0, firstx is set to bin 1
04209    //        if (lastx < firstx then firstx is set to the number of bins
04210    //        ie if firstx=0 and lastx=0 (default) the search is on all bins.
04211    // NOTE2: if maxdiff=0 (default), the first bin with content=c is returned.
04212 
04213    if (fDimension > 1) {
04214       binx = 0;
04215       Error("GetBinWithContent","function is only valid for 1-D histograms");
04216       return 0;
04217    }
04218    if (firstx <= 0) firstx = 1;
04219    if (lastx < firstx) lastx = fXaxis.GetNbins();
04220    Int_t binminx = 0;
04221    Double_t diff, curmax = 1.e240;
04222    for (Int_t i=firstx;i<=lastx;i++) {
04223       diff = TMath::Abs(GetBinContent(i)-c);
04224       if (diff <= 0) {binx = i; return diff;}
04225       if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
04226    }
04227    binx = binminx;
04228    return curmax;
04229 }
04230 
04231 //______________________________________________________________________________
04232 TAxis *TH1::GetXaxis() const
04233 {
04234    // return a pointer to the X axis object
04235 
04236    return &((TH1*)this)->fXaxis;
04237 }
04238 
04239 
04240 //______________________________________________________________________________
04241 TAxis *TH1::GetYaxis() const
04242 {
04243    // return a pointer to the Y axis object
04244 
04245    return &((TH1*)this)->fYaxis;
04246 }
04247 //______________________________________________________________________________
04248 TAxis *TH1::GetZaxis() const
04249 {
04250    // return a pointer to the Z axis object
04251 
04252    return &((TH1*)this)->fZaxis;
04253 }
04254 
04255 //______________________________________________________________________________
04256 Double_t TH1::Interpolate(Double_t x)
04257 {
04258    // Given a point x, approximates the value via linear interpolation
04259    // based on the two nearest bin centers
04260    // Andy Mastbaum 10/21/08
04261 
04262    Int_t xbin = FindBin(x);
04263    Double_t x0,x1,y0,y1;
04264 
04265    if(x<=GetBinCenter(1)) {
04266       return GetBinContent(1);
04267    } else if(x>=GetBinCenter(GetNbinsX())) {
04268       return GetBinContent(GetNbinsX());
04269    } else {
04270       if(x<=GetBinCenter(xbin)) {
04271          y0 = GetBinContent(xbin-1);
04272          x0 = GetBinCenter(xbin-1);
04273          y1 = GetBinContent(xbin);
04274          x1 = GetBinCenter(xbin);
04275       } else {
04276          y0 = GetBinContent(xbin);
04277          x0 = GetBinCenter(xbin);
04278          y1 = GetBinContent(xbin+1);
04279          x1 = GetBinCenter(xbin+1);
04280       }
04281       return y0 + (x-x0)*((y1-y0)/(x1-x0));
04282    }
04283 }
04284 
04285 //______________________________________________________________________________
04286 Double_t TH1::Interpolate(Double_t, Double_t)
04287 {
04288 
04289    //Not yet implemented
04290    Error("Interpolate","This function must be called with 1 argument for a TH1");
04291    return 0;
04292 }
04293 
04294 //______________________________________________________________________________
04295 Double_t TH1::Interpolate(Double_t, Double_t, Double_t)
04296 {
04297 
04298    //Not yet implemented
04299    Error("Interpolate","This function must be called with 1 argument for a TH1");
04300    return 0;
04301 }
04302 
04303 //______________________________________________________________________________
04304 Bool_t TH1::IsBinOverflow(Int_t bin) const
04305 {
04306 
04307    // Return true if the bin is overflow.
04308    Int_t binx, biny, binz;
04309    GetBinXYZ(bin, binx, biny, binz);
04310 
04311    if ( fDimension == 1 )
04312       return binx >= GetNbinsX() + 1;
04313    else if ( fDimension == 2 )
04314       return (binx >= GetNbinsX() + 1) ||
04315              (biny >= GetNbinsY() + 1);
04316    else if ( fDimension == 3 )
04317       return (binx >= GetNbinsX() + 1) ||
04318              (biny >= GetNbinsY() + 1) ||
04319              (binz >= GetNbinsZ() + 1);
04320    else
04321       return 0;
04322 }
04323 
04324 
04325 //______________________________________________________________________________
04326 Bool_t TH1::IsBinUnderflow(Int_t bin) const
04327 {
04328 
04329    // Return true if the bin is overflow.
04330    Int_t binx, biny, binz;
04331    GetBinXYZ(bin, binx, biny, binz);
04332 
04333    if ( fDimension == 1 )
04334       return (binx <= 0);
04335    else if ( fDimension == 2 )
04336       return (binx <= 0 || biny <= 0);
04337    else if ( fDimension == 3 )
04338       return (binx <= 0 || biny <= 0 || binz <= 0);
04339    else
04340       return 0;
04341 }
04342 
04343 //___________________________________________________________________________
04344 void TH1::LabelsDeflate(Option_t *ax)
04345 {
04346    // Reduce the number of bins for this axis to the number of bins having a label.
04347 
04348    Int_t iaxis = AxisChoice(ax);
04349    TAxis *axis = 0;
04350    if (iaxis == 1) axis = GetXaxis();
04351    if (iaxis == 2) axis = GetYaxis();
04352    if (iaxis == 3) axis = GetZaxis();
04353    if (!axis) return;
04354    if (!axis->GetLabels()) return;
04355    TIter next(axis->GetLabels());
04356    TObject *obj;
04357    Int_t nbins = 0;
04358    while ((obj = next())) {
04359       if (obj->GetUniqueID()) nbins++;
04360    }
04361    if (nbins < 1) nbins = 1;
04362    TH1 *hold = (TH1*)Clone();
04363    hold->SetDirectory(0);
04364 
04365    Bool_t timedisp = axis->GetTimeDisplay();
04366    Double_t xmin = axis->GetXmin();
04367    Double_t xmax = axis->GetBinUpEdge(nbins);
04368    if (xmax <= xmin) xmax = xmin +nbins;
04369    axis->SetRange(0,0);
04370    axis->Set(nbins,xmin,xmax);
04371    //Int_t  nbinsx = fXaxis.GetNbins();
04372    //Int_t  nbinsy = fYaxis.GetNbins();
04373    //Int_t  nbinsz = fZaxis.GetNbins();
04374    Int_t  nbinsx = hold->GetXaxis()->GetNbins();
04375    Int_t  nbinsy = hold->GetYaxis()->GetNbins();
04376    Int_t  nbinsz = hold->GetZaxis()->GetNbins();
04377    Int_t ncells = nbinsx+2;
04378    if (GetDimension() > 1) ncells *= nbinsy+2;
04379    if (GetDimension() > 2) ncells *= nbinsz+2;
04380    SetBinsLength(ncells);
04381    Int_t errors = fSumw2.fN;
04382    if (errors) fSumw2.Set(ncells);
04383    axis->SetTimeDisplay(timedisp);
04384 
04385    //now loop on all bins and refill
04386    Double_t err,cu;
04387    Int_t bin,ibin,binx,biny,binz;
04388    Double_t oldEntries = fEntries;
04389    for (binz=1;binz<=nbinsz;binz++) {
04390       for (biny=1;biny<=nbinsy;biny++) {
04391          for (binx=1;binx<=nbinsx;binx++) {
04392             bin = hold->GetBin(binx,biny,binz);
04393             ibin= GetBin(binx,biny,binz);
04394             cu  = hold->GetBinContent(bin);
04395             SetBinContent(ibin,cu);
04396             if (errors) {
04397                err = hold->GetBinError(bin);
04398                SetBinError(ibin,err);
04399             }
04400          }
04401       }
04402    }
04403    fEntries = oldEntries;
04404    delete hold;
04405 }
04406 
04407 //______________________________________________________________________________
04408 void TH1::LabelsInflate(Option_t *ax)
04409 {
04410    // Double the number of bins for axis.
04411    // Refill histogram
04412    // This function is called by TAxis::FindBin(const char *label)
04413 
04414    Int_t iaxis = AxisChoice(ax);
04415    TAxis *axis = 0;
04416    if (iaxis == 1) axis = GetXaxis();
04417    if (iaxis == 2) axis = GetYaxis();
04418    if (iaxis == 3) axis = GetZaxis();
04419    if (!axis) return;
04420 
04421    TH1 *hold = (TH1*)Clone();
04422    hold->SetDirectory(0);
04423 
04424    Bool_t timedisp = axis->GetTimeDisplay();
04425    Int_t  nbxold = fXaxis.GetNbins();
04426    Int_t  nbyold = fYaxis.GetNbins();
04427    Int_t  nbzold = fZaxis.GetNbins();
04428    Int_t nbins   = axis->GetNbins();
04429    Double_t xmin = axis->GetXmin();
04430    Double_t xmax = axis->GetXmax();
04431    xmax = xmin + 2*(xmax-xmin);
04432    axis->SetRange(0,0);
04433    axis->Set(2*nbins,xmin,xmax);
04434    Int_t  nbinsx = fXaxis.GetNbins();
04435    Int_t  nbinsy = fYaxis.GetNbins();
04436    Int_t  nbinsz = fZaxis.GetNbins();
04437    Int_t ncells = nbinsx+2;
04438    if (GetDimension() > 1) ncells *= nbinsy+2;
04439    if (GetDimension() > 2) ncells *= nbinsz+2;
04440    SetBinsLength(ncells);
04441    Int_t errors = fSumw2.fN;
04442    if (errors) fSumw2.Set(ncells);
04443    axis->SetTimeDisplay(timedisp);
04444 
04445    //now loop on all bins and refill
04446    Double_t err,cu;
04447    Double_t oldEntries = fEntries;
04448    Int_t bin,ibin,binx,biny,binz;
04449    Int_t binxmin = 1;
04450    Int_t binxmax = nbinsx;
04451    if (fDimension > 1) {binxmin--; binxmax++;}
04452    for (binz=1;binz<=nbinsz;binz++) {
04453       for (biny=1;biny<=nbinsy;biny++) {
04454          for (binx=binxmin;binx<=binxmax;binx++) {
04455             bin = hold->GetBin(binx,biny,binz);
04456             ibin= GetBin(binx,biny,binz);
04457             if (binx > nbxold+1 || biny > nbyold || binz > nbzold) bin = -1;
04458             if (bin > 0) cu  = hold->GetBinContent(bin);
04459             else         cu = 0;
04460             SetBinContent(ibin,cu);
04461             if (errors) {
04462                if (bin > 0) err = hold->GetBinError(bin);
04463                else         err = 0;
04464                SetBinError(ibin,err);
04465             }
04466          }
04467       }
04468    }
04469    fEntries = oldEntries;
04470    delete hold;
04471 }
04472 
04473 //______________________________________________________________________________
04474 void TH1::LabelsOption(Option_t *option, Option_t *ax)
04475 {
04476    //  Set option(s) to draw axis with labels
04477    //  option = "a" sort by alphabetic order
04478    //         = ">" sort by decreasing values
04479    //         = "<" sort by increasing values
04480    //         = "h" draw labels horizonthal
04481    //         = "v" draw labels vertical
04482    //         = "u" draw labels up (end of label right adjusted)
04483    //         = "d" draw labels down (start of label left adjusted)
04484 
04485    Int_t iaxis = AxisChoice(ax);
04486    TAxis *axis = 0;
04487    if (iaxis == 1) axis = GetXaxis();
04488    if (iaxis == 2) axis = GetYaxis();
04489    if (iaxis == 3) axis = GetZaxis();
04490    if (!axis) return;
04491    THashList *labels = axis->GetLabels();
04492    if (!labels) {
04493       Warning("LabelsOption","Cannot sort. No labels");
04494       return;
04495    }
04496    TString opt = option;
04497    opt.ToLower();
04498    if (opt.Contains("h")) {
04499       axis->SetBit(TAxis::kLabelsHori);
04500       axis->ResetBit(TAxis::kLabelsVert);
04501       axis->ResetBit(TAxis::kLabelsDown);
04502       axis->ResetBit(TAxis::kLabelsUp);
04503    }
04504    if (opt.Contains("v")) {
04505       axis->SetBit(TAxis::kLabelsVert);
04506       axis->ResetBit(TAxis::kLabelsHori);
04507       axis->ResetBit(TAxis::kLabelsDown);
04508       axis->ResetBit(TAxis::kLabelsUp);
04509    }
04510    if (opt.Contains("u")) {
04511       axis->SetBit(TAxis::kLabelsUp);
04512       axis->ResetBit(TAxis::kLabelsVert);
04513       axis->ResetBit(TAxis::kLabelsDown);
04514       axis->ResetBit(TAxis::kLabelsHori);
04515    }
04516    if (opt.Contains("d")) {
04517       axis->SetBit(TAxis::kLabelsDown);
04518       axis->ResetBit(TAxis::kLabelsVert);
04519       axis->ResetBit(TAxis::kLabelsHori);
04520       axis->ResetBit(TAxis::kLabelsUp);
04521    }
04522    Int_t sort = -1;
04523    if (opt.Contains("a")) sort = 0;
04524    if (opt.Contains(">")) sort = 1;
04525    if (opt.Contains("<")) sort = 2;
04526    if (sort < 0) return;
04527    if (sort > 0 && GetDimension() > 2) {
04528       Error("LabelsOption","Sorting by value not implemented for 3-D histograms");
04529       return;
04530    }
04531 
04532    Double_t entries = fEntries;
04533    Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
04534    Int_t *a = new Int_t[n+2];
04535    Int_t i,j,k;
04536    Double_t *cont   = 0;
04537    Double_t *errors = 0;
04538    THashList *labold = new THashList(labels->GetSize(),1);
04539    TIter nextold(labels);
04540    TObject *obj;
04541    while ((obj=nextold())) {
04542       labold->Add(obj);
04543    }
04544    labels->Clear();
04545    if (sort > 0) {
04546       //---sort by values of bins
04547       if (GetDimension() == 1) {
04548          cont = new Double_t[n];
04549          if (fSumw2.fN) errors = new Double_t[n];
04550          for (i=1;i<=n;i++) {
04551             cont[i-1] = GetBinContent(i);
04552             if (errors) errors[i-1] = GetBinError(i);
04553          }
04554          if (sort ==1) TMath::Sort(n,cont,a,kTRUE);  //sort by decreasing values
04555          else          TMath::Sort(n,cont,a,kFALSE); //sort by increasing values
04556          for (i=1;i<=n;i++) {
04557             SetBinContent(i,cont[a[i-1]]);
04558             if (errors) SetBinError(i,errors[a[i-1]]);
04559          }
04560          for (i=1;i<=n;i++) {
04561             obj = labold->At(a[i-1]);
04562             labels->Add(obj);
04563             obj->SetUniqueID(i);
04564          }
04565       } else if (GetDimension()== 2) {
04566          Double_t *pcont = new Double_t[n+2];
04567          for (i=0;i<=n;i++) pcont[i] = 0;
04568          Int_t nx = fXaxis.GetNbins();
04569          Int_t ny = fYaxis.GetNbins();
04570          cont = new Double_t[(nx+2)*(ny+2)];
04571          if (fSumw2.fN) errors = new Double_t[n];
04572          for (i=1;i<=nx;i++) {
04573             for (j=1;j<=ny;j++) {
04574                cont[i+nx*j] = GetBinContent(i,j);
04575                if (errors) errors[i+nx*j] = GetBinError(i,j);
04576                if (axis == GetXaxis()) k = i;
04577                else                    k = j;
04578                pcont[k-1] += cont[i+nx*j];
04579             }
04580          }
04581          if (sort ==1) TMath::Sort(n,pcont,a,kTRUE);  //sort by decreasing values
04582          else          TMath::Sort(n,pcont,a,kFALSE); //sort by increasing values
04583          for (i=0;i<n;i++) {
04584             obj = labold->At(a[i]);
04585             labels->Add(obj);
04586             obj->SetUniqueID(i+1);
04587          }
04588          delete [] pcont;
04589          for (i=1;i<=nx;i++) {
04590             for (j=1;j<=ny;j++) {
04591                if (axis == GetXaxis()) {
04592                   SetBinContent(i,j,cont[a[i-1]+1+nx*j]);
04593                   if (errors) SetBinError(i,j,errors[a[i-1]+1+nx*j]);
04594                } else {
04595                   SetBinContent(i,j,cont[i+nx*(a[j-1]+1)]);
04596                   if (errors) SetBinError(i,j,errors[i+nx*(a[j-1]+1)]);
04597                }
04598             }
04599          }
04600       } else {
04601          //to be implemented
04602       }
04603    } else {
04604       //---alphabetic sort
04605       const UInt_t kUsed = 1<<18;
04606       TObject *objk=0;
04607       a[0] = 0;
04608       a[n+1] = n+1;
04609       for (i=1;i<=n;i++) {
04610          const char *label = "zzzzzzzzzzzz";
04611          for (j=1;j<=n;j++) {
04612             obj = labold->At(j-1);
04613             if (!obj) continue;
04614             if (obj->TestBit(kUsed)) continue;
04615             //use strcasecmp for case non-sensitive sort (may be an option)
04616             if (strcmp(label,obj->GetName()) < 0) continue;
04617             objk = obj;
04618             a[i] = j;
04619             label = obj->GetName();
04620          }
04621          if (objk) {
04622             objk->SetUniqueID(i);
04623             labels->Add(objk);
04624             objk->SetBit(kUsed);
04625          }
04626       }
04627       for (i=1;i<=n;i++) {
04628          obj = labels->At(i-1);
04629          if (!obj) continue;
04630          obj->ResetBit(kUsed);
04631       }
04632 
04633       if (GetDimension() == 1) {
04634          cont = new Double_t[n+2];
04635          if (fSumw2.fN) errors = new Double_t[n+2];
04636          for (i=1;i<=n;i++) {
04637             cont[i] = GetBinContent(a[i]);
04638             if (errors) errors[i] = GetBinError(a[i]);
04639          }
04640          for (i=1;i<=n;i++) {
04641             SetBinContent(i,cont[i]);
04642             if (errors) SetBinError(i,errors[i]);
04643          }
04644       } else if (GetDimension()== 2) {
04645          Int_t nx = fXaxis.GetNbins()+2;
04646          Int_t ny = fYaxis.GetNbins()+2;
04647          cont = new Double_t[nx*ny];
04648          if (fSumw2.fN) errors = new Double_t[nx*ny];
04649          for (i=0;i<nx;i++) {
04650             for (j=0;j<ny;j++) {
04651                cont[i+nx*j] = GetBinContent(i,j);
04652                if (errors) errors[i+nx*j] = GetBinError(i,j);
04653             }
04654          }
04655          for (i=0;i<nx;i++) {
04656             for (j=0;j<ny;j++) {
04657                if (axis == GetXaxis()) {
04658                   SetBinContent(i,j,cont[a[i]+nx*j]);
04659                   if (errors) SetBinError(i,j,errors[a[i]+nx*j]);
04660                } else {
04661                   SetBinContent(i,j,cont[i+nx*a[j]]);
04662                   if (errors) SetBinError(i,j,errors[i+nx*a[j]]);
04663                }
04664             }
04665          }
04666       } else {
04667          Int_t nx = fXaxis.GetNbins()+2;
04668          Int_t ny = fYaxis.GetNbins()+2;
04669          Int_t nz = fZaxis.GetNbins()+2;
04670          cont = new Double_t[nx*ny*nz];
04671          if (fSumw2.fN) errors = new Double_t[nx*ny*nz];
04672          for (i=0;i<nx;i++) {
04673             for (j=0;j<ny;j++) {
04674                for (k=0;k<nz;k++) {
04675                   cont[i+nx*(j+ny*k)] = GetBinContent(i,j,k);
04676                   if (errors) errors[i+nx*(j+ny*k)] = GetBinError(i,j,k);
04677                }
04678             }
04679          }
04680          for (i=0;i<nx;i++) {
04681             for (j=0;j<ny;j++) {
04682                for (k=0;k<nz;k++) {
04683                   if (axis == GetXaxis()) {
04684                      SetBinContent(i,j,k,cont[a[i]+nx*(j+ny*k)]);
04685                      if (errors) SetBinError(i,j,k,errors[a[i]+nx*(j+ny*k)]);
04686                   } else if (axis == GetYaxis()) {
04687                      SetBinContent(i,j,k,cont[i+nx*(a[j]+ny*k)]);
04688                      if (errors) SetBinError(i,j,k,errors[i+nx*(a[j]+ny*k)]);
04689                   } else {
04690                      SetBinContent(i,j,k,cont[i+nx*(j+ny*a[k])]);
04691                      if (errors) SetBinError(i,j,k,errors[i+nx*(j+ny*a[k])]);
04692                   }
04693                }
04694             }
04695          }
04696       }
04697    }
04698    fEntries = entries;
04699    delete labold;
04700    if (a)      delete [] a;
04701    if (cont)   delete [] cont;
04702    if (errors) delete [] errors;
04703 }
04704 
04705 //______________________________________________________________________________
04706 static Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
04707 {
04708    return TMath::Abs(a - b) < epsilon;
04709 }
04710 
04711 //______________________________________________________________________________
04712 static Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
04713 {
04714    return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
04715       AlmostEqual(a - TMath::Floor(a), 1, epsilon);
04716 }
04717 
04718 //______________________________________________________________________________
04719 Bool_t TH1::SameLimitsAndNBins(const TAxis& axis1, const TAxis& axis2)
04720 {
04721    // Same limits and bins.
04722 
04723    if ((axis1.GetNbins() == axis2.GetNbins())
04724       && (axis1.GetXmin() == axis2.GetXmin())
04725       && (axis1.GetXmax() == axis2.GetXmax()))
04726       return kTRUE;
04727    else
04728       return kFALSE;
04729 }
04730 
04731 //______________________________________________________________________________
04732 Bool_t TH1::RecomputeAxisLimits(TAxis& destAxis, const TAxis& anAxis)
04733 {
04734    // Finds new limits for the axis for the Merge function.
04735    // returns false if the limits are incompatible
04736    if (SameLimitsAndNBins(destAxis, anAxis))
04737       return kTRUE;
04738 
04739    if (destAxis.GetXbins()->fN || anAxis.GetXbins()->fN)
04740       return kFALSE;       // user binning not supported
04741 
04742    Double_t width1 = destAxis.GetBinWidth(0);
04743    Double_t width2 = anAxis.GetBinWidth(0);
04744    if (width1 == 0 || width2 == 0)
04745       return kFALSE;       // no binning not supported
04746 
04747    Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
04748    Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
04749    Double_t width = TMath::Max(width1, width2);
04750 
04751    // check the bin size
04752    if (!AlmostInteger(width/width1) || !AlmostInteger(width/width2))
04753       return kFALSE;
04754 
04755    // check the limits
04756    Double_t delta;
04757    delta = (destAxis.GetXmin() - xmin)/width1;
04758    if (!AlmostInteger(delta))
04759       xmin -= (TMath::Ceil(delta) - delta)*width1;
04760 
04761    delta = (anAxis.GetXmin() - xmin)/width2;
04762    if (!AlmostInteger(delta))
04763       xmin -= (TMath::Ceil(delta) - delta)*width2;
04764 
04765    delta = (destAxis.GetXmin() - xmin)/width1;
04766    if (!AlmostInteger(delta))
04767       return kFALSE;
04768 
04769    delta = (xmax - destAxis.GetXmax())/width1;
04770    if (!AlmostInteger(delta))
04771       xmax += (TMath::Ceil(delta) - delta)*width1;
04772 
04773    delta = (xmax - anAxis.GetXmax())/width2;
04774    if (!AlmostInteger(delta))
04775       xmax += (TMath::Ceil(delta) - delta)*width2;
04776 
04777    delta = (xmax - destAxis.GetXmax())/width1;
04778    if (!AlmostInteger(delta))
04779       return kFALSE;
04780 #ifdef DEBUG
04781    if (!AlmostInteger((xmax - xmin) / width)) {   // unnecessary check
04782       printf("TH1::RecomputeAxisLimits - Impossible\n");
04783       return kFALSE;
04784    }
04785 #endif
04786    destAxis.Set(TMath::Nint((xmax - xmin)/width), xmin, xmax);
04787    return kTRUE;
04788 }
04789 
04790 //______________________________________________________________________________
04791 Long64_t TH1::Merge(TCollection *li)
04792 {
04793    // Add all histograms in the collection to this histogram.
04794    // This function computes the min/max for the x axis,
04795    // compute a new number of bins, if necessary,
04796    // add bin contents, errors and statistics.
04797    // If all histograms have bin labels, bins with identical labels
04798    // will be merged, no matter what their order is.
04799    // If overflows are present and limits are different the function will fail.
04800    // The function returns the total number of entries in the result histogram
04801    // if the merge is successfull, -1 otherwise.
04802    //
04803    // IMPORTANT remark. The axis x may have different number
04804    // of bins and different limits, BUT the largest bin width must be
04805    // a multiple of the smallest bin width and the upper limit must also
04806    // be a multiple of the bin width.
04807    // Example:
04808    // void atest() {
04809    //    TH1F *h1 = new TH1F("h1","h1",110,-110,0);
04810    //    TH1F *h2 = new TH1F("h2","h2",220,0,110);
04811    //    TH1F *h3 = new TH1F("h3","h3",330,-55,55);
04812    //    TRandom r;
04813    //    for (Int_t i=0;i<10000;i++) {
04814    //       h1->Fill(r.Gaus(-55,10));
04815    //       h2->Fill(r.Gaus(55,10));
04816    //       h3->Fill(r.Gaus(0,10));
04817    //    }
04818    //
04819    //    TList *list = new TList;
04820    //    list->Add(h1);
04821    //    list->Add(h2);
04822    //    list->Add(h3);
04823    //    TH1F *h = (TH1F*)h1->Clone("h");
04824    //    h->Reset();
04825    //    h.Merge(list);
04826    //    h->Draw();
04827    // }
04828 
04829    if (!li) return 0;
04830    if (li->IsEmpty()) return (Int_t) GetEntries();
04831 
04832    // We don't want to add the clone to gDirectory,
04833    // so remove our kMustCleanup bit temporarily
04834    Bool_t mustCleanup = TestBit(kMustCleanup);
04835    if (mustCleanup) ResetBit(kMustCleanup);
04836    TList inlist;
04837    TH1* hclone = (TH1*)Clone("FirstClone");
04838    if (mustCleanup) SetBit(kMustCleanup);
04839    R__ASSERT(hclone);
04840    BufferEmpty(1);         // To remove buffer.
04841    Reset();                // BufferEmpty sets limits so we can't use it later.
04842    SetEntries(0);
04843    inlist.Add(hclone);
04844    inlist.AddAll(li);
04845 
04846    THashList allLabels;
04847    THashList* labels=GetXaxis()->GetLabels();
04848    Bool_t haveOneLabel=kFALSE;
04849    if (labels) {
04850       TIter iL(labels);
04851       TObjString* lb;
04852       while ((lb=(TObjString*)iL())) {
04853          haveOneLabel |= (lb && lb->String().Length());
04854          if (!allLabels.FindObject(lb))
04855             allLabels.Add(lb);
04856       }
04857    }
04858 
04859    TAxis newXAxis;
04860    Bool_t initialLimitsFound = kFALSE;
04861    Bool_t allHaveLabels = haveOneLabel;
04862    Bool_t same = kTRUE;
04863    Bool_t allHaveLimits = kTRUE;
04864 
04865    TIter next(&inlist);
04866    while (TObject *o = next()) {
04867       TH1* h = dynamic_cast<TH1*> (o);
04868       if (!h) {
04869          Error("Add","Attempt to add object of class: %s to a %s",
04870             o->ClassName(),this->ClassName());
04871          return -1;
04872       }
04873       Bool_t hasLimits = h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax();
04874       allHaveLimits = allHaveLimits && hasLimits;
04875 
04876       if (hasLimits) {
04877          h->BufferEmpty();
04878          if (!initialLimitsFound) {
04879             initialLimitsFound = kTRUE;
04880             newXAxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(),
04881                h->GetXaxis()->GetXmax());
04882          }
04883          else {
04884             if (!RecomputeAxisLimits(newXAxis, *(h->GetXaxis()))) {
04885                Error("Merge", "Cannot merge histograms - limits are inconsistent:\n "
04886                   "first: (%d, %f, %f), second: (%d, %f, %f)",
04887                   newXAxis.GetNbins(), newXAxis.GetXmin(), newXAxis.GetXmax(),
04888                   h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(),
04889                   h->GetXaxis()->GetXmax());
04890             }
04891          }
04892       }
04893       if (allHaveLabels) {
04894          THashList* hlabels=h->GetXaxis()->GetLabels();
04895          Bool_t hasOneLabel=kFALSE;
04896          if (hlabels) {
04897             TIter iL(hlabels);
04898             TObjString* lb;
04899             while ((lb=(TObjString*)iL())) {
04900                hasOneLabel |= (lb && lb->String().Length());
04901                if (!allLabels.FindObject(lb)) {
04902                   allLabels.Add(lb);
04903                   same = kFALSE;
04904                }
04905             }
04906          }
04907          allHaveLabels&=(labels && hasOneLabel);
04908          if (!allHaveLabels)
04909             Warning("Merge","Not all histograms have labels. I will ignore labels,"
04910             " falling back to bin numbering mode.");
04911       }
04912    }
04913    next.Reset();
04914 
04915    same = same && SameLimitsAndNBins(newXAxis, *GetXaxis());
04916    if (!same && initialLimitsFound)
04917       SetBins(newXAxis.GetNbins(), newXAxis.GetXmin(), newXAxis.GetXmax());
04918 
04919    if (!allHaveLimits) {
04920       // fill this histogram with all the data from buffers of histograms without limits
04921       while (TH1* h = (TH1*)next()) {
04922          if (h->GetXaxis()->GetXmin() >= h->GetXaxis()->GetXmax() && h->fBuffer) {
04923             // no limits
04924             Int_t nbentries = (Int_t)h->fBuffer[0];
04925             for (Int_t i = 0; i < nbentries; i++)
04926                Fill(h->fBuffer[2*i + 2], h->fBuffer[2*i + 1]);
04927             // Entries from buffers have to be filled one by one
04928             // because FillN doesn't resize histograms.
04929          }
04930       }
04931       if (!initialLimitsFound)
04932          return (Int_t) GetEntries();  // all histograms have been processed
04933       next.Reset();
04934    }
04935 
04936    //merge bin contents and errors
04937    Double_t stats[kNstat], totstats[kNstat];
04938    for (Int_t i=0;i<kNstat;i++) {totstats[i] = stats[i] = 0;}
04939    GetStats(totstats);
04940    Double_t nentries = GetEntries();
04941    Int_t binx, ix, nx;
04942    Double_t cu;
04943    Bool_t canRebin=TestBit(kCanRebin);
04944    if (!allHaveLabels) ResetBit(kCanRebin); // reset, otherwise setting the under/overflow will rebin
04945    while (TH1* h=(TH1*)next()) {
04946       // process only if the histogram has limits; otherwise it was processed before
04947       if (h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax()) {
04948          // import statistics
04949          h->GetStats(stats);
04950          for (Int_t i=0;i<kNstat;i++)
04951             totstats[i] += stats[i];
04952          nentries += h->GetEntries();
04953 
04954          nx = h->GetXaxis()->GetNbins();
04955          for (binx = 0; binx <= nx + 1; binx++) {
04956             cu = h->GetBinContent(binx);
04957             if (!allHaveLabels || binx==0 || binx== nx+1) {
04958                if ((!same)    && (binx==0 || binx== nx+1)) {
04959                   if (cu != 0) {
04960                      Error("Merge", "Cannot merge histograms - the histograms have"
04961                         " different limits and undeflows/overflows are present."
04962                         " The initial histogram is now broken!");
04963                      return -1;
04964                   }
04965                }
04966                ix = fXaxis.FindBin(h->GetXaxis()->GetBinCenter(binx));
04967             } else {
04968                const char* label=h->GetXaxis()->GetBinLabel(binx);
04969                if (!label || label[0]==0) {
04970                   ix = fXaxis.FindBin(h->GetXaxis()->GetBinCenter(binx));
04971                } else {
04972                   ix = fXaxis.FindBin(label);
04973                   if (ix==-1) ix = fXaxis.FindBin(h->GetXaxis()->GetBinCenter(binx));
04974                }
04975             }
04976             if (ix >= 0) {
04977                AddBinContent(ix,cu);
04978                if (fSumw2.fN) {
04979                   Double_t error1 = h->GetBinError(binx);
04980                   fSumw2.fArray[ix] += error1*error1;
04981                }
04982             }
04983          }
04984       }
04985    }
04986    if (canRebin) SetBit(kCanRebin);
04987 
04988    //copy merged stats
04989    PutStats(totstats);
04990    SetEntries(nentries);
04991    inlist.Remove(hclone);
04992    delete hclone;
04993    return (Long64_t)nentries;
04994 }
04995 
04996 //______________________________________________________________________________
04997 void TH1::Multiply(TF1 *f1, Double_t c1)
04998 {
04999    // Performs the operation: this = this*c1*f1
05000    // if errors are defined (see TH1::Sumw2), errors are also recalculated.
05001    //
05002    // Only bins inside the function range are recomputed.
05003    // IMPORTANT NOTE: If you intend to use the errors of this histogram later
05004    // you should call Sumw2 before making this operation.
05005    // This is particularly important if you fit the histogram after TH1::Multiply
05006 
05007    if (!f1) {
05008       Error("Add","Attempt to multiply by a non-existing function");
05009       return;
05010    }
05011 
05012    Int_t nbinsx = GetNbinsX();
05013    Int_t nbinsy = GetNbinsY();
05014    Int_t nbinsz = GetNbinsZ();
05015    if (fDimension < 2) nbinsy = -1;
05016    if (fDimension < 3) nbinsz = -1;
05017 
05018    // reset min-maximum
05019    SetMinimum();
05020    SetMaximum();
05021 
05022    //    Reset the kCanRebin option. Otherwise SetBinContent on the overflow bin
05023    //    would resize the axis limits!
05024    ResetBit(kCanRebin);
05025 
05026    //   - Loop on bins (including underflows/overflows)
05027    Int_t bin, binx, biny, binz;
05028    Double_t cu,w;
05029    Double_t xx[3];
05030    Double_t *params = 0;
05031    f1->InitArgs(xx,params);
05032    for (binz=0;binz<=nbinsz+1;binz++) {
05033       xx[2] = fZaxis.GetBinCenter(binz);
05034       for (biny=0;biny<=nbinsy+1;biny++) {
05035          xx[1] = fYaxis.GetBinCenter(biny);
05036          for (binx=0;binx<=nbinsx+1;binx++) {
05037             xx[0] = fXaxis.GetBinCenter(binx);
05038             if (!f1->IsInside(xx)) continue;
05039             TF1::RejectPoint(kFALSE);
05040             bin = binx +(nbinsx+2)*(biny + (nbinsy+2)*binz);
05041             Double_t error1 = GetBinError(bin);
05042             cu  = c1*f1->EvalPar(xx);
05043             if (TF1::RejectedPoint()) continue;
05044             w = GetBinContent(bin)*cu;
05045             SetBinContent(bin,w);
05046             if (fSumw2.fN) {
05047                fSumw2.fArray[bin] = cu*cu*error1*error1;
05048             }
05049          }
05050       }
05051    }
05052    ResetStats();
05053 }
05054 
05055 //______________________________________________________________________________
05056 void TH1::Multiply(const TH1 *h1)
05057 {
05058    //   -*-*-*-*-*-*-*-*-*Multiply this histogram by h1*-*-*-*-*-*-*-*-*-*-*-*-*
05059    //                     =============================
05060    //
05061    //   this = this*h1
05062    //
05063    //   If errors of this are available (TH1::Sumw2), errors are recalculated.
05064    //   Note that if h1 has Sumw2 set, Sumw2 is automatically called for this
05065    //   if not already set.
05066    //
05067    // IMPORTANT NOTE: If you intend to use the errors of this histogram later
05068    // you should call Sumw2 before making this operation.
05069    // This is particularly important if you fit the histogram after TH1::Multiply
05070 
05071    if (!h1) {
05072       Error("Multiply","Attempt to multiply by a non-existing histogram");
05073       return;
05074    }
05075 
05076    Int_t nbinsx = GetNbinsX();
05077    Int_t nbinsy = GetNbinsY();
05078    Int_t nbinsz = GetNbinsZ();
05079 
05080    try {
05081       CheckConsistency(this,h1);
05082    } catch(DifferentNumberOfBins&) {
05083       Error("Multiply","Attempt to multiply histograms with different number of bins");
05084       return;
05085    } catch(DifferentAxisLimits&) {
05086       Warning("Multiply","Attempt to multiply histograms with different axis limits");
05087    } catch(DifferentBinLimits&) {
05088       Warning("Multiply","Attempt to multiply histograms with different bin limits");
05089    }
05090 
05091    if (fDimension < 2) nbinsy = -1;
05092    if (fDimension < 3) nbinsz = -1;
05093 
05094    //    Create Sumw2 if h1 has Sumw2 set
05095    if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
05096 
05097    //   - Reset min-  maximum
05098    SetMinimum();
05099    SetMaximum();
05100 
05101    //    Reset the kCanRebin option. Otherwise SetBinContent on the overflow bin
05102    //    would resize the axis limits!
05103    ResetBit(kCanRebin);
05104 
05105    //   - Loop on bins (including underflows/overflows)
05106    Int_t bin, binx, biny, binz;
05107    Double_t c0,c1,w;
05108    for (binz=0;binz<=nbinsz+1;binz++) {
05109       for (biny=0;biny<=nbinsy+1;biny++) {
05110          for (binx=0;binx<=nbinsx+1;binx++) {
05111             bin = GetBin(binx,biny,binz);
05112             c0  = GetBinContent(bin);
05113             c1  = h1->GetBinContent(bin);
05114             w   = c0*c1;
05115             SetBinContent(bin,w);
05116             if (fSumw2.fN) {
05117                Double_t e0 = GetBinError(bin);
05118                Double_t e1 = h1->GetBinError(bin);
05119                fSumw2.fArray[bin] = (e0*e0*c1*c1 + e1*e1*c0*c0);
05120             }
05121          }
05122       }
05123    }
05124    ResetStats();
05125 }
05126 
05127 
05128 //______________________________________________________________________________
05129 void TH1::Multiply(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
05130 {
05131    //   -*-*-*Replace contents of this histogram by multiplication of h1 by h2*-*
05132    //         ================================================================
05133    //
05134    //   this = (c1*h1)*(c2*h2)
05135    //
05136    //   If errors of this are available (TH1::Sumw2), errors are recalculated.
05137    //   Note that if h1 or h2 have Sumw2 set, Sumw2 is automatically called for this
05138    //   if not already set.
05139    //
05140    // IMPORTANT NOTE: If you intend to use the errors of this histogram later
05141    // you should call Sumw2 before making this operation.
05142    // This is particularly important if you fit the histogram after TH1::Multiply
05143 
05144    TString opt = option;
05145    opt.ToLower();
05146    //   Bool_t binomial = kFALSE;
05147    //   if (opt.Contains("b")) binomial = kTRUE;
05148    if (!h1 || !h2) {
05149       Error("Multiply","Attempt to multiply by a non-existing histogram");
05150       return;
05151    }
05152 
05153    Int_t nbinsx = GetNbinsX();
05154    Int_t nbinsy = GetNbinsY();
05155    Int_t nbinsz = GetNbinsZ();
05156 
05157    try {
05158       CheckConsistency(h1,h2);
05159       CheckConsistency(this,h1);
05160    } catch(DifferentNumberOfBins&) {
05161       Error("Multiply","Attempt to multiply histograms with different number of bins");
05162       return;
05163    } catch(DifferentAxisLimits&) {
05164       Warning("Multiply","Attempt to multiply histograms with different axis limits");
05165    } catch(DifferentBinLimits&) {
05166       Warning("Multiply","Attempt to multiply histograms with different bin limits");
05167    }
05168 
05169    if (fDimension < 2) nbinsy = -1;
05170    if (fDimension < 3) nbinsz = -1;
05171 
05172    //    Create Sumw2 if h1 or h2 have Sumw2 set
05173    if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
05174 
05175    //   - Reset min - maximum
05176    SetMinimum();
05177    SetMaximum();
05178 
05179    //    Reset the kCanRebin option. Otherwise SetBinContent on the overflow bin
05180    //    would resize the axis limits!
05181    ResetBit(kCanRebin);
05182 
05183    //   - Loop on bins (including underflows/overflows)
05184    Int_t bin, binx, biny, binz;
05185    Double_t b1,b2,w,d1,d2;
05186    d1 = c1*c1;
05187    d2 = c2*c2;
05188    for (binz=0;binz<=nbinsz+1;binz++) {
05189       for (biny=0;biny<=nbinsy+1;biny++) {
05190          for (binx=0;binx<=nbinsx+1;binx++) {
05191             bin = binx +(nbinsx+2)*(biny + (nbinsy+2)*binz);
05192             b1  = h1->GetBinContent(bin);
05193             b2  = h2->GetBinContent(bin);
05194             w   = (c1*b1)*(c2*b2);
05195             SetBinContent(bin,w);
05196             if (fSumw2.fN) {
05197                Double_t e1 = h1->GetBinError(bin);
05198                Double_t e2 = h2->GetBinError(bin);
05199                fSumw2.fArray[bin] = d1*d2*(e1*e1*b2*b2 + e2*e2*b1*b1);
05200             }
05201          }
05202       }
05203    }
05204    ResetStats();
05205 }
05206 
05207 //______________________________________________________________________________
05208 void TH1::Paint(Option_t *option)
05209 {
05210    //   -*-*-*-*-*-*-*Control routine to paint any kind of histograms*-*-*-*-*-*-*
05211    //                 ===============================================
05212    //
05213    //  This function is automatically called by TCanvas::Update.
05214    //  (see TH1::Draw for the list of options)
05215 
05216    GetPainter(option);
05217 
05218    if (fPainter) {
05219       if (strlen(option) > 0) fPainter->Paint(option);
05220       else                    fPainter->Paint(fOption.Data());
05221    }
05222 }
05223 
05224 //______________________________________________________________________________
05225 TH1 *TH1::Rebin(Int_t ngroup, const char*newname, const Double_t *xbins)
05226 {
05227    //   Rebin this histogram
05228    //
05229    //  -case 1  xbins=0
05230    //   if newname is not blank a new temporary histogram hnew is created.
05231    //   else the current histogram is modified (default)
05232    //   The parameter ngroup indicates how many bins of this have to me merged
05233    //   into one bin of hnew
05234    //   If the original histogram has errors stored (via Sumw2), the resulting
05235    //   histograms has new errors correctly calculated.
05236    //
05237    //   examples: if h1 is an existing TH1F histogram with 100 bins
05238    //     h1->Rebin();  //merges two bins in one in h1: previous contents of h1 are lost
05239    //     h1->Rebin(5); //merges five bins in one in h1
05240    //     TH1F *hnew = h1->Rebin(5,"hnew"); // creates a new histogram hnew
05241    //                                       //merging 5 bins of h1 in one bin
05242    //
05243    //   NOTE:  If ngroup is not an exact divider of the number of bins,
05244    //          the top limit of the rebinned histogram is changed
05245    //          to the upper edge of the bin=newbins*ngroup and the corresponding
05246    //          bins are added to the overflow bin.
05247    //          Statistics will be recomputed from the new bin contents.
05248    //
05249    //  -case 2  xbins!=0
05250    //   a new histogram is created (you should specify newname).
05251    //   The parameter is the number of variable size bins in the created histogram.
05252    //   The array xbins must contain ngroup+1 elements that represent the low-edge
05253    //   of the bins.
05254    //   If the original histogram has errors stored (via Sumw2), the resulting
05255    //   histograms has new errors correctly calculated.
05256    //
05257    //   examples: if h1 is an existing TH1F histogram with 100 bins
05258    //     Double_t xbins[25] = {...} array of low-edges (xbins[25] is the upper edge of last bin
05259    //     h1->Rebin(24,"hnew",xbins);  //creates a new variable bin size histogram hnew
05260 
05261    Int_t nbins    = fXaxis.GetNbins();
05262    Double_t xmin  = fXaxis.GetXmin();
05263    Double_t xmax  = fXaxis.GetXmax();
05264    if ((ngroup <= 0) || (ngroup > nbins)) {
05265       Error("Rebin", "Illegal value of ngroup=%d",ngroup);
05266       return 0;
05267    }
05268 
05269    if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
05270       Error("Rebin", "Operation valid on 1-D histograms only");
05271       return 0;
05272    }
05273    if (!newname && xbins) {
05274       Error("Rebin","if xbins is specified, newname must be given");
05275       return 0;
05276    }
05277 
05278    Int_t newbins = nbins/ngroup;
05279    if (!xbins) {
05280       Int_t nbg = nbins/ngroup;
05281       if (nbg*ngroup != nbins) {
05282          Warning("Rebin", "ngroup=%d must be an exact divider of nbins=%d",ngroup,nbins);
05283       }
05284    }
05285    else {
05286    // in the case of xbins given (rebinning in variable bins) ngroup is the news number of bins.
05287    //  and number of grouped bins is not constant.
05288    // when looping for setting the contents for the new histogram we
05289    // need to loop on all bins of original histogram. Set then ngroup=nbins
05290       newbins = ngroup;
05291       ngroup = nbins;
05292    }
05293 
05294    // Save old bin contents into a new array
05295    Double_t entries = fEntries;
05296    Double_t *oldBins = new Double_t[nbins+2];
05297    Int_t bin, i;
05298    for (bin=0;bin<nbins+2;bin++) oldBins[bin] = GetBinContent(bin);
05299    Double_t *oldErrors = 0;
05300    if (fSumw2.fN != 0) {
05301       oldErrors = new Double_t[nbins+2];
05302       for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
05303    }
05304 
05305    // create a clone of the old histogram if newname is specified
05306    TH1 *hnew = this;
05307    if ((newname && strlen(newname) > 0) || xbins) {
05308       hnew = (TH1*)Clone(newname);
05309    }
05310 
05311    //reset kCanRebin bit to avoid a rebinning in SetBinContent
05312    Int_t bitRebin = hnew->TestBit(kCanRebin);
05313    hnew->SetBit(kCanRebin,0);
05314 
05315    // save original statistics
05316    Double_t stat[kNstat];
05317    GetStats(stat);
05318    bool resetStat = false;
05319    // change axis specs and rebuild bin contents array::RebinAx
05320    if(!xbins && (newbins*ngroup != nbins)) {
05321       xmax = fXaxis.GetBinUpEdge(newbins*ngroup);
05322       resetStat = true; //stats must be reset because top bins will be moved to overflow bin
05323    }
05324    // save the TAttAxis members (reset by SetBins)
05325    Int_t    nDivisions  = fXaxis.GetNdivisions();
05326    Color_t  axisColor   = fXaxis.GetAxisColor();
05327    Color_t  labelColor  = fXaxis.GetLabelColor();
05328    Style_t  labelFont   = fXaxis.GetLabelFont();
05329    Float_t  labelOffset = fXaxis.GetLabelOffset();
05330    Float_t  labelSize   = fXaxis.GetLabelSize();
05331    Float_t  tickLength  = fXaxis.GetTickLength();
05332    Float_t  titleOffset = fXaxis.GetTitleOffset();
05333    Float_t  titleSize   = fXaxis.GetTitleSize();
05334    Color_t  titleColor  = fXaxis.GetTitleColor();
05335    Style_t  titleFont   = fXaxis.GetTitleFont();
05336 
05337    if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){ // variable bin sizes
05338       Double_t *bins = new Double_t[newbins+1];
05339       for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
05340       hnew->SetBins(newbins,bins); //this also changes errors array (if any)
05341       delete [] bins;
05342    } else if (xbins) {
05343       hnew->SetBins(newbins,xbins);
05344    } else {
05345       hnew->SetBins(newbins,xmin,xmax);
05346    }
05347 
05348    // Restore axis attributes
05349    fXaxis.SetNdivisions(nDivisions);
05350    fXaxis.SetAxisColor(axisColor);
05351    fXaxis.SetLabelColor(labelColor);
05352    fXaxis.SetLabelFont(labelFont);
05353    fXaxis.SetLabelOffset(labelOffset);
05354    fXaxis.SetLabelSize(labelSize);
05355    fXaxis.SetTickLength(tickLength);
05356    fXaxis.SetTitleOffset(titleOffset);
05357    fXaxis.SetTitleSize(titleSize);
05358    fXaxis.SetTitleColor(titleColor);
05359    fXaxis.SetTitleFont(titleFont);
05360 
05361    // copy merged bin contents (ignore under/overflows)
05362    // Start merging only once the new lowest edge is reached
05363    Int_t startbin = 1;
05364    const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
05365    while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
05366       startbin++;
05367    }
05368    Int_t oldbin = startbin;
05369    Double_t binContent, binError;
05370    for (bin = 1;bin<=newbins;bin++) {
05371       binContent = 0;
05372       binError   = 0;
05373       Int_t imax = ngroup;
05374       Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
05375       for (i=0;i<ngroup;i++) {
05376          if( (hnew == this && (oldbin+i > nbins)) ||
05377              ( hnew != this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
05378             imax = i;
05379             break;
05380          }
05381          binContent += oldBins[oldbin+i];
05382          if (oldErrors) binError += oldErrors[oldbin+i]*oldErrors[oldbin+i];
05383       }
05384       hnew->SetBinContent(bin,binContent);
05385       if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
05386       oldbin += imax;
05387    }
05388    // sum underfllow and overflow contents until startbin
05389    binContent = 0;
05390    binError = 0;
05391    for (i = 0; i < startbin; ++i)  {
05392       binContent += oldBins[i];
05393       if (oldErrors) binError += oldErrors[i]*oldErrors[i];
05394    }
05395    hnew->SetBinContent(0,binContent);
05396    if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
05397    // sum overflow
05398    binContent = 0;
05399    binError = 0;
05400    for (i = oldbin; i <= nbins+1; ++i)  {
05401       binContent += oldBins[i];
05402       if (oldErrors) binError += oldErrors[i]*oldErrors[i];
05403    }
05404    hnew->SetBinContent(newbins+1,binContent);
05405    if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
05406    hnew->SetBit(kCanRebin,bitRebin);
05407 
05408    //restore statistics and entries  modified by SetBinContent
05409    hnew->SetEntries(entries);
05410    if (!resetStat) hnew->PutStats(stat);
05411    delete [] oldBins;
05412    if (oldErrors) delete [] oldErrors;
05413    return hnew;
05414 }
05415 
05416 //______________________________________________________________________________
05417 Bool_t TH1::FindNewAxisLimits(const TAxis* axis, const Double_t point, Double_t& newMin, Double_t &newMax)
05418 {
05419    // finds new limits for the axis so that *point* is within the range and
05420    // the limits are compatible with the previous ones (see TH1::Merge).
05421    // new limits are put into *newMin* and *newMax* variables.
05422    // axis - axis whose limits are to be recomputed
05423    // point - point that should fit within the new axis limits
05424    // newMin - new minimum will be stored here
05425    // newMax - new maximum will be stored here.
05426    // false if failed (e.g. if the initial axis limits are wrong
05427    // or the new range is more than 2^64 times the old one).
05428 
05429    Double_t xmin = axis->GetXmin();
05430    Double_t xmax = axis->GetXmax();
05431    if (xmin >= xmax) return kFALSE;
05432    Double_t range = xmax-xmin;
05433    Double_t binsize = range / axis->GetNbins();
05434 
05435    //recompute new axis limits by doubling the current range
05436    Int_t ntimes = 0;
05437    while (point < xmin) {
05438       if (ntimes++ > 64)
05439          return kFALSE;
05440       xmin = xmin - range;
05441       range *= 2;
05442       binsize *= 2;
05443       // make sure that the merging will be correct
05444       if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
05445          xmin += 0.5 * binsize;
05446          xmax += 0.5 * binsize;  // won't work with a histogram with only one bin, but I don't care
05447       }
05448    }
05449    while (point >= xmax) {
05450       if (ntimes++ > 64)
05451          return kFALSE;
05452       xmax = xmax + range;
05453       range *= 2;
05454       binsize *= 2;
05455       // make sure that the merging will be correct
05456       if ( xmin / binsize - TMath::Floor(xmin / binsize) >= 0.5) {
05457          xmin -= 0.5 * binsize;
05458          xmax -= 0.5 * binsize;  // won't work with a histogram with only one bin, but I don't care
05459       }
05460    }
05461    newMin = xmin;
05462    newMax = xmax;
05463    //   Info("FindNewAxisLimits", "OldAxis: (%lf, %lf), new: (%lf, %lf), point: %lf",
05464    //      axis->GetXmin(), axis->GetXmax(), xmin, xmax, point);
05465 
05466    return kTRUE;
05467 }
05468 
05469 //______________________________________________________________________________
05470 void TH1::RebinAxis(Double_t x, TAxis *axis)
05471 {
05472    // Histogram is resized along axis such that x is in the axis range.
05473    // The new axis limits are recomputed by doubling iteratively
05474    // the current axis range until the specified value x is within the limits.
05475    // The algorithm makes a copy of the histogram, then loops on all bins
05476    // of the old histogram to fill the rebinned histogram.
05477    // Takes into account errors (Sumw2) if any.
05478    // The algorithm works for 1-d, 2-D and 3-D histograms.
05479    // The bit kCanRebin must be set before invoking this function.
05480    //  Ex:  h->SetBit(TH1::kCanRebin);
05481 
05482    if (!TestBit(kCanRebin)) return;
05483    if (TMath::IsNaN(x)) {         // x may be a NaN
05484       ResetBit(kCanRebin);
05485       return;
05486    }
05487 
05488    if (axis->GetXmin() >= axis->GetXmax()) return;
05489    if (axis->GetNbins() <= 0) return;
05490 
05491    Double_t xmin, xmax;
05492    if (!FindNewAxisLimits(axis, x, xmin, xmax))
05493       return;
05494 
05495    //save a copy of this histogram
05496    TH1 *hold = (TH1*)Clone();
05497    hold->SetDirectory(0);
05498    //set new axis limits
05499    axis->SetLimits(xmin,xmax);
05500 
05501    Int_t  nbinsx = fXaxis.GetNbins();
05502    Int_t  nbinsy = fYaxis.GetNbins();
05503    Int_t  nbinsz = fZaxis.GetNbins();
05504 
05505    //now loop on all bins and refill
05506    Double_t err,cu;
05507    Double_t bx,by,bz;
05508    Int_t errors = GetSumw2N();
05509    Int_t ix,iy,iz,ibin,binx,biny,binz,bin;
05510    Reset("ICE"); //reset only Integral, contents and Errors
05511    for (binz=1;binz<=nbinsz;binz++) {
05512       bz  = hold->GetZaxis()->GetBinCenter(binz);
05513       iz  = fZaxis.FindFixBin(bz);
05514       for (biny=1;biny<=nbinsy;biny++) {
05515          by  = hold->GetYaxis()->GetBinCenter(biny);
05516          iy  = fYaxis.FindFixBin(by);
05517          for (binx=1;binx<=nbinsx;binx++) {
05518             bx = hold->GetXaxis()->GetBinCenter(binx);
05519             ix  = fXaxis.FindFixBin(bx);
05520             bin = hold->GetBin(binx,biny,binz);
05521             ibin= GetBin(ix,iy,iz);
05522             cu  = hold->GetBinContent(bin);
05523             AddBinContent(ibin,cu);
05524             if (errors) {
05525                err = hold->GetBinError(bin);
05526                fSumw2.fArray[ibin] += err*err;
05527             }
05528          }
05529       }
05530    }
05531    delete hold;
05532 }
05533 
05534 //______________________________________________________________________________
05535 void TH1::RecursiveRemove(TObject *obj)
05536 {
05537    // Recursively remove object from the list of functions
05538 
05539    if (fFunctions) {
05540       if (!fFunctions->TestBit(kInvalidObject)) fFunctions->RecursiveRemove(obj);
05541    }
05542 }
05543 
05544 //______________________________________________________________________________
05545 void TH1::Scale(Double_t c1, Option_t *option)
05546 {
05547    //   -*-*-*Multiply this histogram by a constant c1*-*-*-*-*-*-*-*-*
05548    //         ========================================
05549    //
05550    //   this = c1*this
05551    //
05552    // Note that both contents and errors(if any) are scaled.
05553    // This function uses the services of TH1::Add
05554    //
05555    // IMPORTANT NOTE: If you intend to use the errors of this histogram later
05556    // you should call Sumw2 before making this operation.
05557    // This is particularly important if you fit the histogram after TH1::Scale
05558    //
05559    // One can scale an histogram such that the bins integral is equal to
05560    // the normalization parameter via TH1::Scale(Double_t norm), where norm
05561    // is the desired normalization divided by the integral of the histogram.
05562    //
05563    // If option contains "width" the bin contents and errors are divided
05564    // by the bin width.
05565 
05566    TString opt = option;
05567    opt.ToLower();
05568    Double_t ent = fEntries;
05569    if (opt.Contains("width")) Add(this,this,c1,-1);
05570    else                       Add(this,this,c1,0);
05571    fEntries = ent;
05572 
05573    //if contours set, must also scale contours
05574    Int_t ncontours = GetContour();
05575    if (ncontours == 0) return;
05576    Double_t *levels = fContour.GetArray();
05577    for (Int_t i=0;i<ncontours;i++) {
05578       levels[i] *= c1;
05579    }
05580 }
05581 
05582 
05583 //______________________________________________________________________________
05584 void TH1::SetDefaultBufferSize(Int_t buffersize)
05585 {
05586    // static function to set the default buffer size for automatic histograms.
05587    // When an histogram is created with one of its axis lower limit greater
05588    // or equal to its upper limit, the function SetBuffer is automatically
05589    // called with the default buffer size.
05590 
05591    if (buffersize < 0) buffersize = 0;
05592    fgBufferSize = buffersize;
05593 }
05594 
05595 
05596 //______________________________________________________________________________
05597 void TH1::SetDefaultSumw2(Bool_t sumw2)
05598 {
05599    // static function.
05600    // When this static function is called with sumw2=kTRUE, all new
05601    // histograms will automatically activate the storage
05602    // of the sum of squares of errors, ie TH1::Sumw2 is automatically called.
05603 
05604    fgDefaultSumw2 = sumw2;
05605 }
05606 
05607 //______________________________________________________________________________
05608 void TH1::SetTitle(const char *title)
05609 {
05610    // Change (i.e. set) the title
05611    //
05612    //   if title is in the form "stringt;stringx;stringy;stringz"
05613    //   the histogram title is set to stringt, the x axis title to stringx,
05614    //   the y axis title to stringy, and the z axis title to stringz.
05615    //   To insert the character ";" in one of the titles, one should use "#;"
05616    //   or "#semicolon".
05617 
05618    fTitle = title;
05619    fTitle.ReplaceAll("#;",2,"#semicolon",10);
05620 
05621    // Decode fTitle. It may contain X, Y and Z titles
05622    TString str1 = fTitle, str2;
05623    Int_t isc = str1.Index(";");
05624    Int_t lns = str1.Length();
05625 
05626    if (isc >=0 ) {
05627       fTitle = str1(0,isc);
05628       str1   = str1(isc+1, lns);
05629       isc    = str1.Index(";");
05630       if (isc >=0 ) {
05631          str2 = str1(0,isc);
05632          str2.ReplaceAll("#semicolon",10,";",1);
05633          fXaxis.SetTitle(str2.Data());
05634          lns  = str1.Length();
05635          str1 = str1(isc+1, lns);
05636          isc  = str1.Index(";");
05637          if (isc >=0 ) {
05638             str2 = str1(0,isc);
05639             str2.ReplaceAll("#semicolon",10,";",1);
05640             fYaxis.SetTitle(str2.Data());
05641             lns  = str1.Length();
05642             str1 = str1(isc+1, lns);
05643             str1.ReplaceAll("#semicolon",10,";",1);
05644             fZaxis.SetTitle(str1.Data());
05645          } else {
05646             str1.ReplaceAll("#semicolon",10,";",1);
05647             fYaxis.SetTitle(str1.Data());
05648          }
05649       } else {
05650          str1.ReplaceAll("#semicolon",10,";",1);
05651          fXaxis.SetTitle(str1.Data());
05652       }
05653    }
05654 
05655    fTitle.ReplaceAll("#semicolon",10,";",1);
05656 
05657    if (gPad && TestBit(kMustCleanup)) gPad->Modified();
05658 }
05659 
05660 // -------------------------------------------------------------------------
05661 void  TH1::SmoothArray(Int_t nn, Double_t *xx, Int_t ntimes)
05662 {
05663    // smooth array xx, translation of Hbook routine hsmoof.F
05664    // based on algorithm 353QH twice presented by J. Friedman
05665    // in Proc.of the 1974 CERN School of Computing, Norway, 11-24 August, 1974.
05666 
05667    Int_t ii, jj, ik, jk, kk, nn2;
05668    Double_t hh[6] = {0,0,0,0,0,0};
05669    Double_t *yy = new Double_t[nn];
05670    Double_t *zz = new Double_t[nn];
05671    Double_t *rr = new Double_t[nn];
05672 
05673    for (Int_t pass=0;pass<ntimes;pass++) {
05674       // first copy original data into temp array
05675 
05676       for (ii = 0; ii < nn; ii++) {
05677          yy[ii] = xx[ii];
05678       }
05679 
05680       //  do 353 i.e. running median 3, 5, and 3 in a single loop
05681       for  (kk = 1; kk <= 3; kk++)  {
05682          ik = 0;
05683          if  (kk == 2)  ik = 1;
05684          nn2 = nn - ik - 1;
05685          // do all elements beside the first and last point for median 3
05686          //  and first two and last 2 for median 5
05687          for  (ii = ik + 1; ii < nn2; ii++)  {
05688             for  (jj = 0; jj < 3; jj++)   {
05689                hh[jj] = yy[ii + jj - 1];
05690             }
05691             zz[ii] = TMath::Median(3 + 2*ik, hh);
05692          }
05693 
05694          if  (kk == 1)  {   // first median 3
05695             // first point
05696             hh[0] = 3*yy[1] - 2*yy[2];
05697             hh[1] = yy[0];
05698             hh[2] = yy[1];
05699             zz[0] = TMath::Median(3, hh);
05700             // last point
05701             hh[0] = yy[nn - 2];
05702             hh[1] = yy[nn - 1];
05703             hh[2] = 3*yy[nn - 2] - 2*yy[nn - 3];
05704             zz[nn - 1] = TMath::Median(3, hh);
05705          }
05706          if  (kk == 2)  {   //  median 5
05707             //  first point remains the same
05708             zz[0] = yy[0];
05709             for  (ii = 0; ii < 3; ii++) {
05710                hh[ii] = yy[ii];
05711             }
05712             zz[1] = TMath::Median(3, hh);
05713             // last two points
05714             for  (ii = 0; ii < 3; ii++) {
05715                hh[ii] = yy[nn - 3 + ii];
05716             }
05717             zz[nn - 2] = TMath::Median(3, hh);
05718             zz[nn - 1] = yy[nn - 1];
05719          }
05720       }
05721 
05722       // quadratic interpolation for flat segments
05723       for (ii = 2; ii < (nn - 2); ii++) {
05724          if  (zz[ii - 1] != zz[ii]) continue;
05725          if  (zz[ii] != zz[ii + 1]) continue;
05726          hh[0] = zz[ii - 2] - zz[ii];
05727          hh[1] = zz[ii + 2] - zz[ii];
05728          if  (hh[0] * hh[1] < 0) continue;
05729          jk = 1;
05730          if  ( TMath::Abs(hh[1]) > TMath::Abs(hh[0]) ) jk = -1;
05731          yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
05732          yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
05733       }
05734 
05735       // running means
05736       for  (ii = 1; ii < nn - 1; ii++) {
05737          rr[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
05738       }
05739       rr[0] = yy[0];
05740       rr[nn - 1] = yy[nn - 1];
05741 
05742       // now do the same for residuals
05743 
05744       for  (ii = 0; ii < nn; ii++)  {
05745          yy[ii] = xx[ii] - rr[ii];
05746       }
05747 
05748       //  do 353 i.e. running median 3, 5, and 3 in a single loop
05749       for  (kk = 1; kk <= 3; kk++)  {
05750          ik = 0;
05751          if  (kk == 2)  ik = 1;
05752          nn2 = nn - ik - 1;
05753          // do all elements beside the first and last point for median 3
05754          //  and first two and last 2 for median 5
05755          for  (ii = ik + 1; ii < nn2; ii++)  {
05756             for  (jj = 0; jj < 3; jj++) {
05757                hh[jj] = yy[ii + jj - 1];
05758             }
05759             zz[ii] = TMath::Median(3 + 2*ik, hh);
05760          }
05761 
05762          if  (kk == 1)  {   // first median 3
05763             // first point
05764             hh[0] = 3*yy[1] - 2*yy[2];
05765             hh[1] = yy[0];
05766             hh[2] = yy[1];
05767             zz[0] = TMath::Median(3, hh);
05768             // last point
05769             hh[0] = yy[nn - 2];
05770             hh[1] = yy[nn - 1];
05771             hh[2] = 3*yy[nn - 2] - 2*yy[nn - 3];
05772             zz[nn - 1] = TMath::Median(3, hh);
05773          }
05774          if  (kk == 2)  {   //  median 5
05775             //  first point remains the same
05776             zz[0] = yy[0];
05777             for  (ii = 0; ii < 3; ii++) {
05778                hh[ii] = yy[ii];
05779             }
05780             zz[1] = TMath::Median(3, hh);
05781             // last two points
05782             for  (ii = 0; ii < 3; ii++) {
05783                hh[ii] = yy[nn - 3 + ii];
05784             }
05785             zz[nn - 2] = TMath::Median(3, hh);
05786             zz[nn - 1] = yy[nn - 1];
05787          }
05788       }
05789 
05790       // quadratic interpolation for flat segments
05791       for (ii = 2; ii < (nn - 2); ii++) {
05792          if  (zz[ii - 1] != zz[ii]) continue;
05793          if  (zz[ii] != zz[ii + 1]) continue;
05794          hh[0] = zz[ii - 2] - zz[ii];
05795          hh[1] = zz[ii + 2] - zz[ii];
05796          if  (hh[0] * hh[1] < 0) continue;
05797          jk = 1;
05798          if  ( TMath::Abs(hh[1]) > TMath::Abs(hh[0]) ) jk = -1;
05799          yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk]/6.;
05800          yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
05801       }
05802 
05803       // running means
05804       for  (ii = 1; ii < (nn - 1); ii++) {
05805          zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
05806       }
05807       zz[0] = yy[0];
05808       zz[nn - 1] = yy[nn - 1];
05809 
05810       //  add smoothed xx and smoothed residuals
05811 
05812       for  (ii = 0; ii < nn; ii++) {
05813          if (xx[ii] < 0) xx[ii] = rr[ii] + zz[ii];
05814          else            xx[ii] = TMath::Abs(rr[ii] + zz[ii]);
05815       }
05816    }
05817    delete [] yy;
05818    delete [] zz;
05819    delete [] rr;
05820 }
05821 
05822 
05823 // ------------------------------------------------------------------------
05824 void  TH1::Smooth(Int_t ntimes, Option_t *option)
05825 {
05826    // Smooth bin contents of this histogram.
05827    // if option contains "R" smoothing is applied only to the bins
05828    // defined in the X axis range (default is to smooth all bins)
05829    // Bin contents are replaced by their smooth values.
05830    // Errors (if any) are not modified.
05831    // the smoothing procedure is repeated ntimes (default=1)
05832 
05833    if (fDimension != 1) {
05834       Error("Smooth","Smooth only supported for 1-d histograms");
05835       return;
05836    }
05837    Int_t nbins = fXaxis.GetNbins();
05838    Int_t firstbin = 1, lastbin = nbins;
05839    TString opt = option;
05840    opt.ToLower();
05841    if (opt.Contains("r")) {
05842       firstbin= fXaxis.GetFirst();
05843       lastbin  = fXaxis.GetLast();
05844    }
05845    nbins = lastbin - firstbin + 1;
05846    Double_t *xx = new Double_t[nbins];
05847    Double_t nent = fEntries;
05848    Int_t i;
05849    for (i=0;i<nbins;i++) {
05850       xx[i] = GetBinContent(i+firstbin);
05851    }
05852 
05853    TH1::SmoothArray(nbins,xx,ntimes);
05854 
05855    for (i=0;i<nbins;i++) {
05856       SetBinContent(i+firstbin,xx[i]);
05857    }
05858    fEntries = nent;
05859    delete [] xx;
05860 
05861    if (gPad) gPad->Modified();
05862 }
05863 
05864 
05865 // ------------------------------------------------------------------------
05866 void  TH1::StatOverflows(Bool_t flag)
05867 {
05868    //  if flag=kTRUE, underflows and overflows are used by the Fill functions
05869    //  in the computation of statistics (mean value, RMS).
05870    //  By default, underflows or overflows are not used.
05871 
05872    fgStatOverflows = flag;
05873 }
05874 
05875 //_______________________________________________________________________
05876 void TH1::Streamer(TBuffer &b)
05877 {
05878    //   -*-*-*-*-*-*-*Stream a class object*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
05879    //                 =====================
05880    if (b.IsReading()) {
05881       UInt_t R__s, R__c;
05882       Version_t R__v = b.ReadVersion(&R__s, &R__c);
05883       if (fDirectory) fDirectory->Remove(this);
05884       fDirectory = 0;
05885       if (R__v > 2) {
05886          b.ReadClassBuffer(TH1::Class(), this, R__v, R__s, R__c);
05887 
05888          ResetBit(kMustCleanup);
05889          fXaxis.SetParent(this);
05890          fYaxis.SetParent(this);
05891          fZaxis.SetParent(this);
05892          TIter next(fFunctions);
05893          TObject *obj;
05894          while ((obj=next())) {
05895             if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(this);
05896          }
05897          return;
05898       }
05899       //process old versions before automatic schema evolution
05900       TNamed::Streamer(b);
05901       TAttLine::Streamer(b);
05902       TAttFill::Streamer(b);
05903       TAttMarker::Streamer(b);
05904       b >> fNcells;
05905       fXaxis.Streamer(b);
05906       fYaxis.Streamer(b);
05907       fZaxis.Streamer(b);
05908       fXaxis.SetParent(this);
05909       fYaxis.SetParent(this);
05910       fZaxis.SetParent(this);
05911       b >> fBarOffset;
05912       b >> fBarWidth;
05913       b >> fEntries;
05914       b >> fTsumw;
05915       b >> fTsumw2;
05916       b >> fTsumwx;
05917       b >> fTsumwx2;
05918       if (R__v < 2) {
05919          Float_t maximum, minimum, norm;
05920          Float_t *contour=0;
05921          b >> maximum; fMaximum = maximum;
05922          b >> minimum; fMinimum = minimum;
05923          b >> norm;    fNormFactor = norm;
05924          Int_t n = b.ReadArray(contour);
05925          fContour.Set(n);
05926          for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
05927          delete [] contour;
05928       } else {
05929          b >> fMaximum;
05930          b >> fMinimum;
05931          b >> fNormFactor;
05932          fContour.Streamer(b);
05933       }
05934       fSumw2.Streamer(b);
05935       fOption.Streamer(b);
05936       fFunctions->Delete();
05937       fFunctions->Streamer(b);
05938       b.CheckByteCount(R__s, R__c, TH1::IsA());
05939 
05940    } else {
05941       b.WriteClassBuffer(TH1::Class(),this);
05942    }
05943 }
05944 
05945 //______________________________________________________________________________
05946 void TH1::Print(Option_t *option) const
05947 {
05948    //   -*-*-*-*-*Print some global quantities for this histogram*-*-*-*-*-*-*-*
05949    //             ===============================================
05950    //
05951    //  If option "base" is given, number of bins and ranges are also printed
05952    //  If option "range" is given, bin contents and errors are also printed
05953    //                     for all bins in the current range (default 1-->nbins)
05954    //  If option "all" is given, bin contents and errors are also printed
05955    //                     for all bins including under and overflows.
05956    //
05957    printf( "TH1.Print Name  = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
05958    TString opt = option;
05959    opt.ToLower();
05960    Int_t all;
05961    if      (opt.Contains("all"))   all = 0;
05962    else if (opt.Contains("range")) all = 1;
05963    else if (opt.Contains("base"))  all = 2;
05964    else                            return;
05965 
05966    Int_t bin, binx, biny, binz;
05967    Int_t firstx=0,lastx=0,firsty=0,lasty=0,firstz=0,lastz=0;
05968    if (all == 0) {
05969       lastx  = fXaxis.GetNbins()+1;
05970       if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
05971       if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
05972    } else {
05973       firstx = fXaxis.GetFirst(); lastx  = fXaxis.GetLast();
05974       if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
05975       if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
05976    }
05977 
05978    if (all== 2) {
05979       printf("          Title = %s\n", GetTitle());
05980       printf("          NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
05981       if( fDimension > 1) printf(", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
05982       if( fDimension > 2) printf(", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
05983       printf("\n");
05984       return;
05985    }
05986 
05987    Double_t w,e;
05988    Double_t x,y,z;
05989    if (fDimension == 1) {
05990       for (binx=firstx;binx<=lastx;binx++) {
05991          x = fXaxis.GetBinCenter(binx);
05992          w = GetBinContent(binx);
05993          e = GetBinError(binx);
05994          if(fSumw2.fN) printf(" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
05995          else          printf(" fSumw[%d]=%g, x=%g\n",binx,w,x);
05996       }
05997    }
05998    if (fDimension == 2) {
05999       for (biny=firsty;biny<=lasty;biny++) {
06000          y = fYaxis.GetBinCenter(biny);
06001          for (binx=firstx;binx<=lastx;binx++) {
06002             bin = GetBin(binx,biny);
06003             x = fXaxis.GetBinCenter(binx);
06004             w = GetBinContent(bin);
06005             e = GetBinError(bin);
06006             if(fSumw2.fN) printf(" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
06007             else          printf(" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
06008          }
06009       }
06010    }
06011    if (fDimension == 3) {
06012       for (binz=firstz;binz<=lastz;binz++) {
06013          z = fZaxis.GetBinCenter(binz);
06014          for (biny=firsty;biny<=lasty;biny++) {
06015             y = fYaxis.GetBinCenter(biny);
06016             for (binx=firstx;binx<=lastx;binx++) {
06017                bin = GetBin(binx,biny,binz);
06018                x = fXaxis.GetBinCenter(binx);
06019                w = GetBinContent(bin);
06020                e = GetBinError(bin);
06021                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);
06022                else          printf(" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
06023             }
06024          }
06025       }
06026    }
06027 }
06028 
06029 //______________________________________________________________________________
06030 void TH1::Rebuild(Option_t *)
06031 {
06032    // Using the current bin info, recompute the arrays for contents and errors
06033 
06034    SetBinsLength();
06035    if (fSumw2.fN) {
06036       fSumw2.Set(fNcells);
06037    }
06038 }
06039 
06040 //______________________________________________________________________________
06041 void TH1::Reset(Option_t *option)
06042 {
06043    //   -*-*-*-*-*-*Reset this histogram: contents, errors, etc*-*-*-*-*-*-*-*
06044    //               ===========================================
06045    //
06046    // if option "ICE" is specified, resets only Integral, Contents and Errors.
06047    // if option "M"   is specified, resets also Minimum and Maximum
06048 
06049    TString opt = option;
06050    opt.ToUpper();
06051    fSumw2.Reset();
06052    if (fIntegral) {delete [] fIntegral; fIntegral = 0;}
06053 
06054    if (opt.Contains("M")) {
06055       SetMinimum();
06056       SetMaximum();
06057    }
06058    if (opt.Contains("ICE")) return;
06059    if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
06060    fTsumw       = 0;
06061    fTsumw2      = 0;
06062    fTsumwx      = 0;
06063    fTsumwx2     = 0;
06064    fEntries     = 0;
06065 
06066    TObject *stats = fFunctions->FindObject("stats");
06067    fFunctions->Remove(stats);
06068    //special logic to support the case where the same object is
06069    //added multiple times in fFunctions.
06070    //This case happens when the same object is added with different
06071    //drawing modes
06072    TObject *obj;
06073    while ((obj  = fFunctions->First())) {
06074       while(fFunctions->Remove(obj)) { }
06075       delete obj;
06076    }
06077    if(stats) fFunctions->Add(stats);
06078    fContour.Set(0);
06079 }
06080 
06081 //______________________________________________________________________________
06082 void TH1::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
06083 {
06084    // Save primitive as a C++ statement(s) on output stream out
06085 
06086    Bool_t nonEqiX = kFALSE;
06087    Bool_t nonEqiY = kFALSE;
06088    Bool_t nonEqiZ = kFALSE;
06089    Int_t i;
06090    static Int_t nxaxis = 0;
06091    static Int_t nyaxis = 0;
06092    static Int_t nzaxis = 0;
06093    TString sxaxis="xAxis",syaxis="yAxis",szaxis="zAxis";
06094 
06095    // Check if the histogram has equidistant X bins or not.  If not, we
06096    // create an array holding the bins.
06097    if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
06098       nonEqiX = kTRUE;
06099       nxaxis++;
06100       sxaxis += nxaxis;
06101       out << "   Double_t "<<sxaxis<<"[" << GetXaxis()->GetXbins()->fN
06102          << "] = {";
06103       for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
06104          if (i != 0) out << ", ";
06105          out << GetXaxis()->GetXbins()->fArray[i];
06106       }
06107       out << "}; " << endl;
06108    }
06109    // If the histogram is 2 or 3 dimensional, check if the histogram
06110    // has equidistant Y bins or not.  If not, we create an array
06111    // holding the bins.
06112    if (fDimension > 1 && GetYaxis()->GetXbins()->fN &&
06113       GetYaxis()->GetXbins()->fArray) {
06114          nonEqiY = kTRUE;
06115          nyaxis++;
06116          syaxis += nyaxis;
06117          out << "   Double_t "<<syaxis<<"[" << GetYaxis()->GetXbins()->fN
06118             << "] = {";
06119          for (i = 0; i < GetYaxis()->GetXbins()->fN; i++) {
06120             if (i != 0) out << ", ";
06121             out << GetYaxis()->GetXbins()->fArray[i];
06122          }
06123          out << "}; " << endl;
06124    }
06125    // IF the histogram is 3 dimensional, check if the histogram
06126    // has equidistant Z bins or not.  If not, we create an array
06127    // holding the bins.
06128    if (fDimension > 2 && GetZaxis()->GetXbins()->fN &&
06129       GetZaxis()->GetXbins()->fArray) {
06130          nonEqiZ = kTRUE;
06131          nzaxis++;
06132          szaxis += nzaxis;
06133          out << "   Double_t "<<szaxis<<"[" << GetZaxis()->GetXbins()->fN
06134             << "] = {";
06135          for (i = 0; i < GetZaxis()->GetXbins()->fN; i++) {
06136             if (i != 0) out << ", ";
06137             out << GetZaxis()->GetXbins()->fArray[i];
06138          }
06139          out << "}; " << endl;
06140    }
06141 
06142    char quote = '"';
06143    out <<"   "<<endl;
06144    out <<"   "<< ClassName() <<" *";
06145 
06146    //histogram pointer has by default teh histogram name.
06147    //however, in case histogram has no directory, it is safer to add a incremental suffix
06148    static Int_t hcounter = 0;
06149    TString histName = GetName();
06150    if (!fDirectory && !histName.Contains("Graph")) {
06151       hcounter++;
06152       histName += "__";
06153       histName += hcounter;
06154    }
06155    const char *hname = histName.Data();
06156 
06157 
06158    out << hname << " = new " << ClassName() << "(" << quote
06159       << hname << quote << "," << quote<< GetTitle() << quote
06160       << "," << GetXaxis()->GetNbins();
06161    if (nonEqiX)
06162       out << ", "<<sxaxis;
06163    else
06164       out << "," << GetXaxis()->GetXmin()
06165       << "," << GetXaxis()->GetXmax();
06166    if (fDimension > 1) {
06167       out << "," << GetYaxis()->GetNbins();
06168       if (nonEqiY)
06169          out << ", "<<syaxis;
06170       else
06171          out << "," << GetYaxis()->GetXmin()
06172          << "," << GetYaxis()->GetXmax();
06173    }
06174    if (fDimension > 2) {
06175       out << "," << GetZaxis()->GetNbins();
06176       if (nonEqiZ)
06177          out << ", "<<szaxis;
06178       else
06179          out << "," << GetZaxis()->GetXmin()
06180          << "," << GetZaxis()->GetXmax();
06181    }
06182    out << ");" << endl;
06183 
06184    // save bin contents
06185    Int_t bin;
06186    for (bin=0;bin<fNcells;bin++) {
06187       Double_t bc = GetBinContent(bin);
06188       if (bc) {
06189          out<<"   "<<hname<<"->SetBinContent("<<bin<<","<<bc<<");"<<endl;
06190       }
06191    }
06192 
06193    // save bin errors
06194    if (fSumw2.fN) {
06195       for (bin=0;bin<fNcells;bin++) {
06196          Double_t be = GetBinError(bin);
06197          if (be) {
06198             out<<"   "<<hname<<"->SetBinError("<<bin<<","<<be<<");"<<endl;
06199          }
06200       }
06201    }
06202 
06203    TH1::SavePrimitiveHelp(out, hname, option);
06204 }
06205 
06206 //______________________________________________________________________________
06207 void TH1::SavePrimitiveHelp(ostream &out, const char *hname, Option_t *option /*= ""*/)
06208 {
06209    // helper function for the SavePrimitive functions from TH1
06210    // or classes derived from TH1, eg TProfile, TProfile2D.
06211 
06212    char quote = '"';
06213    if (TMath::Abs(GetBarOffset()) > 1e-5) {
06214       out<<"   "<<hname<<"->SetBarOffset("<<GetBarOffset()<<");"<<endl;
06215    }
06216    if (TMath::Abs(GetBarWidth()-1) > 1e-5) {
06217       out<<"   "<<hname<<"->SetBarWidth("<<GetBarWidth()<<");"<<endl;
06218    }
06219    if (fMinimum != -1111) {
06220       out<<"   "<<hname<<"->SetMinimum("<<fMinimum<<");"<<endl;
06221    }
06222    if (fMaximum != -1111) {
06223       out<<"   "<<hname<<"->SetMaximum("<<fMaximum<<");"<<endl;
06224    }
06225    if (fNormFactor != 0) {
06226       out<<"   "<<hname<<"->SetNormFactor("<<fNormFactor<<");"<<endl;
06227    }
06228    if (fEntries != 0) {
06229       out<<"   "<<hname<<"->SetEntries("<<fEntries<<");"<<endl;
06230    }
06231    if (fDirectory == 0) {
06232       out<<"   "<<hname<<"->SetDirectory(0);"<<endl;
06233    }
06234    if (TestBit(kNoStats)) {
06235       out<<"   "<<hname<<"->SetStats(0);"<<endl;
06236    }
06237    if (fOption.Length() != 0) {
06238       out<<"   "<<hname<<"->SetOption("<<quote<<fOption.Data()<<quote<<");"<<endl;
06239    }
06240 
06241    // save contour levels
06242    Int_t ncontours = GetContour();
06243    if (ncontours > 0) {
06244       out<<"   "<<hname<<"->SetContour("<<ncontours<<");"<<endl;
06245       Double_t zlevel;
06246       for (Int_t bin=0;bin<ncontours;bin++) {
06247          if (gPad->GetLogz()) {
06248             zlevel = TMath::Power(10,GetContourLevel(bin));
06249          } else {
06250             zlevel = GetContourLevel(bin);
06251          }
06252          out<<"   "<<hname<<"->SetContourLevel("<<bin<<","<<zlevel<<");"<<endl;
06253       }
06254    }
06255 
06256    // save list of functions
06257    TObjOptLink *lnk = (TObjOptLink*)fFunctions->FirstLink();
06258    TObject *obj;
06259    while (lnk) {
06260       obj = lnk->GetObject();
06261       obj->SavePrimitive(out,"nodraw");
06262       if (obj->InheritsFrom(TF1::Class())) {
06263          out<<"   "<<hname<<"->GetListOfFunctions()->Add("<<obj->GetName()<<");"<<endl;
06264       } else if (obj->InheritsFrom("TPaveStats")) {
06265          out<<"   "<<hname<<"->GetListOfFunctions()->Add(ptstats);"<<endl;
06266          out<<"   ptstats->SetParent("<<hname<<"->GetListOfFunctions());"<<endl;
06267       } else {
06268          out<<"   "<<hname<<"->GetListOfFunctions()->Add("<<obj->GetName()<<","<<quote<<lnk->GetOption()<<quote<<");"<<endl;
06269       }
06270       lnk = (TObjOptLink*)lnk->Next();
06271    }
06272 
06273    // save attributes
06274    SaveFillAttributes(out,hname,0,1001);
06275    SaveLineAttributes(out,hname,1,1,1);
06276    SaveMarkerAttributes(out,hname,1,1,1);
06277    fXaxis.SaveAttributes(out,hname,"->GetXaxis()");
06278    fYaxis.SaveAttributes(out,hname,"->GetYaxis()");
06279    fZaxis.SaveAttributes(out,hname,"->GetZaxis()");
06280    TString opt = option;
06281    opt.ToLower();
06282    if (!opt.Contains("nodraw")) {
06283       out<<"   "<<hname<<"->Draw("
06284          <<quote<<option<<quote<<");"<<endl;
06285    }
06286 }
06287 
06288 //______________________________________________________________________________
06289 void TH1::UseCurrentStyle()
06290 {
06291    //   Copy current attributes from/to current style
06292 
06293    if (!gStyle) return;
06294    if (gStyle->IsReading()) {
06295       fXaxis.ResetAttAxis("X");
06296       fYaxis.ResetAttAxis("Y");
06297       fZaxis.ResetAttAxis("Z");
06298       SetBarOffset(gStyle->GetBarOffset());
06299       SetBarWidth(gStyle->GetBarWidth());
06300       SetFillColor(gStyle->GetHistFillColor());
06301       SetFillStyle(gStyle->GetHistFillStyle());
06302       SetLineColor(gStyle->GetHistLineColor());
06303       SetLineStyle(gStyle->GetHistLineStyle());
06304       SetLineWidth(gStyle->GetHistLineWidth());
06305       SetMarkerColor(gStyle->GetMarkerColor());
06306       SetMarkerStyle(gStyle->GetMarkerStyle());
06307       SetMarkerSize(gStyle->GetMarkerSize());
06308       Int_t dostat = gStyle->GetOptStat();
06309       if (gStyle->GetOptFit() && !dostat) dostat = 1000000001;
06310       SetStats(dostat);
06311    } else {
06312       gStyle->SetBarOffset(fBarOffset);
06313       gStyle->SetBarWidth(fBarWidth);
06314       gStyle->SetHistFillColor(GetFillColor());
06315       gStyle->SetHistFillStyle(GetFillStyle());
06316       gStyle->SetHistLineColor(GetLineColor());
06317       gStyle->SetHistLineStyle(GetLineStyle());
06318       gStyle->SetHistLineWidth(GetLineWidth());
06319       gStyle->SetMarkerColor(GetMarkerColor());
06320       gStyle->SetMarkerStyle(GetMarkerStyle());
06321       gStyle->SetMarkerSize(GetMarkerSize());
06322       gStyle->SetOptStat(TestBit(kNoStats));
06323    }
06324    TIter next(GetListOfFunctions());
06325    TObject *obj;
06326 
06327    while ((obj = next())) {
06328       obj->UseCurrentStyle();
06329    }
06330 }
06331 
06332 //______________________________________________________________________________
06333 Double_t TH1::GetMean(Int_t axis) const
06334 {
06335    //  For axis = 1,2 or 3 returns the mean value of the histogram along
06336    //  X,Y or Z axis.
06337    //  For axis = 11, 12, 13 returns the standard error of the mean value
06338    //  of the histogram along X, Y or Z axis
06339    //
06340    //  Note that the mean value/RMS is computed using the bins in the currently
06341    //  defined range (see TAxis::SetRange). By default the range includes
06342    //  all bins from 1 to nbins included, excluding underflows and overflows.
06343    //  To force the underflows and overflows in the computation, one must
06344    //  call the static function TH1::StatOverflows(kTRUE) before filling
06345    //  the histogram.
06346 
06347 
06348 
06349    //   -*-*-*-*-*-*Return mean value of this histogram along the X axis*-*-*-*-*
06350    //               ====================================================
06351    //  Note that the mean value/RMS is computed using the bins in the currently
06352    //  defined range (see TAxis::SetRange). By default the range includes
06353    //  all bins from 1 to nbins included, excluding underflows and overflows.
06354    //  To force the underflows and overflows in the computation, one must
06355    //  call the static function TH1::StatOverflows(kTRUE) before filling
06356    //  the histogram.
06357 
06358    if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
06359    Double_t stats[kNstat];
06360    for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
06361    GetStats(stats);
06362    if (stats[0] == 0) return 0;
06363    if (axis<4){
06364       Int_t ax[3] = {2,4,7};
06365       return stats[ax[axis-1]]/stats[0];
06366    } else {
06367       // mean error = RMS / sqrt( Neff )
06368       Double_t rms = GetRMS(axis-10);
06369       Double_t neff = GetEffectiveEntries();
06370       return ( neff > 0 ? rms/TMath::Sqrt(neff) : 0. );
06371    }
06372 }
06373 
06374 //______________________________________________________________________________
06375 Double_t TH1::GetMeanError(Int_t axis) const
06376 {
06377    //   -*-*-*-*-*-*Return standard error of mean of this histogram along the X axis*-*-*-*-*
06378    //               ====================================================
06379    //  Note that the mean value/RMS is computed using the bins in the currently
06380    //  defined range (see TAxis::SetRange). By default the range includes
06381    //  all bins from 1 to nbins included, excluding underflows and overflows.
06382    //  To force the underflows and overflows in the computation, one must
06383    //  call the static function TH1::StatOverflows(kTRUE) before filling
06384    //  the histogram.
06385    //  Also note, that although the definition of standard error doesn't include the
06386    //  assumption of normality, many uses of this feature implicitly assume it.
06387 
06388    return GetMean(axis+10);
06389 }
06390 
06391 //______________________________________________________________________________
06392 Double_t TH1::GetRMS(Int_t axis) const
06393 {
06394    //  For axis = 1,2 or 3 returns the Sigma value of the histogram along
06395    //  X, Y or Z axis
06396    //  For axis = 11, 12 or 13 returns the error of RMS estimation along
06397    //  X, Y or Z axis for Normal distribution
06398    //
06399    //     Note that the mean value/sigma is computed using the bins in the currently
06400    //  defined range (see TAxis::SetRange). By default the range includes
06401    //  all bins from 1 to nbins included, excluding underflows and overflows.
06402    //  To force the underflows and overflows in the computation, one must
06403    //  call the static function TH1::StatOverflows(kTRUE) before filling
06404    //  the histogram.
06405    //  Note that this function returns the Standard Deviation (Sigma)
06406    //  of the distribution (not RMS).
06407    //  The Sigma estimate is computed as Sqrt((1/N)*(Sum(x_i-x_mean)^2))
06408    //  The name "RMS" was introduced many years ago (Hbook/PAW times).
06409    //  We kept the name for continuity.
06410 
06411    if (axis<1 || (axis>3 && axis<11) || axis>13) return 0;
06412 
06413    Double_t x, rms2, stats[kNstat];
06414    for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
06415    GetStats(stats);
06416    if (stats[0] == 0) return 0;
06417    Int_t ax[3] = {2,4,7};
06418    Int_t axm = ax[axis%10 - 1];
06419    x    = stats[axm]/stats[0];
06420    rms2 = TMath::Abs(stats[axm+1]/stats[0] -x*x);
06421    if (axis<10)
06422       return TMath::Sqrt(rms2);
06423    else {
06424       // The right formula for RMS error depends on 4th momentum (see Kendall-Stuart Vol 1 pag 243)
06425       // formula valid for only gaussian distribution ( 4-th momentum =  3 * sigma^4 )
06426       Double_t neff = GetEffectiveEntries();
06427       return ( neff > 0 ? TMath::Sqrt(rms2/(2*neff) ) : 0. );
06428    }
06429 }
06430 
06431 //______________________________________________________________________________
06432 Double_t TH1::GetRMSError(Int_t axis) const
06433 {
06434    //  Return error of RMS estimation for Normal distribution
06435    //
06436    //  Note that the mean value/RMS is computed using the bins in the currently
06437    //  defined range (see TAxis::SetRange). By default the range includes
06438    //  all bins from 1 to nbins included, excluding underflows and overflows.
06439    //  To force the underflows and overflows in the computation, one must
06440    //  call the static function TH1::StatOverflows(kTRUE) before filling
06441    //  the histogram.
06442    //  Value returned is standard deviation of sample standard deviation.
06443    //  Note that it is an approximated value which is valid only in the case that the
06444    //  original data distribution is Normal. The correct one would require
06445    //  the 4-th momentum value, which cannot be accuratly estimated from an histogram since
06446    //  the x-information for all entries is not kept.
06447 
06448    return GetRMS(axis+10);
06449 }
06450 
06451 //______________________________________________________________________________
06452 Double_t TH1::GetSkewness(Int_t axis) const
06453 {
06454    //For axis = 1, 2 or 3 returns skewness of the histogram along x, y or z axis.
06455    //For axis = 11, 12 or 13 returns the approximate standard error of skewness
06456    //of the histogram along x, y or z axis
06457    //Note, that since third and fourth moment are not calculated
06458    //at the fill time, skewness and its standard error are computed bin by bin
06459 
06460 
06461    if (axis > 0 && axis <= 3){
06462 
06463       Double_t mean = GetMean(axis);
06464       Double_t rms = GetRMS(axis);
06465       Double_t rms3 = rms*rms*rms;
06466 
06467       Int_t firstBinX = fXaxis.GetFirst();
06468       Int_t lastBinX  = fXaxis.GetLast();
06469       Int_t firstBinY = fYaxis.GetFirst();
06470       Int_t lastBinY  = fYaxis.GetLast();
06471       Int_t firstBinZ = fZaxis.GetFirst();
06472       Int_t lastBinZ  = fZaxis.GetLast();
06473       // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
06474       if (fgStatOverflows) {
06475         if ( !fXaxis.TestBit(TAxis::kAxisRange) ) {
06476             if (firstBinX == 1) firstBinX = 0;
06477             if (lastBinX ==  fXaxis.GetNbins() ) lastBinX += 1;
06478          }
06479          if ( !fYaxis.TestBit(TAxis::kAxisRange) ) {
06480             if (firstBinY == 1) firstBinY = 0;
06481             if (lastBinY ==  fYaxis.GetNbins() ) lastBinY += 1;
06482          }
06483          if ( !fZaxis.TestBit(TAxis::kAxisRange) ) {
06484             if (firstBinZ == 1) firstBinZ = 0;
06485             if (lastBinZ ==  fZaxis.GetNbins() ) lastBinZ += 1;
06486          }
06487       }
06488 
06489       Double_t x = 0;
06490       Double_t sum=0;
06491       Double_t np=0;
06492       for (Int_t  binx = firstBinX; binx <= lastBinX; binx++) {
06493          for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
06494             for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
06495                if (axis==1 ) x = fXaxis.GetBinCenter(binx);
06496                else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
06497                else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
06498                Double_t w = GetBinContent(binx,biny,binz);
06499                np+=w;
06500                sum+=w*(x-mean)*(x-mean)*(x-mean);
06501             }
06502          }
06503       }
06504       sum/=np*rms3;
06505       return sum;
06506    }
06507    else if (axis > 10 && axis <= 13) {
06508       //compute standard error of skewness
06509       // assume parent normal distribution use formula from  Kendall-Stuart, Vol 1 pag 243, second edition
06510       Double_t neff = GetEffectiveEntries();
06511       return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
06512    }
06513    else {
06514       Error("GetSkewness", "illegal value of parameter");
06515       return 0;
06516    }
06517 }
06518 
06519 //______________________________________________________________________________
06520 Double_t TH1::GetKurtosis(Int_t axis) const
06521 {
06522    //For axis =1, 2 or 3 returns kurtosis of the histogram along x, y or z axis.
06523    //Kurtosis(gaussian(0, 1)) = 0.
06524    //For axis =11, 12 or 13 returns the approximate standard error of kurtosis
06525    //of the histogram along x, y or z axis
06526    //Note, that since third and fourth moment are not calculated
06527    //at the fill time, kurtosis and its standard error are computed bin by bin
06528 
06529    if (axis > 0 && axis <= 3){
06530 
06531       Double_t mean = GetMean(axis);
06532       Double_t rms = GetRMS(axis);
06533       Double_t rms4 = rms*rms*rms*rms;
06534 
06535       Int_t firstBinX = fXaxis.GetFirst();
06536       Int_t lastBinX  = fXaxis.GetLast();
06537       Int_t firstBinY = fYaxis.GetFirst();
06538       Int_t lastBinY  = fYaxis.GetLast();
06539       Int_t firstBinZ = fZaxis.GetFirst();
06540       Int_t lastBinZ  = fZaxis.GetLast();
06541       // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
06542       if (fgStatOverflows) {
06543         if ( !fXaxis.TestBit(TAxis::kAxisRange) ) {
06544             if (firstBinX == 1) firstBinX = 0;
06545             if (lastBinX ==  fXaxis.GetNbins() ) lastBinX += 1;
06546          }
06547          if ( !fYaxis.TestBit(TAxis::kAxisRange) ) {
06548             if (firstBinY == 1) firstBinY = 0;
06549             if (lastBinY ==  fYaxis.GetNbins() ) lastBinY += 1;
06550          }
06551          if ( !fZaxis.TestBit(TAxis::kAxisRange) ) {
06552             if (firstBinZ == 1) firstBinZ = 0;
06553             if (lastBinZ ==  fZaxis.GetNbins() ) lastBinZ += 1;
06554          }
06555       }
06556 
06557       Double_t x = 0;
06558       Double_t sum=0;
06559       Double_t np=0;
06560       for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
06561          for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
06562             for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
06563                if (axis==1 ) x = fXaxis.GetBinCenter(binx);
06564                else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
06565                else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
06566                Double_t w = GetBinContent(binx,biny,binz);
06567                np+=w;
06568                sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
06569             }
06570          }
06571       }
06572       sum/=(np*rms4);
06573       return sum-3;
06574 
06575    } else if (axis > 10 && axis <= 13) {
06576       //compute standard error of skewness
06577       // assume parent normal distribution use formula from  Kendall-Stuart, Vol 1 pag 243, second edition
06578       Double_t neff = GetEffectiveEntries();
06579       return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
06580    }
06581    else {
06582       Error("GetKurtosis", "illegal value of parameter");
06583       return 0;
06584    }
06585 }
06586 
06587 
06588 //______________________________________________________________________________
06589 void TH1::GetStats(Double_t *stats) const
06590 {
06591    // fill the array stats from the contents of this histogram
06592    // The array stats must be correctly dimensionned in the calling program.
06593    // stats[0] = sumw
06594    // stats[1] = sumw2
06595    // stats[2] = sumwx
06596    // stats[3] = sumwx2
06597    //
06598    // If no axis-subrange is specified (via TAxis::SetRange), the array stats
06599    // is simply a copy of the statistics quantities computed at filling time.
06600    // If a sub-range is specified, the function recomputes these quantities
06601    // from the bin contents in the current axis range.
06602    //
06603    //  Note that the mean value/RMS is computed using the bins in the currently
06604    //  defined range (see TAxis::SetRange). By default the range includes
06605    //  all bins from 1 to nbins included, excluding underflows and overflows.
06606    //  To force the underflows and overflows in the computation, one must
06607    //  call the static function TH1::StatOverflows(kTRUE) before filling
06608    //  the histogram.
06609 
06610    if (fBuffer) ((TH1*)this)->BufferEmpty();
06611 
06612    // Loop on bins (possibly including underflows/overflows)
06613    Int_t bin, binx;
06614    Double_t w,err;
06615    Double_t x;
06616    if ((fTsumw == 0 && fEntries > 0) || fXaxis.TestBit(TAxis::kAxisRange)) {
06617       for (bin=0;bin<4;bin++) stats[bin] = 0;
06618 
06619       Int_t firstBinX = fXaxis.GetFirst();
06620       Int_t lastBinX  = fXaxis.GetLast();
06621       // include underflow/overflow if TH1::StatOverflows(kTRUE) in case no range is set on the axis
06622       if (fgStatOverflows && !fXaxis.TestBit(TAxis::kAxisRange)) {
06623          if (firstBinX == 1) firstBinX = 0;
06624          if (lastBinX ==  fXaxis.GetNbins() ) lastBinX += 1;
06625       }
06626       for (binx = firstBinX; binx <= lastBinX; binx++) {
06627          x   = fXaxis.GetBinCenter(binx);
06628          w   = TMath::Abs(GetBinContent(binx));
06629          err = TMath::Abs(GetBinError(binx));
06630          stats[0] += w;
06631          stats[1] += err*err;
06632          stats[2] += w*x;
06633          stats[3] += w*x*x;
06634       }
06635    } else {
06636       stats[0] = fTsumw;
06637       stats[1] = fTsumw2;
06638       stats[2] = fTsumwx;
06639       stats[3] = fTsumwx2;
06640    }
06641 }
06642 
06643 //______________________________________________________________________________
06644 void TH1::PutStats(Double_t *stats)
06645 {
06646    // Replace current statistics with the values in array stats
06647 
06648    fTsumw   = stats[0];
06649    fTsumw2  = stats[1];
06650    fTsumwx  = stats[2];
06651    fTsumwx2 = stats[3];
06652 }
06653 
06654 //______________________________________________________________________________
06655 void TH1::ResetStats()
06656 {
06657    // Reset the statistics including the number of entries
06658    // and replace with values calculates from bin content
06659    // The number of entries is set to the total bin content or (in case of weighted histogram)
06660    // to number of effective entries
06661    Double_t stats[kNstat] = {0};
06662    fTsumw = 0;
06663    fEntries = 1; // to force re-calculation of the statistics in TH1::GetStats
06664    GetStats(stats);
06665    PutStats(stats);
06666    fEntries = TMath::Abs(fTsumw);
06667    // use effective entries for weighted histograms:  (sum_w) ^2 / sum_w2
06668    if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
06669 }
06670 
06671 //______________________________________________________________________________
06672 Double_t TH1::GetSumOfWeights() const
06673 {
06674    //   -*-*-*-*-*-*Return the sum of weights excluding under/overflows*-*-*-*-*
06675    //               ===================================================
06676    Int_t bin,binx,biny,binz;
06677    Double_t sum =0;
06678    for(binz=1; binz<=fZaxis.GetNbins(); binz++) {
06679       for(biny=1; biny<=fYaxis.GetNbins(); biny++) {
06680          for(binx=1; binx<=fXaxis.GetNbins(); binx++) {
06681             bin = GetBin(binx,biny,binz);
06682             sum += GetBinContent(bin);
06683          }
06684       }
06685    }
06686    return sum;
06687 }
06688 
06689 
06690 //______________________________________________________________________________
06691 Double_t TH1::Integral(Option_t *option) const
06692 {
06693    //Return integral of bin contents. Only bins in the bins range are considered.
06694    // By default the integral is computed as the sum of bin contents in the range.
06695    // if option "width" is specified, the integral is the sum of
06696    // the bin contents multiplied by the bin width in x.
06697 
06698    return Integral(fXaxis.GetFirst(),fXaxis.GetLast(),option);
06699 }
06700 
06701 //______________________________________________________________________________
06702 Double_t TH1::Integral(Int_t binx1, Int_t binx2, Option_t *option) const
06703 {
06704    //Return integral of bin contents in range [binx1,binx2]
06705    // By default the integral is computed as the sum of bin contents in the range.
06706    // if option "width" is specified, the integral is the sum of
06707    // the bin contents multiplied by the bin width in x.
06708    double err = 0;
06709    return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
06710 }
06711 //______________________________________________________________________________
06712 Double_t TH1::IntegralAndError(Int_t binx1, Int_t binx2, Double_t & error, Option_t *option) const
06713 {
06714    //Return integral of bin contents in range [binx1,binx2] and its error
06715    // By default the integral is computed as the sum of bin contents in the range.
06716    // if option "width" is specified, the integral is the sum of
06717    // the bin contents multiplied by the bin width in x.
06718    // the error is computed using error propagation from the bin errors assumming that
06719    // all the bins are uncorrelated
06720    return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
06721 }
06722 
06723 
06724 //______________________________________________________________________________
06725 Double_t TH1::DoIntegral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error ,
06726                           Option_t *option, Bool_t doError) const
06727 {
06728    // internal function compute integral and optionally the error  between the limits
06729    // specified by the bin number values working for all histograms (1D, 2D and 3D)
06730 
06731    Int_t nbinsx = GetNbinsX();
06732    if (binx1 < 0) binx1 = 0;
06733    if (binx2 > nbinsx+1 || binx2 < binx1) binx2 = nbinsx+1;
06734    if (GetDimension() > 1) {
06735       Int_t nbinsy = GetNbinsY();
06736       if (biny1 < 0) biny1 = 0;
06737       if (biny2 > nbinsy+1 || biny2 < biny1) biny2 = nbinsy+1;
06738    } else {
06739       biny1 = 0; biny2 = 0;
06740    }
06741    if (GetDimension() > 2) {
06742       Int_t nbinsz = GetNbinsZ();
06743       if (binz1 < 0) binz1 = 0;
06744       if (binz2 > nbinsz+1 || binz2 < binz1) binz2 = nbinsz+1;
06745    } else {
06746       binz1 = 0; binz2 = 0;
06747    }
06748 
06749    //   - Loop on bins in specified range
06750    TString opt = option;
06751    opt.ToLower();
06752    Bool_t width   = kFALSE;
06753    if (opt.Contains("width")) width = kTRUE;
06754 
06755 
06756    Double_t dx = 1.;
06757    Double_t dy = 1.;
06758    Double_t dz = 1.;
06759    Double_t integral = 0;
06760    Double_t igerr2 = 0;
06761    for (Int_t binx = binx1; binx <= binx2; ++binx) {
06762       if (width) dx = fXaxis.GetBinWidth(binx);
06763       for (Int_t biny = biny1; biny <= biny2; ++biny) {
06764          if (width) dy = fYaxis.GetBinWidth(biny);
06765          for (Int_t binz = binz1; binz <= binz2; ++binz) {
06766             if (width) dz = fZaxis.GetBinWidth(binz);
06767             Int_t bin  = GetBin(binx, biny, binz);
06768             if (width) integral += GetBinContent(bin)*dx*dy*dz;
06769             else       integral += GetBinContent(bin);
06770             if (doError) {
06771                if (width)  igerr2 += GetBinError(bin)*GetBinError(bin)*dx*dx*dy*dy*dz*dz;
06772                else        igerr2 += GetBinError(bin)*GetBinError(bin);
06773             }
06774          }
06775       }
06776    }
06777 
06778    if (doError) error = TMath::Sqrt(igerr2);
06779    return integral;
06780 }
06781 
06782 
06783 //______________________________________________________________________________
06784 Double_t TH1::KolmogorovTest(const TH1 *h2, Option_t *option) const
06785 {
06786    //  Statistical test of compatibility in shape between
06787    //  THIS histogram and h2, using Kolmogorov test.
06788    //
06789    //     Default: Ignore under- and overflow bins in comparison
06790    //
06791    //     option is a character string to specify options
06792    //         "U" include Underflows in test  (also for 2-dim)
06793    //         "O" include Overflows     (also valid for 2-dim)
06794    //         "N" include comparison of normalizations
06795    //         "D" Put out a line of "Debug" printout
06796    //         "M" Return the Maximum Kolmogorov distance instead of prob
06797    //         "X" Run the pseudo experiments post-processor with the following procedure:
06798    //             make pseudoexperiments based on random values from the parent
06799    //             distribution and compare the KS distance of the pseudoexperiment
06800    //             to the parent distribution. Bin the KS distances in a histogram,
06801    //             and then take the integral of all the KS values above the value
06802    //             obtained from the original data to Monte Carlo distribution.
06803    //             The number of pseudo-experiments nEXPT is currently fixed at 1000.
06804    //             The function returns the integral.
06805    //             (thanks to Ben Kilminster to submit this procedure). Note that
06806    //             this option "X" is much slower.
06807    //
06808    //   The returned function value is the probability of test
06809    //       (much less than one means NOT compatible)
06810    //
06811    //  Code adapted by Rene Brun from original HBOOK routine HDIFF
06812    //
06813    //  NOTE1
06814    //  A good description of the Kolmogorov test can be seen at:
06815    //    http://www.itl.nist.gov/div898/handbook/eda/section3/eda35g.htm
06816    //
06817    //  NOTE2
06818    //  see also alternative function TH1::Chi2Test
06819    //  The Kolmogorov test is assumed to give better results than Chi2Test
06820    //  in case of histograms with low statistics.
06821    //
06822    //  NOTE3 (Jan Conrad, Fred James)
06823    //  "The returned value PROB is calculated such that it will be
06824    //  uniformly distributed between zero and one for compatible histograms,
06825    //  provided the data are not binned (or the number of bins is very large
06826    //  compared with the number of events). Users who have access to unbinned
06827    //  data and wish exact confidence levels should therefore not put their data
06828    //  into histograms, but should call directly TMath::KolmogorovTest. On
06829    //  the other hand, since TH1 is a convenient way of collecting data and
06830    //  saving space, this function has been provided. However, the values of
06831    //  PROB for binned data will be shifted slightly higher than expected,
06832    //  depending on the effects of the binning. For example, when comparing two
06833    //  uniform distributions of 500 events in 100 bins, the values of PROB,
06834    //  instead of being exactly uniformly distributed between zero and one, have
06835    //  a mean value of about 0.56. We can apply a useful
06836    //  rule: As long as the bin width is small compared with any significant
06837    //  physical effect (for example the experimental resolution) then the binning
06838    //  cannot have an important effect. Therefore, we believe that for all
06839    //  practical purposes, the probability value PROB is calculated correctly
06840    //  provided the user is aware that:
06841    //     1. The value of PROB should not be expected to have exactly the correct
06842    //  distribution for binned data.
06843    //     2. The user is responsible for seeing to it that the bin widths are
06844    //  small compared with any physical phenomena of interest.
06845    //     3. The effect of binning (if any) is always to make the value of PROB
06846    //  slightly too big. That is, setting an acceptance criterion of (PROB>0.05
06847    //  will assure that at most 5% of truly compatible histograms are rejected,
06848    //  and usually somewhat less."
06849 
06850    TString opt = option;
06851    opt.ToUpper();
06852 
06853    Double_t prob = 0;
06854    TH1 *h1 = (TH1*)this;
06855    if (h2 == 0) return 0;
06856    TAxis *axis1 = h1->GetXaxis();
06857    TAxis *axis2 = h2->GetXaxis();
06858    Int_t ncx1   = axis1->GetNbins();
06859    Int_t ncx2   = axis2->GetNbins();
06860 
06861    // Check consistency of dimensions
06862    if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
06863       Error("KolmogorovTest","Histograms must be 1-D\n");
06864       return 0;
06865    }
06866 
06867    // Check consistency in number of channels
06868    if (ncx1 != ncx2) {
06869       Error("KolmogorovTest","Number of channels is different, %d and %d\n",ncx1,ncx2);
06870       return 0;
06871    }
06872 
06873    // Check consistency in channel edges
06874    Double_t difprec = 1e-5;
06875    Double_t diff1 = TMath::Abs(axis1->GetXmin() - axis2->GetXmin());
06876    Double_t diff2 = TMath::Abs(axis1->GetXmax() - axis2->GetXmax());
06877    if (diff1 > difprec || diff2 > difprec) {
06878       Error("KolmogorovTest","histograms with different binning");
06879       return 0;
06880    }
06881 
06882    Bool_t afunc1 = kFALSE;
06883    Bool_t afunc2 = kFALSE;
06884    Double_t sum1 = 0, sum2 = 0;
06885    Double_t ew1, ew2, w1 = 0, w2 = 0;
06886    Int_t bin;
06887    Int_t ifirst = 1;
06888    Int_t ilast = ncx1;
06889    // integral of all bins (use underflow/overflow if option)
06890    if (opt.Contains("U")) ifirst = 0;
06891    if (opt.Contains("O")) ilast = ncx1 +1;
06892    for (bin = ifirst; bin <= ilast; bin++) {
06893       sum1 += h1->GetBinContent(bin);
06894       sum2 += h2->GetBinContent(bin);
06895       ew1   = h1->GetBinError(bin);
06896       ew2   = h2->GetBinError(bin);
06897       w1   += ew1*ew1;
06898       w2   += ew2*ew2;
06899    }
06900    if (sum1 == 0) {
06901       Error("KolmogorovTest","Histogram1 %s integral is zero\n",h1->GetName());
06902       return 0;
06903    }
06904    if (sum2 == 0) {
06905       Error("KolmogorovTest","Histogram2 %s integral is zero\n",h2->GetName());
06906       return 0;
06907    }
06908 
06909    // calculate the effective entries.
06910    // the case when errors are zero (w1 == 0 or w2 ==0) are equivalent to
06911    // compare to a function. In that case the rescaling is done only on sqrt(esum2) or sqrt(esum1)
06912    Double_t esum1 = 0, esum2 = 0;
06913    if (w1 > 0)
06914       esum1 = sum1 * sum1 / w1;
06915    else
06916       afunc1 = kTRUE;    // use later for calculating z
06917 
06918    if (w2 > 0)
06919       esum2 = sum2 * sum2 / w2;
06920    else
06921       afunc2 = kTRUE;    // use later for calculating z
06922 
06923    if (afunc2 && afunc1) {
06924       Error("KolmogorovTest","Errors are zero for both histograms\n");
06925       return 0;
06926    }
06927 
06928 
06929    Double_t s1 = 1/sum1;
06930    Double_t s2 = 1/sum2;
06931 
06932    // Find largest difference for Kolmogorov Test
06933    Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
06934 
06935    for (bin=ifirst;bin<=ilast;bin++) {
06936       rsum1 += s1*h1->GetBinContent(bin);
06937       rsum2 += s2*h2->GetBinContent(bin);
06938       dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
06939    }
06940 
06941    // Get Kolmogorov probability
06942    Double_t z, prb1=0, prb2=0, prb3=0;
06943 
06944    // case h1 is exact (has zero errors)
06945   if  (afunc1)
06946       z = dfmax*TMath::Sqrt(esum2);
06947   // case h2 has zero errors
06948   else if (afunc2)
06949       z = dfmax*TMath::Sqrt(esum1);
06950   else
06951      // for comparison between two data sets
06952      z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
06953 
06954    prob = TMath::KolmogorovProb(z);
06955 
06956    // option N to combine normalization makes sense if both afunc1 and afunc2 are false
06957    if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
06958       // Combine probabilities for shape and normalization,
06959       prb1 = prob;
06960       Double_t d12    = esum1-esum2;
06961       Double_t chi2   = d12*d12/(esum1+esum2);
06962       prb2 = TMath::Prob(chi2,1);
06963       // see Eadie et al., section 11.6.2
06964       if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
06965       else                      prob = 0;
06966    }
06967    // X option. Pseudo-experiments post-processor to determine KS probability
06968    const Int_t nEXPT = 1000;
06969    if (opt.Contains("X") && !(afunc1 || afunc2 ) ) {
06970       Double_t dSEXPT;
06971       TH1 *hExpt = (TH1*)(gDirectory ? gDirectory->CloneObject(this,kFALSE) : gROOT->CloneObject(this,kFALSE));
06972       // make nEXPT experiments (this should be a parameter)
06973       prb3 = 0;
06974       for (Int_t i=0; i < nEXPT; i++) {
06975          hExpt->Reset();
06976          hExpt->FillRandom(h1,(Int_t)esum2);
06977          dSEXPT = KolmogorovTest(hExpt,"M");
06978          if (dSEXPT>dfmax) prb3 += 1.0;
06979       }
06980       prb3 /= (Double_t)nEXPT;
06981       delete hExpt;
06982    }
06983 
06984    // debug printout
06985    if (opt.Contains("D")) {
06986       printf(" Kolmo Prob  h1 = %s, sum bin content =%g  effective entries =%g\n",h1->GetName(),sum1,esum1);
06987       printf(" Kolmo Prob  h2 = %s, sum bin content =%g  effective entries =%g\n",h2->GetName(),sum2,esum2);
06988       printf(" Kolmo Prob     = %g, Max Dist = %g\n",prob,dfmax);
06989       if (opt.Contains("N"))
06990          printf(" Kolmo Prob     = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
06991       if (opt.Contains("X"))
06992          printf(" Kolmo Prob     = %f with %d pseudo-experiments\n",prb3,nEXPT);
06993    }
06994    // This numerical error condition should never occur:
06995    if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
06996    if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
06997 
06998    if(opt.Contains("M"))      return dfmax;
06999    else if(opt.Contains("X")) return prb3;
07000    else                       return prob;
07001 }
07002 
07003 //______________________________________________________________________________
07004 void TH1::SetContent(const Double_t *content)
07005 {
07006    //   -*-*-*-*-*-*Replace bin contents by the contents of array content*-*-*-*
07007    //               =====================================================
07008    Int_t bin;
07009    Double_t bincontent;
07010    for (bin=0; bin<fNcells; bin++) {
07011       bincontent = *(content + bin);
07012       SetBinContent(bin, bincontent);
07013    }
07014 }
07015 
07016 //______________________________________________________________________________
07017 Int_t TH1::GetContour(Double_t *levels)
07018 {
07019    //  Return contour values into array levels if pointer levels is non zero
07020    //
07021    //  The function returns the number of contour levels.
07022    //  see GetContourLevel to return one contour only
07023    //
07024 
07025    Int_t nlevels = fContour.fN;
07026    if (levels) {
07027       if (nlevels == 0) {
07028          nlevels = 20;
07029          SetContour(nlevels);
07030       } else {
07031          if (TestBit(kUserContour) == 0) SetContour(nlevels);
07032       }
07033       for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
07034    }
07035    return nlevels;
07036 }
07037 
07038 //______________________________________________________________________________
07039 Double_t TH1::GetContourLevel(Int_t level) const
07040 {
07041    // Return value of contour number level
07042    // see GetContour to return the array of all contour levels
07043 
07044    if (level <0 || level >= fContour.fN) return 0;
07045    Double_t zlevel = fContour.fArray[level];
07046    return zlevel;
07047 }
07048 
07049 //______________________________________________________________________________
07050 Double_t TH1::GetContourLevelPad(Int_t level) const
07051 {
07052    // Return the value of contour number "level" in Pad coordinates ie: if the Pad
07053    // is in log scale along Z it returns le log of the contour level value.
07054    // see GetContour to return the array of all contour levels
07055 
07056    if (level <0 || level >= fContour.fN) return 0;
07057    Double_t zlevel = fContour.fArray[level];
07058 
07059    // In case of user defined contours and Pad in log scale along Z,
07060    // fContour.fArray doesn't contain the log of the contour whereas it does
07061    // in case of equidistant contours.
07062    if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
07063       if (zlevel <= 0) return 0;
07064       zlevel = TMath::Log10(zlevel);
07065    }
07066    return zlevel;
07067 }
07068 
07069 //______________________________________________________________________________
07070 void TH1::SetBuffer(Int_t buffersize, Option_t * /*option*/)
07071 {
07072    // set the maximum number of entries to be kept in the buffer
07073 
07074    if (fBuffer) {
07075       BufferEmpty();
07076       delete [] fBuffer;
07077       fBuffer = 0;
07078    }
07079    if (buffersize <= 0) {
07080       fBufferSize = 0;
07081       return;
07082    }
07083    if (buffersize < 100) buffersize = 100;
07084    fBufferSize = 1 + buffersize*(fDimension+1);
07085    fBuffer = new Double_t[fBufferSize];
07086    memset(fBuffer,0,8*fBufferSize);
07087 }
07088 
07089 //______________________________________________________________________________
07090 void TH1::SetContour(Int_t  nlevels, const Double_t *levels)
07091 {
07092    //   -*-*-*-*-*-*Set the number and values of contour levels*-*-*-*-*-*-*-*-*
07093    //               ===========================================
07094    //
07095    //  By default the number of contour levels is set to 20.
07096    //
07097    //  if argument levels = 0 or missing, equidistant contours are computed
07098    //
07099 
07100    Int_t level;
07101    ResetBit(kUserContour);
07102    if (nlevels <=0 ) {
07103       fContour.Set(0);
07104       return;
07105    }
07106    fContour.Set(nlevels);
07107 
07108    //   -  Contour levels are specified
07109    if (levels) {
07110       SetBit(kUserContour);
07111       for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
07112    } else {
07113       //   - contour levels are computed automatically as equidistant contours
07114       Double_t zmin = GetMinimum();
07115       Double_t zmax = GetMaximum();
07116       if ((zmin == zmax) && (zmin != 0)) {
07117          zmax += 0.01*TMath::Abs(zmax);
07118          zmin -= 0.01*TMath::Abs(zmin);
07119       }
07120       Double_t dz   = (zmax-zmin)/Double_t(nlevels);
07121       if (gPad && gPad->GetLogz()) {
07122          if (zmax <= 0) return;
07123          if (zmin <= 0) zmin = 0.001*zmax;
07124          zmin = TMath::Log10(zmin);
07125          zmax = TMath::Log10(zmax);
07126          dz   = (zmax-zmin)/Double_t(nlevels);
07127       }
07128       for (level=0; level<nlevels; level++) {
07129          fContour.fArray[level] = zmin + dz*Double_t(level);
07130       }
07131    }
07132 }
07133 
07134 //______________________________________________________________________________
07135 void TH1::SetContourLevel(Int_t level, Double_t value)
07136 {
07137    //   -*-*-*-*-*-*-*-*-*Set value for one contour level*-*-*-*-*-*-*-*-*-*-*-*
07138    //                     ===============================
07139    if (level <0 || level >= fContour.fN) return;
07140    SetBit(kUserContour);
07141    fContour.fArray[level] = value;
07142 }
07143 
07144 //______________________________________________________________________________
07145 Double_t TH1::GetMaximum(Double_t maxval) const
07146 {
07147    //  Return maximum value smaller than maxval of bins in the range,
07148    //  unless the value has been overridden by TH1::SetMaximum,
07149    //  in which case it returns that value. (This happens, for example,
07150    //  when the histogram is drawn and the y or z axis limits are changed
07151    //
07152    //  To get the maximum value of bins in the histogram regardless of
07153    //  whether the value has been overridden, use
07154    //      h->GetBinContent(h->GetMaximumBin())
07155 
07156    if (fMaximum != -1111) return fMaximum;
07157    Int_t bin, binx, biny, binz;
07158    Int_t xfirst  = fXaxis.GetFirst();
07159    Int_t xlast   = fXaxis.GetLast();
07160    Int_t yfirst  = fYaxis.GetFirst();
07161    Int_t ylast   = fYaxis.GetLast();
07162    Int_t zfirst  = fZaxis.GetFirst();
07163    Int_t zlast   = fZaxis.GetLast();
07164    Double_t maximum = -FLT_MAX, value;
07165    for (binz=zfirst;binz<=zlast;binz++) {
07166       for (biny=yfirst;biny<=ylast;biny++) {
07167          for (binx=xfirst;binx<=xlast;binx++) {
07168             bin = GetBin(binx,biny,binz);
07169             value = GetBinContent(bin);
07170             if (value > maximum && value < maxval) maximum = value;
07171          }
07172       }
07173    }
07174    return maximum;
07175 }
07176 
07177 //______________________________________________________________________________
07178 Int_t TH1::GetMaximumBin() const
07179 {
07180    //   -*-*-*-*-*Return location of bin with maximum value in the range*-*
07181    //             ======================================================
07182    Int_t locmax, locmay, locmaz;
07183    return GetMaximumBin(locmax, locmay, locmaz);
07184 }
07185 
07186 //______________________________________________________________________________
07187 Int_t TH1::GetMaximumBin(Int_t &locmax, Int_t &locmay, Int_t &locmaz) const
07188 {
07189    //   -*-*-*-*-*Return location of bin with maximum value in the range*-*
07190    //             ======================================================
07191    Int_t bin, binx, biny, binz;
07192    Int_t locm;
07193    Int_t xfirst  = fXaxis.GetFirst();
07194    Int_t xlast   = fXaxis.GetLast();
07195    Int_t yfirst  = fYaxis.GetFirst();
07196    Int_t ylast   = fYaxis.GetLast();
07197    Int_t zfirst  = fZaxis.GetFirst();
07198    Int_t zlast   = fZaxis.GetLast();
07199    Double_t maximum = -FLT_MAX, value;
07200    locm = locmax = locmay = locmaz = 0;
07201    for (binz=zfirst;binz<=zlast;binz++) {
07202       for (biny=yfirst;biny<=ylast;biny++) {
07203          for (binx=xfirst;binx<=xlast;binx++) {
07204             bin = GetBin(binx,biny,binz);
07205             value = GetBinContent(bin);
07206             if (value > maximum) {
07207                maximum = value;
07208                locm    = bin;
07209                locmax  = binx;
07210                locmay  = biny;
07211                locmaz  = binz;
07212             }
07213          }
07214       }
07215    }
07216    return locm;
07217 }
07218 
07219 //______________________________________________________________________________
07220 Double_t TH1::GetMinimum(Double_t minval) const
07221 {
07222    //  Return minimum value smaller than maxval of bins in the range,
07223    //  unless the value has been overridden by TH1::SetMinimum,
07224    //  in which case it returns that value. (This happens, for example,
07225    //  when the histogram is drawn and the y or z axis limits are changed
07226    //
07227    //  To get the minimum value of bins in the histogram regardless of
07228    //  whether the value has been overridden, use
07229    //     h->GetBinContent(h->GetMinimumBin())
07230 
07231    if (fMinimum != -1111) return fMinimum;
07232    Int_t bin, binx, biny, binz;
07233    Int_t xfirst  = fXaxis.GetFirst();
07234    Int_t xlast   = fXaxis.GetLast();
07235    Int_t yfirst  = fYaxis.GetFirst();
07236    Int_t ylast   = fYaxis.GetLast();
07237    Int_t zfirst  = fZaxis.GetFirst();
07238    Int_t zlast   = fZaxis.GetLast();
07239    Double_t minimum=FLT_MAX, value;
07240    for (binz=zfirst;binz<=zlast;binz++) {
07241       for (biny=yfirst;biny<=ylast;biny++) {
07242          for (binx=xfirst;binx<=xlast;binx++) {
07243             bin = GetBin(binx,biny,binz);
07244             value = GetBinContent(bin);
07245             if (value < minimum && value > minval) minimum = value;
07246          }
07247       }
07248    }
07249    return minimum;
07250 }
07251 
07252 //______________________________________________________________________________
07253 Int_t TH1::GetMinimumBin() const
07254 {
07255    //   -*-*-*-*-*Return location of bin with minimum value in the range*-*
07256    //             ======================================================
07257    Int_t locmix, locmiy, locmiz;
07258    return GetMinimumBin(locmix, locmiy, locmiz);
07259 }
07260 
07261 //______________________________________________________________________________
07262 Int_t TH1::GetMinimumBin(Int_t &locmix, Int_t &locmiy, Int_t &locmiz) const
07263 {
07264    //   -*-*-*-*-*Return location of bin with minimum value in the range*-*
07265    //             ======================================================
07266    Int_t bin, binx, biny, binz;
07267    Int_t locm;
07268    Int_t xfirst  = fXaxis.GetFirst();
07269    Int_t xlast   = fXaxis.GetLast();
07270    Int_t yfirst  = fYaxis.GetFirst();
07271    Int_t ylast   = fYaxis.GetLast();
07272    Int_t zfirst  = fZaxis.GetFirst();
07273    Int_t zlast   = fZaxis.GetLast();
07274    Double_t minimum = FLT_MAX, value;
07275    locm = locmix = locmiy = locmiz = 0;
07276    for (binz=zfirst;binz<=zlast;binz++) {
07277       for (biny=yfirst;biny<=ylast;biny++) {
07278          for (binx=xfirst;binx<=xlast;binx++) {
07279             bin = GetBin(binx,biny,binz);
07280             value = GetBinContent(bin);
07281             if (value < minimum) {
07282                minimum = value;
07283                locm    = bin;
07284                locmix  = binx;
07285                locmiy  = biny;
07286                locmiz  = binz;
07287             }
07288          }
07289       }
07290    }
07291    return locm;
07292 }
07293 
07294 //______________________________________________________________________________
07295 void TH1::SetBins(Int_t nx, Double_t xmin, Double_t xmax)
07296 {
07297    //   -*-*-*-*-*-*-*Redefine  x axis parameters*-*-*-*-*-*-*-*-*-*-*-*
07298    //                 ===========================
07299    // The X axis parameters are modified.
07300    // The bins content array is resized
07301    // if errors (Sumw2) the errors array is resized
07302    // The previous bin contents are lost
07303    // To change only the axis limits, see TAxis::SetRange
07304 
07305    if (GetDimension() != 1) {
07306       Error("SetBins","Operation only valid for 1-d histograms");
07307       return;
07308    }
07309    fXaxis.SetRange(0,0);
07310    fXaxis.Set(nx,xmin,xmax);
07311    fYaxis.Set(1,0,1);
07312    fZaxis.Set(1,0,1);
07313    fNcells = nx+2;
07314    SetBinsLength(fNcells);
07315    if (fSumw2.fN) {
07316       fSumw2.Set(fNcells);
07317    }
07318 }
07319 
07320 //______________________________________________________________________________
07321 void TH1::SetBins(Int_t nx, const Double_t *xBins)
07322 {
07323    //   -*-*-*-*-*-*-*Redefine  x axis parameters with variable bin sizes *-*-*-*-*-*-*-*-*-*
07324    //                 ===================================================
07325    // The X axis parameters are modified.
07326    // The bins content array is resized
07327    // if errors (Sumw2) the errors array is resized
07328    // The previous bin contents are lost
07329    // To change only the axis limits, see TAxis::SetRange
07330    // xBins is supposed to be of length nx+1
07331    if (GetDimension() != 1) {
07332       Error("SetBins","Operation only valid for 1-d histograms");
07333       return;
07334    }
07335    fXaxis.SetRange(0,0);
07336    fXaxis.Set(nx,xBins);
07337    fYaxis.Set(1,0,1);
07338    fZaxis.Set(1,0,1);
07339    fNcells = nx+2;
07340    SetBinsLength(fNcells);
07341    if (fSumw2.fN) {
07342       fSumw2.Set(fNcells);
07343    }
07344 }
07345 
07346 //______________________________________________________________________________
07347 void TH1::SetBins(Int_t nx, Double_t xmin, Double_t xmax, Int_t ny, Double_t ymin, Double_t ymax)
07348 {
07349    //   -*-*-*-*-*-*-*Redefine  x and y axis parameters*-*-*-*-*-*-*-*-*-*-*-*
07350    //                 =================================
07351    // The X and Y axis parameters are modified.
07352    // The bins content array is resized
07353    // if errors (Sumw2) the errors array is resized
07354    // The previous bin contents are lost
07355    // To change only the axis limits, see TAxis::SetRange
07356 
07357    if (GetDimension() != 2) {
07358       Error("SetBins","Operation only valid for 2-D histograms");
07359       return;
07360    }
07361    fXaxis.SetRange(0,0);
07362    fYaxis.SetRange(0,0);
07363    fXaxis.Set(nx,xmin,xmax);
07364    fYaxis.Set(ny,ymin,ymax);
07365    fZaxis.Set(1,0,1);
07366    fNcells = (nx+2)*(ny+2);
07367    SetBinsLength(fNcells);
07368    if (fSumw2.fN) {
07369       fSumw2.Set(fNcells);
07370    }
07371 }
07372 
07373 //______________________________________________________________________________
07374 void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins)
07375 {
07376    //   -*-*-*-*-*-*-*Redefine  x and y axis parameters with variable bin sizes *-*-*-*-*-*-*-*-*
07377    //                 =========================================================
07378    // The X and Y axis parameters are modified.
07379    // The bins content array is resized
07380    // if errors (Sumw2) the errors array is resized
07381    // The previous bin contents are lost
07382    // To change only the axis limits, see TAxis::SetRange
07383    // xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1
07384 
07385    if (GetDimension() != 2) {
07386       Error("SetBins","Operation only valid for 2-D histograms");
07387       return;
07388    }
07389    fXaxis.SetRange(0,0);
07390    fYaxis.SetRange(0,0);
07391    fXaxis.Set(nx,xBins);
07392    fYaxis.Set(ny,yBins);
07393    fZaxis.Set(1,0,1);
07394    fNcells = (nx+2)*(ny+2);
07395    SetBinsLength(fNcells);
07396    if (fSumw2.fN) {
07397       fSumw2.Set(fNcells);
07398    }
07399 }
07400 
07401 
07402 //______________________________________________________________________________
07403 void TH1::SetBins(Int_t nx, Double_t xmin, Double_t xmax, Int_t ny, Double_t ymin, Double_t ymax, Int_t nz, Double_t zmin, Double_t zmax)
07404 {
07405    //   -*-*-*-*-*-*-*Redefine  x, y and z axis parameters*-*-*-*-*-*-*-*-*-*-*-*
07406    //                 ====================================
07407    // The X, Y and Z axis parameters are modified.
07408    // The bins content array is resized
07409    // if errors (Sumw2) the errors array is resized
07410    // The previous bin contents are lost
07411    // To change only the axis limits, see TAxis::SetRange
07412 
07413    if (GetDimension() != 3) {
07414       Error("SetBins","Operation only valid for 3-D histograms");
07415       return;
07416    }
07417    fXaxis.SetRange(0,0);
07418    fYaxis.SetRange(0,0);
07419    fZaxis.SetRange(0,0);
07420    fXaxis.Set(nx,xmin,xmax);
07421    fYaxis.Set(ny,ymin,ymax);
07422    fZaxis.Set(nz,zmin,zmax);
07423    fNcells = (nx+2)*(ny+2)*(nz+2);
07424    SetBinsLength(fNcells);
07425    if (fSumw2.fN) {
07426       fSumw2.Set(fNcells);
07427    }
07428 }
07429 
07430 //______________________________________________________________________________
07431 void TH1::SetBins(Int_t nx, const Double_t *xBins, Int_t ny, const Double_t *yBins, Int_t nz, const Double_t *zBins)
07432 {
07433    //   -*-*-*-*-*-*-*Redefine  x, y and z axis parameters with variable bin sizes *-*-*-*-*-*-*-*-*
07434    //                 ============================================================
07435    // The X, Y and Z axis parameters are modified.
07436    // The bins content array is resized
07437    // if errors (Sumw2) the errors array is resized
07438    // The previous bin contents are lost
07439    // To change only the axis limits, see TAxis::SetRange
07440    // xBins is supposed to be of length nx+1, yBins is supposed to be of length ny+1,
07441    // zBins is supposed to be of length nz+1
07442 
07443    if (GetDimension() != 3) {
07444       Error("SetBins","Operation only valid for 3-D histograms");
07445       return;
07446    }
07447    fXaxis.SetRange(0,0);
07448    fYaxis.SetRange(0,0);
07449    fZaxis.SetRange(0,0);
07450    fXaxis.Set(nx,xBins);
07451    fYaxis.Set(ny,yBins);
07452    fYaxis.Set(nz,zBins);
07453    fNcells = (nx+2)*(ny+2)*(nz+2);
07454    SetBinsLength(fNcells);
07455    if (fSumw2.fN) {
07456       fSumw2.Set(fNcells);
07457    }
07458 }
07459 
07460 //______________________________________________________________________________
07461 void TH1::SetMaximum(Double_t maximum)
07462 {
07463    // Set the maximum value for the Y axis, in case of 1-D histograms,
07464    // or the Z axis in case of 2-D histograms
07465    //
07466    // By default the maximum value used in drawing is the maximum value of the histogram plus
07467    // a margin of 10 per cent. If this function has been called, the value of 'maximum' is
07468    // used, with no extra margin.
07469    //
07470    // TH1::GetMaximum returns the maximum value of the bins in the histogram, unless the
07471    // maximum has been set manually by this function or by altering the y/z axis limits.
07472    // Use TH1::GetMaximumBin to find the bin with the maximum value of an histogram
07473    //
07474    fMaximum = maximum;
07475 }
07476 
07477 
07478 //______________________________________________________________________________
07479 void TH1::SetMinimum(Double_t minimum)
07480 {
07481    // Set the minimum value for the Y axis, in case of 1-D histograms,
07482    // or the Z axis in case of 2-D histograms
07483    //
07484    // By default the minimum value used in drawing is the minimum value of the histogram plus
07485    // a margin of 10 per cent. If this function has been called, the value of 'minimum' is
07486    // used, with no extra margin.
07487    //
07488    // TH1::GetMinimum returns the minimum value of the bins in the histogram, unless the
07489    // minimum has been set manually by this function or by altering the y/z axis limits.
07490    // Use TH1::GetMinimumBin to find the bin with the minimum value of an histogram
07491    //
07492    fMinimum = minimum;
07493 }
07494 
07495 //______________________________________________________________________________
07496 void TH1::SetDirectory(TDirectory *dir)
07497 {
07498    // By default when an histogram is created, it is added to the list
07499    // of histogram objects in the current directory in memory.
07500    // Remove reference to this histogram from current directory and add
07501    // reference to new directory dir. dir can be 0 in which case the
07502    // histogram does not belong to any directory.
07503 
07504    if (fDirectory == dir) return;
07505    if (fDirectory) fDirectory->Remove(this);
07506    fDirectory = dir;
07507    if (fDirectory) fDirectory->Append(this);
07508 }
07509 
07510 
07511 //______________________________________________________________________________
07512 void TH1::SetError(const Double_t *error)
07513 {
07514    //   -*-*-*-*-*-*-*Replace bin errors by values in array error*-*-*-*-*-*-*-*-*
07515    //                 ===========================================
07516    Int_t bin;
07517    Double_t binerror;
07518    for (bin=0; bin<fNcells; bin++) {
07519       binerror = error[bin];
07520       SetBinError(bin, binerror);
07521    }
07522 }
07523 
07524 //______________________________________________________________________________
07525 void TH1::SetName(const char *name)
07526 {
07527    // Change the name of this histogram
07528    //
07529 
07530    //  Histograms are named objects in a THashList.
07531    //  We must update the hashlist if we change the name
07532    if (fDirectory) fDirectory->Remove(this);
07533    fName = name;
07534    if (fDirectory) fDirectory->Append(this);
07535 }
07536 
07537 //______________________________________________________________________________
07538 void TH1::SetNameTitle(const char *name, const char *title)
07539 {
07540    // Change the name and title of this histogram
07541    //
07542 
07543    //  Histograms are named objects in a THashList.
07544    //  We must update the hashlist if we change the name
07545    if (fDirectory) fDirectory->Remove(this);
07546    fName  = name;
07547    SetTitle(title);
07548    if (fDirectory) fDirectory->Append(this);
07549 }
07550 
07551 //______________________________________________________________________________
07552 void TH1::SetStats(Bool_t stats)
07553 {
07554    //   -*-*-*-*-*-*-*Set statistics option on/off
07555    //                 ============================
07556    //  By default, the statistics box is drawn.
07557    //  The paint options can be selected via gStyle->SetOptStats.
07558    //  This function sets/resets the kNoStats bin in the histogram object.
07559    //  It has priority over the Style option.
07560 
07561    ResetBit(kNoStats);
07562    if (!stats) {
07563       SetBit(kNoStats);
07564       //remove the "stats" object from the list of functions
07565       if (fFunctions) {
07566          TObject *obj = fFunctions->FindObject("stats");
07567          if (obj) {
07568             fFunctions->Remove(obj);
07569             delete obj;
07570          }
07571       }
07572    }
07573 }
07574 
07575 //______________________________________________________________________________
07576 void TH1::Sumw2()
07577 {
07578    // Create structure to store sum of squares of weights*-*-*-*-*-*-*-*
07579    //
07580    //     if histogram is already filled, the sum of squares of weights
07581    //     is filled with the existing bin contents
07582    //
07583    //     The error per bin will be computed as sqrt(sum of squares of weight)
07584    //     for each bin.
07585    //
07586    //  This function is automatically called when the histogram is created
07587    //  if the static function TH1::SetDefaultSumw2 has been called before.
07588 
07589       if (fSumw2.fN == fNcells) {
07590          if (!fgDefaultSumw2 )
07591             Warning("Sumw2","Sum of squares of weights structure already created");
07592          return;
07593       }
07594 
07595    fSumw2.Set(fNcells);
07596 
07597    if ( fEntries > 0 )
07598       for (Int_t bin=0; bin<fNcells; bin++) {
07599          fSumw2.fArray[bin] = TMath::Abs(GetBinContent(bin));
07600       }
07601 }
07602 
07603 //______________________________________________________________________________
07604 TF1 *TH1::GetFunction(const char *name) const
07605 {
07606    //   -*-*-*Return pointer to function with name*-*-*-*-*-*-*-*-*-*-*-*-*
07607    //         ===================================
07608    //
07609    // Functions such as TH1::Fit store the fitted function in the list of
07610    // functions of this histogram.
07611 
07612    return (TF1*)fFunctions->FindObject(name);
07613 }
07614 
07615 //______________________________________________________________________________
07616 Double_t TH1::GetBinError(Int_t bin) const
07617 {
07618    //   -*-*-*-*-*Return value of error associated to bin number bin*-*-*-*-*
07619    //             ==================================================
07620    //
07621    //    if the sum of squares of weights has been defined (via Sumw2),
07622    //    this function returns the sqrt(sum of w2).
07623    //    otherwise it returns the sqrt(contents) for this bin.
07624    //
07625    //   -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
07626 
07627    if (bin < 0) bin = 0;
07628    if (bin >= fNcells) bin = fNcells-1;
07629    if (fBuffer) ((TH1*)this)->BufferEmpty();
07630    if (fSumw2.fN) {
07631       Double_t err2 = fSumw2.fArray[bin];
07632       return TMath::Sqrt(err2);
07633    }
07634    Double_t error2 = TMath::Abs(GetBinContent(bin));
07635    return TMath::Sqrt(error2);
07636 }
07637 
07638 //______________________________________________________________________________
07639 Double_t TH1::GetBinError(Int_t binx, Int_t biny) const
07640 {
07641    //   -*-*-*-*-*Return error of bin number binx, biny
07642    //             =====================================
07643    // NB: Function to be called for 2-D histograms only
07644 
07645    Int_t bin = GetBin(binx,biny);
07646    return GetBinError(bin);
07647 }
07648 
07649 //______________________________________________________________________________
07650 Double_t TH1::GetBinError(Int_t binx, Int_t biny, Int_t binz) const
07651 {
07652    //   -*-*-*-*-*Return error of bin number binx,biny,binz
07653    //             =========================================
07654    // NB: Function to be called for 3-D histograms only
07655 
07656    Int_t bin = GetBin(binx,biny,binz);
07657    return GetBinError(bin);
07658 }
07659 
07660 //______________________________________________________________________________
07661 Double_t TH1::GetCellContent(Int_t binx, Int_t biny) const
07662 {
07663    //   -*-*-*-*-*Return content of bin number binx, biny
07664    //             =====================================
07665    // NB: Function to be called for 2-D histograms only
07666 
07667    Int_t bin = GetBin(binx,biny);
07668    return GetBinContent(bin);
07669 }
07670 
07671 //______________________________________________________________________________
07672 Double_t TH1::GetCellError(Int_t binx, Int_t biny) const
07673 {
07674    //   -*-*-*-*-*Return error of bin number binx, biny
07675    //             =====================================
07676    // NB: Function to be called for 2-D histograms only
07677 
07678    Int_t bin = GetBin(binx,biny);
07679    return GetBinError(bin);
07680 }
07681 
07682 //______________________________________________________________________________
07683 void TH1::SetBinError(Int_t bin, Double_t error)
07684 {
07685    // see convention for numbering bins in TH1::GetBin
07686    if (!fSumw2.fN) Sumw2();
07687    if (bin <0 || bin>= fSumw2.fN) return;
07688    fSumw2.fArray[bin] = error*error;
07689 }
07690 
07691 //______________________________________________________________________________
07692 void TH1::SetBinContent(Int_t binx, Int_t biny, Double_t content)
07693 {
07694    // see convention for numbering bins in TH1::GetBin
07695    if (binx <0 || binx>fXaxis.GetNbins()+1) return;
07696    if (biny <0 || biny>fYaxis.GetNbins()+1) return;
07697    Int_t bin = GetBin(binx,biny);
07698    SetBinContent(bin,content);
07699 }
07700 
07701 //______________________________________________________________________________
07702 void TH1::SetBinContent(Int_t binx, Int_t biny, Int_t binz, Double_t content)
07703 {
07704    // see convention for numbering bins in TH1::GetBin
07705    if (binx <0 || binx>fXaxis.GetNbins()+1) return;
07706    if (biny <0 || biny>fYaxis.GetNbins()+1) return;
07707    if (binz <0 || binz>fZaxis.GetNbins()+1) return;
07708    Int_t bin = GetBin(binx,biny,binz);
07709    SetBinContent(bin,content);
07710 }
07711 
07712 //______________________________________________________________________________
07713 void TH1::SetCellContent(Int_t binx, Int_t biny, Double_t content)
07714 {
07715    // Set cell content.
07716 
07717    if (binx <0 || binx>fXaxis.GetNbins()+1) return;
07718    if (biny <0 || biny>fYaxis.GetNbins()+1) return;
07719    Int_t bin = GetBin(binx,biny);
07720    SetBinContent(bin,content);
07721 }
07722 
07723 //______________________________________________________________________________
07724 void TH1::SetBinError(Int_t binx, Int_t biny, Double_t error)
07725 {
07726    // see convention for numbering bins in TH1::GetBin
07727    if (binx <0 || binx>fXaxis.GetNbins()+1) return;
07728    if (biny <0 || biny>fYaxis.GetNbins()+1) return;
07729    Int_t bin = GetBin(binx,biny);
07730    SetBinError(bin,error);
07731 }
07732 
07733 //______________________________________________________________________________
07734 void TH1::SetBinError(Int_t binx, Int_t biny, Int_t binz, Double_t error)
07735 {
07736    // see convention for numbering bins in TH1::GetBin
07737    if (binx <0 || binx>fXaxis.GetNbins()+1) return;
07738    if (biny <0 || biny>fYaxis.GetNbins()+1) return;
07739    if (binz <0 || binz>fZaxis.GetNbins()+1) return;
07740    Int_t bin = GetBin(binx,biny,binz);
07741    SetBinError(bin,error);
07742 }
07743 
07744 //______________________________________________________________________________
07745 void TH1::SetCellError(Int_t binx, Int_t biny, Double_t error)
07746 {
07747    // see convention for numbering bins in TH1::GetBin
07748    if (binx <0 || binx>fXaxis.GetNbins()+1) return;
07749    if (biny <0 || biny>fYaxis.GetNbins()+1) return;
07750    if (!fSumw2.fN) Sumw2();
07751    Int_t bin = biny*(fXaxis.GetNbins()+2) + binx;
07752    fSumw2.fArray[bin] = error*error;
07753 }
07754 
07755 //______________________________________________________________________________
07756 void TH1::SetBinContent(Int_t, Double_t)
07757 {
07758    // see convention for numbering bins in TH1::GetBin
07759    AbstractMethod("SetBinContent");
07760 }
07761 
07762 //______________________________________________________________________________
07763 TH1 *TH1::ShowBackground(Int_t niter, Option_t *option)
07764 {
07765 //   This function calculates the background spectrum in this histogram.
07766 //   The background is returned as a histogram.
07767 //
07768 //   Function parameters:
07769 //   -niter, number of iterations (default value = 2)
07770 //      Increasing niter make the result smoother and lower.
07771 //   -option: may contain one of the following options
07772 //      - to set the direction parameter
07773 //        "BackDecreasingWindow". By default the direction is BackIncreasingWindow
07774 //      - filterOrder-order of clipping filter,  (default "BackOrder2"
07775 //                  -possible values= "BackOrder4"
07776 //                                    "BackOrder6"
07777 //                                    "BackOrder8"
07778 //      - "nosmoothing"- if selected, the background is not smoothed
07779 //           By default the background is smoothed.
07780 //      - smoothWindow-width of smoothing window, (default is "BackSmoothing3")
07781 //                  -possible values= "BackSmoothing5"
07782 //                                    "BackSmoothing7"
07783 //                                    "BackSmoothing9"
07784 //                                    "BackSmoothing11"
07785 //                                    "BackSmoothing13"
07786 //                                    "BackSmoothing15"
07787 //      - "nocompton"- if selected the estimation of Compton edge
07788 //                  will be not be included   (by default the compton estimation is set)
07789 //      - "same" : if this option is specified, the resulting background
07790 //                 histogram is superimposed on the picture in the current pad.
07791 //                 This option is given by default.
07792 //
07793 //  NOTE that the background is only evaluated in the current range of this histogram.
07794 //  i.e., if this has a bin range (set via h->GetXaxis()->SetRange(binmin, binmax),
07795 //  the returned histogram will be created with the same number of bins
07796 //  as this input histogram, but only bins from binmin to binmax will be filled
07797 //  with the estimated background.
07798 //
07799 
07800 
07801    return (TH1*)gROOT->ProcessLineFast(Form("TSpectrum::StaticBackground((TH1*)0x%lx,%d,\"%s\")",
07802                                             (ULong_t)this, niter, option));
07803 }
07804 
07805 //______________________________________________________________________________
07806 Int_t TH1::ShowPeaks(Double_t sigma, Option_t *option, Double_t threshold)
07807 {
07808    //Interface to TSpectrum::Search.
07809    //The function finds peaks in this histogram where the width is > sigma
07810    //and the peak maximum greater than threshold*maximum bin content of this.
07811    //For more details see TSpectrum::Search.
07812    //Note the difference in the default value for option compared to TSpectrum::Search
07813    //option="" by default (instead of "goff").
07814 
07815    return (Int_t)gROOT->ProcessLineFast(Form("TSpectrum::StaticSearch((TH1*)0x%lx,%g,\"%s\",%g)",
07816                                              (ULong_t)this, sigma, option, threshold));
07817 }
07818 
07819 
07820 //______________________________________________________________________________
07821 TH1* TH1::TransformHisto(TVirtualFFT *fft, TH1* h_output,  Option_t *option)
07822 {
07823 //For a given transform (first parameter), fills the histogram (second parameter)
07824 //with the transform output data, specified in the third parameter
07825 //If the 2nd parameter h_output is empty, a new histogram (TH1D or TH2D) is created
07826 //and the user is responsible for deleting it.
07827 // Available options:
07828 //   "RE" - real part of the output
07829 //   "IM" - imaginary part of the output
07830 //   "MAG" - magnitude of the output
07831 //   "PH"  - phase of the output
07832 
07833    if (fft->GetNdim()>2){
07834       printf("Only 1d and 2d\n");
07835       return 0;
07836    }
07837    Int_t binx,biny;
07838    TString opt = option;
07839    opt.ToUpper();
07840    Int_t *n = fft->GetN();
07841    TH1 *hout=0;
07842    if (h_output) hout = h_output;
07843    else {
07844       TString name = TString::Format("out_%s", opt.Data());
07845       if (fft->GetNdim()==1)
07846          hout = new TH1D(name, name,n[0], 0, n[0]);
07847       else if (fft->GetNdim()==2)
07848          hout = new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
07849    }
07850    R__ASSERT(hout != 0);
07851    TString type=fft->GetType();
07852    Int_t ind[2];
07853    if (opt.Contains("RE")){
07854       if (type.Contains("2C") || type.Contains("2HC")) {
07855          Double_t re, im;
07856          for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
07857             for (biny=1; biny<=hout->GetNbinsY(); biny++) {
07858                ind[0] = binx-1; ind[1] = biny-1;
07859                fft->GetPointComplex(ind, re, im);
07860                hout->SetBinContent(binx, biny, re);
07861             }
07862          }
07863       } else {
07864          for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
07865             for (biny=1; biny<=hout->GetNbinsY(); biny++) {
07866                ind[0] = binx-1; ind[1] = biny-1;
07867                hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
07868             }
07869          }
07870       }
07871    }
07872    if (opt.Contains("IM")) {
07873       if (type.Contains("2C") || type.Contains("2HC")) {
07874          Double_t re, im;
07875          for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
07876             for (biny=1; biny<=hout->GetNbinsY(); biny++) {
07877                ind[0] = binx-1; ind[1] = biny-1;
07878                fft->GetPointComplex(ind, re, im);
07879                hout->SetBinContent(binx, biny, im);
07880             }
07881          }
07882       } else {
07883          printf("No complex numbers in the output");
07884          return 0;
07885       }
07886    }
07887    if (opt.Contains("MA")) {
07888       if (type.Contains("2C") || type.Contains("2HC")) {
07889          Double_t re, im;
07890          for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
07891             for (biny=1; biny<=hout->GetNbinsY(); biny++) {
07892                ind[0] = binx-1; ind[1] = biny-1;
07893                fft->GetPointComplex(ind, re, im);
07894                hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
07895             }
07896          }
07897       } else {
07898          for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
07899             for (biny=1; biny<=hout->GetNbinsY(); biny++) {
07900                ind[0] = binx-1; ind[1] = biny-1;
07901                hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
07902             }
07903          }
07904       }
07905    }
07906    if (opt.Contains("PH")) {
07907       if (type.Contains("2C") || type.Contains("2HC")){
07908          Double_t re, im, ph;
07909          for (binx = 1; binx<=hout->GetNbinsX(); binx++){
07910             for (biny=1; biny<=hout->GetNbinsY(); biny++){
07911                ind[0] = binx-1; ind[1] = biny-1;
07912                fft->GetPointComplex(ind, re, im);
07913                if (TMath::Abs(re) > 1e-13){
07914                   ph = TMath::ATan(im/re);
07915                   //find the correct quadrant
07916                   if (re<0 && im<0)
07917                      ph -= TMath::Pi();
07918                   if (re<0 && im>=0)
07919                      ph += TMath::Pi();
07920                } else {
07921                   if (TMath::Abs(im) < 1e-13)
07922                      ph = 0;
07923                   else if (im>0)
07924                      ph = TMath::Pi()*0.5;
07925                   else
07926                      ph = -TMath::Pi()*0.5;
07927                }
07928                hout->SetBinContent(binx, biny, ph);
07929             }
07930          }
07931       } else {
07932          printf("Pure real output, no phase");
07933          return 0;
07934       }
07935    }
07936 
07937    return hout;
07938 }
07939 
07940 
07941 
07942 //______________________________________________________________________________
07943 //                     TH1C methods
07944 // TH1C : histograms with one byte per channel.   Maximum bin content = 127
07945 //______________________________________________________________________________
07946 
07947 ClassImp(TH1C)
07948 
07949 //______________________________________________________________________________
07950 TH1C::TH1C(): TH1(), TArrayC()
07951 {
07952    // Constructor.
07953 
07954    fDimension = 1;
07955    SetBinsLength(3);
07956    if (fgDefaultSumw2) Sumw2();
07957 }
07958 
07959 //______________________________________________________________________________
07960 TH1C::TH1C(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
07961 : TH1(name,title,nbins,xlow,xup)
07962 {
07963    //
07964    //    Create a 1-Dim histogram with fix bins of type char (one byte per channel)
07965    //    ==========================================================================
07966    //                    (see TH1::TH1 for explanation of parameters)
07967    //
07968    fDimension = 1;
07969    TArrayC::Set(fNcells);
07970 
07971    if (xlow >= xup) SetBuffer(fgBufferSize);
07972    if (fgDefaultSumw2) Sumw2();
07973 }
07974 
07975 //______________________________________________________________________________
07976 TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
07977 : TH1(name,title,nbins,xbins)
07978 {
07979    //
07980    //    Create a 1-Dim histogram with variable bins of type char (one byte per channel)
07981    //    ==========================================================================
07982    //                    (see TH1::TH1 for explanation of parameters)
07983    //
07984    fDimension = 1;
07985    TArrayC::Set(fNcells);
07986    if (fgDefaultSumw2) Sumw2();
07987 }
07988 
07989 //______________________________________________________________________________
07990 TH1C::TH1C(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
07991 : TH1(name,title,nbins,xbins)
07992 {
07993    //
07994    //    Create a 1-Dim histogram with variable bins of type char (one byte per channel)
07995    //    ==========================================================================
07996    //                    (see TH1::TH1 for explanation of parameters)
07997    //
07998    fDimension = 1;
07999    TArrayC::Set(fNcells);
08000    if (fgDefaultSumw2) Sumw2();
08001 }
08002 
08003 //______________________________________________________________________________
08004 TH1C::~TH1C()
08005 {
08006    // Destructor.
08007 }
08008 
08009 //______________________________________________________________________________
08010 TH1C::TH1C(const TH1C &h1c) : TH1(), TArrayC()
08011 {
08012    // Copy constructor.
08013 
08014    ((TH1C&)h1c).Copy(*this);
08015 }
08016 
08017 //______________________________________________________________________________
08018 void TH1C::AddBinContent(Int_t bin)
08019 {
08020    //   -*-*-*-*-*-*-*-*Increment bin content by 1*-*-*-*-*-*-*-*-*-*-*-*-*-*
08021    //                   ==========================
08022 
08023    if (fArray[bin] < 127) fArray[bin]++;
08024 }
08025 
08026 //______________________________________________________________________________
08027 void TH1C::AddBinContent(Int_t bin, Double_t w)
08028 {
08029    //   -*-*-*-*-*-*-*-*Increment bin content by w*-*-*-*-*-*-*-*-*-*-*-*-*-*
08030    //                   ==========================
08031 
08032    Int_t newval = fArray[bin] + Int_t(w);
08033    if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
08034    if (newval < -127) fArray[bin] = -127;
08035    if (newval >  127) fArray[bin] =  127;
08036 }
08037 
08038 //______________________________________________________________________________
08039 void TH1C::Copy(TObject &newth1) const
08040 {
08041    // Copy this to newth1
08042 
08043    TH1::Copy(newth1);
08044 }
08045 
08046 //______________________________________________________________________________
08047 TH1 *TH1C::DrawCopy(Option_t *option) const
08048 {
08049    // Draw copy.
08050 
08051    TString opt = option;
08052    opt.ToLower();
08053    if (gPad && !opt.Contains("same")) gPad->Clear();
08054    TH1C *newth1 = (TH1C*)Clone();
08055    newth1->SetDirectory(0);
08056    newth1->SetBit(kCanDelete);
08057    newth1->AppendPad(option);
08058    return newth1;
08059 }
08060 
08061 //______________________________________________________________________________
08062 Double_t TH1C::GetBinContent(Int_t bin) const
08063 {
08064    // see convention for numbering bins in TH1::GetBin
08065 
08066    if (fBuffer) ((TH1C*)this)->BufferEmpty();
08067    if (bin < 0) bin = 0;
08068    if (bin >= fNcells) bin = fNcells-1;
08069    if (!fArray) return 0;
08070    return Double_t (fArray[bin]);
08071 }
08072 
08073 //______________________________________________________________________________
08074 void TH1C::Reset(Option_t *option)
08075 {
08076    // Reset.
08077 
08078    TH1::Reset(option);
08079    TArrayC::Reset();
08080 }
08081 
08082 //______________________________________________________________________________
08083 void TH1C::SetBinContent(Int_t bin, Double_t content)
08084 {
08085    // Set bin content
08086    // see convention for numbering bins in TH1::GetBin
08087    // In case the bin number is greater than the number of bins and
08088    // the timedisplay option is set or the kCanRebin bit is set,
08089    // the number of bins is automatically doubled to accomodate the new bin
08090 
08091    fEntries++;
08092    fTsumw = 0;
08093    if (bin < 0) return;
08094    if (bin >= fNcells-1) {
08095       if (fXaxis.GetTimeDisplay()) {
08096          while (bin >=  fNcells-1)  LabelsInflate();
08097       } else {
08098          if (!TestBit(kCanRebin)) {
08099             if (bin == fNcells-1) fArray[bin] = Char_t (content);
08100             return;
08101          }
08102          while (bin >= fNcells-1)  LabelsInflate();
08103       }
08104    }
08105    fArray[bin] = Char_t (content);
08106 }
08107 
08108 //______________________________________________________________________________
08109 void TH1C::SetBinsLength(Int_t n)
08110 {
08111    // Set total number of bins including under/overflow
08112    // Reallocate bin contents array
08113 
08114    if (n < 0) n = fXaxis.GetNbins() + 2;
08115    fNcells = n;
08116    TArrayC::Set(n);
08117 }
08118 
08119 //______________________________________________________________________________
08120 TH1C& TH1C::operator=(const TH1C &h1)
08121 {
08122    // Operator =
08123 
08124    if (this != &h1)  ((TH1C&)h1).Copy(*this);
08125    return *this;
08126 }
08127 
08128 
08129 //______________________________________________________________________________
08130 TH1C operator*(Double_t c1, const TH1C &h1)
08131 {
08132    // Operator *
08133 
08134    TH1C hnew = h1;
08135    hnew.Scale(c1);
08136    hnew.SetDirectory(0);
08137    return hnew;
08138 }
08139 
08140 //______________________________________________________________________________
08141 TH1C operator+(const TH1C &h1, const TH1C &h2)
08142 {
08143    // Operator +
08144 
08145    TH1C hnew = h1;
08146    hnew.Add(&h2,1);
08147    hnew.SetDirectory(0);
08148    return hnew;
08149 }
08150 
08151 //______________________________________________________________________________
08152 TH1C operator-(const TH1C &h1, const TH1C &h2)
08153 {
08154    // Operator -
08155 
08156    TH1C hnew = h1;
08157    hnew.Add(&h2,-1);
08158    hnew.SetDirectory(0);
08159    return hnew;
08160 }
08161 
08162 //______________________________________________________________________________
08163 TH1C operator*(const TH1C &h1, const TH1C &h2)
08164 {
08165    // Operator *
08166 
08167    TH1C hnew = h1;
08168    hnew.Multiply(&h2);
08169    hnew.SetDirectory(0);
08170    return hnew;
08171 }
08172 
08173 //______________________________________________________________________________
08174 TH1C operator/(const TH1C &h1, const TH1C &h2)
08175 {
08176    // Operator /
08177 
08178    TH1C hnew = h1;
08179    hnew.Divide(&h2);
08180    hnew.SetDirectory(0);
08181    return hnew;
08182 }
08183 
08184 
08185 
08186 //______________________________________________________________________________
08187 //                     TH1S methods
08188 // TH1S : histograms with one short per channel.  Maximum bin content = 32767
08189 //______________________________________________________________________________
08190 
08191 ClassImp(TH1S)
08192 
08193 //______________________________________________________________________________
08194 TH1S::TH1S(): TH1(), TArrayS()
08195 {
08196    // Constructor.
08197 
08198    fDimension = 1;
08199    SetBinsLength(3);
08200    if (fgDefaultSumw2) Sumw2();
08201 }
08202 
08203 //______________________________________________________________________________
08204 TH1S::TH1S(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
08205 : TH1(name,title,nbins,xlow,xup)
08206 {
08207    //
08208    //    Create a 1-Dim histogram with fix bins of type short
08209    //    ====================================================
08210    //           (see TH1::TH1 for explanation of parameters)
08211    //
08212    fDimension = 1;
08213    TArrayS::Set(fNcells);
08214 
08215    if (xlow >= xup) SetBuffer(fgBufferSize);
08216    if (fgDefaultSumw2) Sumw2();
08217 }
08218 
08219 //______________________________________________________________________________
08220 TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
08221 : TH1(name,title,nbins,xbins)
08222 {
08223    //
08224    //    Create a 1-Dim histogram with variable bins of type short
08225    //    =========================================================
08226    //           (see TH1::TH1 for explanation of parameters)
08227    //
08228    fDimension = 1;
08229    TArrayS::Set(fNcells);
08230    if (fgDefaultSumw2) Sumw2();
08231 }
08232 
08233 //______________________________________________________________________________
08234 TH1S::TH1S(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
08235 : TH1(name,title,nbins,xbins)
08236 {
08237    //
08238    //    Create a 1-Dim histogram with variable bins of type short
08239    //    =========================================================
08240    //           (see TH1::TH1 for explanation of parameters)
08241    //
08242    fDimension = 1;
08243    TArrayS::Set(fNcells);
08244    if (fgDefaultSumw2) Sumw2();
08245 }
08246 
08247 //______________________________________________________________________________
08248 TH1S::~TH1S()
08249 {
08250    // Destructor.
08251 }
08252 
08253 //______________________________________________________________________________
08254 TH1S::TH1S(const TH1S &h1s) : TH1(), TArrayS()
08255 {
08256    // Copy constructor.
08257 
08258    ((TH1S&)h1s).Copy(*this);
08259 }
08260 
08261 //______________________________________________________________________________
08262 void TH1S::AddBinContent(Int_t bin)
08263 {
08264    //   -*-*-*-*-*-*-*-*Increment bin content by 1*-*-*-*-*-*-*-*-*-*-*-*-*-*
08265    //                   ==========================
08266 
08267    if (fArray[bin] < 32767) fArray[bin]++;
08268 }
08269 
08270 //______________________________________________________________________________
08271 void TH1S::AddBinContent(Int_t bin, Double_t w)
08272 {
08273    //                   Increment bin content by w
08274    //                   ==========================
08275 
08276    Int_t newval = fArray[bin] + Int_t(w);
08277    if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
08278    if (newval < -32767) fArray[bin] = -32767;
08279    if (newval >  32767) fArray[bin] =  32767;
08280 }
08281 
08282 //______________________________________________________________________________
08283 void TH1S::Copy(TObject &newth1) const
08284 {
08285    // Copy this to newth1
08286 
08287    TH1::Copy(newth1);
08288 }
08289 
08290 //______________________________________________________________________________
08291 TH1 *TH1S::DrawCopy(Option_t *option) const
08292 {
08293    // Draw copy.
08294 
08295    TString opt = option;
08296    opt.ToLower();
08297    if (gPad && !opt.Contains("same")) gPad->Clear();
08298    TH1S *newth1 = (TH1S*)Clone();
08299    newth1->SetDirectory(0);
08300    newth1->SetBit(kCanDelete);
08301    newth1->AppendPad(option);
08302    return newth1;
08303 }
08304 
08305 //______________________________________________________________________________
08306 Double_t TH1S::GetBinContent(Int_t bin) const
08307 {
08308    // see convention for numbering bins in TH1::GetBin
08309    if (fBuffer) ((TH1S*)this)->BufferEmpty();
08310    if (bin < 0) bin = 0;
08311    if (bin >= fNcells) bin = fNcells-1;
08312    if (!fArray) return 0;
08313    return Double_t (fArray[bin]);
08314 }
08315 
08316 //______________________________________________________________________________
08317 void TH1S::Reset(Option_t *option)
08318 {
08319    // Reset.
08320 
08321    TH1::Reset(option);
08322    TArrayS::Reset();
08323 }
08324 
08325 //______________________________________________________________________________
08326 void TH1S::SetBinContent(Int_t bin, Double_t content)
08327 {
08328    // Set bin content
08329    // see convention for numbering bins in TH1::GetBin
08330    // In case the bin number is greater than the number of bins and
08331    // the timedisplay option is set or the kCanRebin bit is set,
08332    // the number of bins is automatically doubled to accomodate the new bin
08333 
08334    fEntries++;
08335    fTsumw = 0;
08336    if (bin < 0) return;
08337    if (bin >= fNcells-1) {
08338       if (fXaxis.GetTimeDisplay()) {
08339          while (bin >=  fNcells-1)  LabelsInflate();
08340       } else {
08341          if (!TestBit(kCanRebin)) {
08342             if (bin == fNcells-1) fArray[bin] = Short_t (content);
08343             return;
08344          }
08345          while (bin >= fNcells-1)  LabelsInflate();
08346       }
08347    }
08348    fArray[bin] = Short_t (content);
08349 }
08350 
08351 //______________________________________________________________________________
08352 void TH1S::SetBinsLength(Int_t n)
08353 {
08354    // Set total number of bins including under/overflow
08355    // Reallocate bin contents array
08356 
08357    if (n < 0) n = fXaxis.GetNbins() + 2;
08358    fNcells = n;
08359    TArrayS::Set(n);
08360 }
08361 
08362 //______________________________________________________________________________
08363 TH1S& TH1S::operator=(const TH1S &h1)
08364 {
08365    // Operator =
08366 
08367    if (this != &h1)  ((TH1S&)h1).Copy(*this);
08368    return *this;
08369 }
08370 
08371 
08372 //______________________________________________________________________________
08373 TH1S operator*(Double_t c1, const TH1S &h1)
08374 {
08375    // Operator *
08376 
08377    TH1S hnew = h1;
08378    hnew.Scale(c1);
08379    hnew.SetDirectory(0);
08380    return hnew;
08381 }
08382 
08383 //______________________________________________________________________________
08384 TH1S operator+(const TH1S &h1, const TH1S &h2)
08385 {
08386    // Operator +
08387 
08388    TH1S hnew = h1;
08389    hnew.Add(&h2,1);
08390    hnew.SetDirectory(0);
08391    return hnew;
08392 }
08393 
08394 //______________________________________________________________________________
08395 TH1S operator-(const TH1S &h1, const TH1S &h2)
08396 {
08397    // Operator -
08398 
08399    TH1S hnew = h1;
08400    hnew.Add(&h2,-1);
08401    hnew.SetDirectory(0);
08402    return hnew;
08403 }
08404 
08405 //______________________________________________________________________________
08406 TH1S operator*(const TH1S &h1, const TH1S &h2)
08407 {
08408    // Operator *
08409 
08410    TH1S hnew = h1;
08411    hnew.Multiply(&h2);
08412    hnew.SetDirectory(0);
08413    return hnew;
08414 }
08415 
08416 //______________________________________________________________________________
08417 TH1S operator/(const TH1S &h1, const TH1S &h2)
08418 {
08419    // Operator /
08420 
08421    TH1S hnew = h1;
08422    hnew.Divide(&h2);
08423    hnew.SetDirectory(0);
08424    return hnew;
08425 }
08426 
08427 
08428 //______________________________________________________________________________
08429 //                     TH1I methods
08430 // TH1I : histograms with one int per channel.    Maximum bin content = 2147483647
08431 //______________________________________________________________________________
08432 
08433 ClassImp(TH1I)
08434 
08435 //______________________________________________________________________________
08436 TH1I::TH1I(): TH1(), TArrayI()
08437 {
08438    // Constructor.
08439 
08440    fDimension = 1;
08441    SetBinsLength(3);
08442    if (fgDefaultSumw2) Sumw2();
08443 }
08444 
08445 //______________________________________________________________________________
08446 TH1I::TH1I(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
08447 : TH1(name,title,nbins,xlow,xup)
08448 {
08449    //
08450    //    Create a 1-Dim histogram with fix bins of type integer
08451    //    ====================================================
08452    //           (see TH1::TH1 for explanation of parameters)
08453    //
08454    fDimension = 1;
08455    TArrayI::Set(fNcells);
08456 
08457    if (xlow >= xup) SetBuffer(fgBufferSize);
08458    if (fgDefaultSumw2) Sumw2();
08459 }
08460 
08461 //______________________________________________________________________________
08462 TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
08463 : TH1(name,title,nbins,xbins)
08464 {
08465    //
08466    //    Create a 1-Dim histogram with variable bins of type integer
08467    //    =========================================================
08468    //           (see TH1::TH1 for explanation of parameters)
08469    //
08470    fDimension = 1;
08471    TArrayI::Set(fNcells);
08472    if (fgDefaultSumw2) Sumw2();
08473 }
08474 
08475 //______________________________________________________________________________
08476 TH1I::TH1I(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
08477 : TH1(name,title,nbins,xbins)
08478 {
08479    //
08480    //    Create a 1-Dim histogram with variable bins of type integer
08481    //    =========================================================
08482    //           (see TH1::TH1 for explanation of parameters)
08483    //
08484    fDimension = 1;
08485    TArrayI::Set(fNcells);
08486    if (fgDefaultSumw2) Sumw2();
08487 }
08488 
08489 //______________________________________________________________________________
08490 TH1I::~TH1I()
08491 {
08492    // Destructor.
08493 }
08494 
08495 //______________________________________________________________________________
08496 TH1I::TH1I(const TH1I &h1i) : TH1(), TArrayI()
08497 {
08498    // Copy constructor.
08499 
08500    ((TH1I&)h1i).Copy(*this);
08501 }
08502 
08503 //______________________________________________________________________________
08504 void TH1I::AddBinContent(Int_t bin)
08505 {
08506    //   -*-*-*-*-*-*-*-*Increment bin content by 1*-*-*-*-*-*-*-*-*-*-*-*-*-*
08507    //                   ==========================
08508 
08509    if (fArray[bin] < 2147483647) fArray[bin]++;
08510 }
08511 
08512 //______________________________________________________________________________
08513 void TH1I::AddBinContent(Int_t bin, Double_t w)
08514 {
08515    //                   Increment bin content by w
08516    //                   ==========================
08517 
08518    Int_t newval = fArray[bin] + Int_t(w);
08519    if (newval > -2147483647 && newval < 2147483647) {fArray[bin] = Int_t(newval); return;}
08520    if (newval < -2147483647) fArray[bin] = -2147483647;
08521    if (newval >  2147483647) fArray[bin] =  2147483647;
08522 }
08523 
08524 //______________________________________________________________________________
08525 void TH1I::Copy(TObject &newth1) const
08526 {
08527    // Copy this to newth1
08528 
08529    TH1::Copy(newth1);
08530 }
08531 
08532 //______________________________________________________________________________
08533 TH1 *TH1I::DrawCopy(Option_t *option) const
08534 {
08535    // Draw copy.
08536 
08537    TString opt = option;
08538    opt.ToLower();
08539    if (gPad && !opt.Contains("same")) gPad->Clear();
08540    TH1I *newth1 = (TH1I*)Clone();
08541    newth1->SetDirectory(0);
08542    newth1->SetBit(kCanDelete);
08543    newth1->AppendPad(option);
08544    return newth1;
08545 }
08546 
08547 //______________________________________________________________________________
08548 Double_t TH1I::GetBinContent(Int_t bin) const
08549 {
08550    // see convention for numbering bins in TH1::GetBin
08551    if (fBuffer) ((TH1I*)this)->BufferEmpty();
08552    if (bin < 0) bin = 0;
08553    if (bin >= fNcells) bin = fNcells-1;
08554    if (!fArray) return 0;
08555    return Double_t (fArray[bin]);
08556 }
08557 
08558 //______________________________________________________________________________
08559 void TH1I::Reset(Option_t *option)
08560 {
08561    // Reset.
08562 
08563    TH1::Reset(option);
08564    TArrayI::Reset();
08565 }
08566 
08567 //______________________________________________________________________________
08568 void TH1I::SetBinContent(Int_t bin, Double_t content)
08569 {
08570    // Set bin content
08571    // see convention for numbering bins in TH1::GetBin
08572    // In case the bin number is greater than the number of bins and
08573    // the timedisplay option is set or the kCanRebin bit is set,
08574    // the number of bins is automatically doubled to accomodate the new bin
08575 
08576    fEntries++;
08577    fTsumw = 0;
08578    if (bin < 0) return;
08579    if (bin >= fNcells-1) {
08580       if (fXaxis.GetTimeDisplay()) {
08581          while (bin >=  fNcells-1)  LabelsInflate();
08582       } else {
08583          if (!TestBit(kCanRebin)) {
08584             if (bin == fNcells-1) fArray[bin] = Int_t (content);
08585             return;
08586          }
08587          while (bin >= fNcells-1)  LabelsInflate();
08588       }
08589    }
08590    fArray[bin] = Int_t (content);
08591 }
08592 
08593 //______________________________________________________________________________
08594 void TH1I::SetBinsLength(Int_t n)
08595 {
08596    // Set total number of bins including under/overflow
08597    // Reallocate bin contents array
08598 
08599    if (n < 0) n = fXaxis.GetNbins() + 2;
08600    fNcells = n;
08601    TArrayI::Set(n);
08602 }
08603 
08604 //______________________________________________________________________________
08605 TH1I& TH1I::operator=(const TH1I &h1)
08606 {
08607    // Operator =
08608 
08609    if (this != &h1)  ((TH1I&)h1).Copy(*this);
08610    return *this;
08611 }
08612 
08613 
08614 //______________________________________________________________________________
08615 TH1I operator*(Double_t c1, const TH1I &h1)
08616 {
08617    // Operator *
08618 
08619    TH1I hnew = h1;
08620    hnew.Scale(c1);
08621    hnew.SetDirectory(0);
08622    return hnew;
08623 }
08624 
08625 //______________________________________________________________________________
08626 TH1I operator+(const TH1I &h1, const TH1I &h2)
08627 {
08628    // Operator +
08629 
08630    TH1I hnew = h1;
08631    hnew.Add(&h2,1);
08632    hnew.SetDirectory(0);
08633    return hnew;
08634 }
08635 
08636 //______________________________________________________________________________
08637 TH1I operator-(const TH1I &h1, const TH1I &h2)
08638 {
08639    // Operator -
08640 
08641    TH1I hnew = h1;
08642    hnew.Add(&h2,-1);
08643    hnew.SetDirectory(0);
08644    return hnew;
08645 }
08646 
08647 //______________________________________________________________________________
08648 TH1I operator*(const TH1I &h1, const TH1I &h2)
08649 {
08650    // Operator *
08651 
08652    TH1I hnew = h1;
08653    hnew.Multiply(&h2);
08654    hnew.SetDirectory(0);
08655    return hnew;
08656 }
08657 
08658 //______________________________________________________________________________
08659 TH1I operator/(const TH1I &h1, const TH1I &h2)
08660 {
08661    // Operator /
08662 
08663    TH1I hnew = h1;
08664    hnew.Divide(&h2);
08665    hnew.SetDirectory(0);
08666    return hnew;
08667 }
08668 
08669 
08670 //______________________________________________________________________________
08671 //                     TH1F methods
08672 // TH1F : histograms with one float per channel.  Maximum precision 7 digits
08673 //______________________________________________________________________________
08674 
08675 ClassImp(TH1F)
08676 
08677 //______________________________________________________________________________
08678 TH1F::TH1F(): TH1(), TArrayF()
08679 {
08680    // Constructor.
08681 
08682    fDimension = 1;
08683    SetBinsLength(3);
08684    if (fgDefaultSumw2) Sumw2();
08685 }
08686 
08687 //______________________________________________________________________________
08688 TH1F::TH1F(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
08689 : TH1(name,title,nbins,xlow,xup)
08690 {
08691    //
08692    //    Create a 1-Dim histogram with fix bins of type float
08693    //    ====================================================
08694    //           (see TH1::TH1 for explanation of parameters)
08695    //
08696    fDimension = 1;
08697    TArrayF::Set(fNcells);
08698 
08699    if (xlow >= xup) SetBuffer(fgBufferSize);
08700    if (fgDefaultSumw2) Sumw2();
08701 }
08702 
08703 //______________________________________________________________________________
08704 TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
08705 : TH1(name,title,nbins,xbins)
08706 {
08707    //
08708    //    Create a 1-Dim histogram with variable bins of type float
08709    //    =========================================================
08710    //           (see TH1::TH1 for explanation of parameters)
08711    //
08712    fDimension = 1;
08713    TArrayF::Set(fNcells);
08714    if (fgDefaultSumw2) Sumw2();
08715 }
08716 
08717 //______________________________________________________________________________
08718 TH1F::TH1F(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
08719 : TH1(name,title,nbins,xbins)
08720 {
08721    //
08722    //    Create a 1-Dim histogram with variable bins of type float
08723    //    =========================================================
08724    //           (see TH1::TH1 for explanation of parameters)
08725    //
08726    fDimension = 1;
08727    TArrayF::Set(fNcells);
08728    if (fgDefaultSumw2) Sumw2();
08729 }
08730 
08731 //______________________________________________________________________________
08732 TH1F::TH1F(const TVectorF &v)
08733 : TH1("TVectorF","",v.GetNrows(),0,v.GetNrows())
08734 {
08735    // Create a histogram from a TVectorF
08736    // by default the histogram name is "TVectorF" and title = ""
08737 
08738    TArrayF::Set(fNcells);
08739    fDimension = 1;
08740    Int_t ivlow  = v.GetLwb();
08741    for (Int_t i=0;i<fNcells-2;i++) {
08742       SetBinContent(i+1,v(i+ivlow));
08743    }
08744    TArrayF::Set(fNcells);
08745    if (fgDefaultSumw2) Sumw2();
08746 }
08747 
08748 //______________________________________________________________________________
08749 TH1F::TH1F(const TH1F &h) : TH1(), TArrayF()
08750 {
08751    // Copy Constructor.
08752 
08753    ((TH1F&)h).Copy(*this);
08754 }
08755 
08756 //______________________________________________________________________________
08757 TH1F::~TH1F()
08758 {
08759    // Destructor.
08760 }
08761 
08762 //______________________________________________________________________________
08763 void TH1F::Copy(TObject &newth1) const
08764 {
08765    // Copy this to newth1.
08766 
08767    TH1::Copy(newth1);
08768 }
08769 
08770 //______________________________________________________________________________
08771 TH1 *TH1F::DrawCopy(Option_t *option) const
08772 {
08773    // Draw copy.
08774 
08775    TString opt = option;
08776    opt.ToLower();
08777    if (gPad && !opt.Contains("same")) gPad->Clear();
08778    TH1F *newth1 = (TH1F*)Clone();
08779    newth1->SetDirectory(0);
08780    newth1->SetBit(kCanDelete);
08781    newth1->AppendPad(option);
08782    return newth1;
08783 }
08784 
08785 //______________________________________________________________________________
08786 Double_t TH1F::GetBinContent(Int_t bin) const
08787 {
08788    // see convention for numbering bins in TH1::GetBin
08789    if (fBuffer) ((TH1F*)this)->BufferEmpty();
08790    if (bin < 0) bin = 0;
08791    if (bin >= fNcells) bin = fNcells-1;
08792    if (!fArray) return 0;
08793    return Double_t (fArray[bin]);
08794 }
08795 
08796 //______________________________________________________________________________
08797 void TH1F::Reset(Option_t *option)
08798 {
08799    // Reset.
08800 
08801    TH1::Reset(option);
08802    TArrayF::Reset();
08803 }
08804 
08805 //______________________________________________________________________________
08806 void TH1F::SetBinContent(Int_t bin, Double_t content)
08807 {
08808    // Set bin content
08809    // see convention for numbering bins in TH1::GetBin
08810    // In case the bin number is greater than the number of bins and
08811    // the timedisplay option is set or the kCanRebin bit is set,
08812    // the number of bins is automatically doubled to accomodate the new bin
08813 
08814    fEntries++;
08815    fTsumw = 0;
08816    if (bin < 0) return;
08817    if (bin >= fNcells-1) {
08818       if (fXaxis.GetTimeDisplay()) {
08819          while (bin >=  fNcells-1)  LabelsInflate();
08820       } else {
08821          if (!TestBit(kCanRebin)) {
08822             if (bin == fNcells-1) fArray[bin] = Float_t (content);
08823             return;
08824          }
08825          while (bin >= fNcells-1)  LabelsInflate();
08826       }
08827    }
08828    fArray[bin] = Float_t (content);
08829 }
08830 
08831 //______________________________________________________________________________
08832 void TH1F::SetBinsLength(Int_t n)
08833 {
08834    // Set total number of bins including under/overflow
08835    // Reallocate bin contents array
08836 
08837    if (n < 0) n = fXaxis.GetNbins() + 2;
08838    fNcells = n;
08839    TArrayF::Set(n);
08840 }
08841 
08842 //______________________________________________________________________________
08843 TH1F& TH1F::operator=(const TH1F &h1)
08844 {
08845    // Operator =
08846 
08847    if (this != &h1)  ((TH1F&)h1).Copy(*this);
08848    return *this;
08849 }
08850 
08851 
08852 //______________________________________________________________________________
08853 TH1F operator*(Double_t c1, const TH1F &h1)
08854 {
08855    // Operator *
08856 
08857    TH1F hnew = h1;
08858    hnew.Scale(c1);
08859    hnew.SetDirectory(0);
08860    return hnew;
08861 }
08862 
08863 //______________________________________________________________________________
08864 TH1F operator+(const TH1F &h1, const TH1F &h2)
08865 {
08866    // Operator +
08867 
08868    TH1F hnew = h1;
08869    hnew.Add(&h2,1);
08870    hnew.SetDirectory(0);
08871    return hnew;
08872 }
08873 
08874 //______________________________________________________________________________
08875 TH1F operator-(const TH1F &h1, const TH1F &h2)
08876 {
08877    // Operator -
08878 
08879    TH1F hnew = h1;
08880    hnew.Add(&h2,-1);
08881    hnew.SetDirectory(0);
08882    return hnew;
08883 }
08884 
08885 //______________________________________________________________________________
08886 TH1F operator*(const TH1F &h1, const TH1F &h2)
08887 {
08888    // Operator *
08889 
08890    TH1F hnew = h1;
08891    hnew.Multiply(&h2);
08892    hnew.SetDirectory(0);
08893    return hnew;
08894 }
08895 
08896 //______________________________________________________________________________
08897 TH1F operator/(const TH1F &h1, const TH1F &h2)
08898 {
08899    // Operator /
08900 
08901    TH1F hnew = h1;
08902    hnew.Divide(&h2);
08903    hnew.SetDirectory(0);
08904    return hnew;
08905 }
08906 
08907 
08908 
08909 //______________________________________________________________________________
08910 //                     TH1D methods
08911 // TH1D : histograms with one double per channel. Maximum precision 14 digits
08912 //______________________________________________________________________________
08913 
08914 ClassImp(TH1D)
08915 
08916 //______________________________________________________________________________
08917 TH1D::TH1D(): TH1(), TArrayD()
08918 {
08919    // Constructor.
08920 
08921    fDimension = 1;
08922    SetBinsLength(3);
08923    if (fgDefaultSumw2) Sumw2();
08924 }
08925 
08926 //______________________________________________________________________________
08927 TH1D::TH1D(const char *name,const char *title,Int_t nbins,Double_t xlow,Double_t xup)
08928 : TH1(name,title,nbins,xlow,xup)
08929 {
08930    //
08931    //    Create a 1-Dim histogram with fix bins of type double
08932    //    =====================================================
08933    //           (see TH1::TH1 for explanation of parameters)
08934    //
08935    fDimension = 1;
08936    TArrayD::Set(fNcells);
08937 
08938    if (xlow >= xup) SetBuffer(fgBufferSize);
08939    if (fgDefaultSumw2) Sumw2();
08940 }
08941 
08942 //______________________________________________________________________________
08943 TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Float_t *xbins)
08944 : TH1(name,title,nbins,xbins)
08945 {
08946    //
08947    //    Create a 1-Dim histogram with variable bins of type double
08948    //    =====================================================
08949    //           (see TH1::TH1 for explanation of parameters)
08950    //
08951    fDimension = 1;
08952    TArrayD::Set(fNcells);
08953    if (fgDefaultSumw2) Sumw2();
08954 }
08955 
08956 //______________________________________________________________________________
08957 TH1D::TH1D(const char *name,const char *title,Int_t nbins,const Double_t *xbins)
08958 : TH1(name,title,nbins,xbins)
08959 {
08960    //
08961    //    Create a 1-Dim histogram with variable bins of type double
08962    //    =====================================================
08963    //           (see TH1::TH1 for explanation of parameters)
08964    //
08965    fDimension = 1;
08966    TArrayD::Set(fNcells);
08967    if (fgDefaultSumw2) Sumw2();
08968 }
08969 
08970 //______________________________________________________________________________
08971 TH1D::TH1D(const TVectorD &v)
08972 : TH1("TVectorD","",v.GetNrows(),0,v.GetNrows())
08973 {
08974    // Create a histogram from a TVectorD
08975    // by default the histogram name is "TVectorD" and title = ""
08976 
08977    TArrayD::Set(fNcells);
08978    fDimension = 1;
08979    Int_t ivlow  = v.GetLwb();
08980    for (Int_t i=0;i<fNcells-2;i++) {
08981       SetBinContent(i+1,v(i+ivlow));
08982    }
08983    TArrayD::Set(fNcells);
08984    if (fgDefaultSumw2) Sumw2();
08985 }
08986 
08987 //______________________________________________________________________________
08988 TH1D::~TH1D()
08989 {
08990    // Destructor.
08991 }
08992 
08993 //______________________________________________________________________________
08994 TH1D::TH1D(const TH1D &h1d) : TH1(), TArrayD()
08995 {
08996    // Constructor.
08997 
08998    ((TH1D&)h1d).Copy(*this);
08999 }
09000 
09001 //______________________________________________________________________________
09002 void TH1D::Copy(TObject &newth1) const
09003 {
09004    // Copy this to newth1
09005 
09006    TH1::Copy(newth1);
09007 }
09008 
09009 //______________________________________________________________________________
09010 TH1 *TH1D::DrawCopy(Option_t *option) const
09011 {
09012    // Draw copy.
09013 
09014    TString opt = option;
09015    opt.ToLower();
09016    if (gPad && !opt.Contains("same")) gPad->Clear();
09017    TH1D *newth1 = (TH1D*)Clone();
09018    newth1->SetDirectory(0);
09019    newth1->SetBit(kCanDelete);
09020    newth1->AppendPad(option);
09021    return newth1;
09022 }
09023 
09024 //______________________________________________________________________________
09025 Double_t TH1D::GetBinContent(Int_t bin) const
09026 {
09027    // see convention for numbering bins in TH1::GetBin
09028    if (fBuffer) ((TH1D*)this)->BufferEmpty();
09029    if (bin < 0) bin = 0;
09030    if (bin >= fNcells) bin = fNcells-1;
09031    if (!fArray) return 0;
09032    return Double_t (fArray[bin]);
09033 }
09034 
09035 //______________________________________________________________________________
09036 void TH1D::Reset(Option_t *option)
09037 {
09038    // Reset.
09039 
09040    TH1::Reset(option);
09041    TArrayD::Reset();
09042 }
09043 
09044 //______________________________________________________________________________
09045 void TH1D::SetBinContent(Int_t bin, Double_t content)
09046 {
09047    // Set bin content
09048    // see convention for numbering bins in TH1::GetBin
09049    // In case the bin number is greater than the number of bins and
09050    // the timedisplay option is set or the kCanRebin bit is set,
09051    // the number of bins is automatically doubled to accomodate the new bin
09052 
09053    fEntries++;
09054    fTsumw = 0;
09055    if (bin < 0) return;
09056    if (bin >= fNcells-1) {
09057       if (fXaxis.GetTimeDisplay()) {
09058          while (bin >=  fNcells-1)  LabelsInflate();
09059       } else {
09060          if (!TestBit(kCanRebin)) {
09061             if (bin == fNcells-1) fArray[bin] = content;
09062             return;
09063          }
09064          while (bin >= fNcells-1)  LabelsInflate();
09065       }
09066    }
09067    fArray[bin] = content;
09068 }
09069 
09070 //______________________________________________________________________________
09071 void TH1D::SetBinsLength(Int_t n)
09072 {
09073    // Set total number of bins including under/overflow
09074    // Reallocate bin contents array
09075 
09076    if (n < 0) n = fXaxis.GetNbins() + 2;
09077    fNcells = n;
09078    TArrayD::Set(n);
09079 }
09080 
09081 //______________________________________________________________________________
09082 TH1D& TH1D::operator=(const TH1D &h1)
09083 {
09084    // Operator =
09085 
09086    if (this != &h1)  ((TH1D&)h1).Copy(*this);
09087    return *this;
09088 }
09089 
09090 //______________________________________________________________________________
09091 TH1D operator*(Double_t c1, const TH1D &h1)
09092 {
09093    // Operator *
09094 
09095    TH1D hnew = h1;
09096    hnew.Scale(c1);
09097    hnew.SetDirectory(0);
09098    return hnew;
09099 }
09100 
09101 //______________________________________________________________________________
09102 TH1D operator+(const TH1D &h1, const TH1D &h2)
09103 {
09104    // Operator +
09105 
09106    TH1D hnew = h1;
09107    hnew.Add(&h2,1);
09108    hnew.SetDirectory(0);
09109    return hnew;
09110 }
09111 
09112 //______________________________________________________________________________
09113 TH1D operator-(const TH1D &h1, const TH1D &h2)
09114 {
09115    // Operator -
09116 
09117    TH1D hnew = h1;
09118    hnew.Add(&h2,-1);
09119    hnew.SetDirectory(0);
09120    return hnew;
09121 }
09122 
09123 //______________________________________________________________________________
09124 TH1D operator*(const TH1D &h1, const TH1D &h2)
09125 {
09126    // Operator *
09127 
09128    TH1D hnew = h1;
09129    hnew.Multiply(&h2);
09130    hnew.SetDirectory(0);
09131    return hnew;
09132 }
09133 
09134 //______________________________________________________________________________
09135 TH1D operator/(const TH1D &h1, const TH1D &h2)
09136 {
09137    // Operator /
09138 
09139    TH1D hnew = h1;
09140    hnew.Divide(&h2);
09141    hnew.SetDirectory(0);
09142    return hnew;
09143 }
09144 
09145 //______________________________________________________________________________
09146 TH1 *R__H(Int_t hid)
09147 {
09148    //return pointer to histogram with name
09149    //   hid if id >=0
09150    //   h_id if id <0
09151 
09152    TString hname;
09153    if(hid >= 0) hname.Form("h%d",hid);
09154    else         hname.Form("h_%d",hid);
09155    return (TH1*)gDirectory->Get(hname);
09156 }
09157 
09158 //______________________________________________________________________________
09159 TH1 *R__H(const char * hname)
09160 {
09161    //return pointer to histogram with name hname
09162 
09163    return (TH1*)gDirectory->Get(hname);
09164 }

Generated on Tue Jul 5 14:24:19 2011 for ROOT_528-00b_version by  doxygen 1.5.1