ATLAS Offline Software
Trigger.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // This source file implements all of the functions related to trigger
6 // in the SUSYObjDef_xAOD class
7 
8 // Local include(s):
10 
17 
19 
20 #ifndef XAOD_STANDALONE // For now metadata is Athena-only
22 #endif
23 
24 #include <regex>
25 
26 namespace ST {
27 
28  const static SG::Decorator<char> dec_trigmatched("trigmatched");
29 
30 bool SUSYObjDef_xAOD::IsMETTrigPassed(unsigned int runnumber, bool j400_OR) const {
31 
32  // Returns MET trigger decision for recommended lowest unprescaled evolution described in
33  // https://twiki.cern.ch/twiki/bin/viewauth/Atlas/LowestUnprescaled
34  // For period vs run number, see https://atlas-tagservices.cern.ch/tagservices/RunBrowser/runBrowserReport/rBR_Period_Report.php
35 
36  // if no runNumber specified, just read it from the current event
37  unsigned int rn;
38  if(runnumber>0){
39  rn = runnumber;
40  }
41  else{
42  rn = GetRunNumber(); // it takes care of dealing with data and MC
43  }
44 
45  int year = treatAsYear(rn);
46 
47  if (year == 2015) return IsMETTrigPassed("HLT_xe70_mht",j400_OR); //2015
48  else if(year == 2016 && rn >= 296939 && rn <= 302872 ) return IsMETTrigPassed("HLT_xe90_mht_L1XE50",j400_OR); //2016 A-D3
49  else if(year == 2016 && rn >= 302919 && rn <= 303892 ) return IsMETTrigPassed("HLT_xe100_mht_L1XE50",j400_OR); //2016 D4-F1
50  else if(year == 2016 && rn >= 303943) return IsMETTrigPassed("HLT_xe110_mht_L1XE50",j400_OR); //2016 F2-(open)
51  else if(year == 2017 && rn >= 325713 && rn <= 331975 ) return IsMETTrigPassed("HLT_xe110_pufit_L1XE55", false); // 2017 B1-D5
52  else if(year == 2017 && rn >= 332303 ) return IsMETTrigPassed("HLT_xe110_pufit_L1XE50", false); // 2017 D6-(open)
53  else if(year == 2018 && rn >= 348885 && rn <= 350013 ) return IsMETTrigPassed("HLT_xe110_pufit_xe70_L1XE50", false); // 2018 B-C5
54  else if(year == 2018 && rn >= 350067 ) return IsMETTrigPassed("HLT_xe110_pufit_xe65_L1XE50", false); // 2018 C5-(open)
55  else if(year == 2022) return IsMETTrigPassed("HLT_xe65_cell_xe90_pfopufit_L1XE50",false); // 2022
56  else if(year == 2023) return IsMETTrigPassed("HLT_xe65_cell_xe90_pfopufit_L1XE50",false); // 2023
57  else if(year == 2024) return IsMETTrigPassed("HLT_xe65_cell_xe105_nn_L1jXE100",false); // 2024
58 
59  return false;
60 }
61 
62 // Can't be const because of the lazy init of the map - JBurr: Now fixed
63 bool SUSYObjDef_xAOD::IsMETTrigPassed(const std::string& triggerName, bool j400_OR) const {
64  // NB - this now applies to the entire function...
65  //std::string L1item = "L1_XE50"; For now, I'll assume all the triggers use L1_XE50 - might need changing in the future.
66 
67  // First check if we're affected by the L1_XE50 bug
68  bool L1_XE50 = m_trigDecTool->isPassed("L1_XE50");
69  bool L1_XE55 = m_trigDecTool->isPassed("L1_XE55");
70  bool HLT_noalg_L1J400 = m_trigDecTool->isPassed("HLT_noalg_L1J400");
71  if (!L1_XE50 && j400_OR && HLT_noalg_L1J400) {
72  return emulateHLT(triggerName);
73  }
74  else if (L1_XE50 || L1_XE55) {
75  // See if the TDT knows about this
76  {
77  std::scoped_lock lock (m_triggerCacheMutex);
78  if (isTrigInTDT(lock, triggerName) ) return m_trigDecTool->isPassed(triggerName);
79  }
80  return emulateHLT(triggerName);
81  }
82  return false;
83 }
84 
85 bool SUSYObjDef_xAOD::isTrigInTDT(std::scoped_lock<std::mutex>& /*lock*/,
86  const std::string& triggerName) const
87 {
88  auto mapItr = m_checkedTriggers.find(triggerName);
89  if ( mapItr == m_checkedTriggers.end() ) {
90  const auto *cg = m_trigDecTool->getChainGroup(triggerName);
91  return m_checkedTriggers[triggerName] = cg->getListOfTriggers().size() != 0;
92  }
93  else {
94  return mapItr->second;
95  }
96 }
97 
98 
99 bool SUSYObjDef_xAOD::emulateHLT(const std::string& triggerName) const {
100  std::scoped_lock lock (m_triggerCacheMutex);
101  // First, check if we've already tried using this trigger
102  auto funcItr = m_metTriggerFuncs.find(triggerName);
103  if (funcItr != m_metTriggerFuncs.end() )
104  return funcItr->second();
105 
106  // Next, check that it really is a HLT MET trigger
107  if (triggerName.substr(0,6) != "HLT_xe") {
108  ATH_MSG_ERROR( "Requested trigger " << triggerName << " isn't a MET trigger! (HLT MET items should begin with 'HLT_xe'). Will return false." );
109  return false;
110  }
111 
112  // Next, parse the name to work out which containers are needed to emulate the decision
113  std::vector<std::pair<int, std::string> > hypos; // algorithms and thresholds needed
114  std::string temp(triggerName);
115  // Note, we need to split on '_AND_' used for the combined mht+cell trigger
116  do {
117  auto pos = temp.find("_AND_");
118  std::string itemName = temp.substr(0, pos);
119  ATH_MSG_DEBUG( "Split trigger item " << itemName );
120  if (pos == std::string::npos)
121  temp = "";
122  else
123  temp = temp.substr(pos + 5);
124 
125  std::regex expr("HLT_xe([[:digit:]]+)_?(mht|pufit|pueta|tc_lcw|)_?(?:L1XE([[:digit:]]+)|)");
126  std::smatch sm;
127  if (!std::regex_match(itemName, sm, expr) ) {
128  ATH_MSG_WARNING( "Regex reading for item " << itemName << " (" << triggerName << ") failed! Will be ignored!" );
129  continue;
130  }
131  if (sm.size() < 4) { // first object is the whole match, then there are three capture groups
132  ATH_MSG_WARNING( "Regex failed to capture the right groups for item " << itemName << " (" << triggerName << ") failed! Will be ignored!" );
133  for (unsigned int ii = 0; ii < sm.size(); ++ii) {
134  ATH_MSG_WARNING( sm[ii] );
135  }
136  continue;
137  }
138  int threshold = std::stoi(sm[1] );
139  std::string algKey = sm[2];
140  std::string metContBaseName = "HLT_xAOD__TrigMissingETContainer_TrigEFMissingET";
141  if (algKey.empty()) hypos.push_back(std::make_pair(threshold, metContBaseName) );
142  else if (algKey == "mht") hypos.push_back(std::make_pair(threshold, metContBaseName+"_mht") );
143  else if (algKey == "pufit") hypos.push_back(std::make_pair(threshold, metContBaseName+"_topocl_PUC") );
144  else if (algKey == "pueta") hypos.push_back(std::make_pair(threshold, metContBaseName+"_topocl_PS") );
145  else if (algKey == "tc_lcw") hypos.push_back(std::make_pair(threshold, metContBaseName+"topocl") );
146 
147  ATH_MSG_DEBUG( "Container: " << hypos.back().second << ", Threshold: " << hypos.back().first );
148 
149  if (sm[3] != "" && sm[3] != "50") {
150  ATH_MSG_WARNING( "The trigger requires a different L1 item to L1_XE50! This currently isn't allowed for in the code so the emulation will be slightly wrong" );
151  // Note, now the L1 part is done in the previous section. However I'm keeping this warning here.
152  }
153  }
154  while (!temp.empty());
155 
156  // Check if we have the containers and construct the lambda
157  // Already done the L1 decision - only care about HLT
158  std::function<bool()> lambda;
159  bool hasRequired = true;
160  if (hypos.empty()) lambda = [] () {return false;};
161  else {
162  for (const auto& pair : hypos) {
163  if (evtStore()->contains<xAOD::TrigMissingETContainer>(pair.second) ) {
164  auto lambda_hypo = [this, pair] () {
165  const xAOD::TrigMissingETContainer* cont(nullptr);
166  if (evtStore()->retrieve(cont, pair.second) ) {
167  if (cont->empty()) return false;
168  float ex = cont->front()->ex() * 0.001;
169  float ey = cont->front()->ey() * 0.001;
170  float met = std::sqrt(ex*ex + ey*ey);
171  return met > pair.first;
172  }
173  else {
174  return false;
175  }
176  };
177  // an empty std::function evaluates to false
178  if (lambda) {
179  lambda = [lambda, lambda_hypo] () {
180  return lambda() && lambda_hypo();
181  };
182  }
183  else {
184  lambda = lambda_hypo;
185  }
186  }
187  else {
188  hasRequired = false;
189  ATH_MSG_WARNING( "Container: " << pair.second << " missing!" );
190  }
191  }
192  }
193  if (hasRequired) {
194  m_metTriggerFuncs[triggerName] = lambda;
195  return m_metTriggerFuncs.at(triggerName)();
196  }
197  // We can't get the exact trigger decision :( . Look for an alternative
198  std::vector<std::string> replacementTriggers({"HLT_xe110_mht_L1XE50", "HLT_xe100_mht_L1XE50", "HLT_xe90_mht_L1XE50", "HLT_xe70_mht"});
199  for (const std::string& trigName : replacementTriggers) {
200  if (isTrigInTDT(lock, trigName) ) {
201  ATH_MSG_WARNING( "Trigger " << triggerName << " not available and direct emulation impossible! Will use " << trigName << " instead!");
202  m_metTriggerFuncs[triggerName] = [this, trigName] () {
203  return m_trigDecTool->isPassed(trigName);
204  };
205  return m_metTriggerFuncs.at(triggerName)();
206  }
207  }
208  ATH_MSG_ERROR( "Cannot find the trigger in the menu, direct emulation is impossible and no replacement triggers are available! Will return false" );
209  m_metTriggerFuncs.at(triggerName) = [] () {return false;};
210  return m_metTriggerFuncs.at(triggerName)();
211 }
212 
213 
214 
215 bool SUSYObjDef_xAOD::IsTrigPassed(const std::string& tr_item, unsigned int condition) const {
216  return m_trigDecTool->isPassed(tr_item, condition);
217 }
218 
219 
220 bool SUSYObjDef_xAOD::IsTrigMatched(const xAOD::IParticle *part, const std::string& tr_item) {
221  return this->IsTrigMatched({part}, tr_item);
222 }
223 
224 
225 bool SUSYObjDef_xAOD::IsTrigMatched(const xAOD::IParticle *part1, const xAOD::IParticle *part2, const std::string& tr_item) {
226  return this->IsTrigMatched({part1, part2}, tr_item);
227 }
228 
229 
230 bool SUSYObjDef_xAOD::IsTrigMatched(const std::vector<const xAOD::IParticle*>& v, const std::string& tr_item) {
231  return m_trigMatchingTool->match(v, tr_item);
232 }
233 
234 
235 bool SUSYObjDef_xAOD::IsTrigMatched(const std::initializer_list<const xAOD::IParticle*> &v, const std::string& tr_item) {
236  return m_trigMatchingTool->match(v, tr_item);
237 }
238 
239 
241  dec_trigmatched(*p) = 0;
242 
243  for(const auto *it = i1; it != i2; ++it) {
244  auto result = static_cast<int>(this->IsTrigMatched(p, *it));
245  dec_trigmatched(*p) += result;
246  const SG::Decorator<char> dec(*it);
247  dec(*p) = result;
248  }
249 }
250 
251 
252 void SUSYObjDef_xAOD::TrigMatch(const xAOD::IParticle* p, const std::initializer_list<std::string>& items) {
253  this->TrigMatch(p, items.begin(), items.end());
254 }
255 
256 
257 void SUSYObjDef_xAOD::TrigMatch(const xAOD::IParticle* p, const std::vector<std::string>& items) {
258  dec_trigmatched(*p) = 0;
259 
260  for(const auto& item: items) {
261  auto result = static_cast<int>(this->IsTrigMatched(p, item));
262  dec_trigmatched(*p) += result;
263  const SG::Decorator<char> dec(item);
264  dec(*p) = result;
265  }
266 }
267 
268 
269 void SUSYObjDef_xAOD::TrigMatch(const std::initializer_list<const xAOD::IParticle*> &v, const std::initializer_list<std::string> &items) {
270  for(const auto& p : v) {
271  this->TrigMatch(p, items);
272  }
273 }
274 
275 
276 void SUSYObjDef_xAOD::TrigMatch(const std::initializer_list<const xAOD::IParticle*> &v, const std::vector<std::string>& items) {
277  for(const auto& p : v) {
278  this->TrigMatch(p, items);
279  }
280 }
281 
282 
283 void SUSYObjDef_xAOD::TrigMatch(const xAOD::IParticleContainer* v, const std::vector<std::string>& items) {
284  for(const auto& p : *v) {
285  this->TrigMatch(p, items);
286  }
287 }
288 
289 
290 void SUSYObjDef_xAOD::TrigMatch(const xAOD::IParticleContainer* v, const std::initializer_list<std::string>& items) {
291  for(const auto& p : *v) {
292  this->TrigMatch(p, items);
293  }
294 }
295 
296 
297 void SUSYObjDef_xAOD::TrigMatch(const xAOD::IParticle* p, const std::string& item) {
298  return this->TrigMatch(p, {item});
299 }
300 
301 
302 void SUSYObjDef_xAOD::TrigMatch(const xAOD::IParticleContainer* v, const std::string& item) {
303  return this->TrigMatch(v, {item});
304 }
305 
306 
307 void SUSYObjDef_xAOD::TrigMatch(const std::initializer_list<const xAOD::IParticle*> &v, const std::string& item) {
308  return this->TrigMatch(v, {item});
309 }
310 
311 
312 float SUSYObjDef_xAOD::GetTrigPrescale(const std::string & tr_item) const {
313  return m_trigDecTool->getPrescale(tr_item);
314 }
315 
316 
317 const Trig::ChainGroup* SUSYObjDef_xAOD::GetTrigChainGroup(const std::string& tr_item) const {
318  return m_trigDecTool->getChainGroup(tr_item);
319 }
320 
321 
322  std::vector<std::string> SUSYObjDef_xAOD::GetTriggerOR(const std::string& trigExpr) const {
323 
324  static const std::string delOR = "_OR_";
325  std::vector<std::string> trigchains = {};
326  std::string newtrigExpr = TString(trigExpr).Copy().ReplaceAll("||",delOR).Data();
327  newtrigExpr = TString(trigExpr).Copy().ReplaceAll(" ","").Data();
328 
329  size_t pos = 0;
330  while ((pos = newtrigExpr.find(delOR)) != std::string::npos) {
331  trigchains.push_back( "HLT_"+newtrigExpr.substr(0, pos) );
332  newtrigExpr.erase(0, pos + delOR.length());
333  }
334  if(pos==std::string::npos)
335  trigchains.push_back("HLT_"+newtrigExpr);
336 
337  return trigchains;
338  }
339 
340  void SUSYObjDef_xAOD::GetTriggerTokens(std::string trigExpr, std::vector<std::string>& v_trigs15_cache, std::vector<std::string>& v_trigs16_cache, std::vector<std::string>& v_trigs17_cache, std::vector<std::string>& v_trigs18_cache, std::vector<std::string>& v_trigs22_cache) const {
341 
342  // e.g. 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
343 
344  static const std::string del15 = "_2015_";
345  static const std::string del16 = "_2016_";
346  static const std::string del17 = "_2017_";
347  static const std::string del18 = "_2018_";
348  static const std::string del22 = "_2022_";
349 
350  size_t pos = 0;
351  std::string token15, token16, token17, token18, token22;
352 
353  //get trigger tokens for 2015, 2016, 2017, 2018 and 2022
354  if ( (pos = trigExpr.find(del15)) != std::string::npos) {
355  trigExpr.erase(0, pos + del15.length());
356 
357  pos = 0;
358  while ((pos = trigExpr.find(del16)) != std::string::npos) {
359  token15 = trigExpr.substr(0, pos);
360  token16 = trigExpr.erase(0, pos + del16.length() + del17.length() - 1);
361  // 2016-2018 use exact the same trigger string
362  token17 = token16;
363  token18 = token16;
364  }
365  }
366 
367  if ( (pos = trigExpr.find(del22)) != std::string::npos) {
368  trigExpr.erase(0, pos + del22.length());
369  }
370 
371  //redefine in case of custom user input
372  if(!m_isRun3){
373  if(token15.empty()) token15 = trigExpr;
374  if(token16.empty()) token16 = trigExpr;
375  if(token17.empty()) token17 = trigExpr;
376  if(token18.empty()) token18 = trigExpr;
377  }
378  else{
379  if(token22.empty()) token22 = trigExpr;
380  }
381 
382  //get trigger chains for matching in 2015 and 2018
383  if(!m_isRun3){
384  v_trigs15_cache = GetTriggerOR(token15);
385  v_trigs16_cache = GetTriggerOR(token16);
386  v_trigs17_cache = GetTriggerOR(token17);
387  v_trigs18_cache = GetTriggerOR(token18);
388  }
389  //get trigger chains for matching in 2022
390  else{
391  v_trigs22_cache = GetTriggerOR(token22);
392  }
393  }
394 
396  {
398  }
399 
401 
402  double trig_sf(1.);
403 
404  if (trigExpr!="multiLepton" && trigExpr!="diLepton") {
405  ATH_MSG_ERROR( "Failed to retrieve multi-lepton trigger SF");
406  return trig_sf;
407  }
408 
409  std::vector<const xAOD::Electron*> elec_trig;
410  for (const xAOD::Electron* electron : electrons) {
411  if (!acc_passOR(*electron)) continue;
412  if (!acc_signal(*electron)) continue;
413  elec_trig.push_back(electron);
414  }
415 
416  std::vector<const xAOD::Muon*> muon_trig;
417  for (const xAOD::Muon* muon : muons) {
418  if (!acc_passOR(*muon)) continue;
419  if (!acc_signal(*muon)) continue;
420  muon_trig.push_back(muon);
421  }
422 
423  bool matched = false;
424  if ((elec_trig.size()+muon_trig.size())>1 && trigExpr=="diLepton") {
426  ATH_MSG_ERROR ("trigGlobEffCorrTool::Trigger matching could not be checked, interrupting execution.");
427  }
428  } else if ((elec_trig.size()+muon_trig.size())>2 && trigExpr=="multiLepton") {
430  ATH_MSG_ERROR ("trigGlobEffCorrTool::Trigger matching could not be checked, interrupting execution.");
431  }
432  }
433 
435  if ((elec_trig.size()+muon_trig.size())>1 && trigExpr=="diLepton" && matched) {
436  result = m_trigGlobalEffCorrTool_diLep->getEfficiencyScaleFactor( elec_trig, muon_trig, trig_sf);
437  }
438  else if ((elec_trig.size()+muon_trig.size())>2 && trigExpr=="multiLepton" && matched) {
439  result = m_trigGlobalEffCorrTool_multiLep->getEfficiencyScaleFactor( elec_trig, muon_trig, trig_sf);
440  }
441 
442  switch (result) {
444  ATH_MSG_ERROR( "Failed to retrieve multi-lepton trigger SF");
445  return 1.;
447  ATH_MSG_VERBOSE( "OutOfValidityRange found for multi-lepton trigger SF");
448  return 1.;
449  default:
450  break;
451  }
452 
453  return trig_sf;
454 }
455 
456 double SUSYObjDef_xAOD::GetTriggerGlobalEfficiencySFsys(const xAOD::ElectronContainer& electrons, const xAOD::MuonContainer& muons, const CP::SystematicSet& systConfig, const std::string& trigExpr) {
457 
458  double sf(1.);
459 
460  //Set the new systematic variation
461  if (trigExpr == "diLepton") {
463  if (ret != StatusCode::SUCCESS) {
464  ATH_MSG_ERROR("Cannot configure TrigGlobalEfficiencyCorrectionTool (dilepton trigger) for systematic var. " << systConfig.name() );
465  }
466  }
467 
468  if (trigExpr == "multiLepton") {
470  if (ret != StatusCode::SUCCESS) {
471  ATH_MSG_ERROR("Cannot configure TrigGlobalEfficiencyCorrectionTool (multi-lepton trigger) for systematic var. " << systConfig.name() );
472  }
473  }
474 
475  //Get the SF for new config
476  sf = GetTriggerGlobalEfficiencySF (electrons, muons, trigExpr);
477 
478  //Roll back to default
479  if (trigExpr == "diLepton") {
481  if (ret != StatusCode::SUCCESS) {
482  ATH_MSG_ERROR("Cannot configure TrigGlobalEfficiencyCorrectionTool (dilepton trigger) back to default.");
483  }
484  }
485  if (trigExpr == "multiLepton") {
487  if (ret != StatusCode::SUCCESS) {
488  ATH_MSG_ERROR("Cannot configure TrigGlobalEfficiencyCorrectionTool (multi-lepton trigger) back to default.");
489  }
490  }
491 
492  return sf;
493 }
494 
495 //
496 // GetTriggerGlobalEfficiencySF function is meant to be used for "asymmetric" diphoton trigger SFs
497 //
498 double SUSYObjDef_xAOD::GetTriggerGlobalEfficiencySF(const xAOD::PhotonContainer& photons, const std::string& trigExpr) {
499 
500  double trig_sf(1.);
501 
502  if (trigExpr!="diPhoton") {
503  ATH_MSG_ERROR( "Failed to retrieve diphoton trigger SF");
504  return trig_sf;
505  }
506 
507  std::vector<const xAOD::Photon*> ph_trig;
508  for (const xAOD::Photon* photon : photons) {
509  if (!acc_passOR(*photon)) continue;
510  if (!acc_signal(*photon)) continue;
511  ph_trig.push_back(photon);
512  }
513 
515  if (ph_trig.size()>1) {
517  }
518 
519  switch (result) {
521  ATH_MSG_ERROR( "Failed to retrieve diphoton trigger SF");
522  return 1.;
524  ATH_MSG_VERBOSE( "OutOfValidityRange found for diphoton trigger SF");
525  return 1.;
526  default:
527  break;
528  }
529 
530  return trig_sf;
531 }
532 
533 double SUSYObjDef_xAOD::GetTriggerGlobalEfficiencySFsys(const xAOD::PhotonContainer& photons, const CP::SystematicSet& systConfig, const std::string& trigExpr) {
534 
535  double sf(1.);
536 
537  //Set the new systematic variation
539  if (ret != StatusCode::SUCCESS) {
540  ATH_MSG_ERROR("Cannot configure TrigGlobalEfficiencyCorrectionTool (diphoton trigger) for systematic var. " << systConfig.name() );
541  }
542 
543  //Get the SF for new config
544  sf = GetTriggerGlobalEfficiencySF (photons, trigExpr);
545 
546  //Roll back to default
548  if (ret != StatusCode::SUCCESS) {
549  ATH_MSG_ERROR("Cannot configure TrigGlobalEfficiencyCorrectionTool (diphoton trigger) back to default.");
550  }
551 
552  return sf;
553 }
554 
556 
557  double trig_eff(1.);
558  double trig_eff_data(1.);
559 
560  if (trigExpr!="multiLepton" && trigExpr!="diLepton") {
561  ATH_MSG_ERROR( "Failed to retrieve multi-lepton trigger efficiency");
562  return trig_eff;
563  }
564 
565  std::vector<const xAOD::Electron*> elec_trig;
566  for (const xAOD::Electron* electron : electrons) {
567  if (!acc_passOR(*electron)) continue;
568  if (!acc_signal(*electron)) continue;
569  elec_trig.push_back(electron);
570  }
571 
572  std::vector<const xAOD::Muon*> muon_trig;
573  for (const xAOD::Muon* muon : muons) {
574  if (!acc_passOR(*muon)) continue;
575  if (!acc_signal(*muon)) continue;
576  muon_trig.push_back(muon);
577  }
578 
579  bool matched = false;
580  if ((elec_trig.size()+muon_trig.size())>1 && trigExpr=="diLepton") {
582  ATH_MSG_ERROR ("trigGlobEffCorrTool::Trigger matching could not be checked, interrupting execution.");
583  }
584  } else if ((elec_trig.size()+muon_trig.size())>2 && trigExpr=="multiLepton") {
586  ATH_MSG_ERROR ("trigGlobEffCorrTool::Trigger matching could not be checked, interrupting execution.");
587  }
588  }
589 
591  if ((elec_trig.size()+muon_trig.size())>1 && trigExpr=="diLepton" && matched) {
592  result = m_trigGlobalEffCorrTool_diLep->getEfficiency( elec_trig, muon_trig, trig_eff_data, trig_eff);
593  }
594  else if ((elec_trig.size()+muon_trig.size())>2 && trigExpr=="multiLepton" && matched) {
595  result = m_trigGlobalEffCorrTool_multiLep->getEfficiency( elec_trig, muon_trig, trig_eff_data, trig_eff);
596  }
597 
598  switch (result) {
600  ATH_MSG_ERROR( "Failed to retrieve multi-lepton trigger efficiency");
601  return 1.;
603  ATH_MSG_VERBOSE( "OutOfValidityRange found for multi-lepton trigger efficiency");
604  return 1.;
605  default:
606  break;
607  }
608 
609  if (isData()) return trig_eff_data;
610  else return trig_eff;
611 }
612 
613 //
614 // GetTriggerGlobalEfficiency function is meant to be used for "asymmetric" diphoton trigger SFs
615 //
616 double SUSYObjDef_xAOD::GetTriggerGlobalEfficiency(const xAOD::PhotonContainer& photons, const std::string& trigExpr) {
617 
618  double trig_eff(1.);
619  double trig_eff_data(1.);
620 
621  if (trigExpr!="diPhoton") {
622  ATH_MSG_ERROR( "Failed to retrieve diphoton trigger efficiency");
623  return trig_eff;
624  }
625 
626  std::vector<const xAOD::Photon*> ph_trig;
627  for (const xAOD::Photon* photon : photons) {
628  if (!acc_passOR(*photon)) continue;
629  if (!acc_signal(*photon)) continue;
630  ph_trig.push_back(photon);
631  }
632 
634  if (ph_trig.size()>1) {
635  result = m_trigGlobalEffCorrTool_diPhoton->getEfficiency(ph_trig, trig_eff_data, trig_eff);
636  }
637 
638  switch (result) {
640  ATH_MSG_ERROR( "Failed to retrieve diphoton trigger efficiency");
641  return 1.;
643  ATH_MSG_VERBOSE( "OutOfValidityRange found for diphoton trigger efficiency");
644  return 1.;
645  default:
646  break;
647  }
648 
649  if (isData()) return trig_eff_data;
650  else return trig_eff;
651 }
652 
653 }
654 
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
ST::SUSYObjDef_xAOD::emulateHLT
bool emulateHLT(const std::string &triggerName) const
Definition: Trigger.cxx:99
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
ST::SUSYObjDef_xAOD::m_trigGlobalEffCorrTool_multiLep
asg::AnaToolHandle< ITrigGlobalEfficiencyCorrectionTool > m_trigGlobalEffCorrTool_multiLep
Definition: SUSYObjDef_xAOD.h:942
ST::SUSYObjDef_xAOD::GetTriggerGlobalEfficiencySFsys
double GetTriggerGlobalEfficiencySFsys(const xAOD::ElectronContainer &electrons, const xAOD::MuonContainer &muons, const CP::SystematicSet &systConfig, const std::string &trigExpr="diLepton") override final
Definition: Trigger.cxx:456
ST::SUSYObjDef_xAOD::m_triggerCacheMutex
std::mutex m_triggerCacheMutex
Definition: SUSYObjDef_xAOD.h:446
get_generator_info.result
result
Definition: get_generator_info.py:21
ST::SUSYObjDef_xAOD::m_trigGlobalEffCorrTool_diPhoton
asg::AnaToolHandle< ITrigGlobalEfficiencyCorrectionTool > m_trigGlobalEffCorrTool_diPhoton
Definition: SUSYObjDef_xAOD.h:950
FeatureContainer.h
ITrigConfigTool.h
ITrigGlobalEfficiencyCorrectionTool.h
ST::SUSYObjDef_xAOD::GetTriggerOR
std::vector< std::string > GetTriggerOR(const std::string &trigExpr) const
Definition: Trigger.cxx:322
ST::SUSYObjDef_xAOD::GetTriggerTokens
void GetTriggerTokens(std::string, std::vector< std::string > &, std::vector< std::string > &, std::vector< std::string > &, std::vector< std::string > &, std::vector< std::string > &) const
Definition: Trigger.cxx:340
ST::SUSYObjDef_xAOD::GetTriggerFeatures
Trig::FeatureContainer GetTriggerFeatures(const std::string &chainName="EF_.*", unsigned int condition=TrigDefs::Physics) const
Definition: Trigger.cxx:395
ST
Definition: Electrons.cxx:41
skel.it
it
Definition: skel.GENtoEVGEN.py:396
CP::SystematicSet
Class to wrap a set of SystematicVariations.
Definition: SystematicSet.h:31
CP::SystematicSet::name
std::string name() const
returns: the systematics joined into a single string.
Definition: SystematicSet.cxx:278
SUSYObjDef_xAOD.h
TrigDecisionTool.h
LArG4GenerateShowerLib.condition
condition
Definition: LArG4GenerateShowerLib.py:19
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
ST::SUSYObjDef_xAOD::m_trigMatchingTool
asg::AnaToolHandle< Trig::IMatchingTool > m_trigMatchingTool
Definition: SUSYObjDef_xAOD.h:954
python.AtlRunQueryAMI.year
year
Definition: AtlRunQueryAMI.py:226
Trig::TrigDecisionToolCore::features
FeatureContainer features(const Trig::ChainGroup *group, unsigned int condition=TrigDefs::Physics) const
Runs 1, 2.
Definition: DecisionAccess.cxx:92
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
Trig::FeatureContainer
Definition: FeatureContainer.h:54
part1
Definition: part1.py:1
ST::SUSYObjDef_xAOD::m_trigGlobalEffCorrTool_diLep
asg::AnaToolHandle< ITrigGlobalEfficiencyCorrectionTool > m_trigGlobalEffCorrTool_diLep
Definition: SUSYObjDef_xAOD.h:934
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
CP::CorrectionCode::OutOfValidityRange
@ OutOfValidityRange
Input object is out of validity range.
Definition: CorrectionCode.h:37
CP::CorrectionCode::Error
@ Error
Some error happened during the object correction.
Definition: CorrectionCode.h:36
met
Definition: IMETSignificance.h:24
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ST::SUSYObjDef_xAOD::GetRunNumber
unsigned int GetRunNumber() const override final
Definition: SUSYObjDef_xAOD.cxx:3017
SG::Decorator< char >
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ST::SUSYObjDef_xAOD::IsTrigPassed
bool IsTrigPassed(const std::string &, unsigned int condition=TrigDefs::Physics) const override final
Definition: Trigger.cxx:215
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
DataVector::front
const T * front() const
Access the first element in the collection as an rvalue.
python.BunchSpacingUtils.rn
rn
Definition: BunchSpacingUtils.py:87
TrigMissingETContainer.h
ST::SUSYObjDef_xAOD::isData
bool isData() const override final
Definition: SUSYObjDef_xAOD.h:156
ST::SUSYObjDef_xAOD::IsTrigMatched
bool IsTrigMatched(const xAOD::IParticle *part, const std::string &tr_item) override final
Definition: Trigger.cxx:220
ST::SUSYObjDef_xAOD::GetTriggerGlobalEfficiency
double GetTriggerGlobalEfficiency(const xAOD::ElectronContainer &electrons, const xAOD::MuonContainer &muons, const std::string &trigExpr="diLepton") override final
Definition: Trigger.cxx:555
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
Trig::TrigDecisionTool::isPassed
virtual bool isPassed(const std::string &chain, unsigned int condition) const
true if given chain passed
Definition: TrigDecisionTool.cxx:270
DeMoScan.runnumber
runnumber
Definition: DeMoScan.py:266
part2
Definition: part2.py:1
Trig::ChainGroup
Definition: ChainGroup.h:51
ST::SUSYObjDef_xAOD::IsMETTrigPassed
bool IsMETTrigPassed(unsigned int runnumber=0, bool j400_OR=false) const override final
Definition: Trigger.cxx:30
ST::SUSYObjDef_xAOD::TrigMatch
void TrigMatch(const xAOD::IParticle *p, std::initializer_list< std::string >::iterator, std::initializer_list< std::string >::iterator) override final
Definition: Trigger.cxx:240
threshold
Definition: chainparser.cxx:74
python.ElectronD3PDObject.matched
matched
Definition: ElectronD3PDObject.py:138
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:79
item
Definition: ItemListSvc.h:43
xAOD::Electron_v1
Definition: Electron_v1.h:34
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
Conditions.h
ST::SUSYObjDef_xAOD::GetTrigPrescale
float GetTrigPrescale(const std::string &) const override final
Definition: Trigger.cxx:312
AthAnalysisHelper.h
Trig::TrigDecisionToolCore::getPrescale
float getPrescale(const Trig::ChainGroup *chaingroup, unsigned int condition=TrigDefs::Physics) const
Definition: ConfigurationAccess.cxx:88
python.PyAthena.v
v
Definition: PyAthena.py:154
ST::SUSYObjDef_xAOD::GetTrigChainGroup
const Trig::ChainGroup * GetTrigChainGroup(const std::string &) const override final
Definition: Trigger.cxx:317
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
IMatchingTool.h
xAOD::photon
@ photon
Definition: TrackingPrimitives.h:199
ITrigGlobalEfficiencyCorrectionTool::checkTriggerMatching
virtual CP::CorrectionCode checkTriggerMatching(bool &matched, const std::vector< const xAOD::IParticle * > &particles)=0
xAOD::Photon_v1
Definition: Photon_v1.h:37
mapkey::sf
@ sf
Definition: TElectronEfficiencyCorrectionTool.cxx:38
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
ITrigGlobalEfficiencyCorrectionTool::getEfficiency
virtual CP::CorrectionCode getEfficiency(const std::vector< const xAOD::IParticle * > &particles, double &efficiencyData, double &efficiencyMc)=0
ST::SUSYObjDef_xAOD::GetTriggerGlobalEfficiencySF
double GetTriggerGlobalEfficiencySF(const xAOD::ElectronContainer &electrons, const xAOD::MuonContainer &muons, const std::string &trigExpr="diLepton") override final
Definition: Trigger.cxx:400
ST::SUSYObjDef_xAOD::m_isRun3
bool m_isRun3
Definition: SUSYObjDef_xAOD.h:795
ST::SUSYObjDef_xAOD::m_trigDecTool
asg::AnaToolHandle< Trig::TrigDecisionTool > m_trigDecTool
Definition: SUSYObjDef_xAOD.h:953
python.TriggerAPI.TriggerAPISession.chainName
chainName
Definition: TriggerAPISession.py:426
CP::CorrectionCode
Return value from object correction CP tools.
Definition: CorrectionCode.h:31
ST::SUSYObjDef_xAOD::m_currentSyst
CP::SystematicSet m_currentSyst
Definition: SUSYObjDef_xAOD.h:808
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
Trig::TrigDecisionToolCore::getChainGroup
const Trig::ChainGroup * getChainGroup(const std::vector< std::string > &patterns, TrigDefs::Group props=TrigDefs::Group::Default) const
Create/get chain group (.
Definition: ChainGroupFunctions.cxx:38
Trig::ChainGroup::getListOfTriggers
std::vector< std::string > getListOfTriggers() const
Definition: ChainGroup.cxx:467
Trig::IMatchingTool::match
virtual bool match(const xAOD::IParticle &recoObject, const std::string &chain, double matchThreshold=0.1, bool rerun=false) const =0
single object trigger matching. matchThreshold is typically the deltaR requirement to obtain positive...
ST::SUSYObjDef_xAOD::treatAsYear
int treatAsYear(const int runNumber=-1) const override final
Definition: SUSYObjDef_xAOD.cxx:3071
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
CP::ISystematicsTool::applySystematicVariation
virtual StatusCode applySystematicVariation(const SystematicSet &systConfig)=0
effects: configure this tool for the given list of systematic variations.
DataVector::empty
bool empty() const noexcept
Returns true if the collection is empty.
InDetDD::electrons
@ electrons
Definition: InDetDD_Defs.h:17
ST::SUSYObjDef_xAOD::isTrigInTDT
bool isTrigInTDT(std::scoped_lock< std::mutex > &lock, const std::string &triggerName) const
Definition: Trigger.cxx:85