BAT  0.9.4
The Bayesian analysis toolkit
 All Classes Namespaces Functions Variables Enumerations
BCMVCDataModel.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 "BCMVCDataModel.h"
12 
13 #include "../../BAT/BCH1D.h"
14 #include "../../BAT/BCH2D.h"
15 #include "../../BAT/BCLog.h"
16 #include "../../BAT/BCMath.h"
17 #include "../../BAT/BCParameter.h"
18 
19 #include <TCanvas.h>
20 #include <TMarker.h>
21 #include <TMath.h>
22 
23 #include <iomanip>
24 
25 // ---------------------------------------------------------
26 BCMVCDataModel::BCMVCDataModel(BCMVCombination* mvc) : BCModel("BCMVCDataModel")
27 {
28  SetNMeasurements(mvc->GetNMeasurements(),
29  mvc->GetParameter(0)->GetLowerLimit(),
30  mvc->GetParameter(0)->GetUpperLimit());
31  SetVectorMeasurements(mvc->GetVectorMeasurements());
32  SetVectorObservable(mvc->GetVectorObservable());
33  SetCovarianceMatrix(mvc->GetCovarianceMatrix());
34 }
35 
36 // ---------------------------------------------------------
37 BCMVCDataModel::~BCMVCDataModel()
38 {
39 }
40 
41 // ---------------------------------------------------------
42 void BCMVCDataModel::SetNMeasurements(int n, double min, double max)
43 {
44  for (int i = 0; i < n; ++i)
45  AddParameter(Form("measurement_%i", i), min, max);
46 }
47 
48 // ---------------------------------------------------------
49 void BCMVCDataModel::SetCovarianceMatrix(TMatrixD matrix)
50 {
51  fCovarianceMatrix.Clear();
52  fCovarianceMatrix.ResizeTo(matrix);
53  fCovarianceMatrix = matrix;
54 
55  fInvCovarianceMatrix.Clear();
56  fInvCovarianceMatrix.ResizeTo(fCovarianceMatrix);
57  fInvCovarianceMatrix = fCovarianceMatrix;
58  fInvCovarianceMatrix.Invert();
59 
60  fDetCovariance = fCovarianceMatrix.Determinant();
61 }
62 
63 // ---------------------------------------------------------
64 void BCMVCDataModel::SetParameters(std::vector<double> parameters)
65 {
66  fPars = parameters;
67  int nmeas = GetNParameters();
68 
69  fVectorObservables.Clear();
70  fVectorObservables.ResizeTo(nmeas);
71 
72  for (int i = 0; i < nmeas; ++i) {
73  fVectorObservables[i] = fPars[fVectorObservable[i]];
74  }
75 }
76 
77 // ---------------------------------------------------------
78 void BCMVCDataModel::SetMeasurementRanges(const std::vector<double> & min, const std::vector<double> & max)
79 {
80  unsigned npar = GetNParameters();
81 
82  if ( (min.size() != npar) || (max.size() != npar) ) {
83  BCLog::OutWarning("BCMVCDataModel::SetnMeasurementRanges. Size of ranges does not fit the number of measurements.");
84  return;
85  }
86 
87  // set the parameter ranges
88  for (unsigned i = 0; i < npar; ++i) {
89  GetParameter(i)->SetLimits(min.at(i), max.at(i));
90  }
91 
92 }
93 
94 // ---------------------------------------------------------
95 void BCMVCDataModel::SetMeasurementRanges(double min, double max)
96 {
97  std::vector<double> min_vec(GetNParameters(), min);
98  std::vector<double> max_vec(GetNParameters(), max);
99  SetMeasurementRanges(min_vec, max_vec);
100 }
101 
102 // ---------------------------------------------------------
103 double BCMVCDataModel::LogLikelihood(const std::vector<double> &parameters)
104 {
105  double logprob = 0.;
106 
107  int nmeas = GetNParameters();
108 
109  // copy parameters into a vector
110  TVectorD observables(nmeas);
111  TVectorD measurements(nmeas);
112 
113  for (int i = 0; i < nmeas; ++i) {
114  observables[i] = fPars[fVectorObservable[i]];
115  measurements[i] = parameters[i];
116  }
117 
118  TVectorD prod1 = observables - measurements;
119  TVectorD prod2 = fInvCovarianceMatrix * prod1;
120  double prod = prod1 * prod2;
121 
122  logprob = -0.5 * prod - log(TMath::Power(2*TMath::Pi(), nmeas/2.) * sqrt(fDetCovariance));
123 
124  return logprob;
125 }
126 
127 // ---------------------------------------------------------
128 double BCMVCDataModel::LogAPrioriProbability(const std::vector<double> &parameters)
129 {
130  double logprob = 0.;
131 
132  (void) parameters; // suppress compiler warning about unused parameters
133 
134  return logprob;
135 }
136 
137 // ---------------------------------------------------------
138 void BCMVCDataModel::MCMCUserIterationInterface()
139 {
140  // get number of chains
141  int nchains = MCMCGetNChains();
142 
143  // get number of parameters
144  int npar = GetNParameters();
145 
146  // loop over all chains and fill histogram
147  for (int i = 0; i < nchains; ++i) {
148  // get the current values of the parameters x and y. These are
149 
150  // copy parameters into a vector
151  TVectorD observables(npar);
152  TVectorD measurements(npar);
153 
154  for (int j = 0; j < npar; ++j) {
155  observables[j] = fPars[fVectorObservable[j]];
156  measurements[j] = fMCMCx.at(i * npar + j);
157  }
158 
159  double chi2 = Chi2(observables, measurements);
160 
161  // fill the histogram
162  if (fHistChi2)
163  fHistChi2->Fill(chi2);
164  }
165 }
166 
167 // ---------------------------------------------------------
168 void BCMVCDataModel::PrintToys(std::string filename)
169 {
170  // check if file extension is pdf
171  if ( (filename.find_last_of(".") != std::string::npos) &&
172  (filename.substr(filename.find_last_of(".")+1) == "pdf") ) {
173  ; // it's a PDF file
174 
175  }
176  else if ( (filename.find_last_of(".") != std::string::npos) &&
177  (filename.substr(filename.find_last_of(".")+1) == "ps") ) {
178  ; // it's a PS file
179  }
180  else {
181  ; // make it a PDF file
182  filename += ".pdf";
183  }
184 
185  int npars = GetNParameters();
186 
187  TCanvas* c1 = new TCanvas("");
188  c1->cd();
189 
190  // calculate observed chi2
191  double chi2 = Chi2(fVectorObservables, fVectorMeasurements);
192 
193  // calculate expected chi2 distribution
194  BCH1D* hist_chi2 = new BCH1D(fHistChi2);
195  if (hist_chi2->GetHistogram()->Integral("width") > 0)
196  hist_chi2->GetHistogram()->Scale(1.0/hist_chi2->GetHistogram()->Integral("width"));
197  else {
198  BCLog::OutWarning("BCMVCDataModel::PrintToys. Chi2 histogram not normalized. Abort printing.");
199  return;
200  }
201 
202  // calculate p-value
203  double pvalue = hist_chi2->GetHistogram()->Integral(hist_chi2->GetHistogram()->FindBin(chi2), hist_chi2->GetHistogram()->GetNbinsX(), "width");
204 
205  // draw expected chi2 distribution
206  hist_chi2->Draw("BTllB1CS1L", 1-pvalue);
207 
208  c1->Print(std::string(filename+"(").c_str());
209 
210  // draw all 1D histograms indicating observed value
211  for (int i = 0; i < npars; ++i) {
212  double obs = fVectorMeasurements[i];
213  const BCParameter* par = GetParameter(i);
214  BCH1D* hist_par = GetMarginalized(par);
215  double p = hist_par->GetHistogram()->Integral(hist_par->GetHistogram()->FindBin(obs), hist_par->GetHistogram()->GetNbinsX(), "width");
216  hist_par->Draw("BTllB1CS1L", 1-p);
217  c1->Print(filename.c_str());
218  }
219 
220  // draw all 2D histograms indicating observed values
221  for (int i = 0; i < npars; ++i) {
222  for (int j = 0; j < i; ++j) {
223  double obs_i = fVectorMeasurements[i];
224  double obs_j = fVectorMeasurements[j];
225  const BCParameter* par_i = GetParameter(i);
226  const BCParameter* par_j = GetParameter(j);
227  BCH2D* hist_par = GetMarginalized(par_i, par_j);
228  hist_par->Draw("BTfB3CS1");
229  TMarker* m = new TMarker();
230  m->SetMarkerStyle(21);
231  m->DrawMarker(obs_j, obs_i);
232  if (i == npars - 1 && j == i-1)
233  c1->Print(std::string(filename+")").c_str());
234  else
235  c1->Print(filename.c_str());
236  }
237  }
238 
239 }
240 
241 // ---------------------------------------------------------
242 void BCMVCDataModel::PrintSummary() {
243 
244  std::cout << " Goodness-of-fit test:" << std::endl << std::endl;
245 
246  // calculate observed chi2
247  double chi2 = Chi2(fVectorObservables, fVectorMeasurements);
248 
249  // calculate expected chi2 distribution
250  BCH1D* hist_chi2 = new BCH1D(fHistChi2);
251  hist_chi2->GetHistogram()->Scale(1.0/hist_chi2->GetHistogram()->Integral("width"));
252 
253  // calculate p-value
254  double pvalue = hist_chi2->GetHistogram()->Integral(hist_chi2->GetHistogram()->FindBin(chi2), hist_chi2->GetHistogram()->GetNbinsX(), "width");
255 
256  std::cout << " chi2 : " << chi2 << std::endl;
257  std::cout << " p-value : " << pvalue << std::endl;
258  std::cout << std::endl;
259 
260 }
261 
262 // ---------------------------------------------------------
263 double BCMVCDataModel::Chi2(TVectorD observables, TVectorD measurements)
264 {
265  TVectorD prod1 = observables - measurements;
266  TVectorD prod2 = fInvCovarianceMatrix * prod1;
267  double chi2 = prod1 * prod2;
268 
269  return chi2;
270 }
271 
272 // ---------------------------------------------------------
void Draw(std::string options="BTfB3CS1meangmodelmode", std::vector< double > intervals=std::vector< double >(0))
Definition: BCH2D.cxx:171
The base class for all user-defined models.
Definition: BCModel.h:50
A class for handling 2D distributions.
Definition: BCH2D.h:37
A class representing a parameter of a model.
Definition: BCParameter.h:28
virtual int AddParameter(BCParameter *parameter)
Definition: BCModel.cxx:225
TH1D * GetHistogram()
Definition: BCH1D.h:53
double LogLikelihood(const std::vector< double > &parameters)
A class for handling 1D distributions.
Definition: BCH1D.h:31
double LogAPrioriProbability(const std::vector< double > &parameters)
void Draw(std::string options="BTsiB3CS1D0Lmeanmode", std::vector< double > intervals=std::vector< double >(0))
Definition: BCH1D.cxx:231