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

BCModel.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008-2010, Daniel Kollar and Kevin Kroeninger.
00003  * All rights reserved.
00004  *
00005  * For the licensing terms see doc/COPYING.
00006  */
00007 
00008 // ---------------------------------------------------------
00009 
00010 #include "BAT/BCModel.h"
00011 
00012 #include "BAT/BCDataPoint.h"
00013 #include "BAT/BCDataSet.h"
00014 #include "BAT/BCParameter.h"
00015 #include "BAT/BCH1D.h"
00016 #include "BAT/BCH2D.h"
00017 #include "BAT/BCGoFTest.h"
00018 #include "BAT/BCLog.h"
00019 #include "BAT/BCErrorCodes.h"
00020 #include "BAT/BCMath.h"
00021 #include "BAT/BCModelOutput.h"
00022 
00023 #include <TROOT.h>
00024 #include <TCanvas.h>
00025 #include <TPostScript.h>
00026 #include <TDirectory.h>
00027 #include <TFile.h>
00028 #include <TKey.h>
00029 #include <TTree.h>
00030 #include <TMath.h>
00031 #include <TGraph.h>
00032 #include <TH2D.h>
00033 #include <TH1I.h>
00034 #include <TRandom3.h>
00035 #include <TF1.h>
00036 #include <Math/QuantFuncMathCore.h>
00037 
00038 #include <algorithm>
00039 #include <set>
00040 
00041 #include <fstream>
00042 #include <iomanip>
00043 
00044 // ---------------------------------------------------------
00045 BCModel::BCModel(const char * name)
00046    : BCIntegrate()
00047 {
00048    fNormalization = -1.;
00049    fDataSet = 0;
00050    fParameterSet = new BCParameterSet;
00051 
00052    fIndex = -1;
00053    fPValue = -1;
00054    fPValueNDoF = -1;
00055    fChi2NDoF = -1;
00056 
00057    fName = (char *) name;
00058    flag_ConditionalProbabilityEntry = true;
00059 
00060    fDataPointUpperBoundaries = 0;
00061    fDataPointLowerBoundaries = 0;
00062 
00063    fErrorBandXY = 0;
00064 
00065    fGoFNChains = 5;
00066    fGoFNIterationsMax = 100000;
00067    fGoFNIterationsRun = 2000;
00068 
00069    flag_discrete = false;
00070 
00071    fPriorConstantAll = false;
00072    fPriorConstantValue = 0;
00073 }
00074 
00075 // ---------------------------------------------------------
00076 BCModel::BCModel()
00077    : BCIntegrate()
00078 {
00079    fNormalization = -1.;
00080    fDataSet = 0;
00081    fParameterSet = new BCParameterSet();
00082 
00083    fIndex = -1;
00084    fPValue = -1;
00085    fPValueNDoF = -1;
00086    fChi2NDoF = -1;
00087 
00088    fName = "model";
00089    fDataPointUpperBoundaries = 0;
00090    fDataPointLowerBoundaries = 0;
00091 
00092    flag_ConditionalProbabilityEntry = true;
00093 
00094    fGoFNChains = 5;
00095    fGoFNIterationsMax = 100000;
00096    fGoFNIterationsRun = 2000;
00097 
00098    flag_discrete = false;
00099 
00100    fPriorConstantAll = false;
00101    fPriorConstantValue = 0;
00102 }
00103 
00104 // ---------------------------------------------------------
00105 BCModel::~BCModel()
00106 {
00107    for (unsigned int i = 0; i < GetNParameters(); ++i) 
00108       delete fPriorContainer[i]; 
00109    fPriorContainer.clear();
00110 
00111    delete fParameterSet;
00112 
00113    delete fDataPointLowerBoundaries;
00114    delete fDataPointUpperBoundaries;
00115 }
00116 
00117 // ---------------------------------------------------------
00118 int BCModel::GetNDataPoints()
00119 {
00120    int npoints = 0;
00121    if (fDataSet)
00122       npoints = fDataSet->GetNDataPoints();
00123    else {
00124       BCLog::OutWarning("BCModel::GetNDataPoints() : No data set defined.");
00125       return ERROR_NOEVENTS;
00126    }
00127 
00128    return npoints;
00129 }
00130 
00131 // ---------------------------------------------------------
00132 BCDataPoint * BCModel::GetDataPoint(unsigned int index)
00133 {
00134    if (fDataSet)
00135       return fDataSet->GetDataPoint(index);
00136 
00137    BCLog::OutWarning("BCModel::GetDataPoint : No data set defined.");
00138    return 0;
00139 }
00140 
00141 // ---------------------------------------------------------
00142 BCParameter * BCModel::GetParameter(int index)
00143 {
00144    if (!fParameterSet)
00145       return 0;
00146 
00147    if (index < 0 || index >= (int)GetNParameters()) {
00148       BCLog::OutWarning(
00149             Form("BCModel::GetParameter : Parameter index %d not within range.",index));
00150       return 0;
00151    }
00152 
00153    return fParameterSet->at(index);
00154 }
00155 
00156 // ---------------------------------------------------------
00157 BCParameter * BCModel::GetParameter(const char * name)
00158 {
00159    if (!fParameterSet)
00160       return 0;
00161 
00162    int index = -1;
00163    for (unsigned int i = 0; i < GetNParameters(); i++)
00164       if (name == GetParameter(i)->GetName())
00165          index = i;
00166 
00167    if (index < 0) {
00168       BCLog::OutWarning(
00169             Form("BCModel::GetParameter : Model %s has no parameter named '%s'",
00170                  GetName().data(), name));
00171       return 0;
00172    }
00173 
00174    return GetParameter(index);
00175 }
00176 
00177 // ---------------------------------------------------------
00178 double BCModel::GetBestFitParameter(unsigned int index)
00179 {
00180    if(index >= GetNParameters()) {
00181       BCLog::OutError("BCModel::GetBestFitParameter : Parameter index out of range, returning -1e+111.");
00182       return -1e+111;
00183    }
00184 
00185    if(fBestFitParameters.size()==0) {
00186       BCLog::OutError("BCModel::GetBestFitParameter : Mode finding not yet run, returning center of the range.");
00187       return (GetParameter(index)->GetUpperLimit() + GetParameter(index)->GetLowerLimit() ) / 2.;
00188    }
00189 
00190    return fBestFitParameters[index];
00191 }
00192 
00193 // ---------------------------------------------------------
00194 double BCModel::GetBestFitParameterError(unsigned int index)
00195 {
00196    if(index >= GetNParameters()) {
00197       BCLog::OutError("BCModel::GetBestFitParameterError : Parameter index out of range, returning -1.");
00198       return -1;
00199    }
00200 
00201    if(fBestFitParameterErrors.size()==0) {
00202       BCLog::OutError("BCModel::GetBestFitParameterError : Mode finding not yet run, returning -1.");
00203       return -1.;
00204    }
00205 
00206    if(fBestFitParameterErrors[index]<0.)
00207       BCLog::OutWarning("BCModel::GetBestFitParameterError : Parameter error not available, returning -1.");
00208 
00209    return fBestFitParameterErrors[index];
00210 }
00211 
00212 // ---------------------------------------------------------
00213 double BCModel::GetBestFitParameterMarginalized(unsigned int index)
00214 {
00215    if(index >= GetNParameters()) {
00216       BCLog::OutError("BCModel::GetBestFitParameterMarginalized : Parameter index out of range, returning -1e+111.");
00217       return -1e+111;
00218    }
00219 
00220    if(fBestFitParametersMarginalized.size()==0) {
00221       BCLog::OutError("BCModel::GetBestFitParameterMarginalized : MCMC not yet run, returning center of the range.");
00222       return (GetParameter(index)->GetUpperLimit() + GetParameter(index)->GetLowerLimit() ) / 2.;
00223    }
00224 
00225    return fBestFitParametersMarginalized[index];
00226 }
00227 
00228 // ---------------------------------------------------------
00229 void BCModel::SetNbins(const char * parname, int nbins)
00230 {
00231    BCParameter * p = GetParameter(parname);
00232    if (!p) {
00233       BCLog::OutWarning(
00234             Form("BCModel::SetNbins : Parameter '%s' not found so Nbins not set",parname));
00235       return;
00236    }
00237 
00238    BCIntegrate::SetNbins(nbins, p->GetIndex());
00239 }
00240 
00241 // ---------------------------------------------------------
00242 std::vector<double> BCModel::GetErrorBand(double level)
00243 {
00244    std::vector<double> errorband;
00245 
00246    if (!fErrorBandXY)
00247       return errorband;
00248 
00249    int nx = fErrorBandXY->GetNbinsX();
00250    errorband.assign(nx, 0.);
00251 
00252    // loop over x and y bins
00253    for (int ix = 1; ix <= nx; ix++) {
00254       TH1D * temphist = fErrorBandXY->ProjectionY("temphist", ix, ix);
00255 
00256       int nprobSum = 1;
00257       double q[1];
00258       double probSum[1];
00259       probSum[0] = level;
00260 
00261       temphist->GetQuantiles(nprobSum, q, probSum);
00262 
00263       errorband[ix - 1] = q[0];
00264    }
00265 
00266    return errorband;
00267 }
00268 
00269 // ---------------------------------------------------------
00270 TGraph * BCModel::GetErrorBandGraph(double level1, double level2)
00271 {
00272    if (!fErrorBandXY)
00273       return 0;
00274 
00275    // define new graph
00276    int nx = fErrorBandXY->GetNbinsX();
00277 
00278    TGraph * graph = new TGraph(2 * nx);
00279    graph->SetFillStyle(1001);
00280    graph->SetFillColor(kYellow);
00281 
00282    // get error bands
00283    std::vector<double> ymin = GetErrorBand(level1);
00284    std::vector<double> ymax = GetErrorBand(level2);
00285 
00286    for (int i = 0; i < nx; i++) {
00287       graph->SetPoint(i, fErrorBandXY->GetXaxis()->GetBinCenter(i + 1), ymin[i]);
00288       graph->SetPoint(nx + i, fErrorBandXY->GetXaxis()->GetBinCenter(nx - i), ymax[nx - i - 1]);
00289    }
00290 
00291    return graph;
00292 }
00293 
00294 // ---------------------------------------------------------
00295 TH2D * BCModel::GetErrorBandXY_yellow(double level, int nsmooth)
00296 {
00297    if (!fErrorBandXY)
00298       return 0;
00299 
00300    int nx = fErrorBandXY->GetNbinsX();
00301    int ny = fErrorBandXY->GetNbinsY();
00302 
00303    // copy existing histogram
00304    TH2D * hist_tempxy = (TH2D*) fErrorBandXY->Clone(
00305          TString::Format("%s_sub_%f.2", fErrorBandXY->GetName(), level));
00306    hist_tempxy->Reset();
00307    hist_tempxy->SetFillColor(kYellow);
00308 
00309    // loop over x bins
00310    for (int ix = 1; ix < nx; ix++) {
00311       BCH1D * hist_temp = new BCH1D();
00312 
00313       TH1D * hproj = fErrorBandXY->ProjectionY("temphist", ix, ix);
00314       if (nsmooth > 0)
00315          hproj->Smooth(nsmooth);
00316 
00317       hist_temp->SetHistogram(hproj);
00318 
00319       TH1D * hist_temp_yellow = hist_temp->GetSmallestIntervalHistogram(level);
00320 
00321       for (int iy = 1; iy <= ny; ++iy)
00322          hist_tempxy->SetBinContent(ix, iy, hist_temp_yellow->GetBinContent(iy));
00323 
00324       delete hist_temp_yellow;
00325       delete hist_temp;
00326    }
00327 
00328    return hist_tempxy;
00329 }
00330 
00331 // ---------------------------------------------------------
00332 TGraph * BCModel::GetFitFunctionGraph(std::vector<double> parameters)
00333 {
00334    if (!fErrorBandXY)
00335       return 0;
00336 
00337    // define new graph
00338    int nx = fErrorBandXY->GetNbinsX();
00339    TGraph * graph = new TGraph(nx);
00340 
00341    // loop over x values
00342    for (int i = 0; i < nx; i++) {
00343       double x = fErrorBandXY->GetXaxis()->GetBinCenter(i + 1);
00344 
00345       std::vector<double> xvec;
00346       xvec.push_back(x);
00347       double y = FitFunction(xvec, parameters);
00348       xvec.clear();
00349 
00350       graph->SetPoint(i, x, y);
00351    }
00352 
00353    return graph;
00354 }
00355 
00356 // ---------------------------------------------------------
00357 TGraph * BCModel::GetFitFunctionGraph(std::vector<double> parameters, double xmin, double xmax, int n)
00358 {
00359    // define new graph
00360    TGraph * graph = new TGraph(n + 1);
00361 
00362    double dx = (xmax - xmin) / (double) n;
00363 
00364    // loop over x values
00365    for (int i = 0; i <= n; i++) {
00366       double x = (double) i * dx + xmin;
00367       std::vector<double> xvec;
00368       xvec.push_back(x);
00369       double y = FitFunction(xvec, parameters);
00370 
00371       xvec.clear();
00372 
00373       graph->SetPoint(i, x, y);
00374    }
00375 
00376    return graph;
00377 }
00378 
00379 // ---------------------------------------------------------
00380 bool BCModel::GetFlagBoundaries()
00381 {
00382    if (!fDataPointLowerBoundaries)
00383       return false;
00384 
00385    if (!fDataPointUpperBoundaries)
00386       return false;
00387 
00388    if (fDataPointLowerBoundaries->GetNValues() != fDataSet->GetDataPoint(0)->GetNValues())
00389       return false;
00390 
00391    if (fDataPointUpperBoundaries->GetNValues() != fDataSet->GetDataPoint(0)->GetNValues())
00392       return false;
00393 
00394    return true;
00395 }
00396 
00397 // ---------------------------------------------------------
00398 void BCModel::SetSingleDataPoint(BCDataPoint * datapoint)
00399 {
00400    // create new data set consisting of a single data point
00401    BCDataSet * dataset = new BCDataSet();
00402 
00403    // add the data point
00404    dataset->AddDataPoint(datapoint);
00405 
00406    // set this new data set
00407    SetDataSet(dataset);
00408 }
00409 
00410 // ---------------------------------------------------------
00411 void BCModel::SetSingleDataPoint(BCDataSet * dataset, unsigned int index)
00412 {
00413    if (index < 0 || index > dataset->GetNDataPoints())
00414       return;
00415 
00416    SetSingleDataPoint(dataset->GetDataPoint(index));
00417 }
00418 
00419 // ---------------------------------------------------------
00420 void BCModel::SetDataBoundaries(unsigned int index, double lowerboundary, double upperboundary, bool fixed)
00421 {
00422    // check if data set exists
00423    if (!fDataSet) {
00424       BCLog::OutError("BCModel::SetDataBoundaries : Need to define data set first.");
00425       return;
00426    }
00427 
00428    // check if index is within range
00429    if (index < 0 || index > fDataSet->GetDataPoint(0)->GetNValues()) {
00430       BCLog::OutError("BCModel::SetDataBoundaries : Index out of range.");
00431       return;
00432    }
00433 
00434    // check if boundary data points exist
00435    if (!fDataPointLowerBoundaries)
00436       fDataPointLowerBoundaries = new BCDataPoint(fDataSet->GetDataPoint(0)->GetNValues());
00437 
00438    if (!fDataPointUpperBoundaries)
00439       fDataPointUpperBoundaries = new BCDataPoint(fDataSet->GetDataPoint(0)->GetNValues());
00440 
00441    if (fDataFixedValues.size() == 0)
00442       fDataFixedValues.assign(fDataSet->GetDataPoint(0)->GetNValues(), false);
00443 
00444    // set boundaries
00445    fDataPointLowerBoundaries->SetValue(index, lowerboundary);
00446    fDataPointUpperBoundaries->SetValue(index, upperboundary);
00447    fDataFixedValues[index] = fixed;
00448 }
00449 
00450 // ---------------------------------------------------------
00451 void BCModel::SetErrorBandContinuous(bool flag)
00452 {
00453    fErrorBandContinuous = flag;
00454 
00455    if (flag)
00456       return;
00457 
00458    // clear x-values
00459    fErrorBandX.clear();
00460 
00461    // copy data x-values
00462    for (unsigned int i = 0; i < fDataSet->GetNDataPoints(); ++i)
00463       fErrorBandX.push_back(fDataSet->GetDataPoint(i)->GetValue(fFitFunctionIndexX));
00464 }
00465 
00466 // ---------------------------------------------------------
00467 int BCModel::AddParameter(const char * name, double lowerlimit, double upperlimit)
00468 {
00469    // create new parameter
00470    BCParameter * parameter = new BCParameter(name, lowerlimit, upperlimit);
00471 
00472    int flag_ok = AddParameter(parameter);
00473    if (flag_ok)
00474       delete parameter;
00475 
00476    return flag_ok;
00477 }
00478 
00479 // ---------------------------------------------------------
00480 int BCModel::AddParameter(BCParameter * parameter)
00481 {
00482    // check if parameter set exists
00483    if (!fParameterSet) {
00484       BCLog::OutError("BCModel::AddParameter : Parameter set does not exist");
00485       return ERROR_PARAMETERSETDOESNOTEXIST;
00486    }
00487 
00488    // check if parameter with same name exists
00489    int flag_exists = 0;
00490    for (unsigned int i = 0; i < GetNParameters(); i++)
00491       if (CompareStrings(parameter->GetName().data(), GetParameter(i)->GetName().data()) == 0)
00492          flag_exists = -1;
00493 
00494    if (flag_exists < 0) {
00495       BCLog::OutError(Form(
00496             "BCModel::AddParameter : Parameter with name %s exists already. ",
00497             parameter->GetName().data()));
00498       return ERROR_PARAMETEREXISTSALREADY;
00499    }
00500 
00501    // define index of new parameter
00502    unsigned int index = fParameterSet->size();
00503    parameter->SetIndex(index);
00504 
00505    // add parameter to parameter container
00506    fParameterSet->push_back(parameter);
00507 
00508    // add empty function to prior container
00509    fPriorContainer.push_back(0); 
00510 
00511    // prior assumed to be non-constant in general case
00512    fPriorContainerConstant.push_back(false);
00513 
00514    // add parameters to integration methods
00515    SetParameters(fParameterSet);
00516 
00517    // reset results
00518    ResetResults();
00519 
00520    return 0;
00521 }
00522 
00523 // ---------------------------------------------------------
00524 double BCModel::LogProbabilityNN(std::vector<double> parameters)
00525 {
00526    // add log of conditional probability
00527    double logprob = LogLikelihood(parameters);
00528 
00529    // add log of prior probability
00530    if(fPriorConstantAll)
00531       logprob += fPriorConstantValue;
00532    else
00533       logprob += LogAPrioriProbability(parameters);
00534 
00535    return logprob;
00536 }
00537 
00538 // ---------------------------------------------------------
00539 double BCModel::LogProbability(std::vector<double> parameters)
00540 {
00541    // check if normalized
00542    if (fNormalization < 0. || fNormalization == 0.) {
00543       BCLog::Out(BCLog::warning, BCLog::warning,"BCModel::LogProbability. Normalization not available or zero.");
00544       return 0.;
00545    }
00546 
00547    return LogProbabilityNN(parameters) - log(fNormalization);
00548 }
00549 
00550 // ---------------------------------------------------------
00551 double BCModel::LogLikelihood(std::vector<double> parameters)
00552 {
00553    double logprob = 0.;
00554 
00555    // add log of conditional probabilities event-by-event
00556    for (unsigned int i = 0; i < fDataSet->GetNDataPoints(); i++) {
00557       BCDataPoint * datapoint = GetDataPoint(i);
00558       logprob += LogConditionalProbabilityEntry(datapoint, parameters);
00559    }
00560 
00561    return logprob;
00562 }
00563 
00564 // ---------------------------------------------------------
00565 double BCModel::LogAPrioriProbability(std::vector<double> parameters)
00566 {
00567    double logprob = 0;
00568 
00569    // get number of parameters
00570    int npar = GetNParameters();
00571 
00572    // loop over all 1-d priors
00573    for (int i = 0; i < npar; ++i) {
00574       // get prior function
00575       TF1* f = fPriorContainer.at(i);
00576 
00577       // check if prior exists
00578       if (f)
00579          logprob += log(f->Eval(parameters.at(i)));
00580 
00581       //use constant only if user has defined it
00582       else {
00583          if (!fPriorContainerConstant[i]) {
00584             BCLog::OutWarning(Form(
00585                   "BCModel::LogAPrioriProbability: Prior for parameter %s "
00586                      "is undefined. Using constant prior to proceed.",
00587                   GetParameter(i)->GetName().c_str()));
00588             logprob -= log(GetParameter(i)->GetRangeWidth());
00589          }
00590       }
00591    }
00592 
00593    //add the contribution from constant priors in one step
00594    logprob += fPriorConstantValue;
00595 
00596    return logprob;
00597 }
00598 
00599 // ---------------------------------------------------------
00600 double BCModel::LogEval(std::vector<double> parameters)
00601 {
00602    return LogProbabilityNN(parameters);
00603 }
00604 
00605 // ---------------------------------------------------------
00606 double BCModel::EvalSampling(std::vector<double> parameters)
00607 {
00608    return SamplingFunction(parameters);
00609 }
00610 
00611 // ---------------------------------------------------------
00612 double BCModel::SamplingFunction(std::vector<double> parameters)
00613 {
00614    double probability = 1.;
00615    for (std::vector<BCParameter *>::const_iterator it = fParameterSet->begin(); it != fParameterSet->end(); ++it)
00616       probability *= 1. / ((*it)->GetUpperLimit() - (*it)->GetLowerLimit());
00617    return probability;
00618 }
00619 
00620 // ---------------------------------------------------------
00621 double BCModel::Normalize()
00622 {
00623    if(fParameterSet->size()<1) {
00624       BCLog::OutError(Form("Normalize : No parameters defined in model \'%s\'. Aborting.",GetName().data()));
00625       return -1.;
00626    }
00627 
00628    BCLog::OutSummary(Form("Model \'%s\': Normalizing probability",GetName().data()));
00629 
00630    unsigned int n = GetNvar();
00631 
00632    // initialize BCIntegrate if not done already
00633    if (n == 0) {
00634       SetParameters(fParameterSet);
00635       n = GetNvar();
00636    }
00637 
00638    // integrate and get best fit parameters
00639    // maybe we have to remove the mode finding from here in the future
00640    fNormalization = Integrate();
00641 
00642    BCLog::OutDetail(Form(" --> Normalization factor : %.6g", fNormalization));
00643 
00644    return fNormalization;
00645 }
00646 
00647 // ---------------------------------------------------------
00648 int BCModel::CheckParameters(std::vector<double> parameters)
00649 {
00650    // check if vectors are of equal size
00651    if (!parameters.size() == fParameterSet->size())
00652       return ERROR_INVALIDNUMBEROFPARAMETERS;
00653 
00654    // check if parameters are within limits
00655    for (unsigned int i = 0; i < fParameterSet->size(); i++) {
00656       BCParameter * modelparameter = fParameterSet->at(i);
00657 
00658       if (modelparameter->GetLowerLimit() > parameters.at(i)
00659           || modelparameter->GetUpperLimit() < parameters.at(i)) {
00660          BCLog::OutError(Form(
00661                "BCModel::CheckParameters : Parameter %s not within limits.",
00662                fParameterSet-> at(i)-> GetName().data()));
00663          return ERROR_PARAMETERNOTWITHINRANGE;
00664       }
00665    }
00666 
00667    return 0;
00668 }
00669 
00670 // ---------------------------------------------------------
00671 void BCModel::FindMode(std::vector<double> start)
00672 {
00673    if(fParameterSet->size()<1) {
00674       BCLog::OutError(Form("FindMode : No parameters defined in model \'%s\'. Aborting.",GetName().data()));
00675       return;
00676    }
00677 
00678    // this implementation is CLEARLY not good we have to work on this.
00679 
00680    BCLog::OutSummary(Form("Model \'%s\': Finding mode",GetName().data()));
00681 
00682    // synchronize parameters in BCIntegrate
00683    SetParameters(fParameterSet);
00684 
00685    switch (GetOptimizationMethod()) {
00686       case BCIntegrate::kOptSA:
00687          FindModeSA(start);
00688          return;
00689 
00690       case BCIntegrate::kOptMinuit: {
00691          int printlevel = -1;
00692          if (BCLog::GetLogLevelScreen() <= BCLog::detail)
00693             printlevel = 0;
00694          if (BCLog::GetLogLevelScreen() <= BCLog::debug)
00695             printlevel = 1;
00696          BCIntegrate::FindModeMinuit(start, printlevel);
00697          return;
00698       }
00699 
00700       case BCIntegrate::kOptMetropolis:
00701           MarginalizeAll();
00702          return;
00703    }
00704 
00705    BCLog::OutError(Form("BCModel::FindMode : Invalid mode finding method: %d",GetOptimizationMethod()));
00706 
00707    return;
00708 }
00709 
00710 // ---------------------------------------------------------
00711 void BCModel::FindModeMinuit(std::vector<double> start, int printlevel)
00712 {
00713    if(fParameterSet->size()<1) {
00714       BCLog::OutError(Form("FindModeMinuit : No parameters defined in model \'%s\'. Aborting.",GetName().data()));
00715       return;
00716    }
00717 
00718    // synchronize parameters in BCIntegrate
00719    SetParameters(fParameterSet);
00720    BCIntegrate::FindModeMinuit(start, printlevel);
00721 }
00722 
00723 // ---------------------------------------------------------
00724 void BCModel::WriteMode(const char * file)
00725 {
00726    ofstream ofi(file);
00727    if (!ofi.is_open()) {
00728       std::cerr << "Couldn't open file " << file << std::endl;
00729       return;
00730    }
00731 
00732    int npar = fParameterSet->size();
00733    for (int i = 0; i < npar; i++)
00734       ofi << fBestFitParameters.at(i) << std::endl;
00735 
00736    ofi << std::endl;
00737    ofi << "#######################################################################"
00738        << std::endl;
00739    ofi << "#" << std::endl;
00740    ofi << "#  This file was created automatically by BCModel::WriteMode() call."
00741        << std::endl;
00742    ofi << "#  It can be read in by call to BCModel::ReadMode()." << std::endl;
00743    ofi << "#  Do not modify it unless you know what you're doing." << std::endl;
00744    ofi << "#" << std::endl;
00745    ofi << "#######################################################################"
00746        << std::endl;
00747    ofi << "#" << std::endl;
00748    ofi << "#  Best fit parameters (mode) for model:" << std::endl;
00749    ofi << "#  \'" << fName.data() << "\'" << std::endl;
00750    ofi << "#" << std::endl;
00751    ofi << "#  Number of parameters: " << npar << std::endl;
00752    ofi << "#  Parameters ordered as above:" << std::endl;
00753 
00754    for (int i = 0; i < npar; i++) {
00755       ofi << "#     " << i << ": ";
00756       ofi << fParameterSet->at(i)->GetName().data() << " = ";
00757       ofi << fBestFitParameters.at(i) << std::endl;
00758    }
00759 
00760    ofi << "#" << std::endl;
00761    ofi << "########################################################################"
00762        << std::endl;
00763 }
00764 
00765 // ---------------------------------------------------------
00766 int BCModel::ReadMode(const char * file)
00767 {
00768    ifstream ifi(file);
00769    if (!ifi.is_open()) {
00770       BCLog::OutError(Form("BCModel::ReadMode : Couldn't open file %s.", file));
00771       return 0;
00772    }
00773 
00774    int npar = fParameterSet->size();
00775    std::vector<double> mode;
00776 
00777    int i = 0;
00778    while (i < npar && !ifi.eof()) {
00779       double a;
00780       ifi >> a;
00781       mode.push_back(a);
00782       i++;
00783    }
00784 
00785    if (i < npar) {
00786       BCLog::OutError(Form("BCModel::ReadMode : Couldn't read mode from file %s.", file));
00787       BCLog::OutError(Form("BCModel::ReadMode : Expected %d parameters, found %d.", npar, i));
00788       return 0;
00789    }
00790 
00791    BCLog::OutSummary(
00792          Form("#  Read in best fit parameters (mode) for model \'%s\' from file %s:",
00793                fName.data(), file));
00794    SetMode(mode);
00795    for (int j = 0; j < npar; j++)
00796       BCLog::OutSummary(Form("#   ->Parameter %d : %s = %e", j,
00797             fParameterSet->at(j)->GetName().data(), fBestFitParameters[j]));
00798 
00799    BCLog::OutWarning("#  ! Best fit values obtained before this call will be overwritten !");
00800 
00801    return npar;
00802 }
00803 
00804 // ---------------------------------------------------------
00805 int BCModel::MarginalizeAll()
00806 {
00807    if(fParameterSet->size()<1) {
00808       BCLog::OutError(Form("MarginalizeAll : No parameters defined in model \'%s\'. Aborting.",GetName().data()));
00809       return 0;
00810    }
00811 
00812    BCLog::OutSummary(Form("Running MCMC for model \'%s\'",GetName().data()));
00813 
00814    // prepare function fitting
00815    double dx = 0.;
00816    double dy = 0.;
00817 
00818    if (fFitFunctionIndexX >= 0) {
00819       dx = (fDataPointUpperBoundaries->GetValue(fFitFunctionIndexX)
00820             - fDataPointLowerBoundaries->GetValue(fFitFunctionIndexX))
00821             / (double) fErrorBandNbinsX;
00822 
00823       dy = (fDataPointUpperBoundaries->GetValue(fFitFunctionIndexY)
00824             - fDataPointLowerBoundaries->GetValue(fFitFunctionIndexY))
00825             / (double) fErrorBandNbinsY;
00826 
00827       fErrorBandXY
00828             = new TH2D(TString::Format("errorbandxy_%d", BCLog::GetHIndex()), "",
00829                   fErrorBandNbinsX,
00830                   fDataPointLowerBoundaries->GetValue(fFitFunctionIndexX) - .5 * dx,
00831                   fDataPointUpperBoundaries->GetValue(fFitFunctionIndexX) + .5 * dx,
00832                   fErrorBandNbinsY,
00833                   fDataPointLowerBoundaries->GetValue(fFitFunctionIndexY) - .5 * dy,
00834                   fDataPointUpperBoundaries->GetValue(fFitFunctionIndexY) + .5 * dy);
00835       fErrorBandXY->SetStats(kFALSE);
00836 
00837       for (int ix = 1; ix <= fErrorBandNbinsX; ++ix)
00838          for (int iy = 1; iy <= fErrorBandNbinsX; ++iy)
00839             fErrorBandXY->SetBinContent(ix, iy, 0.);
00840    }
00841 
00842    MCMCMetropolis();
00843    FindModeMCMC();
00844 
00845    //   PrintResults(Form("%s.txt", GetName().data()));
00846 
00847    return 1;
00848 }
00849 
00850 // ---------------------------------------------------------
00851 BCH1D * BCModel::GetMarginalized(BCParameter * parameter)
00852 {
00853    if (!parameter) {
00854       BCLog::OutError("BCModel::GetMarginalized : Parameter does not exist.");
00855       return 0;
00856    }
00857 
00858    int index = parameter->GetIndex();
00859    if (fMCMCFlagsFillHistograms[index] == false) {
00860       BCLog::OutError(Form(
00861             "BCModel::GetMarginalized : Distribuion for '%s' not filled.",
00862             parameter->GetName().data()));
00863       return 0;
00864    }
00865 
00866    // get histogram
00867    TH1D * hist = MCMCGetH1Marginalized(index);
00868    if (!hist)
00869       return 0;
00870 
00871    // set axis labels
00872    hist->SetName(Form("hist_%s_%s", GetName().data(), parameter->GetName().data()));
00873    hist->SetXTitle(parameter->GetName().data());
00874    hist->SetYTitle(Form("p(%s|data)", parameter->GetName().data()));
00875    hist->SetStats(kFALSE);
00876 
00877    // set histogram
00878    BCH1D * hprob = new BCH1D();
00879    hprob->SetHistogram(hist);
00880 
00881    // set best fit parameter
00882    double bestfit = hprob->GetMode();
00883 
00884    if (fBestFitParametersMarginalized.size() == 0)
00885       for (unsigned int i = 0; i < GetNParameters(); i++)
00886          fBestFitParametersMarginalized.push_back(0.);
00887 
00888    fBestFitParametersMarginalized[index] = bestfit;
00889 
00890    hprob->SetGlobalMode(fBestFitParameters.at(index));
00891 
00892    return hprob;
00893 }
00894 
00895 // ---------------------------------------------------------
00896 int BCModel::ReadMarginalizedFromFile(const char * file)
00897 {
00898    TFile * froot = new TFile(file);
00899    if (!froot->IsOpen()) {
00900       BCLog::OutError(Form("BCModel::ReadMarginalizedFromFile : Couldn't open file %s.", file));
00901       return 0;
00902    }
00903 
00904    // We reset the MCMCEngine here for the moment.
00905    // In the future maybe we only want to do this if the engine
00906    // wans't initialized at all or when there were some changes
00907    // in the model.
00908    // But maybe we want reset everything since we're overwriting
00909    // the marginalized distributions anyway.
00910    MCMCInitialize();
00911 
00912    int k = 0;
00913    int n = GetNParameters();
00914    for (int i = 0; i < n; i++) {
00915       BCParameter * a = GetParameter(i);
00916       TKey * key = froot->GetKey(TString::Format("hist_%s_%s",GetName().data(), a->GetName().data()));
00917       if (key) {
00918          TH1D * h1 = (TH1D*) key->ReadObjectAny(TH1D::Class());
00919          h1->SetDirectory(0);
00920          if (SetMarginalized(i, h1))
00921             k++;
00922       }
00923       else
00924          BCLog::OutWarning(
00925                Form("BCModel::ReadMarginalizedFromFile : Couldn't read histogram \"hist_%s_%s\" from file %s.",
00926                      GetName().data(), a->GetName().data(), file));
00927    }
00928 
00929    for (int i = 0; i < n - 1; i++) {
00930       for (int j = i + 1; j < n; j++) {
00931          BCParameter * a = GetParameter(i);
00932          BCParameter * b = GetParameter(j);
00933          TKey * key = froot->GetKey(
00934                TString::Format("hist_%s_%s_%s",GetName().data(), a->GetName().data(),b->GetName().data()));
00935          if (key) {
00936             TH2D * h2 = (TH2D*) key->ReadObjectAny(TH2D::Class());
00937             h2->SetDirectory(0);
00938             if (SetMarginalized(i, j, h2))
00939                k++;
00940          }
00941          else
00942             BCLog::OutWarning(
00943                   Form("BCModel::ReadMarginalizedFromFile : Couldn't read histogram \"hist_%s_%s_%s\" from file %s.",
00944                         GetName().data(), a->GetName().data(), b->GetName().data(), file));
00945       }
00946    }
00947 
00948    froot->Close();
00949 
00950    return k;
00951 }
00952 
00953 // ---------------------------------------------------------
00954 int BCModel::ReadErrorBandFromFile(const char * file)
00955 {
00956    TFile * froot = new TFile(file);
00957    if (!froot->IsOpen()) {
00958       BCLog::OutWarning(Form("BCModel::ReadErrorBandFromFile. Couldn't open file %s.", file));
00959       return 0;
00960    }
00961 
00962    int r = 0;
00963 
00964    TH2D * h2 = (TH2D*) froot->Get("errorbandxy");
00965    if (h2) {
00966       h2->SetDirectory(0);
00967       h2->SetName(TString::Format("errorbandxy_%d", BCLog::GetHIndex()));
00968       SetErrorBandHisto(h2);
00969       r = 1;
00970    }
00971    else
00972       BCLog::OutWarning(
00973             Form("BCModel::ReadErrorBandFromFile : Couldn't read histogram \"errorbandxy\" from file %s.",file));
00974 
00975    froot->Close();
00976 
00977    return r;
00978 }
00979 
00980 // ---------------------------------------------------------
00981 int BCModel::PrintAllMarginalized1D(const char * filebase)
00982 {
00983    if (fMCMCH1Marginalized.size() == 0) {
00984       BCLog::OutError("BCModel::PrintAllMarginalized : Marginalized distributions not available.");
00985       return 0;
00986    }
00987 
00988    int n = GetNParameters();
00989    for (int i = 0; i < n; i++) {
00990       BCParameter * a = GetParameter(i);
00991       if (GetMarginalized(a))
00992          GetMarginalized(a)->Print(Form("%s_1D_%s.ps", filebase, a->GetName().data()));
00993    }
00994 
00995    return n;
00996 }
00997 
00998 // ---------------------------------------------------------
00999 int BCModel::PrintAllMarginalized2D(const char * filebase)
01000 {
01001    if (fMCMCH2Marginalized.size() == 0) {
01002       BCLog::OutError("BCModel::PrintAllMarginalized : Marginalized distributions not available.");
01003       return 0;
01004    }
01005 
01006    int k = 0;
01007    int n = GetNParameters();
01008    for (int i = 0; i < n - 1; i++) {
01009       for (int j = i + 1; j < n; j++) {
01010          BCParameter * a = GetParameter(i);
01011          BCParameter * b = GetParameter(j);
01012 
01013          double meana = (a->GetLowerLimit() + a->GetUpperLimit()) / 2.;
01014          double deltaa = (a->GetUpperLimit() - a->GetLowerLimit());
01015          if (deltaa <= 1e-7 * meana)
01016             continue;
01017 
01018          double meanb = (b->GetLowerLimit() + b->GetUpperLimit()) / 2.;
01019          double deltab = (b->GetUpperLimit() - b->GetLowerLimit());
01020          if (deltab <= 1e-7 * meanb)
01021             continue;
01022 
01023          if (GetMarginalized(a, b))
01024             GetMarginalized(a, b)->Print(
01025                   Form("%s_2D_%s_%s.ps",filebase, a->GetName().data(), b->GetName().data()));
01026          k++;
01027       }
01028    }
01029 
01030    return k;
01031 }
01032 
01033 // ---------------------------------------------------------
01034 int BCModel::PrintAllMarginalized(const char * file, unsigned int hdiv, unsigned int vdiv)
01035 {
01036    if (!fMCMCFlagFillHistograms) {
01037       BCLog::OutError("BCModel::PrintAllMarginalized : Marginalized distributions not filled.");
01038       return 0;
01039    }
01040 
01041    int npar = GetNParameters();
01042 
01043    if (fMCMCH1Marginalized.size() == 0 || (fMCMCH2Marginalized.size() == 0
01044          && npar > 1)) {
01045       BCLog::OutError(
01046             "BCModel::PrintAllMarginalized : Marginalized distributions not available.");
01047       return 0;
01048    }
01049 
01050    // if there's only one parameter, we just want to call Print()
01051    if (fMCMCH1Marginalized.size() == 1 && fMCMCH2Marginalized.size() == 0) {
01052       BCParameter * a = GetParameter(0);
01053       GetMarginalized(a)->Print(file);
01054       return 1;
01055    }
01056 
01057    int c_width = 600; // default canvas width
01058    int c_height = 600; // default canvas height
01059 
01060    int type = 112; // landscape
01061 
01062    if (hdiv > vdiv) {
01063       if (hdiv > 3) {
01064          c_width = 1000;
01065          c_height = 700;
01066       }
01067       else {
01068          c_width = 800;
01069          c_height = 600;
01070       }
01071    }
01072    else if (hdiv < vdiv) {
01073       if (hdiv > 3) {
01074          c_height = 1000;
01075          c_width = 700;
01076       }
01077       else {
01078          c_height = 800;
01079          c_width = 600;
01080       }
01081       type = 111;
01082    }
01083 
01084    // calculate number of plots
01085    int nplots2d = npar * (npar - 1) / 2;
01086    int nplots = npar + nplots2d;
01087 
01088    // give out warning if too many plots
01089    BCLog::OutSummary(
01090          Form(
01091                "Printing all marginalized distributions (%d x 1D + %d x 2D = %d) into file %s",
01092                npar, nplots2d, nplots, file));
01093    if (nplots > 100)
01094       BCLog::OutDetail("This can take a while...");
01095 
01096    // setup the canvas and postscript file
01097    TCanvas * c = new TCanvas("c", "canvas", c_width, c_height);
01098 
01099    TPostScript * ps = new TPostScript(file, type);
01100 
01101    if (type == 112)
01102       ps->Range(24, 16);
01103    else
01104       ps->Range(16, 24);
01105 
01106    // draw all 1D distributions
01107    ps->NewPage();
01108    c->cd();
01109    c->Clear();
01110    c->Divide(hdiv, vdiv);
01111 
01112    int n = 0;
01113    for (int i = 0; i < npar; i++) {
01114       // get corresponding parameter
01115       BCParameter * a = GetParameter(i);
01116 
01117       // check if histogram exists
01118       if (!GetMarginalized(a))
01119          continue;
01120 
01121       // check if histogram is filled
01122       if (GetMarginalized(a)->GetHistogram()->Integral() <= 0)
01123          continue;
01124 
01125       // if current page is full, switch to new page
01126       if (i != 0 && i % (hdiv * vdiv) == 0) {
01127          c->Update();
01128          ps->NewPage();
01129          c->cd();
01130          c->Clear();
01131          c->Divide(hdiv, vdiv);
01132       }
01133 
01134       // go to next pad
01135       c->cd(i % (hdiv * vdiv) + 1);
01136 
01137       GetMarginalized(a)->Draw();
01138       n++;
01139 
01140       if (n % 100 == 0)
01141          BCLog::OutDetail(Form(" --> %d plots done", n));
01142    }
01143 
01144    if (n > 0) {
01145       c->Update();
01146 
01147       // draw all the 2D distributions
01148       ps->NewPage();
01149       c->cd();
01150       c->Clear();
01151    }
01152 
01153    c->Divide(hdiv, vdiv);
01154 
01155    int k = 0;
01156    for (int i = 0; i < npar - 1; i++) {
01157       if (!fMCMCFlagsFillHistograms[i])
01158          continue;
01159       for (int j = i + 1; j < npar; j++) {
01160          if (!fMCMCFlagsFillHistograms[j])
01161             continue;
01162 
01163          // get corresponding parameters
01164          BCParameter * a = GetParameter(i);
01165          BCParameter * b = GetParameter(j);
01166 
01167          // check if histogram exists
01168          if (!GetMarginalized(a, b))
01169             continue;
01170 
01171          // check if histogram is filled
01172          if (GetMarginalized(a, b)->GetHistogram()->Integral() <= 0)
01173             continue;
01174 
01175          // if current page is full, switch to new page
01176          if (k != 0 && k % (hdiv * vdiv) == 0) {
01177             c->Update();
01178             ps->NewPage();
01179             c->cd();
01180             c->Clear();
01181             c->Divide(hdiv, vdiv);
01182          }
01183 
01184          // go to next pad
01185          c->cd(k % (hdiv * vdiv) + 1);
01186 
01187          double meana = (a->GetLowerLimit() + a->GetUpperLimit()) / 2.;
01188          double deltaa = (a->GetUpperLimit() - a->GetLowerLimit());
01189          if (deltaa <= 1e-7 * meana)
01190             continue;
01191 
01192          double meanb = (b->GetLowerLimit() + b->GetUpperLimit()) / 2.;
01193          double deltab = (b->GetUpperLimit() - b->GetLowerLimit());
01194          if (deltab <= 1e-7 * meanb)
01195             continue;
01196 
01197          GetMarginalized(a, b)->Draw(52);
01198          k++;
01199 
01200          if ((n + k) % 100 == 0)
01201             BCLog::OutDetail(Form(" --> %d plots done", n + k));
01202       }
01203    }
01204 
01205    if ((n + k) > 100 && (n + k) % 100 != 0)
01206       BCLog::OutDetail(Form(" --> %d plots done", n + k));
01207 
01208    c->Update();
01209    ps->Close();
01210 
01211    delete c;
01212    delete ps;
01213 
01214    // return total number of drawn histograms
01215    return n + k;
01216 }
01217 
01218 // ---------------------------------------------------------
01219 BCH2D * BCModel::GetMarginalized(BCParameter * par1, BCParameter * par2)
01220 {
01221    int index1 = par1->GetIndex();
01222    int index2 = par2->GetIndex();
01223 
01224    if (fMCMCFlagsFillHistograms[index1] == false || fMCMCFlagsFillHistograms[index2] == false) {
01225       BCLog::OutError(
01226             Form("BCModel::GetMarginalized : Distribuion for '%s' and/or '%s' not filled.",
01227                   par1->GetName().data(), par2->GetName().data()));
01228       return 0;
01229    }
01230 
01231    if (index1 == index2) {
01232       BCLog::OutError("BCModel::GetMarginalized : Provided parameters are identical. Distribution not available.");
01233       return 0;
01234    }
01235 
01236    BCParameter * npar1 = par1;
01237    BCParameter * npar2 = par2;
01238 
01239    if (index1 > index2) {
01240       npar1 = par2;
01241       npar2 = par1;
01242 
01243       int itmp = index1;
01244       index1 = index2;
01245       index2 = itmp;
01246    }
01247 
01248    // get histogram
01249    TH2D * hist = MCMCGetH2Marginalized(index1, index2);
01250 
01251    if (hist == 0)
01252       return 0;
01253 
01254    BCH2D * hprob = new BCH2D();
01255 
01256    // set axis labels
01257    hist->SetName(Form("hist_%s_%s_%s", GetName().data(), npar1->GetName().data(), npar2->GetName().data()));
01258    hist->SetXTitle(Form("%s", npar1->GetName().data()));
01259    hist->SetYTitle(Form("%s", npar2->GetName().data()));
01260    hist->SetStats(kFALSE);
01261 
01262    double gmode[] = { fBestFitParameters.at(index1), fBestFitParameters.at(index2) };
01263    hprob->SetGlobalMode(gmode);
01264 
01265    // set histogram
01266    hprob->SetHistogram(hist);
01267 
01268    return hprob;
01269 }
01270 
01271 // ---------------------------------------------------------
01272 double BCModel::GetPvalueFromChi2(std::vector<double> par, int sigma_index)
01273 {
01274    double ll = LogLikelihood(par);
01275    int n = GetNDataPoints();
01276 
01277    double sum_sigma = 0;
01278    for (int i = 0; i < n; i++)
01279       sum_sigma += log(GetDataPoint(i)->GetValue(sigma_index));
01280 
01281    double chi2 = -2. * (ll + (double) n / 2. * log(2. * M_PI) + sum_sigma);
01282 
01283    fPValue = TMath::Prob(chi2, n);
01284 
01285    return fPValue;
01286 }
01287 
01288 // ---------------------------------------------------------
01289 std::vector<double> BCModel::GetChi2Runs(int dataIndex, int sigmaIndex)
01290 {
01291    std::vector<double> x;
01292    return x;
01293 }
01294 
01295 // ---------------------------------------------------------
01296 double BCModel::GetPvalueFromChi2Johnson(std::vector<double> par)
01297 {
01298    double chi2 = GetChi2Johnson(par);
01299    // look up corresponding p value
01300    fPValue = TMath::Prob(chi2, NumberBins() - 1);
01301    return fPValue;
01302 }
01303 
01304 // ---------------------------------------------------------
01305 double BCModel::GetChi2Johnson(std::vector<double> par, int nBins)
01306 {
01307    typedef unsigned int uint;
01308 
01309    // number of observations
01310    int n = GetNDataPoints();
01311 
01312    if (nBins < 0)
01313       nBins = NumberBins();
01314 
01315    // fixed width quantiles, including final point!
01316    std::vector<double> a;
01317    for (int i = 0; i <= nBins; i++)
01318       a.push_back(i / double(nBins));
01319 
01320    // determine the bin counts and fill the histogram with data using the CDF
01321    TH1I * hist = new TH1I("h1", "h1 title", nBins, 0., 1.);
01322 
01323    // discrete case requires randomization to allocate counts of bins that cover more
01324    // than one quantile
01325    if (flag_discrete) {
01326       // loop over observations, each may have different likelihood and CDF
01327       for (int j = 0; j < n; j++) {
01328          // actual value
01329             double CDFval = CDF(par, j, false);
01330          // for the bin just before
01331          double CDFlower = CDF(par, j, true);
01332 
01333          // what quantiles q are covered, count from q_1 to q_{nBins}
01334          int qMax = 1;
01335          for (int i = 0; i < nBins; i++) {
01336             if (CDFval > a[i])
01337                qMax = i + 1;
01338             else
01339                break;
01340          }
01341          int qMin = 1;
01342          for (int i = 0; i < nBins; i++) {
01343             if (CDFlower > a[i])
01344                qMin = i + 1;
01345             else
01346                break;
01347          }
01348 
01349          // simplest case: observation bin entirely contained in one quantile
01350          if (qMin == qMax) {
01351             // watch out for overflow because CDF exactly 1
01352             if (CDFval < 1)
01353                hist->Fill(CDFval);
01354             else
01355                hist->AddBinContent(qMax);
01356 
01357             continue; // this observation finished
01358          }
01359 
01360          // if more than quantile is covered need more work:
01361          // determine probabilities of this observation to go for each quantile covered
01362          // as follows: If each quantile has size 0.25 and the CDF(integral of likelihood)
01363          // for current observation gives gives 0.27, but for observation-1 we would have
01364          // 0.20, then 5/7 of the 7% go for first quantile and 2/7 for the second.
01365          // This extend to bins covering more than two quantiles
01366          std::vector<double> prob;
01367          // normalization
01368          double norm = 1 / double(CDFval - CDFlower);
01369 
01370          for (int i = 0; i < (qMax - qMin + 1); i++) {
01371             if (i == 0) {
01372                prob.push_back(norm * (a[qMin] - CDFlower));
01373                continue;
01374             }
01375             if (i == (qMax - qMin)) {
01376                prob.push_back(norm * (CDFval - a[qMax - 1]));
01377                continue;
01378             }
01379             // default case
01380             prob.push_back(norm * (a[i] - a[i - 1]));
01381          }
01382          // have distribution, use inverse-transform method
01383          double U = fRandom->Rndm();
01384          // build up the integral (CDF)
01385          for (uint i = 1; i < prob.size(); i++)
01386             prob[i] += prob[i - 1];
01387          // and search with linear comput. complexity
01388          for (uint i = 0; i < prob.size(); i++) {
01389             // we finally allocate the count, as center of quantile
01390             if (U <= prob[i]) {
01391                hist->Fill((a[qMin + i - 1] + a[qMin + i]) / 2.);
01392                break;
01393             }
01394          }
01395       }
01396    }
01397    else { //continuous case is simple
01398       for (int j = 0; j < n; j++)
01399             hist->Fill(CDF(par, j, false));
01400    }
01401 
01402    // calculate chi^2
01403    double chi2 = 0.;
01404    double mk, pk;
01405    double N = double(n);
01406    for (int i = 1; i <= nBins; i++) {
01407       mk = hist->GetBinContent(i);
01408       pk = a[i] - a[i - 1];
01409       chi2 += (mk - N * pk) * (mk - N * pk) / (N * pk);
01410    }
01411 
01412    delete hist;
01413 
01414    return chi2;
01415 }
01416 
01417 // ---------------------------------------------------------
01418 double BCModel::GetAvalueFromChi2Johnson(TTree * tree, TH1D * distribution)
01419 {
01420    // model parameters
01421    int nPar = (int)GetNParameters();
01422    std::vector<double> param(nPar);
01423 
01424    //parameters saved in branches should be the same
01425    int nParBranches = -1;
01426    tree->SetBranchAddress("fNParameters", &nParBranches);
01427 
01428    //assume all events have same number of parameters, so check only first
01429    tree->GetEntry(0);
01430    if (nParBranches != nPar) {
01431       BCLog::OutError(Form(
01432             "Cannot compute A value: number of parameters in tree (%d)"
01433                "doesn't match  number of parameters in model (%d)",
01434             nParBranches, nPar));
01435       return -1.;
01436    }
01437 
01438    // buffer to construct correct branchnames for parameters, e.g. "fParameter3"
01439    char * branchName = new char[10 + nPar];
01440    // set up variables filled for each sample of parameters
01441    // assume same order as in model
01442    for (int i = 0; i < (int) nPar; i++) {
01443       +sprintf(branchName, "fParameter%d", i);
01444       tree->SetBranchAddress(branchName, &param[i]);
01445    }
01446 
01447    // get the p value from Johson's definition for each param from posterior
01448    long nEntries = tree->GetEntries();
01449 
01450    // RN ~ chi2 with K-1 DoF needed for comparison
01451    std::vector<double> randoms(nEntries);
01452    int K = NumberBins();
01453    BCMath::RandomChi2(randoms, K - 1);
01454 
01455    // number of Johnson chi2 values bigger than reference
01456    int nBigger = 0;
01457    for (int i = 0; i < nEntries; i++) {
01458       tree->GetEntry(i);
01459       double chi2 = GetChi2Johnson(param);
01460       if (distribution != 0)
01461          distribution->Fill(chi2);
01462       // compare to set of chi2 variables
01463       if (chi2 > randoms[i])
01464          nBigger++;
01465    }
01466 
01467    return nBigger / double(nEntries);
01468 }
01469 
01470 // ---------------------------------------------------------
01471 double BCModel::GetPvalueFromChi2NDoF(std::vector<double> par, int sigma_index)
01472 {
01473    double ll = LogLikelihood(par);
01474    int n = GetNDataPoints();
01475    int npar = GetNParameters();
01476 
01477    double sum_sigma = 0;
01478    for (int i = 0; i < n; i++)
01479       sum_sigma += log(GetDataPoint(i)->GetValue(sigma_index));
01480 
01481    double chi2 = -2. * (ll + (double) n / 2. * log(2. * M_PI) + sum_sigma);
01482 
01483    fChi2NDoF = chi2 / double(n - npar);
01484    fPValueNDoF = TMath::Prob(chi2, n - npar);
01485 
01486    return fPValueNDoF;
01487 }
01488 
01489 // ---------------------------------------------------------
01490 double BCModel::GetPvalueFromKolmogorov(const std::vector<double>& par,int index)
01491 {
01492    if (flag_discrete) {
01493       BCLog::OutError(Form("BCModel::GetPvalueFromKolmogorov : "
01494          "test defined only for continuous distributions."));
01495       return -1.;
01496    }
01497 
01498    //calculate the ECDF from the 1D data
01499    std::vector<double> yData = fDataSet->GetDataComponents(index);
01500    TH1D * ECDF = BCMath::ECDF(yData);
01501 
01502    int N = GetNDataPoints();
01503 
01504    // calculated expected CDF for unique points only
01505    std::set<double> uniqueObservations;
01506    for (int i = 0; i < N; i++)
01507        uniqueObservations.insert(CDF(par, i, false));
01508 
01509    int nUnique = uniqueObservations.size();
01510    if (nUnique != ECDF->GetNbinsX() + 1) {
01511       BCLog::OutError(Form("BCModel::GetPvalueFromKolmogorov : "
01512          "Number of unique data points doesn't match (%d vs %d)", nUnique,
01513             ECDF->GetNbinsX() + 1));
01514       return -1.;
01515    }
01516 
01517    // find maximum distance
01518    double distMax = 0.;
01519 
01520    // current distance
01521    double dist = 0.;
01522 
01523    std::set<double>::const_iterator iter = uniqueObservations.begin();
01524    for (int iBin = 0; iBin < nUnique; ++iBin) {
01525       // distance between current points
01526       dist = TMath::Abs(*iter - ECDF->GetBinContent(iBin + 1));
01527       // update maximum if necessary
01528       distMax = TMath::Max(dist, distMax);
01529 
01530 //      BCLog::OutDebug(Form("BCModel::GetPvalueFromKolmogorov : "
01531 //         "expected vs empirical (%f vs %f)", *iter, ECDF->GetBinContent(iBin
01532 //            + 1)));
01533 
01534       // advance to next entry in the set
01535       ++iter;
01536    }
01537 
01538    // correct for total #points, not unique #points.
01539    // would need sqrt(n1*n2/(n1+n2)) if we had two experimental datasets
01540    double z = distMax * sqrt(N);
01541 
01542    fPValue = TMath::KolmogorovProb(z);
01543 
01544 //   BCLog::OutDebug(Form("BCModel::GetPvalueFromKolmogorov : "
01545 //      "max distance vs corrected (%f vs %f)", distMax, z));
01546 
01547    // clean up
01548    delete ECDF;
01549 
01550    return fPValue;
01551 }
01552 
01553 // ---------------------------------------------------------
01554 BCH1D * BCModel::CalculatePValue(std::vector<double> par, bool flag_histogram)
01555 {
01556    BCH1D * hist = 0;
01557 
01558    // print log
01559    BCLog::OutSummary("Do goodness-of-fit-test");
01560 
01561    // create model test
01562    BCGoFTest * goftest = new BCGoFTest("modeltest");
01563 
01564    // set this model as the model to be tested
01565    goftest->SetTestModel(this);
01566 
01567    // set the point in parameter space which is tested an initialize
01568    // the model testing
01569    if (!goftest->SetTestPoint(par))
01570       return 0;
01571 
01572    // disable the creation of histograms to save _a lot_ of memory
01573    // (histograms are not needed for p-value calculation)
01574    goftest->MCMCSetFlagFillHistograms(false);
01575 
01576    // set parameters of the MCMC for the GoFTest
01577    goftest->MCMCSetNChains(fGoFNChains);
01578    goftest->MCMCSetNIterationsMax(fGoFNIterationsMax);
01579    goftest->MCMCSetNIterationsRun(fGoFNIterationsRun);
01580 
01581    // get p-value
01582    fPValue = goftest->GetCalculatedPValue(flag_histogram);
01583 
01584    // get histogram
01585    if (flag_histogram) {
01586       hist = new BCH1D();
01587       hist->SetHistogram(goftest->GetHistogramLogProb());
01588    }
01589 
01590    // delete model test
01591    delete goftest;
01592 
01593    // return histogram
01594    return hist;
01595 }
01596 
01597 // ---------------------------------------------------------
01598 void BCModel::CorrelateDataPointValues(std::vector<double> &x)
01599 {
01600    // ...
01601 }
01602 
01603 // ---------------------------------------------------------
01604 double BCModel::HessianMatrixElement(BCParameter * par1, BCParameter * par2, std::vector<double> point)
01605 {
01606    // check number of entries in vector
01607    if (point.size() != GetNParameters()) {
01608       BCLog::OutWarning("BCModel::HessianMatrixElement. Invalid number of entries in the vector.");
01609       return -1;
01610    }
01611 
01612    // define steps
01613    double nsteps = 1e5;
01614    double dx1 = par1->GetRangeWidth() / nsteps;
01615    double dx2 = par2->GetRangeWidth() / nsteps;
01616 
01617    // define points at which to evaluate
01618    std::vector<double> xpp = point;
01619    std::vector<double> xpm = point;
01620    std::vector<double> xmp = point;
01621    std::vector<double> xmm = point;
01622 
01623    int idx1 = par1->GetIndex();
01624    int idx2 = par2->GetIndex();
01625 
01626    xpp[idx1] += dx1;
01627    xpp[idx2] += dx2;
01628 
01629    xpm[idx1] += dx1;
01630    xpm[idx2] -= dx2;
01631 
01632    xmp[idx1] -= dx1;
01633    xmp[idx2] += dx2;
01634 
01635    xmm[idx1] -= dx1;
01636    xmm[idx2] -= dx2;
01637 
01638    // calculate probability at these points
01639    double ppp = Likelihood(xpp);
01640    double ppm = Likelihood(xpm);
01641    double pmp = Likelihood(xmp);
01642    double pmm = Likelihood(xmm);
01643 
01644    // return derivative
01645    return (ppp + pmm - ppm - pmp) / (4. * dx1 * dx2);
01646 }
01647 
01648 // ---------------------------------------------------------
01649 void BCModel::FixDataAxis(unsigned int index, bool fixed)
01650 {
01651    // check if index is within range
01652    if (index < 0 || index > fDataSet->GetDataPoint(0)->GetNValues()) {
01653       BCLog::OutWarning("BCModel::FixDataAxis. Index out of range.");
01654       return;
01655    }
01656 
01657    if (fDataFixedValues.size() == 0)
01658       fDataFixedValues.assign(fDataSet->GetDataPoint(0)->GetNValues(),
01659             false);
01660 
01661    fDataFixedValues[index] = fixed;
01662 }
01663 
01664 // ---------------------------------------------------------
01665 bool BCModel::GetFixedDataAxis(unsigned int index)
01666 {
01667    // check if index is within range
01668    if (index < 0 || index > fDataSet->GetDataPoint(0)->GetNValues()) {
01669       BCLog::OutWarning("BCModel::GetFixedDataAxis. Index out of range.");
01670       return false;
01671    }
01672 
01673    return fDataFixedValues[index];
01674 }
01675 
01676 // ---------------------------------------------------------
01677 int BCModel::SetPrior(int index, TF1 * f)
01678 {
01679    // check index range
01680    if (index < 0 && index >= int(GetNParameters())) {
01681       BCLog::OutError("BCModel::SetPrior. Index out of range."); 
01682       return 0;
01683    }
01684 
01685    // set function
01686    fPriorContainer[index] = f; 
01687 
01688    // reset all results
01689    ResetResults();
01690 
01691    // no error 
01692    return 1; 
01693 }
01694 
01695 // ---------------------------------------------------------
01696 int BCModel::SetPrior(const char * name, TF1 * f)
01697 {
01698    // find index
01699    int index = -1;
01700    for (unsigned int i = 0; i < GetNParameters(); i++)
01701       if (name == GetParameter(i)->GetName())
01702         index = i;
01703 
01704    // set prior
01705    return SetPrior(index, f);
01706 }
01707 
01708 // ---------------------------------------------------------
01709 int BCModel::SetPriorGauss(int index, double mean, double sigma)
01710 {
01711    // check index range
01712    if (index < 0 && index >= int(GetNParameters())) {
01713       BCLog::OutError("BCModel::SetPrior. Index out of range."); 
01714       return 0;
01715    }
01716 
01717    // create new function
01718    TF1 * f = new TF1(Form("prior_%s", GetParameter(index)->GetName().c_str()),
01719                      "1./sqrt(2.*TMath::Pi())/[1] * exp(- (x-[0])*(x-[0])/2./[1]/[1])",
01720                      GetParameter(index)->GetLowerLimit(), 
01721                      GetParameter(index)->GetUpperLimit()); 
01722    f->SetParameter(0, mean); 
01723    f->SetParameter(1, sigma);
01724 
01725    // set prior
01726    return SetPrior(index, f); 
01727 }
01728 
01729 // ---------------------------------------------------------
01730 int BCModel::SetPriorGauss(const char* name, double mean, double sigma)
01731 {
01732    // find index
01733    int index = -1;
01734    for (unsigned int i = 0; i < GetNParameters(); i++)
01735       if (name == GetParameter(i)->GetName())
01736          index = i;
01737 
01738    // check index range
01739    if (index < 0 && index >= int(GetNParameters())) {
01740       BCLog::OutError("BCModel::SetPrior. Index out of range."); 
01741       return 0;
01742    }
01743 
01744    // set prior
01745    return SetPriorGauss(index, mean, sigma); 
01746 }
01747 
01748 // ---------------------------------------------------------
01749 int BCModel::SetPriorGauss(int index, double mean, double sigmadown, double sigmaup)
01750 {
01751    // check index range
01752    if (index < 0 && index >= int(GetNParameters())) {
01753       BCLog::OutError("BCModel::SetPrior. Index out of range."); 
01754       return 0;
01755    }
01756 
01757    // create new function
01758    TF1 * f = new TF1(Form("prior_%s", GetParameter(index)->GetName().c_str()),
01759                      BCMath::SplitGaussian,
01760                      GetParameter(index)->GetLowerLimit(),
01761                      GetParameter(index)->GetUpperLimit(),
01762                      3);
01763    f->SetParameter(0, mean); 
01764    f->SetParameter(1, sigmadown);
01765    f->SetParameter(2, sigmaup);
01766 
01767    // set prior
01768    return SetPrior(index, f); 
01769 
01770    return 0;
01771 }
01772 
01773 // ---------------------------------------------------------
01774 int BCModel::SetPriorGauss(const char * name, double mean, double sigmadown, double sigmaup)
01775 {
01776    // find index
01777    int index = -1;
01778    for (unsigned int i = 0; i < GetNParameters(); i++)
01779       if (name == GetParameter(i)->GetName())
01780         index = i;
01781 
01782    // check index range
01783    if (index < 0 && index >= int(GetNParameters())) {
01784       BCLog::OutError("BCModel::SetPrior. Index out of range."); 
01785       return 0;
01786    }
01787 
01788    // set prior
01789    return SetPriorGauss(index, mean, sigmadown, sigmaup); 
01790 }
01791 
01792 // ---------------------------------------------------------
01793 int BCModel::SetPriorConstant(int index)
01794 {
01795    // check index range
01796    if (index < 0 && index >= int(GetNParameters())) {
01797       BCLog::OutError("BCModel::SetPrior. Index out of range.");
01798       return 0;
01799    }
01800 
01801    // set prior to a constant
01802    fPriorContainerConstant[index] = true;
01803 
01804    // update value of constant
01805    fPriorConstantValue -= log(GetParameter(index)->GetRangeWidth());
01806 
01807    // reset all results
01808    ResetResults();
01809 
01810    // no error
01811    return 1;
01812 }
01813 
01814 // ---------------------------------------------------------
01815 int BCModel::SetPriorConstant(const char* name)
01816 {
01817    // find index
01818    int index = -1;
01819    for (unsigned int i = 0; i < GetNParameters(); i++) {
01820       if (name == GetParameter(i)->GetName()) {
01821          index = i;
01822          break;
01823       }
01824    }
01825 
01826    if (index == -1) {
01827       BCLog::OutError(Form(
01828             "BCModel::SetPriorConstant. parameter '%s' doesn't exist.", name));
01829       return 0;
01830    }
01831 
01832    return SetPriorConstant(index);
01833 }
01834 
01835 // ---------------------------------------------------------
01836 int BCModel::SetPriorConstantAll()
01837 {
01838    double logprob = 0;
01839 
01840    // get number of parameters
01841    int nPar = GetNParameters();
01842 
01843    if (nPar == 0)
01844       BCLog::OutWarning("BCModel::SetPriorConstantAll. No parameters defined.");
01845 
01846    // loop over all 1-d priors
01847    for (int i = 0; i < nPar; ++i) {
01848 
01849       logprob -= log(GetParameter(i)->GetRangeWidth());
01850    }
01851 
01852    fPriorConstantAll = true;
01853 
01854    fPriorConstantValue = logprob;
01855 
01856    // reset all results
01857    ResetResults();
01858 
01859    // no error
01860    return 1;
01861 }
01862 
01863 // ---------------------------------------------------------
01864 int BCModel::SetParameterRange(int index, double parmin, double parmax)
01865 {
01866    // check index
01867    if (index < 0 || index >= int(GetNParameters())) {
01868       BCLog::OutWarning("BCModel::SetParameterRange() : Index out of range.");
01869       return 0; 
01870    }
01871 
01872    // set parameter ranges in BAT 
01873    GetParameter(index)->SetLowerLimit(parmin); 
01874    GetParameter(index)->SetUpperLimit(parmax); 
01875    fMCMCBoundaryMin[index] = parmin; 
01876    fMCMCBoundaryMax[index] = parmax; 
01877 
01878    // reset results
01879    ResetResults();
01880 
01881    // no error 
01882    return 1; 
01883 }
01884 
01885 // ---------------------------------------------------------
01886 int BCModel::ResetResults()
01887 {
01888    BCIntegrate::IntegrateResetResults();
01889   
01890    BCEngineMCMC::MCMCResetResults();
01891 
01892    // no error
01893    return 1;
01894 }
01895 
01896 // ---------------------------------------------------------
01897 void BCModel::PrintSummary()
01898 {
01899    int nparameters = GetNParameters();
01900 
01901    // model summary
01902    std::cout << std::endl
01903              << "   ---------------------------------" << std::endl
01904              << "    Model : " << fName.data() << std::endl
01905              << "   ---------------------------------" << std::endl
01906              << "     Index                : " << fIndex << std::endl
01907              << "     Number of parameters : " << nparameters << std::endl << std::endl
01908              << "     - Parameters : " << std::endl << std::endl;
01909 
01910    // parameter summary
01911    for (int i = 0; i < nparameters; i++)
01912       fParameterSet->at(i)->PrintSummary();
01913 
01914    // best fit parameters
01915    if (GetBestFitParameters().size() > 0) {
01916       std::cout << std::endl << "     - Best fit parameters :" << std::endl << std::endl;
01917 
01918       for (int i = 0; i < nparameters; i++) {
01919          std::cout << "       " << fParameterSet->at(i)->GetName().data()
01920                    << " = " << GetBestFitParameter(i) << " (overall)" << std::endl;
01921          if ((int) fBestFitParametersMarginalized.size() == nparameters)
01922             std::cout << "       "
01923                       << fParameterSet->at(i)->GetName().data() << " = "
01924                       << GetBestFitParameterMarginalized(i)
01925                       << " (marginalized)" << std::endl;
01926       }
01927    }
01928 
01929    std::cout << std::endl;
01930 
01931    // model testing
01932    if (fPValue >= 0) {
01933       double likelihood = Likelihood(GetBestFitParameters());
01934       std::cout << "   - Model testing:" << std::endl << std::endl
01935                 << "       p(data|lambda*) = " << likelihood << std::endl
01936                 << "       p-value         = " << fPValue << std::endl << std::endl;
01937    }
01938 
01939    // normalization
01940    if (fNormalization > 0)
01941       std::cout << "     Normalization        : " << fNormalization << std::endl;
01942 }
01943 
01944 // ---------------------------------------------------------
01945 void BCModel::PrintResults(const char * file)
01946 {
01947    // print summary of Markov Chain Monte Carlo
01948 
01949    // open file
01950    ofstream ofi(file);
01951 
01952    // check if file is open
01953    if (!ofi.is_open()) {
01954       std::cerr << "Couldn't open file " << file << std::endl;
01955       return;
01956    }
01957 
01958    // number of parameters and chains
01959    int npar = MCMCGetNParameters();
01960    int nchains = MCMCGetNChains();
01961 
01962    // check convergence
01963    bool flag_conv = MCMCGetNIterationsConvergenceGlobal() > 0;
01964 
01965    ofi << std::endl 
01966           << " -----------------------------------------------------" << std::endl 
01967           << " Summary" << std::endl
01968        << " -----------------------------------------------------" << std::endl
01969        << std::endl;
01970 
01971    ofi << " Model summary" << std::endl << " =============" << std::endl
01972        << " Model: " << fName.data() << std::endl
01973        << " Number of parameters: " << npar << std::endl
01974        << " List of Parameters and ranges:" << std::endl;
01975    for (int i = 0; i < npar; ++i)
01976       ofi << "  (" << i << ") Parameter \""
01977           << fParameterSet->at(i)->GetName().data() << "\"" << ": "
01978           << "(" << fParameterSet->at(i)->GetLowerLimit() << ", "
01979           << fParameterSet->at(i)->GetUpperLimit() << ")" << std::endl;
01980    ofi << std::endl;
01981 
01982    // give warning if MCMC did not converge
01983    if (!flag_conv && fMCMCFlagRun)
01984       ofi << " WARNING: the Markov Chain did not converge!" << std::endl
01985           << " Be cautious using the following results!" << std::endl
01986           << std::endl;
01987 
01988    // print results of marginalization (if MCMC was run)
01989    if (fMCMCFlagRun && fMCMCFlagFillHistograms) {
01990       ofi << " Results of the marginalization" << std::endl
01991           << " ==============================" << std::endl
01992           << " List of parameters and properties of the marginalized"
01993           << std::endl << " distributions:" << std::endl;
01994       for (int i = 0; i < npar; ++i) {
01995          if (!fMCMCFlagsFillHistograms[i])
01996             continue;
01997 
01998          BCH1D * bch1d = GetMarginalized(fParameterSet->at(i));
01999 
02000          ofi << "  (" << i << ") Parameter \""
02001              << fParameterSet->at(i)->GetName().data() << "\":" << std::endl
02002 
02003              << "      Mean +- sqrt(V):                " << std::setprecision(4)
02004              << bch1d->GetMean() << " +- " << std::setprecision(4)
02005              << bch1d->GetRMS() << std::endl 
02006 
02007                    << "      Median +- central 68% interval: "
02008              << std::setprecision(4) << bch1d->GetMedian() << " +  "
02009              << std::setprecision(4) << bch1d->GetQuantile(0.84) - bch1d->GetMedian()
02010              << " - " << std::setprecision(4)
02011              << bch1d->GetMedian() - bch1d->GetQuantile(0.16) << std::endl
02012 
02013              << "      (Marginalized) mode:            " << bch1d->GetMode() << std::endl;
02014 
02015          ofi << "       5% quantile:                   " << std::setprecision(4)
02016              << bch1d->GetQuantile(0.05) << std::endl
02017              << "      10% quantile:                   " << std::setprecision(4)
02018              << bch1d->GetQuantile(0.10) << std::endl
02019              << "      16% quantile:                   " << std::setprecision(4)
02020              << bch1d->GetQuantile(0.16) << std::endl
02021              << "      84% quantile:                   " << std::setprecision(4)
02022              << bch1d->GetQuantile(0.85) << std::endl
02023              << "      90% quantile:                   " << std::setprecision(4)
02024              << bch1d->GetQuantile(0.90) << std::endl
02025              << "      95% quantile:                   " << std::setprecision(4)
02026              << bch1d->GetQuantile(0.95) << std::endl;
02027 
02028          std::vector<double> v;
02029          v = bch1d->GetSmallestIntervals(0.68);
02030          int ninter = int(v.size());
02031              
02032              ofi << "      Smallest interval(s) containing 68% and local modes:"
02033                    << std::endl;
02034          for (int j = 0; j < ninter; j += 5)
02035                 ofi << "       (" << v[j] << ", " << v[j + 1]
02036                       << ") (local mode at " << v[j + 3] << " with rel. height "
02037                       << v[j + 2] << "; rel. area " << v[j + 4] << ")"
02038                       << std::endl;
02039              ofi << std::endl;
02040       }
02041    }
02042 
02043    ofi << " Results of the optimization" << std::endl
02044        << " ===========================" << std::endl
02045        << " Optimization algorithm used:";
02046    switch (GetOptimizationMethodMode()) {
02047       case BCIntegrate::kOptSA:
02048          ofi << " Simulated Annealing" << std::endl;
02049          break;
02050       case BCIntegrate::kOptMinuit:
02051          ofi << " Minuit" << std::endl;
02052          break;
02053       case BCIntegrate::kOptMetropolis:
02054          ofi << " MCMC" << std::endl;
02055          break;
02056    }
02057 
02058    if (int(fBestFitParameters.size()) > 0) {
02059       ofi << " List of parameters and global mode:" << std::endl;
02060       for (int i = 0; i < npar; ++i) {
02061          ofi << "  (" << i << ") Parameter \""
02062              << fParameterSet->at(i)->GetName().data() << "\": "
02063              << fBestFitParameters[i];
02064          if(fBestFitParameterErrors[i]>=0.)
02065             ofi << " +- " << fBestFitParameterErrors[i];
02066          ofi << std::endl;
02067       }
02068       ofi << std::endl;
02069    }
02070    else {
02071       ofi << " No best fit information available." << std::endl;
02072       ofi << std::endl;
02073    }
02074 
02075    if (fPValue >= 0.) {
02076       ofi << " Results of the model test" << std::endl
02077           << " =========================" << std::endl
02078           << " p-value at global mode: " << fPValue << std::endl << std::endl;
02079    }
02080 
02081    if (fMCMCFlagRun) {
02082       ofi << " Status of the MCMC" << std::endl << " ==================" << std::endl
02083                << " Convergence reached:                    " << (flag_conv ? "yes" : "no")
02084           << std::endl;
02085 
02086       if (flag_conv)
02087          ofi << " Number of iterations until convergence: "
02088              << MCMCGetNIterationsConvergenceGlobal() << std::endl;
02089       else
02090          ofi << " WARNING: the Markov Chain did not converge! Be\n"
02091              << " cautious using the following results!" << std::endl
02092              << std::endl;
02093       ofi << " Number of chains:                       " << MCMCGetNChains() << std::endl
02094           << " Number of iterations per chain:         " << MCMCGetNIterationsRun() << std::endl
02095           << " Average efficiencies:" << std::endl;
02096 
02097       std::vector<double> efficiencies;
02098       efficiencies.assign(npar, 0.);
02099 
02100       for (int ipar = 0; ipar < npar; ++ipar)
02101          for (int ichain = 0; ichain < nchains; ++ichain) {
02102             int index = ichain * npar + ipar;
02103             efficiencies[ipar] +=
02104                   double(MCMCGetNTrialsTrue().at(index)) / double(MCMCGetNTrialsTrue().at(index)
02105                   + MCMCGetNTrialsFalse().at(index)) / double(nchains) * 100.;
02106          }
02107 
02108       for (int ipar = 0; ipar < npar; ++ipar)
02109          ofi << "  (" << ipar << ") Parameter \""
02110              << fParameterSet->at(ipar)->GetName().data() << "\": "
02111              << efficiencies.at(ipar) << "%" << std::endl;
02112       ofi << std::endl;
02113    }
02114 
02115     ofi << " -----------------------------------------------------" << std::endl
02116           << " Notation: " << std::endl
02117           << " Mean        : mean value of the marg. pdf" << std::endl
02118           << " Median      : maximum of the marg. pdf" << std::endl
02119           << " Marg. mode  : most probable value of the marg. pdf" << std::endl
02120           << " V           : Variance of the marg. pdf" << std::endl
02121           << " Quantiles   : most commonly used quantiles" <<std::endl
02122           << " -----------------------------------------------------" << std::endl
02123           << std::endl;
02124 
02125    // close file
02126    //   ofi.close;
02127 }
02128 
02129 // ---------------------------------------------------------
02130 void BCModel::PrintShortFitSummary(int chi2flag)
02131 {
02132    BCLog::OutSummary("---------------------------------------------------");
02133    BCLog::OutSummary(Form("Fit summary for model \'%s\':", GetName().data()));
02134    BCLog::OutSummary(Form("   Number of parameters:  Npar  = %i", GetNParameters()));
02135    BCLog::OutSummary(Form("   Number of data points: Ndata = %i", GetNDataPoints()));
02136    BCLog::OutSummary("   Number of degrees of freedom:");
02137    BCLog::OutSummary(Form("      NDoF = Ndata - Npar = %i", GetNDataPoints() - GetNParameters()));
02138 
02139    BCLog::OutSummary("   Best fit parameters (global):");
02140    for (unsigned int i = 0; i < GetNParameters(); ++i)
02141       BCLog::OutSummary(Form("      %s = %.3g", GetParameter(i)->GetName().data(), GetBestFitParameter(i)));
02142 
02143    BCLog::OutSummary("   Goodness-of-fit test:");
02144    BCLog::OutSummary(Form("      p-value = %.3g", GetPValue()));
02145    if (chi2flag) {
02146       BCLog::OutSummary(Form("      p-value corrected for NDoF = %.3g", GetPValueNDoF()));
02147       BCLog::OutSummary(Form("      chi2 / NDoF = %.3g", GetChi2NDoF()));
02148    }
02149    BCLog::OutSummary("---------------------------------------------------");
02150 }
02151 
02152 // ---------------------------------------------------------
02153 void BCModel::PrintHessianMatrix(std::vector<double> parameters)
02154 {
02155    // check number of entries in vector
02156    if (parameters.size() != GetNParameters()) {
02157       BCLog::OutError("BCModel::PrintHessianMatrix : Invalid number of entries in the vector");
02158       return;
02159    }
02160 
02161    // print to screen
02162    std::cout << std::endl << " Hessian matrix elements: " << std::endl << " Point: ";
02163 
02164    for (int i = 0; i < int(parameters.size()); i++)
02165       std::cout << parameters.at(i) << " ";
02166    std::cout << std::endl;
02167 
02168    // loop over all parameter pairs
02169    for (unsigned int i = 0; i < GetNParameters(); i++)
02170       for (unsigned int j = 0; j < i; j++) {
02171          // calculate Hessian matrix element
02172          double hessianmatrixelement = HessianMatrixElement(
02173                fParameterSet->at(i), fParameterSet->at(j), parameters);
02174 
02175          // print to screen
02176          std::cout << " " << i << " " << j << " : " << hessianmatrixelement << std::endl;
02177       }
02178 }
02179 
02180 // ---------------------------------------------------------
02181 BCDataPoint * BCModel::VectorToDataPoint(std::vector<double> data)
02182 {
02183    int sizeofvector = int(data.size());
02184    BCDataPoint * datapoint = new BCDataPoint(sizeofvector);
02185    datapoint->SetValues(data);
02186    return datapoint;
02187 }
02188 
02189 // ---------------------------------------------------------
02190 int BCModel::CompareStrings(const char * string1, const char * string2)
02191 {
02192    int flag_same = 0;
02193 
02194    if (strlen(string1) != strlen(string2))
02195       return -1;
02196 
02197    for (int i = 0; i < int(strlen(string1)); i++)
02198       if (string1[i] != string2[i])
02199          flag_same = -1;
02200 
02201    return flag_same;
02202 }
02203 
02204 // ---------------------------------------------------------
02205 

Generated on Mon Aug 30 2010 22:14:54 for Bayesian Analysis Toolkit by  doxygen 1.7.1