BayesianAnalysisToolkit  0.9.3
BCModelManager.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2013, 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 {
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++)
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 // ---------------------------------------------------------
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 
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 
145 {
146  // set marginalization method for all models registered
147  for (unsigned int i = 0; i < GetNModels(); i++)
149 }
150 
151 // ---------------------------------------------------------
152 
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) {
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) {
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.) {
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.) {
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 !!!
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 !!!
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 }