• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

BCHistogramFitter.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008, Daniel Kollar and Kevin Kroeninger.
00003  * All rights reserved.
00004  *
00005  * For the licensing terms see doc/COPYING.
00006  */
00007 
00008 // ---------------------------------------------------------
00009 
00010 #include <TH1D.h>
00011 #include <TF1.h>
00012 #include <TGraph.h>
00013 #include <TString.h>
00014 #include <TPad.h>
00015 #include <TRandom3.h>
00016 #include <TLegend.h>
00017 #include <TMath.h>
00018 #include <Math/ProbFuncMathCore.h> //for ROOT::Math namespace
00019 #include <TString.h>
00020 
00021 #include "BCLog.h"
00022 #include "BCDataSet.h"
00023 #include "BCDataPoint.h"
00024 #include "BCMath.h"
00025 
00026 #include "BCHistogramFitter.h"
00027 
00028 // ---------------------------------------------------------
00029 
00030 BCHistogramFitter::BCHistogramFitter() :
00031    BCModel("HistogramFitter")
00032 {
00033    fHistogram = 0;
00034    fFitFunction = 0;
00035 
00036    // set default options and values
00037    MCMCSetNIterationsRun(2000);
00038    SetFillErrorBand();
00039    fFlagIntegration = true;
00040    flag_discrete = true;
00041 }
00042 
00043 // ---------------------------------------------------------
00044 
00045 BCHistogramFitter::BCHistogramFitter(TH1D * hist, TF1 * func) :
00046    BCModel("HistogramFitter")
00047 {
00048    fHistogram = 0;
00049    fFitFunction = 0;
00050 
00051    SetHistogram(hist);
00052    SetFitFunction(func);
00053 
00054    MCMCSetNIterationsRun(2000);
00055    SetFillErrorBand();
00056    fFlagIntegration = true;
00057    flag_discrete = true;
00058 
00059    fHistogramExpected = 0;
00060 }
00061 
00062 // ---------------------------------------------------------
00063 
00064 int BCHistogramFitter::SetHistogram(TH1D * hist)
00065 {
00066    // check if histogram exists
00067    if (!hist) {
00068       BCLog::Out(BCLog::error, BCLog::error,
00069             "BCHistogramFitter::SetHistogram() : TH1D not created.");
00070       return 0;
00071    }
00072 
00073    // set pointer to histogram
00074    fHistogram = hist;
00075 
00076    // create a data set. this is necessary in order to calculate the
00077    // error band. the data set contains as many data points as there
00078    // are bins.
00079    BCDataSet * ds = new BCDataSet();
00080 
00081    // create data points and add them to the data set.
00082    // the x value is the lower edge of the bin, and
00083    // the y value is the bin count
00084    int nbins = fHistogram->GetNbinsX();
00085    for (int i = 0; i < nbins; ++i) {
00086       BCDataPoint* dp = new BCDataPoint(2);
00087       dp ->SetValue(0, fHistogram->GetBinLowEdge(i + 1));
00088       dp ->SetValue(1, fHistogram->GetBinContent(i + 1));
00089       ds->AddDataPoint(dp);
00090    }
00091 
00092    // set the new data set.
00093    SetDataSet(ds);
00094 
00095    // calculate the lower and upper edge in x.
00096    double xmin = hist->GetBinLowEdge(1);
00097    double xmax = hist->GetBinLowEdge(nbins + 1);
00098 
00099    // calculate the minimum and maximum range in y.
00100    double histymin = hist->GetMinimum();
00101    double histymax = hist->GetMaximum();
00102 
00103    // calculate the minimum and maximum of the function value based on
00104    // the minimum and maximum value in y.
00105    double ymin = TMath::Max(0., histymin - 5. * sqrt(histymin));
00106    double ymax = histymax + 5. * sqrt(histymax);
00107 
00108    // set the data boundaries for x and y values.
00109    SetDataBoundaries(0, xmin, xmax);
00110    SetDataBoundaries(1, ymin, ymax);
00111 
00112    // set the indeces for fitting.
00113    SetFitFunctionIndices(0, 1);
00114 
00115    // no error
00116    return 1;
00117 }
00118 
00119 // ---------------------------------------------------------
00120 
00121 int BCHistogramFitter::SetHistogramExpected(
00122       const std::vector<double>& parameters)
00123 {
00124    //clear up previous memory
00125    if (fHistogramExpected) {
00126       delete fHistogramExpected;
00127    }
00128    //copy all properties from the data histogram
00129    fHistogramExpected = new TH1D(*fHistogram);
00130 
00131    // get the number of bins
00132    int nBins = fHistogramExpected->GetNbinsX();
00133 
00134    // get bin width
00135    double dx = fHistogramExpected->GetBinWidth(1);
00136 
00137    //set the parameters of fit function
00138    fFitFunction->SetParameters(&parameters[0]);
00139 
00140    // get function value of lower bin edge
00141    double fedgelow = fFitFunction->Eval(fHistogramExpected->GetBinLowEdge(1));
00142 
00143    // loop over all bins, skip underflow
00144    for (int ibin = 1; ibin <= nBins; ++ibin) {
00145       // get upper bin edge
00146       double xedgehi = fHistogramExpected->GetBinLowEdge(ibin) + dx;
00147 
00148       //expected count
00149       double yexp = 0.;
00150 
00151       // use ROOT's TH1D::Integral method
00152       if (fFlagIntegration)
00153          yexp = fFitFunction->Integral(xedgehi - dx, xedgehi);
00154 
00155       // use linear interpolation
00156       else {
00157          // get function value at upper bin edge
00158          double fedgehi = fFitFunction->Eval(xedgehi);
00159          yexp = fedgelow * dx + (fedgehi - fedgelow) * dx / 2.;
00160 
00161          // make the upper edge the lower edge for the next iteration
00162          fedgelow = fedgehi;
00163       }
00164 
00165       //write the expectation for the bin
00166       fHistogramExpected->SetBinContent(ibin, yexp);
00167 
00168       //avoid automatic error as sqrt(yexp), used e.g. in Kolmogorov correction factor
00169       fHistogramExpected->SetBinError(ibin, 0.0);
00170 
00171       // but the data under this model have that sqrt(yexp) uncertainty
00172       fHistogram->SetBinError(ibin, sqrt(yexp));
00173 
00174    }
00175    return 1;
00176 }
00177 
00178 // ---------------------------------------------------------
00179 
00180 int BCHistogramFitter::SetFitFunction(TF1 * func)
00181 {
00182    // check if function exists
00183    if (!func) {
00184       BCLog::Out(BCLog::error, BCLog::error,
00185             "BCHistogramFitter::SetFitFunction() : TF1 not created.");
00186       return 0;
00187    }
00188 
00189    // set the function
00190    fFitFunction = func;
00191 
00192    // update the model name to contain the function name
00193    SetName(TString::Format("HistogramFitter with %s", fFitFunction->GetName()));
00194 
00195    // reset parameters
00196    fParameterSet->clear();
00197 
00198    // get the new number of parameters
00199    int n = func->GetNpar();
00200 
00201    // add parameters
00202    for (int i = 0; i < n; ++i) {
00203       double xmin;
00204       double xmax;
00205 
00206       func->GetParLimits(i, xmin, xmax);
00207 
00208       AddParameter(func->GetParName(i), xmin, xmax);
00209    }
00210 
00211    // set flat prior for all parameters by default
00212    SetPriorConstantAll();
00213 
00214    return GetNParameters();
00215 }
00216 
00217 // ---------------------------------------------------------
00218 
00219 BCHistogramFitter::~BCHistogramFitter()
00220 {
00221    delete fHistogramExpected;
00222 }
00223 
00224 // ---------------------------------------------------------
00225 
00226 /*
00227  double BCHistogramFitter::LogAPrioriProbability(std::vector<double> parameters)
00228  {
00229  // using flat probability in all parameters
00230  double logprob = 0.;
00231  for (unsigned int i = 0; i < GetNParameters(); i++)
00232  logprob -= log(GetParameter(i)->GetRangeWidth());
00233 
00234  return logprob;
00235  }
00236  */
00237 
00238 // ---------------------------------------------------------
00239 
00240 double BCHistogramFitter::LogLikelihood(std::vector<double> params)
00241 {
00242    // initialize probability
00243    double loglikelihood = 0;
00244 
00245    // set the parameters of the function
00246    fFitFunction->SetParameters(&params[0]);
00247 
00248    // get the number of bins
00249    int nbins = fHistogram->GetNbinsX();
00250 
00251    // get bin width
00252    double dx = fHistogram->GetBinWidth(1);
00253 
00254    // get function value of lower bin edge
00255    double fedgelow = fFitFunction->Eval(fHistogram->GetBinLowEdge(1));
00256 
00257    // loop over all bins
00258    for (int ibin = 1; ibin <= nbins; ++ibin) {
00259       // get upper bin edge
00260       double xedgehi = fHistogram->GetBinLowEdge(ibin) + dx;
00261 
00262       // get function value at upper bin edge
00263       double fedgehi = fFitFunction->Eval(xedgehi);
00264 
00265       // get the number of observed events
00266       double y = fHistogram->GetBinContent(ibin);
00267 
00268       double yexp = 0.;
00269 
00270       // use ROOT's TH1D::Integral method
00271       if (fFlagIntegration)
00272          yexp = fFitFunction->Integral(xedgehi - dx, xedgehi);
00273 
00274       // use linear interpolation
00275       else {
00276          yexp = fedgelow * dx + (fedgehi - fedgelow) * dx / 2.;
00277 
00278          // make the upper edge the lower edge for the next iteration
00279          fedgelow = fedgehi;
00280       }
00281 
00282       // get the value of the Poisson distribution
00283       loglikelihood += BCMath::LogPoisson(y, yexp);
00284    }
00285 
00286    // // get bin boundaries
00287    // double xmin = fHistogram->GetBinLowEdge(ibin);
00288    // double xmax = fHistogram->GetBinLowEdge(ibin+1);
00289 
00290    // // get the number of observed events
00291    // double y = fHistogram->GetBinContent(ibin);
00292 
00293    // // get the number of expected events
00294    // double yexp = fFitFunction->Integral(xmin, xmax);
00295 
00296    // // get the value of the Poisson distribution
00297    // loglikelihood += BCMath::LogPoisson(y, yexp);
00298 
00299    return loglikelihood;
00300 }
00301 
00302 // ---------------------------------------------------------
00303 
00304 double BCHistogramFitter::FitFunction(std::vector<double> x,
00305       std::vector<double> params)
00306 {
00307    // set the parameters of the function
00308    fFitFunction->SetParameters(&params[0]);
00309 
00310    return fFitFunction->Eval(x[0]) * fHistogram->GetBinWidth(
00311          fHistogram->FindBin(x[0]));
00312 }
00313 
00314 // ---------------------------------------------------------
00315 
00316 int BCHistogramFitter::Fit(TH1D * hist, TF1 * func)
00317 {
00318    // set histogram
00319    if (hist)
00320       SetHistogram(hist);
00321    else {
00322       BCLog::OutError("BCHistogramFitter::Fit : Histogram not defined.");
00323       return 0;
00324    }
00325 
00326    // set function
00327    if (func)
00328       SetFitFunction(func);
00329    else {
00330       BCLog::OutError("BCHistogramFitter::Fit : Fit function not defined.");
00331       return 0;
00332    }
00333 
00334    return Fit();
00335 }
00336 
00337 // ---------------------------------------------------------
00338 
00339 int BCHistogramFitter::Fit()
00340 {
00341    // set histogram
00342    if (!fHistogram) {
00343       BCLog::OutError("BCHistogramFitter::Fit : Histogram not defined.");
00344       return 0;
00345    }
00346 
00347    // set function
00348    if (!fFitFunction) {
00349       BCLog::OutError("BCHistogramFitter::Fit : Fit function not defined.");
00350       return 0;
00351    }
00352 
00353    // perform marginalization
00354    MarginalizeAll();
00355 
00356    // maximize posterior probability, using the best-fit values close
00357    // to the global maximum from the MCMC
00358    FindModeMinuit(GetBestFitParameters(), -1);
00359 
00360    // calculate the p-value using the fast MCMC algorithm
00361    double pvalue;
00362    if (CalculatePValueFast(GetBestFitParameters(), pvalue))
00363       fPValue = pvalue;
00364    else
00365       BCLog::OutWarning(
00366             "BCHistogramFitter::Fit : Could not use the fast p-value evaluation.");
00367 
00368    // print summary to screen
00369    PrintShortFitSummary();
00370 
00371    // no error
00372    return 1;
00373 }
00374 
00375 // ---------------------------------------------------------
00376 
00377 void BCHistogramFitter::DrawFit(const char * options, bool flaglegend)
00378 {
00379    if (!fHistogram) {
00380       BCLog::OutError("BCHistogramFitter::DrawFit : Histogram not defined.");
00381       return;
00382    }
00383 
00384    if (!fFitFunction) {
00385       BCLog::OutError("BCHistogramFitter::DrawFit : Fit function not defined.");
00386       return;
00387    }
00388 
00389    if (!fErrorBandXY || fBestFitParameters.empty()) {
00390       BCLog::OutError("BCHistogramFitter::DrawFit : Fit not performed yet.");
00391       return;
00392    }
00393 
00394    // check wheather options contain "same"
00395    TString opt = options;
00396    opt.ToLower();
00397 
00398    // if not same, draw the histogram first to get the axes
00399    if (!opt.Contains("same"))
00400       fHistogram->Draw(opt.Data());
00401 
00402    // draw the error band as central 68% probability interval
00403    fErrorBand = GetErrorBandGraph(0.16, 0.84);
00404    fErrorBand->Draw("f same");
00405 
00406    // now draw the histogram again since it was covered by the band
00407    fHistogram->Draw(TString::Format("%ssame", opt.Data()));
00408 
00409    // draw the fit function on top
00410    fGraphFitFunction = GetFitFunctionGraph(GetBestFitParameters());
00411    fGraphFitFunction->SetLineColor(kRed);
00412    fGraphFitFunction->SetLineWidth(2);
00413    fGraphFitFunction->Draw("l same");
00414 
00415    // draw legend
00416    if (flaglegend) {
00417       TLegend * legend = new TLegend(0.25, 0.75, 0.55, 0.95);
00418       legend->SetBorderSize(0);
00419       legend->SetFillColor(kWhite);
00420       legend->AddEntry(fHistogram, "Data", "L");
00421       legend->AddEntry(fGraphFitFunction, "Best fit", "L");
00422       legend->AddEntry(fErrorBand, "Error band", "F");
00423       legend->Draw();
00424    }
00425 
00426    gPad->RedrawAxis();
00427 }
00428 
00429 // ---------------------------------------------------------
00430 int BCHistogramFitter::CalculatePValueFast(std::vector<double> par,
00431       double &pvalue, int nIterations)
00432 {
00433    //use NULL pointer for no callback
00434    return CalculatePValueFast(par, 0, pvalue,  nIterations);
00435 }
00436 
00437 // ---------------------------------------------------------
00438 int BCHistogramFitter::CalculatePValueFast(std::vector<double> par, BCHistogramFitterToyDataInterface* callback,
00439       double &pvalue,  int nIterations)
00440 {
00441    // check size of parameter vector
00442    if (par.size() != GetNParameters()) {
00443       BCLog::OutError(
00444             "BCHistogramFitter::CalculatePValueFast : Number of parameters is inconsistent.");
00445       return 0;
00446    }
00447 
00448    // check if histogram exists
00449    if (!fHistogram) {
00450       BCLog::OutError(
00451             "BCHistogramFitter::CalculatePValueFast : Histogram not defined.");
00452       return 0;
00453    }
00454 
00455    // define temporary variables
00456    int nbins = fHistogram->GetNbinsX();
00457 
00458    std::vector<int> histogram;
00459    std::vector<double> expectation;
00460    histogram.assign(nbins, 0);
00461    expectation.assign(nbins, 0);
00462 
00463    double logp = 0;
00464    double logp_start = 0;
00465    int counter_pvalue = 0;
00466 
00467    //update the expected number of events for all bins
00468    SetHistogramExpected(par);
00469 
00470    // define starting distribution as histogram with most likely entries
00471    for (int ibin = 0; ibin < nbins; ++ibin) {
00472 
00473       // get the number of expected events
00474       double yexp = fHistogramExpected->GetBinContent(ibin + 1);
00475 
00476       //most likely observed value = int(expected value)
00477       histogram[ibin] = int(yexp);
00478       expectation[ibin] = yexp;
00479 
00480       // calculate test statistic (= likelihood of entire histogram) for starting distr.
00481       logp += BCMath::LogPoisson(double(int(yexp)), yexp);
00482       //statistic of the observed data set
00483       logp_start += BCMath::LogPoisson(fHistogram->GetBinContent(ibin + 1),
00484             yexp);
00485    }
00486 
00487    // loop over iterations
00488    for (int iiter = 0; iiter < nIterations; ++iiter) {
00489       // loop over bins
00490       for (int ibin = 0; ibin < nbins; ++ibin) {
00491          // random step up or down in statistics for this bin
00492          double ptest = fRandom->Rndm() - 0.5;
00493 
00494          // increase statistics by 1
00495          if (ptest > 0) {
00496             // calculate factor of probability
00497             double r = expectation.at(ibin) / double(histogram.at(ibin) + 1);
00498 
00499             // walk, or don't (this is the Metropolis part)
00500             if (fRandom->Rndm() < r) {
00501                histogram[ibin] = histogram.at(ibin) + 1;
00502                logp += log(r);
00503             }
00504          }
00505 
00506          // decrease statistics by 1
00507          else if (ptest <= 0 && histogram[ibin] > 0) {
00508             // calculate factor of probability
00509             double r = double(histogram.at(ibin)) / expectation.at(ibin);
00510 
00511             // walk, or don't (this is the Metropolis part)
00512             if (fRandom->Rndm() < r) {
00513                histogram[ibin] = histogram.at(ibin) - 1;
00514                logp += log(r);
00515             }
00516          }
00517       } // end of looping over bins
00518 
00519       //one new toy data set is created
00520       //call user interface to calculate arbitrary statistic's distribution
00521       if (callback)
00522          (*callback)(expectation, histogram);
00523 
00524       // increase counter
00525       if (logp < logp_start)
00526          counter_pvalue++;
00527 
00528    } // end of looping over iterations
00529 
00530    // calculate p-value
00531    pvalue = double(counter_pvalue) / double(nIterations);
00532 
00533    // no error
00534    return 1;
00535 }
00536 
00537 // ---------------------------------------------------------
00538 
00539 int BCHistogramFitter::CalculatePValueLikelihood(std::vector<double> par,
00540       double &pvalue)
00541 {
00542    // initialize test statistic -2*lambda
00543    double logLambda = 0.0;
00544 
00545    //Calculate expected counts to compare with
00546    SetHistogramExpected(par);
00547 
00548    for (int ibin = 1; ibin <= fHistogram->GetNbinsX(); ++ibin) {
00549 
00550       // get the number of observed events
00551       double y = fHistogram->GetBinContent(ibin);
00552 
00553       // get the number of expected events
00554       double yexp = fHistogramExpected->GetBinContent(ibin);
00555 
00556       // get the contribution from this datapoint
00557       if (y == 0)
00558          logLambda += yexp;
00559       else
00560          logLambda += yexp - y + y * log(y / yexp);
00561    }
00562 
00563    // rescale
00564    logLambda *= 2.0;
00565 
00566    // compute degrees of freedom for Poisson case
00567    int nDoF = GetNDataPoints() - GetNParameters();
00568 
00569    //p value from chi^2 distribution, returns zero if logLambda < 0
00570    fPValueNDoF = TMath::Prob(logLambda, nDoF);
00571    pvalue = fPValueNDoF;
00572 
00573    // no error
00574    return 1;
00575 }
00576 
00577 // ---------------------------------------------------------
00578 
00579 int BCHistogramFitter::CalculatePValueLeastSquares(std::vector<double> par,
00580       double &pvalue, bool weightExpect)
00581 {
00582    // initialize test statistic chi^2
00583    double chi2 = 0.0;
00584 
00585    //Calculate expected counts to compare with
00586    SetHistogramExpected(par);
00587 
00588    for (int ibin = 1; ibin <= fHistogram->GetNbinsX(); ++ibin) {
00589 
00590       // get the number of observed events
00591       double y = fHistogram->GetBinContent(ibin);
00592 
00593       // get the number of expected events
00594       double yexp = fHistogramExpected->GetBinContent(ibin);
00595 
00596       //convert 1/0.0 into 1 for weighted sum
00597       double weight;
00598       if (weightExpect)
00599          weight = (yexp > 0) ? yexp : 1.0;
00600       else
00601          weight = (y > 0) ? y : 1.0;
00602 
00603       // get the contribution from this datapoint
00604       chi2 += (y - yexp) * (y - yexp) / weight;
00605    }
00606 
00607    // compute degrees of freedom for Poisson case
00608    int nDoF = GetNDataPoints() - GetNParameters();
00609 
00610    // p value from chi^2 distribution, returns zero if logLambda < 0
00611    fPValueNDoF = TMath::Prob(chi2, nDoF);
00612    pvalue = fPValueNDoF;
00613 
00614    // no error
00615    return 1;
00616 }
00617 
00618 // ---------------------------------------------------------
00619 
00620 int BCHistogramFitter::CalculatePValueKolmogorov(std::vector<double> par,
00621       double& pvalue)
00622 {
00623    if (!fHistogramExpected || !fHistogram) {
00624       BCLog::OutError("BCHistogramFitter::CalculatePValueKolmogorov: "
00625          "Please define the reference distribution by calling \n"
00626          "BCHistogramFitter::SetHistogramExpected() first!");
00627       return 0;
00628    }
00629 
00630    //update expected counts with current parameters
00631    SetHistogramExpected(par);
00632 
00633    //perform the test
00634    pvalue = fHistogramExpected->KolmogorovTest(fHistogram);
00635 
00636    fPValue = pvalue;
00637 
00638    // no error
00639    return 1;
00640 }
00641 
00642 // ---------------------------------------------------------
00643 
00644 double BCHistogramFitter::CDF(const std::vector<double>& parameters, int index,
00645       bool lower)
00646 {
00647 
00648    if (parameters.empty())
00649       BCLog::OutWarning("BCHistogramFitter::CDF: parameter vector empty!");
00650    //histogram stores underflow in bin 0, so datapoint 0 is in bin 1
00651    index++;
00652 
00653    // get the number of observed events (should be integer)
00654    double yObs = fHistogram->GetBinContent(index);
00655 
00656    // if(double( (unsigned int)yObs)==yObs)
00657    //    BCLog::OutWarning(Form(
00658    //          "BCHistogramFitter::CDF: using bin count %f that  is not an integer!",yObs));
00659 
00660    // get function value of lower bin edge
00661    double edgeLow = fHistogram->GetBinLowEdge(index);
00662    double edgeHigh = edgeLow + fHistogram->GetBinWidth(index);
00663 
00664    // expectation value of this bin
00665    double yExp = 0.0;
00666 
00667    // use ROOT's TH1D::Integral method
00668    if (fFlagIntegration)
00669       yExp = fFitFunction->Integral(edgeLow, edgeHigh, &parameters[0]);
00670 
00671    // use linear interpolation
00672    else {
00673       double dx = fHistogram->GetBinWidth(index);
00674       double fEdgeLow = fFitFunction->Eval(edgeLow);
00675       double fEdgeHigh = fFitFunction->Eval(edgeHigh);
00676       yExp = fEdgeLow * dx + (fEdgeHigh - fEdgeLow) * dx / 2.;
00677    }
00678 
00679    // usually Poisson bins do not agree with fixed probability bins
00680    // so choose where it should belong
00681 
00682    if (lower) {
00683       if ((int) yObs >= 1)
00684          return ROOT::Math::poisson_cdf((unsigned int) (yObs - 1), yExp);
00685       else
00686          return 0.0;
00687    }
00688    // what if yObs as double doesn't reprepsent a whole number? exceptioN?
00689    if ((double) (unsigned int) yObs != yObs) {
00690       BCLog::OutWarning(Form(
00691             "BCHistogramFitter::CDF: Histogram values should be integer!\n"
00692                " Bin %d = %f", index, yObs));
00693 
00694       //convert randomly to integer
00695       // ex. yObs = 9.785 =>
00696       //      yObs --> 10 with P = 78.5%
00697       //      yObs --> 9  with P = 21.5%
00698       double U = fRandom->Rndm();
00699       double yObsLower = (unsigned int) yObs;
00700       if (U > (yObs - yObsLower))
00701          yObs = yObsLower;
00702       else
00703          yObs = yObsLower + 1;
00704    }
00705 
00706    // BCLog::OutDebug(Form("yExp= %f yObs= %f par2=%",yExp, yObs,parameters.at(2)));
00707    // BCLog::Out(TString::Format("yExp= %f yObs= %f par2=%",yExp, yObs,parameters.at(2)));
00708 
00709    return ROOT::Math::poisson_cdf((unsigned int) yObs, yExp);
00710 }
00711 
00712 // ---------------------------------------------------------

Generated by  doxygen 1.7.1