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

Go to the source code of this file.

Macros

#define MSGSOURCE   "Example 3d"

Functions

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

Macro Definition Documentation

◆ MSGSOURCE

#define MSGSOURCE   "Example 3d"

Definition at line 86 of file TrigGlobEffCorrExample3d.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 electron(s) as 'MyMedium' and 'MyTight'

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: electrons tagged 'MyTight'

Electron-muon trigger: electrons tagged 'MyTight' or 'MyMedium'

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':

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!

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 'MyMedium' & 'MyTight' decorations to random electrons also count tight electrons above e26_xxx threshold and medium electrons above e7_xxx threshold

Events must contain enough leptons to trigger

single-electron trigger

electron-muon

dielectron

Finally retrieve the global trigger scale factor

Definition at line 91 of file TrigGlobEffCorrExample3d.cxx.

92{
94 const char* filename = nullptr;
95 bool debug = false, cmdline_error = false, toys = false;
96 for(int i=1;i<argc;++i)
97 {
98 if(string(argv[i]) == "--debug") debug = true;
99 else if(string(argv[i]) == "--toys") toys = true;
100 else if(!filename && *argv[i]!='-') filename = argv[i];
101 else cmdline_error = true;
102 }
103 if(!filename || cmdline_error)
104 {
105 Error(MSGSOURCE, "No file name received!");
106 Error(MSGSOURCE, " Usage: %s [--debug] [--toys] [DxAOD file name]", argv[0]);
107 return 1;
108 }
109 #ifdef XAOD_STANDALONE
110 xAOD::Init(MSGSOURCE).ignore();
111 TFile* file = TFile::Open(filename, "READ");
112 if(!file)
113 {
114 Error(MSGSOURCE, "Unable to open file!");
115 return 2;
116 }
119 StatusCode::enableFailure();
120 #else
121 IAppMgrUI* app = POOL::Init();
123 TString file(filename);
124 #endif
125 event.readFrom(file).ignore();
126 Long64_t entries = event.getEntries();
127 Info(MSGSOURCE, "Number of events in the file: %lli", entries);
128
129 /* ********************************************************************** */
130
131 Info(MSGSOURCE, "Configuring the electron CP tools");
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;
143 static const SG::Decorator<char> dec_medium("MyMedium");
144 static const SG::Decorator<char> dec_tight("MyTight");
146 std::bernoulli_distribution bernoulliPdf(0.9);
147
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", ""},
160 };
161
162 const char* mapPath = "ElectronEfficiencyCorrection/2015_2017/"
163 "rel21.2/Moriond_February2018_v2/map6.txt";
164 for(auto& cfg : toolConfigs)
165 for(int j=0;j<2;++j)
166 {
167 string name = "AsgElectronEfficiencyCorrectionTool/"
168 + ((j? "ElTrigEff_" : "ElTrigSF_")
169 + std::to_string(factory.size()/2));
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();
175
176 t->setProperty("CorrelationModel", "TOTAL").ignore();
177 t->setProperty("ForceDataType", (int)PATCore::ParticleDataType::Full).ignore();
178 if(t->initialize() != StatusCode::SUCCESS)
179 {
180 Error(MSGSOURCE, "Unable to initialize the electron CP tool <%s>!",
181 t->name().c_str());
182 return 3;
183 }
184 auto& handles = (j? electronSFTools : electronEffTools);
185 handles.push_back(t->getHandle());
188 name = handles[handles.size()-1].name();
189 legsPerTool[name] = cfg[cLEGS];
190 tagsPerTool[name] = cfg[cTAG];
191 if(!j)
192 {
193 for(auto& tag : ::split_comma_delimited(cfg[cTAG]))
194 {
195 if(legsPerTag[tag]=="") legsPerTag[tag] = cfg[cLEGS];
196 else legsPerTag[tag] += "," + cfg[cLEGS];
197 }
198 }
199
200 }
201
202 /* ********************************************************************** */
203
204 Info(MSGSOURCE, "Configuring the muon CP tools");
206 ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
207 asg::AnaToolHandle<CP::IMuonTriggerScaleFactors> muonTool("CP::MuonTriggerScaleFactors/MuonTrigEff");
208 muonTool.setProperty("MuonQuality", "Tight").ignore();
209 muonTool.setProperty("useRel207", false).ignore();
210 if(muonTool.initialize() != StatusCode::SUCCESS)
211 {
212 Error(MSGSOURCE, "Unable to initialize the muon CP tool!");
213 return 3;
214 }
215 muonTools.push_back(muonTool.getHandle());
216
217 /* ********************************************************************** */
218
219 Info(MSGSOURCE, "Configuring the global trigger SF tool");
220 asg::AnaToolHandle<ITrigGlobalEfficiencyCorrectionTool> myTool("TrigGlobalEfficiencyCorrectionTool/TrigGlobal");
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();
235
236 if(debug) myTool.setProperty("OutputLevel", MSG::DEBUG).ignore();
237 if(toys) myTool.setProperty("NumberOfToys", 1000).ignore();
238 if(myTool.initialize() != StatusCode::SUCCESS)
239 {
240 Error(MSGSOURCE, "Unable to initialize the TrigGlob tool!");
241 return 3;
242 }
243
246 const unsigned periodRuns[] = {
248 296939, 300345, 301912, 302737, 303638, 303943, 305291, 307124,
249 305359, 309311, 310015
250 };
251 std::uniform_int_distribution<unsigned> uniformPdf(0,
252 sizeof(periodRuns)/sizeof(*periodRuns) - 1);
253 std::default_random_engine randomEngine;
254
255 static const SG::ConstAccessor<int> truthType("truthType");
256 static const SG::ConstAccessor<int> truthOrigin("truthOrigin");
257
258 /* ********************************************************************** */
259
260 Info(MSGSOURCE, "Starting the event loop");
261 unsigned errors = 0;
262 double nSuitableEvents = 0., sumW = 0.;
263 static const SG::Decorator<unsigned> RandomRunNumberDec("RandomRunNumber");
264 for(Long64_t entry = 0; entry < entries; ++entry)
265 {
266 event.getEntry(entry);
267
269 const xAOD::EventInfo* eventInfo = nullptr;
270 event.retrieve(eventInfo,"EventInfo").ignore();
271 unsigned runNumber = periodRuns[uniformPdf(randomEngine)];
272 RandomRunNumberDec(*eventInfo) = runNumber;
273
274 unsigned nTrig_e26 = 0, nTrig_e7 = 0, nTrig_e17 = 0;
275
276 vector<const xAOD::Electron*> myTriggeringElectrons;
277 const xAOD::ElectronContainer* electrons = nullptr;
278 event.retrieve(electrons,"Electrons").ignore();
279 for(auto electron : *electrons)
280 {
281 if(!electron->caloCluster()) continue;
282 float eta = fabs(electron->caloCluster()->etaBE(2));
283 float pt = electron->pt();
284 if(pt<10e3f || eta>=2.47) continue;
285 if(!truthType.isAvailable(*electron)) continue;
286 if(!truthOrigin.isAvailable(*electron)) continue;
287 int t = truthType(*electron), o = truthOrigin(*electron);
288 if(t!=2 || !(o==10 || (o>=12 && o<=22) || o==43)) continue;
290 if(pt < 7e3f) continue;
291 if(pt >= 18e3f) ++nTrig_e17;
292
293 myTriggeringElectrons.push_back(electron);
294 }
295
296 vector<const xAOD::Muon*> myTriggeringMuons;
297 const xAOD::MuonContainer* muons = nullptr;
298 event.retrieve(muons,"Muons").ignore();
299 for(auto muon : *muons)
300 {
301 if(runNumber >= 324320) break; // delete line once all SFs available for 2017
302 float pt = muon->pt();
303 if(pt<10e3f || fabs(muon->eta())>=2.5) continue;
304 auto mt = muon->muonType();
305 if(mt!=xAOD::Muon::Combined && mt!=xAOD::Muon::MuonStandAlone) continue;
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;
313
314 myTriggeringMuons.push_back(muon);
315 }
316
320 for(auto electron : myTriggeringElectrons)
321 {
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;
328 }
329
331 if(nTrig_e26 < 1
332 && (nTrig_e7==0 || myTriggeringMuons.size()==0)
333 && nTrig_e17 < 2)
334 {
335 continue;
336 }
337
338
340 double sf = 1.;
341 auto cc = myTool->getEfficiencyScaleFactor(myTriggeringElectrons,
342 myTriggeringMuons, sf);
344 {
345 nSuitableEvents += 1;
346 sumW += sf;
347 }
348 else
349 {
350 Warning(MSGSOURCE, "Scale factor evaluation failed");
351 ++errors;
352 }
353 if(errors>10)
354 {
355 Error(MSGSOURCE, "Too many errors reported!");
356 break;
357 }
358 }
359 Info(MSGSOURCE, "Average scale factor: %f (over %ld events)",
360 sumW / nSuitableEvents, long(nSuitableEvents));
361 #ifndef XAOD_STANDALONE
362 ANA_CHECK(app->finalize());
363 #endif
364 return errors? 4 : 0;
365}
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