10 #include "TGraphAsymmErrors.h" 13 #include "Math/QuantFuncMathCore.h" 14 #include "Roo1DTable.h" 15 #include "RooAbsDataStore.h" 16 #include "RooAbsReal.h" 17 #include "RooAddPdf.h" 18 #include "RooBinning.h" 19 #include "RooBinningCategory.h" 20 #include "RooCategory.h" 21 #include "RooChebychev.h" 22 #include "RooDataHist.h" 23 #include "RooDataSet.h" 24 #include "RooEfficiency.h" 25 #include "RooExtendPdf.h" 26 #include "RooFitResult.h" 27 #include "RooFormulaVar.h" 28 #include "RooGaussian.h" 29 #include "RooGenericPdf.h" 30 #include "RooGlobalFunc.h" 31 #include "RooLinkedListIter.h" 32 #include "RooMappedCategory.h" 33 #include "RooMinimizer.h" 34 #include "RooMinuit.h" 35 #include "RooMsgService.h" 36 #include "RooMultiCategory.h" 37 #include "RooNLLVar.h" 38 #include "RooNumIntConfig.h" 40 #include "RooProdPdf.h" 41 #include "RooProfileLL.h" 42 #include "RooRealVar.h" 43 #include "RooSimultaneous.h" 44 #include "RooThresholdCategory.h" 46 #include "RooWorkspace.h" 47 #include "RooTreeDataStore.h" 53 inputTree =
new TChain((inputDirectoryName+
"/"+inputTreeName).c_str());
54 for(
size_t i=0;
i<inputFileNames.size();
i++){
55 inputTree->Add(inputFileNames[
i].c_str());
57 outputFile =
new TFile(outputFileName.c_str(),
"recreate");
58 outputDirectory =
outputFile->mkdir(inputDirectoryName.c_str());
60 saveWorkspace = saveWorkspace_;
62 floatShapeParameters = floatShapeParameters_;
65 if(!floatShapeParameters && fixVars.empty())
std::cout <<
"TagProbeFitter: " <<
"You wnat to fix some variables but do not specify them!";
67 gROOT->SetStyle(
"Plain");
68 gStyle->SetTitleFillColor(0);
69 gStyle->SetPalette(1);
70 gStyle->SetOptStat(0);
71 gStyle->SetPaintTextFormat(
".2f");
77 doSaveDistributionsPlot =
true;
80 RooAbsReal::defaultIntegratorConfig()->setEpsAbs(1
e-13);
81 RooAbsReal::defaultIntegratorConfig()->setEpsRel(1
e-13);
103 split_mode = nevents;
107 RooRealVar
temp(name.c_str(), title.c_str(), low, hi, units.c_str());
108 temp.setBins(5000,
"cache");
114 RooCategory*
c = (RooCategory*) parameterParser.factory(expression.c_str());
118 c->SetName(name.c_str());
119 c->SetTitle(title.c_str());
125 expressionVars.push_back(make_pair(make_pair(expressionName,title), make_pair(expression,arguments)));
131 thresholdCategories.push_back(make_pair(make_pair(categoryName,title), make_pair(varName,cutValue)));
137 pdfs[
name] = pdfCommands;
148 string TagProbeFitter::calculateEfficiency(
string dirName,
const std::vector<string>& effCats,
const std::vector<string>& effStates, vector<string>& unbinnedVariables,
map<
string, vector<double> >& binnedReals,
map<
string, std::vector<string> >& binnedCategories, vector<string>& binToPDFmap){
150 outputDirectory->cd();
152 gDirectory->mkdir(
dirName.c_str())->
cd();
157 for(vector<string>::iterator
v=unbinnedVariables.begin();
v!=unbinnedVariables.end();
v++){
158 dataVars.addClone(
variables[
v->c_str()],
true);
159 if (binnedFit && (
v == unbinnedVariables.begin())) {
160 ((RooRealVar&)dataVars[
v->c_str()]).setBins(massBins);
164 RooArgSet binnedVariables;
165 RooArgSet binCategories;
166 for(
map<
string, vector<double> >::iterator
v=binnedReals.begin();
v!=binnedReals.end();
v++){
167 TString
name =
v->first;
168 if (
variables.find(name) ==
nullptr) {
cerr <<
"Binned variable '"<<name<<
"' not found." << endl;
return "Error"; }
169 binnedVariables.add(*dataVars.addClone(
variables[name]));
170 ((RooRealVar&)binnedVariables[name]).setBinning( RooBinning(
v->second.size()-1, &
v->second[0]) );
171 binCategories.addClone( RooBinningCategory(name+
"_bins", name+
"_bins", (RooRealVar&)binnedVariables[name]) );
176 RooArgSet mappedCategories;
177 for(
map<
string, vector<string> >::iterator
v=binnedCategories.begin();
v!=binnedCategories.end();
v++){
178 TString
name =
v->first;
179 if (
variables.find(name) ==
nullptr) {
cerr <<
"Binned category '"<<name<<
"' not found." << endl;
return "Error"; }
180 categories.add(*dataVars.addClone(
variables[name]));
181 mappedCategories.addClone(RooMappedCategory(name+
"_bins", name+
"_bins", (RooCategory&)categories[name]));
182 for(
unsigned int i = 0;
i<
v->second.size();
i++){
183 ((RooMappedCategory&)mappedCategories[name+
"_bins"]).map(
v->second[
i].c_str(), name+
"_"+TString(
v->second[
i].c_str()).ReplaceAll(
",",
"_"));
188 for (vector<string>::const_iterator effCat = effCats.begin(); effCat != effCats.end(); ++effCat) {
189 if (
variables.find(effCat->c_str()) !=
nullptr) {
190 dataVars.addClone(
variables[effCat->c_str()],
true);
195 for(vector<pair<pair<string,string>, pair<
string, vector<string> > > >::const_iterator
ev = expressionVars.begin(), eve = expressionVars.end();
ev != eve; ++
ev){
196 for (vector<string>::const_iterator it =
ev->second.second.begin(), ed =
ev->second.second.end(); it != ed; ++it) {
202 for(vector<pair<pair<string,string>, pair<string, double> > >::const_iterator tc = thresholdCategories.begin(), tce = thresholdCategories.end(); tc != tce; ++tc){
203 if (
variables.find(tc->second.first.c_str())) dataVars.addClone(
variables[tc->second.first.c_str()],
true);
208 RooDataSet*
data(
nullptr);
210 data =
new RooDataSet(
"data",
"data", inputTree,
212 "", (weightVar.empty() ?
nullptr : weightVar.c_str()));
215 for(vector<pair<pair<string,string>, pair<
string, vector<string> > > >::const_iterator
ev = expressionVars.begin(), eve = expressionVars.end();
ev != eve; ++
ev){
217 for (vector<string>::const_iterator it =
ev->second.second.begin(), ed =
ev->second.second.end(); it != ed; ++it) {
218 args.add(dataVars[it->c_str()]);
220 RooFormulaVar
expr(
ev->first.first.c_str(),
ev->first.second.c_str(),
ev->second.first.c_str(),
args);
221 RooRealVar *
col = (RooRealVar *) data->addColumn(
expr);
222 dataVars.addClone(*col);
226 for(vector<pair<pair<string,string>, pair<string, double> > >::const_iterator tc = thresholdCategories.begin(), tce = thresholdCategories.end(); tc != tce; ++tc){
227 RooThresholdCategory
tmp(tc->first.first.c_str(), tc->first.second.c_str(), (RooAbsReal &)dataVars[tc->second.first.c_str()],
"above", 1);
228 tmp.addThreshold(tc->second.second,
"below",0);
229 RooCategory *
cat = (RooCategory *) data->addColumn(
tmp);
230 dataVars.addClone(*cat);
235 RooMultiCategory allCats(
"allCats",
"allCats", RooArgSet(binCategories, mappedCategories));
239 data->addColumn(allCats);
241 if (effCats.size() == 1) {
242 effName = effCats.front() +
"::" + effStates.front();
243 RooMappedCategory efficiencyCategory(
"_efficiencyCategory_",
"_efficiencyCategory_", (RooCategory&)dataVars[effCats.front().c_str()],
"Failed");
244 efficiencyCategory.map(effStates.front().c_str(),
"Passed");
245 data->addColumn( efficiencyCategory );
247 RooArgSet rooEffCats;
249 for (
size_t i = 0;
i < effCats.size(); ++
i) {
250 if (
i) { multiState +=
";"; effName +=
" && "; }
251 rooEffCats.add((RooCategory &) dataVars[effCats[
i].c_str()]);
252 multiState += effStates[
i];
253 effName = effCats[
i] +
"::" + effStates[
i];
256 RooMultiCategory efficiencyMultiCategory(
"_efficiencyMultiCategory_",
"_efficiencyMultiCategory_", rooEffCats);
257 RooMappedCategory efficiencyCategory(
"_efficiencyCategory_",
"_efficiencyCategory_", efficiencyMultiCategory,
"Failed");
258 efficiencyCategory.map(multiState.c_str(),
"Passed");
259 data->addColumn( efficiencyCategory );
264 RooMappedCategory pdfCategory(
"_pdfCategory_",
"_pdfCategory_", allCats, (!binToPDFmap.empty())?binToPDFmap[0].c_str():
"all");
265 for(
unsigned int i = 1;
i<binToPDFmap.size();
i+=2){
266 pdfCategory.map(binToPDFmap[
i].c_str(), binToPDFmap[
i+1].c_str());
268 if (not split_mode) data->addColumn( pdfCategory );
271 RooRealVar
efficiency(
"efficiency",
"Efficiency", 0, 1);
273 RooDataSet fitEfficiency(
"fit_eff",
"Efficiency from unbinned ML fit", RooArgSet(RooArgSet(binnedVariables, categories), efficiency), StoreAsymError(RooArgSet(binnedVariables, efficiency)));
275 RooDataSet cntEfficiency(
"cnt_eff",
"Efficiency from counting", RooArgSet(RooArgSet(binnedVariables, categories), efficiency), StoreAsymError(RooArgSet(binnedVariables, efficiency)));
278 if(!floatShapeParameters){
280 RooWorkspace*
w =
new RooWorkspace();
282 efficiency.setVal(0);
283 efficiency.setAsymError(0,0);
284 std::cout <<
"ALL dataset: calling doFitEfficiency with pdf: " << pdfCategory.getLabel() << std::endl;
285 doFitEfficiency(w, pdfCategory.getLabel(),
efficiency);
290 inputTree->SetBranchStatus(
"*",
false);
291 TIterator* iter = dataVars.createIterator();
292 TObject*
obj(
nullptr);
293 while ( (obj = iter->Next()) )
294 inputTree->SetBranchStatus(obj->GetName(),
true);
300 std::vector<Int_t> allCatValues;
301 TIterator* it = allCats.typeIterator();
302 for(RooCatType*
t = (RooCatType*)it->Next();
t!=
nullptr;
t = (RooCatType*)it->Next() )
303 allCatValues.push_back(
t->getVal());
304 for (
auto iCat : allCatValues){
305 const RooCatType*
t = allCats.lookupType(iCat);
307 TString catName = t->GetName();
309 if(catName.Contains(
"NotMapped"))
continue;
311 RooDataSet* data_bin(
nullptr);
316 data_bin = (RooDataSet*) data->reduce(Cut(TString::Format(
"allCats==%d",iCat)));
318 data_bin =
new RooDataSet(
"data",
"data",
320 (weightVar.empty() ?
nullptr : weightVar.c_str()));
322 TDirectory*
tmp = gDirectory;
327 unsigned int n_entries = inputTree->GetEntries();
328 printf(
"Input number of events: %u\n", n_entries);
329 unsigned int first_entry = 0;
330 while (first_entry<n_entries){
331 TTree* copyTree = inputTree->CopyTree(
"",
"",split_mode,first_entry);
332 RooTreeDataStore store(
"reader",
"reader",dataVars,*copyTree,
333 "", (weightVar.empty() ?
nullptr : weightVar.c_str()));
334 for (
unsigned int i=0;
i<store.GetEntries(); ++
i){
336 if (allCats.getIndex()==iCat){
337 data_bin->add(dataVars,
338 weightVar.empty() ? 1.0 : dataVars.getRealValue(weightVar.c_str()));
342 first_entry += split_mode;
343 data_bin->Print(
"V");
345 data_bin->Print(
"V");
349 for(vector<pair<pair<string,string>, pair<
string, vector<string> > > >::const_iterator
ev = expressionVars.begin(), eve = expressionVars.end();
ev != eve; ++
ev){
351 for (vector<string>::const_iterator it =
ev->second.second.begin(), ed =
ev->second.second.end(); it != ed; ++it) {
352 args.add(dataVars[it->c_str()]);
354 RooFormulaVar
expr(
ev->first.first.c_str(),
ev->first.second.c_str(),
ev->second.first.c_str(),
args);
355 RooRealVar *
col = (RooRealVar *) data_bin->addColumn(
expr);
356 tmpVars.add(*dataVars.addClone(*col));
360 for(vector<pair<pair<string,string>, pair<string, double> > >::const_iterator tc = thresholdCategories.begin(),
361 tce = thresholdCategories.end(); tc != tce; ++tc){
362 RooThresholdCategory
tmp(tc->first.first.c_str(), tc->first.second.c_str(), (RooAbsReal &)dataVars[tc->second.first.c_str()],
"above", 1);
363 tmp.addThreshold(tc->second.second,
"below",0);
364 RooCategory *
cat = (RooCategory *) data_bin->addColumn(tmp);
365 tmpVars.add(*dataVars.addClone(*cat));
369 if (effCats.size() == 1) {
370 effName = effCats.front() +
"::" + effStates.front();
371 RooMappedCategory efficiencyCategory(
"_efficiencyCategory_",
"_efficiencyCategory_", (RooCategory&)dataVars[effCats.front().c_str()],
"Failed");
372 efficiencyCategory.map(effStates.front().c_str(),
"Passed");
373 data_bin->addColumn( efficiencyCategory );
375 RooArgSet rooEffCats;
377 for (
size_t i = 0;
i < effCats.size(); ++
i) {
378 if (
i) { multiState +=
";"; effName +=
" && "; }
379 rooEffCats.add((RooCategory &) dataVars[effCats[
i].c_str()]);
380 multiState += effStates[
i];
381 effName = effCats[
i] +
"::" + effStates[
i];
384 RooMultiCategory efficiencyMultiCategory(
"_efficiencyMultiCategory_",
"_efficiencyMultiCategory_", rooEffCats);
385 RooMappedCategory efficiencyCategory(
"_efficiencyCategory_",
"_efficiencyCategory_", efficiencyMultiCategory,
"Failed");
386 efficiencyCategory.map(multiState.c_str(),
"Passed");
387 data_bin->addColumn( efficiencyCategory );
389 data_bin->addColumn( pdfCategory );
393 const RooArgSet* row = data_bin->get();
396 TString pdfName(((RooCategory*)row->find(
"_pdfCategory_"))->getLabel());
400 dirName.ReplaceAll(
"{",
"").ReplaceAll(
"}",
"").ReplaceAll(
";",
"__");
401 if(pdfName.Length() > 0){
402 dirName.Append(
"__").Append(pdfName);
405 cout<<
"Fitting bin: "<<dirName<<endl;
407 gDirectory->mkdir(dirName)->cd();
411 RooWorkspace*
w =
new RooWorkspace();
413 w->import(*data_bin);
415 data_bin =
dynamic_cast<RooDataSet*
>(w->data(
"data"));
418 if (doSaveDistributionsPlot) saveDistributionsPlot(w);
420 if(data_bin->numEntries()>0){
422 RooArgSet meanOfVariables;
423 RooLinkedListIter vit = binnedVariables.iterator();
424 for(RooRealVar*
v = (RooRealVar*)vit.Next();
v!=
nullptr;
v = (RooRealVar*)vit.Next() ){
425 meanOfVariables.addClone(*
v);
426 double mean = w->data(
"data")->mean(*
v);
427 RooBinning
binning((RooBinning&)
v->getBinning());
428 int ind =
binning.binNumber(mean);
429 RooRealVar& newVar = (RooRealVar&)meanOfVariables[
v->GetName()];
436 meanOfVariables.addClone(*data_bin->get(0),
true);
438 efficiency.setVal(0);
439 efficiency.setAsymError(0,0);
440 doFitEfficiency(w, pdfName.Data(),
efficiency);
441 fitEfficiency.add( RooArgSet(meanOfVariables, efficiency) );
447 efficiency.setVal(0);
448 doCntEfficiency(w, efficiency);
449 cntEfficiency.add( RooArgSet(meanOfVariables, efficiency) );
457 if (split_mode) dataVars.remove(tmpVars);
459 gDirectory->cd(
"..");
463 fitEfficiency.Write();
464 gDirectory->mkdir(
"fit_eff_plots")->cd();
465 saveEfficiencyPlots(fitEfficiency, effName, binnedVariables, mappedCategories);
466 gDirectory->cd(
"..");
473 cntEfficiency.Write();
474 gDirectory->mkdir(
"cnt_eff_plots")->cd();
475 saveEfficiencyPlots(cntEfficiency, effName, binnedVariables, mappedCategories);
476 gDirectory->cd(
"..");
478 if (not split_mode)
delete data;
486 if(pdfName ==
"all"){
490 createPdf(w, pdfs[pdfName]);
493 std::unique_ptr<RooFitResult>
res;
495 RooAbsData *
data = w->data(
"data");
496 std::unique_ptr<RooDataHist> bdata;
499 const RooArgSet *dataObs = data->get(0);
501 RooArgSet *obs = w->pdf(
"simPdf")->getObservables(dataObs);
502 bdata.reset(
new RooDataHist(
"data_binned",
"data_binned", *obs, *data));
504 data = w->data(
"data_binned");
508 double totPassing = data->sumEntries(
"_efficiencyCategory_==_efficiencyCategory_::Passed");
509 double totFailing = data->sumEntries(
"_efficiencyCategory_==_efficiencyCategory_::Failed");
511 RooAbsReal* simNLL = w->pdf(
"simPdf")->createNLL(*data,Extended(
true),
NumCPU(numCPU));
513 RooMinimizer minimizer(*simNLL);
514 RooMinuit minuit(*simNLL);
515 minuit.setStrategy(1);
516 minuit.setProfile(
true);
517 RooProfileLL profileLL(
"simPdfNLL",
"",*simNLL,*w->var(
"efficiency"));
536 if(!fixVars.empty()){
538 if(!floatShapeParameters && fixVarValues.empty()){
549 minimizer.minimize(
"Minuit2",
"Scan");
558 minimizer.minimize(
"Minuit2",
"Scan");
570 if(!floatShapeParameters) varRestorer(w);
573 minimizer.minimize(
"Minuit2",
"Scan");
578 RooMinimizer* profMinuit = profileLL.minimizer();
579 profMinuit->setProfile(
true);
580 profMinuit->setStrategy(2);
581 profMinuit->setPrintLevel(1);
582 profMinuit->minos(*w->var(
"efficiency"));
583 res.reset( profMinuit->save() );
590 if(floatShapeParameters){
595 minimizer.minimize(
"Minuit2",
"Scan");
598 res.reset( w->pdf(
"simPdf")->fitTo(*data, Save(
true), Extended(
true),
NumCPU(numCPU), Strategy(2),
599 Minos(*w->var(
"efficiency")), PrintLevel(quiet?-1:1),
600 PrintEvalErrors(quiet?-1:1), Warnings(!quiet)) );
606 res->Write(
"fitresults");
607 w->saveSnapshot(
"finalState",w->components());
610 RooRealVar*
e = (RooRealVar*) res->floatParsFinal().find(
"efficiency");
613 efficiency.setVal(e->getVal());
614 Double_t errLo = e->getErrorLo(), errHi = e->getErrorHi();
615 if (errLo == 0 && e->getVal() < 0.5) errLo = e->getMin()-e->getVal();
616 if (errHi == 0 && e->getVal() > 0.5) errHi = e->getMax()-e->getVal();
617 efficiency.setAsymError(errLo, errHi);
619 if (totPassing * totFailing == 0) {
620 RooRealVar* nTot = (RooRealVar*) res->floatParsFinal().find(
"numTot");
621 RooRealVar* fSig = (RooRealVar*) res->floatParsFinal().find(
"fSigAll");
622 double cerr = ROOT::Math::beta_quantile( 1-(1.0-.68540158589942957)/2, 1, nTot->getVal() * fSig->getVal() );
632 if (totPassing == 0) {
633 efficiency.setVal(0);
634 efficiency.setAsymError(0,cerr);
636 efficiency.setVal(1);
637 efficiency.setAsymError(-cerr,0);
646 for(
unsigned int i=0;
i<pdfCommands.size();
i++){
648 if (command.find(
"#import ") == 0) {
649 TDirectory *here = gDirectory;
650 w->import(command.substr(8).c_str());
653 TDirectory *here = gDirectory;
654 w->factory(command.c_str());
660 w->factory(
"expr::nSignalPass('efficiency*fSigAll*numTot', efficiency, fSigAll[.9,0,1],numTot[1,0,1e10])");
661 w->factory(
"expr::nSignalFail('(1-efficiency)*fSigAll*numTot', efficiency, fSigAll,numTot)");
662 w->factory(
"expr::nBkgPass('effBkg*(1-fSigAll)*numTot', effBkg[.9,0,1],fSigAll,numTot)");
663 w->factory(
"expr::nBkgFail('(1-effBkg)*(1-fSigAll)*numTot', effBkg,fSigAll,numTot)");
664 TString sPass =
"signal", sFail =
"signal";
665 if (w->pdf(
"signalPass") !=
nullptr && w->pdf(
"signalFail") !=
nullptr) {
666 if (w->pdf(
"signal") !=
nullptr)
throw std::logic_error(
"You must either define one 'signal' PDF or two PDFs ('signalPass', 'signalFail'), not both!");
667 sPass =
"signalPass"; sFail =
"signalFail";
668 }
else if (w->pdf(
"signal") !=
nullptr) {
669 if (w->pdf(
"signalPass") !=
nullptr || w->pdf(
"signalFail") !=
nullptr) {
670 throw std::logic_error(
"You must either define one 'signal' PDF or two PDFs ('signalPass', 'signalFail'), not both!");
673 throw std::logic_error(
"You must either define one 'signal' PDF or two PDFs ('signalPass', 'signalFail')");
675 w->factory(
"SUM::pdfPass(nSignalPass*"+sPass+
", nBkgPass*backgroundPass)");
676 w->factory(
"SUM::pdfFail(nSignalFail*"+sFail+
", nBkgFail*backgroundFail)");
678 w->factory(
"SIMUL::simPdf(_efficiencyCategory_, Passed=pdfPass, Failed=pdfFail)");
680 if (w->pdf(
"simPdf") ==
nullptr)
throw std::runtime_error(
"Could not create simultaneous fit pdf.");
681 if(w->var(
"signalFractionInPassing") ==
nullptr)
682 w->factory(
"signalFractionInPassing[0.9]");
687 double signalEfficiency = w->var(
"efficiency")->getVal();
688 double signalFractionInPassing = w->var(
"signalFractionInPassing")->getVal();
689 double totPassing = w->data(
"data")->sumEntries(
"_efficiencyCategory_==_efficiencyCategory_::Passed");
690 double totFailinging = w->data(
"data")->sumEntries(
"_efficiencyCategory_==_efficiencyCategory_::Failed");
691 double numSignalAll = totPassing*signalFractionInPassing/signalEfficiency;
696 if(numSignalAll*(1-signalEfficiency) > totFailinging)
697 numSignalAll = totFailinging;
699 w->var(
"numTot")->setVal(totPassing+totFailinging);
700 w->var(
"numTot")->setMax(2.0*(totPassing+totFailinging)+10);
702 if (totPassing == 0) {
703 w->var(
"efficiency")->setVal(0.0);
704 w->var(
"efficiency")->setAsymError(0,1);
705 w->var(
"efficiency")->setConstant(
false);
706 }
else if (totFailinging == 0) {
707 w->var(
"efficiency")->setVal(1.0);
708 w->var(
"efficiency")->setAsymError(-1,0);
709 w->var(
"efficiency")->setConstant(
false);
711 w->var(
"efficiency")->setConstant(
false);
719 w->saveSnapshot(
"initialState",w->components());
724 RooCategory& efficiencyCategory = *w->cat(
"_efficiencyCategory_");
725 RooAbsData* dataAll = (binnedFit ? w->data(
"data_binned") : w->data(
"data") );
726 RooAbsData* dataPass = dataAll->reduce(Cut(
"_efficiencyCategory_==_efficiencyCategory_::Passed"));
727 RooAbsData* dataFail = dataAll->reduce(Cut(
"_efficiencyCategory_==_efficiencyCategory_::Failed"));
728 RooAbsPdf& pdf = *w->pdf(
"simPdf");
729 std::unique_ptr<RooArgSet> obs(pdf.getObservables(*dataAll));
730 RooRealVar*
mass =
nullptr;
731 RooLinkedListIter it = obs->iterator();
732 for(RooAbsArg*
v = (RooAbsArg*)it.Next();
v!=
nullptr;
v = (RooAbsArg*)it.Next() ){
733 if(!
v->InheritsFrom(
"RooRealVar"))
continue;
734 mass = (RooRealVar*)
v;
739 TCanvas
canvas(
"fit_canvas");
741 vector<RooPlot*> frames;
745 frames.push_back(mass->frame(
Name(
"Passing"), Title(
"Passing Probes")));
746 frames.push_back(mass->frame(
Name(
"Failing"), Title(
"Failing Probes")));
747 frames.push_back(mass->frame(
Name(
"All"), Title(
"All Probes")));
749 frames.push_back(mass->frame(
Name(
"Passing"), Title(
"Passing Probes"), Bins(massBins)));
750 frames.push_back(mass->frame(
Name(
"Failing"), Title(
"Failing Probes"), Bins(massBins)));
751 frames.push_back(mass->frame(
Name(
"All"), Title(
"All Probes"), Bins(massBins)));
753 dataPass->plotOn(frames[0]);
754 pdf.plotOn(frames[0], Slice(efficiencyCategory,
"Passed"), ProjWData(*dataPass), LineColor(kGreen));
755 pdf.plotOn(frames[0], Slice(efficiencyCategory,
"Passed"), ProjWData(*dataPass), LineColor(kGreen), Components(
"backgroundPass"), LineStyle(kDashed));
759 dataFail->plotOn(frames[1]);
760 pdf.plotOn(frames[1], Slice(efficiencyCategory,
"Failed"), ProjWData(*dataFail), LineColor(kRed));
761 pdf.plotOn(frames[1], Slice(efficiencyCategory,
"Failed"), ProjWData(*dataFail), LineColor(kRed), Components(
"backgroundFail"), LineStyle(kDashed));
765 dataAll->plotOn(frames.back());
766 pdf.plotOn(frames.back(), ProjWData(*dataAll), LineColor(kBlue));
767 pdf.plotOn(frames.back(), ProjWData(*dataAll), LineColor(kBlue), Components(
"backgroundPass,backgroundFail"), LineStyle(kDashed));
768 frames.back()->Draw();
771 frames.push_back(mass->frame(
Name(
"Fit Results"), Title(
"Fit Results")));
772 pdf.paramOn(frames.back(), dataAll,
"", 0,
"NELU", 0.1, 0.9, 0.9);
774 frames.back()->findObject(Form(
"%s_paramBox",pdf.GetName()))->Draw();
778 for (
size_t i=0;
i<frames.size();
i++) {
787 RooAbsData* dataAll = w->data(
"data");
788 RooAbsData* dataPass = dataAll->reduce(Cut(
"_efficiencyCategory_==_efficiencyCategory_::Passed"));
789 RooAbsData* dataFail = dataAll->reduce(Cut(
"_efficiencyCategory_==_efficiencyCategory_::Failed"));
791 const RooArgSet*
vars = dataAll->get();
792 vector<RooRealVar*> reals;
793 RooLinkedListIter it = vars->iterator();
794 for(RooAbsArg*
v = (RooAbsArg*)it.Next();
v!=
nullptr;
v = (RooAbsArg*)it.Next() ){
795 if(!
v->InheritsFrom(
"RooRealVar"))
continue;
796 reals.push_back((RooRealVar*)
v);
798 TCanvas
canvas(
"distributions_canvas");
799 canvas.Divide(3,reals.size());
800 vector<RooPlot*> frames;
801 for(
unsigned int i=0;
i<reals.size();
i++){
804 frames.push_back(reals[
i]->frame(
Name(
"Passing"), Title(
"Passing Probes"), Bins(100)));
805 dataPass->plotOn(frames.back(), LineColor(kGreen));
806 dataPass->statOn(frames.back());
807 frames.back()->Draw();
810 frames.push_back(reals[
i]->frame(
Name(
"Failing"), Title(
"Failing Probes"), Bins(100)));
811 dataFail->plotOn(frames.back(), LineColor(kRed));
812 dataFail->statOn(frames.back());
813 frames.back()->Draw();
816 frames.push_back(reals[
i]->frame(
Name(
"All"), Title(
"All Probes"), Bins(100)));
817 dataAll->plotOn(frames.back(), LineColor(kBlue));
818 dataAll->statOn(frames.back());
819 frames.back()->Draw();
823 for (
size_t i=0;
i<frames.size();
i++) {
831 RooLinkedListIter v1it = binnedVariables.iterator();
832 bool isOnePoint = (eff.numEntries() == 1);
833 for(RooRealVar* v1 = (RooRealVar*)v1it.Next(); v1!=
nullptr; v1 = (RooRealVar*)v1it.Next() ){
834 RooArgSet binCategories1D;
835 if (v1->numBins() == 1 && !isOnePoint)
continue;
836 RooLinkedListIter v2it = binnedVariables.iterator();
837 for(RooRealVar* v2 = (RooRealVar*)v2it.Next(); v2!=
nullptr; v2 = (RooRealVar*)v2it.Next() ){
838 if(v2 == v1)
continue;
839 if (v2->numBins() == 1 && !isOnePoint)
continue;
840 binCategories1D.addClone( RooBinningCategory(TString(v2->GetName())+
"_bins", TString(v2->GetName())+
"_bins", *v2) );
842 RooArgSet binCategories2D;
843 RooLinkedListIter v3it = binnedVariables.iterator();
844 for(RooRealVar* v3 = (RooRealVar*)v3it.Next(); v3!=
nullptr; v3 = (RooRealVar*)v3it.Next() ){
845 if(v3 == v1 || v3 == v2)
continue;
846 binCategories2D.addClone( RooBinningCategory(TString(v3->GetName())+
"_bins", TString(v3->GetName())+
"_bins", *v3) );
848 RooMultiCategory allCats2D(
"allCats2D",
"allCats2D", RooArgSet(binCategories2D, mappedCategories));
849 if(allCats2D.numTypes()==0){
850 makeEfficiencyPlot2D(eff, *v1, *v2, TString::Format(
"%s_%s_PLOT", v1->GetName(), v2->GetName()),
"", effName);
852 RooDataSet myEff(eff);
853 myEff.addColumn(allCats2D);
854 std::unique_ptr<TIterator> catIt(allCats2D.typeIterator());
855 for(RooCatType*
t = (RooCatType*)catIt->Next();
t!=
nullptr;
t = (RooCatType*)catIt->Next() ){
856 TString catName =
t->GetName();
857 if(catName.Contains(
"NotMapped"))
continue;
858 catName.ReplaceAll(
"{",
"").ReplaceAll(
"}",
"").ReplaceAll(
";",
"_&_");
859 makeEfficiencyPlot2D(myEff, *v1, *v2, TString::Format(
"%s_%s_PLOT_%s",v1->GetName(), v2->GetName(), catName.Data()), catName, effName,
"allCats2D",
t->getVal());
863 RooMultiCategory allCats1D(
"allCats1D",
"allCats1D", RooArgSet(binCategories1D, mappedCategories));
864 if(allCats1D.numTypes()==0){
865 makeEfficiencyPlot1D(eff, *v1, TString::Format(
"%s_PLOT", v1->GetName()),
"", effName);
867 RooDataSet myEff(eff);
868 myEff.addColumn(allCats1D);
869 std::unique_ptr<TIterator> catIt(allCats1D.typeIterator());
870 for(RooCatType*
t = (RooCatType*)catIt->Next();
t!=
nullptr;
t = (RooCatType*)catIt->Next() ){
871 TString catName =
t->GetName();
872 if(catName.Contains(
"NotMapped"))
continue;
873 catName.ReplaceAll(
"{",
"").ReplaceAll(
"}",
"").ReplaceAll(
";",
"_&_");
874 makeEfficiencyPlot1D(myEff, *v1, TString::Format(
"%s_PLOT_%s", v1->GetName(), catName.Data()), catName, effName,
"allCats1D",
t->getVal());
881 TGraphAsymmErrors *
p =
new TGraphAsymmErrors();
882 const RooArgSet *
entry = eff.get();
883 const RooRealVar &vi =
dynamic_cast<const RooRealVar &
>(*entry->find(v.GetName()));
884 const RooRealVar &ei =
dynamic_cast<const RooRealVar &
>(*entry->find(
"efficiency"));
885 for (
unsigned int i = 0,
n = eff.numEntries();
i <
n; ++
i) {
887 if (catName !=
nullptr && entry->getCatIndex(catName) != catIndex)
continue;
888 int j = p->GetN(); p->Set(j+1);
889 p->SetPoint(j, vi.getVal(), ei.getVal() );
890 p->SetPointError(j, -vi.getAsymErrorLo(), vi.getAsymErrorHi(), -ei.getAsymErrorLo(), ei.getAsymErrorHi() );
893 TH1F *frame =
new TH1F(
"frame",
"Efficiency of "+effName, 1, v.getMin(), v.getMax()); frame->SetDirectory(
nullptr);
894 p->SetNameTitle(Form(
"hxy_%s", eff.GetName()),
"Efficiency of "+effName);
895 p->GetXaxis()->SetTitle(strlen(v.getUnit()) ? Form(
"%s (%s)", v.GetName(), v.getUnit()) : v.GetName());
896 p->GetYaxis()->SetTitle(
"Efficiency of "+effName);
897 frame->GetXaxis()->SetTitle(strlen(v.getUnit()) ? Form(
"%s (%s)", v.GetName(), v.getUnit()) : v.GetName());
898 frame->GetYaxis()->SetTitle(
"Efficiency of "+effName);
899 frame->GetYaxis()->SetRangeUser(0,1);
901 p->SetLineWidth(2); p->SetMarkerStyle(kFullCircle); p->SetMarkerSize(1.2);
908 void TagProbeFitter::makeEfficiencyPlot2D(RooDataSet& eff, RooRealVar& v1, RooRealVar& v2,
const TString& plotName,
const TString& plotTitle,
const TString& effName,
const char *catName,
int catIndex){
910 canvas.SetRightMargin(0.15);
911 TH2F*
h =
new TH2F(plotName, plotName, v1.getBinning().numBins(), v1.getBinning().array(), v2.getBinning().numBins(), v2.getBinning().array());
912 const RooArgSet*
set = eff.get();
913 RooRealVar*
e = (RooRealVar*) set->find(
"efficiency");
914 RooRealVar* v1_ = (RooRealVar*) set->find(v1.GetName());
915 RooRealVar* v2_ = (RooRealVar*) set->find(v2.GetName());
916 h->SetTitle(TString::Format(
"%s;%s%s;%s%s;Efficiency of %s", plotTitle.Data(),
917 v1.GetTitle(), TString(v1.getUnit()).Length()==0?
"":TString::Format(
" (%s)", v1.getUnit()).Data(),
918 v2.GetTitle(), TString(v2.getUnit()).Length()==0?
"":TString::Format(
" (%s)", v2.getUnit()).Data(), effName.Data()));
919 h->SetOption(
"colztexte");
920 h->GetZaxis()->SetRangeUser(-0.001,1.001);
922 for(
int i=0;
i<eff.numEntries();
i++){
923 const RooArgSet *
entry = eff.get(
i);
924 if (catName !=
nullptr && entry->getCatIndex(catName) != catIndex)
continue;
925 h->SetBinContent(h->FindBin(v1_->getVal(), v2_->getVal()), e->getVal());
926 h->SetBinError(h->FindBin(v1_->getVal(), v2_->getVal()), (e->getErrorHi()-e->getErrorLo())/2.);
938 int pass = w->data(
"data")->sumEntries(
"_efficiencyCategory_==_efficiencyCategory_::Passed");
939 int fail = w->data(
"data")->sumEntries(
"_efficiencyCategory_==_efficiencyCategory_::Failed");
940 double e = (pass+fail == 0) ? 0 : pass/
double(pass+fail);
942 double alpha = (1.0 - .68540158589942957)/2;
943 double lo = (pass == 0) ? 0.0 : ROOT::Math::beta_quantile( alpha, pass, fail+1 );
944 double hi = (fail == 0) ? 1.0 : ROOT::Math::beta_quantile( 1-alpha, pass+1, fail );
949 efficiency.setVal(e);
950 efficiency.setAsymError(lo-e, hi-e);
954 std::vector<std::string>::const_iterator it;
955 for(it=fixVars.begin(); it<fixVars.end(); it++){
956 if(w->var((*it).c_str()))
957 w->var((*it).c_str())->setAttribute(
"Constant",fix);
959 std::cout <<
"TagProbeFitter: " <<
"Can't find a variable to fix: " << *it;
965 if(!fixVarValues.empty()){
966 std::cout <<
"attempt to save variables more than once!" << std::endl;
969 std::vector<std::string>::const_iterator it;
970 for(it=fixVars.begin(); it<fixVars.end(); it++){
971 fixVarValues.push_back(w->var((*it).c_str())->getVal());
977 if(fixVarValues.size()==fixVars.size())
978 for(
unsigned int i=0;
i< fixVars.size();
i++){
979 std::cout <<
"setting variable " << fixVars[
i].c_str() << std::endl;
980 w->var(fixVars[
i].c_str())->setVal(fixVarValues[
i]);
983 std::cout <<
"fixVars and fixVarValues are not of the same size!" << std::endl;
void doCntEfficiency(RooWorkspace *w, RooRealVar &efficiency)
calculate the efficiecny by counting in the dataset found in the workspace
void makeEfficiencyPlot1D(RooDataSet &eff, RooRealVar &v, const TString &plotName, const TString &plotTitle, const TString &effName, const char *catName=nullptr, int catIndex=-1)
makes the 1D plot
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
void addPdf(std::string pdfName, std::vector< std::string > &pdfCommands)
static PFTauRenderPlugin instance
void setWeightVar(const std::string &weight)
set a variable to be used as weight for a dataset. empty string means no weights. ...
std::string calculateEfficiency(std::string dirName, std::string efficiencyCategory, std::string efficiencyState, std::vector< std::string > &unbinnedVariables, std::map< std::string, std::vector< double > > &binnedReals, std::map< std::string, std::vector< std::string > > &binnedCategories, std::vector< std::string > &binToPDFmap)
calculate the efficiency for a particular binning of the data; it saves everything in the directory "...
void makeEfficiencyPlot2D(RooDataSet &eff, RooRealVar &v1, RooRealVar &v2, const TString &plotName, const TString &plotTitle, const TString &effName, const char *catName=nullptr, int catIndex=-1)
makes the 2D plot
bool addThresholdCategory(std::string categoryName, std::string title, std::string varName, double cutValue)
adds a new category based on a cut
void setQuiet(bool quiet_=true)
suppress most of the output from RooFit and Minuit
TagProbeFitter(const std::vector< std::string > &inputFileNames, std::string inputDirectoryName, std::string inputTreeName, std::string outputFileName, int numCPU=1, bool saveWorkspace_=false, bool floatShapeParameters=true, const std::vector< std::string > &fixVars_=std::vector< std::string >())
construct the fitter with the inputFileName, inputDirectoryName, inputTreeName, outputFileName and sp...
bool addExpression(std::string expressionName, std::string title, std::string expression, const std::vector< std::string > &arguments)
adds a new category based on a cut
void saveEfficiencyPlots(RooDataSet &eff, const TString &effName, RooArgSet &binnedVariables, RooArgSet &mappedCategories)
saves the efficiency plots
void varSaver(RooWorkspace *w)
store values in the vector
void varRestorer(RooWorkspace *w)
restore variables's values for fit starting point
void saveFitPlot(RooWorkspace *w)
saves the fit canvas
~TagProbeFitter()
destructor closes the files
void setInitialValues(RooWorkspace *w)
sets initial values of the PDF parameters based on the data available in the workspace ...
void saveDistributionsPlot(RooWorkspace *w)
saves the distributions canvas
void varFixer(RooWorkspace *w, bool fix)
fix or release variables selected by user
void setSplitMode(unsigned int nevents)
std::vector< std::vector< double > > tmp
TString units(TString variable, Char_t axis)
char data[epos_bytes_allocation]
void setBinsForMassPlots(int bins)
set number of bins to use when making the plots; 0 = automatic
void doSBSEfficiency(RooWorkspace *w, RooRealVar &efficiency)
calculate the efficiecny with side band substraction in the dataset found in the workspace ...
void createPdf(RooWorkspace *w, std::vector< std::string > &pdfCommands)
creates the simultaneous PDF in the workspace according to the "pdfCommands"
void doFitEfficiency(RooWorkspace *w, std::string pdfName, RooRealVar &efficiency)
calculate the efficiecny with a simulataneous maximum likelihood fit in the dataset found in the work...
bool addCategory(std::string categoryName, std::string title, std::string expression)
adds a new category variable to the set of variables describing the data in the tree; "expression" is...
bool addVariable(std::string variableName, std::string title, double low, double hi, std::string units)
adds a new real variable to the set of variables describing the data in the tree