BAT  0.9.4
The Bayesian analysis toolkit
 All Classes Namespaces Functions Variables Enumerations
BCMTFAnalysisFacility.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 "BCMTFAnalysisFacility.h"
12 
13 #include "BCMTF.h"
14 #include "BCMTFChannel.h"
15 #include "BCMTFComparisonTool.h"
16 #include "BCMTFSystematic.h"
17 #include "BCMTFTemplate.h"
18 
19 #include "../../BAT/BCLog.h"
20 #include "../../BAT/BCH1D.h"
21 #include "../../BAT/BCParameter.h"
22 
23 #include <TCanvas.h>
24 #include <TFile.h>
25 #include <TH1D.h>
26 #include <TRandom3.h>
27 #include <TROOT.h>
28 #include <TTree.h>
29 
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <iostream>
33 
34 namespace {
35 // todo this should really throw an exception
36 int HandleChdirError(int error_code, const std::string & caller, const std::string & dir)
37 {
38  // horrible convention in BAT: 1 => no error
39  if (error_code == 0)
40  return 1;
41  BCLog::OutError((caller + ": could not change to " + dir).c_str());
42  return 0;
43 }
44 }
45 
46 // ---------------------------------------------------------
48  : fRandom(new TRandom3(0))
49  , fFlagMarginalize(false)
50  , fLogLevel(BCLog::nothing)
51 {
52  fMTF = mtf;
53  BCLog::OutDetail(Form("Prepared Analysis Facility for MTF model \'%s\'",mtf->GetName().c_str()));
54 }
55 
56 // ---------------------------------------------------------
58 {
59 }
60 
61 // ---------------------------------------------------------
62 std::vector<TH1D> BCMTFAnalysisFacility::BuildEnsemble(const std::vector<double> & parameters, std::string options)
63 {
64  // option flags
65  bool flag_data = false;
66 
67  // check content of options string
68  if (options.find("data") < options.size()) {
69  flag_data = true;
70  }
71 
72  // get number of channels
73  int nchannels = fMTF->GetNChannels();
74 
75  // create vector of histograms
76  std::vector<TH1D> histograms;
77 
78  // loop over channels
79  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
80 
81  // get channel
82  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
83 
84  // create new histogram
85  TH1D hist( *(channel->GetData()->GetHistogram()) );
86 
87  // get number of bins
88  int nbins = hist.GetNbinsX();
89 
90  // loop over all bins
91  for (int ibin = 1; ibin <= nbins; ++ibin) {
92  if (!flag_data) {
93  double expectation = fMTF->Expectation(ichannel, ibin, parameters);
94  double observation = fRandom->Poisson(expectation);
95 
96  hist.SetBinContent(ibin, observation);
97  }
98  }
99 
100  // add histogram
101  histograms.push_back(hist);
102  }
103 
104  // return histograms
105  return histograms;
106 }
107 
108 // ---------------------------------------------------------
109 TTree * BCMTFAnalysisFacility::BuildEnsembles(TTree * tree, int nensembles, std::string options)
110 {
111  // get number of channels
112  int nchannels = fMTF->GetNChannels();
113 
114  BCLog::OutDetail(Form("MTF Building %d ensembles for %d channels.",nensembles,nchannels));
115 
116  // get number of parameters
117  int nparameters = fMTF->GetNParameters();
118 
119  // create tree variables for input tree
120  std::vector<double> parameters(nparameters);
121 
122  // set branch addresses
123  for (int i = 0; i < nparameters; ++i) {
124  tree->SetBranchAddress(Form("Parameter%i", i), &(parameters[i]));
125  }
126 
127  // create tree
128  TTree * tree_out = new TTree("ensembles", "ensembles");
129 
130  // create matrix of number of bins
131  std::vector< std::vector<double> > nbins_matrix;
132 
133  // prepare the tree variables
134  // loop over channels
135  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
136  // get channel
137  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
138 
139  // get number of bins
140  int nbins = channel->GetData()->GetHistogram()->GetNbinsX();
141 
142  // create new matrix row
143  std::vector<double> nbins_column(nbins);
144 
145  // add matrix
146  nbins_matrix.push_back(nbins_column);
147  }
148 
149  std::vector<double> in_parameters(nparameters);
150 
151  // create branches
152  // loop over channels
153  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
154  // get channel
155  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
156 
157  // get number of bins
158  int nbins = channel->GetData()->GetHistogram()->GetNbinsX();
159 
160  // loop over bins
161  for (int ibin = 1; ibin <= nbins; ++ibin) {
162  // create branches
163  tree_out->Branch(Form("channel_%i_bin_%i", ichannel, ibin),
164  &(nbins_matrix[ichannel])[ibin-1], "n/D");
165  }
166  }
167 
168  for (int i = 0; i < nparameters; ++i) {
169  tree_out->Branch(Form("parameter_%i", i), &in_parameters[i], Form("parameter_%i/D", i));
170  }
171 
172  // create vector of histograms
173  std::vector<TH1D> histograms;
174 
175  // loop over ensembles
176  for (int iensemble = 0; iensemble < nensembles; ++iensemble) {
177  // get random event from tree
178  int index = (int) fRandom->Uniform(tree->GetEntries());
179  tree->GetEntry(index);
180 
181  // create ensembles
182  histograms = BuildEnsemble(parameters, options);
183 
184  // copy information from histograms into tree variables
185  // loop over channels
186  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
187  // get channel
188  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
189 
190  // get number of bins
191  int nbins = channel->GetData()->GetHistogram()->GetNbinsX();
192 
193  // loop over bins
194  for (int ibin = 1; ibin <= nbins; ++ibin) {
195  // fill tree variable
196  (nbins_matrix[ichannel])[ibin-1] = histograms.at(ichannel).GetBinContent(ibin);
197  }
198  }
199 
200  // copy parameter information
201  for (int i = 0; i < nparameters; ++i) {
202  in_parameters[i] = parameters.at(i);
203  }
204 
205  // fill tree
206  tree_out->Fill();
207  }
208 
209  // return tree
210  return tree_out;
211 }
212 
213 // ---------------------------------------------------------
214 TTree * BCMTFAnalysisFacility::BuildEnsembles(const std::vector<double> & parameters, int nensembles, std::string options)
215 {
216  // get number of channels
217  int nchannels = fMTF->GetNChannels();
218 
219  BCLog::OutDetail(Form("MTF Building %d ensambles for %d channels.",nensembles,nchannels));
220 
221  // create tree
222  TTree * tree = new TTree("ensembles", "ensembles");
223 
224  // create matrix of number of bins
225  std::vector< std::vector<double> > nbins_matrix;
226 
227  // prepare the tree variables
228  // loop over channels
229  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
230  // get channel
231  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
232 
233  // get number of bins
234  int nbins = channel->GetData()->GetHistogram()->GetNbinsX();
235 
236  // create new matrix row
237  std::vector<double> nbins_column(nbins);
238 
239  // add matrix
240  nbins_matrix.push_back(nbins_column);
241  }
242 
243  // get number of parameters
244  int nparameters = fMTF->GetNParameters();
245 
246  std::vector<double> in_parameters(nparameters);
247 
248  // create branches
249  // loop over channels
250  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
251  // get channel
252  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
253 
254  // get number of bins
255  int nbins = channel->GetData()->GetHistogram()->GetNbinsX();
256 
257  // loop over bins
258  for (int ibin = 1; ibin <= nbins; ++ibin) {
259  // create branches
260  tree->Branch(Form("channel_%i_bin_%i", ichannel, ibin),
261  &(nbins_matrix[ichannel])[ibin-1], "n/D");
262  }
263  }
264 
265  for (int i = 0; i < nparameters; ++i) {
266  tree->Branch(Form("parameter_%i", i), &in_parameters[i], Form("parameter_%i/D", i));
267  }
268 
269  // create vector of histograms
270  std::vector<TH1D> histograms;
271 
272  // loop over ensembles
273  for (int iensemble = 0; iensemble < nensembles; ++iensemble) {
274  // create ensembles
275  histograms = BuildEnsemble(parameters, options);
276 
277  // copy information from histograms into tree variables
278  // loop over channels
279  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
280  // get channel
281  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
282 
283  // get number of bins
284  int nbins = channel->GetData()->GetHistogram()->GetNbinsX();
285 
286  // loop over bins
287  for (int ibin = 1; ibin <= nbins; ++ibin) {
288  // fill tree variable
289  (nbins_matrix[ichannel])[ibin-1] = histograms.at(ichannel).GetBinContent(ibin);
290  }
291  }
292 
293  // copy parameter information
294  for (int i = 0; i < nparameters; ++i) {
295  if (parameters.size() > 0)
296  in_parameters[i] = parameters.at(i);
297  else
298  in_parameters[i] = 0;
299  }
300 
301  // fill tree
302  tree->Fill();
303  }
304 
305  // return tree
306  return tree;
307 }
308 
309 // ---------------------------------------------------------
310 TTree * BCMTFAnalysisFacility::PerformEnsembleTest(const std::vector<double> & parameters, int nensembles, std::string options)
311 {
312  // create new tree
313  TTree * tree = 0;
314 
315  // create ensembles
316  tree = BuildEnsembles(parameters, nensembles, options);
317 
318  // perform ensemble test
319  return PerformEnsembleTest(tree, nensembles, 0, options);
320 }
321 
322 // ---------------------------------------------------------
323 TTree * BCMTFAnalysisFacility::PerformEnsembleTest(TTree * tree, int nensembles, int start, std::string options)
324 {
325  BCLog::OutSummary("Running ensemble test.");
326  if (fFlagMarginalize) {
327  BCLog::OutSummary("Fit for each ensemble is going to be run using MCMC. It can take a while.");
328  }
329 
330  // option flags
331  bool flag_mc = false;
332 
333  // check content of options string
334  if (options.find("MC") < options.size()) {
335  flag_mc = true;
336  }
337 
338  // set log level
339  // It would be better to set the level for the screen and for the file
340  // separately. Perhaps in the future.
343  if(fLogLevel==BCLog::nothing) {
344  BCLog::OutSummary("No log messages for the ensemble fits are going to be printed.");
345  BCLog::SetLogLevel(fLogLevel);
346  }
347  else if(fLogLevel!=lls) {
348  BCLog::OutSummary(Form("The log level for the ensemble test is set to \'%s\'.",BCLog::ToString(fLogLevel)));
349  BCLog::SetLogLevel(fLogLevel);
350  }
351 
352  // get number of channels
353  int nchannels = fMTF->GetNChannels();
354 
355  // define set of histograms for the original data sets
356  std::vector<TH1D *> histograms_data(nchannels);
357 
358  // create matrix of number of bins
359  std::vector< std::vector<double> > nbins_matrix;
360 
361  // prepare the tree
362  // loop over channels
363  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
364  // get channel
365  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
366 
367  // get number of bins
368  int nbins = channel->GetData()->GetHistogram()->GetNbinsX();
369 
370  // create new matrix row
371  std::vector<double> nbins_column(nbins);
372 
373  // add matrix
374  nbins_matrix.push_back(nbins_column);
375  }
376 
377  // loop over channels
378  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
379  // get channel
380  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
381 
382  // get number of bins
383  int nbins = channel->GetData()->GetHistogram()->GetNbinsX();
384 
385  // loop over bins
386  for (int ibin = 1; ibin <= nbins; ++ibin) {
387  // create branches
388  tree->SetBranchAddress(Form("channel_%i_bin_%i", ichannel, ibin),
389  &(nbins_matrix[ichannel])[ibin-1]);
390  }
391  }
392 
393  // get number of parameters
394  int nparameters = fMTF->GetNParameters();
395 
396  // define tree variables
397  std::vector<double> out_parameters(nparameters);
398 
399  for (int i = 0; i < nparameters; ++i) {
400  tree->SetBranchAddress(Form("parameter_%i", i), &out_parameters[i]);
401  }
402 
403  // copy the original data sets
404  // loop over channels
405  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
406  // get channel
407  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
408 
409  // set data pointer
410  histograms_data[ichannel] = channel->GetData()->GetHistogram();
411  }
412 
413  // create output tree
414  TTree * tree_out = new TTree("ensemble_test", "ensemble test");
415 
416  // define tree variables
417  std::vector<double> out_mode_global(nparameters);
418  std::vector<double> out_std_global(nparameters);
419  std::vector<double> out_mode_marginalized(nparameters);
420  std::vector<double> out_mean_marginalized(nparameters);
421  std::vector<double> out_median_marginalized(nparameters);
422  std::vector<double> out_5quantile_marginalized(nparameters);
423  std::vector<double> out_10quantile_marginalized(nparameters);
424  std::vector<double> out_16quantile_marginalized(nparameters);
425  std::vector<double> out_84quantile_marginalized(nparameters);
426  std::vector<double> out_90quantile_marginalized(nparameters);
427  std::vector<double> out_95quantile_marginalized(nparameters);
428  std::vector<double> out_std_marginalized(nparameters);
429  std::vector<double> out_chi2_generated(nchannels);
430  std::vector<double> out_chi2_mode(nchannels);
431  std::vector<double> out_cash_generated(nchannels);
432  std::vector<double> out_cash_mode(nchannels);
433  std::vector<int> out_nevents(nchannels);
434  double out_chi2_generated_total;
435  double out_chi2_mode_total;
436  double out_cash_generated_total;
437  double out_cash_mode_total;
438  int out_nevents_total;
439 
440  // create branches
441  for (int i = 0; i < nparameters; ++i) {
442  tree_out->Branch(Form("parameter_%i", i), &out_parameters[i], Form("parameter %i/D", i));
443  tree_out->Branch(Form("mode_global_%i", i), &out_mode_global[i], Form("global mode of par. %i/D", i));
444  tree_out->Branch(Form("std_global_%i", i), &out_std_global[i], Form("global std of par. %i/D", i));
445  if (fFlagMarginalize) {
446  tree_out->Branch(Form("mode_marginalized_%i", i), &out_mode_marginalized[i], Form("marginalized mode of par. %i/D", i));
447  tree_out->Branch(Form("mean_marginalized_%i", i), &out_mean_marginalized[i], Form("marginalized mean of par. %i/D", i));
448  tree_out->Branch(Form("median_marginalized_%i", i), &out_median_marginalized[i], Form("median of par. %i/D", i));
449  tree_out->Branch(Form("5quantile_marginalized_%i", i), &out_5quantile_marginalized[i], Form("marginalized 5 per cent quantile of par. %i/D", i));
450  tree_out->Branch(Form("10quantile_marginalized_%i", i), &out_10quantile_marginalized[i], Form("marginalized 10 per cent quantile of par. %i/D", i));
451  tree_out->Branch(Form("16quantile_marginalized_%i", i), &out_16quantile_marginalized[i], Form("marginalized 16 per cent quantile of par. %i/D", i));
452  tree_out->Branch(Form("84quantile_marginalized_%i", i), &out_84quantile_marginalized[i], Form("marginalized 84 per cent quantile of par. %i/D", i));
453  tree_out->Branch(Form("90quantile_marginalized_%i", i), &out_90quantile_marginalized[i], Form("marginalized 90 per cent quantile of par. %i/D", i));
454  tree_out->Branch(Form("95quantile_marginalized_%i", i), &out_95quantile_marginalized[i], Form("marginalized 95 per cent quantile of par. %i/D", i));
455  tree_out->Branch(Form("std_marginalized_%i", i), &out_std_marginalized[i], Form("marginalized std of par. %i/D", i));
456  }
457  }
458  for (int i = 0; i < nchannels; ++i) {
459  tree_out->Branch(Form("chi2_generated_%i", i), &out_chi2_generated[i], Form("chi2 (generated par.) in channel %i/D", i));
460  tree_out->Branch(Form("chi2_mode_%i", i), &out_chi2_mode[i], Form("chi2 (mode of par.) in channel %i/D", i));
461  tree_out->Branch(Form("cash_generated_%i", i), &out_cash_generated[i], Form("cash statistic (generated par.) in channel %i/D", i));
462  tree_out->Branch(Form("cash_mode_%i", i), &out_cash_mode[i], Form("cash statistic (mode of par.) in channel %i/D", i));
463  tree_out->Branch(Form("nevents_%i", i), &out_nevents[i], Form("nevents in channel %i/I", i));
464  }
465  tree_out->Branch("chi2_generated_total", &out_chi2_generated_total, "chi2 (generated par.) in all channels/D");
466  tree_out->Branch("chi2_mode_total", &out_chi2_mode_total, "chi2 (mode of par.) in all channels/D");
467  tree_out->Branch("cash_generated_total", &out_cash_generated_total, "cash statistic (generated par.) in all channels/D");
468  tree_out->Branch("cash_mode_total", &out_cash_mode_total, "cash statistic (mode of par.) in all channels/D");
469  tree_out->Branch("nevents_total", &out_nevents_total, "total number of events/I");
470 
471  // define temporary vector of histogram for fluctated templates
472  std::vector<TH1D*> histlist(0);
473 
474  // loop over ensembles
475  for (int iensemble = 0; iensemble < nensembles; ++iensemble) {
476  // print status
477  if ((iensemble+1)%100 == 0 && iensemble > 0) {
478  BCLog::SetLogLevel(lls,llf);
479  int frac = int (double(iensemble+1) / double(nensembles) * 100.);
480  BCLog::OutDetail(Form("Fraction of ensembles analyzed: %i%%",frac));
481  BCLog::SetLogLevel(fLogLevel);
482  }
483 
484  // get next (commented out: random) event from tree
485  // int index = (int) fRandom->Uniform(tree->GetEntries());
486  int index = iensemble + start;
487  tree->GetEntry(index);
488 
489  // define histograms
490  std::vector<TH1D> histograms;
491 
492  // transform matrix into histograms
493  histograms = MatrixToHistograms(nbins_matrix);
494 
495  // loop over channels and set data
496  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
497  // get channel
498  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
499 
500  // overwrite data
501  if (iensemble == 0)
502  channel->GetData()->SetHistogram(0);
503 
504  // set data histogram
505  fMTF->SetData(channel->GetName().c_str(), histograms.at(ichannel));
506  }
507 
508  // fluctuate templates if option "MC" is chosen
509  if (flag_mc) {
510  // get number of templates
511  unsigned int ntemplates = fMTF->GetNProcesses();
512 
513  // loop over channels
514  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
515  // get channel
516  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
517 
518  // loop over all templates
519  for (unsigned int i = 0; i < ntemplates; ++i) {
520 
521  // get histogram
522  TH1D * temphist = channel->GetTemplate(i)->GetHistogram();
523  histlist.push_back(temphist);
524 
525  // replace by fluctuated histogram
526  if (temphist) {
527  TH1D* temphistfluc = new TH1D(channel->GetTemplate(i)->FluctuateHistogram(options, channel->GetTemplate(i)->GetOriginalNorm()));
528  channel->GetTemplate(i)->SetHistogram(temphistfluc, channel->GetTemplate(i)->GetNorm());
529  }
530  }
531  }
532  }
533 
534  // work-around: force initialization
535  fMTF->ResetResults();
536 
537  // check if marginalization should be run and perform analysis
538  if (fFlagMarginalize) {
539  BCLog::SetLogLevel(lls,llf);
540  BCLog::OutDetail(Form("Running MCMC for ensemble %i",iensemble));
541  BCLog::SetLogLevel(fLogLevel);
542 
543  // run mcmc
544  fMTF->MarginalizeAll();
545 
546  // find mode
547  fMTF->FindMode( fMTF->GetBestFitParameters() );
548  }
549  else {
550  // find mode
551  fMTF->FindMode();
552  }
553 
554  // fill tree variables
555  out_mode_global = fMTF->GetBestFitParameters();
556  out_std_global = fMTF->GetBestFitParameterErrors();
557  out_chi2_generated_total = 0;
558  out_chi2_mode_total = 0;
559  out_cash_generated_total = 0;
560  out_cash_mode_total = 0;
561  out_nevents_total = 0;
562 
563  for (int i = 0; i < nparameters; ++i) {
564  if (fFlagMarginalize) {
565  BCH1D * hist = fMTF->GetMarginalized( fMTF->GetParameter(i) );
566  out_mode_marginalized[i] = hist->GetMode();
567  out_mean_marginalized[i] = hist->GetMean();
568  out_median_marginalized[i] = hist->GetMedian();
569  out_5quantile_marginalized[i] = hist->GetQuantile(0.05);
570  out_10quantile_marginalized[i] = hist->GetQuantile(0.10);
571  out_16quantile_marginalized[i] = hist->GetQuantile(0.16);
572  out_84quantile_marginalized[i] = hist->GetQuantile(0.84);
573  out_90quantile_marginalized[i] = hist->GetQuantile(0.90);
574  out_95quantile_marginalized[i] = hist->GetQuantile(0.95);
575  out_std_marginalized[i]=hist->GetRMS();
576  }
577  }
578 
579  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
580  // get channel
581  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
582 
583  // get number of events
584  out_nevents[ichannel] = (int) channel->GetData()->GetHistogram()->Integral();
585 
586  // calculate chi2
587  out_chi2_generated[ichannel] = fMTF->CalculateChi2( ichannel, out_parameters );
588  out_chi2_mode[ichannel] = fMTF->CalculateChi2( ichannel, fMTF->GetBestFitParameters() );
589 
590  // calculate cash statistic
591  out_cash_generated[ichannel] = fMTF->CalculateCash( ichannel, out_parameters );
592  out_cash_mode[ichannel] = fMTF->CalculateCash( ichannel, fMTF->GetBestFitParameters() );
593 
594  // increase the total number of events
595  out_nevents_total += out_nevents[ichannel];
596 
597  // increase the total chi2
598  out_chi2_generated_total += out_chi2_generated[ichannel];
599  out_chi2_mode_total += out_chi2_mode[ichannel];
600 
601  // increase the total cash statistic
602  out_cash_generated_total += out_cash_generated[ichannel];
603  out_cash_mode_total += out_cash_mode[ichannel];
604  }
605 
606  // fill tree
607  tree_out->Fill();
608 
609  // but original template back if options "MC" is chosen
610  if (flag_mc) {
611  // get number of templates
612  unsigned int ntemplates = fMTF->GetNProcesses();
613 
614  // loop over channels
615  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
616  // get channel
617  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
618 
619  // loop over all templates
620  for (unsigned int i = 0; i < ntemplates; ++i) {
621 
622  // get histogram
623  TH1D * temphist = histlist.at(ichannel * ntemplates + i);
624  temphist->Scale(channel->GetTemplate(i)->GetOriginalNorm()/ temphist->Integral());
625 
626  // replace by fluctuated histogram
627  TH1D* temphistfluc = channel->GetTemplate(i)->GetHistogram();
628  delete temphistfluc;
629  channel->GetTemplate(i)->SetHistogram(temphist, channel->GetTemplate(i)->GetNorm());
630  }
631  }
632  histlist.clear();
633  }
634  }
635 
636  // put the original data back in place
637  // loop over channels
638  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
639  // get channel
640  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
641 
642  // set data pointer
643  channel->GetData()->SetHistogram(histograms_data.at(ichannel));
644  }
645 
646  // reset log level
647  BCLog::SetLogLevel(lls,llf);
648 
649  // work-around: force initialization
650  fMTF->ResetResults();
651 
652  BCLog::OutSummary("Ensemble test ran successfully.");
653 
654  // return output tree
655  return tree_out;
656 }
657 
658 // ---------------------------------------------------------
659 std::vector<TH1D> BCMTFAnalysisFacility::MatrixToHistograms(const std::vector< std::vector<double> > & matrix)
660 {
661  // create vector of histograms
662  std::vector<TH1D> histograms;
663 
664  // get number of channels
665  int nchannels = matrix.size();;
666 
667  // loop over channels
668  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
669  // get channel
670  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
671 
672  // get column
673  std::vector<double> nbins_column = matrix[ichannel];
674 
675  // create new histogram
676  TH1D hist( *(channel->GetData()->GetHistogram()) );
677 
678  // get number of bins
679  int nbins = hist.GetNbinsX();
680 
681  // fill bin content
682  for (int ibin = 1; ibin <= nbins; ++ibin) {
683  hist.SetBinContent(ibin, nbins_column.at(ibin-1));
684  }
685 
686  // add histogram to container
687  histograms.push_back(hist);
688  }
689 
690  // return histograms
691  return histograms;
692 
693 }
694 
695 // ---------------------------------------------------------
696 int BCMTFAnalysisFacility::PerformSingleChannelAnalyses(const char * dirname, const char * options)
697 {
698  BCLog::OutSummary(Form("Running single channel analysis in directory \'%s\'.",dirname));
699 
700  // todo check error return values from filesystem operations
701  // ---- create new directory ---- //
702 
703  mkdir(dirname, 0777);
704  int ret = chdir(dirname);
705  if (ret) {
706  return ::HandleChdirError(ret, "BCMTFAnalysisFacility::PerformSingleChannelAnalyses", dirname);
707  }
708 
709  // ---- check options ---- //
710 
711  bool flag_syst = true;
712  bool flag_mcmc = true;
713 
714  if (std::string(options).find("nosyst") < std::string(options).size())
715  flag_syst = false;
716 
717  if (std::string(options).find("mcmc") < std::string(options).size())
718  flag_mcmc = true;
719 
720  // get number of channels
721  int nchannels = fMTF->GetNChannels();
722 
723  // get number of systematics
724  int nsystematics = fMTF->GetNSystematics();
725 
726  // container of flags for channels
727  std::vector<bool> flag_channel(nchannels);
728 
729  // container of flags for systematics
730  std::vector<bool> flag_systematic(nsystematics);
731 
732  // create new container of comparison tools
733  std::vector<BCMTFComparisonTool *> ctc;
734  std::vector<BCMTFComparisonTool *> ctc_mcmc;
735 
736  // get number of parameters
737  int nparameters = fMTF->GetNParameters();
738 
739  // ---- add one comparison tool for each parameter ---- //
740 
741  // loop over all parameters
742  for (int i = 0; i < nparameters; ++ i) {
743  // create new comparison tool
744  BCMTFComparisonTool * ct = new BCMTFComparisonTool(fMTF->GetParameter(i)->GetName().c_str());
745  BCMTFComparisonTool * ct_mcmc = new BCMTFComparisonTool(fMTF->GetParameter(i)->GetName().c_str());
746 
747  // add comparison tool to container
748  ctc.push_back(ct);
749  ctc_mcmc.push_back(ct_mcmc);
750  }
751 
752  // ---- switch on/off all systematics ---- //
753 
754  // loop over all systematics
755  for (int isystematic = 0; isystematic < nsystematics; ++isystematic) {
756  // get systematic
757  BCMTFSystematic * systematic = fMTF->GetSystematic(isystematic);
758 
759  // remember old setting
760  flag_systematic[isystematic] = systematic->GetFlagSystematicActive();
761 
762  // switch off systematic
763  if (flag_systematic[isystematic])
764  systematic->SetFlagSystematicActive(flag_syst);
765  }
766 
767  // ---- switch on all channels ---- //
768 
769  // loop over all channels
770  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
771  // get channel
772  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
773 
774  // remember old setting
775  flag_channel[ichannel] = channel->GetFlagChannelActive();
776 
777  // switch channel on/off
778  channel->SetFlagChannelActive(true);
779  }
780 
781  // ---- perform analysis for combination ---- //
782  if (flag_mcmc) {
783  // work-around: force initialization
784  fMTF->ResetResults();
785 
786  // run mcmc
787  fMTF->MarginalizeAll();
788 
789  // find mode
790  fMTF->FindMode( fMTF->GetBestFitParameters() );
791  }
792  else {
793  // find mode
794  fMTF->FindMode();
795  }
796 
797  // print results
798  if (flag_mcmc)
799  fMTF->PrintAllMarginalized("marginalized_combined.pdf");
800  fMTF->PrintResults("results_combined.txt");
801 
802  // loop over all parameters
803  for (int i = 0; i < nparameters; ++ i) {
804  // get comparison tool
805  BCMTFComparisonTool * ct = ctc.at(i);
806  BCMTFComparisonTool * ct_mcmc = ctc_mcmc.at(i);
807 
808  ct->AddContribution("all channels",
809  fMTF->GetBestFitParameters().at(i),
810  fMTF->GetBestFitParameterErrors().at(i));
811  if (flag_mcmc) {
812  BCH1D * hist = fMTF->GetMarginalized( fMTF->GetParameter(i) );
813 
814  ct_mcmc->AddContribution("all channels",
815  hist->GetMean(),
816  hist->GetRMS());
817  }
818  }
819 
820  // ---- switch off all channels ----//
821 
822  // loop over all channels
823  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
824  // get channel
825  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
826 
827  // switch off channel
828  channel->SetFlagChannelActive(false);
829  }
830 
831  // ---- perform analysis on all channels separately ---- //
832 
833  // loop over all channels
834  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
835  // get channel
836  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
837 
838  // switch on one channel
839  channel->SetFlagChannelActive(true);
840 
841  // perform analysis
842 
843  if (flag_mcmc) {
844  // work-around: force initialization
845  fMTF->ResetResults();
846 
847  // run mcmc
848  fMTF->MarginalizeAll();
849 
850  // find mode
851  fMTF->FindMode( fMTF->GetBestFitParameters() );
852  }
853  else {
854  // find mode
855  fMTF->FindMode();
856  }
857 
858  // print results
859  if (flag_mcmc)
860  fMTF->PrintAllMarginalized(Form("marginalized_channel_%i.pdf", ichannel));
861  fMTF->PrintResults(Form("results_channel_%i.txt", ichannel));
862 
863  // ---- update comparison tools ---- //
864 
865  // loop over all parameters
866  for (int i = 0; i < nparameters; ++ i) {
867  // get comparison tool
868  BCMTFComparisonTool * ct = ctc.at(i);
869  BCMTFComparisonTool * ct_mcmc = ctc_mcmc.at(i);
870 
871  ct->AddContribution(channel->GetName().c_str(),
872  fMTF->GetBestFitParameters().at(i),
873  fMTF->GetBestFitParameterErrors().at(i));
874  if (flag_mcmc) {
875  BCH1D * hist = fMTF->GetMarginalized( fMTF->GetParameter(i) );
876 
877  ct_mcmc->AddContribution(channel->GetName().c_str(),
878  hist->GetMean(),
879  hist->GetRMS());
880  }
881 
882  // switch off channel
883  channel->SetFlagChannelActive(false);
884  }
885  }
886 
887  // ---- reset all systematics ---- //
888  // loop over all systematics
889  for (int isystematic = 0; isystematic < nsystematics; ++isystematic) {
890  // get systematic
891  BCMTFSystematic * systematic = fMTF->GetSystematic(isystematic);
892 
893  // switch off systematic
894  if (flag_systematic[isystematic])
895  systematic->SetFlagSystematicActive(flag_systematic[isystematic]);
896  }
897 
898  // ---- reset all channels ---- //
899 
900  // loop over all channels
901  for (int ichannel = 0; ichannel < nchannels; ++ichannel) {
902  // get channel
903  BCMTFChannel * channel = fMTF->GetChannel(ichannel);
904 
905  // switch channel on/off
906  channel->SetFlagChannelActive(flag_channel[ichannel]);
907  }
908 
909  // ---- workaround: reset MCMC ---- //
910  fMTF->ResetResults();
911 
912  // ---- print everything ---- //
913  TCanvas * c1 = new TCanvas();
914  c1->cd();
915 
916  // draw first one
917  BCMTFComparisonTool * ct = ctc.at(0);
918  ct->DrawOverview();
919  // c1->Print((std::string(filename)+std::string("(")).c_str());
920  c1->Print((std::string("overview.pdf")+std::string("(")).c_str());
921 
922  // loop over all parameters
923  for (int i = 1; i < nparameters-1; ++ i) {
924  // create new comparison tool
925  BCMTFComparisonTool * ct = ctc.at(i);
926 
927  ct->DrawOverview();
928  c1->Print("overview.pdf");
929  }
930 
931  // draw last one
932  ct = ctc.at(nparameters-1);
933  ct->DrawOverview();
934  c1->Print((std::string("overview.pdf")+std::string(")")).c_str());
935 
936  // ---- print everything (mcmc) ---- //
937  if (flag_mcmc) {
938  TCanvas * c2 = new TCanvas();
939  c2->cd();
940 
941  // draw first one
942  BCMTFComparisonTool * ct_mcmc = ctc_mcmc.at(0);
943  ct_mcmc->DrawOverview();
944  // c2->Print((std::string(filename)+std::string("(")).c_str());
945  c2->Print((std::string("overview_mcmc.pdf")+std::string("(")).c_str());
946 
947  // loop over all parameters
948  for (int i = 1; i < nparameters-1; ++ i) {
949  // create new comparison tool
950  BCMTFComparisonTool * ct_mcmc = ctc_mcmc.at(i);
951 
952  ct_mcmc->DrawOverview();
953  c2->Print("overview_mcmc.pdf");
954  }
955 
956  // draw last one
957  ct_mcmc = ctc_mcmc.at(nparameters-1);
958  ct_mcmc->DrawOverview();
959  c2->Print((std::string("overview_mcmc.pdf")+std::string(")")).c_str());
960  delete c2;
961  }
962 
963  // ---- free memory ---- //
964  for (int i = 0; i < nparameters; ++i) {
965  BCMTFComparisonTool * ct = ctc[i];
966  BCMTFComparisonTool * ct_mcmc = ctc_mcmc[i];
967  delete ct;
968  delete ct_mcmc;
969  }
970  ctc.clear();
971  ctc_mcmc.clear();
972 
973  delete c1;
974 
975  // ---- change directory ---- //
976 
977  ret = chdir("../");
978 
979  BCLog::OutSummary("Single channel analysis ran successfully");
980 
981  // no error
982  return 1;
983 }
984 
985 // ---------------------------------------------------------
986 int BCMTFAnalysisFacility::PerformSingleSystematicAnalyses(const char * dirname, const char * options)
987 {
988  BCLog::OutSummary(Form("Running single channel systematic analysis in directory \'%s\'.",dirname));
989 
990  // ---- create new directory ---- //
991 
992  mkdir(dirname, 0777);
993  int ret = chdir(dirname);
994  if (ret) {
995  return ::HandleChdirError(ret, "BCMTFAnalysisFacility::PerformSingleChannelAnalyses", dirname);
996  }
997 
998 
999  // ---- check options ---- //
1000 
1001  bool flag_mcmc = true;
1002 
1003  if (std::string(options).find("mcmc") < std::string(options).size())
1004  flag_mcmc = true;
1005 
1006  // get number of channels
1007  int nchannels = fMTF->GetNChannels();
1008 
1009  // get number of systematics
1010  int nsystematics = fMTF->GetNSystematics();
1011 
1012  // container of flags for channels
1013  std::vector<bool> flag_channel(nchannels);
1014 
1015  // container of flags for systematics
1016  std::vector<bool> flag_systematic(nsystematics);
1017 
1018  // create new container of comparison tools
1019  std::vector<BCMTFComparisonTool *> ctc;
1020 
1021  // get number of parameters
1022  int nparameters = fMTF->GetNParameters();
1023 
1024  // ---- add one comparison tool for each systematic ---- //
1025 
1026  // loop over all parameters
1027  for (int i = 0; i < nparameters; ++ i) {
1028  // create new comparison tool
1029  BCMTFComparisonTool * ct = new BCMTFComparisonTool(fMTF->GetParameter(i)->GetName().c_str());
1030 
1031  // add comparison tool to container
1032  ctc.push_back(ct);
1033  }
1034 
1035  // ---- switch on all systematics ---- //
1036 
1037  for (int isystematic = 0; isystematic < nsystematics; ++ isystematic) {
1038  // get systematic
1039  BCMTFSystematic * systematic = fMTF->GetSystematic(isystematic);
1040 
1041  // remember old setting
1042  flag_systematic[isystematic] = systematic->GetFlagSystematicActive();
1043 
1044  // switch on
1045  systematic->SetFlagSystematicActive(true);
1046  }
1047 
1048  if (flag_mcmc) {
1049  // work-around: force initialization
1050  fMTF->ResetResults();
1051 
1052  // run mcmc
1053  fMTF->MarginalizeAll();
1054 
1055  // find mode
1056  fMTF->FindMode( fMTF->GetBestFitParameters() );
1057  }
1058  else {
1059  // find mode
1060  fMTF->FindMode();
1061  }
1062 
1063  // print results
1064  if (flag_mcmc)
1065  fMTF->PrintAllMarginalized("marginalized_all.pdf");
1066  fMTF->PrintResults("results_all.txt");
1067 
1068  // loop over all parameters
1069  for (int i = 0; i < nparameters; ++ i) {
1070  // get comparison tool
1071  BCMTFComparisonTool * ct = ctc.at(i);
1072 
1073  ct->AddContribution("all systematics",
1074  fMTF->GetBestFitParameters().at(i),
1075  fMTF->GetBestFitParameterErrors().at(i));
1076  }
1077 
1078  // ---- switch off all systematics ---- //
1079 
1080  // loop over all systematics
1081  for (int isystematic = 0; isystematic < nsystematics; ++isystematic) {
1082  // get systematic
1083  BCMTFSystematic * systematic = fMTF->GetSystematic(isystematic);
1084 
1085  // switch off
1086  systematic->SetFlagSystematicActive(false);
1087  }
1088 
1089  // ---- perform analysis with all systematics separately ---- //
1090 
1091  // loop over all channels
1092  for (int isystematic = 0; isystematic < nsystematics; ++isystematic) {
1093  // get systematic
1094  BCMTFSystematic * systematic = fMTF->GetSystematic(isystematic);
1095 
1096  // switch on systematic
1097  systematic->SetFlagSystematicActive(true);
1098 
1099  // perform analysis
1100  if (flag_mcmc) {
1101  // work-around: force initialization
1102  fMTF->ResetResults();
1103 
1104  // run mcmc
1105  fMTF->MarginalizeAll();
1106 
1107  // find mode
1108  fMTF->FindMode( fMTF->GetBestFitParameters() );
1109  }
1110  else {
1111  // find mode
1112  fMTF->FindMode();
1113  }
1114 
1115  // print results
1116  if (flag_mcmc)
1117  fMTF->PrintAllMarginalized(Form("marginalized_systematic_%i.pdf", isystematic));
1118  fMTF->PrintResults(Form("results_systematic_%i.txt", isystematic));
1119 
1120  // ---- update comparison tools ---- //
1121 
1122  // loop over all parameters
1123  for (int i = 0; i < nparameters; ++ i) {
1124  // get comparison tool
1125  BCMTFComparisonTool * ct = ctc.at(i);
1126 
1127  ct->AddContribution(systematic->GetName().c_str(),
1128  fMTF->GetBestFitParameters().at(i),
1129  fMTF->GetBestFitParameterErrors().at(i));
1130  }
1131 
1132  // switch off systematic
1133  systematic->SetFlagSystematicActive(false);
1134  }
1135 
1136  // ---- analysis without any systematic uncertainty ---- //
1137 
1138  if (flag_mcmc) {
1139  // work-around: force initialization
1140  fMTF->ResetResults();
1141 
1142  // run mcmc
1143  fMTF->MarginalizeAll();
1144 
1145  // find mode
1146  fMTF->FindMode( fMTF->GetBestFitParameters() );
1147  }
1148  else {
1149  // find mode
1150  fMTF->FindMode();
1151  }
1152 
1153  // print results
1154  if (flag_mcmc)
1155  fMTF->PrintAllMarginalized("marginalized_none.pdf");
1156  fMTF->PrintResults("results_none.txt");
1157 
1158  // loop over all parameters
1159  for (int i = 0; i < nparameters; ++ i) {
1160  // get comparison tool
1161  BCMTFComparisonTool * ct = ctc.at(i);
1162 
1163  ct->AddContribution("no systematics",
1164  fMTF->GetBestFitParameters().at(i),
1165  fMTF->GetBestFitParameterErrors().at(i));
1166  }
1167 
1168 
1169 
1170  // ---- reset all systematics ---- //
1171 
1172  // loop over all systematics
1173  for (int isystematic = 0; isystematic < nsystematics; ++isystematic) {
1174  // get systematic
1175  BCMTFSystematic * systematic = fMTF->GetSystematic(isystematic);
1176 
1177  // switch off systematic
1178  if (flag_systematic[isystematic])
1179  systematic->SetFlagSystematicActive(flag_systematic[isystematic]);
1180  }
1181 
1182  // ---- workaround: reset MCMC ---- //
1183  fMTF->ResetResults();
1184 
1185  // ---- print everything ---- //
1186  TCanvas * c1 = new TCanvas();
1187  c1->cd();
1188 
1189  // draw first one
1190  BCMTFComparisonTool * ct = ctc.at(0);
1191  ct->DrawOverview();
1192  // c1->Print((std::string(filename)+std::string("(")).c_str());
1193  c1->Print((std::string("overview.pdf")+std::string("(")).c_str());
1194 
1195  // loop over all parameters
1196  for (int i = 1; i < nparameters-1; ++i) {
1197  // create new comparison tool
1198  BCMTFComparisonTool * ct = ctc.at(i);
1199 
1200  ct->DrawOverview();
1201  c1->Print("overview.pdf");
1202  }
1203 
1204  // draw last one
1205  ct = ctc.at(nparameters-1);
1206  ct->DrawOverview();
1207  c1->Print((std::string("overview.pdf")+std::string(")")).c_str());
1208 
1209  // ---- free memory ---- //
1210  for (int i = 0; i < nparameters; ++i) {
1211  BCMTFComparisonTool * ct = ctc[i];
1212  delete ct;
1213  }
1214  ctc.clear();
1215 
1216  delete c1;
1217 
1218  // ---- change directory ---- //
1219 
1220  ret = chdir("../");
1221 
1222  BCLog::OutSummary("Single channel analysis ran successfully");
1223 
1224  // no error
1225  return 1;
1226 }
1227 
1228 // ---------------------------------------------------------
1229 int BCMTFAnalysisFacility::PerformCalibrationAnalysis(const char * dirname, const std::vector<double> & default_parameters, int index, const std::vector<double> & parametervalues, int nensembles)
1230 {
1231  BCLog::OutSummary(Form("Running calibration analysis in directory \'%s\'.",dirname));
1232 
1233  // ---- create new directory ---- //
1234 
1235  mkdir(dirname, 0777);
1236  int ret = chdir(dirname);
1237  if (ret) {
1238  return ::HandleChdirError(ret, "BCMTFAnalysisFacility::PerformSingleChannelAnalyses", dirname);
1239  }
1240 
1241  // ---- loop over parameter values and perform analysis ---- //
1242 
1243  int nvalues = int(parametervalues.size());
1244  for (int ivalue = 0; ivalue < nvalues; ++ivalue) {
1245 
1246  // open file
1247  TFile * file = TFile::Open(Form("ensemble_%i.root", ivalue), "RECREATE");
1248  file->cd();
1249 
1250  // set parameters
1251  std::vector<double> parameters = default_parameters;
1252  parameters[index] = parametervalues.at(ivalue);
1253 
1254  // create ensemble
1255  TTree * tree = PerformEnsembleTest(parameters, nensembles);
1256 
1257  // write tree
1258  tree->Write();
1259 
1260  // close file
1261  file->Close();
1262 
1263  // free memory
1264  delete file;
1265  }
1266 
1267  // ---- change directory ---- //
1268 
1269  ret = chdir("../");
1270 
1271  BCLog::OutSummary("Calibration analysis ran successfully");
1272 
1273  // no error
1274  return 1;
1275 }
1276 
1277 // ---------------------------------------------------------
bool GetFlagSystematicActive()
static BCLog::LogLevel GetLogLevelFile()
Definition: BCLog.h:65
int SetData(const char *channelname, TH1D hist, double minimum=-1, double maximum=-1)
Definition: BCMTF.cxx:207
bool GetFlagChannelActive()
Definition: BCMTFChannel.h:80
static void SetLogLevel(BCLog::LogLevel loglevelscreen, BCLog::LogLevel loglevelfile)
Definition: BCLog.h:94
double GetRMS()
Definition: BCH1D.h:87
int GetNChannels()
Definition: BCMTF.h:65
TTree * PerformEnsembleTest(const std::vector< double > &parameters, int nensembles, std::string options="")
int PerformCalibrationAnalysis(const char *dirname, const std::vector< double > &default_parameters, int index, const std::vector< double > &parametervalues, int nensembles=1000)
void PrintResults(const char *file)
Definition: BCModel.cxx:816
std::vector< TH1D > BuildEnsemble(const std::vector< double > &parameters, std::string options="")
void SetHistogram(TH1D *hist, double norm=1)
A helper class for BCMTFAnalysisFacility storing information.
TTree * BuildEnsembles(const std::vector< double > &parameters, int nensembles, std::string options="")
double GetMean()
Definition: BCH1D.h:58
LogLevel
Definition: BCLog.h:45
BCMTFTemplate * GetTemplate(int index)
Definition: BCMTFChannel.h:68
void AddContribution(const char *name, TH1D hist)
TH1D FluctuateHistogram(std::string options="GZ", double norm=1)
double Expectation(int channelindex, int binindex, const std::vector< double > &parameters)
Definition: BCMTF.cxx:642
int GetNSystematics()
Definition: BCMTF.h:75
double GetOriginalNorm()
Definition: BCMTFTemplate.h:81
void SetFlagSystematicActive(bool flag)
double GetMedian()
Definition: BCH1D.h:67
TH1D * GetHistogram()
Definition: BCMTFTemplate.h:71
double GetMode()
Definition: BCH1D.cxx:52
double CalculateCash(int channelindex, const std::vector< double > &parameters)
Definition: BCMTF.cxx:1098
int PerformSingleChannelAnalyses(const char *dirname, const char *options="")
int GetNProcesses()
Definition: BCMTF.h:70
std::string GetName()
Definition: BCMTFChannel.h:56
A class describing a physics channel.
Definition: BCMTFChannel.h:33
BCMTFTemplate * GetData()
Definition: BCMTFChannel.h:61
A class for handling 1D distributions.
Definition: BCH1D.h:31
static const char * ToString(BCLog::LogLevel)
Definition: BCLog.cxx:155
void SetFlagChannelActive(bool flag)
Definition: BCMTFChannel.h:138
BCMTFSystematic * GetSystematic(int index)
Definition: BCMTF.h:120
std::vector< TH1D > MatrixToHistograms(const std::vector< std::vector< double > > &matrix)
double GetQuantile(double probablity)
Definition: BCH1D.cxx:58
BCMTFChannel * GetChannel(int index)
Definition: BCMTF.h:108
std::string GetName()
double GetNorm()
Definition: BCMTFTemplate.h:76
double CalculateChi2(int channelindex, const std::vector< double > &parameters)
Definition: BCMTF.cxx:1039
static BCLog::LogLevel GetLogLevelScreen()
Definition: BCLog.h:71
int PerformSingleSystematicAnalyses(const char *dirname, const char *options="")
A class for fitting several templates to a data set.
Definition: BCMTF.h:38
const std::string & GetName() const
Definition: BCModel.h:85
A class for managing log messages.
Definition: BCLog.h:29
A class desribing a systematic uncertainty.