ATLAS Offline Software
TrigComboHypoTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "TrigComboHypoTool.h"
6 #include "GaudiKernel/SystemOfUnits.h"
9 
10 #include <Math/Vector4D.h> // for LorentzVector
11 #include <Math/Vector4Dfwd.h> // PtEtaPhiM typedef
12 #include <Math/Vector2D.h> // for DisplacementVector
13 #include <Math/Vector2Dfwd.h> // Polar2DVectorF typedef
14 
17 
18 #include <vector>
19 #include <algorithm>
20 #include <cmath>
21 
22 constexpr float invGeV = 1. / Gaudi::Units::GeV;
23 
24 using namespace TrigCompositeUtils;
25 
26 // Translate strings into enum values
27 const std::map<std::string, TrigComboHypoTool::ComboHypoVars> VarMap = {
28  {"dR", TrigComboHypoTool::ComboHypoVars::DR},
29  {"invm", TrigComboHypoTool::ComboHypoVars::INVM},
30  {"dphi", TrigComboHypoTool::ComboHypoVars::DPHI},
32  {"deta", TrigComboHypoTool::ComboHypoVars::DETA}
33 };
34 
36  const std::string& name,
37  const IInterface* parent)
39 {}
40 
41 
42 bool TrigComboHypoTool::VarInfo::validate(std::string& errmsg) const {
43  if (legA==0){
44  errmsg = "legA ID not set!";
45  return false;
46  }
47  if (legB==0){
48  errmsg="legB ID not set!";
49  return false;
50  }
51  if ((!useMin) && (!useMax)){
52  errmsg="Trying to configure the Tool without setting at least one of UseMin or UseMax!";
53  return false;
54  }
55  if (legA==legB && (legA_is_MET || legB_is_MET)) {
56  errmsg = "Cannot specify the same MET leg for both sides!";
57  return false;
58  }
59  return true;
60 }
61 
62 
64 {
65  ATH_MSG_DEBUG("Variable = " << m_varTag_vec );
66  ATH_MSG_DEBUG("UseCut min = " << m_useMin_vec );
67  ATH_MSG_DEBUG("UseCut max = " << m_useMax_vec );
68  ATH_MSG_DEBUG("varCut min = " << m_varMin_vec );
69  ATH_MSG_DEBUG("varCut max = " << m_varMax_vec );
70  ATH_MSG_DEBUG("LegA = " << m_legA_vec );
71  ATH_MSG_DEBUG("LegB = " << m_legB_vec );
72 
73  ATH_CHECK( m_monTool_vec.retrieve() );
74 
75  if (m_legA_vec.size() != m_legB_vec.size()) {
76  ATH_MSG_ERROR("Trying to configure the Tool with legA and legB vectors of different size!");
77  return StatusCode::FAILURE;
78  }
79  if (m_useMin_vec.size() != m_useMax_vec.size()) {
80  ATH_MSG_ERROR("Trying to configure the Tool with UseMin and UseMax vectors of different size!");
81  return StatusCode::FAILURE;
82  }
83  if (m_legA_vec.size() != m_useMax_vec.size()) {
84  ATH_MSG_ERROR("Trying to configure the Tool with legA/B and UseMax/Min vectors of different size!");
85  return StatusCode::FAILURE;
86  }
87  if (m_varTag_vec.size() != m_useMax_vec.size()) {
88  ATH_MSG_ERROR("Trying to configure the Tool with varTag and UseMax/Min(LegA/B) vectors of different size!");
89  return StatusCode::FAILURE;
90  }
91 
92  for (size_t i=0; i<m_varTag_vec.size(); ++i){
93  VarInfo info;
94  info.index = i;
95  if(!m_monTool_vec.empty()) {
96  info.monToolName = m_monTool_vec[i].name();
97  }
98  if (VarMap.find(m_varTag_vec[i]) == VarMap.end()){
99  ATH_MSG_ERROR("The variable is not present in the ComboHypoVars list");
100  return StatusCode::FAILURE;
101  }
102  info.varTag = (m_varTag_vec[i]);
103  info.var = VarMap.at(m_varTag_vec[i]);
104  //
105  info.useMin = m_useMin_vec[i];
106  if(info.useMin) {info.varMin=m_varMin_vec[i];}
107  info.useMax = m_useMax_vec[i];
108  if(info.useMax) {info.varMax=m_varMax_vec[i];}
109  //
110  info.legA = m_legA_vec[i];
111  info.legA_is_MET = m_isLegA_MET_vec[i];
112  info.legB = m_legB_vec[i];
113  info.legB_is_MET = m_isLegB_MET_vec[i];
114  info.legsAreEqual = info.legA==info.legB;
115 
116  std::string validmsg{""};
117  if(!info.validate(validmsg)) {
118  ATH_MSG_ERROR(validmsg);
119  return StatusCode::FAILURE;
120  }
121 
122  m_varInfo_vec.push_back(info);
123  }
124  ATH_MSG_DEBUG("Initialization completed successfully");
125 
126  return StatusCode::SUCCESS;
127 }
128 
129 
130 StatusCode TrigComboHypoTool::decide(Combo::LegDecisionsMap& passingLegs, const EventContext& /*context*/) const {
131 
132  // if no combinations passed, then exit
133  if (passingLegs.empty()) {
134  return StatusCode::SUCCESS;
135  }
136 
137  ATH_MSG_DEBUG("Looking for legs from " << decisionId() << " in the map. Map contains features for " << passingLegs.size() << " legs, which may be data for many chains.");
138  for(const auto& legpair : passingLegs) {
139  ATH_MSG_DEBUG(" Leg " << legpair.first << " has " << legpair.second.size() << " features");
140  }
141 
142  // select the leg decisions from the map with this ID:
143  std::vector<Combination> legDecisions;
144  ATH_CHECK(selectLegs(passingLegs, legDecisions));
145 
146  // Track if we have at least 2 objects on the target legs that can be used for variable computation
147  bool hasViableLegs{true};
148  // Determine the functional leg multiplicities for combinations to generate
149  std::vector<size_t> legMultiplicityForComputation(legMultiplicity().size(),0);
150  if (m_skipLegCheck) {
151  // Handle the case where there is exactly one leg and hence the chain ID is used
152  // This implies a multiplicity of 2
153  legMultiplicityForComputation[0] = 2;
154  hasViableLegs = legDecisions[0].size() >= 2;
155  } else {
156  for (const VarInfo& varInfo : m_varInfo_vec){
157  ATH_MSG_DEBUG("Var " << varInfo.varTag << " needs legs " << varInfo.legA << ", " << varInfo.legB);
158 
159  // Assess the leg decisions and extract the relevant ones
160  if (passingLegs.contains(varInfo.legA) && passingLegs.contains(varInfo.legB)) {
161  size_t goodLegA{false}, goodLegB{false};
162  int32_t iLegA = getIndexFromLeg(varInfo.legA);
163  int32_t iLegB = getIndexFromLeg(varInfo.legB);
164  if ((iLegA<0) or (iLegB<0)){
165  ATH_MSG_ERROR("TrigComboHypoTool::decide: Index into array is negative");
166  return StatusCode::FAILURE;
167  }
168  goodLegA = !passingLegs[varInfo.legA].empty();
169  legMultiplicityForComputation[iLegA] = std::max<size_t>(1,legMultiplicityForComputation[iLegA]);
170  ATH_MSG_DEBUG("Leg " << varInfo.legA << " has " << passingLegs[varInfo.legA].size() << " features --> " << (goodLegA ? "pass" : "fail"));
171  if(varInfo.legB != varInfo.legA) {
172  goodLegB = !passingLegs[varInfo.legB].empty();
173  ATH_MSG_DEBUG("Leg " << varInfo.legB << " has " << passingLegs[varInfo.legB].size() << " features --> " << (goodLegB ? "pass" : "fail"));
174  legMultiplicityForComputation[iLegB] = std::max<size_t>(1,legMultiplicityForComputation[iLegB]);
175  } else {
176  goodLegB = goodLegA = passingLegs[varInfo.legA].size() >= 2;
177  ATH_MSG_DEBUG("Leg " << varInfo.legA << " has " << passingLegs[varInfo.legA].size() << " features --> " << (goodLegB ? "pass" : "fail"));
178  // If we do a computation on the same leg, we need to generate a pair of objects here
179  legMultiplicityForComputation[iLegA] = std::max<size_t>(2,legMultiplicityForComputation[iLegA]);
180  }
181  hasViableLegs &= (goodLegA && goodLegB);
182  if (!hasViableLegs) {
183  ATH_MSG_DEBUG("Did not find at least 2 features on the target legs to compute " << varInfo.varTag);
184  }
185  } else {
187  "Insufficient passing legs to compute " << varInfo.varTag
188  << ", intended on (" << varInfo.legA << ", " << varInfo.legB << ")"
189  );
190  hasViableLegs = false;
191  }
192  }
193  }
194 
195  if (!hasViableLegs) {
196  ATH_MSG_DEBUG("This ComboHypoTool cannot run in this event, this chain **REJECTS** this event.");
197  eraseFromLegDecisionsMap(passingLegs);
198  if (msgLvl(MSG::DEBUG)) printDebugInformation(passingLegs);
199  return StatusCode::SUCCESS;
200  }
201 
202  // Create and initialise the combinations generator for the requirements of this chain, given the objects available in this event.
203  // Extract the features on legs not used for the decision, so they stay in the navigation
204  Combination extraLegs;
206  for (size_t legindex = 0; size_t legmult : legMultiplicityForComputation){
207  size_t out_of = legDecisions[legindex].size();
208  if(legmult==0) {
209  extraLegs.insert(extraLegs.end(),legDecisions[legindex].cbegin(),legDecisions[legindex].cend());
210  } else {
211  nucg.add({out_of, legmult});
212  ATH_MSG_DEBUG("For leg index " << legindex << " we will be choosing any " << legmult << " Decision Objects out of " << out_of);
213  }
214  ++legindex;
215  }
216 
217  // Iterate over all variable computations
218  std::vector<Combination> passingCombinations;
219  std::vector<float> values;
220  values.reserve(m_varInfo_vec.size());
221  size_t warnings = 0, iterations = 0;
222  // Correct for the legs on which we compute with 2 features
223  auto get_index_offset = [&legMultiplicityForComputation](size_t legindex) {
224  size_t offset{0};
225  for (auto iLeg=legMultiplicityForComputation.cbegin(); iLeg!=legMultiplicityForComputation.cbegin()+legindex; ++iLeg) {
226  offset += (*iLeg)-1;
227  }
228  return offset;
229  };
230  do {
231  bool lastDecision(true);
232  const std::vector<size_t> combination = nucg();
233  ++nucg;
234  ++iterations;
235  values.clear();
236 
237  // This collects all the features contributing to any variable computation
238  Combination combinationToRecord;
239  for (auto iVarInfo = m_varInfo_vec.cbegin(); iVarInfo!=m_varInfo_vec.cend() && lastDecision; ++iVarInfo){
240  // Just the features for the current variable evaluation
241  Combination combinationToCheck;
242 
243  size_t legA_index = 0;
244  size_t legB_index = 0;
245 
246  // For 1-leg chain, the legID is invalid
247  if (!m_skipLegCheck) {
248  legA_index = getIndexFromLeg(iVarInfo->legA);
249  legB_index = getIndexFromLeg(iVarInfo->legB);
250  }
251 
253  "Computing " << iVarInfo->varTag << " on legs "
254  << iVarInfo->legA << " (" << legA_index << "), "
255  << iVarInfo->legB << " (" << legB_index << ")"
256  );
257  if(iVarInfo->legA==iVarInfo->legB) {
258  // 2 objects on 1 leg
259  // Due to multiplicity checks, a computation like 'dRAA' never overlaps with one like 'dRAB'
260  Combination featurePair = {legDecisions[legA_index][combination.at(legA_index+get_index_offset(legA_index))],legDecisions[legA_index][combination.at(legA_index+get_index_offset(legA_index)+1)]};
261  combinationToCheck.insert(combinationToCheck.end(),featurePair.cbegin(),featurePair.cend());
262  combinationToRecord.insert(combinationToRecord.end(),featurePair.cbegin(),featurePair.cend());
263  } else {
264  // 1 object each on 2 legs
265  Combination featurePair = {legDecisions[legA_index][combination.at(legA_index+get_index_offset(legA_index))],legDecisions[legB_index][combination.at(legB_index+get_index_offset(legB_index))]};
266  combinationToCheck.insert(combinationToCheck.end(),featurePair.cbegin(),featurePair.cend());
267  combinationToRecord.insert(combinationToRecord.end(),featurePair.cbegin(),featurePair.cend());
268  }
269 
270  try {
271  lastDecision = executeAlgStep(combinationToCheck, *iVarInfo, values);
272  ATH_MSG_DEBUG("Combination " << (iterations - 1) << " decided to be " << (lastDecision ? "passing" : "failing") << " " << iVarInfo->varTag);
273  } catch (std::exception& e) {
274  ATH_MSG_ERROR(e.what());
275  return StatusCode::FAILURE;
276  }
277 
278  if ((iterations >= m_combinationsThresholdWarn && warnings == 0) or (iterations >= m_combinationsThresholdBreak)) {
279  ATH_MSG_WARNING("Have so far processed " << iterations << " combinations for " << decisionId() << " in this event, " << passingCombinations.size() << " passing.");
280  ++warnings;
281  if (iterations >= m_combinationsThresholdBreak) {
282  ATH_MSG_WARNING("Too many combinations! Breaking the loop at this point.");
283  break;
284  }
285  }
286  }
287 
288  // Assess the collective decision on the combination
289  if (lastDecision) {
290  combinationToRecord.insert(combinationToRecord.end(),extraLegs.cbegin(),extraLegs.cend());
291  passingCombinations.push_back(combinationToRecord);
292  if (m_modeOR == true and m_enableOverride) {
293  break;
294  }
295  } else { // the combination failed
296  if (m_modeOR == false and m_enableOverride) {
297  break;
298  }
299  }
300 
301  // Monitoring of variables for only accepted events
302  if(lastDecision && !m_monTool_vec.empty()) {
303  for (const VarInfo& varInfo : m_varInfo_vec) {
304  float value = values[varInfo.index];
305  auto varOfAccepted = Monitored::Scalar(m_varTag_vec[varInfo.index]+"OfAccepted", value );//varInfo->monToolName+"OfAccepted", value );
306  auto monitorIt = Monitored::Group (m_monTool_vec[varInfo.index], varOfAccepted);
307  ATH_MSG_VERBOSE( varInfo.varTag << " = " << value << " is in range " << varInfo.rangeStr() << ".");
308  ATH_MSG_VERBOSE("m_varTag_vec = "<< m_varTag_vec<<", values = "<<values << ", valIndex = "<< varInfo.index <<", monToolName = " << varInfo.monToolName << ", monToolVec = "<< m_monTool_vec);
309  }
310  }
311  } while (nucg);
312 
313  if (m_modeOR) {
314 
315  ATH_MSG_DEBUG("Passing " << passingCombinations.size() << " combinations out of " << iterations << ", "
316  << decisionId() << (passingCombinations.size() ? " **ACCEPTS**" : " **REJECTS**") << " this event based on OR logic.");
317 
318  if (m_enableOverride) {
319  ATH_MSG_DEBUG("Note: stopped after the first successful combination due to the EnableOverride flag.");
320  }
321 
322  } else { // modeAND
323 
324  const bool passAll = (passingCombinations.size() == iterations);
325 
326  ATH_MSG_DEBUG("Passing " << passingCombinations.size() << " combinations out of " << iterations << ", "
327  << decisionId() << (passAll ? " **ACCEPTS**" : " **REJECTS**") << " this event based on AND logic.");
328 
329  if (m_enableOverride) {
330  ATH_MSG_DEBUG("Note: stopped after the first failed combination due to the EnableOverride flag.");
331  }
332 
333  if (not passAll) {
334  passingCombinations.clear();
335  }
336 
337  }
338 
339  if (not passingCombinations.empty()) { // need partial erasure of the decsions (only those not present in any combination)
340  updateLegDecisionsMap(passingCombinations, passingLegs);
341  } else { // need complete erasure of input decisions
342  eraseFromLegDecisionsMap(passingLegs);
343  }
344 
345  if (msgLvl(MSG::DEBUG)) printDebugInformation(passingLegs);
346  return StatusCode::SUCCESS;
347 }
348 
349 
350 bool TrigComboHypoTool::executeAlgStep(const Combination& combination, const VarInfo& varInfo, std::vector<float> &vals) const {
351  ATH_MSG_DEBUG("Executing selection " << varInfo.index << " of " << m_varInfo_vec.size() << ": " << varInfo.rangeStr());
352 
353  std::pair<KineInfo,KineInfo> kinepair;
354  if(!fillPairKinematics(kinepair, combination, varInfo)) {
355  ATH_MSG_ERROR("Failed to extract kinematics of feature pair!");
356  return false;
357  }
358 
359  if(msgLvl(MSG::VERBOSE)) {
360  float eta_check, phi_check, pt_check;
361  std::tie(eta_check,phi_check,pt_check) = kinepair.first;
362  msg() << MSG::VERBOSE << " Test filled legA kinematics: pt " << pt_check*invGeV << ", eta " << eta_check << ", phi " << phi_check << endmsg;
363 
364  std::tie(eta_check,phi_check,pt_check) = kinepair.second;
365  msg() << MSG::VERBOSE << " Test filled legB kinematics: pt " << pt_check*invGeV << ", eta " << eta_check << ", phi " << phi_check << endmsg;
366  }
367 
368  // apply the cut
369  float value = compute(kinepair,varInfo.var);
370  if(!m_monTool_vec.empty()) {
371  auto varOfProcessed = Monitored::Scalar(m_varTag_vec[varInfo.index]+"OfProcessed" , value );
372  auto monitorIt = Monitored::Group (m_monTool_vec[varInfo.index], varOfProcessed);
373  }
374  vals.push_back(value);
375  bool pass = varInfo.test(value);
376 
377  ATH_MSG_DEBUG(" Found a combination with " << value);
378  if(!pass) {
379  ATH_MSG_DEBUG(" Combination failed var cut: " << varInfo.varTag << " = " << value << " not in range " << varInfo.rangeStr());
380  }
381  return pass;
382 }
383 
384 
386 bool testLegId(const Combo::LegDecision& d, uint32_t targetleg) {
387  auto combId = HLT::Identifier(d.first);
388  if(!TrigCompositeUtils::isLegId(combId)) return false;
389  return combId.numeric() == targetleg;
390 }
391 
392 
393 bool TrigComboHypoTool::fillLegDecisions_sameLeg(std::pair<Combo::LegDecision,Combo::LegDecision>& legpair, const Combination& combination, uint32_t leg) const {
394  Combination leg_features;
395  if(m_skipLegCheck) {
396  // If there is only one leg, the decision IDs don't have a leg ID
397  std::copy(combination.begin(),combination.end(),std::back_inserter(leg_features));
398  } else {
399  // Extract the features matching the legs
400  // We take all of them, so as to be able to check if there is any ambiguity
401  auto isMyLeg = [&leg](const Combo::LegDecision& d) { return testLegId(d,leg); };
402  std::copy_if(combination.begin(),combination.end(),std::back_inserter(leg_features),isMyLeg);
403  }
404 
405  if (leg_features.size()==2) {
406  legpair.first = leg_features[0];
407  legpair.second = leg_features[1];
408  } else {
409  ATH_MSG_ERROR(leg_features.size() << " Decision Objects supplied on leg " << leg
410  << ", must be 2 for same-leg topo selection!");
411  return false;
412  }
413 
414  return true;
415 }
416 
417 
418 bool TrigComboHypoTool::fillLegDecisions_diffLeg(std::pair<Combo::LegDecision,Combo::LegDecision>& legpair, const Combination& combination, uint32_t legA, uint32_t legB) const {
419  // Extract the features matching the legs
420  // We take all of them, so as to be able to check if there is any ambiguity
421  auto isLegA = [&legA](const Combo::LegDecision& d) { return testLegId(d,legA); };
422  auto isLegB = [&legB](const Combo::LegDecision& d) { return testLegId(d,legB); };
423  Combination legA_features, legB_features;
424 
425  std::copy_if(combination.begin(),combination.end(),std::back_inserter(legA_features),isLegA);
426  if(legA_features.size()!=1) {
427  ATH_MSG_ERROR(legA_features.size() << " Decision Objects supplied on leg " << legA
428  << ", must be 1 for different-leg topo selection!");
429  return false;
430  }
431 
432  std::copy_if(combination.begin(),combination.end(),std::back_inserter(legB_features),isLegB);
433  if (legB_features.size()!=1) {
434  ATH_MSG_ERROR(legB_features.size() << " Decision Objects supplied on leg " << legB
435  << ", must be 1 for different-leg topo selection!");
436  return false;
437  }
438 
439  legpair.first = legA_features[0];
440  legpair.second = legB_features[0];
441 
442  return true;
443 }
444 
445 
446 bool TrigComboHypoTool::fillPairKinematics(std::pair<KineInfo,KineInfo>& kinepair, const Combination& combination, const VarInfo& varInfo) const {
447  ATH_MSG_VERBOSE(" Decision objects available = "<< combination);
448  // Check that there are enough features
449  size_t nFeatures(combination.size());
450  if (nFeatures < 2){
451  ATH_MSG_ERROR("Number of Decision Objects passed is less than 2! Sum over decision objects on all legs = " << combination.size() );
452  return false;
453  }
454  std::pair<Combo::LegDecision,Combo::LegDecision> legpair;
455  if (varInfo.legsAreEqual) {fillLegDecisions_sameLeg(legpair,combination,varInfo.legA);}
456  else {fillLegDecisions_diffLeg(legpair,combination,varInfo.legA,varInfo.legB);}
457  ATH_MSG_VERBOSE(" Fill leg A kinematics");
458  if(!fillKineInfo(kinepair.first,legpair.first,varInfo.legA_is_MET)) {
459  ATH_MSG_ERROR("Failed to extract requisite kinematic info from leg " << varInfo.legA << "!");
460  return false;
461  }
462  ATH_MSG_VERBOSE(" Fill leg B kinematics");
463  if(!fillKineInfo(kinepair.second,legpair.second,varInfo.legB_is_MET)) {
464  ATH_MSG_ERROR("Failed to extract requisite kinematic info from leg " << varInfo.legB << "!");
465  return false;
466  }
467  return true;
468  }
469 
470 
472  float eta, phi, pt;
473  if (isMET) {
474  auto pLink = TrigCompositeUtils::findLink<xAOD::TrigMissingETContainer>( *decision.second, featureString() ).link;
475  if (!pLink.isValid()){
476  ATH_MSG_ERROR("link for MET not valid");
477  return false;
478  }
479  ROOT::Math::XYVectorF metv((*pLink)->ex(),(*pLink)->ey());
480  eta = FLOATDEFAULT;
481  phi = metv.phi();
482  pt = metv.r();
483  } else {
484  auto pLink = TrigCompositeUtils::findLink<xAOD::IParticleContainer>( *decision.second, featureString() ).link;
485  if (!pLink.isValid()){
486  ATH_MSG_ERROR("link for IParticle not valid");
487  return false;
488  }
489  eta = (*pLink)->p4().Eta();
490  phi = (*pLink)->p4().Phi();
491  pt = (*pLink)->p4().Pt();
492  }
493  ATH_MSG_VERBOSE(" Filled kinematics with pt " << pt*invGeV << ", eta " << eta << ", phi " << phi);
494  kinematics = std::make_tuple(eta,phi,pt);
495  return true;
496 }
497 
498 
499 float TrigComboHypoTool::compute(const std::pair<KineInfo,KineInfo>& kinepair, ComboHypoVars var) const {
500  const auto& [legA_kine,legB_kine] = kinepair;
501  const auto& [eta1,phi1,pt1] = legA_kine;
502  const auto& [eta2,phi2,pt2] = legB_kine;
503 
504  ATH_MSG_DEBUG(" Leg A has pt " << pt1*invGeV << ", eta " << eta1 << ", phi " << phi1);
505  ATH_MSG_DEBUG(" Leg B has pt " << pt2*invGeV << ", eta " << eta2 << ", phi " << phi2);
506 
507  float value(0);
508  switch(var) {
509  case ComboHypoVars::DR:
510  {
511  value = xAOD::P4Helpers::deltaR(eta1,phi1,eta2,phi2);
512  break;
513  }
514  case ComboHypoVars::DPHI:
515  {
516  value = std::fabs(xAOD::P4Helpers::deltaPhi(phi1,phi2));
517  break;
518  }
519  case ComboHypoVars::INVM:
520  {
521  ROOT::Math::PtEtaPhiMVector p1(pt1,eta1,phi1,0.), p2(pt2,eta2,phi2,0.);
522  value = (p1+p2).M()*invGeV; // Convert to GeV
523  break;
524  }
525  case ComboHypoVars::MT:
526  {
527  //Transverse mass defined for semi-visible decays in hadron colliders. See PDG 49.6, section on kinematics
528  value = std::sqrt(2*pt1*pt2*(1-std::cos(xAOD::P4Helpers::deltaPhi(phi1,phi2) ) ) )*invGeV; // Convert to GeV
529  break;
530  }
531  case ComboHypoVars::DETA:
532  {
533  value = std::fabs(eta2-eta1);
534  break;
535  }
536  default:
537  {
538  ATH_MSG_ERROR("Undefined variable requested -- should never happen!");
539  }
540  }
541  return value;
542 }
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
TrigComboHypoTool::m_legB_vec
Gaudi::Property< std::vector< uint32_t > > m_legB_vec
Definition: TrigComboHypoTool.h:108
TrigComboHypoTool::VarInfo
Organise info per var selection in a struct.
Definition: TrigComboHypoTool.h:50
beamspotnt.var
var
Definition: bin/beamspotnt.py:1393
TrigComboHypoTool::m_monTool_vec
ToolHandleArray< GenericMonitoringTool > m_monTool_vec
Definition: TrigComboHypoTool.h:118
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:18
TrigDefs::Group
Group
Properties of a chain group.
Definition: GroupProperties.h:13
TrigComboHypoTool::m_varMax_vec
Gaudi::Property< std::vector< float > > m_varMax_vec
Definition: TrigComboHypoTool.h:115
ComboHypoToolBase::printDebugInformation
void printDebugInformation(const Combo::LegDecisionsMap &passingLegs) const
Print the output of the tool, after having removed failed Decision Objects.
Definition: ComboHypoToolBase.cxx:264
TrigComboHypoTool::VarInfo::test
bool test(float value) const
Definition: TrigComboHypoTool.h:73
ParticleGun_SamplingFraction.eta2
eta2
Definition: ParticleGun_SamplingFraction.py:96
ComboHypoToolBase::eraseFromLegDecisionsMap
void eraseFromLegDecisionsMap(Combo::LegDecisionsMap &passingLegs) const
For when the tool rejects all combinations.
Definition: ComboHypoToolBase.cxx:253
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
TrigComboHypoTool::initialize
virtual StatusCode initialize() override
Definition: TrigComboHypoTool.cxx:63
TrigComboHypoTool::fillPairKinematics
bool fillPairKinematics(std::pair< KineInfo, KineInfo > &kinepair, const Combination &combination, const VarInfo &varInfo) const
Definition: TrigComboHypoTool.cxx:446
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
xAODP4Helpers.h
hist_file_dump.d
d
Definition: hist_file_dump.py:142
ComboHypoToolBase::updateLegDecisionsMap
void updateLegDecisionsMap(const std::vector< std::vector< Combo::LegDecision >> &passing_comb, Combo::LegDecisionsMap &passingLegs) const
For when the tool accepts some/all combinations.
Definition: ComboHypoToolBase.cxx:216
invGeV
constexpr float invGeV
Definition: TrigComboHypoTool.cxx:22
TrigComboHypoTool::VarInfo::index
size_t index
Definition: TrigComboHypoTool.h:53
TrigComboHypoTool::decide
StatusCode decide(Combo::LegDecisionsMap &passingLegs, const EventContext &) const final
Override the ComboHypoToolBase::decide in order to optimise combination generation This is to avoid e...
Definition: TrigComboHypoTool.cxx:130
TRTCalib_cfilter.p1
p1
Definition: TRTCalib_cfilter.py:130
HLT::NestedUniqueCombinationGenerator
An ensemble of UniqueCombinationGenerator API description.
Definition: TrigCompositeUtils/TrigCompositeUtils/Combinators.h:72
TrigComboHypoTool::m_isLegB_MET_vec
Gaudi::Property< std::vector< bool > > m_isLegB_MET_vec
Definition: TrigComboHypoTool.h:110
test_pyathena.pt
pt
Definition: test_pyathena.py:11
xAOD::P4Helpers::deltaPhi
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition: xAODP4Helpers.h:69
athena.value
value
Definition: athena.py:124
xAOD::eta1
setEt setPhi setE277 setWeta2 eta1
Definition: TrigEMCluster_v1.cxx:41
TrigComboHypoTool::m_varTag_vec
Gaudi::Property< std::vector< std::string > > m_varTag_vec
Gaudi configuration hooks.
Definition: TrigComboHypoTool.h:102
ComboHypoToolBase::m_combinationsThresholdBreak
Gaudi::Property< size_t > m_combinationsThresholdBreak
Definition: ComboHypoToolBase.h:109
ComboHypoToolBase
Base class for tools which cut on properties of multi-object or multi-leg chains. User should derive ...
Definition: ComboHypoToolBase.h:26
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Combo::LegDecisionsMap
std::map< TrigCompositeUtils::DecisionID, std::vector< ElementLink< TrigCompositeUtils::DecisionContainer > > > LegDecisionsMap
LegDecisionsMap For a given chain leg key, this map holds all Decision Objects which are active on th...
Definition: IComboHypoTool.h:28
TrigComboHypoTool::VarInfo::legB
uint32_t legB
Definition: TrigComboHypoTool.h:64
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
ComboHypoToolBase::m_modeOR
Gaudi::Property< bool > m_modeOR
Definition: ComboHypoToolBase.h:112
TrigComboHypoTool::ComboHypoVars
ComboHypoVars
Definition: TrigComboHypoTool.h:36
python.Bindings.values
values
Definition: Control/AthenaPython/python/Bindings.py:808
ComboHypoToolBase::decisionId
virtual HLT::Identifier decisionId() const
retrieves this ComboHypoTool's chain's decision ID
Definition: ComboHypoToolBase.h:41
TrigComboHypoTool::VarInfo::legB_is_MET
bool legB_is_MET
Definition: TrigComboHypoTool.h:63
LVL1::MT
LVL1::L1CaloFcal23Cells2RxMappingTool::mapType MT
Definition: L1CaloFcal23Cells2RxMappingTool.cxx:14
TrigComboHypoTool::Combination
std::vector< Combo::LegDecision > Combination
Definition: TrigComboHypoTool.h:81
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
TrigCompositeUtils.h
TRTCalib_cfilter.p2
p2
Definition: TRTCalib_cfilter.py:131
ComboHypoToolBase::m_enableOverride
Gaudi::Property< bool > m_enableOverride
Definition: ComboHypoToolBase.h:115
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TrigComboHypoTool::fillKineInfo
bool fillKineInfo(KineInfo &kinematics, Combo::LegDecision decision, bool isMET) const
Definition: TrigComboHypoTool.cxx:471
TrigComboHypoTool::VarInfo::legA
uint32_t legA
Definition: TrigComboHypoTool.h:62
TrigComboHypoTool::fillLegDecisions_sameLeg
bool fillLegDecisions_sameLeg(std::pair< Combo::LegDecision, Combo::LegDecision > &legpair, const Combination &combination, uint32_t leg) const
Helpers to extract kinematics from the specified legs of the chain Specialised for two cases – exactl...
Definition: TrigComboHypoTool.cxx:393
TrigComboHypoTool.h
lumiFormat.i
int i
Definition: lumiFormat.py:85
ComboHypoToolBase::legMultiplicity
const std::vector< int > & legMultiplicity() const
Gets the number of legs and the multiplicity required on each leg.
Definition: ComboHypoToolBase.h:54
xAOD::P4Helpers::deltaR
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
Definition: xAODP4Helpers.h:150
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ComboHypoToolBase::m_combinationsThresholdWarn
Gaudi::Property< size_t > m_combinationsThresholdWarn
Definition: ComboHypoToolBase.h:106
calibdata.exception
exception
Definition: calibdata.py:495
TrigComboHypoTool::m_isLegA_MET_vec
Gaudi::Property< std::vector< bool > > m_isLegA_MET_vec
Definition: TrigComboHypoTool.h:109
test_pyathena.parent
parent
Definition: test_pyathena.py:15
TrigComboHypoTool::FLOATDEFAULT
static constexpr float FLOATDEFAULT
Definition: TrigComboHypoTool.h:47
HLT::NestedUniqueCombinationGenerator::add
void add(const UniqueCombinationGenerator &gen)
Definition: Combinators.cxx:83
AnalysisUtils::copy_if
Out copy_if(In first, const In &last, Out res, const Pred &p)
Definition: IFilterUtils.h:30
compute_lumi.leg
leg
Definition: compute_lumi.py:95
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
TrigMissingETContainer.h
TrigComboHypoTool::executeAlgStep
bool executeAlgStep(const Combination &combination, const VarInfo &, std::vector< float > &values) const
Implementation of selection on individual variables.
Definition: TrigComboHypoTool.cxx:350
TrigComboHypoTool::TrigComboHypoTool
TrigComboHypoTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: TrigComboHypoTool.cxx:35
TrigComboHypoTool::KineInfo
std::tuple< float, float, float > KineInfo
Typedef for convenience, will contain eta/phi/pt info.
Definition: TrigComboHypoTool.h:80
HLT::Identifier
Definition: TrigCompositeUtils/TrigCompositeUtils/HLTIdentifier.h:19
TrigComboHypoTool::m_varInfo_vec
std::vector< VarInfo > m_varInfo_vec
Internal variables for more efficient config lookup.
Definition: TrigComboHypoTool.h:121
TrigCompositeUtils::featureString
const std::string & featureString()
Definition: TrigCompositeUtilsRoot.cxx:898
ComboHypoToolBase::selectLegs
StatusCode selectLegs(const Combo::LegDecisionsMap &IDCombMap, std::vector< std::vector< Combo::LegDecision >> &leg_decisions) const
Creates the per-leg vectors of Decision objects starting from the initial LegDecision map,...
Definition: ComboHypoToolBase.cxx:172
TrigComboHypoTool::compute
float compute(const std::pair< KineInfo, KineInfo > &kinepair, ComboHypoVars var) const
Computation of the variables from the specified kinematics.
Definition: TrigComboHypoTool.cxx:499
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
TrigComboHypoTool::VarInfo::rangeStr
std::string rangeStr() const
Generate range string for printing.
Definition: TrigComboHypoTool.h:70
TrigComboHypoTool::m_useMax_vec
Gaudi::Property< std::vector< bool > > m_useMax_vec
Definition: TrigComboHypoTool.h:104
TrigCompositeUtils::isLegId
bool isLegId(const HLT::Identifier &legIdentifier)
Recognise whether the chain ID is a leg ID.
Definition: TrigCompositeUtilsRoot.cxx:218
TrigCompositeUtils::getIndexFromLeg
int32_t getIndexFromLeg(const HLT::Identifier &legIdentifier)
Extract the numeric index of a leg identifier.
Definition: TrigCompositeUtilsRoot.cxx:190
Combinators.h
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TrigComboHypoTool::m_varMin_vec
Gaudi::Property< std::vector< float > > m_varMin_vec
Definition: TrigComboHypoTool.h:114
TrigComboHypoTool::fillLegDecisions_diffLeg
bool fillLegDecisions_diffLeg(std::pair< Combo::LegDecision, Combo::LegDecision > &legpair, const Combination &combination, uint32_t legA, uint32_t legB) const
Definition: TrigComboHypoTool.cxx:418
TrigComboHypoTool::VarInfo::varTag
std::string varTag
Definition: TrigComboHypoTool.h:51
DEBUG
#define DEBUG
Definition: page_access.h:11
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
TrigComboHypoTool::VarInfo::legA_is_MET
bool legA_is_MET
Definition: TrigComboHypoTool.h:61
TrigComboHypoTool::VarInfo::legsAreEqual
bool legsAreEqual
Definition: TrigComboHypoTool.h:65
TrigComboHypoTool::VarInfo::useMax
bool useMax
Definition: TrigComboHypoTool.h:58
TrigCompositeUtils
Definition: Event/xAOD/xAODTrigger/xAODTrigger/TrigComposite.h:19
TrigComboHypoTool::m_skipLegCheck
Gaudi::Property< bool > m_skipLegCheck
Definition: TrigComboHypoTool.h:111
TrigComboHypoTool::VarInfo::useMin
bool useMin
Definition: TrigComboHypoTool.h:56
calibdata.copy
bool copy
Definition: calibdata.py:26
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
VarMap
const std::map< std::string, TrigComboHypoTool::ComboHypoVars > VarMap
Definition: TrigComboHypoTool.cxx:27
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
testLegId
bool testLegId(const Combo::LegDecision &d, uint32_t targetleg)
Test function to compare decision ID with the legs to be used in var computation.
Definition: TrigComboHypoTool.cxx:386
TrigComboHypoTool::m_useMin_vec
Gaudi::Property< std::vector< bool > > m_useMin_vec
Definition: TrigComboHypoTool.h:103
python.ParticleTypeUtil.info
def info
Definition: ParticleTypeUtil.py:87
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
TrigComboHypoTool::VarInfo::var
ComboHypoVars var
Definition: TrigComboHypoTool.h:52
Combo::LegDecision
std::pair< TrigCompositeUtils::DecisionID, ElementLink< TrigCompositeUtils::DecisionContainer > > LegDecision
LegDecision keeps a given Decision Object associated with a specific leg when being used inside a sin...
Definition: IComboHypoTool.h:33
TrigComboHypoTool::VarInfo::validate
bool validate(std::string &errmsg) const
Check consistency of single var config.
Definition: TrigComboHypoTool.cxx:42
PlotCalibFromCool.vals
vals
Definition: PlotCalibFromCool.py:474
TrigComboHypoTool::m_legA_vec
Gaudi::Property< std::vector< uint32_t > > m_legA_vec
Definition: TrigComboHypoTool.h:107