diff --git a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.cxx b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.cxx index bf15e3950caa070d36e92f92e64af0c9976abddd..640bc6d9f8e140f9f0f3a6bda91db0df866381c4 100644 --- a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.cxx +++ b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.cxx @@ -14,7 +14,7 @@ #include "Identifier/IdentifierHash.h" #include <algorithm> -#include <deque> +#include <array> #include <utility> union RawWord { @@ -46,7 +46,7 @@ StatusCode SCT_RodDecoder::initialize() ATH_CHECK(m_configTool.retrieve()); - // See if strip numbers go from 0 to 767 or vice versa for all the wafers. + // See if strip numbers go from 0 to N_STRIPS_PER_SIDE-1(=767) or vice versa for all the wafers. // swapPhiReadoutDirection will not change during a run. // Since this is access to SiDetectorElement during initialization, // condition object of SiDetectorElementCollection is not accessible. @@ -162,7 +162,6 @@ StatusCode SCT_RodDecoder::finalize() ATH_MSG_INFO("Number of SCT RDOs created-> " << m_nRDOs); if (m_numMissingLinkHeader > 0) ATH_MSG_WARNING("SCT Missing Link Headers found " << m_numMissingLinkHeader); - if (m_numUnknownOfflineID > 0) ATH_MSG_WARNING("SCT unknown onlineIDs found " << m_numUnknownOfflineID); ATH_CHECK(AlgTool::finalize()); ATH_MSG_DEBUG("SCT_RodDecoder::finalize()"); @@ -182,13 +181,13 @@ class SCT_RodDecoderErrorsHelper { public: SCT_RodDecoderErrorsHelper( IDCInDetBSErrContainer& idcContainer ) : m_errorsIDC{ idcContainer } {} - ~SCT_RodDecoderErrorsHelper() { + ~SCT_RodDecoderErrorsHelper() { for ( auto [id, err]: m_accumulatedErrors ) { m_errorsIDC.setOrDrop( id, err ); } } - void add( const IdentifierHash id, SCT_ByteStreamErrors::ErrorType etype) { - SCT_ByteStreamErrors::addError( m_accumulatedErrors[id], etype); + void add(const IdentifierHash id, SCT_ByteStreamErrors::ErrorType etype) { + SCT_ByteStreamErrors::addError(m_accumulatedErrors[id], etype); } private: @@ -207,11 +206,11 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB const uint32_t robID{robFrag.rod_source_id()}; // Determine whether this data was generated using the ROD simulator const uint32_t rodDataType{robFrag.rod_detev_type()}; - const bool rodSimulatedData{static_cast<bool>((rodDataType >> 20) & 1)}; + const bool rodSimulatedData{static_cast<bool>((rodDataType >> 20) & 0x1)}; if (rodSimulatedData) ATH_CHECK(addRODError(robID, SCT_ByteStreamErrors::RODSimulatedData, errs)); // Look for the bit that denotes "Super-condensed" mode - const bool superCondensedMode{static_cast<bool>((rodDataType >> 21) & 1)}; + const bool superCondensedMode{static_cast<bool>((rodDataType >> 21) & 0x1)}; bool condensedMode{true}; @@ -221,27 +220,28 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB int chip{0}; int side{0}; int nStripsInWord{0}; - int linkNumber{0}; - uint32_t onlineID{0}; + int linkNumber{0}; // Determined from header and may be changed for links using Rx redundancy + uint32_t onlineID{0}; // Determined from header and may be changed for links using Rx redundancy + IdentifierHash currentLinkIDHash; // Determined from header and changed for links using Rx redundancy int timeBin{0}; int groupSize{0}; - bool saved[768*2]{false}; - int abcError{0}; - int wordCount{-1}; + std::array<bool, N_STRIPS_PER_SIDE*N_SIDES> saved; + saved.fill(false); RawWord robData; robData.word32=0; - int n; int errors{0}; // Encodes the errors on the header (bit 4: error in condensed mode 1st hit, bit 5: error in condensed mode 2nd hit) // These are for the trigger CacheHelper cache; cache.vecHash = vecHash; - IdentifierHash currentLinkIDHash; - std::vector<int> errorHit; + // For MissingLinkHeaderError + bool foundMissingLinkHeaderError{false}; + std::unordered_set<IdentifierHash> foundHashes; + StatusCode sc{StatusCode::SUCCESS, true}; // Look at ROB status word @@ -290,8 +290,8 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB sc=StatusCode::RECOVERABLE; } // Look at bits 20-23 for DCS HV - // const int hvBits{static_cast<int>((statusWord >> 20) & 0xf)}; - // const bool hvOn{hvBits==0xf}; + // const int hvBits{static_cast<int>((statusWord >> 20) & 0xF)}; + // const bool hvOn{hvBits==0xF}; } } @@ -301,21 +301,111 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB OFFLINE_FRAGMENTS_NAMESPACE::PointerType vecROBData; const unsigned long int vecROBDataSize{robFrag.rod_ndata()}; robFrag.rod_data(vecROBData); - + + // Loop over header, hit element, flagged ABCD error, raw data, trailer words for (unsigned long int i{0}; i<vecROBDataSize; i++) { - wordCount++; robData.word32 = vecROBData[i]; // The data is 16-bits wide packed to a 32-bit word (rob_it1). So we unpack it here. uint16_t data16[2]; data16[1] = robData.word16[0]; data16[0] = robData.word16[1]; - for (n=0; n<2; n++) { + for (int n{0}; n<2; n++) { + // Header + if (((data16[n]>>13)&0x7) == 0x1) { + foundHeader=true; + m_headNumber++; + + // Create the last RDO of the previous link if any + if (saved[side*N_STRIPS_PER_SIDE+strip]==false and oldStrip>=0) { + const int rdoMade{makeRDO(strip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; + if (rdoMade == -1) { + sc=StatusCode::RECOVERABLE; + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); + } + else { + saved[side*N_STRIPS_PER_SIDE+strip] = rdoMade; + } + } + + // Everything is set to default for a new hunt of RDO + strip =0; + oldStrip = -1; + oldSide = -1; + groupSize = 0; + errors = 0; + saved.fill(false); + errorHit.clear(); + + // Link Number (or stream) in the ROD fragment + const int rodlinkNumber{static_cast<int>(data16[n] & 0x7F)}; + + // This is the real calculation for the offline + linkNumber = (((rodlinkNumber >>4)&0x7)*12+(rodlinkNumber &0xF)); + onlineID = ((robID & 0xFFFFFF) | (linkNumber << 24)); + if ((onlineID ==0) or (linkNumber > 95)) { + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); + sc=StatusCode::RECOVERABLE; + ATH_MSG_DEBUG("Header: xxx Link number out of range (skipping following data)" + << std::dec << linkNumber); + break; + } + else { + currentLinkIDHash = m_cabling->getHashFromOnlineId(onlineID); + foundHashes.insert(currentLinkIDHash); + } + // Look for masked off links - bit 7 + if ((data16[n] >> 7) & 0x1) { + ATH_MSG_DEBUG("Masked link " << onlineID << " " << currentLinkIDHash); + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::MaskedLink, errs)); + sc=StatusCode::RECOVERABLE; + } + if (data16[n]&0x800) { + ATH_MSG_DEBUG(" Header: xxx TimeOut Error " << currentLinkIDHash); + m_headErrorTimeout++; + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::TimeOutError, errs)); + sc=StatusCode::RECOVERABLE; + } + + if (data16[n]&0x1000) { + ATH_MSG_DEBUG(" Header: xxx Preamble Error " << currentLinkIDHash); + m_headErrorPreamble++; + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::PreambleError, errs)); + sc=StatusCode::RECOVERABLE; + } + + if (data16[n]&0x400) { + ATH_MSG_DEBUG(" Header: xxx LVL1 ID Error " << currentLinkIDHash); + m_headErrorLvl1ID++; + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::LVL1IDError, errs)); + sc=StatusCode::RECOVERABLE; + } + + if (data16[n]&0x200) { + ATH_MSG_DEBUG(" Header: xxx BCID Error " << currentLinkIDHash); + m_headErrorBCID++; + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::BCIDError, errs)); + sc=StatusCode::RECOVERABLE; + } + + if ((data16[n]&0xF) > 11) { + ATH_MSG_DEBUG(" Header: xxx Error in formatter " << currentLinkIDHash); + m_headErrorFormatter++; + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::FormatterError, errs)); + sc=StatusCode::RECOVERABLE; + } + + condensedMode = static_cast<bool>(data16[n]&0x100); + + continue; + + } // End header + // Hit element - if (data16[n]&0x8000) { + else if (data16[n]&0x8000) { if (not foundHeader) { ATH_MSG_INFO(" Missing link header in ROD " << std::hex << robID << std::dec); - ATH_CHECK(addRODError(robID, SCT_ByteStreamErrors::MissingLinkHeaderError, errs)); + foundMissingLinkHeaderError = true; m_numMissingLinkHeader++; sc = StatusCode::RECOVERABLE; continue; @@ -324,61 +414,68 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB m_nHits++; if (superCondensedMode) { // Super-condensed mode: - // Chip info: 4 bits data16[n]>>11)0xF + // Chip info: 4 bits data16[n]>>11)&0xF // Chip number == (data16[n]>>11)&0x7 // Chip side == (data16[n]>>14)&0x1 - // For example if data16[n]>>11)0xF = 0101 => chip5 or chip5 on side0, data16[n]>>11)0xF = 1101 => chip13 or chip5 on side1 + // For example if (data16[n]>>11)&0xF = 0101 => chip 5 or chip5 on side0, (data16[n]>>11)&0xF = 1101 => chip13 or chip5 on side1 chip = ((data16[n]>>11)&0x7); side = ((data16[n]>>14)&0x1); - strip = chip*128 + ((data16[n]>>4)&0x7F); + strip = chip*N_STRIPS_PER_CHIP + ((data16[n]>>4)&0x7F); timeBin = 0x2; // Assuming timeBin is 010 in super-condensed mode - nStripsInWord = (data16[n]&0xf)+1; - if (chip>5) { - ATH_MSG_DEBUG(" Hit super-condensed : xxx Chip number = " << chip << " > 5 " << " for hit " + nStripsInWord = (data16[n]&0xF)+1; + if (chip>=N_CHIPS_PER_SIDE) { + ATH_MSG_DEBUG(" Hit super-condensed : xxx Chip number = " << chip << " >= "<< N_CHIPS_PER_SIDE << " for hit " << std::hex << data16[n]); m_chipNumberError++; - ATH_CHECK( addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs) ); + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); sc=StatusCode::RECOVERABLE; continue; } // Search for redundancy only for the master chip + bool secondSide{false}; if ((side==1) and ((linkNumber%2)==0)) { if (((strip!=oldStrip) or (side!=oldSide)) and (groupSize>0)) { // If it is a new cluster, make RDO with the previous cluster - const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; + const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; if (rdoMade == -1) { sc=StatusCode::RECOVERABLE; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); } else { - saved[oldSide*768+oldStrip] = rdoMade; + saved[oldSide*N_STRIPS_PER_SIDE+oldStrip] = rdoMade; } oldStrip = strip; oldSide = side; groupSize = 0; } linkNumber++; + secondSide = true; } - if ((side==0) and ((linkNumber%2)!=0)) { + else if ((side==0) and ((linkNumber%2)!=0)) { if (((strip!=oldStrip) or (side!=oldSide)) and (groupSize>0)) { // If it is a new cluster, make RDO with the previous cluster - const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; + const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; if (rdoMade == -1) { sc=StatusCode::RECOVERABLE; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); } else { - saved[oldSide*768+oldStrip] = rdoMade; + saved[oldSide*N_STRIPS_PER_SIDE+oldStrip] = rdoMade; } oldStrip = strip; oldSide = side; groupSize = 0; } linkNumber--; + secondSide = true; } - onlineID = ((robID & 0xFFFFFF)|(linkNumber << 24)); - + if (secondSide) { + onlineID = ((robID & 0xFFFFFF) | (linkNumber << 24)); + currentLinkIDHash = m_cabling->getHashFromOnlineId(onlineID); + foundHashes.insert(currentLinkIDHash); + } + if (groupSize == 0) { oldStrip = strip; // If it's the first super-condensed word oldSide = side; @@ -386,13 +483,13 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB if ((strip!=oldStrip) or (side!=oldSide)) { // If it is a new cluster, make RDO with the previous cluster - const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; + const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; if (rdoMade == -1) { sc=StatusCode::RECOVERABLE; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); } else { - saved[oldSide*768+oldStrip] = rdoMade; + saved[oldSide*N_STRIPS_PER_SIDE+oldStrip] = rdoMade; } oldStrip = strip; oldSide = side; @@ -403,16 +500,16 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB } else if (condensedMode) { // Super-condensed mode: - // Chip info: 4 bits data16[n]>>11)0xF + // Chip info: 4 bits data16[n]>>11)&0xF // Chip number == (data16[n]>>11)&0x7 // Chip side == (data16[n]>>14)&0x1 - // For example if data16[n]>>11)0xF = 0101 => chip5 or chip5 on side0, data16[n]>>11)0xF = 1101 => chip13 or chip5 on side1 + // For example if (data16[n]>>11)&0xF = 0101 => chip5 or chip5 on side0, (data16[n]>>11)&0xF = 1101 => chip13 or chip5 on side1 chip = ((data16[n]>>11)&0x7); side = ((data16[n]>>14)&0x1); - strip = chip*128 + ((data16[n]>>4)&0x7F); + strip = chip*N_STRIPS_PER_CHIP + ((data16[n]>>4)&0x7F); timeBin = 0x2; // Assuming timeBin is 010 in condensed mode - if (chip>5) { - ATH_MSG_DEBUG(" Hit condensed : xxx Chip number = " << chip << " > 5 " << " for hit " + if (chip>=N_CHIPS_PER_SIDE) { + ATH_MSG_DEBUG(" Hit condensed : xxx Chip number = " << chip << " >= " << N_CHIPS_PER_SIDE << " for hit " << std::hex << data16[n]); m_chipNumberError++; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); @@ -421,56 +518,65 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB } // Search for redundancy only for the master chip + bool secondSide{false}; if ((side==1) and ((linkNumber%2)==0)) { if (((strip!=oldStrip) or (side!=oldSide)) and (groupSize>0)) { // If it is a new cluster, make RDO with the previous cluster - const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; + const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; if (rdoMade == -1) { sc=StatusCode::RECOVERABLE; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); } else { - saved[oldSide*768+oldStrip] = rdoMade; + saved[oldSide*N_STRIPS_PER_SIDE+oldStrip] = rdoMade; } oldStrip = strip; oldSide = side; groupSize = 0; } linkNumber++; + secondSide = true; } - if ((side==0) and ((linkNumber%2)!=0)) { + else if ((side==0) and ((linkNumber%2)!=0)) { if (((strip!=oldStrip) or (side!=oldSide)) and (groupSize>0)) { // If it is a new cluster, make RDO with the previous cluster - const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; + const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; if (rdoMade == -1) { sc=StatusCode::RECOVERABLE; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); } else { - saved[oldSide*768+oldStrip] = rdoMade; + saved[oldSide*N_STRIPS_PER_SIDE+oldStrip] = rdoMade; } oldStrip = strip; oldSide = side; groupSize = 0; } linkNumber--; + secondSide = true; } - onlineID = ((robID & 0xFFFFFF)|(linkNumber << 24)); + if (secondSide) { + onlineID = ((robID & 0xFFFFFF) | (linkNumber << 24)); + currentLinkIDHash = m_cabling->getHashFromOnlineId(onlineID); + foundHashes.insert(currentLinkIDHash); + } + if (groupSize == 0) { oldStrip = strip; // If it's the first condensed word oldSide = side; } + if (not (data16[n]&0x1)) { // 1-hit m_singleCondHitNumber++; if ((strip!=oldStrip) or (side!=oldSide)) { // If it is a new cluster, make RDO with the previous cluster - const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; + const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; if (rdoMade == -1) { sc=StatusCode::RECOVERABLE; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); } else { - saved[oldSide*768+oldStrip] = rdoMade; + saved[oldSide*N_STRIPS_PER_SIDE+oldStrip] = rdoMade; } oldStrip = strip; oldSide = side; @@ -487,7 +593,7 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB groupSize = (groupSize>=2 ? groupSize : 1); } else { // 2-hits - if (strip > 767) { + if (strip >= N_STRIPS_PER_SIDE) { ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); sc=StatusCode::RECOVERABLE; @@ -498,13 +604,13 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB m_pairedCondHitNumber++; if ((strip!=oldStrip) or (side!=oldSide)) { // If it is a new cluster, make RDO with the previous cluster - const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; + const int rdoMade{makeRDO(oldStrip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; if (rdoMade == -1) { sc=StatusCode::RECOVERABLE; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); } else { - saved[oldSide*768+oldStrip] = rdoMade; + saved[oldSide*N_STRIPS_PER_SIDE+oldStrip] = rdoMade; } oldStrip = strip; oldSide = side; @@ -529,55 +635,61 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB } else { // Expanded mode: - // Chip info from the first word of expanded cluster : 4 bits data16[n]>>11)0xF + // Chip info from the first word of expanded cluster : 4 bits (data16[n]>>11)&0xF // Chip number == (data16[n]>>11)&0x7 // Chip side == (data16[n]>>14)&0x1 - // For example if data16[n]>>11)0xF = 0101 => chip5 or chip5 on side0, data16[n]>>11)0xF = 1101 => chip13 or chip5 on side1 + // For example if (data16[n]>>11)&0xF = 0101 => chip5 or chip5 on side0, (data16[n]>>11)&0xF = 1101 => chip13 or chip5 on side1 if (not (data16[n]&0x8)) { // 1st hit cluster expanded m_firstExpHitNumber++; chip = ((data16[n]>>11)&0x7); side = ((data16[n]>>14)&0x1); - strip = chip*128 + ((data16[n]>>4)&0x7F); + strip = chip*N_STRIPS_PER_CHIP + ((data16[n]>>4)&0x7F); timeBin = data16[n]&0x7; // Real way for obtaining timeBin info - if (chip>5) { - ATH_MSG_DEBUG("Expanded hit: First hit xxx ERROR chip Nb = " << chip << " > 5"); + if (chip>=N_CHIPS_PER_SIDE) { + ATH_MSG_DEBUG("Expanded hit: First hit xxx ERROR chip Nb = " << chip << " >= " << N_CHIPS_PER_SIDE); m_chipNumberError++; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); continue; } - // Search for redundancy only for the master chip + bool secondSide{false}; if ((side==1) and ((linkNumber%2)==0)) { linkNumber++; + secondSide = true; } - if ((side==0) and ((linkNumber%2)!=0)) { + else if ((side==0) and ((linkNumber%2)!=0)) { linkNumber--; + secondSide = true; } - onlineID = ((robID & 0xFFFFFF) | (linkNumber << 24)); - groupSize = 1; - const int rdoMade{makeRDO(strip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; + if (secondSide) { + onlineID = ((robID & 0xFFFFFF) | (linkNumber << 24)); + currentLinkIDHash = m_cabling->getHashFromOnlineId(onlineID); + foundHashes.insert(currentLinkIDHash); + } + groupSize = 1; + const int rdoMade{makeRDO(strip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; if (rdoMade == -1) { sc=StatusCode::RECOVERABLE; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); } else { - saved[side*768+strip] = rdoMade; + saved[side*N_STRIPS_PER_SIDE+strip] = rdoMade; } groupSize = 0; } else { // Next hits cluster expanded if (data16[n]&0x80) { // Paired hits - if (strip > 767) { + if (strip >= N_STRIPS_PER_SIDE) { ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); sc=StatusCode::RECOVERABLE; ATH_MSG_DEBUG("Expanded mode - strip number out of range"); continue; } m_evenExpHitNumber++; - if (chip>5) { - ATH_MSG_DEBUG("Expanded Hit: paired hits xxx ERROR chip Nb = " << chip << " > 5"); + if (chip>=N_CHIPS_PER_SIDE) { + ATH_MSG_DEBUG("Expanded Hit: paired hits xxx ERROR chip Nb = " << chip << " >= " << N_CHIPS_PER_SIDE); m_chipNumberError++; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); continue; @@ -586,31 +698,31 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB strip++; timeBin = data16[n]&0x7; groupSize = 1; - const int rdoMade1{makeRDO(strip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; + const int rdoMade1{makeRDO(strip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; if (rdoMade1 == -1) { sc=StatusCode::RECOVERABLE; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); } else { - saved[side*768+strip] = rdoMade1; + saved[side*N_STRIPS_PER_SIDE+strip] = rdoMade1; } // Second hit from the pair strip++; timeBin = ((data16[n] >> 4) & 0x7); - const int rdoMade2{makeRDO(strip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; + const int rdoMade2{makeRDO(strip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; if (rdoMade2 == -1) { sc=StatusCode::RECOVERABLE; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); } else { - saved[side*768+strip] = rdoMade2; + saved[side*N_STRIPS_PER_SIDE+strip] = rdoMade2; } groupSize = 0; } else { // Last hit of the cluster m_lastExpHitNumber++; - if (chip>5) { - ATH_MSG_DEBUG("Expanded Hit: last hit xxx ERROR chip Nb = " << chip << " > 5"); + if (chip>=N_CHIPS_PER_SIDE) { + ATH_MSG_DEBUG("Expanded Hit: last hit xxx ERROR chip Nb = " << chip << " >= " << N_CHIPS_PER_SIDE); m_chipNumberError++; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); continue; @@ -618,13 +730,13 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB strip++; timeBin = (data16[n]&0x7); groupSize = 1; - const int rdoMade{makeRDO(strip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; + const int rdoMade{makeRDO(strip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; if (rdoMade == -1) { sc=StatusCode::RECOVERABLE; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); } else { - saved[side*768+strip] = rdoMade; + saved[side*N_STRIPS_PER_SIDE+strip] = rdoMade; } groupSize = 0; } @@ -632,95 +744,85 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB } // End expanded mode } // End of hit element - - // Header - else if (((data16[n]>>13)&0x7) == 0x1) { - foundHeader=true; - - m_headNumber++; - if (saved[side*768+strip]==false and oldStrip>=0) { - const int rdoMade{makeRDO(strip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; - if (rdoMade == -1) { - sc=StatusCode::RECOVERABLE; - ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); - } - else { - saved[side*768+strip] = rdoMade; - } - } - - // Everything is set to default for a new hunt of RDO - strip =0; - oldStrip = -1; - oldSide = -1; - groupSize = 0; - errors = 0; - memset(saved,0,768*2); - errorHit.clear(); + // FlaggedABCD error + else if (((data16[n]>>13)&0x7) == 0x0) { + // 000xxxxxxFFFFEEE + // 000: FlaggedABCD error: xxxxxxx not used, FFFF: chip, EEE: error code - // Link Number (or stream) in the ROD fragment - const int rodlinkNumber{static_cast<int>(data16[n] & 0x7F)}; + if (not foundHeader) { + ATH_MSG_INFO(" Missing link header in ROD " << std::hex << robID << std::dec); + foundMissingLinkHeaderError = true; + m_numMissingLinkHeader++; + sc = StatusCode::RECOVERABLE; + continue; + } - // This is the real calculation for the offline - linkNumber = (((rodlinkNumber >>4)&0x7)*12+(rodlinkNumber &0xF)); - onlineID = ((robID & 0xFFFFFF)|(linkNumber << 24)); - if ((onlineID ==0) or (linkNumber > 95)) { - ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); - sc=StatusCode::RECOVERABLE; - ATH_MSG_DEBUG("Header: xxx Link number out of range (skipping following data)" - << std::dec << linkNumber); - break; + chip = ((data16[n]>>3)&0xF); + int abcError{data16[n]&0x7}; + ATH_MSG_DEBUG(" xxx Flagged ABCD ERROR in chip " << chip + << " Error code abcError " << abcError << " Link Number (or Stream) "<<linkNumber); + m_flagErrorBit++; + // Error code of ABCD error should be 1, 2, 4 or 7. + if (abcError!=0x1 and abcError!=0x2 and abcError!=0x4 and abcError!=0x7) { + ATH_MSG_DEBUG("ABCD error has an invalid error code " << abcError + << " the 16-bit word is 0x" << std::hex << data16[n] << std::dec + << " for hash " << currentLinkIDHash); + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError_Invalid, errs)); } else { - currentLinkIDHash = m_cabling->getHashFromOnlineId(onlineID); - } - // Look for masked off links - bit 7 - if (data16[n] >> 7 & 0x1) { - ATH_MSG_DEBUG("Masked link " << onlineID << " " << currentLinkIDHash); - ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::MaskedLink, errs)); - sc=StatusCode::RECOVERABLE; - } - if (data16[n]&0x800) { - ATH_MSG_DEBUG(" Header: xxx TimeOut Error " << currentLinkIDHash); - m_headErrorTimeout++; - ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::TimeOutError, errs)); - sc=StatusCode::RECOVERABLE; - } - - if (data16[n]&0x1000) { - ATH_MSG_DEBUG(" Header: xxx Preamble Error " << currentLinkIDHash); - m_headErrorPreamble++; - ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::PreambleError, errs)); - sc=StatusCode::RECOVERABLE; - } - - if (data16[n]&0x400) { - ATH_MSG_DEBUG(" Header: xxx LVL1 ID Error " << currentLinkIDHash); - m_headErrorLvl1ID++; - ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::LVL1IDError, errs)); - sc=StatusCode::RECOVERABLE; - } - - if (data16[n]&0x200) { - ATH_MSG_DEBUG(" Header: xxx BCID Error " << currentLinkIDHash); - m_headErrorBCID++; - ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::BCIDError, errs)); - sc=StatusCode::RECOVERABLE; - } - - if ((data16[n]&0xF) > 11) { - ATH_MSG_DEBUG(" Header: xxx Error in formatter " << currentLinkIDHash); - m_headErrorFormatter++; - ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::FormatterError, errs)); - sc=StatusCode::RECOVERABLE; + // Chip is 4 bits. The highest bit 3 represents side. Chip 0-5 on side 0 and chip 8-13 on side 1. + const unsigned int sideABCDError{static_cast<unsigned int>(chip/8)}; + if (currentLinkIDHash.value()%2!=sideABCDError) { + // If the sides from the ABCD error and online ID are different, + // the module is expected to read side 0 via link 1 and side 1 and via link 0. + // Hash Id is flipped. + ATH_MSG_DEBUG("ABCD error and online ID have different side information for hash " << currentLinkIDHash << ". " + << sideABCDError << " from ABCD error and " << currentLinkIDHash.value()%2 << " from online ID"); + currentLinkIDHash = (currentLinkIDHash.value()/2)*2+sideABCDError; + } + // Chip should be 0-5 or 8-13. + if (chip%8>=N_CHIPS_PER_SIDE) { + ATH_MSG_DEBUG("ABCD error has an invalid chip 0x" << std::hex << chip << std::dec + << " the 16-bit word is 0x" << std::hex << data16[n] << std::dec + << " for hash " << currentLinkIDHash.value()); + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError_Invalid, errs)); + } + else { + if ( abcError==0x1) ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError_Error1, errs)); + else if (abcError==0x2) ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError_Error2, errs)); + else if (abcError==0x4) ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError_Error4, errs)); + else if (abcError==0x7) ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError_Error7, errs)); + if ( chip%8==0) ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError_Chip0, errs)); + else if (chip%8==1) ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError_Chip1, errs)); + else if (chip%8==2) ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError_Chip2, errs)); + else if (chip%8==3) ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError_Chip3, errs)); + else if (chip%8==4) ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError_Chip4, errs)); + else if (chip%8==5) ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError_Chip5, errs)); + } } + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ABCDError, errs)); + sc=StatusCode::RECOVERABLE; + continue; + } - condensedMode = static_cast<bool>(data16[n]&0x100); + // Raw Data + else if (((data16[n]>>13)&0x7) == 0x3) { + if (not foundHeader) { + ATH_MSG_INFO(" Missing link header in ROD " << std::hex << robID << std::dec); + foundMissingLinkHeaderError = true; + m_numMissingLinkHeader++; + sc = StatusCode::RECOVERABLE; + continue; + } + ATH_MSG_DEBUG(" xxx Raw Data Mode " << std::hex << data16[n] << std::dec << ": Config Data Mode "); + // Too many errors in the BS for the ROD to decode the data + m_configDataBit++; + ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::RawError, errs)); + sc=StatusCode::RECOVERABLE; continue; - - } // End header - + } + // Trailer else if (((data16[n]>>13)&0x7) == 0x2) { foundHeader=false; @@ -776,85 +878,8 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB } continue; } - - // FlaggedABCD error - // 000xxxxxxFFFFEEE - // 000: FlaggedABCD error: xxxxxxx not used, FFFF: chip, EEE: error code - else if (((data16[n]>>13)&0x7) == 0x0) { - chip = ((data16[n]>>3)&0xF); - abcError = data16[n]&0x7; - // No data should appear for that chip but how do we want to transmit this information? - IdentifierHash flagIDHash; - if (onlineID == 0) { - ATH_MSG_VERBOSE("There is ByteStreamParseError but we don't know which wafer has it."); - continue; - } - else { - flagIDHash = m_cabling->getHashFromOnlineId(onlineID); - } - ATH_MSG_DEBUG(" xxx Flagged ABCD ERROR in chip " << chip - << " Error code abcError " << abcError << " Link Number (or Stream) "<<linkNumber); - m_flagErrorBit++; - // Error code of ABCD error should be 1, 2, 4 or 7. - if (abcError!=0x1 and abcError!=0x2 and abcError!=0x4 and abcError!=0x7) { - ATH_MSG_DEBUG("ABCD error has an invalid error code " << abcError - << " the 16-bit word is 0x" << std::hex << data16[n] << std::dec - << " for hash " << flagIDHash); - ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError_Invalid, errs)); - } - else { - // Chip is 4 bits. The highest bit 3 represents side. Chip 0-5 on side 0 and chip 8-13 on side 1. - const unsigned int sideABCDError{static_cast<unsigned int>(chip/8)}; - if (flagIDHash.value()%2!=sideABCDError) { - // If the sides from the ABCD error and online ID are different, - // the module is expected to read side 0 via link 1 and side 1 and via link 0. - // Hash Id is flipped. - ATH_MSG_DEBUG("ABCD error and online ID have different side information for hash " << flagIDHash << ". " - << sideABCDError << " from ABCD error and " << flagIDHash.value()%2 << " from online ID"); - flagIDHash = (flagIDHash.value()/2)*2+sideABCDError; - } - // Chip should be 0-5 or 8-13. - if (chip%8>=6) { - ATH_MSG_DEBUG("ABCD error has an invalid chip 0x" << std::hex << chip << std::dec - << " the 16-bit word is 0x" << std::hex << data16[n] << std::dec - << " for hash " << flagIDHash.value()); - ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError_Invalid, errs)); - } - else { - if ( abcError==0x1) ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError_Error1, errs)); - else if (abcError==0x2) ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError_Error2, errs)); - else if (abcError==0x4) ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError_Error4, errs)); - else if (abcError==0x7) ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError_Error7, errs)); - if ( chip%8==0) ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError_Chip0, errs)); - else if (chip%8==1) ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError_Chip1, errs)); - else if (chip%8==2) ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError_Chip2, errs)); - else if (chip%8==3) ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError_Chip3, errs)); - else if (chip%8==4) ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError_Chip4, errs)); - else if (chip%8==5) ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError_Chip5, errs)); - } - } - ATH_CHECK(addSingleError(flagIDHash, SCT_ByteStreamErrors::ABCDError, errs)); - sc=StatusCode::RECOVERABLE; - continue; - } - else if (((data16[n]>>13)&0x7) == 0x3) { - // Raw Data - IdentifierHash rawIDHash{0}; - if (onlineID == 0) { - ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); - continue; - } - else { - rawIDHash = m_cabling->getHashFromOnlineId(onlineID); - } - ATH_MSG_DEBUG(" xxx Raw Data Mode " << std::hex << data16[n] << std::dec << ": Config Data Mode "); - // Too many errors in the BS for the ROD to decode the data - m_configDataBit++; - ATH_CHECK(addSingleError(rawIDHash, SCT_ByteStreamErrors::RawError, errs)); - sc=StatusCode::RECOVERABLE; - continue; - } + /// Unknown else { ATH_MSG_DEBUG("Data word format unknown "); m_unknownDataFormat++; @@ -864,44 +889,38 @@ StatusCode SCT_RodDecoder::fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROB } // End of 16-bit word loop } // End of 32-bit word loop - // Create RDO of the last ink or stream of the event - if (saved[side*768+strip]==false and oldStrip>=0) { - const int rdoMade{makeRDO(strip, groupSize, timeBin, onlineID, errors, rdoIDCont, cache, errorHit)}; + // Create the last RDO of the last link of the event + if (saved[side*N_STRIPS_PER_SIDE+strip]==false and oldStrip>=0) { + const int rdoMade{makeRDO(strip, groupSize, timeBin, currentLinkIDHash, errors, rdoIDCont, cache, errorHit)}; if (rdoMade == -1) { sc=StatusCode::RECOVERABLE; ATH_CHECK(addSingleError(currentLinkIDHash, SCT_ByteStreamErrors::ByteStreamParseError, errs)); } else { - saved[side*768+strip] = rdoMade; + saved[side*N_STRIPS_PER_SIDE+strip] = rdoMade; } } + // MissingLinkHeaderError is filled in only FE-lins of the ROD whose headers are not found. + // We cannot know which FE-link does not have header. However, we should not add the error to found ones. + if (foundMissingLinkHeaderError) { + ATH_CHECK(addRODError(robID, SCT_ByteStreamErrors::MissingLinkHeaderError, errs, &foundHashes)); + } + if (sc.isFailure()) ATH_MSG_DEBUG("One or more ByteStream errors found "); return sc; } // makeRDO method -int SCT_RodDecoder::makeRDO(int strip, int groupSize, int timeBin, uint32_t onlineID, int errors, +int SCT_RodDecoder::makeRDO(int strip, int groupSize, int timeBin, + const IdentifierHash& collIDHash, + int errors, ISCT_RDO_Container& rdoIDCont, CacheHelper& cache, const std::vector<int>& errorHit) const { - if (onlineID == 0x0) { - ATH_MSG_WARNING("No link header found, possibly corrupt ByteStream. Will not try to make RDO"); - return -1; - } - // Get offlineId from the link number and ROB number - const IdentifierHash collIDHash{m_cabling->getHashFromOnlineId(onlineID)}; - if (not collIDHash.is_valid()) { - m_numUnknownOfflineID++; - ATH_MSG_ERROR("Unknown OfflineId for OnlineId -> cannot create RDO"); - ATH_MSG_WARNING("Unknown OfflineId for OnlineId " << std::hex << onlineID - << " -> cannot create RDO" << std::dec); - return -1; - } - - if (((strip & 0x7f) + (groupSize-1) > 127) or (strip<0) or (strip>767)) { + if (((strip & 0x7f) + (groupSize-1) >= N_STRIPS_PER_CHIP) or (strip<0) or (strip>=N_STRIPS_PER_SIDE)) { ATH_MSG_WARNING("Cluster with " << groupSize << " strips, starting at strip " << strip << " in collection " << collIDHash << " out of range. Will not make RDO"); return -1; @@ -933,9 +952,9 @@ int SCT_RodDecoder::makeRDO(int strip, int groupSize, int timeBin, uint32_t onli return 0; } - // See if strips go from 0 to 767 or vice versa + // See if strips go from 0 to N_STRIPS_PER_SIDE-1(=767) or vice versa if (m_swapPhiReadoutDirection[collIDHash]) { - strip = 767 - strip; + strip = N_STRIPS_PER_SIDE-1 - strip; strip = strip-(groupSize-1); } @@ -978,12 +997,20 @@ int SCT_RodDecoder::makeRDO(int strip, int groupSize, int timeBin, uint32_t onli // addRODError method StatusCode SCT_RodDecoder::addRODError(uint32_t rodID, SCT_ByteStreamErrors::ErrorType error, - SCT_RodDecoderErrorsHelper& errs) const + SCT_RodDecoderErrorsHelper& errs, + const std::unordered_set<IdentifierHash>* foundHashes) const { std::vector<IdentifierHash> hashIDs; m_cabling->getHashesForRod(hashIDs, rodID); for (const IdentifierHash& hash: hashIDs) { - ATH_CHECK( addSingleError(hash, error, errs) ); + // MissingLinkHeaderError is filled in only FE-links of the ROD whose headers are not found. + // We cannot know which FE-link does not have header. However, we should not add the error to found ones. + if ((error==SCT_ByteStreamErrors::MissingLinkHeaderError) and + foundHashes and foundHashes->count(hash)) { + continue; + } + + ATH_CHECK(addSingleError(hash, error, errs)); } return StatusCode::SUCCESS; } @@ -991,8 +1018,8 @@ StatusCode SCT_RodDecoder::addRODError(uint32_t rodID, SCT_ByteStreamErrors::Err // addSingleError method StatusCode SCT_RodDecoder::addSingleError(const IdentifierHash& hashID, - SCT_ByteStreamErrors::ErrorType error, - SCT_RodDecoderErrorsHelper& errs) const + SCT_ByteStreamErrors::ErrorType error, + SCT_RodDecoderErrorsHelper& errs) const { if (not hashID.is_valid()) { ATH_MSG_INFO("addSingleError hashID " << hashID << " is invalid."); @@ -1022,8 +1049,8 @@ StatusCode SCT_RodDecoder::addSingleError(const IdentifierHash& hashID, // setFirstTempMaskedChip method StatusCode SCT_RodDecoder::setFirstTempMaskedChip(const IdentifierHash& hashID, - unsigned int firstTempMaskedChip, - SCT_RodDecoderErrorsHelper& errs) const + unsigned int firstTempMaskedChip, + SCT_RodDecoderErrorsHelper& errs) const { if (not hashID.is_valid()) { ATH_MSG_INFO("setFirstTempMaskedChip hashID " << hashID << " is invalid."); @@ -1112,7 +1139,7 @@ StatusCode SCT_RodDecoder::setFirstTempMaskedChip(const IdentifierHash& hashID, // Readout sequence is 6, 7, 8, 9, 10, 11, 1, 2, 3, 4, 5. } - static const int chipOrder[5][12]{ + static const int chipOrder[5][N_SIDES*N_CHIPS_PER_SIDE]{ // type=0 not prepared for both link-0 and link-1 are working {}, // type=1 link-1 is broken: chip 0 1 2 3 4 5 6 7 8 9 10 11 @@ -1138,33 +1165,37 @@ StatusCode SCT_RodDecoder::setFirstTempMaskedChip(const IdentifierHash& hashID, // side 1 via link-0. If the first masked chip value on side 1 (0) is // between 1 to 6 (7 to 12), it indicates the module is a special one. // In that case, information is swapped. - if ((6<firstTempMaskedChipSide0 and firstTempMaskedChipSide0<=12) or - (0<firstTempMaskedChipSide1 and firstTempMaskedChipSide1<= 6)) { + if ((N_CHIPS_PER_SIDE<firstTempMaskedChipSide0 and firstTempMaskedChipSide0<=N_SIDES*N_CHIPS_PER_SIDE) or + ( 0<firstTempMaskedChipSide1 and firstTempMaskedChipSide1<= N_CHIPS_PER_SIDE)) { const unsigned int swapFirstTempMaskedChipSide0{firstTempMaskedChipSide0}; firstTempMaskedChipSide0 = firstTempMaskedChipSide1; firstTempMaskedChipSide1 = swapFirstTempMaskedChipSide0; } if (firstTempMaskedChipSide0>0) { - for (unsigned int iChip{firstTempMaskedChipSide0-1}; iChip<6; iChip++) { - ATH_CHECK( addSingleError(hashSide0, SCT_ByteStreamErrors::TempMaskedChipToBit(iChip), errs) ); + for (unsigned int iChip{firstTempMaskedChipSide0-1}; iChip<N_CHIPS_PER_SIDE; iChip++) { + ATH_CHECK(addSingleError(hashSide0, SCT_ByteStreamErrors::TempMaskedChipToBit(iChip), errs)); } } - if (firstTempMaskedChipSide1>6) { - for (unsigned int iChip{firstTempMaskedChipSide1-1}; iChip<12; iChip++) { - ATH_CHECK( addSingleError(hashSide1, SCT_ByteStreamErrors::TempMaskedChipToBit(iChip-6), errs) ); + if (firstTempMaskedChipSide1>N_CHIPS_PER_SIDE) { + for (unsigned int iChip{firstTempMaskedChipSide1-1}; iChip<N_SIDES*N_CHIPS_PER_SIDE; iChip++) { + ATH_CHECK(addSingleError(hashSide1, SCT_ByteStreamErrors::TempMaskedChipToBit(iChip-N_CHIPS_PER_SIDE), errs)); } } } else { // type=1, 2, 3, 4: cases using Rx redundancy bool toBeMasked{false}; - for (int iChip{0}; iChip<12; iChip++) { + for (int iChip{0}; iChip<N_SIDES*N_CHIPS_PER_SIDE; iChip++) { int jChip{chipOrder[type][iChip]}; if (jChip==static_cast<int>(firstTempMaskedChip-1)) toBeMasked = true; if (toBeMasked) { - if (jChip<6) ATH_CHECK( addSingleError(hashSide0, SCT_ByteStreamErrors::TempMaskedChipToBit(jChip), errs)); - else ATH_CHECK( addSingleError(hashSide1, SCT_ByteStreamErrors::TempMaskedChipToBit(jChip-6), errs)); + if (jChip<N_CHIPS_PER_SIDE) { + ATH_CHECK(addSingleError(hashSide0, SCT_ByteStreamErrors::TempMaskedChipToBit(jChip), errs)); + } + else { + ATH_CHECK(addSingleError(hashSide1, SCT_ByteStreamErrors::TempMaskedChipToBit(jChip-N_CHIPS_PER_SIDE), errs)); + } } } } diff --git a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.h b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.h index 69872e543b745aeadad853292eaebfd9ad9e89e8..3337bcd375ee3c539125f65a19276e4f104447dc 100644 --- a/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.h +++ b/InnerDetector/InDetEventCnv/SCT_RawDataByteStreamCnv/src/SCT_RodDecoder.h @@ -21,6 +21,7 @@ #include <atomic> #include <cstdint> #include <string> +#include <unordered_set> #include <vector> class IdentifierHash; @@ -73,6 +74,15 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder> private: + /** + * @enum SCT_DecoderNumbers + * @brief Define frequently used magic numbers + */ + enum SCT_DecoderNumbers { N_SIDES = 2, + N_CHIPS_PER_SIDE = 6, + N_STRIPS_PER_CHIP = 128, + N_STRIPS_PER_SIDE = N_CHIPS_PER_SIDE*N_STRIPS_PER_CHIP, + }; /** * @brief Builds RawData RDO and adds to RDO container * @@ -83,17 +93,18 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder> * 0 if collection was deliberately skipped (for trigger) * -1 if there was an error in the decoding - will be passed on as StatusCode::RECOVERABLE by fillCollection() * - * @param strip Strip number info from the RDO. - * @param groupSize Group size info from the RDO. + * @param strip Strip number info for the RDO. + * @param groupSize Group size info for the RDO. * @param timeBin Time bin info for RDO. - * @param onlineID Online Identifier from the RDO. + * @param collIDHash IdentifierHash for the wafer/side/FE-link where the RDO exists * @param errors Error info. * @param rdoIDCont RDO ID Container to be filled. * @param cache Cache. * @param errorHit Hit error info. */ int makeRDO(int strip, int groupSize, int timeBin, - uint32_t onlineID, int errors, + const IdentifierHash& collIDHash, + int errors, ISCT_RDO_Container& rdoIDCont, CacheHelper& cache, const std::vector<int>& errorHit) const; @@ -104,9 +115,11 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder> * @param rodID Identifer of ROD. * @param errorType Error type info. * @param errs Byte stream error container. + * @param foundHashes FE-links whose headers are found. Used only for MissingLinkHeaderError. */ StatusCode addRODError(uint32_t rodID, SCT_ByteStreamErrors::ErrorType error, - SCT_RodDecoderErrorsHelper& errs) const; + SCT_RodDecoderErrorsHelper& errs, + const std::unordered_set<IdentifierHash>* foundHashes=nullptr) const; /** * @brief Add single eror * @@ -115,8 +128,8 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder> * @param errs Byte stream error container. */ StatusCode addSingleError(const IdentifierHash& hashID, - SCT_ByteStreamErrors::ErrorType error, - SCT_RodDecoderErrorsHelper& errs) const; + SCT_ByteStreamErrors::ErrorType error, + SCT_RodDecoderErrorsHelper& errs) const; /** * @brief Set first temporarily masked chip information from byte stream trailer @@ -126,8 +139,8 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder> * @param errs Byte stream error container. */ StatusCode setFirstTempMaskedChip(const IdentifierHash& hashID, - unsigned int firstTempMaskedChip, - SCT_RodDecoderErrorsHelper& errs) const; + unsigned int firstTempMaskedChip, + SCT_RodDecoderErrorsHelper& errs) const; /** Identifier helper class for the SCT subdetector that creates compact Identifier objects and IdentifierHash or hash IDs. Also allows decoding of these IDs. */ @@ -233,9 +246,6 @@ class SCT_RodDecoder : public extends<AthAlgTool, ISCT_RodDecoder> /** Total number of missing link headers */ mutable std::atomic_uint m_numMissingLinkHeader{0}; - /** Total number of SCT unknown online IDs */ - mutable std::atomic_uint m_numUnknownOfflineID{0}; - /** Swap phi readout direction */ std::vector<bool> m_swapPhiReadoutDirection{}; };