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