diff --git a/algo/detectors/sts/ReadoutConfig.cxx b/algo/detectors/sts/ReadoutConfig.cxx index 1d08012559e01831e9d36b3e7d9fd58bae0de341..f2e187ee6962e7c18ca2908fcc3cc68953aa1cf8 100644 --- a/algo/detectors/sts/ReadoutConfig.cxx +++ b/algo/detectors/sts/ReadoutConfig.cxx @@ -5,6 +5,8 @@ #include "CbmStsAddress.h" #include "ChannelMaskSet.h" +#include "Exceptions.h" +#include "log.hpp" #include <cassert> #include <iomanip> @@ -16,6 +18,25 @@ using namespace cbm::algo; CBM_YAML_INSTANTIATE(sts::ReadoutSetup); +sts::FEBType sts::ReadoutSetup::Component::GetFEBType() const +{ + size_t febsPerCrob = FEBsPerCrob(); + switch (febsPerCrob) { + case 5: return FEBType::FEB8_1; + case 1: return FEBType::FEB8_5; + } + throw FatalError("Invalid number of FEBs per CROB: {}", febsPerCrob); +} + +const std::vector<sts::ReadoutSetup::Elink>& sts::ReadoutSetup::GetElinks(FEBType type) const +{ + switch (type) { + case FEBType::FEB8_1: return elinksFeb8_1; + case FEBType::FEB8_5: return elinksFeb8_5; + } + throw FatalError("Unknown FEB type: {}", static_cast<int>(type)); +} + sts::ReadoutConfig::ReadoutConfig(const ReadoutSetup& config, const ChannelMaskSet& chanMaskSet) { Init(config, chanMaskSet); @@ -61,16 +82,16 @@ void sts::ReadoutConfig::Init(const ReadoutSetup& config, const ChannelMaskSet& // const uint16_t numFebsPerCrob = config.components.at(0).feb2module.at(0).size(); // Number of FEBs per CROB const uint16_t numAsicsPerFeb = config.numAsicsPerFeb; // Number of ASICs per FEB const uint16_t numAsicsPerMod = 2 * numAsicsPerFeb; // Number of ASICs per module - const uint16_t numElinksPerCrob = config.elinks.size(); // Number of elinks per CROB - const uint16_t numFebsPerCrob = 5; ///< Number of FEBs per CROB + const uint16_t numElinksPerCrob = 42; // Number of elinks per CROB const uint16_t numChanPerAsic = 128; ///< Number of channels per ASIC + const uint16_t numElinksPerComp = numCrobPerComp * numElinksPerCrob; + // map from feb ID to adc cut // TODO: Don't hardcode this. Read from configuration file. std::map<size_t, uint32_t> febAdcCuts = {{1, 1}, {2, 1}, {3, 1}, {4, 1}}; // Constructing the map (equipmentId, eLink) -> (module, ASIC within module) - uint16_t numElinksPerComp = numCrobPerComp * numElinksPerCrob; for (uint16_t compIdx = 0; compIdx < numComp; compIdx++) { const auto& component = config.components.at(compIdx); uint16_t equipment = component.equipmentId; @@ -83,7 +104,8 @@ void sts::ReadoutConfig::Init(const ReadoutSetup& config, const ChannelMaskSet& bool isPulser = false; uint16_t elinkId = numElinksPerCrob * crobIdx + elinkIdx; // elink within component - const auto& elink = config.elinks.at(elinkId); + const auto& elinks = config.GetElinks(component.GetFEBType()); + const auto& elink = elinks.at(elinkId); int16_t feb = elink.toFeb; // FEB within CROB @@ -111,8 +133,9 @@ void sts::ReadoutConfig::Init(const ReadoutSetup& config, const ChannelMaskSet& asicInModule = (moduleSide == 1 ? asicInFeb : numAsicsPerMod - 1 - asicInFeb); // Init channel mask - const int32_t febId = feb + compIdx * numCrobPerComp * numFebsPerCrob; - auto mapIt = chanMaskSet.values.find(febId); + const int32_t numFebsPerCrob = component.FEBsPerCrob(); + const int32_t febId = feb + compIdx * numCrobPerComp * numFebsPerCrob; + auto mapIt = chanMaskSet.values.find(febId); if (mapIt != chanMaskSet.values.end()) { const auto& mask = mapIt->second; diff --git a/algo/detectors/sts/ReadoutConfig.h b/algo/detectors/sts/ReadoutConfig.h index 0ce1d1a9ca091bbc0cc5b2ae2db742134b181efb..f78931eebf336434e9ffa9e22c7802e70fbed35c 100644 --- a/algo/detectors/sts/ReadoutConfig.h +++ b/algo/detectors/sts/ReadoutConfig.h @@ -17,6 +17,12 @@ namespace cbm::algo::sts struct ChannelMaskSet; + enum class FEBType + { + FEB8_1, + FEB8_5 + }; + /** * @brief Readout setup / Hardware cabling for STS * Used to create the hardware mapping for the STS unpacker. @@ -40,6 +46,9 @@ namespace cbm::algo::sts std::vector<std::vector<i16>> feb2moduleSide; std::vector<std::vector<bool>> febIsPulser; + FEBType GetFEBType() const; + size_t FEBsPerCrob() const { return feb2module.at(0).size(); } + CBM_YAML_PROPERTIES( yaml::Property(&Component::equipmentId, "equipmentId", "Equipment ID of component. Written to the data stream (MicrosliceDescriptor).", YAML::Hex), @@ -64,12 +73,18 @@ namespace cbm::algo::sts u16 numAsicsPerFeb; std::vector<Module> modules; std::vector<Component> components; - std::vector<Elink> elinks; + std::vector<Elink> elinksFeb8_1; + std::vector<Elink> elinksFeb8_5; + + const std::vector<Elink>& GetElinks(FEBType type) const; CBM_YAML_PROPERTIES(yaml::Property(&ReadoutSetup::numAsicsPerFeb, "numAsicsPerFeb", "Number of ASICs per FEB"), yaml::Property(&ReadoutSetup::modules, "modules", "Modules", {}, YAML::Flow), yaml::Property(&ReadoutSetup::components, "components", "Components", {}, YAML::Flow), - yaml::Property(&ReadoutSetup::elinks, "elinks", "Elinks", {}, YAML::Flow)); + yaml::Property(&ReadoutSetup::elinksFeb8_1, "elinksFeb8_1", + "Elinks for FEB8_1 (1:1 elink:ASIC, 5 FEB / ROB)", {}, YAML::Flow), + yaml::Property(&ReadoutSetup::elinksFeb8_5, "elinksFeb8_5", + "Elinks for FEB8_5 (5:1 elink:ASIC, 1 FEB / ROB)", {}, YAML::Flow)); }; /** @class ReadoutConfig diff --git a/algo/detectors/sts/ReadoutConfig_mCBM2022.cxx b/algo/detectors/sts/ReadoutConfig_mCBM2022.cxx index 882b3ecfb377bb39666373c1c74044e63ba0a056..70c800df5794cb9c7e635e9bce5bc3061d553e90 100644 --- a/algo/detectors/sts/ReadoutConfig_mCBM2022.cxx +++ b/algo/detectors/sts/ReadoutConfig_mCBM2022.cxx @@ -37,7 +37,7 @@ ReadoutConfig ReadoutConfig::MakeMCBM2022() {.equipmentId = 0x1005, .feb2module = {{12, 12, 11, 11, 10}}, .feb2moduleSide = {{1, 0, 1, 0, 1}}, .febIsPulser = {{false, false, false, false, false}}}, }; - setup.elinks = { + setup.elinksFeb8_1 = { {.toFeb = 4, .toAsicFebA = 0x21, .toAsicFebB = 0x27}, {.toFeb = 4, .toAsicFebA = 0x23, .toAsicFebB = 0x25}, {.toFeb = 4, .toAsicFebA = 0x25, .toAsicFebB = 0x23}, @@ -81,6 +81,8 @@ ReadoutConfig ReadoutConfig::MakeMCBM2022() {.toFeb = 0, .toAsicFebA = 0x7, .toAsicFebB = 0x1}, {.toFeb = 0, .toAsicFebA = 0x1, .toAsicFebB = 0x7}, }; + + setup.elinksFeb8_5 = {}; // Not present in mCBM2022 // clang-format on return ReadoutConfig{setup, ChannelMaskSet::MakeMCBM2022()}; diff --git a/algo/detectors/sts/Unpack.cxx b/algo/detectors/sts/Unpack.cxx index c40e4e75c9b4dc990efb68efcd98ebb7c4da60f5..34990d21afbdad145baec5b95b26d2d319d629e6 100644 --- a/algo/detectors/sts/Unpack.cxx +++ b/algo/detectors/sts/Unpack.cxx @@ -46,5 +46,19 @@ Unpack::Unpack(const Config& config) : fConfig(config) Unpack::Result_t Unpack::operator()(const fles::Timeslice& ts) const { constexpr int SystemVersion = 0x20; - return DoUnpack(Subsystem::STS, ts, SystemVersion); + + auto result = DoUnpack(Subsystem::STS, ts, SystemVersion); + // PrintDigisPerModule(result.first); + return result; +} + +void Unpack::PrintDigisPerModule(const PODVector<CbmStsDigi>& digis) const +{ + std::map<u32, size_t> digisPerModule; + for (const auto& digi : digis) { + digisPerModule[digi.GetAddress()]++; + } + for (const auto& [module, numDigis] : digisPerModule) { + L_(info) << "Module " << std::hex << module << std::dec << " has " << numDigis << " digis"; + } } diff --git a/algo/detectors/sts/Unpack.h b/algo/detectors/sts/Unpack.h index 1f01a3beb8aaa06991557932e48a4b906c7c39ca..0670fd8697b7a6e7f4188c7a82716457b503a865 100644 --- a/algo/detectors/sts/Unpack.h +++ b/algo/detectors/sts/Unpack.h @@ -33,6 +33,8 @@ namespace cbm::algo::sts private: Config fConfig; + + void PrintDigisPerModule(const PODVector<CbmStsDigi>& digis) const; }; } // namespace cbm::algo::sts diff --git a/algo/detectors/sts/UnpackMS.cxx b/algo/detectors/sts/UnpackMS.cxx index 4ffb8dc9221433044f607c6ebe4060ca8edec9da..250981bdf9b283b7d8a176316e034b58def747d8 100644 --- a/algo/detectors/sts/UnpackMS.cxx +++ b/algo/detectors/sts/UnpackMS.cxx @@ -5,6 +5,7 @@ #include "UnpackMS.h" #include "StsXyterMessage.h" +#include "log.hpp" #include <cassert> #include <cmath> @@ -37,11 +38,13 @@ namespace cbm::algo::sts // ---Â Number of messages in microslice auto msSize = msDescr.size; if (msSize % sizeof(stsxyter::Message) != 0) { + L_(error) << "Invalid microslice size: " << msSize; result.second.fNumErrInvalidMsSize++; return result; } const uint32_t numMessages = msSize / sizeof(stsxyter::Message); if (numMessages < 2) { + L_(error) << "Microslice too small: " << numMessages; result.second.fNumErrInvalidMsSize++; return result; } @@ -54,12 +57,14 @@ namespace cbm::algo::sts // --- The first message in the MS is expected to be of type EPOCH and can be ignored. if (message[0].GetMessType() != stsxyter::MessType::Epoch) { + L_(error) << "First message in microslice is not of type EPOCH"; result.second.fNumErrInvalidFirstMessage++; return result; } // --- The second message must be of type ts_msb. if (message[1].GetMessType() != stsxyter::MessType::TsMsb) { + L_(error) << "Second message in microslice is not of type TS_MSB"; result.second.fNumErrInvalidFirstMessage++; return result; } diff --git a/algo/log/AlgoFairloggerCompat.h b/algo/log/AlgoFairloggerCompat.h index 941012523ddf8891630dfce9f4b8586ea70803be..29098c49177aa2a979de4a2033f58898eb40d93f 100644 --- a/algo/log/AlgoFairloggerCompat.h +++ b/algo/log/AlgoFairloggerCompat.h @@ -5,6 +5,14 @@ #define CBM_ALGO_BASE_COMPAT_ONLINEDATALOG_H #ifndef NO_ROOT +// Do not include FairLogger in GPU code (header might not be available) +// FIXME: Ensure NO_ROOT is defined for GPU compilation +#if !defined(__NVCC__) && !defined(__HIPCC__) && !defined(SYCL_LANGUAGE_VERSION) +#define CBM_ONLINE_USE_FAIRLOGGER +#endif +#endif + +#ifdef CBM_ONLINE_USE_FAIRLOGGER #include <fairlogger/Logger.h> @@ -18,6 +26,6 @@ static constexpr severity_level warn = severity_level::warning; #endif // LOG -#endif // NO_ROOT +#endif // CBM_ONLINE_USE_FAIRLOGGER #endif // CBM_ALGO_BASE_COMPAT_ONLINEDATALOG_H diff --git a/algo/unpack/CommonUnpacker.cxx b/algo/unpack/CommonUnpacker.cxx index b1c657bc7dceb78da23d1afe046e2f155aafc736..a55564b131cf8af8c7ff9b67b17b34435798e58c 100644 --- a/algo/unpack/CommonUnpacker.cxx +++ b/algo/unpack/CommonUnpacker.cxx @@ -3,6 +3,8 @@ Authors: Felix Weiglhofer [committer], Dominik Smith */ #include "CommonUnpacker.h" +#include "log.hpp" + using namespace cbm::algo; detail::MSData::MSData(const fles::Timeslice& ts, fles::Subsystem subsystem, gsl::span<u16> legalEqIds, u8 sys_ver) @@ -16,15 +18,23 @@ detail::MSData::MSData(const fles::Timeslice& ts, fles::Subsystem subsystem, gsl continue; } + if (this_subsystem == fles::Subsystem::STS) { + L_(debug) << "Found STS component, eq_id: " << ts.descriptor(comp, 0).eq_id + << ", sys_ver: " << int{ts.descriptor(comp, 0).sys_ver}; + } + const u64 numMsInComp = ts.num_microslices(comp); const u16 componentId = ts.descriptor(comp, 0).eq_id; if (ts.descriptor(comp, 0).sys_ver != sys_ver) { + L_(error) << "Invalid system version " << int{ts.descriptor(comp, 0).sys_ver} << " for subsystem " + << ToString(subsystem); monitor.errInvalidSysVer++; continue; } if (std::find(legalEqIds.begin(), legalEqIds.end(), componentId) == legalEqIds.end()) { + L_(error) << "Invalid equipment id " << componentId << " for subsystem " << ToString(subsystem); monitor.errInvalidEqId++; continue; } @@ -38,4 +48,5 @@ detail::MSData::MSData(const fles::Timeslice& ts, fles::Subsystem subsystem, gsl msContent.push_back(ts.content(comp, mslice)); } } + L_(debug) << "Found " << monitor.numMs << " microslices for subsystem " << ToString(subsystem); } diff --git a/core/data/sts/CbmStsAddress.h b/core/data/sts/CbmStsAddress.h index 6cc0b8780468ed2f5080c15b6b5203873b0bef2c..fe33c6e81b8b976b05cc20b67a39a997555731c8 100644 --- a/core/data/sts/CbmStsAddress.h +++ b/core/data/sts/CbmStsAddress.h @@ -10,6 +10,7 @@ #ifndef CBMSTSADDRESS_H #define CBMSTSADDRESS_H 1 +#include "AlgoFairloggerCompat.h" #include "CbmDefs.h" // for ECbmModuleId #include <cassert> // for assert @@ -202,7 +203,12 @@ namespace CbmStsAddress int32_t ret = (address & kDMask) >> kShift[1][kStsUnit]; +#if XPU_IS_CPU // Check that no bits were set, that are stripped by this function. + if (address != UnpackDigiAddress(ret)) { + LOG(error) << "Address " << address << " contains bits that are stripped by PackDigiAddress"; + } +#endif assert(address == UnpackDigiAddress(ret)); return ret; diff --git a/external/InstallParameter.cmake b/external/InstallParameter.cmake index 413b66f62c5522aa82b614d43da7198e47650e98..a003eb7399842fc9b2130de245deaecc2037fe5c 100644 --- a/external/InstallParameter.cmake +++ b/external/InstallParameter.cmake @@ -1,4 +1,4 @@ -set(PARAMETER_VERSION b67255ed77eb1a803ff95f41a2953c0001127220) # 2024-03-05 +set(PARAMETER_VERSION db9c7e6dc8989998898db60a9c490afa9c9c7891) # 2024-03-06 set(PARAMETER_SRC_URL "https://git.cbm.gsi.de/CbmSoft/cbmroot_parameter.git")