36 TMVA::MethodInfo::~MethodInfo()
43 if(gROOT->GetListOfCanvases()->FindObject(canvas))
47 void TMVA::MethodInfo::SetResultHists()
49 TString pname =
"purS_" + methodTitle;
50 TString epname =
"effpurS_" + methodTitle;
51 TString ssigname =
"significance_" + methodTitle;
53 sigE = (TH1*)origSigE->Clone(
"sigEffi");
54 bgdE = (TH1*)origBgdE->Clone(
"bgdEffi");
56 Int_t nbins = sigE->GetNbinsX();
57 Double_t low = sigE->GetBinLowEdge(1);
58 Double_t high = sigE->GetBinLowEdge(nbins+1);
59 purS =
new TH1F(pname, pname, nbins, low, high);
60 sSig =
new TH1F(ssigname, ssigname, nbins, low, high);
61 effpurS =
new TH1F(epname, epname, nbins, low, high);
64 sigE->SetTitle( Form(
"Cut efficiencies for %s classifier", methodTitle.Data()) );
67 TMVAGlob::SetSignalAndBackgroundStyle( sigE, bgdE );
68 TMVAGlob::SetSignalAndBackgroundStyle( purS, bgdE );
69 TMVAGlob::SetSignalAndBackgroundStyle( effpurS, bgdE );
70 sigE->SetFillStyle( 0 );
71 bgdE->SetFillStyle( 0 );
72 sSig->SetFillStyle( 0 );
73 sigE->SetLineWidth( 3 );
74 bgdE->SetLineWidth( 3 );
75 sSig->SetLineWidth( 3 );
78 purS->SetFillStyle( 0 );
79 purS->SetLineWidth( 2 );
80 purS->SetLineStyle( 5 );
81 effpurS->SetFillStyle( 0 );
82 effpurS->SetLineWidth( 2 );
83 effpurS->SetLineStyle( 6 );
86 void TMVA::StatDialogMVAEffs::SetNSignal()
88 fNSignal = fSigInput->GetNumber();
91 void TMVA::StatDialogMVAEffs::SetNBackground()
93 fNBackground = fBkgInput->GetNumber();
96 TString TMVA::StatDialogMVAEffs::GetFormula()
99 auto replace_vars = [](TString & f,
char oldLetter,
char newLetter ) {
100 auto pos = f.First(oldLetter);
101 while(pos != kNPOS) {
102 if ( ( pos > 0 && !TString(f[pos-1]).IsAlpha() ) ||
103 ( pos < f.Length()-1 && !TString(f[pos+1]).IsAlpha() ) )
108 pos = f.Index(oldLetter,pos2);
112 TString formula = fFormula;
113 replace_vars(formula,
'S',
'x');
114 replace_vars(formula,
'B',
'y');
121 TString TMVA::StatDialogMVAEffs::GetLatexFormula()
123 TString f = fFormula;
124 f.ReplaceAll(
"(",
"{");
125 f.ReplaceAll(
")",
"}");
126 f.ReplaceAll(
"sqrt",
"#sqrt");
130 void TMVA::StatDialogMVAEffs::Redraw()
132 UpdateSignificanceHists();
136 void TMVA::StatDialogMVAEffs::Close()
141 TMVA::StatDialogMVAEffs::~StatDialogMVAEffs()
144 TIter next(fInfoList);
146 while ( (info = (MethodInfo*)next()) ) {
154 fSigInput->Disconnect();
155 fBkgInput->Disconnect();
156 fDrawButton->Disconnect();
157 fCloseButton->Disconnect();
159 fMain->CloseWindow();
164 TMVA::StatDialogMVAEffs::StatDialogMVAEffs(TString ds,
const TGWindow* p, Float_t ns, Float_t nb) :
177 UInt_t totalWidth = 500;
178 UInt_t totalHeight = 300;
181 fMain =
new TGMainFrame(p, totalWidth, totalHeight, kMainFrame | kVerticalFrame);
183 TGLabel *sigLab =
new TGLabel(fMain,
"Signal events");
184 fMain->AddFrame(sigLab,
new TGLayoutHints(kLHintsLeft | kLHintsTop,5,5,5,5));
186 fSigInput =
new TGNumberEntry(fMain, (Double_t) fNSignal,5,-1,(TGNumberFormat::EStyle) 5);
187 fSigInput->SetLimits(TGNumberFormat::kNELLimitMin,0,1);
188 fMain->AddFrame(fSigInput,
new TGLayoutHints(kLHintsLeft | kLHintsTop,5,5,5,5));
189 fSigInput->Resize(100,24);
191 TGLabel *bkgLab =
new TGLabel(fMain,
"Background events");
192 fMain->AddFrame(bkgLab,
new TGLayoutHints(kLHintsLeft | kLHintsTop,5,5,5,5));
194 fBkgInput =
new TGNumberEntry(fMain, (Double_t) fNBackground,5,-1,(TGNumberFormat::EStyle) 5);
195 fBkgInput->SetLimits(TGNumberFormat::kNELLimitMin,0,1);
196 fMain->AddFrame(fBkgInput,
new TGLayoutHints(kLHintsLeft | kLHintsTop,5,5,5,5));
197 fBkgInput->Resize(100,24);
199 fButtons =
new TGHorizontalFrame(fMain, totalWidth,30);
201 fCloseButton =
new TGTextButton(fButtons,
"&Close");
202 fButtons->AddFrame(fCloseButton,
new TGLayoutHints(kLHintsLeft | kLHintsTop));
204 fDrawButton =
new TGTextButton(fButtons,
"&Draw");
205 fButtons->AddFrame(fDrawButton,
new TGLayoutHints(kLHintsRight | kLHintsTop,15));
207 fMain->AddFrame(fButtons,
new TGLayoutHints(kLHintsLeft | kLHintsBottom,5,5,5,5));
209 fMain->SetWindowName(
"Significance");
210 fMain->SetWMPosition(0,0);
211 fMain->MapSubwindows();
212 fMain->Resize(fMain->GetDefaultSize());
215 fSigInput->Connect(
"ValueSet(Long_t)",
"TMVA::StatDialogMVAEffs",
this,
"SetNSignal()");
216 fBkgInput->Connect(
"ValueSet(Long_t)",
"TMVA::StatDialogMVAEffs",
this,
"SetNBackground()");
220 fDrawButton->Connect(
"Clicked()",
"TMVA::StatDialogMVAEffs",
this,
"Redraw()");
222 fCloseButton->Connect(
"Clicked()",
"TMVA::StatDialogMVAEffs",
this,
"Close()");
225 void TMVA::StatDialogMVAEffs::UpdateCanvases()
227 if (fInfoList==0)
return;
228 if (fInfoList->First()==0)
return;
229 MethodInfo* info = (MethodInfo*)fInfoList->First();
230 if ( info->canvas==0 ) {
234 TIter next(fInfoList);
235 while ( (info = (MethodInfo*)next()) ) {
236 info->canvas->Update();
237 info->rightAxis->SetWmax(1.1*info->maxSignificance);
238 info->canvas->Modified(kTRUE);
239 info->canvas->Update();
240 info->canvas->Paint();
244 void TMVA::StatDialogMVAEffs::UpdateSignificanceHists()
246 TFormula f(
"sigf",GetFormula());
247 TIter next(fInfoList);
249 TString cname =
"Classifier";
250 if (cname.Length() > maxLenTitle) maxLenTitle = cname.Length();
251 TString str = Form(
"%*s ( #signal, #backgr.) Optimal-cut %s NSig NBkg EffSig EffBkg",
252 maxLenTitle, cname.Data(), GetFormulaString().Data() );
253 cout <<
"--- " << setfill(
'=') << setw(str.Length()) <<
"" << setfill(
' ') << endl;
254 cout <<
"--- " << str << endl;
255 cout <<
"--- " << setfill(
'-') << setw(str.Length()) <<
"" << setfill(
' ') << endl;
256 Double_t maxSig = -1;
257 Double_t maxSigErr = -1;
258 while ((info = (MethodInfo*)next())) {
259 for (Int_t i=1; i<=info->origSigE->GetNbinsX(); i++) {
260 Float_t eS = info->origSigE->GetBinContent( i );
261 Float_t S = eS * fNSignal;
262 Float_t B = info->origBgdE->GetBinContent( i ) * fNBackground;
263 info->purS->SetBinContent( i, (S+B==0)?0:S/(S+B) );
265 Double_t sig = f.Eval(S,B);
268 if (GetFormulaString() ==
"S/sqrt(B)") {
269 maxSigErr = sig * sqrt( 1./S + 1./(2.*B));
272 info->sSig->SetBinContent( i, sig );
273 info->effpurS->SetBinContent( i, eS*info->purS->GetBinContent( i ) );
276 info->maxSignificance = info->sSig->GetMaximum();
277 info->maxSignificanceErr = (maxSigErr > 0) ? maxSigErr : 0;
278 info->sSig->Scale(1/info->maxSignificance);
281 PrintResults( info );
283 cout <<
"--- " << setfill(
'-') << setw(str.Length()) <<
"" << setfill(
' ') << endl << endl;
286 void TMVA::StatDialogMVAEffs::ReadHistograms(TFile* file)
289 TIter next(fInfoList);
291 while ( (info = (MethodInfo*)next()) ) {
297 fInfoList =
new TList;
300 TIter next(file->GetDirectory(dataset.Data())->GetListOfKeys());
302 while( (key = (TKey*)next()) ) {
304 if (!TString(key->GetName()).BeginsWith(
"Method_"))
continue;
305 if( ! gROOT->GetClass(key->GetClassName())->InheritsFrom(
"TDirectory") )
continue;
307 cout <<
"--- Found directory: " << ((TDirectory*)key->ReadObj())->GetName() << endl;
309 TDirectory* mDir = (TDirectory*)key->ReadObj();
311 TIter keyIt(mDir->GetListOfKeys());
313 while((titkey = (TKey*)keyIt())) {
314 if( ! gROOT->GetClass(titkey->GetClassName())->InheritsFrom(
"TDirectory") )
continue;
316 MethodInfo* info =
new MethodInfo();
317 TDirectory* titDir = (TDirectory *)titkey->ReadObj();
319 TMVAGlob::GetMethodName(info->methodName,key);
320 TMVAGlob::GetMethodTitle(info->methodTitle,titDir);
321 if (info->methodTitle.Length() > maxLenTitle) maxLenTitle = info->methodTitle.Length();
322 TString hname =
"MVA_" + info->methodTitle;
324 cout <<
"--- Classifier: " << info->methodTitle << endl;
326 info->sig =
dynamic_cast<TH1*
>(titDir->Get( hname +
"_S" ));
327 info->bgd =
dynamic_cast<TH1*
>(titDir->Get( hname +
"_B" ));
328 info->origSigE =
dynamic_cast<TH1*
>(titDir->Get( hname +
"_effS" ));
329 info->origBgdE =
dynamic_cast<TH1*
>(titDir->Get( hname +
"_effB" ));
330 if (info->origSigE==0 || info->origBgdE==0) {
delete info;
continue; }
332 info->SetResultHists();
333 fInfoList->Add(info);
339 void TMVA::StatDialogMVAEffs::DrawHistograms()
342 Int_t countCanvas = 0;
345 const Int_t width = 600;
346 Int_t signifColor = TColor::GetColor(
"#00aa00" );
348 TIter next(fInfoList);
350 while ( (info = (MethodInfo*)next()) ) {
353 TCanvas *c =
new TCanvas( Form(
"canvas%d", countCanvas+1),
354 Form(
"Cut efficiencies for %s classifier",info->methodTitle.Data()),
355 countCanvas*50+200, countCanvas*20, width, Int_t(width*0.78) );
363 TStyle *TMVAStyle = gROOT->GetStyle(
"Plain");
364 TMVAStyle->SetLineStyleString( 5,
"[32 22]" );
365 TMVAStyle->SetLineStyleString( 6,
"[12 22]" );
370 info->effpurS->SetTitle(
"Cut efficiencies and optimal cut value");
371 if (info->methodTitle.Contains(
"Cuts")) {
372 info->effpurS->GetXaxis()->SetTitle(
"Signal Efficiency" );
375 info->effpurS->GetXaxis()->SetTitle( TString(
"Cut value applied on ") + info->methodTitle +
" output" );
377 info->effpurS->GetYaxis()->SetTitle(
"Efficiency (Purity)" );
378 TMVAGlob::SetFrameStyle( info->effpurS );
381 c->SetRightMargin ( 2.0 );
383 info->effpurS->SetMaximum(1.1);
384 info->effpurS->Draw(
"histl");
386 info->purS->Draw(
"samehistl");
389 info->sigE->Draw(
"samehistl");
390 info->bgdE->Draw(
"samehistl");
392 info->sSig->SetLineColor( signifColor );
393 info->sSig->Draw(
"samehistl");
396 info->effpurS->Draw(
"sameaxis" );
399 TLegend *legend1=
new TLegend( c->GetLeftMargin(), 1 - c->GetTopMargin(),
400 c->GetLeftMargin() + 0.4, 1 - c->GetTopMargin() + 0.12 );
401 legend1->SetFillStyle( 1 );
402 legend1->AddEntry(info->sigE,
"Signal efficiency",
"L");
403 legend1->AddEntry(info->bgdE,
"Background efficiency",
"L");
404 legend1->Draw(
"same");
405 legend1->SetBorderSize(1);
406 legend1->SetMargin( 0.3 );
408 TLegend *legend2=
new TLegend( c->GetLeftMargin() + 0.4, 1 - c->GetTopMargin(),
409 1 - c->GetRightMargin(), 1 - c->GetTopMargin() + 0.12 );
410 legend2->SetFillStyle( 1 );
411 legend2->AddEntry(info->purS,
"Signal purity",
"L");
412 legend2->AddEntry(info->effpurS,
"Signal efficiency*purity",
"L");
413 legend2->AddEntry(info->sSig,GetLatexFormula().Data(),
"L");
414 legend2->Draw(
"same");
415 legend2->SetBorderSize(1);
416 legend2->SetMargin( 0.3 );
419 TLine* effline =
new TLine( info->sSig->GetXaxis()->GetXmin(), 1, info->sSig->GetXaxis()->GetXmax(), 1 );
420 effline->SetLineWidth( 1 );
421 effline->SetLineColor( 1 );
427 tl.SetTextSize( 0.033 );
428 Int_t maxbin = info->sSig->GetMaximumBin();
429 info->line1 = tl.DrawLatex( 0.15, 0.23, Form(
"For %1.0f signal and %1.0f background", fNSignal, fNBackground));
430 tl.DrawLatex( 0.15, 0.19,
"events the maximum "+GetLatexFormula()+
" is");
432 if (info->maxSignificanceErr > 0) {
433 info->line2 = tl.DrawLatex( 0.15, 0.15, Form(
"%5.2f +- %4.2f when cutting at %5.2f",
434 info->maxSignificance,
435 info->maxSignificanceErr,
436 info->sSig->GetXaxis()->GetBinCenter(maxbin)) );
439 info->line2 = tl.DrawLatex( 0.15, 0.15, Form(
"%4.2f when cutting at %5.2f",
440 info->maxSignificance,
441 info->sSig->GetXaxis()->GetBinCenter(maxbin)) );
445 if (info->methodTitle.Contains(
"Cuts")){
446 tl.DrawLatex( 0.13, 0.77,
"Method Cuts provides a bundle of cut selections, each tuned to a");
447 tl.DrawLatex(0.13, 0.74,
"different signal efficiency. Shown is the purity for each cut selection.");
453 info->rightAxis =
new TGaxis(c->GetUxmax(), c->GetUymin(),
454 c->GetUxmax(), c->GetUymax(),0,1.1*info->maxSignificance,510,
"+L");
455 info->rightAxis->SetLineColor ( signifColor );
456 info->rightAxis->SetLabelColor( signifColor );
457 info->rightAxis->SetTitleColor( signifColor );
459 info->rightAxis->SetTitleSize( info->sSig->GetXaxis()->GetTitleSize() );
460 info->rightAxis->SetTitle(
"Significance" );
461 info->rightAxis->Draw();
466 const Bool_t Save_Images = kTRUE;
469 TMVAGlob::imgconv( c, Form(
"%s/plots/mvaeffs_%s",dataset.Data(), info->methodTitle.Data()) );
475 void TMVA::StatDialogMVAEffs::PrintResults(
const MethodInfo* info )
477 Int_t maxbin = info->sSig->GetMaximumBin();
478 if (info->line1 !=0 )
479 info->line1->SetText( 0.15, 0.23, Form(
"For %1.0f signal and %1.0f background", fNSignal, fNBackground));
481 if (info->line2 !=0 ) {
482 if (info->maxSignificanceErr > 0) {
483 info->line2->SetText( 0.15, 0.15, Form(
"%3.2g +- %3.2g when cutting at %3.2g",
484 info->maxSignificance,
485 info->maxSignificanceErr,
486 info->sSig->GetXaxis()->GetBinCenter(maxbin)) );
489 info->line2->SetText( 0.15, 0.15, Form(
"%3.4f when cutting at %3.4f", info->maxSignificance,
490 info->sSig->GetXaxis()->GetBinCenter(maxbin)) );
495 if (info->maxSignificanceErr <= 0) {
496 TString opt = Form(
"%%%is: (%%9.8g,%%9.8g) %%9.4f %%10.6g %%8.7g %%8.7g %%8.4g %%8.4g",
500 info->methodTitle.Data(), fNSignal, fNBackground,
501 info->sSig->GetXaxis()->GetBinCenter( maxbin ),
502 info->maxSignificance,
503 info->origSigE->GetBinContent( maxbin )*fNSignal,
504 info->origBgdE->GetBinContent( maxbin )*fNBackground,
505 info->origSigE->GetBinContent( maxbin ),
506 info->origBgdE->GetBinContent( maxbin ) )
510 TString opt = Form(
"%%%is: (%%9.8g,%%9.8g) %%9.4f (%%8.3g +-%%6.3g) %%8.7g %%8.7g %%8.4g %%8.4g",
514 info->methodTitle.Data(), fNSignal, fNBackground,
515 info->sSig->GetXaxis()->GetBinCenter( maxbin ),
516 info->maxSignificance,
517 info->maxSignificanceErr,
518 info->origSigE->GetBinContent( maxbin )*fNSignal,
519 info->origBgdE->GetBinContent( maxbin )*fNBackground,
520 info->origSigE->GetBinContent( maxbin ),
521 info->origBgdE->GetBinContent( maxbin ) )
526 void TMVA::mvaeffs(TString dataset, TString fin ,
527 Bool_t useTMVAStyle, TString formula )
529 TMVAGlob::Initialize( useTMVAStyle );
531 TGClient * graphicsClient = TGClient::Instance();
532 if (graphicsClient ==
nullptr) {
535 graphicsClient =
new TGClient();
538 StatDialogMVAEffs* gGui =
new StatDialogMVAEffs(dataset,
539 graphicsClient->GetRoot(), 1000, 1000);
542 TFile* file = TMVAGlob::OpenFile( fin );
543 gGui->ReadHistograms(file);
544 gGui->SetFormula(formula);
545 gGui->UpdateSignificanceHists();
546 gGui->DrawHistograms();