Skip to content

Commit 5677f31

Browse files
committed
Modernize code of TagProbeFitter
* avoid using RooFit legacy iterators * use range-based loops * more automatic memory management * remove unused headers * remove redundant code like `Cut("")` (no cut is the default)
1 parent 365705a commit 5677f31

File tree

1 file changed

+73
-112
lines changed

1 file changed

+73
-112
lines changed

PhysicsTools/TagAndProbe/src/TagProbeFitter.cc

Lines changed: 73 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include "TROOT.h"
77
#include "TFile.h"
88
#include "TPad.h"
9-
#include "TText.h"
109
#include "TCanvas.h"
1110
#include "TGraphAsymmErrors.h"
1211
#include "TH2F.h"
@@ -18,22 +17,18 @@
1817
#include "RooCategory.h"
1918
#include "RooDataHist.h"
2019
#include "RooDataSet.h"
21-
#include "RooFitLegacy/RooCatTypeLegacy.h"
2220
#include "RooFitResult.h"
2321
#include "RooFormulaVar.h"
2422
#include "RooGlobalFunc.h"
25-
#include "RooLinkedListIter.h"
2623
#include "RooMappedCategory.h"
2724
#include "RooMinimizer.h"
2825
#include "RooMsgService.h"
2926
#include "RooMultiCategory.h"
3027
#include "RooNumIntConfig.h"
3128
#include "RooPlot.h"
32-
#include "RooProdPdf.h"
3329
#include "RooProfileLL.h"
3430
#include "RooRealVar.h"
3531
#include "RooThresholdCategory.h"
36-
#include "RooTrace.h"
3732
#include "RooWorkspace.h"
3833
#include "RooTreeDataStore.h"
3934

@@ -92,11 +87,7 @@ TagProbeFitter::~TagProbeFitter() {
9287

9388
void TagProbeFitter::setQuiet(bool quiet_) {
9489
quiet = quiet_;
95-
if (quiet) {
96-
RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR);
97-
} else {
98-
RooMsgService::instance().setGlobalKillBelow(RooFit::WARNING);
99-
}
90+
RooMsgService::instance().setGlobalKillBelow(quiet ? RooFit::ERROR : RooFit::WARNING);
10091
}
10192

10293
void TagProbeFitter::setSplitMode(unsigned int nevents) { split_mode = nevents; }
@@ -123,12 +114,12 @@ bool TagProbeFitter::addExpression(string expressionName,
123114
string title,
124115
string expression,
125116
const std::vector<string>& arguments) {
126-
expressionVars.push_back(make_pair(make_pair(expressionName, title), make_pair(expression, arguments)));
117+
expressionVars.emplace_back(make_pair(expressionName, title), make_pair(expression, arguments));
127118
return true;
128119
}
129120

130121
bool TagProbeFitter::addThresholdCategory(string categoryName, string title, string varName, double cutValue) {
131-
thresholdCategories.push_back(make_pair(make_pair(categoryName, title), make_pair(varName, cutValue)));
122+
thresholdCategories.emplace_back(make_pair(categoryName, title), make_pair(varName, cutValue));
132123
return true;
133124
}
134125

@@ -153,68 +144,65 @@ string TagProbeFitter::calculateEfficiency(string dirName,
153144
RooArgSet dataVars;
154145

155146
//collect unbinned variables
156-
for (vector<string>::iterator v = unbinnedVariables.begin(); v != unbinnedVariables.end(); v++) {
157-
dataVars.addClone(variables[v->c_str()], true);
158-
if (binnedFit && (v == unbinnedVariables.begin())) {
159-
((RooRealVar&)dataVars[v->c_str()]).setBins(massBins);
147+
for (std::string const& v : unbinnedVariables) {
148+
dataVars.addClone(variables[v.c_str()], true);
149+
if (binnedFit && (&v == &unbinnedVariables.front())) {
150+
((RooRealVar&)dataVars[v.c_str()]).setBins(massBins);
160151
}
161152
}
162153
//collect the binned variables and the corresponding bin categories
163154
RooArgSet binnedVariables;
164155
RooArgSet binCategories;
165-
for (map<string, vector<double> >::iterator v = binnedReals.begin(); v != binnedReals.end(); v++) {
166-
TString name = v->first;
167-
if (variables.find(name) == nullptr) {
168-
cerr << "Binned variable '" << name << "' not found." << endl;
156+
for (auto const& [name, binEdges] : binnedReals) {
157+
if (variables.find(name.c_str()) == nullptr) {
158+
std::cerr << "Binned variable '" << name << "' not found." << std::endl;
169159
return "Error";
170160
}
171161
binnedVariables.add(*dataVars.addClone(variables[name]));
172-
((RooRealVar&)binnedVariables[name]).setBinning(RooBinning(v->second.size() - 1, &v->second[0]));
173-
binCategories.addClone(RooBinningCategory(name + "_bins", name + "_bins", (RooRealVar&)binnedVariables[name]));
162+
((RooRealVar&)binnedVariables[name]).setBinning(RooBinning(binEdges.size() - 1, binEdges.data()));
163+
std::string nameBins = name + "_bins";
164+
binCategories.addClone(
165+
RooBinningCategory(nameBins.c_str(), nameBins.c_str(), (RooRealVar&)binnedVariables[name.c_str()]));
174166
}
175167

176168
//collect the category variables and the corresponding mapped categories
177169
RooArgSet categories;
178170
RooArgSet mappedCategories;
179-
for (map<string, vector<string> >::iterator v = binnedCategories.begin(); v != binnedCategories.end(); v++) {
180-
TString name = v->first;
181-
if (variables.find(name) == nullptr) {
182-
cerr << "Binned category '" << name << "' not found." << endl;
171+
for (auto const& [name, binnedVariableNames] : binnedCategories) {
172+
if (variables.find(name.c_str()) == nullptr) {
173+
std::cerr << "Binned category '" << name << "' not found." << std::endl;
183174
return "Error";
184175
}
185176
categories.add(*dataVars.addClone(variables[name]));
186-
mappedCategories.addClone(RooMappedCategory(name + "_bins", name + "_bins", (RooCategory&)categories[name]));
187-
for (unsigned int i = 0; i < v->second.size(); i++) {
177+
std::string nameBins = name + "_bins";
178+
mappedCategories.addClone(
179+
RooMappedCategory(nameBins.c_str(), nameBins.c_str(), (RooCategory&)categories[name.c_str()]));
180+
for (std::size_t i = 0; i < binnedVariableNames.size(); i++) {
188181
((RooMappedCategory&)mappedCategories[name + "_bins"])
189-
.map(v->second[i].c_str(), name + "_" + TString(v->second[i].c_str()).ReplaceAll(",", "_"));
182+
.map(binnedVariableNames[i].c_str(),
183+
name + "_" + TString(binnedVariableNames[i].c_str()).ReplaceAll(",", "_"));
190184
}
191185
}
192186

193187
// add the efficiency category if it's not a dynamic one
194-
for (vector<string>::const_iterator effCat = effCats.begin(); effCat != effCats.end(); ++effCat) {
195-
if (variables.find(effCat->c_str()) != nullptr) {
196-
dataVars.addClone(variables[effCat->c_str()], true);
188+
for (std::string const& effCat : effCats) {
189+
if (variables.find(effCat.c_str()) != nullptr) {
190+
dataVars.addClone(variables[effCat.c_str()], true);
197191
}
198192
}
199193

200194
// add all variables used in expressions
201-
for (vector<pair<pair<string, string>, pair<string, vector<string> > > >::const_iterator ev = expressionVars.begin(),
202-
eve = expressionVars.end();
203-
ev != eve;
204-
++ev) {
205-
for (vector<string>::const_iterator it = ev->second.second.begin(), ed = ev->second.second.end(); it != ed; ++it) {
195+
for (auto const& [_, names] : expressionVars) {
196+
for (std::string const& name : names.second) {
206197
// provided that they are real variables themselves
207-
if (variables.find(it->c_str()))
208-
dataVars.addClone(variables[it->c_str()], true);
198+
if (auto* found = variables.find(name.c_str()))
199+
dataVars.addClone(*found, true);
209200
}
210201
}
211202
// add all real variables used in cuts
212-
for (vector<pair<pair<string, string>, pair<string, double> > >::const_iterator tc = thresholdCategories.begin(),
213-
tce = thresholdCategories.end();
214-
tc != tce;
215-
++tc) {
216-
if (variables.find(tc->second.first.c_str()))
217-
dataVars.addClone(variables[tc->second.first.c_str()], true);
203+
for (auto const& [catNameTitle, varNameValue] : thresholdCategories) {
204+
if (variables.find(varNameValue.first.c_str()))
205+
dataVars.addClone(variables[varNameValue.first.c_str()], true);
218206
}
219207

220208
//now add the necessary mass and passing variables to make the unbinned RooDataSet
@@ -224,7 +212,6 @@ string TagProbeFitter::calculateEfficiency(string dirName,
224212
"data",
225213
dataVars,
226214
Import(*inputTree),
227-
/*selExpr=*/Cut(""),
228215
/*wgtVarName=*/WeightVar(weightVar.empty() ? nullptr : weightVar.c_str()));
229216

230217
// Now add all expressions that are computed dynamically
@@ -234,28 +221,22 @@ string TagProbeFitter::calculateEfficiency(string dirName,
234221
ev != eve;
235222
++ev) {
236223
RooArgList args;
237-
for (vector<string>::const_iterator it = ev->second.second.begin(), ed = ev->second.second.end(); it != ed;
238-
++it) {
239-
args.add(dataVars[it->c_str()]);
224+
for (std::string const& it : ev->second.second) {
225+
args.add(dataVars[it.c_str()]);
240226
}
241227
RooFormulaVar expr(ev->first.first.c_str(), ev->first.second.c_str(), ev->second.first.c_str(), args);
242-
RooRealVar* col = (RooRealVar*)data->addColumn(expr);
243-
dataVars.addClone(*col);
228+
dataVars.addClone(*static_cast<RooRealVar*>(data->addColumn(expr)));
244229
}
245230

246231
// And add all dynamic categories from thresholds
247-
for (vector<pair<pair<string, string>, pair<string, double> > >::const_iterator tc = thresholdCategories.begin(),
248-
tce = thresholdCategories.end();
249-
tc != tce;
250-
++tc) {
251-
RooThresholdCategory tmp(tc->first.first.c_str(),
252-
tc->first.second.c_str(),
253-
(RooAbsReal&)dataVars[tc->second.first.c_str()],
232+
for (auto const& [catNameTitle, varNameValue] : thresholdCategories) {
233+
RooThresholdCategory tmp(catNameTitle.first.c_str(),
234+
catNameTitle.second.c_str(),
235+
(RooAbsReal&)dataVars[varNameValue.first.c_str()],
254236
"above",
255237
1);
256-
tmp.addThreshold(tc->second.second, "below", 0);
257-
RooCategory* cat = (RooCategory*)data->addColumn(tmp);
258-
dataVars.addClone(*cat);
238+
tmp.addThreshold(varNameValue.second, "below", 0);
239+
dataVars.addClone(*static_cast<RooCategory*>(data->addColumn(tmp)));
259240
}
260241
}
261242

@@ -307,24 +288,23 @@ string TagProbeFitter::calculateEfficiency(string dirName,
307288

308289
RooDataSet fitEfficiency("fit_eff",
309290
"Efficiency from unbinned ML fit",
310-
RooArgSet(RooArgSet(binnedVariables, categories), efficiency),
291+
{RooArgSet(binnedVariables, categories), efficiency},
311292
StoreAsymError(RooArgSet(binnedVariables, efficiency)));
312293

313294
RooDataSet cntEfficiency("cnt_eff",
314295
"Efficiency from counting",
315-
RooArgSet(RooArgSet(binnedVariables, categories), efficiency),
296+
{RooArgSet(binnedVariables, categories), efficiency},
316297
StoreAsymError(RooArgSet(binnedVariables, efficiency)));
317298

318299
if (not split_mode) {
319300
if (!floatShapeParameters) {
320301
//fitting whole dataset to get initial values for some parameters
321-
RooWorkspace* w = new RooWorkspace();
322-
w->import(*data);
302+
RooWorkspace ws;
303+
ws.import(*data);
323304
efficiency.setVal(0); //reset
324305
efficiency.setAsymError(0, 0);
325306
std::cout << "ALL dataset: calling doFitEfficiency with pdf: " << pdfCategory.getLabel() << std::endl;
326-
doFitEfficiency(w, pdfCategory.getLabel(), efficiency);
327-
delete w;
307+
doFitEfficiency(&ws, pdfCategory.getLabel(), efficiency);
328308
}
329309
} else {
330310
// disactive not needed branches
@@ -336,14 +316,9 @@ string TagProbeFitter::calculateEfficiency(string dirName,
336316
// loop over all bins with the help of allCats
337317
// store index values in a separate vector to avoid issues
338318
// with iteration over changing allCats object
339-
std::vector<Int_t> allCatValues;
340-
TIterator* it = allCats.typeIterator();
341-
for (RooCatType* t = (RooCatType*)it->Next(); t != nullptr; t = (RooCatType*)it->Next())
342-
allCatValues.push_back(t->getVal());
343-
for (auto iCat : allCatValues) {
344-
const RooCatType* t = allCats.lookupType(iCat);
319+
for (auto const& [catNameStr, iCat] : allCats) {
345320
//name of the multicategory
346-
TString catName = t->GetName();
321+
TString catName = catNameStr;
347322
//skip unmapped states
348323
if (catName.Contains("NotMapped"))
349324
continue;
@@ -366,7 +341,7 @@ string TagProbeFitter::calculateEfficiency(string dirName,
366341
printf("Input number of events: %u\n", n_entries);
367342
unsigned int first_entry = 0;
368343
while (first_entry < n_entries) {
369-
TTree* copyTree = inputTree->CopyTree("", "", split_mode, first_entry);
344+
std::unique_ptr<TTree> copyTree{inputTree->CopyTree("", "", split_mode, first_entry)};
370345
RooTreeDataStore store("reader",
371346
"reader",
372347
dataVars,
@@ -379,7 +354,6 @@ string TagProbeFitter::calculateEfficiency(string dirName,
379354
data_bin->add(dataVars, weightVar.empty() ? 1.0 : dataVars.getRealValue(weightVar.c_str()));
380355
}
381356
}
382-
delete copyTree;
383357
first_entry += split_mode;
384358
data_bin->Print("V");
385359
}
@@ -403,18 +377,14 @@ string TagProbeFitter::calculateEfficiency(string dirName,
403377
}
404378

405379
// And add all dynamic categories from thresholds
406-
for (vector<pair<pair<string, string>, pair<string, double> > >::const_iterator tc = thresholdCategories.begin(),
407-
tce = thresholdCategories.end();
408-
tc != tce;
409-
++tc) {
410-
RooThresholdCategory tmp(tc->first.first.c_str(),
411-
tc->first.second.c_str(),
412-
(RooAbsReal&)dataVars[tc->second.first.c_str()],
380+
for (auto const& [catNameTitle, varNameValue] : thresholdCategories) {
381+
RooThresholdCategory tmp(catNameTitle.first.c_str(),
382+
catNameTitle.second.c_str(),
383+
(RooAbsReal&)dataVars[varNameValue.first.c_str()],
413384
"above",
414385
1);
415-
tmp.addThreshold(tc->second.second, "below", 0);
416-
RooCategory* cat = (RooCategory*)data_bin->addColumn(tmp);
417-
tmpVars.add(*dataVars.addClone(*cat));
386+
tmp.addThreshold(varNameValue.second, "below", 0);
387+
tmpVars.add(*dataVars.addClone(*static_cast<RooCategory*>(data_bin->addColumn(tmp))));
418388
}
419389

420390
//setup the efficiency category
@@ -468,8 +438,8 @@ string TagProbeFitter::calculateEfficiency(string dirName,
468438
//import the data
469439
w->import(*data_bin);
470440
delete data_bin; // clean up earlier
471-
data_bin =
472-
dynamic_cast<RooDataSet*>(w->data("data")); // point to the data that's in the workspace now (saves memory)
441+
// point to the data that's in the workspace now (saves memory)
442+
data_bin = dynamic_cast<RooDataSet*>(w->data("data"));
473443

474444
//save the distribution of variables
475445
if (doSaveDistributionsPlot)
@@ -931,9 +901,8 @@ void TagProbeFitter::saveEfficiencyPlots(RooDataSet& eff,
931901
} else {
932902
RooDataSet myEff(eff);
933903
myEff.addColumn(allCats2D);
934-
std::unique_ptr<TIterator> catIt(allCats2D.typeIterator());
935-
for (RooCatType* t = (RooCatType*)catIt->Next(); t != nullptr; t = (RooCatType*)catIt->Next()) {
936-
TString catName = t->GetName();
904+
for (auto const& [catNameStr, catValue] : allCats2D) {
905+
TString catName = catNameStr;
937906
if (catName.Contains("NotMapped"))
938907
continue;
939908
catName.ReplaceAll("{", "").ReplaceAll("}", "").ReplaceAll(";", "_&_");
@@ -944,7 +913,7 @@ void TagProbeFitter::saveEfficiencyPlots(RooDataSet& eff,
944913
catName,
945914
effName,
946915
"allCats2D",
947-
t->getVal());
916+
catValue);
948917
}
949918
}
950919
}
@@ -954,19 +923,13 @@ void TagProbeFitter::saveEfficiencyPlots(RooDataSet& eff,
954923
} else {
955924
RooDataSet myEff(eff);
956925
myEff.addColumn(allCats1D);
957-
std::unique_ptr<TIterator> catIt(allCats1D.typeIterator());
958-
for (RooCatType* t = (RooCatType*)catIt->Next(); t != nullptr; t = (RooCatType*)catIt->Next()) {
959-
TString catName = t->GetName();
926+
for (auto const& [catNameStr, catValue] : allCats1D) {
927+
TString catName = catNameStr;
960928
if (catName.Contains("NotMapped"))
961929
continue;
962930
catName.ReplaceAll("{", "").ReplaceAll("}", "").ReplaceAll(";", "_&_");
963-
makeEfficiencyPlot1D(myEff,
964-
*v1,
965-
TString::Format("%s_PLOT_%s", v1->GetName(), catName.Data()),
966-
catName,
967-
effName,
968-
"allCats1D",
969-
t->getVal());
931+
TString plotName = TString::Format("%s_PLOT_%s", v1->GetName(), catName.Data());
932+
makeEfficiencyPlot1D(myEff, *v1, plotName, catName, effName, "allCats1D", catValue);
970933
}
971934
}
972935
}
@@ -1021,12 +984,12 @@ void TagProbeFitter::makeEfficiencyPlot2D(RooDataSet& eff,
1021984
int catIndex) {
1022985
TCanvas canvas(plotName);
1023986
canvas.SetRightMargin(0.15);
1024-
TH2F* h = new TH2F(plotName,
1025-
plotName,
1026-
v1.getBinning().numBins(),
1027-
v1.getBinning().array(),
1028-
v2.getBinning().numBins(),
1029-
v2.getBinning().array());
987+
auto h = std::make_unique<TH2F>(plotName,
988+
plotName,
989+
v1.getBinning().numBins(),
990+
v1.getBinning().array(),
991+
v2.getBinning().numBins(),
992+
v2.getBinning().array());
1030993
const RooArgSet* set = eff.get();
1031994
RooRealVar* e = (RooRealVar*)set->find("efficiency");
1032995
RooRealVar* v1_ = (RooRealVar*)set->find(v1.GetName());
@@ -1051,7 +1014,6 @@ void TagProbeFitter::makeEfficiencyPlot2D(RooDataSet& eff,
10511014
h->Draw();
10521015
canvas.Draw();
10531016
canvas.Write();
1054-
delete h;
10551017
}
10561018

10571019
void TagProbeFitter::doSBSEfficiency(RooWorkspace* w, RooRealVar& efficiency) {}
@@ -1089,9 +1051,8 @@ void TagProbeFitter::varSaver(RooWorkspace* w) {
10891051
std::cout << "attempt to save variables more than once!" << std::endl;
10901052
return;
10911053
}
1092-
std::vector<std::string>::const_iterator it;
1093-
for (it = fixVars.begin(); it < fixVars.end(); it++) {
1094-
fixVarValues.push_back(w->var((*it).c_str())->getVal());
1054+
for (std::string const& it : fixVars) {
1055+
fixVarValues.push_back(w->var(it.c_str())->getVal());
10951056
}
10961057
}
10971058

0 commit comments

Comments
 (0)