From 24fda6222611d2e078d3ab24609eb252b92823a6 Mon Sep 17 00:00:00 2001 From: yulunmiao Date: Tue, 11 Jun 2024 17:13:24 +0200 Subject: [PATCH] Update unpacker to use HGCalConfiguration structure --- .../HGCalDigi/interface/HGCalECONDInfoSoA.h | 1 + .../interface/HGCalRawDataDefinitions.h | 2 +- .../HGCalDigi/src/alpaka/classes_cuda.h | 2 + .../HGCalDigi/src/alpaka/classes_cuda_def.xml | 3 + .../HGCalDigi/src/alpaka/classes_rocm.h | 2 + .../HGCalDigi/src/alpaka/classes_rocm_def.xml | 3 + DataFormats/HGCalDigi/src/classes.cc | 2 +- DataFormats/HGCalDigi/src/classes.h | 2 + DataFormats/HGCalDigi/src/classes_def.xml | 18 ++- .../HGCalRawToDigi/interface/HGCalUnpacker.h | 4 + .../HGCalRawToDigi/plugins/HGCalRawToDigi.cc | 11 +- .../HGCalRawToDigi/src/HGCalUnpacker.cc | 115 ++++++++++++++---- 12 files changed, 138 insertions(+), 27 deletions(-) diff --git a/DataFormats/HGCalDigi/interface/HGCalECONDInfoSoA.h b/DataFormats/HGCalDigi/interface/HGCalECONDInfoSoA.h index e85514b65951b..977d7b7c3f91b 100644 --- a/DataFormats/HGCalDigi/interface/HGCalECONDInfoSoA.h +++ b/DataFormats/HGCalDigi/interface/HGCalECONDInfoSoA.h @@ -47,6 +47,7 @@ namespace hgcaldigi { // 3: Wrong ECON-D header marker // 4: ECON-D payload length overflow(>469) // 5: unpacked ECON-D length and payload length not match + // 6: S-Link trailer location error SOA_COLUMN(uint8_t, exception), // Location // If exception found before ECON-D, this would be 0 diff --git a/DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h b/DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h index 42fc1e6594f83..8502ddd42f5a5 100644 --- a/DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h +++ b/DataFormats/HGCalDigi/interface/HGCalRawDataDefinitions.h @@ -74,7 +74,7 @@ namespace hgcal { CAPTUREBLOCK_OC_MASK = 0x7, CAPTUREBLOCK_OC_POS = 4, SLINK_BOE_MASK = 0xff, - SLINK_BOE_POS = 23, + SLINK_BOE_POS = 24, SLINK_V_MASK = 0xf, SLINK_V_POS = 19, SLINK_R8_MASK = 0xff, diff --git a/DataFormats/HGCalDigi/src/alpaka/classes_cuda.h b/DataFormats/HGCalDigi/src/alpaka/classes_cuda.h index a78512aa060c5..d1307aa2be58d 100644 --- a/DataFormats/HGCalDigi/src/alpaka/classes_cuda.h +++ b/DataFormats/HGCalDigi/src/alpaka/classes_cuda.h @@ -2,3 +2,5 @@ #include "DataFormats/Common/interface/Wrapper.h" #include "DataFormats/HGCalDigi/interface/HGCalDigiSoA.h" #include "DataFormats/HGCalDigi/interface/alpaka/HGCalDigiDevice.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDInfoSoA.h" +#include "DataFormats/HGCalDigi/interface/alpaka/HGCalECONDInfoDevice.h" \ No newline at end of file diff --git a/DataFormats/HGCalDigi/src/alpaka/classes_cuda_def.xml b/DataFormats/HGCalDigi/src/alpaka/classes_cuda_def.xml index 6abdce5a38391..8eaf2d217a269 100644 --- a/DataFormats/HGCalDigi/src/alpaka/classes_cuda_def.xml +++ b/DataFormats/HGCalDigi/src/alpaka/classes_cuda_def.xml @@ -2,4 +2,7 @@ + + + diff --git a/DataFormats/HGCalDigi/src/alpaka/classes_rocm.h b/DataFormats/HGCalDigi/src/alpaka/classes_rocm.h index a78512aa060c5..d1307aa2be58d 100644 --- a/DataFormats/HGCalDigi/src/alpaka/classes_rocm.h +++ b/DataFormats/HGCalDigi/src/alpaka/classes_rocm.h @@ -2,3 +2,5 @@ #include "DataFormats/Common/interface/Wrapper.h" #include "DataFormats/HGCalDigi/interface/HGCalDigiSoA.h" #include "DataFormats/HGCalDigi/interface/alpaka/HGCalDigiDevice.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDInfoSoA.h" +#include "DataFormats/HGCalDigi/interface/alpaka/HGCalECONDInfoDevice.h" \ No newline at end of file diff --git a/DataFormats/HGCalDigi/src/alpaka/classes_rocm_def.xml b/DataFormats/HGCalDigi/src/alpaka/classes_rocm_def.xml index eae186fd8f407..a8a75f2cdb358 100644 --- a/DataFormats/HGCalDigi/src/alpaka/classes_rocm_def.xml +++ b/DataFormats/HGCalDigi/src/alpaka/classes_rocm_def.xml @@ -2,4 +2,7 @@ + + + diff --git a/DataFormats/HGCalDigi/src/classes.cc b/DataFormats/HGCalDigi/src/classes.cc index 3e2872fba61cd..fbdd550a3212b 100644 --- a/DataFormats/HGCalDigi/src/classes.cc +++ b/DataFormats/HGCalDigi/src/classes.cc @@ -1,4 +1,4 @@ #include "DataFormats/Portable/interface/PortableHostCollectionReadRules.h" #include "DataFormats/HGCalDigi/interface/HGCalDigiHost.h" -SET_PORTABLEHOSTCOLLECTION_READ_RULES(hgcaldigi::HGCalDigiHost); +SET_PORTABLEHOSTCOLLECTION_READ_RULES(hgcaldigi::HGCalDigiHost); \ No newline at end of file diff --git a/DataFormats/HGCalDigi/src/classes.h b/DataFormats/HGCalDigi/src/classes.h index f8b2b0ab29c3f..c2d2b3cc18887 100644 --- a/DataFormats/HGCalDigi/src/classes.h +++ b/DataFormats/HGCalDigi/src/classes.h @@ -8,3 +8,5 @@ #include "DataFormats/HGCalDigi/interface/HGCalDigiHost.h" #include "DataFormats/HGCalDigi/interface/HGCalDigiSoA.h" #include "DataFormats/HGCalDigi/interface/HGCalFlaggedECONDInfo.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDInfoHost.h" +#include "DataFormats/HGCalDigi/interface/HGCalECONDInfoSoA.h" \ No newline at end of file diff --git a/DataFormats/HGCalDigi/src/classes_def.xml b/DataFormats/HGCalDigi/src/classes_def.xml index e08aaab75b799..8aa30fe938679 100644 --- a/DataFormats/HGCalDigi/src/classes_def.xml +++ b/DataFormats/HGCalDigi/src/classes_def.xml @@ -48,10 +48,26 @@ - + + + + + + + + + diff --git a/EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h b/EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h index 384bc3e64d095..f886a65d0a078 100644 --- a/EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h +++ b/EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h @@ -15,6 +15,9 @@ #include "DataFormats/HGCalDigi/interface/HGCalDigiHost.h" #include "DataFormats/HGCalDigi/interface/HGCalECONDInfoHost.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" +#include "CondFormats/HGCalObjects/interface/HGCalConfiguration.h" +#include "FWCore/Utilities/interface/Exception.h" + #include #include #include @@ -30,6 +33,7 @@ class HGCalUnpacker { void parseFEDData(unsigned fedId, const FEDRawData& fed_data, const HGCalMappingModuleIndexer& moduleIndexer, + const HGCalConfiguration& config, hgcaldigi::HGCalDigiHost& digis, hgcaldigi::HGCalECONDInfoHost& econdInfo, bool headerOnlyMode = false); diff --git a/EventFilter/HGCalRawToDigi/plugins/HGCalRawToDigi.cc b/EventFilter/HGCalRawToDigi/plugins/HGCalRawToDigi.cc index 5481e7464c351..9499b32e57ada 100644 --- a/EventFilter/HGCalRawToDigi/plugins/HGCalRawToDigi.cc +++ b/EventFilter/HGCalRawToDigi/plugins/HGCalRawToDigi.cc @@ -16,6 +16,8 @@ #include "CondFormats/DataRecord/interface/HGCalElectronicsMappingRcd.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingModuleIndexer.h" #include "CondFormats/HGCalObjects/interface/HGCalMappingCellIndexer.h" +#include "CondFormats/DataRecord/interface/HGCalModuleConfigurationRcd.h" +#include "CondFormats/HGCalObjects/interface/HGCalConfiguration.h" // #include "CondFormats/HGCalObjects/interface/alpaka/HGCalMappingParameterDeviceCollection.h" // #include "Geometry/HGCalMapping/interface/HGCalMappingTools.h" @@ -36,6 +38,7 @@ class HGCalRawToDigi : public edm::stream::EDProducer<> { // output tokens const edm::EDPutTokenT digisToken_; + const edm::EDPutTokenT econdInfoToken_; // TODO @hqucms // what else do we want to output? @@ -48,8 +51,10 @@ class HGCalRawToDigi : public edm::stream::EDProducer<> { edm::ESWatcher mapWatcher_; edm::ESGetToken cellIndexToken_; edm::ESGetToken moduleIndexToken_; + edm::ESGetToken configToken_; HGCalMappingCellIndexer cellIndexer_; HGCalMappingModuleIndexer moduleIndexer_; + HGCalConfiguration config_; // TODO @hqucms // how to implement this enabled eRx pattern? Can this be taken from the logical mapping? @@ -67,11 +72,13 @@ class HGCalRawToDigi : public edm::stream::EDProducer<> { HGCalRawToDigi::HGCalRawToDigi(const edm::ParameterSet& iConfig) : fedRawToken_(consumes(iConfig.getParameter("src"))), digisToken_(produces()), + econdInfoToken_(produces()), // flaggedRawDataToken_(produces("UnpackerFlags")), // elecDigisToken_(produces("DIGI")), // elecCMsToken_(produces("CM")), cellIndexToken_(esConsumes()), moduleIndexToken_(esConsumes()), + configToken_(esConsumes()), // unpackerConfig_(HGCalUnpackerConfig{.sLinkBOE = iConfig.getParameter("slinkBOE"), // .cbHeaderMarker = iConfig.getParameter("cbHeaderMarker"), // .econdHeaderMarker = iConfig.getParameter("econdHeaderMarker"), @@ -84,6 +91,7 @@ void HGCalRawToDigi::beginRun(edm::Run const& iRun, edm::EventSetup const& iSetu if (mapWatcher_.check(iSetup)) { moduleIndexer_ = iSetup.getData(moduleIndexToken_); cellIndexer_ = iSetup.getData(cellIndexToken_); + config_ = iSetup.getData(configToken_); } // TODO @hqucms @@ -108,7 +116,7 @@ void HGCalRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) const auto& fed_data = raw_data.FEDData(fedId); if (fed_data.size() == 0) continue; - unpacker_.parseFEDData(fedId, fed_data, moduleIndexer_, digis, econdInfo, /*headerOnlyMode*/ false); + unpacker_.parseFEDData(fedId, fed_data, moduleIndexer_, config_, digis, econdInfo, /*headerOnlyMode*/ false); } // TODO @hqucms @@ -183,6 +191,7 @@ void HGCalRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) // put information to the event iEvent.emplace(digisToken_, std::move(digis)); + iEvent.emplace(econdInfoToken_,std::move(econdInfo)); // iEvent.emplace(flaggedRawDataToken_, std::move(flagged_econds)); // iEvent.emplace(elecDigisToken_, std::move(elec_digis)); // iEvent.emplace(elecCMsToken_, std::move(elec_cms)); diff --git a/EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc b/EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc index 713176888972a..5c1258c93aa85 100644 --- a/EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc +++ b/EventFilter/HGCalRawToDigi/src/HGCalUnpacker.cc @@ -15,6 +15,7 @@ using namespace hgcal; void HGCalUnpacker::parseFEDData(unsigned fedId, const FEDRawData& fed_data, const HGCalMappingModuleIndexer& moduleIndexer, + const HGCalConfiguration& config, hgcaldigi::HGCalDigiHost& digis, hgcaldigi::HGCalECONDInfoHost& econdInfo, bool headerOnlyMode) { @@ -23,6 +24,8 @@ void HGCalUnpacker::parseFEDData(unsigned fedId, // ReadoutSequence object for this FED const auto& fedReadoutSequence = moduleIndexer.fedReadoutSequences_[fedId]; + // Configuration object for this FED + const auto& fedConfig = config.feds[fedId]; // helper functions auto to_32b_words = [](const uint64_t* ptr_64b) { @@ -57,11 +60,22 @@ void HGCalUnpacker::parseFEDData(unsigned fedId, std::cout << "@@@\n"; ptr = header; - // check SLink header (128b) - // TODO - ptr += 2; + // sanity check + auto slink_header = *(ptr + 1); + if (((slink_header >> (BACKEND_FRAME::SLINK_BOE_POS + 32)) & BACKEND_FRAME::SLINK_BOE_MASK) != + fedConfig.slinkHeaderMarker) { + uint32_t ECONDdenseIdx = moduleIndexer.getIndexForModule(fedId, 0); + econdInfo.view()[ECONDdenseIdx].exception() = 1; + econdInfo.view()[ECONDdenseIdx].location() = 0; + throw cms::Exception("CorruptData") << "Expected a S-Link header (BOE: 0x" << std::hex + << fedConfig.slinkHeaderMarker << "), got 0x" << std::hex + << ((slink_header >> (BACKEND_FRAME::SLINK_BOE_POS + 32)) & + BACKEND_FRAME::SLINK_BOE_MASK) + << " from " << slink_header << "." << std::endl; + } + ptr += 2; // counter for the global index of ECON-D in the FED // initialize with -1 (overflow) to start with 0 in the loop uint32_t globalECONDIdx = static_cast(-1); @@ -73,10 +87,22 @@ void HGCalUnpacker::parseFEDData(unsigned fedId, std::cout << "@" << std::setw(8) << std::distance(header, ptr) << ": 0x" << std::hex << std::setfill('0') << std::setw(16) << *ptr << std::dec << std::endl; auto cb_header = *ptr; - ++ptr; std::cout << "fedId = " << fedId << ", captureblockIdx = " << captureblockIdx << ", cb_header = " << std::hex << std::setfill('0') << std::setw(16) << cb_header << std::dec << std::endl; - + // sanity check + if (((cb_header >> (BACKEND_FRAME::CAPTUREBLOCK_RESERVED_POS + 32)) & BACKEND_FRAME::CAPTUREBLOCK_RESERVED_MASK) != + fedConfig.cbHeaderMarker) { + uint32_t ECONDdenseIdx = moduleIndexer.getIndexForModule(fedId, 0); + econdInfo.view()[ECONDdenseIdx].exception() = 2; + econdInfo.view()[ECONDdenseIdx].location() = (uint32_t)(ptr - header); + throw cms::Exception("CorruptData") + << "Expected a capture block header at word " << std::dec << (uint32_t)(ptr - header) << "/0x" << std::hex + << (uint32_t)(ptr - header) << " (reserved word: 0x" << fedConfig.cbHeaderMarker << "), got 0x" + << ((cb_header >> (BACKEND_FRAME::CAPTUREBLOCK_RESERVED_POS + 32)) & + BACKEND_FRAME::CAPTUREBLOCK_RESERVED_MASK) + << " from 0x" << cb_header << "."; + } + ++ptr; // parse Capture Block body (ECON-Ds) for (uint32_t econdIdx = 0; econdIdx < HGCalMappingModuleIndexer::maxECONDperCB_; econdIdx++) { auto econd_pkt_status = (cb_header >> (3 * econdIdx)) & 0b111; @@ -86,11 +112,6 @@ void HGCalUnpacker::parseFEDData(unsigned fedId, // always increment the global ECON-D index (unless inactive/unconnected) globalECONDIdx++; } - - uint32_t ECONDdenseIdx = moduleIndexer.getIndexForModule(fedId, globalECONDIdx); - econdInfo.view()[ECONDdenseIdx].location() = (uint32_t)(ptr - header); - econdInfo.view()[ECONDdenseIdx].cbFlag() = (uint8_t)(econd_pkt_status); - bool pkt_exists = (econd_pkt_status == backend::ECONDPacketStatus::Normal) || (econd_pkt_status == backend::ECONDPacketStatus::PayloadCRCError) || @@ -104,11 +125,28 @@ void HGCalUnpacker::parseFEDData(unsigned fedId, std::cout << "@" << std::setw(8) << std::distance(header, ptr) << ": 0x" << std::hex << std::setfill('0') << std::setw(16) << *ptr << std::dec << std::endl; auto econd_headers = to_32b_words(ptr); + uint32_t ECONDdenseIdx = moduleIndexer.getIndexForModule(fedId, globalECONDIdx); + econdInfo.view()[ECONDdenseIdx].location() = (uint32_t)(ptr - header); + // sanity check + if (((econd_headers[0] >> ECOND_FRAME::HEADER_POS) & ECOND_FRAME::HEADER_MASK) != + fedConfig.econds[globalECONDIdx].headerMarker) { + econdInfo.view()[ECONDdenseIdx].exception() = 3; + throw cms::Exception("CorruptData") + << "Expected a ECON-D header at word " << std::dec << (uint32_t)(ptr - header) << "/0x" << std::hex + << (uint32_t)(ptr - header) << " (marker: 0x" << fedConfig.econds[globalECONDIdx].headerMarker + << "), got 0x" << econd_headers[0] << "."; + } ++ptr; + econdInfo.view()[ECONDdenseIdx].cbFlag() = (uint8_t)(econd_pkt_status); // ECON-D payload length (num of 32b words) // NOTE: in the capture blocks, ECON-D packets do not have the trailing IDLE word const auto econd_payload_length = ((econd_headers[0] >> ECOND_FRAME::PAYLOAD_POS) & ECOND_FRAME::PAYLOAD_MASK); + if (econd_payload_length > 469) { + econdInfo.view()[ECONDdenseIdx].exception() = 4; + throw cms::Exception("CorruptData") + << "Unpacked payload length=" << econd_payload_length << " exceeds the maximal length=469"; + } const auto econdFlag = ((econd_headers[0] >> ECOND_FRAME::BITT_POS) & 0b1111111) + (((econd_headers[1] >> ECOND_FRAME::BITS_POS) & 0b1) << ECONDFlag::BITS_POS); econdInfo.view()[ECONDdenseIdx].payloadLength() = (uint16_t)econd_payload_length; @@ -228,23 +266,45 @@ void HGCalUnpacker::parseFEDData(unsigned fedId, if (((erxHeader >> channelIdx) & 1) == 0) { continue; } - - // TODO: Check what to do with pass through ECOND - // can re-use the implementation in HGCROCChannelDataFrame - // but needs to know whether the ROCs are in characterization mode or not - digis.view()[denseIdx].tctp() = (econd_payload[iword] >> 30) & 0b11; - digis.view()[denseIdx].adcm1() = 0; - digis.view()[denseIdx].adc() = (econd_payload[iword] >> 20) & 0b1111111111; - digis.view()[denseIdx].tot() = (econd_payload[iword] >> 10) & 0b1111111111; - digis.view()[denseIdx].toa() = econd_payload[iword] & 0b1111111111; - digis.view()[denseIdx].cm() = cmSum; - digis.view()[denseIdx].flags() = 0; + // check if in characteristic mode + if (fedConfig.econds[globalECONDIdx].rocs[erxIdx / 2].charMode) { + //characteristic mode + digis.view()[denseIdx].tctp() = (econd_payload[iword] >> 30) & 0b11; + digis.view()[denseIdx].adcm1() = 0; + digis.view()[denseIdx].adc() = (econd_payload[iword] >> 20) & 0b1111111111; + digis.view()[denseIdx].tot() = (econd_payload[iword] >> 10) & 0b1111111111; + digis.view()[denseIdx].toa() = econd_payload[iword] & 0b1111111111; + digis.view()[denseIdx].cm() = cmSum; + digis.view()[denseIdx].flags() = 0; + } else { + //not characteristic mode + digis.view()[denseIdx].tctp() = (econd_payload[iword] >> 30) & 0b11; + + digis.view()[denseIdx].adcm1() = (econd_payload[iword] >> 20) & 0b1111111111; + if (econd_payload[iword] >> 31 & 0b1) { + digis.view()[denseIdx].adc() = 0; + digis.view()[denseIdx].tot() = (econd_payload[iword] >> 10) & 0b1111111111; + } else { + digis.view()[denseIdx].adc() = (econd_payload[iword] >> 10) & 0b1111111111; + digis.view()[denseIdx].tot() = 0; + } + digis.view()[denseIdx].toa() = econd_payload[iword] & 0b1111111111; + digis.view()[denseIdx].cm() = cmSum; + digis.view()[denseIdx].flags() = 0; + } iword += 1; } } } - // end of ECON-D parsing + if (iword != econd_payload_length - 1) { + econdInfo.view()[ECONDdenseIdx].exception() = 5; + throw cms::Exception("CorruptData") + << "Mismatch between unpacked and expected ECON-D #" << (int)globalECONDIdx << " payload length\n" + << " unpacked payload length=" << iword + 1 << "\n" + << " expected payload length=" << econd_payload_length; + } + econdInfo.view()[ECONDdenseIdx].exception() = 0; } // skip the padding word as capture blocks are padded to 128b if (std::distance(ptr, header) % 2) { @@ -254,5 +314,14 @@ void HGCalUnpacker::parseFEDData(unsigned fedId, // check SLink trailer (128b) // TODO - assert(ptr + 2 == trailer); + if (ptr + 2 != trailer) { + uint32_t ECONDdenseIdx = moduleIndexer.getIndexForModule(fedId, 0); + econdInfo.view()[ECONDdenseIdx].exception() = 6; + econdInfo.view()[ECONDdenseIdx].location() = 0; + throw cms::Exception("CorruptData") << "Error finding the S-link trailer, expected at" << std::dec + << (uint32_t)(trailer - header) << "/0x" << std::hex + << (uint32_t)(trailer - header) << "Unpacked trailer at" << std::dec + << (uint32_t)(trailer - header + 2) << "/0x" << std::hex + << (uint32_t)(ptr - header + 2); + } }