00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "config.h"
00011
00012 #include "BAT/BCIntegrate.h"
00013 #include "BAT/BCLog.h"
00014 #include "BAT/BCMath.h"
00015
00016 #include <TH1D.h>
00017 #include <TH2D.h>
00018 #include <TMinuit.h>
00019 #include <TRandom3.h>
00020 #include <TTree.h>
00021
00022 #ifdef HAVE_CUBA_H
00023 #include "cuba.h"
00024 #endif
00025
00026
00027
00028 class BCIntegrate * global_this;
00029
00030
00031 BCIntegrate::BCIntegrate() : BCEngineMCMC()
00032 {
00033 fNvar=0;
00034 fNiterPerDimension = 100;
00035 fNSamplesPer2DBin = 100;
00036 fRandom = new TRandom3(0);
00037
00038 fNIterationsMax = 1000000;
00039 fRelativePrecision = 1e-3;
00040
00041 #ifdef HAVE_CUBA_H
00042 fIntegrationMethod = BCIntegrate::kIntCuba;
00043 #else
00044 fIntegrationMethod = BCIntegrate::kIntMonteCarlo;
00045 #endif
00046 fMarginalizationMethod = BCIntegrate::kMargMetropolis;
00047 fOptimizationMethod = BCIntegrate::kOptMinuit;
00048
00049 fNbins=100;
00050
00051 fDataPointLowerBoundaries = 0;
00052 fDataPointUpperBoundaries = 0;
00053
00054 fFillErrorBand = false;
00055
00056 fFitFunctionIndexX = -1;
00057 fFitFunctionIndexY = -1;
00058
00059 fErrorBandNbinsX = 100;
00060 fErrorBandNbinsY = 500;
00061
00062 fErrorBandContinuous = true;
00063
00064 fMinuit = 0;
00065 fMinuitArglist[0] = 20000;
00066 fMinuitArglist[1] = 0.01;
00067
00068 fFlagWriteMarkovChain = false;
00069 fMarkovChainTree = 0;
00070
00071 fMarkovChainStepSize = 0.1;
00072
00073 fMarkovChainAutoN = true;
00074 }
00075
00076
00077 BCIntegrate::BCIntegrate(BCParameterSet * par) : BCEngineMCMC(1)
00078 {
00079 fNvar=0;
00080 fNiterPerDimension = 100;
00081 fNSamplesPer2DBin = 100;
00082 fRandom = new TRandom3(0);
00083
00084 fNbins=100;
00085
00086 this->SetParameters(par);
00087
00088 fDataPointLowerBoundaries = 0;
00089 fDataPointUpperBoundaries = 0;
00090
00091 fFillErrorBand = false;
00092
00093 fFitFunctionIndexX = -1;
00094 fFitFunctionIndexY = -1;
00095
00096 fErrorBandNbinsX = 100;
00097 fErrorBandNbinsY = 200;
00098
00099 fErrorBandContinuous = true;
00100
00101 fMinuit = 0;
00102 fMinuitArglist[0] = 20000;
00103 fMinuitArglist[1] = 0.01;
00104
00105 fFlagWriteMarkovChain = false;
00106 fMarkovChainTree = 0;
00107
00108 fMarkovChainStepSize = 0.1;
00109
00110 fMarkovChainAutoN = true;
00111 }
00112
00113
00114 BCIntegrate::~BCIntegrate()
00115 {
00116 DeleteVarList();
00117
00118 fx=0;
00119
00120 delete fRandom;
00121 fRandom=0;
00122
00123 if (fMinuit)
00124 delete fMinuit;
00125
00126 int n1 = fHProb1D.size();
00127 if(n1>0)
00128 {
00129 for (int i=0;i<n1;i++)
00130 delete fHProb1D.at(i);
00131 }
00132
00133 int n2 = fHProb2D.size();
00134 if(n2>0)
00135 {
00136 for (int i=0;i<n2;i++)
00137 delete fHProb2D.at(i);
00138 }
00139 }
00140
00141
00142 void BCIntegrate::SetParameters(BCParameterSet * par)
00143 {
00144 DeleteVarList();
00145
00146 fx = par;
00147 fNvar = fx->size();
00148 fMin = new double[fNvar];
00149 fMax = new double[fNvar];
00150 fVarlist = new int[fNvar];
00151
00152 this->ResetVarlist(1);
00153
00154 for(int i=0;i<fNvar;i++)
00155 {
00156 fMin[i]=(fx->at(i))->GetLowerLimit();
00157 fMax[i]=(fx->at(i))->GetUpperLimit();
00158 }
00159
00160 fXmetro0.clear();
00161 for(int i=0;i<fNvar;i++)
00162 fXmetro0.push_back((fMin[i]+fMax[i])/2.0);
00163
00164 fXmetro1.clear();
00165 fXmetro1.assign(fNvar,0.);
00166
00167 fMCMCBoundaryMin.clear();
00168 fMCMCBoundaryMax.clear();
00169
00170 for(int i=0;i<fNvar;i++)
00171 {
00172 fMCMCBoundaryMin.push_back(fMin[i]);
00173 fMCMCBoundaryMax.push_back(fMax[i]);
00174 }
00175
00176 for (int i = int(fMCMCH1NBins.size()); i<fNvar; ++i)
00177 fMCMCH1NBins.push_back(100);
00178
00179 fMCMCNParameters = fNvar;
00180 }
00181
00182
00183 void BCIntegrate::SetMarkovChainInitialPosition(std::vector<double> position)
00184 {
00185 int n = position.size();
00186
00187 fXmetro0.clear();
00188
00189 for (int i = 0; i < n; ++i)
00190 fXmetro0.push_back(position.at(i));
00191 }
00192
00193
00194 void BCIntegrate::DeleteVarList()
00195 {
00196 if(fNvar)
00197 {
00198 delete[] fVarlist;
00199 fVarlist=0;
00200
00201 delete[] fMin;
00202 fMin=0;
00203
00204 delete[] fMax;
00205 fMax=0;
00206
00207 fx=0;
00208 fNvar=0;
00209 }
00210 }
00211
00212
00213 void BCIntegrate::SetNbins(int nbins, int index)
00214 {
00215 if (fNvar == 0)
00216 return;
00217
00218
00219 if (index >= fNvar)
00220 {
00221 BCLog::Out(BCLog::warning, BCLog::warning,"BCIntegrate::SetNbins : Index out of range.");
00222 return;
00223 }
00224
00225 else if (index < 0)
00226 {
00227 for (int i = 0; i < fNvar; ++i)
00228 this -> SetNbins(nbins, i);
00229 return;
00230 }
00231
00232
00233 if (nbins <= 0)
00234 nbins = 10;
00235
00236 fMCMCH1NBins[index] = nbins;
00237
00238 return;
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 void BCIntegrate::SetVarList(int * varlist)
00280 {
00281 for(int i=0;i<fNvar;i++)
00282 fVarlist[i]=varlist[i];
00283 }
00284
00285
00286 void BCIntegrate::ResetVarlist(int v)
00287 {
00288 for(int i=0;i<fNvar;i++)
00289 fVarlist[i]=v;
00290 }
00291
00292
00293 double BCIntegrate::Eval(std::vector <double> x)
00294 {
00295 BCLog::Out(BCLog::warning, BCLog::warning, "BCIntegrate::Eval. No function. Function needs to be overloaded.");
00296 return 0;
00297 }
00298
00299
00300 double BCIntegrate::LogEval(std::vector <double> x)
00301 {
00302
00303 return log(this->Eval(x));
00304 }
00305
00306
00307 double BCIntegrate::EvalSampling(std::vector <double> x)
00308 {
00309 BCLog::Out(BCLog::warning, BCLog::warning, "BCIntegrate::EvalSampling. No function. Function needs to be overloaded.");
00310 return 0;
00311 }
00312
00313
00314 double BCIntegrate::LogEvalSampling(std::vector <double> x)
00315 {
00316 return log(this->EvalSampling(x));
00317 }
00318
00319
00320 double BCIntegrate::EvalPrint(std::vector <double> x)
00321 {
00322 double val=this->Eval(x);
00323
00324 BCLog::Out(BCLog::detail, BCLog::detail, Form("BCIntegrate::EvalPrint. Value: %d.", val));
00325
00326 return val;
00327 }
00328
00329
00330 void BCIntegrate::SetIntegrationMethod(BCIntegrate::BCIntegrationMethod method)
00331 {
00332 #ifdef HAVE_CUBA_H
00333 fIntegrationMethod = method;
00334 #else
00335 BCLog::Out(BCLog::warning,BCLog::warning,"!!! This version of BAT is compiled without Cuba.");
00336 BCLog::Out(BCLog::warning,BCLog::warning," Monte Carlo Sampled Mean integration method will be used.");
00337 BCLog::Out(BCLog::warning,BCLog::warning," To be able to use Cuba integration, install Cuba and recompile BAT.");
00338 #endif
00339 }
00340
00341
00342 double BCIntegrate::Integrate()
00343 {
00344 std::vector <double> parameter;
00345 parameter.assign(fNvar, 0.0);
00346
00347 switch(fIntegrationMethod)
00348 {
00349 case BCIntegrate::kIntMonteCarlo:
00350 return IntegralMC(parameter);
00351
00352 case BCIntegrate::kIntMetropolis:
00353 return this -> IntegralMetro(parameter);
00354
00355 case BCIntegrate::kIntImportance:
00356 return this -> IntegralImportance(parameter);
00357
00358 case BCIntegrate::kIntCuba:
00359 #ifdef HAVE_CUBA_H
00360 return this -> CubaIntegrate();
00361 #else
00362 BCLog::Out(BCLog::error,BCLog::error,"!!! This version of BAT is compiled without Cuba.");
00363 BCLog::Out(BCLog::error,BCLog::error," Use other integration methods or install Cuba and recompile BAT.");
00364 #endif
00365 }
00366
00367 BCLog::Out(BCLog::error, BCLog::error,
00368 Form("BCIntegrate::Integrate : Invalid integration method: %d", fIntegrationMethod));
00369
00370 return 0;
00371 }
00372
00373
00374 double BCIntegrate::IntegralMC(std::vector <double> x, int * varlist)
00375 {
00376 this->SetVarList(varlist);
00377 return IntegralMC(x);
00378 }
00379
00380
00381 double BCIntegrate::IntegralMC(std::vector <double> x)
00382 {
00383
00384 int NvarNow=0;
00385
00386 for(int i = 0; i < fNvar; i++)
00387 if(fVarlist[i])
00388 NvarNow++;
00389
00390
00391 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Running MC integation over %i dimensions.", NvarNow));
00392 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Maximum number of iterations: %i", this->GetNIterationsMax()));
00393 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Aimed relative precision: %e", this->GetRelativePrecision()));
00394
00395
00396 double D = 1.0;
00397 for(int i = 0; i < fNvar; i++)
00398 if (fVarlist[i])
00399 D = D * (fMax[i] - fMin[i]);
00400
00401
00402 double pmax = 0.0;
00403 double sumW = 0.0;
00404 double sumW2 = 0.0;
00405 double integral = 0.0;
00406 double variance = 0.0;
00407 double relprecision = 1.0;
00408
00409 std::vector <double> randx;
00410 randx.assign(fNvar, 0.0);
00411
00412
00413 fNIterations = 0;
00414
00415
00416 while ((fRelativePrecision < relprecision && fNIterationsMax > fNIterations) || fNIterations < 10)
00417 {
00418
00419 fNIterations++;
00420
00421
00422 this -> GetRandomVector(randx);
00423
00424
00425 for(int i = 0; i < fNvar; i++)
00426 {
00427 if(fVarlist[i])
00428 randx[i]=fMin[i]+randx[i]*(fMax[i]-fMin[i]);
00429 else
00430 randx[i]=x[i];
00431 }
00432
00433
00434 double value = this->Eval(randx);
00435
00436
00437 sumW += value;
00438 sumW2 += value * value;
00439
00440
00441 if (value > pmax)
00442 {
00443
00444 pmax = value;
00445
00446
00447 fBestFitParameters.clear();
00448
00449
00450 for(int i = 0; i < fNvar; i++)
00451 fBestFitParameters.push_back(randx.at(i));
00452 }
00453
00454
00455 integral = D * sumW / fNIterations;
00456
00457 if (fNIterations%10000 == 0)
00458 {
00459 variance = (1.0 / double(fNIterations)) * (D * D * sumW2 / double(fNIterations) - integral * integral);
00460 double error = sqrt(variance);
00461 relprecision = error / integral;
00462
00463 BCLog::Out(BCLog::debug, BCLog::debug,
00464 Form("BCIntegrate::IntegralMC. Iteration %i, integral: %e +- %e.", fNIterations, integral, error));
00465 }
00466 }
00467
00468 fError = variance / fNIterations;
00469
00470
00471 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Result of integration: %e +- %e in %i iterations.", integral, sqrt(variance), fNIterations));
00472 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Obtained relative precision: %e. ", sqrt(variance) / integral));
00473
00474 return integral;
00475 }
00476
00477
00478
00479 double BCIntegrate::IntegralMetro(std::vector <double> x)
00480 {
00481
00482 BCLog::Out(BCLog::debug, BCLog::debug, Form("BCIntegrate::IntegralMetro. Integate over %i dimensions.", fNvar));
00483
00484
00485 double Niter = pow(fNiterPerDimension, fNvar);
00486
00487
00488 if(Niter>1e5)
00489 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Total number of iterations in Metropolis: %d.", Niter));
00490
00491
00492 double sumI = 0;
00493
00494
00495 std::vector <double> randx;
00496 randx.assign(fNvar,0.);
00497 InitMetro();
00498
00499
00500 double pmax = 0.0;
00501
00502
00503 for(int i = 0; i <= Niter; i++)
00504 {
00505
00506 this -> GetRandomPointSamplingMetro(randx);
00507
00508
00509 double val_f = this -> Eval(randx);
00510
00511
00512 double val_g = this -> EvalSampling(randx);
00513
00514
00515 if (val_g > 0)
00516 sumI += val_f / val_g;
00517
00518
00519 if (val_f > pmax)
00520 {
00521
00522 pmax = val_f;
00523
00524
00525 fBestFitParameters.clear();
00526
00527
00528 for(int i = 0; i < fNvar; i++)
00529 fBestFitParameters.push_back(randx.at(i));
00530 }
00531
00532
00533 if((i+1)%100000 == 0)
00534 BCLog::Out(BCLog::debug, BCLog::debug,
00535 Form("BCIntegrate::IntegralMetro. Iteration %d, integral: %d.", i+1, sumI/(i+1)));
00536 }
00537
00538
00539 double result=sumI/Niter;
00540
00541
00542 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Integral is %f in %i iterations.", result, Niter));
00543
00544 return result;
00545 }
00546
00547
00548 double BCIntegrate::IntegralImportance(std::vector <double> x)
00549 {
00550
00551 BCLog::Out(BCLog::debug, BCLog::debug, Form("BCIntegrate::IntegralImportance. Integate over %i dimensions.", fNvar));
00552
00553
00554 double Niter = pow(fNiterPerDimension, fNvar);
00555
00556
00557 if(Niter>1e5)
00558 BCLog::Out(BCLog::detail, BCLog::detail, Form("BCIntegrate::IntegralImportance. Total number of iterations: %d.", Niter));
00559
00560
00561 double sumI = 0;
00562
00563 std::vector <double> randx;
00564 randx.assign(fNvar,0.);
00565
00566
00567 double pmax = 0.0;
00568
00569
00570 for(int i = 0; i <= Niter; i++)
00571 {
00572
00573 this -> GetRandomPointImportance(randx);
00574
00575
00576 double val_f = this -> Eval(randx);
00577
00578
00579 double val_g = this -> EvalSampling(randx);
00580
00581
00582 if (val_g > 0)
00583 sumI += val_f / val_g;
00584
00585
00586 if (val_f > pmax)
00587 {
00588
00589 pmax = val_f;
00590
00591
00592 fBestFitParameters.clear();
00593
00594
00595 for(int i = 0; i < fNvar; i++)
00596 fBestFitParameters.push_back(randx.at(i));
00597 }
00598
00599
00600 if((i+1)%100000 == 0)
00601 BCLog::Out(BCLog::debug, BCLog::debug,
00602 Form("BCIntegrate::IntegralImportance. Iteration %d, integral: %d.", i+1, sumI/(i+1)));
00603 }
00604
00605
00606 double result=sumI/Niter;
00607
00608
00609 BCLog::Out(BCLog::debug, BCLog::debug, Form("BCIntegrate::IntegralImportance. Integral %f in %i iterations.", result, Niter));
00610
00611 return result;
00612 }
00613
00614
00615 TH1D* BCIntegrate::Marginalize(BCParameter * parameter)
00616 {
00617 BCLog::Out(BCLog::detail, BCLog::detail,
00618 Form(" --> Marginalizing model wrt. parameter %s using method %d.", parameter->GetName().data(), fMarginalizationMethod));
00619
00620 switch(fMarginalizationMethod)
00621 {
00622 case BCIntegrate::kMargMonteCarlo:
00623 return MarginalizeByIntegrate(parameter);
00624
00625 case BCIntegrate::kMargMetropolis:
00626 return MarginalizeByMetro(parameter);
00627 }
00628
00629 BCLog::Out(BCLog::warning, BCLog::warning,
00630 Form("BCIntegrate::Marginalize. Invalid marginalization method: %d. Return 0.", fMarginalizationMethod));
00631
00632 return 0;
00633 }
00634
00635
00636 TH2D * BCIntegrate::Marginalize(BCParameter * parameter1, BCParameter * parameter2)
00637 {
00638 switch(fMarginalizationMethod)
00639 {
00640 case BCIntegrate::kMargMonteCarlo:
00641 return MarginalizeByIntegrate(parameter1,parameter2);
00642
00643 case BCIntegrate::kMargMetropolis:
00644 return MarginalizeByMetro(parameter1,parameter2);
00645 }
00646
00647 BCLog::Out(BCLog::warning, BCLog::warning,
00648 Form("BCIntegrate::Marginalize. Invalid marginalization method: %d. Return 0.", fMarginalizationMethod));
00649
00650 return 0;
00651 }
00652
00653
00654 TH1D* BCIntegrate::MarginalizeByIntegrate(BCParameter * parameter)
00655 {
00656
00657 this->ResetVarlist(1);
00658 int index = parameter->GetIndex();
00659 this->UnsetVar(index);
00660
00661
00662 double hmin = parameter -> GetLowerLimit();
00663 double hmax = parameter -> GetUpperLimit();
00664 double hdx = (hmax - hmin) / double(fNbins);
00665 TH1D * hist = new TH1D("hist","", fNbins, hmin, hmax);
00666
00667
00668 std::vector <double> randx;
00669 randx.assign(fNvar, 0.0);
00670
00671 for(int i=0;i<=fNbins;i++)
00672 {
00673 randx[index] = hmin + (double)i * hdx;
00674
00675 double val = IntegralMC(randx);
00676 hist->Fill(randx[index], val);
00677 }
00678
00679
00680 hist -> Scale( 1./hist->Integral("width") );
00681
00682 return hist;
00683 }
00684
00685
00686 TH2D * BCIntegrate::MarginalizeByIntegrate(BCParameter * parameter1, BCParameter * parameter2)
00687 {
00688
00689 this->ResetVarlist(1);
00690 int index1 = parameter1->GetIndex();
00691 this->UnsetVar(index1);
00692 int index2 = parameter2->GetIndex();
00693 this->UnsetVar(index2);
00694
00695
00696 double hmin1 = parameter1 -> GetLowerLimit();
00697 double hmax1 = parameter1 -> GetUpperLimit();
00698 double hdx1 = (hmax1 - hmin1) / double(fNbins);
00699
00700 double hmin2 = parameter2 -> GetLowerLimit();
00701 double hmax2 = parameter2 -> GetUpperLimit();
00702 double hdx2 = (hmax2 - hmin2) / double(fNbins);
00703
00704 TH2D * hist = new TH2D(Form("hist_%s_%s", parameter1 -> GetName().data(), parameter2 -> GetName().data()),"",
00705 fNbins, hmin1, hmax1,
00706 fNbins, hmin2, hmax2);
00707
00708
00709 std::vector <double> randx;
00710 randx.assign(fNvar, 0.0);
00711
00712 for(int i=0;i<=fNbins;i++)
00713 {
00714 randx[index1] = hmin1 + (double)i * hdx1;
00715 for(int j=0;j<=fNbins;j++)
00716 {
00717 randx[index2] = hmin2 + (double)j * hdx2;
00718
00719 double val = IntegralMC(randx);
00720 hist->Fill(randx[index1],randx[index2], val);
00721 }
00722 }
00723
00724
00725 hist -> Scale(1.0/hist->Integral("width"));
00726
00727 return hist;
00728 }
00729
00730
00731 TH1D * BCIntegrate::MarginalizeByMetro(BCParameter * parameter)
00732 {
00733 int niter = fMarkovChainNIterations;
00734
00735 if (fMarkovChainAutoN == true)
00736 niter = fNbins*fNbins*fNSamplesPer2DBin*fNvar;
00737
00738 BCLog::Out(BCLog::detail, BCLog::detail,
00739 Form(" --> Number of samples in Metropolis marginalization: %d.", niter));
00740
00741
00742 int index = parameter->GetIndex();
00743
00744
00745 double hmin = parameter -> GetLowerLimit();
00746 double hmax = parameter -> GetUpperLimit();
00747 TH1D * hist = new TH1D("hist","", fNbins, hmin, hmax);
00748
00749
00750 std::vector <double> randx;
00751 randx.assign(fNvar, 0.0);
00752 InitMetro();
00753
00754 for(int i=0;i<=niter;i++)
00755 {
00756 GetRandomPointMetro(randx);
00757 hist->Fill(randx[index]);
00758 }
00759
00760
00761 hist -> Scale(1.0/hist->Integral("width"));
00762
00763 return hist;
00764 }
00765
00766
00767 TH2D * BCIntegrate::MarginalizeByMetro(BCParameter * parameter1, BCParameter * parameter2)
00768 {
00769 int niter=fNbins*fNbins*fNSamplesPer2DBin*fNvar;
00770
00771
00772 int index1 = parameter1->GetIndex();
00773 int index2 = parameter2->GetIndex();
00774
00775
00776 double hmin1 = parameter1 -> GetLowerLimit();
00777 double hmax1 = parameter1 -> GetUpperLimit();
00778
00779 double hmin2 = parameter2 -> GetLowerLimit();
00780 double hmax2 = parameter2 -> GetUpperLimit();
00781
00782 TH2D * hist = new TH2D(Form("hist_%s_%s", parameter1 -> GetName().data(), parameter2 -> GetName().data()),"",
00783 fNbins, hmin1, hmax1,
00784 fNbins, hmin2, hmax2);
00785
00786
00787 std::vector <double> randx;
00788 randx.assign(fNvar, 0.0);
00789 InitMetro();
00790
00791 for(int i=0;i<=niter;i++)
00792 {
00793 GetRandomPointMetro(randx);
00794 hist->Fill(randx[index1],randx[index2]);
00795 }
00796
00797
00798 hist -> Scale(1.0/hist->Integral("width"));
00799
00800 return hist;
00801 }
00802
00803
00804 int BCIntegrate::MarginalizeAllByMetro(const char * name="")
00805 {
00806 int niter=fNbins*fNbins*fNSamplesPer2DBin*fNvar;
00807
00808 BCLog::Out(BCLog::detail, BCLog::detail,
00809 Form(" --> Number of samples in Metropolis marginalization: %d.", niter));
00810
00811
00812 for(int i=0;i<fNvar;i++)
00813 {
00814 double hmin1 = fx->at(i) -> GetLowerLimit();
00815 double hmax1 = fx->at(i) -> GetUpperLimit();
00816
00817 TH1D * h1 = new TH1D(
00818 TString::Format("h%s_%s", name, fx->at(i) -> GetName().data()),"",
00819 fNbins, hmin1, hmax1);
00820
00821 fHProb1D.push_back(h1);
00822 }
00823
00824
00825 for(int i=0;i<fNvar-1;i++)
00826 for(int j=i+1;j<fNvar;j++)
00827 {
00828 double hmin1 = fx->at(i) -> GetLowerLimit();
00829 double hmax1 = fx->at(i) -> GetUpperLimit();
00830
00831 double hmin2 = fx->at(j) -> GetLowerLimit();
00832 double hmax2 = fx->at(j) -> GetUpperLimit();
00833
00834 TH2D * h2 = new TH2D(
00835 TString::Format("h%s_%s_%s", name, fx->at(i) -> GetName().data(), fx->at(j) -> GetName().data()),"",
00836 fNbins, hmin1, hmax1,
00837 fNbins, hmin2, hmax2);
00838
00839 fHProb2D.push_back(h2);
00840 }
00841
00842
00843 int nh2d = fHProb2D.size();
00844
00845 BCLog::Out(BCLog::detail, BCLog::detail,
00846 Form(" --> Marginalizing %d 1D distributions and %d 2D distributions.", fNvar, nh2d));
00847
00848
00849 double dx = 0.0;
00850 double dy = 0.0;
00851
00852 if (fFitFunctionIndexX >= 0)
00853 {
00854 dx = (fDataPointUpperBoundaries -> GetValue(fFitFunctionIndexX) -
00855 fDataPointLowerBoundaries -> GetValue(fFitFunctionIndexX))
00856 / double(fErrorBandNbinsX);
00857
00858 dx = (fDataPointUpperBoundaries -> GetValue(fFitFunctionIndexY) -
00859 fDataPointLowerBoundaries -> GetValue(fFitFunctionIndexY))
00860 / double(fErrorBandNbinsY);
00861
00862 fErrorBandXY = new TH2D(
00863 TString::Format("errorbandxy_%d",BCLog::GetHIndex()), "",
00864 fErrorBandNbinsX,
00865 fDataPointLowerBoundaries -> GetValue(fFitFunctionIndexX) - 0.5 * dx,
00866 fDataPointUpperBoundaries -> GetValue(fFitFunctionIndexX) + 0.5 * dx,
00867 fErrorBandNbinsY,
00868 fDataPointLowerBoundaries -> GetValue(fFitFunctionIndexY) - 0.5 * dy,
00869 fDataPointUpperBoundaries -> GetValue(fFitFunctionIndexY) + 0.5 * dy);
00870 fErrorBandXY -> SetStats(kFALSE);
00871
00872 for (int ix = 1; ix <= fErrorBandNbinsX; ++ix)
00873 for (int iy = 1; iy <= fErrorBandNbinsX; ++iy)
00874 fErrorBandXY -> SetBinContent(ix, iy, 0.0);
00875 }
00876
00877
00878 std::vector <double> randx;
00879
00880 randx.assign(fNvar, 0.0);
00881 InitMetro();
00882
00883
00884 fNacceptedMCMC = 0;
00885
00886
00887 for(int i=0;i<=niter;i++)
00888 {
00889 GetRandomPointMetro(randx);
00890
00891
00892 if (fFlagWriteMarkovChain)
00893 {
00894 fMCMCIteration = i;
00895 fMarkovChainTree -> Fill();
00896 }
00897
00898 for(int j=0;j<fNvar;j++)
00899 fHProb1D[j] -> Fill( randx[j] );
00900
00901 int ih=0;
00902 for(int j=0;j<fNvar-1;j++)
00903 for(int k=j+1;k<fNvar;k++)
00904 {
00905 fHProb2D[ih] -> Fill(randx[j],randx[k]);
00906 ih++;
00907 }
00908
00909 if((i+1)%100000==0)
00910 BCLog::Out(BCLog::debug, BCLog::debug,
00911 Form("BCIntegrate::MarginalizeAllByMetro. %d samples done.",i+1));
00912
00913
00914
00915 if (fFitFunctionIndexX >= 0)
00916 {
00917
00918
00919
00920 if (fErrorBandContinuous)
00921 {
00922 double x = 0;
00923
00924 for (int ix = 0; ix < fErrorBandNbinsX; ix++)
00925 {
00926
00927
00928 x = fErrorBandXY -> GetXaxis() -> GetBinCenter(ix + 1);
00929
00930
00931
00932 std::vector <double> xvec;
00933 xvec.push_back(x);
00934
00935 double y = this -> FitFunction(xvec, randx);
00936
00937 xvec.clear();
00938
00939
00940
00941 fErrorBandXY -> Fill(x, y);
00942 }
00943 }
00944
00945
00946
00947 else
00948 {
00949
00950 int ndatapoints = int(fErrorBandX.size());
00951
00952 double x = 0;
00953
00954 for (int ix = 0; ix < ndatapoints; ++ix)
00955 {
00956
00957
00958 x = fErrorBandX.at(ix);
00959
00960
00961
00962 std::vector <double> xvec;
00963 xvec.push_back(x);
00964
00965 double y = this -> FitFunction(xvec, randx);
00966
00967 xvec.clear();
00968
00969
00970
00971 fErrorBandXY -> Fill(x, y);
00972 }
00973
00974 }
00975 }
00976 }
00977
00978
00979
00980 for(int i=0;i<fNvar;i++)
00981 fHProb1D[i] -> Scale( 1./fHProb1D[i]->Integral("width") );
00982
00983 for (int i=0;i<nh2d;i++)
00984 fHProb2D[i] -> Scale( 1./fHProb2D[i]->Integral("width") );
00985
00986 if (fFitFunctionIndexX >= 0)
00987 fErrorBandXY -> Scale(1.0/fErrorBandXY -> Integral() * fErrorBandXY -> GetNbinsX());
00988
00989 if (fFitFunctionIndexX >= 0)
00990 {
00991 for (int ix = 1; ix <= fErrorBandNbinsX; ix++)
00992 {
00993 double sum = 0;
00994
00995 for (int iy = 1; iy <= fErrorBandNbinsY; iy++)
00996 sum += fErrorBandXY -> GetBinContent(ix, iy);
00997
00998 for (int iy = 1; iy <= fErrorBandNbinsY; iy++)
00999 {
01000 double newvalue = fErrorBandXY -> GetBinContent(ix, iy) / sum;
01001 fErrorBandXY -> SetBinContent(ix, iy, newvalue);
01002 }
01003 }
01004 }
01005
01006 BCLog::Out(BCLog::detail, BCLog::detail,
01007 Form("BCIntegrate::MarginalizeAllByMetro done with %i trials and %i accepted trials. Efficiency is %f",fNmetro, fNacceptedMCMC, double(fNacceptedMCMC)/double(fNmetro)));
01008
01009 return fNvar+nh2d;
01010
01011 }
01012
01013
01014 TH1D * BCIntegrate::GetH1D(int parIndex)
01015 {
01016 if(fHProb1D.size()==0)
01017 {
01018 BCLog::Out(BCLog::warning, BCLog::warning,
01019 "BCModel::GetH1D. MarginalizeAll() has to be run prior to this to fill the distributions.");
01020 return 0;
01021 }
01022
01023 if(parIndex<0 || parIndex>fNvar)
01024 {
01025 BCLog::Out(BCLog::warning, BCLog::warning,
01026 Form("BCIntegrate::GetH1D. Parameter index %d is invalid.",parIndex));
01027 return 0;
01028 }
01029
01030 return fHProb1D[parIndex];
01031 }
01032
01033
01034 int BCIntegrate::GetH2DIndex(int parIndex1, int parIndex2)
01035 {
01036 if(parIndex1>fNvar-1 || parIndex1<0)
01037 {
01038 BCLog::Out(BCLog::warning, BCLog::warning,
01039 Form("BCIntegrate::GetH2DIndex. Parameter index %d is invalid", parIndex1));
01040 return -1;
01041 }
01042
01043 if(parIndex2>fNvar-1 || parIndex2<0)
01044 {
01045 BCLog::Out(BCLog::warning, BCLog::warning,
01046 Form("BCIntegrate::GetH2DIndex. Parameter index %d is invalid", parIndex2));
01047 return -1;
01048 }
01049
01050 if(parIndex1==parIndex2)
01051 {
01052 BCLog::Out(BCLog::warning, BCLog::warning,
01053 Form("BCIntegrate::GetH2DIndex. Parameters have equal indeces: %d , %d", parIndex1, parIndex2));
01054 return -1;
01055 }
01056
01057 if(parIndex1>parIndex2)
01058 {
01059 BCLog::Out(BCLog::warning, BCLog::warning,
01060 "BCIntegrate::GetH2DIndex. First parameters must be smaller than second (sorry).");
01061 return -1;
01062 }
01063
01064 int index=0;
01065 for(int i=0;i<fNvar-1;i++)
01066 for(int j=i+1;j<fNvar;j++)
01067 {
01068 if(i==parIndex1 && j==parIndex2)
01069 return index;
01070 index++;
01071 }
01072
01073 BCLog::Out(BCLog::warning, BCLog::warning,
01074 "BCIntegrate::GetH2DIndex. Invalid index combination.");
01075
01076 return -1;
01077 }
01078
01079
01080 TH2D * BCIntegrate::GetH2D(int parIndex1, int parIndex2)
01081 {
01082 if(fHProb2D.size()==0)
01083 {
01084 BCLog::Out(BCLog::warning, BCLog::warning,
01085 "BCModel::GetH2D. MarginalizeAll() has to be run prior to this to fill the distributions.");
01086 return 0;
01087 }
01088
01089 int hindex = this -> GetH2DIndex(parIndex1, parIndex2);
01090 if(hindex==-1)
01091 return 0;
01092
01093 if(hindex>(int)fHProb2D.size()-1)
01094 {
01095 BCLog::Out(BCLog::warning, BCLog::warning,
01096 "BCIntegrate::GetH2D. Got invalid index from GetH2DIndex(). Something went wrong.");
01097 return 0;
01098 }
01099
01100 return fHProb2D[hindex];
01101 }
01102
01103
01104 double BCIntegrate::GetRandomPoint(std::vector <double> &x)
01105 {
01106 this->GetRandomVector(x);
01107
01108 for(int i=0;i<fNvar;i++)
01109 x[i]=fMin[i]+x[i]*(fMax[i]-fMin[i]);
01110
01111 return this->Eval(x);
01112 }
01113
01114
01115 double BCIntegrate::GetRandomPointImportance(std::vector <double> &x)
01116 {
01117 double p = 1.1;
01118 double g = 1.0;
01119
01120 while (p>g)
01121 {
01122 this->GetRandomVector(x);
01123
01124 for(int i=0;i<fNvar;i++)
01125 x[i] = fMin[i] + x[i] * (fMax[i]-fMin[i]);
01126
01127 p = fRandom->Rndm();
01128
01129 g = this -> EvalSampling(x);
01130 }
01131
01132 return this->Eval(x);
01133 }
01134
01135
01136 void BCIntegrate::InitMetro()
01137 {
01138 fNmetro=0;
01139
01140 if (fXmetro0.size() <= 0)
01141 {
01142
01143 for(int i=0;i<fNvar;i++)
01144 fXmetro0.push_back((fMin[i]+fMax[i])/2.0);
01145 }
01146
01147 fMarkovChainValue = this -> LogEval(fXmetro0);
01148
01149
01150 std::vector <double> x;
01151 x.assign(fNvar,0.);
01152
01153 for(int i=0;i<1000;i++)
01154 GetRandomPointMetro(x);
01155
01156 fNmetro = 0;
01157
01158 }
01159
01160
01161 void BCIntegrate::GetRandomPointMetro(std::vector <double> &x)
01162 {
01163
01164 this->GetRandomVectorMetro(fXmetro1);
01165
01166
01167 int in=1;
01168 for(int i=0;i<fNvar;i++)
01169 {
01170 fXmetro1[i] = fXmetro0[i] + fXmetro1[i] * (fMax[i]-fMin[i]);
01171
01172
01173 if( fXmetro1[i]<fMin[i] || fXmetro1[i]>fMax[i] )
01174 in=0;
01175 }
01176
01177
01178
01179 double p0 = fMarkovChainValue;
01180 double p1 = 0;
01181 int accept=0;
01182
01183 if(in)
01184 {
01185 p1 = this -> LogEval(fXmetro1);
01186
01187 if(p1>=p0)
01188 accept=1;
01189 else
01190 {
01191 double r=log(fRandom->Rndm());
01192 if(r<p1-p0)
01193 accept=1;
01194 }
01195 }
01196
01197
01198 if(accept)
01199 {
01200
01201 fNacceptedMCMC++;
01202
01203 for(int i=0;i<fNvar;i++)
01204 {
01205 fXmetro0[i]=fXmetro1[i];
01206 x[i]=fXmetro1[i];
01207 fMarkovChainValue = p1;
01208 }
01209
01210 }
01211 else
01212 for(int i=0;i<fNvar;i++)
01213 {
01214 x[i]=fXmetro0[i];
01215 fXmetro1[i] = x[i];
01216 fMarkovChainValue = p0;
01217 }
01218
01219 fNmetro++;
01220
01221 }
01222
01223
01224 void BCIntegrate::GetRandomPointSamplingMetro(std::vector <double> &x)
01225 {
01226
01227 this->GetRandomVectorMetro(fXmetro1);
01228
01229
01230 int in=1;
01231 for(int i=0;i<fNvar;i++)
01232 {
01233 fXmetro1[i] = fXmetro0[i] + fXmetro1[i] * (fMax[i]-fMin[i]);
01234
01235
01236 if( fXmetro1[i]<fMin[i] || fXmetro1[i]>fMax[i] )
01237 in=0;
01238 }
01239
01240
01241 double p0 = this -> LogEvalSampling(fXmetro0);
01242 double p1=0;
01243 if(in)
01244 p1= this -> LogEvalSampling(fXmetro1);
01245
01246
01247 int accept=0;
01248 if(in)
01249 {
01250 if(p1>=p0)
01251 accept=1;
01252 else
01253 {
01254 double r=log(fRandom->Rndm());
01255 if(r<p1-p0)
01256 accept=1;
01257 }
01258 }
01259
01260
01261 if(accept)
01262 for(int i=0;i<fNvar;i++)
01263 {
01264 fXmetro0[i]=fXmetro1[i];
01265 x[i]=fXmetro1[i];
01266 }
01267 else
01268 for(int i=0;i<fNvar;i++)
01269 x[i]=fXmetro0[i];
01270
01271 fNmetro++;
01272 }
01273
01274
01275 void BCIntegrate::GetRandomVector(std::vector <double> &x)
01276 {
01277 double * randx = new double[fNvar];
01278
01279 fRandom -> RndmArray(fNvar, randx);
01280
01281 for(int i=0;i<fNvar;i++)
01282 x[i] = randx[i];
01283
01284 delete[] randx;
01285 randx = 0;
01286 }
01287
01288
01289 void BCIntegrate::GetRandomVectorMetro(std::vector <double> &x)
01290 {
01291 double * randx = new double[fNvar];
01292
01293 fRandom -> RndmArray(fNvar, randx);
01294
01295 for(int i=0;i<fNvar;i++)
01296 x[i] = 2.0 * (randx[i] - 0.5) * fMarkovChainStepSize;
01297
01298 delete[] randx;
01299 randx = 0;
01300 }
01301
01302
01303 TMinuit * BCIntegrate::GetMinuit()
01304 {
01305
01306 if (!fMinuit)
01307 fMinuit = new TMinuit();
01308
01309 return fMinuit;
01310
01311 }
01312
01313
01314
01315 void BCIntegrate::FindModeMinuit(std::vector<double> start, int printlevel)
01316 {
01317 bool have_start = true;
01318
01319
01320 if (int(start.size()) != fNvar)
01321 have_start = false;
01322
01323
01324 global_this = this;
01325
01326
01327 if (fMinuit)
01328 delete fMinuit;
01329 fMinuit = new TMinuit(fNvar);
01330
01331
01332 fMinuit -> SetFCN(&BCIntegrate::FCNLikelihood);
01333
01334
01335 fMinuit -> SetPrintLevel(printlevel);
01336
01337
01338 int flag;
01339 for (int i = 0; i < fNvar; i++)
01340 {
01341 double starting_point = (fMin[i]+fMax[i])/2.;
01342 if(have_start)
01343 starting_point = start[i];
01344 fMinuit -> mnparm(i,
01345 fx -> at(i) -> GetName().data(),
01346 starting_point,
01347 (fMax[i]-fMin[i])/100.0,
01348 fMin[i],
01349 fMax[i],
01350 flag);
01351 }
01352
01353
01354 fMinuit -> mnexcm("MIGRAD", fMinuitArglist, 2, flag);
01355
01356
01357 fMinuitErrorFlag = flag;
01358
01359
01360 fBestFitParameters.clear();
01361
01362 for (int i = 0; i < fNvar; i++)
01363 {
01364 double par;
01365 double parerr;
01366 fMinuit -> GetParameter(i, par, parerr);
01367 fBestFitParameters.push_back(par);
01368 }
01369
01370
01371 delete fMinuit;
01372 fMinuit = 0;
01373
01374 return;
01375 }
01376
01377
01378
01379 void BCIntegrate::SetMode(std::vector <double> mode)
01380 {
01381 if((int)mode.size() == fNvar)
01382 {
01383 fBestFitParameters.clear();
01384 for (int i = 0; i < fNvar; i++)
01385 fBestFitParameters.push_back(mode[i]);
01386 }
01387 }
01388
01389
01390
01391 void BCIntegrate::FCNLikelihood(int &npar, double * grad, double &fval, double * par, int flag)
01392 {
01393
01394
01395 std::vector <double> parameters;
01396
01397 int n = global_this -> GetNvar();
01398
01399 for (int i = 0; i < n; i++)
01400 parameters.push_back(par[i]);
01401
01402 fval = - global_this -> LogEval(parameters);
01403
01404
01405
01406 parameters.clear();
01407
01408 }
01409
01410
01411
01412
01413 void BCIntegrate::FindModeMCMC()
01414 {
01415
01416
01417
01418
01419
01420
01421
01422 double probmax = (this -> MCMCGetMaximumLogProb()).at(0);
01423 fBestFitParameters = this -> MCMCGetMaximumPoint(0);
01424
01425
01426 for (int i = 1; i < fMCMCNChains; ++i)
01427 {
01428 double prob = (this -> MCMCGetMaximumLogProb()).at(i);
01429
01430
01431 if (prob > probmax)
01432 {
01433 probmax = prob;
01434
01435 fBestFitParameters.clear();
01436
01437 fBestFitParameters = this -> MCMCGetMaximumPoint(i);
01438 }
01439 }
01440
01441 }
01442
01443
01444 void BCIntegrate::CubaIntegrand(const int *ndim, const double xx[],
01445 const int *ncomp, double ff[])
01446 {
01447 #ifdef HAVE_CUBA_H
01448
01449 double jacobian = 1.0;
01450
01451 std::vector<double> scaled_parameters;
01452
01453 for (int i = 0; i < *ndim; i++)
01454 {
01455 double range = global_this -> fx -> at(i) -> GetUpperLimit() - global_this -> fx -> at(i) -> GetLowerLimit();
01456
01457
01458 jacobian *= range;
01459
01460
01461 scaled_parameters.push_back(global_this -> fx -> at(i) -> GetLowerLimit() + xx[i] * range);
01462 }
01463
01464
01465 ff[0] = global_this -> Eval(scaled_parameters);
01466
01467
01468 ff[0] *= jacobian;
01469
01470
01471 ff[0] *= 1e99;
01472
01473
01474 scaled_parameters.clear();
01475 #else
01476 BCLog::Out(BCLog::error,BCLog::error,"!!! This version of BAT is compiled without Cuba.");
01477 BCLog::Out(BCLog::error,BCLog::error," Use other integration methods or install Cuba and recompile BAT.");
01478 #endif
01479 }
01480
01481
01482 double BCIntegrate::CubaIntegrate()
01483 {
01484 #ifdef HAVE_CUBA_H
01485 double EPSREL = 1e-3;
01486 double EPSABS = 1e-12;
01487 double VERBOSE = 0;
01488 double MINEVAL = 0;
01489 double MAXEVAL = 2000000;
01490 double NSTART = 25000;
01491 double NINCREASE = 25000;
01492
01493 std::vector<double> parameters_double;
01494 std::vector<double> parameters_int;
01495
01496 parameters_double.push_back(EPSREL);
01497 parameters_double.push_back(EPSABS);
01498
01499 parameters_int.push_back(VERBOSE);
01500 parameters_int.push_back(MINEVAL);
01501 parameters_int.push_back(MAXEVAL);
01502 parameters_int.push_back(NSTART);
01503 parameters_int.push_back(NINCREASE);
01504
01505
01506 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Running Cuba/Vegas integation over %i dimensions.", fNvar));
01507 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Maximum number of iterations: %i", (int)MAXEVAL));
01508 BCLog::Out(BCLog::detail, BCLog::detail, Form(" --> Aimed relative precision: %e", EPSREL));
01509
01510 return this -> CubaIntegrate(0, parameters_double, parameters_int);
01511 #else
01512 BCLog::Out(BCLog::error,BCLog::error,"!!! This version of BAT is compiled without Cuba.");
01513 BCLog::Out(BCLog::error,BCLog::error," Use other integration methods or install Cuba and recompile BAT.");
01514 return 0.;
01515 #endif
01516 }
01517
01518
01519 double BCIntegrate::CubaIntegrate(int method, std::vector<double> parameters_double, std::vector<double> parameters_int)
01520 {
01521 #ifdef HAVE_CUBA_H
01522 const int NDIM = int(fx ->size());
01523 const int NCOMP = 1;
01524
01525 const double EPSREL = parameters_double[0];
01526 const double EPSABS = parameters_double[1];
01527 const int VERBOSE = int(parameters_int[0]);
01528 const int MINEVAL = int(parameters_int[1]);
01529 const int MAXEVAL = int(parameters_int[2]);
01530
01531 int neval;
01532 int fail;
01533 int nregions;
01534 double integral[NCOMP];
01535 double error[NCOMP];
01536 double prob[NCOMP];
01537
01538 global_this = this;
01539
01540 integrand_t an_integrand = &BCIntegrate::CubaIntegrand;
01541
01542 if (method == 0)
01543 {
01544
01545 const int NSTART = int(parameters_int[3]);
01546 const int NINCREASE = int(parameters_int[4]);
01547
01548
01549 Vegas(NDIM, NCOMP, an_integrand,
01550 EPSREL, EPSABS, VERBOSE, MINEVAL, MAXEVAL,
01551 NSTART, NINCREASE,
01552 &neval, &fail, integral, error, prob);
01553 }
01554 else if (method == 1)
01555 {
01556
01557 const int LAST = int(parameters_int[3]);
01558 const int NNEW = int(parameters_int[4]);
01559 const int FLATNESS = int(parameters_int[5]);
01560
01561
01562 Suave(NDIM, NCOMP, an_integrand,
01563 EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
01564 NNEW, FLATNESS,
01565 &nregions, &neval, &fail, integral, error, prob);
01566 }
01567 else if (method == 2)
01568 {
01569
01570 const int KEY1 = int(parameters_int[3]);
01571 const int KEY2 = int(parameters_int[4]);
01572 const int KEY3 = int(parameters_int[5]);
01573 const int MAXPASS = int(parameters_int[6]);
01574 const int BORDER = int(parameters_int[7]);
01575 const int MAXCHISQ = int(parameters_int[8]);
01576 const int MINDEVIATION = int(parameters_int[9]);
01577 const int NGIVEN = int(parameters_int[10]);
01578 const int LDXGIVEN = int(parameters_int[11]);
01579 const int NEXTRA = int(parameters_int[12]);
01580
01581
01582 Divonne(NDIM, NCOMP, an_integrand,
01583 EPSREL, EPSABS, VERBOSE, MINEVAL, MAXEVAL,
01584 KEY1, KEY2, KEY3, MAXPASS, BORDER, MAXCHISQ, MINDEVIATION,
01585 NGIVEN, LDXGIVEN, NULL, NEXTRA, NULL,
01586 &nregions, &neval, &fail, integral, error, prob);
01587 }
01588 else if (method == 3)
01589 {
01590
01591 const int LAST = int(parameters_int[3]);
01592 const int KEY = int(parameters_int[4]);
01593
01594
01595 Cuhre(NDIM, NCOMP, an_integrand,
01596 EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL, KEY,
01597 &nregions, &neval, &fail, integral, error, prob);
01598 }
01599 else
01600 {
01601 std::cout << " Integration method not available. " << std::endl;
01602 integral[0] = -1e99;
01603 }
01604
01605 if (fail != 0)
01606 {
01607 std::cout << " Warning, integral did not converge with the given set of parameters. "<< std::endl;
01608 std::cout << " neval = " << neval << std::endl;
01609 std::cout << " fail = " << fail << std::endl;
01610 std::cout << " integral = " << integral[0] << std::endl;
01611 std::cout << " error = " << error[0] << std::endl;
01612 std::cout << " prob = " << prob[0] << std::endl;
01613 }
01614
01615 return integral[0] / 1e99;
01616 #else
01617 BCLog::Out(BCLog::error,BCLog::error,"!!! This version of BAT is compiled without Cuba.");
01618 BCLog::Out(BCLog::error,BCLog::error," Use other integration methods or install Cuba and recompile BAT.");
01619 return 0.;
01620 #endif
01621 }
01622
01623
01624 void BCIntegrate::MCMCIterationInterface()
01625 {
01626
01627
01628
01629
01630 this -> MCMCFillErrorBand();
01631
01632
01633 this -> MCMCUserIterationInterface();
01634 }
01635
01636
01637 void BCIntegrate::MCMCFillErrorBand()
01638 {
01639 if (!fFillErrorBand)
01640 return;
01641
01642
01643 if (fFitFunctionIndexX < 0)
01644 return;
01645
01646
01647 if (fErrorBandContinuous)
01648 {
01649 double x = 0;
01650 for (int ix = 0; ix < fErrorBandNbinsX; ix++)
01651 {
01652
01653 x = fErrorBandXY -> GetXaxis() -> GetBinCenter(ix + 1);
01654
01655
01656 std::vector <double> xvec;
01657 xvec.push_back(x);
01658
01659
01660 for (int ichain = 0; ichain < this -> MCMCGetNChains(); ++ichain)
01661 {
01662
01663 double y = this -> FitFunction(xvec, this -> MCMCGetx(ichain));
01664
01665
01666 fErrorBandXY -> Fill(x, y);
01667 }
01668
01669 xvec.clear();
01670 }
01671 }
01672
01673 else
01674 {
01675 int ndatapoints = int(fErrorBandX.size());
01676 double x = 0;
01677
01678 for (int ix = 0; ix < ndatapoints; ++ix)
01679 {
01680
01681 x = fErrorBandX.at(ix);
01682
01683
01684 std::vector <double> xvec;
01685 xvec.push_back(x);
01686
01687
01688 for (int ichain = 0; ichain < this -> MCMCGetNChains(); ++ichain)
01689 {
01690
01691 double y = this -> FitFunction(xvec, this -> MCMCGetx(ichain));
01692
01693
01694 fErrorBandXY -> Fill(x, y);
01695 }
01696
01697 xvec.clear();
01698 }
01699 }
01700 }
01701
01702
01703