For property 'ElectronEfficiencyTools':
For property 'ElectronScaleFactorTools':
For property 'ListOfLegsPerTool':
For property 'ListOfTagsPerTool':
For property 'ElectronLegsPerTag':
To tag electrons according to the PID criteria they fulfil
To emulate PID selection (90% loose-to-medium/medium-to-tight eff.)
RAII on-the-fly creation of electron CP tools:
<key in map file>, <PID WP>, <iso WP> Single-electron trigger: only electrons tagged 'PID2' (TightLH+iso)
Electron-muon trigger: electrons tagged 'PID2' or 'PID1' (MediumLH)
Dielectron trigger: all electrons (tagged or not)
one instance per trigger leg x working point
two instances: 0 -> MC efficiencies, 1 -> SFs
Safer to retrieve the name from the final ToolHandle, it might be prefixed (by the parent tool name) when the handle is copied
For property 'MuonTools':
Special character '?' indicates that the decorated value is to be suffixed to the name (=> 'PID1' for medium, 'PID2' for tight)
Uniform random run number generation spanning the target dataset. In real life, use the PileupReweightingTool instead!
2016 periods A-L
Get a random run number, and decorate the event info
electron must be above softest trigger threshold (e7 here
muon must be above softest trigger threshold (mu24 here)
Add 'PID' decorations to random electrons also count 'Tight' electrons above e26_xxx threshold and 'Medium' electrons above e7_xxx threshold
Set decorated value to 2 for TightLH+iso or 1 for MediumLH
Events must contain enough leptons to trigger
single-electron trigger
electron-muon
dielectron
Finally retrieve the global trigger scale factor
Definition at line 89 of file TrigGlobEffCorrExample3e.cxx.
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();
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];
203 ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
205 muonTool.setProperty(
"MuonQuality",
"Tight").ignore();
206 muonTool.setProperty(
"useRel207",
false).ignore();
207 if(muonTool.initialize() != StatusCode::SUCCESS)
212 muonTools.push_back(muonTool.getHandle());
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;
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;
282 if(!truthType.isAvailable(*
electron))
continue;
283 if(!truthOrigin.isAvailable(*
electron))
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;
305 if(!truthOrigin.isAvailable(mtp))
continue;
306 int t = truthType(mtp), o = truthOrigin(mtp);
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)
338 auto cc = myTool->getEfficiencyScaleFactor(myTriggeringElectrons,
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