ATLAS Offline Software
Loading...
Searching...
No Matches
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
21constexpr float invGeV = 1. / Gaudi::Units::GeV;
22
23using namespace TrigCompositeUtils;
24
25// Translate strings into enum values
26const std::map<std::string, TrigComboHypoTool::ComboHypoVars> VarMap = {
32};
33
35 const std::string& name,
36 const IInterface* parent)
37 : ComboHypoToolBase(type, name, parent)
38{}
39
40
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
129StatusCode 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
349bool 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
385bool 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
392bool 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
417bool 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
445bool 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
470bool TrigComboHypoTool::fillKineInfo(TrigComboHypoTool::KineInfo& kinematics, Combo::LegDecision decision, bool isMET) const {
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());
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
498float 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) {
509 {
510 value = xAOD::P4Helpers::deltaR(eta1,phi1,eta2,phi2);
511 break;
512 }
514 {
515 value = std::fabs(xAOD::P4Helpers::deltaPhi(phi1,phi2));
516 break;
517 }
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 }
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 }
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}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
constexpr float invGeV
const std::map< std::string, Trig3VarComboHypoTool::ComboHypoVars > VarMap
bool testLegId(const Combo::LegDecision &d, uint32_t targetleg)
Test function to compare decision ID with the legs to be used in var computation.
static thread_local std::ostringstream errmsg
Definition WaferTree.h:25
const std::vector< int > & legMultiplicity() const
Gets the number of legs and the multiplicity required on each leg.
Gaudi::Property< bool > m_modeOR
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,...
void printDebugInformation(const Combo::LegDecisionsMap &passingLegs) const
Print the output of the tool, after having removed failed Decision Objects.
Gaudi::Property< size_t > m_combinationsThresholdWarn
void eraseFromLegDecisionsMap(Combo::LegDecisionsMap &passingLegs) const
For when the tool rejects all combinations.
ComboHypoToolBase(const std::string &type, const std::string &name, const IInterface *parent)
Gaudi::Property< size_t > m_combinationsThresholdBreak
virtual HLT::Identifier decisionId() const
retrieves this ComboHypoTool's chain's decision ID
Gaudi::Property< bool > m_enableOverride
void updateLegDecisionsMap(const std::vector< std::vector< Combo::LegDecision > > &passing_comb, Combo::LegDecisionsMap &passingLegs) const
For when the tool accepts some/all combinations.
An ensemble of UniqueCombinationGenerator API description.
void add(const UniqueCombinationGenerator &gen)
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
Gaudi::Property< std::vector< float > > m_varMax_vec
float compute(const std::pair< KineInfo, KineInfo > &kinepair, ComboHypoVars var) const
Computation of the variables from the specified kinematics.
StatusCode decide(Combo::LegDecisionsMap &passingLegs, const EventContext &) const final
Override the ComboHypoToolBase::decide in order to optimise combination generation This is to avoid e...
bool executeAlgStep(const Combination &combination, const VarInfo &, std::vector< float > &values) const
Implementation of selection on individual variables.
Gaudi::Property< std::vector< bool > > m_isLegB_MET_vec
bool fillLegDecisions_diffLeg(std::pair< Combo::LegDecision, Combo::LegDecision > &legpair, const Combination &combination, uint32_t legA, uint32_t legB) const
Gaudi::Property< std::vector< bool > > m_useMin_vec
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...
bool fillKineInfo(KineInfo &kinematics, Combo::LegDecision decision, bool isMET) const
Gaudi::Property< std::vector< uint32_t > > m_legA_vec
static constexpr float FLOATDEFAULT
std::vector< Combo::LegDecision > Combination
Gaudi::Property< std::vector< bool > > m_isLegA_MET_vec
bool fillPairKinematics(std::pair< KineInfo, KineInfo > &kinepair, const Combination &combination, const VarInfo &varInfo) const
std::tuple< float, float, float > KineInfo
Typedef for convenience, will contain eta/phi/pt info.
Gaudi::Property< std::vector< bool > > m_useMax_vec
Gaudi::Property< bool > m_skipLegCheck
Gaudi::Property< std::vector< float > > m_varMin_vec
TrigComboHypoTool(const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode initialize() override
ToolHandleArray< GenericMonitoringTool > m_monTool_vec
std::vector< VarInfo > m_varInfo_vec
Internal variables for more efficient config lookup.
Gaudi::Property< std::vector< std::string > > m_varTag_vec
Gaudi configuration hooks.
Gaudi::Property< std::vector< uint32_t > > m_legB_vec
const std::string & featureString()
int32_t getIndexFromLeg(const HLT::Identifier &legIdentifier)
Extract the numeric index of a leg identifier.
LinkInfo< T > findLink(const Decision *start, const std::string &linkName, const bool suppressMultipleLinksWarning=false)
Perform a recursive search for ElementLinks of type T and name 'linkName', starting from Decision obj...
bool isLegId(const HLT::Identifier &legIdentifier)
Recognise whether the chain ID is a leg ID.
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
Organise info per var selection in a struct.
bool validate(std::string &errmsg) const
Check consistency of single var config.
std::string rangeStr() const
Generate range string for printing.
bool test(float value) const
MsgStream & msg
Definition testRead.cxx:32