ATLAS Offline Software
Loading...
Searching...
No Matches
Trig3VarComboHypoTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "GaudiKernel/SystemOfUnits.h"
9
10#include <Math/Vector4Dfwd.h> // PtEtaPhiM typedef
11#include <Math/Vector2D.h> // for XYVectorF
12
16
17#include <algorithm>
18#include <cmath>
19#include <map>
20#include <stdexcept>
21
22constexpr float invGeV = 1. / Gaudi::Units::GeV;
23
24using namespace TrigCompositeUtils;
25
26// Translate strings into enum values
27const std::map<std::string, Trig3VarComboHypoTool::ComboHypoVars> VarMap = {
29};
30
32 const std::string& name,
33 const IInterface* parent)
34 : ComboHypoToolBase(type, name, parent)
35{ }
36
38 if (legA==0){
39 errmsg = "legA ID not set!";
40 return false;
41 }
42 if (legB==0){
43 errmsg="legB ID not set!";
44 return false;
45 }
46 if (legC==0){
47 errmsg="legC 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==legC || legB==legC) {
55 errmsg = "Currently all legs must be different";
56 return false;
57 }
58 return true;
59}
60
62 ATH_MSG_DEBUG("Variable = " << m_varTag_vec );
63 ATH_MSG_DEBUG("UseCut min = " << m_useMin_vec );
64 ATH_MSG_DEBUG("UseCut max = " << m_useMax_vec );
65 ATH_MSG_DEBUG("varCut min = " << m_varMin_vec );
66 ATH_MSG_DEBUG("varCut max = " << m_varMax_vec );
67 ATH_MSG_DEBUG("LegA = " << m_legA_vec );
68 ATH_MSG_DEBUG("LegB = " << m_legB_vec );
69 ATH_MSG_DEBUG("LegC = " << m_legC_vec );
70
71 ATH_CHECK( m_monTool_vec.retrieve() );
72
73 if (m_legA_vec.size() != m_legB_vec.size() || m_legA_vec.size() != m_legC_vec.size()) {
74 ATH_MSG_ERROR("Trying to configure the Tool with legA/legB/legC vectors of different size!");
75 return StatusCode::FAILURE;
76 }
77 if (m_useMin_vec.size() != m_useMax_vec.size()) {
78 ATH_MSG_ERROR("Trying to configure the Tool with UseMin and UseMax vectors of different size!");
79 return StatusCode::FAILURE;
80 }
81 if (m_legA_vec.size() != m_useMax_vec.size()) {
82 ATH_MSG_ERROR("Trying to configure the Tool with legA/B and UseMax/Min vectors of different size!");
83 return StatusCode::FAILURE;
84 }
85 if (m_varTag_vec.size() != m_useMax_vec.size()) {
86 ATH_MSG_ERROR("Trying to configure the Tool with varTag and UseMax/Min(LegA/B/C) vectors of different size!");
87 return StatusCode::FAILURE;
88 }
89
90 for (size_t i=0; i<m_varTag_vec.size(); ++i){
91 VarInfo info;
92 info.index = i;
93 if(!m_monTool_vec.empty()) {
94 info.monToolName = m_monTool_vec[i].name();
95 }
96 if (VarMap.find(m_varTag_vec[i]) == VarMap.end()){
97 ATH_MSG_ERROR("The variable is not present in the ComboHypoVars list");
98 return StatusCode::FAILURE;
99 }
100 info.varTag = (m_varTag_vec[i]);
101 info.var = VarMap.at(m_varTag_vec[i]);
102 //
103 info.useMin = m_useMin_vec[i];
104 if(info.useMin) {info.varMin=m_varMin_vec[i];}
105 info.useMax = m_useMax_vec[i];
106 if(info.useMax) {info.varMax=m_varMax_vec[i];}
107 //
108 info.legA = m_legA_vec[i];
109 info.legA_is_MET = m_isLegA_MET_vec[i];
110 info.legB = m_legB_vec[i];
111 info.legB_is_MET = m_isLegB_MET_vec[i];
112 info.legC = m_legC_vec[i];
113 info.legC_is_MET = m_isLegC_MET_vec[i];
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
128StatusCode Trig3VarComboHypoTool::decide(Combo::LegDecisionsMap& passingLegs, const EventContext& /*context*/) const {
129
130 // if no combinations passed, then exit
131 if (passingLegs.empty()) {
132 return StatusCode::SUCCESS;
133 }
134
135 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.");
136 for(const auto& legpair : passingLegs) {
137 ATH_MSG_DEBUG(" Leg " << legpair.first << " has " << legpair.second.size() << " features");
138 }
139
140 // select the leg decisions from the map with this ID:
141 std::vector<Combination> legDecisions;
142 ATH_CHECK(selectLegs(passingLegs, legDecisions));
143
144 // Track if we have at least 3 objects on the target legs that can be used for variable computation
145 bool hasViableLegs{true};
146 // Determine the functional leg multiplicities for combinations to generate
147 std::vector<size_t> legMultiplicityForComputation(legMultiplicity().size(),0);
148 for (const VarInfo& varInfo : m_varInfo_vec){
149 ATH_MSG_DEBUG("Var " << varInfo.varTag << " needs legs " << varInfo.legA << ", " << varInfo.legB << ", " << varInfo.legC);
150
151 // Assess the leg decisions and extract the relevant ones
152 if (passingLegs.contains(varInfo.legA) && passingLegs.contains(varInfo.legB) && passingLegs.contains(varInfo.legC)) {
153 bool goodLegA{false}, goodLegB{false}, goodLegC{false};
154 int32_t iLegA = getIndexFromLeg(varInfo.legA);
155 int32_t iLegB = getIndexFromLeg(varInfo.legB);
156 int32_t iLegC = getIndexFromLeg(varInfo.legC);
157 if ((iLegA<0) or (iLegB<0) or (iLegC<0)){
158 ATH_MSG_ERROR("Trig3VarComboHypoTool::decide: Index into array is negative");
159 return StatusCode::FAILURE;
160 }
161 goodLegA = !passingLegs[varInfo.legA].empty();
162 legMultiplicityForComputation[iLegA] = std::max<size_t>(1,legMultiplicityForComputation[iLegA]);
163 ATH_MSG_DEBUG("Leg " << varInfo.legA << " has " << passingLegs[varInfo.legA].size() << " features --> " << (goodLegA ? "pass" : "fail"));
164
165 if(varInfo.legB == varInfo.legA) {
166 ATH_MSG_ERROR("Trig3VarComboHypoTool::decide: legB has to be different from legA");
167 return StatusCode::FAILURE;
168 }
169 goodLegB = !passingLegs[varInfo.legB].empty();
170 ATH_MSG_DEBUG("Leg " << varInfo.legB << " has " << passingLegs[varInfo.legB].size() << " features --> " << (goodLegB ? "pass" : "fail"));
171 legMultiplicityForComputation[iLegB] = std::max<size_t>(1,legMultiplicityForComputation[iLegB]);
172
173 if(varInfo.legC == varInfo.legA) {
174 ATH_MSG_ERROR("Trig3VarComboHypoTool::decide: legC has to be different from legA");
175 return StatusCode::FAILURE;
176 }
177 if(varInfo.legC == varInfo.legB) {
178 ATH_MSG_ERROR("Trig3VarComboHypoTool::decide: legC has to be different from legB");
179 return StatusCode::FAILURE;
180 }
181 goodLegC = !passingLegs[varInfo.legC].empty();
182 ATH_MSG_DEBUG("Leg " << varInfo.legC << " has " << passingLegs[varInfo.legC].size() << " features --> " << (goodLegC ? "pass" : "fail"));
183 legMultiplicityForComputation[iLegC] = std::max<size_t>(1,legMultiplicityForComputation[iLegC]);
184
185 hasViableLegs &= (goodLegA && goodLegB && goodLegC);
186 if (!hasViableLegs) {
187 ATH_MSG_DEBUG("Did not find at least 3 features on the target legs to compute " << varInfo.varTag);
188 }
189 } else {
191 "Insufficient passing legs to compute " << varInfo.varTag
192 << ", intended on (" << varInfo.legA << ", " << varInfo.legB << ", " << varInfo.legC << ")"
193 );
194 hasViableLegs = false;
195 }
196
197 }
198
199 if (!hasViableLegs) {
200 ATH_MSG_DEBUG("This Trig3VarComboHypoTool cannot run in this event, this chain **REJECTS** this event.");
201 eraseFromLegDecisionsMap(passingLegs);
202 if (msgLvl(MSG::DEBUG)) printDebugInformation(passingLegs);
203 return StatusCode::SUCCESS;
204 }
205
206 // Create and initialise the combinations generator for the requirements of this chain, given the objects available in this event.
207 // Extract the features on legs not used for the decision, so they stay in the navigation
208 Combination extraLegs;
210 for (size_t legindex = 0; size_t legmult : legMultiplicityForComputation){
211 size_t out_of = legDecisions[legindex].size();
212 if(legmult==0) {
213 extraLegs.insert(extraLegs.end(),legDecisions[legindex].cbegin(),legDecisions[legindex].cend());
214 } else {
215 nucg.add({out_of, legmult});
216 ATH_MSG_DEBUG("For leg index " << legindex << " we will be choosing any " << legmult << " Decision Objects out of " << out_of);
217 }
218 ++legindex;
219 }
220
221 // Iterate over all variable computations
222 std::vector<Combination> passingCombinations;
223 std::vector<float> values;
224 values.reserve(m_varInfo_vec.size());
225 size_t warnings = 0, iterations = 0;
226 // Correct for the legs on which we compute with 3 features
227 auto get_index_offset = [&legMultiplicityForComputation](size_t legindex) {
228 size_t offset{0};
229 for (auto iLeg=legMultiplicityForComputation.cbegin(); iLeg!=legMultiplicityForComputation.cbegin()+legindex; ++iLeg) {
230 offset += (*iLeg)-1;
231 }
232 return offset;
233 };
234 do {
235 bool lastDecision(true);
236 const std::vector<size_t> combination = nucg();
237 ++nucg;
238 ++iterations;
239 values.clear();
240
241 // This collects all the features contributing to any variable computation
242 Combination combinationToRecord;
243 for (auto iVarInfo = m_varInfo_vec.cbegin(); iVarInfo!=m_varInfo_vec.cend() && lastDecision; ++iVarInfo){
244 // Just the features for the current variable evaluation
245 Combination combinationToCheck;
246
247 size_t legA_index{0};
248 size_t legB_index{0};
249 size_t legC_index{0};
250
251 legA_index = getIndexFromLeg(iVarInfo->legA);
252 legB_index = getIndexFromLeg(iVarInfo->legB);
253 legC_index = getIndexFromLeg(iVarInfo->legC);
254
256 "Computing " << iVarInfo->varTag << " on legs "
257 << iVarInfo->legA << " (" << legA_index << "), "
258 << iVarInfo->legB << " (" << legB_index << "), "
259 << iVarInfo->legC << " (" << legC_index << ")"
260 );
261 if(iVarInfo->legA==iVarInfo->legB) {
262 ATH_MSG_DEBUG(" legA == legB is not allowed");
263 break;
264 }
265 if(iVarInfo->legA==iVarInfo->legC) {
266 ATH_MSG_DEBUG(" legA == legC is not allowed");
267 break;
268 }
269 if(iVarInfo->legB==iVarInfo->legC) {
270 ATH_MSG_DEBUG(" legB == legC is not allowed");
271 break;
272 }
273
274 // 1 object each on 3 legs
275 Combination featureTrio = {legDecisions[legA_index][combination.at(legA_index+get_index_offset(legA_index))],
276 legDecisions[legB_index][combination.at(legB_index+get_index_offset(legB_index))],
277 legDecisions[legC_index][combination.at(legC_index+get_index_offset(legC_index))]};
278 combinationToCheck.insert(combinationToCheck.end(),featureTrio.cbegin(),featureTrio.cend());
279 combinationToRecord.insert(combinationToRecord.end(),featureTrio.cbegin(),featureTrio.cend());
280
281 try {
282 lastDecision = executeAlgStep(combinationToCheck, *iVarInfo, values);
283 ATH_MSG_DEBUG("Combination " << (iterations - 1) << " decided to be " << (lastDecision ? "passing" : "failing") << " " << iVarInfo->varTag);
284 } catch (std::exception& e) {
285 ATH_MSG_ERROR(e.what());
286 return StatusCode::FAILURE;
287 }
288
289 if ((iterations >= m_combinationsThresholdWarn && warnings == 0) or (iterations >= m_combinationsThresholdBreak)) {
290 ATH_MSG_WARNING("Have so far processed " << iterations << " combinations for " << decisionId() << " in this event, " << passingCombinations.size() << " passing.");
291 ++warnings;
292 if (iterations >= m_combinationsThresholdBreak) {
293 ATH_MSG_WARNING("Too many combinations! Breaking the loop at this point.");
294 break;
295 }
296 }
297 }
298
299 // Assess the collective decision on the combination
300 if (lastDecision) {
301 combinationToRecord.insert(combinationToRecord.end(),extraLegs.cbegin(),extraLegs.cend());
302 passingCombinations.push_back(std::move(combinationToRecord));
303 if (m_modeOR == true and m_enableOverride) {
304 break;
305 }
306 } else { // the combination failed
307 if (m_modeOR == false and m_enableOverride) {
308 break;
309 }
310 }
311
312 // Monitoring of variables for only accepted events
313 if(lastDecision && !m_monTool_vec.empty()) {
314 for (const VarInfo& varInfo : m_varInfo_vec) {
315 float value = values[varInfo.index];
316 auto varOfAccepted = Monitored::Scalar(m_varTag_vec[varInfo.index]+"OfAccepted", value );//varInfo->monToolName+"OfAccepted", value );
317 auto monitorIt = Monitored::Group (m_monTool_vec[varInfo.index], varOfAccepted);
318 ATH_MSG_VERBOSE( varInfo.varTag << " = " << value << " is in range " << varInfo.rangeStr() << ".");
319 ATH_MSG_VERBOSE("m_varTag_vec = "<< m_varTag_vec<<", values = "<<values << ", valIndex = "<< varInfo.index <<", monToolName = " << varInfo.monToolName << ", monToolVec = "<< m_monTool_vec);
320 }
321 }
322
323 } while (nucg);
324
325 if (m_modeOR) {
326
327 ATH_MSG_DEBUG("Passing " << passingCombinations.size() << " combinations out of " << iterations << ", "
328 << decisionId() << (passingCombinations.size() ? " **ACCEPTS**" : " **REJECTS**") << " this event based on OR logic.");
329
330 if (m_enableOverride) {
331 ATH_MSG_DEBUG("Note: stopped after the first successful combination due to the EnableOverride flag.");
332 }
333
334 } else { // modeAND
335
336 const bool passAll = (passingCombinations.size() == iterations);
337
338 ATH_MSG_DEBUG("Passing " << passingCombinations.size() << " combinations out of " << iterations << ", "
339 << decisionId() << (passAll ? " **ACCEPTS**" : " **REJECTS**") << " this event based on AND logic.");
340
341 if (m_enableOverride) {
342 ATH_MSG_DEBUG("Note: stopped after the first failed combination due to the EnableOverride flag.");
343 }
344
345 if (not passAll) {
346 passingCombinations.clear();
347 }
348
349 }
350
351 if (not passingCombinations.empty()) { // need partial erasure of the decsions (only those not present in any combination)
352 updateLegDecisionsMap(passingCombinations, passingLegs);
353 } else { // need complete erasure of input decisions
354 eraseFromLegDecisionsMap(passingLegs);
355 }
356
357 if (msgLvl(MSG::DEBUG)) printDebugInformation(passingLegs);
358 return StatusCode::SUCCESS;
359}
360
361bool Trig3VarComboHypoTool::executeAlgStep(const Combination& combination, const VarInfo& varInfo, std::vector<float> &vals) const {
362 ATH_MSG_DEBUG("Executing selection " << varInfo.index << " of " << m_varInfo_vec.size() << ": " << varInfo.rangeStr());
363
364 std::tuple<KineInfo,KineInfo,KineInfo> kinetrio;
365 if(!fillTrioKinematics(kinetrio, combination, varInfo)) {
366 ATH_MSG_ERROR("Failed to extract kinematics of feature trio!");
367 return false;
368 }
369
370 if(msgLvl(MSG::VERBOSE)) {
371 float etaCheck, phiCheck, ptCheck;
372 std::tie(etaCheck,phiCheck,ptCheck) = std::get<0>(kinetrio);
373 msg() << MSG::VERBOSE << " Test filled legA kinematics: pt " << ptCheck*invGeV << ", eta " << etaCheck << ", phi " << phiCheck << endmsg;
374
375 std::tie(etaCheck,phiCheck,ptCheck) = std::get<1>(kinetrio);
376 msg() << MSG::VERBOSE << " Test filled legB kinematics: pt " << ptCheck*invGeV << ", eta " << etaCheck << ", phi " << phiCheck << endmsg;
377
378 std::tie(etaCheck,phiCheck,ptCheck) = std::get<2>(kinetrio);
379 msg() << MSG::VERBOSE << " Test filled legC kinematics: pt " << ptCheck*invGeV << ", eta " << etaCheck << ", phi " << phiCheck << endmsg;
380 }
381
382 // apply the cut
383 float value = compute(kinetrio,varInfo.var);
384 if(!m_monTool_vec.empty()) {
385 auto varOfProcessed = Monitored::Scalar(m_varTag_vec[varInfo.index]+"OfProcessed" , value );
386 auto monitorIt = Monitored::Group (m_monTool_vec[varInfo.index], varOfProcessed);
387 }
388 vals.push_back(value);
389 bool pass = varInfo.test(value);
390
391 ATH_MSG_DEBUG(" Found a combination with " << value);
392 if(!pass) {
393 ATH_MSG_DEBUG(" Combination failed var cut: " << varInfo.varTag << " = " << value << " not in range " << varInfo.rangeStr());
394 }
395 return pass;
396}
397
399bool testLegId3varcombo(const Combo::LegDecision& d, uint32_t targetleg) {
400 auto combId = HLT::Identifier(d.first);
401 if(!TrigCompositeUtils::isLegId(combId)) return false;
402 return combId.numeric() == targetleg;
403}
404
405bool Trig3VarComboHypoTool::fillLegDecisions_diffLeg(std::tuple<Combo::LegDecision,Combo::LegDecision,Combo::LegDecision>& legtrio, const Combination& combination, uint32_t legA, uint32_t legB, uint32_t legC) const {
406 // Extract the features matching the legs
407 // We take all of them, so as to be able to check if there is any ambiguity
408 auto isLegA = [&legA](const Combo::LegDecision& d) { return testLegId3varcombo(d,legA); };
409 auto isLegB = [&legB](const Combo::LegDecision& d) { return testLegId3varcombo(d,legB); };
410 auto isLegC = [&legC](const Combo::LegDecision& d) { return testLegId3varcombo(d,legC); };
411 Combination legA_features, legB_features, legC_features;
412
413 std::copy_if(combination.begin(),combination.end(),std::back_inserter(legA_features),isLegA);
414 if(legA_features.size()!=1) {
415 ATH_MSG_ERROR(legA_features.size() << " Decision Objects supplied on leg " << legA
416 << ", must be 1 for different-leg topo selection!");
417 return false;
418 }
419
420 std::copy_if(combination.begin(),combination.end(),std::back_inserter(legB_features),isLegB);
421 if (legB_features.size()!=1) {
422 ATH_MSG_ERROR(legB_features.size() << " Decision Objects supplied on leg " << legB
423 << ", must be 1 for different-leg topo selection!");
424 return false;
425 }
426
427 std::copy_if(combination.begin(),combination.end(),std::back_inserter(legC_features),isLegC);
428 if (legC_features.size()!=1) {
429 ATH_MSG_ERROR(legB_features.size() << " Decision Objects supplied on leg " << legC
430 << ", must be 1 for different-leg topo selection!");
431 return false;
432 }
433
434 std::get<0>(legtrio) = legA_features[0];
435 std::get<1>(legtrio) = legB_features[0];
436 std::get<2>(legtrio) = legC_features[0];
437
438 return true;
439}
440
441bool Trig3VarComboHypoTool::fillTrioKinematics(std::tuple<KineInfo,KineInfo,KineInfo>& kinetrio, const Combination& combination, const VarInfo& varInfo) const {
442 ATH_MSG_VERBOSE(" Decision objects available = "<< combination);
443 // Check that there are enough features
444 size_t nFeatures(combination.size());
445 if (nFeatures < 3){
446 ATH_MSG_ERROR("Number of Decision Objects passed is less than 3! Sum over decision objects on all legs = " << combination.size() );
447 return false;
448 }
449 std::tuple<Combo::LegDecision,Combo::LegDecision,Combo::LegDecision> legtrio;
450 fillLegDecisions_diffLeg(legtrio,combination,varInfo.legA,varInfo.legB,varInfo.legC);
451 ATH_MSG_VERBOSE(" Fill leg A kinematics");
452 if(!fillKineInfo(std::get<0>(kinetrio),std::get<0>(legtrio),varInfo.legA_is_MET)) {
453 ATH_MSG_ERROR("Failed to extract requisite kinematic info from leg " << varInfo.legA << "!");
454 return false;
455 }
456 ATH_MSG_VERBOSE(" Fill leg B kinematics");
457 if(!fillKineInfo(std::get<1>(kinetrio),std::get<1>(legtrio),varInfo.legB_is_MET)) {
458 ATH_MSG_ERROR("Failed to extract requisite kinematic info from leg " << varInfo.legB << "!");
459 return false;
460 }
461 ATH_MSG_VERBOSE(" Fill leg C kinematics");
462 if(!fillKineInfo(std::get<2>(kinetrio),std::get<2>(legtrio),varInfo.legC_is_MET)) {
463 ATH_MSG_ERROR("Failed to extract requisite kinematic info from leg " << varInfo.legC << "!");
464 return false;
465 }
466 return true;
467}
468
469bool Trig3VarComboHypoTool::fillKineInfo(Trig3VarComboHypoTool::KineInfo& kinematics, Combo::LegDecision decision, bool isMET) const {
470 float eta, phi, pt;
471 if (isMET) {
472 auto pLink = TrigCompositeUtils::findLink<xAOD::TrigMissingETContainer>( *decision.second, featureString() ).link;
473 if (!pLink.isValid()){
474 ATH_MSG_ERROR("link for MET not valid");
475 return false;
476 }
477 ROOT::Math::XYVectorF metv((*pLink)->ex(),(*pLink)->ey());
479 phi = metv.phi();
480 pt = metv.r();
481 } else {
482 auto pLink = TrigCompositeUtils::findLink<xAOD::IParticleContainer>( *decision.second, featureString() ).link;
483 if (!pLink.isValid()){
484 ATH_MSG_ERROR("link for IParticle not valid");
485 return false;
486 }
487 eta = (*pLink)->p4().Eta();
488 phi = (*pLink)->p4().Phi();
489 pt = (*pLink)->p4().Pt();
490 }
491 ATH_MSG_VERBOSE(" Filled kinematics with pt " << pt*invGeV << ", eta " << eta << ", phi " << phi);
492 kinematics = std::make_tuple(eta,phi,pt);
493 return true;
494}
495
496float Trig3VarComboHypoTool::compute(const std::tuple<KineInfo,KineInfo,KineInfo>& kinetrio, ComboHypoVars var) const {
497 const auto& [legA_kine,legB_kine,legC_kine] = kinetrio;
498 const auto& [eta1,phi1,pt1] = legA_kine;
499 const auto& [eta2,phi2,pt2] = legB_kine;
500 const auto& [eta3,phi3,pt3] = legC_kine;
501
502 ATH_MSG_DEBUG(" Leg A has pt " << pt1*invGeV << ", eta " << eta1 << ", phi " << phi1);
503 ATH_MSG_DEBUG(" Leg B has pt " << pt2*invGeV << ", eta " << eta2 << ", phi " << phi2);
504 ATH_MSG_DEBUG(" Leg C has pt " << pt3*invGeV << ", eta " << eta3 << ", phi " << phi3);
505
506 float value{0.0f};
507 switch(var) {
509 {
510 ROOT::Math::PtEtaPhiMVector p1(pt1,eta1,phi1,0.), p2(pt2,eta2,phi2,0.);
511 value = (p1+p2).M()*invGeV; // Convert to GeV
512
513 // require legC objects are isolated from legA and legB
514 float dRAC = xAOD::P4Helpers::deltaR(eta1,phi1,eta3,phi3);
515 float dRBC = xAOD::P4Helpers::deltaR(eta2,phi2,eta3,phi3);
516
517 ATH_MSG_DEBUG(" invmAB = " << value << ", dRAC = " << dRAC << ", dRBC = " << dRBC);
518
519 if(dRAC < 0.2 || dRBC < 0.2)
520 value = -1.;
521
522 break;
523 }
524 default:
525 {
526 ATH_MSG_ERROR("Undefined variable requested -- should never happen!");
527 }
528 }
529 return value;
530}
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)
Header file to be included by clients of the Monitored infrastructure.
constexpr float invGeV
bool testLegId3varcombo(const Combo::LegDecision &d, uint32_t targetleg)
Test function to compare decision ID with the legs to be used in var computation.
const std::map< std::string, Trig3VarComboHypoTool::ComboHypoVars > VarMap
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
bool fillKineInfo(KineInfo &kinematics, Combo::LegDecision decision, bool isMET) const
static constexpr float FLOATDEFAULT
Gaudi::Property< std::vector< bool > > m_useMax_vec
Gaudi::Property< std::vector< std::string > > m_varTag_vec
Gaudi configuration hooks.
Gaudi::Property< std::vector< float > > m_varMin_vec
ToolHandleArray< GenericMonitoringTool > m_monTool_vec
bool executeAlgStep(const Combination &combination, const VarInfo &, std::vector< float > &values) const
Implementation of selection on individual variables.
std::vector< Combo::LegDecision > Combination
virtual StatusCode initialize() override
Gaudi::Property< std::vector< uint32_t > > m_legA_vec
StatusCode decide(Combo::LegDecisionsMap &passingLegs, const EventContext &) const final
Override the ComboHypoToolBase::decide in order to optimise combination generation This is to avoid e...
Trig3VarComboHypoTool(const std::string &type, const std::string &name, const IInterface *parent)
float compute(const std::tuple< KineInfo, KineInfo, KineInfo > &kinetrio, ComboHypoVars var) const
Computation of the variables from the specified kinematics.
Gaudi::Property< std::vector< bool > > m_isLegC_MET_vec
std::vector< VarInfo > m_varInfo_vec
Internal variables for more efficient config lookup.
Gaudi::Property< std::vector< uint32_t > > m_legC_vec
std::tuple< float, float, float > KineInfo
alias for convenience, will contain eta/phi/pt info
Gaudi::Property< std::vector< uint32_t > > m_legB_vec
bool fillLegDecisions_diffLeg(std::tuple< Combo::LegDecision, Combo::LegDecision, Combo::LegDecision > &legtrio, const Combination &combination, uint32_t legA, uint32_t legB, uint32_t legC) const
Gaudi::Property< std::vector< bool > > m_isLegB_MET_vec
Gaudi::Property< std::vector< bool > > m_useMin_vec
Gaudi::Property< std::vector< bool > > m_isLegA_MET_vec
bool fillTrioKinematics(std::tuple< KineInfo, KineInfo, KineInfo > &kinetrio, const Combination &combination, const VarInfo &varInfo) const
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 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.
MsgStream & msg
Definition testRead.cxx:32