ATLAS Offline Software
Loading...
Searching...
No Matches
TrigGlobEffCorrExample1.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
8/*
9 * Another example: combination of single-lepton, dielectron and dimuon
10 * triggers, using different configurations for each year, and illustrating
11 * how to fill the property 'ListOfLegsPerTool'.
12 *
13 */
14
15// ROOT include(s):
16#include <TFile.h>
17#include <TError.h>
18
19// Infrastructure include(s):
20#ifdef XAOD_STANDALONE
21 #include "xAODRootAccess/Init.h"
24#else
27#endif
28
30// EDM include(s):
42
43// stdlib include(s):
44#include <random>
45#include <vector>
46#include <array>
47using std::vector;
48using std::string;
49
50#define MSGSOURCE "Example 1"
51
54using namespace Test;
55int main(int argc, char* argv[])
56{
58 const char* filename = nullptr;
59 bool debug = false, cmdline_error = false, toys = false;
60 for(int i=1;i<argc;++i)
61 {
62 if(string(argv[i]) == "--debug") debug = true;
63 else if(string(argv[i]) == "--toys") toys = true;
64 else if(!filename && *argv[i]!='-') filename = argv[i];
65 else cmdline_error = true;
66 }
67 if(!filename || cmdline_error)
68 {
69 Error(MSGSOURCE, "No file name received!");
70 Error(MSGSOURCE, " Usage: %s [--debug] [--toys] [DxAOD file name]", argv[0]);
71 return 1;
72 }
73 #ifdef XAOD_STANDALONE
74 xAOD::Init(MSGSOURCE).ignore();
75 TFile* file = TFile::Open(filename, "READ");
76 if(!file)
77 {
78 Error(MSGSOURCE, "Unable to open file!");
79 return 2;
80 }
82 xAOD::TStore store;
83 StatusCode::enableFailure();
84 #else
85 IAppMgrUI* app = POOL::Init();
87 TString file(filename);
88 #endif
89 event.readFrom(file).ignore();
90 Long64_t entries = event.getEntries();
91 Info(MSGSOURCE, "Number of events in the file: %lli", entries);
92
93 /* ********************************************************************** */
94
95 Info(MSGSOURCE, "Configuring the electron CP tools");
97 ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools;
99 ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronSFTools;
101 std::map<string,string> legsPerTool;
102
104 vector<asg::AnaToolHandle<IAsgElectronEfficiencyCorrectionTool>> factory;
105 enum{ cLEGS, cKEY };
106 vector<std::array<string,2>> toolConfigs = {
109 {"e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose, e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0",
110 "SINGLE_E_2015_e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose_2016_2018_e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"},
112 {"e12_lhloose_L1EM10VH, e17_lhvloose_nod0, e24_lhvloose_nod0_L1EM20VH",
113 "DI_E_2015_e12_lhloose_L1EM10VH_2016_e17_lhvloose_nod0_2017_2018_e24_lhvloose_nod0_L1EM20VH"},
115 {"e17_lhvloose_nod0_L1EM15VHI",
116 "DI_E_2015_e12_lhloose_L1EM10VH_2016_e17_lhvloose_nod0_2017_2018_e17_lhvloose_nod0_L1EM15VHI"}
117 };
118
119 const char* mapPath = "ElectronEfficiencyCorrection/2015_2017/"
120 "rel21.2/Consolidation_September2018_v1/map2.txt";
121 for(auto& cfg : toolConfigs)
122 for(int j=0;j<2;++j)
123 {
124 string name = "AsgElectronEfficiencyCorrectionTool/"
125 + ((j? "ElTrigEff_" : "ElTrigSF_")
126 + std::to_string(factory.size()/2));
127 auto t = factory.emplace(factory.end(), name);
128 t->setProperty("MapFilePath", mapPath).ignore();
129 t->setProperty("TriggerKey", string(j?"":"Eff_") + cfg[cKEY]).ignore();
130 t->setProperty("IdKey", "Tight").ignore();
131 t->setProperty("IsoKey", "FCTight").ignore();
132 t->setProperty("CorrelationModel", "TOTAL").ignore();
133 t->setProperty("ForceDataType", (int)PATCore::ParticleDataType::Full).ignore();
134 if(t->initialize() != StatusCode::SUCCESS)
135 {
136 Error(MSGSOURCE, "Unable to initialize the electron CP tool <%s>!",
137 t->name().c_str());
138 return 3;
139 }
140 auto& handles = (j? electronSFTools : electronEffTools);
141 handles.push_back(t->getHandle());
144 name = handles[handles.size()-1].name();
145 legsPerTool[name] = cfg[cLEGS];
146
147 }
148
149 /* ********************************************************************** */
150
151 Info(MSGSOURCE, "Configuring the muon CP tools");
153 ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
154 asg::AnaToolHandle<CP::IMuonTriggerScaleFactors> muonTool("CP::MuonTriggerScaleFactors/MuonTrigEff");
155 muonTool.setProperty("MuonQuality", "Tight").ignore();
156 muonTool.setProperty("useRel207", false).ignore();
157 if(muonTool.initialize() != StatusCode::SUCCESS)
158 {
159 Error(MSGSOURCE, "Unable to initialize the muon CP tool!");
160 return 3;
161 }
162 muonTools.push_back(muonTool.getHandle());
163
164 /* ********************************************************************** */
165
166 Info(MSGSOURCE, "Configuring the global trigger SF tool");
167 asg::AnaToolHandle<ITrigGlobalEfficiencyCorrectionTool> myTool("TrigGlobalEfficiencyCorrectionTool/TrigGlobal");
168 myTool.setProperty("ElectronEfficiencyTools", electronEffTools).ignore();
169 myTool.setProperty("ElectronScaleFactorTools", electronSFTools).ignore();
170 myTool.setProperty("MuonTools", muonTools).ignore();
171 std::map<std::string, std::string> triggers;
172 triggers["2015"] =
173 "mu20_iloose_L1MU15_OR_mu50"
174 "|| mu18_mu8noL1"
175 "|| e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose"
176 "|| 2e12_lhloose_L12EM10VH";
177 triggers["2016"] =
178 "mu26_ivarmedium_OR_mu50"
179 "|| mu22_mu8noL1"
180 "|| e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"
181 "|| 2e17_lhvloose_nod0";
182 std::string only2e24 =
183 "mu26_ivarmedium_OR_mu50"
184 "|| mu22_mu8noL1"
185 "|| e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"
186 "|| 2e24_lhvloose_nod0";
187 std::string nominal = only2e24 + "|| 2e17_lhvloose_nod0_L12EM15VHI";
188 triggers["324320-326695"] = nominal;
189 triggers["326834-328393"] = only2e24;
190 triggers["329385-364292"] = nominal;
191 myTool.setProperty("TriggerCombination", triggers).ignore();
192 myTool.setProperty("ListOfLegsPerTool", legsPerTool).ignore();
193
194 if(debug) myTool.setProperty("OutputLevel", MSG::DEBUG).ignore();
195 if(toys) myTool.setProperty("NumberOfToys", 1000).ignore();
196 if(myTool.initialize() != StatusCode::SUCCESS)
197 {
198 Error(MSGSOURCE, "Unable to initialize the TrigGlob tool!");
199 return 3;
200 }
201
204 const unsigned periodRuns[] = {
206 276073, 278727, 279932, 280423, 281130, 282625,
208 296939, 300345, 301912, 302737, 303638, 303943, 305291, 307124,
209 305359, 309311, 310015,
211 325713, 329385, 330857, 332720, 334842, 336497, 336832, 338183,
213 348885, 349534, 350310, 352274, 354107, 354826, 355261, 355331,
214 355529, 357050, 359191, 361635, 361738, 363664
215 };
216 std::uniform_int_distribution<unsigned> uniformPdf(0,
217 sizeof(periodRuns)/sizeof(*periodRuns) - 1);
218 std::default_random_engine randomEngine;
219
220 static const SG::ConstAccessor<int> truthType("truthType");
221 static const SG::ConstAccessor<int> truthOrigin("truthOrigin");
222
223 /* ********************************************************************** */
224
225 Info(MSGSOURCE, "Starting the event loop");
226 unsigned errors = 0;
227 double nSuitableEvents = 0., sumW = 0.;
228 static const SG::Decorator<unsigned> RandomRunNumberDec("RandomRunNumber");
229 for(Long64_t entry = 0; entry < entries; ++entry)
230 {
231 event.getEntry(entry);
232
234 const xAOD::EventInfo* eventInfo = nullptr;
235 event.retrieve(eventInfo,"EventInfo").ignore();
236 unsigned runNumber = periodRuns[uniformPdf(randomEngine)];
237 RandomRunNumberDec(*eventInfo) = runNumber;
238
239 unsigned nTrig1L = 0, nTrig2mu = 0;
240
241 vector<const xAOD::Electron*> myTriggeringElectrons;
242 const xAOD::ElectronContainer* electrons = nullptr;
243 event.retrieve(electrons,"Electrons").ignore();
244 for(auto electron : *electrons)
245 {
246 if(!electron->caloCluster()) continue;
247 float eta = fabs(electron->caloCluster()->etaBE(2));
248 float pt = electron->pt();
249 if(pt<10e3f || eta>=2.47) continue;
250 if(!truthType.isAvailable(*electron)) continue;
251 if(!truthOrigin.isAvailable(*electron)) continue;
252 int t = truthType(*electron), o = truthOrigin(*electron);
253 if(t!=2 || !(o==10 || (o>=12 && o<=22) || o==43)) continue;
255 if((runNumber>=326834 && runNumber<=328393 && pt<25e3f)
256 || (runNumber>290000 && pt<18e3f)
257 || (pt<13e3f)) continue;
259 if(pt >= (runNumber>290000? 27e3f : 25e3f)) ++nTrig1L;
260
261 myTriggeringElectrons.push_back(electron);
262 }
263
264 vector<const xAOD::Muon*> myTriggeringMuons;
265 const xAOD::MuonContainer* muons = nullptr;
266 event.retrieve(muons,"Muons").ignore();
267 for(auto muon : *muons)
268 {
269 float pt = muon->pt();
270 if(pt<10e3f || fabs(muon->eta())>=2.5) continue;
271 auto mt = muon->muonType();
272 if(mt!=xAOD::Muon::Combined && mt!=xAOD::Muon::MuonStandAlone) continue;
273 auto& mtp = *(muon->primaryTrackParticle());
274 if(!truthType.isAvailable(mtp)) continue;
275 if(!truthOrigin.isAvailable(mtp)) continue;
276 int t = truthType(mtp), o = truthOrigin(mtp);
277 if(t!=6 || !(o==10 || (o>=12 && o<=22) || o==43)) continue;
279 if(pt < 10e3f) continue;
281 if(pt >= (runNumber>290000? 27.3e3f : 21e3f)) ++nTrig1L;
283 if(pt >= (runNumber>290000? 23e3f : 19e3f)) ++nTrig2mu;
284
285 myTriggeringMuons.push_back(muon);
286 }
287
289 if(nTrig1L==0
290 && myTriggeringElectrons.size()<2
291 && (nTrig2mu==0 || myTriggeringMuons.size()<2))
292 {
293 continue;
294 }
295
296
298 double sf = 1.;
299 auto cc = myTool->getEfficiencyScaleFactor(myTriggeringElectrons,
300 myTriggeringMuons, sf);
302 {
303 nSuitableEvents += 1;
304 sumW += sf;
305 }
306 else
307 {
308 Warning(MSGSOURCE, "Scale factor evaluation failed");
309 ++errors;
310 }
311 if(errors>10)
312 {
313 Error(MSGSOURCE, "Too many errors reported!");
314 break;
315 }
316 }
317 Info(MSGSOURCE, "Average scale factor: %f (over %ld events)",
318 sumW / nSuitableEvents, long(nSuitableEvents));
319 #ifndef XAOD_STANDALONE
320 ANA_CHECK(app->finalize());
321 #endif
322 return errors? 4 : 0;
323}
324
Scalar eta() const
pseudorapidity method
Base class for elements of a container that can have aux data.
Helper class to provide constant type-safe access to aux data.
macros for messaging and checking status codes
#define ANA_CHECK(EXP)
check whether the given expression was successful
#define ANA_MSG_HEADER(NAME)
for standalone code this creates a new message category
#define ANA_MSG_SOURCE(NAME, TITLE)
the source code part of ANA_MSG_SOURCE
#define ANA_CHECK_SET_TYPE(TYPE)
set the type for ANA_CHECK to report failures
Helper class to provide type-safe access to aux data.
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
StatusCode setProperty(const std::string &property, const T2 &value)
set the given property of the tool.
StatusCode initialize()
initialize the tool
const ToolHandle< T > & getHandle() const noexcept
the tool handle we wrap
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
int main()
Definition hello.cxx:18
double entries
Definition listroot.cxx:49
IAppMgrUI * Init(const char *options="POOLRootAccess/basic.opts")
Bootstraps (creates and configures) the Gaudi Application with the provided options file.
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