ATLAS Offline Software
TrigGlobalEfficiencyAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
11 #include "PATCore/PATCoreEnums.h"
12 
14  ISvcLocator *svcLoc)
15  : EL::AnaAlgorithm(name, svcLoc)
16 {
17  declareProperty("matchingTool", m_trigMatchingTool, "trigger matching tool");
18 }
19 
21 {
22 
23  if (m_trigList_2015.empty() && m_trigList_2016.empty() && m_trigList_2017.empty() && m_trigList_2018.empty()
24  && m_trigList_2022.empty() && m_trigList_2023.empty() && m_trigList_2024.empty() && m_trigList_2025.empty()) {
25  ATH_MSG_ERROR("A list of triggers needs to be provided");
26  return StatusCode::FAILURE;
27  }
28 
29  ANA_CHECK(m_electronsHandle.initialize(m_systematicsList, SG::AllowEmpty));
30  ANA_CHECK(m_muonsHandle.initialize(m_systematicsList, SG::AllowEmpty));
31  ANA_CHECK(m_photonsHandle.initialize(m_systematicsList, SG::AllowEmpty));
32 
33  ANA_CHECK(m_electronSelection.initialize(m_systematicsList, m_electronsHandle, SG::AllowEmpty));
34  ANA_CHECK(m_muonSelection.initialize(m_systematicsList, m_muonsHandle, SG::AllowEmpty));
35  ANA_CHECK(m_photonSelection.initialize(m_systematicsList, m_photonsHandle, SG::AllowEmpty));
36 
37  ANA_CHECK(m_eventInfoHandle.initialize(m_systematicsList));
38  ANA_CHECK(m_scaleFactorDecoration.initialize(m_systematicsList, m_eventInfoHandle));
39  ANA_CHECK(m_matchingDecoration.initialize(m_systematicsList, m_eventInfoHandle));
40 
41  ANA_CHECK (m_filterParams.initialize(m_systematicsList));
42 
43  // retrieve the trigger matching tool
44  ANA_CHECK(m_trigMatchingTool.retrieve());
45 
46  // prepare trigger data
47  TrigGlobEffCorr::ImportData triggerData;
48  ANA_CHECK(triggerData.importTriggers());
49  const auto & triggerDict = triggerData.getDictionary();
50  std::unordered_map<std::string, TrigGlobEffCorr::ImportData::TrigDef> triggerDefs;
51  for (const auto &[key, trigDef] : triggerData.getTriggerDefs()) {
52  auto it = triggerDict.find(key);
53  if (it != triggerDict.end()) {
54  triggerDefs[it->second] = trigDef;
55  }
56  }
57 
58  // now we can build a map of triggers per year, and extract the electron/photon legs as needed
59  std::unordered_map<std::string, std::vector<std::string> > trigMap;
60  trigMap["2015"] = m_trigList_2015;
61  trigMap["2016"] = m_trigList_2016;
62  trigMap["2017"] = m_trigList_2017;
63  trigMap["2018"] = m_trigList_2018;
64  trigMap["2022"] = m_trigList_2022;
65  trigMap["2023"] = m_trigList_2023;
66  trigMap["2024"] = m_trigList_2024;
67  trigMap["2025"] = m_trigList_2025;
68 
69  // combine all the trigger legs in the expected format
70  std::map<std::string, std::string> triggerCombination;
71  auto combineStrings = [](const std::vector<std::string>& input ) {
72  std::string combinedString;
73  bool first = true;
74  for (const auto & i : input) {
75  if (!first) {
76  combinedString += " || ";
77  }
78  combinedString += i;
79  first = false;
80  }
81  return combinedString;
82  };
83  for (const auto &[year, triggers] : trigMap) {
84  if (triggers.empty()) continue;
85  if (triggerCombination.find(year) == triggerCombination.end()) {
86  triggerCombination[year] = "";
87  } else {
88  triggerCombination[year] += " || ";
89  }
90  triggerCombination[year] += combineStrings(triggers);
91  }
92 
93  // collect the combined electron and photon trigger keys supported by Egamma
94  std::map<std::string,std::string> electronLegsPerKey, photonLegsPerKey;
95  if (!m_doMatchingOnly) {
96  if (m_isRun3Geo) {
97  ANA_CHECK(TrigGlobalEfficiencyCorrectionTool::suggestElectronMapKeys(triggerCombination, "2015_2025/rel22.2/2025_Precision2023_Recommendation", electronLegsPerKey));
98  }
99  else {
100  ANA_CHECK(TrigGlobalEfficiencyCorrectionTool::suggestElectronMapKeys(triggerCombination, "2015_2018/rel21.2/Precision_Summer2020_v1", electronLegsPerKey));
101  }
102  ANA_CHECK(TrigGlobalEfficiencyCorrectionTool::suggestPhotonMapKeys(triggerCombination, "2015_2018/rel21.2/Summer2020_Rec_v1", photonLegsPerKey));
103  }
104 
105  std::map<std::string, std::string> legsPerTool;
107 
108  // ELECTRON TOOLS
109  ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools, electronSFTools;
110  int nTools = 0;
111  if (!m_electronsHandle.empty() && !m_doMatchingOnly) {
112  if (m_electronID.empty()) ATH_MSG_ERROR("Electron ID was not set for TrigGlobalEfficiencyAlg!");
113  for (const auto &[trigKey, triggers] : electronLegsPerKey) {
114  if (trigKey == nameForDefaultSF) { // no tool needed in this case
115  auto [itr, added] = legsPerTool.emplace(nameForDefaultSF, triggers);
116  if (!added) itr->second += "," + triggers;
117  continue;
118  }
119  nTools++;
120  for (bool isSFTool : {true, false}) { // one tool instance for efficiencies, another for scale factors
121  auto t = m_electronToolsFactory.emplace(m_electronToolsFactory.end(),
122  "AsgElectronEfficiencyCorrectionTool/ElTrigEff_"
123  + std::to_string(isSFTool) + "_" + std::to_string(nTools) + "_" + m_electronID.value() + "_" + m_electronIsol.value());
124  if (!m_isRun3Geo) {
125  ANA_CHECK(t->setProperty("MapFilePath", "ElectronEfficiencyCorrection/2015_2018/rel21.2/Precision_Summer2020_v1/map4.txt"));
126  }
127  ANA_CHECK(t->setProperty("IdKey", m_electronID.value()));
128  ANA_CHECK(t->setProperty("IsoKey", m_electronIsol.value()));
129  ANA_CHECK(t->setProperty("TriggerKey", isSFTool ? trigKey : "Eff_" + trigKey ));
130  ANA_CHECK(t->setProperty("CorrelationModel", "TOTAL"));
131  ANA_CHECK(t->setProperty("ForceDataType", PATCore::ParticleDataType::Full));
132  ANA_CHECK(t->setProperty("OutputLevel", msg().level()));
133  ANA_CHECK(t->initialize());
134  // now record the handle
135  auto& handles = (isSFTool? electronSFTools : electronEffTools);
136  handles.push_back(t->getHandle());
137  std::string name = handles[handles.size()-1].name();
138  legsPerTool[name] = triggers;
139  // and add the systematics
140  ANA_CHECK(m_systematicsList.addSystematics( *handles[handles.size()-1] ));
141  }
142  }
143  }
144 
145  // PHOTON TOOLS
146  ToolHandleArray<IAsgPhotonEfficiencyCorrectionTool> photonEffTools, photonSFTools;
147  nTools = 0;
148  if (!m_photonsHandle.empty() && !m_doMatchingOnly) {
149  if (m_photonIsol.empty()) ATH_MSG_ERROR("Photon Isolation was not set for TrigGlobalEfficiencyAlg!");
150  for (const auto &[trigKey, triggers] : photonLegsPerKey) {
151  if (trigKey == nameForDefaultSF) { // no tool needed in this case
152  auto [itr, added] = legsPerTool.emplace(nameForDefaultSF, triggers);
153  if (!added) itr->second += "," + triggers;
154  continue;
155  }
156  nTools++;
157  for (bool isSFTool : {true, false}) { // one tool instance for efficiencies, another for scale factors
158  auto t = m_photonToolsFactory.emplace(m_photonToolsFactory.end(),
159  "AsgPhotonEfficiencyCorrectionTool/PhTrigEff_"
160  + std::to_string(isSFTool) + "_" + std::to_string(nTools) + "_" + m_photonIsol.value());
161  if (!m_isRun3Geo) {
162  ANA_CHECK(t->setProperty("MapFilePath", "PhotonEfficiencyCorrection/2015_2018/rel21.2/Summer2020_Rec_v1/map3.txt"));
163  }
164  ANA_CHECK(t->setProperty("IsoKey", m_photonIsol.value()));
165  ANA_CHECK(t->setProperty("TriggerKey", isSFTool ? trigKey : "Eff_" + trigKey ));
166  ANA_CHECK(t->setProperty("ForceDataType", PATCore::ParticleDataType::Full));
167  ANA_CHECK(t->setProperty("OutputLevel", msg().level()));
168  ANA_CHECK(t->initialize());
169  // now record the handle
170  auto& handles = (isSFTool? photonSFTools : photonEffTools);
171  handles.push_back(t->getHandle());
172  std::string name = handles[handles.size()-1].name();
173  legsPerTool[name] = triggers;
174  // and add the systematics
175  ANA_CHECK(m_systematicsList.addSystematics( *handles[handles.size()-1] ));
176  }
177  }
178  }
179 
180  // MUON TOOLS
181  ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
182  if (!m_muonsHandle.empty() && !m_doMatchingOnly) {
183  if (m_muonID.empty()) ATH_MSG_ERROR("Muon ID was not set for TrigGlobalEfficiencyAlg!");
184  m_muonTool = asg::AnaToolHandle<CP::IMuonTriggerScaleFactors>("CP::MuonTriggerScaleFactors/MuonTrigEff_" + m_muonID.value());
185  ANA_CHECK(m_muonTool.setProperty("MuonQuality", m_muonID.value()));
186  ANA_CHECK(m_muonTool.setProperty("AllowZeroSF", true));
187  ANA_CHECK(m_muonTool.initialize());
188  // now record the handle
189  muonTools.push_back(m_muonTool.getHandle());
190  // and add the efficiency systematics
191  ANA_CHECK(m_systematicsList.addSystematics( *m_muonTool ));
192  }
193 
194  // finally, set up the global trigger tool
195  m_tgecTool = asg::AnaToolHandle<ITrigGlobalEfficiencyCorrectionTool>("TrigGlobalEfficiencyCorrectionTool/TrigGlobal_" + this->name() );
196  ANA_CHECK(m_tgecTool.setProperty("ElectronEfficiencyTools", electronEffTools));
197  ANA_CHECK(m_tgecTool.setProperty("ElectronScaleFactorTools", electronSFTools));
198  ANA_CHECK(m_tgecTool.setProperty("PhotonEfficiencyTools", photonEffTools));
199  ANA_CHECK(m_tgecTool.setProperty("PhotonScaleFactorTools", photonSFTools));
200  ANA_CHECK(m_tgecTool.setProperty("MuonTools", muonTools));
201  ANA_CHECK(m_tgecTool.setProperty("ListOfLegsPerTool", legsPerTool));
202  ANA_CHECK(m_tgecTool.setProperty("TriggerCombination", triggerCombination));
203  ANA_CHECK(m_tgecTool.setProperty("TriggerMatchingTool", m_trigMatchingTool));
204  ANA_CHECK(m_tgecTool.setProperty("NumberOfToys", m_numToys));
205  ANA_CHECK(m_tgecTool.setProperty("OutputLevel", MSG::ERROR));
206  ANA_CHECK(m_tgecTool.initialize());
207 
208  ANA_CHECK(m_systematicsList.initialize());
209 
210  return StatusCode::SUCCESS;
211 }
212 
214 {
215 
216  CP::SysFilterReporterCombiner filterCombiner (m_filterParams, m_noFilter.value());
217 
218  for (const auto & syst : m_systematicsList.systematicsVector()) {
219  CP::SysFilterReporter filter (filterCombiner, syst);
220 
221  // retrieve lepton collections with selections
222  const xAOD::ElectronContainer* electrons(nullptr);
223  const xAOD::PhotonContainer* photons(nullptr);
224  const xAOD::MuonContainer* muons(nullptr);
225  std::vector<const xAOD::Electron*> selectedElectrons;
226  std::vector<const xAOD::Photon*> selectedPhotons;
227  std::vector<const xAOD::Muon*> selectedMuons;
228 
229  if (!m_electronsHandle.empty()) {
230  ANA_CHECK(m_electronsHandle.retrieve(electrons, syst));
231  for (const xAOD::Electron *el: *electrons) {
232  if (m_electronSelection.getBool(*el, syst)) selectedElectrons.push_back(el);
233  }
234  }
235  if (!m_photonsHandle.empty()) {
236  ANA_CHECK(m_photonsHandle.retrieve(photons, syst));
237  for (const xAOD::Photon *ph: *photons) {
238  if (m_photonSelection.getBool(*ph, syst)) selectedPhotons.push_back(ph);
239  }
240  }
241  if (!m_muonsHandle.empty()) {
242  ANA_CHECK(m_muonsHandle.retrieve(muons, syst));
243  for (const xAOD::Muon *mu: *muons) {
244  if (m_muonSelection.getBool(*mu, syst)) selectedMuons.push_back(mu);
245  }
246  }
247 
248  ANA_CHECK(m_tgecTool->applySystematicVariation(syst));
249 
250  // compute the scale factor
251  double sf;
252  if (selectedElectrons.empty() && selectedMuons.empty() && selectedPhotons.empty()) sf = 1.0;
253  else if (m_doMatchingOnly) sf = 1.0;
254  else {
255  sf = NAN;
256  m_tgecTool->getEfficiencyScaleFactor(selectedElectrons, selectedMuons, selectedPhotons,
257  sf).ignore();
258  }
259 
260  // check if we have trigger matching
261  bool matched = false;
262  if (!(selectedElectrons.empty() && selectedMuons.empty() && selectedPhotons.empty())) {
263  ANA_CHECK(m_tgecTool->checkTriggerMatching(matched, selectedElectrons, selectedMuons, selectedPhotons));
264  }
265  if (matched) filter.setPassed(true);
266 
267  // decorate them onto the EventInfo
268  const xAOD::EventInfo *evtInfo {nullptr};
269  ANA_CHECK(m_eventInfoHandle.retrieve(evtInfo, syst));
270  m_scaleFactorDecoration.set(*evtInfo, sf, syst);
271  m_matchingDecoration.set(*evtInfo, matched, syst);
272 
273  }
274 
275  return StatusCode::SUCCESS;
276 }
277 
279 {
280 
281  ANA_CHECK (m_filterParams.finalize());
282  return StatusCode::SUCCESS;
283 }
CP::SysFilterReporterCombiner
a reporter class that combines the filter decisions for all systematics
Definition: SysFilterReporterCombiner.h:34
asg::AnaToolHandle< CP::IMuonTriggerScaleFactors >
TrigGlobalEfficiencyCorrectionTool::suggestElectronMapKeys
static CP::CorrectionCode suggestElectronMapKeys(const std::map< std::string, std::string > &triggerCombination, const std::string &version, std::map< std::string, std::string > &legsPerKey)
Definition: TrigGlobalEfficiencyCorrectionTool.h:75
skel.it
it
Definition: skel.GENtoEVGEN.py:407
ANA_CHECK
#define ANA_CHECK(EXP)
check whether the given expression was successful
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:324
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
python.TrigTLAMonitorAlgorithm.triggers
triggers
Definition: TrigTLAMonitorAlgorithm.py:196
python.AtlRunQueryAMI.year
year
Definition: AtlRunQueryAMI.py:225
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
SysFilterReporter.h
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
covarianceTool.filter
filter
Definition: covarianceTool.py:514
CP::TrigGlobalEfficiencyAlg::m_trigMatchingTool
ToolHandle< Trig::IMatchingTool > m_trigMatchingTool
trigger matching tool
Definition: TrigGlobalEfficiencyAlg.h:55
PATCore::ParticleDataType::Full
@ Full
Definition: PATCoreEnums.h:22
CP::TrigGlobalEfficiencyAlg::initialize
virtual StatusCode initialize() final override
Definition: TrigGlobalEfficiencyAlg.cxx:20
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
TrigGlobEffCorr::ImportData
Definition: ImportData.h:86
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Definition: AthCommonDataStore.h:145
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
PATCoreEnums.h
CP::SysFilterReporter
a systematics aware filter reporter
Definition: SysFilterReporter.h:44
plotIsoValidation.el
el
Definition: plotIsoValidation.py:197
EL
This module defines the arguments passed from the BATCH driver to the BATCH worker.
Definition: AsgComponentFactories.h:16
TrigGlobEffCorr::ImportData::getDictionary
const std::map< std::size_t, std::string > & getDictionary() const
Definition: ImportData.h:142
SysFilterReporterCombiner.h
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
python.ElectronD3PDObject.matched
matched
Definition: ElectronD3PDObject.py:138
xAOD::Electron_v1
Definition: Electron_v1.h:34
EventInfo.h
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
CP::TrigGlobalEfficiencyAlg::finalize
virtual StatusCode finalize() final override
Definition: TrigGlobalEfficiencyAlg.cxx:278
xAOD::Photon_v1
Definition: Photon_v1.h:37
mapkey::sf
@ sf
Definition: TElectronEfficiencyCorrectionTool.cxx:38
CP::TrigGlobalEfficiencyAlg::execute
virtual StatusCode execute() final override
Definition: TrigGlobalEfficiencyAlg.cxx:213
DeMoScan.first
bool first
Definition: DeMoScan.py:534
ITrigGlobalEfficiencyCorrectionTool::toolnameForDefaultScaleFactor
static std::string toolnameForDefaultScaleFactor()
To be used with the ListOfLegsPerTool property:
Definition: ITrigGlobalEfficiencyCorrectionTool.h:56
TrigGlobEffCorr::ImportData::getTriggerDefs
const std::map< std::size_t, TrigDef > & getTriggerDefs() const
Definition: ImportData.h:126
TrigGlobEffCorr::ImportData::importTriggers
bool importTriggers()
Definition: ImportData.cxx:99
TrigGlobalEfficiencyAlg.h
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:51
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:30
CP::TrigGlobalEfficiencyAlg::TrigGlobalEfficiencyAlg
TrigGlobalEfficiencyAlg(const std::string &name, ISvcLocator *pSvcLocator=nullptr)
Definition: TrigGlobalEfficiencyAlg.cxx:13
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
TrigGlobalEfficiencyCorrectionTool::suggestPhotonMapKeys
static CP::CorrectionCode suggestPhotonMapKeys(const std::map< std::string, std::string > &triggerCombination, const std::string &version, std::map< std::string, std::string > &legsPerKey)
Definition: TrigGlobalEfficiencyCorrectionTool.h:82
InDetDD::electrons
@ electrons
Definition: InDetDD_Defs.h:17
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37