diff --git a/Trigger/TrigSteer/L1Decoder/python/L1DecoderConfig.py b/Trigger/TrigSteer/L1Decoder/python/L1DecoderConfig.py index 422f28bd146681137c8776c941a84716fefb3897..bcf84590999f0a96c1412654775bcde6d0748100 100644 --- a/Trigger/TrigSteer/L1Decoder/python/L1DecoderConfig.py +++ b/Trigger/TrigSteer/L1Decoder/python/L1DecoderConfig.py @@ -95,9 +95,22 @@ def createMuonRoIUnpackers(): return [muUnpacker],[muRerunUnpacker] +from L1Decoder.L1DecoderConf import L1TriggerResultMaker +class L1TriggerResultMaker(L1TriggerResultMaker): + def __init__(self, name='L1TriggerResultMaker', *args, **kwargs): + super(L1TriggerResultMaker, self).__init__(name, *args, **kwargs) -from L1Decoder.L1DecoderConf import L1Decoder + # Muon RoIs + self.MuRoIKey = "LVL1MuonRoIs" + self.MuRoILinkName = "mu_roi" + + # Placeholder for other L1 xAOD outputs: + # - CTP result + # - L1Topo result + # - L1Calo (Run3) RoIs + +from L1Decoder.L1DecoderConf import L1Decoder class L1Decoder(L1Decoder) : def __init__(self, name='L1Decoder', *args, **kwargs): super(L1Decoder, self).__init__(name, *args, **kwargs) @@ -167,11 +180,12 @@ def L1DecoderCfg(flags): acc.merge( TrigConfigSvcCfg( flags ) ) acc.merge( HLTPrescaleCondAlgCfg( flags ) ) - # Add the algorithm producing the input RoIBResult - from TrigT1ResultByteStream.TrigT1ResultByteStreamConfig import RoIBResultDecoderCfg, L1TriggerResultMakerCfg + # Add the algorithms producing the input RoIBResult (legacy L1) / L1TriggerResult (Run-3 L1) + from TrigT1ResultByteStream.TrigT1ResultByteStreamConfig import RoIBResultDecoderCfg, L1TriggerByteStreamDecoderCfg # TODO: implement flags to allow disabling either RoIBResult or L1TriggerResult acc.merge( RoIBResultDecoderCfg(flags) ) - acc.merge( L1TriggerResultMakerCfg(flags) ) + acc.merge( L1TriggerByteStreamDecoderCfg(flags) ) + acc.addEventAlgo( L1TriggerResultMaker() ) return acc,decoderAlg diff --git a/Trigger/TrigT1/TrigT1ResultByteStream/src/L1TriggerResultMaker.cxx b/Trigger/TrigSteer/L1Decoder/src/L1TriggerResultMaker.cxx similarity index 53% rename from Trigger/TrigT1/TrigT1ResultByteStream/src/L1TriggerResultMaker.cxx rename to Trigger/TrigSteer/L1Decoder/src/L1TriggerResultMaker.cxx index a11add6d1887c6310b21ca1dc3443688becb6c96..a58731242b331760d3966d99770f0c7ea8b872fb 100644 --- a/Trigger/TrigT1/TrigT1ResultByteStream/src/L1TriggerResultMaker.cxx +++ b/Trigger/TrigSteer/L1Decoder/src/L1TriggerResultMaker.cxx @@ -5,6 +5,19 @@ #include "L1TriggerResultMaker.h" #include "xAODTrigger/TrigCompositeAuxContainer.h" +namespace { + template<class T> void makeLink(const SG::ReadHandleKey<T>& rhk, + xAOD::TrigComposite& target, + const std::string& linkName, + const EventContext& eventContext) { + ElementLink<T> link = ElementLink<T>(rhk.key(), 0, eventContext); + target.typelessSetObjectLink(linkName, + link.key(), + ClassID_traits<T>::ID(), + /*index =*/ 0); + } +} + // ============================================================================= // Standard constructor // ============================================================================= @@ -17,18 +30,7 @@ L1TriggerResultMaker::L1TriggerResultMaker(const std::string& name, ISvcLocator* StatusCode L1TriggerResultMaker::initialize() { ATH_MSG_DEBUG("Initialising " << name()); ATH_CHECK(m_l1TriggerResultWHKey.initialize()); - ATH_CHECK(m_decoderTools.retrieve()); - ATH_CHECK(m_robDataProviderSvc.retrieve()); - return StatusCode::SUCCESS; -} - -// ============================================================================= -// Implementation of AthReentrantAlgorithm::finalize -// ============================================================================= -StatusCode L1TriggerResultMaker::finalize() { - ATH_MSG_DEBUG("Finalising " << name()); - ATH_CHECK(m_robDataProviderSvc.release()); - ATH_CHECK(m_decoderTools.release()); + ATH_CHECK(m_muRoIKey.initialize()); return StatusCode::SUCCESS; } @@ -39,27 +41,22 @@ StatusCode L1TriggerResultMaker::execute(const EventContext& eventContext) const ATH_MSG_DEBUG("Executing " << name()); // Create and record the L1TriggerResult container - SG::WriteHandle<xAOD::TrigCompositeContainer> handle(m_l1TriggerResultWHKey, eventContext); + SG::WriteHandle<xAOD::TrigCompositeContainer> l1trHandle(m_l1TriggerResultWHKey, eventContext); auto cont = std::make_unique<xAOD::TrigCompositeContainer>(); auto auxcont = std::make_unique<xAOD::TrigCompositeAuxContainer>(); cont->setStore(auxcont.get()); - ATH_CHECK(handle.record(std::move(cont), std::move(auxcont))); + ATH_CHECK(l1trHandle.record(std::move(cont), std::move(auxcont))); ATH_MSG_DEBUG("Recorded L1TriggerResult with key " << m_l1TriggerResultWHKey.key()); - // Retrieve the BS data and fill a new L1TriggerResult - IROBDataProviderSvc::VROBFRAG vrobf; - handle->push_back(new xAOD::TrigComposite); - for (const auto& decoderTool : m_decoderTools) { - vrobf.clear(); - m_robDataProviderSvc->getROBData(eventContext, decoderTool->robIds(), vrobf, name()); - ATH_CHECK(decoderTool->convert(vrobf, *(handle->back()), eventContext)); - // Verify if the link was created - if (!handle->back()->hasObjectLink(decoderTool->linkName())) { - ATH_MSG_ERROR("Decoder tool " << decoderTool.name() << " failed to link the xAOD RoI object to L1TriggerResult" - << " with the link name " << decoderTool->linkName()); - return StatusCode::FAILURE; - } - } + // Create new L1TriggerResult in the container + l1trHandle->push_back(new xAOD::TrigComposite); + + // Retrieve the L1 xAOD containers to verify they exist + auto muRoIHandle = SG::makeHandle(m_muRoIKey, eventContext); + ATH_CHECK(muRoIHandle.isValid()); + + // Link the L1 xAOD containers (actually their first elements) to L1TriggerResult + makeLink(m_muRoIKey, *(l1trHandle->back()), m_muRoILinkName.value(), eventContext); return StatusCode::SUCCESS; } diff --git a/Trigger/TrigT1/TrigT1ResultByteStream/src/L1TriggerResultMaker.h b/Trigger/TrigSteer/L1Decoder/src/L1TriggerResultMaker.h similarity index 58% rename from Trigger/TrigT1/TrigT1ResultByteStream/src/L1TriggerResultMaker.h rename to Trigger/TrigSteer/L1Decoder/src/L1TriggerResultMaker.h index 81c9a2471252076ddfc0ffee8ec1cb4f9795ccb1..be3e56030c30e13f060a65134db6569d8cafc0c3 100644 --- a/Trigger/TrigT1/TrigT1ResultByteStream/src/L1TriggerResultMaker.h +++ b/Trigger/TrigSteer/L1Decoder/src/L1TriggerResultMaker.h @@ -6,16 +6,16 @@ #define TRIGT1RESULTBYTESTREAM_L1TRIGGERRESULTMAKER_H // Trigger includes -#include "TrigT1ResultByteStream/IL1TriggerByteStreamTool.h" +#include "xAODTrigger/MuonRoIContainer.h" #include "xAODTrigger/TrigCompositeContainer.h" // Athena includes #include "AthenaBaseComps/AthReentrantAlgorithm.h" -#include "ByteStreamCnvSvcBase/IROBDataProviderSvc.h" -#include "StoreGate/WriteHandle.h" +#include "StoreGate/ReadHandleKey.h" +#include "StoreGate/WriteHandleKey.h" /** @class L1TriggerResultMaker - * @brief Algorithm creating RoIBResult from ByteStream representation + * @brief Algorithm creating L1TriggerResult and linking the relevant L1 xAOD collections to it **/ class L1TriggerResultMaker : public AthReentrantAlgorithm { public: @@ -24,22 +24,23 @@ public: // ------------------------- AthReentrantAlgorithm methods ------------------- virtual StatusCode initialize() override; - virtual StatusCode finalize() override; virtual StatusCode execute(const EventContext& eventContext) const override; private: // ------------------------- Properties -------------------------------------- - /// StoreGate key for the output RoIBResult SG::WriteHandleKey<xAOD::TrigCompositeContainer> m_l1TriggerResultWHKey { this, "L1TriggerResultWHKey", "L1TriggerResult", "Key of the output L1 Trigger Result"}; - // ------------------------- Tool/Service handles ---------------------------- - /// Tool performing the decoding work - ToolHandleArray<IL1TriggerByteStreamTool> m_decoderTools { - this, "DecoderTools", {}, "Array of tools performing the decoding work"}; - /// ROBDataProvider service handle - ServiceHandle<IROBDataProviderSvc> m_robDataProviderSvc { - this, "ROBDataProviderSvc", "ROBDataProviderSvc", "ROB data provider"}; + // Muon RoIs + SG::ReadHandleKey<xAOD::MuonRoIContainer> m_muRoIKey { + this, "MuRoIKey", "LVL1MuonRoIs", "Key of the muon RoI container to be linked to L1 Trigger Result"}; + Gaudi::Property<std::string> m_muRoILinkName { + this, "MuRoILinkName", "mu_roi", "Name of the link to be created from L1 Trigger Result to muon RoI container"}; + + // Placeholder for other L1 xAOD outputs: + // - CTP result + // - L1Topo result + // - L1Calo (Run3) RoIs }; #endif // TRIGT1RESULTBYTESTREAM_L1TRIGGERRESULTMAKER_H diff --git a/Trigger/TrigSteer/L1Decoder/src/components/L1Decoder_entries.cxx b/Trigger/TrigSteer/L1Decoder/src/components/L1Decoder_entries.cxx index 67bb34747cf00174112a9b96efe72cf73822fae4..e17042a57404438d23d46493f4e66b8bb35e1f28 100644 --- a/Trigger/TrigSteer/L1Decoder/src/components/L1Decoder_entries.cxx +++ b/Trigger/TrigSteer/L1Decoder/src/components/L1Decoder_entries.cxx @@ -18,7 +18,7 @@ #include "../PrescalingTool.h" #include "../PrescalingEmulationTool.h" #include "../CreateFullScanRoI.h" - +#include "../L1TriggerResultMaker.h" DECLARE_COMPONENT( L1CaloDecoder ) DECLARE_COMPONENT( FakeRoI ) @@ -40,3 +40,4 @@ DECLARE_COMPONENT( PrescalingTool ) DECLARE_COMPONENT( PrescalingEmulationTool ) DECLARE_COMPONENT( RerunRoIsUnpackingTool ) DECLARE_COMPONENT( CreateFullScanRoI ) +DECLARE_COMPONENT( L1TriggerResultMaker ) diff --git a/Trigger/TrigT1/TrigT1ResultByteStream/TrigT1ResultByteStream/IL1TriggerByteStreamTool.h b/Trigger/TrigT1/TrigT1ResultByteStream/TrigT1ResultByteStream/IL1TriggerByteStreamTool.h index 9717932b0bebbfb55f0bdd18286f44a5f681e7ac..300b84b6efa494099737d8df816d2adf8f20f3c2 100644 --- a/Trigger/TrigT1/TrigT1ResultByteStream/TrigT1ResultByteStream/IL1TriggerByteStreamTool.h +++ b/Trigger/TrigT1/TrigT1ResultByteStream/TrigT1ResultByteStream/IL1TriggerByteStreamTool.h @@ -20,40 +20,29 @@ public: /** * @brief Convert BS -> xAOD * - * The implementation should create an xAOD RoI object from the raw data, record it in the event store, - * and then link it to the l1TriggerResult object. + * The implementation should create an xAOD RoI object from the raw data and record it in the event store + * using a WriteHandle it declares. **/ - virtual StatusCode convert(const std::vector<const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment*>& vrobf, - xAOD::TrigComposite& l1TriggerResult, - const EventContext& eventContext) const = 0; + virtual StatusCode convertFromBS(const std::vector<const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment*>& vrobf, + const EventContext& eventContext) const = 0; /** * @brief Convert xAOD -> BS * - * The implementation should take the xAOD RoI object linked to the l1TriggerResult object, + * The implementation should take the xAOD RoI object from the event store using a ReadHandle it declares, * convert it to raw data, and fill the vrobf vector. **/ - virtual StatusCode convert(const xAOD::TrigComposite& l1TriggerResult, - std::vector<const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment*>& vrobf, - const EventContext& eventContext) const = 0; + virtual StatusCode convertToBS(std::vector<const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment*>& vrobf, + const EventContext& eventContext) const = 0; /** - * @brief List of IDs of ROBs which the convert() methods expect in the vrobf input/output parameter + * @brief List of IDs of ROBs which the convert methods expect in the vrobf input/output parameter * * The implementation has to hold a Gaudi::Property<vector<uint32_t>> to declare the ROB IDs it requires/provides * and this method has to return the value of this property. There is no easy way to declare a Gaudi::Property here * in the interface, so it is delegated to the implementation. **/ virtual const std::vector<uint32_t> robIds() const = 0; - - /** - * @brief Name of the link between the xAOD RoI converted by the implementation from/to raw data - * - * The implementation has to hold a Gaudi::Property<std::string> to declare the link name it requires/provides - * and this method has to return the value of this property. There is no easy way to declare a Gaudi::Property here - * in the interface, so it is delegated to the implementation. - **/ - virtual const std::string linkName() const = 0; }; #endif // TRIGT1RESULTBYTESTREAM_IL1TRIGGERBYTESTREAMTOOL_H diff --git a/Trigger/TrigT1/TrigT1ResultByteStream/python/TrigT1ResultByteStreamConfig.py b/Trigger/TrigT1/TrigT1ResultByteStream/python/TrigT1ResultByteStreamConfig.py index 53851d5d59e5730a6d1dfc0d09537ae82659e9e7..f746167aab49b6828756d274d57bf8cc1b544e4f 100644 --- a/Trigger/TrigT1/TrigT1ResultByteStream/python/TrigT1ResultByteStreamConfig.py +++ b/Trigger/TrigT1/TrigT1ResultByteStream/python/TrigT1ResultByteStreamConfig.py @@ -14,8 +14,8 @@ def RoIBResultDecoderCfg(flags): acc.addEventAlgo(decoderAlg) return acc -def L1TriggerResultMakerCfg(flags): - from TrigT1ResultByteStream.TrigT1ResultByteStreamConf import L1TriggerResultMaker,ExampleL1TriggerByteStreamTool +def L1TriggerByteStreamDecoderCfg(flags): + from TrigT1ResultByteStream.TrigT1ResultByteStreamConf import L1TriggerByteStreamDecoderAlg,ExampleL1TriggerByteStreamTool from libpyeformat_helper import SourceIdentifier,SubDetector # Placeholder for real decoder tools - now it's just an example @@ -23,14 +23,12 @@ def L1TriggerResultMakerCfg(flags): muctpi_robid = int(SourceIdentifier(SubDetector.TDAQ_MUON_CTP_INTERFACE, muctpi_moduleid)) exampleTool = ExampleL1TriggerByteStreamTool(ROBIDs=[muctpi_robid], MUCTPIModuleId=muctpi_moduleid, - MuonRoIContainerWriteKey="LVL1MuonRoIs", - LinkName="mu_roi") + MuonRoIContainerWriteKey="LVL1MuonRoIs") decoderTools = [exampleTool] - decoderAlg = L1TriggerResultMaker(name="L1TriggerResultMaker", - L1TriggerResultWHKey="L1TriggerResult", - DecoderTools=decoderTools) + decoderAlg = L1TriggerByteStreamDecoderAlg(name="L1TriggerByteStreamDecoder", + DecoderTools=decoderTools) from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator acc = ComponentAccumulator() @@ -44,4 +42,4 @@ def L1ByteStreamDecodersRecExSetup(enableRun2L1=True, enableRun3L1=True): if enableRun2L1: CAtoGlobalWrapper(RoIBResultDecoderCfg,ConfigFlags) if enableRun3L1: - CAtoGlobalWrapper(L1TriggerResultMakerCfg,ConfigFlags) + CAtoGlobalWrapper(L1TriggerByteStreamDecoderCfg,ConfigFlags) diff --git a/Trigger/TrigT1/TrigT1ResultByteStream/src/ExampleL1TriggerByteStreamTool.cxx b/Trigger/TrigT1/TrigT1ResultByteStream/src/ExampleL1TriggerByteStreamTool.cxx index d0bc7d292d12e300b9d973b4d3b62b1eb7a55e68..716f047ce303e0d00c3b322d987909599acf71e6 100644 --- a/Trigger/TrigT1/TrigT1ResultByteStream/src/ExampleL1TriggerByteStreamTool.cxx +++ b/Trigger/TrigT1/TrigT1ResultByteStream/src/ExampleL1TriggerByteStreamTool.cxx @@ -15,14 +15,19 @@ ExampleL1TriggerByteStreamTool::ExampleL1TriggerByteStreamTool(const std::string : base_class(type, name, parent) {} StatusCode ExampleL1TriggerByteStreamTool::initialize() { + if (m_roiWriteKey.empty() == m_roiReadKey.empty()) { + ATH_MSG_ERROR("Exactly one of the read / write handle keys has to be set and the other has to be empty, " + << "but they are \"" << m_roiReadKey.key() << "\" / \"" << m_roiWriteKey.key() << "\""); + return StatusCode::FAILURE; + } ATH_CHECK(m_roiWriteKey.initialize(!m_roiWriteKey.empty())); + ATH_CHECK(m_roiReadKey.initialize(!m_roiReadKey.empty())); return StatusCode::SUCCESS; } // BS->xAOD conversion -StatusCode ExampleL1TriggerByteStreamTool::convert(const std::vector<const ROBF*>& vrobf, - xAOD::TrigComposite& l1TriggerResult, - const EventContext& eventContext) const { +StatusCode ExampleL1TriggerByteStreamTool::convertFromBS(const std::vector<const ROBF*>& vrobf, + const EventContext& eventContext) const { if (m_roiWriteKey.empty()) { ATH_MSG_ERROR("Conversion from BS to xAOD RoI requested but RoI WriteHandleKey is empty"); return StatusCode::FAILURE; @@ -36,13 +41,6 @@ StatusCode ExampleL1TriggerByteStreamTool::convert(const std::vector<const ROBF* ATH_CHECK(handle.record(std::move(cont), std::move(auxcont))); ATH_MSG_DEBUG("Recorded MuonRoIContainer with key " << m_roiWriteKey.key()); - // Link the RoI container (actually its first element) to L1TriggerResult - ElementLink<xAOD::MuonRoIContainer> link = ElementLink<xAOD::MuonRoIContainer>(m_roiWriteKey.key(), 0, eventContext); - l1TriggerResult.typelessSetObjectLink(m_linkName.value(), - link.key(), - ClassID_traits<xAOD::MuonRoIContainer>::ID(), - /*index =*/ 0); - // Find the ROB fragment to decode const eformat::helper::SourceIdentifier sid(eformat::TDAQ_MUON_CTP_INTERFACE, m_muCTPIModuleID.value()); auto it = std::find_if(vrobf.begin(), vrobf.end(), [&sid](const ROBF* rob){return rob->rob_source_id() == sid.code();}); @@ -68,15 +66,11 @@ StatusCode ExampleL1TriggerByteStreamTool::convert(const std::vector<const ROBF* } /// xAOD->BS conversion -StatusCode ExampleL1TriggerByteStreamTool::convert(const xAOD::TrigComposite& l1TriggerResult, - std::vector<const ROBF*>& /*vrobf*/, - const EventContext& /*eventContext*/) const { - +StatusCode ExampleL1TriggerByteStreamTool::convertToBS(std::vector<const ROBF*>& /*vrobf*/, + const EventContext& eventContext) const { // Retrieve the RoI container - if (!l1TriggerResult.hasObjectLink(m_linkName.value())) { - ATH_MSG_ERROR("L1TriggerResult does not have a link \"" << m_linkName << "\""); - return StatusCode::FAILURE; - } + auto muonRoIs = SG::makeHandle(m_roiReadKey, eventContext); + ATH_CHECK(muonRoIs.isValid()); // TODO: implement this part when new code requesting the xAOD->BS conversion is implemented (ATR-19542) diff --git a/Trigger/TrigT1/TrigT1ResultByteStream/src/ExampleL1TriggerByteStreamTool.h b/Trigger/TrigT1/TrigT1ResultByteStream/src/ExampleL1TriggerByteStreamTool.h index 1003f9401122cf8c7a03c45f428c88d4de89a3ce..dd6c72cf0c7ad6db91f6900ea9ae324357486e01 100644 --- a/Trigger/TrigT1/TrigT1ResultByteStream/src/ExampleL1TriggerByteStreamTool.h +++ b/Trigger/TrigT1/TrigT1ResultByteStream/src/ExampleL1TriggerByteStreamTool.h @@ -21,8 +21,8 @@ * * This example decodes Muon RoIs from MUCTPI raw data, filling the results with dummy values. Real implementations * should have very similar structure and should implement the same functionality and properties. In particular, - * their BS->xAOD convert method should also record a new xAOD collection in the event store and link it to the - * L1TriggerResult object, as presented here. + * the convertFromBS method should record a new xAOD collection in the event store using a WriteHandle, and the + * convertToBS method should take the xAOD collection from the event store using a ReadHandle. **/ class ExampleL1TriggerByteStreamTool : public extends<AthAlgTool, IL1TriggerByteStreamTool> { public: @@ -34,35 +34,30 @@ public: // ------------------------- IL1TriggerByteStreamTool methods ---------------- /// BS->xAOD conversion - virtual StatusCode convert(const std::vector<const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment*>& vrobf, - xAOD::TrigComposite& l1TriggerResult, - const EventContext& eventContext) const override; + virtual StatusCode convertFromBS(const std::vector<const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment*>& vrobf, + const EventContext& eventContext) const override; /// xAOD->BS conversion - virtual StatusCode convert(const xAOD::TrigComposite& l1TriggerResult, - std::vector<const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment*>& vrobf, - const EventContext& eventContext) const override; + virtual StatusCode convertToBS(std::vector<const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment*>& vrobf, + const EventContext& eventContext) const override; /// Declare ROB IDs for conversion virtual const std::vector<uint32_t> robIds() const override {return m_robIds.value();} - /// Declare name of the link from L1TriggerResult to the xAOD RoI - virtual const std::string linkName() const override {return m_linkName.value();} private: // ------------------------- Properties -------------------------------------- - // The following two are required by the interface + // ROBIDs property required by the interface Gaudi::Property<std::vector<uint32_t>> m_robIds { this, "ROBIDs", {}, "List of ROB IDs required for conversion to/from xAOD RoI"}; - Gaudi::Property<std::string> m_linkName { - this, "LinkName", "UNDEFINED_LINK_NAME", "Name of the link from L1TriggerResult to the xAOD RoI"}; + // It is a good idea to have also the module IDs configurable in case they change at some point + Gaudi::Property<uint16_t> m_muCTPIModuleID { + this, "MUCTPIModuleId", 1, "Module ID of MUCTPI ROB with RoI information"}; - /// Write key should be reset to empty string in python configuration if the tool is in xAOD->BS mode of operation + // Only write key should be set to non-empty string in python configuration if the tool is in BS->xAOD mode of operation SG::WriteHandleKey<xAOD::MuonRoIContainer> m_roiWriteKey { - this, "MuonRoIContainerWriteKey", "LVL1MuonRoIs", "Write handle key to MuonRoIContainer for conversion from ByteStream"}; + this, "MuonRoIContainerWriteKey", "", "Write handle key to MuonRoIContainer for conversion from ByteStream"}; + // Only read key should be set to non-empty string in python configuration if the tool is in xAOD->BS mode of operation + SG::ReadHandleKey<xAOD::MuonRoIContainer> m_roiReadKey { + this, "MuonRoIContainerReadKey", "", "Read handle key to MuonRoIContainer for conversion to ByteStream"}; - // It is a good idea to have the module IDs configurable in case they change at some point - /// MUCTPI Module ID to decode - Gaudi::Property<uint16_t> m_muCTPIModuleID { - this, "MUCTPIModuleId", 1, "Module ID of MUCTPI ROB with RoI information" - }; }; #endif // TRIGT1RESULTBYTESTREAM_EXAMPLEL1TRIGGERBYTESTREAMTOOL_H diff --git a/Trigger/TrigT1/TrigT1ResultByteStream/src/L1TriggerByteStreamDecoderAlg.cxx b/Trigger/TrigT1/TrigT1ResultByteStream/src/L1TriggerByteStreamDecoderAlg.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9334a729897af2ca01d3299bf3b5fc07afe12fe7 --- /dev/null +++ b/Trigger/TrigT1/TrigT1ResultByteStream/src/L1TriggerByteStreamDecoderAlg.cxx @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#include "L1TriggerByteStreamDecoderAlg.h" + +// ============================================================================= +// Standard constructor +// ============================================================================= +L1TriggerByteStreamDecoderAlg::L1TriggerByteStreamDecoderAlg(const std::string& name, ISvcLocator* svcLoc) +: AthReentrantAlgorithm(name, svcLoc) {} + +// ============================================================================= +// Implementation of AthReentrantAlgorithm::initialize +// ============================================================================= +StatusCode L1TriggerByteStreamDecoderAlg::initialize() { + ATH_MSG_DEBUG("Initialising " << name()); + ATH_CHECK(m_decoderTools.retrieve()); + ATH_CHECK(m_robDataProviderSvc.retrieve()); + return StatusCode::SUCCESS; +} + +// ============================================================================= +// Implementation of AthReentrantAlgorithm::finalize +// ============================================================================= +StatusCode L1TriggerByteStreamDecoderAlg::finalize() { + ATH_MSG_DEBUG("Finalising " << name()); + ATH_CHECK(m_robDataProviderSvc.release()); + ATH_CHECK(m_decoderTools.release()); + return StatusCode::SUCCESS; +} + +// ============================================================================= +// Implementation of AthReentrantAlgorithm::execute +// ============================================================================= +StatusCode L1TriggerByteStreamDecoderAlg::execute(const EventContext& eventContext) const { + ATH_MSG_DEBUG("Executing " << name()); + + // Retrieve the BS data and call the decoder tools + IROBDataProviderSvc::VROBFRAG vrobf; + for (const auto& decoderTool : m_decoderTools) { + vrobf.clear(); + m_robDataProviderSvc->getROBData(eventContext, decoderTool->robIds(), vrobf, name()); + ATH_CHECK(decoderTool->convertFromBS(vrobf, eventContext)); + } + + return StatusCode::SUCCESS; +} diff --git a/Trigger/TrigT1/TrigT1ResultByteStream/src/L1TriggerByteStreamDecoderAlg.h b/Trigger/TrigT1/TrigT1ResultByteStream/src/L1TriggerByteStreamDecoderAlg.h new file mode 100644 index 0000000000000000000000000000000000000000..1af617f97e17d5ace60a3d770a4f994118fe430c --- /dev/null +++ b/Trigger/TrigT1/TrigT1ResultByteStream/src/L1TriggerByteStreamDecoderAlg.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TRIGT1RESULTBYTESTREAM_L1TRIGGERBYTESTREAMDECODERALG_H +#define TRIGT1RESULTBYTESTREAM_L1TRIGGERBYTESTREAMDECODERALG_H + +// Trigger includes +#include "TrigT1ResultByteStream/IL1TriggerByteStreamTool.h" + +// Athena includes +#include "AthenaBaseComps/AthReentrantAlgorithm.h" +#include "ByteStreamCnvSvcBase/IROBDataProviderSvc.h" + +/** @class L1TriggerByteStreamDecoderAlg + * @brief Algorithm calling tools to convert L1 ByteStream into xAOD collections + **/ +class L1TriggerByteStreamDecoderAlg : public AthReentrantAlgorithm { +public: + /// Standard constructor + L1TriggerByteStreamDecoderAlg(const std::string& name, ISvcLocator* svcLoc); + + // ------------------------- AthReentrantAlgorithm methods ------------------- + virtual StatusCode initialize() override; + virtual StatusCode finalize() override; + virtual StatusCode execute(const EventContext& eventContext) const override; + +private: + // ------------------------- Tool/Service handles ---------------------------- + /// Tool performing the decoding work + ToolHandleArray<IL1TriggerByteStreamTool> m_decoderTools { + this, "DecoderTools", {}, "Array of tools performing the decoding work"}; + /// ROBDataProvider service handle + ServiceHandle<IROBDataProviderSvc> m_robDataProviderSvc { + this, "ROBDataProviderSvc", "ROBDataProviderSvc", "ROB data provider"}; +}; + +#endif // TRIGT1RESULTBYTESTREAM_L1TRIGGERBYTESTREAMDECODERALG_H diff --git a/Trigger/TrigT1/TrigT1ResultByteStream/src/components/TrigT1ResultByteStream_entries.cxx b/Trigger/TrigT1/TrigT1ResultByteStream/src/components/TrigT1ResultByteStream_entries.cxx index fc6a0aecc4c6daf2460fade6b79802b32dc67c65..8c5b33ce982bc0a9dbb1ffba9df71b13349039f1 100644 --- a/Trigger/TrigT1/TrigT1ResultByteStream/src/components/TrigT1ResultByteStream_entries.cxx +++ b/Trigger/TrigT1/TrigT1ResultByteStream/src/components/TrigT1ResultByteStream_entries.cxx @@ -15,7 +15,7 @@ #include "TrigT1ResultByteStream/RoIBResultByteStreamTool.h" #include "../RoIBResultByteStreamDecoderAlg.h" -#include "../L1TriggerResultMaker.h" +#include "../L1TriggerByteStreamDecoderAlg.h" #include "../ExampleL1TriggerByteStreamTool.h" // ROBF for offline @@ -41,5 +41,5 @@ DECLARE_COMPONENT( RecRoIBResultByteStreamTool ) DECLARE_COMPONENT( RoIBResultByteStreamTool ) DECLARE_COMPONENT( RoIBResultByteStreamDecoderAlg ) -DECLARE_COMPONENT( L1TriggerResultMaker ) +DECLARE_COMPONENT( L1TriggerByteStreamDecoderAlg ) DECLARE_COMPONENT( ExampleL1TriggerByteStreamTool ) diff --git a/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone.py b/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone.py index 4e89781c122f6984fe468af53e413dbec9aa7253..dfb0a1830b776eb30687116b73edf4b50cc0b6a3 100644 --- a/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone.py +++ b/Trigger/TriggerCommon/TriggerJobOpts/share/runHLT_standalone.py @@ -444,10 +444,13 @@ if opt.doL1Unpacking: from L1Decoder.L1DecoderConfig import L1Decoder l1decoder = L1Decoder("L1Decoder") l1decoder.ctpUnpacker.ForceEnableAllChains = opt.forceEnableAllChains + if opt.decodePhaseIL1: + from L1Decoder.L1DecoderConfig import L1TriggerResultMaker + topSequence += L1TriggerResultMaker() + else: + l1decoder.L1TriggerResult = "" if not opt.decodeLegacyL1: l1decoder.RoIBResult = "" - if not opt.decodePhaseIL1: - l1decoder.L1TriggerResult = "" if TriggerFlags.doTransientByteStream(): transTypeKey = ("TransientBSOutType","StoreGateSvc+TransientBSOutKey") l1decoder.ExtraInputs += [transTypeKey]