BAT  0.9.4
The Bayesian analysis toolkit
 All Classes Namespaces Functions Variables Enumerations
BCModelManager.cxx
1 /*
2  * Copyright (C) 2007-2014, the BAT core developer team
3  * All rights reserved.
4  *
5  * For the licensing terms see doc/COPYING.
6  * For documentation see http://mpp.mpg.de/bat
7  */
8 
9 // ---------------------------------------------------------
10 
11 #include "BCModelManager.h"
12 
13 #include "BCDataPoint.h"
14 #include "BCLog.h"
15 
16 #include <TString.h>
17 
18 #include <fstream>
19 #include <iostream>
20 
21 // ---------------------------------------------------------
22 
24 {
25  fModelContainer = new BCModelContainer();
26  fDataSet = 0;
27 }
28 
29 // ---------------------------------------------------------
30 
32 {
33  delete fModelContainer;
34  delete fDataSet;
35 }
36 
37 // ---------------------------------------------------------
38 
40 {
41  modelmanager.Copy(*this);
42 }
43 
44 // ---------------------------------------------------------
45 
47 {
48  if (this != &modelmanager)
49  modelmanager.Copy(* this);
50 
51  return * this;
52 }
53 
54 // ---------------------------------------------------------
55 
57 {
58  // set data set
59  fDataSet = dataset;
60 
61  // set data set of all models in the manager
62  for (unsigned int i = 0; i < GetNModels(); i++)
63  GetModel(i)->SetDataSet(fDataSet);
64 }
65 
66 // ---------------------------------------------------------
67 
69 {
70  // create new data set consisting of a single data point
71  BCDataSet * dataset = new BCDataSet();
72 
73  // add the data point
74  dataset->AddDataPoint(datapoint);
75 
76  // set this new data set
77  SetDataSet(dataset);
78 }
79 
80 // ---------------------------------------------------------
81 
82 void BCModelManager::SetSingleDataPoint(BCDataSet * dataset, unsigned int index)
83 {
84  if (index > dataset->GetNDataPoints())
85  return;
86 
87  SetSingleDataPoint(dataset->GetDataPoint(index));
88 }
89 
90 // ---------------------------------------------------------
91 
92 void BCModelManager::AddModel(BCModel * model, double probability)
93 {
94  // set a priori probability of new model
95  model->SetModelAPrioriProbability(probability);
96 
97  // set data set
98  model->SetDataSet(fDataSet);
99 
100  // fill model into container
101  fModelContainer->push_back(model);
102 }
103 
104 // ---------------------------------------------------------
105 void BCModelManager::SetNIterationsMax(int niterations)
106 {
107  for (unsigned int i = 0; i < GetNModels(); i++)
108  GetModel(i)->SetNIterationsMax(niterations);
109 }
110 
111 // ---------------------------------------------------------
113 {
114  for (unsigned int i = 0; i < GetNModels(); i++)
115  GetModel(i)->SetNIterationsMin(niterations);
116 }
117 
118 // ---------------------------------------------------------
120 {
121  for (unsigned int i = 0; i < GetNModels(); i++)
122  GetModel(i)->SetNIterationsPrecisionCheck(niterations);
123 }
124 
125 // ---------------------------------------------------------
127 {
128  for (unsigned int i = 0; i < GetNModels(); i++)
129  GetModel(i)->SetNIterationsOutput(niterations);
130 }
131 
132 // ---------------------------------------------------------
133 
134 void BCModelManager::SetIntegrationMethod(BCIntegrate::BCIntegrationMethod method)
135 {
136  // set integration method for all models registered
137 
138  for (unsigned int i = 0; i < GetNModels(); i++)
139  GetModel(i)->SetIntegrationMethod(method);
140 }
141 
142 // ---------------------------------------------------------
143 
144 void BCModelManager::SetMarginalizationMethod(BCIntegrate::BCMarginalizationMethod method)
145 {
146  // set marginalization method for all models registered
147  for (unsigned int i = 0; i < GetNModels(); i++)
148  GetModel(i)->SetMarginalizationMethod(method);
149 }
150 
151 // ---------------------------------------------------------
152 
153 void BCModelManager::SetOptimizationMethod(BCIntegrate::BCOptimizationMethod method)
154 {
155  // set mode finding method for all models registered
156  for (unsigned int i = 0; i < GetNModels(); i++)
157  GetModel(i)->SetOptimizationMethod(method);
158 }
159 
160 // ---------------------------------------------------------
161 
162 void BCModelManager::SetRelativePrecision(double relprecision)
163 {
164  // set relative precision for all models registered
165  for (unsigned int i = 0; i < GetNModels(); i++)
166  GetModel(i)->SetRelativePrecision(relprecision);
167 }
168 
169 // ---------------------------------------------------------
170 
171 void BCModelManager::SetAbsolutePrecision(double absprecision)
172 {
173  // set absolute precision for all models registered
174  for (unsigned int i = 0; i < GetNModels(); i++)
175  GetModel(i)->SetAbsolutePrecision(absprecision);
176 }
177 
178 // ---------------------------------------------------------
179 
180 void BCModelManager::SetNbins(unsigned int n)
181 {
182  // set number of bins for all models registered
183  for (unsigned int i = 0; i < GetNModels(); i++)
184  GetModel(i)->SetNbins(n);
185 }
186 
187 // ---------------------------------------------------------
188 
190 {
191  // set lower boundary point for all models registered
192  for (unsigned int i = 0; i < GetNModels(); i++)
193  GetModel(i)->SetDataPointLowerBoundaries(datasetlowerboundaries);
194 }
195 
196 // ---------------------------------------------------------
197 
199 {
200  // set upper boundary point for all models registered
201  for (unsigned int i = 0; i < GetNModels(); i++)
202  GetModel(i)->SetDataPointUpperBoundaries(datasetupperboundaries);
203 }
204 
205 // ---------------------------------------------------------
206 
207 void BCModelManager::SetDataPointLowerBoundary(int index, double lowerboundary)
208 {
209  // set lower bounday values for all models registered
210  for (unsigned int i = 0; i < GetNModels(); i++)
211  GetModel(i)->SetDataPointLowerBoundary(index, lowerboundary);
212 }
213 
214 // ---------------------------------------------------------
215 
216 void BCModelManager::SetDataPointUpperBoundary(int index, double upperboundary)
217 {
218  // set upper boundary values for all models registered
219  for (unsigned int i = 0; i < GetNModels(); i++)
220  GetModel(i)->SetDataPointUpperBoundary(index, upperboundary);
221 }
222 
223 // ---------------------------------------------------------
224 
225 void BCModelManager::SetDataBoundaries(int index, double lowerboundary, double upperboundary)
226 {
227  // set lower and upper boundary values for all models registered
228  for (unsigned int i = 0; i < GetNModels(); i++)
229  GetModel(i)->SetDataBoundaries(index, lowerboundary, upperboundary);
230 }
231 
232 // ---------------------------------------------------------
233 void BCModelManager::SetNChains(unsigned int n)
234 {
235  // set number of Markov chains for all models registered
236  for (unsigned int i = 0; i < GetNModels(); i++)
237  GetModel(i)->MCMCSetNChains(n);
238 }
239 
240 // ---------------------------------------------------------
241 
242 int BCModelManager::ReadDataFromFileTree(const char * filename, const char * treename, const char * branchnames)
243 {
244  if (fModelContainer->size() == 0) {
245  BCLog::OutError("BCModelManager::ReadDataFromFileTree : No model defined.");
246  return -1;
247  }
248 
249  // create data set
250  if (!fDataSet)
251  fDataSet = new BCDataSet();
252  else
253  fDataSet->Reset();
254 
255  // read data from tree
256  int read_file = fDataSet->ReadDataFromFileTree(filename, treename, branchnames);
257 
258  if (read_file >=0) {
259  SetDataSet(fDataSet);
260 
261  for (unsigned int i = 0; i < GetNModels(); i++)
262  fModelContainer->at(i)->SetDataSet(fDataSet);
263  }
264  else if (read_file == -1) {
265  delete fDataSet;
266  return -1;
267  }
268 
269  return 0;
270 }
271 
272 // ---------------------------------------------------------
273 
274 int BCModelManager::ReadDataFromFileTxt(const char * filename, int nbranches)
275 {
276  if (fModelContainer->size() == 0) {
277  BCLog::OutError("BCModelManager::ReadDataFromFileTree. No model defined.");
278  return -1;
279  }
280 
281  // create data set
282  if (!fDataSet)
283  fDataSet = new BCDataSet();
284  else
285  fDataSet->Reset();
286 
287  // read data from txt file
288  int read_file = fDataSet->ReadDataFromFileTxt(filename, nbranches);
289 
290  if (read_file >=0) {
291  SetDataSet(fDataSet);
292 
293  for (unsigned int i = 0; i < GetNModels(); i++)
294  fModelContainer->at(i)->SetDataSet(fDataSet);
295  }
296  else {
297  delete fDataSet;
298  return -1;
299  }
300 
301  return 0;
302 }
303 
304 // ---------------------------------------------------------
305 
307 {
308  // initialize likelihood norm
309  double normalization = 0.0;
310 
311  BCLog::OutSummary("Running normalization of all models.");
312 
313  for (unsigned int i = 0; i < GetNModels(); i++) {
314  fModelContainer->at(i)->Integrate();
315 
316  // add to total normalization
317  normalization += (fModelContainer->at(i)->GetIntegral() * fModelContainer->at(i)->GetModelAPrioriProbability());
318  }
319 
320  // set model a posteriori probabilities
321  for (unsigned int i = 0; i < GetNModels(); i++)
322  fModelContainer->at(i)->SetModelAPosterioriProbability(
323  (fModelContainer->at(i)->GetIntegral() * fModelContainer->at(i)->GetModelAPrioriProbability()) /
324  normalization);
325 }
326 
327 // ---------------------------------------------------------
328 
329 double BCModelManager::BayesFactor(const unsigned int imodel1, const unsigned int imodel2)
330 {
331  // Bayes Factors are the likelihoods integrated over the parameters
332  // Is this equal to the posteriors?
333  // NOOOO
334  // But it is equal to normalization factors.
335 
336  const double norm1 = fModelContainer->at(imodel1)->GetIntegral();
337  const double norm2 = fModelContainer->at(imodel2)->GetIntegral();
338 
339  // check model 1
340  if(norm1<0.) {
341  BCLog::OutError(
342  Form("BCModelManager::BayesFactor : Model %s (index %d) not normalized. Cannot calculate Bayes factor.",
343  fModelContainer->at(imodel1)->GetName().data(),imodel1));
344  return -1.;
345  }
346 
347  // check model 2
348  if(norm2<0.) {
349  BCLog::OutError(
350  Form("BCModelManager::BayesFactor : Model %s (index %d) not normalized. Cannot calculate Bayes factor.",
351  fModelContainer->at(imodel2)->GetName().data(),imodel2));
352  return -1.;
353  }
354 
355  // denominator cannot be zero
356  if(norm2==0. && norm1!=0.) {// not good since norm2 is double !!!
357  BCLog::OutError(
358  Form("BCModelManager::BayesFactor : Model %s (index %d) has ZERO probability. Bayes factor is infinite.",
359  fModelContainer->at(imodel2)->GetName().data(),imodel2));
360  return -1.;
361  }
362 
363  // denominator cannot be zero unless also numerator is zero
364  if(norm2==0. && norm1==0.) {// not good since norm2 and norm1 are both double !!!
365  BCLog::OutWarning(
366  Form("BCModelManager::BayesFactor : Models %s and %s have ZERO probability. Bayes factor is unknown. Returning 1.",
367  fModelContainer->at(imodel2)->GetName().data(),fModelContainer->at(imodel1)->GetName().data()));
368  return 1.;
369  }
370 
371  // now calculate the factor
372  return norm1/norm2;
373 }
374 
375 // ---------------------------------------------------------
376 
378 {
379  // finds mode for all models registered
380  for (unsigned int i = 0; i < GetNModels(); i++)
381  GetModel(i)->FindMode();
382 }
383 
384 // ---------------------------------------------------------
385 
387 {
388  // marginalizes all models registered
389  for (unsigned int i = 0; i < GetNModels(); i++)
390  GetModel(i)->MarginalizeAll();
391 }
392 
393 // ---------------------------------------------------------
394 
396 {
397  // marginalizes all models registered
398  for (unsigned int i = 0; i < GetNModels(); i++)
399  GetModel(i)->WriteMarkovChain(flag);
400 }
401 
402 // ---------------------------------------------------------
403 
404 void BCModelManager::CalculatePValue(bool flag_histogram)
405 {
406  // calculate p-value for all models
407  for (unsigned int i = 0; i < GetNModels(); i++)
408  GetModel(i)->CalculatePValue(GetModel(i)->GetBestFitParameters(), flag_histogram);
409 }
410 
411 // ---------------------------------------------------------
412 
413 void BCModelManager::PrintSummary(const char * file)
414 {
415  std::ofstream out;
416  std::streambuf * old_buffer = 0;
417 
418  if(file) {
419  out.open(file);
420  if (!out.is_open()) {
421  std::cerr<<"Couldn't open file "<<file<<std::endl;
422  return;
423  }
424  old_buffer = std::cout.rdbuf(out.rdbuf());
425  }
426 
427  // model summary
428  int nmodels = fModelContainer->size();
429  std::cout<<std::endl
430  <<"======================================"<<std::endl
431  <<" Summary"<<std::endl
432  <<"======================================"<<std::endl
433  <<std::endl
434  <<" Number of models : "<<nmodels<<std::endl
435  <<std::endl
436  <<" - Models:"<<std::endl;
437 
438  for (int i = 0; i < nmodels; i++)
439  fModelContainer->at(i)->PrintSummary();
440 
441  // data summary
442  std::cout<<" - Data:"<<std::endl
443  <<std::endl
444  <<" Number of entries: "<<fDataSet->GetNDataPoints()<<std::endl
445  <<std::endl;
446 
447  std::cout<<"======================================"<<std::endl
448  <<" Model comparison"<<std::endl
449  <<std::endl;
450 
451  // probability summary
452  std::cout<<" - A priori probabilities:"<<std::endl<<std::endl;
453 
454  for (int i=0; i<nmodels; i++)
455  std::cout<<" p("<< fModelContainer->at(i)->GetName()
456  <<") = "<< fModelContainer->at(i)->GetModelAPrioriProbability()
457  <<std::endl;
458  std::cout<<std::endl;
459 
460  std::cout<<" - A posteriori probabilities:"<<std::endl<<std::endl;
461 
462  for (int i = 0; i < nmodels; i++)
463  std::cout<<" p("<< fModelContainer->at(i)->GetName()
464  <<" | data) = "<< fModelContainer->at(i)->GetModelAPosterioriProbability()
465  <<std::endl;
466  std::cout<<std::endl;
467 
468  std::cout<<"======================================"<<std::endl<<std::endl;
469 
470  if (file)
471  std::cout.rdbuf(old_buffer);
472 
473 }
474 
475 // ---------------------------------------------------------
476 
478 {
479  std::ofstream out;
480  std::streambuf * old_buffer = 0;
481 
482  if(file) {
483  out.open(file);
484  if (!out.is_open()) {
485  std::cerr<<"Couldn't open file "<<file<<std::endl;
486  return;
487  }
488  old_buffer = std::cout.rdbuf(out.rdbuf());
489  }
490 
491  // model summary
492  int nmodels = fModelContainer->size();
493  std::cout<<std::endl
494  <<"==========================================="<<std::endl
495  <<" Model Comparison Summary"<<std::endl
496  <<"==========================================="<<std::endl
497  <<std::endl
498  <<" Number of models : "<<nmodels<<std::endl
499  <<std::endl;
500 
501  // probability summary
502  std::cout<<" - A priori probabilities:"<<std::endl<<std::endl;
503 
504  for (int i=0; i<nmodels; i++)
505  std::cout<<" p("<< fModelContainer->at(i)->GetName()
506  <<") = "<< fModelContainer->at(i)->GetModelAPrioriProbability()
507  <<std::endl;
508  std::cout<<std::endl;
509 
510  std::cout<<" - A posteriori probabilities:"<<std::endl<<std::endl;
511 
512  for (int i = 0; i < nmodels; i++)
513  std::cout<<" p("<< fModelContainer->at(i)->GetName()
514  <<" | data) = "<< fModelContainer->at(i)->GetModelAPosterioriProbability()
515  <<std::endl;
516  std::cout<<std::endl;
517 
518  // Bayes factors summary
519  std::cout<<" - Bayes factors:"<<std::endl<<std::endl;
520  for (int i = 0; i < nmodels-1; i++)
521  for (int j = i+1; j < nmodels; j++)
522  std::cout<<" K = p(data | "<<fModelContainer->at(i)->GetName()<<") / "
523  <<"p(data | "<<fModelContainer->at(j)->GetName()<<") = "
524  <<BayesFactor(i,j)<<std::endl;
525  std::cout<<std::endl;
526 
527  // p-values summary
528  std::cout
529  <<" - p-values:"<<std::endl
530  <<std::endl;
531 
532  for (int i = 0; i < nmodels; i++)
533  {
534  double p = fModelContainer->at(i)->GetPValue();
535  std::cout <<" "<< fModelContainer->at(i)->GetName();
536  if(p>=0.)
537  std::cout<<": p-value = "<< p;
538  else
539  std::cout<<": p-value not calculated";
540  std::cout<<std::endl;
541  }
542  std::cout<<std::endl;
543 
544  std::cout<<"==========================================="<<std::endl<<std::endl;
545 
546  if (file)
547  std::cout.rdbuf(old_buffer);
548 
549 }
550 
551 // ---------------------------------------------------------
552 
554 {
555  // print summary of all models
556  for (unsigned int i = 0; i < GetNModels(); i++)
557  GetModel(i)->PrintResults(Form("%s.txt", GetModel(i)->GetName().data()));
558 }
559 
560 // ---------------------------------------------------------
561 
562 void BCModelManager::Copy(BCModelManager & modelmanager) const
563 {
564  // don't copy the content only the pointers
565  modelmanager.fModelContainer = fModelContainer;
566  modelmanager.fDataSet = fDataSet;
567 }
void SetDataPointUpperBoundary(int index, double upperboundary)
Definition: BCModel.cxx:552
double BayesFactor(const unsigned int imodel1, const unsigned int imodel2)
void SetModelAPrioriProbability(double probability)
Definition: BCModel.h:152
void SetAbsolutePrecision(double absprecision)
void SetDataPointLowerBoundaries(BCDataPoint *datasetlowerboundaries)
Definition: BCModel.h:193
void SetRelativePrecision(double relprecision)
void SetOptimizationMethod(BCIntegrate::BCOptimizationMethod method)
void SetDataPointLowerBoundary(int index, double lowerboundary)
void CalculatePValue(bool flag_histogram=false)
BCModelManager & operator=(const BCModelManager &modelmanager)
void SetDataPointUpperBoundaries(BCDataPoint *datasetupperboundaries)
A class representing a data point.
Definition: BCDataPoint.h:31
void SetDataBoundaries(int index, double lowerboundary, double upperboundary)
void AddModel(BCModel *model, double probability=0.)
A class representing a set of BCModels.
void SetDataSet(BCDataSet *dataset)
Definition: BCModel.h:178
void SetIntegrationMethod(BCIntegrate::BCIntegrationMethod method)
void SetNIterationsOutput(int niterations)
void PrintResults(const char *file)
Definition: BCModel.cxx:816
The base class for all user-defined models.
Definition: BCModel.h:50
void SetNChains(unsigned int n)
A class representing a set of data points.
Definition: BCDataSet.h:37
int ReadDataFromFileTree(const char *filename, const char *treename, const char *branchnames)
Definition: BCDataSet.cxx:135
void Reset()
Definition: BCDataSet.cxx:373
void PrintModelComparisonSummary(const char *filename=0)
void SetMarginalizationMethod(BCIntegrate::BCMarginalizationMethod method)
void SetNIterationsPrecisionCheck(int niterations)
int ReadDataFromFileTxt(const char *filename, int nbranches)
void SetSingleDataPoint(BCDataPoint *datapoint)
void SetDataPointUpperBoundary(int index, double upperboundary)
void SetNbins(unsigned int n)
int ReadDataFromFileTxt(const char *filename, int nvariables)
Definition: BCDataSet.cxx:277
int ReadDataFromFileTree(const char *filename, const char *treename, const char *branchnames)
BCDataPoint * GetDataPoint(unsigned int index)
Definition: BCDataSet.cxx:98
BCModel * GetModel(int index)
unsigned int GetNDataPoints()
Definition: BCDataSet.cxx:79
unsigned int GetNModels()
void SetDataPointUpperBoundaries(BCDataPoint *datasetupperboundaries)
Definition: BCModel.h:199
void SetDataSet(BCDataSet *dataset)
void SetDataPointLowerBoundary(int index, double lowerboundary)
Definition: BCModel.cxx:546
void WriteMarkovChain(bool flag)
void AddDataPoint(BCDataPoint *datapoint)
Definition: BCDataSet.cxx:358
virtual ~BCModelManager()
void SetNIterationsMin(int niterations)
void SetDataPointLowerBoundaries(BCDataPoint *datasetlowerboundaries)
void PrintSummary(const char *filename=0)