00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <TCanvas.h>
00011 #include <TPostScript.h>
00012 #include <TLegend.h>
00013 #include <TH2D.h>
00014 #include <TGraphErrors.h>
00015 #include <TGraphAsymmErrors.h>
00016 #include <TStyle.h>
00017 #include <TLatex.h>
00018 #include <TMarker.h>
00019 #include <TArrow.h>
00020 #include <TGaxis.h>
00021 #include <TF1.h>
00022 #include <TLine.h>
00023
00024 #include <iostream>
00025 #include <fstream>
00026
00027 #include <BAT/BCModel.h>
00028 #include <BAT/BCSummaryPriorModel.h>
00029 #include <BAT/BCH1D.h>
00030 #include <BAT/BCH2D.h>
00031 #include <BAT/BCLog.h>
00032
00033 #include <BAT/BCSummaryTool.h>
00034
00035 unsigned int BCSummaryTool::fHCounter=0;
00036
00037
00038 BCSummaryTool::BCSummaryTool()
00039 : fModel(0)
00040 , fPriorModel(0)
00041 , fFlagInfoMarg(false)
00042 , fFlagInfoOpt(false)
00043 {
00044
00045 fSumProb.push_back(0.05);
00046 fSumProb.push_back(0.10);
00047 fSumProb.push_back(0.1587);
00048 fSumProb.push_back(0.50);
00049 fSumProb.push_back(0.8413);
00050 fSumProb.push_back(0.90);
00051 fSumProb.push_back(0.95);
00052
00053
00054 gStyle->SetPaintTextFormat(".2g");
00055 }
00056
00057
00058 BCSummaryTool::BCSummaryTool(BCModel * model)
00059 : fModel(model)
00060 , fPriorModel(0)
00061 , fFlagInfoMarg(false)
00062 , fFlagInfoOpt(false)
00063 {
00064
00065 fSumProb.push_back(0.05);
00066 fSumProb.push_back(0.10);
00067 fSumProb.push_back(0.1587);
00068 fSumProb.push_back(0.50);
00069 fSumProb.push_back(0.8413);
00070 fSumProb.push_back(0.90);
00071 fSumProb.push_back(0.95);
00072
00073
00074 gStyle->SetPaintTextFormat(".2g");
00075 }
00076
00077
00078 BCSummaryTool::~BCSummaryTool()
00079 {
00080 delete fPriorModel;
00081 }
00082
00083
00084 int BCSummaryTool::CopySummaryData()
00085 {
00086
00087 if (!fModel)
00088 return 0;
00089
00090
00091 fParName.clear();
00092 fParMin.clear();
00093 fParMax.clear();
00094 fMean.clear();
00095 fMargMode.clear();
00096 fGlobalMode.clear();
00097 fQuantiles.clear();
00098 fSmallInt.clear();
00099 fRMS.clear();
00100 fCorrCoeff.clear();
00101
00102
00103 int npar = fModel->GetNParameters();
00104 int nquantiles = int( fSumProb.size() );
00105
00106
00107 for (int i = 0; i < npar; ++i) {
00108
00109
00110 fParName.push_back( (fModel->GetParameter(i)->GetName()) );
00111 fParMin.push_back( fModel->GetParameter(i)->GetLowerLimit() );
00112 fParMax.push_back( fModel->GetParameter(i)->GetUpperLimit() );
00113
00114
00115 if (fModel->MCMCGetFlagRun()) {
00116 fFlagInfoMarg = true;
00117 BCH1D * bch1d_temp = fModel->GetMarginalized( fModel->GetParameter(i) );
00118 fMean.push_back( bch1d_temp->GetMean() );
00119 fRMS.push_back( bch1d_temp->GetRMS() );
00120 fMargMode.push_back( bch1d_temp->GetMode() );
00121 for (int j = 0; j < nquantiles; ++j)
00122 fQuantiles.push_back( bch1d_temp->GetQuantile( fSumProb.at(j) ) );
00123 std::vector <double> intervals = bch1d_temp->GetSmallestIntervals();
00124 int nintervals = int(intervals.size() / 5);
00125 fSmallInt.push_back(nintervals);
00126 fSmallInt.insert( fSmallInt.end(), intervals.begin(), intervals.end() );
00127
00128
00129 for (int j = 0; j < npar; ++j) {
00130 if (i!=j) {
00131 BCH2D * bch2d_temp = fModel->GetMarginalized(fModel->GetParameter(i),fModel->GetParameter(j));
00132 fCorrCoeff.push_back( bch2d_temp->GetHistogram()->GetCorrelationFactor() );
00133 }
00134 else
00135 fCorrCoeff.push_back(1.0);
00136 }
00137 }
00138 else {
00139
00140 }
00141
00142
00143 if ((fModel->GetBestFitParameters()).size() > 0) {
00144 fFlagInfoOpt = true;
00145 fGlobalMode.push_back ( (fModel->GetBestFitParameters()).at(i) );
00146 }
00147 else {
00148
00149 }
00150 }
00151
00152
00153 return 1;
00154 };
00155
00156
00157 int BCSummaryTool::PrintParameterPlot(const char * filename)
00158 {
00159
00160 if (!CopySummaryData())
00161 return 0;
00162
00163
00164 int npar = fModel->GetNParameters();
00165 int nquantiles = int( fSumProb.size() );
00166
00167
00168 TH1D * hist_axes = new TH1D(
00169 TString::Format("hist_axes_par_%d",getNextIndex()),
00170 ";;Scaled parameter range [a.u.]",npar, -0.5, npar-0.5);
00171 hist_axes->SetStats(kFALSE);
00172 for (int i = 0; i < npar; ++i)
00173 hist_axes->GetXaxis()->SetBinLabel( i+1, fParName.at(i).c_str() );
00174
00175 hist_axes->GetXaxis()->SetLabelSize(0.06);
00176 hist_axes->GetXaxis()->SetTickLength(0.0);
00177 hist_axes->GetYaxis()->SetRangeUser(-0.1, 1.1);
00178 hist_axes->GetYaxis()->SetTickLength(0.0);
00179
00180
00181 TGraphErrors * graph_quantiles = new TGraphErrors(npar*nquantiles);
00182 graph_quantiles->SetMarkerSize(0);
00183 graph_quantiles->SetLineColor(38);
00184 graph_quantiles->SetLineStyle(2);
00185
00186 TGraphErrors * graph_mean = new TGraphErrors(npar);
00187 graph_mean->SetMarkerColor(kBlack);
00188 graph_mean->SetMarkerStyle(20);
00189
00190 TGraphErrors * graph_mode = new TGraphErrors(npar);
00191 graph_mode->SetMarkerColor(kRed);
00192 graph_mode->SetMarkerStyle(20);
00193
00194 TGraphAsymmErrors * graph_intervals = new TGraphAsymmErrors(0);
00195 graph_intervals->SetFillColor(kYellow);
00196 graph_intervals->SetLineStyle(2);
00197 graph_intervals->SetLineColor(kRed);
00198 graph_intervals->SetMarkerSize(0);
00199
00200
00201 int indexintervals = 0;
00202
00203
00204 if (fFlagInfoMarg) {
00205 for (int i = 0; i < npar; ++i) {
00206 for (int j = 0; j < nquantiles; ++j) {
00207 graph_quantiles->SetPoint(i*nquantiles+j,double(i),
00208 (fQuantiles.at(i*nquantiles+j) - fParMin.at(i))/(fParMax.at(i)-fParMin.at(i)));
00209 graph_quantiles->SetPointError(i*nquantiles+j, 0.5, 0.0);
00210 }
00211 }
00212 }
00213
00214
00215 if (fFlagInfoMarg) {
00216 for (int i = 0; i < npar; ++i) {
00217
00218 graph_mean->SetPoint(i, double(i), (fMean.at(i) - fParMin.at(i))/(fParMax.at(i)-fParMin.at(i)));
00219 graph_mean->SetPointError(i, 0.0, fRMS.at(i)/(fParMax.at(i)-fParMin.at(i)));
00220 }
00221 }
00222
00223
00224 if (fFlagInfoOpt) {
00225 for (int i = 0; i < npar; ++i)
00226 graph_mode->SetPoint(i, double(i), (fGlobalMode.at(i) - fParMin.at(i))/(fParMax.at(i)-fParMin.at(i)));
00227 }
00228
00229
00230 if (fFlagInfoMarg) {
00231 for (int i = 0; i < npar; ++i) {
00232 int nintervals = int(fSmallInt.at(indexintervals++));
00233 for (int j = 0; j < nintervals; ++j) {
00234 double xmin = fSmallInt.at(indexintervals++);
00235 double xmax = fSmallInt.at(indexintervals++);
00236 indexintervals++;
00237 double xlocalmaxpos = fSmallInt.at(indexintervals++);
00238 indexintervals++;
00239 int npoints = graph_intervals->GetN();
00240 graph_intervals->SetPoint(npoints,double(i),
00241 (xlocalmaxpos - fParMin.at(i))/(fParMax.at(i)-fParMin.at(i)));
00242 graph_intervals->SetPointError(npoints,0.5, 0.5,
00243 (xlocalmaxpos - xmin)/(fParMax.at(i)-fParMin.at(i)),
00244 (xmax - xlocalmaxpos)/(fParMax.at(i)-fParMin.at(i)));
00245 }
00246 }
00247 }
00248
00249
00250 TLegend * legend = new TLegend(0.15, 0.88, 0.85, 0.99);
00251 legend->SetBorderSize(0);
00252 legend->SetFillColor(0);
00253
00254
00255 TLatex * latex = new TLatex();
00256 latex->SetTextSize(0.02);
00257
00258
00259 TLine * line_top = new TLine(-0.5, 1.0, npar-0.5, 1.0);
00260 line_top->SetLineColor(kBlack);
00261 line_top->SetLineStyle(1);
00262 line_top->SetLineWidth(2);
00263
00264 TLine * line_bot = new TLine(-0.5, 0.0, npar-0.5, 0.0);
00265 line_bot->SetLineColor(kBlack);
00266 line_bot->SetLineStyle(1);
00267 line_bot->SetLineWidth(2);
00268
00269
00270 TCanvas * c_par = new TCanvas(TString::Format("c_par_%d",getNextIndex()));
00271 c_par->cd();
00272 hist_axes->Draw();
00273 line_top->Draw();
00274 line_bot->Draw();
00275 if (fFlagInfoMarg) {
00276 graph_intervals->DrawClone("SAME2");
00277 for (int i = 0; i < graph_intervals->GetN(); ++i)
00278 graph_intervals->SetPointError(i, 0.5, 0.5, 0.0, 0.0);
00279 graph_intervals->Draw("SAMEPZ");
00280 graph_quantiles->Draw("SAMEPZ");
00281 graph_mean->Draw("SAMEP");
00282 legend->AddEntry(graph_quantiles, "Quantiles (5%, 10%, 16%, 50%, 84%, 90%, 95%)", "L");
00283 legend->AddEntry(graph_mean, "Mean and RMS", "LEP");
00284 legend->AddEntry(graph_intervals, "Smallest 68% intervals and local modes", "FL");
00285 }
00286 if (fFlagInfoOpt) {
00287 graph_mode->Draw("SAMEP");
00288 legend->AddEntry(graph_mode, "Global mode", "P");
00289 }
00290 for (int i = 0; i < npar;++i) {
00291
00292
00293 latex->DrawLatex(double(i)-0.1, 0.010-0.07, Form("%+3.3f", fParMin.at(i)));
00294 latex->DrawLatex(double(i)-0.1, 0.965+0.07, Form("%+3.3f", fParMax.at(i)));
00295 }
00296 latex->SetNDC();
00297 latex->DrawLatex(0.9, 0.175, "Par. min.");
00298 latex->DrawLatex(0.9, 0.83, "Par. max.");
00299 legend->Draw("SAME");
00300 gPad->RedrawAxis();
00301 c_par->Print(filename);
00302
00303
00304 return 1;
00305 }
00306
00307
00308 int BCSummaryTool::PrintCorrelationPlot(const char * filename)
00309 {
00310
00311 if (!CopySummaryData())
00312 return 0;
00313
00314
00315 if (!fFlagInfoMarg)
00316 return 0;
00317
00318
00319 int npar = fModel->GetNParameters();
00320
00321
00322 TH2D * hist_corr = new TH2D(
00323 TString::Format("hist_corr_%d",getNextIndex()),
00324 ";;",npar, -0.5, npar-0.5,npar, -0.5, npar-0.5);
00325 hist_corr->SetStats(kFALSE);
00326 hist_corr->GetXaxis()->SetTickLength(0.0);
00327
00328 hist_corr->GetYaxis()->SetTickLength(0.0);
00329
00330 hist_corr->GetZaxis()->SetRangeUser(-1.0, 1.0);
00331
00332 for (int i = 0; i < npar; ++i) {
00333 hist_corr->GetXaxis()->SetLabelSize(0.06);
00334 hist_corr->GetYaxis()->SetLabelSize(0.06);
00335 if (npar < 5) {
00336 hist_corr->GetXaxis()->SetBinLabel( i+1, fParName.at(i).c_str() );
00337 hist_corr->GetYaxis()->SetBinLabel( npar-i, fParName.at(i).c_str() );
00338 }
00339 else {
00340 hist_corr->GetXaxis()->SetBinLabel( i+1, TString::Format("%d",i) );
00341 hist_corr->GetYaxis()->SetBinLabel( npar-i, TString::Format("%d",i) );
00342 }
00343 }
00344
00345
00346 for (int i = 0; i < npar; ++i)
00347 for (int j = 0; j < npar; ++j) {
00348 int index = i * npar + j;
00349 double corr = fCorrCoeff.at(index);
00350 hist_corr->SetBinContent(i+1, npar-j, corr);
00351 }
00352
00353
00354 TCanvas * c_corr = new TCanvas(TString::Format("c_corr_%d",getNextIndex()));
00355 c_corr->cd();
00356 hist_corr->Draw("colz text");
00357
00358 TF1 * f = new TF1("fUp","x",-0.5,npar-0.5);
00359 TGaxis * A1 = new TGaxis(-0.5,npar-0.5,npar-0.5,npar-0.5,"fUp",100,"-");
00360 A1->ImportAxisAttributes(hist_corr->GetXaxis());
00361 A1->Draw();
00362
00363
00364
00365 hist_corr->GetXaxis()->SetLabelSize(0.);
00366 hist_corr->Draw("colz text same");
00367
00368
00369 TLine * lA1 = new TLine(-0.5,npar-0.5,npar-0.5,npar-0.5);
00370 lA1->Draw("same");
00371 TLine * lA2 = new TLine(npar-0.5,npar-0.5,npar-0.5,-0.5);
00372 lA2->Draw("same");
00373
00374 gPad->RedrawAxis();
00375 c_corr->Print(filename);
00376
00377 delete f;
00378 delete A1;
00379 delete lA1;
00380 delete lA2;
00381 delete hist_corr;
00382 delete c_corr;
00383
00384
00385 return 1;
00386 }
00387
00388
00389 int BCSummaryTool::PrintKnowlegdeUpdatePlot(const char * filename)
00390 {
00391
00392 CalculatePriorModel();
00393
00394
00395 TPostScript * ps = new TPostScript(filename);
00396
00397
00398 TCanvas * c_update = new TCanvas(TString::Format("c_update_%d",getNextIndex()));
00399
00400 c_update->Update();
00401 ps->NewPage();
00402 c_update->cd();
00403
00404
00405 TLegend * legend1d = new TLegend(0.15, 0.88, 0.85, 0.94);
00406 legend1d->SetBorderSize(0);
00407 legend1d->SetFillColor(0);
00408
00409
00410 int npar = fModel->GetNParameters();
00411 for (int i = 0; i < npar; ++i) {
00412
00413 c_update->Update();
00414 ps->NewPage();
00415 c_update->cd();
00416
00417
00418 BCParameter * par = fModel->GetParameter(i);
00419 TH1D * hist_prior = fPriorModel->GetMarginalized(par)->GetHistogram();
00420 hist_prior->SetLineColor(kRed);
00421 TH1D * hist_posterior = fModel->GetMarginalized(par)->GetHistogram();
00422
00423
00424 if (!i) {
00425 legend1d->AddEntry(hist_prior, "Prior probability", "L");
00426 legend1d->AddEntry(hist_posterior, "Posterior probability", "L");
00427 }
00428
00429
00430 hist_prior->Scale(hist_posterior->Integral()/hist_prior->Integral());
00431
00432
00433 double max_prior = hist_prior->GetMaximum();
00434 double max_posterior = hist_posterior->GetMaximum();
00435 double max = 1.1 * TMath::Max(max_prior, max_posterior);
00436
00437
00438 c_update->cd();
00439 hist_prior->GetXaxis()->SetNdivisions(508);
00440 hist_posterior->GetXaxis()->SetNdivisions(508);
00441 hist_prior->Draw();
00442 hist_posterior->Draw("SAME");
00443 legend1d->Draw("SAME");
00444
00445
00446 hist_prior->GetYaxis()->SetRangeUser(0.0, max);
00447 hist_posterior->GetYaxis()->SetRangeUser(0.0, max);
00448 }
00449
00450
00451 TLegend * legend2d = new TLegend(0.15, 0.88, 0.85, 0.99);
00452 legend2d->SetBorderSize(0);
00453 legend2d->SetFillColor(0);
00454
00455
00456 TMarker * marker_prior = new TMarker();
00457 marker_prior->SetMarkerStyle(24);
00458 marker_prior->SetMarkerColor(kRed);
00459
00460 TMarker * marker_posterior = new TMarker();
00461 marker_posterior->SetMarkerStyle(24);
00462 marker_posterior->SetMarkerColor(kBlack);
00463
00464 TArrow * arrow = new TArrow();
00465 arrow->SetArrowSize(0.02);
00466 arrow->SetLineColor(kBlue);
00467 arrow->SetLineStyle(2);
00468
00469
00470 for (int i = 0; i < npar; ++i) {
00471 for (int j = 0; j < i; ++j) {
00472
00473 c_update->Update();
00474 ps->NewPage();
00475 c_update->cd();
00476
00477
00478 BCParameter * par1 = fModel->GetParameter(i);
00479 BCParameter * par2 = fModel->GetParameter(j);
00480
00481
00482 BCH2D * bch2d_2dprior = fPriorModel->GetMarginalized(par1, par2);
00483 BCH2D * bch2d_2dposterior = fModel->GetMarginalized(par1, par2);
00484
00485
00486 TH2D * hist_2dprior = bch2d_2dprior->GetHistogram();
00487 hist_2dprior->SetLineColor(kRed);
00488 TH2D * hist_2dposterior = bch2d_2dposterior->GetHistogram();
00489
00490
00491 hist_2dprior->Scale(1.0/hist_2dprior->Integral("width"));
00492 hist_2dposterior->Scale(1.0/hist_2dposterior->Integral("width"));
00493
00494
00495 bch2d_2dprior -> CalculateIntegratedHistogram();
00496 bch2d_2dposterior -> CalculateIntegratedHistogram();
00497
00498 double level[1] = {bch2d_2dprior->GetLevel(0.32)};
00499 hist_2dprior->SetContour(1, level);
00500 hist_2dprior->Draw("CONT3");
00501 level[0] = bch2d_2dposterior->GetLevel(0.32);
00502 hist_2dposterior->SetContour(1, level);
00503 hist_2dposterior->Draw("CONT3 SAME");
00504
00505 std::vector <double> mode_prior = fPriorModel->GetBestFitParameters();
00506 std::vector <double> mode_posterior = fModel->GetBestFitParameters();
00507
00508 marker_prior->DrawMarker(mode_prior.at(j), mode_prior.at(i));
00509 marker_posterior->DrawMarker(mode_posterior.at(j), mode_posterior.at(i));
00510 arrow->DrawArrow(mode_prior.at(j), mode_prior.at(i), mode_posterior.at(j), mode_posterior.at(i));
00511
00512 if (i==1 && j == 0) {
00513 legend2d->AddEntry(hist_2dprior, "68% prior contour", "L");
00514 legend2d->AddEntry(hist_2dposterior, "68% posterior contour", "L");
00515 legend2d->AddEntry(marker_prior, "Prior mode", "P");
00516 legend2d->AddEntry(marker_posterior, "Posterior mode", "P");
00517 legend2d->AddEntry(arrow, "Change in mode", "L");
00518 }
00519 legend2d->Draw();
00520 }
00521 }
00522
00523
00524 c_update->Update();
00525 ps->Close();
00526
00527
00528 delete legend1d;
00529 delete legend2d;
00530 delete marker_prior;
00531 delete marker_posterior;
00532 delete arrow;
00533 delete ps;
00534 delete c_update;
00535
00536
00537 return 1;
00538 }
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 int BCSummaryTool::PrintParameterLatex(const char * filename)
00582 {
00583
00584 std::ofstream ofi(filename);
00585 ofi.precision(3);
00586
00587
00588 if(!ofi.is_open()) {
00589 std::cerr << "Couldn't open file " << filename <<std::endl;
00590 return 0;
00591 }
00592
00593
00594 int npar = fModel->GetNParameters();
00595
00596
00597 ofi
00598 << "\\documentclass[11pt, a4paper]{article}" << std::endl
00599 << std::endl
00600 << "\\begin{document}" << std::endl
00601 << std::endl
00602 << "\\begin{table}[ht!]" << std::endl
00603 << "\\begin{center}" << std::endl
00604 <<"\\begin{tabular}{llllllll}" << std::endl
00605 << "\\hline" << std::endl
00606 << "Parameter & Mean & RMS & Gl. mode & Mode & Median & 16\\% quant. & 84\\% quant. \\\\" << std::endl
00607 << "\\hline" << std::endl;
00608
00609 for (int i = 0; i < npar; ++i) {
00610 BCParameter * par = fModel->GetParameter(i);
00611 BCH1D * bch1d = fModel->GetMarginalized(par);
00612 ofi
00613 << par->GetName() << " & "
00614 << bch1d->GetMean() << " & "
00615 << bch1d->GetRMS() << " & "
00616 << fModel->GetBestFitParameters().at(i) << " & "
00617 << bch1d->GetMode() << " & "
00618 << bch1d->GetMedian() << " & "
00619 << bch1d->GetQuantile(0.16) << " & "
00620 << bch1d->GetQuantile(0.84) << " \\\\" << std::endl;
00621 }
00622 ofi
00623 << "\\hline" << std::endl
00624 << "\\end{tabular}" << std::endl
00625 << "\\caption{Summary of the parameter estimates.}" << std::endl
00626 << "\\end{center}" << std::endl
00627 << "\\end{table}" << std::endl
00628 << std::endl
00629 << "\\end{document}" << std::endl;
00630
00631
00632 ofi.close();
00633
00634
00635 return 1;
00636 }
00637
00638
00639 int BCSummaryTool::CalculatePriorModel()
00640 {
00641
00642 delete fPriorModel;
00643
00644 fPriorModel = new BCSummaryPriorModel();
00645
00646
00647 fPriorModel->SetTestModel(fModel);
00648
00649
00650 fPriorModel->PerformAnalysis();
00651
00652
00653 return 1;
00654 }
00655
00656