00001 #include <TFile.h>
00002 #include <TTree.h>
00003 #include <TROOT.h>
00004 #include <TRandom3.h>
00005 #include <TPostScript.h>
00006 #include <TCanvas.h>
00007
00008 #include <math.h>
00009 #include <iostream>
00010
00011 #include <BAT/BCLog.h>
00012 #include <BAT/BCH1D.h>
00013
00014 #include "BCTemplateFitter.h"
00015 #include "BCTemplateEnsembleTest.h"
00016
00017 using namespace std;
00018
00019
00020 BCTemplateEnsembleTest::BCTemplateEnsembleTest()
00021 : fTemplateFitter(0)
00022 , fFile(0)
00023 , fTree(0)
00024 , fEnsembleCounter(0)
00025 , fEnsembleExpectation(0)
00026 , fNEnsembles(0)
00027 , fFlagMCMC(false)
00028 {
00029 fRandom = new TRandom3(0);
00030 }
00031
00032
00033 BCTemplateEnsembleTest::~BCTemplateEnsembleTest()
00034 {
00035 if (fRandom)
00036 delete fRandom;
00037 }
00038
00039
00040 int BCTemplateEnsembleTest::SetEnsembleTemplate(TH1D hist)
00041 {
00042
00043 double integral = hist.Integral();
00044
00045
00046 if (integral <= 0) {
00047 std::cout << "Template not valid. Integral is lower or equal to 0." << std::endl;
00048 return 0;
00049 }
00050
00051
00052 fEnsembleTemplate = hist;
00053
00054
00055 fEnsembleTemplate.Scale(1.0/integral);
00056
00057
00058 return 1;
00059 };
00060
00061
00062 int BCTemplateEnsembleTest::PerformEnsembleTest(TTree* tree)
00063 {
00064
00065 BCLog::LogLevel ll = BCLog::GetLogLevelScreen();
00066 BCLog::SetLogLevel(BCLog::nothing);
00067
00068
00069 fTemplateFitter->Initialize();
00070
00071
00072 PrepareTree();
00073
00074
00075 int npar = fTemplateFitter->GetNParameters();
00076
00077
00078 if (tree) {
00079 fTemplateParameters = std::vector<double>(npar);
00080 for (int i = 0; i < npar; ++i) {
00081 tree->SetBranchAddress(Form("Parameter%i", i), &(fTemplateParameters[i]));
00082 }
00083 }
00084
00085
00086 for(int j = 0; j < fNEnsembles; j++){
00087
00088
00089 if ((j+1) % 100 == 0 && j > 0)
00090 std::cout << "Fraction of ensembles analyzed: " << double(j+1) / double(fNEnsembles) * 100 << "%" << std::endl;
00091
00092
00093 if (tree) {
00094 int index = fRandom->Uniform(tree->GetEntries());
00095 tree->GetEntry(index);
00096 }
00097
00098
00099 TH1D* ensemble = BuildEnsemble();
00100
00101
00102 fTemplateFitter->SetData(*ensemble);
00103
00104
00105 fTemplateFitter->FindMode();
00106
00107
00108 if(fFlagMCMC) {
00109 fTemplateFitter->MCMCInitialize();
00110
00111 fTemplateFitter->MarginalizeAll();
00112
00113
00114 fTemplateFitter->FindMode(fTemplateFitter->GetBestFitParameters());
00115
00116
00117 for (int i = 0; i < npar; ++i) {
00118 BCH1D* hist = fTemplateFitter->GetMarginalized(fTemplateFitter->GetParameter(i));
00119 fOutParModeMarg[i] = hist->GetMode();
00120 fOutParMedianMarg[i] = hist->GetMedian();
00121 fOutParMeanMarg[i] = hist->GetMean();
00122 fOutParRMSMarg[i] = hist->GetRMS();
00123 fOutParErrorUpMarg[i] = hist->GetQuantile(0.84)-hist->GetMode();
00124 fOutParErrorDownMarg[i] = hist->GetMode()-hist->GetQuantile(0.16);
00125 fOutParQuantile5Marg[i] = hist->GetQuantile(0.05);
00126 fOutParQuantile10Marg[i] = hist->GetQuantile(0.10);
00127 fOutParQuantile90Marg[i] = hist->GetQuantile(0.90);
00128 fOutParQuantile95Marg[i] = hist->GetQuantile(0.95);
00129 fOutParPullMarg[i] = -1;
00130 double error = 0.5 * (fOutParErrorUpMarg.at(i) + fOutParErrorDownMarg.at(i));
00131 if (error > 0)
00132 fOutParPullMarg[i] = (fOutParModeMarg.at(i) - fTemplateParameters.at(i)) / ( error );
00133 }
00134 fOutChi2Marg = fTemplateFitter->CalculateChi2( fTemplateFitter->GetBestFitParametersMarginalized() );
00135 fOutChi2ProbMarg = fTemplateFitter->CalculateChi2Prob(fTemplateFitter->GetBestFitParametersMarginalized());
00136 }
00137
00138 if (fFlagMCMC) {
00139 int nratios = fTemplateFitter->GetNRatios();
00140 for (int i = 0; i < nratios; ++i) {
00141 TH1D histtemp = fTemplateFitter->GetHistRatio1D(i);
00142 BCH1D * hist = new BCH1D( &histtemp );
00143 fOutRatioModeMarg[i] = hist->GetMode();
00144 fOutRatioMedianMarg[i] = hist->GetMedian();
00145 fOutRatioMeanMarg[i] = hist->GetMean();
00146 fOutRatioRMSMarg[i] = hist->GetRMS();
00147 fOutRatioErrorUpMarg[i] = hist->GetQuantile(0.84)-hist->GetMode();
00148 fOutRatioErrorDownMarg[i] = hist->GetMode()-hist->GetQuantile(0.16);
00149 fOutRatioQuantile5Marg[i] = hist->GetQuantile(0.05);
00150 fOutRatioQuantile10Marg[i] = hist->GetQuantile(0.10);
00151 fOutRatioQuantile90Marg[i] = hist->GetQuantile(0.90);
00152 fOutRatioQuantile95Marg[i] = hist->GetQuantile(0.95);
00153 }
00154 }
00155
00156
00157 fOutParValue = fTemplateParameters;
00158 fOutParModeGlobal = fTemplateFitter->GetBestFitParameters();
00159 fOutParErrorUpGlobal = fTemplateFitter->GetBestFitParameterErrors();
00160 fOutParErrorDownGlobal = fTemplateFitter->GetBestFitParameterErrors();
00161 fOutChi2Global = fTemplateFitter->CalculateChi2( fTemplateFitter->GetBestFitParameters() );
00162 fOutNDF = fTemplateFitter->GetNDF();
00163 fOutChi2ProbGlobal = fTemplateFitter->CalculateChi2Prob(fTemplateFitter->GetBestFitParameters());
00164 fOutKSProb = fTemplateFitter->CalculateKSProb();
00165 fOutPValue = fTemplateFitter->CalculatePValue();
00166 fOutNEvents = int(fTemplateFitter->GetData().Integral());
00167
00168 for (int i = 0; i < npar; ++i) {
00169 fOutParPullGlobal[i] = -1;
00170 double error = 0.5 * (fOutParErrorUpGlobal.at(i) + fOutParErrorDownGlobal.at(i));
00171 if (error > 0)
00172 fOutParPullGlobal[i] = (fOutParModeGlobal.at(i) - fTemplateParameters.at(i)) / ( error );
00173 }
00174
00175
00176 fTree->Fill();
00177 }
00178
00179
00180 BCLog::SetLogLevel(ll);
00181
00182
00183 return 1;
00184 }
00185
00186
00187 TH1D* BCTemplateEnsembleTest::BuildEnsemble()
00188 {
00189
00190 int nbins = fTemplateFitter->GetData().GetNbinsX();
00191
00192
00193 TH1D* ensemble = new TH1D(fTemplateFitter->GetData());
00194
00195
00196 fEnsembleCounter++;
00197
00198
00199 std::vector<double> parameters = fTemplateParameters;
00200
00201
00202 for(int ibin = 1; ibin <= nbins; ++ibin){
00203 double nexp = fTemplateFitter->Expectation(ibin, parameters);
00204 double nobs = gRandom->Poisson(nexp);
00205
00206
00207 ensemble->SetBinContent(ibin, nobs);
00208 }
00209
00210
00211 return ensemble;
00212 }
00213
00214
00215 int BCTemplateEnsembleTest::Write(const char * filename)
00216 {
00217
00218 fFile = new TFile(filename, "RECREATE");
00219
00220
00221 fTree->Write();
00222
00223
00224 fFile->Close();
00225
00226
00227 delete fFile;
00228
00229
00230 return 1;
00231 }
00232
00233
00234 int BCTemplateEnsembleTest::PrepareTree()
00235 {
00236
00237 if (fTree)
00238 delete fTree;
00239
00240
00241 fTree = new TTree("fTree", "fTree");
00242
00243
00244 int npar = fTemplateFitter->GetNParameters();
00245 int nratios = fTemplateFitter->GetNRatios();
00246
00247
00248 fOutParValue.assign(npar, 0);
00249 fOutParModeGlobal.assign(npar, 0);
00250 fOutParErrorUpGlobal.assign(npar, 0);
00251 fOutParErrorDownGlobal.assign(npar, 0);
00252 fOutParPullGlobal.assign(npar, 0);
00253 fOutParModeMarg.assign(npar, 0);
00254 fOutParMeanMarg.assign(npar, 0);
00255 fOutParMedianMarg.assign(npar, 0);
00256 fOutParRMSMarg.assign(npar, 0);
00257 fOutParErrorUpMarg.assign(npar, 0);
00258 fOutParErrorDownMarg.assign(npar, 0);
00259 fOutParPullMarg.assign(npar, 0);
00260 fOutParQuantile5Marg.assign(npar, 0);
00261 fOutParQuantile10Marg.assign(npar, 0);
00262 fOutParQuantile90Marg.assign(npar, 0);
00263 fOutParQuantile95Marg.assign(npar, 0);
00264 fOutRatioModeMarg.assign(nratios, 0);
00265 fOutRatioMeanMarg.assign(nratios, 0);
00266 fOutRatioMedianMarg.assign(nratios, 0);
00267 fOutRatioRMSMarg.assign(nratios, 0);
00268 fOutRatioErrorUpMarg.assign(nratios, 0);
00269 fOutRatioErrorDownMarg.assign(nratios, 0);
00270 fOutRatioQuantile5Marg.assign(nratios, 0);
00271 fOutRatioQuantile10Marg.assign(nratios, 0);
00272 fOutRatioQuantile90Marg.assign(nratios, 0);
00273 fOutRatioQuantile95Marg.assign(nratios, 0);
00274
00275 fTree->Branch("chi2_global", &fOutChi2Global, "chi2 (global)/D");
00276 fTree->Branch("ndf", &fOutNDF, "ndf/I");
00277 fTree->Branch("chi2prob_global", &fOutChi2ProbGlobal, "chi2 prob probability (global)/D");
00278 fTree->Branch("KSprob", &fOutKSProb, "KS probability/D");
00279 fTree->Branch("pvalue", &fOutPValue, "p-value/D");
00280 fTree->Branch("nevents", &fOutNEvents, "n events/I");
00281
00282 for (int i = 0; i < npar; ++i) {
00283
00284 fTree->Branch(Form("parameter_%i", i), &fOutParValue[i], Form("parameter_%i/D", i));
00285 fTree->Branch(Form("par_global_mode_par_%i", i), &fOutParModeGlobal[i], Form("par_global_Mode_par_%i/D", i));
00286 fTree->Branch(Form("par_global_error_up_par_%i", i), &fOutParErrorUpGlobal[i], Form("par_global_error_up_par_%i/D", i));
00287 fTree->Branch(Form("par_global_error_down_par_%i", i), &fOutParErrorDownGlobal[i], Form("par_global_error_down_par_%i/D", i));
00288 fTree->Branch(Form("par_global_pull_par_%i", i), &fOutParPullGlobal[i], Form("par_global_pull_par_%i/D", i));
00289
00290 if(fFlagMCMC) {
00291 fTree->Branch(Form("par_marg_mode_par_%i", i), &fOutParModeMarg[i], Form("par_marg_mode_par_%i/D", i));
00292 fTree->Branch(Form("par_marg_mean_par_%i", i), &fOutParMeanMarg[i], Form("par_marg_mean_par_%i/D", i));
00293 fTree->Branch(Form("par_marg_median_par_%i", i), &fOutParMedianMarg[i], Form("par_marg_median_par_%i/D", i));
00294 fTree->Branch(Form("par_marg_rms_par_%i", i), &fOutParRMSMarg[i], Form("par_marg_rms_par_%i/D", i));
00295 fTree->Branch(Form("par_marg_error_up_par_%i", i), &fOutParErrorUpMarg[i], Form("par_marg_ErrorUp_par_%i/D", i));
00296 fTree->Branch(Form("par_marg_error_down_par_%i", i), &fOutParErrorDownMarg[i], Form("par_marg_error_down_par_%i/D", i));
00297 fTree->Branch(Form("par_marg_pull_par_%i", i), &fOutParPullMarg[i], Form("par_marg_pull_par_%i/D", i));
00298 fTree->Branch(Form("par_marg_quantile5_par_%i", i), &fOutParQuantile5Marg[i], Form("par_marg_Quantile5_par_%i/D", i));
00299 fTree->Branch(Form("par_marg_quantile10_par_%i", i), &fOutParQuantile10Marg[i], Form("par_marg_Quantile10_par_%i/D", i));
00300 fTree->Branch(Form("par_marg_quantile90_par_%i", i), &fOutParQuantile90Marg[i], Form("par_marg_Quantile90_par_%i/D", i));
00301 fTree->Branch(Form("par_marg_quantile95_par_%i", i), &fOutParQuantile95Marg[i], Form("par_marg_Quantile95_par_%i/D", i));
00302 }
00303 }
00304
00305 if (fFlagMCMC) {
00306 fTree->Branch("chi2_marg", &fOutChi2Marg, "chi2 (marginalized)/D");
00307 fTree->Branch("chi2prob_marg", &fOutChi2ProbMarg, "chi2 prob probability (marginalized)/D");
00308
00309 for (int i = 0; i < nratios; ++i) {
00310 fTree->Branch(Form("ratio_marg_mode_ratio_%i", i), &fOutRatioModeMarg[i], Form("ratio_marg_mode_ratio_%i/D", i));
00311 fTree->Branch(Form("ratio_marg_mean_ratio_%i", i), &fOutRatioMeanMarg[i], Form("ratio_marg_mean_ratio_%i/D", i));
00312 fTree->Branch(Form("ratio_marg_median_ratio_%i", i), &fOutRatioMedianMarg[i], Form("ratio_marg_median_ratio_%i/D", i));
00313 fTree->Branch(Form("ratio_marg_rms_ratio_%i", i), &fOutRatioRMSMarg[i], Form("ratio_marg_rms_ratio_%i/D", i));
00314 fTree->Branch(Form("ratio_marg_error_up_ratio_%i", i), &fOutRatioErrorUpMarg[i], Form("ratio_marg_ErrorUp_ratio_%i/D", i));
00315 fTree->Branch(Form("ratio_marg_error_down_ratio_%i", i), &fOutRatioErrorDownMarg[i], Form("ratio_marg_error_down_ratio_%i/D", i));
00316 fTree->Branch(Form("ratio_marg_quantile5_ratio_%i", i), &fOutRatioQuantile5Marg[i], Form("ratio_marg_Quantile5_ratio_%i/D", i));
00317 fTree->Branch(Form("ratio_marg_quantile10_ratio_%i", i), &fOutRatioQuantile10Marg[i], Form("ratio_marg_Quantile10_ratio_%i/D", i));
00318 fTree->Branch(Form("ratio_marg_quantile90_ratio_%i", i), &fOutRatioQuantile90Marg[i], Form("ratio_marg_Quantile90_ratio_%i/D", i));
00319 fTree->Branch(Form("ratio_marg_quantile95_ratio_%i", i), &fOutRatioQuantile95Marg[i], Form("ratio_marg_Quantile95_ratio_%i/D", i));
00320 }
00321 }
00322
00323
00324 return 1;
00325 }
00326
00327
00328
00329 void BCTemplateEnsembleTest::PrintPulls(const char* filename)
00330 {
00331
00332 TPostScript * ps = new TPostScript(filename);
00333
00334
00335 TCanvas * canvas = new TCanvas();
00336
00337 canvas->Update();
00338 ps->NewPage();
00339 canvas->cd();
00340
00341
00342 int npar = fTemplateFitter->GetNParameters();
00343
00344
00345 std::vector<TH1D*> histcontainer = std::vector<TH1D*>(0);
00346
00347
00348 for (int j = 0; j < npar; ++j) {
00349 TH1D* hist = new TH1D("", "Pull;N", 11, -5.5, 5.5);
00350 histcontainer.push_back(hist);
00351 }
00352
00353
00354 for (int i = 0; i < fNEnsembles; ++i) {
00355
00356
00357 fTree->GetEntry(i);
00358
00359
00360 for (int j = 0; j < npar; ++j) {
00361 histcontainer[j]->Fill(fOutParPullGlobal[j]);
00362 }
00363 }
00364
00365
00366 for (int j = 0; j < npar; ++j) {
00367
00368 canvas->Update();
00369 ps->NewPage();
00370 canvas->cd();
00371
00372 canvas->cd();
00373 histcontainer.at(j)->Draw();
00374 }
00375
00376 canvas->Update();
00377 ps->Close();
00378
00379
00380 delete ps;
00381 delete canvas;
00382
00383 }
00384
00385