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_isRun3Geo) {
96  ANA_CHECK(TrigGlobalEfficiencyCorrectionTool::suggestElectronMapKeys(triggerCombination, "2015_2025/rel22.2/2022_Summer_Prerecom_v1", electronLegsPerKey));
97  }
98  else {
99  ANA_CHECK(TrigGlobalEfficiencyCorrectionTool::suggestElectronMapKeys(triggerCombination, "2015_2018/rel21.2/Precision_Summer2020_v1", electronLegsPerKey));
100  }
101  ANA_CHECK(TrigGlobalEfficiencyCorrectionTool::suggestPhotonMapKeys(triggerCombination, "2015_2018/rel21.2/Summer2020_Rec_v1", photonLegsPerKey));
102 
103  std::map<std::string, std::string> legsPerTool;
105 
106  // ELECTRON TOOLS
107  ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools, electronSFTools;
108  int nTools = 0;
109  if (!m_electronsHandle.empty() && !m_doMatchingOnly) {
110  if (m_electronID.empty()) ATH_MSG_ERROR("Electron ID was not set for TrigGlobalEfficiencyAlg!");
111  for (const auto &[trigKey, triggers] : electronLegsPerKey) {
112  if (trigKey == nameForDefaultSF) { // no tool needed in this case
113  auto [itr, added] = legsPerTool.emplace(nameForDefaultSF, triggers);
114  if (!added) itr->second += "," + triggers;
115  continue;
116  }
117  nTools++;
118  for (bool isSFTool : {true, false}) { // one tool instance for efficiencies, another for scale factors
119  auto t = m_electronToolsFactory.emplace(m_electronToolsFactory.end(),
120  "AsgElectronEfficiencyCorrectionTool/ElTrigEff_"
121  + std::to_string(isSFTool) + "_" + std::to_string(nTools) + "_" + m_electronID.value() + "_" + m_electronIsol.value());
122  if (!m_isRun3Geo) {
123  ANA_CHECK(t->setProperty("MapFilePath", "ElectronEfficiencyCorrection/2015_2018/rel21.2/Precision_Summer2020_v1/map4.txt"));
124  }
125  ANA_CHECK(t->setProperty("IdKey", m_electronID.value()));
126  ANA_CHECK(t->setProperty("IsoKey", m_electronIsol.value()));
127  ANA_CHECK(t->setProperty("TriggerKey", isSFTool ? trigKey : "Eff_" + trigKey ));
128  ANA_CHECK(t->setProperty("CorrelationModel", "TOTAL"));
129  ANA_CHECK(t->setProperty("ForceDataType", PATCore::ParticleDataType::Full));
130  ANA_CHECK(t->setProperty("OutputLevel", msg().level()));
131  ANA_CHECK(t->initialize());
132  // now record the handle
133  auto& handles = (isSFTool? electronSFTools : electronEffTools);
134  handles.push_back(t->getHandle());
135  std::string name = handles[handles.size()-1].name();
136  legsPerTool[name] = triggers;
137  // and add the systematics
138  ANA_CHECK(m_systematicsList.addSystematics( *handles[handles.size()-1] ));
139  }
140  }
141  }
142 
143  // PHOTON TOOLS
144  ToolHandleArray<IAsgPhotonEfficiencyCorrectionTool> photonEffTools, photonSFTools;
145  nTools = 0;
146  if (!m_photonsHandle.empty() && !m_doMatchingOnly) {
147  if (m_photonIsol.empty()) ATH_MSG_ERROR("Photon Isolation was not set for TrigGlobalEfficiencyAlg!");
148  for (const auto &[trigKey, triggers] : photonLegsPerKey) {
149  if (trigKey == nameForDefaultSF) { // no tool needed in this case
150  auto [itr, added] = legsPerTool.emplace(nameForDefaultSF, triggers);
151  if (!added) itr->second += "," + triggers;
152  continue;
153  }
154  nTools++;
155  for (bool isSFTool : {true, false}) { // one tool instance for efficiencies, another for scale factors
156  auto t = m_photonToolsFactory.emplace(m_photonToolsFactory.end(),
157  "AsgPhotonEfficiencyCorrectionTool/PhTrigEff_"
158  + std::to_string(isSFTool) + "_" + std::to_string(nTools) + "_" + m_photonIsol.value());
159  if (!m_isRun3Geo) {
160  ANA_CHECK(t->setProperty("MapFilePath", "PhotonEfficiencyCorrection/2015_2018/rel21.2/Summer2020_Rec_v1/map3.txt"));
161  }
162  ANA_CHECK(t->setProperty("IsoKey", m_photonIsol.value()));
163  ANA_CHECK(t->setProperty("TriggerKey", isSFTool ? trigKey : "Eff_" + trigKey ));
164  ANA_CHECK(t->setProperty("ForceDataType", PATCore::ParticleDataType::Full));
165  ANA_CHECK(t->setProperty("OutputLevel", msg().level()));
166  ANA_CHECK(t->initialize());
167  // now record the handle
168  auto& handles = (isSFTool? photonSFTools : photonEffTools);
169  handles.push_back(t->getHandle());
170  std::string name = handles[handles.size()-1].name();
171  legsPerTool[name] = triggers;
172  // and add the systematics
173  ANA_CHECK(m_systematicsList.addSystematics( *handles[handles.size()-1] ));
174  }
175  }
176  }
177 
178  // MUON TOOLS
179  ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
180  if (!m_muonsHandle.empty() && !m_doMatchingOnly) {
181  if (m_muonID.empty()) ATH_MSG_ERROR("Muon ID was not set for TrigGlobalEfficiencyAlg!");
182  m_muonTool = asg::AnaToolHandle<CP::IMuonTriggerScaleFactors>("CP::MuonTriggerScaleFactors/MuonTrigEff_" + m_muonID.value());
183  ANA_CHECK(m_muonTool.setProperty("MuonQuality", m_muonID.value()));
184  ANA_CHECK(m_muonTool.setProperty("AllowZeroSF", true));
185  ANA_CHECK(m_muonTool.initialize());
186  // now record the handle
187  muonTools.push_back(m_muonTool.getHandle());
188  // and add the efficiency systematics
189  ANA_CHECK(m_systematicsList.addSystematics( *m_muonTool ));
190  }
191 
192  // finally, set up the global trigger tool
193  m_tgecTool = asg::AnaToolHandle<ITrigGlobalEfficiencyCorrectionTool>("TrigGlobalEfficiencyCorrectionTool/TrigGlobal_" + this->name() );
194  ANA_CHECK(m_tgecTool.setProperty("ElectronEfficiencyTools", electronEffTools));
195  ANA_CHECK(m_tgecTool.setProperty("ElectronScaleFactorTools", electronSFTools));
196  ANA_CHECK(m_tgecTool.setProperty("PhotonEfficiencyTools", photonEffTools));
197  ANA_CHECK(m_tgecTool.setProperty("PhotonScaleFactorTools", photonSFTools));
198  ANA_CHECK(m_tgecTool.setProperty("MuonTools", muonTools));
199  ANA_CHECK(m_tgecTool.setProperty("ListOfLegsPerTool", legsPerTool));
200  ANA_CHECK(m_tgecTool.setProperty("TriggerCombination", triggerCombination));
201  ANA_CHECK(m_tgecTool.setProperty("TriggerMatchingTool", m_trigMatchingTool));
202  ANA_CHECK(m_tgecTool.setProperty("OutputLevel", MSG::ERROR));
203  ANA_CHECK(m_tgecTool.initialize());
204 
205  ANA_CHECK(m_systematicsList.initialize());
206 
207  return StatusCode::SUCCESS;
208 }
209 
211 {
212 
213  CP::SysFilterReporterCombiner filterCombiner (m_filterParams, m_noFilter.value());
214 
215  for (const auto & syst : m_systematicsList.systematicsVector()) {
216  CP::SysFilterReporter filter (filterCombiner, syst);
217 
218  // retrieve lepton collections with selections
219  const xAOD::ElectronContainer* electrons(nullptr);
220  const xAOD::PhotonContainer* photons(nullptr);
221  const xAOD::MuonContainer* muons(nullptr);
222  std::vector<const xAOD::Electron*> selectedElectrons;
223  std::vector<const xAOD::Photon*> selectedPhotons;
224  std::vector<const xAOD::Muon*> selectedMuons;
225 
226  if (!m_electronsHandle.empty()) {
227  ANA_CHECK(m_electronsHandle.retrieve(electrons, syst));
228  for (const xAOD::Electron *el: *electrons) {
229  if (m_electronSelection.getBool(*el, syst)) selectedElectrons.push_back(el);
230  }
231  }
232  if (!m_photonsHandle.empty()) {
233  ANA_CHECK(m_photonsHandle.retrieve(photons, syst));
234  for (const xAOD::Photon *ph: *photons) {
235  if (m_photonSelection.getBool(*ph, syst)) selectedPhotons.push_back(ph);
236  }
237  }
238  if (!m_muonsHandle.empty()) {
239  ANA_CHECK(m_muonsHandle.retrieve(muons, syst));
240  for (const xAOD::Muon *mu: *muons) {
241  if (m_muonSelection.getBool(*mu, syst)) selectedMuons.push_back(mu);
242  }
243  }
244 
245  ANA_CHECK(m_tgecTool->applySystematicVariation(syst));
246 
247  // compute the scale factor
248  double sf;
249  if (selectedElectrons.empty() && selectedMuons.empty() && selectedPhotons.empty()) sf = 1.0;
250  else if (m_doMatchingOnly) sf = 1.0;
251  else {
252  sf = NAN;
253  m_tgecTool->getEfficiencyScaleFactor(selectedElectrons, selectedMuons, selectedPhotons,
254  sf).ignore();
255  }
256 
257  // check if we have trigger matching
258  bool matched = false;
259  if (!(selectedElectrons.empty() && selectedMuons.empty() && selectedPhotons.empty())) {
260  ANA_CHECK(m_tgecTool->checkTriggerMatching(matched, selectedElectrons, selectedMuons, selectedPhotons));
261  }
262  if (matched) filter.setPassed(true);
263 
264  // decorate them onto the EventInfo
265  const xAOD::EventInfo *evtInfo {nullptr};
266  ANA_CHECK(m_eventInfoHandle.retrieve(evtInfo, syst));
267  m_scaleFactorDecoration.set(*evtInfo, sf, syst);
268  m_matchingDecoration.set(*evtInfo, matched, syst);
269 
270  }
271 
272  return StatusCode::SUCCESS;
273 }
274 
276 {
277 
278  ANA_CHECK (m_filterParams.finalize());
279  return StatusCode::SUCCESS;
280 }
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:62
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
TrigGlobEffCorr::ImportData::getTriggerDefs
const std::map< std::size_t, TrigDef > & getTriggerDefs() const
Definition: ImportData.h:125
skel.it
it
Definition: skel.GENtoEVGEN.py:396
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:226
TrigGlobEffCorr::ImportData::getDictionary
const std::map< std::size_t, std::string > & getDictionary() const
Definition: ImportData.h:130
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:88
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
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: AlgorithmWorkerData.h:24
SysFilterReporterCombiner.h
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
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:275
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:210
DeMoScan.first
bool first
Definition: DeMoScan.py:536
ITrigGlobalEfficiencyCorrectionTool::toolnameForDefaultScaleFactor
static std::string toolnameForDefaultScaleFactor()
To be used with the ListOfLegsPerTool property:
Definition: ITrigGlobalEfficiencyCorrectionTool.h:56
TrigGlobEffCorr::ImportData::importTriggers
bool importTriggers()
Definition: ImportData.cxx:106
TrigGlobalEfficiencyAlg.h
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
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:67
InDetDD::electrons
@ electrons
Definition: InDetDD_Defs.h:17
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37