diff --git a/algo/detectors/tof/ReadoutConfig.cxx b/algo/detectors/tof/ReadoutConfig.cxx index 29eb2570dadc1932f3ee29fb82de771e2d75cf21..017839f3f342c1b44c8c6b7b22dff16233a06f1f 100644 --- a/algo/detectors/tof/ReadoutConfig.cxx +++ b/algo/detectors/tof/ReadoutConfig.cxx @@ -62,8 +62,26 @@ namespace cbm::algo::tof } // ------------------------------------------------------------------------------------ + + // --- Mapping (equimentId, elink) -> time offset ------------------------------------- + int32_t ReadoutConfig::TimeOffsetMap(uint16_t equipmentId, uint16_t elinkId) + { + int32_t result = 0; + auto equipIter = fTimeOffsetMap.find(equipmentId); + if (equipIter != fTimeOffsetMap.end()) { + if (elinkId < equipIter->second.size()) { + result = equipIter->second.at(elinkId); + } + } + return result; + } + // ------------------------------------------------------------------------------------ + + void ReadoutConfig::Init(const ReadoutSetup& pars) { + fTimeOffset = pars.timeOffset; + // Constructing the map (equipmentId, eLink, channel) -> (TOF address) const uint32_t numChanPerComp = pars.NChansPerComponent(); @@ -74,9 +92,14 @@ namespace cbm::algo::tof uint16_t equipment = pars.eqIds.at(comp); fReadoutMap[equipment].resize(pars.NElinksPerComponent()); + fTimeOffsetMap[equipment].resize(pars.NElinksPerComponent()); for (uint16_t elink = 0; elink < pars.NElinksPerComponent(); elink++) { fReadoutMap[equipment][elink].resize(pars.nChannelsPerAsic); + + const uint32_t crob = elink / pars.NElinksPerCrob() + comp * pars.NCrobsPerComponent(); + fTimeOffsetMap[equipment][elink] = pars.crobs[crob].timeOffset; + const uint32_t asicId = pars.CheckInnerComp(equipment) ? ElinkIdxToGet4IdxInner(elink, pars) : ElinkIdxToGet4Idx(elink, pars); diff --git a/algo/detectors/tof/ReadoutConfig.h b/algo/detectors/tof/ReadoutConfig.h index 041d545390cb5b50f204a09d8c304e763e630cc9..a4f74121b8199f7db8dc06be7a5161c281db5f64 100644 --- a/algo/detectors/tof/ReadoutConfig.h +++ b/algo/detectors/tof/ReadoutConfig.h @@ -27,14 +27,17 @@ namespace cbm::algo::tof i32 rpcType; i32 rpcSide; i32 nRPC; + i32 timeOffset; CBM_YAML_PROPERTIES( yaml::Property(&CROB::moduleId, "moduleId", "Unique ID of module the CROB resides in"), yaml::Property(&CROB::rpcType, "rpcType", "add explanation."), yaml::Property(&CROB::rpcSide, "rpcSide", "add explanation."), - yaml::Property(&CROB::nRPC, "nRPC", "number of RPCs.")); + yaml::Property(&CROB::nRPC, "nRPC", "number of RPCs."), + yaml::Property(&CROB::timeOffset, "timeOffset", "time offset for CROB")); }; + i32 timeOffset; i32 nFebsPerComponent; i32 nAsicsPerFeb; i32 nChannelsPerAsic; @@ -45,24 +48,25 @@ namespace cbm::algo::tof std::vector<i32> elink2AsicInner; std::vector<i32> asic2PadI; - CBM_YAML_PROPERTIES(yaml::Property(&ReadoutSetup::nFebsPerComponent, "nFebsPerComponent", "Number of FEBs per component"), + CBM_YAML_PROPERTIES(yaml::Property(&ReadoutSetup::timeOffset, "timeOffset", "Time offset for TOF"), + yaml::Property(&ReadoutSetup::nFebsPerComponent, "nFebsPerComponent", "Number of FEBs per component"), yaml::Property(&ReadoutSetup::nAsicsPerFeb, "nAsicsPerFeb", "Number of ASICs per FEB"), yaml::Property(&ReadoutSetup::nChannelsPerAsic, "nChannelsPerAsic", "Number of channels per ASIC"), yaml::Property(&ReadoutSetup::nCrobPerComponent, "nCrobPerComponent", "Number of CROBs per component"), yaml::Property(&ReadoutSetup::crobs, "crobs", "Crobs", {}, YAML::Flow), yaml::Property(&ReadoutSetup::eqIds, "eqIds", "Array to hold the unique IDs (equipment ID) for all TOF DPBs" , YAML::Flow, YAML::Hex), - yaml::Property(&ReadoutSetup::elink2Asic, "elink2Asic", "Mapping to eLink to ASIC number within CROB. Mapping is the same for each CROB. (size: nElinksPerCrob)" , YAML::Flow), - yaml::Property(&ReadoutSetup::elink2AsicInner, "elink2AsicInner", "add explanation" , YAML::Flow), - yaml::Property(&ReadoutSetup::asic2PadI, "asic2PadI", "Mapping in Readout chain PCBs; Map from GET4 channel to PADI channel (size: nChansPerFeb)" , YAML::Flow)); - + yaml::Property(&ReadoutSetup::elink2Asic, "elink2Asic", "Mapping to eLink to ASIC number within CROB. Mapping is the same for each CROB. (size: nElinksPerCrob)" , YAML::Flow), + yaml::Property(&ReadoutSetup::elink2AsicInner, "elink2AsicInner", "add explanation" , YAML::Flow), + yaml::Property(&ReadoutSetup::asic2PadI, "asic2PadI", "Mapping in Readout chain PCBs; Map from GET4 channel to PADI channel (size: nChansPerFeb)" , YAML::Flow)); + size_t NComponents() const { return eqIds.size(); } + size_t NCROBs() const { return crobs.size(); } i32 NFebsPerCrob() const { return nFebsPerComponent / nCrobPerComponent; } i32 NChansPerFeb() const { return nAsicsPerFeb * nChannelsPerAsic; } i32 NChansPerComponent() const { return nChannelsPerAsic * NElinksPerComponent(); } i32 NElinksPerCrob() const { return nAsicsPerFeb * NFebsPerCrob(); } i32 NElinksPerComponent() const { return NElinksPerCrob() * nCrobPerComponent; } - size_t NCROBs() const { return crobs.size(); } - size_t NComponents() const { return eqIds.size(); } + i32 NCrobsPerComponent() const { return nCrobPerComponent; } bool CheckBmonComp(uint32_t uCompId) const { return ((uCompId & 0xFFF0) == 0xABF0); } bool CheckInnerComp(uint32_t uCompId) const { return ((uCompId & 0xFFF0) == 0xBBC0); } @@ -80,6 +84,11 @@ namespace cbm::algo::tof /** @brief Destructor **/ ~ReadoutConfig(); + /** @brief System time offset for TOF + ** @return Value of system time offset + **/ + i32 TimeOffset() const { return fTimeOffset; } + /** @brief Equipment in the configuration ** @return Vector of equipment IDs **/ @@ -98,7 +107,21 @@ namespace cbm::algo::tof */ std::vector<uint32_t> Map(uint16_t equipId, uint16_t elink); + /** @brief API: Mapping from component and elink to time offset + ** @param equipId Equipment identifier (component) + ** @param elink Elink number within component + ** @return Time Offset + */ + int32_t TimeOffsetMap(uint16_t equipId, uint16_t elink); + private: + // --- BMon system time offset + int32_t fTimeOffset = 0; + + // --- TOF elink time offsets + // --- Map index: (equipment, elink), map value: (time offset) + std::map<uint16_t, std::vector<uint64_t>> fTimeOffsetMap = {}; + // --- TOF readout map // --- Map index: (equipment, elink, channel), map value: (TOF address) std::map<uint16_t, std::vector<std::vector<uint32_t>>> fReadoutMap = {}; diff --git a/algo/detectors/tof/Unpack.cxx b/algo/detectors/tof/Unpack.cxx index 3f6dbb2d5d3e1013a2787c7ef37dedd55bd12b47..2c95397abd95f51d6b99b406040b344f0f70f063 100644 --- a/algo/detectors/tof/Unpack.cxx +++ b/algo/detectors/tof/Unpack.cxx @@ -11,8 +11,8 @@ using fles::Subsystem; Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout) { - constexpr i32 SystemTimeOffset = 40; - constexpr u8 SystemVersion = 0x00; + constexpr u8 SystemVersion = 0x00; + i32 SysTimeOffset = fReadout.TimeOffset(); auto equipIdsTof = fReadout.GetEquipmentIds(); for (auto& equip : equipIdsTof) { @@ -21,7 +21,7 @@ Unpack::Unpack(const ReadoutConfig& readout) : fReadout(readout) for (size_t elink = 0; elink < numElinks; elink++) { tof::UnpackElinkPar elinkPar; elinkPar.fChannelUId = fReadout.Map(equip, elink); // Vector of TOF addresses for this elink - elinkPar.fTimeOffset = SystemTimeOffset; + elinkPar.fTimeOffset = SysTimeOffset + fReadout.TimeOffsetMap(equip, elink); // Time offset for this elink par.fElinkParams.push_back(elinkPar); } auto algo = std::make_unique<UnpackMS>(std::move(par));