11 #include "BCMTFAnalysisFacility.h"
14 #include "BCMTFChannel.h"
15 #include "BCMTFComparisonTool.h"
16 #include "BCMTFSystematic.h"
17 #include "BCMTFTemplate.h"
19 #include "../../BAT/BCLog.h"
20 #include "../../BAT/BCH1D.h"
21 #include "../../BAT/BCParameter.h"
36 int HandleChdirError(
int error_code,
const std::string & caller,
const std::string & dir)
41 BCLog::OutError((caller +
": could not change to " + dir).c_str());
48 : fRandom(new TRandom3(0))
49 , fFlagMarginalize(false)
50 , fLogLevel(
BCLog::nothing)
53 BCLog::OutDetail(Form(
"Prepared Analysis Facility for MTF model \'%s\'",mtf->
GetName().c_str()));
65 bool flag_data =
false;
68 if (options.find(
"data") < options.size()) {
76 std::vector<TH1D> histograms;
79 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
88 int nbins = hist.GetNbinsX();
91 for (
int ibin = 1; ibin <= nbins; ++ibin) {
93 double expectation = fMTF->
Expectation(ichannel, ibin, parameters);
94 double observation = fRandom->Poisson(expectation);
96 hist.SetBinContent(ibin, observation);
101 histograms.push_back(hist);
114 BCLog::OutDetail(Form(
"MTF Building %d ensembles for %d channels.",nensembles,nchannels));
117 int nparameters = fMTF->GetNParameters();
120 std::vector<double> parameters(nparameters);
123 for (
int i = 0; i < nparameters; ++i) {
124 tree->SetBranchAddress(Form(
"Parameter%i", i), &(parameters[i]));
128 TTree * tree_out =
new TTree(
"ensembles",
"ensembles");
131 std::vector< std::vector<double> > nbins_matrix;
135 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
143 std::vector<double> nbins_column(nbins);
146 nbins_matrix.push_back(nbins_column);
149 std::vector<double> in_parameters(nparameters);
153 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
161 for (
int ibin = 1; ibin <= nbins; ++ibin) {
163 tree_out->Branch(Form(
"channel_%i_bin_%i", ichannel, ibin),
164 &(nbins_matrix[ichannel])[ibin-1],
"n/D");
168 for (
int i = 0; i < nparameters; ++i) {
169 tree_out->Branch(Form(
"parameter_%i", i), &in_parameters[i], Form(
"parameter_%i/D", i));
173 std::vector<TH1D> histograms;
176 for (
int iensemble = 0; iensemble < nensembles; ++iensemble) {
178 int index = (int) fRandom->Uniform(tree->GetEntries());
179 tree->GetEntry(index);
186 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
194 for (
int ibin = 1; ibin <= nbins; ++ibin) {
196 (nbins_matrix[ichannel])[ibin-1] = histograms.at(ichannel).GetBinContent(ibin);
201 for (
int i = 0; i < nparameters; ++i) {
202 in_parameters[i] = parameters.at(i);
219 BCLog::OutDetail(Form(
"MTF Building %d ensambles for %d channels.",nensembles,nchannels));
222 TTree * tree =
new TTree(
"ensembles",
"ensembles");
225 std::vector< std::vector<double> > nbins_matrix;
229 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
237 std::vector<double> nbins_column(nbins);
240 nbins_matrix.push_back(nbins_column);
244 int nparameters = fMTF->GetNParameters();
246 std::vector<double> in_parameters(nparameters);
250 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
258 for (
int ibin = 1; ibin <= nbins; ++ibin) {
260 tree->Branch(Form(
"channel_%i_bin_%i", ichannel, ibin),
261 &(nbins_matrix[ichannel])[ibin-1],
"n/D");
265 for (
int i = 0; i < nparameters; ++i) {
266 tree->Branch(Form(
"parameter_%i", i), &in_parameters[i], Form(
"parameter_%i/D", i));
270 std::vector<TH1D> histograms;
273 for (
int iensemble = 0; iensemble < nensembles; ++iensemble) {
279 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
287 for (
int ibin = 1; ibin <= nbins; ++ibin) {
289 (nbins_matrix[ichannel])[ibin-1] = histograms.at(ichannel).GetBinContent(ibin);
294 for (
int i = 0; i < nparameters; ++i) {
295 if (parameters.size() > 0)
296 in_parameters[i] = parameters.at(i);
298 in_parameters[i] = 0;
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.");
331 bool flag_mc =
false;
334 if (options.find(
"MC") < options.size()) {
343 if(fLogLevel==BCLog::nothing) {
344 BCLog::OutSummary(
"No log messages for the ensemble fits are going to be printed.");
347 else if(fLogLevel!=lls) {
348 BCLog::OutSummary(Form(
"The log level for the ensemble test is set to \'%s\'.",
BCLog::ToString(fLogLevel)));
356 std::vector<TH1D *> histograms_data(nchannels);
359 std::vector< std::vector<double> > nbins_matrix;
363 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
371 std::vector<double> nbins_column(nbins);
374 nbins_matrix.push_back(nbins_column);
378 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
386 for (
int ibin = 1; ibin <= nbins; ++ibin) {
388 tree->SetBranchAddress(Form(
"channel_%i_bin_%i", ichannel, ibin),
389 &(nbins_matrix[ichannel])[ibin-1]);
394 int nparameters = fMTF->GetNParameters();
397 std::vector<double> out_parameters(nparameters);
399 for (
int i = 0; i < nparameters; ++i) {
400 tree->SetBranchAddress(Form(
"parameter_%i", i), &out_parameters[i]);
405 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
414 TTree * tree_out =
new TTree(
"ensemble_test",
"ensemble test");
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;
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));
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));
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");
472 std::vector<TH1D*> histlist(0);
475 for (
int iensemble = 0; iensemble < nensembles; ++iensemble) {
477 if ((iensemble+1)%100 == 0 && iensemble > 0) {
479 int frac = int (
double(iensemble+1) /
double(nensembles) * 100.);
480 BCLog::OutDetail(Form(
"Fraction of ensembles analyzed: %i%%",frac));
486 int index = iensemble + start;
487 tree->GetEntry(index);
490 std::vector<TH1D> histograms;
496 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
505 fMTF->
SetData(channel->
GetName().c_str(), histograms.at(ichannel));
514 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
519 for (
unsigned int i = 0; i < ntemplates; ++i) {
523 histlist.push_back(temphist);
535 fMTF->ResetResults();
538 if (fFlagMarginalize) {
540 BCLog::OutDetail(Form(
"Running MCMC for ensemble %i",iensemble));
544 fMTF->MarginalizeAll();
547 fMTF->FindMode( fMTF->GetBestFitParameters() );
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;
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();
579 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
587 out_chi2_generated[ichannel] = fMTF->
CalculateChi2( ichannel, out_parameters );
588 out_chi2_mode[ichannel] = fMTF->
CalculateChi2( ichannel, fMTF->GetBestFitParameters() );
591 out_cash_generated[ichannel] = fMTF->
CalculateCash( ichannel, out_parameters );
592 out_cash_mode[ichannel] = fMTF->
CalculateCash( ichannel, fMTF->GetBestFitParameters() );
595 out_nevents_total += out_nevents[ichannel];
598 out_chi2_generated_total += out_chi2_generated[ichannel];
599 out_chi2_mode_total += out_chi2_mode[ichannel];
602 out_cash_generated_total += out_cash_generated[ichannel];
603 out_cash_mode_total += out_cash_mode[ichannel];
615 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
620 for (
unsigned int i = 0; i < ntemplates; ++i) {
623 TH1D * temphist = histlist.at(ichannel * ntemplates + i);
638 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
650 fMTF->ResetResults();
652 BCLog::OutSummary(
"Ensemble test ran successfully.");
662 std::vector<TH1D> histograms;
665 int nchannels = matrix.size();;
668 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
673 std::vector<double> nbins_column = matrix[ichannel];
679 int nbins = hist.GetNbinsX();
682 for (
int ibin = 1; ibin <= nbins; ++ibin) {
683 hist.SetBinContent(ibin, nbins_column.at(ibin-1));
687 histograms.push_back(hist);
698 BCLog::OutSummary(Form(
"Running single channel analysis in directory \'%s\'.",dirname));
703 mkdir(dirname, 0777);
704 int ret = chdir(dirname);
706 return ::HandleChdirError(ret,
"BCMTFAnalysisFacility::PerformSingleChannelAnalyses", dirname);
711 bool flag_syst =
true;
712 bool flag_mcmc =
true;
714 if (std::string(options).find(
"nosyst") < std::string(options).size())
717 if (std::string(options).find(
"mcmc") < std::string(options).size())
727 std::vector<bool> flag_channel(nchannels);
730 std::vector<bool> flag_systematic(nsystematics);
733 std::vector<BCMTFComparisonTool *> ctc;
734 std::vector<BCMTFComparisonTool *> ctc_mcmc;
737 int nparameters = fMTF->GetNParameters();
742 for (
int i = 0; i < nparameters; ++ i) {
749 ctc_mcmc.push_back(ct_mcmc);
755 for (
int isystematic = 0; isystematic < nsystematics; ++isystematic) {
763 if (flag_systematic[isystematic])
770 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
784 fMTF->ResetResults();
787 fMTF->MarginalizeAll();
790 fMTF->FindMode( fMTF->GetBestFitParameters() );
799 fMTF->PrintAllMarginalized(
"marginalized_combined.pdf");
803 for (
int i = 0; i < nparameters; ++ i) {
809 fMTF->GetBestFitParameters().at(i),
810 fMTF->GetBestFitParameterErrors().at(i));
812 BCH1D * hist = fMTF->GetMarginalized( fMTF->GetParameter(i) );
823 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
834 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
845 fMTF->ResetResults();
848 fMTF->MarginalizeAll();
851 fMTF->FindMode( fMTF->GetBestFitParameters() );
860 fMTF->PrintAllMarginalized(Form(
"marginalized_channel_%i.pdf", ichannel));
861 fMTF->
PrintResults(Form(
"results_channel_%i.txt", ichannel));
866 for (
int i = 0; i < nparameters; ++ i) {
872 fMTF->GetBestFitParameters().at(i),
873 fMTF->GetBestFitParameterErrors().at(i));
875 BCH1D * hist = fMTF->GetMarginalized( fMTF->GetParameter(i) );
889 for (
int isystematic = 0; isystematic < nsystematics; ++isystematic) {
894 if (flag_systematic[isystematic])
901 for (
int ichannel = 0; ichannel < nchannels; ++ichannel) {
910 fMTF->ResetResults();
913 TCanvas * c1 =
new TCanvas();
920 c1->Print((std::string(
"overview.pdf")+std::string(
"(")).c_str());
923 for (
int i = 1; i < nparameters-1; ++ i) {
928 c1->Print(
"overview.pdf");
932 ct = ctc.at(nparameters-1);
934 c1->Print((std::string(
"overview.pdf")+std::string(
")")).c_str());
938 TCanvas * c2 =
new TCanvas();
945 c2->Print((std::string(
"overview_mcmc.pdf")+std::string(
"(")).c_str());
948 for (
int i = 1; i < nparameters-1; ++ i) {
953 c2->Print(
"overview_mcmc.pdf");
957 ct_mcmc = ctc_mcmc.at(nparameters-1);
959 c2->Print((std::string(
"overview_mcmc.pdf")+std::string(
")")).c_str());
964 for (
int i = 0; i < nparameters; ++i) {
979 BCLog::OutSummary(
"Single channel analysis ran successfully");
988 BCLog::OutSummary(Form(
"Running single channel systematic analysis in directory \'%s\'.",dirname));
992 mkdir(dirname, 0777);
993 int ret = chdir(dirname);
995 return ::HandleChdirError(ret,
"BCMTFAnalysisFacility::PerformSingleChannelAnalyses", dirname);
1001 bool flag_mcmc =
true;
1003 if (std::string(options).find(
"mcmc") < std::string(options).size())
1013 std::vector<bool> flag_channel(nchannels);
1016 std::vector<bool> flag_systematic(nsystematics);
1019 std::vector<BCMTFComparisonTool *> ctc;
1022 int nparameters = fMTF->GetNParameters();
1027 for (
int i = 0; i < nparameters; ++ i) {
1037 for (
int isystematic = 0; isystematic < nsystematics; ++ isystematic) {
1050 fMTF->ResetResults();
1053 fMTF->MarginalizeAll();
1056 fMTF->FindMode( fMTF->GetBestFitParameters() );
1065 fMTF->PrintAllMarginalized(
"marginalized_all.pdf");
1069 for (
int i = 0; i < nparameters; ++ i) {
1074 fMTF->GetBestFitParameters().at(i),
1075 fMTF->GetBestFitParameterErrors().at(i));
1081 for (
int isystematic = 0; isystematic < nsystematics; ++isystematic) {
1092 for (
int isystematic = 0; isystematic < nsystematics; ++isystematic) {
1102 fMTF->ResetResults();
1105 fMTF->MarginalizeAll();
1108 fMTF->FindMode( fMTF->GetBestFitParameters() );
1117 fMTF->PrintAllMarginalized(Form(
"marginalized_systematic_%i.pdf", isystematic));
1118 fMTF->
PrintResults(Form(
"results_systematic_%i.txt", isystematic));
1123 for (
int i = 0; i < nparameters; ++ i) {
1128 fMTF->GetBestFitParameters().at(i),
1129 fMTF->GetBestFitParameterErrors().at(i));
1140 fMTF->ResetResults();
1143 fMTF->MarginalizeAll();
1146 fMTF->FindMode( fMTF->GetBestFitParameters() );
1155 fMTF->PrintAllMarginalized(
"marginalized_none.pdf");
1159 for (
int i = 0; i < nparameters; ++ i) {
1164 fMTF->GetBestFitParameters().at(i),
1165 fMTF->GetBestFitParameterErrors().at(i));
1173 for (
int isystematic = 0; isystematic < nsystematics; ++isystematic) {
1178 if (flag_systematic[isystematic])
1183 fMTF->ResetResults();
1186 TCanvas * c1 =
new TCanvas();
1193 c1->Print((std::string(
"overview.pdf")+std::string(
"(")).c_str());
1196 for (
int i = 1; i < nparameters-1; ++i) {
1201 c1->Print(
"overview.pdf");
1205 ct = ctc.at(nparameters-1);
1207 c1->Print((std::string(
"overview.pdf")+std::string(
")")).c_str());
1210 for (
int i = 0; i < nparameters; ++i) {
1222 BCLog::OutSummary(
"Single channel analysis ran successfully");
1231 BCLog::OutSummary(Form(
"Running calibration analysis in directory \'%s\'.",dirname));
1235 mkdir(dirname, 0777);
1236 int ret = chdir(dirname);
1238 return ::HandleChdirError(ret,
"BCMTFAnalysisFacility::PerformSingleChannelAnalyses", dirname);
1243 int nvalues = int(parametervalues.size());
1244 for (
int ivalue = 0; ivalue < nvalues; ++ivalue) {
1247 TFile * file = TFile::Open(Form(
"ensemble_%i.root", ivalue),
"RECREATE");
1251 std::vector<double> parameters = default_parameters;
1252 parameters[index] = parametervalues.at(ivalue);
1271 BCLog::OutSummary(
"Calibration analysis ran successfully");
bool GetFlagSystematicActive()
static BCLog::LogLevel GetLogLevelFile()
int SetData(const char *channelname, TH1D hist, double minimum=-1, double maximum=-1)
bool GetFlagChannelActive()
static void SetLogLevel(BCLog::LogLevel loglevelscreen, BCLog::LogLevel loglevelfile)
TTree * PerformEnsembleTest(const std::vector< double > ¶meters, int nensembles, std::string options="")
int PerformCalibrationAnalysis(const char *dirname, const std::vector< double > &default_parameters, int index, const std::vector< double > ¶metervalues, int nensembles=1000)
void PrintResults(const char *file)
std::vector< TH1D > BuildEnsemble(const std::vector< double > ¶meters, std::string options="")
void SetHistogram(TH1D *hist, double norm=1)
TTree * BuildEnsembles(const std::vector< double > ¶meters, int nensembles, std::string options="")
BCMTFTemplate * GetTemplate(int index)
TH1D FluctuateHistogram(std::string options="GZ", double norm=1)
double Expectation(int channelindex, int binindex, const std::vector< double > ¶meters)
void SetFlagSystematicActive(bool flag)
double CalculateCash(int channelindex, const std::vector< double > ¶meters)
BCMTFAnalysisFacility(BCMTF *mtf)
int PerformSingleChannelAnalyses(const char *dirname, const char *options="")
A class describing a physics channel.
BCMTFTemplate * GetData()
A class for handling 1D distributions.
static const char * ToString(BCLog::LogLevel)
void SetFlagChannelActive(bool flag)
BCMTFSystematic * GetSystematic(int index)
std::vector< TH1D > MatrixToHistograms(const std::vector< std::vector< double > > &matrix)
double GetQuantile(double probablity)
BCMTFChannel * GetChannel(int index)
double CalculateChi2(int channelindex, const std::vector< double > ¶meters)
static BCLog::LogLevel GetLogLevelScreen()
int PerformSingleSystematicAnalyses(const char *dirname, const char *options="")
A class for fitting several templates to a data set.
const std::string & GetName() const
A class for managing log messages.
A class desribing a systematic uncertainty.