From 3ea508e27629ac846df4838c920b9b4c93adfad7 Mon Sep 17 00:00:00 2001 From: Tim Martin <tim.martin@cern.ch> Date: Thu, 19 Mar 2020 16:30:29 +0000 Subject: [PATCH] [ATR-21112] Input maker refactor - custom ROI Tools for EventViewCreator --- .../python/ComponentAccumulatorTest.py | 6 +- .../python/UnifyProperties.py | 1 - .../TrigEFMissingET/doc/METMenuSequences.md | 2 +- .../TrigT2CaloCommon/python/CaloDef.py | 5 +- .../DecisionHandling/InputMakerBase.h | 39 +-- .../DecisionHandling/InputMakerBase.icc | 40 +++ .../DecisionHandling/TrigCompositeUtils.icc | 194 ----------- .../DecisionHandling/src/InputMakerBase.cxx | 166 +++------- .../DecisionHandling/src/InputMakerForRoI.cxx | 71 ++-- .../DecisionHandling/src/InputMakerForRoI.h | 4 +- .../TrigCompositeUtils/CMakeLists.txt | 5 + .../TrigCompositeUtils/TrigCompositeUtils.h | 13 +- .../TrigCompositeUtils/TrigCompositeUtils.icc | 37 ++- .../ViewAlgs/ViewAlgs/IViewCreatorROITool.h | 39 +++ .../src/EventViewCreatorAlgorithm.cxx | 304 +++++++----------- .../ViewAlgs/src/EventViewCreatorAlgorithm.h | 75 +++-- .../src/EventViewCreatorAlgorithm.icc | 25 ++ .../src/EventViewCreatorAlgorithmWithJets.cxx | 131 ++++---- .../EventViewCreatorAlgorithmWithMuons.cxx | 213 ++++++------ .../src/ViewCreatorInitialROITool.cxx | 31 ++ .../ViewAlgs/src/ViewCreatorInitialROITool.h | 35 ++ .../src/ViewCreatorPreviousROITool.cxx | 33 ++ .../ViewAlgs/src/ViewCreatorPreviousROITool.h | 32 ++ .../src/components/ViewAlgs_entries.cxx | 7 +- .../share/q221_RDOtoRDOTrig_mt1_build.ref | 19 +- .../share/ref_RDOtoRDOTrig_mt1_build.ref | 19 +- .../TrigUpgradeTest/share/egammaRinger.py | 7 +- .../TrigUpgradeTest/share/full_menu_build.ref | 17 +- .../TrigUpgradeTest/share/photon.withViews.py | 11 +- .../TrigUpgradeTest/src/TestInputMaker.cxx | 100 +++--- .../share/ref_data_v1Dev_build.ref | 17 +- .../HLTMenuConfig/Bjet/BjetSequenceSetup.py | 6 +- .../Bphysics/BphysicsSequenceSetup.py | 7 +- .../BeamspotChainConfiguration.py | 7 +- .../StreamingChainConfiguration.py | 2 +- .../EventBuildingSequenceSetup.py | 2 +- .../Egamma/ElectronSequenceSetup.py | 5 +- .../Egamma/PhotonSequenceSetup.py | 6 +- .../Egamma/PrecisionCaloSequenceSetup.py | 3 +- .../Egamma/PrecisionElectronSequenceSetup.py | 7 +- .../python/HLTMenuConfig/Menu/CFValidation.py | 3 + .../python/HLTMenuConfig/Menu/LS2_v1.py | 14 +- .../HLTMenuConfig/Menu/MenuComponents.py | 7 +- .../HLTMenuConfig/Menu/Physics_pp_run3_v1.py | 5 +- .../MinBias/MinBiasChainConfiguration.py | 2 +- .../HLTMenuConfig/Muon/MuonSequenceSetup.py | 54 ++-- .../HLTMenuConfig/Tau/TauRecoSequences.py | 22 +- 47 files changed, 897 insertions(+), 953 deletions(-) create mode 100644 Trigger/TrigSteer/DecisionHandling/DecisionHandling/InputMakerBase.icc delete mode 100644 Trigger/TrigSteer/DecisionHandling/DecisionHandling/TrigCompositeUtils.icc create mode 100644 Trigger/TrigSteer/ViewAlgs/ViewAlgs/IViewCreatorROITool.h create mode 100644 Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.icc create mode 100644 Trigger/TrigSteer/ViewAlgs/src/ViewCreatorInitialROITool.cxx create mode 100644 Trigger/TrigSteer/ViewAlgs/src/ViewCreatorInitialROITool.h create mode 100644 Trigger/TrigSteer/ViewAlgs/src/ViewCreatorPreviousROITool.cxx create mode 100644 Trigger/TrigSteer/ViewAlgs/src/ViewCreatorPreviousROITool.h diff --git a/Control/AthenaConfiguration/python/ComponentAccumulatorTest.py b/Control/AthenaConfiguration/python/ComponentAccumulatorTest.py index ebed27dc89e..37cd271c226 100644 --- a/Control/AthenaConfiguration/python/ComponentAccumulatorTest.py +++ b/Control/AthenaConfiguration/python/ComponentAccumulatorTest.py @@ -445,7 +445,7 @@ class TestMergeComponentsFromDifferentBranches( unittest.TestCase ): seq2 = seqAND("seq2") innerSeq2 = seqAND("innerSeq2") - firstAlg = MergeableAlgorithm("alg1", InputMakerInputDecisions=["input1"], InputMakerOutputDecisions=["output1"]) + firstAlg = MergeableAlgorithm("alg1", InputMakerInputDecisions=["input1"]) ca.addSequence(seq1) ca.addSequence(innerSeq1, parentName=seq1.name()) @@ -458,7 +458,7 @@ class TestMergeComponentsFromDifferentBranches( unittest.TestCase ): innerSeqCopy = seqAND("innerSeq2") level2SeqCopy = seqAND("level2Seq2") - secondAlg = MergeableAlgorithm("alg1", InputMakerInputDecisions=["input2"], InputMakerOutputDecisions=["output2"]) + secondAlg = MergeableAlgorithm("alg1", InputMakerInputDecisions=["input2"]) secondCa = ComponentAccumulator() secondCa.addSequence(innerSeqCopy) @@ -472,9 +472,7 @@ class TestMergeComponentsFromDifferentBranches( unittest.TestCase ): self.assertEqual(len(foundAlgs), 2) self.assertEqual(set(foundAlgs[0].InputMakerInputDecisions), {"input1", "input2"}) - self.assertEqual(set(foundAlgs[0].InputMakerOutputDecisions), {"output1", "output2"}) self.assertEqual(set(foundAlgs[1].InputMakerInputDecisions), {"input1", "input2"}) - self.assertEqual(set(foundAlgs[1].InputMakerOutputDecisions), {"output1", "output2"}) ca.printConfig() ca.wasMerged() diff --git a/Control/AthenaConfiguration/python/UnifyProperties.py b/Control/AthenaConfiguration/python/UnifyProperties.py index 10bc9541d32..97a96abbf0c 100644 --- a/Control/AthenaConfiguration/python/UnifyProperties.py +++ b/Control/AthenaConfiguration/python/UnifyProperties.py @@ -76,7 +76,6 @@ _propsToUnify={"GeoModelSvc.DetectorTools":unifySet, "dummyService.AList": unifySet, "dummyTool.BList" : unifySet, "*.InputMakerInputDecisions": unifySet, - "*.InputMakerOutputDecisions": unifySet, "AddressRemappingSvc.TypeKeyRenameMaps": unifySet, "AuditorSvc.Auditors": unifySet, "MetaDataSvc.MetaDataTools": unifySet, diff --git a/Trigger/TrigAlgorithms/TrigEFMissingET/doc/METMenuSequences.md b/Trigger/TrigAlgorithms/TrigEFMissingET/doc/METMenuSequences.md index 54dd7c3d373..8e4d09e5c77 100644 --- a/Trigger/TrigAlgorithms/TrigEFMissingET/doc/METMenuSequences.md +++ b/Trigger/TrigAlgorithms/TrigEFMissingET/doc/METMenuSequences.md @@ -24,7 +24,7 @@ from DecisionHandling.DecisionHandlingConf import InputMakerForRoI InputMakerAlg = InputMakerForRoI("MetCellInputMaker", RoIsLink="initialRoI") InputMakerAlg.RoIs='METCellRoI' InputMakerAlg.InputMakerInputDecisions=[mapThresholdToL1DecisionCollection("XE")] -InputMakerAlg.InputMakerOutputDecisions=["InputMaker_from_L1MET"] +InputMakerAlg.InputMakerOutputDecisions="InputMaker_from_L1MET" topSequence += InputMakerAlg from TriggerMenuMT.HLTMenuConfig.MET.METSequences import metCellRecoSequence diff --git a/Trigger/TrigAlgorithms/TrigT2CaloCommon/python/CaloDef.py b/Trigger/TrigAlgorithms/TrigT2CaloCommon/python/CaloDef.py index 9517d9cc50c..147e78c881b 100644 --- a/Trigger/TrigAlgorithms/TrigT2CaloCommon/python/CaloDef.py +++ b/Trigger/TrigAlgorithms/TrigT2CaloCommon/python/CaloDef.py @@ -1,6 +1,6 @@ from AthenaCommon.Constants import ERROR from AthenaCommon.CFElements import seqAND, parOR -from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm +from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool def setMinimalCaloSetup() : from AthenaCommon.AppMgr import ServiceMgr as svcMgr @@ -76,6 +76,7 @@ def fastCaloEVCreator(): fastCaloViewsMaker = EventViewCreatorAlgorithm( "IMfastCalo" ) fastCaloViewsMaker.ViewFallThrough = True fastCaloViewsMaker.RoIsLink = "initialRoI" + fastCaloViewsMaker.RoITool = ViewCreatorInitialROITool() fastCaloViewsMaker.InViewRoIs = InViewRoIs fastCaloViewsMaker.Views = "EMCaloViews" fastCaloViewsMaker.ViewNodeName = "fastCaloInViewSequence" @@ -87,7 +88,7 @@ def createFastCaloSequence(EMRoIDecisions, doRinger=False, ClustersName="HLT_L2C (fastCaloViewsMaker, InViewRoIs) = fastCaloEVCreator() # connect to RoIs fastCaloViewsMaker.InputMakerInputDecisions = [ EMRoIDecisions ] - fastCaloViewsMaker.InputMakerOutputDecisions = [ EMRoIDecisions + "IMOUTPUT"] + fastCaloViewsMaker.InputMakerOutputDecisions = EMRoIDecisions + "IMOUTPUT" (fastCaloInViewSequence, sequenceOut) = fastCaloRecoSequence(InViewRoIs, doRinger=doRinger, ClustersName=ClustersName, RingerKey=RingerKey) diff --git a/Trigger/TrigSteer/DecisionHandling/DecisionHandling/InputMakerBase.h b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/InputMakerBase.h index e56db192ed1..756d4de7603 100644 --- a/Trigger/TrigSteer/DecisionHandling/DecisionHandling/InputMakerBase.h +++ b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/InputMakerBase.h @@ -5,8 +5,7 @@ #ifndef DECISIONHANDLING_INPUTMAKERBASE_H #define DECISIONHANDLING_INPUTMAKERBASE_H 1 -#include "DecisionHandling/TrigCompositeUtils.h" -#include "AthenaBaseComps/AthAlgorithm.h" +#include "TrigCompositeUtils/TrigCompositeUtils.h" #include "AthenaBaseComps/AthReentrantAlgorithm.h" #include "StoreGate/ReadHandleKeyArray.h" @@ -30,41 +29,45 @@ This is a base class for HLT InputMakers to reduce boilerplate and enforce the c const SG::ReadHandleKeyArray<TrigCompositeUtils::DecisionContainer>& decisionInputs() const; /// methods for derived classes to access handles of the base class input and output decisions; other read/write handles may be implemented by derived classes - const SG::WriteHandleKeyArray<TrigCompositeUtils::DecisionContainer>& decisionOutputs() const; + const SG::WriteHandleKey<TrigCompositeUtils::DecisionContainer>& decisionOutputs() const; // name of link to the RoI - StringProperty m_roisLink { this, "RoIsLink", "initialRoI", "Name of EL to RoI object linked to the decision" }; + StringProperty m_roisLink {this, "RoIsLink", "initialRoI", + "Name of EL to RoI object linked to the decision, used in merging input Decision objects when mergeUsingFeature=False." }; + Gaudi::Property<bool> m_mergeUsingFeature {this, "mergeUsingFeature", false, + "True=the IParicle-derived feature from the previous step is used to determine identical inputs. False=the ROI located with the RoIsLink property is used to determine identical inputs" }; + // helper methods for derived classes to reduce boiler plate code // ///////////////////////////////////////////////////////////////////// /// provides debug printout of the output of the algorithm - void debugPrintOut(const EventContext& context, const std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> >& outputHandles) const; - - /// does the standard handling of input decisions: read from handles with all the checks, create corresponding output handles and link them, copies links and return outputHandles - StatusCode decisionInputToOutput(const EventContext& context, std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > & outputHandles) const; + void debugPrintOut(const EventContext& context, SG::WriteHandle<TrigCompositeUtils::DecisionContainer>& outputHandle) const; /// does the standard handling of input decisions: read from handles with all the checks, create merged output handles and link them, copies links and return outputHandles - StatusCode decisionInputToMergedOutput(const EventContext& context, std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > & outputHandles) const; + StatusCode decisionInputToOutput(const EventContext& context, SG::WriteHandle<TrigCompositeUtils::DecisionContainer>& outputHandle) const; - /// counts valid input decisions - size_t countInputHandles( const EventContext& context ) const; + /// Checks for merge-able Decision objects coming from N upstream filters. Check based on stored element link in typed CONTAINER with 'linkNameToMatch' + template<typename CONTAINER> + size_t matchDecision(const TrigCompositeUtils::DecisionContainer* outDecisions, + const TrigCompositeUtils::Decision* toMatch, + const std::string& linkNameToMatch) const; - // setting strategy for output creation: merged means one decision per ROI - Gaudi::Property<bool> m_mergeOutputs { this, "mergeOutputs", true, "true=outputs are merged, false=one output per input" }; + /// Wrapper around matchDecision. Returns boolean if the match was successful. + bool matchInCollection(const TrigCompositeUtils::DecisionContainer* toMatchAgainst, + const TrigCompositeUtils::Decision* toMatch, + size_t& matchIndex) const; - private: - /// input decisions, will be implicit (renounced). + /// input decisions array, will be implicit (renounced). SG::ReadHandleKeyArray<TrigCompositeUtils::DecisionContainer> m_inputs { this, "InputMakerInputDecisions", {}, "Input Decisions (implicit)" }; /// output decisions - SG::WriteHandleKeyArray<TrigCompositeUtils::DecisionContainer> m_outputs { this, "InputMakerOutputDecisions", {}, "Ouput Decisions" }; - - + SG::WriteHandleKey<TrigCompositeUtils::DecisionContainer> m_outputs { this, "InputMakerOutputDecisions", "", "Output Decisions" }; }; +#include "InputMakerBase.icc" #endif // DECISIONHANDLING_INPUTMAKERBASE_H diff --git a/Trigger/TrigSteer/DecisionHandling/DecisionHandling/InputMakerBase.icc b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/InputMakerBase.icc new file mode 100644 index 00000000000..496914524d5 --- /dev/null +++ b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/InputMakerBase.icc @@ -0,0 +1,40 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +template<typename CONTAINER> +size_t InputMakerBase::matchDecision(const TrigCompositeUtils::DecisionContainer* outDecisions, + const TrigCompositeUtils::Decision* toMatch, + const std::string& linkNameToMatch) const +{ + const std::vector<TrigCompositeUtils::LinkInfo<CONTAINER>> myObject = TrigCompositeUtils::findLinks<CONTAINER>(toMatch, linkNameToMatch, TrigDefs::lastFeatureOfType); + + if (myObject.size() != 1) { + ATH_MSG_ERROR("InputMakerBase::matchDecision Did not locate exactly one object of type '" << ClassID_traits<CONTAINER>::typeName() << "' having searched for a link named '" << linkNameToMatch + << "', found " << myObject.size() << ". Unable to match this Decision object."); + for (const auto& li : myObject) { + ATH_MSG_ERROR(" -- " << li.link.dataID() << ":" << li.link.index() << ". Dump:" << *(li.source)); + } + return std::numeric_limits<std::size_t>::max(); + } + + // Look for match + for (size_t index = 0; index < outDecisions->size(); ++index) { + const TrigCompositeUtils::Decision* checkDecision = outDecisions->at(index); + if (checkDecision == nullptr) { + ATH_MSG_ERROR("Failed to get Decision object " << index << " of " << outDecisions->size()); + return std::numeric_limits<std::size_t>::max(); + } + const std::vector<TrigCompositeUtils::LinkInfo<CONTAINER>> checkObject = TrigCompositeUtils::findLinks<CONTAINER>(checkDecision, linkNameToMatch, TrigDefs::lastFeatureOfType); + if (checkObject.size() != 1) { + ATH_MSG_ERROR("Logic error. Expect myObject().size() == 1 and checkObject.size() == 1." + << " But have checkObject.size() = " << checkObject.size() << ". Unable to match this Decision object."); + return std::numeric_limits<std::size_t>::max(); + } + if (myObject.at(0).link == checkObject.at(0).link) { + return index; + } + } + + return std::numeric_limits<std::size_t>::max(); +} diff --git a/Trigger/TrigSteer/DecisionHandling/DecisionHandling/TrigCompositeUtils.icc b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/TrigCompositeUtils.icc deleted file mode 100644 index 0bb2f6f8c6e..00000000000 --- a/Trigger/TrigSteer/DecisionHandling/DecisionHandling/TrigCompositeUtils.icc +++ /dev/null @@ -1,194 +0,0 @@ -/* - Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration -*/ - -#include "AthenaKernel/getMessageSvc.h" - -namespace TrigCompositeUtils { - - /** - * @brief Creates and right away records the Container CONT with the key. - * No Aux store. - * Returns the WriteHandle. - * If possible provide the context that comes via an argument to execute otherwise it will default to looking it up which is slower. - **/ - template<class CONT> - SG::WriteHandle<CONT> createAndStoreNoAux( const SG::WriteHandleKey<CONT>& key, const EventContext& ctx ) { - SG::WriteHandle<CONT> handle( key, ctx ); - auto data = std::make_unique<CONT>() ; - if (handle.record( std::move( data ) ).isFailure()) { - throw std::runtime_error( "ERROR in TrigCompositeUtils::createAndStoreNoAux Unable to record " + key.key()); - } - return handle; - } - - /** - * @brief Creates and right away records the Container CONT with the key. - * With Aux store. - * Returns the WriteHandle. - * If possible provide the context that comes via an argument to execute otherwise it will default to looking it up which is slower. - **/ - template<class CONT, class AUX> - SG::WriteHandle<CONT> createAndStoreWithAux( const SG::WriteHandleKey<CONT>& key, const EventContext& ctx ) { - SG::WriteHandle<CONT> handle( key, ctx ); - auto data = std::make_unique<CONT>() ; - auto aux = std::make_unique<AUX>() ; - data->setStore( aux.get() ); - if (handle.record( std::move( data ), std::move( aux ) ).isFailure()) { - throw std::runtime_error( "ERROR in TrigCompositeUtils::createAndStoreWithAux Unable to record " + key.key()); - } - return handle; - } - - template<typename T> - void - findLinks(const xAOD::TrigComposite* start, const std::string& linkName, std::vector<LinkInfo<T>>& links) { - ElementLinkVector<T> featureLinks; - if (start->hasObjectCollectionLinks(linkName, ClassID_traits<T>::ID())) { - featureLinks = start->objectCollectionLinks<T>(linkName); - } - if (start->hasObjectLink(linkName, ClassID_traits<T>::ID())) { - featureLinks.push_back(start->objectLink<T>(linkName)); - } - for (const ElementLink<T>& featureLink : featureLinks) { - // Check for duplicates - if (std::none_of(links.begin(), links.end(), [&](const auto& li) { return (li.link == featureLink); } )) - { - links.emplace_back(start, featureLink); - } - } - // Recursive - for (const auto& seed : getLinkToPrevious(start)) { - findLinks<T>(*seed, linkName, links); - } - } - - template<typename T> - std::vector<LinkInfo<T>> - findLinks(const xAOD::TrigComposite* start, const std::string& linkName) { - std::vector<LinkInfo<T>> links; - findLinks(start, linkName, links); - return links; - } - - template<typename T> - LinkInfo<T> - findLink(const xAOD::TrigComposite* start, const std::string& linkName, const bool suppressMultipleLinksWarning) { - std::vector<LinkInfo<T>> links = findLinks<T>(start, linkName); - if (links.size() > 1 && !suppressMultipleLinksWarning) { - MsgStream(Athena::getMessageSvc(), "TrigCompositeUtils::findLink") << MSG::WARNING - << links.size() << " links found for " << linkName - << " returning the first link, consider using findLinks." << endmsg; - } - if (links.size() > 0) { - return links.at(0); - } - return LinkInfo<T>(); // invalid link - } - - template<class CONTAINER> - void filterLinkVectorByContainerKey(const std::string& containerSGKey, ElementLinkVector<CONTAINER>& vector) { - if (containerSGKey == "") { - return; - } - auto it = std::remove_if(vector.begin(), vector.end(), [&](const ElementLink<CONTAINER>& el) { - return (el.dataID().find(containerSGKey) == std::string::npos); - }); - // Collection has been re-ordered to put the bad elements at the end - vector.erase(it, vector.end()); - } - - template<class CONTAINER> - const std::vector< LinkInfo<CONTAINER> > getFeaturesOfType( - const std::vector<ElementLinkVector<DecisionContainer>>& linkVector, - const std::string containerSGKey, - const bool lastFeatureOfType, - const std::string& navElementLinkKey, - const DecisionIDContainer chainIDs) { - - std::vector< LinkInfo<CONTAINER> > features; - // For each unique path through the navigation for a given chain - for (const ElementLinkVector<DecisionContainer>& decisionPath : linkVector) { - // For each step along this path, starting at the terminus and working back towards L1 - for (const ElementLink<DecisionContainer>& decisionObjLink : decisionPath) { - const Decision* decisionObj = (*decisionObjLink); - ElementLinkVector<CONTAINER> featureLinks; - - // Look up what named links are available in the Decision Object - std::vector<std::string> availableLinkNames; - if (navElementLinkKey == "") { - const std::vector<std::string> getSingleLinkNames = decisionObj->getObjectNames<CONTAINER>(); - const std::vector<std::string> getCollectionLinkNames = decisionObj->getObjectCollectionNames<CONTAINER>(); - std::copy(getSingleLinkNames.begin(), getSingleLinkNames.end(), std::back_inserter(availableLinkNames)); - std::copy(getCollectionLinkNames.begin(), getCollectionLinkNames.end(), std::back_inserter(availableLinkNames)); - } else { // Just looking for an explicitly named feature - availableLinkNames.push_back( navElementLinkKey ); - } - - // Fetch the named links that we're interested in - for (const std::string& featureNameToGet : availableLinkNames) { - // This try block protects against ExcCLIDMismatch throws from - // features which do not derive from IParticle, when an IParticle interface is requested. - try { - // Slices may have added link collections. These links may have been to objects in different containers. - if (decisionObj->hasObjectCollectionLinks(featureNameToGet, ClassID_traits< CONTAINER >::ID())) { - ElementLinkVector<CONTAINER> collectionLinks = decisionObj->objectCollectionLinks<CONTAINER>( featureNameToGet ); - filterLinkVectorByContainerKey<CONTAINER>(containerSGKey, collectionLinks); - std::copy(collectionLinks.begin(), collectionLinks.end(), std::back_inserter(featureLinks)); - } - } catch (SG::ExcCLIDMismatch&) { - // This is in place to catch the exception caused by non-IParticle features when an IParticle interface is requested. - // We're fine to catch this silently and cary on looking at the next Decision object in the graph - } - try { - // Slices may have added single links. Note: the framework-specified "feature" link is always a single link. - if (decisionObj->hasObjectLink(featureNameToGet, ClassID_traits< CONTAINER >::ID())) { - ElementLinkVector<CONTAINER> singleEntryVector; // Filtering function operates on a vector - singleEntryVector.push_back( decisionObj->objectLink<CONTAINER>( featureNameToGet ) ); - filterLinkVectorByContainerKey<CONTAINER>(containerSGKey, singleEntryVector); - std::copy(singleEntryVector.begin(), singleEntryVector.end(), std::back_inserter(featureLinks)); - } - } catch (SG::ExcCLIDMismatch&) { - // Silently. As above. - } - } - - // Check if the Decsision object is active for a specific set of Chains-of-interest (as supplied by the TDT) - ActiveState state = ActiveState::UNSET; - if (chainIDs.size() > 0) { - // If we were given a list of chains to consider then we start assuming none passed this decisionObj - state = ActiveState::INACTIVE; - for (DecisionID id : chainIDs) { - if (std::count(decisionObj->decisions().begin(), decisionObj->decisions().end(), id) == 1) { - state = ActiveState::ACTIVE; - break; - } - } - } - - // Copy the fetched links into the return vector - for (const ElementLink<CONTAINER>& featureLink : featureLinks) { - typename std::vector<LinkInfo<CONTAINER>>::iterator vecIt = std::find_if(features.begin(), features.end(), [&](const auto& li) { return li.link == featureLink; } ); - if (vecIt == features.end()) { - // Link did not already exist - add it to the output - features.emplace_back( decisionObj, featureLink, state ); - } else { - // Link already existed - if the link's state in the return vector is INACTIVE but is ACTIVE here, - // then we need to change it to ACTIVE as this denotes one-or-more of the requested chains were active for the object. - if (vecIt->state == ActiveState::INACTIVE) { - vecIt->state = ActiveState::ACTIVE; - } - } - } - - // Stop processing this path through the navigation if the lastFeatureOfType flag is set - if (featureLinks.size() && lastFeatureOfType) { - break; - } - - } // for (decisionLink : decisionPath) - } // for (decisionPath : linkVector) - return features; - } - -} diff --git a/Trigger/TrigSteer/DecisionHandling/src/InputMakerBase.cxx b/Trigger/TrigSteer/DecisionHandling/src/InputMakerBase.cxx index 249351a5aee..42dd49638ff 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/InputMakerBase.cxx +++ b/Trigger/TrigSteer/DecisionHandling/src/InputMakerBase.cxx @@ -18,13 +18,12 @@ const SG::ReadHandleKeyArray<TrigCompositeUtils::DecisionContainer>& InputMakerB return m_inputs; } -const SG::WriteHandleKeyArray<TrigCompositeUtils::DecisionContainer>& InputMakerBase::decisionOutputs() const{ +const SG::WriteHandleKey<TrigCompositeUtils::DecisionContainer>& InputMakerBase::decisionOutputs() const{ return m_outputs; } StatusCode InputMakerBase::sysInitialize() { CHECK( AthReentrantAlgorithm::sysInitialize() ); // initialise base class - ATH_MSG_DEBUG("mergeOutputs is "<<m_mergeOutputs); CHECK( m_inputs.initialize() ); renounceArray(m_inputs); // make inputs implicit, i.e. not required by scheduler ATH_MSG_DEBUG("Will consume implicit decisions:" ); @@ -32,120 +31,72 @@ StatusCode InputMakerBase::sysInitialize() { ATH_MSG_DEBUG( " "<<input.key() ); } CHECK( m_outputs.initialize() ); - ATH_MSG_DEBUG(" and produce decisions: "); - for (auto& output: m_outputs){ - ATH_MSG_DEBUG( " "<<output.key() ); - } - return StatusCode::SUCCESS; + ATH_MSG_DEBUG(" and produce decisions: " << m_outputs.key()); + return StatusCode::SUCCESS; } - -// For each input Decision in the input container, create an output Decision in the corresponding output container and link them. +// Create one output container and merge all inputs into this, using heuristics to identify equal Decision objects. // If the input is invalid or empty, the output is not created, resulting as invalid -StatusCode InputMakerBase::decisionInputToOutput(const EventContext& context, std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > & outputHandles) const{ - - if (!m_mergeOutputs) ATH_MSG_DEBUG("Creating one output per input"); - else ATH_MSG_DEBUG("Creating one merged output per RoI"); - - outputHandles = decisionOutputs().makeHandles(context); - //size_t tot_inputs = countInputHandles( context ); - size_t outputIndex = 0; - TrigCompositeUtils::DecisionContainer* outDecisions = nullptr; - if (m_mergeOutputs){ - TrigCompositeUtils::createAndStore(outputHandles[outputIndex]); // one only - outDecisions = outputHandles[outputIndex].ptr(); - } +StatusCode InputMakerBase::decisionInputToOutput(const EventContext& context, SG::WriteHandle<TrigCompositeUtils::DecisionContainer>& outputHandle) const{ - // If using m_mergeOutputs, then collate all RoIs that are stored in this input container - ElementLinkVector<TrigRoiDescriptorCollection> RoIsFromDecision; + ATH_MSG_DEBUG("Creating one merged output per Decision object"); + ATH_CHECK( outputHandle.isValid() ); + TrigCompositeUtils::DecisionContainer* outDecisions = outputHandle.ptr(); - for ( auto inputKey: decisionInputs() ) { auto inputHandle = SG::makeHandle( inputKey, context ); if( not inputHandle.isValid() ) { - ATH_MSG_DEBUG( "Got no decisions from input "<< inputKey.key() << " because handle not valid"); - outputIndex++; + ATH_MSG_DEBUG( "Got no decisions from input "<< inputKey.key() << " because implicit handle not valid"); continue; } - if( inputHandle->size() == 0){ // input filtered out - ATH_MSG_DEBUG( "Got no decisions from input "<< inputKey.key()<<": handle is valid but container is empty."); - outputIndex++; + if( inputHandle->size() == 0){ + ATH_MSG_DEBUG( "Got no decisions from input "<< inputKey.key()<<": implicit handle is valid but container is empty."); continue; } ATH_MSG_DEBUG( "Running on input "<< inputKey.key()<<" with " << inputHandle->size() << " elements" ); - // We have an input container with >= 1 Decision objects. Create an output container with the same index. - if (! m_mergeOutputs){ - TrigCompositeUtils::createAndStore(outputHandles[outputIndex]); - outDecisions = outputHandles[outputIndex].ptr(); - } + size_t input_counter = 0; + for (const TrigCompositeUtils::Decision* inputDecision : *inputHandle){ + ATH_MSG_DEBUG( " -- Input Decision " << input_counter <<": has " <<TrigCompositeUtils::getLinkToPrevious(inputDecision).size()<<" previous links"); - // loop over decisions retrieved from this input - size_t input_counter =0; + size_t alreadyAddedIndex = std::numeric_limits<std::size_t>::max(); + const bool alreadyAdded = matchInCollection(outDecisions, inputDecision, alreadyAddedIndex); - for (const TrigCompositeUtils::Decision* inputDecision : *inputHandle){ - ATH_MSG_DEBUG( " - Input Decision "<<input_counter <<": has " <<TrigCompositeUtils::getLinkToPrevious(inputDecision).size()<<" previous links"); TrigCompositeUtils::Decision* newDec = nullptr; - bool addDecision = false; - ElementLink<TrigRoiDescriptorCollection> roiEL = ElementLink<TrigRoiDescriptorCollection>(); - - if (m_mergeOutputs){ - // Get RoI from this input decision - const auto roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( inputDecision, m_roisLink.value()); - CHECK( roiELInfo.isValid() ); - roiEL = roiELInfo.link; - const auto roiIt = std::find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL); - addDecision = (roiIt == RoIsFromDecision.end()); - // addDecision is positive here if we have *not* before encountered this RoI within this input collection. - if (addDecision) { - RoIsFromDecision.push_back(roiEL); // To keep track of which we have used - ATH_MSG_DEBUG( " -- Found new RoI:" << **roiEL <<": creating new decision"); - } - else{ - ATH_MSG_DEBUG( " -- Found old RoI:" << **roiEL <<": merging to this one"); - } - } else { // Not merging, keep a 1-to-1 mapping of Decisions in Input & Output containers - addDecision=true; - } - - if ( addDecision ){ - // Create a new Decision in the Output container to mirror one in the Input container + if (alreadyAdded) { // Already added, at alreadyAddedIndex + newDec = outDecisions->at( alreadyAddedIndex ); + ATH_MSG_DEBUG( " -- Matched to existing, " << inputKey.key() << " index " << input_counter << " is merged into existing output index " << alreadyAddedIndex); + } else { // Not already added, make new newDec = TrigCompositeUtils::newDecisionIn( outDecisions ); - } else{ - // addDecision can only be false if m_mergeOutputs was true and roiEL was found within RoIsFromDecision - // Re-use a Decision already added to the Output container - const auto roiIt = std::find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL); - if (roiIt == RoIsFromDecision.end()) { - ATH_MSG_ERROR("Logic error in decisionInputToOutput. Cannot find existing RoI."); - return StatusCode::FAILURE; - } - const size_t roiCounter = std::distance( RoIsFromDecision.begin(), roiIt ); - newDec = outDecisions->at(roiCounter); - ATH_MSG_DEBUG("Merging with output decision n. "<< roiCounter); + ATH_MSG_DEBUG( " -- Did not match to existing, " << inputKey.key() << " index " << input_counter << " creates output index " << outDecisions->size()-1); } - // if merged output, there are more than one seed: is it ok? + // Note: We will call linkToPrevious and insertDecisionIDs N times on a single "newDec", where N is the number of inputDecision which checkExisting determines are the same object. TrigCompositeUtils::linkToPrevious( newDec, inputDecision, context ); // Link inputDecision object as the 'seed' of newDec TrigCompositeUtils::insertDecisionIDs( inputDecision, newDec ); // Copy decision IDs from inputDecision into newDec - TrigCompositeUtils::DecisionIDContainer objDecisions; - TrigCompositeUtils::decisionIDs( newDec, objDecisions ); - ATH_MSG_DEBUG(" -- This output decision has now "<< (TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( newDec, m_roisLink.value())).isValid() <<" valid "<<m_roisLink.value() <<", "<< TrigCompositeUtils::getLinkToPrevious(newDec).size() <<" seeds and "<<objDecisions.size()<<" decisionIds"); + ATH_MSG_DEBUG(" -- This output decision now has " << TrigCompositeUtils::getLinkToPrevious(newDec).size() << " seeds and "<< newDec->decisions().size() << " decisionIds"); input_counter++; } // loop over input decisions - if (! m_mergeOutputs) - ATH_MSG_DEBUG( "Filled output key " << decisionOutputs()[ outputIndex ].key() <<" of size "<<outDecisions->size() <<" at index "<< outputIndex); - outputIndex++; - } // end of first loop over input keys + } // end of: for ( auto inputKey: decisionInputs() ) return StatusCode::SUCCESS; } +bool InputMakerBase::matchInCollection(const DecisionContainer* toMatchAgainst, const Decision* toMatch, size_t& matchIndex) const { + if ( m_mergeUsingFeature ) { + matchIndex = matchDecision<xAOD::IParticleContainer>(toMatchAgainst, toMatch, featureString()); + } else { + matchIndex = matchDecision<TrigRoiDescriptorCollection>(toMatchAgainst, toMatch, m_roisLink.value()); + } + return (matchIndex != std::numeric_limits<std::size_t>::max()); +} + -void InputMakerBase::debugPrintOut(const EventContext& context, const std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> >& outputHandles) const{ +void InputMakerBase::debugPrintOut(const EventContext& context, SG::WriteHandle<TrigCompositeUtils::DecisionContainer>& outputHandle) const{ size_t validInput=0; for ( auto inputKey: decisionInputs() ) { auto inputHandle = SG::makeHandle( inputKey, context ); @@ -158,47 +109,16 @@ void InputMakerBase::debugPrintOut(const EventContext& context, const std::vecto } } } - ATH_MSG_DEBUG( "number of implicit ReadHandles for input decisions is " << decisionInputs().size() << ", " << validInput << " are valid/notempty" ); + ATH_MSG_DEBUG( "Number of implicit ReadHandles for input decisions is " << decisionInputs().size() << ", " << validInput << " are valid/not-empty" ); - size_t validOutput=0; - for ( auto outHandle: outputHandles ) { - if( not outHandle.isValid() ) continue; - validOutput++; - } - ATH_MSG_DEBUG("Produced " << validOutput << " valid/notempty output decisions containers"); - if (! m_mergeOutputs){ - if(validInput != validOutput) { - ATH_MSG_ERROR("Found valid/notempty: " << validInput << " inputs and " << validOutput << " outputs"); - } - } - - for ( auto outHandle: outputHandles ) { - if( not outHandle.isValid() ) continue; - ATH_MSG_DEBUG(outHandle.key() <<" with "<< outHandle->size() <<" decisions:"); - for (auto outdecision: *outHandle){ - TrigCompositeUtils::DecisionIDContainer objDecisions; - TrigCompositeUtils::decisionIDs( outdecision, objDecisions ); - ATH_MSG_DEBUG("Number of positive decisions for this output: " << objDecisions.size() ); - for ( TrigCompositeUtils::DecisionID id : objDecisions ) { - ATH_MSG_DEBUG( " --- decision " << HLT::Identifier( id ) ); - } - } + ATH_MSG_DEBUG("Output " << outputHandle.key() <<" with "<< outputHandle->size() <<" decisions:"); + for (const auto outdecision : *outputHandle){ + TrigCompositeUtils::DecisionIDContainer objDecisions; + TrigCompositeUtils::decisionIDs( outdecision, objDecisions ); + ATH_MSG_DEBUG("Number of positive decisions for this output: " << objDecisions.size() ); + for ( TrigCompositeUtils::DecisionID id : objDecisions ) { + ATH_MSG_DEBUG( " --- decision " << HLT::Identifier( id ) ); + } } } - - -size_t InputMakerBase::countInputHandles( const EventContext& context ) const { - size_t validInputCount=0; - for ( auto &inputKey: decisionInputs() ) { - auto inputHandle = SG::makeHandle( inputKey, context ); - ATH_MSG_DEBUG(" "<<inputKey.key()<<(inputHandle.isValid()? " is valid": " is not valid" ) ); - if (inputHandle.isValid()) validInputCount++; - } - ATH_MSG_DEBUG( "number of implicit ReadHandles is " << decisionInputs().size() <<", "<< validInputCount<<" are valid" ); - return validInputCount; -} - - - - diff --git a/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.cxx b/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.cxx index 1907b463a2e..eb4be8cb27c 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.cxx +++ b/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.cxx @@ -13,6 +13,7 @@ using TrigCompositeUtils::Decision; using TrigCompositeUtils::linkToPrevious; using TrigCompositeUtils::getLinkToPrevious; using TrigCompositeUtils::findLink; +using TrigCompositeUtils::createAndStore; InputMakerForRoI:: InputMakerForRoI( const std::string& name, ISvcLocator* pSvcLocator ) @@ -28,9 +29,10 @@ StatusCode InputMakerForRoI::initialize() { StatusCode InputMakerForRoI::execute( const EventContext& context ) const { ATH_MSG_DEBUG( "Executing " << name() << "..." ); - // call base class helper method to read input decisions, loop over them create outputs and connect them, returns with outputHandles filled - std::vector< SG::WriteHandle<DecisionContainer> > outputHandles; - ATH_CHECK (decisionInputToOutput(context, outputHandles)); + // create the output decisions from the input collections + SG::WriteHandle<DecisionContainer> outputHandle = createAndStore( decisionOutputs(), context ); + ATH_CHECK(decisionInputToOutput(context, outputHandle)); + ATH_CHECK(outputHandle.isValid()); // Prepare Outputs std::unique_ptr< TrigRoiDescriptorCollection > oneRoIColl( new TrigRoiDescriptorCollection() ); @@ -38,39 +40,34 @@ StatusCode InputMakerForRoI::execute( const EventContext& context ) const { // use also this: ElementLinkVector<xAOD::MuonRoIContainer> getMuonRoILinks = obj->objectCollectionLinks<xAOD::MuonRoIContainer>("ManyMuonRoIs"); std::vector <ElementLink<TrigRoiDescriptorCollection> > RoIsFromDecision; // used to check for duplicate features linked to different inputHandles - // loop over output decisions, navigate to inputs - for (auto outputHandle: outputHandles) { - if( not outputHandle.isValid() ) { - ATH_MSG_DEBUG( "Got no decisions from output "<< outputHandle.key() << " because handle not valid"); - continue; - } - if( outputHandle->size() == 0){ // input filtered out - ATH_MSG_DEBUG( "Got no decisions from output "<< outputHandle.key()<<": handle is valid but container is empty."); - continue; - } - ATH_MSG_DEBUG( "Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); - // loop over output decisions in container of outputHandle, follow link to inputDecision - for ( auto outputDecision : *outputHandle){ - ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); - for (auto input: inputLinks){ - const Decision* inputDecision = *input; - auto roiELInfo = findLink<TrigRoiDescriptorCollection>( inputDecision, m_roisLink.value() ); - auto roiEL = roiELInfo.link; - ATH_CHECK( roiEL.isValid() ); + if( outputHandle->size() == 0) { + ATH_MSG_WARNING( "Have no decisions in output handle "<< outputHandle.key() << ". Handle is valid but container is empty. " + << "Check why this EventViewCreatorAlgorithm was unlocked by a Filter, if the Filter then gave it no inputs."); + return StatusCode::SUCCESS; + } - // avoid adding the same feature multiple times: check if not in container, if not add it - if ( find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL) == RoIsFromDecision.end() ) { - RoIsFromDecision.push_back(roiEL); // just to keep track of which we have used - const TrigRoiDescriptor* roi = *roiEL; - ATH_MSG_DEBUG("Found RoI:" <<*roi<<" FS="<<roi->isFullscan()); - //make a new one: - TrigRoiDescriptor* newroi= new TrigRoiDescriptor(*roi); //use copy constructor - oneRoIColl->push_back(newroi); - ATH_MSG_DEBUG("Added RoI:" <<*newroi<<" FS="<<newroi->isFullscan()); - } - } // loop over previous input links - } // loop over decisions - } // loop over output keys + ATH_MSG_DEBUG( "Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); + // loop over output decisions in container of outputHandle, follow link to inputDecision + for ( auto outputDecision : *outputHandle){ + ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); + for (auto input: inputLinks){ + const Decision* inputDecision = *input; + auto roiELInfo = findLink<TrigRoiDescriptorCollection>( inputDecision, m_roisLink.value() ); + auto roiEL = roiELInfo.link; + ATH_CHECK( roiEL.isValid() ); + + // avoid adding the same feature multiple times: check if not in container, if not add it + if ( find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL) == RoIsFromDecision.end() ) { + RoIsFromDecision.push_back(roiEL); // just to keep track of which we have used + const TrigRoiDescriptor* roi = *roiEL; + ATH_MSG_DEBUG("Found RoI:" <<*roi<<" FS="<<roi->isFullscan()); + //make a new one: + TrigRoiDescriptor* newroi= new TrigRoiDescriptor(*roi); //use copy constructor + oneRoIColl->push_back(newroi); + ATH_MSG_DEBUG("Added RoI:" <<*newroi<<" FS="<<newroi->isFullscan()); + } + } // loop over previous input links + } // loop over decisions // Finally, record output @@ -79,7 +76,9 @@ StatusCode InputMakerForRoI::execute( const EventContext& context ) const { ATH_CHECK( roi_outputHandle.record(std::move(oneRoIColl)) ); // call base class helper method to print some debug messages summarising the content of the outputHandles. - if (msgLvl(MSG::DEBUG)) debugPrintOut(context, outputHandles); + if (msgLvl(MSG::DEBUG)) { + debugPrintOut(context, outputHandle); + } return StatusCode::SUCCESS; } diff --git a/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.h b/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.h index 3cea7e6f60f..e3de1291347 100644 --- a/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.h +++ b/Trigger/TrigSteer/DecisionHandling/src/InputMakerForRoI.h @@ -26,9 +26,7 @@ virtual StatusCode execute(const EventContext&) const override; private: - SG::WriteHandleKey<TrigRoiDescriptorCollection> m_RoIs {this,"RoIs", "Unspecified", "Nam eof the RoIs extracted from the decisions"}; - // want to try also const? - //SG::WriteHandleKey< ConstDataVector<TrigRoiDescriptorCollection> > m_RoIs{ this, "RoIs", "Unspecified", "Name of the RoIs extracted from the decisions" }; + SG::WriteHandleKey<TrigRoiDescriptorCollection> m_RoIs {this,"RoIs", "Unspecified", "Name of the RoIs extracted from the decisions"}; }; diff --git a/Trigger/TrigSteer/TrigCompositeUtils/CMakeLists.txt b/Trigger/TrigSteer/TrigCompositeUtils/CMakeLists.txt index e1fc6e80028..8b226cf74b3 100644 --- a/Trigger/TrigSteer/TrigCompositeUtils/CMakeLists.txt +++ b/Trigger/TrigSteer/TrigCompositeUtils/CMakeLists.txt @@ -3,6 +3,11 @@ # Declare the package name. atlas_subdir( TrigCompositeUtils ) +# Declare the package's dependencies: +atlas_depends_on_subdirs( PUBLIC + Trigger/TrigEvent/TrigDecisionInterface + ) + # Set up the (non-)standalone compilation. set( extra_srcs ) set( extra_libs ) diff --git a/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/TrigCompositeUtils.h b/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/TrigCompositeUtils.h index 335d7e29ed2..fa3fff465c6 100644 --- a/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/TrigCompositeUtils.h +++ b/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/TrigCompositeUtils.h @@ -22,6 +22,8 @@ #include "xAODTrigger/TrigCompositeContainer.h" #include "xAODTrigger/TrigCompositeAuxContainer.h" +#include "TrigDecisionInterface/Conditions.h" + #include "HLTIdentifier.h" namespace TrigCompositeUtils { @@ -294,19 +296,20 @@ namespace TrigCompositeUtils { : source{s}, link{l}, state{as} {} bool isValid() const { - return source && link.isValid(); } + return source && link.isValid(); + } /** * @brief helper conversion to make it usable with CHECK macro expecting StatusCode */ operator StatusCode () { - return (isValid() ? StatusCode::SUCCESS : StatusCode::FAILURE); } + return (isValid() ? StatusCode::SUCCESS : StatusCode::FAILURE); + } const xAOD::TrigComposite *source; ElementLink<T> link; ActiveState state; }; - /// @name Constant string literals used within the HLT /// @{ const std::string& initialRoIString(); @@ -362,7 +365,7 @@ namespace TrigCompositeUtils { */ template<typename T> void - findLinks(const xAOD::TrigComposite* start, const std::string& linkName, std::vector<LinkInfo<T>>& links); + findLinks(const xAOD::TrigComposite* start, const std::string& linkName, std::vector<LinkInfo<T>>& links, unsigned int behaviour = TrigDefs::allFeaturesOfType); /** * @brief search back the TC links for the object of type T linked to the one of TC (recursively) @@ -373,7 +376,7 @@ namespace TrigCompositeUtils { */ template<typename T> std::vector<LinkInfo<T>> - findLinks(const xAOD::TrigComposite* start, const std::string& linkName); + findLinks(const xAOD::TrigComposite* start, const std::string& linkName, unsigned int behaviour = TrigDefs::allFeaturesOfType); /** diff --git a/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/TrigCompositeUtils.icc b/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/TrigCompositeUtils.icc index f80bcc6ebb3..7233c3560bf 100644 --- a/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/TrigCompositeUtils.icc +++ b/Trigger/TrigSteer/TrigCompositeUtils/TrigCompositeUtils/TrigCompositeUtils.icc @@ -42,7 +42,7 @@ namespace TrigCompositeUtils { template<typename T> void - findLinks(const xAOD::TrigComposite* start, const std::string& linkName, std::vector<LinkInfo<T>>& links) { + findLinks(const xAOD::TrigComposite* start, const std::string& linkName, std::vector<LinkInfo<T>>& links, unsigned int behaviour) { ElementLinkVector<T> featureLinks; if (start->hasObjectCollectionLinks(linkName, ClassID_traits<T>::ID())) { featureLinks = start->objectCollectionLinks<T>(linkName); @@ -50,24 +50,49 @@ namespace TrigCompositeUtils { if (start->hasObjectLink(linkName, ClassID_traits<T>::ID())) { featureLinks.push_back(start->objectLink<T>(linkName)); } + const bool linkFound = (featureLinks.size() > 0); for (const ElementLink<T>& featureLink : featureLinks) { // Check for duplicates - if (std::none_of(links.begin(), links.end(), [&](const auto& li) { return (li.link == featureLink); } )) + if (std::none_of(links.begin(), links.end(), + [&](const auto& li) { + if (li.link == featureLink) { + if (li.source != start && linkName != initialRoIString() && linkName != roiString()) { + // Leaving this warning in for now, but there are known cases of the FS ROI being re-used + // in multiple outputs from the L1 decoder. E.g. HLTNav_L1J:0 and HLTNav_L1MET:0 + // so supressing for initialRoIString(). + // Similar case for tau, just with an ROI created in Step1 + const auto A = decisionToElementLink(start); + const auto B = decisionToElementLink(li.source); + MsgStream(Athena::getMessageSvc(), "TrigCompositeUtils::findLink") << MSG::WARNING + << "Found '" << linkName << "' by multiple paths, but " + << "the links are coming from different places in the navigation graph. " << std::endl + << "From A:" << A.dataID() << ":" << A.index() << " Dump:" << std::endl << *start << std::endl + << "From B:" << B.dataID() << ":" << B.index() << " Dump:" << std::endl << *(li.source) << endmsg; + } + return true; + } + return false; + } + )) { links.emplace_back(start, featureLink); } } - // Recursive + // Early exit + if (linkFound && behaviour == TrigDefs::lastFeatureOfType) { + return; + } + // If not Early Exit, then recurse for (const auto& seed : getLinkToPrevious(start)) { - findLinks<T>(*seed, linkName, links); + findLinks<T>(*seed, linkName, links, behaviour); } } template<typename T> std::vector<LinkInfo<T>> - findLinks(const xAOD::TrigComposite* start, const std::string& linkName) { + findLinks(const xAOD::TrigComposite* start, const std::string& linkName, unsigned int behaviour) { std::vector<LinkInfo<T>> links; - findLinks(start, linkName, links); + findLinks(start, linkName, links, behaviour); return links; } diff --git a/Trigger/TrigSteer/ViewAlgs/ViewAlgs/IViewCreatorROITool.h b/Trigger/TrigSteer/ViewAlgs/ViewAlgs/IViewCreatorROITool.h new file mode 100644 index 00000000000..a9df7caa588 --- /dev/null +++ b/Trigger/TrigSteer/ViewAlgs/ViewAlgs/IViewCreatorROITool.h @@ -0,0 +1,39 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef VIEWALGS_IVIEWCREATORROITOOL_H +#define VIEWALGS_IVIEWCREATORROITOOL_H + +#include "GaudiKernel/IAlgTool.h" +#include "GaudiKernel/StatusCode.h" +#include "GaudiKernel/Property.h" +#include "DecisionHandling/TrigCompositeUtils.h" + +/** + * @class IViewCreatorROITool + * MT Trigger Tool interface used to determine the correct ROI to spawn an EventView on for a given Decision object. + **/ +class IViewCreatorROITool : virtual public IAlgTool +{ +public: + + DeclareInterfaceID(IViewCreatorROITool, 1, 0); + + virtual ~IViewCreatorROITool() = default; + +/** + * @brief Supply ROIs for the Decision objects in the mutable decisions container. + * For each entry in decisions, the tool is expected to either locate an existing ROI in the history of the Decision object + * (e.g. the initialRoI). Or, to create a new ROIDescriptor (e.g. by getting the "feature" from the Decision object and + * constructing an ROI around it) and to store this new ROI in an output collection. In this later case, the concrete tool + * should register a SG::WriteHandle<TrigRoiDescriptorCollection> in which to store these new ROI. + * + * Either way, the new ROI should be linked to the Decision object for use in the parent EventViewCreatorAlgorithm via + * decision->setObjectLink(TrigCompositeUtils::roiString(), roiElementLink); + **/ + virtual StatusCode attachROILinks(TrigCompositeUtils::DecisionContainer& decisions, const EventContext& ctx) const = 0; + +}; + +#endif //> !VIEWALGS_IVIEWCREATORROITOOL_H diff --git a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.cxx b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.cxx index d40074bceb0..e4dd872746f 100644 --- a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.cxx +++ b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.cxx @@ -10,6 +10,8 @@ #include "AthViews/View.h" #include "DecisionHandling/TrigCompositeUtils.h" +#include <sstream> + using namespace TrigCompositeUtils; EventViewCreatorAlgorithm::EventViewCreatorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator ) @@ -21,213 +23,155 @@ StatusCode EventViewCreatorAlgorithm::initialize() { ATH_MSG_DEBUG("Will produce views=" << m_viewsKey << " roIs=" << m_inViewRoIs ); ATH_CHECK( m_viewsKey.initialize() ); ATH_CHECK( m_inViewRoIs.initialize() ); + ATH_CHECK( m_roiTool.retrieve() ); + ATH_CHECK( m_cachedViewsKey.initialize(SG::AllowEmpty) ); return StatusCode::SUCCESS; } StatusCode EventViewCreatorAlgorithm::execute( const EventContext& context ) const { - if (m_mergeOutputs) - return executeMerged(context); - - // create the output decisions, similar to inputs (copy basic links) - std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > outputHandles; - ATH_CHECK (decisionInputToOutput(context, outputHandles)); + // create the output decisions from the input collections + ATH_MSG_DEBUG("Starting to merge " << decisionInputs().size() << " inputs to the " << decisionOutputs().key() << " output."); + SG::WriteHandle<DecisionContainer> outputHandle = createAndStore( decisionOutputs(), context ); + ATH_CHECK(outputHandle.isValid()); + ATH_CHECK(decisionInputToOutput(context, outputHandle)); + ATH_MSG_DEBUG("Merging complete"); - // make the views - auto viewsHandle = SG::makeHandle( m_viewsKey, context ); - auto viewVector1 = std::make_unique< ViewContainer >(); - ATH_CHECK( viewsHandle.record( std::move( viewVector1 ) ) ); + auto viewsHandle = SG::makeHandle( m_viewsKey, context ); + ATH_CHECK( viewsHandle.record( std::make_unique<ViewContainer>() ) ); auto viewVector = viewsHandle.ptr(); - unsigned int viewCounter = 0; - - //map all RoIs that are stored - ElementLinkVector<TrigRoiDescriptorCollection> RoIsFromDecision; - - // loop over decisions - for (auto outputHandle: outputHandles) { - if( not outputHandle.isValid() ) { - ATH_MSG_DEBUG( "Got no decisions from output "<< outputHandle.key() << " because handle not valid"); - continue; - } - - if( outputHandle->size() == 0){ // input filtered out - ATH_MSG_DEBUG( "Got no decisions from output "<< outputHandle.key()<<": handle is valid but container is empty."); - continue; - } - ATH_MSG_DEBUG( "Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); - // loop over output decisions in container of outputHandle, follow link to inputDecision - for ( auto outputDecision : *outputHandle){ - ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); - ATH_MSG_DEBUG( "Got inputLinks with " << inputLinks.size() << " elements" ); - // loop over input links as predecessors - for (auto input: inputLinks){ - const Decision* inputDecision = *input; - // find the RoI - const auto roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( inputDecision, m_roisLink.value() ); - const auto roiEL = roiELInfo.link; - ATH_CHECK( roiEL.isValid() ); - // check if already found - auto roiIt=find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL); - if ( roiIt == RoIsFromDecision.end() ){ - RoIsFromDecision.push_back(roiEL); // just to keep track of which we have used - ATH_MSG_DEBUG("Found RoI:" <<**roiEL<<" FS="<<(*roiEL)->isFullscan()); - ATH_MSG_DEBUG("Positive decisions on RoI, making view" ); - // make the view - auto newView = ViewHelper::makeView( name()+"_view", viewCounter++, m_viewFallThrough ); //pointer to the view - - // Use a fall-through filter if one is provided - if ( m_viewFallFilter.size() ) { - newView->setFilter( m_viewFallFilter ); - } - - viewVector->push_back( newView ); - - // link decision to this view - outputDecision->setObjectLink( TrigCompositeUtils::viewString(), ElementLink< ViewContainer >(m_viewsKey.key(), viewVector->size()-1 ));//adding view to TC - ATH_MSG_DEBUG( "Adding new view to new decision; storing view in viewVector component " << viewVector->size()-1 ); - ATH_CHECK( linkViewToParent( inputDecision, viewVector->back() ) ); - ATH_CHECK( placeRoIInView( roiEL, viewVector->back(), context ) ); - } - else { - int iview = roiIt - RoIsFromDecision.begin(); - auto theview = viewVector->at(iview); - // check that this view is not already linked to this decision (this is true if the mergerd output is enabled) - const auto existView = TrigCompositeUtils::findLink<ViewContainer> (outputDecision, TrigCompositeUtils::viewString()); - const auto existViewLink= existView.link; - if (existViewLink.isValid() && existViewLink == ElementLink< ViewContainer >(m_viewsKey.key(), iview )){ - ATH_MSG_DEBUG( "View already linked, doing nothing"); - } else if (existViewLink.isValid()){ - ATH_MSG_ERROR( "View already linked, but it is the wrong view! Configuration problem. Got " << existViewLink.index() << ", expected " << iview); - return StatusCode::FAILURE; - } else { - outputDecision->setObjectLink( TrigCompositeUtils::viewString(), ElementLink< ViewContainer >(m_viewsKey.key(), iview ) ); //adding view to TC - ATH_MSG_DEBUG( "Adding already mapped view " << iview << " in ViewVector , to new decision"); - ATH_CHECK( linkViewToParent( inputDecision, theview ) ); - } - } - }// loop over previous inputs - } // loop over decisions - }// loop over output keys - - // launch view execution - ATH_MSG_DEBUG( "Launching execution in " << viewVector->size() << " views" ); - ATH_CHECK( ViewHelper::scheduleViews( viewVector, // Vector containing views - m_viewNodeName, // CF node to attach views to - context, // Source context - getScheduler(), - m_reverseViews ) ); - - // report number of views, stored already when container was created - // auto viewsHandle = SG::makeHandle( m_viewsKey ); - // ATH_CHECK( viewsHandle.record( std::move( viewVector ) ) ); - ATH_MSG_DEBUG( "Store "<< viewsHandle->size() <<" Views"); - if (msgLvl(MSG::DEBUG)) debugPrintOut(context, outputHandles); - return StatusCode::SUCCESS; -} + // Check for an optional input handle to use as a source of cached, already-executed, views. + const DecisionContainer* cachedViews = nullptr; + if (!m_cachedViewsKey.empty()) { + SG::ReadHandle<DecisionContainer> cachedRH = SG::makeHandle(m_cachedViewsKey, context); + ATH_CHECK(cachedRH.isValid()); + cachedViews = cachedRH.ptr(); + } + // Keep track of the ROIs we spwan a View for, do not spawn duplicates. + // For many cases, this will be covered by the Merging operation preceding this. + ElementLinkVector<TrigRoiDescriptorCollection> RoIsFromDecision; + if( outputHandle->size() == 0) { + ATH_MSG_WARNING( "Have no decisions in output handle "<< outputHandle.key() << ". Handle is valid but container is empty. " + << "Check why this EventViewCreatorAlgorithm was unlocked by a Filter, if the Filter then gave it no inputs."); + } else { + ATH_MSG_DEBUG( "Have output " << outputHandle.key() << " with " << outputHandle->size() << " elements" ); + } -StatusCode EventViewCreatorAlgorithm::executeMerged( const EventContext& context ) const { + // Find and link to the output Decision objects the ROIs to run over + ATH_CHECK( m_roiTool->attachROILinks(*outputHandle, context) ); - // create the output decisions, similar to inputs (copy basic links) - std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > outputHandles; - ATH_CHECK (decisionInputToOutput(context, outputHandles)); + for ( Decision* outputDecision : *outputHandle ) { - // make the views - auto viewsHandle = SG::makeHandle( m_viewsKey, context ); - auto viewVector1 = std::make_unique< ViewContainer >(); - ATH_CHECK( viewsHandle.record( std::move( viewVector1 ) ) ); - auto viewVector = viewsHandle.ptr(); - unsigned int viewCounter = 0; + if (!outputDecision->hasObjectLink(roiString(), ClassID_traits<TrigRoiDescriptorCollection>::ID())) { + ATH_MSG_ERROR("No '" << roiString() << "'link was attached by the ROITool. Decision object dump:" << *outputDecision); + return StatusCode::FAILURE; + } + const ElementLink<TrigRoiDescriptorCollection> roiEL = outputDecision->objectLink<TrigRoiDescriptorCollection>(roiString()); + ATH_CHECK(roiEL.isValid()); + + // We do one of three things here, either... + // a) We realise that an identically configured past EVCA has already run a View on an equivilant ROI. If so we can re-use this. + // b) We encounter a new ROI and hence need to spawn a new view. + // c) We encounter a ROI that we have already seen in looping over this outputHandle, we can re-use a view. + + // cachedIndex and useCached are to do with a) + size_t cachedIndex = std::numeric_limits<std::size_t>::max(); + const bool useCached = checkCache(cachedViews, outputDecision, cachedIndex); + + // roiIt is to do with b) and c) + auto roiIt = find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL); + + if (useCached) { + + // Re-use an aready processed view from a previously executed EVCA instance + const Decision* cached = cachedViews->at(cachedIndex); + ElementLink<ViewContainer> cachedViewEL = cached->objectLink<ViewContainer>(viewString()); + ElementLink<TrigRoiDescriptorCollection> cachedROIEL = cached->objectLink<TrigRoiDescriptorCollection>(roiString()); + ATH_CHECK(cachedViewEL.isValid()); + ATH_CHECK(cachedROIEL.isValid()); + ATH_MSG_DEBUG("Re-using cached existing view from " << cachedViewEL.dataID() << ", index:" << cachedViewEL.index() + << " on ROI " << **cachedROIEL); + outputDecision->setObjectLink( viewString(), cachedViewEL ); + outputDecision->setObjectLink( roiString(), cachedROIEL ); + // Note: This overwrites the link created in the above tool with what should be a spatially identical ROI (check?) + + } else if ( roiIt == RoIsFromDecision.end() ) { + + // We have not yet spawned an ROI on this View. Do it now. + RoIsFromDecision.push_back(roiEL); + ATH_MSG_DEBUG("Found RoI:" << **roiEL << " FS=" << (*roiEL)->isFullscan() << ". Making View."); + SG::View* newView = ViewHelper::makeView( name()+"_view", viewVector->size() /*view counter*/, m_viewFallThrough ); + viewVector->push_back( newView ); + // Use a fall-through filter if one is provided + if ( m_viewFallFilter.size() ) { + newView->setFilter( m_viewFallFilter ); + } + // Set parent view, if required. Note: Must be called before we link the new view to outputDecision. + ATH_CHECK(linkViewToParent(outputDecision, newView)); + // Add the single ROI into the view to seed it. + ATH_CHECK(placeRoIInView(roiEL, viewVector->back(), context)); + // Link the view to the Decision object + outputDecision->setObjectLink( viewString(), ElementLink<ViewContainer>(m_viewsKey.key(), viewVector->size()-1 )); + ATH_MSG_DEBUG( "Made new View, storing view in viewVector " << m_viewsKey.key() << " index:" << viewVector->size()-1 ); - //map all RoIs that are stored - ElementLinkVector<TrigRoiDescriptorCollection> RoIsFromDecision; + } else { - // loop over decisions - for (auto outputHandle: outputHandles) { - if( not outputHandle.isValid() ) { - ATH_MSG_DEBUG( "Got no decisions from output "<< outputHandle.key() << " because handle not valid"); - continue; - } + // We have already spawned a ROI in this View. Link it here too. + const size_t existingIndex = std::distance(RoIsFromDecision.begin(), roiIt); + ATH_MSG_DEBUG("Found existing View, stored in view in viewVector " << m_viewsKey.key() << " index:" << existingIndex ); + outputDecision->setObjectLink( viewString(), ElementLink<ViewContainer>(m_viewsKey.key(), existingIndex )); //adding View link to Decision - if( outputHandle->size() == 0){ // input filtered out - ATH_MSG_DEBUG( "Got no decisions from output "<< outputHandle.key()<<": handle is valid but container is empty."); - continue; } - ATH_MSG_DEBUG( "Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); - // loop over output decisions in container of outputHandle, follow link to inputDecision - for ( auto outputDecision : *outputHandle){ - const auto roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( outputDecision, m_roisLink.value() ); - const auto roiEL = roiELInfo.link; - ATH_CHECK( roiEL.isValid() ); - // check if already found - auto roiIt=find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL); - if ( roiIt == RoIsFromDecision.end() ){ - RoIsFromDecision.push_back(roiEL); // just to keep track of which we have used - ATH_MSG_DEBUG("Found RoI:" <<**roiEL<<" FS="<<(*roiEL)->isFullscan()); - ATH_MSG_DEBUG("Positive decisions on RoI, making view" ); - // make the view - auto newView = ViewHelper::makeView( name()+"_view", viewCounter++, m_viewFallThrough ); //pointer to the view - - // Use a fall-through filter if one is provided - if ( m_viewFallFilter.size() ) { - newView->setFilter( m_viewFallFilter ); - } - - viewVector->push_back( newView ); - - // link decision to this view - outputDecision->setObjectLink( TrigCompositeUtils::viewString(), ElementLink< ViewContainer >(m_viewsKey.key(), viewVector->size()-1 ));//adding view to TC - ATH_MSG_DEBUG( "Adding new view to new decision; storing view in viewVector component " << viewVector->size()-1 ); - ATH_CHECK( placeRoIInView( roiEL, viewVector->back(), context ) ); - ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); - ATH_MSG_DEBUG( "Got inputLinks with " << inputLinks.size() << " elements" ); - for (auto input: inputLinks){ - const Decision* inputDecision = *input; - ATH_CHECK( linkViewToParent( inputDecision, viewVector->back() ) ); - } - } - else { - ATH_MSG_DEBUG( "View already linked, doing nothing"); - } - } // loop over decisions - }// loop over output keys + } // loop over output decisions // launch view execution - ATH_MSG_DEBUG( "Launching execution in " << viewVector->size() << " views" ); - ATH_CHECK( ViewHelper::scheduleViews( viewVector, // Vector containing views - m_viewNodeName, // CF node to attach views to - context, // Source context - getScheduler(), - m_reverseViews ) ); + ATH_MSG_DEBUG( "Launching execution in " << viewVector->size() << " unique views" ); + ATH_CHECK( ViewHelper::scheduleViews( viewVector, // Vector containing views + m_viewNodeName, // CF node to attach views to + context, // Source context + getScheduler(), // Scheduler to launch with + m_reverseViews ) ); // Debug option - if (msgLvl(MSG::DEBUG)) debugPrintOut(context, outputHandles); + if (msgLvl(MSG::DEBUG)) { + debugPrintOut(context, outputHandle); + } return StatusCode::SUCCESS; } +bool EventViewCreatorAlgorithm::checkCache(const DecisionContainer* cachedViews, const Decision* outputDecision, size_t& cachedIndex) const { + if (cachedViews == nullptr) { + return false; // No cached input configured, which is fine. + } + return matchInCollection(cachedViews, outputDecision, cachedIndex); +} -StatusCode EventViewCreatorAlgorithm::linkViewToParent( const TrigCompositeUtils::Decision* inputDecision, SG::View* newView ) const { - if ( m_requireParentView ) { - // see if there is a view linked to the decision object, if so link it to the view that is just made - LinkInfo<ViewContainer> parentViewLinkInfo = findLink<ViewContainer>(inputDecision, viewString(), /*suppressMultipleLinksWarning*/ true ); - if ( parentViewLinkInfo.isValid() ) { - ATH_CHECK( parentViewLinkInfo.link.isValid() ); - auto parentView = *parentViewLinkInfo.link; - newView->linkParent( parentView ); - ATH_MSG_DEBUG( "Parent view linked" ); - } else { - ATH_MSG_ERROR( "Parent view not linked because it could not be found" ); - ATH_MSG_ERROR( TrigCompositeUtils::dump( inputDecision, [](const xAOD::TrigComposite* tc){ - return "TC " + tc->name() + ( tc->hasObjectLink("view") ? " has view " : " has no view " ); - } ) ); - return StatusCode::FAILURE; - } - } else { - ATH_MSG_DEBUG( "Parent view linking not required" ); +StatusCode EventViewCreatorAlgorithm::linkViewToParent( const TrigCompositeUtils::Decision* outputDecision, SG::View* newView ) const { + if (!m_requireParentView) { + ATH_MSG_DEBUG("Parent view linking not required"); + return StatusCode::SUCCESS; + } + // We must call this BEFORE having added the new link, check + if (outputDecision->hasObjectLink(viewString())) { + ATH_MSG_ERROR("Called linkViewToParent on a Decision object which already has been given a '" + << viewString << "' link. Call this fn BEFORE linking the new View."); + return StatusCode::FAILURE; + } + std::vector<LinkInfo<ViewContainer>> parentViews = findLinks<ViewContainer>(outputDecision, viewString(), TrigDefs::lastFeatureOfType); + if (parentViews.size() == 0) { + ATH_MSG_ERROR("Could not find the parent View, but 'RequireParentView' is true."); + return StatusCode::FAILURE; + } + ATH_MSG_DEBUG( "Will link " << parentViews.size() << " parent view(s)" ); + for (const LinkInfo<ViewContainer>& parentViewLI : parentViews) { + ATH_CHECK(parentViewLI.isValid()); + newView->linkParent( *(parentViewLI.link) ); + ATH_MSG_DEBUG( "Parent view linked (" << parentViewLI.link.dataID() << ", index:" << parentViewLI.link.index() << ")" ); } return StatusCode::SUCCESS; } diff --git a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.h b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.h index ef230e5c700..d0d42d3b816 100644 --- a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.h +++ b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.h @@ -21,11 +21,15 @@ #include "GaudiKernel/IScheduler.h" #include "AthViews/View.h" - /** - * @class EventViewCreatorAlgorithm - * @brief Used at the start of a sequence to create the EventViews: retrieves filtered collection via menu decision from previous step and writes it out directly so it can be used as input by the reco alg that follows in sequence. - **/ +#include "ViewAlgs/IViewCreatorROITool.h" +/** + * @class EventViewCreatorAlgorithm + * @brief Used at the start of a sequence to create the EventViews: retrieves filtered collections via menu decision from previous + * step, merges them and writes out a merged collection to be consumed by HypoAlg(s). + * Spawns EventViews for each unique ROI associated to each Decision object in the merged output. + * Links the EventView and the ROI to each Decision object in the merged output. + **/ class EventViewCreatorAlgorithm : public ::InputMakerBase @@ -39,35 +43,60 @@ class EventViewCreatorAlgorithm : public ::InputMakerBase protected: EventViewCreatorAlgorithm(); - - // Used instead of execute, when mergeOutputs is true - // Note: if we enforce the merging beahviour this will become the default execute() - StatusCode executeMerged(const EventContext&) const; - //Output views for merging - SG::WriteHandleKey< ViewContainer > m_viewsKey{ this, "Views", "Unspecified", "The key of views collection produced" }; + SG::WriteHandleKey< ViewContainer > m_viewsKey{ this, "Views", "Unspecified", + "The key of views collection produced" }; - // same handles as inputMakerForRoI - SG::WriteHandleKey< ConstDataVector<TrigRoiDescriptorCollection> > m_inViewRoIs{ this, "InViewRoIs", "Unspecified", "Name with which the RoIs shoudl be inserted into the views" }; + SG::WriteHandleKey< ConstDataVector<TrigRoiDescriptorCollection> > m_inViewRoIs{ this, "InViewRoIs", "Unspecified", + "Name of the collection which should be inserted into the just-spawned views to seed them with their ROI" }; // needs for views Gaudi::Property< std::string > m_schedulerName { this, "SchedulerName", "AvalancheSchedulerSvc", "Name of the scheduler" }; - Gaudi::Property< std::string > m_viewNodeName{ this, "ViewNodeName", "", "Name of the CF node to attach a view to" }; + Gaudi::Property< std::string > m_viewNodeName{ this, "ViewNodeName", "", "Name of the ControlFlow node to attach new views to" }; - Gaudi::Property< bool > m_viewFallThrough { this, "ViewFallThrough", false, "Set whether views may accesas StoreGate directly to retrieve data" }; - Gaudi::Property< bool > m_requireParentView { this, "RequireParentView", false, "Fail if the parent view can not be found" }; - Gaudi::Property< bool > m_reverseViews { this, "ReverseViewsDebug", false, "Reverse order of views, as a debugging option" }; - Gaudi::Property< std::vector< std::string > > m_viewFallFilter { this, "FallThroughFilter", {}, "A list of SG keys (or parts of them) that can come from StoreGate" }; + Gaudi::Property< bool > m_viewFallThrough { this, "ViewFallThrough", false, + "Set whether views may access StoreGate directly to retrieve data" }; + Gaudi::Property< std::vector< std::string > > m_viewFallFilter { this, "FallThroughFilter", {}, + "An optional list of SG keys (or parts of them) that can come from StoreGate via FallThrough" }; + Gaudi::Property< bool > m_requireParentView { this, "RequireParentView", false, + "For each new view, locate and link a parent view (previous step). Fail if the parent view can not be found." }; - // methods - /** - * @brief makes sure the views are linked, if configuration requireParentView is set, failure to set the parent is an error - **/ - StatusCode linkViewToParent( const TrigCompositeUtils::Decision* inputDecsion, SG::View* newView ) const; + Gaudi::Property< bool > m_reverseViews { this, "ReverseViewsDebug", false, + "Reverse order of views, as a debugging option" }; + + SG::ReadHandleKey<TrigCompositeUtils::DecisionContainer> m_cachedViewsKey { this, "InputCachedViews", "", + "Optional ReadHandle on the output (InputMakerOutputDecisions) of an EVCA in a previous Step, whose Views can be re-used" }; + + ToolHandle<IViewCreatorROITool> m_roiTool{this, "RoITool", "", + "Tool used to supply per-Decision Object the RoI on which the Decision Object's view is to be spawned"}; + + /** + * @brief Makes sure the views are linked, if configuration requireParentView is set. Failure to set the parent is an error + **/ + StatusCode linkViewToParent( const TrigCompositeUtils::Decision* outputDecision, SG::View* newView ) const; + + /** + * @brief Seeds a newly created view with an ROI collection containing the single seeding ROI + **/ StatusCode placeRoIInView( const ElementLink<TrigRoiDescriptorCollection>& roi, SG::View* view, const EventContext& context ) const; - inline SmartIF<IScheduler> getScheduler() const {return svcLoc()->service<IScheduler>(m_schedulerName,false);} + + /** + * @brief Obtain smart pointer to scheduler in order to schedule newly spawned views + **/ + SmartIF<IScheduler> getScheduler() const; + + /** + * @brief Allow for the re-use of EventViews run in a previous Step in another EVCA instance configured + * to spawn EventViews using the same reconstruction sequence (i.e. both algs should share a common ViewNodeName). + **/ + bool checkCache(const TrigCompositeUtils::DecisionContainer* cachedViews, + const TrigCompositeUtils::Decision* outputDecision, + size_t& cachedIndex) const; + }; +#include "EventViewCreatorAlgorithm.icc" + #endif diff --git a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.icc b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.icc new file mode 100644 index 00000000000..b8b44539b41 --- /dev/null +++ b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithm.icc @@ -0,0 +1,25 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +inline SmartIF<IScheduler> EventViewCreatorAlgorithm::getScheduler() const { + return svcLoc()->service<IScheduler>(m_schedulerName, false); +} + +// NOTE: This is TODO + +// template<class OBJECT> +// StatusCode EventViewCreatorAlgorithm::placeFeatureInView( const OBJECT* theObject, SG::View* view, const EventContext& context ) const { +// ATH_MSG_ALWAYS( "Adding Feature of type " << ClassID_traits<OBJECT>::typeName() << " To View : " << m_inViewFeatureKey.key() ); +// auto oneObjectCollection = std::make_unique< ConstDataVector< OBJECT > >(); +// oneObjectCollection->clear( SG::VIEW_ELEMENTS ); +// oneObjectCollection->push_back( theObject ); + +// //store in the view +// auto handle = SG::makeHandle( m_inViewFeatureKey,context ); +// ATH_CHECK( handle.setProxyDict( view ) ); +// ATH_CHECK( handle.record( std::move( oneObjectCollection ) ) ); +// return StatusCode::SUCCESS; +// } + + diff --git a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithmWithJets.cxx b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithmWithJets.cxx index 3661fd9d0ee..571777458ce 100644 --- a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithmWithJets.cxx +++ b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithmWithJets.cxx @@ -29,9 +29,9 @@ StatusCode EventViewCreatorAlgorithmWithJets::initialize() { } StatusCode EventViewCreatorAlgorithmWithJets::execute( const EventContext& context ) const { - // create the output decisions, similar to inputs (copy basic links) - std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > outputHandles; - ATH_CHECK (decisionInputToOutput(context, outputHandles)); + // create the output decisions from the input collections + SG::WriteHandle<DecisionContainer> outputHandle = createAndStore( decisionOutputs(), context ); + ATH_CHECK (decisionInputToOutput(context, outputHandle)); // make the views auto viewsHandle = SG::makeHandle( m_viewsKey, context ); @@ -43,70 +43,69 @@ StatusCode EventViewCreatorAlgorithmWithJets::execute( const EventContext& conte //map all RoIs that are stored std::vector <ElementLink<TrigRoiDescriptorCollection> > RoIsFromDecision; - for (auto outputHandle: outputHandles) { - if( not outputHandle.isValid() ) { - ATH_MSG_DEBUG( "Got no decisions from output "<< outputHandle.key() << " because handle not valid"); - continue; - } - if( outputHandle->size() == 0){ // input filtered out - ATH_MSG_ERROR( "Got no decisions from output "<< outputHandle.key()<<": handle is valid but container is empty. Is this expected?"); - return StatusCode::FAILURE; - } - - ATH_MSG_DEBUG( "Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); - // loop over output decisions in container of outputHandle, follow link to inputDecision - for ( auto outputDecision : *outputHandle){ - ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); - // loop over input links as predecessors - for (auto input: inputLinks){ - const Decision* inputDecision = *input; - - // Retrieve jets ... - ATH_MSG_DEBUG( "Checking there are jets linked to decision object" ); - TrigCompositeUtils::LinkInfo< xAOD::JetContainer > jetELInfo = TrigCompositeUtils::findLink< xAOD::JetContainer >( inputDecision,TrigCompositeUtils::featureString() ); - ATH_CHECK( jetELInfo.isValid() ); - const xAOD::Jet *jet = *jetELInfo.link; - ATH_MSG_DEBUG( "Placing xAOD::JetContainer " ); - ATH_MSG_DEBUG( " -- pt="<< jet->p4().Et() <<" eta="<< jet->eta() << " phi="<< jet->phi() ); + if( not outputHandle.isValid() ) { + ATH_MSG_ERROR( "Got no decisions from output "<< outputHandle.key() << " because handle not valid"); + return StatusCode::FAILURE; + } + if( outputHandle->size() == 0){ // input filtered out + ATH_MSG_ERROR( "Got no decisions from output "<< outputHandle.key()<<": handle is valid but container is empty. Is this expected?"); + return StatusCode::FAILURE; + } + + ATH_MSG_DEBUG( "Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); + // loop over output decisions in container of outputHandle, follow link to inputDecision + for ( auto outputDecision : *outputHandle){ + ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); + // loop over input links as predecessors + for (auto input: inputLinks){ + const Decision* inputDecision = *input; + + // Retrieve jets ... + ATH_MSG_DEBUG( "Checking there are jets linked to decision object" ); + TrigCompositeUtils::LinkInfo< xAOD::JetContainer > jetELInfo = TrigCompositeUtils::findLink< xAOD::JetContainer >( inputDecision,TrigCompositeUtils::featureString() ); + ATH_CHECK( jetELInfo.isValid() ); + const xAOD::Jet *jet = *jetELInfo.link; + ATH_MSG_DEBUG( "Placing xAOD::JetContainer " ); + ATH_MSG_DEBUG( " -- pt="<< jet->p4().Et() <<" eta="<< jet->eta() << " phi="<< jet->phi() ); + + // find the RoI + auto roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( inputDecision, m_roisLink.value() ); + auto roiEL = roiELInfo.link; + ATH_CHECK( roiEL.isValid() ); + // check if already found + auto roiIt=find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL); + if ( roiIt == RoIsFromDecision.end() ){ + RoIsFromDecision.push_back(roiEL); // just to keep track of which we have used + const TrigRoiDescriptor* roi = *roiEL; + ATH_MSG_DEBUG("Found RoI:" <<*roi<<" FS="<<roi->isFullscan()); + ATH_MSG_DEBUG( "Positive decisions on RoI, preparing view" ); - // find the RoI - auto roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( inputDecision, m_roisLink.value() ); - auto roiEL = roiELInfo.link; - ATH_CHECK( roiEL.isValid() ); - // check if already found - auto roiIt=find(RoIsFromDecision.begin(), RoIsFromDecision.end(), roiEL); - if ( roiIt == RoIsFromDecision.end() ){ - RoIsFromDecision.push_back(roiEL); // just to keep track of which we have used - const TrigRoiDescriptor* roi = *roiEL; - ATH_MSG_DEBUG("Found RoI:" <<*roi<<" FS="<<roi->isFullscan()); - ATH_MSG_DEBUG( "Positive decisions on RoI, preparing view" ); - - // make the view - ATH_MSG_DEBUG( "Making the View" ); - auto newView = ViewHelper::makeView( name()+"_view", viewCounter++, m_viewFallThrough ); //pointer to the view - - // Use a fall-through filter if one is provided - if ( m_viewFallFilter.size() ) { - newView->setFilter( m_viewFallFilter ); - } - - viewVector->push_back( newView ); - - // link decision to this view - outputDecision->setObjectLink( TrigCompositeUtils::viewString(), ElementLink< ViewContainer >(m_viewsKey.key(), viewVector->size()-1 ));//adding view to TC - ATH_MSG_DEBUG( "Adding new view to new decision; storing view in viewVector component " << viewVector->size()-1 ); - ATH_CHECK( linkViewToParent( inputDecision, viewVector->back() ) ); - ATH_CHECK( placeRoIInView( roiEL, viewVector->back(), context ) ); - ATH_CHECK( placeJetInView( jet, viewVector->back(), context ) ); - } - else { - int iview = roiIt-RoIsFromDecision.begin(); - outputDecision->setObjectLink( TrigCompositeUtils::viewString(), ElementLink< ViewContainer >(m_viewsKey.key(), iview ) ); //adding view to TC - ATH_MSG_DEBUG( "Adding already mapped view " << iview << " in ViewVector , to new decision"); + // make the view + ATH_MSG_DEBUG( "Making the View" ); + auto newView = ViewHelper::makeView( name()+"_view", viewCounter++, m_viewFallThrough ); //pointer to the view + + // Use a fall-through filter if one is provided + if ( m_viewFallFilter.size() ) { + newView->setFilter( m_viewFallFilter ); } - }// loop over previous inputs - } // loop over decisions - }// loop over output keys + + viewVector->push_back( newView ); + ATH_CHECK( linkViewToParent( inputDecision, viewVector->back() ) ); + + // link decision to this view + + outputDecision->setObjectLink( TrigCompositeUtils::viewString(), ElementLink< ViewContainer >(m_viewsKey.key(), viewVector->size()-1 ));//adding view to TC + ATH_MSG_DEBUG( "Adding new view to new decision; storing view in viewVector component " << viewVector->size()-1 ); + ATH_CHECK( placeRoIInView( roiEL, viewVector->back(), context ) ); + ATH_CHECK( placeJetInView( jet, viewVector->back(), context ) ); + } + else { + int iview = roiIt-RoIsFromDecision.begin(); + outputDecision->setObjectLink( TrigCompositeUtils::viewString(), ElementLink< ViewContainer >(m_viewsKey.key(), iview ) ); //adding view to TC + ATH_MSG_DEBUG( "Adding already mapped view " << iview << " in ViewVector , to new decision"); + } + }// loop over previous inputs + } // loop over decisions ATH_MSG_DEBUG( "Launching execution in " << viewVector->size() << " views" ); ATH_CHECK( ViewHelper::scheduleViews( viewVector, // Vector containing views @@ -119,7 +118,7 @@ StatusCode EventViewCreatorAlgorithmWithJets::execute( const EventContext& conte // auto viewsHandle = SG::makeHandle( m_viewsKey ); // ATH_CHECK( viewsHandle.record( std::move( viewVector ) ) ); ATH_MSG_DEBUG( "Store "<< viewsHandle->size() <<" Views"); - if (msgLvl(MSG::DEBUG)) debugPrintOut(context, outputHandles); + if (msgLvl(MSG::DEBUG)) debugPrintOut(context, outputHandle); return StatusCode::SUCCESS; } diff --git a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithmWithMuons.cxx b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithmWithMuons.cxx index dc3ba9a9bef..fe10424f982 100644 --- a/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithmWithMuons.cxx +++ b/Trigger/TrigSteer/ViewAlgs/src/EventViewCreatorAlgorithmWithMuons.cxx @@ -35,9 +35,9 @@ StatusCode EventViewCreatorAlgorithmWithMuons::initialize() { } StatusCode EventViewCreatorAlgorithmWithMuons::execute( const EventContext& context ) const { - // create the output decisions, similar to inputs (copy basic links) - std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > outputHandles; - ATH_CHECK (decisionInputToOutput(context, outputHandles)); + // create the output decisions from the input collections + SG::WriteHandle<DecisionContainer> outputHandle = createAndStore( decisionOutputs(), context ); + ATH_CHECK (decisionInputToOutput(context, outputHandle)); // make the views auto viewsHandle = SG::makeHandle( m_viewsKey, context ); @@ -58,112 +58,115 @@ StatusCode EventViewCreatorAlgorithmWithMuons::execute( const EventContext& cont std::vector <ElementLink<TrigRoiDescriptorCollection> > RoIsFromDecision; // Store new ROI Descriptors - SG::WriteHandle<TrigRoiDescriptorCollection> roisWriteHandle = TrigCompositeUtils::createAndStoreNoAux(m_roisWriteHandleKey, context); + SG::WriteHandle<TrigRoiDescriptorCollection> roisWriteHandle = createAndStoreNoAux(m_roisWriteHandleKey, context); - for (auto outputHandle: outputHandles) { - if( not outputHandle.isValid() ) { - ATH_MSG_DEBUG( "Got no decisions from output "<< outputHandle.key() << " because handle not valid"); - continue; - } - if( outputHandle->size() == 0){ // input filtered out - ATH_MSG_ERROR( "Got no decisions from output "<< outputHandle.key()<<": handle is valid but container is empty. Is this expected?"); - return StatusCode::FAILURE; - } - ATH_MSG_DEBUG( "Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); + if( not outputHandle.isValid() ) { + ATH_MSG_ERROR( "Got no decisions from output "<< outputHandle.key() << " because handle not valid"); + return StatusCode::FAILURE; + } - if(m_doFSRoI){ - //create one RoI over full detector - auto roi = new TrigRoiDescriptor(true); - roisWriteHandle->push_back( roi ); - const auto roiEL = ElementLink<TrigRoiDescriptorCollection>(*roisWriteHandle, roisWriteHandle->size() - 1, context); - - // make the view - ATH_MSG_DEBUG( "Making the View "<<name()<<"_view" ); - auto newView = ViewHelper::makeView( name()+"_view", viewCounter++, m_viewFallThrough ); - - // Use a fall-through filter if one is provided - if ( m_viewFallFilter.size() ) { - newView->setFilter( m_viewFallFilter ); - } - - viewVector->push_back( newView ); - ATH_CHECK( placeRoIInView( roiEL, viewVector->back(), context ) ); + if( outputHandle->size() == 0){ // input filtered out + ATH_MSG_ERROR( "Got no decisions from output "<< outputHandle.key()<<": handle is valid but container is empty. Is this expected?"); + return StatusCode::FAILURE; + } + + ATH_MSG_DEBUG( "Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); + + if(m_doFSRoI){ + //create one RoI over full detector + auto roi = new TrigRoiDescriptor(true); + roisWriteHandle->push_back( roi ); + const auto roiEL = ElementLink<TrigRoiDescriptorCollection>(*roisWriteHandle, roisWriteHandle->size() - 1, context); + + // make the view + ATH_MSG_DEBUG( "Making the View "<<name()<<"_view" ); + auto newView = ViewHelper::makeView( name()+"_view", viewCounter++, m_viewFallThrough ); + + // Use a fall-through filter if one is provided + if ( m_viewFallFilter.size() ) { + newView->setFilter( m_viewFallFilter ); } - // loop over output decisions in container of outputHandle, follow link to inputDecision - for ( auto outputDecision : *outputHandle){ - ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); - - if(m_doFSRoI){ - // link decision to this view - outputDecision->setObjectLink( "view", ElementLink< ViewContainer >(m_viewsKey.key(), viewVector->size()-1 ));//adding view to TC - } - else{ - - //create one RoI per muon - - // loop over input links as predecessors - for (auto input: inputLinks){ - const Decision* inputDecision = *input; - - if(m_doLateMu){ - // Retrieve late muon rois ... - ATH_MSG_DEBUG( "Checking there are out-of-time rois linked to decision object" ); - TrigCompositeUtils::LinkInfo< TrigRoiDescriptorCollection > lateRoIELInfo = TrigCompositeUtils::findLink< TrigRoiDescriptorCollection >( inputDecision,m_lateRoIsLink ); - ATH_CHECK( lateRoIELInfo.isValid() ); - const TrigRoiDescriptor *lateRoI = *lateRoIELInfo.link; - // parameters for RoI to record - reta = lateRoI->eta(); - retap = lateRoI->etaPlus(); - retam = lateRoI->etaMinus(); - rphi = lateRoI->phi(); - rphip = lateRoI->phiPlus(); - rphim = lateRoI->phiMinus(); - } - else{ - // Retrieve muons ... - ATH_MSG_DEBUG( "Checking there are muons linked to decision object" ); - TrigCompositeUtils::LinkInfo< xAOD::MuonContainer > muonELInfo = TrigCompositeUtils::findLink< xAOD::MuonContainer >( inputDecision,m_muonsLink ); - ATH_CHECK( muonELInfo.isValid() ); - muon = *muonELInfo.link; - ATH_MSG_DEBUG( "Placing xAOD::MuonContainer " ); - ATH_MSG_DEBUG( " -- pt="<< muon->p4().Et() <<" eta="<< muon->eta() << " muon="<< muon->phi() ); - - // parameters for RoI around muon - reta = muon->eta(); - retap = muon->eta()+m_roiEtaWidth; - retam = muon->eta()-m_roiEtaWidth; - rphi = muon->phi(); - rphip = muon->phi()+m_roiPhiWidth; - rphim = muon->phi()-m_roiPhiWidth; - } - auto roi = new TrigRoiDescriptor(reta, retam, retap, rphi, rphim, rphip); - roisWriteHandle->push_back( roi ); - const auto roiEL = ElementLink<TrigRoiDescriptorCollection>(*roisWriteHandle, roisWriteHandle->size() - 1, context); - ATH_CHECK( roiEL.isValid() ); - ATH_MSG_DEBUG("Created roi around muon: "<<*roi); - // make the view - ATH_MSG_DEBUG( "Making the View "<<name()<<"_view" ); - auto newView = ViewHelper::makeView( name()+"_view", viewCounter++, m_viewFallThrough ); //pointer to the view - - // Use a fall-through filter if one is provided - if ( m_viewFallFilter.size() ) { - newView->setFilter( m_viewFallFilter ); - } - - viewVector->push_back( newView ); - - // link decision to this view - outputDecision->setObjectLink( TrigCompositeUtils::viewString(), ElementLink< ViewContainer >(m_viewsKey.key(), viewVector->size()-1 ));//adding view to TC - ATH_MSG_DEBUG( "Adding new view to new decision; storing view in viewVector component " << viewVector->size()-1 ); - ATH_CHECK( linkViewToParent( inputDecision, viewVector->back() ) ); - ATH_CHECK( placeRoIInView( roiEL, viewVector->back(), context ) ); - if(!m_doLateMu) ATH_CHECK( placeMuonInView( muon, viewVector->back(), context ) ); - }// loop over previous inputs - }//Not FS view - } // loop over decisions - }// loop over output keys + viewVector->push_back( newView ); + ATH_CHECK( placeRoIInView( roiEL, viewVector->back(), context ) ); + } + + // loop over output decisions in container of outputHandle, follow link to inputDecision + for ( auto outputDecision : *outputHandle){ + ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); + + if(m_doFSRoI){ + // link decision to this view + outputDecision->setObjectLink( "view", ElementLink< ViewContainer >(m_viewsKey.key(), viewVector->size()-1 ));//adding view to TC + } else{ + + //create one RoI per muon + + // loop over input links as predecessors + for (auto input: inputLinks){ + const Decision* inputDecision = *input; + + if(m_doLateMu){ + + // Retrieve late muon rois ... + ATH_MSG_DEBUG( "Checking there are out-of-time rois linked to decision object" ); + TrigCompositeUtils::LinkInfo< TrigRoiDescriptorCollection > lateRoIELInfo = TrigCompositeUtils::findLink< TrigRoiDescriptorCollection >( inputDecision,m_lateRoIsLink ); + ATH_CHECK( lateRoIELInfo.isValid() ); + const TrigRoiDescriptor *lateRoI = *lateRoIELInfo.link; + // parameters for RoI to record + reta = lateRoI->eta(); + retap = lateRoI->etaPlus(); + retam = lateRoI->etaMinus(); + rphi = lateRoI->phi(); + rphip = lateRoI->phiPlus(); + rphim = lateRoI->phiMinus(); + + } else{ + + // Retrieve muons ... + ATH_MSG_DEBUG( "Checking there are muons linked to decision object" ); + TrigCompositeUtils::LinkInfo< xAOD::MuonContainer > muonELInfo = TrigCompositeUtils::findLink< xAOD::MuonContainer >( inputDecision,m_muonsLink ); + ATH_CHECK( muonELInfo.isValid() ); + muon = *muonELInfo.link; + ATH_MSG_DEBUG( "Placing xAOD::MuonContainer " ); + ATH_MSG_DEBUG( " -- pt="<< muon->p4().Et() <<" eta="<< muon->eta() << " muon="<< muon->phi() ); + + // parameters for RoI around muon + reta = muon->eta(); + retap = muon->eta()+m_roiEtaWidth; + retam = muon->eta()-m_roiEtaWidth; + rphi = muon->phi(); + rphip = muon->phi()+m_roiPhiWidth; + rphim = muon->phi()-m_roiPhiWidth; + + } + + auto roi = new TrigRoiDescriptor(reta, retam, retap, rphi, rphim, rphip); + roisWriteHandle->push_back( roi ); + const auto roiEL = ElementLink<TrigRoiDescriptorCollection>(*roisWriteHandle, roisWriteHandle->size() - 1, context); + ATH_CHECK( roiEL.isValid() ); + ATH_MSG_DEBUG("Created roi around muon: "<<*roi); + // make the view + ATH_MSG_DEBUG( "Making the View "<<name()<<"_view" ); + SG::View* newView = ViewHelper::makeView( name()+"_view", viewCounter++, m_viewFallThrough ); //pointer to the view + viewVector->push_back( newView ); + // Use a fall-through filter if one is provided + if ( m_viewFallFilter.size() ) { + newView->setFilter( m_viewFallFilter ); + } + ATH_CHECK( linkViewToParent( inputDecision, newView ) ); + // link decision to this view + outputDecision->setObjectLink( TrigCompositeUtils::viewString(), ElementLink< ViewContainer >(m_viewsKey.key(), viewVector->size()-1 ));//adding view to TC + + ATH_MSG_DEBUG( "Adding new view to new decision; storing view in viewVector component " << viewVector->size()-1 ); + ATH_CHECK( placeRoIInView( roiEL, viewVector->back(), context ) ); + if(!m_doLateMu) { + ATH_CHECK( placeMuonInView( muon, viewVector->back(), context ) ); + } + }// loop over previous inputs + }//Not FS view + } // loop over decisions ATH_MSG_DEBUG( "Launching execution in " << viewVector->size() << " views" ); ATH_CHECK( ViewHelper::scheduleViews( viewVector, // Vector containing views @@ -172,7 +175,7 @@ StatusCode EventViewCreatorAlgorithmWithMuons::execute( const EventContext& cont getScheduler(), m_reverseViews ) ); - if (msgLvl(MSG::DEBUG)) debugPrintOut(context, outputHandles); + if (msgLvl(MSG::DEBUG)) debugPrintOut(context, outputHandle); return StatusCode::SUCCESS; } diff --git a/Trigger/TrigSteer/ViewAlgs/src/ViewCreatorInitialROITool.cxx b/Trigger/TrigSteer/ViewAlgs/src/ViewCreatorInitialROITool.cxx new file mode 100644 index 00000000000..b92b2cf1d11 --- /dev/null +++ b/Trigger/TrigSteer/ViewAlgs/src/ViewCreatorInitialROITool.cxx @@ -0,0 +1,31 @@ + +/* +Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TrigSteeringEvent/TrigRoiDescriptorCollection.h" +#include "ViewCreatorInitialROITool.h" + +using namespace TrigCompositeUtils; + +ViewCreatorInitialROITool::ViewCreatorInitialROITool(const std::string& type, const std::string& name, const IInterface* parent) + : base_class(type, name, parent) + {} + +StatusCode ViewCreatorInitialROITool::attachROILinks(TrigCompositeUtils::DecisionContainer& decisions, const EventContext&) const { + // Locate "initialRoI" for each Decision object, re-attach the ElementLink as "roi" to the current Decision object. + for ( Decision* outputDecision : decisions ) { + const std::vector<LinkInfo<TrigRoiDescriptorCollection>> myROI = findLinks<TrigRoiDescriptorCollection>(outputDecision, initialRoIString(), TrigDefs::lastFeatureOfType); + + if (myROI.size() != 1) { + ATH_MSG_ERROR("Did not find exactly one '" << initialRoIString() << "' for Decision object index " << outputDecision->index() + << ", found " << myROI.size() << ". Unable to supply single ROI to spawn EventView on."); + for (const auto& li : myROI) { + ATH_MSG_ERROR(" -- " << li.link.dataID() << ":" << li.link.index() << ". Dump:" << *(li.source)); + } + } + + outputDecision->setObjectLink(roiString(), myROI.at(0).link); + } + return StatusCode::SUCCESS; +} diff --git a/Trigger/TrigSteer/ViewAlgs/src/ViewCreatorInitialROITool.h b/Trigger/TrigSteer/ViewAlgs/src/ViewCreatorInitialROITool.h new file mode 100644 index 00000000000..bb297e595e3 --- /dev/null +++ b/Trigger/TrigSteer/ViewAlgs/src/ViewCreatorInitialROITool.h @@ -0,0 +1,35 @@ +/* +Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef VIEWALGS_VIEWCREATORINITIALROITOOL_H +#define VIEWALGS_VIEWCREATORINITIALROITOOL_H + +#include "AthenaBaseComps/AthAlgTool.h" +#include "ViewAlgs/IViewCreatorROITool.h" + +/** + * @class ViewCreatorInitialROITool + * Basic ROI provider tool which retrieves and re-attaches an existing "initialRoI" ElementLink. + * This implies running the EventView spawned for the Decision object on the ROIDescriptor originating from L1. + * + * Every Decision object in decisions must have a single "initialRoI" element link added at the root of + * the navigation graph for the Decision object. + * + * This basic tool should be replaced with more advanced slice-specific ones where appropriate. + **/ +class ViewCreatorInitialROITool: public extends<AthAlgTool, IViewCreatorROITool> +{ +public: + ViewCreatorInitialROITool(const std::string& type, const std::string& name, const IInterface* parent); + + virtual ~ViewCreatorInitialROITool() = default; + +/** + * @brief Tool interface method. Context not used in this tool implementation. + **/ + virtual StatusCode attachROILinks(TrigCompositeUtils::DecisionContainer& decisions, const EventContext& ctx) const override; + +}; + +#endif //> !VIEWALGS_VIEWCREATORINITIALROITOOL_H diff --git a/Trigger/TrigSteer/ViewAlgs/src/ViewCreatorPreviousROITool.cxx b/Trigger/TrigSteer/ViewAlgs/src/ViewCreatorPreviousROITool.cxx new file mode 100644 index 00000000000..f7724e8438e --- /dev/null +++ b/Trigger/TrigSteer/ViewAlgs/src/ViewCreatorPreviousROITool.cxx @@ -0,0 +1,33 @@ + +/* +Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TrigSteeringEvent/TrigRoiDescriptorCollection.h" +#include "ViewCreatorPreviousROITool.h" + +using namespace TrigCompositeUtils; + +ViewCreatorPreviousROITool::ViewCreatorPreviousROITool(const std::string& type, const std::string& name, const IInterface* parent) + : base_class(type, name, parent) + {} + +StatusCode ViewCreatorPreviousROITool::attachROILinks(TrigCompositeUtils::DecisionContainer& decisions, const EventContext&) const { + // Locate "roi" for each Decision object from previous step, re-attach the ElementLink as "roi" to the current Decision object. + // I.e. don't update the "roi", just re-use the one from the previous Step. + for ( Decision* outputDecision : decisions ) { + const std::vector<LinkInfo<TrigRoiDescriptorCollection>> myROI = findLinks<TrigRoiDescriptorCollection>(outputDecision, roiString(), TrigDefs::lastFeatureOfType); + + if (myROI.size() != 1) { + ATH_MSG_ERROR("Did not find exactly one '" << roiString() << "' for Decision object index " << outputDecision->index() + << ", found " << myROI.size() << ". Unable to supply single ROI to spawn EventView on."); + for (const auto& li : myROI) { + ATH_MSG_ERROR(" -- " << li.link.dataID() << ":" << li.link.index() << ". Dump:" << *(li.source)); + } + return StatusCode::FAILURE; + } + + outputDecision->setObjectLink(roiString(), myROI.at(0).link); + } + return StatusCode::SUCCESS; +} diff --git a/Trigger/TrigSteer/ViewAlgs/src/ViewCreatorPreviousROITool.h b/Trigger/TrigSteer/ViewAlgs/src/ViewCreatorPreviousROITool.h new file mode 100644 index 00000000000..3f8d022df75 --- /dev/null +++ b/Trigger/TrigSteer/ViewAlgs/src/ViewCreatorPreviousROITool.h @@ -0,0 +1,32 @@ +/* +Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef VIEWALGS_VIEWCREATORPREVIOUSROITOOL_H +#define VIEWALGS_VIEWCREATORPREVIOUSROITOOL_H + +#include "AthenaBaseComps/AthAlgTool.h" +#include "ViewAlgs/IViewCreatorROITool.h" + +/** + * @class ViewCreatorPreviousROITool + * Basic ROI provider tool which retrieves and re-attaches an existing "roi" ElementLink. + * This implies running the EventView spawned for the Decision object on the ROIDescriptor originating from the previous step. + * + * This basic tool should be replaced with more advanced slice-specific ones where appropriate. + **/ +class ViewCreatorPreviousROITool: public extends<AthAlgTool, IViewCreatorROITool> +{ +public: + ViewCreatorPreviousROITool(const std::string& type, const std::string& name, const IInterface* parent); + + virtual ~ViewCreatorPreviousROITool() = default; + +/** + * @brief Tool interface method. Context not used in this tool implementation. + **/ + virtual StatusCode attachROILinks(TrigCompositeUtils::DecisionContainer& decisions, const EventContext& ctx) const override; + +}; + +#endif //> !VIEWALGS_VIEWCREATORPREVIOUSROITOOL_H diff --git a/Trigger/TrigSteer/ViewAlgs/src/components/ViewAlgs_entries.cxx b/Trigger/TrigSteer/ViewAlgs/src/components/ViewAlgs_entries.cxx index b2d16b8ea8b..f6731ff406b 100644 --- a/Trigger/TrigSteer/ViewAlgs/src/components/ViewAlgs_entries.cxx +++ b/Trigger/TrigSteer/ViewAlgs/src/components/ViewAlgs_entries.cxx @@ -4,11 +4,12 @@ #include "../EventViewCreatorAlgorithmWithJets.h" #include "../EventViewCreatorAlgorithmWithMuons.h" #include "../MergeViews.h" - - +#include "../ViewCreatorInitialROITool.h" +#include "../ViewCreatorPreviousROITool.h" DECLARE_COMPONENT( EventViewCreatorAlgorithm ) DECLARE_COMPONENT( EventViewCreatorAlgorithmWithJets ) DECLARE_COMPONENT( EventViewCreatorAlgorithmWithMuons ) DECLARE_COMPONENT( MergeViews ) - +DECLARE_COMPONENT( ViewCreatorInitialROITool ) +DECLARE_COMPONENT( ViewCreatorPreviousROITool ) diff --git a/Trigger/TrigValidation/TrigAnalysisTest/share/q221_RDOtoRDOTrig_mt1_build.ref b/Trigger/TrigValidation/TrigAnalysisTest/share/q221_RDOtoRDOTrig_mt1_build.ref index c64272ee5bc..78ad2ae88dc 100644 --- a/Trigger/TrigValidation/TrigAnalysisTest/share/q221_RDOtoRDOTrig_mt1_build.ref +++ b/Trigger/TrigValidation/TrigAnalysisTest/share/q221_RDOtoRDOTrig_mt1_build.ref @@ -19,27 +19,12 @@ TrigSignatureMoniMT INFO -- #3965466087 Features TrigSignatureMoniMT INFO HLT_2j330_a10t_lcw_jes_35smcINF_L1J100 #1295975955 TrigSignatureMoniMT INFO -- #1295975955 Events 3 3 0 - - - - 0 TrigSignatureMoniMT INFO -- #1295975955 Features 0 - - - - -TrigSignatureMoniMT INFO HLT_2mu10_bJpsimumu_L12MU10 #3498558358 -TrigSignatureMoniMT INFO -- #3498558358 Events 3 3 3 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #3498558358 Features 12 0 0 0 0 -TrigSignatureMoniMT INFO HLT_2mu10_bUpsimumu_L12MU10 #234102568 -TrigSignatureMoniMT INFO -- #234102568 Events 3 3 3 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #234102568 Features 12 0 0 0 0 TrigSignatureMoniMT INFO HLT_2mu14_L12MU10 #2619091790 TrigSignatureMoniMT INFO -- #2619091790 Events 3 3 3 1 1 1 - 1 TrigSignatureMoniMT INFO -- #2619091790 Features 12 4 4 4 - TrigSignatureMoniMT INFO HLT_2mu15_L12MU10 #557204938 TrigSignatureMoniMT INFO -- #557204938 Events 3 3 3 1 1 1 - 1 TrigSignatureMoniMT INFO -- #557204938 Features 12 4 4 4 - -TrigSignatureMoniMT INFO HLT_2mu4_bDimu_L12MU4 #1730084172 -TrigSignatureMoniMT INFO -- #1730084172 Events 4 4 4 1 0 0 0 0 -TrigSignatureMoniMT INFO -- #1730084172 Features 16 9 0 0 0 -TrigSignatureMoniMT INFO HLT_2mu4_bJpsimumu_L12MU4 #4276347155 -TrigSignatureMoniMT INFO -- #4276347155 Events 4 4 4 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #4276347155 Features 16 0 0 0 0 -TrigSignatureMoniMT INFO HLT_2mu4_bUpsimumu_L12MU4 #4008168535 -TrigSignatureMoniMT INFO -- #4008168535 Events 4 4 4 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #4008168535 Features 16 0 0 0 0 TrigSignatureMoniMT INFO HLT_2mu4_muonqual_L12MU4 #1584776935 TrigSignatureMoniMT INFO -- #1584776935 Events 4 4 4 4 4 4 - 4 TrigSignatureMoniMT INFO -- #1584776935 Features 16 16 24 20 - @@ -123,7 +108,7 @@ TrigSignatureMoniMT INFO -- #3534544568 Events TrigSignatureMoniMT INFO -- #3534544568 Features 0 0 0 0 - TrigSignatureMoniMT INFO HLT_g20_etcut_LArPEB_L1EM15 #2706532790 TrigSignatureMoniMT INFO -- #2706532790 Events 14 14 14 14 12 12 - 12 -TrigSignatureMoniMT INFO -- #2706532790 Features 24 24 22 22 - +TrigSignatureMoniMT INFO -- #2706532790 Features 24 24 22 20 - TrigSignatureMoniMT INFO HLT_g35_medium_g25_medium_L12EM20VH #1158879722 TrigSignatureMoniMT INFO -- #1158879722 Events 2 2 - - - - - 0 TrigSignatureMoniMT INFO -- #1158879722 Features - - - - - @@ -132,7 +117,7 @@ TrigSignatureMoniMT INFO -- #471243435 Events TrigSignatureMoniMT INFO -- #471243435 Features 140 140 190 - - TrigSignatureMoniMT INFO HLT_g5_etcut_LArPEB_L1EM3 #3486231698 TrigSignatureMoniMT INFO -- #3486231698 Events 20 20 20 20 20 20 - 20 -TrigSignatureMoniMT INFO -- #3486231698 Features 140 140 190 190 - +TrigSignatureMoniMT INFO -- #3486231698 Features 140 140 190 120 - TrigSignatureMoniMT INFO HLT_g5_loose_L1EM3 #3230088967 TrigSignatureMoniMT INFO -- #3230088967 Events 20 20 17 17 17 9 - 9 TrigSignatureMoniMT INFO -- #3230088967 Features 57 57 117 14 - diff --git a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_mt1_build.ref b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_mt1_build.ref index d204d01db4a..823a9af7718 100644 --- a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_mt1_build.ref +++ b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_mt1_build.ref @@ -19,27 +19,12 @@ TrigSignatureMoniMT INFO -- #3965466087 Features TrigSignatureMoniMT INFO HLT_2j330_a10t_lcw_jes_35smcINF_L1J100 #1295975955 TrigSignatureMoniMT INFO -- #1295975955 Events 3 3 0 - - - - 0 TrigSignatureMoniMT INFO -- #1295975955 Features 0 - - - - -TrigSignatureMoniMT INFO HLT_2mu10_bJpsimumu_L12MU10 #3498558358 -TrigSignatureMoniMT INFO -- #3498558358 Events 3 3 3 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #3498558358 Features 12 0 0 0 0 -TrigSignatureMoniMT INFO HLT_2mu10_bUpsimumu_L12MU10 #234102568 -TrigSignatureMoniMT INFO -- #234102568 Events 3 3 3 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #234102568 Features 12 0 0 0 0 TrigSignatureMoniMT INFO HLT_2mu14_L12MU10 #2619091790 TrigSignatureMoniMT INFO -- #2619091790 Events 3 3 3 1 1 1 - 1 TrigSignatureMoniMT INFO -- #2619091790 Features 12 4 4 4 - TrigSignatureMoniMT INFO HLT_2mu15_L12MU10 #557204938 TrigSignatureMoniMT INFO -- #557204938 Events 3 3 3 1 1 1 - 1 TrigSignatureMoniMT INFO -- #557204938 Features 12 4 4 4 - -TrigSignatureMoniMT INFO HLT_2mu4_bDimu_L12MU4 #1730084172 -TrigSignatureMoniMT INFO -- #1730084172 Events 4 4 4 1 0 0 0 0 -TrigSignatureMoniMT INFO -- #1730084172 Features 16 9 0 0 0 -TrigSignatureMoniMT INFO HLT_2mu4_bJpsimumu_L12MU4 #4276347155 -TrigSignatureMoniMT INFO -- #4276347155 Events 4 4 4 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #4276347155 Features 16 0 0 0 0 -TrigSignatureMoniMT INFO HLT_2mu4_bUpsimumu_L12MU4 #4008168535 -TrigSignatureMoniMT INFO -- #4008168535 Events 4 4 4 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #4008168535 Features 16 0 0 0 0 TrigSignatureMoniMT INFO HLT_2mu4_muonqual_L12MU4 #1584776935 TrigSignatureMoniMT INFO -- #1584776935 Events 4 4 4 4 4 4 - 4 TrigSignatureMoniMT INFO -- #1584776935 Features 16 16 24 20 - @@ -123,7 +108,7 @@ TrigSignatureMoniMT INFO -- #3534544568 Events TrigSignatureMoniMT INFO -- #3534544568 Features 0 0 0 0 - TrigSignatureMoniMT INFO HLT_g20_etcut_LArPEB_L1EM15 #2706532790 TrigSignatureMoniMT INFO -- #2706532790 Events 14 14 14 14 12 12 - 12 -TrigSignatureMoniMT INFO -- #2706532790 Features 24 24 22 22 - +TrigSignatureMoniMT INFO -- #2706532790 Features 24 24 22 20 - TrigSignatureMoniMT INFO HLT_g35_medium_g25_medium_L12EM20VH #1158879722 TrigSignatureMoniMT INFO -- #1158879722 Events 2 2 - - - - - 0 TrigSignatureMoniMT INFO -- #1158879722 Features - - - - - @@ -132,7 +117,7 @@ TrigSignatureMoniMT INFO -- #471243435 Events TrigSignatureMoniMT INFO -- #471243435 Features 137 137 190 - - TrigSignatureMoniMT INFO HLT_g5_etcut_LArPEB_L1EM3 #3486231698 TrigSignatureMoniMT INFO -- #3486231698 Events 20 20 20 20 20 20 - 20 -TrigSignatureMoniMT INFO -- #3486231698 Features 137 137 190 190 - +TrigSignatureMoniMT INFO -- #3486231698 Features 137 137 190 118 - TrigSignatureMoniMT INFO HLT_g5_loose_L1EM3 #3230088967 TrigSignatureMoniMT INFO -- #3230088967 Events 20 20 17 17 17 9 - 9 TrigSignatureMoniMT INFO -- #3230088967 Features 56 56 116 12 - diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/egammaRinger.py b/Trigger/TrigValidation/TrigUpgradeTest/share/egammaRinger.py index 9db33913147..5f6cdba46bf 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/share/egammaRinger.py +++ b/Trigger/TrigValidation/TrigUpgradeTest/share/egammaRinger.py @@ -4,7 +4,7 @@ from AthenaCommon.Constants import ERROR, DEBUG from AthenaCommon.CFElements import seqAND -from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm +from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool doWriteRDOTrigger = False @@ -56,10 +56,11 @@ fastCaloViewsMaker = EventViewCreatorAlgorithm( "fastCaloViewsMaker", OutputLeve fastCaloViewsMaker.ViewFallThrough = True fastCaloViewsMaker.InputMakerInputDecisions = [ "FilteredEMRoIDecisions" ] fastCaloViewsMaker.RoIsLink = "initialRoI" +fastCaloViewsMaker.RoITool = ViewCreatorInitialROITool() fastCaloViewsMaker.InViewRoIs = InViewRoIs fastCaloViewsMaker.Views = "EMCaloViews" fastCaloViewsMaker.ViewNodeName = "fastCaloInViewSequence" -fastCaloViewsMaker.InputMakerOutputDecisions = [ "L2CaloLinks"] +fastCaloViewsMaker.InputMakerOutputDecisions = "L2CaloLinks" clusterMaker.OutputLevel=FATAL if doRinger: @@ -80,7 +81,7 @@ for t in fastCaloHypo.HypoTools: fastCaloHypo.HypoOutputDecisions = "EgammaCaloDecisions" fastCaloHypo.OutputLevel= DEBUG -fastCaloHypo.HypoInputDecisions = fastCaloViewsMaker.InputMakerOutputDecisions[0] # __l1RoIDecisions +fastCaloHypo.HypoInputDecisions = fastCaloViewsMaker.InputMakerOutputDecisions # __l1RoIDecisions fastCaloSequence = seqAND("fastCaloSequence", [fastCaloViewsMaker, fastCaloInViewSequence, fastCaloHypo ]) diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/full_menu_build.ref b/Trigger/TrigValidation/TrigUpgradeTest/share/full_menu_build.ref index a864297a165..a9c40f9d240 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/share/full_menu_build.ref +++ b/Trigger/TrigValidation/TrigUpgradeTest/share/full_menu_build.ref @@ -19,27 +19,12 @@ TrigSignatureMoniMT INFO -- #3965466087 Features TrigSignatureMoniMT INFO HLT_2j330_a10t_lcw_jes_35smcINF_L1J100 #1295975955 TrigSignatureMoniMT INFO -- #1295975955 Events 20 20 0 - - - - 0 TrigSignatureMoniMT INFO -- #1295975955 Features 0 - - - - -TrigSignatureMoniMT INFO HLT_2mu10_bJpsimumu_L12MU10 #3498558358 -TrigSignatureMoniMT INFO -- #3498558358 Events 20 20 0 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #3498558358 Features 0 0 0 0 0 -TrigSignatureMoniMT INFO HLT_2mu10_bUpsimumu_L12MU10 #234102568 -TrigSignatureMoniMT INFO -- #234102568 Events 20 20 0 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #234102568 Features 0 0 0 0 0 TrigSignatureMoniMT INFO HLT_2mu14_L12MU10 #2619091790 TrigSignatureMoniMT INFO -- #2619091790 Events 20 20 0 0 0 0 - 0 TrigSignatureMoniMT INFO -- #2619091790 Features 0 0 0 0 - TrigSignatureMoniMT INFO HLT_2mu15_L12MU10 #557204938 TrigSignatureMoniMT INFO -- #557204938 Events 20 20 0 0 0 0 - 0 TrigSignatureMoniMT INFO -- #557204938 Features 0 0 0 0 - -TrigSignatureMoniMT INFO HLT_2mu4_bDimu_L12MU4 #1730084172 -TrigSignatureMoniMT INFO -- #1730084172 Events 20 20 1 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #1730084172 Features 4 0 0 0 0 -TrigSignatureMoniMT INFO HLT_2mu4_bJpsimumu_L12MU4 #4276347155 -TrigSignatureMoniMT INFO -- #4276347155 Events 20 20 1 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #4276347155 Features 4 0 0 0 0 -TrigSignatureMoniMT INFO HLT_2mu4_bUpsimumu_L12MU4 #4008168535 -TrigSignatureMoniMT INFO -- #4008168535 Events 20 20 1 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #4008168535 Features 4 0 0 0 0 TrigSignatureMoniMT INFO HLT_2mu4_muonqual_L12MU4 #1584776935 TrigSignatureMoniMT INFO -- #1584776935 Events 20 20 1 0 0 0 - 0 TrigSignatureMoniMT INFO -- #1584776935 Features 4 0 0 0 - @@ -138,7 +123,7 @@ TrigSignatureMoniMT INFO -- #471243435 Events TrigSignatureMoniMT INFO -- #471243435 Features 41 41 50 - - TrigSignatureMoniMT INFO HLT_g5_etcut_LArPEB_L1EM3 #3486231698 TrigSignatureMoniMT INFO -- #3486231698 Events 20 20 13 13 13 13 - 13 -TrigSignatureMoniMT INFO -- #3486231698 Features 41 41 50 50 - +TrigSignatureMoniMT INFO -- #3486231698 Features 41 41 50 36 - TrigSignatureMoniMT INFO HLT_g5_loose_L1EM3 #3230088967 TrigSignatureMoniMT INFO -- #3230088967 Events 20 20 10 10 10 2 - 2 TrigSignatureMoniMT INFO -- #3230088967 Features 15 15 31 2 - diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/photon.withViews.py b/Trigger/TrigValidation/TrigUpgradeTest/share/photon.withViews.py index ae7b2636702..e6728c83928 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/share/photon.withViews.py +++ b/Trigger/TrigValidation/TrigUpgradeTest/share/photon.withViews.py @@ -18,7 +18,7 @@ trigL2CaloRingerFexMT = init_ringer() from AthenaCommon.CFElements import parOR, seqOR, seqAND, stepSeq, findAlgorithm from DecisionHandling.DecisionHandlingConf import RoRSeqFilter, DumpDecisions -from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm +from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool def createFastCaloSequence(rerun=False): @@ -40,17 +40,18 @@ def createFastCaloSequence(rerun=False): fastCaloViewsMaker = EventViewCreatorAlgorithm( __prefix+"fastCaloViewsMaker" ) fastCaloViewsMaker.ViewFallThrough = True fastCaloViewsMaker.InputMakerInputDecisions = [ __forViewDecsions ] - fastCaloViewsMaker.RoIsLink = "initialRoI" # -||- - fastCaloViewsMaker.InViewRoIs = "EMCaloRoIs" # contract with the fastCalo + fastCaloViewsMaker.RoIsLink = "initialRoI" + fastCaloViewsMaker.RoITool = ViewCreatorInitialROITool() + fastCaloViewsMaker.InViewRoIs = "EMCaloRoIs" fastCaloViewsMaker.Views = __prefix+"EMCaloViews" fastCaloViewsMaker.ViewNodeName = __prefix+"fastCaloInViewAlgs" - fastCaloViewsMaker.InputMakerOutputDecisions = [ "L2CaloLinks"] + fastCaloViewsMaker.InputMakerOutputDecisions = "L2CaloLinks" clusterMaker.RoIs = fastCaloViewsMaker.InViewRoIs from TrigEgammaHypo.TrigEgammaHypoConf import TrigL2CaloHypoAlgMT from TrigEgammaHypo.TrigL2CaloHypoTool import TrigL2CaloHypoToolFromName fastCaloHypo = TrigL2CaloHypoAlgMT( __prefix+"L2CaloHypo" ) - fastCaloHypo.HypoInputDecisions = fastCaloViewsMaker.InputMakerOutputDecisions[0] # __l1RoIDecisions + fastCaloHypo.HypoInputDecisions = fastCaloViewsMaker.InputMakerOutputDecisions # __l1RoIDecisions # fastCaloHypo.Views = fastCaloViewsMaker.Views fastCaloHypo.CaloClusters = clusterMaker.ClustersName # fastCaloHypo.RoIs = fastCaloViewsMaker.InViewRoIs diff --git a/Trigger/TrigValidation/TrigUpgradeTest/src/TestInputMaker.cxx b/Trigger/TrigValidation/TrigUpgradeTest/src/TestInputMaker.cxx index 4644a942119..33936a0e6c7 100644 --- a/Trigger/TrigValidation/TrigUpgradeTest/src/TestInputMaker.cxx +++ b/Trigger/TrigValidation/TrigUpgradeTest/src/TestInputMaker.cxx @@ -38,8 +38,8 @@ namespace HLTTest { ATH_MSG_DEBUG( "Executing " << name() << "..." ); // call base class helper method to read input decisions, loop over them create outputs and connect them, returns with outputHandles filled - std::vector< SG::WriteHandle<TrigCompositeUtils::DecisionContainer> > outputHandles; - CHECK (decisionInputToOutput(context, outputHandles)); + SG::WriteHandle<DecisionContainer> outputHandle = createAndStore( decisionOutputs(), context ); + CHECK (decisionInputToOutput(context, outputHandle)); // output collection, as a view container so it can be given const features auto reco_output = std::make_unique<xAOD::TrigCompositeContainer>(); @@ -48,54 +48,52 @@ namespace HLTTest { std::vector<const FeatureOBJ*> featuresFromDecision; // used to check for duplicate features linked to different inputHandles // loop over output decisions, navigate to inputs - for (auto outputHandle: outputHandles) { - if( not outputHandle.isValid() ) { - ATH_MSG_DEBUG( "TestInputMaker: Got no decisions from output "<< outputHandle.key() << " because handle not valid"); - continue; - } - if( outputHandle->size() == 0){ // input filtered out - ATH_MSG_ERROR( "TestInputMaker: Got no decisions from output "<< outputHandle.key()<<": handle is valid but container is empty. Is this expected?"); - return StatusCode::FAILURE; - } - - ATH_MSG_DEBUG( "TestInputMaker: Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); - // loop over output decisions in container of outputHandle, follow link to inputDecision - int count =0; - for (const auto outputDecision : *outputHandle){ - const ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); - ATH_MSG_DEBUG("Element "<< count << " has " << inputLinks.size() <<" previous links"); - for (const auto input: inputLinks){ - ATH_MSG_DEBUG( " -- Got seed link to input "<<input.dataID() <<" and index "<< input.index() ); - const Decision* inputDecision = *input; - const auto roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( inputDecision, m_roisLink.value()); - CHECK( roiELInfo.isValid() ); - - // retrieve input feature from input decision (TrigComposite), will in this case be a TrigRoiDescriptor - const auto featureLinkInfo = TrigCompositeUtils::findLink<FeatureContainer>( inputDecision, m_linkName.value()); - CHECK( featureLinkInfo.isValid() ); - - // link input reco object to outputDecision - const auto featureLink = featureLinkInfo.link; - const FeatureOBJ* feature = *featureLink; - ATH_MSG_DEBUG(" -- Found feature " <<m_linkName.value() <<":" << **featureLink); - - // merge reco outputs that are linked to the same feature (RoI): this avoids processing the same RoI from TC decisions from different chains - - // avoid adding the same feature multiple times: check if not in container, if not add it - if ( find(featuresFromDecision.begin(), featuresFromDecision.end(), feature) == featuresFromDecision.end() ){ - featuresFromDecision.push_back(feature); // just to keep track of which we have used - // create the "reco" output: this would normally be a copy of the reco input or something derived from it, e.g. detector data inside a RoI. A TrigComposite is used here just for a trivial example. - auto newFeature = new xAOD::TrigComposite; - reco_output->push_back(newFeature); - newFeature->setObjectLink(m_linkName.value(), featureLink); - ATH_MSG_DEBUG(" -- Added " <<m_linkName.value() << " and " << m_roisLink.value() << " to reco object"); - } - }//loop over previous inputs - // For early tests, create TC, link to RoiD, push back onto TCC. - // Later will output RoID collection directly via tool. - count++; - } // loop over decisions - } // loop over output keys + if( not outputHandle.isValid() ) { + ATH_MSG_ERROR( "TestInputMaker: Got no decisions from output "<< outputHandle.key() << " because handle not valid"); + return StatusCode::FAILURE; + } + if( outputHandle->size() == 0){ // input filtered out + ATH_MSG_ERROR( "TestInputMaker: Got no decisions from output "<< outputHandle.key()<<": handle is valid but container is empty."); + return StatusCode::FAILURE; + } + + ATH_MSG_DEBUG( "TestInputMaker: Got output "<< outputHandle.key()<<" with " << outputHandle->size() << " elements" ); + // loop over output decisions in container of outputHandle, follow link to inputDecision + int count =0; + for (const auto outputDecision : *outputHandle){ + const ElementLinkVector<DecisionContainer> inputLinks = getLinkToPrevious(outputDecision); + ATH_MSG_DEBUG("Element "<< count << " has " << inputLinks.size() <<" previous links"); + for (const auto input: inputLinks){ + ATH_MSG_DEBUG( " -- Got seed link to input "<<input.dataID() <<" and index "<< input.index() ); + const Decision* inputDecision = *input; + const auto roiELInfo = TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>( inputDecision, m_roisLink.value()); + CHECK( roiELInfo.isValid() ); + + // retrieve input feature from input decision (TrigComposite), will in this case be a TrigRoiDescriptor + const auto featureLinkInfo = TrigCompositeUtils::findLink<FeatureContainer>( inputDecision, m_linkName.value()); + CHECK( featureLinkInfo.isValid() ); + + // link input reco object to outputDecision + const auto featureLink = featureLinkInfo.link; + const FeatureOBJ* feature = *featureLink; + ATH_MSG_DEBUG(" -- Found feature " <<m_linkName.value() <<":" << **featureLink); + + // merge reco outputs that are linked to the same feature (RoI): this avoids processing the same RoI from TC decisions from different chains + + // avoid adding the same feature multiple times: check if not in container, if not add it + if ( find(featuresFromDecision.begin(), featuresFromDecision.end(), feature) == featuresFromDecision.end() ){ + featuresFromDecision.push_back(feature); // just to keep track of which we have used + // create the "reco" output: this would normally be a copy of the reco input or something derived from it, e.g. detector data inside a RoI. A TrigComposite is used here just for a trivial example. + auto newFeature = new xAOD::TrigComposite; + reco_output->push_back(newFeature); + newFeature->setObjectLink(m_linkName.value(), featureLink); + ATH_MSG_DEBUG(" -- Added " <<m_linkName.value() << " and " << m_roisLink.value() << " to reco object"); + } + }//loop over previous inputs + // For early tests, create TC, link to RoiD, push back onto TCC. + // Later will output RoID collection directly via tool. + count++; + } // loop over decisions // Finally, record output ATH_MSG_DEBUG("Produced "<<reco_output->size() <<" reco objects and stored in "<<m_recoOutput); @@ -103,7 +101,7 @@ namespace HLTTest { CHECK( reco_outputHandle.record(std::move(reco_output), std::move(aux)) ); // call base class helper method to print some debug messages summarising the content of the outputHandles. - if (msgLvl(MSG::DEBUG)) debugPrintOut(context, outputHandles); + if (msgLvl(MSG::DEBUG)) debugPrintOut(context, outputHandle); return StatusCode::SUCCESS; } diff --git a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref index a864297a165..a9c40f9d240 100644 --- a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref +++ b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref @@ -19,27 +19,12 @@ TrigSignatureMoniMT INFO -- #3965466087 Features TrigSignatureMoniMT INFO HLT_2j330_a10t_lcw_jes_35smcINF_L1J100 #1295975955 TrigSignatureMoniMT INFO -- #1295975955 Events 20 20 0 - - - - 0 TrigSignatureMoniMT INFO -- #1295975955 Features 0 - - - - -TrigSignatureMoniMT INFO HLT_2mu10_bJpsimumu_L12MU10 #3498558358 -TrigSignatureMoniMT INFO -- #3498558358 Events 20 20 0 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #3498558358 Features 0 0 0 0 0 -TrigSignatureMoniMT INFO HLT_2mu10_bUpsimumu_L12MU10 #234102568 -TrigSignatureMoniMT INFO -- #234102568 Events 20 20 0 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #234102568 Features 0 0 0 0 0 TrigSignatureMoniMT INFO HLT_2mu14_L12MU10 #2619091790 TrigSignatureMoniMT INFO -- #2619091790 Events 20 20 0 0 0 0 - 0 TrigSignatureMoniMT INFO -- #2619091790 Features 0 0 0 0 - TrigSignatureMoniMT INFO HLT_2mu15_L12MU10 #557204938 TrigSignatureMoniMT INFO -- #557204938 Events 20 20 0 0 0 0 - 0 TrigSignatureMoniMT INFO -- #557204938 Features 0 0 0 0 - -TrigSignatureMoniMT INFO HLT_2mu4_bDimu_L12MU4 #1730084172 -TrigSignatureMoniMT INFO -- #1730084172 Events 20 20 1 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #1730084172 Features 4 0 0 0 0 -TrigSignatureMoniMT INFO HLT_2mu4_bJpsimumu_L12MU4 #4276347155 -TrigSignatureMoniMT INFO -- #4276347155 Events 20 20 1 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #4276347155 Features 4 0 0 0 0 -TrigSignatureMoniMT INFO HLT_2mu4_bUpsimumu_L12MU4 #4008168535 -TrigSignatureMoniMT INFO -- #4008168535 Events 20 20 1 0 0 0 0 0 -TrigSignatureMoniMT INFO -- #4008168535 Features 4 0 0 0 0 TrigSignatureMoniMT INFO HLT_2mu4_muonqual_L12MU4 #1584776935 TrigSignatureMoniMT INFO -- #1584776935 Events 20 20 1 0 0 0 - 0 TrigSignatureMoniMT INFO -- #1584776935 Features 4 0 0 0 - @@ -138,7 +123,7 @@ TrigSignatureMoniMT INFO -- #471243435 Events TrigSignatureMoniMT INFO -- #471243435 Features 41 41 50 - - TrigSignatureMoniMT INFO HLT_g5_etcut_LArPEB_L1EM3 #3486231698 TrigSignatureMoniMT INFO -- #3486231698 Events 20 20 13 13 13 13 - 13 -TrigSignatureMoniMT INFO -- #3486231698 Features 41 41 50 50 - +TrigSignatureMoniMT INFO -- #3486231698 Features 41 41 50 36 - TrigSignatureMoniMT INFO HLT_g5_loose_L1EM3 #3230088967 TrigSignatureMoniMT INFO -- #3230088967 Events 20 20 10 10 10 2 - 2 TrigSignatureMoniMT INFO -- #3230088967 Features 15 15 31 2 - diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bjet/BjetSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bjet/BjetSequenceSetup.py index e8fb8a48611..f5451678be4 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bjet/BjetSequenceSetup.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bjet/BjetSequenceSetup.py @@ -31,8 +31,9 @@ def bJetStep1Sequence(): jetsKey = "HLT_AntiKt4EMTopoJets_subjesgscIS_ftf" prmVtxKey = "HLT_EFHistoPrmVtx" - from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm + from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool InputMakerAlg = EventViewCreatorAlgorithm( "IMBJet_step2", RoIsLink="initialRoI" ) + InputMakerAlg.RoITool = ViewCreatorInitialROITool() InputMakerAlg.Views = "FullScanBjetView" InputMakerAlg.InViewRoIs = "FullScanRoI" InputMakerAlg.ViewFallThrough = True @@ -80,10 +81,11 @@ def bJetStep2Sequence(): roisLink = "step1RoI" prmVtxKey = "HLT_EFHistoPrmVtx" - from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithmWithJets + from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithmWithJets, ViewCreatorInitialROITool InputMakerAlg = EventViewCreatorAlgorithmWithJets( "IMBJet_step3",RoIsLink=roisLink ) InputMakerAlg.ViewFallThrough = True InputMakerAlg.RequireParentView = True + InputMakerAlg.RoITool = ViewCreatorInitialROITool() # NOT USED! TO BE REPLACED WITH NEW TOOL ON CONVERTING EventViewCreatorAlgorithmWithJets -> EventViewCreatorAlgorithm InputMakerAlg.Views = "BTagViews" InputMakerAlg.InViewRoIs = "InViewRoIs" InputMakerAlg.InViewJets = "InViewJets" diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/BphysicsSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/BphysicsSequenceSetup.py index a1a09560664..d20b32d7a32 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/BphysicsSequenceSetup.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Bphysics/BphysicsSequenceSetup.py @@ -25,7 +25,7 @@ def dimuL2Sequence(name = 'Dimu'): def dimuEFSequence(name = 'Dimu'): from AthenaCommon import CfgMgr from AthenaCommon.CFElements import parOR, seqAND - from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm + from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool from TriggerMenuMT.HLTMenuConfig.Muon.MuonSetup import muonNames muNames = muonNames().getNames('RoI') @@ -34,8 +34,9 @@ def dimuEFSequence(name = 'Dimu'): dimuefViewsMaker = EventViewCreatorAlgorithm('IMdimuef') dimuefViewsMaker.ViewFallThrough = True - dimuefViewsMaker.RoIsLink = 'initialRoI' # -||- - dimuefViewsMaker.InViewRoIs = 'DimuEFRoIs' # contract with the consumer + dimuefViewsMaker.RoIsLink = 'initialRoI' + dimuefViewsMaker.RoITool = ViewCreatorInitialROITool() + dimuefViewsMaker.InViewRoIs = 'DimuEFRoIs' dimuefViewsMaker.Views = 'DimuEFViewRoIs' dimuefViewsMaker.ViewNodeName = dimuefRecoSequence.name() dimuefViewsMaker.RequireParentView = True diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/BeamspotChainConfiguration.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/BeamspotChainConfiguration.py index 1fb9bbcb10b..59fddf42bc7 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/BeamspotChainConfiguration.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/BeamspotChainConfiguration.py @@ -9,7 +9,7 @@ from TrigStreamerHypo.TrigStreamerHypoConfigMT import StreamerHypoToolMTgenerato from TrigStreamerHypo.TrigStreamerHypoConf import TrigStreamerHypoAlgMT from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence from AthenaCommon.CFElements import seqAND -from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm +from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool #---------------------------------------------------------------- @@ -25,8 +25,9 @@ def allTE_trkfast_Cfg( flags ): def allTE_trkfast(): inputMakerAlg = EventViewCreatorAlgorithm("IM_beamspot") inputMakerAlg.ViewFallThrough = True - inputMakerAlg.RoIsLink = "initialRoI" # -||- - inputMakerAlg.InViewRoIs = "beamspotInputRoIs" # contract with the consumer + inputMakerAlg.RoIsLink = "initialRoI" + inputMakerAlg.RoITool = ViewCreatorInitialROITool() + inputMakerAlg.InViewRoIs = "beamspotInputRoIs" inputMakerAlg.Views = "beamspotViewRoIs" from TrigInDetConfig.InDetSetup import makeInDetAlgs diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/StreamingChainConfiguration.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/StreamingChainConfiguration.py index fbe4ee4bfc4..c8ffd0373c1 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/StreamingChainConfiguration.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CalibCosmicMon/StreamingChainConfiguration.py @@ -22,7 +22,7 @@ def StreamingSequenceCfg( flags ): def StreamingMenuSequence(): - inputMakerAlg = InputMakerForRoI("IM_streamerInputMaker", mergeOutputs=False) + inputMakerAlg = InputMakerForRoI("IM_streamerInputMaker") inputMakerAlg.RoIs="streamerInputRoIs" streamingSequence = seqAND("streamerSequence", [inputMakerAlg]) diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/EventBuildingSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/EventBuildingSequenceSetup.py index eb25a96e8ed..75772095f5e 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/EventBuildingSequenceSetup.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/CommonSequences/EventBuildingSequenceSetup.py @@ -81,7 +81,7 @@ def pebInfoWriterTool(name, eventBuildType): def pebInputMaker(eventBuildType): - maker = InputMakerForRoI("IMpeb_"+eventBuildType, mergeOutputs=False) + maker = InputMakerForRoI("IMpeb_"+eventBuildType) maker.RoIs = "pebInputRoI_" + eventBuildType return maker diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/ElectronSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/ElectronSequenceSetup.py index b4cd900b24d..037e16318f5 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/ElectronSequenceSetup.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/ElectronSequenceSetup.py @@ -11,7 +11,7 @@ from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence, RecoFr # Until such time as FS and RoI collections do not interfere, a hacky fix #from AthenaCommon.CFElements import parOR, seqAND from AthenaCommon.CFElements import seqAND -from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm +from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool from TrigEDMConfig.TriggerEDMRun3 import recordable def fastElectronSequence(ConfigFlags): @@ -42,7 +42,8 @@ def fastElectronSequence(ConfigFlags): # EVCreator: l2ElectronViewsMaker = EventViewCreatorAlgorithm("IMl2Electron") - l2ElectronViewsMaker.RoIsLink = "initialRoI" # -||- + l2ElectronViewsMaker.RoIsLink = "initialRoI" + l2ElectronViewsMaker.RoITool = ViewCreatorInitialROITool() l2ElectronViewsMaker.InViewRoIs = RoIs l2ElectronViewsMaker.Views = "EMElectronViews" l2ElectronViewsMaker.ViewFallThrough = True diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PhotonSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PhotonSequenceSetup.py index db780b12566..bdfc11fa958 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PhotonSequenceSetup.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PhotonSequenceSetup.py @@ -3,7 +3,7 @@ # menu components from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence, RecoFragmentsPool from AthenaCommon.CFElements import parOR, seqAND -from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm +from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool import AthenaCommon.CfgMgr as CfgMgr from TrigEDMConfig.TriggerEDMRun3 import recordable @@ -29,6 +29,7 @@ def fastPhotonMenuSequence(): l2PhotonViewsMaker.RoIsLink = "initialRoI" l2PhotonViewsMaker.InViewRoIs = "EMIDRoIs" #l2PhotonViewsMaker.InViewRoIs = "EMCaloRoIs" + l2PhotonViewsMaker.RoITool = ViewCreatorInitialROITool() l2PhotonViewsMaker.Views = "EMPhotonViews" l2PhotonViewsMaker.ViewFallThrough = True l2PhotonViewsMaker.RequireParentView = True @@ -67,7 +68,8 @@ def precisionPhotonSequence(ConfigFlags): precisionPhotonViewsMaker = EventViewCreatorAlgorithm( "IMprecisionPhoton") precisionPhotonViewsMaker.ViewFallThrough = True precisionPhotonViewsMaker.RequireParentView = True - precisionPhotonViewsMaker.RoIsLink = "initialRoI" # + precisionPhotonViewsMaker.RoIsLink = "initialRoI" # ROI link used to merge inputs + precisionPhotonViewsMaker.RoITool = ViewCreatorInitialROITool() # Tool used to supply ROIs for EventViews precisionPhotonViewsMaker.InViewRoIs = InViewRoIs # names to use for the collection of which the RoIs are picked up precisionPhotonViewsMaker.Views = "precisionPhotonViews" # Output container which has the view objects diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PrecisionCaloSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PrecisionCaloSequenceSetup.py index fd30c985f25..16ffb099d64 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PrecisionCaloSequenceSetup.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PrecisionCaloSequenceSetup.py @@ -5,7 +5,7 @@ # menu components from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence, RecoFragmentsPool from AthenaCommon.CFElements import seqAND -from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm +from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool from AthenaConfiguration.AllConfigFlags import ConfigFlags from TrigEDMConfig.TriggerEDMRun3 import recordable @@ -20,6 +20,7 @@ def precisionCaloSequence(ConfigFlags): precisionCaloViewsMaker = EventViewCreatorAlgorithm( "IMprecisionCalo") precisionCaloViewsMaker.ViewFallThrough = True precisionCaloViewsMaker.RoIsLink = "initialRoI" + precisionCaloViewsMaker.RoITool = ViewCreatorInitialROITool() precisionCaloViewsMaker.InViewRoIs = InViewRoIs precisionCaloViewsMaker.Views = "precisionCaloViews" precisionCaloViewsMaker.RequireParentView = True diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PrecisionElectronSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PrecisionElectronSequenceSetup.py index a4cd9177ae0..ef6f786ca71 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PrecisionElectronSequenceSetup.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Egamma/PrecisionElectronSequenceSetup.py @@ -7,7 +7,7 @@ from AthenaConfiguration.AllConfigFlags import ConfigFlags # menu components from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import MenuSequence, RecoFragmentsPool from AthenaCommon.CFElements import parOR, seqAND -from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm +from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool def precisionElectronSequence(ConfigFlags): @@ -15,8 +15,9 @@ def precisionElectronSequence(ConfigFlags): InViewRoIs = "precisionElectron" # EVCreator: precisionTrackViewsMaker = EventViewCreatorAlgorithm("IMprecisionTrack") - precisionTrackViewsMaker.RoIsLink = "initialRoI" # -||- - precisionTrackViewsMaker.InViewRoIs = InViewRoIs # contract with the precisionCalo + precisionTrackViewsMaker.RoIsLink = "initialRoI" + precisionTrackViewsMaker.RoITool = ViewCreatorInitialROITool() + precisionTrackViewsMaker.InViewRoIs = InViewRoIs precisionTrackViewsMaker.Views = "precisionElectronViews" #precisionTrackViews precisionTrackViewsMaker.ViewFallThrough = True precisionTrackViewsMaker.RequireParentView = True diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/CFValidation.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/CFValidation.py index 948cca5d5ca..7425df5cdff 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/CFValidation.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/CFValidation.py @@ -76,6 +76,9 @@ def checkVDV( inputNodes, ancestorNames, allEVCAs ): raise RuntimeError( "Found duplicate view node name " + node.ViewNodeName + " configured for EVCAs " + node.name() + " and " + allEVCAs[ node.ViewNodeName ].name() ) allEVCAs[ node.ViewNodeName ] = node + if not hasattr(node, "RoITool"): + raise RuntimeError( "Node name " + node.name() + " was not supplied with a RoITool" ) + # Explore nested CF if isSequence( node ): diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py index 577b0256e59..e9be877863f 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py @@ -14,7 +14,8 @@ from TriggerMenuMT.HLTMenuConfig.Menu.MenuPrescaleConfig import addSliceChainsTo import TriggerMenuMT.HLTMenuConfig.Menu.MC_pp_run3_v1 as mc_menu import TriggerMenuMT.HLTMenuConfig.Menu.PhysicsP1_pp_run3_v1 as p1_menu -from TriggerMenuMT.HLTMenuConfig.Menu.Physics_pp_run3_v1 import PhysicsStream,SingleMuonGroup,MultiMuonGroup,SingleElectronGroup,MultiElectronGroup,SinglePhotonGroup,MultiPhotonGroup,SingleMETGroup,MultiMETGroup,SingleJetGroup,MultiJetGroup,SingleBjetGroup,SingleTauGroup,EgammaStreamersGroup,MinBiasGroup,BphysicsGroup +from TriggerMenuMT.HLTMenuConfig.Menu.Physics_pp_run3_v1 import PhysicsStream,SingleMuonGroup,MultiMuonGroup,SingleElectronGroup,MultiElectronGroup,SinglePhotonGroup,MultiPhotonGroup,SingleMETGroup,MultiMETGroup,SingleJetGroup,MultiJetGroup,SingleBjetGroup,SingleTauGroup,EgammaStreamersGroup,MinBiasGroup +#BphysicsGroup (re-add to the preceding line when putting bphys back in) def setupMenu(): @@ -179,12 +180,13 @@ def setupMenu(): ChainProp(name="HLT_tau160_perf_tracktwoMVA_L1TAU100",groups=SingleTauGroup), ] + # TimM temporary disable due to !31039 TriggerFlags.BphysicsSlice.signatures = TriggerFlags.BphysicsSlice.signatures() + [ - #ATR 20603 - ChainProp(name='HLT_2mu4_bJpsimumu_L12MU4', groups=BphysicsGroup), - ChainProp(name='HLT_2mu4_bUpsimumu_L12MU4', groups=BphysicsGroup), - #ATR-20839 - ChainProp(name='HLT_2mu4_bDimu_L12MU4', groups=BphysicsGroup), + # #ATR 20603 + # ChainProp(name='HLT_2mu4_bJpsimumu_L12MU4', groups=BphysicsGroup), + # ChainProp(name='HLT_2mu4_bUpsimumu_L12MU4', groups=BphysicsGroup), + # #ATR-20839 + # ChainProp(name='HLT_2mu4_bDimu_L12MU4', groups=BphysicsGroup), ] TriggerFlags.CombinedSlice.signatures = TriggerFlags.CombinedSlice.signatures() + [ ] diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py index e68b209822c..16c8845094e 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/MenuComponents.py @@ -872,13 +872,14 @@ class InViewReco( ComponentAccumulator ): self.mainSeq = seqAND( name ) self.addSequence( self.mainSeq ) - from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm + from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool if viewMaker: self.viewMakerAlg = viewMaker else: self.viewMakerAlg = EventViewCreatorAlgorithm("IM"+name, ViewFallThrough = True, - RoIsLink = 'initialRoI', # -||- + RoIsLink = 'initialRoI', + RoITool = ViewCreatorInitialROITool(), InViewRoIs = name+'RoIs', Views = name+'Views', ViewNodeName = name+"InView") @@ -894,7 +895,7 @@ class InViewReco( ComponentAccumulator ): def addInput(self, inKey, outKey ): """Adds input (DecisionsContainer) from which the views should be created """ self.viewMakerAlg.InputMakerInputDecisions += [ inKey ] - self.viewMakerAlg.InputMakerOutputDecisions += [ outKey ] + self.viewMakerAlg.InputMakerOutputDecisions = outKey def mergeReco( self, ca ): """ Merged CA movnig reconstruction algorithms into the right sequence """ diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/Physics_pp_run3_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/Physics_pp_run3_v1.py index b99541be336..b0b1833308e 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/Physics_pp_run3_v1.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/Physics_pp_run3_v1.py @@ -102,10 +102,11 @@ def setupMenu(): #ATR-20049 ChainProp(name="HLT_tau160_mediumRNN_tracktwoMVA_L1TAU100", groups=SingleTauGroup), ] + # TimM temporary disable due to !31039 TriggerFlags.BphysicsSlice.signatures = [ #ATR-20049 - ChainProp(name='HLT_2mu10_bJpsimumu_L12MU10', groups=BphysicsGroup), - ChainProp(name='HLT_2mu10_bUpsimumu_L12MU10', groups=BphysicsGroup), + # ChainProp(name='HLT_2mu10_bJpsimumu_L12MU10', groups=BphysicsGroup), + # ChainProp(name='HLT_2mu10_bUpsimumu_L12MU10', groups=BphysicsGroup), ] TriggerFlags.CombinedSlice.signatures = [ ChainProp(name='HLT_e3_etcut1step_mu6fast_L1EM8I_MU10', l1SeedThresholds=['EM8I', 'MU10'], stream=[PhysicsStream], groups=MultiElectronGroup), #L1 item thresholds in wrong order (EM first, then MU) diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MinBias/MinBiasChainConfiguration.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MinBias/MinBiasChainConfiguration.py index 68621f9d2e3..91bfb8e08cb 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MinBias/MinBiasChainConfiguration.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/MinBias/MinBiasChainConfiguration.py @@ -17,7 +17,7 @@ def MinBiasSequenceCfg( flags ): def MinBiasMenuSequence(): - inputMakerAlg = InputMakerForRoI("IM_minbiasInputMaker", mergeOutputs=False) + inputMakerAlg = InputMakerForRoI("IM_minbiasInputMaker") inputMakerAlg.RoIs="minbiasInputRoIs" class MinBiasChainConfig(ChainConfigurationBase): diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py index 0ef2d6c50e0..155dcc12e10 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Muon/MuonSequenceSetup.py @@ -24,7 +24,7 @@ muonCombinedRecFlags.doStatisticalCombination = False muonCombinedRecFlags.doCombinedFit = True muonRecFlags.enableErrorTuning = False -from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm +from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool, ViewCreatorPreviousROITool #muon container names (for RoI based sequences) from TriggerMenuMT.HLTMenuConfig.Muon.MuonSetup import muonNames @@ -37,8 +37,9 @@ def muFastAlgSequence(ConfigFlags): ### set the EVCreator ### l2MuViewsMaker = EventViewCreatorAlgorithm("IMl2Mu") l2MuViewsMaker.ViewFallThrough = True - l2MuViewsMaker.RoIsLink = "initialRoI" # -||- - l2MuViewsMaker.InViewRoIs = "MURoIs" # contract with the consumer + l2MuViewsMaker.RoIsLink = "initialRoI" + l2MuViewsMaker.RoITool = ViewCreatorInitialROITool() + l2MuViewsMaker.InViewRoIs = "MURoIs" l2MuViewsMaker.Views = "MUViewRoIs" ### get muFast reco sequence ### @@ -102,7 +103,8 @@ def muCombAlgSequence(ConfigFlags): ### set the EVCreator ### l2muCombViewsMaker = EventViewCreatorAlgorithm("IMl2muComb") l2muCombViewsMaker.ViewFallThrough = True #if this needs to access anything from the previous step, from within the view - l2muCombViewsMaker.RoIsLink = "roi" # setting to RoI updated L2MuonSA + l2muCombViewsMaker.RoIsLink = "roi" # setting to RoI updated L2MuonSA. Used in merging to determin identical Decision objects + l2muCombViewsMaker.RoITool = ViewCreatorPreviousROITool() # Use the "roi" link from the previous step when spawning new view l2muCombViewsMaker.InViewRoIs = "MUIDRoIs" #name of the RoIS inside of the view, because in principle we can have more than one RoI/view l2muCombViewsMaker.Views = "MUCombViewRoIs" #output of the views maker (key in "storegate") l2muCombViewsMaker.RequireParentView = True @@ -117,7 +119,8 @@ def muCombAlgSequence(ConfigFlags): muonChainFilter = MuonChainFilterAlg("FilterBphysChains") bphysChains =getBphysChainNames() muonChainFilter.ChainsToFilter=bphysChains - muonChainFilter.InputDecisions = l2muCombViewsMaker.InputMakerOutputDecisions + if hasattr(l2muCombViewsMaker, "InputMakerOutputDecisions"): + muonChainFilter.InputDecisions = [ l2muCombViewsMaker.InputMakerOutputDecisions ] muonChainFilter.L2MuCombContainer = sequenceOut muCombFilterSequence = seqAND("l2muCombFilterSequence", [muonChainFilter, muCombRecoSequence]) @@ -182,8 +185,9 @@ def muEFSAAlgSequence(ConfigFlags): efsaViewsMaker = EventViewCreatorAlgorithm("IMefsa") efsaViewsMaker.ViewFallThrough = True - efsaViewsMaker.RoIsLink = "roi" # -||- - efsaViewsMaker.InViewRoIs = "MUEFSARoIs" # contract with the consumer + efsaViewsMaker.RoIsLink = "initialRoI" # Note: This is for L1-seeded muons, can use the "initialRoI" for input maker merging + efsaViewsMaker.RoITool = ViewCreatorPreviousROITool() # Use "roi" link to spawn views + efsaViewsMaker.InViewRoIs = "MUEFSARoIs" efsaViewsMaker.Views = "MUEFSAViewRoIs" efsaViewsMaker.RequireParentView = True @@ -244,8 +248,9 @@ def muEFCBAlgSequence(ConfigFlags): efcbViewsMaker = EventViewCreatorAlgorithm("IMefcbtotal") efcbViewsMaker.ViewFallThrough = True - efcbViewsMaker.RoIsLink = "roi" # -||- - efcbViewsMaker.InViewRoIs = "MUEFCBRoIs" # contract with the consumer + efcbViewsMaker.RoIsLink = "roi" + efcbViewsMaker.RoITool = ViewCreatorPreviousROITool() # Use "roi" link to spawn views + efcbViewsMaker.InViewRoIs = "MUEFCBRoIs" efcbViewsMaker.Views = "MUEFCBViewRoIs" efcbViewsMaker.RequireParentView = True @@ -306,8 +311,9 @@ def muEFCBInvMassSequence(): invMViewsMaker = EventViewCreatorAlgorithm("IMmuinvm") invMViewsMaker.ViewFallThrough = True - invMViewsMaker.RoIsLink = "initialRoI" # -||- - invMViewsMaker.InViewRoIs = "muInvMRoIs" # contract with the consumer + invMViewsMaker.RoIsLink = "initialRoI" + invMViewsMaker.RoITool = ViewCreatorInitialROITool() + invMViewsMaker.InViewRoIs = "muInvMRoIs" invMViewsMaker.Views = "muInvMViewRoIs" invMViewsMaker.ViewNodeName = invMassRecoSequence.name() invMViewsMaker.RequireParentView = True @@ -336,6 +342,7 @@ def muEFSAFSAlgSequence(ConfigFlags): from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithmWithMuons efsafsInputMaker = EventViewCreatorAlgorithmWithMuons("IMMuonFS", RoIsLink="initialRoI") efsafsInputMaker.InViewRoIs = "MUFSRoIs" + efsafsInputMaker.RoITool = ViewCreatorInitialROITool() # NOT USED! TO BE REPLACED WITH NEW TOOL ON CONVERTING EventViewCreatorAlgorithmWithMuons -> EventViewCreatorAlgorithm efsafsInputMaker.Views = "MUFSViewRoI" efsafsInputMaker.ViewFallThrough=True efsafsInputMaker.CreateFSRoI=True @@ -376,10 +383,11 @@ def muEFCBFSAlgSequence(ConfigFlags): from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithmWithMuons efcbfsInputMaker = EventViewCreatorAlgorithmWithMuons("IMEFCBFS") efcbfsInputMaker.ViewFallThrough = True - efcbfsInputMaker.mergeOutputs = False + efcbfsInputMaker.mergeUsingFeature = True efcbfsInputMaker.Views = "MUCBFSViews" efcbfsInputMaker.InViewRoIs = "MUCBFSRoIs" efcbfsInputMaker.RoIsLink = "initialRoI" + efcbfsInputMaker.RoITool = ViewCreatorInitialROITool() # NOT USED! TO BE REPLACED WITH NEW TOOL ON CONVERTING EventViewCreatorAlgorithmWithMuons -> EventViewCreatorAlgorithm efcbfsInputMaker.InViewMuons = "InViewMuons" efcbfsInputMaker.MuonsLink = "feature" efcbfsInputMaker.RequireParentView = True @@ -417,8 +425,9 @@ def efLateMuRoIAlgSequence(ConfigFlags): eflateViewsMaker = EventViewCreatorAlgorithm("IMeflatemuroi") eflateViewsMaker.ViewFallThrough = True - eflateViewsMaker.RoIsLink = "initialRoI" # -||- - eflateViewsMaker.InViewRoIs = "MULATERoIs" # contract with the consumer + eflateViewsMaker.RoIsLink = "initialRoI" + eflateViewsMaker.RoITool = ViewCreatorInitialROITool() + eflateViewsMaker.InViewRoIs = "MULATERoIs" eflateViewsMaker.Views = "MULATEViewRoIs" @@ -454,8 +463,9 @@ def efLateMuAlgSequence(ConfigFlags): from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithmWithMuons eflateViewsMaker = EventViewCreatorAlgorithmWithMuons("IMeflatemu") eflateViewsMaker.ViewFallThrough = True - eflateViewsMaker.RoIsLink = "initialRoI" # -||- - eflateViewsMaker.InViewRoIs = "MUEFLATERoIs" # contract with the consumer + eflateViewsMaker.RoIsLink = "initialRoI" + eflateViewsMaker.InViewRoIs = "MUEFLATERoIs" + eflateViewsMaker.RoITool = ViewCreatorInitialROITool() # NOT USED! TO BE REPLACED WITH NEW TOOL ON CONVERTING EventViewCreatorAlgorithmWithMuons -> EventViewCreatorAlgorithm eflateViewsMaker.Views = "MUEFLATEViewRoIs" eflateViewsMaker.DoLateMu = True eflateViewsMaker.LateRoIsLink = "feature" @@ -501,8 +511,9 @@ def muIsoAlgSequence(ConfigFlags): l2muIsoViewsMaker = EventViewCreatorAlgorithm("IMl2muIso") l2muIsoViewsMaker.ViewFallThrough = True - l2muIsoViewsMaker.RoIsLink = "initialRoI" # -||- - l2muIsoViewsMaker.InViewRoIs = "MUIsoRoIs" # contract with the consumer + l2muIsoViewsMaker.RoIsLink = "initialRoI" + l2muIsoViewsMaker.RoITool = ViewCreatorInitialROITool() + l2muIsoViewsMaker.InViewRoIs = "MUIsoRoIs" l2muIsoViewsMaker.Views = "MUIsoViewRoIs" l2muIsoViewsMaker.RequireParentView = True @@ -542,14 +553,15 @@ def muEFIsoAlgSequence(ConfigFlags): from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithmWithMuons efmuIsoViewsMaker = EventViewCreatorAlgorithmWithMuons("IMefmuIso") efmuIsoViewsMaker.ViewFallThrough = True - efmuIsoViewsMaker.RoIsLink = "initialRoI" # -||- - efmuIsoViewsMaker.InViewRoIs = "MUEFIsoRoIs" # contract with the consumer + efmuIsoViewsMaker.RoIsLink = "initialRoI" + efmuIsoViewsMaker.RoITool = ViewCreatorInitialROITool() # NOT USED! TO BE REPLACED WITH NEW TOOL ON CONVERTING EventViewCreatorAlgorithmWithMuons -> EventViewCreatorAlgorithm + efmuIsoViewsMaker.InViewRoIs = "MUEFIsoRoIs" efmuIsoViewsMaker.Views = "MUEFIsoViewRoIs" efmuIsoViewsMaker.InViewMuons = "IsoViewMuons" efmuIsoViewsMaker.MuonsLink = "feature" efmuIsoViewsMaker.RoIEtaWidth=0.15 efmuIsoViewsMaker.RoIPhiWidth=0.15 - efmuIsoViewsMaker.mergeOutputs = False + efmuIsoViewsMaker.mergeUsingFeature = True efmuIsoViewsMaker.RoisWriteHandleKey = "IsoMuRoIs" efmuIsoViewsMaker.InViewMuonCandidates = "IsoMuonCandidates" diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Tau/TauRecoSequences.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Tau/TauRecoSequences.py index 9dfcf702fac..fb1e6c239bb 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Tau/TauRecoSequences.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Tau/TauRecoSequences.py @@ -3,7 +3,7 @@ # from AthenaCommon.CFElements import parOR, seqAND -from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm +from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm, ViewCreatorInitialROITool, ViewCreatorPreviousROITool from TrigT2CaloCommon.CaloDef import HLTLCTopoRecoSequence from TrigEDMConfig.TriggerEDMRun3 import recordable from TriggerMenuMT.HLTMenuConfig.Menu.MenuComponents import RecoFragmentsPool @@ -130,6 +130,7 @@ def tauCaloSequence(ConfigFlags): tauCaloViewsMaker = EventViewCreatorAlgorithm( "IMtauCalo") tauCaloViewsMaker.ViewFallThrough = True tauCaloViewsMaker.RoIsLink = "initialRoI" + tauCaloViewsMaker.RoITool = ViewCreatorInitialROITool() tauCaloViewsMaker.InViewRoIs = InViewRoIs tauCaloViewsMaker.Views = "TAUCaloViews" tauCaloViewsMaker.ViewNodeName = RecoSequenceName @@ -147,6 +148,7 @@ def tauCaloMVASequence(ConfigFlags): tauCaloMVAViewsMaker = EventViewCreatorAlgorithm( "IMtauCaloMVA") tauCaloMVAViewsMaker.ViewFallThrough = True tauCaloMVAViewsMaker.RoIsLink = "initialRoI" + tauCaloMVAViewsMaker.RoITool = ViewCreatorInitialROITool() tauCaloMVAViewsMaker.InViewRoIs = InViewRoIs tauCaloMVAViewsMaker.Views = "TAUCaloMVAViews" tauCaloMVAViewsMaker.ViewNodeName = RecoSequenceName @@ -291,7 +293,8 @@ def tauFTFTrackTwoSequence(ConfigFlags): RecoSequenceName = "tauFTFTrackTwoInViewSequence" ftfTrackTwoViewsMaker = EventViewCreatorAlgorithm("IMFTFTrackTwo") - ftfTrackTwoViewsMaker.RoIsLink = "roi" # -||- + ftfTrackTwoViewsMaker.RoIsLink = "roi" + ftfTrackTwoViewsMaker.RoITool = ViewCreatorPreviousROITool() ftfTrackTwoViewsMaker.InViewRoIs = "TIsoViewRoIs" # contract with the fast track core ftfTrackTwoViewsMaker.Views = "TAUFTFTrackTwoViews" ftfTrackTwoViewsMaker.ViewFallThrough = True @@ -308,7 +311,8 @@ def tauFTFTrackSequence(ConfigFlags): RecoSequenceName = "tauFTFTrackInViewSequence" ftfTrackViewsMaker = EventViewCreatorAlgorithm("IMFTFTrack") - ftfTrackViewsMaker.RoIsLink = "roi" # -||- + ftfTrackViewsMaker.RoIsLink = "roi" + ftfTrackViewsMaker.RoITool = ViewCreatorPreviousROITool() ftfTrackViewsMaker.InViewRoIs = "TIdViewRoIs" # contract with the fast track core ftfTrackViewsMaker.Views = "TAUFTFTrackViews" ftfTrackViewsMaker.ViewFallThrough = True @@ -325,7 +329,8 @@ def tauFTFIdSequence(ConfigFlags): RecoSequenceName = "tauFTFIdInViewSequence" ftfIdViewsMaker = EventViewCreatorAlgorithm("IMFTFId") - ftfIdViewsMaker.RoIsLink = "roi" # -||- + ftfIdViewsMaker.RoIsLink = "roi" + ftfIdViewsMaker.RoITool = ViewCreatorPreviousROITool() ftfIdViewsMaker.InViewRoIs = "TIdViewRoIs" # contract with the fast track core ftfIdViewsMaker.Views = "TAUFTFIdViews" ftfIdViewsMaker.ViewFallThrough = True @@ -342,8 +347,9 @@ def tauFTFCoreSequence(ConfigFlags): RecoSequenceName = "tauFTFCoreInViewSequence" ftfCoreViewsMaker = EventViewCreatorAlgorithm("IMFTFCore") - ftfCoreViewsMaker.RoIsLink = "roi" # -||- + ftfCoreViewsMaker.RoIsLink = "roi" ftfCoreViewsMaker.InViewRoIs = "TCoreViewRoIs" # contract with the fastCalo + ftfCoreViewsMaker.RoITool = ViewCreatorPreviousROITool() ftfCoreViewsMaker.Views = "TAUFTFCoreViews" ftfCoreViewsMaker.ViewFallThrough = True ftfCoreViewsMaker.RequireParentView = True @@ -359,7 +365,8 @@ def tauFTFIsoSequence(ConfigFlags): RecoSequenceName = "tauFTFIsoInViewSequence" ftfIsoViewsMaker = EventViewCreatorAlgorithm("IMFTFIso") - ftfIsoViewsMaker.RoIsLink = "roi" # -||- + ftfIsoViewsMaker.RoIsLink = "roi" + ftfIsoViewsMaker.RoITool = ViewCreatorPreviousROITool() ftfIsoViewsMaker.InViewRoIs = "TIsoViewRoIs" # contract with the fast track core ftfIsoViewsMaker.Views = "TAUFTFIsoViews" ftfIsoViewsMaker.ViewFallThrough = True @@ -376,7 +383,8 @@ def tauEFSequence(ConfigFlags): RecoSequenceName = "tauEFInViewSequence" efViewsMaker = EventViewCreatorAlgorithm("IMTauEF") - efViewsMaker.RoIsLink = "roi" # -||- + efViewsMaker.RoIsLink = "roi" + efViewsMaker.RoITool = ViewCreatorPreviousROITool() efViewsMaker.InViewRoIs = "TIsoViewRoIs" # contract with the fast track core efViewsMaker.Views = "TAUEFViews" efViewsMaker.ViewFallThrough = True -- GitLab