Commit 1843b6d0 authored by Tim Martin's avatar Tim Martin Committed by Adam Edward Barton
Browse files

[ATR-23807][ATR-23688][ATR-23421][ATR-23817] Jet and Bjet refactor ComboHypo Leg Restrictions

parent 41a2db74
# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
from AthenaConfiguration.ComponentFactory import CompFactory
......@@ -20,7 +20,3 @@ def TimeBurnerHypoToolGen(chainDict):
return self.name
return DummyHypo(chainDict['chainName'])
def PassthroughComboHypoCfg(name):
return CompFactory.PassthroughComboHypo(name)
/*
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
#include "PassthroughComboHypo.h"
#include "xAODTrigger/TrigComposite.h"
#include "TrigCompositeUtils/TrigCompositeUtils.h"
using namespace TrigCompositeUtils;
PassthroughComboHypo::PassthroughComboHypo(const std::string& name, ISvcLocator* pSvcLocator)
: ::ComboHypo(name, pSvcLocator) {
}
StatusCode PassthroughComboHypo::initialize() {
ATH_MSG_DEBUG( "PassthroughComboHypo::initialize()" );
return ::ComboHypo::initialize();
}
StatusCode PassthroughComboHypo::execute(const EventContext& context) const {
ATH_MSG_DEBUG( "PassthroughComboHypo::execute()" );
for (size_t input_counter = 0; input_counter < decisionsInput().size(); ++input_counter ) {
// New output collection to mirror input collection
SG::WriteHandle<DecisionContainer> outputHandle = createAndStore(decisionsOutput().at(input_counter), context);
SG::ReadHandle<DecisionContainer> inputHandle = SG::makeHandle(decisionsInput().at(input_counter), context);
if (inputHandle.isValid()) {
ATH_MSG_DEBUG("Copying to output " << inputHandle->size() << " Decision objects from handle input handle #"
<< input_counter << ", " << decisionsInput().at(input_counter).key());
for (const Decision* inputDecision : *inputHandle) {
// Get all passing IDs from inputDecision
DecisionIDContainer inputDecisionIDs;
decisionIDs(inputDecision, inputDecisionIDs);
// Create 1-to-1 output Decision object, linked to inputDecision
Decision* outputDecision = newDecisionIn(outputHandle.ptr(), inputDecision, comboHypoAlgNodeName(), context);
// Copy in all the same passing IDs
insertDecisionIDs(inputDecisionIDs, outputDecision);
}
} else {
ATH_MSG_ERROR("Unable to resolve required Input Handle: " << decisionsInput().at(input_counter).key());
ATH_MSG_ERROR("Check menu configuration. If this ComboHypo is executed then all of the producers of its inputs should have run.");
return StatusCode::FAILURE;
}
}
return StatusCode::SUCCESS;
}
\ No newline at end of file
/*
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
#ifndef TRIGGENERICALGS_PASSTHROUGHCOMBOHYPO_H
#define TRIGGENERICALGS_PASSTHROUGHCOMBOHYPO_H 1
#include "DecisionHandling/ComboHypo.h"
/**
* @class PassthroughComboHypo
* @brief Generic slot-in ComboHypo class to be used for cases where all combined logic has already been applied
* Copies all input collections to output, unchanged.
*/
class PassthroughComboHypo: public ::ComboHypo {
public:
PassthroughComboHypo(const std::string& name, ISvcLocator* pSvcLocator);
PassthroughComboHypo() = delete;
virtual ~PassthroughComboHypo() = default;
virtual StatusCode initialize() override;
virtual StatusCode execute(const EventContext& context) const override;
};
#endif // TRIGGENERICALGS_PASSTHROUGHCOMBOHYPO_H
\ No newline at end of file
#include "../TimeBurner.h"
#include "../RandomErrorAlg.h"
#include "../PassthroughComboHypo.h"
DECLARE_COMPONENT( TimeBurner )
DECLARE_COMPONENT( RandomErrorAlg )
DECLARE_COMPONENT( PassthroughComboHypo )
......@@ -17,6 +17,53 @@ if debug:
def trigJetHypoToolFromDict(chain_dict):
from DecisionHandling.TrigCompositeUtils import isLegId, getLegIndexInt
chain_name = chain_dict['chainName']
jet_signature_identifiers = ['Jet', 'Bjet']
if isLegId(chain_name):
# For multi-leg chains which include jet legs we have a -- SPECIAL BEHAVIOUR --
# We instantiate a HypoTool only for the *first* jet leg, whichever leg that happens to be in the chain
# This single HypoTool gets configured to perform the selection for _all_ of the jet legs, and to report
# the per-jet passing status for all of these legs.
#
# Here we determine if this is the 2nd+ jet leg of a multi-leg chain which has jet legs, and return None tool if it is
# Can we fetch this from elsewhere?
leg_id = getLegIndexInt(chain_name)
# CHECK: If we have called trigJetHypoToolFromDict, then the chain_dict['signatures'] list must contain at minimum one entry from the jet_signature_identifiers list.
if not any(signature in chain_dict['signatures'] for signature in jet_signature_identifiers):
raise Exception("[trigJetHypoToolFromDict] No {} in {} for chain {}. Please update this list of jet signatures.".format(tuple(jet_signature_identifiers),tuple(chain_dict['signatures']),chain_name))
# CHECK: All Jet and Bjet legs (i.e. signatures from jet_signature_identifiers) must be contiguous
# (this check is probable best put somewhere else?)
status = 0
for entry in chain_dict['signatures']:
if status == 0 and entry in jet_signature_identifiers:
status = 1
elif status == 1 and entry not in jet_signature_identifiers:
status = 2
elif status == 2 and entry in jet_signature_identifiers:
raise Exception("[trigJetHypoToolFromDict] All {} legs should be contiguous in the signatures list, modify the ordering of the chain {}. Signatures:{}.".format(tuple(jet_signature_identifiers),chain_name, tuple(chain_dict['signatures'])))
# CHECK: The leg_id must correspond to a Signature from jet_signature_identifiers. At the time of implementation, this is not guaranteed and can be affected by alignment.
# If this check fails for any chain, then we need to look again at how the legXXX ordering maps to the chain_dict['signatures'] ordering.
if not any(signature in chain_dict['signatures'][leg_id] for signature in jet_signature_identifiers):
raise Exception("[trigJetHypoToolFromDict] For this code to work for chain {}, the signature at index {} must be one of {}. But the signature list is: {}".format(chain_name,leg_id,tuple(jet_signature_identifiers),tuple(chain_dict['signatures'])))
# Locate the first index within chain_dict['signatures'] which contains an signature listed in jet_signature_identifiers
first_leg_index = 999
for signature in jet_signature_identifiers:
if signature in chain_dict['signatures']:
first_leg_index = min(first_leg_index, chain_dict['signatures'].index(signature))
if leg_id > first_leg_index:
logger.debug("Not returning a HypoTool for {} as this isn't the first leg with any of {} (leg signatures are {})".format(chain_name,tuple(jet_signature_identifiers),tuple(chain_dict['signatures'])))
return None
logger.debug("Returning a HypoTool for {} as this is the first leg with any of {} (leg signatures are {})".format(chain_name,tuple(jet_signature_identifiers),tuple(chain_dict['signatures'])))
hypo_tool = hypotool_from_chaindict(chain_dict)
hypo_tool.visit_debug = debug
......
......@@ -344,6 +344,7 @@ def hypotool_from_chaindict(chain_dict, visit_debug=False):
toolclass, name = toolfactory('hypo_tool')
startLabelIndex, endLabelIndex = getLabelIndices(chain_dict)
args = {'name': chain_dict['chainName'],
# for reporting passing jets:
'visit_debug': visit_debug,
......
/*
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
#include <algorithm>
......@@ -19,7 +19,14 @@ TrigJetHypoAlg::TrigJetHypoAlg( const std::string& name,
StatusCode TrigJetHypoAlg::initialize() {
CHECK( m_hypoTools.retrieve() );
// Jet special case: only one jet HypoTool is provided per chain, even if the chain has multiple jet legs.
// Suppose HLT_e5_2e10_j10_j20_mu40. Only the leg002 jet HypoTool will be provided, and this will
// compute the result for both the leg002 and leg003 here.
for (auto& tool : m_hypoTools) {
if (not tool.empty()) {
ATH_CHECK(tool.retrieve());
}
}
CHECK( m_jetsKey.initialize() );
return StatusCode::SUCCESS;
}
......@@ -94,7 +101,7 @@ TrigJetHypoAlg::decide(const xAOD::JetContainer* jets,
// with those in the preceding step.
Decision* newDecision = nullptr;
newDecision = TrigCompositeUtils::newDecisionIn(outputDecisions, previousDecision, TrigCompositeUtils::hypoAlgNodeName(), context);
// Needs a dummy feature link -- we will specify the input RoI
// Needs a dummy feature link -- we will specify the input RoI which triggers special behaviour in the ComboHypo, equivilant to the "noCombo" below
if(!newDecision->hasObjectLink(TrigCompositeUtils::featureString())) {
newDecision->setObjectLink<TrigRoiDescriptorCollection>(TrigCompositeUtils::featureString(),
TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>(newDecision, TrigCompositeUtils::initialRoIString()).link);
......@@ -118,7 +125,11 @@ TrigJetHypoAlg::decide(const xAOD::JetContainer* jets,
const xAOD::JetContainer* jetCont = static_cast<const xAOD::JetContainer*>(jet->container());
ElementLink<xAOD::JetContainer> jetLink =
ElementLink<xAOD::JetContainer>(*jetCont, jet->index());
ElementLink<xAOD::JetContainer>(*jetCont, jet->index());
// Create a decoration. This is used to comminicate to the following ComboHypo that the
// DecisionObject should be excluded from downstream multiplicity checks.
newDecision->setDetail<int32_t>("noCombo", 1);
newDecision->setObjectLink<xAOD::JetContainer>(TrigCompositeUtils::featureString(), jetLink);
jetHypoInputs.push_back( std::make_pair(jet, newDecision) );
......@@ -160,6 +171,9 @@ TrigJetHypoAlg::decide(const xAOD::JetContainer* jets,
previousDecisionIDs.insert(leglessPreviousDecisionIDs.begin(), leglessPreviousDecisionIDs.end());
for (const auto& tool: m_hypoTools) {
if (tool.empty()) {
continue;
}
ATH_MSG_DEBUG("Now computing decision for " << tool->name());
CHECK(tool->decide(jets, previousDecisionIDs, jetHypoInputs));
}
......
......@@ -26,6 +26,10 @@
using TrigCompositeUtils::DecisionID;
using TrigCompositeUtils::Decision;
using TrigCompositeUtils::DecisionContainer;
using TrigCompositeUtils::isLegId;
using TrigCompositeUtils::getIDFromLeg;
using TrigCompositeUtils::createLegName;
TrigJetHypoTool::TrigJetHypoTool(const std::string& type,
const std::string& name,
......@@ -41,29 +45,32 @@ TrigJetHypoTool::~TrigJetHypoTool(){
StatusCode TrigJetHypoTool::initialize(){
if (!(m_endLabelIndex > 0)){
ATH_MSG_ERROR("endLabelIndex must be > 0, is " +
std::to_string(m_endLabelIndex));
ATH_MSG_ERROR("endLabelIndex must be > 0, is " + std::to_string(m_endLabelIndex));
return StatusCode::FAILURE;
}
if (m_endLabelIndex == 1u) {
// This is a single-leg jet chain.
m_decisionIDs.push_back(m_decisionID);
} else {
if(TrigCompositeUtils::isLegId(m_decisionID)){
HLT::Identifier noLegNameDecisionID = TrigCompositeUtils::getIDFromLeg(m_decisionID);
for (std::size_t i = m_startLabelIndex; i != m_endLabelIndex; ++i){
m_decisionIDs.push_back(TrigCompositeUtils::createLegName(noLegNameDecisionID,
i));
}
} else {
for (std::size_t i = m_startLabelIndex; i != m_endLabelIndex; ++i){
m_decisionIDs.push_back(TrigCompositeUtils::createLegName(m_decisionID,
i));
}
// This is a multi-leg chain with (m_endLabelIndex - m_startLabelIndex) jet legs contained within
if(not isLegId(m_decisionID)){
ATH_MSG_ERROR(name() << " is being configured to do jet selection for a multi-leg chain, from leg " << m_startLabelIndex <<
" to " << m_endLabelIndex << ", the HypoTool's name must therefore start with legXXX_ rather than HLT_");
return StatusCode::FAILURE;
}
HLT::Identifier noLegNameDecisionID = getIDFromLeg(m_decisionID);
for (std::size_t i = m_startLabelIndex; i != m_endLabelIndex; ++i){
m_decisionIDs.push_back(createLegName(noLegNameDecisionID, i));
ATH_MSG_DEBUG("Adding jet-leg " << m_decisionIDs.size()-1 << " for " << noLegNameDecisionID << ", this is leg " << i << " in the chain:" << m_decisionIDs.back());
}
}
if (m_visitDebug){
......@@ -71,7 +78,6 @@ StatusCode TrigJetHypoTool::initialize(){
CHECK(m_helper->getDescription(collector));
auto s = collector.toString();
for(const auto& l : lineSplitter(s)){
ATH_MSG_INFO(l);
}
......@@ -88,13 +94,13 @@ StatusCode TrigJetHypoTool::finalize(){
StatusCode
TrigJetHypoTool::decide(const xAOD::JetContainer* jets,
const TrigCompositeUtils::DecisionIDContainer& previousDecisionIDs,
std::vector<JetDecision>& jetHypoInputs) const {
const TrigCompositeUtils::DecisionIDContainer& previousDecisionIDs,
std::vector<JetDecision>& jetHypoInputs) const {
// need only check against the decision ID corresponding to the name
// of this hypo. Leg indices are irrelevant at this point.
if (not TrigCompositeUtils::passed(m_decisionID.numeric(),
previousDecisionIDs)) {
previousDecisionIDs)) {
return StatusCode::SUCCESS;
}
......@@ -141,9 +147,9 @@ TrigJetHypoTool::decide(const xAOD::JetContainer* jets,
if (infocollector){
std::string msg =
"hypo testing done: no of input jets " + std::to_string(jets->size())
+ " no of participating jets " + std::to_string(jetCollector.size())
+ " pass: false ";
"hypo testing done: no of input jets " + std::to_string(jets->size())
+ " no of participating jets " + std::to_string(jetCollector.size())
+ " pass: false ";
infocollector->collect("TrigJetHypoTool", msg);
}
......@@ -189,12 +195,12 @@ const HLT::Identifier& TrigJetHypoTool::getID(std::size_t i) const{
StatusCode
TrigJetHypoTool::checkPassingJets(const xAODJetCollector& jetCollector,
const std::unique_ptr<ITrigJetHypoInfoCollector>& infocollector) const {
const std::unique_ptr<ITrigJetHypoInfoCollector>& infocollector) const {
if (jetCollector.empty()) {
ATH_MSG_ERROR("HypoTool passed the event for " <<
m_chainName << " ev " << m_eventSN->m_id <<
", but did not specify which jets participated");
m_chainName << " ev " << m_eventSN->m_id <<
", but did not specify which jets participated");
return StatusCode::FAILURE;
}
......@@ -203,6 +209,12 @@ TrigJetHypoTool::checkPassingJets(const xAODJetCollector& jetCollector,
ATH_MSG_ERROR("inconsistent number of leg indices");
return StatusCode::FAILURE;
}
ATH_MSG_DEBUG("check passing jets? does it work?");
ATH_MSG_DEBUG("There are some indices: " << legIndices.size());
for(size_t i = 0; i < legIndices.size(); i ++){
ATH_MSG_DEBUG(" -- leg " << i << " has index " << legIndices.at(i));
}
// jet hypo inputs:
// pairs of const xAOD::Jet* (first) and mutable Decision* (second)
......@@ -211,7 +223,7 @@ TrigJetHypoTool::checkPassingJets(const xAODJetCollector& jetCollector,
if (infocollector) {
infocollector->
collect(name(),
"no of xAODJets " + std::to_string(participating_jets.size()));
"no of xAODJets " + std::to_string(participating_jets.size()));
auto legInds = jetCollector.legInds();
std::stringstream ss;
......@@ -220,7 +232,7 @@ TrigJetHypoTool::checkPassingJets(const xAODJetCollector& jetCollector,
auto jets = jetCollector.xAODJets(label);
ss << label << " [\n";
for(const auto& j : jets){
ss << static_cast<const void*>(j) << '\n';
ss << static_cast<const void*>(j) << '\n';
}
ss << "]\n";
}
......@@ -232,7 +244,7 @@ TrigJetHypoTool::checkPassingJets(const xAODJetCollector& jetCollector,
StatusCode
TrigJetHypoTool::reportPassingJets(const xAODJetCollector& jetCollector,
const std::vector<JetDecision>& jetHypoInputs) const {
const std::vector<JetDecision>& jetHypoInputs) const {
auto legIndices = jetCollector.legInds();
for(const auto& legInd : legIndices){
......@@ -245,8 +257,8 @@ TrigJetHypoTool::reportPassingJets(const xAODJetCollector& jetCollector,
StatusCode
TrigJetHypoTool::reportLeg(const std::vector<const xAOD::Jet*>& jets,
const std::vector<JetDecision>& jetHypoInputs,
int legInd) const {
const std::vector<JetDecision>& jetHypoInputs,
int legInd) const {
// check if input jet is a participating jet. If so , add
// its Decision object.
......@@ -257,16 +269,11 @@ TrigJetHypoTool::reportLeg(const std::vector<const xAOD::Jet*>& jets,
// Add the Leg DecisionID.
// Required by any downstream Steps which need to consume jets which
// are satisfying this leg's jet cuts
// are satisfying this leg's jet cuts and by the following ComboHypo
// Note that if the chain is single-leg, then the ID will be the chain-ID
// rathe than a leg-specific ID
passingIDs.insert(getID(legInd).numeric());
// Also add the Chain DecisionID.
// If this is a single-leg chain, then getID(legInd) == m_decisionID
// DecisionIDContainer is a set, so will avoid any duplication
// We always include the Chain DecisionID such that this leg may
// pass the event at this point, if there are no further Steps.
passingIDs.insert(m_decisionID.numeric());
// Copy these passingIDs into the Decision Object
// This call also performs de-duplication
TrigCompositeUtils::insertDecisionIDs(passingIDs, pair.second);
......@@ -278,8 +285,7 @@ TrigJetHypoTool::reportLeg(const std::vector<const xAOD::Jet*>& jets,
bool
TrigJetHypoTool::inputJetParticipates(const std::vector<const xAOD::Jet*>& jets,
const JetDecision& pair) const {
const JetDecision& pair) const {
return std::find(jets.begin(), jets.end(), pair.first) != jets.end();
}
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
#include "TrigStreamerHypoAlg.h"
......@@ -39,9 +39,10 @@ StatusCode TrigStreamerHypoAlg::execute( const EventContext& context ) const {
// Create output Decision object, link it to prevDecision.
Decision* newDecision = newDecisionIn(newDecisions, previousDecision, hypoAlgNodeName(), context);
// Obligatory link to feature. Use a dummy link here (a link to self)
ElementLink<DecisionContainer> dummyLink(*newDecisions, newDecisions->size()-1, context);
newDecision->setObjectLink(featureString(), dummyLink);
// Obligatory link to feature. Re-using the initial ROI.
// If this happens to be a FullScan ROI, then the following ComboHypo will also pass this leg through without cuts
LinkInfo<TrigRoiDescriptorCollection> featureLinkInfo = findLink<TrigRoiDescriptorCollection>(previousDecision, initialRoIString());
newDecision->setObjectLink(featureString(), featureLinkInfo.link);
hypoInfo.emplace_back(newDecision, previousDecision);
}
......
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
// ********************************************************************
......@@ -24,7 +24,7 @@ TrigStreamerHypoTool::~TrigStreamerHypoTool() {}
StatusCode TrigStreamerHypoTool::initialize() {
ATH_MSG_DEBUG("Initializing TrigStreamerHypoTool");
ATH_MSG_DEBUG("Initializing TrigStreamerHypoTool for " << name());
return StatusCode::SUCCESS;
}
......
/*
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
#ifndef DECISIONHANDLING_COMBOHYPO_H
#define DECISIONHANDLING_COMBOHYPO_H
......@@ -34,21 +34,19 @@ class ComboHypo : public ::AthReentrantAlgorithm {
virtual StatusCode initialize() override;
virtual StatusCode execute(const EventContext& context) const override;
virtual StatusCode finalize() override;
protected:
const SG::ReadHandleKeyArray<TrigCompositeUtils::DecisionContainer>& decisionsInput() const { return m_inputs; }
const SG::WriteHandleKeyArray<TrigCompositeUtils::DecisionContainer>& decisionsOutput() const { return m_outputs; }
const Combo::MultiplicityReqMap& triggerMultiplicityMap() const { return m_multiplicitiesReqMap.value(); }
const Combo::LegMap& triggerLegMap() const { return m_legMap.value(); }
ToolHandleArray<ComboHypoToolBase>& hypoTools() { return m_hypoTools; }
const ToolHandleArray<ComboHypoToolBase>& hypoTools() const { return m_hypoTools; }
private:
SG::ReadHandleKeyArray<TrigCompositeUtils::DecisionContainer> m_inputs { this, "HypoInputDecisions", {}, "Input Decisions" };
SG::WriteHandleKeyArray<TrigCompositeUtils::DecisionContainer> m_outputs { this, "HypoOutputDecisions", {}, "Ouput Decisions" };
SG::WriteHandleKeyArray<TrigCompositeUtils::DecisionContainer> m_outputs { this, "HypoOutputDecisions", {}, "Output Decisions" };
Gaudi::Property<bool> m_requireUniqueROI {this, "RequireUniqueROI", false,
"Require each Feature in each leg of the combination to come from a unique L1 seeding ROI."};
......@@ -56,8 +54,8 @@ class ComboHypo : public ::AthReentrantAlgorithm {
Gaudi::Property< Combo::MultiplicityReqMap > m_multiplicitiesReqMap{this, "MultiplicitiesMap", {},
"Map from the chain name to multiplicities required at each input"};
Gaudi::Property< Combo::LegMap > m_legMap{this, "LegMap", {},
"Map from the chain name to legs required at each input"};
Gaudi::Property< Combo::LegMap > m_legToInputCollectionMap{this, "LegToInputCollectionMap", {},
"Map from the chain name to the per-leg index in this algorithm's ReadHandleKeyArray which should be used as the source of incoming Decision Objects on the leg."};
Gaudi::Property<bool> m_checkMultiplicityMap { this, "CheckMultiplicityMap", true,
"Perform a consistency check of the MultiplicitiesMap"};
......@@ -78,12 +76,18 @@ class ComboHypo : public ::AthReentrantAlgorithm {
* @param[out] featureIndex Index inside the featureKey collection.
* @param[out] roiKey Type-less SG Key hash of the collection hosting the Decision node's initial ROI collection.
* @param[out] roiIndex Index inside the roiKey collection.
* @param[out] roiFullscan Flag indicating if the located initial ROI has the FullScan flag enabled.
* @param[out] roiIsFullscan Flag indicating if the located initial ROI has the FullScan flag enabled.
* Triggers special behaviour allowing the ROI to satisfy arbitrary multiplicities in an arbitrary number of legs.
* @param[out] objectRequestsNoMultiplicityCheck Flag indicating of the DecisionObject requested not be included in the multiplicity computation.
* Triggers special behaviour allowing the DecisionObject to satisfy arbitrary multiplicities in an arbitrary number of legs.
* @param[inout] priorFeaturesMap Data structure collating for a given feature (key) what the prior features were integrated over all previous steps (value set).
**/
StatusCode extractFeatureAndRoI(const ElementLink<TrigCompositeUtils::DecisionContainer>& EL,
uint32_t& featureKey, uint16_t& featureIndex, uint32_t& roiKey, uint16_t& roiIndex, bool& roiFullscan, std::map<uint32_t, std::set<uint32_t>>& priorFeaturesMap) const;
uint32_t& featureKey, uint16_t& featureIndex,
uint32_t& roiKey, uint16_t& roiIndex,
bool& roiIsFullscan,
bool& objectRequestsNoMultiplicityCheck,
std::map<uint32_t, std::set<uint32_t>>& priorFeaturesMap) const;
/**
......
# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
from AthenaCommon.AlgScheduler import AlgScheduler
from AthenaCommon.CFElements import parOR
......@@ -330,18 +330,8 @@ def generateChainsManually():
makeChainStep("Step1_2muAs_empty", multiplicity=[]),
makeChainStep("Step2_2muAs", [mu21, mu21], multiplicity=[1,1]) ])
]
from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import dictFromChainName
from TriggerMenuMT.HLTMenuConfig.Menu.ChainDictTools import splitChainDictInLegs
# test change of multiplicity
chainName = 'HLT_TestChain5_ev1_TestChain8_ev1_merge_L12EM3'
cd = dictFromChainName(chainName )
cdicts = splitChainDictInLegs(cd)
CombChains += [ makeChain(name = chainName, L1Thresholds = ["EM3", "EM3"], ChainSteps=[
makeChainStep("Step1_em1merged", [el11], multiplicity = [1], chainDicts = [cdicts[0]] ),
makeChainStep("Step2_em1merged", [el21, el22], multiplicity = [1,1], chainDicts = cdicts)
])
]
# Note: There used to be a test here of change of multiplicity signature, e.g. from multiplicity = [1]
# in Step1 to multiplicity = [1,1] in Step2. This is no longer supported.
HLTChains += CombChains
......
......@@ -138,9 +138,6 @@ TrigSignatureMoni INFO -- #20247
TrigSignatureMoni INFO HLT_TestChain5_ev1_TestChain8_ev1_L12EM3 #2709794009
TrigSignatureMoni INFO -- #2709794009 Events 1 1 1 1 - - 1
TrigSignatureMoni INFO -- #2709794009 Features 4 4 - -
TrigSignatureMoni INFO HLT_TestChain5_ev1_TestChain8_ev1_merge_L12EM3 #3022516030
TrigSignatureMoni INFO -- #3022516030 Events 1 1 0 0 - - 0
TrigSignatureMoni INFO -- #3022516030 Features 2 0 - -
TrigSignatureMoni INFO HLT_TestChain5_ev2_L1EM7 #1760405581
TrigSignatureMoni INFO -- #1760405581 Events 0 0 0 0 - - 0
TrigSignatureMoni INFO -- #1760405581 Features 0 0 - -
......
......@@ -48,23 +48,9 @@ StatusCode ComboHypo::initialize() {
if (msgLvl(MSG::INFO)){
ATH_MSG_INFO( "with this multiplicity map: ");
for ( const auto& m : m_multiplicitiesReqMap ) {
std::stringstream msgSS;
msgSS << "[";
for (const int mult : m.second){
msgSS << mult << ", ";
}
msgSS.seekp(-2,msgSS.cur); // remove comma
msgSS << "]";
std::stringstream msgSSleg;
msgSSleg << "[";
for (const int nleg : m_legMap[m.first]){
msgSSleg << nleg << ", ";
}
msgSSleg.seekp(-2,msgSSleg.cur); // remove comma
msgSSleg << "]";
ATH_MSG_INFO("-- " << m.first << " multiplicities: " << msgSS.str() <<" , legs: " << msgSSleg.str());
ATH_MSG_INFO("-- " << m.first
<< " multiplicities: " << m.second
<<", input-collection-indicies: " << m_legToInputCollectionMap[m.first]);
}
}
......@@ -72,11 +58,22 @@ StatusCode ComboHypo::initialize() {
bool errorOccured = false;
if (m_checkMultiplicityMap) {
for ( const auto& m : m_multiplicitiesReqMap ) {
if ( m.second.size() > maxMult ) {
for ( const auto& [key, value] : m_multiplicitiesReqMap ) {
// Check the size of the multiplicities-required-per-leg vector is the same as the input-collection-index-per-leg vector
Combo::LegMap::const_iterator it_input = m_legToInputCollectionMap.find(key);
if (it_input == m_legToInputCollectionMap.end()) {
ATH_MSG_ERROR(key << " was not registered in the LegToInputCollectionMap");
errorOccured = true;