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