12 m_decisionId(
HLT::Identifier::fromToolName(
name)), m_legMultiplicities()
18 const Combo::MultiplicityReqMap::const_iterator
it = multiplicityRequiredMap.find(nameOfToolsChain);
20 if (
it == multiplicityRequiredMap.end()) {
21 ATH_MSG_ERROR(
"ComboHypoTool for " <<
m_decisionId <<
" could not find its required multiplcity data in the map supplied by its parent alg.");
22 return StatusCode::FAILURE;
27 ATH_MSG_ERROR(
"ComboHypoTool for " <<
m_decisionId <<
" was listed in the supplied multiplicityRequiredMap, but data was not supplied for any legs.");
28 return StatusCode::FAILURE;
35 return StatusCode::FAILURE;
45 return StatusCode::SUCCESS;
50 ATH_MSG_ERROR(
"ComboHypoTool for " <<
m_decisionId <<
" has not been properly configured. setLegMultiplicity should be called by the parent alg in initalize");
51 return StatusCode::FAILURE;
55 if (passingLegs.size() == 0) {
56 return StatusCode::SUCCESS;
59 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.");
62 std::vector<std::vector<Combo::LegDecision>> legDecisions;
67 if (legDecisions.at(legIndex).size() <
static_cast<size_t>(
m_legMultiplicities.at(legIndex))) {
69 ATH_MSG_DEBUG(
"This ComboHypoTool cannot run in this event, this chain **REJECTS** this event.");
72 return StatusCode::SUCCESS;
80 const size_t out_of = legDecisions.at(legIndex).size();
81 nucg.
add({out_of, choose_any});
82 ATH_MSG_DEBUG(
"For leg " << legIndex <<
" we will be choosing any " << choose_any <<
" Decision Objects out of " << out_of);
85 std::vector<std::vector<Combo::LegDecision>> passingCombinations;
87 size_t warnings = 0, iterations = 0;
90 const std::vector<size_t> combination = nucg();
92 std::vector<Combo::LegDecision> combinationToCheck;
94 size_t location_in_combination = 0;
99 const size_t objectIndex = combination.at(location_in_combination++);
100 combinationToCheck.push_back( legDecisions.at(legIndex).at(objectIndex) );
108 ATH_MSG_DEBUG(
"Combination " << (iterations - 1) <<
" decided to be passing");
109 passingCombinations.push_back(combinationToCheck);
120 return StatusCode::FAILURE;
124 ATH_MSG_WARNING(
"Have so far processed " << iterations <<
" combinations for " <<
m_decisionId <<
" in this event, " << passingCombinations.size() <<
" passing.");
127 ATH_MSG_WARNING(
"Too many combinations! Breaking the loop at this point.");
137 ATH_MSG_DEBUG(
"Passing " << passingCombinations.size() <<
" combinations out of " << iterations <<
", "
138 <<
m_decisionId << (passingCombinations.size() ?
" **ACCEPTS**" :
" **REJECTS**") <<
" this event based on OR logic.");
141 ATH_MSG_DEBUG(
"Note: stopped after the first successful combination due to the EnableOverride flag.");
146 const bool passAll = (passingCombinations.size() == iterations);
148 ATH_MSG_DEBUG(
"Passing " << passingCombinations.size() <<
" combinations out of " << iterations <<
", "
149 <<
m_decisionId << (passAll ?
" **ACCEPTS**" :
" **REJECTS**") <<
" this event based on AND logic.");
152 ATH_MSG_DEBUG(
"Note: stopped after the first failed combination due to the EnableOverride flag.");
156 passingCombinations.clear();
161 if (not passingCombinations.empty()) {
168 return StatusCode::SUCCESS;
189 std::vector<Combo::LegDecision> decisionObjectsOnLeg;
192 const Combo::LegDecisionsMap::const_iterator
it = IDCombMap.find(legIdentifier.
numeric());
194 if (
it != IDCombMap.end()) {
196 decisionObjectsOnLeg.emplace_back(legIdentifier,
el);
200 legDecisions.push_back(std::move(decisionObjectsOnLeg));
206 for (
const auto&
leg : legDecisions) {
208 for (
const auto& dEL :
leg) {
213 return StatusCode::SUCCESS;
219 for (
const std::vector<Combo::LegDecision>& comb : passingComb) {
221 for (
const auto& [
id,
EL] : comb) {
228 for (
auto&
it : passingLegs) {
233 std::vector<ElementLink<DecisionContainer>> updatedDecisionObjectsOnLeg;
236 for (
const std::vector<Combo::LegDecision>& comb : passingComb) {
237 for (
const auto& [
id,
EL] : comb) {
239 if (
id == legId and
std::find(updatedDecisionObjectsOnLeg.begin(), updatedDecisionObjectsOnLeg.end(),
EL) == updatedDecisionObjectsOnLeg.end()) {
241 updatedDecisionObjectsOnLeg.push_back(
EL);
248 it.second = updatedDecisionObjectsOnLeg;
254 for (
auto&
it : passingLegs) {
257 const size_t nDecisionObjects =
it.second.size();
266 for (
const auto& [
id, ELV] : passingLegs) {
270 for (
const auto&
EL : ELV) {
275 return StatusCode::SUCCESS;
280 ATH_MSG_ERROR(
"Do not use ComboHypoToolBase on its own, inherit this class and override executeAlg.");
285 ATH_MSG_ERROR(
"Do not use ComboHypoToolBase on its own, inherit this class and override decideOnSingleObject.");
286 ATH_MSG_ERROR(
"NOTE: Only if you are also supplying your own decide(...) implimentation, or similar.");
287 ATH_MSG_ERROR(
"NOTE: Most uses cases should only need to override executeAlg(...).");
288 return StatusCode::FAILURE;