BAT  0.9.4
The Bayesian analysis toolkit
 All Classes Namespaces Functions Variables Enumerations
BCRooInterface.cxx
1 #include "BCRooInterface.h"
2 #include "../../BAT/BCMath.h"
3 #include "../../BAT/BCParameter.h"
4 
5 #include <RooGlobalFunc.h>
6 #include <RooMsgService.h>
7 #include <RooProdPdf.h>
8 #include <RooUniform.h>
9 #include <RooWorkspace.h>
10 #include <TFile.h>
11 
12 //for testing
13 #include "RooRealVar.h"
14 #include "RooAbsReal.h"
15 #include "RooRandom.h"
16 
17 #include <iostream>
18 
19 // ---------------------------------------------------------
20 void BCRooInterface::Initialize( RooAbsData& data,
21  RooAbsPdf& model,
22  RooAbsPdf& prior_trans,
23  const RooArgSet* params,
24  const RooArgSet& listPOI )
25 {
26 
27  fData = &data;
28  fModel = &model;
29 
30  // make the product of both priors to get the full prior probability function
31  RooAbsPdf* prior_total = &prior_trans;
32  if (prior_total!=0 ) {
33  fPrior = prior_total;
34  }
35  else {
36  std::cout << "No prior PDF: without taking action the program would crash\n";
37  std::cout << "No prior PDF: adding dummy uniform pdf on the interval [0..1]\n";
38  priorhelpvar = new RooRealVar("priorhelpvar","",0.0, 1.0 );
39  _addeddummyprior = true;
40  RooUniform* priorhelpdist = new RooUniform("priorhelpdist","", *priorhelpvar);
41  fPrior = priorhelpdist;
42  }
43 
44  std::cout << "Imported parameters:\n";
45  fParams = new RooArgList(listPOI);
46  const RooArgSet* paramsTmp = params;
47  if (paramsTmp!=0)
48  fParams->add(*paramsTmp);
49  fParams->Print("v");
50 
51  fParamsPOI = new RooArgList(listPOI);
52  // create the log-likelihood function
53  // fNll = new RooNLLVar("fNll","",*fModel,*fData,true/*extended*/);
54 
55  RooArgSet* constrainedParams = fModel->getParameters(*fData);
56  fNll = fModel->createNLL(*fData, RooFit::Constrain(*constrainedParams) );
57 
59 
60  if(_fillChain) {
62  }
63 }
64 
65 // ---------------------------------------------------------
66 
67 void BCRooInterface::Initialize( const char* rootFile,
68  const char* wsName,
69  const char* dataName,
70  const char* modelName,
71  const char* priorName,
72  const char* priorNuisanceName,
73  const char* paramsName,
74  const char* listPOIName )
75 {
76  // retrieve the RooFit inputs from the ROOT file
77 
78  /*
79  // hard coded names in the workspace
80  char* rootFile = "bat_workspace.root";
81  char* wsName= "batWS";
82  char* dataName= "data";
83  char* modelName= "model";
84  char* priorName= "priorPOI";
85  char* priorNuisanceName= "priorNuisance";
86  char* paramsName= "parameters";
87  char* listPOIName= "POI";
88  */
89 
90  std::cout << "Opening " << rootFile << std::endl;
91  TFile* file = TFile::Open(rootFile);
92  std::cout << "content :\n";
93  file->ls();
94 
95  RooWorkspace* bat_ws = (RooWorkspace*) file->Get(wsName);
96  bat_ws->Print("v");
97 
98  fData = (RooAbsData*) bat_ws->data(dataName);
99  fModel = (RooAbsPdf*) bat_ws->function(modelName);
100 
101  // make the product of both priors to get the full prior probability function
102  RooAbsPdf* priorPOI = (RooAbsPdf*) bat_ws->function(priorName);
103  RooAbsPdf* priorNuisance = (RooAbsPdf*) bat_ws->pdf(priorNuisanceName);
104  if (priorNuisance!=0 && priorPOI!=0) {
105  fPrior = new RooProdPdf("fPrior","complete prior",*priorPOI,*priorNuisance);
106  }
107  else {
108  if ( priorNuisance!=0 )
109  fPrior=priorNuisance;
110  else if ( priorPOI!=0 )
111  fPrior = priorPOI;
112  else{
113  std::cout << "No prior PDF: without taking action the program would crash\n";
114  std::cout << "No prior PDF: adding dummy uniform pdf on the interval [0..1]\n";
115  priorhelpvar = new RooRealVar("priorhelpvar","",0.0, 1.0 );
116  _addeddummyprior = true;
117  RooUniform* priorhelpdist = new RooUniform("priorhelpdist","", *priorhelpvar);
118  fPrior = priorhelpdist;
119  }
120  }
121 
122  std::cout << "Imported parameters:\n";
123  fParams = new RooArgList(*(bat_ws->set(listPOIName)));
124  RooArgSet* paramsTmp = (RooArgSet*) bat_ws->set(paramsName);
125  if (paramsTmp!=0) {
126  fParams->add(*paramsTmp);
127  }
128  if (_addeddummyprior == true ) {
129  fParams->add(*priorhelpvar);
130  }
131  fParams->Print("v");
132 
133  // create the log-likelihood function
134  //fNll = new RooNLLVar("fNll","",*fModel,*fData,true/*extended*/);
135  RooArgSet* constrainedParams = fModel->getParameters(*fData);
136  fNll = fModel->createNLL(*fData, RooFit::Constrain(*constrainedParams) );
137 
138  file->Close();
139 
141 }
142 
143 // ---------------------------------------------------------
144 BCRooInterface::BCRooInterface(const char* name, bool fillChain) :
145  BCModel(name),
146  fData(NULL),
147  fModel(NULL),
148  fNll(NULL),
149  fObservables(NULL),
150  fParams(NULL),
151  fParamsPOI(NULL),
152  fPrior(NULL),
153  _default_nbins(150),
154  priorhelpvar(NULL),
155  _addeddummyprior(false),
156  _fillChain(fillChain),
157  fFirstComparison(false),
158  _roostatsMarkovChain(NULL)
159 {
160  // todo this interface not ready for grid marginalization yet
161  SetMarginalizationMethod(BCIntegrate::kMargMetropolis);
162 }
163 
164 // ---------------------------------------------------------
165 BCRooInterface::~BCRooInterface()
166 { // default destructor
167  if(_fillChain) {
168  delete _roostatsMarkovChain;
169  }
170 }
171 
172 // ---------------------------------------------------------
174 { // define for BAT the list of parameters, range and plot binning
175 
176  int nParams = fParams->getSize();
177  for (int iParam=0; iParam<nParams; iParam++) {
178  RooRealVar* ipar = (RooRealVar*) fParams->at(iParam);
179  BCParameter * bcpar = new BCParameter(ipar->GetName(),ipar->getMin(),ipar->getMax());
180  bcpar->SetNbins(_default_nbins);
181  this->AddParameter(bcpar);
182  std::cout << "added parameter: " << bcpar->GetName() << " defined in range [ " << bcpar->GetLowerLimit() << " - "
183  << bcpar->GetUpperLimit() << " ] with number of bins: " << bcpar->GetNbins() << " \n";
184  }
185 
186  for(std::list< std::pair<const char*,int> >::iterator listiter = _nbins_list.begin(); listiter != _nbins_list.end(); listiter++) {
187  GetParameter((*listiter).first)->SetNbins((*listiter).second);
188  std::cout << "adjusted parameter: " << (*listiter).first << " to number of bins: " << (*listiter).second << " \n";
189  }
190 }
191 
192 // ---------------------------------------------------------
193 double BCRooInterface::LogLikelihood(const std::vector<double> & parameters)
194 { // this methods returns the logarithm of the conditional probability: p(data|parameters)
195 
196  // retrieve the values of the parameters to be tested
197  int nParams = fParams->getSize();
198  for (int iParam=0; iParam<nParams; iParam++) {
199  RooRealVar* ipar = (RooRealVar*) fParams->at(iParam);
200  ipar->setVal(parameters.at(iParam));
201  }
202 
203  // compute the log of the likelihood function
204  double logprob = -fNll->getVal();
205  return logprob;
206 }
207 
208 // ---------------------------------------------------------
209 double BCRooInterface::LogAPrioriProbability(const std::vector<double> & parameters)
210 { // this method returs the logarithm of the prior probability for the parameters: p(parameters).
211  // retrieve the values of the parameters to be tested
212  int nParams = fParams->getSize();
213  for (int iParam=0; iParam<nParams; iParam++) {
214  RooRealVar* ipar = (RooRealVar*) fParams->at(iParam);
215  ipar->setVal(parameters.at(iParam));
216  }
217  // compute the log of the prior function
218  RooArgSet* tmpArgSet = new RooArgSet(*fParams);
219  double prob = fPrior->getVal(tmpArgSet);
220  delete tmpArgSet;
221  if (prob<1e-300)
222  prob = 1e-300;
223  return log(prob);
224 }
225 
226 void BCRooInterface::SetNumBins(const char * parname, int nbins)
227 {
228  for(std::list< std::pair<const char*,int> >::iterator listiter = _nbins_list.begin(); listiter != _nbins_list.end(); listiter++) {
229  if(!strcmp((*listiter).first, parname)) {
230  (*listiter).second = nbins;
231  return;
232  }
233  }
234  _nbins_list.push_back( std::make_pair(parname,nbins) );
235 }
236 
238 {
239  _default_nbins = nbins;
240 }
241 
243 {
244  //RooArgSet * tempRooArgSetPointer = new RooArgSet(* fParams, "paramsMarkovChainPointer");
245  //_parametersForMarkovChain = RooArgSet(* fParams, "paramsMarkovChainPointer");
246  //fParams->snapshot(_parametersForMarkovChain);
247 
248  //store only POI in RooStats MarkovChain object
249  //_parametersForMarkovChainPrevious.add(*fParamsPOI);
250  //_parametersForMarkovChainCurrent.add(*fParamsPOI);
251 
252  _parametersForMarkovChainPrevious.add(*fParams);
253  _parametersForMarkovChainCurrent.add(*fParams);
254 
255  std::cout << "size of _parametersForMarkovChain: " << _parametersForMarkovChainCurrent.getSize() << std::endl;
256  std::cout << "size of fParamsPOI: " << fParamsPOI->getSize() << std::endl;
257  //std::cout << "size of tempRooArgSetPointer: " << tempRooArgSetPointer->getSize() << std::endl;
258 
259  _roostatsMarkovChain = new RooStats::MarkovChain();
260  //test stuff begin
261  //the following way of creating the MArkovChain object does not work!:
262  //_roostatsMarkovChain = new RooStats::MarkovChain(_parametersForMarkovChain);
263  //test stuff end
264  std::cout << "setting up parameters for RooStats markov chain" << std::endl;
265  _parametersForMarkovChainPrevious.writeToStream(std::cout, false);
266 
267  //initialize fPreviousStep, fCurrentStep, fVecWeights
268  int nchains = MCMCGetNChains();
269  for(int countChains = 1; countChains<=nchains ; countChains++ ) {
270  double tempweight = 1.0;
271  fVecWeights.push_back(tempweight);
272  std::vector<double> tempvec;
273  TIterator* setiter = fParamsPOI->createIterator();
274  double tempval = 0.;
275  while(setiter->Next()){
276  tempvec.push_back(tempval);
277  }
278  fPreviousStep.push_back(tempvec);
279  fCurrentStep.push_back(tempvec);
280  }
281 
282  fFirstComparison = true;
283 
284  //test stuff begin
285  //var1 = new RooRealVar("var1","var1", 10., 0., 100.);
286  //fParamsTest = new RooArgList();
287  //fParamsTest->add(*var1);
288  //_parametersForMarkovChain_test.add(*fParamsTest);
289  //fIterationInterfacecount = 0;
290  //test stuff end
291 }
292 
293 // to be added: add elements with higher weights if elements repeat to avoid unneccessarily long chains
295 {
296  //fIterationInterfacecount+=1;
297 
298  if(_fillChain) {
299  //std::cout << "Hei-ho running with fillChain!" << std::endl;
300  // get number of chains
301  int nchains = MCMCGetNChains();
302 
303  // get number of parameters
304  int npar = GetNParameters();
305  //std::cout << "number of parameters is: " << npar << std::endl;
306 
307  // loop over all chains and fill histogram
308  for (int i = 0; i < nchains; ++i) {
309  // get the current values of the parameters. These are
310  // stored in fMCMCx.
311 
312  // std::cout << "log(likelihood*prior)" << *GetMarkovChainValue() << std::endl; //does not work this way?!
313  TIterator* setiter = fParams->createIterator();
314  int j = 0;
315 
316  //store only POI in RooStats MarkovChain object
317  //TIterator* setiter = fParamsPOI->createIterator();
318  //int j = 0;
319 
320  while(setiter->Next()){
321 
322  //check parameter names
323  const BCParameter * tempBCparam = GetParameter(j);
324 
325  //_parametersForMarkovChainCurrent->Print();
326 
327  const char * paramnamepointer = (tempBCparam->GetName()).c_str();
328  double xij = fMCMCx.at(i * npar + j);
329  AddToCurrentChainElement(xij, i, j);
330  RooRealVar* parampointer = (RooRealVar*) &(_parametersForMarkovChainCurrent[paramnamepointer]);
331  parampointer->setVal(xij);
332  //std::cout << "Chain " << i << " param: " << tempBCparam->GetName() << " Value: " << xij << std::endl;
333  j++;
334  }
335 
336 
337  // will only work if _parametersForMarkovChain had correct info!
338 
339  //test stuff begin
340  //var1->setVal( RooRandom::randomGenerator()->Uniform(100.) );
341  //
342  //_roostatsMarkovChain->Add(_parametersForMarkovChain_test, 0.001, 1.0);
343  //
344  //test stuff end
345 
346  if( !(EqualsLastChainElement(i)) ) {
347  double weight = GetWeightForChain(i);
348  _roostatsMarkovChain->Add(_parametersForMarkovChainPrevious, -1.* MCMCGetLogProbx(j), weight);
349  _parametersForMarkovChainPrevious = _parametersForMarkovChainCurrent;
350  }
351  }
352  }
353 }
354 
355 void BCRooInterface::AddToCurrentChainElement(double xij, int chainNum, int poiNum)
356 {
357  fCurrentStep[chainNum][poiNum] = xij;
358 }
359 
360 bool BCRooInterface::EqualsLastChainElement(int chainNum)
361 {
362  bool equals = true;
363  std::vector<double>::iterator itPrevious = fPreviousStep[chainNum].begin();
364 
365  if(fFirstComparison == true) {
366  fFirstComparison = false;
367  _parametersForMarkovChainPrevious = _parametersForMarkovChainCurrent;
368  return true;
369  }
370 
371 
372  for (std::vector<double>::iterator itCurrent = fCurrentStep[chainNum].begin(); itCurrent != fCurrentStep[chainNum].end(); ++itCurrent) {
373  if(*itCurrent != *itPrevious) {
374  equals = false;
375  fPreviousStep[chainNum] = fCurrentStep[chainNum];
376  break;
377  }
378  ++itPrevious;
379  }
380 
381  if(equals == true) {
382  fVecWeights[chainNum] += 1.0;
383  }
384 
385  return equals;
386 
387 }
388 
389 double BCRooInterface::GetWeightForChain(int chainNum)
390 {
391  double retval = fVecWeights[chainNum];
392  fVecWeights[chainNum]= 1.0 ;
393  return retval;
394 }
395 
void SetupRooStatsMarkovChain()
setup RooStats Markov Chain
double GetLowerLimit() const
Definition: BCParameter.h:65
void MCMCIterationInterface()
overloaded function from BCIntegrate to fill RooStats Markov Chain with every accepted step ...
void SetNumBins(const char *parname, int nbins)
set the number of histogram bins for a specific parameter
The base class for all user-defined models.
Definition: BCModel.h:50
void DefineParameters()
Overloaded methods.
A class representing a parameter of a model.
Definition: BCParameter.h:28
double LogLikelihood(const std::vector< double > &parameters)
void Initialize(RooAbsData &data, RooAbsPdf &model, RooAbsPdf &prior, const RooArgSet *params, const RooArgSet &listPOI)
Other method of this class.
virtual int AddParameter(BCParameter *parameter)
Definition: BCModel.cxx:225
double LogAPrioriProbability(const std::vector< double > &parameters)
double GetUpperLimit() const
Definition: BCParameter.h:70
const std::string & GetName() const
Definition: BCParameter.h:54