<key in map file>, <PID WP>, <iso WP> Single-electron trigger: electrons tagged 'MyTight'
Safer to retrieve the name from the final ToolHandle, it might be prefixed (by the parent tool name) when the handle is copied
Listing 'Tight' first as it has higher priority (an electron with both non-zero 'Tight'+'Medium' decorations will then be tagged as 'Tight')
Uniform random run number generation spanning the target dataset. In real life, use the PileupReweightingTool instead!
Add 'MyMedium' & 'MyTight' decorations to random electrons also count tight electrons above e26_xxx threshold and medium electrons above e7_xxx threshold
95 bool debug =
false, cmdline_error =
false, toys =
false;
99 else if(
string(
argv[
i]) ==
"--toys") toys =
true;
101 else cmdline_error =
true;
109 #ifdef XAOD_STANDALONE
119 StatusCode::enableFailure();
125 event.readFrom(
file).ignore();
126 Long64_t
entries =
event.getEntries();
133 ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools;
135 ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronSFTools;
137 std::map<std::string,std::string> legsPerTool;
139 std::map<std::string,std::string> tagsPerTool;
141 std::map<std::string,std::string> legsPerTag;
146 std::bernoulli_distribution bernoulliPdf(0.9);
149 vector<asg::AnaToolHandle<IAsgElectronEfficiencyCorrectionTool>> factory;
150 enum{ cLEGS, cTAG, cKEY, cPID, cISO };
151 std::vector<std::array<std::string,5> > toolConfigs = {
154 {
"e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0",
"MyTight",
155 "2016_e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0",
"Tight",
"GradientLoose"},
157 {
"e7_lhmedium_nod0",
"MyMedium,MyTight",
"2016_e7_lhmedium_nod0",
"Medium",
""},
159 {
"e17_lhvloose_nod0",
"*,MyMedium,MyTight",
"2016_e17_lhvloose_nod0",
"LooseBLayer",
""},
162 const char* mapPath =
"ElectronEfficiencyCorrection/2015_2017/"
163 "rel21.2/Moriond_February2018_v2/map6.txt";
164 for(
auto&
cfg : toolConfigs)
167 string name =
"AsgElectronEfficiencyCorrectionTool/"
168 + ((j?
"ElTrigEff_" :
"ElTrigSF_")
170 auto t = factory.emplace(factory.end(),
name);
171 t->setProperty(
"MapFilePath", mapPath).ignore();
172 t->setProperty(
"TriggerKey",
string(j?
"":
"Eff_") +
cfg[cKEY]).
ignore();
173 t->setProperty(
"IdKey",
cfg[cPID]).ignore();
174 t->setProperty(
"IsoKey",
cfg[cISO]).ignore();
176 t->setProperty(
"CorrelationModel",
"TOTAL").ignore();
178 if(
t->initialize() != StatusCode::SUCCESS)
180 Error(
MSGSOURCE,
"Unable to initialize the electron CP tool <%s>!",
184 auto& handles = (j? electronSFTools : electronEffTools);
185 handles.push_back(
t->getHandle());
188 name = handles[handles.size()-1].name();
189 legsPerTool[
name] =
cfg[cLEGS];
193 for(
auto&
tag : ::split_comma_delimited(
cfg[cTAG]))
195 if(legsPerTag[
tag]==
"") legsPerTag[
tag] =
cfg[cLEGS];
196 else legsPerTag[
tag] +=
"," +
cfg[cLEGS];
206 ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
208 muonTool.setProperty(
"MuonQuality",
"Tight").ignore();
209 muonTool.setProperty(
"useRel207",
false).ignore();
210 if(muonTool.initialize() != StatusCode::SUCCESS)
215 muonTools.push_back(muonTool.getHandle());
221 myTool.setProperty(
"ElectronEfficiencyTools", electronEffTools).ignore();
222 myTool.setProperty(
"ElectronScaleFactorTools", electronSFTools).ignore();
223 myTool.setProperty(
"MuonTools", muonTools).ignore();
224 const char* triggers2016 =
225 "e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"
226 "|| e7_lhmedium_nod0_mu24"
227 "|| 2e17_lhvloose_nod0";
228 myTool.setProperty(
"TriggerCombination2016", triggers2016).ignore();
231 myTool.setProperty(
"LeptonTagDecorations",
"MyTight,MyMedium").ignore();
232 myTool.setProperty(
"ListOfLegsPerTool", legsPerTool).ignore();
233 myTool.setProperty(
"ListOfTagsPerTool", tagsPerTool).ignore();
234 myTool.setProperty(
"ListOfLegsPerTag", legsPerTag).ignore();
237 if(toys) myTool.setProperty(
"NumberOfToys", 1000).ignore();
238 if(myTool.initialize() != StatusCode::SUCCESS)
246 const unsigned periodRuns[] = {
248 296939, 300345, 301912, 302737, 303638, 303943, 305291, 307124,
249 305359, 309311, 310015
251 std::uniform_int_distribution<unsigned> uniformPdf(0,
252 sizeof(periodRuns)/
sizeof(*periodRuns) - 1);
253 std::default_random_engine randomEngine;
262 double nSuitableEvents = 0., sumW = 0.;
266 event.getEntry(
entry);
270 event.retrieve(eventInfo,
"EventInfo").ignore();
271 unsigned runNumber = periodRuns[uniformPdf(randomEngine)];
272 RandomRunNumberDec(*eventInfo) =
runNumber;
274 unsigned nTrig_e26 = 0, nTrig_e7 = 0, nTrig_e17 = 0;
276 vector<const xAOD::Electron*> myTriggeringElectrons;
278 event.retrieve(
electrons,
"Electrons").ignore();
281 if(!
electron->caloCluster())
continue;
282 float eta = fabs(
electron->caloCluster()->etaBE(2));
284 if(pt<10e3f || eta>=2.47)
continue;
285 if(!truthType.isAvailable(*
electron))
continue;
286 if(!truthOrigin.isAvailable(*
electron))
continue;
288 if(
t!=2 || !(o==10 || (o>=12 && o<=22) || o==43))
continue;
290 if(
pt < 7e3f)
continue;
291 if(
pt >= 18e3f) ++nTrig_e17;
293 myTriggeringElectrons.push_back(
electron);
296 vector<const xAOD::Muon*> myTriggeringMuons;
298 event.retrieve(muons,
"Muons").ignore();
299 for(
auto muon : *muons)
303 if(
pt<10e3f || fabs(
muon->eta())>=2.5)
continue;
304 auto mt =
muon->muonType();
306 auto& mtp = *(
muon->primaryTrackParticle());
307 if(!truthType.isAvailable(mtp))
continue;
308 if(!truthOrigin.isAvailable(mtp))
continue;
309 int t = truthType(mtp), o = truthOrigin(mtp);
310 if(
t!=6 || !(o==10 || (o>=12 && o<=22) || o==43))
continue;
312 if(
pt < 25.2e3f)
continue;
314 myTriggeringMuons.push_back(
muon);
320 for(
auto electron : myTriggeringElectrons)
322 bool medium = bernoulliPdf(randomEngine);
323 dec_medium(*
electron) = medium? 1 : 0;
324 if(medium &&
electron->pt()>8e3f) ++nTrig_e7;
325 bool tight = medium && bernoulliPdf(randomEngine);
326 dec_tight(*
electron) = tight? 1 : 0;
327 if(tight &&
electron->pt()>27e3f) ++nTrig_e26;
332 && (nTrig_e7==0 || myTriggeringMuons.size()==0)
341 auto cc = myTool->getEfficiencyScaleFactor(myTriggeringElectrons,
342 myTriggeringMuons,
sf);
345 nSuitableEvents += 1;
350 Warning(
MSGSOURCE,
"Scale factor evaluation failed");
359 Info(
MSGSOURCE,
"Average scale factor: %f (over %ld events)",
360 sumW / nSuitableEvents,
long(nSuitableEvents));
361 #ifndef XAOD_STANDALONE