From abc0c732844f80a457c57683f54d0770e255f5e9 Mon Sep 17 00:00:00 2001 From: Zvi Tarem <zvi.tarem@cern.ch> Date: Fri, 24 Sep 2021 17:31:17 +0200 Subject: [PATCH] Create and fill an sTGC Pad Trigger RDO container in SG --- .../NSW_PadTriggerDataContainerCnv_p1.cxx | 17 ++++-- .../src/PadTrig_ROD_Decoder.cxx | 43 +++++++------- .../MuonRDO/MuonRDO/NSW_PadTriggerData.h | 23 ++++++-- .../MuonRDO/NSW_PadTriggerDataContainer.h | 3 +- .../MuonRDO/src/NSW_PadTriggerData.cxx | 36 +++++++++-- .../src/NSW_PadTriggerDataContainer.cxx | 10 ++-- Trigger/TrigT1/TrigT1NSW/share/NSWL1.py | 6 +- .../TrigT1/TrigT1NSW/src/NSWL1Simulation.cxx | 33 +++++++++-- .../TrigT1/TrigT1NSW/src/NSWL1Simulation.h | 7 ++- .../TrigT1NSWSimTools/PadTriggerAdapter.h | 21 +++++++ .../src/PadTriggerAdapter.cxx | 59 +++++++++++++++++++ .../src/PadTriggerLookupTool.cxx | 3 + 12 files changed, 209 insertions(+), 52 deletions(-) create mode 100644 Trigger/TrigT1/TrigT1NSWSimTools/TrigT1NSWSimTools/PadTriggerAdapter.h create mode 100644 Trigger/TrigT1/TrigT1NSWSimTools/src/PadTriggerAdapter.cxx diff --git a/MuonSpectrometer/MuonCnv/MuonEventTPCnv/src/MuonRDO/NSW_PadTriggerDataContainerCnv_p1.cxx b/MuonSpectrometer/MuonCnv/MuonEventTPCnv/src/MuonRDO/NSW_PadTriggerDataContainerCnv_p1.cxx index 1539f78b4549..8bd2eee4842c 100644 --- a/MuonSpectrometer/MuonCnv/MuonEventTPCnv/src/MuonRDO/NSW_PadTriggerDataContainerCnv_p1.cxx +++ b/MuonSpectrometer/MuonCnv/MuonEventTPCnv/src/MuonRDO/NSW_PadTriggerDataContainerCnv_p1.cxx @@ -9,8 +9,15 @@ void NSW_PadTriggerDataContainerCnv_p1::persToTrans(const NSW_PadTriggerDataCont for (const auto& pCollection : persistentObj->m_collections) { std::array<std::vector<uint16_t>, 3> persistent_hitlists{ pCollection.m_precedingHitlist, pCollection.m_currentHitlist, pCollection.m_followingHitlist }; // Can initialize here with std::move(persistent_hitlists) and modify the transient constructor accordingly - auto tCollection = std::make_unique<NSW_PadTriggerData>(pCollection.m_identifierHash, pCollection.m_sectorID, - pCollection.m_sectorSize, pCollection.m_endcap, pCollection.m_BCID, pCollection.m_L1ID, persistent_hitlists); + auto tCollection = std::make_unique<NSW_PadTriggerData>( + pCollection.m_identifierHash, + pCollection.m_sectorID, + static_cast<NSW_PadTriggerData::SectorSize>(pCollection.m_sectorSize), + static_cast<NSW_PadTriggerData::Endcap>(pCollection.m_endcap), + pCollection.m_BCID, + pCollection.m_L1ID, + persistent_hitlists); + tCollection->reserve(pCollection.m_segments.size()); for (std::size_t i{}; i < pCollection.m_segments.size(); i++) { tCollection->push_back(m_segmentConverter.createTransient(&pCollection.m_segments.at(i), log)); @@ -31,14 +38,14 @@ void NSW_PadTriggerDataContainerCnv_p1::transToPers(const NSW_PadTriggerDataCont } persistentObj->m_collections.reserve(transientObj->size()); // Iterate over collections - for (const Muon::NSW_PadTriggerData* tCollection : *transientObj) { + for (const auto& tCollection : *transientObj) { NSW_PadTriggerData_p1 pCollection{}; pCollection.m_segments.reserve(tCollection->size()); pCollection.m_identifierHash = tCollection->identifierHash(); pCollection.m_sectorID = tCollection->sectorID(); - pCollection.m_sectorSize = tCollection->sectorSize(); - pCollection.m_endcap = tCollection->endcap(); + pCollection.m_sectorSize = static_cast<uint8_t>(tCollection->sectorSize()); + pCollection.m_endcap = static_cast<uint8_t>(tCollection->endcap()); pCollection.m_BCID = tCollection->BCID(); pCollection.m_L1ID = tCollection->L1ID(); diff --git a/MuonSpectrometer/MuonCnv/MuonSTGC_CnvTools/src/PadTrig_ROD_Decoder.cxx b/MuonSpectrometer/MuonCnv/MuonSTGC_CnvTools/src/PadTrig_ROD_Decoder.cxx index 78599be7923b..a95752ff7623 100644 --- a/MuonSpectrometer/MuonCnv/MuonSTGC_CnvTools/src/PadTrig_ROD_Decoder.cxx +++ b/MuonSpectrometer/MuonCnv/MuonSTGC_CnvTools/src/PadTrig_ROD_Decoder.cxx @@ -12,14 +12,14 @@ namespace Muon { //===================================================================== PadTrig_ROD_Decoder::PadTrig_ROD_Decoder(const std::string& type, const std::string& name, const IInterface* parent) -: AthAlgTool(type, name, parent) +: AthAlgTool(type, name, parent) { declareInterface<IPadTrig_ROD_Decoder>(this); } //===================================================================== -StatusCode PadTrig_ROD_Decoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment& fragment, NSW_PadTriggerDataContainer& rdo) const +StatusCode PadTrig_ROD_Decoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment& fragment, NSW_PadTriggerDataContainer& rdo) const { try { fragment.check(); @@ -27,7 +27,7 @@ StatusCode PadTrig_ROD_Decoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE ATH_MSG_ERROR(ex.what()); return StatusCode::FAILURE; } - + eformat::helper::SourceIdentifier sourceID{fragment.rob_source_id()}; // FIXME this hash calculation MUST be done in an IdHelper! @@ -42,20 +42,20 @@ StatusCode PadTrig_ROD_Decoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE ATH_MSG_ERROR("Collection ID " << hashID << " already found in RDO container, skipping"); return StatusCode::FAILURE; } - + OFFLINE_FRAGMENTS_NAMESPACE::PointerType data{}; fragment.rod_data(data); if (!data) { ATH_MSG_WARNING("No data found for this ROBFragment, skipping"); return StatusCode::FAILURE; } - + // TODO better error handling? return parseBytestream(data, fragment.rod_ndata(), rdo, hashID); } //===================================================================== -StatusCode PadTrig_ROD_Decoder::parseBytestream(OFFLINE_FRAGMENTS_NAMESPACE::PointerType data, std::size_t size, NSW_PadTriggerDataContainer& rdo, const IdentifierHash hashID) const +StatusCode PadTrig_ROD_Decoder::parseBytestream(OFFLINE_FRAGMENTS_NAMESPACE::PointerType data, std::size_t size, NSW_PadTriggerDataContainer& rdo, const IdentifierHash hashID) const { // Refer to: // https://espace.cern.ch/ATLAS-NSW-ELX/Shared%20Documents/Pad%20Trigger/PadTrig_Raw_Format.pdf @@ -72,7 +72,7 @@ StatusCode PadTrig_ROD_Decoder::parseBytestream(OFFLINE_FRAGMENTS_NAMESPACE::Poi ATH_MSG_ERROR("Corrupted ROBFragment, skipping! Expected " << EXPECTED_SIZE << " words, got " << size); return StatusCode::FAILURE; } - + const uint16_t bcid = (extractByte(data, 2) >> 4 & 0xf) << 8 | extractByte(data, 3); const uint32_t l1id = __builtin_bswap32(data[3]); const uint8_t endcap = (data[2] & (0b1 << 7)) ? 1 : 0; // 1 = Endcap A, 0 = Endcap C @@ -98,11 +98,12 @@ StatusCode PadTrig_ROD_Decoder::parseBytestream(OFFLINE_FRAGMENTS_NAMESPACE::Poi if (observedHits != (hitMultiplicity & 0xfff)) { ATH_MSG_WARNING("Expected " << static_cast<uint32_t>(hitMultiplicity & 0xfff) << " set bits, observed " << observedHits); } - + byteIndex += BITMAP_SIZE; } - - auto collection = new NSW_PadTriggerData{ hashID, sectorID, sectorSize, endcap, bcid, l1id, hitAddresses}; + + auto collection = new NSW_PadTriggerData{ hashID, sectorID, static_cast<NSW_PadTriggerData::SectorSize>(sectorSize), + static_cast<NSW_PadTriggerData::Endcap>(endcap), bcid, l1id, hitAddresses}; // Status word length byteIndex += 2; @@ -118,7 +119,7 @@ StatusCode PadTrig_ROD_Decoder::parseBytestream(OFFLINE_FRAGMENTS_NAMESPACE::Poi //===================================================================== -std::vector<uint16_t> PadTrig_ROD_Decoder::parseBitmap(OFFLINE_FRAGMENTS_NAMESPACE::PointerType data, std::size_t byteIndex, std::size_t& hitCount, bool isSmallSector) const +std::vector<uint16_t> PadTrig_ROD_Decoder::parseBitmap(OFFLINE_FRAGMENTS_NAMESPACE::PointerType data, std::size_t byteIndex, std::size_t& hitCount, bool isSmallSector) const { std::vector<uint16_t> addressList{}; constexpr std::size_t PFEB_COUNT = 24; @@ -127,16 +128,16 @@ std::vector<uint16_t> PadTrig_ROD_Decoder::parseBitmap(OFFLINE_FRAGMENTS_NAMESPA size_t Nchannels{85}; // default value for (std::size_t pfeb{}; pfeb < PFEB_COUNT; pfeb++) { - + // pFEBs are sent in reverse order: last pFEB (pFEB23) sent first auto& currentBitmap = bitmaps[PFEB_COUNT - pfeb - 1]; - // Size of the current pFEB bitmap + // Size of the current pFEB bitmap if (m_channelMapping) Nchannels = isSmallSector ? SMALL_PFEB_SIZES[PFEB_COUNT - pfeb - 1] : LARGE_PFEB_SIZES[PFEB_COUNT - pfeb - 1]; - + for (std::size_t channel{}; channel < Nchannels; channel++) currentBitmap.push_back(extractBit(data, byteIndex * 8 + (bitOffset + channel) + 8)); - + bitOffset += currentBitmap.size(); } @@ -161,7 +162,7 @@ std::vector<uint16_t> PadTrig_ROD_Decoder::parseBitmap(OFFLINE_FRAGMENTS_NAMESPA chOffset += bitmaps[pfeb].size(); continue; } - + for (std::size_t ch{}; ch < bitmaps[pfeb].size(); ch++) { if (bitmaps[pfeb][ch]) { // TODO The address is a simple running counter for now. @@ -176,12 +177,12 @@ std::vector<uint16_t> PadTrig_ROD_Decoder::parseBitmap(OFFLINE_FRAGMENTS_NAMESPA //===================================================================== -void PadTrig_ROD_Decoder::parseSegments(OFFLINE_FRAGMENTS_NAMESPACE::PointerType data, std::size_t byteIndex, NSW_PadTriggerData& collection) const +void PadTrig_ROD_Decoder::parseSegments(OFFLINE_FRAGMENTS_NAMESPACE::PointerType data, std::size_t byteIndex, NSW_PadTriggerData& collection) const { // Refer to: // https://espace.cern.ch/ATLAS-NSW-ELX/Shared%20Documents/Pad%20Trigger/Pad_to_TP_data_format.pdf // const uint16_t bcidAndFlags = extractByte(data, byteIndex) << 8 | extractByte(data, byteIndex + 1); - + // TODO compare BCID with one found in header? Do something with flags? //const uint8_t flags = (bcidAndFlags & 0xf000) >> 12; //const uint16_t bcid = bcidAndFlags & 0xfff; @@ -194,7 +195,7 @@ void PadTrig_ROD_Decoder::parseSegments(OFFLINE_FRAGMENTS_NAMESPACE::PointerType if (bandID == 0xff) { continue; } - + // FIXME phiID currently bit-packed (6 bits * 4), should be 8 bits * 4? const uint8_t phiID = extractByte(data, byteIndex + 4 + i); const auto wedge0ActiveLayers = extractByte(data, byteIndex + 8); @@ -210,7 +211,7 @@ void PadTrig_ROD_Decoder::parseSegments(OFFLINE_FRAGMENTS_NAMESPACE::PointerType //===================================================================== -bool PadTrig_ROD_Decoder::extractBit(OFFLINE_FRAGMENTS_NAMESPACE::PointerType data, std::size_t index) const +bool PadTrig_ROD_Decoder::extractBit(OFFLINE_FRAGMENTS_NAMESPACE::PointerType data, std::size_t index) const { // Swap to big endian, as we're dealing with a contiguous bit vector const uint32_t word = __builtin_bswap32(data[index / 32]); @@ -221,7 +222,7 @@ bool PadTrig_ROD_Decoder::extractBit(OFFLINE_FRAGMENTS_NAMESPACE::PointerType da //===================================================================== -uint8_t PadTrig_ROD_Decoder::extractByte(OFFLINE_FRAGMENTS_NAMESPACE::PointerType data, std::size_t index) const +uint8_t PadTrig_ROD_Decoder::extractByte(OFFLINE_FRAGMENTS_NAMESPACE::PointerType data, std::size_t index) const { // Swap to big endian, so byte extracted will match the byte at the given index in the contiguous packet const uint32_t word = data[index / 4]; diff --git a/MuonSpectrometer/MuonRDO/MuonRDO/NSW_PadTriggerData.h b/MuonSpectrometer/MuonRDO/MuonRDO/NSW_PadTriggerData.h index 30ecd4c35723..a1d17512d62a 100644 --- a/MuonSpectrometer/MuonRDO/MuonRDO/NSW_PadTriggerData.h +++ b/MuonSpectrometer/MuonRDO/MuonRDO/NSW_PadTriggerData.h @@ -14,26 +14,37 @@ namespace Muon { class NSW_PadTriggerData : public DataVector<NSW_PadTriggerSegment> { using hitlist_t = std::vector<uint16_t>; public: - NSW_PadTriggerData(IdentifierHash identifierHash, uint8_t sectorID, uint8_t sectorSize, uint8_t endcap, + enum class Endcap : uint8_t { C = 0, A = 1 }; + enum class SectorSize : uint8_t { SMALL = 0, LARGE = 1 }; + + NSW_PadTriggerData(IdentifierHash identifierHash, uint8_t sectorID, SectorSize sectorSize, Endcap endcap, uint32_t BCID, uint32_t L1ID, const std::array<hitlist_t, 3>& hitlists); IdentifierHash identifierHash() const; std::string string() const; uint8_t sectorID() const noexcept; - uint8_t sectorSize() const noexcept; - uint8_t endcap() const noexcept; + SectorSize sectorSize() const noexcept; + Endcap endcap() const noexcept; uint32_t BCID() const noexcept; uint32_t L1ID() const noexcept; + + void sectorID(uint8_t sectorID) noexcept; + void sectorSize(SectorSize sectorSize) noexcept; + void endcap(Endcap endcap) noexcept; + void BCID(uint32_t BCID) noexcept; + void L1ID(uint32_t L1ID) noexcept; + void hitlists(const std::array<hitlist_t, 3>& hitlists); const std::array<hitlist_t, 3>& hitlists() const; friend std::ostream& operator<<(std::ostream& stream, const NSW_PadTriggerData& rhs); friend MsgStream& operator<<(MsgStream& stream, const NSW_PadTriggerData& rhs); + private: IdentifierHash m_identifierHash; uint8_t m_sectorID; - uint8_t m_sectorSize; - uint8_t m_endcap; + SectorSize m_sectorSize; + Endcap m_endcap; uint32_t m_BCID; uint32_t m_L1ID; // List of pad hits, in a 3BC window around the L1A BC @@ -41,4 +52,4 @@ private: }; } // namespace Muon -#endif // MUONRDO_NSW_PADTRIGGERDATA \ No newline at end of file +#endif // MUONRDO_NSW_PADTRIGGERDATA diff --git a/MuonSpectrometer/MuonRDO/MuonRDO/NSW_PadTriggerDataContainer.h b/MuonSpectrometer/MuonRDO/MuonRDO/NSW_PadTriggerDataContainer.h index ac296b6f6a0e..ee76fb0cb8df 100644 --- a/MuonSpectrometer/MuonRDO/MuonRDO/NSW_PadTriggerDataContainer.h +++ b/MuonSpectrometer/MuonRDO/MuonRDO/NSW_PadTriggerDataContainer.h @@ -14,6 +14,7 @@ namespace Muon { class NSW_PadTriggerDataContainer : public IdentifiableContainer<NSW_PadTriggerData> { public: + static constexpr std::size_t HASH_MAX{32}; NSW_PadTriggerDataContainer(); NSW_PadTriggerDataContainer(unsigned int hashMax); @@ -29,4 +30,4 @@ public: CLASS_DEF( Muon::NSW_PadTriggerDataContainer , 1176278125 , 1 ) -#endif // MUONRDO_NSW_PADTRIGGERRAWDATACONTAINER \ No newline at end of file +#endif // MUONRDO_NSW_PADTRIGGERRAWDATACONTAINER diff --git a/MuonSpectrometer/MuonRDO/src/NSW_PadTriggerData.cxx b/MuonSpectrometer/MuonRDO/src/NSW_PadTriggerData.cxx index 99fc260c411a..1cc2f2359d6b 100644 --- a/MuonSpectrometer/MuonRDO/src/NSW_PadTriggerData.cxx +++ b/MuonSpectrometer/MuonRDO/src/NSW_PadTriggerData.cxx @@ -1,8 +1,8 @@ #include "MuonRDO/NSW_PadTriggerData.h" namespace Muon { -NSW_PadTriggerData::NSW_PadTriggerData(IdentifierHash identifierHash, uint8_t sectorID, uint8_t sectorSize, - uint8_t endcap, uint32_t BCID, uint32_t L1ID, const std::array<hitlist_t, 3>& hitlists) +NSW_PadTriggerData::NSW_PadTriggerData(IdentifierHash identifierHash, uint8_t sectorID, SectorSize sectorSize, + Endcap endcap, uint32_t BCID, uint32_t L1ID, const std::array<hitlist_t, 3>& hitlists) : m_identifierHash(identifierHash), m_sectorID(sectorID), m_sectorSize(sectorSize), m_endcap(endcap), m_BCID(BCID), m_L1ID(L1ID), m_hitlists(hitlists) { } @@ -20,11 +20,11 @@ uint8_t NSW_PadTriggerData::sectorID() const noexcept { return m_sectorID; } -uint8_t NSW_PadTriggerData::sectorSize() const noexcept { +NSW_PadTriggerData::SectorSize NSW_PadTriggerData::sectorSize() const noexcept { return m_sectorSize; } -uint8_t NSW_PadTriggerData::endcap() const noexcept { +NSW_PadTriggerData::Endcap NSW_PadTriggerData::endcap() const noexcept { return m_endcap; } @@ -36,6 +36,32 @@ uint32_t NSW_PadTriggerData::L1ID() const noexcept { return m_L1ID; } +void NSW_PadTriggerData::sectorID(uint8_t sectorID) noexcept { + m_sectorID = sectorID; +} + +void NSW_PadTriggerData::sectorSize(NSW_PadTriggerData::SectorSize sectorSize) noexcept { + m_sectorSize = sectorSize; +} + +void NSW_PadTriggerData::endcap(NSW_PadTriggerData::Endcap endcap) noexcept { + m_endcap = endcap; +} + +void NSW_PadTriggerData::BCID(uint32_t BCID) noexcept { + m_BCID = BCID; +} + +void NSW_PadTriggerData::L1ID(uint32_t L1ID) noexcept { + m_L1ID = L1ID; +} + +void NSW_PadTriggerData::hitlists(const std::array<hitlist_t, 3>& hitlists) { + // Can be optimized w/ taking param by value - depends on use case + m_hitlists = hitlists; +} + + const std::array<NSW_PadTriggerData::hitlist_t, 3>& NSW_PadTriggerData::hitlists() const { return m_hitlists; } @@ -48,4 +74,4 @@ MsgStream& operator<<(MsgStream& stream, const NSW_PadTriggerData& rhs) { return stream << rhs.string(); } -} // namespace Muon \ No newline at end of file +} // namespace Muon diff --git a/MuonSpectrometer/MuonRDO/src/NSW_PadTriggerDataContainer.cxx b/MuonSpectrometer/MuonRDO/src/NSW_PadTriggerDataContainer.cxx index 4030d0697908..4628520d6c80 100644 --- a/MuonSpectrometer/MuonRDO/src/NSW_PadTriggerDataContainer.cxx +++ b/MuonSpectrometer/MuonRDO/src/NSW_PadTriggerDataContainer.cxx @@ -3,23 +3,23 @@ namespace Muon { NSW_PadTriggerDataContainer::NSW_PadTriggerDataContainer() - : IdentifiableContainer<NSW_PadTriggerData>(0) { } + : IdentifiableContainer<NSW_PadTriggerData>(HASH_MAX) { } -NSW_PadTriggerDataContainer::NSW_PadTriggerDataContainer(unsigned int hashMax) +NSW_PadTriggerDataContainer::NSW_PadTriggerDataContainer(unsigned int hashMax) : IdentifiableContainer<NSW_PadTriggerData>(hashMax) { } - + const CLID& NSW_PadTriggerDataContainer::classID() { return ClassID_traits<NSW_PadTriggerDataContainer>::ID(); } const CLID& NSW_PadTriggerDataContainer::clID() const { - return classID(); + return classID(); } std::string NSW_PadTriggerDataContainer::string() const { std::stringstream sstream{}; sstream << "Number of collections: " << numberOfCollections() << ". Contains collections: " << std::endl; - for (const auto* collection : *this) { + for (const auto& collection : *this) { sstream << collection->string() << std::endl; } return sstream.str(); diff --git a/Trigger/TrigT1/TrigT1NSW/share/NSWL1.py b/Trigger/TrigT1/TrigT1NSW/share/NSWL1.py index 753b5e96e3d2..394d2dde9d07 100644 --- a/Trigger/TrigT1/TrigT1NSW/share/NSWL1.py +++ b/Trigger/TrigT1/TrigT1NSW/share/NSWL1.py @@ -29,10 +29,10 @@ else: ################################################### from AthenaCommon.DetFlags import DetFlags DetFlags.detdescr.Muon_setOn() -DetFlags.sTGC_setOff() +DetFlags.sTGC_setOn() DetFlags.Micromegas_setOn() DetFlags.digitize.Micromegas_setOn() -DetFlags.digitize.sTGC_setOff() +DetFlags.digitize.sTGC_setOn() DetFlags.Truth_setOn() DetFlags.Print() @@ -55,7 +55,7 @@ svcMgr += Muon__MuonIdHelperSvc("MuonIdHelperSvc",HasCSC=MuonGeometryFlags.hasCS include('TrigT1NSW/TrigT1NSW_jobOptions.py') #Switch on and off trigger simulaton components sTGC / MicroMegas -topSequence.NSWL1Simulation.DosTGC=False +topSequence.NSWL1Simulation.DosTGC=True topSequence.NSWL1Simulation.UseLookup=False #use lookup table for the pad trigger topSequence.NSWL1Simulation.DoMM=True topSequence.NSWL1Simulation.DoMMDiamonds=True diff --git a/Trigger/TrigT1/TrigT1NSW/src/NSWL1Simulation.cxx b/Trigger/TrigT1/TrigT1NSW/src/NSWL1Simulation.cxx index e465f8a5bb62..8b6100dd61a5 100644 --- a/Trigger/TrigT1/TrigT1NSW/src/NSWL1Simulation.cxx +++ b/Trigger/TrigT1/TrigT1NSW/src/NSWL1Simulation.cxx @@ -41,7 +41,7 @@ namespace NSWL1 { declareProperty( "DoMM", m_doMM = true, "Run data analysis for MM" ); declareProperty( "DoMMDiamonds", m_doMMDiamonds = false, "Run data analysis for MM using Diamond Roads algorithm" ); declareProperty( "DosTGC", m_dosTGC = false, "Run data analysis for sTGCs" ); - + // declare monitoring tools declareProperty( "AthenaMonTools", m_monitors, "List of monitoring tools to be run with this instance, if incorrect then tool is silently skipped."); declareProperty( "PadTdsTool", m_pad_tds, "Tool that simulates the functionalities of the PAD TDS"); @@ -54,12 +54,13 @@ namespace NSWL1 { declareProperty( "MMStripTdsTool", m_mmstrip_tds, "Tool that simulates the functionalities of the MM STRIP TDS"); declareProperty( "MMTriggerTool", m_mmtrigger, "Tool that simulates the MM Trigger"); declareProperty( "NSWTrigRDOContainerName", m_trigRdoContainer = "NSWTRGRDO"," Give a name to NSW trigger rdo container"); + declareProperty( "PadTriggerRDOName", m_padTriggerRdoKey = "NSWPADTRGRDO", "Name of the pad trigger RDO"); } StatusCode NSWL1Simulation::initialize() { ATH_MSG_INFO( "initialize " << name() ); - ATH_CHECK( m_trigRdoContainer.initialize() ); + ATH_CHECK( m_trigRdoContainer.initialize() ); // Create an register the ntuple if requested, add branch for event and run number if ( m_doNtuple ) { ITHistSvc* tHistSvc; @@ -91,8 +92,9 @@ namespace NSWL1 { ATH_CHECK(m_strip_tds.retrieve()); //ATH_CHECK(m_strip_cluster.retrieve()); //ATH_CHECK(m_strip_segment.retrieve()); + ATH_CHECK(m_padTriggerRdoKey.initialize()); } - + if(m_doMM ){ ATH_CHECK(m_mmtrigger.retrieve()); } @@ -134,11 +136,16 @@ namespace NSWL1 { else{ ATH_CHECK( m_pad_trigger->compute_pad_triggers(pads, padTriggers) ); } - + ATH_CHECK( m_strip_tds->gather_strip_data(strips,padTriggers) ); //ATH_CHECK( m_strip_cluster->cluster_strip_data(strips,clusters) ); //ATH_CHECK( m_strip_segment->find_segments(clusters,trgContainer) ); - + + auto padTriggerRdoHandle = SG::makeHandle(m_padTriggerRdoKey); + auto padTriggerContainer = std::make_unique<Muon::NSW_PadTriggerDataContainer>(); + ATH_CHECK(PadTriggerAdapter::fillContainer(padTriggerContainer, padTriggers, m_current_evt)); + ATH_CHECK(padTriggerRdoHandle.record(std::move(padTriggerContainer))); + auto rdohandle = SG::makeHandle( m_trigRdoContainer ); ATH_CHECK( rdohandle.record( std::move(trgContainer))); } @@ -152,6 +159,22 @@ namespace NSWL1 { } if (m_tree) m_tree->Fill(); + // Dump content of the pad trigger collection + if (m_dosTGC) + { + const Muon::NSW_PadTriggerDataContainer* padTriggerContainer; + ATH_CHECK(evtStore()->retrieve(padTriggerContainer, m_padTriggerRdoKey.key())); + ATH_MSG_DEBUG("Pad Trigger Container size: " << padTriggerContainer->size()); + for (const auto &padTriggerData : *padTriggerContainer) + { + ATH_MSG_DEBUG(" " << *padTriggerData); + for (const auto & padTriggerSegment : *padTriggerData) + { + ATH_MSG_DEBUG(" " << *padTriggerSegment); + } + } + } + return StatusCode::SUCCESS; } diff --git a/Trigger/TrigT1/TrigT1NSW/src/NSWL1Simulation.h b/Trigger/TrigT1/TrigT1NSW/src/NSWL1Simulation.h index 119a2dc270be..7a50dd57c665 100644 --- a/Trigger/TrigT1/TrigT1NSW/src/NSWL1Simulation.h +++ b/Trigger/TrigT1/TrigT1NSW/src/NSWL1Simulation.h @@ -22,7 +22,12 @@ #include "TrigT1NSWSimTools/IPadTriggerLogicTool.h" #include "TrigT1NSWSimTools/IPadTriggerLookupTool.h" +#include "MuonRDO/NSW_PadTriggerDataContainer.h" +#include "TrigT1NSWSimTools/PadTriggerAdapter.h" + // Forward includes +class StoreGateSvc; +class IMonitorToolBase; class TTree; @@ -93,7 +98,7 @@ namespace NSWL1 { protected: SG::WriteHandleKey<Muon::NSW_TrigRawDataContainer> m_trigRdoContainer; - + SG::WriteHandleKey<Muon::NSW_PadTriggerDataContainer> m_padTriggerRdoKey; }; // end of NSWL1Simulation class diff --git a/Trigger/TrigT1/TrigT1NSWSimTools/TrigT1NSWSimTools/PadTriggerAdapter.h b/Trigger/TrigT1/TrigT1NSWSimTools/TrigT1NSWSimTools/PadTriggerAdapter.h new file mode 100644 index 000000000000..92951b66c372 --- /dev/null +++ b/Trigger/TrigT1/TrigT1NSWSimTools/TrigT1NSWSimTools/PadTriggerAdapter.h @@ -0,0 +1,21 @@ +#ifndef TRIGT1NSWSIMTOOLS_PADTRIGGERADAPTER_H +#define TRIGT1NSWSIMTOOLS_PADTRIGGERADAPTER_H + +#include "MuonRDO/NSW_PadTriggerData.h" +#include "MuonRDO/NSW_PadTriggerDataContainer.h" +#include "MuonRDO/NSW_PadTriggerSegment.h" +#include "TrigT1NSWSimTools/PadTrigger.h" + +namespace NSWL1{ +namespace PadTriggerAdapter { +// Convert a single simulated pad trigger segment to the RDO version of a pad trigger segment. +Muon::NSW_PadTriggerSegment segment(const NSWL1::PadTrigger& data); + +// Fill a pad trigger data container with data from a vector of pad trigger segments. +// If the container isn't empty, new data is simply appended to it. +StatusCode fillContainer(const std::unique_ptr<Muon::NSW_PadTriggerDataContainer>& out, + const std::vector<std::unique_ptr<NSWL1::PadTrigger>>& triggers, const uint32_t l1id); +} // namespace NSWL1 +} // namespace PadTriggerAdapter + +#endif // TRIGT1NSWSIMTOOLS_PADTRIGGERADAPTER_H \ No newline at end of file diff --git a/Trigger/TrigT1/TrigT1NSWSimTools/src/PadTriggerAdapter.cxx b/Trigger/TrigT1/TrigT1NSWSimTools/src/PadTriggerAdapter.cxx new file mode 100644 index 000000000000..b95452e7a898 --- /dev/null +++ b/Trigger/TrigT1/TrigT1NSWSimTools/src/PadTriggerAdapter.cxx @@ -0,0 +1,59 @@ +#include "TrigT1NSWSimTools/PadTriggerAdapter.h" + +namespace NSWL1 { +namespace PadTriggerAdapter { +Muon::NSW_PadTriggerSegment segment(const NSWL1::PadTrigger& data) { + return Muon::NSW_PadTriggerSegment{ + static_cast<uint8_t>(data.bandId()), + static_cast<uint8_t>(data.phiId()), + {static_cast<uint8_t>(data.trgSelectedLayersInner().size()), + static_cast<uint8_t>(data.trgSelectedLayersOuter().size())} + }; +} + +// TODO should probably be a tool, and then we can retrieve event data from +// evtStore +StatusCode +fillContainer(const std::unique_ptr<Muon::NSW_PadTriggerDataContainer> &out, + const std::vector<std::unique_ptr<NSWL1::PadTrigger>> &triggers, + const uint32_t l1id) { + using TriggerList = std::vector<const NSWL1::PadTrigger *>; + using TriggerMap = std::map<uint32_t, TriggerList>; + TriggerMap triggerMap; + // Filter by sector: + for (const auto &pt : triggers) { + // `sector` in range [0, 16) + auto sector = pt->triggerSectorNumber() - 1; + auto endcap = pt->sideId(); + if (sector == -1 || endcap == -1) { + return StatusCode::FAILURE; + } + // Calculate hash, range [0, 32) + const uint32_t hash = 16 * endcap + sector; + auto it = triggerMap.find(hash); + if (it == triggerMap.end()) { + it = triggerMap.insert(std::make_pair(hash, TriggerList())).first; + } + it->second.push_back(pt.get()); + } + for (const auto &item : triggerMap) { + uint32_t hash = item.first; + const TriggerList &triggerList = item.second; + auto pt = triggerList[0]; + auto newCollection = new Muon::NSW_PadTriggerData( + hash, pt->sectorId(), + static_cast<Muon::NSW_PadTriggerData::SectorSize>(pt->isSmall() ? 0 + : 1), + static_cast<Muon::NSW_PadTriggerData::Endcap>(pt->sideId()), + pt->bctag(), l1id, {}); + if (out->addCollection(newCollection, hash).isFailure()) { + return StatusCode::FAILURE; + } + for (auto pt : triggerList) + newCollection->push_back( + std::make_unique<Muon::NSW_PadTriggerSegment>(segment(*pt))); + } + return StatusCode::SUCCESS; +} +} // namespace PadTriggerAdapter +} // namespace NSWL1 diff --git a/Trigger/TrigT1/TrigT1NSWSimTools/src/PadTriggerLookupTool.cxx b/Trigger/TrigT1/TrigT1NSWSimTools/src/PadTriggerLookupTool.cxx index e7b649fb5fc1..cc12d32fa5e3 100644 --- a/Trigger/TrigT1/TrigT1NSWSimTools/src/PadTriggerLookupTool.cxx +++ b/Trigger/TrigT1/TrigT1NSWSimTools/src/PadTriggerLookupTool.cxx @@ -141,6 +141,9 @@ StatusCode PadTriggerLookupTool::expandCoincidenceTable(){//There we append 3o4s int phiid=kv.second.second; for(const int& in : innerIndices ){ std::vector<int> pattern=kv.first;//copy + if(pattern.at(in)==nullPadNumber || pattern.at(in+4)==nullPadNumber){ + continue; + } pattern.at(in)=nullPadNumber; for(const int& out :outerIndices){ int thispattern=pattern.at(out); -- GitLab