Loading [MathJax]/jax/input/TeX/config.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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  ATH_CHECK(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 = getIndexFromLeg(iVarInfo->legA);
244  size_t legB_index = getIndexFromLeg(iVarInfo->legB);
245  // For 1-leg chain, the legID is invalid
246  if(m_skipLegCheck) {legA_index = legB_index = 0;}
247 
249  "Computing " << iVarInfo->varTag << " on legs "
250  << iVarInfo->legA << " (" << legA_index << "), "
251  << iVarInfo->legB << " (" << legB_index << ")"
252  );
253  if(iVarInfo->legA==iVarInfo->legB) {
254  // 2 objects on 1 leg
255  // Due to multiplicity checks, a computation like 'dRAA' never overlaps with one like 'dRAB'
256  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)]};
257  combinationToCheck.insert(combinationToCheck.end(),featurePair.cbegin(),featurePair.cend());
258  combinationToRecord.insert(combinationToRecord.end(),featurePair.cbegin(),featurePair.cend());
259  } else {
260  // 1 object each on 2 legs
261  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))]};
262  combinationToCheck.insert(combinationToCheck.end(),featurePair.cbegin(),featurePair.cend());
263  combinationToRecord.insert(combinationToRecord.end(),featurePair.cbegin(),featurePair.cend());
264  }
265 
266  try {
267  lastDecision = executeAlgStep(combinationToCheck, *iVarInfo, values);
268  ATH_MSG_DEBUG("Combination " << (iterations - 1) << " decided to be " << (lastDecision ? "passing" : "failing") << " " << iVarInfo->varTag);
269  } catch (std::exception& e) {
270  ATH_MSG_ERROR(e.what());
271  return StatusCode::FAILURE;
272  }
273 
274  if ((iterations >= m_combinationsThresholdWarn && warnings == 0) or (iterations >= m_combinationsThresholdBreak)) {
275  ATH_MSG_WARNING("Have so far processed " << iterations << " combinations for " << decisionId() << " in this event, " << passingCombinations.size() << " passing.");
276  ++warnings;
277  if (iterations >= m_combinationsThresholdBreak) {
278  ATH_MSG_WARNING("Too many combinations! Breaking the loop at this point.");
279  break;
280  }
281  }
282  }
283 
284  // Assess the collective decision on the combination
285  if (lastDecision) {
286  combinationToRecord.insert(combinationToRecord.end(),extraLegs.cbegin(),extraLegs.cend());
287  passingCombinations.push_back(combinationToRecord);
288  if (m_modeOR == true and m_enableOverride) {
289  break;
290  }
291  } else { // the combination failed
292  if (m_modeOR == false and m_enableOverride) {
293  break;
294  }
295  }
296 
297  // Monitoring of variables for only accepted events
298  if(lastDecision && !m_monTool_vec.empty()) {
299  for (const VarInfo& varInfo : m_varInfo_vec) {
300  float value = values[varInfo.index];
301  auto varOfAccepted = Monitored::Scalar(m_varTag_vec[varInfo.index]+"OfAccepted", value );//varInfo->monToolName+"OfAccepted", value );
302  auto monitorIt = Monitored::Group (m_monTool_vec[varInfo.index], varOfAccepted);
303  ATH_MSG_VERBOSE( varInfo.varTag << " = " << value << " is in range " << varInfo.rangeStr() << ".");
304  ATH_MSG_VERBOSE("m_varTag_vec = "<< m_varTag_vec<<", values = "<<values << ", valIndex = "<< varInfo.index <<", monToolName = " << varInfo.monToolName << ", monToolVec = "<< m_monTool_vec);
305  }
306  }
307  } while (nucg);
308 
309  if (m_modeOR) {
310 
311  ATH_MSG_DEBUG("Passing " << passingCombinations.size() << " combinations out of " << iterations << ", "
312  << decisionId() << (passingCombinations.size() ? " **ACCEPTS**" : " **REJECTS**") << " this event based on OR logic.");
313 
314  if (m_enableOverride) {
315  ATH_MSG_DEBUG("Note: stopped after the first successful combination due to the EnableOverride flag.");
316  }
317 
318  } else { // modeAND
319 
320  const bool passAll = (passingCombinations.size() == iterations);
321 
322  ATH_MSG_DEBUG("Passing " << passingCombinations.size() << " combinations out of " << iterations << ", "
323  << decisionId() << (passAll ? " **ACCEPTS**" : " **REJECTS**") << " this event based on AND logic.");
324 
325  if (m_enableOverride) {
326  ATH_MSG_DEBUG("Note: stopped after the first failed combination due to the EnableOverride flag.");
327  }
328 
329  if (not passAll) {
330  passingCombinations.clear();
331  }
332 
333  }
334 
335  if (not passingCombinations.empty()) { // need partial erasure of the decsions (only those not present in any combination)
336  updateLegDecisionsMap(passingCombinations, passingLegs);
337  } else { // need complete erasure of input decisions
338  eraseFromLegDecisionsMap(passingLegs);
339  }
340 
341  ATH_CHECK(printDebugInformation(passingLegs));
342  return StatusCode::SUCCESS;
343 }
344 
345 
346 bool TrigComboHypoTool::executeAlgStep(const Combination& combination, const VarInfo& varInfo, std::vector<float> &vals) const {
347  ATH_MSG_DEBUG("Executing selection " << varInfo.index << " of " << m_varInfo_vec.size() << ": " << varInfo.rangeStr());
348 
349  std::pair<KineInfo,KineInfo> kinepair;
350  if(!fillPairKinematics(kinepair, combination, varInfo)) {
351  ATH_MSG_ERROR("Failed to extract kinematics of feature pair!");
352  return false;
353  }
354 
355  if(msgLvl(MSG::VERBOSE)) {
356  float eta_check, phi_check, pt_check;
357  std::tie(eta_check,phi_check,pt_check) = kinepair.first;
358  msg() << MSG::VERBOSE << " Test filled legA kinematics: pt " << pt_check*invGeV << ", eta " << eta_check << ", phi " << phi_check << endmsg;
359 
360  std::tie(eta_check,phi_check,pt_check) = kinepair.second;
361  msg() << MSG::VERBOSE << " Test filled legB kinematics: pt " << pt_check*invGeV << ", eta " << eta_check << ", phi " << phi_check << endmsg;
362  }
363 
364  // apply the cut
365  float value = compute(kinepair,varInfo.var);
366  if(!m_monTool_vec.empty()) {
367  auto varOfProcessed = Monitored::Scalar(m_varTag_vec[varInfo.index]+"OfProcessed" , value );
368  auto monitorIt = Monitored::Group (m_monTool_vec[varInfo.index], varOfProcessed);
369  }
370  vals.push_back(value);
371  bool pass = varInfo.test(value);
372 
373  ATH_MSG_DEBUG(" Found a combination with " << value);
374  if(!pass) {
375  ATH_MSG_DEBUG(" Combination failed var cut: " << varInfo.varTag << " = " << value << " not in range " << varInfo.rangeStr());
376  }
377  return pass;
378 }
379 
380 
382 bool testLegId(const Combo::LegDecision& d, uint32_t targetleg) {
383  auto combId = HLT::Identifier(d.first);
384  if(!TrigCompositeUtils::isLegId(combId)) return false;
385  return combId.numeric() == targetleg;
386 }
387 
388 
389 bool TrigComboHypoTool::fillLegDecisions_sameLeg(std::pair<Combo::LegDecision,Combo::LegDecision>& legpair, const Combination& combination, uint32_t leg) const {
390  Combination leg_features;
391  if(m_skipLegCheck) {
392  // If there is only one leg, the decision IDs don't have a leg ID
393  std::copy(combination.begin(),combination.end(),std::back_inserter(leg_features));
394  } else {
395  // Extract the features matching the legs
396  // We take all of them, so as to be able to check if there is any ambiguity
397  auto isMyLeg = [&leg](const Combo::LegDecision& d) { return testLegId(d,leg); };
398  std::copy_if(combination.begin(),combination.end(),std::back_inserter(leg_features),isMyLeg);
399  }
400 
401  if (leg_features.size()==2) {
402  legpair.first = leg_features[0];
403  legpair.second = leg_features[1];
404  } else {
405  ATH_MSG_ERROR(leg_features.size() << " Decision Objects supplied on leg " << leg
406  << ", must be 2 for same-leg topo selection!");
407  return false;
408  }
409 
410  return true;
411 }
412 
413 
414 bool TrigComboHypoTool::fillLegDecisions_diffLeg(std::pair<Combo::LegDecision,Combo::LegDecision>& legpair, const Combination& combination, uint32_t legA, uint32_t legB) const {
415  // Extract the features matching the legs
416  // We take all of them, so as to be able to check if there is any ambiguity
417  auto isLegA = [&legA](const Combo::LegDecision& d) { return testLegId(d,legA); };
418  auto isLegB = [&legB](const Combo::LegDecision& d) { return testLegId(d,legB); };
419  Combination legA_features, legB_features;
420 
421  std::copy_if(combination.begin(),combination.end(),std::back_inserter(legA_features),isLegA);
422  if(legA_features.size()!=1) {
423  ATH_MSG_ERROR(legA_features.size() << " Decision Objects supplied on leg " << legA
424  << ", must be 1 for different-leg topo selection!");
425  return false;
426  }
427 
428  std::copy_if(combination.begin(),combination.end(),std::back_inserter(legB_features),isLegB);
429  if (legB_features.size()!=1) {
430  ATH_MSG_ERROR(legB_features.size() << " Decision Objects supplied on leg " << legB
431  << ", must be 1 for different-leg topo selection!");
432  return false;
433  }
434 
435  legpair.first = legA_features[0];
436  legpair.second = legB_features[0];
437 
438  return true;
439 }
440 
441 
442 bool TrigComboHypoTool::fillPairKinematics(std::pair<KineInfo,KineInfo>& kinepair, const Combination& combination, const VarInfo& varInfo) const {
443  ATH_MSG_VERBOSE(" Decision objects available = "<< combination);
444  // Check that there are enough features
445  size_t nFeatures(combination.size());
446  if (nFeatures < 2){
447  ATH_MSG_ERROR("Number of Decision Objects passed is less than 2! Sum over decision objects on all legs = " << combination.size() );
448  return false;
449  }
450  std::pair<Combo::LegDecision,Combo::LegDecision> legpair;
451  if (varInfo.legsAreEqual) {fillLegDecisions_sameLeg(legpair,combination,varInfo.legA);}
452  else {fillLegDecisions_diffLeg(legpair,combination,varInfo.legA,varInfo.legB);}
453  ATH_MSG_VERBOSE(" Fill leg A kinematics");
454  if(!fillKineInfo(kinepair.first,legpair.first,varInfo.legA_is_MET)) {
455  ATH_MSG_ERROR("Failed to extract requisite kinematic info from leg " << varInfo.legA << "!");
456  return false;
457  }
458  ATH_MSG_VERBOSE(" Fill leg B kinematics");
459  if(!fillKineInfo(kinepair.second,legpair.second,varInfo.legB_is_MET)) {
460  ATH_MSG_ERROR("Failed to extract requisite kinematic info from leg " << varInfo.legB << "!");
461  return false;
462  }
463  return true;
464  }
465 
466 
468  float eta, phi, pt;
469  if (isMET) {
470  auto pLink = TrigCompositeUtils::findLink<xAOD::TrigMissingETContainer>( *decision.second, featureString() ).link;
471  if (!pLink.isValid()){
472  ATH_MSG_ERROR("link for MET not valid");
473  return false;
474  }
475  ROOT::Math::XYVectorF metv((*pLink)->ex(),(*pLink)->ey());
476  eta = FLOATDEFAULT;
477  phi = metv.phi();
478  pt = metv.r();
479  } else {
480  auto pLink = TrigCompositeUtils::findLink<xAOD::IParticleContainer>( *decision.second, featureString() ).link;
481  if (!pLink.isValid()){
482  ATH_MSG_ERROR("link for IParticle not valid");
483  return false;
484  }
485  eta = (*pLink)->p4().Eta();
486  phi = (*pLink)->p4().Phi();
487  pt = (*pLink)->p4().Pt();
488  }
489  ATH_MSG_VERBOSE(" Filled kinematics with pt " << pt*invGeV << ", eta " << eta << ", phi " << phi);
490  kinematics = std::make_tuple(eta,phi,pt);
491  return true;
492 }
493 
494 
495 float TrigComboHypoTool::compute(const std::pair<KineInfo,KineInfo>& kinepair, ComboHypoVars var) const {
496  const auto& [legA_kine,legB_kine] = kinepair;
497  const auto& [eta1,phi1,pt1] = legA_kine;
498  const auto& [eta2,phi2,pt2] = legB_kine;
499 
500  ATH_MSG_DEBUG(" Leg A has pt " << pt1*invGeV << ", eta " << eta1 << ", phi " << phi1);
501  ATH_MSG_DEBUG(" Leg B has pt " << pt2*invGeV << ", eta " << eta2 << ", phi " << phi2);
502 
503  float value(0);
504  switch(var) {
505  case ComboHypoVars::DR:
506  {
507  value = xAOD::P4Helpers::deltaR(eta1,phi1,eta2,phi2);
508  break;
509  }
510  case ComboHypoVars::DPHI:
511  {
512  value = std::fabs(xAOD::P4Helpers::deltaPhi(phi1,phi2));
513  break;
514  }
515  case ComboHypoVars::INVM:
516  {
517  ROOT::Math::PtEtaPhiMVector p1(pt1,eta1,phi1,0.), p2(pt2,eta2,phi2,0.);
518  value = (p1+p2).M()*invGeV; // Convert to GeV
519  break;
520  }
521  case ComboHypoVars::MT:
522  {
523  //Transverse mass defined for semi-visible decays in hadron colliders. See PDG 49.6, section on kinematics
524  value = std::sqrt(2*pt1*pt2*(1-std::cos(xAOD::P4Helpers::deltaPhi(phi1,phi2) ) ) )*invGeV; // Convert to GeV
525  break;
526  }
527  case ComboHypoVars::DETA:
528  {
529  value = std::fabs(eta2-eta1);
530  break;
531  }
532  default:
533  {
534  ATH_MSG_ERROR("Undefined variable requested -- should never happen!");
535  }
536  }
537  return value;
538 }
grepfile.info
info
Definition: grepfile.py:38
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:1394
TrigComboHypoTool::m_monTool_vec
ToolHandleArray< GenericMonitoringTool > m_monTool_vec
Definition: TrigComboHypoTool.h:118
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:115
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:442
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
xAODP4Helpers.h
hist_file_dump.d
d
Definition: hist_file_dump.py:143
ComboHypoToolBase::printDebugInformation
StatusCode printDebugInformation(const Combo::LegDecisionsMap &passingLegs) const
Print the output of the tool, after having removed failed Decision Objects.
Definition: ComboHypoToolBase.cxx:264
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:805
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:467
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:389
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:496
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:346
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:20
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:884
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:495
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:204
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: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:414
TrigComboHypoTool::VarInfo::varTag
std::string varTag
Definition: TrigComboHypoTool.h:51
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:27
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:382
TrigComboHypoTool::m_useMin_vec
Gaudi::Property< std::vector< bool > > m_useMin_vec
Definition: TrigComboHypoTool.h:103
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