ATLAS Offline Software
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"
22  #include "xAODRootAccess/TEvent.h"
23  #include "xAODRootAccess/TStore.h"
24 #else
26  #include "POOLRootAccess/TEvent.h"
27 #endif
28 
30 // EDM include(s):
31 #include "AsgTools/AnaToolHandle.h"
37 #include "xAODMuon/MuonContainer.h"
38 #include "PATCore/PATCoreEnums.h"
42 
43 // stdlib include(s):
44 #include <random>
45 #include <vector>
46 #include <array>
47 using std::vector;
48 using std::string;
49 
50 #define MSGSOURCE "Example 1"
51 
52 ANA_MSG_HEADER(Test)
54 using namespace Test;
55 int main(int argc, char* argv[])
56 {
57  ANA_CHECK_SET_TYPE(bool)
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  }
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;
258  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 
asg::AnaToolHandle::initialize
StatusCode initialize()
initialize the tool
store
StoreGateSvc * store
Definition: fbtTestBasics.cxx:69
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
asg::AnaToolHandle< CP::IMuonTriggerScaleFactors >
MSGSOURCE
#define MSGSOURCE
Definition: TrigGlobEffCorrExample1.cxx:50
IAsgElectronEfficiencyCorrectionTool.h
ITrigGlobalEfficiencyCorrectionTool.h
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
test_pyathena.pt
pt
Definition: test_pyathena.py:11
ANA_CHECK
#define ANA_CHECK(EXP)
check whether the given expression was successful
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:324
SG::ConstAccessor< int >
LArCellConditions.argv
argv
Definition: LArCellConditions.py:112
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
python.TrigTLAMonitorAlgorithm.triggers
triggers
Definition: TrigTLAMonitorAlgorithm.py:196
xAOD::TEvent::kClassAccess
@ kClassAccess
Access auxiliary data using the aux containers.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:97
asg::AnaToolHandle::setProperty
StatusCode setProperty(const std::string &property, const T2 &value)
set the given property of the tool.
POOL::Init
IAppMgrUI * Init(const char *options="POOLRootAccess/basic.opts")
Bootstraps (creates and configures) the Gaudi Application with the provided options file.
Definition: PhysicsAnalysis/POOLRootAccess/src/TEvent.cxx:29
POOL::TEvent::kClassAccess
@ kClassAccess
Definition: PhysicsAnalysis/POOLRootAccess/POOLRootAccess/TEvent.h:45
ANA_MSG_HEADER
#define ANA_MSG_HEADER(NAME)
for standalone code this creates a new message category
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:113
PATCore::ParticleDataType::Full
@ Full
Definition: PATCoreEnums.h:22
DiTauMassTools::ignore
void ignore(T &&)
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:54
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:58
ElectronContainer.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
top::nominal
@ nominal
Definition: ScaleFactorRetriever.h:29
MessageCheck.h
macros for messaging and checking status codes
PATCoreEnums.h
TEvent.h
IMuonTriggerScaleFactors.h
file
TFile * file
Definition: tile_monitor.h:29
Init.h
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
AnaToolHandle.h
Trk::Combined
@ Combined
Definition: TrackSummaryTool.h:32
mergePhysValFiles.errors
list errors
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:43
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
ANA_MSG_SOURCE
#define ANA_MSG_SOURCE(NAME, TITLE)
the source code part of ANA_MSG_SOURCE
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:133
POOL::TEvent
Definition: PhysicsAnalysis/POOLRootAccess/POOLRootAccess/TEvent.h:39
TEvent.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
debug
const bool debug
Definition: MakeUncertaintyPlots.cxx:53
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
WriteCaloSwCorrections.cfg
cfg
Definition: WriteCaloSwCorrections.py:23
EventInfo.h
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
MuonContainer.h
AthAnalysisHelper.h
DeMoAtlasDataLoss.runNumber
string runNumber
Definition: DeMoAtlasDataLoss.py:64
CP::CorrectionCode::Ok
@ Ok
The correction was done successfully.
Definition: CorrectionCode.h:38
ITrigGlobalEfficiencyCorrectionTool::getEfficiencyScaleFactor
virtual CP::CorrectionCode getEfficiencyScaleFactor(const std::vector< const xAOD::IParticle * > &particles, double &efficiencyScaleFactor)=0
asg::AnaToolHandle::getHandle
const ToolHandle< T > & getHandle() const noexcept
the tool handle we wrap
xAOD::TStore
A relatively simple transient store for objects created in analysis.
Definition: TStore.h:44
mapkey::sf
@ sf
Definition: TElectronEfficiencyCorrectionTool.cxx:38
ANA_CHECK_SET_TYPE
#define ANA_CHECK_SET_TYPE(TYPE)
set the type for ANA_CHECK to report failures
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:314
DEBUG
#define DEBUG
Definition: page_access.h:11
main
int main(int argc, char *argv[])
Definition: TrigGlobEffCorrExample1.cxx:55
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
entries
double entries
Definition: listroot.cxx:49
SG::ConstAccessor::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
L1Topo::Error
Error
The different types of error that can be flagged in the L1TopoRDO.
Definition: Error.h:16
ConstAccessor.h
Helper class to provide constant type-safe access to aux data.
Decorator.h
Helper class to provide type-safe access to aux data.
TStore.h
InDetDD::electrons
@ electrons
Definition: InDetDD_Defs.h:17
xAOD::TEvent
Tool for accessing xAOD files outside of Athena.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:81
AuxElement.h
Base class for elements of a container that can have aux data.
python.handimod.cc
int cc
Definition: handimod.py:523
xAOD::Init
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition: Init.cxx:31