50 #ifdef XAOD_STANDALONE
82 namespace {
vector<string> split_comma_delimited(
const std::string&); }
84 #define MSGSOURCE "Example 3e"
93 bool debug =
false, cmdline_error =
false, toys =
false;
97 else if(
string(
argv[
i]) ==
"--toys") toys =
true;
99 else cmdline_error =
true;
107 #ifdef XAOD_STANDALONE
117 StatusCode::enableFailure();
123 event.readFrom(
file).ignore();
124 Long64_t
entries =
event.getEntries();
129 Info(
MSGSOURCE,
"Configuring the electron CP tools");
131 ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools;
133 ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronSFTools;
135 std::map<std::string,std::string> legsPerTool;
137 std::map<std::string,std::string> tagsPerTool;
139 std::map<std::string,std::string> legsPerTag;
143 std::bernoulli_distribution bernoulliPdf(0.9);
146 vector<asg::AnaToolHandle<IAsgElectronEfficiencyCorrectionTool>> factory;
147 enum{ cLEGS, cTAG, cKEY, cPID, cISO };
148 std::vector<std::array<std::string,5> > toolConfigs = {
151 {
"e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0",
"PID2",
152 "2016_e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0",
"Tight",
"GradientLoose"},
154 {
"e7_lhmedium_nod0",
"PID1,PID2",
"2016_e7_lhmedium_nod0",
"Medium",
""},
156 {
"e17_lhvloose_nod0",
"*,PID1,PID2",
"2016_e17_lhvloose_nod0",
"LooseBLayer",
""},
159 const char* mapPath =
"ElectronEfficiencyCorrection/2015_2017/"
160 "rel21.2/Moriond_February2018_v2/map6.txt";
161 for(
auto&
cfg : toolConfigs)
164 string name =
"AsgElectronEfficiencyCorrectionTool/"
165 + ((j?
"ElTrigEff_" :
"ElTrigSF_")
167 auto t = factory.emplace(factory.end(),
name);
168 t->setProperty(
"MapFilePath", mapPath).ignore();
169 t->setProperty(
"TriggerKey",
string(j?
"":
"Eff_") +
cfg[cKEY]).
ignore();
170 t->setProperty(
"IdKey",
cfg[cPID]).ignore();
171 t->setProperty(
"IsoKey",
cfg[cISO]).ignore();
173 t->setProperty(
"CorrelationModel",
"TOTAL").ignore();
175 if(
t->initialize() != StatusCode::SUCCESS)
177 Error(
MSGSOURCE,
"Unable to initialize the electron CP tool <%s>!",
181 auto& handles = (j? electronSFTools : electronEffTools);
182 handles.push_back(
t->getHandle());
185 name = handles[handles.size()-1].name();
186 legsPerTool[
name] =
cfg[cLEGS];
190 for(
auto&
tag : ::split_comma_delimited(
cfg[cTAG]))
192 if(legsPerTag[
tag]==
"") legsPerTag[
tag] =
cfg[cLEGS];
193 else legsPerTag[
tag] +=
"," +
cfg[cLEGS];
201 Info(
MSGSOURCE,
"Configuring the muon CP tools");
203 ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
205 muonTool.
setProperty(
"MuonQuality",
"Tight").ignore();
207 if(muonTool.
initialize() != StatusCode::SUCCESS)
212 muonTools.push_back(muonTool.
getHandle());
216 Info(
MSGSOURCE,
"Configuring the global trigger SF tool");
218 myTool.
setProperty(
"ElectronEfficiencyTools", electronEffTools).ignore();
219 myTool.
setProperty(
"ElectronScaleFactorTools", electronSFTools).ignore();
220 myTool.
setProperty(
"MuonTools", muonTools).ignore();
221 const char* triggers2016 =
222 "e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"
223 "|| e7_lhmedium_nod0_mu24"
224 "|| 2e17_lhvloose_nod0";
225 myTool.
setProperty(
"TriggerCombination2016", triggers2016).ignore();
228 myTool.
setProperty(
"LeptonTagDecorations",
"PID?").ignore();
229 myTool.
setProperty(
"ListOfLegsPerTool", legsPerTool).ignore();
230 myTool.
setProperty(
"ListOfTagsPerTool", tagsPerTool).ignore();
231 myTool.
setProperty(
"ListOfLegsPerTag", legsPerTag).ignore();
234 if(toys) myTool.
setProperty(
"NumberOfToys", 1000).ignore();
235 if(myTool.
initialize() != StatusCode::SUCCESS)
243 const unsigned periodRuns[] = {
245 296939, 300345, 301912, 302737, 303638, 303943, 305291, 307124,
246 305359, 309311, 310015
248 std::uniform_int_distribution<unsigned> uniformPdf(0,
249 sizeof(periodRuns)/
sizeof(*periodRuns) - 1);
250 std::default_random_engine randomEngine;
257 Info(
MSGSOURCE,
"Starting the event loop");
259 double nSuitableEvents = 0., sumW = 0.;
263 event.getEntry(
entry);
267 event.retrieve(eventInfo,
"EventInfo").ignore();
268 unsigned runNumber = periodRuns[uniformPdf(randomEngine)];
269 RandomRunNumberDec(*eventInfo) =
runNumber;
271 unsigned nTrig_e26 = 0, nTrig_e7 = 0, nTrig_e17 = 0;
273 vector<const xAOD::Electron*> myTriggeringElectrons;
275 event.retrieve(
electrons,
"Electrons").ignore();
278 if(!
electron->caloCluster())
continue;
279 float eta = fabs(
electron->caloCluster()->etaBE(2));
281 if(pt<10e3f || eta>=2.47)
continue;
285 if(
t!=2 || !(o==10 || (o>=12 && o<=22) || o==43))
continue;
287 if(
pt < 7e3f)
continue;
288 if(
pt >= 18e3f) ++nTrig_e17;
290 myTriggeringElectrons.push_back(
electron);
293 vector<const xAOD::Muon*> myTriggeringMuons;
295 event.retrieve(muons,
"Muons").ignore();
296 for(
auto muon : *muons)
300 if(
pt<10e3f || fabs(
muon->eta())>=2.5)
continue;
301 auto mt =
muon->muonType();
303 auto& mtp = *(
muon->primaryTrackParticle());
304 if(!
truthType.isAvailable(mtp))
continue;
307 if(
t!=6 || !(o==10 || (o>=12 && o<=22) || o==43))
continue;
309 if(
pt < 25.2e3f)
continue;
311 myTriggeringMuons.push_back(
muon);
317 for(
auto electron : myTriggeringElectrons)
319 bool medium = bernoulliPdf(randomEngine);
320 bool tight = medium && bernoulliPdf(randomEngine);
322 dec_pid(*
electron) = tight? 2 : medium? 1 : 0;
323 if(medium &&
electron->pt()>8e3f) ++nTrig_e7;
324 if(tight &&
electron->pt()>27e3f) ++nTrig_e26;
329 && (nTrig_e7==0 || myTriggeringMuons.size()==0)
339 myTriggeringMuons,
sf);
342 nSuitableEvents += 1;
347 Warning(
MSGSOURCE,
"Scale factor evaluation failed");
356 Info(
MSGSOURCE,
"Average scale factor: %f (over %ld events)",
357 sumW / nSuitableEvents,
long(nSuitableEvents));
358 #ifndef XAOD_STANDALONE
369 std::stringstream
ss(
s);
370 std::vector<std::string>
tokens;
372 while(std::getline(
ss, token,
','))
374 if(token.length())
tokens.push_back(token);