ATLAS Offline Software
Loading...
Searching...
No Matches
TrigGlobEffCorrExample3e.cxx File Reference

Go to the source code of this file.

Macros

#define MSGSOURCE   "Example 3e"

Functions

int main (int argc, char *argv[])

Macro Definition Documentation

◆ MSGSOURCE

#define MSGSOURCE   "Example 3e"

Definition at line 84 of file TrigGlobEffCorrExample3e.cxx.

Function Documentation

◆ main()

int main ( int argc,
char * argv[] )

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.

90{
92 const char* filename = nullptr;
93 bool debug = false, cmdline_error = false, toys = false;
94 for(int i=1;i<argc;++i)
95 {
96 if(string(argv[i]) == "--debug") debug = true;
97 else if(string(argv[i]) == "--toys") toys = true;
98 else if(!filename && *argv[i]!='-') filename = argv[i];
99 else cmdline_error = true;
100 }
101 if(!filename || cmdline_error)
102 {
103 Error(MSGSOURCE, "No file name received!");
104 Error(MSGSOURCE, " Usage: %s [--debug] [--toys] [DxAOD file name]", argv[0]);
105 return 1;
106 }
107 #ifdef XAOD_STANDALONE
108 xAOD::Init(MSGSOURCE).ignore();
109 TFile* file = TFile::Open(filename, "READ");
110 if(!file)
111 {
112 Error(MSGSOURCE, "Unable to open file!");
113 return 2;
114 }
117 StatusCode::enableFailure();
118 #else
119 IAppMgrUI* app = POOL::Init();
121 TString file(filename);
122 #endif
123 event.readFrom(file).ignore();
124 Long64_t entries = event.getEntries();
125 Info(MSGSOURCE, "Number of events in the file: %lli", entries);
126
127 /* ********************************************************************** */
128
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;
141 static const SG::Decorator<char> dec_pid("PID");
143 std::bernoulli_distribution bernoulliPdf(0.9);
144
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", ""},
157 };
158
159 const char* mapPath = "ElectronEfficiencyCorrection/2015_2017/"
160 "rel21.2/Moriond_February2018_v2/map6.txt";
161 for(auto& cfg : toolConfigs)
162 for(int j=0;j<2;++j)
163 {
164 string name = "AsgElectronEfficiencyCorrectionTool/"
165 + ((j? "ElTrigEff_" : "ElTrigSF_")
166 + std::to_string(factory.size()/2));
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();
172
173 t->setProperty("CorrelationModel", "TOTAL").ignore();
174 t->setProperty("ForceDataType", (int)PATCore::ParticleDataType::Full).ignore();
175 if(t->initialize() != StatusCode::SUCCESS)
176 {
177 Error(MSGSOURCE, "Unable to initialize the electron CP tool <%s>!",
178 t->name().c_str());
179 return 3;
180 }
181 auto& handles = (j? electronSFTools : electronEffTools);
182 handles.push_back(t->getHandle());
185 name = handles[handles.size()-1].name();
186 legsPerTool[name] = cfg[cLEGS];
187 tagsPerTool[name] = cfg[cTAG];
188 if(!j)
189 {
190 for(auto& tag : ::split_comma_delimited(cfg[cTAG]))
191 {
192 if(legsPerTag[tag]=="") legsPerTag[tag] = cfg[cLEGS];
193 else legsPerTag[tag] += "," + cfg[cLEGS];
194 }
195 }
196
197 }
198
199 /* ********************************************************************** */
200
201 Info(MSGSOURCE, "Configuring the muon CP tools");
203 ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
204 asg::AnaToolHandle<CP::IMuonTriggerScaleFactors> muonTool("CP::MuonTriggerScaleFactors/MuonTrigEff");
205 muonTool.setProperty("MuonQuality", "Tight").ignore();
206 muonTool.setProperty("useRel207", false).ignore();
207 if(muonTool.initialize() != StatusCode::SUCCESS)
208 {
209 Error(MSGSOURCE, "Unable to initialize the muon CP tool!");
210 return 3;
211 }
212 muonTools.push_back(muonTool.getHandle());
213
214 /* ********************************************************************** */
215
216 Info(MSGSOURCE, "Configuring the global trigger SF tool");
217 asg::AnaToolHandle<ITrigGlobalEfficiencyCorrectionTool> myTool("TrigGlobalEfficiencyCorrectionTool/TrigGlobal");
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();
232
233 if(debug) myTool.setProperty("OutputLevel", MSG::DEBUG).ignore();
234 if(toys) myTool.setProperty("NumberOfToys", 1000).ignore();
235 if(myTool.initialize() != StatusCode::SUCCESS)
236 {
237 Error(MSGSOURCE, "Unable to initialize the TrigGlob tool!");
238 return 3;
239 }
240
243 const unsigned periodRuns[] = {
245 296939, 300345, 301912, 302737, 303638, 303943, 305291, 307124,
246 305359, 309311, 310015
247 };
248 std::uniform_int_distribution<unsigned> uniformPdf(0,
249 sizeof(periodRuns)/sizeof(*periodRuns) - 1);
250 std::default_random_engine randomEngine;
251
252 static const SG::ConstAccessor<int> truthType("truthType");
253 static const SG::ConstAccessor<int> truthOrigin("truthOrigin");
254
255 /* ********************************************************************** */
256
257 Info(MSGSOURCE, "Starting the event loop");
258 unsigned errors = 0;
259 double nSuitableEvents = 0., sumW = 0.;
260 static const SG::Decorator<unsigned> RandomRunNumberDec("RandomRunNumber");
261 for(Long64_t entry = 0; entry < entries; ++entry)
262 {
263 event.getEntry(entry);
264
266 const xAOD::EventInfo* eventInfo = nullptr;
267 event.retrieve(eventInfo,"EventInfo").ignore();
268 unsigned runNumber = periodRuns[uniformPdf(randomEngine)];
269 RandomRunNumberDec(*eventInfo) = runNumber;
270
271 unsigned nTrig_e26 = 0, nTrig_e7 = 0, nTrig_e17 = 0;
272
273 vector<const xAOD::Electron*> myTriggeringElectrons;
274 const xAOD::ElectronContainer* electrons = nullptr;
275 event.retrieve(electrons,"Electrons").ignore();
276 for(auto electron : *electrons)
277 {
278 if(!electron->caloCluster()) continue;
279 float eta = fabs(electron->caloCluster()->etaBE(2));
280 float pt = electron->pt();
281 if(pt<10e3f || eta>=2.47) continue;
282 if(!truthType.isAvailable(*electron)) continue;
283 if(!truthOrigin.isAvailable(*electron)) continue;
284 int t = truthType(*electron), o = truthOrigin(*electron);
285 if(t!=2 || !(o==10 || (o>=12 && o<=22) || o==43)) continue;
287 if(pt < 7e3f) continue;
288 if(pt >= 18e3f) ++nTrig_e17;
289
290 myTriggeringElectrons.push_back(electron);
291 }
292
293 vector<const xAOD::Muon*> myTriggeringMuons;
294 const xAOD::MuonContainer* muons = nullptr;
295 event.retrieve(muons,"Muons").ignore();
296 for(auto muon : *muons)
297 {
298 if(runNumber >= 324320) break; // delete line once all SFs available for 2017
299 float pt = muon->pt();
300 if(pt<10e3f || fabs(muon->eta())>=2.5) continue;
301 auto mt = muon->muonType();
302 if(mt!=xAOD::Muon::Combined && mt!=xAOD::Muon::MuonStandAlone) continue;
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;
310
311 myTriggeringMuons.push_back(muon);
312 }
313
317 for(auto electron : myTriggeringElectrons)
318 {
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;
325 }
326
328 if(nTrig_e26 < 1
329 && (nTrig_e7==0 || myTriggeringMuons.size()==0)
330 && nTrig_e17 < 2)
331 {
332 continue;
333 }
334
335
337 double sf = 1.;
338 auto cc = myTool->getEfficiencyScaleFactor(myTriggeringElectrons,
339 myTriggeringMuons, sf);
341 {
342 nSuitableEvents += 1;
343 sumW += sf;
344 }
345 else
346 {
347 Warning(MSGSOURCE, "Scale factor evaluation failed");
348 ++errors;
349 }
350 if(errors>10)
351 {
352 Error(MSGSOURCE, "Too many errors reported!");
353 break;
354 }
355 }
356 Info(MSGSOURCE, "Average scale factor: %f (over %ld events)",
357 sumW / nSuitableEvents, long(nSuitableEvents));
358 #ifndef XAOD_STANDALONE
359 ANA_CHECK(app->finalize());
360 #endif
361 return errors? 4 : 0;
362}
Scalar eta() const
pseudorapidity method
#define ANA_CHECK(EXP)
check whether the given expression was successful
#define ANA_CHECK_SET_TYPE(TYPE)
set the type for ANA_CHECK to report failures
const bool debug
@ Ok
The correction was done successfully.
Helper class to provide constant type-safe access to aux data.
Helper class to provide type-safe access to aux data.
Definition Decorator.h:59
a modified tool handle that allows its owner to configure new tools from the C++ side
Tool for accessing xAOD files outside of Athena.
@ kClassAccess
Access auxiliary data using the aux containers.
A relatively simple transient store for objects created in analysis.
Definition TStore.h:45
double entries
Definition listroot.cxx:49
int truthOrigin(const U &p)
int truthType(const U &p)
Error
The different types of error that can be flagged in the L1TopoRDO.
Definition Error.h:16
IAppMgrUI * Init(const char *options="POOLRootAccess/basic.opts")
Bootstraps (creates and configures) the Gaudi Application with the provided options file.
TestStore store
Definition TestStore.cxx:23
@ Info
Definition ZDCMsg.h:20
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition Init.cxx:31
ElectronContainer_v1 ElectronContainer
Definition of the current "electron container version".
EventInfo_v1 EventInfo
Definition of the latest event info version.
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
#define MSGSOURCE
Test code to test ElectronPhotonVariableCorrectionTool Dictionaries.
TFile * file